infra-kit 0.1.93 → 0.1.95

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.
Files changed (45) hide show
  1. package/.eslintcache +1 -1
  2. package/.turbo/turbo-eslint-check.log +4 -5
  3. package/.turbo/turbo-prettier-check.log +7 -5
  4. package/.turbo/turbo-test.log +82 -18
  5. package/.turbo/turbo-ts-check.log +10 -5
  6. package/dist/cli.js +37 -34
  7. package/dist/cli.js.map +4 -4
  8. package/dist/mcp.js +30 -27
  9. package/dist/mcp.js.map +4 -4
  10. package/package.json +2 -2
  11. package/src/commands/doctor/doctor.ts +119 -1
  12. package/src/commands/env-clear/env-clear.ts +1 -1
  13. package/src/commands/env-list/env-list.ts +1 -1
  14. package/src/commands/env-load/env-load.ts +1 -1
  15. package/src/commands/env-status/env-status.ts +1 -1
  16. package/src/commands/gh-merge-dev/gh-merge-dev.ts +1 -1
  17. package/src/commands/gh-release-deliver/gh-release-deliver.ts +1 -1
  18. package/src/commands/gh-release-deploy-all/gh-release-deploy-all.ts +1 -1
  19. package/src/commands/gh-release-deploy-selected/gh-release-deploy-selected.ts +1 -1
  20. package/src/commands/gh-release-list/gh-release-list.ts +1 -1
  21. package/src/commands/init/init.ts +3 -3
  22. package/src/commands/release-create/release-create.ts +1 -1
  23. package/src/commands/release-create-batch/release-create-batch.ts +1 -1
  24. package/src/commands/version/version.ts +1 -1
  25. package/src/commands/worktrees-add/index.ts +2 -1
  26. package/src/commands/worktrees-add/worktrees-add.ts +55 -14
  27. package/src/commands/worktrees-list/worktrees-list.ts +1 -1
  28. package/src/commands/worktrees-remove/worktrees-remove.ts +68 -4
  29. package/src/commands/worktrees-sync/worktrees-sync.ts +69 -5
  30. package/src/entry/cli.ts +25 -4
  31. package/src/integrations/clickup/.gitkeep +0 -0
  32. package/src/integrations/cmux/close-workspace-by-title.ts +51 -0
  33. package/src/integrations/cmux/index.ts +2 -0
  34. package/src/integrations/cmux/workspace-title.ts +17 -0
  35. package/src/integrations/cursor/add-folders-to-workspace.ts +84 -0
  36. package/src/integrations/cursor/index.ts +3 -0
  37. package/src/integrations/cursor/remove-folders-from-workspace.ts +93 -0
  38. package/src/integrations/cursor/resolve-workspace-path.ts +13 -0
  39. package/src/integrations/doppler/doppler-project.ts +2 -2
  40. package/src/lib/__tests__/infra-kit-config.test.ts +64 -14
  41. package/src/lib/infra-kit-config/index.ts +2 -0
  42. package/src/lib/infra-kit-config/infra-kit-config.ts +143 -0
  43. package/tsconfig.json +3 -2
  44. package/tsconfig.tsbuildinfo +1 -1
  45. package/src/lib/infra-kit-config.ts +0 -69
package/dist/cli.js.map CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../src/entry/cli.ts", "../src/commands/doctor/doctor.ts", "../src/lib/logger/index.ts", "../src/commands/env-clear/env-clear.ts", "../src/lib/constants.ts", "../src/commands/env-list/env-list.ts", "../src/lib/infra-kit-config.ts", "../src/lib/git-utils/git-utils.ts", "../src/integrations/doppler/doppler-project.ts", "../src/commands/env-load/env-load.ts", "../src/integrations/doppler/doppler-cli-auth.ts", "../src/lib/command-echo/command-echo.ts", "../src/commands/env-status/env-status.ts", "../src/commands/gh-merge-dev/gh-merge-dev.ts", "../src/integrations/gh/gh-cli-auth/gh-cli-auth.ts", "../src/integrations/gh/gh-release-prs/gh-release-prs.ts", "../src/lib/release-utils/release-utils.ts", "../src/integrations/jira/api.ts", "../src/lib/version-utils/version-utils.ts", "../src/commands/gh-release-deliver/gh-release-deliver.ts", "../src/commands/gh-release-deploy-all/gh-release-deploy-all.ts", "../src/commands/gh-release-deploy-selected/gh-release-deploy-selected.ts", "../src/commands/gh-release-list/gh-release-list.ts", "../src/commands/init/init.ts", "../src/commands/release-create/release-create.ts", "../src/commands/release-create-batch/release-create-batch.ts", "../src/commands/version/version.ts", "../package.json", "../src/commands/worktrees-add/worktrees-add.ts", "../src/integrations/cmux/open-workspace-with-layout.ts", "../src/commands/worktrees-list/worktrees-list.ts", "../src/commands/worktrees-remove/worktrees-remove.ts", "../src/commands/worktrees-sync/worktrees-sync.ts"],
4
- "sourcesContent": ["import select, { Separator } from '@inquirer/select'\nimport { Command, Option } from 'commander'\nimport process from 'node:process'\n\nimport { doctor } from 'src/commands/doctor'\nimport { envClear } from 'src/commands/env-clear'\nimport { envList } from 'src/commands/env-list'\nimport { envLoad } from 'src/commands/env-load'\nimport { envStatus } from 'src/commands/env-status'\nimport { ghMergeDev } from 'src/commands/gh-merge-dev'\nimport { ghReleaseDeliver } from 'src/commands/gh-release-deliver'\nimport { ghReleaseDeployAll } from 'src/commands/gh-release-deploy-all'\nimport { ghReleaseDeploySelected } from 'src/commands/gh-release-deploy-selected'\nimport { ghReleaseList } from 'src/commands/gh-release-list'\nimport { init } from 'src/commands/init'\nimport { releaseCreate } from 'src/commands/release-create'\nimport { releaseCreateBatch } from 'src/commands/release-create-batch'\nimport { version } from 'src/commands/version'\nimport { worktreesAdd } from 'src/commands/worktrees-add'\nimport { worktreesList } from 'src/commands/worktrees-list'\nimport { worktreesRemove } from 'src/commands/worktrees-remove'\nimport { worktreesSync } from 'src/commands/worktrees-sync'\nimport { logger } from 'src/lib/logger'\n\nconst program = new Command()\n\nconst runProgram = async (argv?: string[]): Promise<void> => {\n try {\n if (argv) {\n await program.parseAsync(argv)\n } else {\n await program.parseAsync()\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n\n logger.error(message)\n process.exit(1)\n }\n}\n\nprogram\n .command('merge-dev')\n .description('Merge dev branch into every release branch')\n .option('-a, --all', 'Select all active release branches')\n .option('-y, --yes', 'Skip confirmation prompt')\n .action(async (options) => {\n await ghMergeDev({ all: options.all, confirmedCommand: options.yes })\n })\n\nprogram\n .command('release-list')\n .description('List all release branches')\n .action(async () => {\n await ghReleaseList()\n })\n\nprogram\n .command('release-create')\n .description('Create a single release branch')\n .option('-v, --version <version>', 'Specify the version to create, e.g. 1.2.5')\n .option('-d, --description <description>', 'Optional description for the Jira version')\n .addOption(new Option('-t, --type <type>', 'Release type (default: regular)').choices(['regular', 'hotfix']))\n .option('-y, --yes', 'Skip confirmation prompt')\n .option('--no-checkout', 'Do not checkout the created branch after creation (checkout is default)')\n .action(async (options) => {\n await releaseCreate({\n version: options.version,\n description: options.description,\n type: options.type,\n confirmedCommand: options.yes,\n checkout: options.checkout,\n })\n })\n\nprogram\n .command('release-create-batch')\n .description('Create multiple release branches (batch operation)')\n .option('-v, --versions <versions>', 'Specify the versions to create by comma, e.g. 1.2.5, 1.2.6')\n .addOption(new Option('-t, --type <type>', 'Release type (default: regular)').choices(['regular', 'hotfix']))\n .option('-y, --yes', 'Skip confirmation prompt')\n .action(async (options) => {\n await releaseCreateBatch({\n versions: options.versions,\n type: options.type,\n confirmedCommand: options.yes,\n })\n })\n\nprogram\n .command('release-deploy-all')\n .description('Deploy any release branch to any environment')\n .option('-v, --version <version>', 'Specify the version to deploy, e.g. 1.2.5')\n .option('-e, --env <env>', 'Specify the environment to deploy to, e.g. dev')\n .option('--skip-terraform', 'Skip terraform deployment step')\n .action(async (options) => {\n await ghReleaseDeployAll({ version: options.version, env: options.env, skipTerraform: options.skipTerraform })\n })\n\nprogram\n .command('release-deploy-selected')\n .description('Deploy selected services from release branch to any environment')\n .option('-v, --version <version>', 'Specify the version to deploy, e.g. 1.2.5')\n .option('-e, --env <env>', 'Specify the environment to deploy to, e.g. dev')\n .option('-s, --services <services...>', 'Specify services to deploy, e.g. client-be client-fe')\n .option('--skip-terraform', 'Skip terraform deployment step')\n .action(async (options) => {\n await ghReleaseDeploySelected({\n version: options.version,\n env: options.env,\n services: options.services,\n skipTerraform: options.skipTerraform,\n })\n })\n\nprogram\n .command('release-deliver')\n .description('Release a new version to production')\n .option('-v, --version <version>', 'Specify the version to release, e.g. 1.2.5')\n .option('-y, --yes', 'Skip confirmation prompt')\n .action(async (options) => {\n await ghReleaseDeliver({ version: options.version, confirmedCommand: options.yes })\n })\n\nprogram\n .command('worktrees-sync')\n .description('Remove release worktrees whose PRs are no longer open')\n .option('-y, --yes', 'Skip confirmation prompt')\n .action(async (options) => {\n await worktreesSync({ confirmedCommand: options.yes })\n })\n\nprogram\n .command('worktrees-add')\n .description('Add git worktrees for release branches')\n .option('-y, --yes', 'Skip confirmation prompt')\n .option('-a, --all', 'Select all active release branches')\n .option('-v, --versions <versions>', 'Specify versions by comma, e.g. 1.2.5, 1.2.6')\n .option('-c, --cursor', 'Open created worktrees in Cursor')\n .option('--no-cursor', 'Skip Cursor prompt')\n .option('-g, --github-desktop', 'Open created worktrees in GitHub Desktop')\n .option('--no-github-desktop', 'Skip GitHub Desktop prompt')\n .option('-m, --cmux', 'Open created worktrees in cmux (3-pane layout)')\n .option('--no-cmux', 'Skip cmux prompt')\n .action(async (options) => {\n await worktreesAdd({\n confirmedCommand: options.yes,\n all: options.all,\n versions: options.versions,\n cursor: options.cursor,\n githubDesktop: options.githubDesktop,\n cmux: options.cmux,\n })\n })\n\nprogram\n .command('worktrees-list')\n .description('List all git worktrees with detailed information')\n .action(async () => {\n await worktreesList()\n })\n\nprogram\n .command('worktrees-remove')\n .description('Remove git worktrees for release branches')\n .option('-y, --yes', 'Skip confirmation prompt')\n .option('-a, --all', 'Select all active release branches')\n .option('-v, --versions <versions>', 'Specify versions by comma, e.g. 1.2.5, 1.2.6')\n .action(async (options) => {\n await worktreesRemove({ confirmedCommand: options.yes, all: options.all, versions: options.versions })\n })\n\nprogram\n .command('doctor')\n .description('Check installation and authentication status of gh and doppler CLIs')\n .action(async () => {\n await doctor()\n })\n\nprogram\n .command('version')\n .description('Print the installed infra-kit CLI version')\n .action(async () => {\n await version()\n })\n\nprogram\n .command('env-status')\n .description('Show Doppler authentication status and detected project info')\n .action(async () => {\n await envStatus()\n })\n\nprogram\n .command('env-list')\n .description('List available Doppler configs for the detected project')\n .action(async () => {\n await envList()\n })\n\nprogram\n .command('init')\n .description('Inject shell integration into your profile .zshrc')\n .action(async () => {\n await init()\n })\n\nprogram\n .command('env-load')\n .description('Load Doppler env vars for a config. Source the returned file path to apply.')\n .option('-c, --config <config>', 'Environment config name to load (e.g. dev, arthur)')\n .action(async (options) => {\n await envLoad({ config: options.config })\n })\n\nprogram\n .command('env-clear')\n .description('Clear loaded env vars. Source the returned file path to apply.')\n .action(async () => {\n await envClear()\n })\n\nif (process.argv.length <= 2) {\n const releaseCommands = [\n 'merge-dev',\n 'release-list',\n 'release-create',\n 'release-create-batch',\n 'release-deploy-all',\n 'release-deploy-selected',\n 'release-deliver',\n ]\n const worktreeCommands = ['worktrees-add', 'worktrees-list', 'worktrees-remove', 'worktrees-sync']\n const envCommands = ['doctor', 'init', 'version', 'env-status', 'env-list', 'env-load', 'env-clear']\n\n const commandMap = new Map(\n program.commands.map((cmd) => {\n return [cmd.name(), cmd]\n }),\n )\n\n const allNames = [...releaseCommands, ...worktreeCommands, ...envCommands]\n const maxLen = Math.max(\n ...allNames.map((n) => {\n return n.length\n }),\n )\n\n const toChoices = (names: string[]) => {\n return names\n .filter((n) => {\n return commandMap.has(n)\n })\n .map((n) => {\n return {\n name: `${n.padEnd(maxLen)} ${commandMap.get(n)!.description()}`,\n value: n,\n }\n })\n }\n\n const selected = await select(\n {\n message: 'Select a command to run',\n choices: [\n new Separator(' '),\n new Separator('\u2014 Release Management \u2014'),\n ...toChoices(releaseCommands),\n new Separator(' '),\n new Separator('\u2014 Worktrees \u2014'),\n ...toChoices(worktreeCommands),\n new Separator(' '),\n new Separator('\u2014 Environment \u2014'),\n ...toChoices(envCommands),\n ],\n },\n { output: process.stderr },\n )\n\n await runProgram(['node', 'infra-kit', selected])\n} else {\n await runProgram()\n}\n", "import { z } from 'zod'\nimport { $ } from 'zx'\n\nimport { logger } from 'src/lib/logger'\nimport type { ToolsExecutionResult } from 'src/types'\n\ninterface CheckResult {\n name: string\n status: 'pass' | 'fail'\n message: string\n}\n\nconst checkCommand = async (\n name: string,\n command: string[],\n successMsg: string,\n failMsg: string,\n): Promise<CheckResult> => {\n try {\n await $`${command}`\n\n return { name, status: 'pass', message: successMsg }\n } catch {\n return { name, status: 'fail', message: failMsg }\n }\n}\n\n/**\n * Check installation and authentication status of gh, doppler, and aws CLIs\n */\nexport const doctor = async (): Promise<ToolsExecutionResult> => {\n const checks: CheckResult[] = await Promise.all([\n checkCommand(\n 'gh installed',\n ['gh', '--version'],\n 'GitHub CLI is installed',\n 'GitHub CLI is not installed. Install from: https://cli.github.com/',\n ),\n checkCommand(\n 'gh authenticated',\n ['gh', 'auth', 'status'],\n 'GitHub CLI is authenticated',\n 'GitHub CLI is not authenticated. Run: gh auth login',\n ),\n checkCommand(\n 'doppler installed',\n ['doppler', '--version'],\n 'Doppler CLI is installed',\n 'Doppler CLI is not installed. Install from: https://docs.doppler.com/docs/install-cli',\n ),\n checkCommand(\n 'doppler authenticated',\n ['doppler', 'me'],\n 'Doppler CLI is authenticated',\n 'Doppler CLI is not authenticated. Run: doppler login',\n ),\n checkCommand(\n 'aws installed',\n ['aws', '--version'],\n 'AWS CLI is installed',\n 'AWS CLI is not installed. Install from: https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html',\n ),\n // INFO: no need now, util the user does not load the env variables, the aws cli is not authenticated\n // checkCommand(\n // 'aws authenticated',\n // ['aws', 'sts', 'get-caller-identity'],\n // 'AWS CLI is authenticated',\n // 'AWS CLI is not authenticated. Run: aws configure (or aws sso login)',\n // ),\n ])\n\n logger.info('Doctor check results:\\n')\n\n for (const check of checks) {\n const icon = check.status === 'pass' ? '[PASS]' : '[FAIL]'\n\n logger.info(` ${icon} ${check.name}: ${check.message}`)\n }\n\n const structuredContent = {\n checks: checks.map((c) => {\n return { name: c.name, status: c.status, message: c.message }\n }),\n allPassed: checks.every((c) => {\n return c.status === 'pass'\n }),\n }\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(structuredContent, null, 2),\n },\n ],\n structuredContent,\n }\n}\n\n// MCP Tool Registration\nexport const doctorMcpTool = {\n name: 'doctor',\n description: 'Check installation and authentication status of gh, doppler, and aws CLIs',\n inputSchema: {},\n outputSchema: {\n checks: z\n .array(\n z.object({\n name: z.string().describe('Name of the check'),\n status: z.enum(['pass', 'fail']).describe('Check result'),\n message: z.string().describe('Details about the check result'),\n }),\n )\n .describe('List of all check results'),\n allPassed: z.boolean().describe('Whether all checks passed'),\n },\n handler: doctor,\n}\n", "import process from 'node:process'\nimport pino from 'pino'\nimport pretty from 'pino-pretty'\n\n// eslint-disable-next-line sonarjs/publicly-writable-directories\nexport const LOG_FILE_PATH = '/tmp/mcp-infra-kit.log'\n\nexport const initLoggerMcp = () => {\n const logLevel = process.argv.includes('--debug') ? 'debug' : 'info'\n\n const logger = pino({ level: logLevel }, pino.destination({ dest: LOG_FILE_PATH }))\n\n logger.info(`Logger initialized with level: ${logLevel}. Logging to: ${LOG_FILE_PATH}`)\n\n return logger\n}\n\nexport const initLoggerCLI = () => {\n const logLevel = process.argv.includes('--debug') ? 'debug' : 'info'\n\n const ignoreFields = ['time', 'pid', 'hostname']\n\n if (logLevel === 'debug') {\n ignoreFields.push('level')\n }\n\n const logger = pino(\n { level: logLevel },\n pretty({\n destination: 2,\n ignore: ignoreFields.join(','),\n colorize: true,\n }),\n )\n\n return logger\n}\n\n// Singleton logger instance for CLI usage\nexport const logger = initLoggerCLI()\n", "import fs from 'node:fs'\nimport path from 'node:path'\nimport process from 'node:process'\nimport { z } from 'zod'\n\nimport {\n ENV_CLEAR_FILE,\n ENV_LOAD_FILE,\n INFRA_KIT_ENV_CONFIG_VAR,\n INFRA_KIT_ENV_LOADED_AT_VAR,\n INFRA_KIT_ENV_PROJECT_VAR,\n atomicWriteFileSync,\n getSessionCacheDir,\n parseVarNamesFromEnvFile,\n} from 'src/lib/constants'\nimport type { ToolsExecutionResult } from 'src/types'\n\n/**\n * Clear loaded env vars. Prints a file path to stdout that must be sourced to apply.\n * The env-clear shell alias does this automatically. Throws when no env is loaded\n * so CLI callers exit non-zero and MCP callers receive a structured tool error.\n */\nexport const envClear = async (): Promise<ToolsExecutionResult> => {\n const cacheDir = getSessionCacheDir()\n const envLoadPath = path.join(cacheDir, ENV_LOAD_FILE)\n\n if (!fs.existsSync(envLoadPath)) {\n throw new Error('No loaded environment found. Run `env-load` first.')\n }\n\n const varNames = parseVarNamesFromEnvFile(envLoadPath)\n\n const unsetLines = [\n ...varNames.map((v) => {\n return `unset ${v}`\n }),\n `unset ${INFRA_KIT_ENV_CONFIG_VAR}`,\n `unset ${INFRA_KIT_ENV_PROJECT_VAR}`,\n `unset ${INFRA_KIT_ENV_LOADED_AT_VAR}`,\n ]\n\n const clearFilePath = path.resolve(cacheDir, ENV_CLEAR_FILE)\n\n fs.mkdirSync(cacheDir, { recursive: true, mode: 0o700 })\n\n atomicWriteFileSync(clearFilePath, `${unsetLines.join('\\n')}\\n`, 0o600)\n\n // REQUIRED\n process.stdout.write(`${clearFilePath}\\n`)\n\n // Remove env load file so the next env-clear call correctly reports \"no env loaded\".\n fs.unlinkSync(envLoadPath)\n\n const structuredContent = {\n filePath: clearFilePath,\n variableCount: varNames.length,\n unsetStatements: unsetLines,\n }\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(structuredContent, null, 2),\n },\n ],\n structuredContent,\n }\n}\n\n// MCP Tool Registration\nexport const envClearMcpTool = {\n name: 'env-clear',\n description:\n 'Generate a shell script that unsets every env var previously loaded by env-load for this session, plus the infra-kit session metadata vars. Does NOT mutate the calling process. When `infra-kit init` has installed the zsh shell integration, the user\\'s terminal auto-sources the unset script on its next prompt (precmd hook) \u2014 so calling this via MCP will clear the vars in the shell that launched Claude Code automatically. Other callers must source \"<filePath>\" themselves or surface it to the user. Errors if no env is currently loaded.',\n inputSchema: {},\n outputSchema: {\n filePath: z.string().describe('Path to the file that must be sourced to apply'),\n variableCount: z.number().describe('Number of variables cleared'),\n unsetStatements: z.array(z.string()).describe('Unset statements generated'),\n },\n handler: envClear,\n}\n", "import fs from 'node:fs'\nimport os from 'node:os'\nimport path from 'node:path'\nimport process from 'node:process'\n\nexport const ENV_LOAD_FILE = 'env-load.sh'\nexport const ENV_CLEAR_FILE = 'env-clear.sh'\n\nexport const INFRA_KIT_SESSION_VAR = 'INFRA_KIT_SESSION'\nexport const INFRA_KIT_ENV_CONFIG_VAR = 'INFRA_KIT_ENV_CONFIG'\nexport const INFRA_KIT_ENV_PROJECT_VAR = 'INFRA_KIT_ENV_PROJECT'\nexport const INFRA_KIT_ENV_LOADED_AT_VAR = 'INFRA_KIT_ENV_LOADED_AT'\n\n/**\n * Matches a line of the form `KEY=...` where KEY is an env-var identifier\n * (letter or underscore, then word chars). Capture group 1 is the name. Shared\n * between env-load (validation, var counting) and parseVarNamesFromEnvFile.\n */\nexport const ENV_VAR_LINE_PATTERN = /^([A-Z_]\\w*)=/i\n\nexport const parseVarNamesFromEnvFile = (filePath: string): string[] => {\n if (!fs.existsSync(filePath)) return []\n\n const content = fs.readFileSync(filePath, 'utf-8')\n const names: string[] = []\n\n for (const line of content.split('\\n')) {\n const match = ENV_VAR_LINE_PATTERN.exec(line)\n\n if (match) {\n names.push(match[1]!)\n }\n }\n\n return names\n}\n\n/**\n * Root cache dir for infra-kit across all sessions. Resolved from\n * $XDG_CACHE_HOME when set, falling back to ~/.cache/infra-kit. Keep in sync\n * with the shell block emitted by `infra-kit init` (src/commands/init/init.ts).\n */\nexport const getCacheRoot = (): string => {\n const xdg = process.env.XDG_CACHE_HOME\n const base = xdg && xdg.length > 0 ? xdg : path.join(os.homedir(), '.cache')\n\n return path.join(base, 'infra-kit')\n}\n\nexport const getSessionCacheDir = (): string => {\n const session = process.env[INFRA_KIT_SESSION_VAR]\n\n if (!session) {\n throw new Error(`${INFRA_KIT_SESSION_VAR} is not set. Run \\`infra-kit init\\` then \\`source ~/.zshrc\\`.`)\n }\n\n return path.join(getCacheRoot(), session)\n}\n\n/**\n * Write content atomically: write to a pid-suffixed temp file in the same\n * directory, then rename. fs.renameSync is atomic on a single filesystem, so\n * concurrent writers can't produce a half-written secret file.\n */\nexport const atomicWriteFileSync = (filePath: string, content: string, mode: number): void => {\n const tmpPath = `${filePath}.tmp.${process.pid}`\n\n fs.writeFileSync(tmpPath, content, { mode })\n\n try {\n fs.renameSync(tmpPath, filePath)\n } catch (error) {\n fs.rmSync(tmpPath, { force: true })\n throw error\n }\n}\n\nexport const WORKTREES_DIR_SUFFIX = '-worktrees'\n// eslint-disable-next-line sonarjs/publicly-writable-directories\nexport const LOG_FILE_PATH = '/tmp/mcp-infra-kit.log'\n", "import { z } from 'zod'\n\nimport { getDopplerProject } from 'src/integrations/doppler/doppler-project'\nimport { getInfraKitConfig } from 'src/lib/infra-kit-config'\nimport { logger } from 'src/lib/logger'\nimport type { ToolsExecutionResult } from 'src/types'\n\n/**\n * List available Doppler configs for the detected project.\n *\n * Purely local: reads infra-kit.yml and does not call Doppler. We intentionally\n * do not run validateDopplerCliAndAuth here \u2014 users listing envs often do so\n * before `doppler login`, and a spurious auth error would be misleading.\n */\nexport const envList = async (): Promise<ToolsExecutionResult> => {\n const project = await getDopplerProject()\n const { environments } = await getInfraKitConfig()\n\n logger.info(`Doppler project: ${project}\\n`)\n logger.info('Available configs:')\n\n for (const env of environments) {\n logger.info(` - ${env}`)\n }\n\n const structuredContent = {\n project,\n configs: environments,\n }\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(structuredContent, null, 2),\n },\n ],\n structuredContent,\n }\n}\n\n// MCP Tool Registration\nexport const envListMcpTool = {\n name: 'env-list',\n description:\n 'List the environments the project is configured to support. Returns the `environments` list declared in infra-kit.yml at the project root (not a live fetch from Doppler) plus the Doppler project name resolved from the same file. Read-only.',\n inputSchema: {},\n outputSchema: {\n project: z.string().describe('Detected Doppler project name'),\n configs: z.array(z.string()).describe('Available environment configs'),\n },\n handler: envList,\n}\n", "import fs from 'node:fs/promises'\nimport path from 'node:path'\nimport yaml from 'yaml'\nimport { z } from 'zod'\n\nimport { getProjectRoot } from 'src/lib/git-utils'\n\nconst INFRA_KIT_CONFIG_FILE = 'infra-kit.yml'\n\nconst jiraTaskManagerProviderSchema = z.object({\n type: z.literal('jira'),\n baseUrl: z.string().url(),\n projectId: z.number().int().positive(),\n})\n\nconst infraKitConfigSchema = z.object({\n dopplerProjectName: z.string().min(1),\n environments: z.array(z.string().min(1)).min(1),\n taskManagerProvider: z.union([z.string(), z.literal(false), jiraTaskManagerProviderSchema]),\n})\n\nexport type InfraKitConfig = z.infer<typeof infraKitConfigSchema>\n\ninterface CacheEntry {\n mtimeMs: number\n value: InfraKitConfig\n}\n\nlet cached: CacheEntry | null = null\n\n/**\n * Read and validate infra-kit.yml. Results are cached per file mtime so the\n * long-running MCP server picks up edits without a restart \u2014 if the user edits\n * infra-kit.yml mid-session, the next call re-reads it.\n */\nexport const getInfraKitConfig = async (): Promise<InfraKitConfig> => {\n const projectRoot = await getProjectRoot()\n const configPath = path.join(projectRoot, INFRA_KIT_CONFIG_FILE)\n\n let stat: Awaited<ReturnType<typeof fs.stat>>\n\n try {\n stat = await fs.stat(configPath)\n } catch {\n cached = null\n throw new Error(`infra-kit.yml not found at ${configPath}`)\n }\n\n if (cached && cached.mtimeMs === stat.mtimeMs) {\n return cached.value\n }\n\n const raw = await fs.readFile(configPath, 'utf-8')\n const parsed = yaml.parse(raw)\n const result = infraKitConfigSchema.safeParse(parsed)\n\n if (!result.success) {\n throw new Error(`Invalid infra-kit.yml at ${configPath}: ${result.error.message}`)\n }\n\n cached = { mtimeMs: stat.mtimeMs, value: result.data }\n\n return result.data\n}\n\n/** For tests \u2014 drops the in-memory cache. */\nexport const resetInfraKitConfigCache = (): void => {\n cached = null\n}\n", "import path from 'node:path'\nimport { $ } from 'zx'\n\n/**\n * Get current git worktrees\n *\n * @returns [release/v1.18.22, release/v1.18.23, release/v1.18.24] or [feature/mobile-app, feature/explore-page, feature/login-page]\n */\nexport const getCurrentWorktrees = async (type: 'release' | 'feature'): Promise<string[]> => {\n const worktreesOutput = await $`git worktree list`\n\n const worktreeLines = worktreesOutput.stdout.split('\\n').filter(Boolean)\n\n const worktreePredicateMap = {\n release: releaseWorktreePredicate,\n feature: featureWorktreePredicate,\n }\n\n return worktreeLines.map(worktreePredicateMap[type]).filter((branch) => {\n return branch !== null\n })\n}\n\n/**\n * Extract a release branch name from a `git worktree list` output line.\n *\n * Returns `null` for lines that are not release worktrees.\n *\n * @example\n * releaseWorktreePredicate('/path/to/release/v1.18.22 abc1234 [release/v1.18.22]')\n * // => 'release/v1.18.22'\n *\n * @example\n * releaseWorktreePredicate('/path/to/feature/login abc1234 [feature/login]')\n * // => null\n */\nconst releaseWorktreePredicate = (line: string): string | null => {\n const parts = line.split(' ').filter(Boolean)\n\n if (parts.length < 3 || !parts[0]?.includes('release/v')) return null\n\n return `release/${parts[0]?.split('/').pop() || ''}`\n}\n\n/**\n * Extract a feature branch name from a `git worktree list` output line.\n *\n * Returns `null` for lines that are not feature worktrees.\n *\n * @example\n * featureWorktreePredicate('/path/to/feature/login-page abc1234 [feature/login-page]')\n * // => 'feature/login-page'\n *\n * @example\n * featureWorktreePredicate('/path/to/release/v1.18.22 abc1234 [release/v1.18.22]')\n * // => null\n */\nconst featureWorktreePredicate = (line: string): string | null => {\n const parts = line.split(' ').filter(Boolean)\n\n if (parts.length < 3 || !parts[0]?.includes('feature/')) return null\n\n return `feature/${parts[0]?.split('/').pop() || ''}`\n}\n\n/**\n * Get the current project root directory\n */\nexport const getProjectRoot = async (): Promise<string> => {\n const result = await $`git rev-parse --show-toplevel`\n\n return result.stdout.trim()\n}\n\n/**\n * Get the current repository name (basename of the project root)\n */\nexport const getRepoName = async (): Promise<string> => {\n const projectRoot = await getProjectRoot()\n\n return path.basename(projectRoot)\n}\n", "import { getInfraKitConfig } from 'src/lib/infra-kit-config'\n\n/**\n * Resolve Doppler project name from infra-kit.yml at the project root\n */\nexport const getDopplerProject = async (): Promise<string> => {\n const { dopplerProjectName } = await getInfraKitConfig()\n\n return dopplerProjectName\n}\n", "import select from '@inquirer/select'\nimport { Buffer } from 'node:buffer'\nimport fs from 'node:fs'\nimport path from 'node:path'\nimport process from 'node:process'\nimport { z } from 'zod'\nimport { $ } from 'zx'\n\nimport { validateDopplerCliAndAuth } from 'src/integrations/doppler'\nimport { getDopplerProject } from 'src/integrations/doppler/doppler-project'\nimport { commandEcho } from 'src/lib/command-echo'\nimport {\n ENV_LOAD_FILE,\n ENV_VAR_LINE_PATTERN,\n INFRA_KIT_ENV_CONFIG_VAR,\n INFRA_KIT_ENV_LOADED_AT_VAR,\n INFRA_KIT_ENV_PROJECT_VAR,\n atomicWriteFileSync,\n getSessionCacheDir,\n} from 'src/lib/constants'\nimport { getInfraKitConfig } from 'src/lib/infra-kit-config'\nimport type { ToolsExecutionResult } from 'src/types'\n\ninterface EnvLoadArgs {\n config?: string\n}\n\n/**\n * Load environment variables from Doppler for the given config\n */\nexport const envLoad = async (args: EnvLoadArgs): Promise<ToolsExecutionResult> => {\n await validateDopplerCliAndAuth()\n\n const { config } = args\n\n commandEcho.start('env-load')\n\n let selectedConfig = ''\n\n if (config) {\n selectedConfig = config\n } else {\n const { environments } = await getInfraKitConfig()\n\n commandEcho.setInteractive()\n selectedConfig = await select(\n {\n message: 'Select environment config',\n choices: environments.map((env) => {\n return { name: env, value: env }\n }),\n },\n // Render to stderr so the prompt is visible when stdout is captured via $() in the shell function.\n // Only env-load and env-clear use the $() stdout-capture shell pattern.\n { output: process.stderr },\n )\n }\n\n commandEcho.addOption('--config', selectedConfig)\n\n const project = await getDopplerProject()\n\n const envContent = await downloadDopplerSecrets(project, selectedConfig)\n\n assertValidEnvContent(envContent)\n\n // Build env file content in dotenv format\n const loadedAt = new Date().toISOString()\n const envFileLines = [\n 'set -a',\n envContent,\n `${INFRA_KIT_ENV_CONFIG_VAR}=${shellSingleQuote(selectedConfig)}`,\n `${INFRA_KIT_ENV_PROJECT_VAR}=${shellSingleQuote(project)}`,\n `${INFRA_KIT_ENV_LOADED_AT_VAR}=${shellSingleQuote(loadedAt)}`,\n 'set +a',\n ]\n\n const cacheDir = getSessionCacheDir()\n const envFilePath = path.resolve(cacheDir, ENV_LOAD_FILE)\n\n fs.mkdirSync(cacheDir, { recursive: true, mode: 0o700 })\n atomicWriteFileSync(envFilePath, `${envFileLines.join('\\n')}\\n`, 0o600)\n\n // REQUIRED\n process.stdout.write(`${envFilePath}\\n`)\n\n // Logs to stderr (pino \u2192 pretty-print), so it doesn't pollute the captured\n // file path that the shell wrapper reads from stdout.\n commandEcho.print()\n\n const varCount = countEnvVarLines(envContent)\n\n const structuredContent = {\n filePath: envFilePath,\n variableCount: varCount,\n project,\n config: selectedConfig,\n }\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(structuredContent, null, 2),\n },\n ],\n structuredContent,\n }\n}\n\n/**\n * Cap the Doppler stdout we're willing to accept. A well-formed env bundle is\n * O(10 KB); megabytes would indicate a service regression or the wrong stream\n * being captured, and we don't want to write that to disk or source it.\n */\nexport const DOPPLER_MAX_OUTPUT_BYTES = 1024 * 1024\n\n/**\n * Hard upper bound for the Doppler subprocess. Well under zx's default so a\n * hung call surfaces quickly instead of blocking an interactive shell or an\n * MCP tool handler.\n */\nconst DOPPLER_DOWNLOAD_TIMEOUT_MS = 30_000\n\nconst downloadDopplerSecrets = async (project: string, config: string): Promise<string> => {\n const prevQuiet = $.quiet\n\n $.quiet = true\n try {\n const result =\n await $`doppler secrets download --no-file --format env --project ${project} --config ${config}`.timeout(\n DOPPLER_DOWNLOAD_TIMEOUT_MS,\n )\n\n assertDopplerOutputSize(result.stdout)\n\n return result.stdout.trim()\n } finally {\n $.quiet = prevQuiet\n }\n}\n\nexport const assertDopplerOutputSize = (stdout: string): void => {\n const bytes = Buffer.byteLength(stdout, 'utf-8')\n\n if (bytes > DOPPLER_MAX_OUTPUT_BYTES) {\n throw new Error(\n `doppler returned unexpectedly large output (${bytes} bytes > ${DOPPLER_MAX_OUTPUT_BYTES}) \u2014 refusing to write to disk`,\n )\n }\n}\n\nconst countEnvVarLines = (content: string): number => {\n return content.split('\\n').filter((line) => {\n return ENV_VAR_LINE_PATTERN.test(line)\n }).length\n}\n\nconst SHELL_DIRECTIVE_LINES = new Set(['set -a', 'set +a'])\n\nexport const shellSingleQuote = (value: string): string => {\n const escaped = value.replaceAll(\"'\", \"'\\\\''\")\n\n return `'${escaped}'`\n}\n\n/**\n * Guard against Doppler returning non-env output (auth warnings on stdout,\n * partial downloads, HTML error pages, etc.). Every non-blank, non-directive\n * line must match KEY=VALUE \u2014 skipping directives keeps future format tweaks\n * cheap without loosening the check.\n */\nexport const assertValidEnvContent = (content: string): void => {\n if (content.trim().length === 0) {\n throw new Error('doppler returned empty output for env-load')\n }\n\n for (const line of content.split('\\n')) {\n const trimmed = line.trim()\n\n if (trimmed.length === 0 || SHELL_DIRECTIVE_LINES.has(trimmed)) continue\n\n if (!ENV_VAR_LINE_PATTERN.test(trimmed)) {\n throw new Error(\n `doppler returned unexpected output for env-load (expected KEY=value lines, got: ${JSON.stringify(trimmed.slice(0, 80))})`,\n )\n }\n }\n}\n\n// MCP Tool Registration\nexport const envLoadMcpTool = {\n name: 'env-load',\n description:\n 'Download the env vars for a Doppler config and write them to a temporary shell script. Does NOT mutate the calling process \u2014 returns the path to a script that must be sourced (\"source <filePath>\") for the vars to take effect. The infra-kit shell wrapper auto-sources; direct MCP callers must handle sourcing themselves or surface filePath to the user. \"config\" is required when invoked via MCP (the CLI interactive picker is unreachable without a TTY).',\n inputSchema: {\n config: z\n .string()\n .describe('Doppler config / environment name to load (e.g. \"dev\", \"arthur\", \"renana\"). Required for MCP calls.'),\n },\n outputSchema: {\n filePath: z.string().describe('Path to the file that must be sourced to apply variables'),\n variableCount: z.number().describe('Number of variables loaded'),\n project: z.string().describe('Doppler project name'),\n config: z.string().describe('Doppler config name'),\n },\n handler: envLoad,\n}\n", "import { $ } from 'zx'\n\n/**\n * Validate Doppler CLI installation and authentication status. Throws on failure\n * so callers (CLI entry, MCP tool handler) can translate to the right surface \u2014\n * CLI exits non-zero; MCP returns a structured tool error instead of tearing\n * down the server.\n */\nexport const validateDopplerCliAndAuth = async (): Promise<void> => {\n try {\n await $`doppler --version`\n } catch (error: unknown) {\n throw new Error('Doppler CLI is not installed. Install it from: https://docs.doppler.com/docs/install-cli', {\n cause: error,\n })\n }\n\n try {\n await $`doppler me`\n } catch (error: unknown) {\n throw new Error('Doppler CLI is not authenticated. Run: doppler login', { cause: error })\n }\n}\n", "import { logger } from 'src/lib/logger'\n\ninterface CommandOption {\n flag: string\n value: string | string[] | boolean\n}\n\nconst createCommandEcho = () => {\n let commandName = ''\n let options: CommandOption[] = []\n let isInteractive = false\n\n return {\n /**\n * Initialize command echo for a new command\n */\n start(name: string): void {\n commandName = name\n options = []\n isInteractive = false\n },\n\n /**\n * Mark that the command had interactive input (prompts)\n * Call this once when ANY prompt happens\n */\n setInteractive(): void {\n isInteractive = true\n },\n\n /**\n * Track an option selection\n * @param flag The CLI flag (e.g., \"--versions\")\n * @param value The selected value\n */\n addOption(flag: string, value: string | string[] | boolean): void {\n options.push({ flag, value })\n },\n\n /**\n * Print the equivalent CLI command if there was interactive input\n */\n print(): void {\n if (!isInteractive || options.length === 0) {\n return\n }\n\n const formattedOptions = options\n .map((opt) => {\n if (typeof opt.value === 'boolean') {\n return opt.value ? opt.flag : ''\n }\n\n if (Array.isArray(opt.value)) {\n return `${opt.flag} \"${opt.value.join(', ')}\"`\n }\n\n return `${opt.flag} \"${opt.value}\"`\n })\n .filter(Boolean)\n .join(' ')\n\n logger.info(`\uD83D\uDCDF Equivalent command: \\npnpm exec infra-kit ${commandName} ${formattedOptions}\\n`)\n },\n\n /**\n * Reset state (useful for testing)\n */\n reset(): void {\n commandName = ''\n options = []\n isInteractive = false\n },\n }\n}\n\n// Singleton instance (same pattern as logger)\nexport const commandEcho = createCommandEcho()\n", "import path from 'node:path'\nimport process from 'node:process'\nimport { z } from 'zod'\n\nimport { validateDopplerCliAndAuth } from 'src/integrations/doppler'\nimport {\n ENV_LOAD_FILE,\n INFRA_KIT_ENV_CONFIG_VAR,\n INFRA_KIT_ENV_LOADED_AT_VAR,\n INFRA_KIT_ENV_PROJECT_VAR,\n INFRA_KIT_SESSION_VAR,\n getSessionCacheDir,\n parseVarNamesFromEnvFile,\n} from 'src/lib/constants'\nimport { logger } from 'src/lib/logger'\nimport type { ToolsExecutionResult } from 'src/types'\n\n/**\n * Show Doppler authentication status and detected project info\n */\nexport const envStatus = async (): Promise<ToolsExecutionResult> => {\n await validateDopplerCliAndAuth()\n\n logger.info('Environment session status:')\n\n // Check session-loaded vars \u2014 getSessionCacheDir() throws if INFRA_KIT_SESSION is unset\n const cacheDir = getSessionCacheDir()\n\n const sessionId = process.env[INFRA_KIT_SESSION_VAR]!\n const envLoadPath = path.join(cacheDir, ENV_LOAD_FILE)\n\n let sessionLoadedCount = 0\n let sessionTotalCount = 0\n\n const sessionConfig = process.env[INFRA_KIT_ENV_CONFIG_VAR] ?? null\n const sessionProject = process.env[INFRA_KIT_ENV_PROJECT_VAR] ?? null\n const sessionLoadedAt = process.env[INFRA_KIT_ENV_LOADED_AT_VAR] ?? null\n\n if (sessionConfig) {\n const varNames = parseVarNamesFromEnvFile(envLoadPath)\n\n if (varNames.length > 0) {\n sessionTotalCount = varNames.length\n sessionLoadedCount = varNames.filter((v) => {\n return v in process.env\n }).length\n }\n\n const loadedAtDisplay = sessionLoadedAt?.replace(/\\.\\d{3}Z$/, '') ?? null\n\n logger.info(\n ` ${sessionConfig}: ${sessionLoadedCount} of ${sessionTotalCount} vars loaded (project: ${sessionProject}, loadedAt: ${loadedAtDisplay}, session: ${sessionId})\\n`,\n )\n\n if (sessionTotalCount > 0 && sessionLoadedCount < sessionTotalCount) {\n const missing = sessionTotalCount - sessionLoadedCount\n\n logger.warn(\n ` ${missing} cached var(s) are not present in the current process \u2014 env-load needs to be re-sourced, or vars were unset manually.`,\n )\n }\n } else {\n logger.info(` Session ${sessionId}: no env loaded\\n`)\n }\n\n const structuredContent = {\n sessionId,\n sessionLoadedCount,\n sessionTotalCount,\n sessionConfig,\n sessionProject,\n sessionLoadedAt,\n }\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(structuredContent, null, 2),\n },\n ],\n structuredContent,\n }\n}\n\n// MCP Tool Registration\nexport const envStatusMcpTool = {\n name: 'env-status',\n description:\n 'Report which Doppler project/config is currently loaded in the terminal session, when it was loaded, and how many variables are cached. Read-only \u2014 use env-load / env-clear to change the terminal session.',\n inputSchema: {},\n outputSchema: {\n sessionId: z.string().describe('Current terminal session ID'),\n sessionLoadedCount: z.number().describe('Number of cached vars active in the current session'),\n sessionTotalCount: z.number().describe('Total number of cached var names'),\n sessionConfig: z.string().nullable().describe('Doppler config name of the loaded session (environment name)'),\n sessionProject: z.string().nullable().describe('Doppler project name of the loaded session'),\n sessionLoadedAt: z.string().nullable().describe('ISO 8601 timestamp of when the env was loaded'),\n },\n handler: envStatus,\n}\n", "/* eslint-disable sonarjs/cognitive-complexity */\nimport checkbox from '@inquirer/checkbox'\nimport confirm from '@inquirer/confirm'\nimport process from 'node:process'\nimport { z } from 'zod'\nimport { $ } from 'zx'\n\nimport { getReleasePRsWithInfo } from 'src/integrations/gh'\nimport { commandEcho } from 'src/lib/command-echo'\nimport { logger } from 'src/lib/logger'\nimport { detectReleaseType, formatBranchChoices, getJiraDescriptions } from 'src/lib/release-utils'\nimport type { RequiredConfirmedOptionArg, ToolsExecutionResult } from 'src/types'\n\ninterface GhMergeDevArgs extends RequiredConfirmedOptionArg {\n all: boolean\n}\n\n/**\n * Merge dev into every release branch\n */\nexport const ghMergeDev = async (args: GhMergeDevArgs): Promise<ToolsExecutionResult> => {\n const { all, confirmedCommand } = args\n\n commandEcho.start('merge-dev')\n\n // Only merge dev into regular releases (not hotfixes, which target main)\n const allPRs = await getReleasePRsWithInfo()\n const releasePRsList = allPRs\n .filter((pr) => {\n return detectReleaseType(pr.title) === 'regular'\n })\n .map((pr) => {\n return pr.branch\n })\n\n if (releasePRsList.length === 0) {\n logger.info('\u2139\uFE0F No open release branches found')\n\n commandEcho.print()\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify({ successfulMerges: 0, failedMerges: 0, failedBranches: [], totalBranches: 0 }, null, 2),\n },\n ],\n structuredContent: { successfulMerges: 0, failedMerges: 0, failedBranches: [], totalBranches: 0 },\n }\n }\n\n let selectedReleaseBranches: string[] = []\n\n if (all) {\n selectedReleaseBranches = releasePRsList\n } else {\n commandEcho.setInteractive()\n\n const descriptions = await getJiraDescriptions()\n\n selectedReleaseBranches = await checkbox({\n required: true,\n message: '\uD83C\uDF3F Select release branches',\n choices: formatBranchChoices({ branches: releasePRsList, descriptions }),\n })\n }\n\n // Track --all flag if all branches were selected (either via flag or interactively)\n const allSelected = selectedReleaseBranches.length === releasePRsList.length\n\n if (allSelected) {\n commandEcho.addOption('--all', true)\n } else {\n commandEcho.addOption(\n '--versions',\n selectedReleaseBranches.map((branch) => {\n return branch.replace('release/v', '')\n }),\n )\n }\n\n // Validate input\n // if (selectedReleaseBranches.length === 0) {\n // console.error('No branches provided. Exiting...')\n // process.exit(1)\n // }\n\n const answer = confirmedCommand\n ? true\n : await confirm({\n message: `Are you sure you want to merge dev into these branches: ${selectedReleaseBranches.join(', ')}?`,\n })\n\n if (!confirmedCommand) {\n commandEcho.setInteractive()\n }\n\n if (!answer) {\n logger.info('Operation cancelled. Exiting...')\n process.exit(0)\n }\n\n // Track --yes flag if confirmation was interactive (user confirmed)\n if (!confirmedCommand) {\n commandEcho.addOption('--yes', true)\n }\n\n $.quiet = true\n\n await $`git fetch origin`\n await $`git switch dev`\n await $`git pull origin dev`\n\n const failedBranches: string[] = []\n\n // Merge dev into each branch\n for (const branch of selectedReleaseBranches) {\n const success = await mergeDev(branch)\n\n if (!success) {\n failedBranches.push(branch)\n }\n }\n\n $.quiet = false\n\n if (failedBranches.length > 0) {\n logger.info(`\\n\u26A0\uFE0F ${failedBranches.length} branch(es) failed to merge automatically.\\n`)\n logger.info('\uD83D\uDCCB Manual merge script for failed branches:')\n for (const branch of failedBranches) {\n logger.info(\n `# 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`,\n )\n }\n logger.info(\n `\u2705 ${selectedReleaseBranches.length - failedBranches.length}/${selectedReleaseBranches.length} merges completed successfully.`,\n )\n } else {\n logger.info('\u2705 All merges completed successfully!\\n')\n }\n\n commandEcho.print()\n\n const structuredContent = {\n successfulMerges: selectedReleaseBranches.length - failedBranches.length,\n failedMerges: failedBranches.length,\n failedBranches,\n totalBranches: selectedReleaseBranches.length,\n }\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(structuredContent, null, 2),\n },\n ],\n structuredContent,\n }\n}\n\nconst mergeDev = async (branch: string): Promise<boolean> => {\n try {\n await $`git switch ${branch}`\n\n await $`git pull origin ${branch}`\n\n await $`git merge origin/dev --no-edit`\n\n await $`git push origin ${branch}`\n\n await $`git switch dev`\n\n logger.info(`Successfully merged dev into ${branch}`)\n\n return true\n } catch (error: unknown) {\n logger.error({ error, branch }, `Error merging dev into ${branch}`)\n\n await $`git reset --merge HEAD~1`\n\n return false\n }\n}\n\n// MCP Tool Registration\nexport const ghMergeDevMcpTool = {\n name: 'gh-merge-dev',\n description:\n 'Merge origin/dev into every open regular (non-hotfix) release branch and push the result. Mutates local git state and the remote release branches. When invoked via MCP, pass all=true \u2014 the branch picker is unreachable without a TTY, and the confirmation prompt is auto-skipped for MCP calls, so the caller is responsible for gating. Irreversible once pushed.',\n inputSchema: {\n all: z\n .boolean()\n .optional()\n .describe(\n 'Target every open regular release branch. Must be true for MCP calls (the interactive picker is unavailable without a TTY).',\n ),\n },\n outputSchema: {\n successfulMerges: z.number().describe('Number of successful merges'),\n failedMerges: z.number().describe('Number of failed merges'),\n failedBranches: z.array(z.string()).describe('List of branches that failed to merge'),\n totalBranches: z.number().describe('Total number of branches processed'),\n },\n handler: ghMergeDev,\n}\n", "import process from 'node:process'\nimport { $ } from 'zx'\n\nimport { logger } from 'src/lib/logger'\n\n/**\n * Validate GitHub CLI installation and authentication status and throw an error if not valid\n */\nexport const validateGitHubCliAndAuth = async () => {\n try {\n await $`gh --version`\n } catch (error: unknown) {\n logger.error({ error }, 'Error: GitHub CLI (gh) is not installed.')\n logger.error('Please install it from: https://cli.github.com/')\n process.exit(1)\n }\n\n try {\n await $`gh auth status`\n } catch (error: unknown) {\n logger.error({ error }, 'Error: GitHub CLI (gh) is not authenticated.')\n logger.error('Please authenticate it from: https://cli.github.com/manual/gh_auth_login or type \"gh auth login\"')\n process.exit(1)\n }\n}\n", "import process from 'node:process'\nimport { $ } from 'zx'\n\nimport { logger } from 'src/lib/logger'\nimport { getBaseBranch } from 'src/lib/release-utils'\nimport type { ReleaseType } from 'src/lib/release-utils'\nimport { sortVersions } from 'src/lib/version-utils'\n\ninterface ReleasePR {\n headRefName: string\n number: number\n state: string\n title: string\n baseRefName: string\n}\n\nexport interface ReleasePRInfo {\n branch: string\n title: string\n}\n\n/**\n * Fetch all open release/hotfix PRs from GitHub.\n * Searches both dev (regular) and main (hotfix) base branches.\n * Returns deduplicated ReleasePR objects.\n */\nconst fetchAllReleasePRs = async (): Promise<ReleasePR[]> => {\n const releasePRs =\n await $`gh pr list --search \"Release in:title\" --base dev --json number,title,headRefName,state,baseRefName`\n\n const hotfixPRs =\n await $`gh pr list --search \"Hotfix in:title\" --base main --json number,title,headRefName,state,baseRefName`\n\n const all: ReleasePR[] = [...JSON.parse(releasePRs.stdout), ...JSON.parse(hotfixPRs.stdout)]\n\n // Deduplicate by headRefName\n const seen = new Set<string>()\n\n return all.filter((pr) => {\n if (seen.has(pr.headRefName)) return false\n\n seen.add(pr.headRefName)\n\n return true\n })\n}\n\n/**\n * Fetch open release PRs from GitHub with 'Release' or 'Hotfix' in the title and base 'dev'.\n * Returns an array of headRefName strings sorted by semver in ascending order.\n *\n * @returns [release/v1.18.22, release/v1.18.23, release/v1.18.24] (sorted by semver)\n */\nexport const getReleasePRs = async (): Promise<string[]> => {\n try {\n const prs = await fetchAllReleasePRs()\n\n if (prs.length === 0) {\n logger.error('\u274C No release PRs found. Check the project folder for the script. Exiting...')\n\n process.exit(1)\n }\n\n return sortVersions(\n prs.map((pr) => {\n return pr.headRefName\n }),\n )\n } catch (error) {\n logger.error({ error }, '\u274C Error fetching release PRs')\n\n process.exit(1)\n }\n}\n\n/**\n * Fetch open release PRs with title info (for detecting release type).\n * Returns ReleasePRInfo objects sorted by semver.\n */\nexport const getReleasePRsWithInfo = async (): Promise<ReleasePRInfo[]> => {\n try {\n const prs = await fetchAllReleasePRs()\n\n if (prs.length === 0) {\n logger.error('\u274C No release PRs found. Check the project folder for the script. Exiting...')\n process.exit(1)\n }\n\n const sortedBranches = sortVersions(\n prs.map((pr) => {\n return pr.headRefName\n }),\n )\n const prByBranch = new Map(\n prs.map((pr) => {\n return [pr.headRefName, pr]\n }),\n )\n\n return sortedBranches.map((branch) => {\n return {\n branch,\n title: prByBranch.get(branch)!.title,\n }\n })\n } catch (error) {\n logger.error({ error }, '\u274C Error fetching release PRs')\n process.exit(1)\n }\n}\n\ninterface CreateReleaseBranchArgs {\n version: string\n jiraVersionUrl: string\n type: ReleaseType\n description?: string\n}\n\n// Function to create a release branch\nexport const createReleaseBranch = async (\n args: CreateReleaseBranchArgs,\n): Promise<{ branchName: string; prUrl: string }> => {\n const { version, jiraVersionUrl, type, description } = args\n const titlePrefix = type === 'hotfix' ? 'Hotfix' : 'Release'\n const baseBranch = getBaseBranch(type)\n\n const branchName = `release/v${version}`\n\n const body = description && description.trim() !== '' ? `${jiraVersionUrl}\\n\\n${description}` : `${jiraVersionUrl} \\n`\n\n try {\n $.quiet = true\n\n await $`git switch ${baseBranch}`\n await $`git pull origin ${baseBranch}`\n await $`git checkout -b ${branchName}`\n await $`git push -u origin ${branchName}`\n await $`git commit --allow-empty-message --allow-empty --message ''`\n await $`git push origin ${branchName}`\n\n // Create PR and capture URL\n const prResult =\n await $`gh pr create --title \"${titlePrefix} v${version}\" --body ${body} --base ${baseBranch} --head ${branchName}`\n\n const prLink = prResult.stdout.trim()\n\n await $`git switch ${baseBranch}`\n\n $.quiet = false\n\n return {\n branchName,\n prUrl: prLink,\n }\n } catch (error: unknown) {\n logger.error({ error, branchName }, `Error creating release branch ${branchName}`)\n\n throw error\n }\n}\n", "import { $ } from 'zx'\n\nimport { createReleaseBranch } from 'src/integrations/gh'\nimport { createJiraVersion, getProjectVersions, loadJiraConfigOptional } from 'src/integrations/jira'\nimport type { JiraConfig } from 'src/integrations/jira'\n\nexport type ReleaseType = 'regular' | 'hotfix'\n\n/**\n * Get the base branch for a release type.\n * Regular releases branch from/to dev, hotfixes branch from/to main.\n */\nexport const getBaseBranch = (type: ReleaseType): string => {\n return type === 'hotfix' ? 'main' : 'dev'\n}\n\nexport interface ReleaseCreationResult {\n version: string\n type: ReleaseType\n branchName: string\n prUrl: string\n jiraVersionUrl: string\n}\n\n/**\n * Prepare git repository for release creation\n * Fetches latest changes, switches to base branch, and pulls latest\n */\nexport const prepareGitForRelease = async (type: ReleaseType = 'regular'): Promise<void> => {\n const baseBranch = getBaseBranch(type)\n\n $.quiet = true\n\n await $`git fetch origin`\n await $`git switch ${baseBranch}`\n await $`git pull origin ${baseBranch}`\n\n $.quiet = false\n}\n\ninterface CreateSingleReleaseArgs {\n version: string\n jiraConfig: JiraConfig\n description?: string\n type?: ReleaseType\n}\n\n/**\n * Create a single release by creating both Jira version and GitHub release branch\n */\nexport const createSingleRelease = async (args: CreateSingleReleaseArgs): Promise<ReleaseCreationResult> => {\n const { version, jiraConfig, description, type = 'regular' } = args\n // 1. Create Jira version (mandatory)\n const versionName = `v${version}`\n\n const result = await createJiraVersion(\n {\n name: versionName,\n projectId: jiraConfig.projectId,\n description: description || '',\n released: false,\n archived: false,\n },\n jiraConfig,\n )\n\n // Construct user-friendly Jira URL using project key from API response\n const jiraVersionUrl = `${jiraConfig.baseUrl}/projects/${result.version!.projectId}/versions/${result.version!.id}/tab/release-report-all-issues`\n\n // 2. Create GitHub release branch\n const releaseInfo = await createReleaseBranch({ version, jiraVersionUrl, type, description })\n\n return {\n version,\n type,\n branchName: releaseInfo.branchName,\n prUrl: releaseInfo.prUrl,\n jiraVersionUrl,\n }\n}\n\n/**\n * Fetch Jira version descriptions mapped by version name (e.g., \"v1.2.5\" \u2192 \"Some description\")\n * Gracefully returns empty map if Jira is unavailable\n */\nexport const getJiraDescriptions = async (): Promise<Map<string, string>> => {\n const descriptions = new Map<string, string>()\n\n const jiraConfig = await loadJiraConfigOptional()\n\n if (!jiraConfig) return descriptions\n\n try {\n const versions = await getProjectVersions(jiraConfig)\n\n for (const version of versions) {\n if (version.description) {\n descriptions.set(version.name, version.description)\n }\n }\n } catch {\n // Jira fetch failed, continue without descriptions\n }\n\n return descriptions\n}\n\n/**\n * Format a version string with its release type tag, e.g. \"1.2.5 [regular]\"\n * When maxVersionLength is provided, pads the version for alignment.\n */\nexport const formatVersionLabel = (version: string, type: ReleaseType, maxVersionLength?: number): string => {\n const padding = maxVersionLength ? ' '.repeat(maxVersionLength - version.length + 3) : ' '\n const tag = `[${type}]`.padEnd(11)\n\n return `${version}${padding}${tag}`\n}\n\n/**\n * Detect release type from PR title.\n * PRs titled \"Hotfix v...\" are hotfix, everything else is regular.\n */\nexport const detectReleaseType = (title: string): ReleaseType => {\n return title.toLowerCase().startsWith('hotfix') ? 'hotfix' : 'regular'\n}\n\ninterface FormatBranchChoicesArgs {\n branches: string[]\n descriptions: Map<string, string>\n types?: Map<string, ReleaseType>\n}\n\n/**\n * Format release branch names as checkbox choices with aligned type tags and Jira descriptions\n */\nexport const formatBranchChoices = (args: FormatBranchChoicesArgs): { name: string; value: string }[] => {\n const { branches, descriptions, types } = args\n\n const versionNames = branches.map((b) => {\n return b.replace('release/v', '')\n })\n\n const maxLen = Math.max(\n ...versionNames.map((v) => {\n return v.length\n }),\n )\n\n return branches.map((branch, i) => {\n const version = versionNames[i] as string\n const type = types ? types.get(branch) || 'regular' : undefined\n const desc = descriptions.get(`v${version}`)\n const padding = ' '.repeat(maxLen - version.length + 3)\n\n let name = type ? formatVersionLabel(version, type, maxLen) : version\n\n if (desc) {\n name = type ? `${name} ${desc}` : `${version}${padding}${desc}`\n }\n\n return { name, value: branch }\n })\n}\n", "import process from 'node:process'\n\nimport { logger } from 'src/lib/logger'\n\nimport type {\n CreateJiraVersionParams,\n CreateJiraVersionResult,\n DeliverJiraReleaseParams,\n DeliverJiraReleaseResult,\n JiraConfig,\n JiraVersion,\n UpdateJiraVersionParams,\n UpdateJiraVersionResult,\n} from './types.js'\n\n/**\n * Creates a new version in Jira using the REST API\n * @param params - Version creation parameters\n * @param config - Jira configuration (baseUrl, token, projectId)\n * @returns Result containing created version or error\n */\nexport const createJiraVersion = async (\n params: CreateJiraVersionParams,\n config: JiraConfig,\n): Promise<CreateJiraVersionResult> => {\n try {\n const { baseUrl, token, email, projectId } = config\n\n // Use current date if not provided\n // const releaseDate =\n // params.releaseDate || new Date().toISOString().split('T')[0] // 2025-12-06\n\n // Prepare request body\n const requestBody = {\n name: params.name,\n projectId: params.projectId || projectId,\n description: params.description || '',\n // releaseDate,\n released: params.released || false,\n archived: params.archived || false,\n }\n\n // logger.info(\n // { version: params.name, projectId: requestBody.projectId },\n // 'Creating Jira version',\n // )\n\n // Make API request\n const url = `${baseUrl}/rest/api/3/version`\n\n // Create Basic auth credentials\n const credentials = btoa(`${email}:${token}`)\n\n const response = await fetch(url, {\n method: 'POST',\n headers: {\n Accept: 'application/json',\n 'Content-Type': 'application/json',\n Authorization: `Basic ${credentials}`,\n },\n body: JSON.stringify(requestBody),\n })\n\n if (!response.ok) {\n const errorText = await response.text()\n\n logger.error(\n {\n status: response.status,\n statusText: response.statusText,\n error: errorText,\n },\n 'Failed to create Jira version',\n )\n\n throw new Error(`HTTP ${response.status}: ${response.statusText}`)\n }\n\n const version = (await response.json()) as JiraVersion\n\n // logger.info(\n // { versionId: version.id, versionName: version.name },\n // 'Successfully created Jira version',\n // )\n\n return {\n success: true,\n version,\n }\n } catch (error) {\n logger.error({ error }, 'Error creating Jira version')\n\n throw error\n }\n}\n\n/**\n * Gets all versions for a project from Jira\n * @param config - Jira configuration\n * @returns Array of JiraVersion objects\n */\nexport const getProjectVersions = async (config: JiraConfig): Promise<JiraVersion[]> => {\n try {\n const { baseUrl, token, email, projectId } = config\n\n const url = `${baseUrl}/rest/api/3/project/${projectId}/versions`\n const credentials = btoa(`${email}:${token}`)\n\n const response = await fetch(url, {\n method: 'GET',\n headers: {\n Accept: 'application/json',\n Authorization: `Basic ${credentials}`,\n },\n })\n\n if (!response.ok) {\n const errorText = await response.text()\n\n logger.error(\n {\n status: response.status,\n statusText: response.statusText,\n error: errorText,\n },\n 'Failed to get Jira project versions',\n )\n\n throw new Error(`HTTP ${response.status}: ${response.statusText}`)\n }\n\n const versions = (await response.json()) as JiraVersion[]\n\n return versions\n } catch (error) {\n logger.error({ error }, 'Error getting Jira project versions')\n\n throw error\n }\n}\n\n/**\n * Finds a Jira version by name in the project\n * @param versionName - Name of the version to find (e.g., \"v1.33.10\")\n * @param config - Jira configuration\n * @returns JiraVersion if found, null otherwise\n */\nconst findVersionByName = async (versionName: string, config: JiraConfig): Promise<JiraVersion | null> => {\n try {\n const versions = await getProjectVersions(config)\n const version = versions.find((v) => {\n return v.name === versionName\n })\n\n return version || null\n } catch (error) {\n logger.error({ error, versionName }, 'Error finding Jira version by name')\n\n throw error\n }\n}\n\n/**\n * Updates an existing Jira version\n * @param params - Update parameters\n * @param config - Jira configuration\n * @returns Result containing updated version or error\n */\nconst updateJiraVersion = async (\n params: UpdateJiraVersionParams,\n config: JiraConfig,\n): Promise<UpdateJiraVersionResult> => {\n try {\n const { baseUrl, token, email } = config\n\n // Prepare request body - only include fields that are provided\n const requestBody: Record<string, any> = {\n released: params.released ?? true,\n archived: params.archived ?? false,\n }\n\n // Add releaseDate if provided, otherwise use current date when releasing\n if (params.releaseDate) {\n requestBody.releaseDate = params.releaseDate\n } else if (params.released !== false) {\n requestBody.releaseDate = new Date().toISOString().split('T')[0] // YYYY-MM-DD\n }\n\n if (params.description !== undefined) {\n requestBody.description = params.description\n }\n\n const url = `${baseUrl}/rest/api/3/version/${params.versionId}`\n const credentials = btoa(`${email}:${token}`)\n\n const response = await fetch(url, {\n method: 'PUT',\n headers: {\n Accept: 'application/json',\n 'Content-Type': 'application/json',\n Authorization: `Basic ${credentials}`,\n },\n body: JSON.stringify(requestBody),\n })\n\n if (!response.ok) {\n const errorText = await response.text()\n\n logger.error(\n {\n status: response.status,\n statusText: response.statusText,\n error: errorText,\n },\n 'Failed to update Jira version',\n )\n\n throw new Error(`HTTP ${response.status}: ${response.statusText}`)\n }\n\n const version = (await response.json()) as JiraVersion\n\n return {\n success: true,\n version,\n }\n } catch (error) {\n logger.error({ error }, 'Error updating Jira version')\n\n throw error\n }\n}\n\n/**\n * Delivers a Jira release by marking it as released with the current date\n * @param params - Parameters containing the version name\n * @param config - Jira configuration\n * @returns Result containing updated version\n * @throws Error if version not found or update fails\n */\nexport const deliverJiraRelease = async (\n params: DeliverJiraReleaseParams,\n config: JiraConfig,\n): Promise<DeliverJiraReleaseResult> => {\n try {\n const { versionName } = params\n\n // Find the version by name\n const version = await findVersionByName(versionName, config)\n\n if (!version) {\n logger.error({ versionName }, 'Jira version not found')\n throw new Error(`Version \"${versionName}\" not found in Jira project`)\n }\n\n // Update the version to mark it as released\n const result = await updateJiraVersion(\n {\n versionId: version.id,\n released: true,\n releaseDate: new Date().toISOString().split('T')[0], // Current date in YYYY-MM-DD format\n },\n config,\n )\n\n return result\n } catch (error) {\n logger.error({ error }, 'Error delivering Jira release')\n throw error\n }\n}\n\n/**\n * Loads Jira configuration from environment variables\n * @throws Error with detailed message if configuration is missing or invalid\n * @returns Promise<JiraConfig>\n */\nexport const loadJiraConfig = async (): Promise<JiraConfig> => {\n const baseUrl = process.env.JIRA_BASE_URL\n const token = process.env.JIRA_TOKEN || process.env.JIRA_API_TOKEN\n const projectIdStr = process.env.JIRA_PROJECT_ID\n const email = process.env.JIRA_EMAIL\n\n const missingVars: string[] = []\n\n if (!baseUrl) missingVars.push('JIRA_BASE_URL (e.g., https://your-domain.atlassian.net)')\n if (!token) missingVars.push('JIRA_TOKEN or JIRA_API_TOKEN (your Jira API token)')\n if (!projectIdStr) missingVars.push('JIRA_PROJECT_ID (numeric project ID)')\n if (!email) missingVars.push('JIRA_EMAIL (your Jira email address)')\n\n if (missingVars.length > 0) {\n const errorMessage = [\n 'Jira configuration is required but incomplete.',\n 'Please configure the following environment variables:',\n ...missingVars.map((v) => {\n return ` - ${v}`\n }),\n '',\n 'You can set these in your .env file or as environment variables.',\n ].join('\\n')\n\n throw new Error(errorMessage)\n }\n\n const projectId = Number.parseInt(projectIdStr!, 10)\n\n if (Number.isNaN(projectId)) {\n throw new TypeError(`Invalid JIRA_PROJECT_ID: \"${projectIdStr}\" must be a numeric value (e.g., 10001)`)\n }\n\n return {\n baseUrl: baseUrl!.replace(/\\/$/, ''), // Remove trailing slash\n token: token!,\n projectId,\n email: email!,\n }\n}\n\n/**\n * Attempts to load Jira configuration from environment variables\n * Returns null if configuration is missing or invalid (for optional Jira integration)\n * @returns Promise<JiraConfig | null>\n */\nexport const loadJiraConfigOptional = async (): Promise<JiraConfig | null> => {\n try {\n const config = await loadJiraConfig()\n\n return config\n } catch (error) {\n logger.warn({ error }, 'Jira configuration not available, skipping Jira integration')\n\n return null\n }\n}\n", "/**\n * Parse version string into major, minor, patch numbers\n */\nexport const parseVersion = (versionStr: string): [number, number, number] => {\n return versionStr.replace('release/', '').slice(1).split('.').map(Number) as [number, number, number]\n}\n\n/**\n * Sort version strings in ascending order\n * Note: Returns a new sorted array without mutating the original\n */\nexport const sortVersions = (versions: string[]): string[] => {\n return [...versions].sort((a, b) => {\n const [majA, minA, patchA] = parseVersion(a)\n const [majB, minB, patchB] = parseVersion(b)\n\n if (majA !== majB) return (majA ?? 0) - (majB ?? 0)\n if (minA !== minB) return (minA ?? 0) - (minB ?? 0)\n\n return (patchA ?? 0) - (patchB ?? 0)\n })\n}\n", "import confirm from '@inquirer/confirm'\nimport select from '@inquirer/select'\nimport process from 'node:process'\nimport { z } from 'zod'\nimport { $ } from 'zx'\n\nimport { getReleasePRsWithInfo } from 'src/integrations/gh'\nimport { deliverJiraRelease, loadJiraConfigOptional } from 'src/integrations/jira'\nimport { commandEcho } from 'src/lib/command-echo'\nimport { logger } from 'src/lib/logger'\nimport { detectReleaseType, formatBranchChoices, getJiraDescriptions } from 'src/lib/release-utils'\nimport type { ReleaseType } from 'src/lib/release-utils'\nimport type { RequiredConfirmedOptionArg, ToolsExecutionResult } from 'src/types'\n\ninterface GhReleaseDeliverArgs extends RequiredConfirmedOptionArg {\n version: string\n}\n\n/**\n * Deliver a release branch to production\n */\nexport const ghReleaseDeliver = async (args: GhReleaseDeliverArgs): Promise<ToolsExecutionResult> => {\n const { version, confirmedCommand } = args\n\n commandEcho.start('release-deliver')\n\n const releasePRsInfo = await getReleasePRsWithInfo()\n\n const branches = releasePRsInfo.map((pr) => {\n return pr.branch\n })\n\n const releaseTypes = new Map<string, ReleaseType>(\n releasePRsInfo.map((pr) => {\n return [pr.branch, detectReleaseType(pr.title)]\n }),\n )\n\n let selectedReleaseBranch = '' // \"release/v1.8.0\"\n\n if (version) {\n selectedReleaseBranch = `release/v${version}`\n } else {\n commandEcho.setInteractive()\n\n const descriptions = await getJiraDescriptions()\n\n selectedReleaseBranch = await select({\n message: '\uD83C\uDF3F Select release branch',\n choices: formatBranchChoices({ branches, descriptions, types: releaseTypes }),\n })\n }\n\n const selectedVersion = selectedReleaseBranch.replace('release/v', '')\n\n commandEcho.addOption('--version', selectedVersion)\n\n // Check if release branch exists in the list\n const prInfo = releasePRsInfo.find((pr) => {\n return pr.branch === selectedReleaseBranch\n })\n\n if (!prInfo) {\n logger.error(`\u274C Release branch ${selectedReleaseBranch} not found in open PRs. Exiting...`)\n process.exit(1)\n }\n\n const releaseType: ReleaseType = detectReleaseType(prInfo.title)\n\n const answer = confirmedCommand\n ? true\n : await confirm({\n message: `Are you sure you want to deliver version ${selectedReleaseBranch} to production?`,\n })\n\n if (!confirmedCommand) {\n commandEcho.setInteractive()\n }\n\n if (!answer) {\n logger.info('Operation cancelled. Exiting...')\n process.exit(0)\n }\n\n // Track --yes flag if confirmation was interactive (user confirmed)\n commandEcho.addOption('--yes', true)\n\n try {\n $.quiet = true\n\n if (releaseType === 'hotfix') {\n // Hotfix: merge directly into main, deploy, sync back to dev\n await $`gh pr merge ${selectedReleaseBranch} --squash --admin --delete-branch`\n\n $.quiet = false\n\n await $`gh workflow run deploy-all.yml --ref main -f environment=prod`\n\n $.quiet = true\n\n // Sync main into dev\n await $`git switch main && git pull && git switch dev && git pull && git merge main --no-edit && git push`\n } else {\n // Regular: merge into dev, create RC PR to main, merge to main, deploy, sync\n await $`gh pr merge ${selectedReleaseBranch} --squash --admin --delete-branch`\n await $`gh pr create --base main --head dev --title \"Release v${selectedVersion} (RC)\" --body \"\"`\n await $`gh pr merge dev --squash --admin`\n\n $.quiet = false\n\n await $`gh workflow run deploy-all.yml --ref main -f environment=prod`\n\n $.quiet = true\n\n // Sync main into dev\n await $`git switch main && git pull && git switch dev && git pull && git merge main --no-edit && git push`\n }\n\n $.quiet = false\n\n // Deliver Jira release if Jira is configured\n const jiraConfig = await loadJiraConfigOptional()\n\n if (jiraConfig) {\n try {\n const versionName = selectedReleaseBranch.replace('release/', '')\n\n await deliverJiraRelease({ versionName }, jiraConfig)\n } catch (error) {\n logger.error({ error }, 'Failed to deliver Jira release (non-blocking)')\n }\n } else {\n logger.info('\uD83D\uDD14 Jira is not configured, skipping Jira release delivery')\n }\n\n logger.info(`Successfully delivered ${selectedReleaseBranch} to production!`)\n\n commandEcho.print()\n\n const structuredContent = {\n releaseBranch: selectedReleaseBranch,\n version: selectedReleaseBranch.replace('release/v', ''),\n type: releaseType,\n success: true,\n }\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(structuredContent, null, 2),\n },\n ],\n structuredContent,\n }\n } catch (error: unknown) {\n logger.error({ error }, '\u274C Error merging release branch into dev')\n process.exit(1)\n }\n}\n\n// MCP Tool Registration\nexport const ghReleaseDeliverMcpTool = {\n name: 'gh-release-deliver',\n description:\n 'Deliver a release to production. For hotfixes: squash-merges the release branch to main and dispatches the deploy-all workflow. For regular releases: squash-merges to dev, opens an RC PR, merges dev into main, dispatches the deploy-all workflow, then syncs main back to dev. Also releases the matching Jira fix version if Jira is configured. Dispatches the deploy workflow fire-and-forget \u2014 the tool returns once the workflow is accepted by GitHub, not when the deployment finishes. Irreversible production operation: the confirmation prompt is auto-skipped for MCP calls, so the caller is responsible for gating. \"version\" is required when invoked via MCP (the picker is unreachable without a TTY).',\n inputSchema: {\n version: z.string().describe('Release version to deliver to production (e.g., \"1.2.5\"). Required for MCP calls.'),\n },\n outputSchema: {\n releaseBranch: z.string().describe('The release branch that was delivered'),\n version: z.string().describe('The version that was delivered'),\n type: z.enum(['regular', 'hotfix']).describe('Release type'),\n success: z.boolean().describe('Whether the delivery was successful'),\n },\n handler: ghReleaseDeliver,\n}\n", "import select from '@inquirer/select'\nimport process from 'node:process'\nimport { z } from 'zod'\nimport { $ } from 'zx'\n\nimport { getReleasePRsWithInfo } from 'src/integrations/gh'\nimport { commandEcho } from 'src/lib/command-echo'\nimport { getInfraKitConfig } from 'src/lib/infra-kit-config'\nimport { logger } from 'src/lib/logger'\nimport { detectReleaseType, formatBranchChoices, getJiraDescriptions } from 'src/lib/release-utils'\nimport type { ReleaseType } from 'src/lib/release-utils'\nimport type { ToolsExecutionResult } from 'src/types'\n\ninterface GhReleaseDeployAllArgs {\n version: string\n env: string\n skipTerraform?: boolean\n}\n\n/**\n * Deploy a release branch to an environment\n */\nexport const ghReleaseDeployAll = async (args: GhReleaseDeployAllArgs): Promise<ToolsExecutionResult> => {\n const { version, env, skipTerraform } = args\n\n commandEcho.start('release-deploy-all')\n\n let selectedReleaseBranch = '' // \"release/v1.8.0\"\n\n if (version) {\n selectedReleaseBranch = version === 'dev' ? 'dev' : `release/v${version}`\n } else {\n commandEcho.setInteractive()\n\n const releasePRsInfo = await getReleasePRsWithInfo()\n\n const branches = releasePRsInfo.map((pr) => {\n return pr.branch\n })\n\n const releaseTypes = new Map<string, ReleaseType>(\n releasePRsInfo.map((pr) => {\n return [pr.branch, detectReleaseType(pr.title)]\n }),\n )\n\n const descriptions = await getJiraDescriptions()\n\n selectedReleaseBranch = await select({\n message: '\uD83C\uDF3F Select release branch',\n choices: [{ name: 'dev', value: 'dev' }, ...formatBranchChoices({ branches, descriptions, types: releaseTypes })],\n })\n }\n\n const selectedVersion = selectedReleaseBranch === 'dev' ? 'dev' : selectedReleaseBranch.replace('release/v', '')\n\n commandEcho.addOption('--version', selectedVersion)\n\n const { environments } = await getInfraKitConfig()\n\n let selectedEnv = ''\n\n if (env) {\n selectedEnv = env\n } else {\n commandEcho.setInteractive()\n\n selectedEnv = await select({\n message: '\uD83E\uDDEA Select environment',\n choices: environments.map((env) => {\n return {\n name: env,\n value: env,\n }\n }),\n })\n }\n\n commandEcho.addOption('--env', selectedEnv)\n\n if (!environments.includes(selectedEnv)) {\n logger.error(`\u274C Invalid environment: ${selectedEnv}. Exiting...`)\n process.exit(1)\n }\n\n const shouldSkipTerraform = skipTerraform ?? false\n\n if (shouldSkipTerraform) {\n commandEcho.addOption('--skip-terraform', true)\n }\n\n try {\n $.quiet = true\n\n const skipTerraformFlag = shouldSkipTerraform ? ['-f', 'skip_terraform_deploy=true'] : []\n\n await $`gh workflow run deploy-all.yml --ref ${selectedReleaseBranch} -f environment=${selectedEnv} ${skipTerraformFlag}`\n\n $.quiet = false\n\n logger.info(\n `Successfully launched deploy-all workflow_dispatch for release branch: ${selectedReleaseBranch} and environment: ${selectedEnv}`,\n )\n\n commandEcho.print()\n\n const structuredContent = {\n releaseBranch: selectedReleaseBranch,\n version: selectedReleaseBranch.replace('release/v', ''),\n environment: selectedEnv,\n skipTerraformDeploy: shouldSkipTerraform,\n success: true,\n }\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(structuredContent, null, 2),\n },\n ],\n structuredContent,\n }\n } catch (error: unknown) {\n logger.error({ error }, '\u274C Error launching workflow')\n process.exit(1)\n }\n}\n\n// MCP Tool Registration\nexport const ghReleaseDeployAllMcpTool = {\n name: 'gh-release-deploy-all',\n description:\n 'Dispatch the deploy-all.yml GitHub Actions workflow to deploy every service from a release branch to the given environment. Fire-and-forget \u2014 returns once GitHub accepts the workflow_dispatch, NOT when the deployment finishes; watch the workflow run for completion status. Use gh-release-deploy-selected for a subset of services. Pass version=\"dev\" to deploy from the dev branch instead of a release branch. Both \"version\" and \"env\" are required when invoked via MCP (interactive pickers are unavailable without a TTY).',\n inputSchema: {\n version: z\n .string()\n .describe(\n 'Release version to deploy from (e.g. \"1.2.5\") \u2014 resolves to the release/vX.Y.Z branch. Pass \"dev\" to deploy from the dev branch instead. Required for MCP calls.',\n ),\n env: z\n .string()\n .describe(\n 'Target environment name \u2014 must match an env configured for the project (e.g. \"dev\", \"renana\", \"oriana\"). Required for MCP calls.',\n ),\n skipTerraform: z.boolean().optional().describe('Skip the terraform deployment stage.'),\n },\n outputSchema: {\n releaseBranch: z.string().describe('The release branch that was deployed'),\n version: z.string().describe('The version that was deployed'),\n environment: z.string().describe('The environment deployed to'),\n skipTerraformDeploy: z.boolean().describe('Whether terraform deployment was skipped'),\n success: z.boolean().describe('Whether the deployment was successful'),\n },\n handler: ghReleaseDeployAll,\n}\n", "import checkbox from '@inquirer/checkbox'\nimport select from '@inquirer/select'\nimport fs from 'node:fs/promises'\nimport { resolve } from 'node:path'\nimport process from 'node:process'\nimport yaml from 'yaml'\nimport { z } from 'zod'\nimport { $ } from 'zx'\n\nimport { getReleasePRsWithInfo } from 'src/integrations/gh'\nimport { commandEcho } from 'src/lib/command-echo'\nimport { getProjectRoot } from 'src/lib/git-utils'\nimport { getInfraKitConfig } from 'src/lib/infra-kit-config'\nimport { logger } from 'src/lib/logger'\nimport { detectReleaseType, formatBranchChoices, getJiraDescriptions } from 'src/lib/release-utils'\nimport type { ReleaseType } from 'src/lib/release-utils'\nimport type { ToolsExecutionResult } from 'src/types'\n\ninterface GhReleaseDeploySelectedArgs {\n version: string\n env: string\n services: string[]\n skipTerraform?: boolean\n}\n\n/**\n * Deploy selected services from a release branch to an environment\n */\n// eslint-disable-next-line sonarjs/cognitive-complexity\nexport const ghReleaseDeploySelected = async (args: GhReleaseDeploySelectedArgs): Promise<ToolsExecutionResult> => {\n const { version, env, services, skipTerraform } = args\n\n commandEcho.start('release-deploy-selected')\n\n let selectedReleaseBranch = ''\n\n if (version) {\n selectedReleaseBranch = version === 'dev' ? 'dev' : `release/v${version}`\n } else {\n commandEcho.setInteractive()\n\n const releasePRsInfo = await getReleasePRsWithInfo()\n\n const branches = releasePRsInfo.map((pr) => {\n return pr.branch\n })\n\n const releaseTypes = new Map<string, ReleaseType>(\n releasePRsInfo.map((pr) => {\n return [pr.branch, detectReleaseType(pr.title)]\n }),\n )\n\n const descriptions = await getJiraDescriptions()\n\n selectedReleaseBranch = await select({\n message: '\uD83C\uDF3F Select release branch',\n choices: [{ name: 'dev', value: 'dev' }, ...formatBranchChoices({ branches, descriptions, types: releaseTypes })],\n })\n }\n\n const selectedVersion = selectedReleaseBranch === 'dev' ? 'dev' : selectedReleaseBranch.replace('release/v', '')\n\n commandEcho.addOption('--version', selectedVersion)\n\n const { environments } = await getInfraKitConfig()\n\n let selectedEnv = ''\n\n if (env) {\n selectedEnv = env\n } else {\n commandEcho.setInteractive()\n\n selectedEnv = await select({\n message: '\uD83E\uDDEA Select environment',\n choices: environments.map((env) => {\n return {\n name: env,\n value: env,\n }\n }),\n })\n }\n\n commandEcho.addOption('--env', selectedEnv)\n\n if (!environments.includes(selectedEnv)) {\n logger.error(`\u274C Invalid environment: ${selectedEnv}. Exiting...`)\n process.exit(1)\n }\n\n // Parse available services from workflow file\n const availableServices = await parseServicesFromWorkflow()\n\n if (availableServices.length === 0) {\n logger.error('\u274C No services found in workflow file. Exiting...')\n\n process.exit(1)\n }\n\n let selectedServices: string[] = []\n\n if (services && services.length > 0) {\n selectedServices = services\n } else {\n commandEcho.setInteractive()\n\n selectedServices = await checkbox({\n message: '\uD83D\uDE80 Select services to deploy (space to select, enter to confirm)',\n choices: availableServices.map((svc) => {\n return {\n name: svc,\n value: svc,\n }\n }),\n })\n }\n\n commandEcho.addOption('--services', selectedServices)\n\n if (selectedServices.length === 0) {\n logger.error('\u274C No services selected. Exiting...')\n process.exit(1)\n }\n\n // Validate all selected services\n const invalidServices = selectedServices.filter((svc) => {\n return !availableServices.includes(svc)\n })\n\n if (invalidServices.length > 0) {\n logger.error(\n `\u274C Invalid services: ${invalidServices.join(', ')}. Available services: ${availableServices.join(', ')}`,\n )\n process.exit(1)\n }\n\n const shouldSkipTerraform = skipTerraform ?? false\n\n if (shouldSkipTerraform) {\n commandEcho.addOption('--skip-terraform', true)\n }\n\n try {\n $.quiet = true\n\n // Build the workflow command with boolean flags for each selected service\n const serviceFlags = selectedServices.flatMap((svc) => {\n return ['-f', `${svc}=true`]\n })\n const skipTerraformFlag = shouldSkipTerraform ? ['-f', 'skip_terraform_deploy=true'] : []\n\n await $`gh workflow run deploy-selected-services.yml --ref ${selectedReleaseBranch} -f environment=${selectedEnv} ${serviceFlags} ${skipTerraformFlag}`\n\n $.quiet = false\n\n logger.info(\n `Successfully launched deploy-selected-services workflow_dispatch for release branch: ${selectedReleaseBranch}, environment: ${selectedEnv}, services: ${selectedServices.join(', ')}`,\n )\n\n commandEcho.print()\n\n const structuredContent = {\n releaseBranch: selectedReleaseBranch,\n version: selectedReleaseBranch.replace('release/v', ''),\n environment: selectedEnv,\n services: selectedServices,\n skipTerraformDeploy: shouldSkipTerraform,\n success: true,\n }\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(structuredContent, null, 2),\n },\n ],\n structuredContent,\n }\n } catch (error: unknown) {\n logger.error({ error }, '\u274C Error launching workflow')\n process.exit(1)\n }\n}\n\n/**\n * Parse available services from the workflow file\n * Services are defined as boolean inputs (excluding skip_terraform_deploy)\n */\nconst parseServicesFromWorkflow = async (): Promise<string[]> => {\n const projectRoot = await getProjectRoot()\n\n const workflowPath = resolve(projectRoot, '.github/workflows/deploy-selected-services.yml')\n\n const content = await fs.readFile(workflowPath, 'utf-8')\n const parsed = yaml.parse(content)\n\n const inputs = parsed.on.workflow_dispatch.inputs\n const services: string[] = []\n\n for (const [key, value] of Object.entries(inputs)) {\n // Filter for boolean type inputs, excluding non-service flags\n if ((value as { type: string }).type === 'boolean' && key !== 'skip_terraform_deploy') {\n services.push(key)\n }\n }\n\n return services\n}\n\n// MCP Tool Registration\nexport const ghReleaseDeploySelectedMcpTool = {\n name: 'gh-release-deploy-selected',\n description:\n 'Dispatch the deploy-selected-services.yml GitHub Actions workflow to deploy a chosen subset of services from a release branch to the given environment. Fire-and-forget \u2014 returns once GitHub accepts the workflow_dispatch, NOT when the deployment finishes; watch the workflow run for completion status. Service names are validated against the boolean inputs declared in the workflow. Use gh-release-deploy-all for every service. \"version\", \"env\", and \"services\" are all required when invoked via MCP (interactive pickers are unavailable without a TTY).',\n inputSchema: {\n version: z\n .string()\n .describe(\n 'Release version to deploy from (e.g. \"1.2.5\") \u2014 resolves to the release/vX.Y.Z branch. Pass \"dev\" to deploy from the dev branch instead. Required for MCP calls.',\n ),\n env: z\n .string()\n .describe(\n 'Target environment name \u2014 must match an env configured for the project (e.g. \"dev\", \"renana\", \"oriana\"). Required for MCP calls.',\n ),\n services: z\n .array(z.string())\n .describe(\n 'Service names to deploy. Each must match a boolean input declared in .github/workflows/deploy-selected-services.yml (e.g. \"client-be\", \"client-fe\"). Required for MCP calls.',\n ),\n skipTerraform: z.boolean().optional().describe('Skip the terraform deployment stage.'),\n },\n outputSchema: {\n releaseBranch: z.string().describe('The release branch that was deployed'),\n version: z.string().describe('The version that was deployed'),\n environment: z.string().describe('The environment deployed to'),\n services: z.array(z.string()).describe('The services that were deployed'),\n skipTerraformDeploy: z.boolean().describe('Whether terraform deployment was skipped'),\n success: z.boolean().describe('Whether the deployment was successful'),\n },\n handler: ghReleaseDeploySelected,\n}\n", "import { z } from 'zod'\n\nimport { getReleasePRsWithInfo } from 'src/integrations/gh'\nimport { logger } from 'src/lib/logger'\nimport { detectReleaseType, formatVersionLabel, getJiraDescriptions } from 'src/lib/release-utils'\nimport type { ToolsExecutionResult } from 'src/types'\n\n/**\n * List all open release branches\n */\nexport const ghReleaseList = async (): Promise<ToolsExecutionResult> => {\n const releasePRs = await getReleasePRsWithInfo()\n\n const releases = releasePRs.map((pr) => {\n return {\n version: pr.branch.replace('release/', ''),\n type: detectReleaseType(pr.title),\n }\n })\n\n const jiraDescriptions = await getJiraDescriptions()\n\n const maxVersionLength = Math.max(\n ...releases.map((r) => {\n return r.version.length\n }),\n )\n\n const formattedLines = releases.map((release) => {\n const label = formatVersionLabel(release.version, release.type, maxVersionLength)\n const description = jiraDescriptions.get(release.version)\n\n if (description) {\n return `${label} ${description}`\n }\n\n return label\n })\n\n logger.info('All release branches: \\n')\n logger.info(`\\n${formattedLines.join('\\n')}\\n`)\n\n const structuredContent = {\n releases: releases.map((release) => {\n return {\n version: release.version,\n type: release.type,\n description: jiraDescriptions.get(release.version) || null,\n }\n }),\n count: releases.length,\n }\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(structuredContent, null, 2),\n },\n ],\n structuredContent,\n }\n}\n\n// MCP Tool Registration\nexport const ghReleaseListMcpTool = {\n name: 'gh-release-list',\n description:\n 'List every open release PR with its version, type (regular / hotfix), and associated Jira fix-version description. Read-only; sourced from GitHub and Jira.',\n inputSchema: {},\n outputSchema: {\n releases: z\n .array(\n z.object({\n version: z.string().describe('Release version'),\n type: z.enum(['regular', 'hotfix']).describe('Release type'),\n description: z.string().nullable().describe('Jira version description'),\n }),\n )\n .describe('List of all release branches'),\n count: z.number().describe('Number of release branches'),\n },\n handler: ghReleaseList,\n}\n", "import fs from 'node:fs'\nimport os from 'node:os'\nimport path from 'node:path'\n\nimport { logger } from 'src/lib/logger'\n\nconst MARKER_START = '# -- infra-kit:begin --'\nconst MARKER_END = '# -- infra-kit:end --'\n\nconst LEGACY_PAIRED: [start: string, end: string][] = [['# region infra-kit', '# endregion infra-kit']]\nconst LEGACY_SINGLE = '# infra-kit shell functions'\n\n/**\n * Append infra-kit shell functions directly to .zshrc.\n */\nexport const init = async (): Promise<void> => {\n const zshrcPath = path.join(os.homedir(), '.zshrc')\n const shellBlock = buildShellBlock()\n\n if (fs.existsSync(zshrcPath)) {\n const content = fs.readFileSync(zshrcPath, 'utf-8')\n const cleaned = removeExistingBlock(content)\n\n fs.writeFileSync(zshrcPath, cleaned)\n }\n\n fs.appendFileSync(zshrcPath, `\\n${shellBlock}\\n`)\n logger.info(`Added infra-kit shell functions to ${zshrcPath}`)\n logger.info('Run `source ~/.zshrc` or open a new terminal to activate.')\n}\n\nconst isBlockLine = (line: string): boolean => {\n return (\n line.startsWith('#') ||\n line.startsWith('alias ') ||\n line.startsWith('env-load') ||\n line.startsWith('env-clear') ||\n line.startsWith('env-status') ||\n line.startsWith('if ') ||\n line.startsWith(' export INFRA_KIT_SESSION') ||\n line.startsWith('export _INFRA_KIT_') ||\n line.startsWith(': ${_INFRA_KIT_') ||\n line.startsWith('fi') ||\n line.startsWith('zmodload ') ||\n line.startsWith('autoload ') ||\n line.startsWith('add-zsh-hook ') ||\n line.startsWith('_infra_kit_autoload')\n )\n}\n\nconst removeBetween = (content: string, start: string, end: string): string | null => {\n const startIdx = content.indexOf(start)\n const endIdx = content.indexOf(end)\n\n if (startIdx === -1 || endIdx === -1) return null\n\n // eslint-disable-next-line sonarjs/slow-regex\n const before = content.slice(0, startIdx).replace(/\\n+$/, '')\n const after = content.slice(endIdx + end.length).replace(/^\\n+/, '')\n\n return before + (after ? `\\n${after}` : '')\n}\n\nconst removeExistingBlock = (content: string): string => {\n // 1. Current markers\n const result = removeBetween(content, MARKER_START, MARKER_END)\n\n if (result !== null) return result\n\n // 2. Legacy paired markers (# region / # endregion)\n for (const [start, end] of LEGACY_PAIRED) {\n const legacyResult = removeBetween(content, start, end)\n\n if (legacyResult !== null) return legacyResult\n }\n\n // 3. Oldest format: single marker + heuristic scan\n const legacyIdx = content.indexOf(LEGACY_SINGLE)\n\n if (legacyIdx === -1) return content\n\n // eslint-disable-next-line sonarjs/slow-regex\n const before = content.slice(0, legacyIdx).replace(/\\n+$/, '')\n const afterLines = content.slice(legacyIdx).split('\\n')\n\n let i = 0\n\n while (i < afterLines.length && isBlockLine(afterLines[i]!)) {\n i++\n }\n\n const remaining = afterLines.slice(i).join('\\n')\n\n return before + (remaining ? `\\n${remaining}` : '')\n}\n\nconst buildShellBlock = (): string => {\n const runCmd = 'pnpm exec infra-kit'\n\n return [\n MARKER_START,\n 'zmodload zsh/stat 2>/dev/null',\n 'zmodload zsh/datetime 2>/dev/null',\n // eslint-disable-next-line no-template-curly-in-string\n 'if [[ -z \"${INFRA_KIT_SESSION}\" ]]; then',\n ' export INFRA_KIT_SESSION=$(head -c 4 /dev/urandom | xxd -p)',\n 'fi',\n // eslint-disable-next-line no-template-curly-in-string\n ': ${_INFRA_KIT_LAST_LOAD_MTIME:=0}',\n // eslint-disable-next-line no-template-curly-in-string\n ': ${_INFRA_KIT_LAST_CLEAR_MTIME:=0}',\n // eslint-disable-next-line no-template-curly-in-string\n ': ${_INFRA_KIT_SHELL_STARTED:=${EPOCHSECONDS:-0}}',\n 'export _INFRA_KIT_LAST_LOAD_MTIME _INFRA_KIT_LAST_CLEAR_MTIME _INFRA_KIT_SHELL_STARTED',\n `env-load() { local f m; f=$(${runCmd} env-load \"$@\") || return; m=$(zstat +mtime -- \"$f\" 2>/dev/null || echo 0); _INFRA_KIT_LAST_LOAD_MTIME=$m; source \"$f\"; ${runCmd} env-status; }`,\n `env-clear() { local f m; f=$(${runCmd} env-clear) || return; m=$(zstat +mtime -- \"$f\" 2>/dev/null || echo 0); _INFRA_KIT_LAST_CLEAR_MTIME=$m; source \"$f\"; ${runCmd} env-status; }`,\n `env-status() { ${runCmd} env-status; }`,\n `alias ik='${runCmd}'`,\n '_infra_kit_autoload() {',\n ' [[ -z \"$INFRA_KIT_SESSION\" ]] && return',\n // eslint-disable-next-line no-template-curly-in-string\n ' local cache_root=\"${XDG_CACHE_HOME:-$HOME/.cache}/infra-kit\"',\n ' local dir=\"$cache_root/$INFRA_KIT_SESSION\"',\n ' local load_file=\"$dir/env-load.sh\"',\n ' local clear_file=\"$dir/env-clear.sh\"',\n ' local mtime',\n ' if [[ -f \"$load_file\" ]]; then',\n ' mtime=$(zstat +mtime -- \"$load_file\" 2>/dev/null || echo 0)',\n ' if (( mtime > _INFRA_KIT_LAST_LOAD_MTIME && mtime >= _INFRA_KIT_SHELL_STARTED )); then',\n ' source \"$load_file\"',\n ' _INFRA_KIT_LAST_LOAD_MTIME=$mtime',\n // eslint-disable-next-line no-template-curly-in-string\n ' print -u2 \"infra-kit: auto-loaded vars for ${INFRA_KIT_ENV_CONFIG:-?}\"',\n ' fi',\n ' fi',\n ' if [[ -f \"$clear_file\" ]]; then',\n ' mtime=$(zstat +mtime -- \"$clear_file\" 2>/dev/null || echo 0)',\n ' if (( mtime > _INFRA_KIT_LAST_CLEAR_MTIME && mtime >= _INFRA_KIT_SHELL_STARTED )); then',\n ' source \"$clear_file\"',\n ' _INFRA_KIT_LAST_CLEAR_MTIME=$mtime',\n ' print -u2 \"infra-kit: auto-cleared env\"',\n ' fi',\n ' fi',\n '}',\n 'autoload -Uz add-zsh-hook',\n 'if (( _INFRA_KIT_SHELL_STARTED > 0 )); then',\n ' add-zsh-hook precmd _infra_kit_autoload',\n 'fi',\n MARKER_END,\n ].join('\\n')\n}\n", "import confirm from '@inquirer/confirm'\nimport select from '@inquirer/select'\nimport process from 'node:process'\nimport { z } from 'zod'\nimport { $, question } from 'zx'\n\nimport { loadJiraConfig } from 'src/integrations/jira'\nimport { commandEcho } from 'src/lib/command-echo'\nimport { logger } from 'src/lib/logger'\nimport { createSingleRelease, prepareGitForRelease } from 'src/lib/release-utils'\nimport type { ReleaseType } from 'src/lib/release-utils'\nimport type { RequiredConfirmedOptionArg, ToolsExecutionResult } from 'src/types'\n\ninterface ReleaseCreateArgs extends RequiredConfirmedOptionArg {\n version?: string\n description?: string\n type?: ReleaseType\n checkout?: boolean\n}\n\n/**\n * Create a single release branch for the specified version\n * Includes Jira version creation and GitHub release branch creation\n */\nexport const releaseCreate = async (args: ReleaseCreateArgs): Promise<ToolsExecutionResult> => {\n const {\n version: inputVersion,\n description: inputDescription,\n type: inputType,\n confirmedCommand,\n checkout: inputCheckout,\n } = args\n\n commandEcho.start('release-create')\n\n let version = inputVersion\n let description = inputDescription\n let type: ReleaseType = inputType || 'regular'\n let checkout = inputCheckout\n\n // Load Jira config - it is now mandatory\n const jiraConfig = await loadJiraConfig()\n\n if (!version) {\n commandEcho.setInteractive()\n version = await question('Enter version (e.g. 1.2.5): ')\n }\n\n // Validate input (validate the version is a valid semver)\n if (!version || version.trim() === '') {\n logger.error('No version provided. Exiting...')\n process.exit(1)\n }\n\n const trimmedVersion = version.trim()\n\n commandEcho.addOption('--version', trimmedVersion)\n\n if (!inputType) {\n commandEcho.setInteractive()\n\n type = await select<ReleaseType>({\n message: 'Select release type:',\n choices: [\n { name: 'regular', value: 'regular' },\n { name: 'hotfix', value: 'hotfix' },\n ],\n default: 'regular',\n })\n }\n\n commandEcho.addOption('--type', type)\n\n if (description === undefined) {\n commandEcho.setInteractive()\n description = await question('Enter description (optional, press Enter to skip): ')\n\n if (description.trim() === '') {\n description = ''\n }\n }\n\n if (description) {\n commandEcho.addOption('--description', description)\n }\n\n const answer = confirmedCommand\n ? true\n : await confirm({\n message: `Are you sure you want to create release branch for version ${trimmedVersion}?`,\n })\n\n if (!confirmedCommand) {\n commandEcho.setInteractive()\n }\n\n if (!answer) {\n logger.info('Operation cancelled. Exiting...')\n process.exit(0)\n }\n\n // Track --yes flag if confirmation was interactive (user confirmed)\n commandEcho.addOption('--yes', true)\n\n await prepareGitForRelease(type)\n\n // Create the release\n const release = await createSingleRelease({ version: trimmedVersion, jiraConfig, description, type })\n\n logger.info(`\u2705 Successfully created release: v${trimmedVersion}`)\n logger.info(`\uD83D\uDD17 GitHub PR: ${release.prUrl}`)\n logger.info(`\uD83D\uDD17 Jira Version: ${release.jiraVersionUrl}`)\n\n // Ask about checkout if not specified\n if (checkout === undefined) {\n commandEcho.setInteractive()\n\n checkout = await confirm({\n message: `Do you want to checkout to the created branch ${release.branchName}?`,\n default: true,\n })\n }\n\n // Track checkout option (--no-checkout if false)\n if (!checkout) {\n commandEcho.addOption('--no-checkout', true)\n }\n\n // Checkout to the created branch by default\n if (checkout) {\n $.quiet = true\n await $`git switch ${release.branchName}`\n $.quiet = false\n\n logger.info(`\uD83D\uDD04 Switched to branch ${release.branchName}`)\n }\n\n commandEcho.print()\n\n const structuredContent = {\n version: trimmedVersion,\n type,\n branchName: release.branchName,\n prUrl: release.prUrl,\n jiraVersionUrl: release.jiraVersionUrl,\n isCheckedOut: checkout,\n }\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(structuredContent, null, 2),\n },\n ],\n structuredContent,\n }\n}\n\n// MCP Tool Registration\nexport const releaseCreateMcpTool = {\n name: 'release-create',\n description:\n 'Create a new release: cuts the release branch off the appropriate base (dev for regular releases, main for hotfixes), opens a GitHub release PR, creates the matching Jira fix version, and optionally checks out to the new branch. Confirmation is auto-skipped for MCP calls, so the caller is responsible for gating. \"version\" is required when invoked via MCP (the interactive input prompt is unreachable without a TTY); \"type\" / \"description\" / \"checkout\" default to regular / empty / true when omitted.',\n inputSchema: {\n version: z.string().describe('Version to create (e.g., \"1.2.5\"). Required for MCP calls.'),\n description: z.string().optional().describe('Optional description for the Jira version'),\n type: z\n .enum(['regular', 'hotfix'])\n .optional()\n .default('regular')\n .describe('Release type: \"regular\" or \"hotfix\" (default: \"regular\")'),\n checkout: z.boolean().optional().default(true).describe('Checkout to the created branch (default: true)'),\n },\n outputSchema: {\n version: z.string().describe('Version number'),\n type: z.enum(['regular', 'hotfix']).describe('Release type'),\n branchName: z.string().describe('Release branch name'),\n prUrl: z.string().describe('GitHub PR URL'),\n jiraVersionUrl: z.string().describe('Jira version URL'),\n isCheckedOut: z.boolean().describe('Whether the branch was checked out'),\n },\n handler: releaseCreate,\n}\n", "import confirm from '@inquirer/confirm'\nimport select from '@inquirer/select'\nimport process from 'node:process'\nimport { z } from 'zod'\nimport { question } from 'zx'\n\nimport { loadJiraConfig } from 'src/integrations/jira'\nimport { commandEcho } from 'src/lib/command-echo'\nimport { logger } from 'src/lib/logger'\nimport { createSingleRelease, prepareGitForRelease } from 'src/lib/release-utils'\nimport type { ReleaseCreationResult, ReleaseType } from 'src/lib/release-utils'\nimport type { RequiredConfirmedOptionArg, ToolsExecutionResult } from 'src/types'\n\ninterface ReleaseCreateBatchArgs extends RequiredConfirmedOptionArg {\n versions: string\n type?: ReleaseType\n}\n\n/**\n * Gather and validate batch release inputs interactively if needed\n */\nconst resolveInputs = async (args: ReleaseCreateBatchArgs): Promise<{ versionsList: string[]; type: ReleaseType }> => {\n const { versions: inputVersions, type: inputType, confirmedCommand } = args\n\n let versionInput = inputVersions\n let type: ReleaseType = inputType || 'regular'\n\n if (!versionInput) {\n commandEcho.setInteractive()\n versionInput = await question('Enter versions by comma (e.g. 1.2.5, 1.2.6): ')\n }\n\n const versionsList = versionInput\n .split(',')\n .map((version) => {\n return version.trim()\n })\n .filter(Boolean)\n\n commandEcho.addOption('--versions', versionsList.join(', '))\n\n if (versionsList.length === 0) {\n logger.error('No versions provided. Exiting...')\n process.exit(1)\n }\n\n if (!inputType) {\n commandEcho.setInteractive()\n\n type = await select<ReleaseType>({\n message: 'Select release type:',\n choices: [\n { name: 'regular', value: 'regular' },\n { name: 'hotfix', value: 'hotfix' },\n ],\n default: 'regular',\n })\n }\n\n commandEcho.addOption('--type', type)\n\n if (versionsList.length === 1) {\n logger.warn('\uD83D\uDCA1 You are creating only one release. Consider using \"create-release\" command for single releases.')\n }\n\n const answer = confirmedCommand\n ? true\n : await confirm({\n message: `Are you sure you want to create release branches for these versions: ${versionsList.join(', ')}?`,\n })\n\n if (!confirmedCommand) {\n commandEcho.setInteractive()\n }\n\n if (!answer) {\n logger.info('Operation cancelled. Exiting...')\n process.exit(0)\n }\n\n commandEcho.addOption('--yes', true)\n\n return { versionsList, type }\n}\n\n/**\n * Create multiple release branches for the specified versions\n * Includes Jira version creation and GitHub release branch creation for each version\n */\nexport const releaseCreateBatch = async (args: ReleaseCreateBatchArgs): Promise<ToolsExecutionResult> => {\n commandEcho.start('release-create-batch')\n\n const jiraConfig = await loadJiraConfig()\n\n const { versionsList, type } = await resolveInputs(args)\n\n await prepareGitForRelease(type)\n\n const releases: ReleaseCreationResult[] = []\n const failedReleases: Array<{ version: string; error: string }> = []\n\n for (const version of versionsList) {\n try {\n // Create each release\n const release = await createSingleRelease({ version, jiraConfig, type })\n\n releases.push(release)\n\n logger.info(`\u2705 Successfully created release: v${version}`)\n logger.info(`\uD83D\uDD17 GitHub PR: ${release.prUrl}`)\n logger.info(`\uD83D\uDD17 Jira Version: ${release.jiraVersionUrl}\\n`)\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error)\n\n failedReleases.push({ version, error: errorMessage })\n\n logger.error(`\u274C Failed to create release: v${version}`)\n logger.error(` Error: ${errorMessage}\\n`)\n }\n }\n\n // Final summary\n const successCount = releases.length\n const failureCount = failedReleases.length\n\n if (successCount === versionsList.length) {\n logger.info(`\u2705 All ${versionsList.length} release branches were created successfully.`)\n } else if (successCount > 0) {\n logger.warn(`\u26A0\uFE0F ${successCount} of ${versionsList.length} release branches were created successfully.`)\n logger.warn(`\u274C ${failureCount} release(s) failed.`)\n } else {\n logger.error(`\u274C All ${versionsList.length} release branches failed to create.`)\n }\n\n commandEcho.print()\n\n const structuredContent = {\n createdBranches: releases.map((r) => {\n return r.branchName\n }),\n successCount,\n failureCount,\n releases,\n failedReleases,\n }\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(structuredContent, null, 2),\n },\n ],\n structuredContent,\n }\n}\n\n// MCP Tool Registration\nexport const releaseCreateBatchMcpTool = {\n name: 'release-create-batch',\n description:\n 'Create several releases in one pass: for each comma-separated version in \"versions\", cuts the release branch off the appropriate base (dev for regular releases, main for hotfixes), opens a GitHub PR, and creates the Jira fix version. Continues on per-version failure and reports which versions succeeded and which failed. Confirmation is auto-skipped for MCP calls, so the caller is responsible for gating. \"versions\" is required when invoked via MCP (the interactive input prompt is unreachable without a TTY). Use release-create for a single version with optional checkout.',\n inputSchema: {\n versions: z\n .string()\n .describe('Comma-separated list of versions to create (e.g., \"1.2.5, 1.2.6\"). Required for MCP calls.'),\n type: z\n .enum(['regular', 'hotfix'])\n .optional()\n .default('regular')\n .describe('Release type: \"regular\" or \"hotfix\" (default: \"regular\")'),\n },\n outputSchema: {\n createdBranches: z.array(z.string()).describe('List of created release branches'),\n successCount: z.number().describe('Number of releases created successfully'),\n failureCount: z.number().describe('Number of releases that failed'),\n releases: z\n .array(\n z.object({\n version: z.string().describe('Version number'),\n type: z.enum(['regular', 'hotfix']).describe('Release type'),\n branchName: z.string().describe('Release branch name'),\n prUrl: z.string().describe('GitHub PR URL'),\n jiraVersionUrl: z.string().describe('Jira version URL'),\n }),\n )\n .describe('Detailed information for each created release with URLs'),\n failedReleases: z\n .array(\n z.object({\n version: z.string().describe('Version number that failed'),\n error: z.string().describe('Error message'),\n }),\n )\n .describe('List of releases that failed with error messages'),\n },\n handler: releaseCreateBatch,\n}\n", "import { z } from 'zod'\n\nimport { logger } from 'src/lib/logger'\nimport type { ToolsExecutionResult } from 'src/types'\n\nimport packageJson from '../../../package.json' with { type: 'json' }\n\n/**\n * Print the infra-kit CLI version\n */\nexport const version = async (): Promise<ToolsExecutionResult> => {\n const cliVersion = packageJson.version\n\n logger.info(cliVersion)\n\n const structuredContent = { version: cliVersion }\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(structuredContent, null, 2),\n },\n ],\n structuredContent,\n }\n}\n\n// MCP Tool Registration\nexport const versionMcpTool = {\n name: 'version',\n description: 'Print the installed infra-kit CLI version',\n inputSchema: {},\n outputSchema: {\n version: z.string().describe('Installed infra-kit CLI version (from package.json)'),\n },\n handler: version,\n}\n", "{\n \"name\": \"infra-kit\",\n \"type\": \"module\",\n \"version\": \"0.1.93\",\n \"description\": \"infra-kit\",\n \"main\": \"dist/cli.js\",\n \"module\": \"dist/cli.js\",\n \"bin\": {\n \"infra-kit\": \"dist/cli.js\",\n \"ik\": \"dist/cli.js\"\n },\n \"engines\": {\n \"node\": \">=24.x\"\n },\n \"scripts\": {\n \"inspector\": \"npx @modelcontextprotocol/inspector node ./dist/mcp.js --debug\",\n \"build\": \"pnpm run clean-artifacts && node ./scripts/build.js\",\n \"clean-artifacts\": \"rm -rf dist\",\n \"clean-cache\": \"rm -rf node_modules/.cache .eslintcache tsconfig.tsbuildinfo .turbo .swc\",\n \"prettier-fix\": \"pnpm exec prettier **/* --write --no-error-on-unmatched-pattern --log-level warn --ignore-path ../../../.prettierignore\",\n \"prettier-check\": \"pnpm exec prettier **/* --check --no-error-on-unmatched-pattern --log-level warn --ignore-path ../../../.prettierignore\",\n \"eslint-check\": \"pnpm exec eslint --cache --quiet --report-unused-disable-directives ./src\",\n \"eslint-fix\": \"pnpm exec eslint --cache --quiet --report-unused-disable-directives ./src --fix\",\n \"ts-check\": \"tsc --noEmit\",\n \"test\": \"pnpm exec vitest run --reporter=dot\",\n \"test-watch\": \"pnpm exec vitest --watch\",\n \"test-ui\": \"pnpm exec vitest --ui\",\n \"test-report\": \"pnpm exec vitest run --coverage\",\n \"qa\": \"pnpm run prettier-check && pnpm run eslint-check && pnpm run ts-check && pnpm run test && echo \u2705 Success\",\n \"fix\": \"pnpm run prettier-fix && pnpm run eslint-fix && pnpm run qa\"\n },\n \"dependencies\": {\n \"@inquirer/checkbox\": \"^5.1.4\",\n \"@inquirer/confirm\": \"^6.0.12\",\n \"@inquirer/select\": \"^5.1.4\",\n \"@modelcontextprotocol/sdk\": \"^1.29.0\",\n \"commander\": \"^14.0.3\",\n \"pino\": \"^10.3.1\",\n \"pino-pretty\": \"^13.1.3\",\n \"yaml\": \"^2.8.3\",\n \"zod\": \"^3.25.76\",\n \"zx\": \"^8.8.5\"\n },\n \"devDependencies\": {\n \"@pkg/eslint-config\": \"workspace:*\",\n \"@pkg/vitest-config\": \"workspace:*\",\n \"esbuild\": \"^0.28.0\",\n \"typescript\": \"^5.9.3\"\n }\n}\n", "/* eslint-disable sonarjs/cognitive-complexity */\nimport checkbox from '@inquirer/checkbox'\nimport confirm from '@inquirer/confirm'\nimport process from 'node:process'\nimport { z } from 'zod'\nimport { $ } from 'zx'\n\nimport { openCmuxWorkspaceWithLayout } from 'src/integrations/cmux'\nimport { getReleasePRsWithInfo } from 'src/integrations/gh'\nimport { commandEcho } from 'src/lib/command-echo'\nimport { WORKTREES_DIR_SUFFIX } from 'src/lib/constants'\nimport { getCurrentWorktrees, getProjectRoot, getRepoName } from 'src/lib/git-utils'\nimport { logger } from 'src/lib/logger'\nimport { detectReleaseType, formatBranchChoices, getJiraDescriptions } from 'src/lib/release-utils'\nimport type { ReleaseType } from 'src/lib/release-utils'\nimport type { RequiredConfirmedOptionArg, ToolsExecutionResult } from 'src/types'\n\n// Constants\nconst FEATURE_DIR = 'feature'\nconst RELEASE_DIR = 'release'\nconst RELEASE_BRANCH_PREFIX = 'release/v'\n\ninterface WorktreeManagementArgs extends RequiredConfirmedOptionArg {\n all: boolean\n versions?: string\n cursor?: boolean\n githubDesktop?: boolean\n cmux?: boolean\n}\n\n/**\n * Manage git worktrees for release branches\n * Creates worktrees for active release branches and removes unused ones\n */\nexport const worktreesAdd = async (options: WorktreeManagementArgs): Promise<ToolsExecutionResult> => {\n const { confirmedCommand, all, versions, cursor, githubDesktop, cmux } = options\n\n commandEcho.start('worktrees-add')\n\n try {\n const currentWorktrees = await getCurrentWorktrees('release')\n const projectRoot = await getProjectRoot()\n\n const worktreeDir = `${projectRoot}${WORKTREES_DIR_SUFFIX}`\n\n await ensureWorktreeDirectory(`${worktreeDir}/${RELEASE_DIR}`)\n await ensureWorktreeDirectory(`${worktreeDir}/${FEATURE_DIR}`)\n\n let selectedReleaseBranches: string[] = []\n\n if (versions) {\n selectedReleaseBranches = versions.split(',').map((v) => {\n return `release/v${v.trim()}`\n })\n } else {\n const releasePRsInfo = await getReleasePRsWithInfo()\n\n const releasePRsList = releasePRsInfo.map((pr) => {\n return pr.branch\n })\n\n if (releasePRsList.length === 0) {\n logger.info('\u2139\uFE0F No open release branches found')\n\n commandEcho.print()\n\n return {\n content: [{ type: 'text', text: JSON.stringify({ createdWorktrees: [], count: 0 }, null, 2) }],\n structuredContent: { createdWorktrees: [], count: 0 },\n }\n }\n\n if (all) {\n selectedReleaseBranches = releasePRsList\n } else {\n commandEcho.setInteractive()\n\n const releaseTypes = new Map<string, ReleaseType>(\n releasePRsInfo.map((pr) => {\n return [pr.branch, detectReleaseType(pr.title)]\n }),\n )\n\n const descriptions = await getJiraDescriptions()\n\n selectedReleaseBranches = await checkbox({\n required: true,\n message: '\uD83C\uDF3F Select release branches',\n choices: formatBranchChoices({ branches: releasePRsList, descriptions, types: releaseTypes }),\n })\n }\n }\n\n // Track --all flag if all branches were selected (either via flag or interactively)\n if (all) {\n commandEcho.addOption('--all', true)\n } else {\n commandEcho.addOption(\n '--versions',\n selectedReleaseBranches.map((branch) => {\n return branch.replace('release/v', '')\n }),\n )\n }\n\n // Ask for confirmation\n const answer = confirmedCommand\n ? true\n : await confirm({\n message: 'Are you sure you want to proceed with these worktree changes?',\n })\n\n if (!confirmedCommand) {\n commandEcho.setInteractive()\n }\n\n if (!answer) {\n logger.info('Operation cancelled. Exiting...')\n process.exit(0)\n }\n\n // Track --yes flag if confirmation was interactive (user confirmed)\n if (!confirmedCommand) {\n commandEcho.addOption('--yes', true)\n }\n\n const openInCursor = cursor ?? (await confirm({ message: 'Open created worktrees in Cursor?' }))\n\n if (typeof cursor === 'undefined') {\n commandEcho.setInteractive()\n }\n\n if (openInCursor) {\n commandEcho.addOption('--cursor', true)\n } else {\n commandEcho.addOption('--no-cursor', true)\n }\n\n const openInGithubDesktop =\n githubDesktop ?? (await confirm({ message: 'Open created worktrees in GitHub Desktop?' }))\n\n if (typeof githubDesktop === 'undefined') {\n commandEcho.setInteractive()\n }\n\n if (openInGithubDesktop) {\n commandEcho.addOption('--github-desktop', true)\n } else {\n commandEcho.addOption('--no-github-desktop', true)\n }\n\n const openInCmux = cmux ?? (await confirm({ message: 'Open created worktrees in cmux?' }))\n\n if (typeof cmux === 'undefined') {\n commandEcho.setInteractive()\n }\n\n if (openInCmux) {\n commandEcho.addOption('--cmux', true)\n } else {\n commandEcho.addOption('--no-cmux', true)\n }\n\n const { branchesToCreate } = categorizeWorktrees({\n selectedReleaseBranches,\n currentWorktrees,\n })\n\n const createdWorktrees = await createWorktrees(branchesToCreate, worktreeDir)\n\n logResults(createdWorktrees)\n\n if (openInCursor) {\n for (const branch of createdWorktrees) {\n await $`cursor ${worktreeDir}/${branch}`\n }\n }\n\n if (openInGithubDesktop) {\n for (const branch of createdWorktrees) {\n await $`github ${worktreeDir}/${branch}`\n await $`sleep 5`\n }\n }\n\n if (openInCmux) {\n const repoName = await getRepoName()\n\n for (const branch of createdWorktrees) {\n const version = branch.replace('release/', '')\n\n await openCmuxWorkspaceWithLayout({\n cwd: `${worktreeDir}/${branch}`,\n title: `${repoName} ${version}`,\n })\n }\n }\n\n commandEcho.print()\n\n const structuredContent = {\n createdWorktrees,\n count: createdWorktrees.length,\n }\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(structuredContent, null, 2),\n },\n ],\n structuredContent,\n }\n } catch (error) {\n logger.error({ error }, '\u274C Error managing worktrees')\n throw error\n }\n}\n\n/**\n * Ensure the worktree directory exists\n */\nconst ensureWorktreeDirectory = async (worktreeDir: string): Promise<void> => {\n await $`mkdir -p ${worktreeDir}`\n}\n\ninterface CategorizeWorktreesArgs {\n selectedReleaseBranches: string[]\n currentWorktrees: string[]\n}\n\n/**\n * Categorize release worktrees into those that need to be created or removed\n */\nconst categorizeWorktrees = (args: CategorizeWorktreesArgs): { branchesToCreate: string[] } => {\n const { selectedReleaseBranches, currentWorktrees } = args\n\n const currentBranchNames = currentWorktrees.filter((branch) => {\n return branch.startsWith(RELEASE_BRANCH_PREFIX)\n })\n\n const branchesToCreate = selectedReleaseBranches.filter((branch) => {\n return !currentBranchNames.includes(branch)\n })\n\n return { branchesToCreate }\n}\n\n/**\n * Create worktrees for the specified branches\n */\nconst createWorktrees = async (branches: string[], worktreeDir: string): Promise<string[]> => {\n const results = await Promise.allSettled(\n branches.map(async (branch) => {\n const worktreePath = `${worktreeDir}/${branch}`\n\n await $`git worktree add ${worktreePath} ${branch}`\n await $({ cwd: worktreePath })`pnpm install`\n\n return branch\n }),\n )\n\n const created: string[] = []\n\n for (const [index, result] of results.entries()) {\n if (result.status === 'fulfilled') {\n created.push(result.value)\n } else {\n const branch = branches[index]\n\n logger.error({ error: result.reason }, `\u274C Failed to create worktree for ${branch}`)\n }\n }\n\n return created\n}\n\n/**\n * Log the results of worktree management\n */\nconst logResults = (created: string[]): void => {\n if (created.length > 0) {\n logger.info('\u2705 Created git worktrees:')\n for (const branch of created) {\n logger.info(branch)\n }\n logger.info('')\n } else {\n logger.info('\u2139\uFE0F No new git worktrees to create')\n }\n}\n\n// MCP Tool Registration\nexport const worktreesAddMcpTool = {\n name: 'worktrees-add',\n description:\n 'Create local git worktrees for release branches under the worktrees directory and run \"pnpm install\" in each. Mutates the local filesystem. When invoked via MCP, pass either \"versions\" (comma-separated) or all=true \u2014 the branch picker and \"open in Cursor / GitHub Desktop / cmux\" follow-up prompts are unreachable without a TTY, and the CLI confirmation is auto-skipped for MCP calls.',\n inputSchema: {\n all: z\n .boolean()\n .optional()\n .describe(\n 'Add worktrees for every open release branch. Either \"all\" or \"versions\" must be provided for MCP calls (the interactive picker is unavailable without a TTY). Ignored if \"versions\" is provided.',\n ),\n versions: z\n .string()\n .optional()\n .describe(\n 'Comma-separated release versions to target (e.g. \"1.2.5, 1.2.6\"). Either \"versions\" or all=true must be provided for MCP calls. Overrides \"all\" when set.',\n ),\n cursor: z\n .boolean()\n .optional()\n .describe(\n 'Open each created worktree in Cursor. Defaults to false in MCP mode (the follow-up prompt is not shown).',\n ),\n githubDesktop: z\n .boolean()\n .optional()\n .describe(\n 'Open each created worktree in GitHub Desktop. Defaults to false in MCP mode (the follow-up prompt is not shown).',\n ),\n cmux: z\n .boolean()\n .optional()\n .describe(\n 'Open each created worktree in a new cmux workspace with a 3-pane layout (left-top, left-bottom, full-height right), all rooted at the worktree directory. Defaults to false in MCP mode (the follow-up prompt is not shown).',\n ),\n },\n outputSchema: {\n createdWorktrees: z.array(z.string()).describe('List of created git worktree branches'),\n count: z.number().describe('Number of git worktrees created'),\n },\n handler: worktreesAdd,\n}\n", "import { $ } from 'zx'\n\ninterface OpenCmuxWorkspaceArgs {\n cwd: string\n title?: string\n}\n\n/**\n * Opens a new cmux workspace rooted at `cwd` with three panes:\n * left-top (primary) | right (full-height)\n * left-bottom |\n * All panes inherit `cwd` from the workspace.\n */\nexport const openCmuxWorkspaceWithLayout = async (args: OpenCmuxWorkspaceArgs): Promise<void> => {\n const { cwd, title } = args\n\n const newWorkspaceOutput = (await $`cmux new-workspace --cwd ${cwd}`).stdout\n\n const workspaceRef = parseWorkspaceRef(newWorkspaceOutput)\n\n const surfacesOutput = (await $`cmux list-pane-surfaces --workspace ${workspaceRef}`).stdout\n\n const leftTopRef = parseFirstSurfaceRef(surfacesOutput)\n\n await $`cmux new-split right --workspace ${workspaceRef} --surface ${leftTopRef}`\n await $`cmux new-split down --workspace ${workspaceRef} --surface ${leftTopRef}`\n\n if (title) {\n await $`cmux rename-workspace --workspace ${workspaceRef} ${title}`\n }\n}\n\n/**\n * Extracts the first `surface:<id>` reference from the output of\n * `cmux list-pane-surfaces`. Used to locate the initial (primary) pane\n * surface so subsequent splits can be anchored relative to it.\n *\n * @example\n * const output = 'surface:12 (active)\\nsurface:13\\n'\n * parseFirstSurfaceRef(output) // => 'surface:12'\n */\nconst parseFirstSurfaceRef = (output: string): string => {\n const match = output.match(/surface:\\d+/)\n\n if (!match) {\n throw new Error('cmux: could not locate initial surface in list-pane-surfaces output')\n }\n\n return match[0]\n}\n\n/**\n * Extracts the `workspace:<id>` reference from the output of\n * `cmux new-workspace`. The returned ref is used to target the newly\n * created workspace in follow-up `cmux` commands (splits, rename, etc.).\n *\n * @example\n * const output = 'created workspace:7\\n'\n * parseWorkspaceRef(output) // => 'workspace:7'\n */\nconst parseWorkspaceRef = (output: string): string => {\n const match = output.match(/workspace:\\d+/)\n\n if (!match) {\n throw new Error('cmux: could not locate workspace ref in new-workspace output')\n }\n\n return match[0]\n}\n", "import { z } from 'zod'\n\nimport { getReleasePRsWithInfo } from 'src/integrations/gh'\nimport { getCurrentWorktrees } from 'src/lib/git-utils'\nimport { logger } from 'src/lib/logger'\nimport { detectReleaseType, formatVersionLabel, getJiraDescriptions } from 'src/lib/release-utils'\nimport type { ReleaseType } from 'src/lib/release-utils'\nimport type { ToolsExecutionResult } from 'src/types'\n\ninterface WorktreeInfo {\n version: string\n type: ReleaseType\n description: string | null\n}\n\n/**\n * List all release git worktrees with version, type, and Jira description\n */\nexport const worktreesList = async (): Promise<ToolsExecutionResult> => {\n const currentWorktrees = await getCurrentWorktrees('release')\n\n if (currentWorktrees.length === 0) {\n logger.info('\u2139\uFE0F No active worktrees found')\n\n return {\n content: [{ type: 'text', text: JSON.stringify({ worktrees: [], count: 0 }, null, 2) }],\n structuredContent: { worktrees: [], count: 0 },\n }\n }\n\n const [releasePRsInfo, jiraDescriptions] = await Promise.all([getReleasePRsWithInfo(), getJiraDescriptions()])\n\n const releaseTypes = new Map<string, ReleaseType>(\n releasePRsInfo.map((pr) => {\n return [pr.branch, detectReleaseType(pr.title)]\n }),\n )\n\n const worktrees: WorktreeInfo[] = currentWorktrees.map((branch) => {\n const version = branch.replace('release/', '')\n const type = releaseTypes.get(branch) || 'regular'\n const description = jiraDescriptions.get(version) || null\n\n return { version, type, description }\n })\n\n // Log formatted output\n const maxVersionLength = Math.max(\n ...worktrees.map((w) => {\n return w.version.length\n }),\n )\n\n const formattedLines = worktrees.map((worktree) => {\n const label = formatVersionLabel(worktree.version, worktree.type, maxVersionLength)\n\n if (worktree.description) {\n return `${label} ${worktree.description}`\n }\n\n return label\n })\n\n logger.info('\uD83C\uDF3F Active worktrees:')\n logger.info(`\\n${formattedLines.join('\\n')}\\n`)\n\n const structuredContent = {\n worktrees,\n count: worktrees.length,\n }\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(structuredContent, null, 2),\n },\n ],\n structuredContent,\n }\n}\n\n// MCP Tool Registration\nexport const worktreesListMcpTool = {\n name: 'worktrees-list',\n description:\n 'List existing release-branch worktrees with version, release type (regular / hotfix), and Jira fix-version description. Read-only.',\n inputSchema: {},\n outputSchema: {\n worktrees: z\n .array(\n z.object({\n version: z.string().describe('Release version'),\n type: z.enum(['regular', 'hotfix']).describe('Release type'),\n description: z.string().nullable().describe('Jira version description'),\n }),\n )\n .describe('List of all worktrees with details'),\n count: z.number().describe('Number of worktrees'),\n },\n handler: worktreesList,\n}\n", "import checkbox from '@inquirer/checkbox'\nimport confirm from '@inquirer/confirm'\nimport process from 'node:process'\nimport { z } from 'zod'\nimport { $ } from 'zx'\n\nimport { getReleasePRsWithInfo } from 'src/integrations/gh'\nimport { commandEcho } from 'src/lib/command-echo'\nimport { WORKTREES_DIR_SUFFIX } from 'src/lib/constants'\nimport { getCurrentWorktrees, getProjectRoot } from 'src/lib/git-utils'\nimport { logger } from 'src/lib/logger'\nimport { detectReleaseType, formatBranchChoices, getJiraDescriptions } from 'src/lib/release-utils'\nimport type { ReleaseType } from 'src/lib/release-utils'\nimport type { RequiredConfirmedOptionArg, ToolsExecutionResult } from 'src/types'\n\n// Constants\ninterface WorktreeManagementArgs extends RequiredConfirmedOptionArg {\n all: boolean\n versions?: string\n}\n\n/**\n * Manage git worktrees for release branches\n * Creates worktrees for active release branches and removes unused ones\n */\nexport const worktreesRemove = async (options: WorktreeManagementArgs): Promise<ToolsExecutionResult> => {\n const { confirmedCommand, all, versions } = options\n\n commandEcho.start('worktrees-remove')\n\n try {\n const currentWorktrees = await getCurrentWorktrees('release')\n\n if (currentWorktrees.length === 0) {\n logger.info('\u2139\uFE0F No active worktrees to remove')\n\n commandEcho.print()\n\n return {\n content: [{ type: 'text', text: JSON.stringify({ removedWorktrees: [], count: 0 }, null, 2) }],\n structuredContent: { removedWorktrees: [], count: 0 },\n }\n }\n\n const projectRoot = await getProjectRoot()\n\n const worktreeDir = `${projectRoot}${WORKTREES_DIR_SUFFIX}`\n\n let selectedReleaseBranches: string[] = []\n\n if (all) {\n selectedReleaseBranches = currentWorktrees\n } else if (versions) {\n selectedReleaseBranches = versions.split(',').map((v) => {\n return `release/v${v.trim()}`\n })\n } else {\n commandEcho.setInteractive()\n\n const [descriptions, prInfo] = await Promise.all([getJiraDescriptions(), getReleasePRsWithInfo()])\n\n const releaseTypes = new Map<string, ReleaseType>(\n prInfo.map((pr) => {\n return [pr.branch, detectReleaseType(pr.title)]\n }),\n )\n\n selectedReleaseBranches = await checkbox({\n required: true,\n message: '\uD83C\uDF3F Select release branches',\n choices: formatBranchChoices({ branches: currentWorktrees, descriptions, types: releaseTypes }),\n })\n }\n\n // Track --all flag if all branches were selected (either via flag or interactively)\n const allSelected = selectedReleaseBranches.length === currentWorktrees.length\n\n if (allSelected) {\n commandEcho.addOption('--all', true)\n } else {\n commandEcho.addOption(\n '--versions',\n selectedReleaseBranches.map((branch) => {\n return branch.replace('release/v', '')\n }),\n )\n }\n\n // Ask for confirmation\n const answer = confirmedCommand\n ? true\n : await confirm({\n message: 'Are you sure you want to proceed with these worktree changes?',\n })\n\n if (!confirmedCommand) {\n commandEcho.setInteractive()\n }\n\n if (!answer) {\n logger.info('Operation cancelled. Exiting...')\n process.exit(0)\n }\n\n // Track --yes flag if confirmation was interactive (user confirmed)\n if (!confirmedCommand) {\n commandEcho.addOption('--yes', true)\n }\n\n const removedWorktrees = await removeWorktrees(selectedReleaseBranches, worktreeDir)\n\n logResults(removedWorktrees)\n\n commandEcho.print()\n\n const structuredContent = {\n removedWorktrees,\n count: removedWorktrees.length,\n }\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(structuredContent, null, 2),\n },\n ],\n structuredContent,\n }\n } catch (error) {\n logger.error({ error }, '\u274C Error managing worktrees')\n throw error\n }\n}\n\n/**\n * Remove worktrees for the specified branches and whole folder\n */\nconst removeWorktrees = async (branches: string[], worktreeDir: string): Promise<string[]> => {\n const results = await Promise.allSettled(\n branches.map(async (branch) => {\n const worktreePath = `${worktreeDir}/${branch}`\n\n await $`git worktree remove ${worktreePath}`\n\n return branch\n }),\n )\n\n const removed: string[] = []\n\n for (const [index, result] of results.entries()) {\n if (result.status === 'fulfilled') {\n removed.push(result.value)\n } else {\n const branch = branches[index]\n\n logger.error({ error: result.reason }, `\u274C Failed to remove worktree for ${branch}`)\n }\n }\n\n if (removed.length === branches.length) {\n await $`git worktree prune`\n await $`rm -rf ${worktreeDir}`\n\n logger.info(`\uD83D\uDDD1\uFE0F Removed worktree folder: ${worktreeDir}`)\n logger.info('')\n }\n\n return removed\n}\n\n/**\n * Log the results of worktree management\n */\nconst logResults = (removed: string[]): void => {\n if (removed.length > 0) {\n logger.info('\u274C Removed worktrees:')\n for (const branch of removed) {\n logger.info(branch)\n }\n logger.info('')\n } else {\n logger.info('\u2139\uFE0F No unused worktrees to remove')\n }\n}\n\n// MCP Tool Registration\nexport const worktreesRemoveMcpTool = {\n name: 'worktrees-remove',\n description:\n 'Remove local git worktrees for release branches. When everything is removed, also runs \"git worktree prune\" and deletes the worktrees directory. When invoked via MCP, pass either \"versions\" (comma-separated) or all=true \u2014 the branch picker is unreachable without a TTY, and the CLI confirmation is auto-skipped for MCP calls, so the caller is responsible for gating.',\n inputSchema: {\n all: z\n .boolean()\n .optional()\n .describe(\n 'Remove every existing worktree. Either \"all\" or \"versions\" must be provided for MCP calls (the interactive picker is unavailable without a TTY). Ignored if \"versions\" is provided.',\n ),\n versions: z\n .string()\n .optional()\n .describe(\n 'Comma-separated release versions to target (e.g. \"1.2.5, 1.2.6\"). Either \"versions\" or all=true must be provided for MCP calls. Overrides \"all\" when set.',\n ),\n },\n outputSchema: {\n removedWorktrees: z.array(z.string()).describe('List of removed git worktree branches'),\n count: z.number().describe('Number of git worktrees removed'),\n },\n handler: worktreesRemove,\n}\n", "import confirm from '@inquirer/confirm'\nimport process from 'node:process'\nimport { z } from 'zod'\nimport { $ } from 'zx'\n\nimport { getReleasePRs } from 'src/integrations/gh'\nimport { commandEcho } from 'src/lib/command-echo'\nimport { WORKTREES_DIR_SUFFIX } from 'src/lib/constants'\nimport { getCurrentWorktrees, getProjectRoot } from 'src/lib/git-utils'\nimport { logger } from 'src/lib/logger'\nimport type { RequiredConfirmedOptionArg, ToolsExecutionResult } from 'src/types'\n\n// Constants\nconst RELEASE_BRANCH_PREFIX = 'release/v'\n\ninterface WorktreeSyncArgs extends RequiredConfirmedOptionArg {}\n\n/**\n * Manage git worktrees for release branches.\n *\n * Creates worktrees for active release branches and removes unused ones\n */\nexport const worktreesSync = async (options: WorktreeSyncArgs): Promise<ToolsExecutionResult> => {\n const { confirmedCommand } = options\n\n commandEcho.start('worktrees-sync')\n\n try {\n const currentWorktrees = await getCurrentWorktrees('release')\n const projectRoot = await getProjectRoot()\n\n const worktreeDir = `${projectRoot}${WORKTREES_DIR_SUFFIX}`\n\n const releasePRsList = await getReleasePRs()\n\n // Ask for confirmation\n const answer = confirmedCommand\n ? true\n : await confirm({\n message: 'Are you sure you want to proceed with these worktree changes?',\n })\n\n if (!confirmedCommand) {\n commandEcho.setInteractive()\n }\n\n if (!answer) {\n logger.info('Operation cancelled. Exiting...')\n process.exit(0)\n }\n\n // Track --yes flag if confirmation was interactive (user confirmed)\n if (!confirmedCommand) {\n commandEcho.addOption('--yes', true)\n }\n\n const { branchesToRemove } = categorizeWorktrees({\n releasePRsList,\n currentWorktrees,\n })\n\n const removedWorktrees = await removeWorktrees(branchesToRemove, worktreeDir)\n\n logResults(removedWorktrees)\n\n commandEcho.print()\n\n const structuredContent = {\n removedWorktrees,\n count: removedWorktrees.length,\n }\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(structuredContent, null, 2),\n },\n ],\n structuredContent,\n }\n } catch (error) {\n logger.error({ error }, '\u274C Error managing worktrees')\n throw error\n }\n}\n\ninterface CategorizeWorktreesArgs {\n releasePRsList: string[]\n currentWorktrees: string[]\n}\n\n/**\n * Categorize worktrees into those that need to be created or removed\n */\nconst categorizeWorktrees = (args: CategorizeWorktreesArgs): { branchesToRemove: string[] } => {\n const { releasePRsList, currentWorktrees } = args\n\n const currentBranchNames = currentWorktrees.filter((branch) => {\n return branch.startsWith(RELEASE_BRANCH_PREFIX)\n })\n\n const branchesToRemove = currentBranchNames.filter((branch) => {\n return !releasePRsList.includes(branch)\n })\n\n return { branchesToRemove }\n}\n\n/**\n * Remove worktrees for the specified branches\n */\nconst removeWorktrees = async (branches: string[], worktreeDir: string): Promise<string[]> => {\n const removed: string[] = []\n\n for (const branch of branches) {\n try {\n const worktreePath = `${worktreeDir}/${branch}`\n\n await $`git worktree remove ${worktreePath}`\n removed.push(branch)\n } catch (error) {\n logger.error({ error, branch }, `\u274C Failed to remove worktree for ${branch}`)\n }\n }\n\n return removed\n}\n\n/**\n * Log the results of worktree management\n */\nconst logResults = (removed: string[]): void => {\n if (removed.length > 0) {\n logger.info('\u274C Removed worktrees:')\n for (const branch of removed) {\n logger.info(branch)\n }\n logger.info('')\n } else {\n logger.info('\u2139\uFE0F No unused worktrees to remove')\n }\n}\n\n// MCP Tool Registration\nexport const worktreesSyncMcpTool = {\n name: 'worktrees-sync',\n description:\n 'Remove worktrees whose release PR is no longer open (stale cleanup). Only removes \u2014 never creates; use worktrees-add to create worktrees for new releases. The CLI confirmation is auto-skipped for MCP calls, so the caller is responsible for gating.',\n inputSchema: {},\n outputSchema: {\n removedWorktrees: z.array(z.string()).describe('List of removed worktree branches'),\n count: z.number().describe('Number of worktrees removed during sync'),\n },\n handler: worktreesSync,\n}\n"],
5
- "mappings": "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",
6
- "names": ["select", "Separator", "Command", "Option", "process", "z", "$", "process", "pino", "pretty", "initLoggerCLI", "logLevel", "process", "ignoreFields", "pino", "pretty", "logger", "checkCommand", "name", "command", "successMsg", "failMsg", "$", "doctor", "checks", "logger", "check", "icon", "structuredContent", "c", "doctorMcpTool", "z", "fs", "path", "process", "z", "fs", "os", "path", "process", "ENV_LOAD_FILE", "ENV_CLEAR_FILE", "INFRA_KIT_SESSION_VAR", "INFRA_KIT_ENV_CONFIG_VAR", "INFRA_KIT_ENV_PROJECT_VAR", "INFRA_KIT_ENV_LOADED_AT_VAR", "ENV_VAR_LINE_PATTERN", "parseVarNamesFromEnvFile", "filePath", "content", "names", "line", "match", "getCacheRoot", "xdg", "base", "getSessionCacheDir", "session", "atomicWriteFileSync", "mode", "tmpPath", "error", "WORKTREES_DIR_SUFFIX", "envClear", "cacheDir", "getSessionCacheDir", "envLoadPath", "path", "ENV_LOAD_FILE", "fs", "varNames", "parseVarNamesFromEnvFile", "unsetLines", "v", "INFRA_KIT_ENV_CONFIG_VAR", "INFRA_KIT_ENV_PROJECT_VAR", "INFRA_KIT_ENV_LOADED_AT_VAR", "clearFilePath", "ENV_CLEAR_FILE", "atomicWriteFileSync", "process", "structuredContent", "envClearMcpTool", "z", "z", "fs", "path", "yaml", "z", "path", "$", "getCurrentWorktrees", "type", "worktreeLines", "worktreePredicateMap", "releaseWorktreePredicate", "featureWorktreePredicate", "branch", "line", "parts", "getProjectRoot", "getRepoName", "projectRoot", "INFRA_KIT_CONFIG_FILE", "jiraTaskManagerProviderSchema", "z", "infraKitConfigSchema", "cached", "getInfraKitConfig", "projectRoot", "getProjectRoot", "configPath", "path", "stat", "fs", "raw", "parsed", "yaml", "result", "getDopplerProject", "dopplerProjectName", "getInfraKitConfig", "envList", "project", "getDopplerProject", "environments", "getInfraKitConfig", "logger", "env", "structuredContent", "envListMcpTool", "z", "select", "Buffer", "fs", "path", "process", "z", "$", "$", "validateDopplerCliAndAuth", "error", "createCommandEcho", "commandName", "options", "isInteractive", "name", "flag", "value", "formattedOptions", "opt", "logger", "commandEcho", "envLoad", "args", "validateDopplerCliAndAuth", "config", "commandEcho", "selectedConfig", "environments", "getInfraKitConfig", "select", "env", "process", "project", "getDopplerProject", "envContent", "downloadDopplerSecrets", "assertValidEnvContent", "loadedAt", "envFileLines", "INFRA_KIT_ENV_CONFIG_VAR", "shellSingleQuote", "INFRA_KIT_ENV_PROJECT_VAR", "INFRA_KIT_ENV_LOADED_AT_VAR", "cacheDir", "getSessionCacheDir", "envFilePath", "path", "ENV_LOAD_FILE", "fs", "atomicWriteFileSync", "varCount", "countEnvVarLines", "structuredContent", "DOPPLER_MAX_OUTPUT_BYTES", "DOPPLER_DOWNLOAD_TIMEOUT_MS", "prevQuiet", "$", "result", "assertDopplerOutputSize", "stdout", "bytes", "Buffer", "content", "line", "ENV_VAR_LINE_PATTERN", "SHELL_DIRECTIVE_LINES", "value", "trimmed", "envLoadMcpTool", "z", "path", "process", "envStatus", "validateDopplerCliAndAuth", "logger", "cacheDir", "getSessionCacheDir", "sessionId", "process", "INFRA_KIT_SESSION_VAR", "envLoadPath", "path", "ENV_LOAD_FILE", "sessionLoadedCount", "sessionTotalCount", "sessionConfig", "INFRA_KIT_ENV_CONFIG_VAR", "sessionProject", "INFRA_KIT_ENV_PROJECT_VAR", "sessionLoadedAt", "INFRA_KIT_ENV_LOADED_AT_VAR", "varNames", "parseVarNamesFromEnvFile", "v", "loadedAtDisplay", "missing", "structuredContent", "envStatusMcpTool", "checkbox", "confirm", "process", "z", "$", "$", "process", "$", "$", "process", "createJiraVersion", "params", "config", "baseUrl", "token", "email", "projectId", "requestBody", "url", "credentials", "response", "errorText", "logger", "error", "getProjectVersions", "findVersionByName", "versionName", "v", "updateJiraVersion", "deliverJiraRelease", "version", "loadJiraConfig", "process", "projectIdStr", "missingVars", "errorMessage", "loadJiraConfigOptional", "getBaseBranch", "type", "prepareGitForRelease", "baseBranch", "$", "createSingleRelease", "args", "version", "jiraConfig", "description", "versionName", "result", "createJiraVersion", "jiraVersionUrl", "releaseInfo", "createReleaseBranch", "getJiraDescriptions", "descriptions", "loadJiraConfigOptional", "versions", "getProjectVersions", "formatVersionLabel", "maxVersionLength", "padding", "tag", "detectReleaseType", "title", "formatBranchChoices", "branches", "types", "versionNames", "b", "maxLen", "v", "branch", "i", "desc", "name", "parseVersion", "versionStr", "sortVersions", "versions", "a", "b", "majA", "minA", "patchA", "majB", "minB", "patchB", "fetchAllReleasePRs", "releasePRs", "$", "hotfixPRs", "all", "seen", "pr", "getReleasePRs", "prs", "logger", "process", "sortVersions", "error", "getReleasePRsWithInfo", "sortedBranches", "prByBranch", "branch", "createReleaseBranch", "args", "version", "jiraVersionUrl", "type", "description", "titlePrefix", "baseBranch", "getBaseBranch", "branchName", "body", "prLink", "ghMergeDev", "args", "all", "confirmedCommand", "commandEcho", "releasePRsList", "getReleasePRsWithInfo", "pr", "detectReleaseType", "logger", "selectedReleaseBranches", "descriptions", "getJiraDescriptions", "checkbox", "formatBranchChoices", "branch", "answer", "confirm", "process", "$", "failedBranches", "mergeDev", "structuredContent", "error", "ghMergeDevMcpTool", "z", "confirm", "select", "process", "z", "$", "ghReleaseDeliver", "args", "version", "confirmedCommand", "commandEcho", "releasePRsInfo", "getReleasePRsWithInfo", "branches", "pr", "releaseTypes", "detectReleaseType", "selectedReleaseBranch", "descriptions", "getJiraDescriptions", "select", "formatBranchChoices", "selectedVersion", "prInfo", "logger", "process", "releaseType", "answer", "confirm", "$", "jiraConfig", "loadJiraConfigOptional", "versionName", "deliverJiraRelease", "error", "structuredContent", "ghReleaseDeliverMcpTool", "z", "select", "process", "z", "$", "ghReleaseDeployAll", "args", "version", "env", "skipTerraform", "commandEcho", "selectedReleaseBranch", "releasePRsInfo", "getReleasePRsWithInfo", "branches", "pr", "releaseTypes", "detectReleaseType", "descriptions", "getJiraDescriptions", "select", "formatBranchChoices", "selectedVersion", "environments", "getInfraKitConfig", "selectedEnv", "logger", "process", "shouldSkipTerraform", "$", "structuredContent", "error", "ghReleaseDeployAllMcpTool", "z", "checkbox", "select", "fs", "resolve", "process", "yaml", "z", "$", "ghReleaseDeploySelected", "args", "version", "env", "services", "skipTerraform", "commandEcho", "selectedReleaseBranch", "releasePRsInfo", "getReleasePRsWithInfo", "branches", "pr", "releaseTypes", "detectReleaseType", "descriptions", "getJiraDescriptions", "select", "formatBranchChoices", "selectedVersion", "environments", "getInfraKitConfig", "selectedEnv", "logger", "process", "availableServices", "parseServicesFromWorkflow", "selectedServices", "checkbox", "svc", "invalidServices", "shouldSkipTerraform", "$", "serviceFlags", "structuredContent", "error", "projectRoot", "getProjectRoot", "workflowPath", "resolve", "content", "fs", "inputs", "yaml", "key", "value", "ghReleaseDeploySelectedMcpTool", "z", "z", "ghReleaseList", "releases", "getReleasePRsWithInfo", "pr", "detectReleaseType", "jiraDescriptions", "getJiraDescriptions", "maxVersionLength", "r", "formattedLines", "release", "label", "formatVersionLabel", "description", "logger", "structuredContent", "ghReleaseListMcpTool", "z", "fs", "os", "path", "MARKER_START", "MARKER_END", "LEGACY_PAIRED", "LEGACY_SINGLE", "init", "zshrcPath", "path", "os", "shellBlock", "buildShellBlock", "fs", "content", "cleaned", "removeExistingBlock", "logger", "isBlockLine", "line", "removeBetween", "start", "end", "startIdx", "endIdx", "before", "after", "result", "legacyResult", "legacyIdx", "afterLines", "remaining", "runCmd", "confirm", "select", "process", "z", "$", "question", "releaseCreate", "args", "inputVersion", "inputDescription", "inputType", "confirmedCommand", "inputCheckout", "commandEcho", "version", "description", "type", "checkout", "jiraConfig", "loadJiraConfig", "question", "logger", "process", "trimmedVersion", "select", "answer", "confirm", "prepareGitForRelease", "release", "createSingleRelease", "$", "structuredContent", "releaseCreateMcpTool", "z", "confirm", "select", "process", "z", "question", "resolveInputs", "args", "inputVersions", "inputType", "confirmedCommand", "versionInput", "type", "commandEcho", "question", "versionsList", "version", "logger", "process", "select", "answer", "confirm", "releaseCreateBatch", "jiraConfig", "loadJiraConfig", "prepareGitForRelease", "releases", "failedReleases", "release", "createSingleRelease", "error", "errorMessage", "successCount", "failureCount", "structuredContent", "r", "releaseCreateBatchMcpTool", "z", "z", "package_default", "version", "cliVersion", "package_default", "logger", "structuredContent", "versionMcpTool", "z", "checkbox", "confirm", "process", "z", "$", "$", "openCmuxWorkspaceWithLayout", "args", "cwd", "title", "newWorkspaceOutput", "workspaceRef", "parseWorkspaceRef", "surfacesOutput", "leftTopRef", "parseFirstSurfaceRef", "output", "match", "FEATURE_DIR", "RELEASE_DIR", "RELEASE_BRANCH_PREFIX", "worktreesAdd", "options", "confirmedCommand", "all", "versions", "cursor", "githubDesktop", "cmux", "commandEcho", "currentWorktrees", "getCurrentWorktrees", "worktreeDir", "getProjectRoot", "WORKTREES_DIR_SUFFIX", "ensureWorktreeDirectory", "selectedReleaseBranches", "v", "releasePRsInfo", "getReleasePRsWithInfo", "releasePRsList", "pr", "logger", "releaseTypes", "detectReleaseType", "descriptions", "getJiraDescriptions", "checkbox", "formatBranchChoices", "branch", "answer", "confirm", "process", "openInCursor", "openInGithubDesktop", "openInCmux", "branchesToCreate", "categorizeWorktrees", "createdWorktrees", "createWorktrees", "logResults", "$", "repoName", "getRepoName", "version", "openCmuxWorkspaceWithLayout", "structuredContent", "error", "args", "currentBranchNames", "branches", "results", "worktreePath", "created", "index", "result", "worktreesAddMcpTool", "z", "z", "worktreesList", "currentWorktrees", "getCurrentWorktrees", "logger", "releasePRsInfo", "jiraDescriptions", "getReleasePRsWithInfo", "getJiraDescriptions", "releaseTypes", "pr", "detectReleaseType", "worktrees", "branch", "version", "type", "description", "maxVersionLength", "w", "formattedLines", "worktree", "label", "formatVersionLabel", "structuredContent", "worktreesListMcpTool", "z", "checkbox", "confirm", "process", "z", "$", "worktreesRemove", "options", "confirmedCommand", "all", "versions", "commandEcho", "currentWorktrees", "getCurrentWorktrees", "logger", "worktreeDir", "getProjectRoot", "WORKTREES_DIR_SUFFIX", "selectedReleaseBranches", "v", "descriptions", "prInfo", "getJiraDescriptions", "getReleasePRsWithInfo", "releaseTypes", "pr", "detectReleaseType", "checkbox", "formatBranchChoices", "branch", "answer", "confirm", "process", "removedWorktrees", "removeWorktrees", "logResults", "structuredContent", "error", "branches", "results", "worktreePath", "$", "removed", "index", "result", "worktreesRemoveMcpTool", "z", "confirm", "process", "z", "$", "RELEASE_BRANCH_PREFIX", "worktreesSync", "options", "confirmedCommand", "commandEcho", "currentWorktrees", "getCurrentWorktrees", "worktreeDir", "getProjectRoot", "WORKTREES_DIR_SUFFIX", "releasePRsList", "getReleasePRs", "answer", "confirm", "logger", "process", "branchesToRemove", "categorizeWorktrees", "removedWorktrees", "removeWorktrees", "logResults", "structuredContent", "error", "args", "branch", "branches", "removed", "worktreePath", "$", "worktreesSyncMcpTool", "z", "program", "Command", "runProgram", "argv", "error", "message", "logger", "process", "options", "ghMergeDev", "ghReleaseList", "Option", "releaseCreate", "releaseCreateBatch", "ghReleaseDeployAll", "ghReleaseDeploySelected", "ghReleaseDeliver", "worktreesSync", "worktreesAdd", "worktreesList", "worktreesRemove", "doctor", "version", "envStatus", "envList", "init", "envLoad", "envClear", "releaseCommands", "worktreeCommands", "envCommands", "commandMap", "cmd", "allNames", "maxLen", "n", "toChoices", "names", "selected", "select", "Separator"]
3
+ "sources": ["../src/entry/cli.ts", "../src/commands/doctor/doctor.ts", "../src/commands/init/init.ts", "../src/lib/logger/index.ts", "../src/lib/git-utils/git-utils.ts", "../src/lib/infra-kit-config/infra-kit-config.ts", "../src/commands/env-clear/env-clear.ts", "../src/lib/constants.ts", "../src/commands/env-list/env-list.ts", "../src/integrations/doppler/doppler-project.ts", "../src/commands/env-load/env-load.ts", "../src/integrations/doppler/doppler-cli-auth.ts", "../src/lib/command-echo/command-echo.ts", "../src/commands/env-status/env-status.ts", "../src/commands/gh-merge-dev/gh-merge-dev.ts", "../src/integrations/gh/gh-cli-auth/gh-cli-auth.ts", "../src/integrations/gh/gh-release-prs/gh-release-prs.ts", "../src/lib/release-utils/release-utils.ts", "../src/integrations/jira/api.ts", "../src/lib/version-utils/version-utils.ts", "../src/commands/gh-release-deliver/gh-release-deliver.ts", "../src/commands/gh-release-deploy-all/gh-release-deploy-all.ts", "../src/commands/gh-release-deploy-selected/gh-release-deploy-selected.ts", "../src/commands/gh-release-list/gh-release-list.ts", "../src/commands/release-create/release-create.ts", "../src/commands/release-create-batch/release-create-batch.ts", "../src/commands/version/version.ts", "../package.json", "../src/commands/worktrees-add/worktrees-add.ts", "../src/integrations/cmux/close-workspace-by-title.ts", "../src/integrations/cmux/open-workspace-with-layout.ts", "../src/integrations/cmux/workspace-title.ts", "../src/integrations/cursor/add-folders-to-workspace.ts", "../src/integrations/cursor/remove-folders-from-workspace.ts", "../src/integrations/cursor/resolve-workspace-path.ts", "../src/commands/worktrees-list/worktrees-list.ts", "../src/commands/worktrees-remove/worktrees-remove.ts", "../src/commands/worktrees-sync/worktrees-sync.ts"],
4
+ "sourcesContent": ["import select, { Separator } from '@inquirer/select'\nimport { Command, Option } from 'commander'\nimport process from 'node:process'\n\nimport { doctor } from 'src/commands/doctor'\nimport { envClear } from 'src/commands/env-clear'\nimport { envList } from 'src/commands/env-list'\nimport { envLoad } from 'src/commands/env-load'\nimport { envStatus } from 'src/commands/env-status'\nimport { ghMergeDev } from 'src/commands/gh-merge-dev'\nimport { ghReleaseDeliver } from 'src/commands/gh-release-deliver'\nimport { ghReleaseDeployAll } from 'src/commands/gh-release-deploy-all'\nimport { ghReleaseDeploySelected } from 'src/commands/gh-release-deploy-selected'\nimport { ghReleaseList } from 'src/commands/gh-release-list'\nimport { init } from 'src/commands/init'\nimport { releaseCreate } from 'src/commands/release-create'\nimport { releaseCreateBatch } from 'src/commands/release-create-batch'\nimport { version } from 'src/commands/version'\nimport { CURSOR_MODES, worktreesAdd } from 'src/commands/worktrees-add'\nimport type { CursorMode } from 'src/commands/worktrees-add'\nimport { worktreesList } from 'src/commands/worktrees-list'\nimport { worktreesRemove } from 'src/commands/worktrees-remove'\nimport { worktreesSync } from 'src/commands/worktrees-sync'\nimport { logger } from 'src/lib/logger'\n\nconst program = new Command()\n\nconst normalizeCursorMode = (value: unknown): CursorMode | undefined => {\n if (typeof value === 'undefined') {\n return undefined\n }\n\n if (value === true) {\n return 'workspace'\n }\n\n if (value === false) {\n return 'none'\n }\n\n if (typeof value === 'string' && (CURSOR_MODES as readonly string[]).includes(value)) {\n return value as CursorMode\n }\n\n throw new Error(`Invalid --cursor value \"${String(value)}\". Expected one of: ${CURSOR_MODES.join(', ')}.`)\n}\n\nconst runProgram = async (argv?: string[]): Promise<void> => {\n try {\n if (argv) {\n await program.parseAsync(argv)\n } else {\n await program.parseAsync()\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n\n logger.error(message)\n process.exit(1)\n }\n}\n\nprogram\n .command('merge-dev')\n .description('Merge dev branch into every release branch')\n .option('-a, --all', 'Select all active release branches')\n .option('-y, --yes', 'Skip confirmation prompt')\n .action(async (options) => {\n await ghMergeDev({ all: options.all, confirmedCommand: options.yes })\n })\n\nprogram\n .command('release-list')\n .description('List all release branches')\n .action(async () => {\n await ghReleaseList()\n })\n\nprogram\n .command('release-create')\n .description('Create a single release branch')\n .option('-v, --version <version>', 'Specify the version to create, e.g. 1.2.5')\n .option('-d, --description <description>', 'Optional description for the Jira version')\n .addOption(new Option('-t, --type <type>', 'Release type (default: regular)').choices(['regular', 'hotfix']))\n .option('-y, --yes', 'Skip confirmation prompt')\n .option('--no-checkout', 'Do not checkout the created branch after creation (checkout is default)')\n .action(async (options) => {\n await releaseCreate({\n version: options.version,\n description: options.description,\n type: options.type,\n confirmedCommand: options.yes,\n checkout: options.checkout,\n })\n })\n\nprogram\n .command('release-create-batch')\n .description('Create multiple release branches (batch operation)')\n .option('-v, --versions <versions>', 'Specify the versions to create by comma, e.g. 1.2.5, 1.2.6')\n .addOption(new Option('-t, --type <type>', 'Release type (default: regular)').choices(['regular', 'hotfix']))\n .option('-y, --yes', 'Skip confirmation prompt')\n .action(async (options) => {\n await releaseCreateBatch({\n versions: options.versions,\n type: options.type,\n confirmedCommand: options.yes,\n })\n })\n\nprogram\n .command('release-deploy-all')\n .description('Deploy any release branch to any environment')\n .option('-v, --version <version>', 'Specify the version to deploy, e.g. 1.2.5')\n .option('-e, --env <env>', 'Specify the environment to deploy to, e.g. dev')\n .option('--skip-terraform', 'Skip terraform deployment step')\n .action(async (options) => {\n await ghReleaseDeployAll({ version: options.version, env: options.env, skipTerraform: options.skipTerraform })\n })\n\nprogram\n .command('release-deploy-selected')\n .description('Deploy selected services from release branch to any environment')\n .option('-v, --version <version>', 'Specify the version to deploy, e.g. 1.2.5')\n .option('-e, --env <env>', 'Specify the environment to deploy to, e.g. dev')\n .option('-s, --services <services...>', 'Specify services to deploy, e.g. client-be client-fe')\n .option('--skip-terraform', 'Skip terraform deployment step')\n .action(async (options) => {\n await ghReleaseDeploySelected({\n version: options.version,\n env: options.env,\n services: options.services,\n skipTerraform: options.skipTerraform,\n })\n })\n\nprogram\n .command('release-deliver')\n .description('Release a new version to production')\n .option('-v, --version <version>', 'Specify the version to release, e.g. 1.2.5')\n .option('-y, --yes', 'Skip confirmation prompt')\n .action(async (options) => {\n await ghReleaseDeliver({ version: options.version, confirmedCommand: options.yes })\n })\n\nprogram\n .command('worktrees-sync')\n .description('Remove release worktrees whose PRs are no longer open')\n .option('-y, --yes', 'Skip confirmation prompt')\n .action(async (options) => {\n await worktreesSync({ confirmedCommand: options.yes })\n })\n\nprogram\n .command('worktrees-add')\n .description('Add git worktrees for release branches')\n .option('-y, --yes', 'Skip confirmation prompt')\n .option('-a, --all', 'Select all active release branches')\n .option('-v, --versions <versions>', 'Specify versions by comma, e.g. 1.2.5, 1.2.6')\n .option('-c, --cursor [mode]', 'Cursor mode for created worktrees: workspace (default) | windows | none')\n .option('--no-cursor', 'Skip Cursor (alias for --cursor none)')\n .option('-g, --github-desktop', 'Open created worktrees in GitHub Desktop')\n .option('--no-github-desktop', 'Skip GitHub Desktop prompt')\n .option('-m, --cmux', 'Open created worktrees in cmux (3-pane layout)')\n .option('--no-cmux', 'Skip cmux prompt')\n .action(async (options) => {\n await worktreesAdd({\n confirmedCommand: options.yes,\n all: options.all,\n versions: options.versions,\n cursor: normalizeCursorMode(options.cursor),\n githubDesktop: options.githubDesktop,\n cmux: options.cmux,\n })\n })\n\nprogram\n .command('worktrees-list')\n .description('List all git worktrees with detailed information')\n .action(async () => {\n await worktreesList()\n })\n\nprogram\n .command('worktrees-remove')\n .description('Remove git worktrees for release branches')\n .option('-y, --yes', 'Skip confirmation prompt')\n .option('-a, --all', 'Select all active release branches')\n .option('-v, --versions <versions>', 'Specify versions by comma, e.g. 1.2.5, 1.2.6')\n .action(async (options) => {\n await worktreesRemove({ confirmedCommand: options.yes, all: options.all, versions: options.versions })\n })\n\nprogram\n .command('doctor')\n .description('Check installation and authentication status of gh and doppler CLIs')\n .action(async () => {\n await doctor()\n })\n\nprogram\n .command('version')\n .description('Print the installed infra-kit CLI version')\n .action(async () => {\n await version()\n })\n\nprogram\n .command('env-status')\n .description('Show Doppler authentication status and detected project info')\n .action(async () => {\n await envStatus()\n })\n\nprogram\n .command('env-list')\n .description('List available Doppler configs for the detected project')\n .action(async () => {\n await envList()\n })\n\nprogram\n .command('init')\n .description('Inject shell integration into your profile .zshrc')\n .action(async () => {\n await init()\n })\n\nprogram\n .command('env-load')\n .description('Load Doppler env vars for a config. Source the returned file path to apply.')\n .option('-c, --config <config>', 'Environment config name to load (e.g. dev, arthur)')\n .action(async (options) => {\n await envLoad({ config: options.config })\n })\n\nprogram\n .command('env-clear')\n .description('Clear loaded env vars. Source the returned file path to apply.')\n .action(async () => {\n await envClear()\n })\n\nif (process.argv.length <= 2) {\n const releaseCommands = [\n 'merge-dev',\n 'release-list',\n 'release-create',\n 'release-create-batch',\n 'release-deploy-all',\n 'release-deploy-selected',\n 'release-deliver',\n ]\n const worktreeCommands = ['worktrees-add', 'worktrees-list', 'worktrees-remove', 'worktrees-sync']\n const envCommands = ['doctor', 'init', 'version', 'env-status', 'env-list', 'env-load', 'env-clear']\n\n const commandMap = new Map(\n program.commands.map((cmd) => {\n return [cmd.name(), cmd]\n }),\n )\n\n const allNames = [...releaseCommands, ...worktreeCommands, ...envCommands]\n const maxLen = Math.max(\n ...allNames.map((n) => {\n return n.length\n }),\n )\n\n const toChoices = (names: string[]) => {\n return names\n .filter((n) => {\n return commandMap.has(n)\n })\n .map((n) => {\n return {\n name: `${n.padEnd(maxLen)} ${commandMap.get(n)!.description()}`,\n value: n,\n }\n })\n }\n\n const selected = await select(\n {\n message: 'Select a command to run',\n choices: [\n new Separator(' '),\n new Separator('\u2014 Release Management \u2014'),\n ...toChoices(releaseCommands),\n new Separator(' '),\n new Separator('\u2014 Worktrees \u2014'),\n ...toChoices(worktreeCommands),\n new Separator(' '),\n new Separator('\u2014 Environment \u2014'),\n ...toChoices(envCommands),\n ],\n },\n { output: process.stderr },\n )\n\n await runProgram(['node', 'infra-kit', selected])\n} else {\n await runProgram()\n}\n", "import fs from 'node:fs'\nimport os from 'node:os'\nimport path from 'node:path'\nimport { z } from 'zod/v4'\nimport { $ } from 'zx'\n\nimport { MARKER_END, MARKER_START, buildShellBlock } from 'src/commands/init/init'\nimport { getProjectRoot } from 'src/lib/git-utils/git-utils'\nimport { getInfraKitConfig, resetInfraKitConfigCache } from 'src/lib/infra-kit-config'\nimport { logger } from 'src/lib/logger'\nimport type { ToolsExecutionResult } from 'src/types'\n\nconst LOCAL_CONFIG_FILE = 'infra-kit.local.yml'\n\ninterface CheckResult {\n name: string\n status: 'pass' | 'fail'\n message: string\n}\n\nconst checkCommand = async (\n name: string,\n command: string[],\n successMsg: string,\n failMsg: string,\n): Promise<CheckResult> => {\n try {\n await $`${command}`\n\n return { name, status: 'pass', message: successMsg }\n } catch {\n return { name, status: 'fail', message: failMsg }\n }\n}\n\nconst checkZshrcInitialized = (): CheckResult => {\n const name = 'zshrc init block'\n const zshrcPath = path.join(os.homedir(), '.zshrc')\n\n if (!fs.existsSync(zshrcPath)) {\n return { name, status: 'fail', message: '~/.zshrc not found. Run: infra-kit init' }\n }\n\n const content = fs.readFileSync(zshrcPath, 'utf-8')\n const startIdx = content.indexOf(MARKER_START)\n const endIdx = content.indexOf(MARKER_END)\n\n if (startIdx === -1 || endIdx === -1 || endIdx < startIdx) {\n return {\n name,\n status: 'fail',\n message: 'infra-kit shell block missing from ~/.zshrc. Run: infra-kit init',\n }\n }\n\n const installedBlock = content.slice(startIdx, endIdx + MARKER_END.length).trim()\n const expectedBlock = buildShellBlock().trim()\n\n if (installedBlock !== expectedBlock) {\n return {\n name,\n status: 'fail',\n message: 'infra-kit shell block in ~/.zshrc is out of date. Run: infra-kit init',\n }\n }\n\n return { name, status: 'pass', message: 'infra-kit shell block in ~/.zshrc is up to date' }\n}\n\nconst checkPnpmWorkspaceVirtualStore = async (): Promise<CheckResult> => {\n const name = 'pnpm enableGlobalVirtualStore'\n\n try {\n const root = await getProjectRoot()\n const yamlPath = path.join(root, 'pnpm-workspace.yaml')\n\n if (!fs.existsSync(yamlPath)) {\n return { name, status: 'fail', message: `pnpm-workspace.yaml not found at ${yamlPath}` }\n }\n\n const content = fs.readFileSync(yamlPath, 'utf-8')\n // eslint-disable-next-line sonarjs/slow-regex\n const enabled = /^\\s*enableGlobalVirtualStore\\s*:\\s*true\\s*$/m.test(content)\n\n if (!enabled) {\n return {\n name,\n status: 'fail',\n message: 'enableGlobalVirtualStore: true is missing in pnpm-workspace.yaml',\n }\n }\n\n return { name, status: 'pass', message: 'enableGlobalVirtualStore: true is set' }\n } catch (err) {\n return {\n name,\n status: 'fail',\n message: `Failed to read pnpm-workspace.yaml: ${(err as Error).message}`,\n }\n }\n}\n\nconst checkInfraKitConfigValid = async (): Promise<CheckResult> => {\n const name = 'infra-kit config valid'\n\n try {\n resetInfraKitConfigCache()\n await getInfraKitConfig()\n\n return {\n name,\n status: 'pass',\n message: 'infra-kit.yml is valid (infra-kit.local.yml overrides applied if present)',\n }\n } catch (err) {\n return { name, status: 'fail', message: (err as Error).message }\n }\n}\n\nconst checkLocalConfigGitignored = async (): Promise<CheckResult> => {\n const name = 'infra-kit.local.yml gitignored'\n\n try {\n const root = await getProjectRoot()\n\n await $({ cwd: root, nothrow: true })`git check-ignore -q ${LOCAL_CONFIG_FILE}`.then((result) => {\n if (result.exitCode !== 0) {\n throw new Error('not ignored')\n }\n })\n\n return { name, status: 'pass', message: `${LOCAL_CONFIG_FILE} is covered by .gitignore` }\n } catch {\n return {\n name,\n status: 'fail',\n message: `${LOCAL_CONFIG_FILE} is not gitignored. Add \"${LOCAL_CONFIG_FILE}\" to .gitignore.`,\n }\n }\n}\n\n/**\n * Check installation and authentication status of gh, doppler, and aws CLIs\n */\nexport const doctor = async (): Promise<ToolsExecutionResult> => {\n const checks: CheckResult[] = await Promise.all([\n checkCommand(\n 'gh installed',\n ['gh', '--version'],\n 'GitHub CLI is installed',\n 'GitHub CLI is not installed. Install from: https://cli.github.com/',\n ),\n checkCommand(\n 'gh authenticated',\n ['gh', 'auth', 'status'],\n 'GitHub CLI is authenticated',\n 'GitHub CLI is not authenticated. Run: gh auth login',\n ),\n checkCommand(\n 'doppler installed',\n ['doppler', '--version'],\n 'Doppler CLI is installed',\n 'Doppler CLI is not installed. Install from: https://docs.doppler.com/docs/install-cli',\n ),\n checkCommand(\n 'doppler authenticated',\n ['doppler', 'me'],\n 'Doppler CLI is authenticated',\n 'Doppler CLI is not authenticated. Run: doppler login',\n ),\n checkCommand(\n 'aws installed',\n ['aws', '--version'],\n 'AWS CLI is installed',\n 'AWS CLI is not installed. Install from: https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html',\n ),\n // INFO: no need now, util the user does not load the env variables, the aws cli is not authenticated\n // checkCommand(\n // 'aws authenticated',\n // ['aws', 'sts', 'get-caller-identity'],\n // 'AWS CLI is authenticated',\n // 'AWS CLI is not authenticated. Run: aws configure (or aws sso login)',\n // ),\n Promise.resolve(checkZshrcInitialized()),\n checkPnpmWorkspaceVirtualStore(),\n checkInfraKitConfigValid(),\n checkLocalConfigGitignored(),\n ])\n\n logger.info('Doctor check results:\\n')\n\n for (const check of checks) {\n const icon = check.status === 'pass' ? '[PASS]' : '[FAIL]'\n\n logger.info(` ${icon} ${check.name}: ${check.message}`)\n }\n\n const structuredContent = {\n checks: checks.map((c) => {\n return { name: c.name, status: c.status, message: c.message }\n }),\n allPassed: checks.every((c) => {\n return c.status === 'pass'\n }),\n }\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(structuredContent, null, 2),\n },\n ],\n structuredContent,\n }\n}\n\n// MCP Tool Registration\nexport const doctorMcpTool = {\n name: 'doctor',\n description: 'Check installation and authentication status of gh, doppler, and aws CLIs',\n inputSchema: {},\n outputSchema: {\n checks: z\n .array(\n z.object({\n name: z.string().describe('Name of the check'),\n status: z.enum(['pass', 'fail']).describe('Check result'),\n message: z.string().describe('Details about the check result'),\n }),\n )\n .describe('List of all check results'),\n allPassed: z.boolean().describe('Whether all checks passed'),\n },\n handler: doctor,\n}\n", "import fs from 'node:fs'\nimport os from 'node:os'\nimport path from 'node:path'\n\nimport { logger } from 'src/lib/logger'\n\nexport const MARKER_START = '# -- infra-kit:begin --'\nexport const MARKER_END = '# -- infra-kit:end --'\n\nconst LEGACY_PAIRED: [start: string, end: string][] = [['# region infra-kit', '# endregion infra-kit']]\nconst LEGACY_SINGLE = '# infra-kit shell functions'\n\n/**\n * Append infra-kit shell functions directly to .zshrc.\n */\nexport const init = async (): Promise<void> => {\n const zshrcPath = path.join(os.homedir(), '.zshrc')\n const shellBlock = buildShellBlock()\n\n if (fs.existsSync(zshrcPath)) {\n const content = fs.readFileSync(zshrcPath, 'utf-8')\n const cleaned = removeExistingBlock(content)\n\n fs.writeFileSync(zshrcPath, cleaned)\n }\n\n fs.appendFileSync(zshrcPath, `\\n${shellBlock}\\n`)\n logger.info(`Added infra-kit shell functions to ${zshrcPath}`)\n logger.info('Run `source ~/.zshrc` or open a new terminal to activate.')\n}\n\nconst isBlockLine = (line: string): boolean => {\n return (\n line.startsWith('#') ||\n line.startsWith('alias ') ||\n line.startsWith('env-load') ||\n line.startsWith('env-clear') ||\n line.startsWith('env-status') ||\n line.startsWith('if ') ||\n line.startsWith(' export INFRA_KIT_SESSION') ||\n line.startsWith('export _INFRA_KIT_') ||\n line.startsWith(': ${_INFRA_KIT_') ||\n line.startsWith('fi') ||\n line.startsWith('zmodload ') ||\n line.startsWith('autoload ') ||\n line.startsWith('add-zsh-hook ') ||\n line.startsWith('_infra_kit_autoload')\n )\n}\n\nconst removeBetween = (content: string, start: string, end: string): string | null => {\n const startIdx = content.indexOf(start)\n const endIdx = content.indexOf(end)\n\n if (startIdx === -1 || endIdx === -1) return null\n\n // eslint-disable-next-line sonarjs/slow-regex\n const before = content.slice(0, startIdx).replace(/\\n+$/, '')\n const after = content.slice(endIdx + end.length).replace(/^\\n+/, '')\n\n return before + (after ? `\\n${after}` : '')\n}\n\nconst removeExistingBlock = (content: string): string => {\n // 1. Current markers\n const result = removeBetween(content, MARKER_START, MARKER_END)\n\n if (result !== null) return result\n\n // 2. Legacy paired markers (# region / # endregion)\n for (const [start, end] of LEGACY_PAIRED) {\n const legacyResult = removeBetween(content, start, end)\n\n if (legacyResult !== null) return legacyResult\n }\n\n // 3. Oldest format: single marker + heuristic scan\n const legacyIdx = content.indexOf(LEGACY_SINGLE)\n\n if (legacyIdx === -1) return content\n\n // eslint-disable-next-line sonarjs/slow-regex\n const before = content.slice(0, legacyIdx).replace(/\\n+$/, '')\n const afterLines = content.slice(legacyIdx).split('\\n')\n\n let i = 0\n\n while (i < afterLines.length && isBlockLine(afterLines[i]!)) {\n i++\n }\n\n const remaining = afterLines.slice(i).join('\\n')\n\n return before + (remaining ? `\\n${remaining}` : '')\n}\n\nexport const buildShellBlock = (): string => {\n const runCmd = 'pnpm exec infra-kit'\n\n return [\n MARKER_START,\n 'zmodload zsh/stat 2>/dev/null',\n 'zmodload zsh/datetime 2>/dev/null',\n // eslint-disable-next-line no-template-curly-in-string\n 'if [[ -z \"${INFRA_KIT_SESSION}\" ]]; then',\n ' export INFRA_KIT_SESSION=$(head -c 4 /dev/urandom | xxd -p)',\n 'fi',\n // eslint-disable-next-line no-template-curly-in-string\n ': ${_INFRA_KIT_LAST_LOAD_MTIME:=0}',\n // eslint-disable-next-line no-template-curly-in-string\n ': ${_INFRA_KIT_LAST_CLEAR_MTIME:=0}',\n // eslint-disable-next-line no-template-curly-in-string\n ': ${_INFRA_KIT_SHELL_STARTED:=${EPOCHSECONDS:-0}}',\n 'export _INFRA_KIT_LAST_LOAD_MTIME _INFRA_KIT_LAST_CLEAR_MTIME _INFRA_KIT_SHELL_STARTED',\n `env-load() { local f m; f=$(${runCmd} env-load \"$@\") || return; m=$(zstat +mtime -- \"$f\" 2>/dev/null || echo 0); _INFRA_KIT_LAST_LOAD_MTIME=$m; source \"$f\"; ${runCmd} env-status; }`,\n `env-clear() { local f m; f=$(${runCmd} env-clear) || return; m=$(zstat +mtime -- \"$f\" 2>/dev/null || echo 0); _INFRA_KIT_LAST_CLEAR_MTIME=$m; source \"$f\"; ${runCmd} env-status; }`,\n `env-status() { ${runCmd} env-status; }`,\n `alias ik='${runCmd}'`,\n '_infra_kit_autoload() {',\n ' [[ -z \"$INFRA_KIT_SESSION\" ]] && return',\n // eslint-disable-next-line no-template-curly-in-string\n ' local cache_root=\"${XDG_CACHE_HOME:-$HOME/.cache}/infra-kit\"',\n ' local dir=\"$cache_root/$INFRA_KIT_SESSION\"',\n ' local load_file=\"$dir/env-load.sh\"',\n ' local clear_file=\"$dir/env-clear.sh\"',\n ' local mtime',\n ' if [[ -f \"$load_file\" ]]; then',\n ' mtime=$(zstat +mtime -- \"$load_file\" 2>/dev/null || echo 0)',\n ' if (( mtime > _INFRA_KIT_LAST_LOAD_MTIME && mtime >= _INFRA_KIT_SHELL_STARTED )); then',\n ' source \"$load_file\"',\n ' _INFRA_KIT_LAST_LOAD_MTIME=$mtime',\n // eslint-disable-next-line no-template-curly-in-string\n ' print -u2 \"infra-kit: auto-loaded vars for ${INFRA_KIT_ENV_CONFIG:-?}\"',\n ' fi',\n ' fi',\n ' if [[ -f \"$clear_file\" ]]; then',\n ' mtime=$(zstat +mtime -- \"$clear_file\" 2>/dev/null || echo 0)',\n ' if (( mtime > _INFRA_KIT_LAST_CLEAR_MTIME && mtime >= _INFRA_KIT_SHELL_STARTED )); then',\n ' source \"$clear_file\"',\n ' _INFRA_KIT_LAST_CLEAR_MTIME=$mtime',\n ' print -u2 \"infra-kit: auto-cleared env\"',\n ' fi',\n ' fi',\n '}',\n 'autoload -Uz add-zsh-hook',\n 'if (( _INFRA_KIT_SHELL_STARTED > 0 )); then',\n ' add-zsh-hook precmd _infra_kit_autoload',\n 'fi',\n MARKER_END,\n ].join('\\n')\n}\n", "import process from 'node:process'\nimport pino from 'pino'\nimport pretty from 'pino-pretty'\n\n// eslint-disable-next-line sonarjs/publicly-writable-directories\nexport const LOG_FILE_PATH = '/tmp/mcp-infra-kit.log'\n\nexport const initLoggerMcp = () => {\n const logLevel = process.argv.includes('--debug') ? 'debug' : 'info'\n\n const logger = pino({ level: logLevel }, pino.destination({ dest: LOG_FILE_PATH }))\n\n logger.info(`Logger initialized with level: ${logLevel}. Logging to: ${LOG_FILE_PATH}`)\n\n return logger\n}\n\nexport const initLoggerCLI = () => {\n const logLevel = process.argv.includes('--debug') ? 'debug' : 'info'\n\n const ignoreFields = ['time', 'pid', 'hostname']\n\n if (logLevel === 'debug') {\n ignoreFields.push('level')\n }\n\n const logger = pino(\n { level: logLevel },\n pretty({\n destination: 2,\n ignore: ignoreFields.join(','),\n colorize: true,\n }),\n )\n\n return logger\n}\n\n// Singleton logger instance for CLI usage\nexport const logger = initLoggerCLI()\n", "import path from 'node:path'\nimport { $ } from 'zx'\n\n/**\n * Get current git worktrees\n *\n * @returns [release/v1.18.22, release/v1.18.23, release/v1.18.24] or [feature/mobile-app, feature/explore-page, feature/login-page]\n */\nexport const getCurrentWorktrees = async (type: 'release' | 'feature'): Promise<string[]> => {\n const worktreesOutput = await $`git worktree list`\n\n const worktreeLines = worktreesOutput.stdout.split('\\n').filter(Boolean)\n\n const worktreePredicateMap = {\n release: releaseWorktreePredicate,\n feature: featureWorktreePredicate,\n }\n\n return worktreeLines.map(worktreePredicateMap[type]).filter((branch) => {\n return branch !== null\n })\n}\n\n/**\n * Extract a release branch name from a `git worktree list` output line.\n *\n * Returns `null` for lines that are not release worktrees.\n *\n * @example\n * releaseWorktreePredicate('/path/to/release/v1.18.22 abc1234 [release/v1.18.22]')\n * // => 'release/v1.18.22'\n *\n * @example\n * releaseWorktreePredicate('/path/to/feature/login abc1234 [feature/login]')\n * // => null\n */\nconst releaseWorktreePredicate = (line: string): string | null => {\n const parts = line.split(' ').filter(Boolean)\n\n if (parts.length < 3 || !parts[0]?.includes('release/v')) return null\n\n return `release/${parts[0]?.split('/').pop() || ''}`\n}\n\n/**\n * Extract a feature branch name from a `git worktree list` output line.\n *\n * Returns `null` for lines that are not feature worktrees.\n *\n * @example\n * featureWorktreePredicate('/path/to/feature/login-page abc1234 [feature/login-page]')\n * // => 'feature/login-page'\n *\n * @example\n * featureWorktreePredicate('/path/to/release/v1.18.22 abc1234 [release/v1.18.22]')\n * // => null\n */\nconst featureWorktreePredicate = (line: string): string | null => {\n const parts = line.split(' ').filter(Boolean)\n\n if (parts.length < 3 || !parts[0]?.includes('feature/')) return null\n\n return `feature/${parts[0]?.split('/').pop() || ''}`\n}\n\n/**\n * Get the current project root directory\n */\nexport const getProjectRoot = async (): Promise<string> => {\n const result = await $`git rev-parse --show-toplevel`\n\n return result.stdout.trim()\n}\n\n/**\n * Get the current repository name (basename of the project root)\n */\nexport const getRepoName = async (): Promise<string> => {\n const projectRoot = await getProjectRoot()\n\n return path.basename(projectRoot)\n}\n", "import fs from 'node:fs/promises'\nimport path from 'node:path'\nimport yaml from 'yaml'\nimport { z } from 'zod/v4'\n\nimport { getProjectRoot } from 'src/lib/git-utils'\n\nconst INFRA_KIT_CONFIG_FILE = 'infra-kit.yml'\nconst INFRA_KIT_LOCAL_CONFIG_FILE = 'infra-kit.local.yml'\n\n// envManagement\nconst dopplerEnvManagementSchema = z.object({\n provider: z.literal('doppler'),\n config: z.object({\n name: z.string().min(1),\n }),\n})\n\nconst envManagementSchema = z.discriminatedUnion('provider', [dopplerEnvManagementSchema])\n\n// ide\nconst cursorIdeConfigSchema = z\n .object({\n mode: z.enum(['workspace', 'windows']).default('workspace'),\n workspaceConfigPath: z.string().min(1).optional(),\n })\n .refine(\n (v) => {\n return v.mode !== 'workspace' || !!v.workspaceConfigPath\n },\n {\n message: 'workspaceConfigPath is required when mode is \"workspace\"',\n path: ['workspaceConfigPath'],\n },\n )\n\nconst cursorIdeSchema = z.object({\n provider: z.literal('cursor'),\n config: cursorIdeConfigSchema,\n})\n\nconst ideSchema = z.discriminatedUnion('provider', [cursorIdeSchema])\n\n// taskManager\nconst jiraTaskManagerSchema = z.object({\n provider: z.literal('jira'),\n config: z.object({\n baseUrl: z.string().url(),\n projectId: z.number().int().positive(),\n }),\n})\n\nconst taskManagerSchema = z.discriminatedUnion('provider', [jiraTaskManagerSchema])\n\nconst infraKitConfigSchema = z.object({\n environments: z.array(z.string().min(1)).min(1),\n envManagement: envManagementSchema,\n ide: ideSchema.optional(),\n taskManager: taskManagerSchema.optional(),\n})\n\nconst infraKitLocalConfigSchema = infraKitConfigSchema.partial()\n\nexport type InfraKitConfig = z.infer<typeof infraKitConfigSchema>\n\ninterface CacheEntry {\n mainMtimeMs: number\n localMtimeMs: number | null\n value: InfraKitConfig\n}\n\nlet cached: CacheEntry | null = null\n\n/**\n * Read and validate `infra-kit.yml`, with optional `infra-kit.local.yml` overrides\n * shallow-merged on top (per-developer, gitignored). Top-level keys (entire\n * capability sections like `ide`, `envManagement`) replace wholesale. Results are\n * cached per file mtimes so the long-running MCP server picks up edits without a\n * restart.\n */\nexport const getInfraKitConfig = async (): Promise<InfraKitConfig> => {\n const projectRoot = await getProjectRoot()\n const mainPath = path.join(projectRoot, INFRA_KIT_CONFIG_FILE)\n const localPath = path.join(projectRoot, INFRA_KIT_LOCAL_CONFIG_FILE)\n\n let mainStat: Awaited<ReturnType<typeof fs.stat>>\n\n try {\n mainStat = await fs.stat(mainPath)\n } catch {\n cached = null\n throw new Error(`infra-kit.yml not found at ${mainPath}`)\n }\n\n const localStat = await statIfExists(localPath)\n const mainMtimeMs = Number(mainStat.mtimeMs)\n const localMtimeMs = localStat ? Number(localStat.mtimeMs) : null\n\n if (cached && cached.mainMtimeMs === mainMtimeMs && cached.localMtimeMs === localMtimeMs) {\n return cached.value\n }\n\n const mainRaw = await fs.readFile(mainPath, 'utf-8')\n const mainParsed = yaml.parse(mainRaw)\n\n let merged: unknown = mainParsed\n\n if (localStat) {\n const localRaw = await fs.readFile(localPath, 'utf-8')\n const localParsedRaw = yaml.parse(localRaw) ?? {}\n\n const localResult = infraKitLocalConfigSchema.safeParse(localParsedRaw)\n\n if (!localResult.success) {\n throw new Error(`Invalid infra-kit.local.yml at ${localPath}: ${z.prettifyError(localResult.error)}`)\n }\n\n merged = { ...(mainParsed as object), ...localResult.data }\n }\n\n const result = infraKitConfigSchema.safeParse(merged)\n\n if (!result.success) {\n throw new Error(`Invalid infra-kit.yml at ${mainPath}: ${z.prettifyError(result.error)}`)\n }\n\n cached = { mainMtimeMs, localMtimeMs, value: result.data }\n\n return result.data\n}\n\n/** For tests \u2014 drops the in-memory cache. */\nexport const resetInfraKitConfigCache = (): void => {\n cached = null\n}\n\nconst statIfExists = async (filePath: string): Promise<Awaited<ReturnType<typeof fs.stat>> | null> => {\n try {\n return await fs.stat(filePath)\n } catch {\n return null\n }\n}\n", "import fs from 'node:fs'\nimport path from 'node:path'\nimport process from 'node:process'\nimport { z } from 'zod/v4'\n\nimport {\n ENV_CLEAR_FILE,\n ENV_LOAD_FILE,\n INFRA_KIT_ENV_CONFIG_VAR,\n INFRA_KIT_ENV_LOADED_AT_VAR,\n INFRA_KIT_ENV_PROJECT_VAR,\n atomicWriteFileSync,\n getSessionCacheDir,\n parseVarNamesFromEnvFile,\n} from 'src/lib/constants'\nimport type { ToolsExecutionResult } from 'src/types'\n\n/**\n * Clear loaded env vars. Prints a file path to stdout that must be sourced to apply.\n * The env-clear shell alias does this automatically. Throws when no env is loaded\n * so CLI callers exit non-zero and MCP callers receive a structured tool error.\n */\nexport const envClear = async (): Promise<ToolsExecutionResult> => {\n const cacheDir = getSessionCacheDir()\n const envLoadPath = path.join(cacheDir, ENV_LOAD_FILE)\n\n if (!fs.existsSync(envLoadPath)) {\n throw new Error('No loaded environment found. Run `env-load` first.')\n }\n\n const varNames = parseVarNamesFromEnvFile(envLoadPath)\n\n const unsetLines = [\n ...varNames.map((v) => {\n return `unset ${v}`\n }),\n `unset ${INFRA_KIT_ENV_CONFIG_VAR}`,\n `unset ${INFRA_KIT_ENV_PROJECT_VAR}`,\n `unset ${INFRA_KIT_ENV_LOADED_AT_VAR}`,\n ]\n\n const clearFilePath = path.resolve(cacheDir, ENV_CLEAR_FILE)\n\n fs.mkdirSync(cacheDir, { recursive: true, mode: 0o700 })\n\n atomicWriteFileSync(clearFilePath, `${unsetLines.join('\\n')}\\n`, 0o600)\n\n // REQUIRED\n process.stdout.write(`${clearFilePath}\\n`)\n\n // Remove env load file so the next env-clear call correctly reports \"no env loaded\".\n fs.unlinkSync(envLoadPath)\n\n const structuredContent = {\n filePath: clearFilePath,\n variableCount: varNames.length,\n unsetStatements: unsetLines,\n }\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(structuredContent, null, 2),\n },\n ],\n structuredContent,\n }\n}\n\n// MCP Tool Registration\nexport const envClearMcpTool = {\n name: 'env-clear',\n description:\n 'Generate a shell script that unsets every env var previously loaded by env-load for this session, plus the infra-kit session metadata vars. Does NOT mutate the calling process. When `infra-kit init` has installed the zsh shell integration, the user\\'s terminal auto-sources the unset script on its next prompt (precmd hook) \u2014 so calling this via MCP will clear the vars in the shell that launched Claude Code automatically. Other callers must source \"<filePath>\" themselves or surface it to the user. Errors if no env is currently loaded.',\n inputSchema: {},\n outputSchema: {\n filePath: z.string().describe('Path to the file that must be sourced to apply'),\n variableCount: z.number().describe('Number of variables cleared'),\n unsetStatements: z.array(z.string()).describe('Unset statements generated'),\n },\n handler: envClear,\n}\n", "import fs from 'node:fs'\nimport os from 'node:os'\nimport path from 'node:path'\nimport process from 'node:process'\n\nexport const ENV_LOAD_FILE = 'env-load.sh'\nexport const ENV_CLEAR_FILE = 'env-clear.sh'\n\nexport const INFRA_KIT_SESSION_VAR = 'INFRA_KIT_SESSION'\nexport const INFRA_KIT_ENV_CONFIG_VAR = 'INFRA_KIT_ENV_CONFIG'\nexport const INFRA_KIT_ENV_PROJECT_VAR = 'INFRA_KIT_ENV_PROJECT'\nexport const INFRA_KIT_ENV_LOADED_AT_VAR = 'INFRA_KIT_ENV_LOADED_AT'\n\n/**\n * Matches a line of the form `KEY=...` where KEY is an env-var identifier\n * (letter or underscore, then word chars). Capture group 1 is the name. Shared\n * between env-load (validation, var counting) and parseVarNamesFromEnvFile.\n */\nexport const ENV_VAR_LINE_PATTERN = /^([A-Z_]\\w*)=/i\n\nexport const parseVarNamesFromEnvFile = (filePath: string): string[] => {\n if (!fs.existsSync(filePath)) return []\n\n const content = fs.readFileSync(filePath, 'utf-8')\n const names: string[] = []\n\n for (const line of content.split('\\n')) {\n const match = ENV_VAR_LINE_PATTERN.exec(line)\n\n if (match) {\n names.push(match[1]!)\n }\n }\n\n return names\n}\n\n/**\n * Root cache dir for infra-kit across all sessions. Resolved from\n * $XDG_CACHE_HOME when set, falling back to ~/.cache/infra-kit. Keep in sync\n * with the shell block emitted by `infra-kit init` (src/commands/init/init.ts).\n */\nexport const getCacheRoot = (): string => {\n const xdg = process.env.XDG_CACHE_HOME\n const base = xdg && xdg.length > 0 ? xdg : path.join(os.homedir(), '.cache')\n\n return path.join(base, 'infra-kit')\n}\n\nexport const getSessionCacheDir = (): string => {\n const session = process.env[INFRA_KIT_SESSION_VAR]\n\n if (!session) {\n throw new Error(`${INFRA_KIT_SESSION_VAR} is not set. Run \\`infra-kit init\\` then \\`source ~/.zshrc\\`.`)\n }\n\n return path.join(getCacheRoot(), session)\n}\n\n/**\n * Write content atomically: write to a pid-suffixed temp file in the same\n * directory, then rename. fs.renameSync is atomic on a single filesystem, so\n * concurrent writers can't produce a half-written secret file.\n */\nexport const atomicWriteFileSync = (filePath: string, content: string, mode: number): void => {\n const tmpPath = `${filePath}.tmp.${process.pid}`\n\n fs.writeFileSync(tmpPath, content, { mode })\n\n try {\n fs.renameSync(tmpPath, filePath)\n } catch (error) {\n fs.rmSync(tmpPath, { force: true })\n throw error\n }\n}\n\nexport const WORKTREES_DIR_SUFFIX = '-worktrees'\n// eslint-disable-next-line sonarjs/publicly-writable-directories\nexport const LOG_FILE_PATH = '/tmp/mcp-infra-kit.log'\n", "import { z } from 'zod/v4'\n\nimport { getDopplerProject } from 'src/integrations/doppler/doppler-project'\nimport { getInfraKitConfig } from 'src/lib/infra-kit-config'\nimport { logger } from 'src/lib/logger'\nimport type { ToolsExecutionResult } from 'src/types'\n\n/**\n * List available Doppler configs for the detected project.\n *\n * Purely local: reads infra-kit.yml and does not call Doppler. We intentionally\n * do not run validateDopplerCliAndAuth here \u2014 users listing envs often do so\n * before `doppler login`, and a spurious auth error would be misleading.\n */\nexport const envList = async (): Promise<ToolsExecutionResult> => {\n const project = await getDopplerProject()\n const { environments } = await getInfraKitConfig()\n\n logger.info(`Doppler project: ${project}\\n`)\n logger.info('Available configs:')\n\n for (const env of environments) {\n logger.info(` - ${env}`)\n }\n\n const structuredContent = {\n project,\n configs: environments,\n }\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(structuredContent, null, 2),\n },\n ],\n structuredContent,\n }\n}\n\n// MCP Tool Registration\nexport const envListMcpTool = {\n name: 'env-list',\n description:\n 'List the environments the project is configured to support. Returns the `environments` list declared in infra-kit.yml at the project root (not a live fetch from Doppler) plus the Doppler project name resolved from the same file. Read-only.',\n inputSchema: {},\n outputSchema: {\n project: z.string().describe('Detected Doppler project name'),\n configs: z.array(z.string()).describe('Available environment configs'),\n },\n handler: envList,\n}\n", "import { getInfraKitConfig } from 'src/lib/infra-kit-config'\n\n/**\n * Resolve Doppler project name from infra-kit.yml at the project root\n */\nexport const getDopplerProject = async (): Promise<string> => {\n const { envManagement } = await getInfraKitConfig()\n\n return envManagement.config.name\n}\n", "import select from '@inquirer/select'\nimport { Buffer } from 'node:buffer'\nimport fs from 'node:fs'\nimport path from 'node:path'\nimport process from 'node:process'\nimport { z } from 'zod/v4'\nimport { $ } from 'zx'\n\nimport { validateDopplerCliAndAuth } from 'src/integrations/doppler'\nimport { getDopplerProject } from 'src/integrations/doppler/doppler-project'\nimport { commandEcho } from 'src/lib/command-echo'\nimport {\n ENV_LOAD_FILE,\n ENV_VAR_LINE_PATTERN,\n INFRA_KIT_ENV_CONFIG_VAR,\n INFRA_KIT_ENV_LOADED_AT_VAR,\n INFRA_KIT_ENV_PROJECT_VAR,\n atomicWriteFileSync,\n getSessionCacheDir,\n} from 'src/lib/constants'\nimport { getInfraKitConfig } from 'src/lib/infra-kit-config'\nimport type { ToolsExecutionResult } from 'src/types'\n\ninterface EnvLoadArgs {\n config?: string\n}\n\n/**\n * Load environment variables from Doppler for the given config\n */\nexport const envLoad = async (args: EnvLoadArgs): Promise<ToolsExecutionResult> => {\n await validateDopplerCliAndAuth()\n\n const { config } = args\n\n commandEcho.start('env-load')\n\n let selectedConfig = ''\n\n if (config) {\n selectedConfig = config\n } else {\n const { environments } = await getInfraKitConfig()\n\n commandEcho.setInteractive()\n selectedConfig = await select(\n {\n message: 'Select environment config',\n choices: environments.map((env) => {\n return { name: env, value: env }\n }),\n },\n // Render to stderr so the prompt is visible when stdout is captured via $() in the shell function.\n // Only env-load and env-clear use the $() stdout-capture shell pattern.\n { output: process.stderr },\n )\n }\n\n commandEcho.addOption('--config', selectedConfig)\n\n const project = await getDopplerProject()\n\n const envContent = await downloadDopplerSecrets(project, selectedConfig)\n\n assertValidEnvContent(envContent)\n\n // Build env file content in dotenv format\n const loadedAt = new Date().toISOString()\n const envFileLines = [\n 'set -a',\n envContent,\n `${INFRA_KIT_ENV_CONFIG_VAR}=${shellSingleQuote(selectedConfig)}`,\n `${INFRA_KIT_ENV_PROJECT_VAR}=${shellSingleQuote(project)}`,\n `${INFRA_KIT_ENV_LOADED_AT_VAR}=${shellSingleQuote(loadedAt)}`,\n 'set +a',\n ]\n\n const cacheDir = getSessionCacheDir()\n const envFilePath = path.resolve(cacheDir, ENV_LOAD_FILE)\n\n fs.mkdirSync(cacheDir, { recursive: true, mode: 0o700 })\n atomicWriteFileSync(envFilePath, `${envFileLines.join('\\n')}\\n`, 0o600)\n\n // REQUIRED\n process.stdout.write(`${envFilePath}\\n`)\n\n // Logs to stderr (pino \u2192 pretty-print), so it doesn't pollute the captured\n // file path that the shell wrapper reads from stdout.\n commandEcho.print()\n\n const varCount = countEnvVarLines(envContent)\n\n const structuredContent = {\n filePath: envFilePath,\n variableCount: varCount,\n project,\n config: selectedConfig,\n }\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(structuredContent, null, 2),\n },\n ],\n structuredContent,\n }\n}\n\n/**\n * Cap the Doppler stdout we're willing to accept. A well-formed env bundle is\n * O(10 KB); megabytes would indicate a service regression or the wrong stream\n * being captured, and we don't want to write that to disk or source it.\n */\nexport const DOPPLER_MAX_OUTPUT_BYTES = 1024 * 1024\n\n/**\n * Hard upper bound for the Doppler subprocess. Well under zx's default so a\n * hung call surfaces quickly instead of blocking an interactive shell or an\n * MCP tool handler.\n */\nconst DOPPLER_DOWNLOAD_TIMEOUT_MS = 30_000\n\nconst downloadDopplerSecrets = async (project: string, config: string): Promise<string> => {\n const prevQuiet = $.quiet\n\n $.quiet = true\n try {\n const result =\n await $`doppler secrets download --no-file --format env --project ${project} --config ${config}`.timeout(\n DOPPLER_DOWNLOAD_TIMEOUT_MS,\n )\n\n assertDopplerOutputSize(result.stdout)\n\n return result.stdout.trim()\n } finally {\n $.quiet = prevQuiet\n }\n}\n\nexport const assertDopplerOutputSize = (stdout: string): void => {\n const bytes = Buffer.byteLength(stdout, 'utf-8')\n\n if (bytes > DOPPLER_MAX_OUTPUT_BYTES) {\n throw new Error(\n `doppler returned unexpectedly large output (${bytes} bytes > ${DOPPLER_MAX_OUTPUT_BYTES}) \u2014 refusing to write to disk`,\n )\n }\n}\n\nconst countEnvVarLines = (content: string): number => {\n return content.split('\\n').filter((line) => {\n return ENV_VAR_LINE_PATTERN.test(line)\n }).length\n}\n\nconst SHELL_DIRECTIVE_LINES = new Set(['set -a', 'set +a'])\n\nexport const shellSingleQuote = (value: string): string => {\n const escaped = value.replaceAll(\"'\", \"'\\\\''\")\n\n return `'${escaped}'`\n}\n\n/**\n * Guard against Doppler returning non-env output (auth warnings on stdout,\n * partial downloads, HTML error pages, etc.). Every non-blank, non-directive\n * line must match KEY=VALUE \u2014 skipping directives keeps future format tweaks\n * cheap without loosening the check.\n */\nexport const assertValidEnvContent = (content: string): void => {\n if (content.trim().length === 0) {\n throw new Error('doppler returned empty output for env-load')\n }\n\n for (const line of content.split('\\n')) {\n const trimmed = line.trim()\n\n if (trimmed.length === 0 || SHELL_DIRECTIVE_LINES.has(trimmed)) continue\n\n if (!ENV_VAR_LINE_PATTERN.test(trimmed)) {\n throw new Error(\n `doppler returned unexpected output for env-load (expected KEY=value lines, got: ${JSON.stringify(trimmed.slice(0, 80))})`,\n )\n }\n }\n}\n\n// MCP Tool Registration\nexport const envLoadMcpTool = {\n name: 'env-load',\n description:\n 'Download the env vars for a Doppler config and write them to a temporary shell script. Does NOT mutate the calling process \u2014 returns the path to a script that must be sourced (\"source <filePath>\") for the vars to take effect. The infra-kit shell wrapper auto-sources; direct MCP callers must handle sourcing themselves or surface filePath to the user. \"config\" is required when invoked via MCP (the CLI interactive picker is unreachable without a TTY).',\n inputSchema: {\n config: z\n .string()\n .describe('Doppler config / environment name to load (e.g. \"dev\", \"arthur\", \"renana\"). Required for MCP calls.'),\n },\n outputSchema: {\n filePath: z.string().describe('Path to the file that must be sourced to apply variables'),\n variableCount: z.number().describe('Number of variables loaded'),\n project: z.string().describe('Doppler project name'),\n config: z.string().describe('Doppler config name'),\n },\n handler: envLoad,\n}\n", "import { $ } from 'zx'\n\n/**\n * Validate Doppler CLI installation and authentication status. Throws on failure\n * so callers (CLI entry, MCP tool handler) can translate to the right surface \u2014\n * CLI exits non-zero; MCP returns a structured tool error instead of tearing\n * down the server.\n */\nexport const validateDopplerCliAndAuth = async (): Promise<void> => {\n try {\n await $`doppler --version`\n } catch (error: unknown) {\n throw new Error('Doppler CLI is not installed. Install it from: https://docs.doppler.com/docs/install-cli', {\n cause: error,\n })\n }\n\n try {\n await $`doppler me`\n } catch (error: unknown) {\n throw new Error('Doppler CLI is not authenticated. Run: doppler login', { cause: error })\n }\n}\n", "import { logger } from 'src/lib/logger'\n\ninterface CommandOption {\n flag: string\n value: string | string[] | boolean\n}\n\nconst createCommandEcho = () => {\n let commandName = ''\n let options: CommandOption[] = []\n let isInteractive = false\n\n return {\n /**\n * Initialize command echo for a new command\n */\n start(name: string): void {\n commandName = name\n options = []\n isInteractive = false\n },\n\n /**\n * Mark that the command had interactive input (prompts)\n * Call this once when ANY prompt happens\n */\n setInteractive(): void {\n isInteractive = true\n },\n\n /**\n * Track an option selection\n * @param flag The CLI flag (e.g., \"--versions\")\n * @param value The selected value\n */\n addOption(flag: string, value: string | string[] | boolean): void {\n options.push({ flag, value })\n },\n\n /**\n * Print the equivalent CLI command if there was interactive input\n */\n print(): void {\n if (!isInteractive || options.length === 0) {\n return\n }\n\n const formattedOptions = options\n .map((opt) => {\n if (typeof opt.value === 'boolean') {\n return opt.value ? opt.flag : ''\n }\n\n if (Array.isArray(opt.value)) {\n return `${opt.flag} \"${opt.value.join(', ')}\"`\n }\n\n return `${opt.flag} \"${opt.value}\"`\n })\n .filter(Boolean)\n .join(' ')\n\n logger.info(`\uD83D\uDCDF Equivalent command: \\npnpm exec infra-kit ${commandName} ${formattedOptions}\\n`)\n },\n\n /**\n * Reset state (useful for testing)\n */\n reset(): void {\n commandName = ''\n options = []\n isInteractive = false\n },\n }\n}\n\n// Singleton instance (same pattern as logger)\nexport const commandEcho = createCommandEcho()\n", "import path from 'node:path'\nimport process from 'node:process'\nimport { z } from 'zod/v4'\n\nimport { validateDopplerCliAndAuth } from 'src/integrations/doppler'\nimport {\n ENV_LOAD_FILE,\n INFRA_KIT_ENV_CONFIG_VAR,\n INFRA_KIT_ENV_LOADED_AT_VAR,\n INFRA_KIT_ENV_PROJECT_VAR,\n INFRA_KIT_SESSION_VAR,\n getSessionCacheDir,\n parseVarNamesFromEnvFile,\n} from 'src/lib/constants'\nimport { logger } from 'src/lib/logger'\nimport type { ToolsExecutionResult } from 'src/types'\n\n/**\n * Show Doppler authentication status and detected project info\n */\nexport const envStatus = async (): Promise<ToolsExecutionResult> => {\n await validateDopplerCliAndAuth()\n\n logger.info('Environment session status:')\n\n // Check session-loaded vars \u2014 getSessionCacheDir() throws if INFRA_KIT_SESSION is unset\n const cacheDir = getSessionCacheDir()\n\n const sessionId = process.env[INFRA_KIT_SESSION_VAR]!\n const envLoadPath = path.join(cacheDir, ENV_LOAD_FILE)\n\n let sessionLoadedCount = 0\n let sessionTotalCount = 0\n\n const sessionConfig = process.env[INFRA_KIT_ENV_CONFIG_VAR] ?? null\n const sessionProject = process.env[INFRA_KIT_ENV_PROJECT_VAR] ?? null\n const sessionLoadedAt = process.env[INFRA_KIT_ENV_LOADED_AT_VAR] ?? null\n\n if (sessionConfig) {\n const varNames = parseVarNamesFromEnvFile(envLoadPath)\n\n if (varNames.length > 0) {\n sessionTotalCount = varNames.length\n sessionLoadedCount = varNames.filter((v) => {\n return v in process.env\n }).length\n }\n\n const loadedAtDisplay = sessionLoadedAt?.replace(/\\.\\d{3}Z$/, '') ?? null\n\n logger.info(\n ` ${sessionConfig}: ${sessionLoadedCount} of ${sessionTotalCount} vars loaded (project: ${sessionProject}, loadedAt: ${loadedAtDisplay}, session: ${sessionId})\\n`,\n )\n\n if (sessionTotalCount > 0 && sessionLoadedCount < sessionTotalCount) {\n const missing = sessionTotalCount - sessionLoadedCount\n\n logger.warn(\n ` ${missing} cached var(s) are not present in the current process \u2014 env-load needs to be re-sourced, or vars were unset manually.`,\n )\n }\n } else {\n logger.info(` Session ${sessionId}: no env loaded\\n`)\n }\n\n const structuredContent = {\n sessionId,\n sessionLoadedCount,\n sessionTotalCount,\n sessionConfig,\n sessionProject,\n sessionLoadedAt,\n }\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(structuredContent, null, 2),\n },\n ],\n structuredContent,\n }\n}\n\n// MCP Tool Registration\nexport const envStatusMcpTool = {\n name: 'env-status',\n description:\n 'Report which Doppler project/config is currently loaded in the terminal session, when it was loaded, and how many variables are cached. Read-only \u2014 use env-load / env-clear to change the terminal session.',\n inputSchema: {},\n outputSchema: {\n sessionId: z.string().describe('Current terminal session ID'),\n sessionLoadedCount: z.number().describe('Number of cached vars active in the current session'),\n sessionTotalCount: z.number().describe('Total number of cached var names'),\n sessionConfig: z.string().nullable().describe('Doppler config name of the loaded session (environment name)'),\n sessionProject: z.string().nullable().describe('Doppler project name of the loaded session'),\n sessionLoadedAt: z.string().nullable().describe('ISO 8601 timestamp of when the env was loaded'),\n },\n handler: envStatus,\n}\n", "/* eslint-disable sonarjs/cognitive-complexity */\nimport checkbox from '@inquirer/checkbox'\nimport confirm from '@inquirer/confirm'\nimport process from 'node:process'\nimport { z } from 'zod/v4'\nimport { $ } from 'zx'\n\nimport { getReleasePRsWithInfo } from 'src/integrations/gh'\nimport { commandEcho } from 'src/lib/command-echo'\nimport { logger } from 'src/lib/logger'\nimport { detectReleaseType, formatBranchChoices, getJiraDescriptions } from 'src/lib/release-utils'\nimport type { RequiredConfirmedOptionArg, ToolsExecutionResult } from 'src/types'\n\ninterface GhMergeDevArgs extends RequiredConfirmedOptionArg {\n all: boolean\n}\n\n/**\n * Merge dev into every release branch\n */\nexport const ghMergeDev = async (args: GhMergeDevArgs): Promise<ToolsExecutionResult> => {\n const { all, confirmedCommand } = args\n\n commandEcho.start('merge-dev')\n\n // Only merge dev into regular releases (not hotfixes, which target main)\n const allPRs = await getReleasePRsWithInfo()\n const releasePRsList = allPRs\n .filter((pr) => {\n return detectReleaseType(pr.title) === 'regular'\n })\n .map((pr) => {\n return pr.branch\n })\n\n if (releasePRsList.length === 0) {\n logger.info('\u2139\uFE0F No open release branches found')\n\n commandEcho.print()\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify({ successfulMerges: 0, failedMerges: 0, failedBranches: [], totalBranches: 0 }, null, 2),\n },\n ],\n structuredContent: { successfulMerges: 0, failedMerges: 0, failedBranches: [], totalBranches: 0 },\n }\n }\n\n let selectedReleaseBranches: string[] = []\n\n if (all) {\n selectedReleaseBranches = releasePRsList\n } else {\n commandEcho.setInteractive()\n\n const descriptions = await getJiraDescriptions()\n\n selectedReleaseBranches = await checkbox({\n required: true,\n message: '\uD83C\uDF3F Select release branches',\n choices: formatBranchChoices({ branches: releasePRsList, descriptions }),\n })\n }\n\n // Track --all flag if all branches were selected (either via flag or interactively)\n const allSelected = selectedReleaseBranches.length === releasePRsList.length\n\n if (allSelected) {\n commandEcho.addOption('--all', true)\n } else {\n commandEcho.addOption(\n '--versions',\n selectedReleaseBranches.map((branch) => {\n return branch.replace('release/v', '')\n }),\n )\n }\n\n // Validate input\n // if (selectedReleaseBranches.length === 0) {\n // console.error('No branches provided. Exiting...')\n // process.exit(1)\n // }\n\n const answer = confirmedCommand\n ? true\n : await confirm({\n message: `Are you sure you want to merge dev into these branches: ${selectedReleaseBranches.join(', ')}?`,\n })\n\n if (!confirmedCommand) {\n commandEcho.setInteractive()\n }\n\n if (!answer) {\n logger.info('Operation cancelled. Exiting...')\n process.exit(0)\n }\n\n // Track --yes flag if confirmation was interactive (user confirmed)\n if (!confirmedCommand) {\n commandEcho.addOption('--yes', true)\n }\n\n $.quiet = true\n\n await $`git fetch origin`\n await $`git switch dev`\n await $`git pull origin dev`\n\n const failedBranches: string[] = []\n\n // Merge dev into each branch\n for (const branch of selectedReleaseBranches) {\n const success = await mergeDev(branch)\n\n if (!success) {\n failedBranches.push(branch)\n }\n }\n\n $.quiet = false\n\n if (failedBranches.length > 0) {\n logger.info(`\\n\u26A0\uFE0F ${failedBranches.length} branch(es) failed to merge automatically.\\n`)\n logger.info('\uD83D\uDCCB Manual merge script for failed branches:')\n for (const branch of failedBranches) {\n logger.info(\n `# 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`,\n )\n }\n logger.info(\n `\u2705 ${selectedReleaseBranches.length - failedBranches.length}/${selectedReleaseBranches.length} merges completed successfully.`,\n )\n } else {\n logger.info('\u2705 All merges completed successfully!\\n')\n }\n\n commandEcho.print()\n\n const structuredContent = {\n successfulMerges: selectedReleaseBranches.length - failedBranches.length,\n failedMerges: failedBranches.length,\n failedBranches,\n totalBranches: selectedReleaseBranches.length,\n }\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(structuredContent, null, 2),\n },\n ],\n structuredContent,\n }\n}\n\nconst mergeDev = async (branch: string): Promise<boolean> => {\n try {\n await $`git switch ${branch}`\n\n await $`git pull origin ${branch}`\n\n await $`git merge origin/dev --no-edit`\n\n await $`git push origin ${branch}`\n\n await $`git switch dev`\n\n logger.info(`Successfully merged dev into ${branch}`)\n\n return true\n } catch (error: unknown) {\n logger.error({ error, branch }, `Error merging dev into ${branch}`)\n\n await $`git reset --merge HEAD~1`\n\n return false\n }\n}\n\n// MCP Tool Registration\nexport const ghMergeDevMcpTool = {\n name: 'gh-merge-dev',\n description:\n 'Merge origin/dev into every open regular (non-hotfix) release branch and push the result. Mutates local git state and the remote release branches. When invoked via MCP, pass all=true \u2014 the branch picker is unreachable without a TTY, and the confirmation prompt is auto-skipped for MCP calls, so the caller is responsible for gating. Irreversible once pushed.',\n inputSchema: {\n all: z\n .boolean()\n .optional()\n .describe(\n 'Target every open regular release branch. Must be true for MCP calls (the interactive picker is unavailable without a TTY).',\n ),\n },\n outputSchema: {\n successfulMerges: z.number().describe('Number of successful merges'),\n failedMerges: z.number().describe('Number of failed merges'),\n failedBranches: z.array(z.string()).describe('List of branches that failed to merge'),\n totalBranches: z.number().describe('Total number of branches processed'),\n },\n handler: ghMergeDev,\n}\n", "import process from 'node:process'\nimport { $ } from 'zx'\n\nimport { logger } from 'src/lib/logger'\n\n/**\n * Validate GitHub CLI installation and authentication status and throw an error if not valid\n */\nexport const validateGitHubCliAndAuth = async () => {\n try {\n await $`gh --version`\n } catch (error: unknown) {\n logger.error({ error }, 'Error: GitHub CLI (gh) is not installed.')\n logger.error('Please install it from: https://cli.github.com/')\n process.exit(1)\n }\n\n try {\n await $`gh auth status`\n } catch (error: unknown) {\n logger.error({ error }, 'Error: GitHub CLI (gh) is not authenticated.')\n logger.error('Please authenticate it from: https://cli.github.com/manual/gh_auth_login or type \"gh auth login\"')\n process.exit(1)\n }\n}\n", "import process from 'node:process'\nimport { $ } from 'zx'\n\nimport { logger } from 'src/lib/logger'\nimport { getBaseBranch } from 'src/lib/release-utils'\nimport type { ReleaseType } from 'src/lib/release-utils'\nimport { sortVersions } from 'src/lib/version-utils'\n\ninterface ReleasePR {\n headRefName: string\n number: number\n state: string\n title: string\n baseRefName: string\n}\n\nexport interface ReleasePRInfo {\n branch: string\n title: string\n}\n\n/**\n * Fetch all open release/hotfix PRs from GitHub.\n * Searches both dev (regular) and main (hotfix) base branches.\n * Returns deduplicated ReleasePR objects.\n */\nconst fetchAllReleasePRs = async (): Promise<ReleasePR[]> => {\n const releasePRs =\n await $`gh pr list --search \"Release in:title\" --base dev --json number,title,headRefName,state,baseRefName`\n\n const hotfixPRs =\n await $`gh pr list --search \"Hotfix in:title\" --base main --json number,title,headRefName,state,baseRefName`\n\n const all: ReleasePR[] = [...JSON.parse(releasePRs.stdout), ...JSON.parse(hotfixPRs.stdout)]\n\n // Deduplicate by headRefName\n const seen = new Set<string>()\n\n return all.filter((pr) => {\n if (seen.has(pr.headRefName)) return false\n\n seen.add(pr.headRefName)\n\n return true\n })\n}\n\n/**\n * Fetch open release PRs from GitHub with 'Release' or 'Hotfix' in the title and base 'dev'.\n * Returns an array of headRefName strings sorted by semver in ascending order.\n *\n * @returns [release/v1.18.22, release/v1.18.23, release/v1.18.24] (sorted by semver)\n */\nexport const getReleasePRs = async (): Promise<string[]> => {\n try {\n const prs = await fetchAllReleasePRs()\n\n if (prs.length === 0) {\n logger.error('\u274C No release PRs found. Check the project folder for the script. Exiting...')\n\n process.exit(1)\n }\n\n return sortVersions(\n prs.map((pr) => {\n return pr.headRefName\n }),\n )\n } catch (error) {\n logger.error({ error }, '\u274C Error fetching release PRs')\n\n process.exit(1)\n }\n}\n\n/**\n * Fetch open release PRs with title info (for detecting release type).\n * Returns ReleasePRInfo objects sorted by semver.\n */\nexport const getReleasePRsWithInfo = async (): Promise<ReleasePRInfo[]> => {\n try {\n const prs = await fetchAllReleasePRs()\n\n if (prs.length === 0) {\n logger.error('\u274C No release PRs found. Check the project folder for the script. Exiting...')\n process.exit(1)\n }\n\n const sortedBranches = sortVersions(\n prs.map((pr) => {\n return pr.headRefName\n }),\n )\n const prByBranch = new Map(\n prs.map((pr) => {\n return [pr.headRefName, pr]\n }),\n )\n\n return sortedBranches.map((branch) => {\n return {\n branch,\n title: prByBranch.get(branch)!.title,\n }\n })\n } catch (error) {\n logger.error({ error }, '\u274C Error fetching release PRs')\n process.exit(1)\n }\n}\n\ninterface CreateReleaseBranchArgs {\n version: string\n jiraVersionUrl: string\n type: ReleaseType\n description?: string\n}\n\n// Function to create a release branch\nexport const createReleaseBranch = async (\n args: CreateReleaseBranchArgs,\n): Promise<{ branchName: string; prUrl: string }> => {\n const { version, jiraVersionUrl, type, description } = args\n const titlePrefix = type === 'hotfix' ? 'Hotfix' : 'Release'\n const baseBranch = getBaseBranch(type)\n\n const branchName = `release/v${version}`\n\n const body = description && description.trim() !== '' ? `${jiraVersionUrl}\\n\\n${description}` : `${jiraVersionUrl} \\n`\n\n try {\n $.quiet = true\n\n await $`git switch ${baseBranch}`\n await $`git pull origin ${baseBranch}`\n await $`git checkout -b ${branchName}`\n await $`git push -u origin ${branchName}`\n await $`git commit --allow-empty-message --allow-empty --message ''`\n await $`git push origin ${branchName}`\n\n // Create PR and capture URL\n const prResult =\n await $`gh pr create --title \"${titlePrefix} v${version}\" --body ${body} --base ${baseBranch} --head ${branchName}`\n\n const prLink = prResult.stdout.trim()\n\n await $`git switch ${baseBranch}`\n\n $.quiet = false\n\n return {\n branchName,\n prUrl: prLink,\n }\n } catch (error: unknown) {\n logger.error({ error, branchName }, `Error creating release branch ${branchName}`)\n\n throw error\n }\n}\n", "import { $ } from 'zx'\n\nimport { createReleaseBranch } from 'src/integrations/gh'\nimport { createJiraVersion, getProjectVersions, loadJiraConfigOptional } from 'src/integrations/jira'\nimport type { JiraConfig } from 'src/integrations/jira'\n\nexport type ReleaseType = 'regular' | 'hotfix'\n\n/**\n * Get the base branch for a release type.\n * Regular releases branch from/to dev, hotfixes branch from/to main.\n */\nexport const getBaseBranch = (type: ReleaseType): string => {\n return type === 'hotfix' ? 'main' : 'dev'\n}\n\nexport interface ReleaseCreationResult {\n version: string\n type: ReleaseType\n branchName: string\n prUrl: string\n jiraVersionUrl: string\n}\n\n/**\n * Prepare git repository for release creation\n * Fetches latest changes, switches to base branch, and pulls latest\n */\nexport const prepareGitForRelease = async (type: ReleaseType = 'regular'): Promise<void> => {\n const baseBranch = getBaseBranch(type)\n\n $.quiet = true\n\n await $`git fetch origin`\n await $`git switch ${baseBranch}`\n await $`git pull origin ${baseBranch}`\n\n $.quiet = false\n}\n\ninterface CreateSingleReleaseArgs {\n version: string\n jiraConfig: JiraConfig\n description?: string\n type?: ReleaseType\n}\n\n/**\n * Create a single release by creating both Jira version and GitHub release branch\n */\nexport const createSingleRelease = async (args: CreateSingleReleaseArgs): Promise<ReleaseCreationResult> => {\n const { version, jiraConfig, description, type = 'regular' } = args\n // 1. Create Jira version (mandatory)\n const versionName = `v${version}`\n\n const result = await createJiraVersion(\n {\n name: versionName,\n projectId: jiraConfig.projectId,\n description: description || '',\n released: false,\n archived: false,\n },\n jiraConfig,\n )\n\n // Construct user-friendly Jira URL using project key from API response\n const jiraVersionUrl = `${jiraConfig.baseUrl}/projects/${result.version!.projectId}/versions/${result.version!.id}/tab/release-report-all-issues`\n\n // 2. Create GitHub release branch\n const releaseInfo = await createReleaseBranch({ version, jiraVersionUrl, type, description })\n\n return {\n version,\n type,\n branchName: releaseInfo.branchName,\n prUrl: releaseInfo.prUrl,\n jiraVersionUrl,\n }\n}\n\n/**\n * Fetch Jira version descriptions mapped by version name (e.g., \"v1.2.5\" \u2192 \"Some description\")\n * Gracefully returns empty map if Jira is unavailable\n */\nexport const getJiraDescriptions = async (): Promise<Map<string, string>> => {\n const descriptions = new Map<string, string>()\n\n const jiraConfig = await loadJiraConfigOptional()\n\n if (!jiraConfig) return descriptions\n\n try {\n const versions = await getProjectVersions(jiraConfig)\n\n for (const version of versions) {\n if (version.description) {\n descriptions.set(version.name, version.description)\n }\n }\n } catch {\n // Jira fetch failed, continue without descriptions\n }\n\n return descriptions\n}\n\n/**\n * Format a version string with its release type tag, e.g. \"1.2.5 [regular]\"\n * When maxVersionLength is provided, pads the version for alignment.\n */\nexport const formatVersionLabel = (version: string, type: ReleaseType, maxVersionLength?: number): string => {\n const padding = maxVersionLength ? ' '.repeat(maxVersionLength - version.length + 3) : ' '\n const tag = `[${type}]`.padEnd(11)\n\n return `${version}${padding}${tag}`\n}\n\n/**\n * Detect release type from PR title.\n * PRs titled \"Hotfix v...\" are hotfix, everything else is regular.\n */\nexport const detectReleaseType = (title: string): ReleaseType => {\n return title.toLowerCase().startsWith('hotfix') ? 'hotfix' : 'regular'\n}\n\ninterface FormatBranchChoicesArgs {\n branches: string[]\n descriptions: Map<string, string>\n types?: Map<string, ReleaseType>\n}\n\n/**\n * Format release branch names as checkbox choices with aligned type tags and Jira descriptions\n */\nexport const formatBranchChoices = (args: FormatBranchChoicesArgs): { name: string; value: string }[] => {\n const { branches, descriptions, types } = args\n\n const versionNames = branches.map((b) => {\n return b.replace('release/v', '')\n })\n\n const maxLen = Math.max(\n ...versionNames.map((v) => {\n return v.length\n }),\n )\n\n return branches.map((branch, i) => {\n const version = versionNames[i] as string\n const type = types ? types.get(branch) || 'regular' : undefined\n const desc = descriptions.get(`v${version}`)\n const padding = ' '.repeat(maxLen - version.length + 3)\n\n let name = type ? formatVersionLabel(version, type, maxLen) : version\n\n if (desc) {\n name = type ? `${name} ${desc}` : `${version}${padding}${desc}`\n }\n\n return { name, value: branch }\n })\n}\n", "import process from 'node:process'\n\nimport { logger } from 'src/lib/logger'\n\nimport type {\n CreateJiraVersionParams,\n CreateJiraVersionResult,\n DeliverJiraReleaseParams,\n DeliverJiraReleaseResult,\n JiraConfig,\n JiraVersion,\n UpdateJiraVersionParams,\n UpdateJiraVersionResult,\n} from './types.js'\n\n/**\n * Creates a new version in Jira using the REST API\n * @param params - Version creation parameters\n * @param config - Jira configuration (baseUrl, token, projectId)\n * @returns Result containing created version or error\n */\nexport const createJiraVersion = async (\n params: CreateJiraVersionParams,\n config: JiraConfig,\n): Promise<CreateJiraVersionResult> => {\n try {\n const { baseUrl, token, email, projectId } = config\n\n // Use current date if not provided\n // const releaseDate =\n // params.releaseDate || new Date().toISOString().split('T')[0] // 2025-12-06\n\n // Prepare request body\n const requestBody = {\n name: params.name,\n projectId: params.projectId || projectId,\n description: params.description || '',\n // releaseDate,\n released: params.released || false,\n archived: params.archived || false,\n }\n\n // logger.info(\n // { version: params.name, projectId: requestBody.projectId },\n // 'Creating Jira version',\n // )\n\n // Make API request\n const url = `${baseUrl}/rest/api/3/version`\n\n // Create Basic auth credentials\n const credentials = btoa(`${email}:${token}`)\n\n const response = await fetch(url, {\n method: 'POST',\n headers: {\n Accept: 'application/json',\n 'Content-Type': 'application/json',\n Authorization: `Basic ${credentials}`,\n },\n body: JSON.stringify(requestBody),\n })\n\n if (!response.ok) {\n const errorText = await response.text()\n\n logger.error(\n {\n status: response.status,\n statusText: response.statusText,\n error: errorText,\n },\n 'Failed to create Jira version',\n )\n\n throw new Error(`HTTP ${response.status}: ${response.statusText}`)\n }\n\n const version = (await response.json()) as JiraVersion\n\n // logger.info(\n // { versionId: version.id, versionName: version.name },\n // 'Successfully created Jira version',\n // )\n\n return {\n success: true,\n version,\n }\n } catch (error) {\n logger.error({ error }, 'Error creating Jira version')\n\n throw error\n }\n}\n\n/**\n * Gets all versions for a project from Jira\n * @param config - Jira configuration\n * @returns Array of JiraVersion objects\n */\nexport const getProjectVersions = async (config: JiraConfig): Promise<JiraVersion[]> => {\n try {\n const { baseUrl, token, email, projectId } = config\n\n const url = `${baseUrl}/rest/api/3/project/${projectId}/versions`\n const credentials = btoa(`${email}:${token}`)\n\n const response = await fetch(url, {\n method: 'GET',\n headers: {\n Accept: 'application/json',\n Authorization: `Basic ${credentials}`,\n },\n })\n\n if (!response.ok) {\n const errorText = await response.text()\n\n logger.error(\n {\n status: response.status,\n statusText: response.statusText,\n error: errorText,\n },\n 'Failed to get Jira project versions',\n )\n\n throw new Error(`HTTP ${response.status}: ${response.statusText}`)\n }\n\n const versions = (await response.json()) as JiraVersion[]\n\n return versions\n } catch (error) {\n logger.error({ error }, 'Error getting Jira project versions')\n\n throw error\n }\n}\n\n/**\n * Finds a Jira version by name in the project\n * @param versionName - Name of the version to find (e.g., \"v1.33.10\")\n * @param config - Jira configuration\n * @returns JiraVersion if found, null otherwise\n */\nconst findVersionByName = async (versionName: string, config: JiraConfig): Promise<JiraVersion | null> => {\n try {\n const versions = await getProjectVersions(config)\n const version = versions.find((v) => {\n return v.name === versionName\n })\n\n return version || null\n } catch (error) {\n logger.error({ error, versionName }, 'Error finding Jira version by name')\n\n throw error\n }\n}\n\n/**\n * Updates an existing Jira version\n * @param params - Update parameters\n * @param config - Jira configuration\n * @returns Result containing updated version or error\n */\nconst updateJiraVersion = async (\n params: UpdateJiraVersionParams,\n config: JiraConfig,\n): Promise<UpdateJiraVersionResult> => {\n try {\n const { baseUrl, token, email } = config\n\n // Prepare request body - only include fields that are provided\n const requestBody: Record<string, any> = {\n released: params.released ?? true,\n archived: params.archived ?? false,\n }\n\n // Add releaseDate if provided, otherwise use current date when releasing\n if (params.releaseDate) {\n requestBody.releaseDate = params.releaseDate\n } else if (params.released !== false) {\n requestBody.releaseDate = new Date().toISOString().split('T')[0] // YYYY-MM-DD\n }\n\n if (params.description !== undefined) {\n requestBody.description = params.description\n }\n\n const url = `${baseUrl}/rest/api/3/version/${params.versionId}`\n const credentials = btoa(`${email}:${token}`)\n\n const response = await fetch(url, {\n method: 'PUT',\n headers: {\n Accept: 'application/json',\n 'Content-Type': 'application/json',\n Authorization: `Basic ${credentials}`,\n },\n body: JSON.stringify(requestBody),\n })\n\n if (!response.ok) {\n const errorText = await response.text()\n\n logger.error(\n {\n status: response.status,\n statusText: response.statusText,\n error: errorText,\n },\n 'Failed to update Jira version',\n )\n\n throw new Error(`HTTP ${response.status}: ${response.statusText}`)\n }\n\n const version = (await response.json()) as JiraVersion\n\n return {\n success: true,\n version,\n }\n } catch (error) {\n logger.error({ error }, 'Error updating Jira version')\n\n throw error\n }\n}\n\n/**\n * Delivers a Jira release by marking it as released with the current date\n * @param params - Parameters containing the version name\n * @param config - Jira configuration\n * @returns Result containing updated version\n * @throws Error if version not found or update fails\n */\nexport const deliverJiraRelease = async (\n params: DeliverJiraReleaseParams,\n config: JiraConfig,\n): Promise<DeliverJiraReleaseResult> => {\n try {\n const { versionName } = params\n\n // Find the version by name\n const version = await findVersionByName(versionName, config)\n\n if (!version) {\n logger.error({ versionName }, 'Jira version not found')\n throw new Error(`Version \"${versionName}\" not found in Jira project`)\n }\n\n // Update the version to mark it as released\n const result = await updateJiraVersion(\n {\n versionId: version.id,\n released: true,\n releaseDate: new Date().toISOString().split('T')[0], // Current date in YYYY-MM-DD format\n },\n config,\n )\n\n return result\n } catch (error) {\n logger.error({ error }, 'Error delivering Jira release')\n throw error\n }\n}\n\n/**\n * Loads Jira configuration from environment variables\n * @throws Error with detailed message if configuration is missing or invalid\n * @returns Promise<JiraConfig>\n */\nexport const loadJiraConfig = async (): Promise<JiraConfig> => {\n const baseUrl = process.env.JIRA_BASE_URL\n const token = process.env.JIRA_TOKEN || process.env.JIRA_API_TOKEN\n const projectIdStr = process.env.JIRA_PROJECT_ID\n const email = process.env.JIRA_EMAIL\n\n const missingVars: string[] = []\n\n if (!baseUrl) missingVars.push('JIRA_BASE_URL (e.g., https://your-domain.atlassian.net)')\n if (!token) missingVars.push('JIRA_TOKEN or JIRA_API_TOKEN (your Jira API token)')\n if (!projectIdStr) missingVars.push('JIRA_PROJECT_ID (numeric project ID)')\n if (!email) missingVars.push('JIRA_EMAIL (your Jira email address)')\n\n if (missingVars.length > 0) {\n const errorMessage = [\n 'Jira configuration is required but incomplete.',\n 'Please configure the following environment variables:',\n ...missingVars.map((v) => {\n return ` - ${v}`\n }),\n '',\n 'You can set these in your .env file or as environment variables.',\n ].join('\\n')\n\n throw new Error(errorMessage)\n }\n\n const projectId = Number.parseInt(projectIdStr!, 10)\n\n if (Number.isNaN(projectId)) {\n throw new TypeError(`Invalid JIRA_PROJECT_ID: \"${projectIdStr}\" must be a numeric value (e.g., 10001)`)\n }\n\n return {\n baseUrl: baseUrl!.replace(/\\/$/, ''), // Remove trailing slash\n token: token!,\n projectId,\n email: email!,\n }\n}\n\n/**\n * Attempts to load Jira configuration from environment variables\n * Returns null if configuration is missing or invalid (for optional Jira integration)\n * @returns Promise<JiraConfig | null>\n */\nexport const loadJiraConfigOptional = async (): Promise<JiraConfig | null> => {\n try {\n const config = await loadJiraConfig()\n\n return config\n } catch (error) {\n logger.warn({ error }, 'Jira configuration not available, skipping Jira integration')\n\n return null\n }\n}\n", "/**\n * Parse version string into major, minor, patch numbers\n */\nexport const parseVersion = (versionStr: string): [number, number, number] => {\n return versionStr.replace('release/', '').slice(1).split('.').map(Number) as [number, number, number]\n}\n\n/**\n * Sort version strings in ascending order\n * Note: Returns a new sorted array without mutating the original\n */\nexport const sortVersions = (versions: string[]): string[] => {\n return [...versions].sort((a, b) => {\n const [majA, minA, patchA] = parseVersion(a)\n const [majB, minB, patchB] = parseVersion(b)\n\n if (majA !== majB) return (majA ?? 0) - (majB ?? 0)\n if (minA !== minB) return (minA ?? 0) - (minB ?? 0)\n\n return (patchA ?? 0) - (patchB ?? 0)\n })\n}\n", "import confirm from '@inquirer/confirm'\nimport select from '@inquirer/select'\nimport process from 'node:process'\nimport { z } from 'zod/v4'\nimport { $ } from 'zx'\n\nimport { getReleasePRsWithInfo } from 'src/integrations/gh'\nimport { deliverJiraRelease, loadJiraConfigOptional } from 'src/integrations/jira'\nimport { commandEcho } from 'src/lib/command-echo'\nimport { logger } from 'src/lib/logger'\nimport { detectReleaseType, formatBranchChoices, getJiraDescriptions } from 'src/lib/release-utils'\nimport type { ReleaseType } from 'src/lib/release-utils'\nimport type { RequiredConfirmedOptionArg, ToolsExecutionResult } from 'src/types'\n\ninterface GhReleaseDeliverArgs extends RequiredConfirmedOptionArg {\n version: string\n}\n\n/**\n * Deliver a release branch to production\n */\nexport const ghReleaseDeliver = async (args: GhReleaseDeliverArgs): Promise<ToolsExecutionResult> => {\n const { version, confirmedCommand } = args\n\n commandEcho.start('release-deliver')\n\n const releasePRsInfo = await getReleasePRsWithInfo()\n\n const branches = releasePRsInfo.map((pr) => {\n return pr.branch\n })\n\n const releaseTypes = new Map<string, ReleaseType>(\n releasePRsInfo.map((pr) => {\n return [pr.branch, detectReleaseType(pr.title)]\n }),\n )\n\n let selectedReleaseBranch = '' // \"release/v1.8.0\"\n\n if (version) {\n selectedReleaseBranch = `release/v${version}`\n } else {\n commandEcho.setInteractive()\n\n const descriptions = await getJiraDescriptions()\n\n selectedReleaseBranch = await select({\n message: '\uD83C\uDF3F Select release branch',\n choices: formatBranchChoices({ branches, descriptions, types: releaseTypes }),\n })\n }\n\n const selectedVersion = selectedReleaseBranch.replace('release/v', '')\n\n commandEcho.addOption('--version', selectedVersion)\n\n // Check if release branch exists in the list\n const prInfo = releasePRsInfo.find((pr) => {\n return pr.branch === selectedReleaseBranch\n })\n\n if (!prInfo) {\n logger.error(`\u274C Release branch ${selectedReleaseBranch} not found in open PRs. Exiting...`)\n process.exit(1)\n }\n\n const releaseType: ReleaseType = detectReleaseType(prInfo.title)\n\n const answer = confirmedCommand\n ? true\n : await confirm({\n message: `Are you sure you want to deliver version ${selectedReleaseBranch} to production?`,\n })\n\n if (!confirmedCommand) {\n commandEcho.setInteractive()\n }\n\n if (!answer) {\n logger.info('Operation cancelled. Exiting...')\n process.exit(0)\n }\n\n // Track --yes flag if confirmation was interactive (user confirmed)\n commandEcho.addOption('--yes', true)\n\n try {\n $.quiet = true\n\n if (releaseType === 'hotfix') {\n // Hotfix: merge directly into main, deploy, sync back to dev\n await $`gh pr merge ${selectedReleaseBranch} --squash --admin --delete-branch`\n\n $.quiet = false\n\n await $`gh workflow run deploy-all.yml --ref main -f environment=prod`\n\n $.quiet = true\n\n // Sync main into dev\n await $`git switch main && git pull && git switch dev && git pull && git merge main --no-edit && git push`\n } else {\n // Regular: merge into dev, create RC PR to main, merge to main, deploy, sync\n await $`gh pr merge ${selectedReleaseBranch} --squash --admin --delete-branch`\n await $`gh pr create --base main --head dev --title \"Release v${selectedVersion} (RC)\" --body \"\"`\n await $`gh pr merge dev --squash --admin`\n\n $.quiet = false\n\n await $`gh workflow run deploy-all.yml --ref main -f environment=prod`\n\n $.quiet = true\n\n // Sync main into dev\n await $`git switch main && git pull && git switch dev && git pull && git merge main --no-edit && git push`\n }\n\n $.quiet = false\n\n // Deliver Jira release if Jira is configured\n const jiraConfig = await loadJiraConfigOptional()\n\n if (jiraConfig) {\n try {\n const versionName = selectedReleaseBranch.replace('release/', '')\n\n await deliverJiraRelease({ versionName }, jiraConfig)\n } catch (error) {\n logger.error({ error }, 'Failed to deliver Jira release (non-blocking)')\n }\n } else {\n logger.info('\uD83D\uDD14 Jira is not configured, skipping Jira release delivery')\n }\n\n logger.info(`Successfully delivered ${selectedReleaseBranch} to production!`)\n\n commandEcho.print()\n\n const structuredContent = {\n releaseBranch: selectedReleaseBranch,\n version: selectedReleaseBranch.replace('release/v', ''),\n type: releaseType,\n success: true,\n }\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(structuredContent, null, 2),\n },\n ],\n structuredContent,\n }\n } catch (error: unknown) {\n logger.error({ error }, '\u274C Error merging release branch into dev')\n process.exit(1)\n }\n}\n\n// MCP Tool Registration\nexport const ghReleaseDeliverMcpTool = {\n name: 'gh-release-deliver',\n description:\n 'Deliver a release to production. For hotfixes: squash-merges the release branch to main and dispatches the deploy-all workflow. For regular releases: squash-merges to dev, opens an RC PR, merges dev into main, dispatches the deploy-all workflow, then syncs main back to dev. Also releases the matching Jira fix version if Jira is configured. Dispatches the deploy workflow fire-and-forget \u2014 the tool returns once the workflow is accepted by GitHub, not when the deployment finishes. Irreversible production operation: the confirmation prompt is auto-skipped for MCP calls, so the caller is responsible for gating. \"version\" is required when invoked via MCP (the picker is unreachable without a TTY).',\n inputSchema: {\n version: z.string().describe('Release version to deliver to production (e.g., \"1.2.5\"). Required for MCP calls.'),\n },\n outputSchema: {\n releaseBranch: z.string().describe('The release branch that was delivered'),\n version: z.string().describe('The version that was delivered'),\n type: z.enum(['regular', 'hotfix']).describe('Release type'),\n success: z.boolean().describe('Whether the delivery was successful'),\n },\n handler: ghReleaseDeliver,\n}\n", "import select from '@inquirer/select'\nimport process from 'node:process'\nimport { z } from 'zod/v4'\nimport { $ } from 'zx'\n\nimport { getReleasePRsWithInfo } from 'src/integrations/gh'\nimport { commandEcho } from 'src/lib/command-echo'\nimport { getInfraKitConfig } from 'src/lib/infra-kit-config'\nimport { logger } from 'src/lib/logger'\nimport { detectReleaseType, formatBranchChoices, getJiraDescriptions } from 'src/lib/release-utils'\nimport type { ReleaseType } from 'src/lib/release-utils'\nimport type { ToolsExecutionResult } from 'src/types'\n\ninterface GhReleaseDeployAllArgs {\n version: string\n env: string\n skipTerraform?: boolean\n}\n\n/**\n * Deploy a release branch to an environment\n */\nexport const ghReleaseDeployAll = async (args: GhReleaseDeployAllArgs): Promise<ToolsExecutionResult> => {\n const { version, env, skipTerraform } = args\n\n commandEcho.start('release-deploy-all')\n\n let selectedReleaseBranch = '' // \"release/v1.8.0\"\n\n if (version) {\n selectedReleaseBranch = version === 'dev' ? 'dev' : `release/v${version}`\n } else {\n commandEcho.setInteractive()\n\n const releasePRsInfo = await getReleasePRsWithInfo()\n\n const branches = releasePRsInfo.map((pr) => {\n return pr.branch\n })\n\n const releaseTypes = new Map<string, ReleaseType>(\n releasePRsInfo.map((pr) => {\n return [pr.branch, detectReleaseType(pr.title)]\n }),\n )\n\n const descriptions = await getJiraDescriptions()\n\n selectedReleaseBranch = await select({\n message: '\uD83C\uDF3F Select release branch',\n choices: [{ name: 'dev', value: 'dev' }, ...formatBranchChoices({ branches, descriptions, types: releaseTypes })],\n })\n }\n\n const selectedVersion = selectedReleaseBranch === 'dev' ? 'dev' : selectedReleaseBranch.replace('release/v', '')\n\n commandEcho.addOption('--version', selectedVersion)\n\n const { environments } = await getInfraKitConfig()\n\n let selectedEnv = ''\n\n if (env) {\n selectedEnv = env\n } else {\n commandEcho.setInteractive()\n\n selectedEnv = await select({\n message: '\uD83E\uDDEA Select environment',\n choices: environments.map((env) => {\n return {\n name: env,\n value: env,\n }\n }),\n })\n }\n\n commandEcho.addOption('--env', selectedEnv)\n\n if (!environments.includes(selectedEnv)) {\n logger.error(`\u274C Invalid environment: ${selectedEnv}. Exiting...`)\n process.exit(1)\n }\n\n const shouldSkipTerraform = skipTerraform ?? false\n\n if (shouldSkipTerraform) {\n commandEcho.addOption('--skip-terraform', true)\n }\n\n try {\n $.quiet = true\n\n const skipTerraformFlag = shouldSkipTerraform ? ['-f', 'skip_terraform_deploy=true'] : []\n\n await $`gh workflow run deploy-all.yml --ref ${selectedReleaseBranch} -f environment=${selectedEnv} ${skipTerraformFlag}`\n\n $.quiet = false\n\n logger.info(\n `Successfully launched deploy-all workflow_dispatch for release branch: ${selectedReleaseBranch} and environment: ${selectedEnv}`,\n )\n\n commandEcho.print()\n\n const structuredContent = {\n releaseBranch: selectedReleaseBranch,\n version: selectedReleaseBranch.replace('release/v', ''),\n environment: selectedEnv,\n skipTerraformDeploy: shouldSkipTerraform,\n success: true,\n }\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(structuredContent, null, 2),\n },\n ],\n structuredContent,\n }\n } catch (error: unknown) {\n logger.error({ error }, '\u274C Error launching workflow')\n process.exit(1)\n }\n}\n\n// MCP Tool Registration\nexport const ghReleaseDeployAllMcpTool = {\n name: 'gh-release-deploy-all',\n description:\n 'Dispatch the deploy-all.yml GitHub Actions workflow to deploy every service from a release branch to the given environment. Fire-and-forget \u2014 returns once GitHub accepts the workflow_dispatch, NOT when the deployment finishes; watch the workflow run for completion status. Use gh-release-deploy-selected for a subset of services. Pass version=\"dev\" to deploy from the dev branch instead of a release branch. Both \"version\" and \"env\" are required when invoked via MCP (interactive pickers are unavailable without a TTY).',\n inputSchema: {\n version: z\n .string()\n .describe(\n 'Release version to deploy from (e.g. \"1.2.5\") \u2014 resolves to the release/vX.Y.Z branch. Pass \"dev\" to deploy from the dev branch instead. Required for MCP calls.',\n ),\n env: z\n .string()\n .describe(\n 'Target environment name \u2014 must match an env configured for the project (e.g. \"dev\", \"renana\", \"oriana\"). Required for MCP calls.',\n ),\n skipTerraform: z.boolean().optional().describe('Skip the terraform deployment stage.'),\n },\n outputSchema: {\n releaseBranch: z.string().describe('The release branch that was deployed'),\n version: z.string().describe('The version that was deployed'),\n environment: z.string().describe('The environment deployed to'),\n skipTerraformDeploy: z.boolean().describe('Whether terraform deployment was skipped'),\n success: z.boolean().describe('Whether the deployment was successful'),\n },\n handler: ghReleaseDeployAll,\n}\n", "import checkbox from '@inquirer/checkbox'\nimport select from '@inquirer/select'\nimport fs from 'node:fs/promises'\nimport { resolve } from 'node:path'\nimport process from 'node:process'\nimport yaml from 'yaml'\nimport { z } from 'zod/v4'\nimport { $ } from 'zx'\n\nimport { getReleasePRsWithInfo } from 'src/integrations/gh'\nimport { commandEcho } from 'src/lib/command-echo'\nimport { getProjectRoot } from 'src/lib/git-utils'\nimport { getInfraKitConfig } from 'src/lib/infra-kit-config'\nimport { logger } from 'src/lib/logger'\nimport { detectReleaseType, formatBranchChoices, getJiraDescriptions } from 'src/lib/release-utils'\nimport type { ReleaseType } from 'src/lib/release-utils'\nimport type { ToolsExecutionResult } from 'src/types'\n\ninterface GhReleaseDeploySelectedArgs {\n version: string\n env: string\n services: string[]\n skipTerraform?: boolean\n}\n\n/**\n * Deploy selected services from a release branch to an environment\n */\n// eslint-disable-next-line sonarjs/cognitive-complexity\nexport const ghReleaseDeploySelected = async (args: GhReleaseDeploySelectedArgs): Promise<ToolsExecutionResult> => {\n const { version, env, services, skipTerraform } = args\n\n commandEcho.start('release-deploy-selected')\n\n let selectedReleaseBranch = ''\n\n if (version) {\n selectedReleaseBranch = version === 'dev' ? 'dev' : `release/v${version}`\n } else {\n commandEcho.setInteractive()\n\n const releasePRsInfo = await getReleasePRsWithInfo()\n\n const branches = releasePRsInfo.map((pr) => {\n return pr.branch\n })\n\n const releaseTypes = new Map<string, ReleaseType>(\n releasePRsInfo.map((pr) => {\n return [pr.branch, detectReleaseType(pr.title)]\n }),\n )\n\n const descriptions = await getJiraDescriptions()\n\n selectedReleaseBranch = await select({\n message: '\uD83C\uDF3F Select release branch',\n choices: [{ name: 'dev', value: 'dev' }, ...formatBranchChoices({ branches, descriptions, types: releaseTypes })],\n })\n }\n\n const selectedVersion = selectedReleaseBranch === 'dev' ? 'dev' : selectedReleaseBranch.replace('release/v', '')\n\n commandEcho.addOption('--version', selectedVersion)\n\n const { environments } = await getInfraKitConfig()\n\n let selectedEnv = ''\n\n if (env) {\n selectedEnv = env\n } else {\n commandEcho.setInteractive()\n\n selectedEnv = await select({\n message: '\uD83E\uDDEA Select environment',\n choices: environments.map((env) => {\n return {\n name: env,\n value: env,\n }\n }),\n })\n }\n\n commandEcho.addOption('--env', selectedEnv)\n\n if (!environments.includes(selectedEnv)) {\n logger.error(`\u274C Invalid environment: ${selectedEnv}. Exiting...`)\n process.exit(1)\n }\n\n // Parse available services from workflow file\n const availableServices = await parseServicesFromWorkflow()\n\n if (availableServices.length === 0) {\n logger.error('\u274C No services found in workflow file. Exiting...')\n\n process.exit(1)\n }\n\n let selectedServices: string[] = []\n\n if (services && services.length > 0) {\n selectedServices = services\n } else {\n commandEcho.setInteractive()\n\n selectedServices = await checkbox({\n message: '\uD83D\uDE80 Select services to deploy (space to select, enter to confirm)',\n choices: availableServices.map((svc) => {\n return {\n name: svc,\n value: svc,\n }\n }),\n })\n }\n\n commandEcho.addOption('--services', selectedServices)\n\n if (selectedServices.length === 0) {\n logger.error('\u274C No services selected. Exiting...')\n process.exit(1)\n }\n\n // Validate all selected services\n const invalidServices = selectedServices.filter((svc) => {\n return !availableServices.includes(svc)\n })\n\n if (invalidServices.length > 0) {\n logger.error(\n `\u274C Invalid services: ${invalidServices.join(', ')}. Available services: ${availableServices.join(', ')}`,\n )\n process.exit(1)\n }\n\n const shouldSkipTerraform = skipTerraform ?? false\n\n if (shouldSkipTerraform) {\n commandEcho.addOption('--skip-terraform', true)\n }\n\n try {\n $.quiet = true\n\n // Build the workflow command with boolean flags for each selected service\n const serviceFlags = selectedServices.flatMap((svc) => {\n return ['-f', `${svc}=true`]\n })\n const skipTerraformFlag = shouldSkipTerraform ? ['-f', 'skip_terraform_deploy=true'] : []\n\n await $`gh workflow run deploy-selected-services.yml --ref ${selectedReleaseBranch} -f environment=${selectedEnv} ${serviceFlags} ${skipTerraformFlag}`\n\n $.quiet = false\n\n logger.info(\n `Successfully launched deploy-selected-services workflow_dispatch for release branch: ${selectedReleaseBranch}, environment: ${selectedEnv}, services: ${selectedServices.join(', ')}`,\n )\n\n commandEcho.print()\n\n const structuredContent = {\n releaseBranch: selectedReleaseBranch,\n version: selectedReleaseBranch.replace('release/v', ''),\n environment: selectedEnv,\n services: selectedServices,\n skipTerraformDeploy: shouldSkipTerraform,\n success: true,\n }\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(structuredContent, null, 2),\n },\n ],\n structuredContent,\n }\n } catch (error: unknown) {\n logger.error({ error }, '\u274C Error launching workflow')\n process.exit(1)\n }\n}\n\n/**\n * Parse available services from the workflow file\n * Services are defined as boolean inputs (excluding skip_terraform_deploy)\n */\nconst parseServicesFromWorkflow = async (): Promise<string[]> => {\n const projectRoot = await getProjectRoot()\n\n const workflowPath = resolve(projectRoot, '.github/workflows/deploy-selected-services.yml')\n\n const content = await fs.readFile(workflowPath, 'utf-8')\n const parsed = yaml.parse(content)\n\n const inputs = parsed.on.workflow_dispatch.inputs\n const services: string[] = []\n\n for (const [key, value] of Object.entries(inputs)) {\n // Filter for boolean type inputs, excluding non-service flags\n if ((value as { type: string }).type === 'boolean' && key !== 'skip_terraform_deploy') {\n services.push(key)\n }\n }\n\n return services\n}\n\n// MCP Tool Registration\nexport const ghReleaseDeploySelectedMcpTool = {\n name: 'gh-release-deploy-selected',\n description:\n 'Dispatch the deploy-selected-services.yml GitHub Actions workflow to deploy a chosen subset of services from a release branch to the given environment. Fire-and-forget \u2014 returns once GitHub accepts the workflow_dispatch, NOT when the deployment finishes; watch the workflow run for completion status. Service names are validated against the boolean inputs declared in the workflow. Use gh-release-deploy-all for every service. \"version\", \"env\", and \"services\" are all required when invoked via MCP (interactive pickers are unavailable without a TTY).',\n inputSchema: {\n version: z\n .string()\n .describe(\n 'Release version to deploy from (e.g. \"1.2.5\") \u2014 resolves to the release/vX.Y.Z branch. Pass \"dev\" to deploy from the dev branch instead. Required for MCP calls.',\n ),\n env: z\n .string()\n .describe(\n 'Target environment name \u2014 must match an env configured for the project (e.g. \"dev\", \"renana\", \"oriana\"). Required for MCP calls.',\n ),\n services: z\n .array(z.string())\n .describe(\n 'Service names to deploy. Each must match a boolean input declared in .github/workflows/deploy-selected-services.yml (e.g. \"client-be\", \"client-fe\"). Required for MCP calls.',\n ),\n skipTerraform: z.boolean().optional().describe('Skip the terraform deployment stage.'),\n },\n outputSchema: {\n releaseBranch: z.string().describe('The release branch that was deployed'),\n version: z.string().describe('The version that was deployed'),\n environment: z.string().describe('The environment deployed to'),\n services: z.array(z.string()).describe('The services that were deployed'),\n skipTerraformDeploy: z.boolean().describe('Whether terraform deployment was skipped'),\n success: z.boolean().describe('Whether the deployment was successful'),\n },\n handler: ghReleaseDeploySelected,\n}\n", "import { z } from 'zod/v4'\n\nimport { getReleasePRsWithInfo } from 'src/integrations/gh'\nimport { logger } from 'src/lib/logger'\nimport { detectReleaseType, formatVersionLabel, getJiraDescriptions } from 'src/lib/release-utils'\nimport type { ToolsExecutionResult } from 'src/types'\n\n/**\n * List all open release branches\n */\nexport const ghReleaseList = async (): Promise<ToolsExecutionResult> => {\n const releasePRs = await getReleasePRsWithInfo()\n\n const releases = releasePRs.map((pr) => {\n return {\n version: pr.branch.replace('release/', ''),\n type: detectReleaseType(pr.title),\n }\n })\n\n const jiraDescriptions = await getJiraDescriptions()\n\n const maxVersionLength = Math.max(\n ...releases.map((r) => {\n return r.version.length\n }),\n )\n\n const formattedLines = releases.map((release) => {\n const label = formatVersionLabel(release.version, release.type, maxVersionLength)\n const description = jiraDescriptions.get(release.version)\n\n if (description) {\n return `${label} ${description}`\n }\n\n return label\n })\n\n logger.info('All release branches: \\n')\n logger.info(`\\n${formattedLines.join('\\n')}\\n`)\n\n const structuredContent = {\n releases: releases.map((release) => {\n return {\n version: release.version,\n type: release.type,\n description: jiraDescriptions.get(release.version) || null,\n }\n }),\n count: releases.length,\n }\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(structuredContent, null, 2),\n },\n ],\n structuredContent,\n }\n}\n\n// MCP Tool Registration\nexport const ghReleaseListMcpTool = {\n name: 'gh-release-list',\n description:\n 'List every open release PR with its version, type (regular / hotfix), and associated Jira fix-version description. Read-only; sourced from GitHub and Jira.',\n inputSchema: {},\n outputSchema: {\n releases: z\n .array(\n z.object({\n version: z.string().describe('Release version'),\n type: z.enum(['regular', 'hotfix']).describe('Release type'),\n description: z.string().nullable().describe('Jira version description'),\n }),\n )\n .describe('List of all release branches'),\n count: z.number().describe('Number of release branches'),\n },\n handler: ghReleaseList,\n}\n", "import confirm from '@inquirer/confirm'\nimport select from '@inquirer/select'\nimport process from 'node:process'\nimport { z } from 'zod/v4'\nimport { $, question } from 'zx'\n\nimport { loadJiraConfig } from 'src/integrations/jira'\nimport { commandEcho } from 'src/lib/command-echo'\nimport { logger } from 'src/lib/logger'\nimport { createSingleRelease, prepareGitForRelease } from 'src/lib/release-utils'\nimport type { ReleaseType } from 'src/lib/release-utils'\nimport type { RequiredConfirmedOptionArg, ToolsExecutionResult } from 'src/types'\n\ninterface ReleaseCreateArgs extends RequiredConfirmedOptionArg {\n version?: string\n description?: string\n type?: ReleaseType\n checkout?: boolean\n}\n\n/**\n * Create a single release branch for the specified version\n * Includes Jira version creation and GitHub release branch creation\n */\nexport const releaseCreate = async (args: ReleaseCreateArgs): Promise<ToolsExecutionResult> => {\n const {\n version: inputVersion,\n description: inputDescription,\n type: inputType,\n confirmedCommand,\n checkout: inputCheckout,\n } = args\n\n commandEcho.start('release-create')\n\n let version = inputVersion\n let description = inputDescription\n let type: ReleaseType = inputType || 'regular'\n let checkout = inputCheckout\n\n // Load Jira config - it is now mandatory\n const jiraConfig = await loadJiraConfig()\n\n if (!version) {\n commandEcho.setInteractive()\n version = await question('Enter version (e.g. 1.2.5): ')\n }\n\n // Validate input (validate the version is a valid semver)\n if (!version || version.trim() === '') {\n logger.error('No version provided. Exiting...')\n process.exit(1)\n }\n\n const trimmedVersion = version.trim()\n\n commandEcho.addOption('--version', trimmedVersion)\n\n if (!inputType) {\n commandEcho.setInteractive()\n\n type = await select<ReleaseType>({\n message: 'Select release type:',\n choices: [\n { name: 'regular', value: 'regular' },\n { name: 'hotfix', value: 'hotfix' },\n ],\n default: 'regular',\n })\n }\n\n commandEcho.addOption('--type', type)\n\n if (description === undefined) {\n commandEcho.setInteractive()\n description = await question('Enter description (optional, press Enter to skip): ')\n\n if (description.trim() === '') {\n description = ''\n }\n }\n\n if (description) {\n commandEcho.addOption('--description', description)\n }\n\n const answer = confirmedCommand\n ? true\n : await confirm({\n message: `Are you sure you want to create release branch for version ${trimmedVersion}?`,\n })\n\n if (!confirmedCommand) {\n commandEcho.setInteractive()\n }\n\n if (!answer) {\n logger.info('Operation cancelled. Exiting...')\n process.exit(0)\n }\n\n // Track --yes flag if confirmation was interactive (user confirmed)\n commandEcho.addOption('--yes', true)\n\n await prepareGitForRelease(type)\n\n // Create the release\n const release = await createSingleRelease({ version: trimmedVersion, jiraConfig, description, type })\n\n logger.info(`\u2705 Successfully created release: v${trimmedVersion}`)\n logger.info(`\uD83D\uDD17 GitHub PR: ${release.prUrl}`)\n logger.info(`\uD83D\uDD17 Jira Version: ${release.jiraVersionUrl}`)\n\n // Ask about checkout if not specified\n if (checkout === undefined) {\n commandEcho.setInteractive()\n\n checkout = await confirm({\n message: `Do you want to checkout to the created branch ${release.branchName}?`,\n default: true,\n })\n }\n\n // Track checkout option (--no-checkout if false)\n if (!checkout) {\n commandEcho.addOption('--no-checkout', true)\n }\n\n // Checkout to the created branch by default\n if (checkout) {\n $.quiet = true\n await $`git switch ${release.branchName}`\n $.quiet = false\n\n logger.info(`\uD83D\uDD04 Switched to branch ${release.branchName}`)\n }\n\n commandEcho.print()\n\n const structuredContent = {\n version: trimmedVersion,\n type,\n branchName: release.branchName,\n prUrl: release.prUrl,\n jiraVersionUrl: release.jiraVersionUrl,\n isCheckedOut: checkout,\n }\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(structuredContent, null, 2),\n },\n ],\n structuredContent,\n }\n}\n\n// MCP Tool Registration\nexport const releaseCreateMcpTool = {\n name: 'release-create',\n description:\n 'Create a new release: cuts the release branch off the appropriate base (dev for regular releases, main for hotfixes), opens a GitHub release PR, creates the matching Jira fix version, and optionally checks out to the new branch. Confirmation is auto-skipped for MCP calls, so the caller is responsible for gating. \"version\" is required when invoked via MCP (the interactive input prompt is unreachable without a TTY); \"type\" / \"description\" / \"checkout\" default to regular / empty / true when omitted.',\n inputSchema: {\n version: z.string().describe('Version to create (e.g., \"1.2.5\"). Required for MCP calls.'),\n description: z.string().optional().describe('Optional description for the Jira version'),\n type: z\n .enum(['regular', 'hotfix'])\n .optional()\n .default('regular')\n .describe('Release type: \"regular\" or \"hotfix\" (default: \"regular\")'),\n checkout: z.boolean().optional().default(true).describe('Checkout to the created branch (default: true)'),\n },\n outputSchema: {\n version: z.string().describe('Version number'),\n type: z.enum(['regular', 'hotfix']).describe('Release type'),\n branchName: z.string().describe('Release branch name'),\n prUrl: z.string().describe('GitHub PR URL'),\n jiraVersionUrl: z.string().describe('Jira version URL'),\n isCheckedOut: z.boolean().describe('Whether the branch was checked out'),\n },\n handler: releaseCreate,\n}\n", "import confirm from '@inquirer/confirm'\nimport select from '@inquirer/select'\nimport process from 'node:process'\nimport { z } from 'zod/v4'\nimport { question } from 'zx'\n\nimport { loadJiraConfig } from 'src/integrations/jira'\nimport { commandEcho } from 'src/lib/command-echo'\nimport { logger } from 'src/lib/logger'\nimport { createSingleRelease, prepareGitForRelease } from 'src/lib/release-utils'\nimport type { ReleaseCreationResult, ReleaseType } from 'src/lib/release-utils'\nimport type { RequiredConfirmedOptionArg, ToolsExecutionResult } from 'src/types'\n\ninterface ReleaseCreateBatchArgs extends RequiredConfirmedOptionArg {\n versions: string\n type?: ReleaseType\n}\n\n/**\n * Gather and validate batch release inputs interactively if needed\n */\nconst resolveInputs = async (args: ReleaseCreateBatchArgs): Promise<{ versionsList: string[]; type: ReleaseType }> => {\n const { versions: inputVersions, type: inputType, confirmedCommand } = args\n\n let versionInput = inputVersions\n let type: ReleaseType = inputType || 'regular'\n\n if (!versionInput) {\n commandEcho.setInteractive()\n versionInput = await question('Enter versions by comma (e.g. 1.2.5, 1.2.6): ')\n }\n\n const versionsList = versionInput\n .split(',')\n .map((version) => {\n return version.trim()\n })\n .filter(Boolean)\n\n commandEcho.addOption('--versions', versionsList.join(', '))\n\n if (versionsList.length === 0) {\n logger.error('No versions provided. Exiting...')\n process.exit(1)\n }\n\n if (!inputType) {\n commandEcho.setInteractive()\n\n type = await select<ReleaseType>({\n message: 'Select release type:',\n choices: [\n { name: 'regular', value: 'regular' },\n { name: 'hotfix', value: 'hotfix' },\n ],\n default: 'regular',\n })\n }\n\n commandEcho.addOption('--type', type)\n\n if (versionsList.length === 1) {\n logger.warn('\uD83D\uDCA1 You are creating only one release. Consider using \"create-release\" command for single releases.')\n }\n\n const answer = confirmedCommand\n ? true\n : await confirm({\n message: `Are you sure you want to create release branches for these versions: ${versionsList.join(', ')}?`,\n })\n\n if (!confirmedCommand) {\n commandEcho.setInteractive()\n }\n\n if (!answer) {\n logger.info('Operation cancelled. Exiting...')\n process.exit(0)\n }\n\n commandEcho.addOption('--yes', true)\n\n return { versionsList, type }\n}\n\n/**\n * Create multiple release branches for the specified versions\n * Includes Jira version creation and GitHub release branch creation for each version\n */\nexport const releaseCreateBatch = async (args: ReleaseCreateBatchArgs): Promise<ToolsExecutionResult> => {\n commandEcho.start('release-create-batch')\n\n const jiraConfig = await loadJiraConfig()\n\n const { versionsList, type } = await resolveInputs(args)\n\n await prepareGitForRelease(type)\n\n const releases: ReleaseCreationResult[] = []\n const failedReleases: Array<{ version: string; error: string }> = []\n\n for (const version of versionsList) {\n try {\n // Create each release\n const release = await createSingleRelease({ version, jiraConfig, type })\n\n releases.push(release)\n\n logger.info(`\u2705 Successfully created release: v${version}`)\n logger.info(`\uD83D\uDD17 GitHub PR: ${release.prUrl}`)\n logger.info(`\uD83D\uDD17 Jira Version: ${release.jiraVersionUrl}\\n`)\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error)\n\n failedReleases.push({ version, error: errorMessage })\n\n logger.error(`\u274C Failed to create release: v${version}`)\n logger.error(` Error: ${errorMessage}\\n`)\n }\n }\n\n // Final summary\n const successCount = releases.length\n const failureCount = failedReleases.length\n\n if (successCount === versionsList.length) {\n logger.info(`\u2705 All ${versionsList.length} release branches were created successfully.`)\n } else if (successCount > 0) {\n logger.warn(`\u26A0\uFE0F ${successCount} of ${versionsList.length} release branches were created successfully.`)\n logger.warn(`\u274C ${failureCount} release(s) failed.`)\n } else {\n logger.error(`\u274C All ${versionsList.length} release branches failed to create.`)\n }\n\n commandEcho.print()\n\n const structuredContent = {\n createdBranches: releases.map((r) => {\n return r.branchName\n }),\n successCount,\n failureCount,\n releases,\n failedReleases,\n }\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(structuredContent, null, 2),\n },\n ],\n structuredContent,\n }\n}\n\n// MCP Tool Registration\nexport const releaseCreateBatchMcpTool = {\n name: 'release-create-batch',\n description:\n 'Create several releases in one pass: for each comma-separated version in \"versions\", cuts the release branch off the appropriate base (dev for regular releases, main for hotfixes), opens a GitHub PR, and creates the Jira fix version. Continues on per-version failure and reports which versions succeeded and which failed. Confirmation is auto-skipped for MCP calls, so the caller is responsible for gating. \"versions\" is required when invoked via MCP (the interactive input prompt is unreachable without a TTY). Use release-create for a single version with optional checkout.',\n inputSchema: {\n versions: z\n .string()\n .describe('Comma-separated list of versions to create (e.g., \"1.2.5, 1.2.6\"). Required for MCP calls.'),\n type: z\n .enum(['regular', 'hotfix'])\n .optional()\n .default('regular')\n .describe('Release type: \"regular\" or \"hotfix\" (default: \"regular\")'),\n },\n outputSchema: {\n createdBranches: z.array(z.string()).describe('List of created release branches'),\n successCount: z.number().describe('Number of releases created successfully'),\n failureCount: z.number().describe('Number of releases that failed'),\n releases: z\n .array(\n z.object({\n version: z.string().describe('Version number'),\n type: z.enum(['regular', 'hotfix']).describe('Release type'),\n branchName: z.string().describe('Release branch name'),\n prUrl: z.string().describe('GitHub PR URL'),\n jiraVersionUrl: z.string().describe('Jira version URL'),\n }),\n )\n .describe('Detailed information for each created release with URLs'),\n failedReleases: z\n .array(\n z.object({\n version: z.string().describe('Version number that failed'),\n error: z.string().describe('Error message'),\n }),\n )\n .describe('List of releases that failed with error messages'),\n },\n handler: releaseCreateBatch,\n}\n", "import { z } from 'zod/v4'\n\nimport { logger } from 'src/lib/logger'\nimport type { ToolsExecutionResult } from 'src/types'\n\nimport packageJson from '../../../package.json' with { type: 'json' }\n\n/**\n * Print the infra-kit CLI version\n */\nexport const version = async (): Promise<ToolsExecutionResult> => {\n const cliVersion = packageJson.version\n\n logger.info(cliVersion)\n\n const structuredContent = { version: cliVersion }\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(structuredContent, null, 2),\n },\n ],\n structuredContent,\n }\n}\n\n// MCP Tool Registration\nexport const versionMcpTool = {\n name: 'version',\n description: 'Print the installed infra-kit CLI version',\n inputSchema: {},\n outputSchema: {\n version: z.string().describe('Installed infra-kit CLI version (from package.json)'),\n },\n handler: version,\n}\n", "{\n \"name\": \"infra-kit\",\n \"type\": \"module\",\n \"version\": \"0.1.95\",\n \"description\": \"infra-kit\",\n \"main\": \"dist/cli.js\",\n \"module\": \"dist/cli.js\",\n \"bin\": {\n \"infra-kit\": \"dist/cli.js\",\n \"ik\": \"dist/cli.js\"\n },\n \"engines\": {\n \"node\": \">=24.x\"\n },\n \"scripts\": {\n \"inspector\": \"npx @modelcontextprotocol/inspector node ./dist/mcp.js --debug\",\n \"build\": \"pnpm run clean-artifacts && node ./scripts/build.js\",\n \"clean-artifacts\": \"rm -rf dist\",\n \"clean-cache\": \"rm -rf node_modules/.cache .eslintcache tsconfig.tsbuildinfo .turbo .swc\",\n \"prettier-fix\": \"pnpm exec prettier **/* --write --no-error-on-unmatched-pattern --log-level warn --ignore-path ../../../.prettierignore\",\n \"prettier-check\": \"pnpm exec prettier **/* --check --no-error-on-unmatched-pattern --log-level warn --ignore-path ../../../.prettierignore\",\n \"eslint-check\": \"pnpm exec eslint --cache --quiet --report-unused-disable-directives ./src\",\n \"eslint-fix\": \"pnpm exec eslint --cache --quiet --report-unused-disable-directives ./src --fix\",\n \"ts-check\": \"tsc --noEmit\",\n \"test\": \"pnpm exec vitest run --reporter=dot\",\n \"test-watch\": \"pnpm exec vitest --watch\",\n \"test-ui\": \"pnpm exec vitest --ui\",\n \"test-report\": \"pnpm exec vitest run --coverage\",\n \"qa\": \"pnpm run prettier-check && pnpm run eslint-check && pnpm run ts-check && pnpm run test && echo \u2705 Success\",\n \"fix\": \"pnpm run prettier-fix && pnpm run eslint-fix && pnpm run qa\"\n },\n \"dependencies\": {\n \"@inquirer/checkbox\": \"^5.1.4\",\n \"@inquirer/confirm\": \"^6.0.12\",\n \"@inquirer/select\": \"^5.1.4\",\n \"@modelcontextprotocol/sdk\": \"^1.29.0\",\n \"commander\": \"^14.0.3\",\n \"pino\": \"^10.3.1\",\n \"pino-pretty\": \"^13.1.3\",\n \"yaml\": \"^2.8.3\",\n \"zod\": \"^3.25.76\",\n \"zx\": \"^8.8.5\"\n },\n \"devDependencies\": {\n \"@pkg/eslint-config\": \"workspace:*\",\n \"@pkg/vitest-config\": \"workspace:*\",\n \"esbuild\": \"^0.28.0\",\n \"typescript\": \"catalog:\"\n }\n}\n", "/* eslint-disable sonarjs/cognitive-complexity */\nimport checkbox from '@inquirer/checkbox'\nimport confirm from '@inquirer/confirm'\nimport select from '@inquirer/select'\nimport process from 'node:process'\nimport { z } from 'zod/v4'\nimport { $ } from 'zx'\n\nimport { buildCmuxWorkspaceTitle, openCmuxWorkspaceWithLayout } from 'src/integrations/cmux'\nimport { addFoldersToCursorWorkspace, resolveCursorWorkspacePath } from 'src/integrations/cursor'\nimport { getReleasePRsWithInfo } from 'src/integrations/gh'\nimport { commandEcho } from 'src/lib/command-echo'\nimport { WORKTREES_DIR_SUFFIX } from 'src/lib/constants'\nimport { getCurrentWorktrees, getProjectRoot, getRepoName } from 'src/lib/git-utils'\nimport { getInfraKitConfig } from 'src/lib/infra-kit-config'\nimport { logger } from 'src/lib/logger'\nimport { detectReleaseType, formatBranchChoices, getJiraDescriptions } from 'src/lib/release-utils'\nimport type { ReleaseType } from 'src/lib/release-utils'\nimport type { RequiredConfirmedOptionArg, ToolsExecutionResult } from 'src/types'\n\n// Constants\nconst FEATURE_DIR = 'feature'\nconst RELEASE_DIR = 'release'\nconst RELEASE_BRANCH_PREFIX = 'release/v'\n\nexport const CURSOR_MODES = ['workspace', 'windows', 'none'] as const\nexport type CursorMode = (typeof CURSOR_MODES)[number]\n\ninterface WorktreeManagementArgs extends RequiredConfirmedOptionArg {\n all: boolean\n versions?: string\n cursor?: CursorMode\n githubDesktop?: boolean\n cmux?: boolean\n}\n\n/**\n * Manage git worktrees for release branches\n * Creates worktrees for active release branches and removes unused ones\n */\nexport const worktreesAdd = async (options: WorktreeManagementArgs): Promise<ToolsExecutionResult> => {\n const { confirmedCommand, all, versions, cursor, githubDesktop, cmux } = options\n\n commandEcho.start('worktrees-add')\n\n try {\n const currentWorktrees = await getCurrentWorktrees('release')\n const projectRoot = await getProjectRoot()\n\n const worktreeDir = `${projectRoot}${WORKTREES_DIR_SUFFIX}`\n\n await ensureWorktreeDirectory(`${worktreeDir}/${RELEASE_DIR}`)\n await ensureWorktreeDirectory(`${worktreeDir}/${FEATURE_DIR}`)\n\n let selectedReleaseBranches: string[] = []\n\n if (versions) {\n selectedReleaseBranches = versions.split(',').map((v) => {\n return `release/v${v.trim()}`\n })\n } else {\n const releasePRsInfo = await getReleasePRsWithInfo()\n\n const releasePRsList = releasePRsInfo.map((pr) => {\n return pr.branch\n })\n\n if (releasePRsList.length === 0) {\n logger.info('\u2139\uFE0F No open release branches found')\n\n commandEcho.print()\n\n return {\n content: [{ type: 'text', text: JSON.stringify({ createdWorktrees: [], count: 0 }, null, 2) }],\n structuredContent: { createdWorktrees: [], count: 0 },\n }\n }\n\n if (all) {\n selectedReleaseBranches = releasePRsList\n } else {\n commandEcho.setInteractive()\n\n const releaseTypes = new Map<string, ReleaseType>(\n releasePRsInfo.map((pr) => {\n return [pr.branch, detectReleaseType(pr.title)]\n }),\n )\n\n const descriptions = await getJiraDescriptions()\n\n selectedReleaseBranches = await checkbox({\n required: true,\n message: '\uD83C\uDF3F Select release branches',\n choices: formatBranchChoices({ branches: releasePRsList, descriptions, types: releaseTypes }),\n })\n }\n }\n\n // Track --all flag if all branches were selected (either via flag or interactively)\n if (all) {\n commandEcho.addOption('--all', true)\n } else {\n commandEcho.addOption(\n '--versions',\n selectedReleaseBranches.map((branch) => {\n return branch.replace('release/v', '')\n }),\n )\n }\n\n // Ask for confirmation\n const answer = confirmedCommand\n ? true\n : await confirm({\n message: 'Are you sure you want to proceed with these worktree changes?',\n })\n\n if (!confirmedCommand) {\n commandEcho.setInteractive()\n }\n\n if (!answer) {\n logger.info('Operation cancelled. Exiting...')\n process.exit(0)\n }\n\n // Track --yes flag if confirmation was interactive (user confirmed)\n if (!confirmedCommand) {\n commandEcho.addOption('--yes', true)\n }\n\n const cursorMode: CursorMode =\n cursor ??\n (await select<CursorMode>({\n message: 'Cursor mode for created worktrees?',\n default: 'workspace',\n choices: [\n {\n name: 'Add to workspace file',\n value: 'workspace',\n description: 'Append each worktree as a folder in ide.config.workspaceConfigPath, then open the workspace',\n },\n {\n name: 'Open separate windows',\n value: 'windows',\n description: 'Open each created worktree in its own Cursor window',\n },\n { name: 'Skip', value: 'none', description: 'Do not open Cursor' },\n ],\n }))\n\n if (typeof cursor === 'undefined') {\n commandEcho.setInteractive()\n }\n\n commandEcho.addOption('--cursor', cursorMode)\n\n const openInGithubDesktop =\n githubDesktop ?? (await confirm({ message: 'Open created worktrees in GitHub Desktop?' }))\n\n if (typeof githubDesktop === 'undefined') {\n commandEcho.setInteractive()\n }\n\n if (openInGithubDesktop) {\n commandEcho.addOption('--github-desktop', true)\n } else {\n commandEcho.addOption('--no-github-desktop', true)\n }\n\n const openInCmux = cmux ?? (await confirm({ message: 'Open created worktrees in cmux?' }))\n\n if (typeof cmux === 'undefined') {\n commandEcho.setInteractive()\n }\n\n if (openInCmux) {\n commandEcho.addOption('--cmux', true)\n } else {\n commandEcho.addOption('--no-cmux', true)\n }\n\n const { branchesToCreate } = categorizeWorktrees({\n selectedReleaseBranches,\n currentWorktrees,\n })\n\n const createdWorktrees = await createWorktrees(branchesToCreate, worktreeDir)\n\n logResults(createdWorktrees)\n\n if (cursorMode === 'workspace') {\n const config = await getInfraKitConfig()\n const cursorConfig = config.ide?.provider === 'cursor' ? config.ide.config : undefined\n\n if (!cursorConfig?.workspaceConfigPath) {\n logger.warn('\u26A0\uFE0F Skipping Cursor: ide.config.workspaceConfigPath is not set in infra-kit.yml')\n } else {\n const workspacePath = resolveCursorWorkspacePath(cursorConfig.workspaceConfigPath, projectRoot)\n\n const folderPaths = createdWorktrees.map((branch) => {\n return `${worktreeDir}/${branch}`\n })\n\n const { added, skipped } = await addFoldersToCursorWorkspace({ workspacePath, folderPaths })\n\n const skippedSuffix = skipped.length > 0 ? ` (${skipped.length} already present)` : ''\n\n logger.info(`\u2705 Added ${added.length} folder(s) to ${workspacePath}${skippedSuffix}`)\n\n await $`cursor ${workspacePath}`\n }\n } else if (cursorMode === 'windows') {\n for (const branch of createdWorktrees) {\n await $`cursor ${worktreeDir}/${branch}`\n }\n }\n\n if (openInGithubDesktop) {\n for (const branch of createdWorktrees) {\n await $`github ${worktreeDir}/${branch}`\n await $`sleep 5`\n }\n }\n\n if (openInCmux) {\n const repoName = await getRepoName()\n\n for (const branch of createdWorktrees) {\n const title = buildCmuxWorkspaceTitle({ repoName, branch })\n\n await openCmuxWorkspaceWithLayout({\n cwd: `${worktreeDir}/${branch}`,\n title,\n })\n }\n }\n\n commandEcho.print()\n\n const structuredContent = {\n createdWorktrees,\n count: createdWorktrees.length,\n }\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(structuredContent, null, 2),\n },\n ],\n structuredContent,\n }\n } catch (error) {\n logger.error({ error }, '\u274C Error managing worktrees')\n throw error\n }\n}\n\n/**\n * Ensure the worktree directory exists\n */\nconst ensureWorktreeDirectory = async (worktreeDir: string): Promise<void> => {\n await $`mkdir -p ${worktreeDir}`\n}\n\ninterface CategorizeWorktreesArgs {\n selectedReleaseBranches: string[]\n currentWorktrees: string[]\n}\n\n/**\n * Categorize release worktrees into those that need to be created or removed\n */\nconst categorizeWorktrees = (args: CategorizeWorktreesArgs): { branchesToCreate: string[] } => {\n const { selectedReleaseBranches, currentWorktrees } = args\n\n const currentBranchNames = currentWorktrees.filter((branch) => {\n return branch.startsWith(RELEASE_BRANCH_PREFIX)\n })\n\n const branchesToCreate = selectedReleaseBranches.filter((branch) => {\n return !currentBranchNames.includes(branch)\n })\n\n return { branchesToCreate }\n}\n\n/**\n * Create worktrees for the specified branches\n */\nconst createWorktrees = async (branches: string[], worktreeDir: string): Promise<string[]> => {\n const results = await Promise.allSettled(\n branches.map(async (branch) => {\n const worktreePath = `${worktreeDir}/${branch}`\n\n await $`git worktree add ${worktreePath} ${branch}`\n await $({ cwd: worktreePath })`pnpm install`\n\n return branch\n }),\n )\n\n const created: string[] = []\n\n for (const [index, result] of results.entries()) {\n if (result.status === 'fulfilled') {\n created.push(result.value)\n } else {\n const branch = branches[index]\n\n logger.error({ error: result.reason }, `\u274C Failed to create worktree for ${branch}`)\n }\n }\n\n return created\n}\n\n/**\n * Log the results of worktree management\n */\nconst logResults = (created: string[]): void => {\n if (created.length > 0) {\n logger.info('\u2705 Created git worktrees:')\n for (const branch of created) {\n logger.info(branch)\n }\n logger.info('')\n } else {\n logger.info('\u2139\uFE0F No new git worktrees to create')\n }\n}\n\n// MCP Tool Registration\nexport const worktreesAddMcpTool = {\n name: 'worktrees-add',\n description:\n 'Create local git worktrees for release branches under the worktrees directory and run \"pnpm install\" in each. Mutates the local filesystem. When invoked via MCP, pass either \"versions\" (comma-separated) or all=true \u2014 the branch picker and \"open in Cursor / GitHub Desktop / cmux\" follow-up prompts are unreachable without a TTY, and the CLI confirmation is auto-skipped for MCP calls.',\n inputSchema: {\n all: z\n .boolean()\n .optional()\n .describe(\n 'Add worktrees for every open release branch. Either \"all\" or \"versions\" must be provided for MCP calls (the interactive picker is unavailable without a TTY). Ignored if \"versions\" is provided.',\n ),\n versions: z\n .string()\n .optional()\n .describe(\n 'Comma-separated release versions to target (e.g. \"1.2.5, 1.2.6\"). Either \"versions\" or all=true must be provided for MCP calls. Overrides \"all\" when set.',\n ),\n cursor: z\n .enum(CURSOR_MODES)\n .optional()\n .describe(\n 'Cursor open mode for created worktrees. \"workspace\" (default behavior when set interactively) appends each worktree as a folder to \"ide.config.workspaceConfigPath\" in infra-kit.yml and opens the workspace. \"windows\" opens each worktree in its own Cursor window. \"none\" skips Cursor. Defaults to \"none\" in MCP mode (the follow-up prompt is not shown).',\n ),\n githubDesktop: z\n .boolean()\n .optional()\n .describe(\n 'Open each created worktree in GitHub Desktop. Defaults to false in MCP mode (the follow-up prompt is not shown).',\n ),\n cmux: z\n .boolean()\n .optional()\n .describe(\n 'Open each created worktree in a new cmux workspace with a 3-pane layout (left-top, left-bottom, full-height right), all rooted at the worktree directory. Defaults to false in MCP mode (the follow-up prompt is not shown).',\n ),\n },\n outputSchema: {\n createdWorktrees: z.array(z.string()).describe('List of created git worktree branches'),\n count: z.number().describe('Number of git worktrees created'),\n },\n handler: worktreesAdd,\n}\n", "import { $ } from 'zx'\n\nimport { logger } from 'src/lib/logger'\n\n/**\n * Best-effort close of the cmux workspace whose title exactly matches `title`.\n * Silently no-ops if cmux isn't running, the workspace isn't found, or close fails.\n */\nexport const closeCmuxWorkspaceByTitle = async (title: string): Promise<void> => {\n try {\n const listOutput = (await $`cmux list-workspaces`.quiet()).stdout\n\n const ref = findWorkspaceRefByTitle(listOutput, title)\n\n if (!ref) {\n return\n }\n\n await $`cmux close-workspace --workspace ${ref}`.quiet()\n } catch (error) {\n logger.debug({ error, title }, 'cmux: skipped closing workspace')\n }\n}\n\n/**\n * Parses `cmux list-workspaces` output and returns the workspace ref whose\n * title exactly matches `title`, or undefined if no match.\n *\n * Each line looks like:\n * \" workspace:8 hulyo-monorepo v1.48.0\"\n * \"* workspace:6 obsidian-workspace [selected]\"\n */\nconst findWorkspaceRefByTitle = (output: string, title: string): string | undefined => {\n for (const rawLine of output.split('\\n')) {\n // eslint-disable-next-line sonarjs/slow-regex, regexp/no-super-linear-backtracking\n const match = rawLine.match(/^[* ]\\s*(workspace:\\d+)\\s+(.+?)(?:\\s+\\[selected\\])?\\s*$/)\n\n if (!match) {\n continue\n }\n\n const ref = match[1]\n const lineTitle = match[2]?.trim() ?? ''\n\n if (lineTitle === title) {\n return ref\n }\n }\n\n return undefined\n}\n", "import { $ } from 'zx'\n\ninterface OpenCmuxWorkspaceArgs {\n cwd: string\n title?: string\n}\n\n/**\n * Opens a new cmux workspace rooted at `cwd` with three panes:\n * left-top (primary) | right (full-height)\n * left-bottom |\n * All panes inherit `cwd` from the workspace.\n */\nexport const openCmuxWorkspaceWithLayout = async (args: OpenCmuxWorkspaceArgs): Promise<void> => {\n const { cwd, title } = args\n\n const newWorkspaceOutput = (await $`cmux new-workspace --cwd ${cwd}`).stdout\n\n const workspaceRef = parseWorkspaceRef(newWorkspaceOutput)\n\n const surfacesOutput = (await $`cmux list-pane-surfaces --workspace ${workspaceRef}`).stdout\n\n const leftTopRef = parseFirstSurfaceRef(surfacesOutput)\n\n await $`cmux new-split right --workspace ${workspaceRef} --surface ${leftTopRef}`\n await $`cmux new-split down --workspace ${workspaceRef} --surface ${leftTopRef}`\n\n if (title) {\n await $`cmux rename-workspace --workspace ${workspaceRef} ${title}`\n }\n}\n\n/**\n * Extracts the first `surface:<id>` reference from the output of\n * `cmux list-pane-surfaces`. Used to locate the initial (primary) pane\n * surface so subsequent splits can be anchored relative to it.\n *\n * @example\n * const output = 'surface:12 (active)\\nsurface:13\\n'\n * parseFirstSurfaceRef(output) // => 'surface:12'\n */\nconst parseFirstSurfaceRef = (output: string): string => {\n const match = output.match(/surface:\\d+/)\n\n if (!match) {\n throw new Error('cmux: could not locate initial surface in list-pane-surfaces output')\n }\n\n return match[0]\n}\n\n/**\n * Extracts the `workspace:<id>` reference from the output of\n * `cmux new-workspace`. The returned ref is used to target the newly\n * created workspace in follow-up `cmux` commands (splits, rename, etc.).\n *\n * @example\n * const output = 'created workspace:7\\n'\n * parseWorkspaceRef(output) // => 'workspace:7'\n */\nconst parseWorkspaceRef = (output: string): string => {\n const match = output.match(/workspace:\\d+/)\n\n if (!match) {\n throw new Error('cmux: could not locate workspace ref in new-workspace output')\n }\n\n return match[0]\n}\n", "interface BuildCmuxWorkspaceTitleArgs {\n repoName: string\n branch: string\n}\n\n/**\n * Builds the cmux workspace title used by `worktrees-add` and looked up by\n * `worktrees-remove`. The `release/` prefix is stripped so the title reads\n * e.g. `\"hulyo-monorepo v1.48.0\"` for branch `\"release/v1.48.0\"`.\n */\nexport const buildCmuxWorkspaceTitle = (args: BuildCmuxWorkspaceTitleArgs): string => {\n const { repoName, branch } = args\n\n const version = branch.replace('release/', '')\n\n return `${repoName} ${version}`\n}\n", "import fs from 'node:fs/promises'\nimport path from 'node:path'\n\ninterface AddFoldersToCursorWorkspaceArgs {\n workspacePath: string\n folderPaths: string[]\n}\n\ninterface AddFoldersToCursorWorkspaceResult {\n added: string[]\n skipped: string[]\n}\n\ninterface WorkspaceFolderEntry {\n path: string\n name?: string\n}\n\ninterface WorkspaceFile {\n folders?: WorkspaceFolderEntry[]\n [key: string]: unknown\n}\n\n/**\n * Adds folders to a Cursor (`.code-workspace`) file's `folders` array, skipping\n * entries that already point to the same absolute path. Folder paths are written\n * as relative to the workspace file's directory to match Cursor's default style.\n */\nexport const addFoldersToCursorWorkspace = async (\n args: AddFoldersToCursorWorkspaceArgs,\n): Promise<AddFoldersToCursorWorkspaceResult> => {\n const { workspacePath, folderPaths } = args\n\n const workspaceDir = path.dirname(workspacePath)\n\n let raw: string\n\n try {\n raw = await fs.readFile(workspacePath, 'utf-8')\n } catch (error) {\n throw new Error(`Cursor workspace file not found at ${workspacePath}: ${(error as Error).message}`)\n }\n\n let parsed: WorkspaceFile\n\n try {\n parsed = JSON.parse(raw) as WorkspaceFile\n } catch (error) {\n throw new Error(\n `Failed to parse ${workspacePath} as JSON. Comments (JSONC) are not supported. ${(error as Error).message}`,\n )\n }\n\n const existingFolders = parsed.folders ?? []\n const existingAbsolutePaths = new Set(\n existingFolders.map((entry) => {\n return path.resolve(workspaceDir, entry.path)\n }),\n )\n\n const added: string[] = []\n const skipped: string[] = []\n\n for (const folderPath of folderPaths) {\n const absolutePath = path.resolve(folderPath)\n\n if (existingAbsolutePaths.has(absolutePath)) {\n skipped.push(folderPath)\n continue\n }\n\n const relativePath = path.relative(workspaceDir, absolutePath)\n\n existingFolders.push({ path: relativePath })\n existingAbsolutePaths.add(absolutePath)\n added.push(folderPath)\n }\n\n parsed.folders = existingFolders\n\n await fs.writeFile(workspacePath, `${JSON.stringify(parsed, null, 2)}\\n`, 'utf-8')\n\n return { added, skipped }\n}\n", "import fs from 'node:fs/promises'\nimport path from 'node:path'\n\ninterface RemoveFoldersFromCursorWorkspaceArgs {\n workspacePath: string\n folderPaths: string[]\n}\n\ninterface RemoveFoldersFromCursorWorkspaceResult {\n removed: string[]\n notFound: string[]\n}\n\ninterface WorkspaceFolderEntry {\n path: string\n name?: string\n}\n\ninterface WorkspaceFile {\n folders?: WorkspaceFolderEntry[]\n [key: string]: unknown\n}\n\n/**\n * Removes folders from a Cursor (`.code-workspace`) file's `folders` array. Entries\n * are matched by resolved absolute path, so relative and absolute entries pointing\n * at the same folder are both removed.\n */\nexport const removeFoldersFromCursorWorkspace = async (\n args: RemoveFoldersFromCursorWorkspaceArgs,\n): Promise<RemoveFoldersFromCursorWorkspaceResult> => {\n const { workspacePath, folderPaths } = args\n\n const workspaceDir = path.dirname(workspacePath)\n\n let raw: string\n\n try {\n raw = await fs.readFile(workspacePath, 'utf-8')\n } catch (error) {\n throw new Error(`Cursor workspace file not found at ${workspacePath}: ${(error as Error).message}`)\n }\n\n let parsed: WorkspaceFile\n\n try {\n parsed = JSON.parse(raw) as WorkspaceFile\n } catch (error) {\n throw new Error(\n `Failed to parse ${workspacePath} as JSON. Comments (JSONC) are not supported. ${(error as Error).message}`,\n )\n }\n\n const existingFolders = parsed.folders ?? []\n const targetAbsolutePaths = new Set(\n folderPaths.map((folderPath) => {\n return path.resolve(folderPath)\n }),\n )\n\n const removedAbsolutePaths = new Set<string>()\n\n const filteredFolders = existingFolders.filter((entry) => {\n const entryAbsolutePath = path.resolve(workspaceDir, entry.path)\n\n if (targetAbsolutePaths.has(entryAbsolutePath)) {\n removedAbsolutePaths.add(entryAbsolutePath)\n\n return false\n }\n\n return true\n })\n\n parsed.folders = filteredFolders\n\n await fs.writeFile(workspacePath, `${JSON.stringify(parsed, null, 2)}\\n`, 'utf-8')\n\n const removed: string[] = []\n const notFound: string[] = []\n\n for (const folderPath of folderPaths) {\n const absolutePath = path.resolve(folderPath)\n\n if (removedAbsolutePaths.has(absolutePath)) {\n removed.push(folderPath)\n } else {\n notFound.push(folderPath)\n }\n }\n\n return { removed, notFound }\n}\n", "import path from 'node:path'\n\n/**\n * Resolves the configured Cursor workspace path against the project root.\n * Absolute paths are returned unchanged.\n */\nexport const resolveCursorWorkspacePath = (configValue: string, projectRoot: string): string => {\n if (path.isAbsolute(configValue)) {\n return configValue\n }\n\n return path.resolve(projectRoot, configValue)\n}\n", "import { z } from 'zod/v4'\n\nimport { getReleasePRsWithInfo } from 'src/integrations/gh'\nimport { getCurrentWorktrees } from 'src/lib/git-utils'\nimport { logger } from 'src/lib/logger'\nimport { detectReleaseType, formatVersionLabel, getJiraDescriptions } from 'src/lib/release-utils'\nimport type { ReleaseType } from 'src/lib/release-utils'\nimport type { ToolsExecutionResult } from 'src/types'\n\ninterface WorktreeInfo {\n version: string\n type: ReleaseType\n description: string | null\n}\n\n/**\n * List all release git worktrees with version, type, and Jira description\n */\nexport const worktreesList = async (): Promise<ToolsExecutionResult> => {\n const currentWorktrees = await getCurrentWorktrees('release')\n\n if (currentWorktrees.length === 0) {\n logger.info('\u2139\uFE0F No active worktrees found')\n\n return {\n content: [{ type: 'text', text: JSON.stringify({ worktrees: [], count: 0 }, null, 2) }],\n structuredContent: { worktrees: [], count: 0 },\n }\n }\n\n const [releasePRsInfo, jiraDescriptions] = await Promise.all([getReleasePRsWithInfo(), getJiraDescriptions()])\n\n const releaseTypes = new Map<string, ReleaseType>(\n releasePRsInfo.map((pr) => {\n return [pr.branch, detectReleaseType(pr.title)]\n }),\n )\n\n const worktrees: WorktreeInfo[] = currentWorktrees.map((branch) => {\n const version = branch.replace('release/', '')\n const type = releaseTypes.get(branch) || 'regular'\n const description = jiraDescriptions.get(version) || null\n\n return { version, type, description }\n })\n\n // Log formatted output\n const maxVersionLength = Math.max(\n ...worktrees.map((w) => {\n return w.version.length\n }),\n )\n\n const formattedLines = worktrees.map((worktree) => {\n const label = formatVersionLabel(worktree.version, worktree.type, maxVersionLength)\n\n if (worktree.description) {\n return `${label} ${worktree.description}`\n }\n\n return label\n })\n\n logger.info('\uD83C\uDF3F Active worktrees:')\n logger.info(`\\n${formattedLines.join('\\n')}\\n`)\n\n const structuredContent = {\n worktrees,\n count: worktrees.length,\n }\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(structuredContent, null, 2),\n },\n ],\n structuredContent,\n }\n}\n\n// MCP Tool Registration\nexport const worktreesListMcpTool = {\n name: 'worktrees-list',\n description:\n 'List existing release-branch worktrees with version, release type (regular / hotfix), and Jira fix-version description. Read-only.',\n inputSchema: {},\n outputSchema: {\n worktrees: z\n .array(\n z.object({\n version: z.string().describe('Release version'),\n type: z.enum(['regular', 'hotfix']).describe('Release type'),\n description: z.string().nullable().describe('Jira version description'),\n }),\n )\n .describe('List of all worktrees with details'),\n count: z.number().describe('Number of worktrees'),\n },\n handler: worktreesList,\n}\n", "import checkbox from '@inquirer/checkbox'\nimport confirm from '@inquirer/confirm'\nimport process from 'node:process'\nimport { z } from 'zod/v4'\nimport { $ } from 'zx'\n\nimport { buildCmuxWorkspaceTitle, closeCmuxWorkspaceByTitle } from 'src/integrations/cmux'\nimport { removeFoldersFromCursorWorkspace, resolveCursorWorkspacePath } from 'src/integrations/cursor'\nimport { getReleasePRsWithInfo } from 'src/integrations/gh'\nimport { commandEcho } from 'src/lib/command-echo'\nimport { WORKTREES_DIR_SUFFIX } from 'src/lib/constants'\nimport { getCurrentWorktrees, getProjectRoot, getRepoName } from 'src/lib/git-utils'\nimport { getInfraKitConfig } from 'src/lib/infra-kit-config'\nimport { logger } from 'src/lib/logger'\nimport { detectReleaseType, formatBranchChoices, getJiraDescriptions } from 'src/lib/release-utils'\nimport type { ReleaseType } from 'src/lib/release-utils'\nimport type { RequiredConfirmedOptionArg, ToolsExecutionResult } from 'src/types'\n\n// Constants\ninterface WorktreeManagementArgs extends RequiredConfirmedOptionArg {\n all: boolean\n versions?: string\n}\n\n/**\n * Manage git worktrees for release branches\n * Creates worktrees for active release branches and removes unused ones\n */\nexport const worktreesRemove = async (options: WorktreeManagementArgs): Promise<ToolsExecutionResult> => {\n const { confirmedCommand, all, versions } = options\n\n commandEcho.start('worktrees-remove')\n\n try {\n const currentWorktrees = await getCurrentWorktrees('release')\n\n if (currentWorktrees.length === 0) {\n logger.info('\u2139\uFE0F No active worktrees to remove')\n\n commandEcho.print()\n\n return {\n content: [{ type: 'text', text: JSON.stringify({ removedWorktrees: [], count: 0 }, null, 2) }],\n structuredContent: { removedWorktrees: [], count: 0 },\n }\n }\n\n const projectRoot = await getProjectRoot()\n\n const worktreeDir = `${projectRoot}${WORKTREES_DIR_SUFFIX}`\n\n let selectedReleaseBranches: string[] = []\n\n if (all) {\n selectedReleaseBranches = currentWorktrees\n } else if (versions) {\n selectedReleaseBranches = versions.split(',').map((v) => {\n return `release/v${v.trim()}`\n })\n } else {\n commandEcho.setInteractive()\n\n const [descriptions, prInfo] = await Promise.all([getJiraDescriptions(), getReleasePRsWithInfo()])\n\n const releaseTypes = new Map<string, ReleaseType>(\n prInfo.map((pr) => {\n return [pr.branch, detectReleaseType(pr.title)]\n }),\n )\n\n selectedReleaseBranches = await checkbox({\n required: true,\n message: '\uD83C\uDF3F Select release branches',\n choices: formatBranchChoices({ branches: currentWorktrees, descriptions, types: releaseTypes }),\n })\n }\n\n // Track --all flag if all branches were selected (either via flag or interactively)\n const allSelected = selectedReleaseBranches.length === currentWorktrees.length\n\n if (allSelected) {\n commandEcho.addOption('--all', true)\n } else {\n commandEcho.addOption(\n '--versions',\n selectedReleaseBranches.map((branch) => {\n return branch.replace('release/v', '')\n }),\n )\n }\n\n // Ask for confirmation\n const answer = confirmedCommand\n ? true\n : await confirm({\n message: 'Are you sure you want to proceed with these worktree changes?',\n })\n\n if (!confirmedCommand) {\n commandEcho.setInteractive()\n }\n\n if (!answer) {\n logger.info('Operation cancelled. Exiting...')\n process.exit(0)\n }\n\n // Track --yes flag if confirmation was interactive (user confirmed)\n if (!confirmedCommand) {\n commandEcho.addOption('--yes', true)\n }\n\n const repoName = await getRepoName()\n\n const removedWorktrees = await removeWorktrees({\n branches: selectedReleaseBranches,\n worktreeDir,\n repoName,\n })\n\n await syncCursorWorkspaceOnRemove({ removedWorktrees, worktreeDir, projectRoot })\n\n logResults(removedWorktrees)\n\n commandEcho.print()\n\n const structuredContent = {\n removedWorktrees,\n count: removedWorktrees.length,\n }\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(structuredContent, null, 2),\n },\n ],\n structuredContent,\n }\n } catch (error) {\n logger.error({ error }, '\u274C Error managing worktrees')\n throw error\n }\n}\n\ninterface RemoveWorktreesArgs {\n branches: string[]\n worktreeDir: string\n repoName: string\n}\n\n/**\n * Remove worktrees for the specified branches and whole folder\n */\nconst removeWorktrees = async (args: RemoveWorktreesArgs): Promise<string[]> => {\n const { branches, worktreeDir, repoName } = args\n\n const results = await Promise.allSettled(\n branches.map(async (branch) => {\n const worktreePath = `${worktreeDir}/${branch}`\n\n const title = buildCmuxWorkspaceTitle({ repoName, branch })\n\n await closeCmuxWorkspaceByTitle(title)\n\n await $`git worktree remove ${worktreePath}`\n\n return branch\n }),\n )\n\n const removed: string[] = []\n\n for (const [index, result] of results.entries()) {\n if (result.status === 'fulfilled') {\n removed.push(result.value)\n } else {\n const branch = branches[index]\n\n logger.error({ error: result.reason }, `\u274C Failed to remove worktree for ${branch}`)\n }\n }\n\n if (removed.length === branches.length) {\n await $`git worktree prune`\n await $`rm -rf ${worktreeDir}`\n\n logger.info(`\uD83D\uDDD1\uFE0F Removed worktree folder: ${worktreeDir}`)\n logger.info('')\n }\n\n return removed\n}\n\ninterface SyncCursorWorkspaceOnRemoveArgs {\n removedWorktrees: string[]\n worktreeDir: string\n projectRoot: string\n}\n\n/**\n * Strip removed worktrees from the configured Cursor workspace's `folders` array.\n * No-op if Cursor isn't configured, mode isn't \"workspace\", or no worktrees were removed.\n */\nconst syncCursorWorkspaceOnRemove = async (args: SyncCursorWorkspaceOnRemoveArgs): Promise<void> => {\n const { removedWorktrees, worktreeDir, projectRoot } = args\n\n if (removedWorktrees.length === 0) {\n return\n }\n\n const config = await getInfraKitConfig()\n const cursorConfig = config.ide?.provider === 'cursor' ? config.ide.config : undefined\n\n if (!cursorConfig || cursorConfig.mode !== 'workspace' || !cursorConfig.workspaceConfigPath) {\n return\n }\n\n const workspacePath = resolveCursorWorkspacePath(cursorConfig.workspaceConfigPath, projectRoot)\n\n const folderPaths = removedWorktrees.map((branch) => {\n return `${worktreeDir}/${branch}`\n })\n\n try {\n const { removed } = await removeFoldersFromCursorWorkspace({ workspacePath, folderPaths })\n\n if (removed.length > 0) {\n logger.info(`\u2705 Removed ${removed.length} folder(s) from ${workspacePath}`)\n }\n } catch (error) {\n logger.warn({ error }, `\u26A0\uFE0F Failed to update Cursor workspace at ${workspacePath}`)\n }\n}\n\n/**\n * Log the results of worktree management\n */\nconst logResults = (removed: string[]): void => {\n if (removed.length > 0) {\n logger.info('\u274C Removed worktrees:')\n for (const branch of removed) {\n logger.info(branch)\n }\n logger.info('')\n } else {\n logger.info('\u2139\uFE0F No unused worktrees to remove')\n }\n}\n\n// MCP Tool Registration\nexport const worktreesRemoveMcpTool = {\n name: 'worktrees-remove',\n description:\n 'Remove local git worktrees for release branches. When everything is removed, also runs \"git worktree prune\" and deletes the worktrees directory. When invoked via MCP, pass either \"versions\" (comma-separated) or all=true \u2014 the branch picker is unreachable without a TTY, and the CLI confirmation is auto-skipped for MCP calls, so the caller is responsible for gating.',\n inputSchema: {\n all: z\n .boolean()\n .optional()\n .describe(\n 'Remove every existing worktree. Either \"all\" or \"versions\" must be provided for MCP calls (the interactive picker is unavailable without a TTY). Ignored if \"versions\" is provided.',\n ),\n versions: z\n .string()\n .optional()\n .describe(\n 'Comma-separated release versions to target (e.g. \"1.2.5, 1.2.6\"). Either \"versions\" or all=true must be provided for MCP calls. Overrides \"all\" when set.',\n ),\n },\n outputSchema: {\n removedWorktrees: z.array(z.string()).describe('List of removed git worktree branches'),\n count: z.number().describe('Number of git worktrees removed'),\n },\n handler: worktreesRemove,\n}\n", "import confirm from '@inquirer/confirm'\nimport process from 'node:process'\nimport { z } from 'zod/v4'\nimport { $ } from 'zx'\n\nimport { buildCmuxWorkspaceTitle, closeCmuxWorkspaceByTitle } from 'src/integrations/cmux'\nimport { removeFoldersFromCursorWorkspace, resolveCursorWorkspacePath } from 'src/integrations/cursor'\nimport { getReleasePRs } from 'src/integrations/gh'\nimport { commandEcho } from 'src/lib/command-echo'\nimport { WORKTREES_DIR_SUFFIX } from 'src/lib/constants'\nimport { getCurrentWorktrees, getProjectRoot, getRepoName } from 'src/lib/git-utils'\nimport { getInfraKitConfig } from 'src/lib/infra-kit-config'\nimport { logger } from 'src/lib/logger'\nimport type { RequiredConfirmedOptionArg, ToolsExecutionResult } from 'src/types'\n\n// Constants\nconst RELEASE_BRANCH_PREFIX = 'release/v'\n\ninterface WorktreeSyncArgs extends RequiredConfirmedOptionArg {}\n\n/**\n * Manage git worktrees for release branches.\n *\n * Creates worktrees for active release branches and removes unused ones\n */\nexport const worktreesSync = async (options: WorktreeSyncArgs): Promise<ToolsExecutionResult> => {\n const { confirmedCommand } = options\n\n commandEcho.start('worktrees-sync')\n\n try {\n const currentWorktrees = await getCurrentWorktrees('release')\n const projectRoot = await getProjectRoot()\n\n const worktreeDir = `${projectRoot}${WORKTREES_DIR_SUFFIX}`\n\n const releasePRsList = await getReleasePRs()\n\n // Ask for confirmation\n const answer = confirmedCommand\n ? true\n : await confirm({\n message: 'Are you sure you want to proceed with these worktree changes?',\n })\n\n if (!confirmedCommand) {\n commandEcho.setInteractive()\n }\n\n if (!answer) {\n logger.info('Operation cancelled. Exiting...')\n process.exit(0)\n }\n\n // Track --yes flag if confirmation was interactive (user confirmed)\n if (!confirmedCommand) {\n commandEcho.addOption('--yes', true)\n }\n\n const { branchesToRemove } = categorizeWorktrees({\n releasePRsList,\n currentWorktrees,\n })\n\n const repoName = await getRepoName()\n\n const removedWorktrees = await removeWorktrees({\n branches: branchesToRemove,\n worktreeDir,\n repoName,\n })\n\n await syncCursorWorkspaceOnRemove({ removedWorktrees, worktreeDir, projectRoot })\n\n logResults(removedWorktrees)\n\n commandEcho.print()\n\n const structuredContent = {\n removedWorktrees,\n count: removedWorktrees.length,\n }\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(structuredContent, null, 2),\n },\n ],\n structuredContent,\n }\n } catch (error) {\n logger.error({ error }, '\u274C Error managing worktrees')\n throw error\n }\n}\n\ninterface CategorizeWorktreesArgs {\n releasePRsList: string[]\n currentWorktrees: string[]\n}\n\n/**\n * Categorize worktrees into those that need to be created or removed\n */\nconst categorizeWorktrees = (args: CategorizeWorktreesArgs): { branchesToRemove: string[] } => {\n const { releasePRsList, currentWorktrees } = args\n\n const currentBranchNames = currentWorktrees.filter((branch) => {\n return branch.startsWith(RELEASE_BRANCH_PREFIX)\n })\n\n const branchesToRemove = currentBranchNames.filter((branch) => {\n return !releasePRsList.includes(branch)\n })\n\n return { branchesToRemove }\n}\n\ninterface RemoveWorktreesArgs {\n branches: string[]\n worktreeDir: string\n repoName: string\n}\n\n/**\n * Remove worktrees for the specified branches and close their cmux workspaces\n */\nconst removeWorktrees = async (args: RemoveWorktreesArgs): Promise<string[]> => {\n const { branches, worktreeDir, repoName } = args\n\n const removed: string[] = []\n\n for (const branch of branches) {\n try {\n const worktreePath = `${worktreeDir}/${branch}`\n\n const title = buildCmuxWorkspaceTitle({ repoName, branch })\n\n await closeCmuxWorkspaceByTitle(title)\n\n await $`git worktree remove ${worktreePath}`\n removed.push(branch)\n } catch (error) {\n logger.error({ error, branch }, `\u274C Failed to remove worktree for ${branch}`)\n }\n }\n\n return removed\n}\n\ninterface SyncCursorWorkspaceOnRemoveArgs {\n removedWorktrees: string[]\n worktreeDir: string\n projectRoot: string\n}\n\n/**\n * Strip removed worktrees from the configured Cursor workspace's `folders` array.\n * No-op if Cursor isn't configured, mode isn't \"workspace\", or no worktrees were removed.\n */\nconst syncCursorWorkspaceOnRemove = async (args: SyncCursorWorkspaceOnRemoveArgs): Promise<void> => {\n const { removedWorktrees, worktreeDir, projectRoot } = args\n\n if (removedWorktrees.length === 0) {\n return\n }\n\n const config = await getInfraKitConfig()\n const cursorConfig = config.ide?.provider === 'cursor' ? config.ide.config : undefined\n\n if (!cursorConfig || cursorConfig.mode !== 'workspace' || !cursorConfig.workspaceConfigPath) {\n return\n }\n\n const workspacePath = resolveCursorWorkspacePath(cursorConfig.workspaceConfigPath, projectRoot)\n\n const folderPaths = removedWorktrees.map((branch) => {\n return `${worktreeDir}/${branch}`\n })\n\n try {\n const { removed: removedEntries } = await removeFoldersFromCursorWorkspace({ workspacePath, folderPaths })\n\n if (removedEntries.length > 0) {\n logger.info(`\u2705 Removed ${removedEntries.length} folder(s) from ${workspacePath}`)\n }\n } catch (error) {\n logger.warn({ error }, `\u26A0\uFE0F Failed to update Cursor workspace at ${workspacePath}`)\n }\n}\n\n/**\n * Log the results of worktree management\n */\nconst logResults = (removed: string[]): void => {\n if (removed.length > 0) {\n logger.info('\u274C Removed worktrees:')\n for (const branch of removed) {\n logger.info(branch)\n }\n logger.info('')\n } else {\n logger.info('\u2139\uFE0F No unused worktrees to remove')\n }\n}\n\n// MCP Tool Registration\nexport const worktreesSyncMcpTool = {\n name: 'worktrees-sync',\n description:\n 'Remove worktrees whose release PR is no longer open (stale cleanup). Only removes \u2014 never creates; use worktrees-add to create worktrees for new releases. The CLI confirmation is auto-skipped for MCP calls, so the caller is responsible for gating.',\n inputSchema: {},\n outputSchema: {\n removedWorktrees: z.array(z.string()).describe('List of removed worktree branches'),\n count: z.number().describe('Number of worktrees removed during sync'),\n },\n handler: worktreesSync,\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["select", "Separator", "Command", "Option", "process", "fs", "os", "path", "z", "$", "fs", "os", "path", "process", "pino", "pretty", "initLoggerCLI", "logLevel", "process", "ignoreFields", "pino", "pretty", "logger", "MARKER_START", "MARKER_END", "LEGACY_PAIRED", "LEGACY_SINGLE", "init", "zshrcPath", "path", "os", "shellBlock", "buildShellBlock", "fs", "content", "cleaned", "removeExistingBlock", "logger", "isBlockLine", "line", "removeBetween", "start", "end", "startIdx", "endIdx", "before", "after", "result", "legacyResult", "legacyIdx", "afterLines", "i", "remaining", "runCmd", "path", "$", "getCurrentWorktrees", "type", "worktreeLines", "worktreePredicateMap", "releaseWorktreePredicate", "featureWorktreePredicate", "branch", "line", "parts", "getProjectRoot", "getRepoName", "projectRoot", "fs", "path", "yaml", "z", "INFRA_KIT_CONFIG_FILE", "INFRA_KIT_LOCAL_CONFIG_FILE", "dopplerEnvManagementSchema", "z", "envManagementSchema", "cursorIdeConfigSchema", "v", "cursorIdeSchema", "ideSchema", "jiraTaskManagerSchema", "taskManagerSchema", "infraKitConfigSchema", "infraKitLocalConfigSchema", "cached", "getInfraKitConfig", "projectRoot", "getProjectRoot", "mainPath", "path", "localPath", "mainStat", "fs", "localStat", "statIfExists", "mainMtimeMs", "localMtimeMs", "mainRaw", "mainParsed", "yaml", "merged", "localRaw", "localParsedRaw", "localResult", "result", "resetInfraKitConfigCache", "filePath", "LOCAL_CONFIG_FILE", "checkCommand", "name", "command", "successMsg", "failMsg", "$", "checkZshrcInitialized", "zshrcPath", "path", "os", "fs", "content", "startIdx", "MARKER_START", "endIdx", "MARKER_END", "installedBlock", "expectedBlock", "buildShellBlock", "checkPnpmWorkspaceVirtualStore", "root", "getProjectRoot", "yamlPath", "err", "checkInfraKitConfigValid", "resetInfraKitConfigCache", "getInfraKitConfig", "checkLocalConfigGitignored", "result", "doctor", "checks", "logger", "check", "icon", "structuredContent", "c", "doctorMcpTool", "z", "fs", "path", "process", "z", "fs", "os", "path", "process", "ENV_LOAD_FILE", "ENV_CLEAR_FILE", "INFRA_KIT_SESSION_VAR", "INFRA_KIT_ENV_CONFIG_VAR", "INFRA_KIT_ENV_PROJECT_VAR", "INFRA_KIT_ENV_LOADED_AT_VAR", "ENV_VAR_LINE_PATTERN", "parseVarNamesFromEnvFile", "filePath", "content", "names", "line", "match", "getCacheRoot", "xdg", "base", "getSessionCacheDir", "session", "atomicWriteFileSync", "mode", "tmpPath", "error", "WORKTREES_DIR_SUFFIX", "envClear", "cacheDir", "getSessionCacheDir", "envLoadPath", "path", "ENV_LOAD_FILE", "fs", "varNames", "parseVarNamesFromEnvFile", "unsetLines", "v", "INFRA_KIT_ENV_CONFIG_VAR", "INFRA_KIT_ENV_PROJECT_VAR", "INFRA_KIT_ENV_LOADED_AT_VAR", "clearFilePath", "ENV_CLEAR_FILE", "atomicWriteFileSync", "process", "structuredContent", "envClearMcpTool", "z", "z", "getDopplerProject", "envManagement", "getInfraKitConfig", "envList", "project", "getDopplerProject", "environments", "getInfraKitConfig", "logger", "env", "structuredContent", "envListMcpTool", "z", "select", "Buffer", "fs", "path", "process", "z", "$", "$", "validateDopplerCliAndAuth", "error", "createCommandEcho", "commandName", "options", "isInteractive", "name", "flag", "value", "formattedOptions", "opt", "logger", "commandEcho", "envLoad", "args", "validateDopplerCliAndAuth", "config", "commandEcho", "selectedConfig", "environments", "getInfraKitConfig", "select", "env", "process", "project", "getDopplerProject", "envContent", "downloadDopplerSecrets", "assertValidEnvContent", "loadedAt", "envFileLines", "INFRA_KIT_ENV_CONFIG_VAR", "shellSingleQuote", "INFRA_KIT_ENV_PROJECT_VAR", "INFRA_KIT_ENV_LOADED_AT_VAR", "cacheDir", "getSessionCacheDir", "envFilePath", "path", "ENV_LOAD_FILE", "fs", "atomicWriteFileSync", "varCount", "countEnvVarLines", "structuredContent", "DOPPLER_MAX_OUTPUT_BYTES", "DOPPLER_DOWNLOAD_TIMEOUT_MS", "prevQuiet", "$", "result", "assertDopplerOutputSize", "stdout", "bytes", "Buffer", "content", "line", "ENV_VAR_LINE_PATTERN", "SHELL_DIRECTIVE_LINES", "value", "trimmed", "envLoadMcpTool", "z", "path", "process", "z", "envStatus", "validateDopplerCliAndAuth", "logger", "cacheDir", "getSessionCacheDir", "sessionId", "process", "INFRA_KIT_SESSION_VAR", "envLoadPath", "path", "ENV_LOAD_FILE", "sessionLoadedCount", "sessionTotalCount", "sessionConfig", "INFRA_KIT_ENV_CONFIG_VAR", "sessionProject", "INFRA_KIT_ENV_PROJECT_VAR", "sessionLoadedAt", "INFRA_KIT_ENV_LOADED_AT_VAR", "varNames", "parseVarNamesFromEnvFile", "v", "loadedAtDisplay", "missing", "structuredContent", "envStatusMcpTool", "z", "checkbox", "confirm", "process", "z", "$", "$", "process", "$", "$", "process", "createJiraVersion", "params", "config", "baseUrl", "token", "email", "projectId", "requestBody", "url", "credentials", "response", "errorText", "logger", "error", "getProjectVersions", "findVersionByName", "versionName", "v", "updateJiraVersion", "deliverJiraRelease", "version", "loadJiraConfig", "process", "projectIdStr", "missingVars", "errorMessage", "loadJiraConfigOptional", "getBaseBranch", "type", "prepareGitForRelease", "baseBranch", "$", "createSingleRelease", "args", "version", "jiraConfig", "description", "versionName", "result", "createJiraVersion", "jiraVersionUrl", "releaseInfo", "createReleaseBranch", "getJiraDescriptions", "descriptions", "loadJiraConfigOptional", "versions", "getProjectVersions", "formatVersionLabel", "maxVersionLength", "padding", "tag", "detectReleaseType", "title", "formatBranchChoices", "branches", "types", "versionNames", "b", "maxLen", "v", "branch", "i", "desc", "name", "parseVersion", "versionStr", "sortVersions", "versions", "a", "b", "majA", "minA", "patchA", "majB", "minB", "patchB", "fetchAllReleasePRs", "releasePRs", "$", "hotfixPRs", "all", "seen", "pr", "getReleasePRs", "prs", "logger", "process", "sortVersions", "error", "getReleasePRsWithInfo", "sortedBranches", "prByBranch", "branch", "createReleaseBranch", "args", "version", "jiraVersionUrl", "type", "description", "titlePrefix", "baseBranch", "getBaseBranch", "branchName", "body", "prLink", "ghMergeDev", "args", "all", "confirmedCommand", "commandEcho", "releasePRsList", "getReleasePRsWithInfo", "pr", "detectReleaseType", "logger", "selectedReleaseBranches", "descriptions", "getJiraDescriptions", "checkbox", "formatBranchChoices", "branch", "answer", "confirm", "process", "$", "failedBranches", "mergeDev", "structuredContent", "error", "ghMergeDevMcpTool", "z", "confirm", "select", "process", "z", "ghReleaseDeliver", "args", "version", "confirmedCommand", "commandEcho", "releasePRsInfo", "getReleasePRsWithInfo", "branches", "pr", "releaseTypes", "detectReleaseType", "selectedReleaseBranch", "descriptions", "getJiraDescriptions", "select", "formatBranchChoices", "selectedVersion", "prInfo", "logger", "process", "releaseType", "answer", "confirm", "jiraConfig", "loadJiraConfigOptional", "versionName", "deliverJiraRelease", "error", "structuredContent", "ghReleaseDeliverMcpTool", "z", "select", "process", "z", "$", "ghReleaseDeployAll", "args", "version", "env", "skipTerraform", "commandEcho", "selectedReleaseBranch", "releasePRsInfo", "getReleasePRsWithInfo", "branches", "pr", "releaseTypes", "detectReleaseType", "descriptions", "getJiraDescriptions", "select", "formatBranchChoices", "selectedVersion", "environments", "getInfraKitConfig", "selectedEnv", "logger", "process", "shouldSkipTerraform", "$", "structuredContent", "error", "ghReleaseDeployAllMcpTool", "z", "checkbox", "select", "fs", "resolve", "process", "yaml", "z", "$", "ghReleaseDeploySelected", "args", "version", "env", "services", "skipTerraform", "commandEcho", "selectedReleaseBranch", "releasePRsInfo", "getReleasePRsWithInfo", "branches", "pr", "releaseTypes", "detectReleaseType", "descriptions", "getJiraDescriptions", "select", "formatBranchChoices", "selectedVersion", "environments", "getInfraKitConfig", "selectedEnv", "logger", "process", "availableServices", "parseServicesFromWorkflow", "selectedServices", "checkbox", "svc", "invalidServices", "shouldSkipTerraform", "$", "serviceFlags", "structuredContent", "error", "projectRoot", "getProjectRoot", "workflowPath", "resolve", "content", "fs", "inputs", "yaml", "key", "value", "ghReleaseDeploySelectedMcpTool", "z", "z", "ghReleaseList", "releases", "getReleasePRsWithInfo", "pr", "detectReleaseType", "jiraDescriptions", "getJiraDescriptions", "maxVersionLength", "r", "formattedLines", "release", "label", "formatVersionLabel", "description", "logger", "structuredContent", "ghReleaseListMcpTool", "z", "confirm", "select", "process", "z", "$", "question", "releaseCreate", "args", "inputVersion", "inputDescription", "inputType", "confirmedCommand", "inputCheckout", "commandEcho", "version", "description", "type", "checkout", "jiraConfig", "loadJiraConfig", "question", "logger", "process", "trimmedVersion", "select", "answer", "confirm", "prepareGitForRelease", "release", "createSingleRelease", "$", "structuredContent", "releaseCreateMcpTool", "z", "confirm", "select", "process", "z", "question", "resolveInputs", "args", "inputVersions", "inputType", "confirmedCommand", "versionInput", "type", "commandEcho", "question", "versionsList", "version", "logger", "process", "select", "answer", "confirm", "releaseCreateBatch", "jiraConfig", "loadJiraConfig", "prepareGitForRelease", "releases", "failedReleases", "release", "createSingleRelease", "error", "errorMessage", "successCount", "failureCount", "structuredContent", "r", "releaseCreateBatchMcpTool", "z", "z", "package_default", "version", "cliVersion", "package_default", "logger", "structuredContent", "versionMcpTool", "z", "checkbox", "confirm", "select", "process", "z", "$", "$", "closeCmuxWorkspaceByTitle", "title", "listOutput", "$", "ref", "findWorkspaceRefByTitle", "error", "logger", "output", "rawLine", "match", "$", "openCmuxWorkspaceWithLayout", "args", "cwd", "title", "newWorkspaceOutput", "workspaceRef", "parseWorkspaceRef", "surfacesOutput", "leftTopRef", "parseFirstSurfaceRef", "output", "match", "buildCmuxWorkspaceTitle", "args", "repoName", "branch", "version", "fs", "path", "addFoldersToCursorWorkspace", "args", "workspacePath", "folderPaths", "workspaceDir", "raw", "error", "parsed", "existingFolders", "existingAbsolutePaths", "entry", "added", "skipped", "folderPath", "absolutePath", "relativePath", "fs", "path", "removeFoldersFromCursorWorkspace", "args", "workspacePath", "folderPaths", "workspaceDir", "raw", "error", "parsed", "existingFolders", "targetAbsolutePaths", "folderPath", "removedAbsolutePaths", "filteredFolders", "entry", "entryAbsolutePath", "removed", "notFound", "absolutePath", "path", "resolveCursorWorkspacePath", "configValue", "projectRoot", "FEATURE_DIR", "RELEASE_DIR", "RELEASE_BRANCH_PREFIX", "CURSOR_MODES", "worktreesAdd", "options", "confirmedCommand", "all", "versions", "cursor", "githubDesktop", "cmux", "commandEcho", "currentWorktrees", "getCurrentWorktrees", "projectRoot", "getProjectRoot", "worktreeDir", "WORKTREES_DIR_SUFFIX", "ensureWorktreeDirectory", "selectedReleaseBranches", "v", "releasePRsInfo", "getReleasePRsWithInfo", "releasePRsList", "pr", "logger", "releaseTypes", "detectReleaseType", "descriptions", "getJiraDescriptions", "checkbox", "formatBranchChoices", "branch", "answer", "confirm", "process", "cursorMode", "select", "openInGithubDesktop", "openInCmux", "branchesToCreate", "categorizeWorktrees", "createdWorktrees", "createWorktrees", "logResults", "config", "getInfraKitConfig", "cursorConfig", "workspacePath", "resolveCursorWorkspacePath", "folderPaths", "added", "skipped", "addFoldersToCursorWorkspace", "skippedSuffix", "$", "repoName", "getRepoName", "title", "buildCmuxWorkspaceTitle", "openCmuxWorkspaceWithLayout", "structuredContent", "error", "args", "currentBranchNames", "branches", "results", "worktreePath", "created", "index", "result", "worktreesAddMcpTool", "z", "z", "worktreesList", "currentWorktrees", "getCurrentWorktrees", "logger", "releasePRsInfo", "jiraDescriptions", "getReleasePRsWithInfo", "getJiraDescriptions", "releaseTypes", "pr", "detectReleaseType", "worktrees", "branch", "version", "type", "description", "maxVersionLength", "w", "formattedLines", "worktree", "label", "formatVersionLabel", "structuredContent", "worktreesListMcpTool", "z", "checkbox", "confirm", "process", "z", "$", "worktreesRemove", "options", "confirmedCommand", "all", "versions", "commandEcho", "currentWorktrees", "getCurrentWorktrees", "logger", "projectRoot", "getProjectRoot", "worktreeDir", "WORKTREES_DIR_SUFFIX", "selectedReleaseBranches", "v", "descriptions", "prInfo", "getJiraDescriptions", "getReleasePRsWithInfo", "releaseTypes", "pr", "detectReleaseType", "checkbox", "formatBranchChoices", "branch", "answer", "confirm", "process", "repoName", "getRepoName", "removedWorktrees", "removeWorktrees", "syncCursorWorkspaceOnRemove", "logResults", "structuredContent", "error", "args", "branches", "results", "worktreePath", "title", "buildCmuxWorkspaceTitle", "closeCmuxWorkspaceByTitle", "$", "removed", "index", "result", "config", "getInfraKitConfig", "cursorConfig", "workspacePath", "resolveCursorWorkspacePath", "folderPaths", "removeFoldersFromCursorWorkspace", "worktreesRemoveMcpTool", "z", "confirm", "process", "z", "$", "RELEASE_BRANCH_PREFIX", "worktreesSync", "options", "confirmedCommand", "commandEcho", "currentWorktrees", "getCurrentWorktrees", "projectRoot", "getProjectRoot", "worktreeDir", "WORKTREES_DIR_SUFFIX", "releasePRsList", "getReleasePRs", "answer", "confirm", "logger", "process", "branchesToRemove", "categorizeWorktrees", "repoName", "getRepoName", "removedWorktrees", "removeWorktrees", "syncCursorWorkspaceOnRemove", "logResults", "structuredContent", "error", "args", "branch", "branches", "removed", "worktreePath", "title", "buildCmuxWorkspaceTitle", "closeCmuxWorkspaceByTitle", "$", "config", "getInfraKitConfig", "cursorConfig", "workspacePath", "resolveCursorWorkspacePath", "folderPaths", "removedEntries", "removeFoldersFromCursorWorkspace", "worktreesSyncMcpTool", "z", "program", "Command", "normalizeCursorMode", "value", "CURSOR_MODES", "runProgram", "argv", "error", "message", "logger", "process", "options", "ghMergeDev", "ghReleaseList", "Option", "releaseCreate", "releaseCreateBatch", "ghReleaseDeployAll", "ghReleaseDeploySelected", "ghReleaseDeliver", "worktreesSync", "worktreesAdd", "worktreesList", "worktreesRemove", "doctor", "version", "envStatus", "envList", "init", "envLoad", "envClear", "releaseCommands", "worktreeCommands", "envCommands", "commandMap", "cmd", "allNames", "maxLen", "n", "toChoices", "names", "selected", "select", "Separator"]
7
7
  }