@episoda/mcp 0.1.11 → 0.1.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +218 -143
- package/dist/cli.js.map +1 -1
- package/dist/dev-server.js +77 -41
- package/dist/dev-server.js.map +1 -1
- package/dist/git-server.js +67 -30
- package/dist/git-server.js.map +1 -1
- package/dist/workflow-server.js +124 -73
- package/dist/workflow-server.js.map +1 -1
- package/package.json +1 -1
package/dist/git-server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/git-server.ts","../src/runtime-config.ts"],"sourcesContent":["/**\n * EP908: Episoda Git MCP Server\n *\n * MCP server for Claude Code agents to perform git operations on dev environments.\n * Provides tools for:\n * - Repository status and info (status, log, diff, branch)\n * - Staging and commits (add, commit, reset)\n * - Remote operations (push, pull, fetch)\n * - Branch management (checkout, create, delete, merge)\n *\n * Usage:\n * npx -y @episoda/mcp git\n *\n * Required environment variables:\n * EPISODA_API_URL - Base URL for Episoda API (e.g., https://episoda.dev)\n * EPISODA_SESSION_TOKEN - Bearer token for API authentication\n *\n * Optional environment variables:\n * MODULE_UID - Module UID (preferred, e.g., EP123) or provide moduleUid per tool call\n * DEV_ENVIRONMENT_ID - UUID of the dev environment (legacy fallback)\n * EPISODA_PROJECT_ID - Project ID (for scoped requests)\n * EPISODA_WORKSPACE_ID - Workspace ID (for scoped requests)\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'\nimport { z } from 'zod'\nimport { hydrateRuntimeConfig } from './runtime-config.js'\n\n// Environment configuration\nlet EPISODA_API_URL = process.env.EPISODA_API_URL || 'https://episoda.dev'\nlet EPISODA_SESSION_TOKEN = process.env.EPISODA_SESSION_TOKEN || ''\nconst DEV_ENVIRONMENT_ID = process.env.DEV_ENVIRONMENT_ID || ''\nconst MODULE_UID = process.env.MODULE_UID || ''\nlet EPISODA_PROJECT_ID = process.env.EPISODA_PROJECT_ID || ''\nlet EPISODA_WORKSPACE_ID = process.env.EPISODA_WORKSPACE_ID || ''\n\nconst targetSchema = {\n moduleUid: z.string().optional().describe('Module UID to target (overrides server default)')\n}\n\ninterface ExecResponse {\n success: boolean\n data?: {\n stdout: string\n stderr: string\n exitCode: number\n timedOut?: boolean\n }\n error?: string\n}\n\n/**\n * Execute a command on the dev environment via unified API\n */\nasync function execCommand(\n command: string,\n options: { cwd?: string; timeout?: number; moduleUid?: string } = {}\n): Promise<ExecResponse> {\n const { cwd, timeout = 30000, moduleUid } = options\n\n const target = moduleUid || MODULE_UID || DEV_ENVIRONMENT_ID\n if (!target) {\n return {\n success: false,\n error: 'Module target missing. Provide moduleUid in the tool call or set MODULE_UID/DEV_ENVIRONMENT_ID.'\n }\n }\n const url = `${EPISODA_API_URL}/api/dev/${target}/exec`\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${EPISODA_SESSION_TOKEN}`\n }\n if (EPISODA_PROJECT_ID) {\n headers['x-project-id'] = EPISODA_PROJECT_ID\n }\n if (EPISODA_WORKSPACE_ID) {\n headers['x-workspace-id'] = EPISODA_WORKSPACE_ID\n }\n\n const response = await fetch(url, {\n method: 'POST',\n headers,\n body: JSON.stringify({ command, cwd, timeout })\n })\n\n if (!response.ok) {\n const text = await response.text()\n return { success: false, error: `API error ${response.status}: ${text}` }\n }\n\n const result = await response.json()\n return result\n}\n\n/**\n * Helper to format git command output for MCP response\n */\nfunction formatGitOutput(result: ExecResponse, errorPrefix: string = 'Git error'): {\n content: Array<{ type: 'text'; text: string }>\n isError?: boolean\n} {\n if (!result.success || !result.data) {\n return {\n content: [{ type: 'text', text: `${errorPrefix}: ${result.error || 'Unknown error'}` }],\n isError: true\n }\n }\n\n const { stdout, stderr, exitCode } = result.data\n\n if (exitCode !== 0) {\n const errorOutput = stderr || stdout || 'Command failed'\n return {\n content: [{ type: 'text', text: `${errorPrefix} (exit ${exitCode}):\\n${errorOutput}` }],\n isError: true\n }\n }\n\n return {\n content: [{ type: 'text', text: stdout || '(no output)' }]\n }\n}\n\n// Create MCP server\nconst server = new McpServer({\n name: 'episoda-git',\n version: '1.0.0'\n}, {\n capabilities: {\n tools: {}\n },\n instructions: `\n Episoda Git MCP Server\n\n This server provides git operations for dev environments (cloud VMs or local machines).\n All commands are executed in the context of the configured dev environment.\n You may pass moduleUid per call to target a specific module.\n\n Categories:\n - Status & Info: git_status, git_log, git_diff, git_show, git_branch_list\n - Staging: git_add, git_reset\n - Commits: git_commit\n - Remote: git_push, git_pull, git_fetch\n - Branches: git_checkout, git_branch_create, git_branch_delete, git_merge\n - Stash: git_stash, git_stash_pop, git_stash_list\n - Worktrees (EP944): git_worktree_list, git_worktree_add, git_worktree_remove, git_worktree_prune\n\n Worktrees allow multiple working directories to share a single repository,\n enabling parallel development on multiple branches/modules simultaneously.\n `\n})\n\n// ============================================\n// Status & Info Tools\n// ============================================\n\nserver.registerTool(\n 'git_status',\n {\n description: 'Show the working tree status (staged, unstaged, untracked files)',\n inputSchema: {\n ...targetSchema,\n cwd: z.string().optional().describe('Working directory path (defaults to repo root)')\n }\n },\n async (args) => {\n const result = await execCommand('git status', { cwd: args.cwd, moduleUid: args.moduleUid })\n return formatGitOutput(result, 'Failed to get git status')\n }\n)\n\nserver.registerTool(\n 'git_log',\n {\n description: 'Show commit logs',\n inputSchema: {\n ...targetSchema,\n count: z.number().optional().describe('Number of commits to show (default: 10)'),\n oneline: z.boolean().optional().describe('Use one-line format (default: true)'),\n branch: z.string().optional().describe('Branch name (default: current branch)'),\n cwd: z.string().optional().describe('Working directory path')\n }\n },\n async (args) => {\n const count = args.count || 10\n const format = args.oneline !== false ? '--oneline' : '--format=medium'\n const branch = args.branch || ''\n\n const result = await execCommand(\n `git log ${format} -n ${count} ${branch}`.trim(),\n { cwd: args.cwd, moduleUid: args.moduleUid }\n )\n return formatGitOutput(result, 'Failed to get git log')\n }\n)\n\nserver.registerTool(\n 'git_diff',\n {\n description: 'Show changes between commits, commit and working tree, etc.',\n inputSchema: {\n ...targetSchema,\n staged: z.boolean().optional().describe('Show staged changes (--cached)'),\n file: z.string().optional().describe('Specific file to diff'),\n commit: z.string().optional().describe('Compare against specific commit'),\n cwd: z.string().optional().describe('Working directory path')\n }\n },\n async (args) => {\n let cmd = 'git diff'\n if (args.staged) cmd += ' --cached'\n if (args.commit) cmd += ` ${args.commit}`\n if (args.file) cmd += ` -- ${args.file}`\n\n const result = await execCommand(cmd, { cwd: args.cwd, moduleUid: args.moduleUid })\n return formatGitOutput(result, 'Failed to get diff')\n }\n)\n\nserver.registerTool(\n 'git_show',\n {\n description: 'Show details of a specific commit',\n inputSchema: {\n ...targetSchema,\n commit: z.string().describe('Commit hash or reference (e.g., HEAD, abc123)'),\n stat: z.boolean().optional().describe('Show diffstat only'),\n cwd: z.string().optional().describe('Working directory path')\n }\n },\n async (args) => {\n let cmd = `git show ${args.commit}`\n if (args.stat) cmd += ' --stat'\n\n const result = await execCommand(cmd, { cwd: args.cwd, moduleUid: args.moduleUid })\n return formatGitOutput(result, 'Failed to show commit')\n }\n)\n\nserver.registerTool(\n 'git_branch_list',\n {\n description: 'List branches',\n inputSchema: {\n ...targetSchema,\n all: z.boolean().optional().describe('Show all branches including remotes'),\n remote: z.boolean().optional().describe('Show only remote branches'),\n cwd: z.string().optional().describe('Working directory path')\n }\n },\n async (args) => {\n let cmd = 'git branch'\n if (args.all) cmd += ' -a'\n else if (args.remote) cmd += ' -r'\n\n const result = await execCommand(cmd, { cwd: args.cwd, moduleUid: args.moduleUid })\n return formatGitOutput(result, 'Failed to list branches')\n }\n)\n\n// ============================================\n// Staging Tools\n// ============================================\n\nserver.registerTool(\n 'git_add',\n {\n description: 'Add file contents to the staging area',\n inputSchema: {\n ...targetSchema,\n files: z.array(z.string()).describe('Files to add (use [\".\"] for all)'),\n cwd: z.string().optional().describe('Working directory path')\n }\n },\n async (args) => {\n const files = args.files.map(f => `\"${f}\"`).join(' ')\n const result = await execCommand(`git add ${files}`, { cwd: args.cwd, moduleUid: args.moduleUid })\n\n if (!result.success || (result.data && result.data.exitCode !== 0)) {\n return formatGitOutput(result, 'Failed to add files')\n }\n\n return {\n content: [{ type: 'text', text: `Added ${args.files.length} file(s) to staging area` }]\n }\n }\n)\n\nserver.registerTool(\n 'git_reset',\n {\n description: 'Unstage files or reset to a commit',\n inputSchema: {\n ...targetSchema,\n files: z.array(z.string()).optional().describe('Files to unstage'),\n hard: z.boolean().optional().describe('Hard reset (WARNING: discards changes)'),\n commit: z.string().optional().describe('Commit to reset to'),\n cwd: z.string().optional().describe('Working directory path')\n }\n },\n async (args) => {\n let cmd = 'git reset'\n if (args.hard) cmd += ' --hard'\n if (args.commit) cmd += ` ${args.commit}`\n if (args.files && args.files.length > 0) {\n cmd += ' -- ' + args.files.map(f => `\"${f}\"`).join(' ')\n }\n\n const result = await execCommand(cmd, { cwd: args.cwd, moduleUid: args.moduleUid })\n return formatGitOutput(result, 'Failed to reset')\n }\n)\n\n// ============================================\n// Commit Tools\n// ============================================\n\nserver.registerTool(\n 'git_commit',\n {\n description: 'Record changes to the repository',\n inputSchema: {\n ...targetSchema,\n message: z.string().describe('Commit message'),\n all: z.boolean().optional().describe('Stage all modified files before commit (-a)'),\n amend: z.boolean().optional().describe('Amend the previous commit'),\n cwd: z.string().optional().describe('Working directory path')\n }\n },\n async (args) => {\n // Escape message for shell\n const escapedMessage = args.message.replace(/'/g, \"'\\\\''\")\n\n let cmd = `git commit -m '${escapedMessage}'`\n if (args.all) cmd = cmd.replace('git commit', 'git commit -a')\n if (args.amend) cmd += ' --amend'\n\n const result = await execCommand(cmd, { cwd: args.cwd, moduleUid: args.moduleUid })\n return formatGitOutput(result, 'Failed to commit')\n }\n)\n\n// ============================================\n// Remote Tools\n// ============================================\n\nserver.registerTool(\n 'git_push',\n {\n description: 'Push commits to remote repository',\n inputSchema: {\n ...targetSchema,\n remote: z.string().optional().describe('Remote name (default: origin)'),\n branch: z.string().optional().describe('Branch name'),\n force: z.boolean().optional().describe('Force push (use with caution!)'),\n setUpstream: z.boolean().optional().describe('Set upstream tracking (-u)'),\n cwd: z.string().optional().describe('Working directory path')\n }\n },\n async (args) => {\n let cmd = 'git push'\n if (args.setUpstream) cmd += ' -u'\n if (args.force) cmd += ' --force-with-lease' // Safer than --force\n if (args.remote) cmd += ` ${args.remote}`\n if (args.branch) cmd += ` ${args.branch}`\n\n const result = await execCommand(cmd, { cwd: args.cwd, timeout: 60000, moduleUid: args.moduleUid })\n return formatGitOutput(result, 'Failed to push')\n }\n)\n\nserver.registerTool(\n 'git_pull',\n {\n description: 'Fetch and integrate changes from remote',\n inputSchema: {\n ...targetSchema,\n remote: z.string().optional().describe('Remote name (default: origin)'),\n branch: z.string().optional().describe('Branch name'),\n rebase: z.boolean().optional().describe('Rebase instead of merge'),\n cwd: z.string().optional().describe('Working directory path')\n }\n },\n async (args) => {\n let cmd = 'git pull'\n if (args.rebase) cmd += ' --rebase'\n if (args.remote) cmd += ` ${args.remote}`\n if (args.branch) cmd += ` ${args.branch}`\n\n const result = await execCommand(cmd, { cwd: args.cwd, timeout: 60000, moduleUid: args.moduleUid })\n return formatGitOutput(result, 'Failed to pull')\n }\n)\n\nserver.registerTool(\n 'git_fetch',\n {\n description: 'Download objects and refs from remote',\n inputSchema: {\n ...targetSchema,\n remote: z.string().optional().describe('Remote name (default: all remotes)'),\n prune: z.boolean().optional().describe('Remove deleted remote branches'),\n cwd: z.string().optional().describe('Working directory path')\n }\n },\n async (args) => {\n let cmd = 'git fetch'\n if (args.prune) cmd += ' --prune'\n if (args.remote) cmd += ` ${args.remote}`\n else cmd += ' --all'\n\n const result = await execCommand(cmd, { cwd: args.cwd, timeout: 60000, moduleUid: args.moduleUid })\n return formatGitOutput(result, 'Failed to fetch')\n }\n)\n\n// ============================================\n// Branch Management Tools\n// ============================================\n\nserver.registerTool(\n 'git_checkout',\n {\n description: 'Switch branches or restore working tree files',\n inputSchema: {\n ...targetSchema,\n target: z.string().describe('Branch name, commit, or file path'),\n create: z.boolean().optional().describe('Create new branch (-b)'),\n cwd: z.string().optional().describe('Working directory path')\n }\n },\n async (args) => {\n let cmd = 'git checkout'\n if (args.create) cmd += ' -b'\n cmd += ` ${args.target}`\n\n const result = await execCommand(cmd, { cwd: args.cwd, moduleUid: args.moduleUid })\n return formatGitOutput(result, 'Failed to checkout')\n }\n)\n\nserver.registerTool(\n 'git_branch_create',\n {\n description: 'Create a new branch',\n inputSchema: {\n ...targetSchema,\n name: z.string().describe('Name for the new branch'),\n startPoint: z.string().optional().describe('Starting commit/branch'),\n checkout: z.boolean().optional().describe('Switch to new branch after creation'),\n cwd: z.string().optional().describe('Working directory path')\n }\n },\n async (args) => {\n let cmd: string\n if (args.checkout) {\n cmd = `git checkout -b ${args.name}`\n } else {\n cmd = `git branch ${args.name}`\n }\n if (args.startPoint) cmd += ` ${args.startPoint}`\n\n const result = await execCommand(cmd, { cwd: args.cwd, moduleUid: args.moduleUid })\n\n if (!result.success || (result.data && result.data.exitCode !== 0)) {\n return formatGitOutput(result, 'Failed to create branch')\n }\n\n return {\n content: [{\n type: 'text',\n text: `Created branch '${args.name}'${args.checkout ? ' and switched to it' : ''}`\n }]\n }\n }\n)\n\nserver.registerTool(\n 'git_branch_delete',\n {\n description: 'Delete a branch',\n inputSchema: {\n ...targetSchema,\n name: z.string().describe('Branch name to delete'),\n force: z.boolean().optional().describe('Force delete unmerged branch (-D)'),\n remote: z.boolean().optional().describe('Delete remote branch'),\n cwd: z.string().optional().describe('Working directory path')\n }\n },\n async (args) => {\n let cmd: string\n if (args.remote) {\n cmd = `git push origin --delete ${args.name}`\n } else {\n cmd = `git branch ${args.force ? '-D' : '-d'} ${args.name}`\n }\n\n const result = await execCommand(cmd, { cwd: args.cwd, moduleUid: args.moduleUid })\n return formatGitOutput(result, 'Failed to delete branch')\n }\n)\n\nserver.registerTool(\n 'git_merge',\n {\n description: 'Join two or more development histories together',\n inputSchema: {\n ...targetSchema,\n branch: z.string().describe('Branch to merge into current branch'),\n noFf: z.boolean().optional().describe('Create merge commit even for fast-forward'),\n squash: z.boolean().optional().describe('Squash commits into single commit'),\n message: z.string().optional().describe('Merge commit message'),\n cwd: z.string().optional().describe('Working directory path')\n }\n },\n async (args) => {\n let cmd = `git merge ${args.branch}`\n if (args.noFf) cmd += ' --no-ff'\n if (args.squash) cmd += ' --squash'\n if (args.message) {\n const escapedMessage = args.message.replace(/'/g, \"'\\\\''\")\n cmd += ` -m '${escapedMessage}'`\n }\n\n const result = await execCommand(cmd, { cwd: args.cwd, moduleUid: args.moduleUid })\n return formatGitOutput(result, 'Failed to merge')\n }\n)\n\n// ============================================\n// Stash Tools\n// ============================================\n\nserver.registerTool(\n 'git_stash',\n {\n description: 'Stash changes in working directory',\n inputSchema: {\n ...targetSchema,\n message: z.string().optional().describe('Description for the stash'),\n includeUntracked: z.boolean().optional().describe('Include untracked files'),\n cwd: z.string().optional().describe('Working directory path')\n }\n },\n async (args) => {\n let cmd = 'git stash push'\n if (args.includeUntracked) cmd += ' --include-untracked'\n if (args.message) {\n const escapedMessage = args.message.replace(/'/g, \"'\\\\''\")\n cmd += ` -m '${escapedMessage}'`\n }\n\n const result = await execCommand(cmd, { cwd: args.cwd, moduleUid: args.moduleUid })\n return formatGitOutput(result, 'Failed to stash')\n }\n)\n\nserver.registerTool(\n 'git_stash_pop',\n {\n description: 'Apply and remove a stash',\n inputSchema: {\n ...targetSchema,\n index: z.number().optional().describe('Stash index (default: 0, most recent)'),\n cwd: z.string().optional().describe('Working directory path')\n }\n },\n async (args) => {\n const stashRef = args.index !== undefined ? `stash@{${args.index}}` : ''\n const result = await execCommand(`git stash pop ${stashRef}`.trim(), { cwd: args.cwd, moduleUid: args.moduleUid })\n return formatGitOutput(result, 'Failed to pop stash')\n }\n)\n\nserver.registerTool(\n 'git_stash_list',\n {\n description: 'List stashed changes',\n inputSchema: {\n ...targetSchema,\n cwd: z.string().optional().describe('Working directory path')\n }\n },\n async (args) => {\n const result = await execCommand('git stash list', { cwd: args.cwd, moduleUid: args.moduleUid })\n return formatGitOutput(result, 'Failed to list stashes')\n }\n)\n\n// ============================================\n// EP944: Worktree Tools\n// ============================================\n\nserver.registerTool(\n 'git_worktree_list',\n {\n description: 'List all worktrees in the repository. Worktrees allow multiple working directories to share a single repository.',\n inputSchema: {\n ...targetSchema,\n cwd: z.string().optional().describe('Working directory path (must be inside a git repo)')\n }\n },\n async (args) => {\n const result = await execCommand('git worktree list', { cwd: args.cwd, moduleUid: args.moduleUid })\n return formatGitOutput(result, 'Failed to list worktrees')\n }\n)\n\nserver.registerTool(\n 'git_worktree_add',\n {\n description: 'Create a new worktree at the specified path for the given branch. This allows working on multiple branches simultaneously.',\n inputSchema: {\n ...targetSchema,\n path: z.string().describe('Path where the new worktree will be created'),\n branch: z.string().describe('Branch to checkout in the new worktree'),\n create: z.boolean().optional().describe('Create a new branch if it does not exist (-b)'),\n cwd: z.string().optional().describe('Working directory path (must be inside a git repo)')\n }\n },\n async (args) => {\n let cmd = 'git worktree add'\n if (args.create) {\n cmd += ` -b ${args.branch} \"${args.path}\"`\n } else {\n cmd += ` \"${args.path}\" ${args.branch}`\n }\n\n const result = await execCommand(cmd, { cwd: args.cwd, moduleUid: args.moduleUid })\n\n if (!result.success || (result.data && result.data.exitCode !== 0)) {\n return formatGitOutput(result, 'Failed to create worktree')\n }\n\n return {\n content: [{\n type: 'text',\n text: `Created worktree at '${args.path}' for branch '${args.branch}'`\n }]\n }\n }\n)\n\nserver.registerTool(\n 'git_worktree_remove',\n {\n description: 'Remove a worktree. The branch is preserved in the repository - only the working directory is removed.',\n inputSchema: {\n ...targetSchema,\n path: z.string().describe('Path of the worktree to remove'),\n force: z.boolean().optional().describe('Force removal even with uncommitted changes'),\n cwd: z.string().optional().describe('Working directory path (must be inside a git repo)')\n }\n },\n async (args) => {\n let cmd = `git worktree remove \"${args.path}\"`\n if (args.force) cmd += ' --force'\n\n const result = await execCommand(cmd, { cwd: args.cwd, moduleUid: args.moduleUid })\n\n if (!result.success || (result.data && result.data.exitCode !== 0)) {\n return formatGitOutput(result, 'Failed to remove worktree')\n }\n\n return {\n content: [{\n type: 'text',\n text: `Removed worktree at '${args.path}'`\n }]\n }\n }\n)\n\nserver.registerTool(\n 'git_worktree_prune',\n {\n description: 'Clean up stale worktree administrative files. Run this if worktrees were manually deleted.',\n inputSchema: {\n ...targetSchema,\n cwd: z.string().optional().describe('Working directory path (must be inside a git repo)')\n }\n },\n async (args) => {\n const result = await execCommand('git worktree prune', { cwd: args.cwd, moduleUid: args.moduleUid })\n\n if (!result.success || (result.data && result.data.exitCode !== 0)) {\n return formatGitOutput(result, 'Failed to prune worktrees')\n }\n\n return {\n content: [{\n type: 'text',\n text: 'Pruned stale worktree entries'\n }]\n }\n }\n)\n\n// ============================================\n// Start Server\n// ============================================\n\nasync function main() {\n const runtimeConfig = await hydrateRuntimeConfig()\n EPISODA_API_URL = runtimeConfig.apiUrl\n EPISODA_SESSION_TOKEN = runtimeConfig.sessionToken\n EPISODA_PROJECT_ID = runtimeConfig.projectId\n EPISODA_WORKSPACE_ID = runtimeConfig.workspaceId\n\n if (!MODULE_UID && !DEV_ENVIRONMENT_ID) {\n console.warn('[episoda-git] Warning: MODULE_UID/DEV_ENVIRONMENT_ID not set. Provide moduleUid per tool call.')\n }\n\n const transport = new StdioServerTransport()\n await server.connect(transport)\n\n const devTarget = MODULE_UID || DEV_ENVIRONMENT_ID || 'NOT SET'\n console.error('[episoda-git] MCP server started')\n console.error(`[episoda-git] API URL: ${EPISODA_API_URL}`)\n console.error(`[episoda-git] Dev Target: ${devTarget}`)\n console.error(`[episoda-git] Token: ${EPISODA_SESSION_TOKEN ? '****' : 'NOT SET'}`)\n}\n\nmain().catch((error) => {\n console.error('[episoda-git] Fatal error:', error)\n process.exit(1)\n})\n","import * as fs from 'node:fs'\nimport * as os from 'node:os'\nimport * as path from 'node:path'\n\nconst DEFAULT_API_URL = 'https://episoda.dev'\nconst DEFAULT_CONFIG_FILE = 'config.json'\n\ninterface EpisodaLocalConfig {\n access_token?: string\n project_id?: string\n workspace_id?: string\n api_url?: string\n}\n\nexport interface RuntimeConfig {\n apiUrl: string\n sessionToken: string\n projectId: string\n workspaceId: string\n}\n\nconst normalizeEnv = (value?: string): string | undefined => {\n if (!value) return undefined\n const trimmed = value.trim()\n return trimmed.length > 0 ? trimmed : undefined\n}\n\nconst readEnvConfig = () => ({\n apiUrl: normalizeEnv(process.env.EPISODA_API_URL),\n sessionToken: normalizeEnv(process.env.EPISODA_SESSION_TOKEN),\n projectId: normalizeEnv(process.env.EPISODA_PROJECT_ID),\n workspaceId: normalizeEnv(process.env.EPISODA_WORKSPACE_ID)\n})\n\nconst buildMissingMessage = (missing: string[], apiUrl: string): string => {\n return [\n `[episoda-mcp] Missing auth context: ${missing.join(', ')}`,\n '[episoda-mcp] Set EPISODA_* env vars or run:',\n `[episoda-mcp] episoda auth --api-url ${apiUrl}`\n ].join('\\n')\n}\n\nconst getConfigPath = (): string => {\n // MCP supports a full-path override in addition to the core-style config dir.\n if (process.env.EPISODA_CONFIG_PATH) {\n return process.env.EPISODA_CONFIG_PATH\n }\n const configDir = process.env.EPISODA_CONFIG_DIR || path.join(os.homedir(), '.episoda')\n return path.join(configDir, DEFAULT_CONFIG_FILE)\n}\n\nconst loadLocalConfig = (): EpisodaLocalConfig | null => {\n const configPath = getConfigPath()\n if (!fs.existsSync(configPath)) {\n return null\n }\n try {\n const content = fs.readFileSync(configPath, 'utf8')\n return JSON.parse(content) as EpisodaLocalConfig\n } catch (error) {\n console.error('[episoda-mcp] Failed to load config:', error)\n return null\n }\n}\n\nexport async function resolveRuntimeConfig(): Promise<RuntimeConfig> {\n const envConfig = readEnvConfig()\n\n let fileConfig: EpisodaLocalConfig | null = null\n if (!envConfig.sessionToken || !envConfig.projectId || !envConfig.workspaceId || !envConfig.apiUrl) {\n fileConfig = loadLocalConfig()\n }\n\n const resolved: RuntimeConfig = {\n apiUrl: envConfig.apiUrl || fileConfig?.api_url || DEFAULT_API_URL,\n sessionToken: envConfig.sessionToken || fileConfig?.access_token || '',\n projectId: envConfig.projectId || fileConfig?.project_id || '',\n workspaceId: envConfig.workspaceId || fileConfig?.workspace_id || ''\n }\n\n const missing: string[] = []\n if (!resolved.sessionToken) missing.push('EPISODA_SESSION_TOKEN')\n if (!resolved.projectId) missing.push('EPISODA_PROJECT_ID')\n if (!resolved.workspaceId) missing.push('EPISODA_WORKSPACE_ID')\n\n if (missing.length > 0) {\n throw new Error(buildMissingMessage(missing, resolved.apiUrl))\n }\n\n return resolved\n}\n\nexport async function hydrateRuntimeConfig(): Promise<RuntimeConfig> {\n const resolved = await resolveRuntimeConfig()\n\n if (!normalizeEnv(process.env.EPISODA_API_URL)) {\n process.env.EPISODA_API_URL = resolved.apiUrl\n }\n if (!normalizeEnv(process.env.EPISODA_SESSION_TOKEN)) {\n process.env.EPISODA_SESSION_TOKEN = resolved.sessionToken\n }\n if (!normalizeEnv(process.env.EPISODA_PROJECT_ID)) {\n process.env.EPISODA_PROJECT_ID = resolved.projectId\n }\n if (!normalizeEnv(process.env.EPISODA_WORKSPACE_ID)) {\n process.env.EPISODA_WORKSPACE_ID = resolved.workspaceId\n }\n\n return resolved\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/git-server.ts","../src/runtime-config.ts","../src/request-executors.ts"],"sourcesContent":["/**\n * EP908: Episoda Git MCP Server\n *\n * MCP server for Claude Code agents to perform git operations on dev environments.\n * Provides tools for:\n * - Repository status and info (status, log, diff, branch)\n * - Staging and commits (add, commit, reset)\n * - Remote operations (push, pull, fetch)\n * - Branch management (checkout, create, delete, merge)\n *\n * Usage:\n * npx -y @episoda/mcp git\n *\n * Required environment variables:\n * EPISODA_API_URL - Base URL for Episoda API (e.g., https://episoda.dev)\n * EPISODA_SESSION_TOKEN - Bearer token for API authentication\n *\n * Optional environment variables:\n * MODULE_UID - Module UID (preferred, e.g., EP123) or provide moduleUid per tool call\n * DEV_ENVIRONMENT_ID - UUID of the dev environment (legacy fallback)\n * EPISODA_PROJECT_ID - Project ID (for scoped requests)\n * EPISODA_WORKSPACE_ID - Workspace ID (for scoped requests)\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'\nimport { z } from 'zod'\nimport { hydrateRuntimeConfig } from './runtime-config.js'\nimport { executeGitCommandRequest } from './request-executors.js'\n\n// Environment configuration\nlet EPISODA_API_URL = process.env.EPISODA_API_URL || 'https://episoda.dev'\nlet EPISODA_SESSION_TOKEN = process.env.EPISODA_SESSION_TOKEN || ''\nconst DEV_ENVIRONMENT_ID = process.env.DEV_ENVIRONMENT_ID || ''\nconst MODULE_UID = process.env.MODULE_UID || ''\nlet EPISODA_PROJECT_ID = process.env.EPISODA_PROJECT_ID || ''\nlet EPISODA_WORKSPACE_ID = process.env.EPISODA_WORKSPACE_ID || ''\nlet EPISODA_MACHINE_UUID = process.env.EPISODA_MACHINE_UUID || ''\n\nconst targetSchema = {\n moduleUid: z.string().optional().describe('Module UID to target (overrides server default)')\n}\n\ninterface ExecResponse {\n success: boolean\n data?: {\n stdout: string\n stderr: string\n exitCode: number\n timedOut?: boolean\n }\n error?: string\n}\n\n/**\n * Execute a command on the dev environment via unified API\n */\nasync function execCommand(\n command: string,\n options: { cwd?: string; timeout?: number; moduleUid?: string } = {}\n): Promise<ExecResponse> {\n const { cwd, timeout = 30000, moduleUid } = options\n\n const target = moduleUid || MODULE_UID || DEV_ENVIRONMENT_ID\n if (!target) {\n return {\n success: false,\n error: 'Module target missing. Provide moduleUid in the tool call or set MODULE_UID/DEV_ENVIRONMENT_ID.'\n }\n }\n return executeGitCommandRequest(\n {\n apiUrl: EPISODA_API_URL,\n sessionToken: EPISODA_SESSION_TOKEN,\n projectId: EPISODA_PROJECT_ID,\n workspaceId: EPISODA_WORKSPACE_ID,\n // EP1376: Intentional parity with workflow/dev MCP servers.\n machineUuid: EPISODA_MACHINE_UUID\n },\n { target, command, cwd, timeout }\n )\n}\n\n/**\n * Helper to format git command output for MCP response\n */\nfunction formatGitOutput(result: ExecResponse, errorPrefix: string = 'Git error'): {\n content: Array<{ type: 'text'; text: string }>\n isError?: boolean\n} {\n if (!result.success || !result.data) {\n return {\n content: [{ type: 'text', text: `${errorPrefix}: ${result.error || 'Unknown error'}` }],\n isError: true\n }\n }\n\n const { stdout, stderr, exitCode } = result.data\n\n if (exitCode !== 0) {\n const errorOutput = stderr || stdout || 'Command failed'\n return {\n content: [{ type: 'text', text: `${errorPrefix} (exit ${exitCode}):\\n${errorOutput}` }],\n isError: true\n }\n }\n\n return {\n content: [{ type: 'text', text: stdout || '(no output)' }]\n }\n}\n\n// Create MCP server\nconst server = new McpServer({\n name: 'episoda-git',\n version: '1.0.0'\n}, {\n capabilities: {\n tools: {}\n },\n instructions: `\n Episoda Git MCP Server\n\n This server provides git operations for dev environments (cloud VMs or local machines).\n All commands are executed in the context of the configured dev environment.\n You may pass moduleUid per call to target a specific module.\n\n Categories:\n - Status & Info: git_status, git_log, git_diff, git_show, git_branch_list\n - Staging: git_add, git_reset\n - Commits: git_commit\n - Remote: git_push, git_pull, git_fetch\n - Branches: git_checkout, git_branch_create, git_branch_delete, git_merge\n - Stash: git_stash, git_stash_pop, git_stash_list\n - Worktrees (EP944): git_worktree_list, git_worktree_add, git_worktree_remove, git_worktree_prune\n\n Worktrees allow multiple working directories to share a single repository,\n enabling parallel development on multiple branches/modules simultaneously.\n `\n})\n\n// ============================================\n// Status & Info Tools\n// ============================================\n\nserver.registerTool(\n 'git_status',\n {\n description: 'Show the working tree status (staged, unstaged, untracked files)',\n inputSchema: {\n ...targetSchema,\n cwd: z.string().optional().describe('Working directory path (defaults to repo root)')\n }\n },\n async (args) => {\n const result = await execCommand('git status', { cwd: args.cwd, moduleUid: args.moduleUid })\n return formatGitOutput(result, 'Failed to get git status')\n }\n)\n\nserver.registerTool(\n 'git_log',\n {\n description: 'Show commit logs',\n inputSchema: {\n ...targetSchema,\n count: z.number().optional().describe('Number of commits to show (default: 10)'),\n oneline: z.boolean().optional().describe('Use one-line format (default: true)'),\n branch: z.string().optional().describe('Branch name (default: current branch)'),\n cwd: z.string().optional().describe('Working directory path')\n }\n },\n async (args) => {\n const count = args.count || 10\n const format = args.oneline !== false ? '--oneline' : '--format=medium'\n const branch = args.branch || ''\n\n const result = await execCommand(\n `git log ${format} -n ${count} ${branch}`.trim(),\n { cwd: args.cwd, moduleUid: args.moduleUid }\n )\n return formatGitOutput(result, 'Failed to get git log')\n }\n)\n\nserver.registerTool(\n 'git_diff',\n {\n description: 'Show changes between commits, commit and working tree, etc.',\n inputSchema: {\n ...targetSchema,\n staged: z.boolean().optional().describe('Show staged changes (--cached)'),\n file: z.string().optional().describe('Specific file to diff'),\n commit: z.string().optional().describe('Compare against specific commit'),\n cwd: z.string().optional().describe('Working directory path')\n }\n },\n async (args) => {\n let cmd = 'git diff'\n if (args.staged) cmd += ' --cached'\n if (args.commit) cmd += ` ${args.commit}`\n if (args.file) cmd += ` -- ${args.file}`\n\n const result = await execCommand(cmd, { cwd: args.cwd, moduleUid: args.moduleUid })\n return formatGitOutput(result, 'Failed to get diff')\n }\n)\n\nserver.registerTool(\n 'git_show',\n {\n description: 'Show details of a specific commit',\n inputSchema: {\n ...targetSchema,\n commit: z.string().describe('Commit hash or reference (e.g., HEAD, abc123)'),\n stat: z.boolean().optional().describe('Show diffstat only'),\n cwd: z.string().optional().describe('Working directory path')\n }\n },\n async (args) => {\n let cmd = `git show ${args.commit}`\n if (args.stat) cmd += ' --stat'\n\n const result = await execCommand(cmd, { cwd: args.cwd, moduleUid: args.moduleUid })\n return formatGitOutput(result, 'Failed to show commit')\n }\n)\n\nserver.registerTool(\n 'git_branch_list',\n {\n description: 'List branches',\n inputSchema: {\n ...targetSchema,\n all: z.boolean().optional().describe('Show all branches including remotes'),\n remote: z.boolean().optional().describe('Show only remote branches'),\n cwd: z.string().optional().describe('Working directory path')\n }\n },\n async (args) => {\n let cmd = 'git branch'\n if (args.all) cmd += ' -a'\n else if (args.remote) cmd += ' -r'\n\n const result = await execCommand(cmd, { cwd: args.cwd, moduleUid: args.moduleUid })\n return formatGitOutput(result, 'Failed to list branches')\n }\n)\n\n// ============================================\n// Staging Tools\n// ============================================\n\nserver.registerTool(\n 'git_add',\n {\n description: 'Add file contents to the staging area',\n inputSchema: {\n ...targetSchema,\n files: z.array(z.string()).describe('Files to add (use [\".\"] for all)'),\n cwd: z.string().optional().describe('Working directory path')\n }\n },\n async (args) => {\n const files = args.files.map(f => `\"${f}\"`).join(' ')\n const result = await execCommand(`git add ${files}`, { cwd: args.cwd, moduleUid: args.moduleUid })\n\n if (!result.success || (result.data && result.data.exitCode !== 0)) {\n return formatGitOutput(result, 'Failed to add files')\n }\n\n return {\n content: [{ type: 'text', text: `Added ${args.files.length} file(s) to staging area` }]\n }\n }\n)\n\nserver.registerTool(\n 'git_reset',\n {\n description: 'Unstage files or reset to a commit',\n inputSchema: {\n ...targetSchema,\n files: z.array(z.string()).optional().describe('Files to unstage'),\n hard: z.boolean().optional().describe('Hard reset (WARNING: discards changes)'),\n commit: z.string().optional().describe('Commit to reset to'),\n cwd: z.string().optional().describe('Working directory path')\n }\n },\n async (args) => {\n let cmd = 'git reset'\n if (args.hard) cmd += ' --hard'\n if (args.commit) cmd += ` ${args.commit}`\n if (args.files && args.files.length > 0) {\n cmd += ' -- ' + args.files.map(f => `\"${f}\"`).join(' ')\n }\n\n const result = await execCommand(cmd, { cwd: args.cwd, moduleUid: args.moduleUid })\n return formatGitOutput(result, 'Failed to reset')\n }\n)\n\n// ============================================\n// Commit Tools\n// ============================================\n\nserver.registerTool(\n 'git_commit',\n {\n description: 'Record changes to the repository',\n inputSchema: {\n ...targetSchema,\n message: z.string().describe('Commit message'),\n all: z.boolean().optional().describe('Stage all modified files before commit (-a)'),\n amend: z.boolean().optional().describe('Amend the previous commit'),\n cwd: z.string().optional().describe('Working directory path')\n }\n },\n async (args) => {\n // Escape message for shell\n const escapedMessage = args.message.replace(/'/g, \"'\\\\''\")\n\n let cmd = `git commit -m '${escapedMessage}'`\n if (args.all) cmd = cmd.replace('git commit', 'git commit -a')\n if (args.amend) cmd += ' --amend'\n\n const result = await execCommand(cmd, { cwd: args.cwd, moduleUid: args.moduleUid })\n return formatGitOutput(result, 'Failed to commit')\n }\n)\n\n// ============================================\n// Remote Tools\n// ============================================\n\nserver.registerTool(\n 'git_push',\n {\n description: 'Push commits to remote repository',\n inputSchema: {\n ...targetSchema,\n remote: z.string().optional().describe('Remote name (default: origin)'),\n branch: z.string().optional().describe('Branch name'),\n force: z.boolean().optional().describe('Force push (use with caution!)'),\n setUpstream: z.boolean().optional().describe('Set upstream tracking (-u)'),\n cwd: z.string().optional().describe('Working directory path')\n }\n },\n async (args) => {\n let cmd = 'git push'\n if (args.setUpstream) cmd += ' -u'\n if (args.force) cmd += ' --force-with-lease' // Safer than --force\n if (args.remote) cmd += ` ${args.remote}`\n if (args.branch) cmd += ` ${args.branch}`\n\n const result = await execCommand(cmd, { cwd: args.cwd, timeout: 60000, moduleUid: args.moduleUid })\n return formatGitOutput(result, 'Failed to push')\n }\n)\n\nserver.registerTool(\n 'git_pull',\n {\n description: 'Fetch and integrate changes from remote',\n inputSchema: {\n ...targetSchema,\n remote: z.string().optional().describe('Remote name (default: origin)'),\n branch: z.string().optional().describe('Branch name'),\n rebase: z.boolean().optional().describe('Rebase instead of merge'),\n cwd: z.string().optional().describe('Working directory path')\n }\n },\n async (args) => {\n let cmd = 'git pull'\n if (args.rebase) cmd += ' --rebase'\n if (args.remote) cmd += ` ${args.remote}`\n if (args.branch) cmd += ` ${args.branch}`\n\n const result = await execCommand(cmd, { cwd: args.cwd, timeout: 60000, moduleUid: args.moduleUid })\n return formatGitOutput(result, 'Failed to pull')\n }\n)\n\nserver.registerTool(\n 'git_fetch',\n {\n description: 'Download objects and refs from remote',\n inputSchema: {\n ...targetSchema,\n remote: z.string().optional().describe('Remote name (default: all remotes)'),\n prune: z.boolean().optional().describe('Remove deleted remote branches'),\n cwd: z.string().optional().describe('Working directory path')\n }\n },\n async (args) => {\n let cmd = 'git fetch'\n if (args.prune) cmd += ' --prune'\n if (args.remote) cmd += ` ${args.remote}`\n else cmd += ' --all'\n\n const result = await execCommand(cmd, { cwd: args.cwd, timeout: 60000, moduleUid: args.moduleUid })\n return formatGitOutput(result, 'Failed to fetch')\n }\n)\n\n// ============================================\n// Branch Management Tools\n// ============================================\n\nserver.registerTool(\n 'git_checkout',\n {\n description: 'Switch branches or restore working tree files',\n inputSchema: {\n ...targetSchema,\n target: z.string().describe('Branch name, commit, or file path'),\n create: z.boolean().optional().describe('Create new branch (-b)'),\n cwd: z.string().optional().describe('Working directory path')\n }\n },\n async (args) => {\n let cmd = 'git checkout'\n if (args.create) cmd += ' -b'\n cmd += ` ${args.target}`\n\n const result = await execCommand(cmd, { cwd: args.cwd, moduleUid: args.moduleUid })\n return formatGitOutput(result, 'Failed to checkout')\n }\n)\n\nserver.registerTool(\n 'git_branch_create',\n {\n description: 'Create a new branch',\n inputSchema: {\n ...targetSchema,\n name: z.string().describe('Name for the new branch'),\n startPoint: z.string().optional().describe('Starting commit/branch'),\n checkout: z.boolean().optional().describe('Switch to new branch after creation'),\n cwd: z.string().optional().describe('Working directory path')\n }\n },\n async (args) => {\n let cmd: string\n if (args.checkout) {\n cmd = `git checkout -b ${args.name}`\n } else {\n cmd = `git branch ${args.name}`\n }\n if (args.startPoint) cmd += ` ${args.startPoint}`\n\n const result = await execCommand(cmd, { cwd: args.cwd, moduleUid: args.moduleUid })\n\n if (!result.success || (result.data && result.data.exitCode !== 0)) {\n return formatGitOutput(result, 'Failed to create branch')\n }\n\n return {\n content: [{\n type: 'text',\n text: `Created branch '${args.name}'${args.checkout ? ' and switched to it' : ''}`\n }]\n }\n }\n)\n\nserver.registerTool(\n 'git_branch_delete',\n {\n description: 'Delete a branch',\n inputSchema: {\n ...targetSchema,\n name: z.string().describe('Branch name to delete'),\n force: z.boolean().optional().describe('Force delete unmerged branch (-D)'),\n remote: z.boolean().optional().describe('Delete remote branch'),\n cwd: z.string().optional().describe('Working directory path')\n }\n },\n async (args) => {\n let cmd: string\n if (args.remote) {\n cmd = `git push origin --delete ${args.name}`\n } else {\n cmd = `git branch ${args.force ? '-D' : '-d'} ${args.name}`\n }\n\n const result = await execCommand(cmd, { cwd: args.cwd, moduleUid: args.moduleUid })\n return formatGitOutput(result, 'Failed to delete branch')\n }\n)\n\nserver.registerTool(\n 'git_merge',\n {\n description: 'Join two or more development histories together',\n inputSchema: {\n ...targetSchema,\n branch: z.string().describe('Branch to merge into current branch'),\n noFf: z.boolean().optional().describe('Create merge commit even for fast-forward'),\n squash: z.boolean().optional().describe('Squash commits into single commit'),\n message: z.string().optional().describe('Merge commit message'),\n cwd: z.string().optional().describe('Working directory path')\n }\n },\n async (args) => {\n let cmd = `git merge ${args.branch}`\n if (args.noFf) cmd += ' --no-ff'\n if (args.squash) cmd += ' --squash'\n if (args.message) {\n const escapedMessage = args.message.replace(/'/g, \"'\\\\''\")\n cmd += ` -m '${escapedMessage}'`\n }\n\n const result = await execCommand(cmd, { cwd: args.cwd, moduleUid: args.moduleUid })\n return formatGitOutput(result, 'Failed to merge')\n }\n)\n\n// ============================================\n// Stash Tools\n// ============================================\n\nserver.registerTool(\n 'git_stash',\n {\n description: 'Stash changes in working directory',\n inputSchema: {\n ...targetSchema,\n message: z.string().optional().describe('Description for the stash'),\n includeUntracked: z.boolean().optional().describe('Include untracked files'),\n cwd: z.string().optional().describe('Working directory path')\n }\n },\n async (args) => {\n let cmd = 'git stash push'\n if (args.includeUntracked) cmd += ' --include-untracked'\n if (args.message) {\n const escapedMessage = args.message.replace(/'/g, \"'\\\\''\")\n cmd += ` -m '${escapedMessage}'`\n }\n\n const result = await execCommand(cmd, { cwd: args.cwd, moduleUid: args.moduleUid })\n return formatGitOutput(result, 'Failed to stash')\n }\n)\n\nserver.registerTool(\n 'git_stash_pop',\n {\n description: 'Apply and remove a stash',\n inputSchema: {\n ...targetSchema,\n index: z.number().optional().describe('Stash index (default: 0, most recent)'),\n cwd: z.string().optional().describe('Working directory path')\n }\n },\n async (args) => {\n const stashRef = args.index !== undefined ? `stash@{${args.index}}` : ''\n const result = await execCommand(`git stash pop ${stashRef}`.trim(), { cwd: args.cwd, moduleUid: args.moduleUid })\n return formatGitOutput(result, 'Failed to pop stash')\n }\n)\n\nserver.registerTool(\n 'git_stash_list',\n {\n description: 'List stashed changes',\n inputSchema: {\n ...targetSchema,\n cwd: z.string().optional().describe('Working directory path')\n }\n },\n async (args) => {\n const result = await execCommand('git stash list', { cwd: args.cwd, moduleUid: args.moduleUid })\n return formatGitOutput(result, 'Failed to list stashes')\n }\n)\n\n// ============================================\n// EP944: Worktree Tools\n// ============================================\n\nserver.registerTool(\n 'git_worktree_list',\n {\n description: 'List all worktrees in the repository. Worktrees allow multiple working directories to share a single repository.',\n inputSchema: {\n ...targetSchema,\n cwd: z.string().optional().describe('Working directory path (must be inside a git repo)')\n }\n },\n async (args) => {\n const result = await execCommand('git worktree list', { cwd: args.cwd, moduleUid: args.moduleUid })\n return formatGitOutput(result, 'Failed to list worktrees')\n }\n)\n\nserver.registerTool(\n 'git_worktree_add',\n {\n description: 'Create a new worktree at the specified path for the given branch. This allows working on multiple branches simultaneously.',\n inputSchema: {\n ...targetSchema,\n path: z.string().describe('Path where the new worktree will be created'),\n branch: z.string().describe('Branch to checkout in the new worktree'),\n create: z.boolean().optional().describe('Create a new branch if it does not exist (-b)'),\n cwd: z.string().optional().describe('Working directory path (must be inside a git repo)')\n }\n },\n async (args) => {\n let cmd = 'git worktree add'\n if (args.create) {\n cmd += ` -b ${args.branch} \"${args.path}\"`\n } else {\n cmd += ` \"${args.path}\" ${args.branch}`\n }\n\n const result = await execCommand(cmd, { cwd: args.cwd, moduleUid: args.moduleUid })\n\n if (!result.success || (result.data && result.data.exitCode !== 0)) {\n return formatGitOutput(result, 'Failed to create worktree')\n }\n\n return {\n content: [{\n type: 'text',\n text: `Created worktree at '${args.path}' for branch '${args.branch}'`\n }]\n }\n }\n)\n\nserver.registerTool(\n 'git_worktree_remove',\n {\n description: 'Remove a worktree. The branch is preserved in the repository - only the working directory is removed.',\n inputSchema: {\n ...targetSchema,\n path: z.string().describe('Path of the worktree to remove'),\n force: z.boolean().optional().describe('Force removal even with uncommitted changes'),\n cwd: z.string().optional().describe('Working directory path (must be inside a git repo)')\n }\n },\n async (args) => {\n let cmd = `git worktree remove \"${args.path}\"`\n if (args.force) cmd += ' --force'\n\n const result = await execCommand(cmd, { cwd: args.cwd, moduleUid: args.moduleUid })\n\n if (!result.success || (result.data && result.data.exitCode !== 0)) {\n return formatGitOutput(result, 'Failed to remove worktree')\n }\n\n return {\n content: [{\n type: 'text',\n text: `Removed worktree at '${args.path}'`\n }]\n }\n }\n)\n\nserver.registerTool(\n 'git_worktree_prune',\n {\n description: 'Clean up stale worktree administrative files. Run this if worktrees were manually deleted.',\n inputSchema: {\n ...targetSchema,\n cwd: z.string().optional().describe('Working directory path (must be inside a git repo)')\n }\n },\n async (args) => {\n const result = await execCommand('git worktree prune', { cwd: args.cwd, moduleUid: args.moduleUid })\n\n if (!result.success || (result.data && result.data.exitCode !== 0)) {\n return formatGitOutput(result, 'Failed to prune worktrees')\n }\n\n return {\n content: [{\n type: 'text',\n text: 'Pruned stale worktree entries'\n }]\n }\n }\n)\n\n// ============================================\n// Start Server\n// ============================================\n\nexport async function startServer() {\n const runtimeConfig = await hydrateRuntimeConfig()\n EPISODA_API_URL = runtimeConfig.apiUrl\n EPISODA_SESSION_TOKEN = runtimeConfig.sessionToken\n EPISODA_PROJECT_ID = runtimeConfig.projectId\n EPISODA_WORKSPACE_ID = runtimeConfig.workspaceId\n EPISODA_MACHINE_UUID = runtimeConfig.machineUuid || ''\n\n if (!MODULE_UID && !DEV_ENVIRONMENT_ID) {\n console.warn('[episoda-git] Warning: MODULE_UID/DEV_ENVIRONMENT_ID not set. Provide moduleUid per tool call.')\n }\n\n const transport = new StdioServerTransport()\n await server.connect(transport)\n\n const devTarget = MODULE_UID || DEV_ENVIRONMENT_ID || 'NOT SET'\n console.error('[episoda-git] MCP server started')\n console.error(`[episoda-git] API URL: ${EPISODA_API_URL}`)\n console.error(`[episoda-git] Dev Target: ${devTarget}`)\n console.error(`[episoda-git] Token: ${EPISODA_SESSION_TOKEN ? '****' : 'NOT SET'}`)\n}\n\nif (process.env.EPISODA_MCP_NO_AUTOSTART !== '1') {\n startServer().catch((error) => {\n console.error('[episoda-git] Fatal error:', error)\n process.exit(1)\n })\n}\n","import * as fs from 'node:fs'\nimport * as os from 'node:os'\nimport * as path from 'node:path'\n\nconst DEFAULT_API_URL = 'https://episoda.dev'\nconst DEFAULT_CONFIG_FILE = 'config.json'\n\ninterface EpisodaLocalConfig {\n access_token?: string\n project_id?: string\n workspace_id?: string\n api_url?: string\n machine_uuid?: string\n device_id?: string // deprecated alias for machine_uuid\n}\n\nexport interface RuntimeConfig {\n apiUrl: string\n sessionToken: string\n projectId: string\n workspaceId: string\n machineUuid?: string\n}\n\nconst normalizeEnv = (value?: string): string | undefined => {\n if (!value) return undefined\n const trimmed = value.trim()\n return trimmed.length > 0 ? trimmed : undefined\n}\n\nconst readEnvConfig = () => ({\n apiUrl: normalizeEnv(process.env.EPISODA_API_URL),\n sessionToken: normalizeEnv(process.env.EPISODA_SESSION_TOKEN),\n projectId: normalizeEnv(process.env.EPISODA_PROJECT_ID),\n workspaceId: normalizeEnv(process.env.EPISODA_WORKSPACE_ID),\n machineUuid: normalizeEnv(process.env.EPISODA_MACHINE_UUID)\n})\n\nconst buildMissingMessage = (missing: string[], apiUrl: string): string => {\n return [\n `[episoda-mcp] Missing auth context: ${missing.join(', ')}`,\n '[episoda-mcp] Set EPISODA_* env vars or run:',\n `[episoda-mcp] episoda auth --api-url ${apiUrl}`\n ].join('\\n')\n}\n\nconst getConfigPath = (): string => {\n // MCP supports a full-path override in addition to the core-style config dir.\n if (process.env.EPISODA_CONFIG_PATH) {\n return process.env.EPISODA_CONFIG_PATH\n }\n const configDir = process.env.EPISODA_CONFIG_DIR || path.join(os.homedir(), '.episoda')\n return path.join(configDir, DEFAULT_CONFIG_FILE)\n}\n\nconst loadLocalConfig = (): EpisodaLocalConfig | null => {\n const configPath = getConfigPath()\n if (!fs.existsSync(configPath)) {\n return null\n }\n try {\n const content = fs.readFileSync(configPath, 'utf8')\n return JSON.parse(content) as EpisodaLocalConfig\n } catch (error) {\n console.error('[episoda-mcp] Failed to load config:', error)\n return null\n }\n}\n\nexport async function resolveRuntimeConfig(): Promise<RuntimeConfig> {\n const envConfig = readEnvConfig()\n\n let fileConfig: EpisodaLocalConfig | null = null\n if (!envConfig.sessionToken || !envConfig.projectId || !envConfig.workspaceId || !envConfig.apiUrl || !envConfig.machineUuid) {\n fileConfig = loadLocalConfig()\n }\n\n const resolved: RuntimeConfig = {\n apiUrl: envConfig.apiUrl || fileConfig?.api_url || DEFAULT_API_URL,\n sessionToken: envConfig.sessionToken || fileConfig?.access_token || '',\n projectId: envConfig.projectId || fileConfig?.project_id || '',\n workspaceId: envConfig.workspaceId || fileConfig?.workspace_id || '',\n machineUuid: envConfig.machineUuid || fileConfig?.machine_uuid || fileConfig?.device_id || undefined\n }\n\n const missing: string[] = []\n if (!resolved.sessionToken) missing.push('EPISODA_SESSION_TOKEN')\n if (!resolved.projectId) missing.push('EPISODA_PROJECT_ID')\n if (!resolved.workspaceId) missing.push('EPISODA_WORKSPACE_ID')\n\n if (missing.length > 0) {\n throw new Error(buildMissingMessage(missing, resolved.apiUrl))\n }\n\n return resolved\n}\n\nexport async function hydrateRuntimeConfig(): Promise<RuntimeConfig> {\n const resolved = await resolveRuntimeConfig()\n\n if (!normalizeEnv(process.env.EPISODA_API_URL)) {\n process.env.EPISODA_API_URL = resolved.apiUrl\n }\n if (!normalizeEnv(process.env.EPISODA_SESSION_TOKEN)) {\n process.env.EPISODA_SESSION_TOKEN = resolved.sessionToken\n }\n if (!normalizeEnv(process.env.EPISODA_PROJECT_ID)) {\n process.env.EPISODA_PROJECT_ID = resolved.projectId\n }\n if (!normalizeEnv(process.env.EPISODA_WORKSPACE_ID)) {\n process.env.EPISODA_WORKSPACE_ID = resolved.workspaceId\n }\n if (resolved.machineUuid && !normalizeEnv(process.env.EPISODA_MACHINE_UUID)) {\n process.env.EPISODA_MACHINE_UUID = resolved.machineUuid\n }\n\n return resolved\n}\n","export interface McpRuntimeContext {\n apiUrl: string\n sessionToken: string\n projectId?: string\n workspaceId?: string\n machineUuid?: string\n}\n\nexport interface GitExecResponse {\n success: boolean\n data?: {\n stdout: string\n stderr: string\n exitCode: number\n timedOut?: boolean\n }\n error?: string\n}\n\nexport function buildMcpHeaders(runtime: McpRuntimeContext): Record<string, string> {\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${runtime.sessionToken}`,\n }\n\n if (runtime.projectId) {\n headers['x-project-id'] = runtime.projectId\n }\n if (runtime.workspaceId) {\n headers['x-workspace-id'] = runtime.workspaceId\n }\n if (runtime.machineUuid) {\n headers['x-machine-uuid'] = runtime.machineUuid\n }\n\n return headers\n}\n\nexport async function apiRequest<T>(\n runtime: McpRuntimeContext,\n method: 'GET' | 'POST' | 'PATCH' | 'DELETE',\n path: string,\n body?: Record<string, unknown>,\n fetchImpl: typeof fetch = fetch\n): Promise<T> {\n const url = `${runtime.apiUrl}${path}`\n const options: RequestInit = {\n method,\n headers: buildMcpHeaders(runtime)\n }\n\n if (body && method !== 'GET') {\n options.body = JSON.stringify(body)\n }\n\n const response = await fetchImpl(url, options)\n if (!response.ok) {\n const text = await response.text()\n throw new Error(`API error ${response.status}: ${text}`)\n }\n\n return response.json() as Promise<T>\n}\n\nexport async function executeTransitionModule(\n runtime: McpRuntimeContext,\n args: { module_uid: string; target_state: 'ready' | 'doing' | 'review' | 'done' },\n fetchImpl: typeof fetch = fetch\n) {\n interface TransitionResponse {\n success: boolean\n module?: { uid: string; state: string }\n error?: string\n }\n\n const result = await apiRequest<TransitionResponse>(\n runtime,\n 'POST',\n `/api/modules/${args.module_uid}/transition`,\n { targetState: args.target_state },\n fetchImpl\n )\n\n if (!result.success) {\n return { content: [{ type: 'text' as const, text: `Error: ${result.error}` }], isError: true }\n }\n\n return {\n content: [{\n type: 'text' as const,\n text: `Module ${args.module_uid} transitioned to ${args.target_state}`\n }]\n }\n}\n\nexport async function executeGitCommandRequest(\n runtime: McpRuntimeContext,\n args: { target: string; command: string; cwd?: string; timeout?: number },\n fetchImpl: typeof fetch = fetch\n): Promise<GitExecResponse> {\n const response = await fetchImpl(`${runtime.apiUrl}/api/dev/${args.target}/exec`, {\n method: 'POST',\n headers: buildMcpHeaders(runtime),\n body: JSON.stringify({\n command: args.command,\n cwd: args.cwd,\n timeout: args.timeout ?? 30000\n })\n })\n\n if (!response.ok) {\n return {\n success: false,\n error: `HTTP ${response.status}: ${response.statusText}`,\n }\n }\n\n return response.json() as Promise<GitExecResponse>\n}\n\n"],"mappings":";;;AAwBA,SAAS,iBAAiB;AAC1B,SAAS,4BAA4B;AACrC,SAAS,SAAS;;;AC1BlB,YAAY,QAAQ;AACpB,YAAY,QAAQ;AACpB,YAAY,UAAU;AAEtB,IAAM,kBAAkB;AACxB,IAAM,sBAAsB;AAmB5B,IAAM,eAAe,CAAC,UAAuC;AAC3D,MAAI,CAAC,MAAO,QAAO;AACnB,QAAM,UAAU,MAAM,KAAK;AAC3B,SAAO,QAAQ,SAAS,IAAI,UAAU;AACxC;AAEA,IAAM,gBAAgB,OAAO;AAAA,EAC3B,QAAQ,aAAa,QAAQ,IAAI,eAAe;AAAA,EAChD,cAAc,aAAa,QAAQ,IAAI,qBAAqB;AAAA,EAC5D,WAAW,aAAa,QAAQ,IAAI,kBAAkB;AAAA,EACtD,aAAa,aAAa,QAAQ,IAAI,oBAAoB;AAAA,EAC1D,aAAa,aAAa,QAAQ,IAAI,oBAAoB;AAC5D;AAEA,IAAM,sBAAsB,CAAC,SAAmB,WAA2B;AACzE,SAAO;AAAA,IACL,uCAAuC,QAAQ,KAAK,IAAI,CAAC;AAAA,IACzD;AAAA,IACA,0CAA0C,MAAM;AAAA,EAClD,EAAE,KAAK,IAAI;AACb;AAEA,IAAM,gBAAgB,MAAc;AAElC,MAAI,QAAQ,IAAI,qBAAqB;AACnC,WAAO,QAAQ,IAAI;AAAA,EACrB;AACA,QAAM,YAAY,QAAQ,IAAI,sBAA2B,UAAQ,WAAQ,GAAG,UAAU;AACtF,SAAY,UAAK,WAAW,mBAAmB;AACjD;AAEA,IAAM,kBAAkB,MAAiC;AACvD,QAAM,aAAa,cAAc;AACjC,MAAI,CAAI,cAAW,UAAU,GAAG;AAC9B,WAAO;AAAA,EACT;AACA,MAAI;AACF,UAAM,UAAa,gBAAa,YAAY,MAAM;AAClD,WAAO,KAAK,MAAM,OAAO;AAAA,EAC3B,SAAS,OAAO;AACd,YAAQ,MAAM,wCAAwC,KAAK;AAC3D,WAAO;AAAA,EACT;AACF;AAEA,eAAsB,uBAA+C;AACnE,QAAM,YAAY,cAAc;AAEhC,MAAI,aAAwC;AAC5C,MAAI,CAAC,UAAU,gBAAgB,CAAC,UAAU,aAAa,CAAC,UAAU,eAAe,CAAC,UAAU,UAAU,CAAC,UAAU,aAAa;AAC5H,iBAAa,gBAAgB;AAAA,EAC/B;AAEA,QAAM,WAA0B;AAAA,IAC9B,QAAQ,UAAU,UAAU,YAAY,WAAW;AAAA,IACnD,cAAc,UAAU,gBAAgB,YAAY,gBAAgB;AAAA,IACpE,WAAW,UAAU,aAAa,YAAY,cAAc;AAAA,IAC5D,aAAa,UAAU,eAAe,YAAY,gBAAgB;AAAA,IAClE,aAAa,UAAU,eAAe,YAAY,gBAAgB,YAAY,aAAa;AAAA,EAC7F;AAEA,QAAM,UAAoB,CAAC;AAC3B,MAAI,CAAC,SAAS,aAAc,SAAQ,KAAK,uBAAuB;AAChE,MAAI,CAAC,SAAS,UAAW,SAAQ,KAAK,oBAAoB;AAC1D,MAAI,CAAC,SAAS,YAAa,SAAQ,KAAK,sBAAsB;AAE9D,MAAI,QAAQ,SAAS,GAAG;AACtB,UAAM,IAAI,MAAM,oBAAoB,SAAS,SAAS,MAAM,CAAC;AAAA,EAC/D;AAEA,SAAO;AACT;AAEA,eAAsB,uBAA+C;AACnE,QAAM,WAAW,MAAM,qBAAqB;AAE5C,MAAI,CAAC,aAAa,QAAQ,IAAI,eAAe,GAAG;AAC9C,YAAQ,IAAI,kBAAkB,SAAS;AAAA,EACzC;AACA,MAAI,CAAC,aAAa,QAAQ,IAAI,qBAAqB,GAAG;AACpD,YAAQ,IAAI,wBAAwB,SAAS;AAAA,EAC/C;AACA,MAAI,CAAC,aAAa,QAAQ,IAAI,kBAAkB,GAAG;AACjD,YAAQ,IAAI,qBAAqB,SAAS;AAAA,EAC5C;AACA,MAAI,CAAC,aAAa,QAAQ,IAAI,oBAAoB,GAAG;AACnD,YAAQ,IAAI,uBAAuB,SAAS;AAAA,EAC9C;AACA,MAAI,SAAS,eAAe,CAAC,aAAa,QAAQ,IAAI,oBAAoB,GAAG;AAC3E,YAAQ,IAAI,uBAAuB,SAAS;AAAA,EAC9C;AAEA,SAAO;AACT;;;AClGO,SAAS,gBAAgB,SAAoD;AAClF,QAAM,UAAkC;AAAA,IACtC,gBAAgB;AAAA,IAChB,iBAAiB,UAAU,QAAQ,YAAY;AAAA,EACjD;AAEA,MAAI,QAAQ,WAAW;AACrB,YAAQ,cAAc,IAAI,QAAQ;AAAA,EACpC;AACA,MAAI,QAAQ,aAAa;AACvB,YAAQ,gBAAgB,IAAI,QAAQ;AAAA,EACtC;AACA,MAAI,QAAQ,aAAa;AACvB,YAAQ,gBAAgB,IAAI,QAAQ;AAAA,EACtC;AAEA,SAAO;AACT;AA2DA,eAAsB,yBACpB,SACA,MACA,YAA0B,OACA;AAC1B,QAAM,WAAW,MAAM,UAAU,GAAG,QAAQ,MAAM,YAAY,KAAK,MAAM,SAAS;AAAA,IAChF,QAAQ;AAAA,IACR,SAAS,gBAAgB,OAAO;AAAA,IAChC,MAAM,KAAK,UAAU;AAAA,MACnB,SAAS,KAAK;AAAA,MACd,KAAK,KAAK;AAAA,MACV,SAAS,KAAK,WAAW;AAAA,IAC3B,CAAC;AAAA,EACH,CAAC;AAED,MAAI,CAAC,SAAS,IAAI;AAChB,WAAO;AAAA,MACL,SAAS;AAAA,MACT,OAAO,QAAQ,SAAS,MAAM,KAAK,SAAS,UAAU;AAAA,IACxD;AAAA,EACF;AAEA,SAAO,SAAS,KAAK;AACvB;;;AFvFA,IAAI,kBAAkB,QAAQ,IAAI,mBAAmB;AACrD,IAAI,wBAAwB,QAAQ,IAAI,yBAAyB;AACjE,IAAM,qBAAqB,QAAQ,IAAI,sBAAsB;AAC7D,IAAM,aAAa,QAAQ,IAAI,cAAc;AAC7C,IAAI,qBAAqB,QAAQ,IAAI,sBAAsB;AAC3D,IAAI,uBAAuB,QAAQ,IAAI,wBAAwB;AAC/D,IAAI,uBAAuB,QAAQ,IAAI,wBAAwB;AAE/D,IAAM,eAAe;AAAA,EACnB,WAAW,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,iDAAiD;AAC7F;AAgBA,eAAe,YACb,SACA,UAAkE,CAAC,GAC5C;AACvB,QAAM,EAAE,KAAK,UAAU,KAAO,UAAU,IAAI;AAE5C,QAAM,SAAS,aAAa,cAAc;AAC1C,MAAI,CAAC,QAAQ;AACX,WAAO;AAAA,MACL,SAAS;AAAA,MACT,OAAO;AAAA,IACT;AAAA,EACF;AACA,SAAO;AAAA,IACL;AAAA,MACE,QAAQ;AAAA,MACR,cAAc;AAAA,MACd,WAAW;AAAA,MACX,aAAa;AAAA;AAAA,MAEb,aAAa;AAAA,IACf;AAAA,IACA,EAAE,QAAQ,SAAS,KAAK,QAAQ;AAAA,EAClC;AACF;AAKA,SAAS,gBAAgB,QAAsB,cAAsB,aAGnE;AACA,MAAI,CAAC,OAAO,WAAW,CAAC,OAAO,MAAM;AACnC,WAAO;AAAA,MACL,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,GAAG,WAAW,KAAK,OAAO,SAAS,eAAe,GAAG,CAAC;AAAA,MACtF,SAAS;AAAA,IACX;AAAA,EACF;AAEA,QAAM,EAAE,QAAQ,QAAQ,SAAS,IAAI,OAAO;AAE5C,MAAI,aAAa,GAAG;AAClB,UAAM,cAAc,UAAU,UAAU;AACxC,WAAO;AAAA,MACL,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,GAAG,WAAW,UAAU,QAAQ;AAAA,EAAO,WAAW,GAAG,CAAC;AAAA,MACtF,SAAS;AAAA,IACX;AAAA,EACF;AAEA,SAAO;AAAA,IACL,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,UAAU,cAAc,CAAC;AAAA,EAC3D;AACF;AAGA,IAAM,SAAS,IAAI,UAAU;AAAA,EAC3B,MAAM;AAAA,EACN,SAAS;AACX,GAAG;AAAA,EACD,cAAc;AAAA,IACZ,OAAO,CAAC;AAAA,EACV;AAAA,EACA,cAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAmBhB,CAAC;AAMD,OAAO;AAAA,EACL;AAAA,EACA;AAAA,IACE,aAAa;AAAA,IACb,aAAa;AAAA,MACX,GAAG;AAAA,MACH,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,gDAAgD;AAAA,IACtF;AAAA,EACF;AAAA,EACA,OAAO,SAAS;AACd,UAAM,SAAS,MAAM,YAAY,cAAc,EAAE,KAAK,KAAK,KAAK,WAAW,KAAK,UAAU,CAAC;AAC3F,WAAO,gBAAgB,QAAQ,0BAA0B;AAAA,EAC3D;AACF;AAEA,OAAO;AAAA,EACL;AAAA,EACA;AAAA,IACE,aAAa;AAAA,IACb,aAAa;AAAA,MACX,GAAG;AAAA,MACH,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,yCAAyC;AAAA,MAC/E,SAAS,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,qCAAqC;AAAA,MAC9E,QAAQ,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,uCAAuC;AAAA,MAC9E,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,wBAAwB;AAAA,IAC9D;AAAA,EACF;AAAA,EACA,OAAO,SAAS;AACd,UAAM,QAAQ,KAAK,SAAS;AAC5B,UAAM,SAAS,KAAK,YAAY,QAAQ,cAAc;AACtD,UAAM,SAAS,KAAK,UAAU;AAE9B,UAAM,SAAS,MAAM;AAAA,MACnB,WAAW,MAAM,OAAO,KAAK,IAAI,MAAM,GAAG,KAAK;AAAA,MAC/C,EAAE,KAAK,KAAK,KAAK,WAAW,KAAK,UAAU;AAAA,IAC7C;AACA,WAAO,gBAAgB,QAAQ,uBAAuB;AAAA,EACxD;AACF;AAEA,OAAO;AAAA,EACL;AAAA,EACA;AAAA,IACE,aAAa;AAAA,IACb,aAAa;AAAA,MACX,GAAG;AAAA,MACH,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,gCAAgC;AAAA,MACxE,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,uBAAuB;AAAA,MAC5D,QAAQ,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,iCAAiC;AAAA,MACxE,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,wBAAwB;AAAA,IAC9D;AAAA,EACF;AAAA,EACA,OAAO,SAAS;AACd,QAAI,MAAM;AACV,QAAI,KAAK,OAAQ,QAAO;AACxB,QAAI,KAAK,OAAQ,QAAO,IAAI,KAAK,MAAM;AACvC,QAAI,KAAK,KAAM,QAAO,OAAO,KAAK,IAAI;AAEtC,UAAM,SAAS,MAAM,YAAY,KAAK,EAAE,KAAK,KAAK,KAAK,WAAW,KAAK,UAAU,CAAC;AAClF,WAAO,gBAAgB,QAAQ,oBAAoB;AAAA,EACrD;AACF;AAEA,OAAO;AAAA,EACL;AAAA,EACA;AAAA,IACE,aAAa;AAAA,IACb,aAAa;AAAA,MACX,GAAG;AAAA,MACH,QAAQ,EAAE,OAAO,EAAE,SAAS,+CAA+C;AAAA,MAC3E,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,oBAAoB;AAAA,MAC1D,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,wBAAwB;AAAA,IAC9D;AAAA,EACF;AAAA,EACA,OAAO,SAAS;AACd,QAAI,MAAM,YAAY,KAAK,MAAM;AACjC,QAAI,KAAK,KAAM,QAAO;AAEtB,UAAM,SAAS,MAAM,YAAY,KAAK,EAAE,KAAK,KAAK,KAAK,WAAW,KAAK,UAAU,CAAC;AAClF,WAAO,gBAAgB,QAAQ,uBAAuB;AAAA,EACxD;AACF;AAEA,OAAO;AAAA,EACL;AAAA,EACA;AAAA,IACE,aAAa;AAAA,IACb,aAAa;AAAA,MACX,GAAG;AAAA,MACH,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,qCAAqC;AAAA,MAC1E,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,2BAA2B;AAAA,MACnE,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,wBAAwB;AAAA,IAC9D;AAAA,EACF;AAAA,EACA,OAAO,SAAS;AACd,QAAI,MAAM;AACV,QAAI,KAAK,IAAK,QAAO;AAAA,aACZ,KAAK,OAAQ,QAAO;AAE7B,UAAM,SAAS,MAAM,YAAY,KAAK,EAAE,KAAK,KAAK,KAAK,WAAW,KAAK,UAAU,CAAC;AAClF,WAAO,gBAAgB,QAAQ,yBAAyB;AAAA,EAC1D;AACF;AAMA,OAAO;AAAA,EACL;AAAA,EACA;AAAA,IACE,aAAa;AAAA,IACb,aAAa;AAAA,MACX,GAAG;AAAA,MACH,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS,kCAAkC;AAAA,MACtE,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,wBAAwB;AAAA,IAC9D;AAAA,EACF;AAAA,EACA,OAAO,SAAS;AACd,UAAM,QAAQ,KAAK,MAAM,IAAI,OAAK,IAAI,CAAC,GAAG,EAAE,KAAK,GAAG;AACpD,UAAM,SAAS,MAAM,YAAY,WAAW,KAAK,IAAI,EAAE,KAAK,KAAK,KAAK,WAAW,KAAK,UAAU,CAAC;AAEjG,QAAI,CAAC,OAAO,WAAY,OAAO,QAAQ,OAAO,KAAK,aAAa,GAAI;AAClE,aAAO,gBAAgB,QAAQ,qBAAqB;AAAA,IACtD;AAEA,WAAO;AAAA,MACL,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,SAAS,KAAK,MAAM,MAAM,2BAA2B,CAAC;AAAA,IACxF;AAAA,EACF;AACF;AAEA,OAAO;AAAA,EACL;AAAA,EACA;AAAA,IACE,aAAa;AAAA,IACb,aAAa;AAAA,MACX,GAAG;AAAA,MACH,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS,EAAE,SAAS,kBAAkB;AAAA,MACjE,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,wCAAwC;AAAA,MAC9E,QAAQ,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,oBAAoB;AAAA,MAC3D,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,wBAAwB;AAAA,IAC9D;AAAA,EACF;AAAA,EACA,OAAO,SAAS;AACd,QAAI,MAAM;AACV,QAAI,KAAK,KAAM,QAAO;AACtB,QAAI,KAAK,OAAQ,QAAO,IAAI,KAAK,MAAM;AACvC,QAAI,KAAK,SAAS,KAAK,MAAM,SAAS,GAAG;AACvC,aAAO,SAAS,KAAK,MAAM,IAAI,OAAK,IAAI,CAAC,GAAG,EAAE,KAAK,GAAG;AAAA,IACxD;AAEA,UAAM,SAAS,MAAM,YAAY,KAAK,EAAE,KAAK,KAAK,KAAK,WAAW,KAAK,UAAU,CAAC;AAClF,WAAO,gBAAgB,QAAQ,iBAAiB;AAAA,EAClD;AACF;AAMA,OAAO;AAAA,EACL;AAAA,EACA;AAAA,IACE,aAAa;AAAA,IACb,aAAa;AAAA,MACX,GAAG;AAAA,MACH,SAAS,EAAE,OAAO,EAAE,SAAS,gBAAgB;AAAA,MAC7C,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,6CAA6C;AAAA,MAClF,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,2BAA2B;AAAA,MAClE,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,wBAAwB;AAAA,IAC9D;AAAA,EACF;AAAA,EACA,OAAO,SAAS;AAEd,UAAM,iBAAiB,KAAK,QAAQ,QAAQ,MAAM,OAAO;AAEzD,QAAI,MAAM,kBAAkB,cAAc;AAC1C,QAAI,KAAK,IAAK,OAAM,IAAI,QAAQ,cAAc,eAAe;AAC7D,QAAI,KAAK,MAAO,QAAO;AAEvB,UAAM,SAAS,MAAM,YAAY,KAAK,EAAE,KAAK,KAAK,KAAK,WAAW,KAAK,UAAU,CAAC;AAClF,WAAO,gBAAgB,QAAQ,kBAAkB;AAAA,EACnD;AACF;AAMA,OAAO;AAAA,EACL;AAAA,EACA;AAAA,IACE,aAAa;AAAA,IACb,aAAa;AAAA,MACX,GAAG;AAAA,MACH,QAAQ,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,+BAA+B;AAAA,MACtE,QAAQ,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,aAAa;AAAA,MACpD,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,gCAAgC;AAAA,MACvE,aAAa,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,4BAA4B;AAAA,MACzE,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,wBAAwB;AAAA,IAC9D;AAAA,EACF;AAAA,EACA,OAAO,SAAS;AACd,QAAI,MAAM;AACV,QAAI,KAAK,YAAa,QAAO;AAC7B,QAAI,KAAK,MAAO,QAAO;AACvB,QAAI,KAAK,OAAQ,QAAO,IAAI,KAAK,MAAM;AACvC,QAAI,KAAK,OAAQ,QAAO,IAAI,KAAK,MAAM;AAEvC,UAAM,SAAS,MAAM,YAAY,KAAK,EAAE,KAAK,KAAK,KAAK,SAAS,KAAO,WAAW,KAAK,UAAU,CAAC;AAClG,WAAO,gBAAgB,QAAQ,gBAAgB;AAAA,EACjD;AACF;AAEA,OAAO;AAAA,EACL;AAAA,EACA;AAAA,IACE,aAAa;AAAA,IACb,aAAa;AAAA,MACX,GAAG;AAAA,MACH,QAAQ,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,+BAA+B;AAAA,MACtE,QAAQ,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,aAAa;AAAA,MACpD,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,yBAAyB;AAAA,MACjE,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,wBAAwB;AAAA,IAC9D;AAAA,EACF;AAAA,EACA,OAAO,SAAS;AACd,QAAI,MAAM;AACV,QAAI,KAAK,OAAQ,QAAO;AACxB,QAAI,KAAK,OAAQ,QAAO,IAAI,KAAK,MAAM;AACvC,QAAI,KAAK,OAAQ,QAAO,IAAI,KAAK,MAAM;AAEvC,UAAM,SAAS,MAAM,YAAY,KAAK,EAAE,KAAK,KAAK,KAAK,SAAS,KAAO,WAAW,KAAK,UAAU,CAAC;AAClG,WAAO,gBAAgB,QAAQ,gBAAgB;AAAA,EACjD;AACF;AAEA,OAAO;AAAA,EACL;AAAA,EACA;AAAA,IACE,aAAa;AAAA,IACb,aAAa;AAAA,MACX,GAAG;AAAA,MACH,QAAQ,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,oCAAoC;AAAA,MAC3E,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,gCAAgC;AAAA,MACvE,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,wBAAwB;AAAA,IAC9D;AAAA,EACF;AAAA,EACA,OAAO,SAAS;AACd,QAAI,MAAM;AACV,QAAI,KAAK,MAAO,QAAO;AACvB,QAAI,KAAK,OAAQ,QAAO,IAAI,KAAK,MAAM;AAAA,QAClC,QAAO;AAEZ,UAAM,SAAS,MAAM,YAAY,KAAK,EAAE,KAAK,KAAK,KAAK,SAAS,KAAO,WAAW,KAAK,UAAU,CAAC;AAClG,WAAO,gBAAgB,QAAQ,iBAAiB;AAAA,EAClD;AACF;AAMA,OAAO;AAAA,EACL;AAAA,EACA;AAAA,IACE,aAAa;AAAA,IACb,aAAa;AAAA,MACX,GAAG;AAAA,MACH,QAAQ,EAAE,OAAO,EAAE,SAAS,mCAAmC;AAAA,MAC/D,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,wBAAwB;AAAA,MAChE,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,wBAAwB;AAAA,IAC9D;AAAA,EACF;AAAA,EACA,OAAO,SAAS;AACd,QAAI,MAAM;AACV,QAAI,KAAK,OAAQ,QAAO;AACxB,WAAO,IAAI,KAAK,MAAM;AAEtB,UAAM,SAAS,MAAM,YAAY,KAAK,EAAE,KAAK,KAAK,KAAK,WAAW,KAAK,UAAU,CAAC;AAClF,WAAO,gBAAgB,QAAQ,oBAAoB;AAAA,EACrD;AACF;AAEA,OAAO;AAAA,EACL;AAAA,EACA;AAAA,IACE,aAAa;AAAA,IACb,aAAa;AAAA,MACX,GAAG;AAAA,MACH,MAAM,EAAE,OAAO,EAAE,SAAS,yBAAyB;AAAA,MACnD,YAAY,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,wBAAwB;AAAA,MACnE,UAAU,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,qCAAqC;AAAA,MAC/E,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,wBAAwB;AAAA,IAC9D;AAAA,EACF;AAAA,EACA,OAAO,SAAS;AACd,QAAI;AACJ,QAAI,KAAK,UAAU;AACjB,YAAM,mBAAmB,KAAK,IAAI;AAAA,IACpC,OAAO;AACL,YAAM,cAAc,KAAK,IAAI;AAAA,IAC/B;AACA,QAAI,KAAK,WAAY,QAAO,IAAI,KAAK,UAAU;AAE/C,UAAM,SAAS,MAAM,YAAY,KAAK,EAAE,KAAK,KAAK,KAAK,WAAW,KAAK,UAAU,CAAC;AAElF,QAAI,CAAC,OAAO,WAAY,OAAO,QAAQ,OAAO,KAAK,aAAa,GAAI;AAClE,aAAO,gBAAgB,QAAQ,yBAAyB;AAAA,IAC1D;AAEA,WAAO;AAAA,MACL,SAAS,CAAC;AAAA,QACR,MAAM;AAAA,QACN,MAAM,mBAAmB,KAAK,IAAI,IAAI,KAAK,WAAW,wBAAwB,EAAE;AAAA,MAClF,CAAC;AAAA,IACH;AAAA,EACF;AACF;AAEA,OAAO;AAAA,EACL;AAAA,EACA;AAAA,IACE,aAAa;AAAA,IACb,aAAa;AAAA,MACX,GAAG;AAAA,MACH,MAAM,EAAE,OAAO,EAAE,SAAS,uBAAuB;AAAA,MACjD,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,mCAAmC;AAAA,MAC1E,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,sBAAsB;AAAA,MAC9D,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,wBAAwB;AAAA,IAC9D;AAAA,EACF;AAAA,EACA,OAAO,SAAS;AACd,QAAI;AACJ,QAAI,KAAK,QAAQ;AACf,YAAM,4BAA4B,KAAK,IAAI;AAAA,IAC7C,OAAO;AACL,YAAM,cAAc,KAAK,QAAQ,OAAO,IAAI,IAAI,KAAK,IAAI;AAAA,IAC3D;AAEA,UAAM,SAAS,MAAM,YAAY,KAAK,EAAE,KAAK,KAAK,KAAK,WAAW,KAAK,UAAU,CAAC;AAClF,WAAO,gBAAgB,QAAQ,yBAAyB;AAAA,EAC1D;AACF;AAEA,OAAO;AAAA,EACL;AAAA,EACA;AAAA,IACE,aAAa;AAAA,IACb,aAAa;AAAA,MACX,GAAG;AAAA,MACH,QAAQ,EAAE,OAAO,EAAE,SAAS,qCAAqC;AAAA,MACjE,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,2CAA2C;AAAA,MACjF,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,mCAAmC;AAAA,MAC3E,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,sBAAsB;AAAA,MAC9D,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,wBAAwB;AAAA,IAC9D;AAAA,EACF;AAAA,EACA,OAAO,SAAS;AACd,QAAI,MAAM,aAAa,KAAK,MAAM;AAClC,QAAI,KAAK,KAAM,QAAO;AACtB,QAAI,KAAK,OAAQ,QAAO;AACxB,QAAI,KAAK,SAAS;AAChB,YAAM,iBAAiB,KAAK,QAAQ,QAAQ,MAAM,OAAO;AACzD,aAAO,QAAQ,cAAc;AAAA,IAC/B;AAEA,UAAM,SAAS,MAAM,YAAY,KAAK,EAAE,KAAK,KAAK,KAAK,WAAW,KAAK,UAAU,CAAC;AAClF,WAAO,gBAAgB,QAAQ,iBAAiB;AAAA,EAClD;AACF;AAMA,OAAO;AAAA,EACL;AAAA,EACA;AAAA,IACE,aAAa;AAAA,IACb,aAAa;AAAA,MACX,GAAG;AAAA,MACH,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,2BAA2B;AAAA,MACnE,kBAAkB,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,yBAAyB;AAAA,MAC3E,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,wBAAwB;AAAA,IAC9D;AAAA,EACF;AAAA,EACA,OAAO,SAAS;AACd,QAAI,MAAM;AACV,QAAI,KAAK,iBAAkB,QAAO;AAClC,QAAI,KAAK,SAAS;AAChB,YAAM,iBAAiB,KAAK,QAAQ,QAAQ,MAAM,OAAO;AACzD,aAAO,QAAQ,cAAc;AAAA,IAC/B;AAEA,UAAM,SAAS,MAAM,YAAY,KAAK,EAAE,KAAK,KAAK,KAAK,WAAW,KAAK,UAAU,CAAC;AAClF,WAAO,gBAAgB,QAAQ,iBAAiB;AAAA,EAClD;AACF;AAEA,OAAO;AAAA,EACL;AAAA,EACA;AAAA,IACE,aAAa;AAAA,IACb,aAAa;AAAA,MACX,GAAG;AAAA,MACH,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,uCAAuC;AAAA,MAC7E,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,wBAAwB;AAAA,IAC9D;AAAA,EACF;AAAA,EACA,OAAO,SAAS;AACd,UAAM,WAAW,KAAK,UAAU,SAAY,UAAU,KAAK,KAAK,MAAM;AACtE,UAAM,SAAS,MAAM,YAAY,iBAAiB,QAAQ,GAAG,KAAK,GAAG,EAAE,KAAK,KAAK,KAAK,WAAW,KAAK,UAAU,CAAC;AACjH,WAAO,gBAAgB,QAAQ,qBAAqB;AAAA,EACtD;AACF;AAEA,OAAO;AAAA,EACL;AAAA,EACA;AAAA,IACE,aAAa;AAAA,IACb,aAAa;AAAA,MACX,GAAG;AAAA,MACH,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,wBAAwB;AAAA,IAC9D;AAAA,EACF;AAAA,EACA,OAAO,SAAS;AACd,UAAM,SAAS,MAAM,YAAY,kBAAkB,EAAE,KAAK,KAAK,KAAK,WAAW,KAAK,UAAU,CAAC;AAC/F,WAAO,gBAAgB,QAAQ,wBAAwB;AAAA,EACzD;AACF;AAMA,OAAO;AAAA,EACL;AAAA,EACA;AAAA,IACE,aAAa;AAAA,IACb,aAAa;AAAA,MACX,GAAG;AAAA,MACH,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,oDAAoD;AAAA,IAC1F;AAAA,EACF;AAAA,EACA,OAAO,SAAS;AACd,UAAM,SAAS,MAAM,YAAY,qBAAqB,EAAE,KAAK,KAAK,KAAK,WAAW,KAAK,UAAU,CAAC;AAClG,WAAO,gBAAgB,QAAQ,0BAA0B;AAAA,EAC3D;AACF;AAEA,OAAO;AAAA,EACL;AAAA,EACA;AAAA,IACE,aAAa;AAAA,IACb,aAAa;AAAA,MACX,GAAG;AAAA,MACH,MAAM,EAAE,OAAO,EAAE,SAAS,6CAA6C;AAAA,MACvE,QAAQ,EAAE,OAAO,EAAE,SAAS,wCAAwC;AAAA,MACpE,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,+CAA+C;AAAA,MACvF,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,oDAAoD;AAAA,IAC1F;AAAA,EACF;AAAA,EACA,OAAO,SAAS;AACd,QAAI,MAAM;AACV,QAAI,KAAK,QAAQ;AACf,aAAO,OAAO,KAAK,MAAM,KAAK,KAAK,IAAI;AAAA,IACzC,OAAO;AACL,aAAO,KAAK,KAAK,IAAI,KAAK,KAAK,MAAM;AAAA,IACvC;AAEA,UAAM,SAAS,MAAM,YAAY,KAAK,EAAE,KAAK,KAAK,KAAK,WAAW,KAAK,UAAU,CAAC;AAElF,QAAI,CAAC,OAAO,WAAY,OAAO,QAAQ,OAAO,KAAK,aAAa,GAAI;AAClE,aAAO,gBAAgB,QAAQ,2BAA2B;AAAA,IAC5D;AAEA,WAAO;AAAA,MACL,SAAS,CAAC;AAAA,QACR,MAAM;AAAA,QACN,MAAM,wBAAwB,KAAK,IAAI,iBAAiB,KAAK,MAAM;AAAA,MACrE,CAAC;AAAA,IACH;AAAA,EACF;AACF;AAEA,OAAO;AAAA,EACL;AAAA,EACA;AAAA,IACE,aAAa;AAAA,IACb,aAAa;AAAA,MACX,GAAG;AAAA,MACH,MAAM,EAAE,OAAO,EAAE,SAAS,gCAAgC;AAAA,MAC1D,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,6CAA6C;AAAA,MACpF,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,oDAAoD;AAAA,IAC1F;AAAA,EACF;AAAA,EACA,OAAO,SAAS;AACd,QAAI,MAAM,wBAAwB,KAAK,IAAI;AAC3C,QAAI,KAAK,MAAO,QAAO;AAEvB,UAAM,SAAS,MAAM,YAAY,KAAK,EAAE,KAAK,KAAK,KAAK,WAAW,KAAK,UAAU,CAAC;AAElF,QAAI,CAAC,OAAO,WAAY,OAAO,QAAQ,OAAO,KAAK,aAAa,GAAI;AAClE,aAAO,gBAAgB,QAAQ,2BAA2B;AAAA,IAC5D;AAEA,WAAO;AAAA,MACL,SAAS,CAAC;AAAA,QACR,MAAM;AAAA,QACN,MAAM,wBAAwB,KAAK,IAAI;AAAA,MACzC,CAAC;AAAA,IACH;AAAA,EACF;AACF;AAEA,OAAO;AAAA,EACL;AAAA,EACA;AAAA,IACE,aAAa;AAAA,IACb,aAAa;AAAA,MACX,GAAG;AAAA,MACH,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,oDAAoD;AAAA,IAC1F;AAAA,EACF;AAAA,EACA,OAAO,SAAS;AACd,UAAM,SAAS,MAAM,YAAY,sBAAsB,EAAE,KAAK,KAAK,KAAK,WAAW,KAAK,UAAU,CAAC;AAEnG,QAAI,CAAC,OAAO,WAAY,OAAO,QAAQ,OAAO,KAAK,aAAa,GAAI;AAClE,aAAO,gBAAgB,QAAQ,2BAA2B;AAAA,IAC5D;AAEA,WAAO;AAAA,MACL,SAAS,CAAC;AAAA,QACR,MAAM;AAAA,QACN,MAAM;AAAA,MACR,CAAC;AAAA,IACH;AAAA,EACF;AACF;AAMA,eAAsB,cAAc;AAClC,QAAM,gBAAgB,MAAM,qBAAqB;AACjD,oBAAkB,cAAc;AAChC,0BAAwB,cAAc;AACtC,uBAAqB,cAAc;AACnC,yBAAuB,cAAc;AACrC,yBAAuB,cAAc,eAAe;AAEpD,MAAI,CAAC,cAAc,CAAC,oBAAoB;AACtC,YAAQ,KAAK,gGAAgG;AAAA,EAC/G;AAEA,QAAM,YAAY,IAAI,qBAAqB;AAC3C,QAAM,OAAO,QAAQ,SAAS;AAE9B,QAAM,YAAY,cAAc,sBAAsB;AACtD,UAAQ,MAAM,kCAAkC;AAChD,UAAQ,MAAM,0BAA0B,eAAe,EAAE;AACzD,UAAQ,MAAM,6BAA6B,SAAS,EAAE;AACtD,UAAQ,MAAM,wBAAwB,wBAAwB,SAAS,SAAS,EAAE;AACpF;AAEA,IAAI,QAAQ,IAAI,6BAA6B,KAAK;AAChD,cAAY,EAAE,MAAM,CAAC,UAAU;AAC7B,YAAQ,MAAM,8BAA8B,KAAK;AACjD,YAAQ,KAAK,CAAC;AAAA,EAChB,CAAC;AACH;","names":[]}
|