@geekmidas/cli 0.13.0 → 0.14.0
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/{bundler-B1qy9b-j.cjs → bundler-BjholBlA.cjs} +26 -7
- package/dist/bundler-BjholBlA.cjs.map +1 -0
- package/dist/{bundler-DskIqW2t.mjs → bundler-DWctKN1z.mjs} +27 -8
- package/dist/bundler-DWctKN1z.mjs.map +1 -0
- package/dist/config.d.cts +1 -1
- package/dist/config.d.mts +1 -1
- package/dist/dokploy-api-B7KxOQr3.cjs +3 -0
- package/dist/dokploy-api-C7F9VykY.cjs +317 -0
- package/dist/dokploy-api-C7F9VykY.cjs.map +1 -0
- package/dist/dokploy-api-CaETb2L6.mjs +305 -0
- package/dist/dokploy-api-CaETb2L6.mjs.map +1 -0
- package/dist/dokploy-api-DHvfmWbi.mjs +3 -0
- package/dist/{encryption-Dyf_r1h-.cjs → encryption-D7Efcdi9.cjs} +1 -1
- package/dist/{encryption-Dyf_r1h-.cjs.map → encryption-D7Efcdi9.cjs.map} +1 -1
- package/dist/{encryption-C8H-38Yy.mjs → encryption-h4Nb6W-M.mjs} +1 -1
- package/dist/{encryption-C8H-38Yy.mjs.map → encryption-h4Nb6W-M.mjs.map} +1 -1
- package/dist/index.cjs +1513 -1136
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +1513 -1136
- package/dist/index.mjs.map +1 -1
- package/dist/{openapi-Bt_1FDpT.cjs → openapi-C89hhkZC.cjs} +3 -3
- package/dist/{openapi-Bt_1FDpT.cjs.map → openapi-C89hhkZC.cjs.map} +1 -1
- package/dist/{openapi-BfFlOBCG.mjs → openapi-CZVcfxk-.mjs} +3 -3
- package/dist/{openapi-BfFlOBCG.mjs.map → openapi-CZVcfxk-.mjs.map} +1 -1
- package/dist/{openapi-react-query-B6XTeGqS.mjs → openapi-react-query-CM2_qlW9.mjs} +1 -1
- package/dist/{openapi-react-query-B6XTeGqS.mjs.map → openapi-react-query-CM2_qlW9.mjs.map} +1 -1
- package/dist/{openapi-react-query-B-sNWHFU.cjs → openapi-react-query-iKjfLzff.cjs} +1 -1
- package/dist/{openapi-react-query-B-sNWHFU.cjs.map → openapi-react-query-iKjfLzff.cjs.map} +1 -1
- package/dist/openapi-react-query.cjs +1 -1
- package/dist/openapi-react-query.mjs +1 -1
- package/dist/openapi.cjs +1 -1
- package/dist/openapi.d.cts +1 -1
- package/dist/openapi.d.mts +1 -1
- package/dist/openapi.mjs +1 -1
- package/dist/{storage-kSxTjkNb.mjs → storage-BaOP55oq.mjs} +16 -2
- package/dist/storage-BaOP55oq.mjs.map +1 -0
- package/dist/{storage-Bj1E26lU.cjs → storage-Bn3K9Ccu.cjs} +21 -1
- package/dist/storage-Bn3K9Ccu.cjs.map +1 -0
- package/dist/storage-UfyTn7Zm.cjs +7 -0
- package/dist/storage-nkGIjeXt.mjs +3 -0
- package/dist/{types-BhkZc-vm.d.cts → types-BgaMXsUa.d.cts} +3 -1
- package/dist/{types-BR0M2v_c.d.mts.map → types-BgaMXsUa.d.cts.map} +1 -1
- package/dist/{types-BR0M2v_c.d.mts → types-iFk5ms7y.d.mts} +3 -1
- package/dist/{types-BhkZc-vm.d.cts.map → types-iFk5ms7y.d.mts.map} +1 -1
- package/package.json +3 -3
- package/src/auth/__tests__/credentials.spec.ts +127 -0
- package/src/auth/__tests__/index.spec.ts +69 -0
- package/src/auth/credentials.ts +33 -0
- package/src/auth/index.ts +57 -50
- package/src/build/__tests__/bundler.spec.ts +1 -1
- package/src/build/__tests__/endpoint-analyzer.spec.ts +623 -0
- package/src/build/__tests__/handler-templates.spec.ts +272 -0
- package/src/build/bundler.ts +53 -4
- package/src/build/index.ts +21 -0
- package/src/build/types.ts +6 -0
- package/src/deploy/__tests__/dokploy-api.spec.ts +698 -0
- package/src/deploy/__tests__/dokploy.spec.ts +196 -6
- package/src/deploy/__tests__/index.spec.ts +339 -0
- package/src/deploy/__tests__/init.spec.ts +147 -16
- package/src/deploy/docker.ts +32 -3
- package/src/deploy/dokploy-api.ts +581 -0
- package/src/deploy/dokploy.ts +66 -93
- package/src/deploy/index.ts +587 -32
- package/src/deploy/init.ts +192 -249
- package/src/deploy/types.ts +19 -1
- package/src/dev/__tests__/index.spec.ts +95 -0
- package/src/docker/__tests__/templates.spec.ts +144 -0
- package/src/docker/index.ts +96 -6
- package/src/docker/templates.ts +114 -27
- package/src/generators/EndpointGenerator.ts +2 -2
- package/src/index.ts +34 -13
- package/src/secrets/storage.ts +15 -0
- package/src/types.ts +2 -0
- package/dist/bundler-B1qy9b-j.cjs.map +0 -1
- package/dist/bundler-DskIqW2t.mjs.map +0 -1
- package/dist/storage-BOOpAF8N.cjs +0 -5
- package/dist/storage-Bj1E26lU.cjs.map +0 -1
- package/dist/storage-kSxTjkNb.mjs.map +0 -1
- package/dist/storage-tgZSUnKl.mjs +0 -3
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","names":["options?: CredentialOptions","credentials: StoredCredentials","token: string","endpoint: string","logger","endpoint: string","token: string","message: string","resolve","char: Buffer","options: LoginOptions","options: LogoutOptions","config: GkmConfig","options: BuildOptions","providers: LegacyProvider[]","mainProvider: MainProvider","providersConfig?: ProvidersConfig","providersConfig: ProvidersConfig","config:\n\t\t| boolean\n\t\t| AWSApiGatewayConfig\n\t\t| AWSLambdaConfig\n\t\t| ServerConfig\n\t\t| undefined","ConstructGenerator","context: BuildContext","constructs: GeneratedConstruct<\n\t\t\tCron<any, any, any, any, any, any, any, any>\n\t\t>[]","outputDir: string","options?: GeneratorOptions","logger","cronInfos: CronInfo[]","value: any","sourceFile: string","exportName: string","ConstructGenerator","value: any","context: BuildContext","constructs: GeneratedConstruct<\n\t\t\tFunction<any, any, any, any, any, any, any, any, any, any, any, any>\n\t\t>[]","outputDir: string","options?: GeneratorOptions","logger","functionInfos: FunctionInfo[]","sourceFile: string","exportName: string","ConstructGenerator","value: any","context: BuildContext","constructs: GeneratedConstruct<Subscriber<any, any, any, any, any, any>>[]","outputDir: string","options?: GeneratorOptions","logger","subscriberInfos: SubscriberInfo[]","sourceFile: string","exportName: string","_subscriber: Subscriber<any, any, any, any, any, any>","subscribers: GeneratedConstruct<Subscriber<any, any, any, any, any, any>>[]","exports","logger","envConfig: string | string[] | undefined","cwd: string","loaded: string[]","missing: string[]","port: number","resolve","err: NodeJS.ErrnoException","preferredPort: number","config: GkmConfig['telescope']","isEnabled","telescopeConfig: TelescopeConfig","config: GkmConfig['studio']","studioConfig: StudioConfig","config: GkmConfig['hooks']","cliProduction: boolean","configProduction?: ProductionConfig","config: GkmConfig","options: DevOptions","OPENAPI_OUTPUT_PATH","buildContext: BuildContext","runtime: Runtime","rebuildTimeout: NodeJS.Timeout | null","config: any","context: BuildContext","provider: LegacyProvider","enableOpenApi: boolean","EndpointGenerator","requestedPort: number","portExplicit: boolean","telescope?: NormalizedTelescopeConfig","studio?: NormalizedStudioConfig","logger","outputDir: string","routes: RouteInfo[]","functions: FunctionInfo[]","crons: CronInfo[]","subscribers: SubscriberInfo[]","appInfo: ServerAppInfo","logger","options: BuildOptions","buildContext: BuildContext","EndpointGenerator","result: BuildResult","provider: LegacyProvider","context: BuildContext","rootOutputDir: string","endpointGenerator: EndpointGenerator","functionGenerator: FunctionGenerator","cronGenerator: CronGenerator","subscriberGenerator: SubscriberGenerator","endpoints: GeneratedConstruct<Endpoint<any, any, any, any, any, any>>[]","functions: GeneratedConstruct<Function<any, any, any, any>>[]","crons: GeneratedConstruct<Cron<any, any, any, any>>[]","subscribers: GeneratedConstruct<Subscriber<any, any, any, any, any, any>>[]","enableOpenApi: boolean","skipBundle: boolean","stage?: string","routeMetadata: RouteInfo[]","appInfo: ServerAppInfo","masterKey: string | undefined","logger","registry: string | undefined","imageName: string","tag: string","imageRef: string","options: DockerDeployOptions","resolveDockerConfig","config: GkmConfig","logger","getApiToken","dokployRequest","endpoint: string","baseUrl: string","token: string","body: Record<string, unknown>","applicationId: string","envVars: Record<string, string>","options: DokployDeployOptions","config: Partial<DokployDeployConfig> | undefined","logger","stage: string","options: DeployOptions","masterKey: string | undefined","result: DeployResult","logger","method: 'GET' | 'POST'","endpoint: string","baseUrl: string","token: string","body?: Record<string, unknown>","name: string","description?: string","description","projectId: string","environmentId: string","applicationId: string","registryId: string","config: DokployDeployConfig","cwd: string","newContent: string","options: DeployInitOptions","options: {\n\tendpoint?: string;\n\tresource: 'projects' | 'registries';\n}","DEFAULT_SERVICE_IMAGES: Record<ComposeServiceName, string>","DEFAULT_SERVICE_VERSIONS: Record<ComposeServiceName, string>","serviceName: ComposeServiceName","services: ComposeServicesConfig | ComposeServiceName[]","name","version","options: ComposeOptions","options: Omit<ComposeOptions, 'services'>","detectPackageManager","cwd: string","lockfiles: [string, PackageManager][]","pm: PackageManager","options: MultiStageDockerfileOptions","options: DockerTemplateOptions","config: GkmConfig","logger","options: DockerOptions","result: DockerGeneratedFiles","imageName: string","options: TemplateOptions","template: TemplateConfig","options: TemplateOptions","template: TemplateConfig","services: string[]","volumes: string[]","options: TemplateOptions","template: TemplateConfig","files: GeneratedFile[]","options: TemplateOptions","options: TemplateOptions","_template: TemplateConfig","apiTemplate: TemplateConfig","options: TemplateOptions","file: string","files: GeneratedFile[]","minimalTemplate: TemplateConfig","options: TemplateOptions","file: string","files: GeneratedFile[]","serverlessTemplate: TemplateConfig","options: TemplateOptions","file: string","files: GeneratedFile[]","workerTemplate: TemplateConfig","options: TemplateOptions","file: string","files: GeneratedFile[]","OPENAPI_OUTPUT_PATH","templates: Record<TemplateName, TemplateConfig>","name: TemplateName","name","options: TemplateOptions","template: TemplateConfig","dependencies","devDependencies","scripts","name","obj: Record<string, string>","OPENAPI_OUTPUT_PATH","options: TemplateOptions","template: TemplateConfig","cwd: string","name: string","name","pkgManager: PackageManager","script: string","projectName?: string","options: InitOptions","value: string","name","templateOptions: TemplateOptions","SERVICE_DEFAULTS: Record<\n\tComposeServiceName,\n\tOmit<ServiceCredentials, 'password'>\n>","service: ComposeServiceName","services: ComposeServiceName[]","result: StageSecrets['services']","creds: ServiceCredentials","services: StageSecrets['services']","urls: StageSecrets['urls']","stage: string","secrets: StageSecrets","newCreds: ServiceCredentials","services: ComposeServicesConfig | ComposeServiceName[] | undefined","name","options: SecretsInitOptions","chunks: Buffer[]","key: string","value: string | undefined","options: SecretsSetOptions","options: SecretsShowOptions","options: SecretsRotateOptions","file: string","options: SecretsImportOptions","importedSecrets: Record<string, string>","url: string","Command","pkg","name: string | undefined","options: InitOptions","name","options: {\n\t\t\tprovider?: string;\n\t\t\tproviders?: string;\n\t\t\tenableOpenapi?: boolean;\n\t\t\tproduction?: boolean;\n\t\t\tskipBundle?: boolean;\n\t\t\tstage?: string;\n\t\t}","options: { port?: string; enableOpenapi?: boolean }","options: { input?: string; output?: string; name?: string }","options: DockerOptions","options: {\n\t\t\tbuild?: boolean;\n\t\t\tpush?: boolean;\n\t\t\ttag?: string;\n\t\t\tregistry?: string;\n\t\t\tslim?: boolean;\n\t\t\tskipBundle?: boolean;\n\t\t\tturbo?: boolean;\n\t\t\tturboPackage?: string;\n\t\t}","options: { stage: string; force?: boolean }","key: string","value: string | undefined","options: { stage: string }","options: { stage: string; reveal?: boolean }","options: { stage: string; service?: ComposeServiceName }","file: string","options: { stage: string; merge?: boolean }","options: {\n\t\t\tprovider: string;\n\t\t\tstage: string;\n\t\t\ttag?: string;\n\t\t\tskipPush?: boolean;\n\t\t\tskipBuild?: boolean;\n\t\t}","options: {\n\t\t\tendpoint?: string;\n\t\t\tproject: string;\n\t\t\tapp: string;\n\t\t\tprojectId?: string;\n\t\t\tregistryId?: string;\n\t\t}","options: {\n\t\t\tendpoint?: string;\n\t\t\tprojects?: boolean;\n\t\t\tregistries?: boolean;\n\t\t}","options: { service: string; token?: string; endpoint?: string }","options: { service: string }"],"sources":["../package.json","../src/auth/credentials.ts","../src/auth/index.ts","../src/build/providerResolver.ts","../src/generators/CronGenerator.ts","../src/generators/FunctionGenerator.ts","../src/generators/SubscriberGenerator.ts","../src/dev/index.ts","../src/build/manifests.ts","../src/build/index.ts","../src/deploy/docker.ts","../src/deploy/dokploy.ts","../src/deploy/index.ts","../src/deploy/init.ts","../src/docker/compose.ts","../src/docker/templates.ts","../src/docker/index.ts","../src/init/generators/config.ts","../src/init/generators/docker.ts","../src/init/generators/env.ts","../src/init/generators/models.ts","../src/init/generators/monorepo.ts","../src/init/templates/api.ts","../src/init/templates/minimal.ts","../src/init/templates/serverless.ts","../src/init/templates/worker.ts","../src/init/templates/index.ts","../src/init/generators/package.ts","../src/init/generators/source.ts","../src/init/utils.ts","../src/init/index.ts","../src/secrets/generator.ts","../src/secrets/index.ts","../src/index.ts"],"sourcesContent":["{\n\t\"name\": \"@geekmidas/cli\",\n\t\"version\": \"0.13.0\",\n\t\"description\": \"CLI tools for building Lambda handlers, server applications, and generating OpenAPI specs\",\n\t\"private\": false,\n\t\"type\": \"module\",\n\t\"exports\": {\n\t\t\".\": {\n\t\t\t\"types\": \"./dist/index.d.ts\",\n\t\t\t\"import\": \"./dist/index.mjs\",\n\t\t\t\"require\": \"./dist/index.cjs\"\n\t\t},\n\t\t\"./config\": {\n\t\t\t\"types\": \"./dist/config.d.ts\",\n\t\t\t\"import\": \"./dist/config.mjs\",\n\t\t\t\"require\": \"./dist/config.cjs\"\n\t\t},\n\t\t\"./openapi\": {\n\t\t\t\"types\": \"./dist/openapi.d.ts\",\n\t\t\t\"import\": \"./dist/openapi.mjs\",\n\t\t\t\"require\": \"./dist/openapi.cjs\"\n\t\t},\n\t\t\"./openapi-react-query\": {\n\t\t\t\"types\": \"./dist/openapi-react-query.d.ts\",\n\t\t\t\"import\": \"./dist/openapi-react-query.mjs\",\n\t\t\t\"require\": \"./dist/openapi-react-query.cjs\"\n\t\t}\n\t},\n\t\"bin\": {\n\t\t\"gkm\": \"./dist/index.cjs\"\n\t},\n\t\"scripts\": {\n\t\t\"ts\": \"tsc --noEmit --skipLibCheck src/**/*.ts\",\n\t\t\"test\": \"vitest\",\n\t\t\"test:once\": \"vitest run\",\n\t\t\"test:coverage\": \"vitest run --coverage\"\n\t},\n\t\"repository\": {\n\t\t\"type\": \"git\",\n\t\t\"url\": \"https://github.com/geekmidas/toolbox\"\n\t},\n\t\"dependencies\": {\n\t\t\"@apidevtools/swagger-parser\": \"^10.1.0\",\n\t\t\"chokidar\": \"~4.0.3\",\n\t\t\"commander\": \"^12.1.0\",\n\t\t\"dotenv\": \"~17.2.3\",\n\t\t\"fast-glob\": \"^3.3.2\",\n\t\t\"lodash.kebabcase\": \"^4.1.1\",\n\t\t\"openapi-typescript\": \"^7.4.2\",\n\t\t\"prompts\": \"~2.4.2\"\n\t},\n\t\"devDependencies\": {\n\t\t\"@geekmidas/testkit\": \"workspace:*\",\n\t\t\"@types/lodash.kebabcase\": \"^4.1.9\",\n\t\t\"@types/node\": \"~24.9.1\",\n\t\t\"@types/prompts\": \"~2.4.9\",\n\t\t\"typescript\": \"^5.8.2\",\n\t\t\"vitest\": \"^3.2.4\",\n\t\t\"zod\": \"~4.1.13\"\n\t},\n\t\"peerDependencies\": {\n\t\t\"@geekmidas/constructs\": \"workspace:~\",\n\t\t\"@geekmidas/envkit\": \"workspace:~\",\n\t\t\"@geekmidas/logger\": \"workspace:~\",\n\t\t\"@geekmidas/schema\": \"workspace:~\",\n\t\t\"@geekmidas/telescope\": \"workspace:~\"\n\t},\n\t\"peerDependenciesMeta\": {\n\t\t\"@geekmidas/telescope\": {\n\t\t\t\"optional\": true\n\t\t}\n\t}\n}\n","import { existsSync, mkdirSync } from 'node:fs';\nimport { readFile, unlink, writeFile } from 'node:fs/promises';\nimport { homedir } from 'node:os';\nimport { join } from 'node:path';\n\n/**\n * Stored credentials for various services\n */\nexport interface StoredCredentials {\n\tdokploy?: {\n\t\t/** API token */\n\t\ttoken: string;\n\t\t/** Dokploy endpoint URL */\n\t\tendpoint: string;\n\t\t/** When the credentials were stored */\n\t\tstoredAt: string;\n\t};\n}\n\n/**\n * Options for credential operations\n */\nexport interface CredentialOptions {\n\t/** Root directory for credentials storage (default: user home directory) */\n\troot?: string;\n}\n\n/**\n * Get the path to the credentials directory\n */\nexport function getCredentialsDir(options?: CredentialOptions): string {\n\tconst root = options?.root ?? homedir();\n\treturn join(root, '.gkm');\n}\n\n/**\n * Get the path to the credentials file\n */\nexport function getCredentialsPath(options?: CredentialOptions): string {\n\treturn join(getCredentialsDir(options), 'credentials.json');\n}\n\n/**\n * Ensure the credentials directory exists\n */\nfunction ensureCredentialsDir(options?: CredentialOptions): void {\n\tconst dir = getCredentialsDir(options);\n\tif (!existsSync(dir)) {\n\t\tmkdirSync(dir, { recursive: true, mode: 0o700 });\n\t}\n}\n\n/**\n * Read stored credentials from disk\n */\nexport async function readCredentials(\n\toptions?: CredentialOptions,\n): Promise<StoredCredentials> {\n\tconst path = getCredentialsPath(options);\n\n\tif (!existsSync(path)) {\n\t\treturn {};\n\t}\n\n\ttry {\n\t\tconst content = await readFile(path, 'utf-8');\n\t\treturn JSON.parse(content) as StoredCredentials;\n\t} catch {\n\t\treturn {};\n\t}\n}\n\n/**\n * Write credentials to disk\n */\nexport async function writeCredentials(\n\tcredentials: StoredCredentials,\n\toptions?: CredentialOptions,\n): Promise<void> {\n\tensureCredentialsDir(options);\n\tconst path = getCredentialsPath(options);\n\n\tawait writeFile(path, JSON.stringify(credentials, null, 2), {\n\t\tmode: 0o600, // Owner read/write only\n\t});\n}\n\n/**\n * Store Dokploy credentials\n */\nexport async function storeDokployCredentials(\n\ttoken: string,\n\tendpoint: string,\n\toptions?: CredentialOptions,\n): Promise<void> {\n\tconst credentials = await readCredentials(options);\n\n\tcredentials.dokploy = {\n\t\ttoken,\n\t\tendpoint,\n\t\tstoredAt: new Date().toISOString(),\n\t};\n\n\tawait writeCredentials(credentials, options);\n}\n\n/**\n * Get stored Dokploy credentials\n */\nexport async function getDokployCredentials(\n\toptions?: CredentialOptions,\n): Promise<{\n\ttoken: string;\n\tendpoint: string;\n} | null> {\n\tconst credentials = await readCredentials(options);\n\n\tif (!credentials.dokploy) {\n\t\treturn null;\n\t}\n\n\treturn {\n\t\ttoken: credentials.dokploy.token,\n\t\tendpoint: credentials.dokploy.endpoint,\n\t};\n}\n\n/**\n * Remove Dokploy credentials\n */\nexport async function removeDokployCredentials(\n\toptions?: CredentialOptions,\n): Promise<boolean> {\n\tconst credentials = await readCredentials(options);\n\n\tif (!credentials.dokploy) {\n\t\treturn false;\n\t}\n\n\tdelete credentials.dokploy;\n\tawait writeCredentials(credentials, options);\n\treturn true;\n}\n\n/**\n * Remove all stored credentials\n */\nexport async function removeAllCredentials(\n\toptions?: CredentialOptions,\n): Promise<void> {\n\tconst path = getCredentialsPath(options);\n\n\tif (existsSync(path)) {\n\t\tawait unlink(path);\n\t}\n}\n\n/**\n * Get Dokploy API token, checking stored credentials first, then environment\n */\nexport async function getDokployToken(\n\toptions?: CredentialOptions,\n): Promise<string | null> {\n\t// First check environment variable (takes precedence)\n\tconst envToken = process.env.DOKPLOY_API_TOKEN;\n\tif (envToken) {\n\t\treturn envToken;\n\t}\n\n\t// Then check stored credentials\n\tconst stored = await getDokployCredentials(options);\n\tif (stored) {\n\t\treturn stored.token;\n\t}\n\n\treturn null;\n}\n\n/**\n * Get Dokploy endpoint from stored credentials\n */\nexport async function getDokployEndpoint(\n\toptions?: CredentialOptions,\n): Promise<string | null> {\n\tconst stored = await getDokployCredentials(options);\n\treturn stored?.endpoint ?? null;\n}\n","import { stdin as input, stdout as output } from 'node:process';\nimport * as readline from 'node:readline/promises';\nimport {\n\tgetCredentialsPath,\n\tgetDokployCredentials,\n\tremoveDokployCredentials,\n\tstoreDokployCredentials,\n} from './credentials';\n\nconst logger = console;\n\nexport interface LoginOptions {\n\t/** Service to login to */\n\tservice: 'dokploy';\n\t/** API token (if not provided, will prompt) */\n\ttoken?: string;\n\t/** Endpoint URL */\n\tendpoint?: string;\n}\n\nexport interface LogoutOptions {\n\t/** Service to logout from */\n\tservice?: 'dokploy' | 'all';\n}\n\n/**\n * Validate Dokploy token by making a test API call\n */\nexport async function validateDokployToken(\n\tendpoint: string,\n\ttoken: string,\n): Promise<boolean> {\n\ttry {\n\t\tconst response = await fetch(`${endpoint}/api/project.all`, {\n\t\t\tmethod: 'GET',\n\t\t\theaders: {\n\t\t\t\t'Content-Type': 'application/json',\n\t\t\t\tAuthorization: `Bearer ${token}`,\n\t\t\t},\n\t\t});\n\n\t\treturn response.ok;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Prompt for input (handles both TTY and non-TTY)\n */\nasync function prompt(message: string, hidden = false): Promise<string> {\n\tif (!process.stdin.isTTY) {\n\t\tthrow new Error(\n\t\t\t'Interactive input required. Please provide --token option.',\n\t\t);\n\t}\n\n\tconst rl = readline.createInterface({ input, output });\n\n\ttry {\n\t\tif (hidden) {\n\t\t\t// For hidden input, we need to handle it differently\n\t\t\tprocess.stdout.write(message);\n\n\t\t\treturn new Promise((resolve) => {\n\t\t\t\tlet value = '';\n\n\t\t\t\tconst onData = (char: Buffer) => {\n\t\t\t\t\tconst c = char.toString();\n\n\t\t\t\t\tif (c === '\\n' || c === '\\r') {\n\t\t\t\t\t\tprocess.stdin.removeListener('data', onData);\n\t\t\t\t\t\tprocess.stdin.setRawMode(false);\n\t\t\t\t\t\tprocess.stdout.write('\\n');\n\t\t\t\t\t\tresolve(value);\n\t\t\t\t\t} else if (c === '\\u0003') {\n\t\t\t\t\t\t// Ctrl+C\n\t\t\t\t\t\tprocess.exit(1);\n\t\t\t\t\t} else if (c === '\\u007F' || c === '\\b') {\n\t\t\t\t\t\t// Backspace\n\t\t\t\t\t\tif (value.length > 0) {\n\t\t\t\t\t\t\tvalue = value.slice(0, -1);\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tvalue += c;\n\t\t\t\t\t}\n\t\t\t\t};\n\n\t\t\t\tprocess.stdin.setRawMode(true);\n\t\t\t\tprocess.stdin.resume();\n\t\t\t\tprocess.stdin.on('data', onData);\n\t\t\t});\n\t\t} else {\n\t\t\treturn await rl.question(message);\n\t\t}\n\t} finally {\n\t\trl.close();\n\t}\n}\n\n/**\n * Login to a service\n */\nexport async function loginCommand(options: LoginOptions): Promise<void> {\n\tconst { service, token: providedToken, endpoint: providedEndpoint } = options;\n\n\tif (service === 'dokploy') {\n\t\tlogger.log('\\n🔐 Logging in to Dokploy...\\n');\n\n\t\t// Get endpoint\n\t\tlet endpoint = providedEndpoint;\n\t\tif (!endpoint) {\n\t\t\tendpoint = await prompt(\n\t\t\t\t'Dokploy URL (e.g., https://dokploy.example.com): ',\n\t\t\t);\n\t\t}\n\n\t\t// Normalize endpoint (remove trailing slash)\n\t\tendpoint = endpoint.replace(/\\/$/, '');\n\n\t\t// Validate endpoint format\n\t\ttry {\n\t\t\tnew URL(endpoint);\n\t\t} catch {\n\t\t\tlogger.error('Invalid URL format');\n\t\t\tprocess.exit(1);\n\t\t}\n\n\t\t// Get token\n\t\tlet token = providedToken;\n\t\tif (!token) {\n\t\t\tlogger.log(`\\nGenerate a token at: ${endpoint}/settings/profile\\n`);\n\t\t\ttoken = await prompt('API Token: ', true);\n\t\t}\n\n\t\tif (!token) {\n\t\t\tlogger.error('Token is required');\n\t\t\tprocess.exit(1);\n\t\t}\n\n\t\t// Validate token\n\t\tlogger.log('\\nValidating credentials...');\n\t\tconst isValid = await validateDokployToken(endpoint, token);\n\n\t\tif (!isValid) {\n\t\t\tlogger.error(\n\t\t\t\t'\\n✗ Invalid credentials. Please check your token and try again.',\n\t\t\t);\n\t\t\tprocess.exit(1);\n\t\t}\n\n\t\t// Store credentials\n\t\tawait storeDokployCredentials(token, endpoint);\n\n\t\tlogger.log('\\n✓ Successfully logged in to Dokploy!');\n\t\tlogger.log(` Endpoint: ${endpoint}`);\n\t\tlogger.log(` Credentials stored in: ${getCredentialsPath()}`);\n\t\tlogger.log(\n\t\t\t'\\nYou can now use deploy commands without setting DOKPLOY_API_TOKEN.',\n\t\t);\n\t}\n}\n\n/**\n * Logout from a service\n */\nexport async function logoutCommand(options: LogoutOptions): Promise<void> {\n\tconst { service = 'dokploy' } = options;\n\n\tif (service === 'all') {\n\t\tconst dokployRemoved = await removeDokployCredentials();\n\n\t\tif (dokployRemoved) {\n\t\t\tlogger.log('\\n✓ Logged out from all services');\n\t\t} else {\n\t\t\tlogger.log('\\nNo stored credentials found');\n\t\t}\n\t\treturn;\n\t}\n\n\tif (service === 'dokploy') {\n\t\tconst removed = await removeDokployCredentials();\n\n\t\tif (removed) {\n\t\t\tlogger.log('\\n✓ Logged out from Dokploy');\n\t\t} else {\n\t\t\tlogger.log('\\nNo Dokploy credentials found');\n\t\t}\n\t}\n}\n\n/**\n * Show current login status\n */\nexport async function whoamiCommand(): Promise<void> {\n\tlogger.log('\\n📋 Current credentials:\\n');\n\n\tconst dokploy = await getDokployCredentials();\n\n\tif (dokploy) {\n\t\tlogger.log(' Dokploy:');\n\t\tlogger.log(` Endpoint: ${dokploy.endpoint}`);\n\t\tlogger.log(` Token: ${maskToken(dokploy.token)}`);\n\t} else {\n\t\tlogger.log(' Dokploy: Not logged in');\n\t}\n\n\tlogger.log(`\\n Credentials file: ${getCredentialsPath()}`);\n}\n\n/**\n * Mask a token for display\n */\nexport function maskToken(token: string): string {\n\tif (token.length <= 8) {\n\t\treturn '****';\n\t}\n\treturn `${token.slice(0, 4)}...${token.slice(-4)}`;\n}\n\n// Re-export credentials utilities for use in other modules\nexport {\n\tgetDokployCredentials,\n\tgetDokployEndpoint,\n\tgetDokployToken,\n} from './credentials';\n","import type {\n\tAWSApiGatewayConfig,\n\tAWSLambdaConfig,\n\tBuildOptions,\n\tGkmConfig,\n\tLegacyProvider,\n\tMainProvider,\n\tProvidersConfig,\n\tServerConfig,\n} from '../types';\n\nexport interface ResolvedProviders {\n\tproviders: LegacyProvider[];\n\tenableOpenApi: boolean;\n}\n\n/**\n * Resolves provider configuration from the new simplified system\n * to the internal legacy format for backward compatibility\n */\nexport function resolveProviders(\n\tconfig: GkmConfig,\n\toptions: BuildOptions,\n): ResolvedProviders {\n\tconst providers: LegacyProvider[] = [];\n\tlet enableOpenApi = options.enableOpenApi || false;\n\n\t// Handle legacy providers option (deprecated)\n\tif (options.providers) {\n\t\treturn {\n\t\t\tproviders: options.providers,\n\t\t\tenableOpenApi,\n\t\t};\n\t}\n\n\t// Handle new provider option\n\tif (options.provider) {\n\t\tconst resolvedProviders = resolveMainProvider(\n\t\t\toptions.provider,\n\t\t\tconfig.providers,\n\t\t);\n\t\tproviders.push(...resolvedProviders.providers);\n\t\tenableOpenApi = resolvedProviders.enableOpenApi || enableOpenApi;\n\t}\n\t// Default: build all configured providers\n\telse if (config.providers) {\n\t\tconst resolvedProviders = resolveAllConfiguredProviders(config.providers);\n\t\tproviders.push(...resolvedProviders.providers);\n\t\tenableOpenApi = resolvedProviders.enableOpenApi || enableOpenApi;\n\t}\n\t// Fallback: use default AWS configuration\n\telse {\n\t\tproviders.push('aws-apigatewayv2', 'aws-lambda');\n\t}\n\n\treturn {\n\t\tproviders: [...new Set(providers)], // Remove duplicates\n\t\tenableOpenApi,\n\t};\n}\n\nfunction resolveMainProvider(\n\tmainProvider: MainProvider,\n\tprovidersConfig?: ProvidersConfig,\n): ResolvedProviders {\n\tconst providers: LegacyProvider[] = [];\n\tlet enableOpenApi = false;\n\n\tif (mainProvider === 'aws') {\n\t\tconst awsConfig = providersConfig?.aws;\n\n\t\t// Resolve API Gateway providers\n\t\tif (awsConfig?.apiGateway) {\n\t\t\tif (isEnabled(awsConfig.apiGateway.v1)) {\n\t\t\t\tproviders.push('aws-apigatewayv1');\n\t\t\t}\n\t\t\tif (isEnabled(awsConfig.apiGateway.v2)) {\n\t\t\t\tproviders.push('aws-apigatewayv2');\n\t\t\t}\n\t\t} else {\n\t\t\t// Default: enable v2 if no specific config\n\t\t\tproviders.push('aws-apigatewayv2');\n\t\t}\n\n\t\t// Resolve Lambda providers\n\t\tif (awsConfig?.lambda) {\n\t\t\tif (\n\t\t\t\tisEnabled(awsConfig.lambda.functions) ||\n\t\t\t\tisEnabled(awsConfig.lambda.crons)\n\t\t\t) {\n\t\t\t\tproviders.push('aws-lambda');\n\t\t\t}\n\t\t} else {\n\t\t\t// Default: enable lambda if no specific config\n\t\t\tproviders.push('aws-lambda');\n\t\t}\n\t} else if (mainProvider === 'server') {\n\t\tproviders.push('server');\n\t\tconst serverConfig = providersConfig?.server;\n\n\t\tif (typeof serverConfig === 'object' && serverConfig?.enableOpenApi) {\n\t\t\tenableOpenApi = true;\n\t\t}\n\t}\n\n\treturn { providers, enableOpenApi };\n}\n\nfunction resolveAllConfiguredProviders(\n\tprovidersConfig: ProvidersConfig,\n): ResolvedProviders {\n\tconst providers: LegacyProvider[] = [];\n\tlet enableOpenApi = false;\n\n\t// AWS providers\n\tif (providersConfig.aws) {\n\t\tconst awsProviders = resolveMainProvider('aws', providersConfig);\n\t\tproviders.push(...awsProviders.providers);\n\t}\n\n\t// Server provider\n\tif (providersConfig.server && isEnabled(providersConfig.server)) {\n\t\tproviders.push('server');\n\t\tif (\n\t\t\ttypeof providersConfig.server === 'object' &&\n\t\t\tprovidersConfig.server.enableOpenApi\n\t\t) {\n\t\t\tenableOpenApi = true;\n\t\t}\n\t}\n\n\treturn { providers, enableOpenApi };\n}\n\nfunction isEnabled(\n\tconfig:\n\t\t| boolean\n\t\t| AWSApiGatewayConfig\n\t\t| AWSLambdaConfig\n\t\t| ServerConfig\n\t\t| undefined,\n): boolean {\n\tif (config === undefined) return false;\n\tif (typeof config === 'boolean') return config;\n\treturn config.enabled !== false; // Default to true if enabled is not explicitly false\n}\n\n/**\n * Gets configuration for a specific AWS service\n */\nexport function getAWSServiceConfig<\n\tT extends AWSApiGatewayConfig | AWSLambdaConfig,\n>(\n\tconfig: GkmConfig,\n\tservice: 'apiGateway' | 'lambda',\n\tsubService?: 'v1' | 'v2' | 'functions' | 'crons',\n): T | undefined {\n\tconst awsConfig = config.providers?.aws;\n\tif (!awsConfig) return undefined;\n\n\tif (service === 'apiGateway' && awsConfig.apiGateway) {\n\t\tconst apiConfig = subService\n\t\t\t? awsConfig.apiGateway[subService as 'v1' | 'v2']\n\t\t\t: undefined;\n\t\treturn typeof apiConfig === 'object' ? (apiConfig as T) : undefined;\n\t}\n\n\tif (service === 'lambda' && awsConfig.lambda) {\n\t\tconst lambdaConfig = subService\n\t\t\t? awsConfig.lambda[subService as 'functions' | 'crons']\n\t\t\t: undefined;\n\t\treturn typeof lambdaConfig === 'object' ? (lambdaConfig as T) : undefined;\n\t}\n\n\treturn undefined;\n}\n\n/**\n * Gets server configuration\n */\nexport function getServerConfig(config: GkmConfig): ServerConfig | undefined {\n\tconst serverConfig = config.providers?.server;\n\treturn typeof serverConfig === 'object' ? serverConfig : undefined;\n}\n","import { mkdir, writeFile } from 'node:fs/promises';\nimport { dirname, join, relative } from 'node:path';\nimport { Cron } from '@geekmidas/constructs/crons';\nimport type { BuildContext } from '../build/types';\nimport type { CronInfo } from '../types';\nimport {\n\tConstructGenerator,\n\ttype GeneratedConstruct,\n\ttype GeneratorOptions,\n} from './Generator';\n\nexport class CronGenerator extends ConstructGenerator<\n\tCron<any, any, any, any, any, any, any, any>,\n\tCronInfo[]\n> {\n\tasync build(\n\t\tcontext: BuildContext,\n\t\tconstructs: GeneratedConstruct<\n\t\t\tCron<any, any, any, any, any, any, any, any>\n\t\t>[],\n\t\toutputDir: string,\n\t\toptions?: GeneratorOptions,\n\t): Promise<CronInfo[]> {\n\t\tconst provider = options?.provider || 'aws-lambda';\n\t\tconst logger = console;\n\t\tconst cronInfos: CronInfo[] = [];\n\n\t\tif (constructs.length === 0 || provider !== 'aws-lambda') {\n\t\t\treturn cronInfos;\n\t\t}\n\n\t\t// Create crons subdirectory\n\t\tconst cronsDir = join(outputDir, 'crons');\n\t\tawait mkdir(cronsDir, { recursive: true });\n\n\t\t// Generate cron handlers\n\t\tfor (const { key, construct, path } of constructs) {\n\t\t\tconst handlerFile = await this.generateCronHandler(\n\t\t\t\tcronsDir,\n\t\t\t\tpath.relative,\n\t\t\t\tkey,\n\t\t\t\tcontext,\n\t\t\t);\n\n\t\t\tcronInfos.push({\n\t\t\t\tname: key,\n\t\t\t\thandler: relative(process.cwd(), handlerFile).replace(\n\t\t\t\t\t/\\.ts$/,\n\t\t\t\t\t'.handler',\n\t\t\t\t),\n\t\t\t\tschedule: construct.schedule || 'rate(1 hour)',\n\t\t\t\ttimeout: construct.timeout,\n\t\t\t\tmemorySize: construct.memorySize,\n\t\t\t\tenvironment: await construct.getEnvironment(),\n\t\t\t});\n\n\t\t\tlogger.log(`Generated cron handler: ${key}`);\n\t\t}\n\n\t\treturn cronInfos;\n\t}\n\n\tisConstruct(\n\t\tvalue: any,\n\t): value is Cron<any, any, any, any, any, any, any, any> {\n\t\treturn Cron.isCron(value);\n\t}\n\n\tprivate async generateCronHandler(\n\t\toutputDir: string,\n\t\tsourceFile: string,\n\t\texportName: string,\n\t\tcontext: BuildContext,\n\t): Promise<string> {\n\t\tconst handlerFileName = `${exportName}.ts`;\n\t\tconst handlerPath = join(outputDir, handlerFileName);\n\n\t\tconst relativePath = relative(dirname(handlerPath), sourceFile);\n\t\tconst importPath = relativePath.replace(/\\.ts$/, '.js');\n\n\t\tconst relativeEnvParserPath = relative(\n\t\t\tdirname(handlerPath),\n\t\t\tcontext.envParserPath,\n\t\t);\n\t\tconst relativeLoggerPath = relative(\n\t\t\tdirname(handlerPath),\n\t\t\tcontext.loggerPath,\n\t\t);\n\n\t\tconst content = `import { AWSScheduledFunction } from '@geekmidas/constructs/crons';\nimport { ${exportName} } from '${importPath}';\nimport ${context.envParserImportPattern} from '${relativeEnvParserPath}';\nimport ${context.loggerImportPattern} from '${relativeLoggerPath}';\n\nconst adapter = new AWSScheduledFunction(envParser, ${exportName});\n\nexport const handler = adapter.handler;\n`;\n\n\t\tawait writeFile(handlerPath, content);\n\t\treturn handlerPath;\n\t}\n}\n","import { mkdir, writeFile } from 'node:fs/promises';\nimport { dirname, join, relative } from 'node:path';\nimport { Function } from '@geekmidas/constructs/functions';\nimport type { BuildContext } from '../build/types';\nimport type { FunctionInfo } from '../types';\nimport {\n\tConstructGenerator,\n\ttype GeneratedConstruct,\n\ttype GeneratorOptions,\n} from './Generator';\n\nexport class FunctionGenerator extends ConstructGenerator<\n\tFunction<any, any, any, any, any, any, any, any, any, any, any, any>,\n\tFunctionInfo[]\n> {\n\tisConstruct(\n\t\tvalue: any,\n\t): value is Function<\n\t\tany,\n\t\tany,\n\t\tany,\n\t\tany,\n\t\tany,\n\t\tany,\n\t\tany,\n\t\tany,\n\t\tany,\n\t\tany,\n\t\tany,\n\t\tany\n\t> {\n\t\treturn Function.isFunction(value);\n\t}\n\n\tasync build(\n\t\tcontext: BuildContext,\n\t\tconstructs: GeneratedConstruct<\n\t\t\tFunction<any, any, any, any, any, any, any, any, any, any, any, any>\n\t\t>[],\n\t\toutputDir: string,\n\t\toptions?: GeneratorOptions,\n\t): Promise<FunctionInfo[]> {\n\t\tconst provider = options?.provider || 'aws-lambda';\n\t\tconst logger = console;\n\t\tconst functionInfos: FunctionInfo[] = [];\n\n\t\tif (constructs.length === 0 || provider !== 'aws-lambda') {\n\t\t\treturn functionInfos;\n\t\t}\n\n\t\t// Create functions subdirectory\n\t\tconst functionsDir = join(outputDir, 'functions');\n\t\tawait mkdir(functionsDir, { recursive: true });\n\n\t\t// Generate function handlers\n\t\tfor (const { key, construct, path } of constructs) {\n\t\t\tconst handlerFile = await this.generateFunctionHandler(\n\t\t\t\tfunctionsDir,\n\t\t\t\tpath.relative,\n\t\t\t\tkey,\n\t\t\t\tcontext,\n\t\t\t);\n\n\t\t\tfunctionInfos.push({\n\t\t\t\tname: key,\n\t\t\t\thandler: relative(process.cwd(), handlerFile).replace(\n\t\t\t\t\t/\\.ts$/,\n\t\t\t\t\t'.handler',\n\t\t\t\t),\n\t\t\t\ttimeout: construct.timeout,\n\t\t\t\tmemorySize: construct.memorySize,\n\t\t\t\tenvironment: await construct.getEnvironment(),\n\t\t\t});\n\n\t\t\tlogger.log(`Generated function handler: ${key}`);\n\t\t}\n\n\t\treturn functionInfos;\n\t}\n\n\tprivate async generateFunctionHandler(\n\t\toutputDir: string,\n\t\tsourceFile: string,\n\t\texportName: string,\n\t\tcontext: BuildContext,\n\t): Promise<string> {\n\t\tconst handlerFileName = `${exportName}.ts`;\n\t\tconst handlerPath = join(outputDir, handlerFileName);\n\n\t\tconst relativePath = relative(dirname(handlerPath), sourceFile);\n\t\tconst importPath = relativePath.replace(/\\.ts$/, '.js');\n\n\t\tconst relativeEnvParserPath = relative(\n\t\t\tdirname(handlerPath),\n\t\t\tcontext.envParserPath,\n\t\t);\n\t\tconst relativeLoggerPath = relative(\n\t\t\tdirname(handlerPath),\n\t\t\tcontext.loggerPath,\n\t\t);\n\n\t\tconst content = `import { AWSLambdaFunction } from '@geekmidas/constructs/functions';\nimport { ${exportName} } from '${importPath}';\nimport ${context.envParserImportPattern} from '${relativeEnvParserPath}';\nimport ${context.loggerImportPattern} from '${relativeLoggerPath}';\n\nconst adapter = new AWSLambdaFunction(envParser, ${exportName});\n\nexport const handler = adapter.handler;\n`;\n\n\t\tawait writeFile(handlerPath, content);\n\t\treturn handlerPath;\n\t}\n}\n","import { mkdir, writeFile } from 'node:fs/promises';\nimport { dirname, join, relative } from 'node:path';\nimport { Subscriber } from '@geekmidas/constructs/subscribers';\nimport type { BuildContext } from '../build/types';\nimport type { SubscriberInfo } from '../types';\nimport {\n\tConstructGenerator,\n\ttype GeneratedConstruct,\n\ttype GeneratorOptions,\n} from './Generator';\n\nexport class SubscriberGenerator extends ConstructGenerator<\n\tSubscriber<any, any, any, any, any, any>,\n\tSubscriberInfo[]\n> {\n\tisConstruct(value: any): value is Subscriber<any, any, any, any, any, any> {\n\t\treturn Subscriber.isSubscriber(value);\n\t}\n\n\tasync build(\n\t\tcontext: BuildContext,\n\t\tconstructs: GeneratedConstruct<Subscriber<any, any, any, any, any, any>>[],\n\t\toutputDir: string,\n\t\toptions?: GeneratorOptions,\n\t): Promise<SubscriberInfo[]> {\n\t\tconst provider = options?.provider || 'aws-lambda';\n\t\tconst logger = console;\n\t\tconst subscriberInfos: SubscriberInfo[] = [];\n\n\t\tif (provider === 'server') {\n\t\t\t// Generate subscribers.ts for server-based polling (even if empty)\n\t\t\tawait this.generateServerSubscribersFile(outputDir, constructs);\n\n\t\t\tlogger.log(\n\t\t\t\t`Generated server subscribers file with ${constructs.length} subscribers (polling mode)`,\n\t\t\t);\n\n\t\t\t// Return empty array as server subscribers don't have individual handlers\n\t\t\treturn subscriberInfos;\n\t\t}\n\n\t\tif (constructs.length === 0) {\n\t\t\treturn subscriberInfos;\n\t\t}\n\n\t\tif (provider !== 'aws-lambda') {\n\t\t\treturn subscriberInfos;\n\t\t}\n\n\t\t// Create subscribers subdirectory\n\t\tconst subscribersDir = join(outputDir, 'subscribers');\n\t\tawait mkdir(subscribersDir, { recursive: true });\n\n\t\t// Generate subscriber handlers\n\t\tfor (const { key, construct, path } of constructs) {\n\t\t\tconst handlerFile = await this.generateSubscriberHandler(\n\t\t\t\tsubscribersDir,\n\t\t\t\tpath.relative,\n\t\t\t\tkey,\n\t\t\t\tconstruct,\n\t\t\t\tcontext,\n\t\t\t);\n\n\t\t\tsubscriberInfos.push({\n\t\t\t\tname: key,\n\t\t\t\thandler: relative(process.cwd(), handlerFile).replace(\n\t\t\t\t\t/\\.ts$/,\n\t\t\t\t\t'.handler',\n\t\t\t\t),\n\t\t\t\tsubscribedEvents: construct.subscribedEvents || [],\n\t\t\t\ttimeout: construct.timeout,\n\t\t\t\tmemorySize: construct.memorySize,\n\t\t\t\tenvironment: await construct.getEnvironment(),\n\t\t\t});\n\n\t\t\tlogger.log(`Generated subscriber handler: ${key}`);\n\t\t}\n\n\t\treturn subscriberInfos;\n\t}\n\n\tprivate async generateSubscriberHandler(\n\t\toutputDir: string,\n\t\tsourceFile: string,\n\t\texportName: string,\n\t\t_subscriber: Subscriber<any, any, any, any, any, any>,\n\t\tcontext: BuildContext,\n\t): Promise<string> {\n\t\tconst handlerFileName = `${exportName}.ts`;\n\t\tconst handlerPath = join(outputDir, handlerFileName);\n\n\t\tconst relativePath = relative(dirname(handlerPath), sourceFile);\n\t\tconst importPath = relativePath.replace(/\\.ts$/, '.js');\n\n\t\tconst relativeEnvParserPath = relative(\n\t\t\tdirname(handlerPath),\n\t\t\tcontext.envParserPath,\n\t\t);\n\n\t\tconst content = `import { AWSLambdaSubscriber } from '@geekmidas/constructs/aws';\nimport { ${exportName} } from '${importPath}';\nimport ${context.envParserImportPattern} from '${relativeEnvParserPath}';\n\nconst adapter = new AWSLambdaSubscriber(envParser, ${exportName});\n\nexport const handler = adapter.handler;\n`;\n\n\t\tawait writeFile(handlerPath, content);\n\t\treturn handlerPath;\n\t}\n\n\tprivate async generateServerSubscribersFile(\n\t\toutputDir: string,\n\t\tsubscribers: GeneratedConstruct<Subscriber<any, any, any, any, any, any>>[],\n\t): Promise<string> {\n\t\t// Ensure output directory exists\n\t\tawait mkdir(outputDir, { recursive: true });\n\n\t\tconst subscribersFileName = 'subscribers.ts';\n\t\tconst subscribersPath = join(outputDir, subscribersFileName);\n\n\t\t// Group imports by file\n\t\tconst importsByFile = new Map<string, string[]>();\n\n\t\tfor (const { path, key } of subscribers) {\n\t\t\tconst relativePath = relative(dirname(subscribersPath), path.relative);\n\t\t\tconst importPath = relativePath.replace(/\\.ts$/, '.js');\n\n\t\t\tif (!importsByFile.has(importPath)) {\n\t\t\t\timportsByFile.set(importPath, []);\n\t\t\t}\n\t\t\timportsByFile.get(importPath)?.push(key);\n\t\t}\n\n\t\t// Generate import statements\n\t\tconst imports = Array.from(importsByFile.entries())\n\t\t\t.map(\n\t\t\t\t([importPath, exports]) =>\n\t\t\t\t\t`import { ${exports.join(', ')} } from '${importPath}';`,\n\t\t\t)\n\t\t\t.join('\\n');\n\n\t\tconst allExportNames = subscribers.map(({ key }) => key);\n\n\t\tconst content = `/**\n * Generated subscribers setup\n *\n * ⚠️ WARNING: This is for LOCAL DEVELOPMENT ONLY\n * This uses event polling which is not suitable for production.\n *\n * For production, use AWS Lambda with SQS/SNS event source mappings.\n * Lambda automatically:\n * - Scales based on queue depth\n * - Handles batch processing and retries\n * - Manages dead letter queues\n * - Provides better cost optimization\n *\n * This polling implementation is useful for:\n * - Local development and testing\n * - Understanding event flow without Lambda deployment\n *\n * Supported connection strings:\n * - sqs://region/account-id/queue-name (SQS queue)\n * - sns://region/account-id/topic-name (SNS topic)\n * - rabbitmq://host:port/queue-name (RabbitMQ)\n * - basic://in-memory (In-memory for testing)\n */\nimport type { EnvironmentParser } from '@geekmidas/envkit';\nimport type { Logger } from '@geekmidas/logger';\nimport { EventConnectionFactory, Subscriber } from '@geekmidas/events';\nimport type { EventConnection, EventSubscriber } from '@geekmidas/events';\nimport { ServiceDiscovery } from '@geekmidas/services';\n${imports}\n\nconst subscribers = [\n ${allExportNames.join(',\\n ')}\n];\n\nconst activeSubscribers: EventSubscriber<any>[] = [];\n\nexport async function setupSubscribers(\n envParser: EnvironmentParser<any>,\n logger: Logger,\n): Promise<void> {\n logger.info('Setting up subscribers in polling mode (local development)');\n\n const config = envParser.create((get) => ({\n connectionString: get('EVENT_SUBSCRIBER_CONNECTION_STRING').string().optional(),\n })).parse();\n\n if (!config.connectionString) {\n logger.warn('EVENT_SUBSCRIBER_CONNECTION_STRING not configured, skipping subscriber setup');\n return;\n }\n\n const serviceDiscovery = ServiceDiscovery.getInstance(envParser);\n\n // Create connection once, outside the loop (more efficient)\n // EventConnectionFactory automatically determines the right connection type\n let connection: EventConnection;\n try {\n connection = await EventConnectionFactory.fromConnectionString(config.connectionString);\n\n const connectionType = new URL(config.connectionString).protocol.replace(':', '');\n logger.info({ connectionType }, 'Created shared event connection');\n } catch (error) {\n logger.error({ error }, 'Failed to create event connection');\n return;\n }\n\n for (const subscriber of subscribers) {\n try {\n // Create subscriber from shared connection\n const eventSubscriber = await Subscriber.fromConnection(connection);\n\n // Register services\n const services = subscriber.services.length > 0\n ? await serviceDiscovery.register(subscriber.services)\n : {};\n\n // Subscribe to events\n const subscribedEvents = subscriber.subscribedEvents || [];\n\n if (subscribedEvents.length === 0) {\n logger.warn({ subscriber: subscriber.constructor.name }, 'Subscriber has no subscribed events, skipping');\n continue;\n }\n\n await eventSubscriber.subscribe(subscribedEvents, async (event) => {\n try {\n // Process single event (batch of 1)\n await subscriber.handler({\n events: [event],\n services: services as any,\n logger: subscriber.logger,\n });\n\n logger.debug({ eventType: event.type }, 'Successfully processed event');\n } catch (error) {\n logger.error({ error, event }, 'Failed to process event');\n // Event will become visible again for retry\n }\n });\n\n activeSubscribers.push(eventSubscriber);\n\n logger.info(\n {\n events: subscribedEvents,\n },\n 'Subscriber started polling'\n );\n } catch (error) {\n logger.error({ error, subscriber: subscriber.constructor.name }, 'Failed to setup subscriber');\n }\n }\n\n // Setup graceful shutdown\n const shutdown = () => {\n logger.info('Stopping all subscribers');\n for (const eventSubscriber of activeSubscribers) {\n connection.stop();\n }\n };\n\n process.on('SIGTERM', shutdown);\n process.on('SIGINT', shutdown);\n}\n`;\n\n\t\tawait writeFile(subscribersPath, content);\n\t\treturn subscribersPath;\n\t}\n}\n","import { type ChildProcess, execSync, spawn } from 'node:child_process';\nimport { existsSync } from 'node:fs';\nimport { mkdir } from 'node:fs/promises';\nimport { createServer } from 'node:net';\nimport { join, resolve } from 'node:path';\nimport chokidar from 'chokidar';\nimport { config as dotenvConfig } from 'dotenv';\nimport fg from 'fast-glob';\nimport { resolveProviders } from '../build/providerResolver';\nimport type {\n\tBuildContext,\n\tNormalizedHooksConfig,\n\tNormalizedProductionConfig,\n\tNormalizedStudioConfig,\n\tNormalizedTelescopeConfig,\n} from '../build/types';\nimport { loadConfig, parseModuleConfig } from '../config';\nimport {\n\tCronGenerator,\n\tEndpointGenerator,\n\tFunctionGenerator,\n\tSubscriberGenerator,\n} from '../generators';\nimport {\n\tgenerateOpenApi,\n\tOPENAPI_OUTPUT_PATH,\n\tresolveOpenApiConfig,\n} from '../openapi';\nimport type {\n\tGkmConfig,\n\tLegacyProvider,\n\tProductionConfig,\n\tRuntime,\n\tServerConfig,\n\tStudioConfig,\n\tTelescopeConfig,\n} from '../types';\n\nconst logger = console;\n\n/**\n * Load environment files\n * @internal Exported for testing\n */\nexport function loadEnvFiles(\n\tenvConfig: string | string[] | undefined,\n\tcwd: string = process.cwd(),\n): { loaded: string[]; missing: string[] } {\n\tconst loaded: string[] = [];\n\tconst missing: string[] = [];\n\n\t// Normalize to array\n\tconst envFiles = envConfig\n\t\t? Array.isArray(envConfig)\n\t\t\t? envConfig\n\t\t\t: [envConfig]\n\t\t: ['.env'];\n\n\t// Load each env file in order (later files override earlier)\n\tfor (const envFile of envFiles) {\n\t\tconst envPath = resolve(cwd, envFile);\n\t\tif (existsSync(envPath)) {\n\t\t\tdotenvConfig({ path: envPath, override: true, quiet: true });\n\t\t\tloaded.push(envFile);\n\t\t} else if (envConfig) {\n\t\t\t// Only report as missing if explicitly configured\n\t\t\tmissing.push(envFile);\n\t\t}\n\t}\n\n\treturn { loaded, missing };\n}\n\n/**\n * Check if a port is available\n * @internal Exported for testing\n */\nexport async function isPortAvailable(port: number): Promise<boolean> {\n\treturn new Promise((resolve) => {\n\t\tconst server = createServer();\n\n\t\tserver.once('error', (err: NodeJS.ErrnoException) => {\n\t\t\tif (err.code === 'EADDRINUSE') {\n\t\t\t\tresolve(false);\n\t\t\t} else {\n\t\t\t\tresolve(false);\n\t\t\t}\n\t\t});\n\n\t\tserver.once('listening', () => {\n\t\t\tserver.close();\n\t\t\tresolve(true);\n\t\t});\n\n\t\tserver.listen(port);\n\t});\n}\n\n/**\n * Find an available port starting from the preferred port\n * @internal Exported for testing\n */\nexport async function findAvailablePort(\n\tpreferredPort: number,\n\tmaxAttempts = 10,\n): Promise<number> {\n\tfor (let i = 0; i < maxAttempts; i++) {\n\t\tconst port = preferredPort + i;\n\t\tif (await isPortAvailable(port)) {\n\t\t\treturn port;\n\t\t}\n\t\tlogger.log(`⚠️ Port ${port} is in use, trying ${port + 1}...`);\n\t}\n\n\tthrow new Error(\n\t\t`Could not find an available port after trying ${maxAttempts} ports starting from ${preferredPort}`,\n\t);\n}\n\n/**\n * Normalize telescope configuration\n * @internal Exported for testing\n */\nexport function normalizeTelescopeConfig(\n\tconfig: GkmConfig['telescope'],\n): NormalizedTelescopeConfig | undefined {\n\tif (config === false) {\n\t\treturn undefined;\n\t}\n\n\t// Handle string path (e.g., './src/config/telescope')\n\tif (typeof config === 'string') {\n\t\tconst { path: telescopePath, importPattern: telescopeImportPattern } =\n\t\t\tparseModuleConfig(config, 'telescope');\n\n\t\treturn {\n\t\t\tenabled: true,\n\t\t\ttelescopePath,\n\t\t\ttelescopeImportPattern,\n\t\t\tpath: '/__telescope',\n\t\t\tignore: [],\n\t\t\trecordBody: true,\n\t\t\tmaxEntries: 1000,\n\t\t\twebsocket: true,\n\t\t};\n\t}\n\n\t// Default to enabled in development mode\n\tconst isEnabled =\n\t\tconfig === true || config === undefined || config.enabled !== false;\n\n\tif (!isEnabled) {\n\t\treturn undefined;\n\t}\n\n\tconst telescopeConfig: TelescopeConfig =\n\t\ttypeof config === 'object' ? config : {};\n\n\treturn {\n\t\tenabled: true,\n\t\tpath: telescopeConfig.path ?? '/__telescope',\n\t\tignore: telescopeConfig.ignore ?? [],\n\t\trecordBody: telescopeConfig.recordBody ?? true,\n\t\tmaxEntries: telescopeConfig.maxEntries ?? 1000,\n\t\twebsocket: telescopeConfig.websocket ?? true,\n\t};\n}\n\n/**\n * Normalize studio configuration\n * @internal Exported for testing\n */\nexport function normalizeStudioConfig(\n\tconfig: GkmConfig['studio'],\n): NormalizedStudioConfig | undefined {\n\tif (config === false) {\n\t\treturn undefined;\n\t}\n\n\t// Handle string path (e.g., './src/config/studio')\n\tif (typeof config === 'string') {\n\t\tconst { path: studioPath, importPattern: studioImportPattern } =\n\t\t\tparseModuleConfig(config, 'studio');\n\n\t\treturn {\n\t\t\tenabled: true,\n\t\t\tstudioPath,\n\t\t\tstudioImportPattern,\n\t\t\tpath: '/__studio',\n\t\t\tschema: 'public',\n\t\t};\n\t}\n\n\t// Default to enabled in development mode\n\tconst isEnabled =\n\t\tconfig === true || config === undefined || config.enabled !== false;\n\n\tif (!isEnabled) {\n\t\treturn undefined;\n\t}\n\n\tconst studioConfig: StudioConfig = typeof config === 'object' ? config : {};\n\n\treturn {\n\t\tenabled: true,\n\t\tpath: studioConfig.path ?? '/__studio',\n\t\tschema: studioConfig.schema ?? 'public',\n\t};\n}\n\n/**\n * Normalize hooks configuration\n * @internal Exported for testing\n */\nexport function normalizeHooksConfig(\n\tconfig: GkmConfig['hooks'],\n): NormalizedHooksConfig | undefined {\n\tif (!config?.server) {\n\t\treturn undefined;\n\t}\n\n\t// Resolve the path (handle .ts extension)\n\tconst serverPath = config.server.endsWith('.ts')\n\t\t? config.server\n\t\t: `${config.server}.ts`;\n\n\tconst resolvedPath = resolve(process.cwd(), serverPath);\n\n\treturn {\n\t\tserverHooksPath: resolvedPath,\n\t};\n}\n\n/**\n * Normalize production configuration\n * @internal Exported for testing\n */\nexport function normalizeProductionConfig(\n\tcliProduction: boolean,\n\tconfigProduction?: ProductionConfig,\n): NormalizedProductionConfig | undefined {\n\t// Production mode is only enabled if --production CLI flag is passed\n\tif (!cliProduction) {\n\t\treturn undefined;\n\t}\n\n\t// Merge CLI flag with config options\n\tconst config = configProduction ?? {};\n\n\treturn {\n\t\tenabled: true,\n\t\tbundle: config.bundle ?? true,\n\t\tminify: config.minify ?? true,\n\t\thealthCheck: config.healthCheck ?? '/health',\n\t\tgracefulShutdown: config.gracefulShutdown ?? true,\n\t\texternal: config.external ?? [],\n\t\tsubscribers: config.subscribers ?? 'exclude',\n\t\topenapi: config.openapi ?? false,\n\t\toptimizedHandlers: config.optimizedHandlers ?? true, // Default to optimized handlers in production\n\t};\n}\n\n/**\n * Get production config from GkmConfig\n * @internal\n */\nexport function getProductionConfigFromGkm(\n\tconfig: GkmConfig,\n): ProductionConfig | undefined {\n\tconst serverConfig = config.providers?.server;\n\tif (typeof serverConfig === 'object') {\n\t\treturn (serverConfig as ServerConfig).production;\n\t}\n\treturn undefined;\n}\n\nexport interface DevOptions {\n\tport?: number;\n\tportExplicit?: boolean;\n\tenableOpenApi?: boolean;\n}\n\nexport async function devCommand(options: DevOptions): Promise<void> {\n\t// Load default .env file BEFORE loading config\n\t// This ensures env vars are available when config and its dependencies are loaded\n\tconst defaultEnv = loadEnvFiles('.env');\n\tif (defaultEnv.loaded.length > 0) {\n\t\tlogger.log(`📦 Loaded env: ${defaultEnv.loaded.join(', ')}`);\n\t}\n\n\tconst config = await loadConfig();\n\n\t// Load any additional env files specified in config\n\tif (config.env) {\n\t\tconst { loaded, missing } = loadEnvFiles(config.env);\n\t\tif (loaded.length > 0) {\n\t\t\tlogger.log(`📦 Loaded env: ${loaded.join(', ')}`);\n\t\t}\n\t\tif (missing.length > 0) {\n\t\t\tlogger.warn(`⚠️ Missing env files: ${missing.join(', ')}`);\n\t\t}\n\t}\n\n\t// Force server provider for dev mode\n\tconst resolved = resolveProviders(config, { provider: 'server' });\n\n\tlogger.log('🚀 Starting development server...');\n\tlogger.log(`Loading routes from: ${config.routes}`);\n\tif (config.functions) {\n\t\tlogger.log(`Loading functions from: ${config.functions}`);\n\t}\n\tif (config.crons) {\n\t\tlogger.log(`Loading crons from: ${config.crons}`);\n\t}\n\tif (config.subscribers) {\n\t\tlogger.log(`Loading subscribers from: ${config.subscribers}`);\n\t}\n\tlogger.log(`Using envParser: ${config.envParser}`);\n\n\t// Parse envParser and logger configuration\n\tconst { path: envParserPath, importPattern: envParserImportPattern } =\n\t\tparseModuleConfig(config.envParser, 'envParser');\n\tconst { path: loggerPath, importPattern: loggerImportPattern } =\n\t\tparseModuleConfig(config.logger, 'logger');\n\n\t// Normalize telescope configuration\n\tconst telescope = normalizeTelescopeConfig(config.telescope);\n\tif (telescope) {\n\t\tlogger.log(`🔭 Telescope enabled at ${telescope.path}`);\n\t}\n\n\t// Normalize studio configuration\n\tconst studio = normalizeStudioConfig(config.studio);\n\tif (studio) {\n\t\tlogger.log(`🗄️ Studio enabled at ${studio.path}`);\n\t}\n\n\t// Normalize hooks configuration\n\tconst hooks = normalizeHooksConfig(config.hooks);\n\tif (hooks) {\n\t\tlogger.log(`🪝 Server hooks enabled from ${config.hooks?.server}`);\n\t}\n\n\t// Resolve OpenAPI configuration\n\tconst openApiConfig = resolveOpenApiConfig(config);\n\t// Enable OpenAPI docs endpoint if either root config or provider config enables it\n\tconst enableOpenApi = openApiConfig.enabled || resolved.enableOpenApi;\n\tif (enableOpenApi) {\n\t\tlogger.log(`📄 OpenAPI output: ${OPENAPI_OUTPUT_PATH}`);\n\t}\n\n\tconst buildContext: BuildContext = {\n\t\tenvParserPath,\n\t\tenvParserImportPattern,\n\t\tloggerPath,\n\t\tloggerImportPattern,\n\t\ttelescope,\n\t\tstudio,\n\t\thooks,\n\t};\n\n\t// Build initial version\n\tawait buildServer(\n\t\tconfig,\n\t\tbuildContext,\n\t\tresolved.providers[0] as LegacyProvider,\n\t\tenableOpenApi,\n\t);\n\n\t// Generate OpenAPI spec on startup\n\tif (enableOpenApi) {\n\t\tawait generateOpenApi(config);\n\t}\n\n\t// Determine runtime (default to node)\n\tconst runtime: Runtime = config.runtime ?? 'node';\n\n\t// Start the dev server\n\tconst devServer = new DevServer(\n\t\tresolved.providers[0] as LegacyProvider,\n\t\toptions.port || 3000,\n\t\toptions.portExplicit ?? false,\n\t\tenableOpenApi,\n\t\ttelescope,\n\t\tstudio,\n\t\truntime,\n\t);\n\n\tawait devServer.start();\n\n\t// Watch for file changes\n\tconst envParserFile = config.envParser.split('#')[0] ?? config.envParser;\n\tconst loggerFile = config.logger.split('#')[0] ?? config.logger;\n\n\t// Get hooks file path for watching\n\tconst hooksFileParts = config.hooks?.server?.split('#');\n\tconst hooksFile = hooksFileParts?.[0];\n\n\tconst watchPatterns = [\n\t\tconfig.routes,\n\t\t...(config.functions ? [config.functions] : []),\n\t\t...(config.crons ? [config.crons] : []),\n\t\t...(config.subscribers ? [config.subscribers] : []),\n\t\t// Add .ts extension if not present for config files\n\t\tenvParserFile.endsWith('.ts') ? envParserFile : `${envParserFile}.ts`,\n\t\tloggerFile.endsWith('.ts') ? loggerFile : `${loggerFile}.ts`,\n\t\t// Add hooks file to watch list\n\t\t...(hooksFile\n\t\t\t? [hooksFile.endsWith('.ts') ? hooksFile : `${hooksFile}.ts`]\n\t\t\t: []),\n\t]\n\t\t.flat()\n\t\t.filter((p): p is string => typeof p === 'string');\n\n\t// Normalize patterns - remove leading ./ when using cwd option\n\tconst normalizedPatterns = watchPatterns.map((p) =>\n\t\tp.startsWith('./') ? p.slice(2) : p,\n\t);\n\n\tlogger.log(`👀 Watching for changes in: ${normalizedPatterns.join(', ')}`);\n\n\t// Resolve glob patterns to actual files (chokidar 4.x doesn't support globs)\n\tconst resolvedFiles = await fg(normalizedPatterns, {\n\t\tcwd: process.cwd(),\n\t\tabsolute: false,\n\t\tonlyFiles: true,\n\t});\n\n\t// Also watch the directories for new files\n\tconst dirsToWatch = [\n\t\t...new Set(\n\t\t\tresolvedFiles.map((f) => {\n\t\t\t\tconst parts = f.split('/');\n\t\t\t\treturn parts.slice(0, -1).join('/');\n\t\t\t}),\n\t\t),\n\t];\n\n\tlogger.log(\n\t\t`📁 Found ${resolvedFiles.length} files in ${dirsToWatch.length} directories`,\n\t);\n\n\tconst watcher = chokidar.watch([...resolvedFiles, ...dirsToWatch], {\n\t\tignored: /(^|[/\\\\])\\../, // ignore dotfiles\n\t\tpersistent: true,\n\t\tignoreInitial: true,\n\t\tcwd: process.cwd(),\n\t});\n\n\twatcher.on('ready', () => {\n\t\tlogger.log('🔍 File watcher ready');\n\t});\n\n\twatcher.on('error', (error) => {\n\t\tlogger.error('❌ Watcher error:', error);\n\t});\n\n\tlet rebuildTimeout: NodeJS.Timeout | null = null;\n\n\twatcher.on('change', async (path) => {\n\t\tlogger.log(`📝 File changed: ${path}`);\n\n\t\t// Debounce rebuilds\n\t\tif (rebuildTimeout) {\n\t\t\tclearTimeout(rebuildTimeout);\n\t\t}\n\n\t\trebuildTimeout = setTimeout(async () => {\n\t\t\ttry {\n\t\t\t\tlogger.log('🔄 Rebuilding...');\n\t\t\t\tawait buildServer(\n\t\t\t\t\tconfig,\n\t\t\t\t\tbuildContext,\n\t\t\t\t\tresolved.providers[0] as LegacyProvider,\n\t\t\t\t\tenableOpenApi,\n\t\t\t\t);\n\n\t\t\t\t// Regenerate OpenAPI if enabled\n\t\t\t\tif (enableOpenApi) {\n\t\t\t\t\tawait generateOpenApi(config, { silent: true });\n\t\t\t\t}\n\n\t\t\t\tlogger.log('✅ Rebuild complete, restarting server...');\n\t\t\t\tawait devServer.restart();\n\t\t\t} catch (error) {\n\t\t\t\tlogger.error('❌ Rebuild failed:', (error as Error).message);\n\t\t\t}\n\t\t}, 300);\n\t});\n\n\t// Handle graceful shutdown\n\tlet isShuttingDown = false;\n\tconst shutdown = () => {\n\t\tif (isShuttingDown) return;\n\t\tisShuttingDown = true;\n\n\t\tlogger.log('\\n🛑 Shutting down...');\n\n\t\t// Use sync-style shutdown to ensure it completes before exit\n\t\tPromise.all([watcher.close(), devServer.stop()])\n\t\t\t.catch((err) => {\n\t\t\t\tlogger.error('Error during shutdown:', err);\n\t\t\t})\n\t\t\t.finally(() => {\n\t\t\t\tprocess.exit(0);\n\t\t\t});\n\t};\n\n\tprocess.on('SIGINT', shutdown);\n\tprocess.on('SIGTERM', shutdown);\n}\n\nasync function buildServer(\n\tconfig: any,\n\tcontext: BuildContext,\n\tprovider: LegacyProvider,\n\tenableOpenApi: boolean,\n): Promise<void> {\n\t// Initialize generators\n\tconst endpointGenerator = new EndpointGenerator();\n\tconst functionGenerator = new FunctionGenerator();\n\tconst cronGenerator = new CronGenerator();\n\tconst subscriberGenerator = new SubscriberGenerator();\n\n\t// Load all constructs\n\tconst [allEndpoints, allFunctions, allCrons, allSubscribers] =\n\t\tawait Promise.all([\n\t\t\tendpointGenerator.load(config.routes),\n\t\t\tconfig.functions ? functionGenerator.load(config.functions) : [],\n\t\t\tconfig.crons ? cronGenerator.load(config.crons) : [],\n\t\t\tconfig.subscribers ? subscriberGenerator.load(config.subscribers) : [],\n\t\t]);\n\n\t// Ensure .gkm directory exists\n\tconst outputDir = join(process.cwd(), '.gkm', provider);\n\tawait mkdir(outputDir, { recursive: true });\n\n\t// Build for server provider\n\tawait Promise.all([\n\t\tendpointGenerator.build(context, allEndpoints, outputDir, {\n\t\t\tprovider,\n\t\t\tenableOpenApi,\n\t\t}),\n\t\tfunctionGenerator.build(context, allFunctions, outputDir, { provider }),\n\t\tcronGenerator.build(context, allCrons, outputDir, { provider }),\n\t\tsubscriberGenerator.build(context, allSubscribers, outputDir, { provider }),\n\t]);\n}\n\nclass DevServer {\n\tprivate serverProcess: ChildProcess | null = null;\n\tprivate isRunning = false;\n\tprivate actualPort: number;\n\n\tconstructor(\n\t\tprivate provider: LegacyProvider,\n\t\tprivate requestedPort: number,\n\t\tprivate portExplicit: boolean,\n\t\tprivate enableOpenApi: boolean,\n\t\tprivate telescope?: NormalizedTelescopeConfig,\n\t\tprivate studio?: NormalizedStudioConfig,\n\t\tprivate runtime: Runtime = 'node',\n\t) {\n\t\tthis.actualPort = requestedPort;\n\t}\n\n\tasync start(): Promise<void> {\n\t\tif (this.isRunning) {\n\t\t\tawait this.stop();\n\t\t}\n\n\t\t// Check port availability\n\t\tif (this.portExplicit) {\n\t\t\t// Port was explicitly specified - throw if unavailable\n\t\t\tconst available = await isPortAvailable(this.requestedPort);\n\t\t\tif (!available) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Port ${this.requestedPort} is already in use. ` +\n\t\t\t\t\t\t`Either stop the process using that port or omit -p/--port to auto-select an available port.`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tthis.actualPort = this.requestedPort;\n\t\t} else {\n\t\t\t// Find an available port starting from the default\n\t\t\tthis.actualPort = await findAvailablePort(this.requestedPort);\n\n\t\t\tif (this.actualPort !== this.requestedPort) {\n\t\t\t\tlogger.log(\n\t\t\t\t\t`ℹ️ Port ${this.requestedPort} was in use, using port ${this.actualPort} instead`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\tconst serverEntryPath = join(\n\t\t\tprocess.cwd(),\n\t\t\t'.gkm',\n\t\t\tthis.provider,\n\t\t\t'server.ts',\n\t\t);\n\n\t\t// Create server entry file\n\t\tawait this.createServerEntry();\n\n\t\tlogger.log(`\\n✨ Starting server on port ${this.actualPort}...`);\n\n\t\t// Start the server using tsx (TypeScript execution)\n\t\t// Use detached: true so we can kill the entire process tree\n\t\tthis.serverProcess = spawn(\n\t\t\t'npx',\n\t\t\t['tsx', serverEntryPath, '--port', this.actualPort.toString()],\n\t\t\t{\n\t\t\t\tstdio: 'inherit',\n\t\t\t\tenv: { ...process.env, NODE_ENV: 'development' },\n\t\t\t\tdetached: true,\n\t\t\t},\n\t\t);\n\n\t\tthis.isRunning = true;\n\n\t\tthis.serverProcess.on('error', (error) => {\n\t\t\tlogger.error('❌ Server error:', error);\n\t\t});\n\n\t\tthis.serverProcess.on('exit', (code, signal) => {\n\t\t\tif (code !== null && code !== 0 && signal !== 'SIGTERM') {\n\t\t\t\tlogger.error(`❌ Server exited with code ${code}`);\n\t\t\t}\n\t\t\tthis.isRunning = false;\n\t\t});\n\n\t\t// Give the server a moment to start\n\t\tawait new Promise((resolve) => setTimeout(resolve, 1000));\n\n\t\tif (this.isRunning) {\n\t\t\tlogger.log(`\\n🎉 Server running at http://localhost:${this.actualPort}`);\n\t\t\tif (this.enableOpenApi) {\n\t\t\t\tlogger.log(\n\t\t\t\t\t`📚 API Docs available at http://localhost:${this.actualPort}/__docs`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (this.telescope) {\n\t\t\t\tlogger.log(\n\t\t\t\t\t`🔭 Telescope available at http://localhost:${this.actualPort}${this.telescope.path}`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (this.studio) {\n\t\t\t\tlogger.log(\n\t\t\t\t\t`🗄️ Studio available at http://localhost:${this.actualPort}${this.studio.path}`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\tasync stop(): Promise<void> {\n\t\tconst port = this.actualPort;\n\n\t\tif (this.serverProcess && this.isRunning) {\n\t\t\tconst pid = this.serverProcess.pid;\n\n\t\t\t// Use SIGKILL directly since the server ignores SIGTERM\n\t\t\tif (pid) {\n\t\t\t\ttry {\n\t\t\t\t\tprocess.kill(-pid, 'SIGKILL');\n\t\t\t\t} catch {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tprocess.kill(pid, 'SIGKILL');\n\t\t\t\t\t} catch {\n\t\t\t\t\t\t// Process might already be dead\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthis.serverProcess = null;\n\t\t\tthis.isRunning = false;\n\t\t}\n\n\t\t// Also kill any processes still holding the port\n\t\tthis.killProcessesOnPort(port);\n\t}\n\n\tprivate killProcessesOnPort(port: number): void {\n\t\ttry {\n\t\t\t// Use lsof to find PIDs on the port and kill them with -9\n\t\t\texecSync(`lsof -ti tcp:${port} | xargs kill -9 2>/dev/null || true`, {\n\t\t\t\tstdio: 'ignore',\n\t\t\t});\n\t\t} catch {\n\t\t\t// Ignore errors - port may already be free\n\t\t}\n\t}\n\n\tasync restart(): Promise<void> {\n\t\tconst portToReuse = this.actualPort;\n\t\tawait this.stop();\n\n\t\t// Wait for port to be released (up to 3 seconds)\n\t\tlet attempts = 0;\n\t\twhile (attempts < 30) {\n\t\t\tif (await isPortAvailable(portToReuse)) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tawait new Promise((resolve) => setTimeout(resolve, 100));\n\t\t\tattempts++;\n\t\t}\n\n\t\t// Force reuse the same port\n\t\tthis.requestedPort = portToReuse;\n\t\tawait this.start();\n\t}\n\n\tprivate async createServerEntry(): Promise<void> {\n\t\tconst { writeFile } = await import('node:fs/promises');\n\t\tconst { relative, dirname } = await import('node:path');\n\n\t\tconst serverPath = join(process.cwd(), '.gkm', this.provider, 'server.ts');\n\n\t\tconst relativeAppPath = relative(\n\t\t\tdirname(serverPath),\n\t\t\tjoin(dirname(serverPath), 'app.js'),\n\t\t);\n\n\t\tconst serveCode =\n\t\t\tthis.runtime === 'bun'\n\t\t\t\t? `Bun.serve({\n port,\n fetch: app.fetch,\n });`\n\t\t\t\t: `const { serve } = await import('@hono/node-server');\n const server = serve({\n fetch: app.fetch,\n port,\n });\n // Inject WebSocket support if available\n const injectWs = (app as any).__injectWebSocket;\n if (injectWs) {\n injectWs(server);\n console.log('🔌 Telescope real-time updates enabled');\n }`;\n\n\t\tconst content = `#!/usr/bin/env node\n/**\n * Development server entry point\n * This file is auto-generated by 'gkm dev'\n */\nimport { createApp } from './${relativeAppPath.startsWith('.') ? relativeAppPath : `./${relativeAppPath}`}';\n\nconst port = process.argv.includes('--port')\n ? Number.parseInt(process.argv[process.argv.indexOf('--port') + 1])\n : 3000;\n\n// createApp is async to support optional WebSocket setup\nconst { app, start } = await createApp(undefined, ${this.enableOpenApi});\n\n// Start the server\nstart({\n port,\n serve: async (app, port) => {\n ${serveCode}\n },\n}).catch((error) => {\n console.error('Failed to start server:', error);\n process.exit(1);\n});\n`;\n\n\t\tawait writeFile(serverPath, content);\n\t}\n}\n","import { mkdir, writeFile } from 'node:fs/promises';\nimport { join, relative } from 'node:path';\nimport type {\n\tCronInfo,\n\tFunctionInfo,\n\tRouteInfo,\n\tSubscriberInfo,\n} from '../types';\n\nconst logger = console;\n\nexport type ManifestProvider = 'aws' | 'server';\n\nexport interface ServerAppInfo {\n\thandler: string;\n\tendpoints: string;\n}\n\nexport async function generateAwsManifest(\n\toutputDir: string,\n\troutes: RouteInfo[],\n\tfunctions: FunctionInfo[],\n\tcrons: CronInfo[],\n\tsubscribers: SubscriberInfo[],\n): Promise<void> {\n\tconst manifestDir = join(outputDir, 'manifest');\n\tawait mkdir(manifestDir, { recursive: true });\n\n\t// Filter out 'ALL' method routes (server-specific)\n\tconst awsRoutes = routes.filter((r) => r.method !== 'ALL');\n\n\tconst content = `export const manifest = {\n routes: ${JSON.stringify(awsRoutes, null, 2)},\n functions: ${JSON.stringify(functions, null, 2)},\n crons: ${JSON.stringify(crons, null, 2)},\n subscribers: ${JSON.stringify(subscribers, null, 2)},\n} as const;\n\n// Derived types\nexport type Route = (typeof manifest.routes)[number];\nexport type Function = (typeof manifest.functions)[number];\nexport type Cron = (typeof manifest.crons)[number];\nexport type Subscriber = (typeof manifest.subscribers)[number];\n\n// Useful union types\nexport type Authorizer = Route['authorizer'];\nexport type HttpMethod = Route['method'];\nexport type RoutePath = Route['path'];\n`;\n\n\tconst manifestPath = join(manifestDir, 'aws.ts');\n\tawait writeFile(manifestPath, content);\n\n\tlogger.log(\n\t\t`Generated AWS manifest with ${awsRoutes.length} routes, ${functions.length} functions, ${crons.length} crons, ${subscribers.length} subscribers`,\n\t);\n\tlogger.log(`Manifest: ${relative(process.cwd(), manifestPath)}`);\n}\n\nexport async function generateServerManifest(\n\toutputDir: string,\n\tappInfo: ServerAppInfo,\n\troutes: RouteInfo[],\n\tsubscribers: SubscriberInfo[],\n): Promise<void> {\n\tconst manifestDir = join(outputDir, 'manifest');\n\tawait mkdir(manifestDir, { recursive: true });\n\n\t// For server, extract route metadata (path, method, authorizer)\n\tconst serverRoutes = routes\n\t\t.filter((r) => r.method !== 'ALL')\n\t\t.map((r) => ({\n\t\t\tpath: r.path,\n\t\t\tmethod: r.method,\n\t\t\tauthorizer: r.authorizer,\n\t\t}));\n\n\t// Server subscribers only need name and events\n\tconst serverSubscribers = subscribers.map((s) => ({\n\t\tname: s.name,\n\t\tsubscribedEvents: s.subscribedEvents,\n\t}));\n\n\tconst content = `export const manifest = {\n app: ${JSON.stringify(appInfo, null, 2)},\n routes: ${JSON.stringify(serverRoutes, null, 2)},\n subscribers: ${JSON.stringify(serverSubscribers, null, 2)},\n} as const;\n\n// Derived types\nexport type Route = (typeof manifest.routes)[number];\nexport type Subscriber = (typeof manifest.subscribers)[number];\n\n// Useful union types\nexport type Authorizer = Route['authorizer'];\nexport type HttpMethod = Route['method'];\nexport type RoutePath = Route['path'];\n`;\n\n\tconst manifestPath = join(manifestDir, 'server.ts');\n\tawait writeFile(manifestPath, content);\n\n\tlogger.log(\n\t\t`Generated server manifest with ${serverRoutes.length} routes, ${serverSubscribers.length} subscribers`,\n\t);\n\tlogger.log(`Manifest: ${relative(process.cwd(), manifestPath)}`);\n}\n","import { mkdir } from 'node:fs/promises';\nimport { join, relative } from 'node:path';\nimport type { Cron } from '@geekmidas/constructs/crons';\nimport type { Endpoint } from '@geekmidas/constructs/endpoints';\nimport type { Function } from '@geekmidas/constructs/functions';\nimport type { Subscriber } from '@geekmidas/constructs/subscribers';\nimport { loadConfig, parseModuleConfig } from '../config';\nimport {\n\tgetProductionConfigFromGkm,\n\tnormalizeHooksConfig,\n\tnormalizeProductionConfig,\n\tnormalizeStudioConfig,\n\tnormalizeTelescopeConfig,\n} from '../dev';\nimport {\n\tCronGenerator,\n\tEndpointGenerator,\n\tFunctionGenerator,\n\ttype GeneratedConstruct,\n\tSubscriberGenerator,\n} from '../generators';\nimport type {\n\tBuildOptions,\n\tBuildResult,\n\tLegacyProvider,\n\tRouteInfo,\n} from '../types';\nimport {\n\tgenerateAwsManifest,\n\tgenerateServerManifest,\n\ttype ServerAppInfo,\n} from './manifests';\nimport { resolveProviders } from './providerResolver';\nimport type { BuildContext } from './types';\n\nconst logger = console;\n\nexport async function buildCommand(\n\toptions: BuildOptions,\n): Promise<BuildResult> {\n\tconst config = await loadConfig();\n\n\t// Resolve providers from new config format\n\tconst resolved = resolveProviders(config, options);\n\n\t// Normalize production configuration\n\tconst productionConfigFromGkm = getProductionConfigFromGkm(config);\n\tconst production = normalizeProductionConfig(\n\t\toptions.production ?? false,\n\t\tproductionConfigFromGkm,\n\t);\n\n\tif (production) {\n\t\tlogger.log(`🏭 Building for PRODUCTION`);\n\t}\n\n\tlogger.log(`Building with providers: ${resolved.providers.join(', ')}`);\n\tlogger.log(`Loading routes from: ${config.routes}`);\n\tif (config.functions) {\n\t\tlogger.log(`Loading functions from: ${config.functions}`);\n\t}\n\tif (config.crons) {\n\t\tlogger.log(`Loading crons from: ${config.crons}`);\n\t}\n\tif (config.subscribers) {\n\t\tlogger.log(`Loading subscribers from: ${config.subscribers}`);\n\t}\n\tlogger.log(`Using envParser: ${config.envParser}`);\n\n\t// Parse envParser and logger configuration\n\tconst { path: envParserPath, importPattern: envParserImportPattern } =\n\t\tparseModuleConfig(config.envParser, 'envParser');\n\tconst { path: loggerPath, importPattern: loggerImportPattern } =\n\t\tparseModuleConfig(config.logger, 'logger');\n\n\t// Normalize telescope configuration (disabled in production)\n\tconst telescope = production\n\t\t? undefined\n\t\t: normalizeTelescopeConfig(config.telescope);\n\tif (telescope) {\n\t\tlogger.log(`🔭 Telescope enabled at ${telescope.path}`);\n\t}\n\n\t// Normalize studio configuration (disabled in production)\n\tconst studio = production ? undefined : normalizeStudioConfig(config.studio);\n\tif (studio) {\n\t\tlogger.log(`🗄️ Studio enabled at ${studio.path}`);\n\t}\n\n\t// Normalize hooks configuration\n\tconst hooks = normalizeHooksConfig(config.hooks);\n\tif (hooks) {\n\t\tlogger.log(`🪝 Server hooks enabled`);\n\t}\n\n\tconst buildContext: BuildContext = {\n\t\tenvParserPath,\n\t\tenvParserImportPattern,\n\t\tloggerPath,\n\t\tloggerImportPattern,\n\t\ttelescope,\n\t\tstudio,\n\t\thooks,\n\t\tproduction,\n\t};\n\n\t// Initialize generators\n\tconst endpointGenerator = new EndpointGenerator();\n\tconst functionGenerator = new FunctionGenerator();\n\tconst cronGenerator = new CronGenerator();\n\tconst subscriberGenerator = new SubscriberGenerator();\n\n\t// Load all constructs in parallel\n\tconst [allEndpoints, allFunctions, allCrons, allSubscribers] =\n\t\tawait Promise.all([\n\t\t\tendpointGenerator.load(config.routes),\n\t\t\tconfig.functions ? functionGenerator.load(config.functions) : [],\n\t\t\tconfig.crons ? cronGenerator.load(config.crons) : [],\n\t\t\tconfig.subscribers ? subscriberGenerator.load(config.subscribers) : [],\n\t\t]);\n\n\tlogger.log(`Found ${allEndpoints.length} endpoints`);\n\tlogger.log(`Found ${allFunctions.length} functions`);\n\tlogger.log(`Found ${allCrons.length} crons`);\n\tlogger.log(`Found ${allSubscribers.length} subscribers`);\n\n\tif (\n\t\tallEndpoints.length === 0 &&\n\t\tallFunctions.length === 0 &&\n\t\tallCrons.length === 0 &&\n\t\tallSubscribers.length === 0\n\t) {\n\t\tlogger.log(\n\t\t\t'No endpoints, functions, crons, or subscribers found to process',\n\t\t);\n\t\treturn {};\n\t}\n\n\t// Ensure .gkm directory exists\n\tconst rootOutputDir = join(process.cwd(), '.gkm');\n\tawait mkdir(rootOutputDir, { recursive: true });\n\n\t// Build for each provider and generate per-provider manifests\n\tlet result: BuildResult = {};\n\tfor (const provider of resolved.providers) {\n\t\tconst providerResult = await buildForProvider(\n\t\t\tprovider,\n\t\t\tbuildContext,\n\t\t\trootOutputDir,\n\t\t\tendpointGenerator,\n\t\t\tfunctionGenerator,\n\t\t\tcronGenerator,\n\t\t\tsubscriberGenerator,\n\t\t\tallEndpoints,\n\t\t\tallFunctions,\n\t\t\tallCrons,\n\t\t\tallSubscribers,\n\t\t\tresolved.enableOpenApi,\n\t\t\toptions.skipBundle ?? false,\n\t\t\toptions.stage,\n\t\t);\n\t\t// Keep the master key from the server provider\n\t\tif (providerResult.masterKey) {\n\t\t\tresult = providerResult;\n\t\t}\n\t}\n\treturn result;\n}\n\nasync function buildForProvider(\n\tprovider: LegacyProvider,\n\tcontext: BuildContext,\n\trootOutputDir: string,\n\tendpointGenerator: EndpointGenerator,\n\tfunctionGenerator: FunctionGenerator,\n\tcronGenerator: CronGenerator,\n\tsubscriberGenerator: SubscriberGenerator,\n\tendpoints: GeneratedConstruct<Endpoint<any, any, any, any, any, any>>[],\n\tfunctions: GeneratedConstruct<Function<any, any, any, any>>[],\n\tcrons: GeneratedConstruct<Cron<any, any, any, any>>[],\n\tsubscribers: GeneratedConstruct<Subscriber<any, any, any, any, any, any>>[],\n\tenableOpenApi: boolean,\n\tskipBundle: boolean,\n\tstage?: string,\n): Promise<BuildResult> {\n\tconst outputDir = join(process.cwd(), '.gkm', provider);\n\n\t// Ensure output directory exists\n\tawait mkdir(outputDir, { recursive: true });\n\n\tlogger.log(`\\nGenerating handlers for provider: ${provider}`);\n\n\t// Build all constructs in parallel\n\tconst [routes, functionInfos, cronInfos, subscriberInfos] = await Promise.all(\n\t\t[\n\t\t\tendpointGenerator.build(context, endpoints, outputDir, {\n\t\t\t\tprovider,\n\t\t\t\tenableOpenApi,\n\t\t\t}),\n\t\t\tfunctionGenerator.build(context, functions, outputDir, { provider }),\n\t\t\tcronGenerator.build(context, crons, outputDir, { provider }),\n\t\t\tsubscriberGenerator.build(context, subscribers, outputDir, { provider }),\n\t\t],\n\t);\n\n\tlogger.log(\n\t\t`Generated ${routes.length} routes, ${functionInfos.length} functions, ${cronInfos.length} crons, ${subscriberInfos.length} subscribers for ${provider}`,\n\t);\n\n\t// Generate provider-specific manifest\n\tif (provider === 'server') {\n\t\t// For server, collect actual route metadata from endpoint constructs\n\t\tconst routeMetadata: RouteInfo[] = await Promise.all(\n\t\t\tendpoints.map(async ({ construct }) => ({\n\t\t\t\tpath: construct._path,\n\t\t\t\tmethod: construct.method,\n\t\t\t\thandler: '', // Not needed for server manifest\n\t\t\t\tauthorizer: construct.authorizer?.name ?? 'none',\n\t\t\t})),\n\t\t);\n\n\t\tconst appInfo: ServerAppInfo = {\n\t\t\thandler: relative(process.cwd(), join(outputDir, 'app.ts')),\n\t\t\tendpoints: relative(process.cwd(), join(outputDir, 'endpoints.ts')),\n\t\t};\n\n\t\tawait generateServerManifest(\n\t\t\trootOutputDir,\n\t\t\tappInfo,\n\t\t\trouteMetadata,\n\t\t\tsubscriberInfos,\n\t\t);\n\n\t\t// Bundle for production if enabled\n\t\tlet masterKey: string | undefined;\n\t\tif (context.production?.bundle && !skipBundle) {\n\t\t\tlogger.log(`\\n📦 Bundling production server...`);\n\t\t\tconst { bundleServer } = await import('./bundler');\n\n\t\t\t// Collect all constructs for environment variable validation\n\t\t\tconst allConstructs = [\n\t\t\t\t...endpoints.map((e) => e.construct),\n\t\t\t\t...functions.map((f) => f.construct),\n\t\t\t\t...crons.map((c) => c.construct),\n\t\t\t\t...subscribers.map((s) => s.construct),\n\t\t\t];\n\n\t\t\tconst bundleResult = await bundleServer({\n\t\t\t\tentryPoint: join(outputDir, 'server.ts'),\n\t\t\t\toutputDir: join(outputDir, 'dist'),\n\t\t\t\tminify: context.production.minify,\n\t\t\t\tsourcemap: false,\n\t\t\t\texternal: context.production.external,\n\t\t\t\tstage,\n\t\t\t\tconstructs: allConstructs,\n\t\t\t});\n\t\t\tmasterKey = bundleResult.masterKey;\n\t\t\tlogger.log(`✅ Bundle complete: .gkm/server/dist/server.mjs`);\n\n\t\t\t// Display master key if secrets were injected\n\t\t\tif (masterKey) {\n\t\t\t\tlogger.log(`\\n🔐 Secrets encrypted for deployment`);\n\t\t\t\tlogger.log(` Deploy with: GKM_MASTER_KEY=${masterKey}`);\n\t\t\t}\n\t\t}\n\n\t\treturn { masterKey };\n\t} else {\n\t\t// For AWS providers, generate AWS manifest\n\t\tawait generateAwsManifest(\n\t\t\trootOutputDir,\n\t\t\troutes,\n\t\t\tfunctionInfos,\n\t\t\tcronInfos,\n\t\t\tsubscriberInfos,\n\t\t);\n\t}\n\n\treturn {};\n}\n","import { execSync } from 'node:child_process';\nimport type { GkmConfig } from '../types';\nimport type { DeployResult, DockerDeployConfig } from './types';\n\nconst logger = console;\n\nexport interface DockerDeployOptions {\n\t/** Deployment stage */\n\tstage: string;\n\t/** Image tag */\n\ttag: string;\n\t/** Skip pushing to registry */\n\tskipPush?: boolean;\n\t/** Master key from build */\n\tmasterKey?: string;\n\t/** Docker config from gkm.config */\n\tconfig: DockerDeployConfig;\n}\n\n/**\n * Get the full image reference\n */\nexport function getImageRef(\n\tregistry: string | undefined,\n\timageName: string,\n\ttag: string,\n): string {\n\tif (registry) {\n\t\treturn `${registry}/${imageName}:${tag}`;\n\t}\n\treturn `${imageName}:${tag}`;\n}\n\n/**\n * Build Docker image\n */\nasync function buildImage(imageRef: string): Promise<void> {\n\tlogger.log(`\\n🔨 Building Docker image: ${imageRef}`);\n\n\ttry {\n\t\texecSync(\n\t\t\t`DOCKER_BUILDKIT=1 docker build -f .gkm/docker/Dockerfile -t ${imageRef} .`,\n\t\t\t{\n\t\t\t\tcwd: process.cwd(),\n\t\t\t\tstdio: 'inherit',\n\t\t\t\tenv: { ...process.env, DOCKER_BUILDKIT: '1' },\n\t\t\t},\n\t\t);\n\t\tlogger.log(`✅ Image built: ${imageRef}`);\n\t} catch (error) {\n\t\tthrow new Error(\n\t\t\t`Failed to build Docker image: ${error instanceof Error ? error.message : 'Unknown error'}`,\n\t\t);\n\t}\n}\n\n/**\n * Push Docker image to registry\n */\nasync function pushImage(imageRef: string): Promise<void> {\n\tlogger.log(`\\n☁️ Pushing image: ${imageRef}`);\n\n\ttry {\n\t\texecSync(`docker push ${imageRef}`, {\n\t\t\tcwd: process.cwd(),\n\t\t\tstdio: 'inherit',\n\t\t});\n\t\tlogger.log(`✅ Image pushed: ${imageRef}`);\n\t} catch (error) {\n\t\tthrow new Error(\n\t\t\t`Failed to push Docker image: ${error instanceof Error ? error.message : 'Unknown error'}`,\n\t\t);\n\t}\n}\n\n/**\n * Deploy using Docker (build and optionally push image)\n */\nexport async function deployDocker(\n\toptions: DockerDeployOptions,\n): Promise<DeployResult> {\n\tconst { stage, tag, skipPush, masterKey, config } = options;\n\n\tconst imageName = config.imageName ?? 'app';\n\tconst imageRef = getImageRef(config.registry, imageName, tag);\n\n\t// Build image\n\tawait buildImage(imageRef);\n\n\t// Push to registry if not skipped\n\tif (!skipPush) {\n\t\tif (!config.registry) {\n\t\t\tlogger.warn(\n\t\t\t\t'\\n⚠️ No registry configured. Use --skip-push or configure docker.registry in gkm.config.ts',\n\t\t\t);\n\t\t} else {\n\t\t\tawait pushImage(imageRef);\n\t\t}\n\t}\n\n\t// Output deployment info\n\tlogger.log('\\n✅ Docker deployment ready!');\n\tlogger.log(`\\n📋 Deployment details:`);\n\tlogger.log(` Image: ${imageRef}`);\n\tlogger.log(` Stage: ${stage}`);\n\n\tif (masterKey) {\n\t\tlogger.log(`\\n🔐 Deploy with this environment variable:`);\n\t\tlogger.log(` GKM_MASTER_KEY=${masterKey}`);\n\t\tlogger.log('\\n Example docker run:');\n\t\tlogger.log(` docker run -e GKM_MASTER_KEY=${masterKey} ${imageRef}`);\n\t}\n\n\treturn {\n\t\timageRef,\n\t\tmasterKey,\n\t};\n}\n\n/**\n * Resolve Docker deploy config from gkm config\n */\nexport function resolveDockerConfig(config: GkmConfig): DockerDeployConfig {\n\treturn {\n\t\tregistry: config.docker?.registry,\n\t\timageName: config.docker?.imageName,\n\t};\n}\n","import { getDokployToken } from '../auth';\nimport type { DeployResult, DokployDeployConfig } from './types';\n\nconst logger = console;\n\nexport interface DokployDeployOptions {\n\t/** Deployment stage */\n\tstage: string;\n\t/** Image tag */\n\ttag: string;\n\t/** Image reference */\n\timageRef: string;\n\t/** Master key from build */\n\tmasterKey?: string;\n\t/** Dokploy config from gkm.config */\n\tconfig: DokployDeployConfig;\n}\n\ninterface DokployErrorResponse {\n\tmessage: string;\n\tcode?: string;\n\tissues?: Array<{ message: string }>;\n}\n\n/**\n * Get the Dokploy API token from stored credentials or environment\n */\nasync function getApiToken(): Promise<string> {\n\tconst token = await getDokployToken();\n\tif (!token) {\n\t\tthrow new Error(\n\t\t\t'Dokploy credentials not found.\\n' +\n\t\t\t\t'Run \"gkm login --service dokploy\" to authenticate, or set DOKPLOY_API_TOKEN.',\n\t\t);\n\t}\n\treturn token;\n}\n\n/**\n * Make a request to the Dokploy API\n */\nasync function dokployRequest<T>(\n\tendpoint: string,\n\tbaseUrl: string,\n\ttoken: string,\n\tbody: Record<string, unknown>,\n): Promise<T> {\n\tconst url = `${baseUrl}/api/${endpoint}`;\n\n\tconst response = await fetch(url, {\n\t\tmethod: 'POST',\n\t\theaders: {\n\t\t\t'Content-Type': 'application/json',\n\t\t\tAuthorization: `Bearer ${token}`,\n\t\t},\n\t\tbody: JSON.stringify(body),\n\t});\n\n\tif (!response.ok) {\n\t\tlet errorMessage = `Dokploy API error: ${response.status} ${response.statusText}`;\n\n\t\ttry {\n\t\t\tconst errorBody = (await response.json()) as DokployErrorResponse;\n\t\t\tif (errorBody.message) {\n\t\t\t\terrorMessage = `Dokploy API error: ${errorBody.message}`;\n\t\t\t}\n\t\t\tif (errorBody.issues?.length) {\n\t\t\t\terrorMessage += `\\n Issues: ${errorBody.issues.map((i) => i.message).join(', ')}`;\n\t\t\t}\n\t\t} catch {\n\t\t\t// Ignore JSON parse errors\n\t\t}\n\n\t\tthrow new Error(errorMessage);\n\t}\n\n\treturn response.json() as Promise<T>;\n}\n\n/**\n * Update application environment variables\n */\nasync function updateEnvironment(\n\tbaseUrl: string,\n\ttoken: string,\n\tapplicationId: string,\n\tenvVars: Record<string, string>,\n): Promise<void> {\n\tlogger.log(' Updating environment variables...');\n\n\t// Convert env vars to the format Dokploy expects (KEY=VALUE per line)\n\tconst envString = Object.entries(envVars)\n\t\t.map(([key, value]) => `${key}=${value}`)\n\t\t.join('\\n');\n\n\tawait dokployRequest('application.update', baseUrl, token, {\n\t\tapplicationId,\n\t\tenv: envString,\n\t});\n\n\tlogger.log(' ✓ Environment variables updated');\n}\n\n/**\n * Trigger application deployment\n */\nasync function triggerDeploy(\n\tbaseUrl: string,\n\ttoken: string,\n\tapplicationId: string,\n): Promise<void> {\n\tlogger.log(' Triggering deployment...');\n\n\tawait dokployRequest('application.deploy', baseUrl, token, {\n\t\tapplicationId,\n\t});\n\n\tlogger.log(' ✓ Deployment triggered');\n}\n\n/**\n * Deploy to Dokploy\n */\nexport async function deployDokploy(\n\toptions: DokployDeployOptions,\n): Promise<DeployResult> {\n\tconst { stage, imageRef, masterKey, config } = options;\n\n\tlogger.log(`\\n🎯 Deploying to Dokploy...`);\n\tlogger.log(` Endpoint: ${config.endpoint}`);\n\tlogger.log(` Application: ${config.applicationId}`);\n\n\tconst token = await getApiToken();\n\n\t// Prepare environment variables\n\tconst envVars: Record<string, string> = {};\n\n\tif (masterKey) {\n\t\tenvVars.GKM_MASTER_KEY = masterKey;\n\t}\n\n\t// Update environment if we have variables to set\n\tif (Object.keys(envVars).length > 0) {\n\t\tawait updateEnvironment(\n\t\t\tconfig.endpoint,\n\t\t\ttoken,\n\t\t\tconfig.applicationId,\n\t\t\tenvVars,\n\t\t);\n\t}\n\n\t// Trigger deployment\n\tawait triggerDeploy(config.endpoint, token, config.applicationId);\n\n\tlogger.log('\\n✅ Dokploy deployment initiated!');\n\tlogger.log(`\\n📋 Deployment details:`);\n\tlogger.log(` Image: ${imageRef}`);\n\tlogger.log(` Stage: ${stage}`);\n\tlogger.log(` Application ID: ${config.applicationId}`);\n\n\tif (masterKey) {\n\t\tlogger.log(`\\n🔐 GKM_MASTER_KEY has been set in Dokploy environment`);\n\t}\n\n\t// Construct the probable deployment URL\n\tconst deploymentUrl = `${config.endpoint}/project/${config.projectId}`;\n\tlogger.log(`\\n🔗 View deployment: ${deploymentUrl}`);\n\n\treturn {\n\t\timageRef,\n\t\tmasterKey,\n\t\turl: deploymentUrl,\n\t};\n}\n\n/**\n * Validate Dokploy configuration\n */\nexport function validateDokployConfig(\n\tconfig: Partial<DokployDeployConfig> | undefined,\n): config is DokployDeployConfig {\n\tif (!config) {\n\t\treturn false;\n\t}\n\n\tconst required = ['endpoint', 'projectId', 'applicationId'] as const;\n\tconst missing = required.filter((key) => !config[key]);\n\n\tif (missing.length > 0) {\n\t\tthrow new Error(\n\t\t\t`Missing Dokploy configuration: ${missing.join(', ')}\\n` +\n\t\t\t\t'Configure in gkm.config.ts:\\n' +\n\t\t\t\t' providers: {\\n' +\n\t\t\t\t' dokploy: {\\n' +\n\t\t\t\t\" endpoint: 'https://dokploy.example.com',\\n\" +\n\t\t\t\t\" projectId: 'proj_xxx',\\n\" +\n\t\t\t\t\" applicationId: 'app_xxx',\\n\" +\n\t\t\t\t' },\\n' +\n\t\t\t\t' }',\n\t\t);\n\t}\n\n\treturn true;\n}\n","import { buildCommand } from '../build/index';\nimport { loadConfig } from '../config';\nimport { deployDocker, resolveDockerConfig } from './docker';\nimport { deployDokploy, validateDokployConfig } from './dokploy';\nimport type { DeployOptions, DeployProvider, DeployResult } from './types';\n\nconst logger = console;\n\n/**\n * Generate image tag from stage and timestamp\n */\nfunction generateTag(stage: string): string {\n\tconst timestamp = new Date().toISOString().replace(/[:.]/g, '-').slice(0, 19);\n\treturn `${stage}-${timestamp}`;\n}\n\n/**\n * Main deploy command\n */\nexport async function deployCommand(\n\toptions: DeployOptions,\n): Promise<DeployResult> {\n\tconst { provider, stage, tag, skipPush, skipBuild } = options;\n\n\tlogger.log(`\\n🚀 Deploying to ${provider}...`);\n\tlogger.log(` Stage: ${stage}`);\n\n\t// Load config\n\tconst config = await loadConfig();\n\n\t// Generate tag if not provided\n\tconst imageTag = tag ?? generateTag(stage);\n\tlogger.log(` Tag: ${imageTag}`);\n\n\t// Build for production with secrets injection (unless skipped)\n\tlet masterKey: string | undefined;\n\tif (!skipBuild) {\n\t\tlogger.log(`\\n📦 Building for production...`);\n\t\tconst buildResult = await buildCommand({\n\t\t\tprovider: 'server',\n\t\t\tproduction: true,\n\t\t\tstage,\n\t\t});\n\t\tmasterKey = buildResult.masterKey;\n\t} else {\n\t\tlogger.log(`\\n⏭️ Skipping build (--skip-build)`);\n\t}\n\n\t// Resolve docker config for image reference\n\tconst dockerConfig = resolveDockerConfig(config);\n\tconst imageName = dockerConfig.imageName ?? 'app';\n\tconst registry = dockerConfig.registry;\n\tconst imageRef = registry\n\t\t? `${registry}/${imageName}:${imageTag}`\n\t\t: `${imageName}:${imageTag}`;\n\n\t// Deploy based on provider\n\tlet result: DeployResult;\n\n\tswitch (provider) {\n\t\tcase 'docker': {\n\t\t\tresult = await deployDocker({\n\t\t\t\tstage,\n\t\t\t\ttag: imageTag,\n\t\t\t\tskipPush,\n\t\t\t\tmasterKey,\n\t\t\t\tconfig: dockerConfig,\n\t\t\t});\n\t\t\tbreak;\n\t\t}\n\n\t\tcase 'dokploy': {\n\t\t\t// Validate Dokploy config\n\t\t\tconst dokployConfigRaw = config.providers?.dokploy;\n\t\t\tif (typeof dokployConfigRaw === 'boolean' || !dokployConfigRaw) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t'Dokploy provider requires configuration.\\n' +\n\t\t\t\t\t\t'Configure in gkm.config.ts:\\n' +\n\t\t\t\t\t\t' providers: {\\n' +\n\t\t\t\t\t\t' dokploy: {\\n' +\n\t\t\t\t\t\t\" endpoint: 'https://dokploy.example.com',\\n\" +\n\t\t\t\t\t\t\" projectId: 'proj_xxx',\\n\" +\n\t\t\t\t\t\t\" applicationId: 'app_xxx',\\n\" +\n\t\t\t\t\t\t' },\\n' +\n\t\t\t\t\t\t' }',\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// Validate required fields (throws if missing)\n\t\t\tvalidateDokployConfig(dokployConfigRaw);\n\t\t\tconst dokployConfig = dokployConfigRaw;\n\n\t\t\t// First build and push the Docker image\n\t\t\tawait deployDocker({\n\t\t\t\tstage,\n\t\t\t\ttag: imageTag,\n\t\t\t\tskipPush: false, // Dokploy needs the image in registry\n\t\t\t\tmasterKey,\n\t\t\t\tconfig: {\n\t\t\t\t\tregistry: dokployConfig.registry ?? dockerConfig.registry,\n\t\t\t\t\timageName: dockerConfig.imageName,\n\t\t\t\t},\n\t\t\t});\n\n\t\t\t// Then trigger Dokploy deployment\n\t\t\tresult = await deployDokploy({\n\t\t\t\tstage,\n\t\t\t\ttag: imageTag,\n\t\t\t\timageRef,\n\t\t\t\tmasterKey,\n\t\t\t\tconfig: dokployConfig,\n\t\t\t});\n\t\t\tbreak;\n\t\t}\n\n\t\tcase 'aws-lambda': {\n\t\t\tlogger.log('\\n⚠️ AWS Lambda deployment is not yet implemented.');\n\t\t\tlogger.log(' Use SST or AWS CDK for Lambda deployments.');\n\t\t\tresult = { imageRef, masterKey };\n\t\t\tbreak;\n\t\t}\n\n\t\tdefault: {\n\t\t\tthrow new Error(\n\t\t\t\t`Unknown deploy provider: ${provider}\\n` +\n\t\t\t\t\t'Supported providers: docker, dokploy, aws-lambda',\n\t\t\t);\n\t\t}\n\t}\n\n\tlogger.log('\\n✅ Deployment complete!');\n\n\treturn result;\n}\n\nexport type { DeployOptions, DeployProvider, DeployResult };\n","import { existsSync } from 'node:fs';\nimport { readFile, writeFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { getDokployCredentials, getDokployToken } from '../auth';\nimport type { DokployDeployConfig } from './types';\n\nconst logger = console;\n\nexport interface DeployInitOptions {\n\t/** Dokploy endpoint URL (optional if logged in) */\n\tendpoint?: string;\n\t/** Project name (creates new or uses existing) */\n\tprojectName: string;\n\t/** Application name */\n\tappName: string;\n\t/** Use existing project ID instead of creating/finding */\n\tprojectId?: string;\n\t/** Registry ID in Dokploy (optional) */\n\tregistryId?: string;\n}\n\ninterface DokployProject {\n\tprojectId: string;\n\tname: string;\n\tdescription: string | null;\n\tcreatedAt: string;\n\tadminId: string;\n\tenvironments?: Array<{\n\t\tenvironmentId: string;\n\t\tname: string;\n\t\tdescription: string | null;\n\t}>;\n}\n\ninterface DokployApplication {\n\tapplicationId: string;\n\tname: string;\n\tappName: string;\n\tprojectId: string;\n\tenvironmentId?: string;\n}\n\ninterface DokployRegistry {\n\tregistryId: string;\n\tregistryName: string;\n\tregistryUrl: string;\n\tusername: string;\n\timagePrefix: string | null;\n}\n\n/**\n * Get the Dokploy API token from stored credentials or environment\n */\nasync function getApiToken(): Promise<string> {\n\tconst token = await getDokployToken();\n\tif (!token) {\n\t\tthrow new Error(\n\t\t\t'Dokploy credentials not found.\\n' +\n\t\t\t\t'Run \"gkm login --service dokploy\" to authenticate, or set DOKPLOY_API_TOKEN.',\n\t\t);\n\t}\n\treturn token;\n}\n\n/**\n * Make a request to the Dokploy API\n */\nasync function dokployRequest<T>(\n\tmethod: 'GET' | 'POST',\n\tendpoint: string,\n\tbaseUrl: string,\n\ttoken: string,\n\tbody?: Record<string, unknown>,\n): Promise<T> {\n\tconst url = `${baseUrl}/api/${endpoint}`;\n\n\tconst response = await fetch(url, {\n\t\tmethod,\n\t\theaders: {\n\t\t\t'Content-Type': 'application/json',\n\t\t\tAuthorization: `Bearer ${token}`,\n\t\t},\n\t\tbody: body ? JSON.stringify(body) : undefined,\n\t});\n\n\tif (!response.ok) {\n\t\tlet errorMessage = `Dokploy API error: ${response.status} ${response.statusText}`;\n\n\t\ttry {\n\t\t\tconst errorBody = (await response.json()) as { message?: string };\n\t\t\tif (errorBody.message) {\n\t\t\t\terrorMessage = `Dokploy API error: ${errorBody.message}`;\n\t\t\t}\n\t\t} catch {\n\t\t\t// Ignore JSON parse errors\n\t\t}\n\n\t\tthrow new Error(errorMessage);\n\t}\n\n\t// Handle empty responses\n\tconst text = await response.text();\n\tif (!text) {\n\t\treturn {} as T;\n\t}\n\n\treturn JSON.parse(text) as T;\n}\n\n/**\n * Get all projects from Dokploy\n */\nasync function getProjects(\n\tbaseUrl: string,\n\ttoken: string,\n): Promise<DokployProject[]> {\n\treturn dokployRequest<DokployProject[]>('GET', 'project.all', baseUrl, token);\n}\n\n/**\n * Create a new project in Dokploy\n */\nasync function createProject(\n\tbaseUrl: string,\n\ttoken: string,\n\tname: string,\n\tdescription?: string,\n): Promise<DokployProject> {\n\treturn dokployRequest<DokployProject>(\n\t\t'POST',\n\t\t'project.create',\n\t\tbaseUrl,\n\t\ttoken,\n\t\t{\n\t\t\tname,\n\t\t\tdescription: description || `Created by gkm CLI`,\n\t\t},\n\t);\n}\n\n/**\n * Get project by ID to get environment info\n */\nasync function getProject(\n\tbaseUrl: string,\n\ttoken: string,\n\tprojectId: string,\n): Promise<DokployProject> {\n\treturn dokployRequest<DokployProject>('POST', 'project.one', baseUrl, token, {\n\t\tprojectId,\n\t});\n}\n\n/**\n * Create a new application in Dokploy\n */\nasync function createApplication(\n\tbaseUrl: string,\n\ttoken: string,\n\tname: string,\n\tprojectId: string,\n): Promise<DokployApplication> {\n\t// First get the project to find its environment ID\n\tconst project = await getProject(baseUrl, token, projectId);\n\n\t// Use the first environment or create one\n\tlet environmentId: string;\n\n\tconst firstEnv = project.environments?.[0];\n\tif (firstEnv) {\n\t\tenvironmentId = firstEnv.environmentId;\n\t} else {\n\t\t// Create a default environment\n\t\tconst env = await dokployRequest<{ environmentId: string }>(\n\t\t\t'POST',\n\t\t\t'environment.create',\n\t\t\tbaseUrl,\n\t\t\ttoken,\n\t\t\t{\n\t\t\t\tprojectId,\n\t\t\t\tname: 'production',\n\t\t\t\tdescription: 'Production environment',\n\t\t\t},\n\t\t);\n\t\tenvironmentId = env.environmentId;\n\t}\n\n\treturn dokployRequest<DokployApplication>(\n\t\t'POST',\n\t\t'application.create',\n\t\tbaseUrl,\n\t\ttoken,\n\t\t{\n\t\t\tname,\n\t\t\tprojectId,\n\t\t\tenvironmentId,\n\t\t},\n\t);\n}\n\n/**\n * Configure application for Docker registry deployment\n */\nasync function configureApplicationRegistry(\n\tbaseUrl: string,\n\ttoken: string,\n\tapplicationId: string,\n\tregistryId: string,\n): Promise<void> {\n\tawait dokployRequest('POST', 'application.update', baseUrl, token, {\n\t\tapplicationId,\n\t\tregistryId,\n\t});\n}\n\n/**\n * Get available registries\n */\nasync function getRegistries(\n\tbaseUrl: string,\n\ttoken: string,\n): Promise<DokployRegistry[]> {\n\treturn dokployRequest<DokployRegistry[]>(\n\t\t'GET',\n\t\t'registry.all',\n\t\tbaseUrl,\n\t\ttoken,\n\t);\n}\n\n/**\n * Update gkm.config.ts with Dokploy configuration\n */\nexport async function updateConfig(\n\tconfig: DokployDeployConfig,\n\tcwd: string = process.cwd(),\n): Promise<void> {\n\tconst configPath = join(cwd, 'gkm.config.ts');\n\n\tif (!existsSync(configPath)) {\n\t\tlogger.warn(\n\t\t\t'\\n gkm.config.ts not found. Add this configuration manually:\\n',\n\t\t);\n\t\tlogger.log(` providers: {`);\n\t\tlogger.log(` dokploy: {`);\n\t\tlogger.log(` endpoint: '${config.endpoint}',`);\n\t\tlogger.log(` projectId: '${config.projectId}',`);\n\t\tlogger.log(` applicationId: '${config.applicationId}',`);\n\t\tlogger.log(` },`);\n\t\tlogger.log(` },`);\n\t\treturn;\n\t}\n\n\tconst content = await readFile(configPath, 'utf-8');\n\n\t// Check if providers.dokploy already exists\n\tif (content.includes('dokploy:') && content.includes('applicationId:')) {\n\t\tlogger.log('\\n Dokploy config already exists in gkm.config.ts');\n\t\tlogger.log(' Updating with new values...');\n\t}\n\n\t// Try to add or update the dokploy config\n\tlet newContent: string;\n\n\tif (content.includes('providers:')) {\n\t\t// Add dokploy to existing providers\n\t\tif (content.includes('dokploy:')) {\n\t\t\t// Update existing dokploy config\n\t\t\tnewContent = content.replace(\n\t\t\t\t/dokploy:\\s*\\{[^}]*\\}/,\n\t\t\t\t`dokploy: {\n\t\t\tendpoint: '${config.endpoint}',\n\t\t\tprojectId: '${config.projectId}',\n\t\t\tapplicationId: '${config.applicationId}',\n\t\t}`,\n\t\t\t);\n\t\t} else {\n\t\t\t// Add dokploy to providers\n\t\t\tnewContent = content.replace(\n\t\t\t\t/providers:\\s*\\{/,\n\t\t\t\t`providers: {\n\t\tdokploy: {\n\t\t\tendpoint: '${config.endpoint}',\n\t\t\tprojectId: '${config.projectId}',\n\t\t\tapplicationId: '${config.applicationId}',\n\t\t},`,\n\t\t\t);\n\t\t}\n\t} else {\n\t\t// Add providers section before the closing of defineConfig\n\t\tnewContent = content.replace(\n\t\t\t/}\\s*\\)\\s*;?\\s*$/,\n\t\t\t`\n\tproviders: {\n\t\tdokploy: {\n\t\t\tendpoint: '${config.endpoint}',\n\t\t\tprojectId: '${config.projectId}',\n\t\t\tapplicationId: '${config.applicationId}',\n\t\t},\n\t},\n});`,\n\t\t);\n\t}\n\n\tawait writeFile(configPath, newContent);\n\tlogger.log('\\n ✓ Updated gkm.config.ts with Dokploy configuration');\n}\n\n/**\n * Initialize Dokploy deployment configuration\n */\nexport async function deployInitCommand(\n\toptions: DeployInitOptions,\n): Promise<DokployDeployConfig> {\n\tconst {\n\t\tprojectName,\n\t\tappName,\n\t\tprojectId: existingProjectId,\n\t\tregistryId,\n\t} = options;\n\n\t// Get endpoint from options or stored credentials\n\tlet endpoint = options.endpoint;\n\tif (!endpoint) {\n\t\tconst stored = await getDokployCredentials();\n\t\tif (stored) {\n\t\t\tendpoint = stored.endpoint;\n\t\t} else {\n\t\t\tthrow new Error(\n\t\t\t\t'Dokploy endpoint not specified.\\n' +\n\t\t\t\t\t'Either run \"gkm login --service dokploy\" first, or provide --endpoint.',\n\t\t\t);\n\t\t}\n\t}\n\n\tlogger.log(`\\n🚀 Initializing Dokploy deployment...`);\n\tlogger.log(` Endpoint: ${endpoint}`);\n\n\tconst token = await getApiToken();\n\n\t// Step 1: Find or create project\n\tlet projectId: string;\n\n\tif (existingProjectId) {\n\t\tprojectId = existingProjectId;\n\t\tlogger.log(`\\n📁 Using existing project: ${projectId}`);\n\t} else {\n\t\tlogger.log(`\\n📁 Looking for project: ${projectName}`);\n\n\t\tconst projects = await getProjects(endpoint, token);\n\t\tconst existingProject = projects.find(\n\t\t\t(p) => p.name.toLowerCase() === projectName.toLowerCase(),\n\t\t);\n\n\t\tif (existingProject) {\n\t\t\tprojectId = existingProject.projectId;\n\t\t\tlogger.log(` Found existing project: ${projectId}`);\n\t\t} else {\n\t\t\tlogger.log(` Creating new project...`);\n\t\t\tconst project = await createProject(endpoint, token, projectName);\n\t\t\tprojectId = project.projectId;\n\t\t\tlogger.log(` ✓ Created project: ${projectId}`);\n\t\t}\n\t}\n\n\t// Step 2: Create application\n\tlogger.log(`\\n📦 Creating application: ${appName}`);\n\tconst application = await createApplication(\n\t\tendpoint,\n\t\ttoken,\n\t\tappName,\n\t\tprojectId,\n\t);\n\tlogger.log(` ✓ Created application: ${application.applicationId}`);\n\n\t// Step 3: Configure registry if provided\n\tif (registryId) {\n\t\tlogger.log(`\\n🔧 Configuring registry: ${registryId}`);\n\t\tawait configureApplicationRegistry(\n\t\t\tendpoint,\n\t\t\ttoken,\n\t\t\tapplication.applicationId,\n\t\t\tregistryId,\n\t\t);\n\t\tlogger.log(` ✓ Registry configured`);\n\t} else {\n\t\t// List available registries\n\t\ttry {\n\t\t\tconst registries = await getRegistries(endpoint, token);\n\t\t\tif (registries.length > 0) {\n\t\t\t\tlogger.log(`\\n📋 Available registries:`);\n\t\t\t\tfor (const reg of registries) {\n\t\t\t\t\tlogger.log(\n\t\t\t\t\t\t` - ${reg.registryName}: ${reg.registryUrl} (${reg.registryId})`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tlogger.log(`\\n To use a registry, run with --registry-id <id>`);\n\t\t\t}\n\t\t} catch {\n\t\t\t// Ignore registry listing errors\n\t\t}\n\t}\n\n\t// Step 4: Build config\n\tconst config: DokployDeployConfig = {\n\t\tendpoint,\n\t\tprojectId,\n\t\tapplicationId: application.applicationId,\n\t};\n\n\t// Step 5: Update gkm.config.ts\n\tawait updateConfig(config);\n\n\tlogger.log(`\\n✅ Dokploy deployment initialized!`);\n\tlogger.log(`\\n📋 Configuration:`);\n\tlogger.log(` Project ID: ${projectId}`);\n\tlogger.log(` Application ID: ${application.applicationId}`);\n\tlogger.log(`\\n🔗 View in Dokploy: ${endpoint}/project/${projectId}`);\n\tlogger.log(`\\n📝 Next steps:`);\n\tlogger.log(` 1. Initialize secrets: gkm secrets:init --stage production`);\n\tlogger.log(` 2. Deploy: gkm deploy --provider dokploy --stage production`);\n\n\treturn config;\n}\n\n/**\n * List available Dokploy resources\n */\nexport async function deployListCommand(options: {\n\tendpoint?: string;\n\tresource: 'projects' | 'registries';\n}): Promise<void> {\n\t// Get endpoint from options or stored credentials\n\tlet endpoint = options.endpoint;\n\tif (!endpoint) {\n\t\tconst stored = await getDokployCredentials();\n\t\tif (stored) {\n\t\t\tendpoint = stored.endpoint;\n\t\t} else {\n\t\t\tthrow new Error(\n\t\t\t\t'Dokploy endpoint not specified.\\n' +\n\t\t\t\t\t'Either run \"gkm login --service dokploy\" first, or provide --endpoint.',\n\t\t\t);\n\t\t}\n\t}\n\n\tconst { resource } = options;\n\tconst token = await getApiToken();\n\n\tif (resource === 'projects') {\n\t\tlogger.log(`\\n📁 Projects in ${endpoint}:`);\n\t\tconst projects = await getProjects(endpoint, token);\n\n\t\tif (projects.length === 0) {\n\t\t\tlogger.log(' No projects found');\n\t\t\treturn;\n\t\t}\n\n\t\tfor (const project of projects) {\n\t\t\tlogger.log(`\\n ${project.name} (${project.projectId})`);\n\t\t\tif (project.description) {\n\t\t\t\tlogger.log(` ${project.description}`);\n\t\t\t}\n\t\t}\n\t} else if (resource === 'registries') {\n\t\tlogger.log(`\\n🐳 Registries in ${endpoint}:`);\n\t\tconst registries = await getRegistries(endpoint, token);\n\n\t\tif (registries.length === 0) {\n\t\t\tlogger.log(' No registries configured');\n\t\t\tlogger.log(' Add a registry in Dokploy: Settings > Docker Registry');\n\t\t\treturn;\n\t\t}\n\n\t\tfor (const registry of registries) {\n\t\t\tlogger.log(`\\n ${registry.registryName} (${registry.registryId})`);\n\t\t\tlogger.log(` URL: ${registry.registryUrl}`);\n\t\t\tlogger.log(` Username: ${registry.username}`);\n\t\t\tif (registry.imagePrefix) {\n\t\t\t\tlogger.log(` Prefix: ${registry.imagePrefix}`);\n\t\t\t}\n\t\t}\n\t}\n}\n","import type {\n\tComposeServiceName,\n\tComposeServicesConfig,\n\tServiceConfig,\n} from '../types';\n\n/** Default Docker images for services */\nexport const DEFAULT_SERVICE_IMAGES: Record<ComposeServiceName, string> = {\n\tpostgres: 'postgres',\n\tredis: 'redis',\n\trabbitmq: 'rabbitmq',\n};\n\n/** Default Docker image versions for services */\nexport const DEFAULT_SERVICE_VERSIONS: Record<ComposeServiceName, string> = {\n\tpostgres: '16-alpine',\n\tredis: '7-alpine',\n\trabbitmq: '3-management-alpine',\n};\n\nexport interface ComposeOptions {\n\timageName: string;\n\tregistry: string;\n\tport: number;\n\thealthCheckPath: string;\n\t/** Services config - object format or legacy array format */\n\tservices: ComposeServicesConfig | ComposeServiceName[];\n}\n\n/** Get the default full image reference for a service */\nfunction getDefaultImage(serviceName: ComposeServiceName): string {\n\treturn `${DEFAULT_SERVICE_IMAGES[serviceName]}:${DEFAULT_SERVICE_VERSIONS[serviceName]}`;\n}\n\n/** Normalize services config to a consistent format - returns Map of service name to full image reference */\nfunction normalizeServices(\n\tservices: ComposeServicesConfig | ComposeServiceName[],\n): Map<ComposeServiceName, string> {\n\tconst result = new Map<ComposeServiceName, string>();\n\n\tif (Array.isArray(services)) {\n\t\t// Legacy array format - use default images\n\t\tfor (const name of services) {\n\t\t\tresult.set(name, getDefaultImage(name));\n\t\t}\n\t} else {\n\t\t// Object format\n\t\tfor (const [name, config] of Object.entries(services)) {\n\t\t\tconst serviceName = name as ComposeServiceName;\n\t\t\tif (config === true) {\n\t\t\t\t// boolean true - use default image\n\t\t\t\tresult.set(serviceName, getDefaultImage(serviceName));\n\t\t\t} else if (config && typeof config === 'object') {\n\t\t\t\tconst serviceConfig = config as ServiceConfig;\n\t\t\t\tif (serviceConfig.image) {\n\t\t\t\t\t// Full image reference provided\n\t\t\t\t\tresult.set(serviceName, serviceConfig.image);\n\t\t\t\t} else {\n\t\t\t\t\t// Version only - use default image name with custom version\n\t\t\t\t\tconst version =\n\t\t\t\t\t\tserviceConfig.version ?? DEFAULT_SERVICE_VERSIONS[serviceName];\n\t\t\t\t\tresult.set(\n\t\t\t\t\t\tserviceName,\n\t\t\t\t\t\t`${DEFAULT_SERVICE_IMAGES[serviceName]}:${version}`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t\t// false or undefined - skip\n\t\t}\n\t}\n\n\treturn result;\n}\n\n/**\n * Generate docker-compose.yml for production deployment\n */\nexport function generateDockerCompose(options: ComposeOptions): string {\n\tconst { imageName, registry, port, healthCheckPath, services } = options;\n\n\t// Normalize services to Map<name, version>\n\tconst serviceMap = normalizeServices(services);\n\n\tconst imageRef = registry ? `\\${REGISTRY:-${registry}}/` : '';\n\n\tlet yaml = `version: '3.8'\n\nservices:\n api:\n build:\n context: ../..\n dockerfile: .gkm/docker/Dockerfile\n image: ${imageRef}\\${IMAGE_NAME:-${imageName}}:\\${TAG:-latest}\n container_name: ${imageName}\n restart: unless-stopped\n ports:\n - \"\\${PORT:-${port}}:${port}\"\n environment:\n - NODE_ENV=production\n`;\n\n\t// Add environment variables based on services\n\tif (serviceMap.has('postgres')) {\n\t\tyaml += ` - DATABASE_URL=\\${DATABASE_URL:-postgresql://postgres:postgres@postgres:5432/app}\n`;\n\t}\n\n\tif (serviceMap.has('redis')) {\n\t\tyaml += ` - REDIS_URL=\\${REDIS_URL:-redis://redis:6379}\n`;\n\t}\n\n\tif (serviceMap.has('rabbitmq')) {\n\t\tyaml += ` - RABBITMQ_URL=\\${RABBITMQ_URL:-amqp://rabbitmq:5672}\n`;\n\t}\n\n\tyaml += ` healthcheck:\n test: [\"CMD\", \"wget\", \"-q\", \"--spider\", \"http://localhost:${port}${healthCheckPath}\"]\n interval: 30s\n timeout: 3s\n retries: 3\n`;\n\n\t// Add depends_on if there are services\n\tif (serviceMap.size > 0) {\n\t\tyaml += ` depends_on:\n`;\n\t\tfor (const serviceName of serviceMap.keys()) {\n\t\t\tyaml += ` ${serviceName}:\n condition: service_healthy\n`;\n\t\t}\n\t}\n\n\tyaml += ` networks:\n - app-network\n`;\n\n\t// Add service definitions with images\n\tconst postgresImage = serviceMap.get('postgres');\n\tif (postgresImage) {\n\t\tyaml += `\n postgres:\n image: ${postgresImage}\n container_name: postgres\n restart: unless-stopped\n environment:\n POSTGRES_USER: \\${POSTGRES_USER:-postgres}\n POSTGRES_PASSWORD: \\${POSTGRES_PASSWORD:-postgres}\n POSTGRES_DB: \\${POSTGRES_DB:-app}\n volumes:\n - postgres_data:/var/lib/postgresql/data\n healthcheck:\n test: [\"CMD-SHELL\", \"pg_isready -U postgres\"]\n interval: 5s\n timeout: 5s\n retries: 5\n networks:\n - app-network\n`;\n\t}\n\n\tconst redisImage = serviceMap.get('redis');\n\tif (redisImage) {\n\t\tyaml += `\n redis:\n image: ${redisImage}\n container_name: redis\n restart: unless-stopped\n volumes:\n - redis_data:/data\n healthcheck:\n test: [\"CMD\", \"redis-cli\", \"ping\"]\n interval: 5s\n timeout: 5s\n retries: 5\n networks:\n - app-network\n`;\n\t}\n\n\tconst rabbitmqImage = serviceMap.get('rabbitmq');\n\tif (rabbitmqImage) {\n\t\tyaml += `\n rabbitmq:\n image: ${rabbitmqImage}\n container_name: rabbitmq\n restart: unless-stopped\n environment:\n RABBITMQ_DEFAULT_USER: \\${RABBITMQ_USER:-guest}\n RABBITMQ_DEFAULT_PASS: \\${RABBITMQ_PASSWORD:-guest}\n ports:\n - \"15672:15672\" # Management UI\n volumes:\n - rabbitmq_data:/var/lib/rabbitmq\n healthcheck:\n test: [\"CMD\", \"rabbitmq-diagnostics\", \"-q\", \"ping\"]\n interval: 10s\n timeout: 5s\n retries: 5\n networks:\n - app-network\n`;\n\t}\n\n\t// Add volumes\n\tyaml += `\nvolumes:\n`;\n\n\tif (serviceMap.has('postgres')) {\n\t\tyaml += ` postgres_data:\n`;\n\t}\n\n\tif (serviceMap.has('redis')) {\n\t\tyaml += ` redis_data:\n`;\n\t}\n\n\tif (serviceMap.has('rabbitmq')) {\n\t\tyaml += ` rabbitmq_data:\n`;\n\t}\n\n\t// Add networks\n\tyaml += `\nnetworks:\n app-network:\n driver: bridge\n`;\n\n\treturn yaml;\n}\n\n/**\n * Generate a minimal docker-compose.yml for API only\n */\nexport function generateMinimalDockerCompose(\n\toptions: Omit<ComposeOptions, 'services'>,\n): string {\n\tconst { imageName, registry, port, healthCheckPath } = options;\n\n\tconst imageRef = registry ? `\\${REGISTRY:-${registry}}/` : '';\n\n\treturn `version: '3.8'\n\nservices:\n api:\n build:\n context: ../..\n dockerfile: .gkm/docker/Dockerfile\n image: ${imageRef}\\${IMAGE_NAME:-${imageName}}:\\${TAG:-latest}\n container_name: ${imageName}\n restart: unless-stopped\n ports:\n - \"\\${PORT:-${port}}:${port}\"\n environment:\n - NODE_ENV=production\n healthcheck:\n test: [\"CMD\", \"wget\", \"-q\", \"--spider\", \"http://localhost:${port}${healthCheckPath}\"]\n interval: 30s\n timeout: 3s\n retries: 3\n networks:\n - app-network\n\nnetworks:\n app-network:\n driver: bridge\n`;\n}\n","import { existsSync } from 'node:fs';\nimport { dirname, join, parse } from 'node:path';\nimport type { DockerConfig, GkmConfig } from '../types';\n\nexport type PackageManager = 'pnpm' | 'npm' | 'yarn' | 'bun';\n\nexport interface DockerTemplateOptions {\n\timageName: string;\n\tbaseImage: string;\n\tport: number;\n\thealthCheckPath: string;\n\t/** Whether the build is pre-built (slim Dockerfile) or needs building */\n\tprebuilt: boolean;\n\t/** Detected package manager */\n\tpackageManager: PackageManager;\n}\n\nexport interface MultiStageDockerfileOptions extends DockerTemplateOptions {\n\t/** Enable turbo prune for monorepo optimization */\n\tturbo?: boolean;\n\t/** Package name for turbo prune (defaults to current directory name) */\n\tturboPackage?: string;\n}\n\n/**\n * Detect package manager from lockfiles\n * Walks up the directory tree to find lockfile (for monorepos)\n */\nexport function detectPackageManager(\n\tcwd: string = process.cwd(),\n): PackageManager {\n\tconst lockfiles: [string, PackageManager][] = [\n\t\t['pnpm-lock.yaml', 'pnpm'],\n\t\t['bun.lockb', 'bun'],\n\t\t['yarn.lock', 'yarn'],\n\t\t['package-lock.json', 'npm'],\n\t];\n\n\tlet dir = cwd;\n\tconst root = parse(dir).root;\n\n\t// Walk up the directory tree\n\twhile (dir !== root) {\n\t\tfor (const [lockfile, pm] of lockfiles) {\n\t\t\tif (existsSync(join(dir, lockfile))) {\n\t\t\t\treturn pm;\n\t\t\t}\n\t\t}\n\t\tdir = dirname(dir);\n\t}\n\n\t// Check root directory\n\tfor (const [lockfile, pm] of lockfiles) {\n\t\tif (existsSync(join(root, lockfile))) {\n\t\t\treturn pm;\n\t\t}\n\t}\n\n\treturn 'pnpm'; // default\n}\n\n/**\n * Get package manager specific commands and paths\n */\nfunction getPmConfig(pm: PackageManager) {\n\tconst configs = {\n\t\tpnpm: {\n\t\t\tinstall: 'corepack enable && corepack prepare pnpm@latest --activate',\n\t\t\tlockfile: 'pnpm-lock.yaml',\n\t\t\tfetch: 'pnpm fetch',\n\t\t\tinstallCmd: 'pnpm install --frozen-lockfile --offline',\n\t\t\tcacheTarget: '/root/.local/share/pnpm/store',\n\t\t\tcacheId: 'pnpm',\n\t\t\trun: 'pnpm',\n\t\t\taddGlobal: 'pnpm add -g',\n\t\t},\n\t\tnpm: {\n\t\t\tinstall: '', // npm comes with node\n\t\t\tlockfile: 'package-lock.json',\n\t\t\tfetch: '', // npm doesn't have fetch\n\t\t\tinstallCmd: 'npm ci',\n\t\t\tcacheTarget: '/root/.npm',\n\t\t\tcacheId: 'npm',\n\t\t\trun: 'npm run',\n\t\t\taddGlobal: 'npm install -g',\n\t\t},\n\t\tyarn: {\n\t\t\tinstall: 'corepack enable && corepack prepare yarn@stable --activate',\n\t\t\tlockfile: 'yarn.lock',\n\t\t\tfetch: '', // yarn doesn't have fetch\n\t\t\tinstallCmd: 'yarn install --frozen-lockfile',\n\t\t\tcacheTarget: '/root/.yarn/cache',\n\t\t\tcacheId: 'yarn',\n\t\t\trun: 'yarn',\n\t\t\taddGlobal: 'yarn global add',\n\t\t},\n\t\tbun: {\n\t\t\tinstall: 'npm install -g bun',\n\t\t\tlockfile: 'bun.lockb',\n\t\t\tfetch: '', // bun doesn't have fetch\n\t\t\tinstallCmd: 'bun install --frozen-lockfile',\n\t\t\tcacheTarget: '/root/.bun/install/cache',\n\t\t\tcacheId: 'bun',\n\t\t\trun: 'bun run',\n\t\t\taddGlobal: 'bun add -g',\n\t\t},\n\t};\n\treturn configs[pm];\n}\n\n/**\n * Generate a multi-stage Dockerfile for building from source\n * Optimized for build speed with:\n * - BuildKit cache mounts for package manager store\n * - pnpm fetch for better layer caching (when using pnpm)\n * - Optional turbo prune for monorepos\n */\nexport function generateMultiStageDockerfile(\n\toptions: MultiStageDockerfileOptions,\n): string {\n\tconst {\n\t\tbaseImage,\n\t\tport,\n\t\thealthCheckPath,\n\t\tturbo,\n\t\tturboPackage,\n\t\tpackageManager,\n\t} = options;\n\n\tif (turbo) {\n\t\treturn generateTurboDockerfile({\n\t\t\t...options,\n\t\t\tturboPackage: turboPackage ?? 'api',\n\t\t});\n\t}\n\n\tconst pm = getPmConfig(packageManager);\n\tconst installPm = pm.install\n\t\t? `\\n# Install ${packageManager}\\nRUN ${pm.install}\\n`\n\t\t: '';\n\tconst hasFetch = packageManager === 'pnpm';\n\n\t// pnpm has fetch which allows better caching\n\tconst depsStage = hasFetch\n\t\t? `# Copy lockfile first for better caching\nCOPY ${pm.lockfile} ./\n\n# Fetch dependencies (downloads to virtual store, cached separately)\nRUN --mount=type=cache,id=${pm.cacheId},target=${pm.cacheTarget} \\\\\n ${pm.fetch}\n\n# Copy package.json after fetch\nCOPY package.json ./\n\n# Install from cache (fast - no network needed)\nRUN --mount=type=cache,id=${pm.cacheId},target=${pm.cacheTarget} \\\\\n ${pm.installCmd}`\n\t\t: `# Copy package files\nCOPY package.json ${pm.lockfile} ./\n\n# Install dependencies with cache\nRUN --mount=type=cache,id=${pm.cacheId},target=${pm.cacheTarget} \\\\\n ${pm.installCmd}`;\n\n\treturn `# syntax=docker/dockerfile:1\n# Stage 1: Dependencies\nFROM ${baseImage} AS deps\n\nWORKDIR /app\n${installPm}\n${depsStage}\n\n# Stage 2: Build\nFROM deps AS builder\n\nWORKDIR /app\n\n# Copy source (deps already installed)\nCOPY . .\n\n# Build production server\nRUN ${pm.run} gkm build --provider server --production\n\n# Stage 3: Production\nFROM ${baseImage} AS runner\n\nWORKDIR /app\n\n# Install tini for proper signal handling as PID 1\nRUN apk add --no-cache tini\n\n# Create non-root user\nRUN addgroup --system --gid 1001 nodejs && \\\\\n adduser --system --uid 1001 hono\n\n# Copy bundled server\nCOPY --from=builder --chown=hono:nodejs /app/.gkm/server/dist/server.mjs ./\n\n# Environment\nENV NODE_ENV=production\nENV PORT=${port}\n\n# Health check\nHEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \\\\\n CMD wget -q --spider http://localhost:${port}${healthCheckPath} || exit 1\n\n# Switch to non-root user\nUSER hono\n\nEXPOSE ${port}\n\n# Use tini as entrypoint to handle PID 1 responsibilities\nENTRYPOINT [\"/sbin/tini\", \"--\"]\nCMD [\"node\", \"server.mjs\"]\n`;\n}\n\n/**\n * Generate a Dockerfile optimized for Turbo monorepos\n * Uses turbo prune to create minimal Docker context\n */\nfunction generateTurboDockerfile(options: MultiStageDockerfileOptions): string {\n\tconst { baseImage, port, healthCheckPath, turboPackage, packageManager } =\n\t\toptions;\n\n\tconst pm = getPmConfig(packageManager);\n\tconst installPm = pm.install ? `RUN ${pm.install}` : '';\n\tconst hasFetch = packageManager === 'pnpm';\n\n\t// pnpm has fetch which allows better caching\n\tconst depsInstall = hasFetch\n\t\t? `# Fetch and install from cache\nRUN --mount=type=cache,id=${pm.cacheId},target=${pm.cacheTarget} \\\\\n ${pm.fetch}\n\nRUN --mount=type=cache,id=${pm.cacheId},target=${pm.cacheTarget} \\\\\n ${pm.installCmd}`\n\t\t: `# Install dependencies with cache\nRUN --mount=type=cache,id=${pm.cacheId},target=${pm.cacheTarget} \\\\\n ${pm.installCmd}`;\n\n\treturn `# syntax=docker/dockerfile:1\n# Stage 1: Prune monorepo\nFROM ${baseImage} AS pruner\n\nWORKDIR /app\n\n${installPm}\nRUN ${pm.addGlobal} turbo\n\nCOPY . .\n\n# Prune to only include necessary packages\nRUN turbo prune ${turboPackage} --docker\n\n# Stage 2: Install dependencies\nFROM ${baseImage} AS deps\n\nWORKDIR /app\n\n${installPm}\n\n# Copy pruned lockfile and package.jsons\nCOPY --from=pruner /app/out/${pm.lockfile} ./\nCOPY --from=pruner /app/out/json/ ./\n\n${depsInstall}\n\n# Stage 3: Build\nFROM deps AS builder\n\nWORKDIR /app\n\n# Copy pruned source\nCOPY --from=pruner /app/out/full/ ./\n\n# Build production server\nRUN ${pm.run} gkm build --provider server --production\n\n# Stage 4: Production\nFROM ${baseImage} AS runner\n\nWORKDIR /app\n\nRUN apk add --no-cache tini\n\nRUN addgroup --system --gid 1001 nodejs && \\\\\n adduser --system --uid 1001 hono\n\nCOPY --from=builder --chown=hono:nodejs /app/.gkm/server/dist/server.mjs ./\n\nENV NODE_ENV=production\nENV PORT=${port}\n\nHEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \\\\\n CMD wget -q --spider http://localhost:${port}${healthCheckPath} || exit 1\n\nUSER hono\n\nEXPOSE ${port}\n\nENTRYPOINT [\"/sbin/tini\", \"--\"]\nCMD [\"node\", \"server.mjs\"]\n`;\n}\n\n/**\n * Generate a slim Dockerfile for pre-built bundles\n */\nexport function generateSlimDockerfile(options: DockerTemplateOptions): string {\n\tconst { baseImage, port, healthCheckPath } = options;\n\n\treturn `# Slim Dockerfile for pre-built production bundle\nFROM ${baseImage}\n\nWORKDIR /app\n\n# Install tini for proper signal handling as PID 1\n# Handles SIGTERM propagation and zombie process reaping\nRUN apk add --no-cache tini\n\n# Create non-root user\nRUN addgroup --system --gid 1001 nodejs && \\\\\n adduser --system --uid 1001 hono\n\n# Copy pre-built bundle\nCOPY .gkm/server/dist/server.mjs ./\n\n# Environment\nENV NODE_ENV=production\nENV PORT=${port}\n\n# Health check\nHEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \\\\\n CMD wget -q --spider http://localhost:${port}${healthCheckPath} || exit 1\n\n# Switch to non-root user\nUSER hono\n\nEXPOSE ${port}\n\n# Use tini as entrypoint to handle PID 1 responsibilities\nENTRYPOINT [\"/sbin/tini\", \"--\"]\nCMD [\"node\", \"server.mjs\"]\n`;\n}\n\n/**\n * Generate .dockerignore file\n */\nexport function generateDockerignore(): string {\n\treturn `# Dependencies\nnode_modules\n.pnpm-store\n\n# Build output (except what we need)\n.gkm/aws*\n.gkm/server/*.ts\n!.gkm/server/dist\n\n# IDE and editor\n.idea\n.vscode\n*.swp\n*.swo\n\n# Git\n.git\n.gitignore\n\n# Logs\n*.log\nnpm-debug.log*\npnpm-debug.log*\n\n# Test files\n**/*.test.ts\n**/*.spec.ts\n**/__tests__\ncoverage\n\n# Documentation\ndocs\n*.md\n!README.md\n\n# Environment files (handle secrets separately)\n.env\n.env.*\n!.env.example\n\n# Docker files (don't copy recursively)\nDockerfile*\ndocker-compose*\n.dockerignore\n`;\n}\n\n/**\n * Generate docker-entrypoint.sh for custom startup logic\n */\nexport function generateDockerEntrypoint(): string {\n\treturn `#!/bin/sh\nset -e\n\n# Run any custom startup scripts here\n# Example: wait for database\n# until nc -z $DB_HOST $DB_PORT; do\n# echo \"Waiting for database...\"\n# sleep 1\n# done\n\n# Execute the main command\nexec \"$@\"\n`;\n}\n\n/**\n * Resolve Docker configuration from GkmConfig with defaults\n */\nexport function resolveDockerConfig(\n\tconfig: GkmConfig,\n): Required<Omit<DockerConfig, 'compose'>> & Pick<DockerConfig, 'compose'> {\n\tconst docker = config.docker ?? {};\n\n\t// Try to get image name from package.json name\n\tlet defaultImageName = 'api';\n\ttry {\n\t\t// eslint-disable-next-line @typescript-eslint/no-require-imports\n\t\tconst pkg = require(`${process.cwd()}/package.json`);\n\t\tif (pkg.name) {\n\t\t\t// Remove scope and use just the package name\n\t\t\tdefaultImageName = pkg.name.replace(/^@[^/]+\\//, '');\n\t\t}\n\t} catch {\n\t\t// Ignore if package.json doesn't exist\n\t}\n\n\treturn {\n\t\tregistry: docker.registry ?? '',\n\t\timageName: docker.imageName ?? defaultImageName,\n\t\tbaseImage: docker.baseImage ?? 'node:22-alpine',\n\t\tport: docker.port ?? 3000,\n\t\tcompose: docker.compose,\n\t};\n}\n","import { execSync } from 'node:child_process';\nimport { existsSync } from 'node:fs';\nimport { mkdir, writeFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { loadConfig } from '../config';\nimport { generateDockerCompose, generateMinimalDockerCompose } from './compose';\nimport {\n\tdetectPackageManager,\n\tgenerateDockerEntrypoint,\n\tgenerateDockerignore,\n\tgenerateMultiStageDockerfile,\n\tgenerateSlimDockerfile,\n\tresolveDockerConfig,\n} from './templates';\n\nconst logger = console;\n\nexport interface DockerOptions {\n\t/** Build Docker image after generating files */\n\tbuild?: boolean;\n\t/** Push image to registry after building */\n\tpush?: boolean;\n\t/** Image tag (default: 'latest') */\n\ttag?: string;\n\t/** Container registry URL */\n\tregistry?: string;\n\t/** Use slim Dockerfile (requires pre-built bundle from `gkm build --production`) */\n\tslim?: boolean;\n\t/** Enable turbo prune for monorepo optimization */\n\tturbo?: boolean;\n\t/** Package name for turbo prune (defaults to package.json name) */\n\tturboPackage?: string;\n}\n\nexport interface DockerGeneratedFiles {\n\tdockerfile: string;\n\tdockerCompose: string;\n\tdockerignore: string;\n\tentrypoint: string;\n}\n\n/**\n * Docker command implementation\n * Generates Dockerfile, docker-compose.yml, and related files\n *\n * Default: Multi-stage Dockerfile that builds from source inside Docker\n * --slim: Slim Dockerfile that copies pre-built bundle (requires prior build)\n */\nexport async function dockerCommand(\n\toptions: DockerOptions,\n): Promise<DockerGeneratedFiles> {\n\tconst config = await loadConfig();\n\tconst dockerConfig = resolveDockerConfig(config);\n\n\t// Get health check path from production config\n\tconst serverConfig =\n\t\ttypeof config.providers?.server === 'object'\n\t\t\t? config.providers.server\n\t\t\t: undefined;\n\tconst healthCheckPath = serverConfig?.production?.healthCheck ?? '/health';\n\n\t// Determine Dockerfile type\n\t// Default: Multi-stage (builds inside Docker for reproducibility)\n\t// --slim: Requires pre-built bundle\n\tconst useSlim = options.slim === true;\n\n\tif (useSlim) {\n\t\t// Verify pre-built bundle exists for slim mode\n\t\tconst distDir = join(process.cwd(), '.gkm', 'server', 'dist');\n\t\tconst hasBuild = existsSync(join(distDir, 'server.mjs'));\n\n\t\tif (!hasBuild) {\n\t\t\tthrow new Error(\n\t\t\t\t'Slim Dockerfile requires a pre-built bundle. Run `gkm build --provider server --production` first, or omit --slim to use multi-stage build.',\n\t\t\t);\n\t\t}\n\t}\n\n\t// Generate Docker files\n\tconst dockerDir = join(process.cwd(), '.gkm', 'docker');\n\tawait mkdir(dockerDir, { recursive: true });\n\n\t// Detect package manager from lockfiles\n\tconst packageManager = detectPackageManager();\n\n\tconst templateOptions = {\n\t\timageName: dockerConfig.imageName,\n\t\tbaseImage: dockerConfig.baseImage,\n\t\tport: dockerConfig.port,\n\t\thealthCheckPath,\n\t\tprebuilt: useSlim,\n\t\tturbo: options.turbo,\n\t\tturboPackage: options.turboPackage ?? dockerConfig.imageName,\n\t\tpackageManager,\n\t};\n\n\t// Generate Dockerfile\n\tconst dockerfile = useSlim\n\t\t? generateSlimDockerfile(templateOptions)\n\t\t: generateMultiStageDockerfile(templateOptions);\n\n\tconst dockerMode = useSlim ? 'slim' : options.turbo ? 'turbo' : 'multi-stage';\n\n\tconst dockerfilePath = join(dockerDir, 'Dockerfile');\n\tawait writeFile(dockerfilePath, dockerfile);\n\tlogger.log(\n\t\t`Generated: .gkm/docker/Dockerfile (${dockerMode}, ${packageManager})`,\n\t);\n\n\t// Generate docker-compose.yml\n\tconst composeOptions = {\n\t\timageName: dockerConfig.imageName,\n\t\tregistry: options.registry ?? dockerConfig.registry,\n\t\tport: dockerConfig.port,\n\t\thealthCheckPath,\n\t\tservices: dockerConfig.compose?.services ?? {},\n\t};\n\n\t// Check if there are any services configured\n\tconst hasServices = Array.isArray(composeOptions.services)\n\t\t? composeOptions.services.length > 0\n\t\t: Object.keys(composeOptions.services).length > 0;\n\n\tconst dockerCompose = hasServices\n\t\t? generateDockerCompose(composeOptions)\n\t\t: generateMinimalDockerCompose(composeOptions);\n\n\tconst composePath = join(dockerDir, 'docker-compose.yml');\n\tawait writeFile(composePath, dockerCompose);\n\tlogger.log('Generated: .gkm/docker/docker-compose.yml');\n\n\t// Generate .dockerignore in project root (Docker looks for it there)\n\tconst dockerignore = generateDockerignore();\n\tconst dockerignorePath = join(process.cwd(), '.dockerignore');\n\tawait writeFile(dockerignorePath, dockerignore);\n\tlogger.log('Generated: .dockerignore (project root)');\n\n\t// Generate docker-entrypoint.sh\n\tconst entrypoint = generateDockerEntrypoint();\n\tconst entrypointPath = join(dockerDir, 'docker-entrypoint.sh');\n\tawait writeFile(entrypointPath, entrypoint);\n\tlogger.log('Generated: .gkm/docker/docker-entrypoint.sh');\n\n\tconst result: DockerGeneratedFiles = {\n\t\tdockerfile: dockerfilePath,\n\t\tdockerCompose: composePath,\n\t\tdockerignore: dockerignorePath,\n\t\tentrypoint: entrypointPath,\n\t};\n\n\t// Build Docker image if requested\n\tif (options.build) {\n\t\tawait buildDockerImage(dockerConfig.imageName, options);\n\t}\n\n\t// Push Docker image if requested\n\tif (options.push) {\n\t\tawait pushDockerImage(dockerConfig.imageName, options);\n\t}\n\n\treturn result;\n}\n\n/**\n * Build Docker image\n * Uses BuildKit for cache mount support\n */\nasync function buildDockerImage(\n\timageName: string,\n\toptions: DockerOptions,\n): Promise<void> {\n\tconst tag = options.tag ?? 'latest';\n\tconst registry = options.registry;\n\n\tconst fullImageName = registry\n\t\t? `${registry}/${imageName}:${tag}`\n\t\t: `${imageName}:${tag}`;\n\n\tlogger.log(`\\n🐳 Building Docker image: ${fullImageName}`);\n\n\ttry {\n\t\t// Use BuildKit for cache mount support (required for --mount=type=cache)\n\t\texecSync(\n\t\t\t`DOCKER_BUILDKIT=1 docker build -f .gkm/docker/Dockerfile -t ${fullImageName} .`,\n\t\t\t{\n\t\t\t\tcwd: process.cwd(),\n\t\t\t\tstdio: 'inherit',\n\t\t\t\tenv: { ...process.env, DOCKER_BUILDKIT: '1' },\n\t\t\t},\n\t\t);\n\t\tlogger.log(`✅ Docker image built: ${fullImageName}`);\n\t} catch (error) {\n\t\tthrow new Error(\n\t\t\t`Failed to build Docker image: ${error instanceof Error ? error.message : 'Unknown error'}`,\n\t\t);\n\t}\n}\n\n/**\n * Push Docker image to registry\n */\nasync function pushDockerImage(\n\timageName: string,\n\toptions: DockerOptions,\n): Promise<void> {\n\tconst tag = options.tag ?? 'latest';\n\tconst registry = options.registry;\n\n\tif (!registry) {\n\t\tthrow new Error(\n\t\t\t'Registry is required to push Docker image. Use --registry or configure docker.registry in gkm.config.ts',\n\t\t);\n\t}\n\n\tconst fullImageName = `${registry}/${imageName}:${tag}`;\n\n\tlogger.log(`\\n🚀 Pushing Docker image: ${fullImageName}`);\n\n\ttry {\n\t\texecSync(`docker push ${fullImageName}`, {\n\t\t\tcwd: process.cwd(),\n\t\t\tstdio: 'inherit',\n\t\t});\n\t\tlogger.log(`✅ Docker image pushed: ${fullImageName}`);\n\t} catch (error) {\n\t\tthrow new Error(\n\t\t\t`Failed to push Docker image: ${error instanceof Error ? error.message : 'Unknown error'}`,\n\t\t);\n\t}\n}\n","import type {\n\tGeneratedFile,\n\tTemplateConfig,\n\tTemplateOptions,\n} from '../templates/index.js';\n\n/**\n * Generate configuration files (gkm.config.ts, tsconfig.json, biome.json, turbo.json)\n */\nexport function generateConfigFiles(\n\toptions: TemplateOptions,\n\ttemplate: TemplateConfig,\n): GeneratedFile[] {\n\tconst { telescope, studio, routesStructure } = options;\n\tconst isServerless = template.name === 'serverless';\n\tconst hasWorker = template.name === 'worker';\n\n\t// Get routes glob pattern based on structure\n\tconst getRoutesGlob = () => {\n\t\tswitch (routesStructure) {\n\t\t\tcase 'centralized-endpoints':\n\t\t\t\treturn './src/endpoints/**/*.ts';\n\t\t\tcase 'centralized-routes':\n\t\t\t\treturn './src/routes/**/*.ts';\n\t\t\tcase 'domain-based':\n\t\t\t\treturn './src/**/routes/*.ts';\n\t\t}\n\t};\n\n\t// Build gkm.config.ts\n\tlet gkmConfig = `import { defineConfig } from '@geekmidas/cli/config';\n\nexport default defineConfig({\n routes: '${getRoutesGlob()}',\n envParser: './src/config/env#envParser',\n logger: './src/config/logger#logger',`;\n\n\tif (isServerless || hasWorker) {\n\t\tgkmConfig += `\n functions: './src/functions/**/*.ts',`;\n\t}\n\n\tif (hasWorker) {\n\t\tgkmConfig += `\n crons: './src/crons/**/*.ts',\n subscribers: './src/subscribers/**/*.ts',`;\n\t}\n\n\tif (telescope) {\n\t\tgkmConfig += `\n telescope: {\n enabled: true,\n path: '/__telescope',\n },`;\n\t}\n\n\tif (studio) {\n\t\tgkmConfig += `\n studio: './src/config/studio#studio',`;\n\t}\n\n\t// Always add openapi config (output path is fixed to .gkm/openapi.ts)\n\tgkmConfig += `\n openapi: {\n enabled: true,\n },`;\n\n\tgkmConfig += `\n});\n`;\n\n\t// Build tsconfig.json - extends root for monorepo, standalone for non-monorepo\n\tconst tsConfig = options.monorepo\n\t\t? {\n\t\t\t\textends: '../../tsconfig.json',\n\t\t\t\tcompilerOptions: {\n\t\t\t\t\toutDir: './dist',\n\t\t\t\t\trootDir: './src',\n\t\t\t\t\tbaseUrl: '.',\n\t\t\t\t\tpaths: {\n\t\t\t\t\t\t[`@${options.name}/*`]: ['../../packages/*/src'],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tinclude: ['src/**/*.ts'],\n\t\t\t\texclude: ['node_modules', 'dist'],\n\t\t\t}\n\t\t: {\n\t\t\t\tcompilerOptions: {\n\t\t\t\t\ttarget: 'ES2022',\n\t\t\t\t\tmodule: 'NodeNext',\n\t\t\t\t\tmoduleResolution: 'NodeNext',\n\t\t\t\t\tlib: ['ES2022'],\n\t\t\t\t\tstrict: true,\n\t\t\t\t\tesModuleInterop: true,\n\t\t\t\t\tskipLibCheck: true,\n\t\t\t\t\tforceConsistentCasingInFileNames: true,\n\t\t\t\t\tresolveJsonModule: true,\n\t\t\t\t\tdeclaration: true,\n\t\t\t\t\tdeclarationMap: true,\n\t\t\t\t\toutDir: './dist',\n\t\t\t\t\trootDir: './src',\n\t\t\t\t},\n\t\t\t\tinclude: ['src/**/*.ts'],\n\t\t\t\texclude: ['node_modules', 'dist'],\n\t\t\t};\n\n\t// Skip biome.json and turbo.json for monorepo (they're at root)\n\tif (options.monorepo) {\n\t\treturn [\n\t\t\t{\n\t\t\t\tpath: 'gkm.config.ts',\n\t\t\t\tcontent: gkmConfig,\n\t\t\t},\n\t\t\t{\n\t\t\t\tpath: 'tsconfig.json',\n\t\t\t\tcontent: `${JSON.stringify(tsConfig, null, 2)}\\n`,\n\t\t\t},\n\t\t];\n\t}\n\n\t// Build biome.json\n\tconst biomeConfig = {\n\t\t$schema: 'https://biomejs.dev/schemas/1.9.4/schema.json',\n\t\tvcs: {\n\t\t\tenabled: true,\n\t\t\tclientKind: 'git',\n\t\t\tuseIgnoreFile: true,\n\t\t},\n\t\torganizeImports: {\n\t\t\tenabled: true,\n\t\t},\n\t\tformatter: {\n\t\t\tenabled: true,\n\t\t\tindentStyle: 'space',\n\t\t\tindentWidth: 2,\n\t\t\tlineWidth: 80,\n\t\t},\n\t\tjavascript: {\n\t\t\tformatter: {\n\t\t\t\tquoteStyle: 'single',\n\t\t\t\ttrailingCommas: 'all',\n\t\t\t\tsemicolons: 'always',\n\t\t\t\tarrowParentheses: 'always',\n\t\t\t},\n\t\t},\n\t\tlinter: {\n\t\t\tenabled: true,\n\t\t\trules: {\n\t\t\t\trecommended: true,\n\t\t\t\tcorrectness: {\n\t\t\t\t\tnoUnusedImports: 'error',\n\t\t\t\t\tnoUnusedVariables: 'error',\n\t\t\t\t},\n\t\t\t\tstyle: {\n\t\t\t\t\tnoNonNullAssertion: 'off',\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\tfiles: {\n\t\t\tignore: ['node_modules', 'dist', '.gkm', 'coverage'],\n\t\t},\n\t};\n\n\t// Build turbo.json\n\tconst turboConfig = {\n\t\t$schema: 'https://turbo.build/schema.json',\n\t\ttasks: {\n\t\t\tbuild: {\n\t\t\t\tdependsOn: ['^build'],\n\t\t\t\toutputs: ['dist/**'],\n\t\t\t},\n\t\t\tdev: {\n\t\t\t\tcache: false,\n\t\t\t\tpersistent: true,\n\t\t\t},\n\t\t\ttest: {\n\t\t\t\tdependsOn: ['^build'],\n\t\t\t\tcache: false,\n\t\t\t},\n\t\t\t'test:once': {\n\t\t\t\tdependsOn: ['^build'],\n\t\t\t\toutputs: ['coverage/**'],\n\t\t\t},\n\t\t\ttypecheck: {\n\t\t\t\tdependsOn: ['^build'],\n\t\t\t\toutputs: [],\n\t\t\t},\n\t\t\tlint: {\n\t\t\t\toutputs: [],\n\t\t\t},\n\t\t\tfmt: {\n\t\t\t\toutputs: [],\n\t\t\t},\n\t\t},\n\t};\n\n\treturn [\n\t\t{\n\t\t\tpath: 'gkm.config.ts',\n\t\t\tcontent: gkmConfig,\n\t\t},\n\t\t{\n\t\t\tpath: 'tsconfig.json',\n\t\t\tcontent: `${JSON.stringify(tsConfig, null, 2)}\\n`,\n\t\t},\n\t\t{\n\t\t\tpath: 'biome.json',\n\t\t\tcontent: `${JSON.stringify(biomeConfig, null, 2)}\\n`,\n\t\t},\n\t\t{\n\t\t\tpath: 'turbo.json',\n\t\t\tcontent: `${JSON.stringify(turboConfig, null, 2)}\\n`,\n\t\t},\n\t];\n}\n","import type {\n\tGeneratedFile,\n\tTemplateConfig,\n\tTemplateOptions,\n} from '../templates/index.js';\n\n/**\n * Generate docker-compose.yml based on template and options\n */\nexport function generateDockerFiles(\n\toptions: TemplateOptions,\n\ttemplate: TemplateConfig,\n): GeneratedFile[] {\n\tconst { database } = options;\n\tconst isServerless = template.name === 'serverless';\n\tconst hasWorker = template.name === 'worker';\n\n\tconst services: string[] = [];\n\tconst volumes: string[] = [];\n\n\t// PostgreSQL database\n\tif (database) {\n\t\tservices.push(` postgres:\n image: postgres:16-alpine\n container_name: ${options.name}-postgres\n restart: unless-stopped\n environment:\n POSTGRES_USER: postgres\n POSTGRES_PASSWORD: postgres\n POSTGRES_DB: ${options.name.replace(/-/g, '_')}_dev\n ports:\n - '5432:5432'\n volumes:\n - postgres_data:/var/lib/postgresql/data\n healthcheck:\n test: ['CMD-SHELL', 'pg_isready -U postgres']\n interval: 5s\n timeout: 5s\n retries: 5`);\n\t\tvolumes.push(' postgres_data:');\n\t}\n\n\t// Redis - different setup for serverless vs standard\n\tif (isServerless) {\n\t\t// Use serverless-redis-http for Lambda compatibility\n\t\tservices.push(` redis:\n image: redis:7-alpine\n container_name: ${options.name}-redis\n restart: unless-stopped\n ports:\n - '6379:6379'\n volumes:\n - redis_data:/data\n healthcheck:\n test: ['CMD', 'redis-cli', 'ping']\n interval: 5s\n timeout: 5s\n retries: 5\n\n serverless-redis:\n image: hiett/serverless-redis-http:latest\n container_name: ${options.name}-serverless-redis\n restart: unless-stopped\n ports:\n - '8079:80'\n environment:\n SRH_MODE: env\n SRH_TOKEN: local_dev_token\n SRH_CONNECTION_STRING: redis://redis:6379\n depends_on:\n redis:\n condition: service_healthy`);\n\t\tvolumes.push(' redis_data:');\n\t} else {\n\t\t// Standard Redis for non-serverless templates\n\t\tservices.push(` redis:\n image: redis:7-alpine\n container_name: ${options.name}-redis\n restart: unless-stopped\n ports:\n - '6379:6379'\n volumes:\n - redis_data:/data\n healthcheck:\n test: ['CMD', 'redis-cli', 'ping']\n interval: 5s\n timeout: 5s\n retries: 5`);\n\t\tvolumes.push(' redis_data:');\n\t}\n\n\t// RabbitMQ for worker template\n\tif (hasWorker) {\n\t\tservices.push(` rabbitmq:\n image: rabbitmq:3-management-alpine\n container_name: ${options.name}-rabbitmq\n restart: unless-stopped\n ports:\n - '5672:5672'\n - '15672:15672'\n environment:\n RABBITMQ_DEFAULT_USER: guest\n RABBITMQ_DEFAULT_PASS: guest\n volumes:\n - rabbitmq_data:/var/lib/rabbitmq\n healthcheck:\n test: ['CMD', 'rabbitmq-diagnostics', 'check_running']\n interval: 10s\n timeout: 5s\n retries: 5`);\n\t\tvolumes.push(' rabbitmq_data:');\n\t}\n\n\t// Build docker-compose.yml\n\tlet dockerCompose = `version: '3.8'\n\nservices:\n${services.join('\\n\\n')}\n`;\n\n\tif (volumes.length > 0) {\n\t\tdockerCompose += `\nvolumes:\n${volumes.join('\\n')}\n`;\n\t}\n\n\treturn [\n\t\t{\n\t\t\tpath: 'docker-compose.yml',\n\t\t\tcontent: dockerCompose,\n\t\t},\n\t];\n}\n","import type {\n\tGeneratedFile,\n\tTemplateConfig,\n\tTemplateOptions,\n} from '../templates/index.js';\n\n/**\n * Generate environment files (.env, .env.example, .env.development, .env.test, .gitignore)\n */\nexport function generateEnvFiles(\n\toptions: TemplateOptions,\n\ttemplate: TemplateConfig,\n): GeneratedFile[] {\n\tconst { database } = options;\n\tconst isServerless = template.name === 'serverless';\n\tconst hasWorker = template.name === 'worker';\n\n\t// Build base env content\n\tlet baseEnv = `# Application\nNODE_ENV=development\nPORT=3000\nLOG_LEVEL=info\n`;\n\n\tif (isServerless) {\n\t\tbaseEnv = `# AWS\nSTAGE=dev\nAWS_REGION=us-east-1\nLOG_LEVEL=info\n`;\n\t}\n\n\tif (database) {\n\t\tbaseEnv += `\n# Database\nDATABASE_URL=postgresql://user:password@localhost:5432/mydb\n`;\n\t}\n\n\tif (hasWorker) {\n\t\tbaseEnv += `\n# Message Queue\nRABBITMQ_URL=amqp://localhost:5672\n`;\n\t}\n\n\tbaseEnv += `\n# Authentication\nJWT_SECRET=your-secret-key-change-in-production\n`;\n\n\t// Development env\n\tlet devEnv = `# Development Environment\nNODE_ENV=development\nPORT=3000\nLOG_LEVEL=debug\n`;\n\n\tif (isServerless) {\n\t\tdevEnv = `# Development Environment\nSTAGE=dev\nAWS_REGION=us-east-1\nLOG_LEVEL=debug\n`;\n\t}\n\n\tif (database) {\n\t\tdevEnv += `\n# Database\nDATABASE_URL=postgresql://postgres:postgres@localhost:5432/mydb_dev\n`;\n\t}\n\n\tif (hasWorker) {\n\t\tdevEnv += `\n# Message Queue\nRABBITMQ_URL=amqp://localhost:5672\n`;\n\t}\n\n\tdevEnv += `\n# Authentication\nJWT_SECRET=dev-secret-not-for-production\n`;\n\n\t// Test env\n\tlet testEnv = `# Test Environment\nNODE_ENV=test\nPORT=3001\nLOG_LEVEL=error\n`;\n\n\tif (isServerless) {\n\t\ttestEnv = `# Test Environment\nSTAGE=test\nAWS_REGION=us-east-1\nLOG_LEVEL=error\n`;\n\t}\n\n\tif (database) {\n\t\ttestEnv += `\n# Database\nDATABASE_URL=postgresql://postgres:postgres@localhost:5432/mydb_test\n`;\n\t}\n\n\tif (hasWorker) {\n\t\ttestEnv += `\n# Message Queue\nRABBITMQ_URL=amqp://localhost:5672\n`;\n\t}\n\n\ttestEnv += `\n# Authentication\nJWT_SECRET=test-secret-not-for-production\n`;\n\n\tconst files: GeneratedFile[] = [\n\t\t{\n\t\t\tpath: '.env.example',\n\t\t\tcontent: baseEnv,\n\t\t},\n\t\t{\n\t\t\tpath: '.env',\n\t\t\tcontent: baseEnv,\n\t\t},\n\t\t{\n\t\t\tpath: '.env.development',\n\t\t\tcontent: devEnv,\n\t\t},\n\t\t{\n\t\t\tpath: '.env.test',\n\t\t\tcontent: testEnv,\n\t\t},\n\t];\n\n\t// Only add .gitignore for non-monorepo (monorepo has it at root)\n\tif (!options.monorepo) {\n\t\tconst gitignore = `# Dependencies\nnode_modules/\n\n# Build output\ndist/\n.gkm/\n\n# Environment\n.env\n.env.local\n.env.*.local\n\n# IDE\n.idea/\n.vscode/\n*.swp\n*.swo\n\n# OS\n.DS_Store\nThumbs.db\n\n# Logs\n*.log\nnpm-debug.log*\nyarn-debug.log*\npnpm-debug.log*\n\n# Test coverage\ncoverage/\n\n# TypeScript cache\n*.tsbuildinfo\n`;\n\t\tfiles.push({\n\t\t\tpath: '.gitignore',\n\t\t\tcontent: gitignore,\n\t\t});\n\t}\n\n\treturn files;\n}\n","import type { GeneratedFile, TemplateOptions } from '../templates/index.js';\n\n/**\n * Generate packages/models for shared Zod schemas (monorepo only)\n */\nexport function generateModelsPackage(\n\toptions: TemplateOptions,\n): GeneratedFile[] {\n\tif (!options.monorepo) {\n\t\treturn [];\n\t}\n\n\t// Package name based on project name\n\tconst packageName = `@${options.name}/models`;\n\n\t// package.json for models\n\tconst packageJson = {\n\t\tname: packageName,\n\t\tversion: '0.0.1',\n\t\tprivate: true,\n\t\ttype: 'module',\n\t\texports: {\n\t\t\t'.': {\n\t\t\t\ttypes: './dist/index.d.ts',\n\t\t\t\timport: './dist/index.js',\n\t\t\t},\n\t\t\t'./*': {\n\t\t\t\ttypes: './dist/*.d.ts',\n\t\t\t\timport: './dist/*.js',\n\t\t\t},\n\t\t},\n\t\tscripts: {\n\t\t\tbuild: 'tsc',\n\t\t\t'build:watch': 'tsc --watch',\n\t\t\ttypecheck: 'tsc --noEmit',\n\t\t},\n\t\tdependencies: {\n\t\t\tzod: '~4.1.0',\n\t\t},\n\t\tdevDependencies: {\n\t\t\ttypescript: '~5.8.2',\n\t\t},\n\t};\n\n\t// tsconfig.json for models - extends root\n\tconst tsConfig = {\n\t\textends: '../../tsconfig.json',\n\t\tcompilerOptions: {\n\t\t\toutDir: './dist',\n\t\t\trootDir: './src',\n\t\t},\n\t\tinclude: ['src/**/*.ts'],\n\t\texclude: ['node_modules', 'dist'],\n\t};\n\n\t// Main index.ts with example schemas\n\tconst indexTs = `import { z } from 'zod';\n\n// ============================================\n// Common Schemas\n// ============================================\n\nexport const idSchema = z.string().uuid();\n\nexport const timestampsSchema = z.object({\n createdAt: z.coerce.date(),\n updatedAt: z.coerce.date(),\n});\n\nexport const paginationSchema = z.object({\n page: z.coerce.number().int().positive().default(1),\n limit: z.coerce.number().int().positive().max(100).default(20),\n});\n\nexport const paginatedResponseSchema = <T extends z.ZodTypeAny>(itemSchema: T) =>\n z.object({\n items: z.array(itemSchema),\n total: z.number(),\n page: z.number(),\n limit: z.number(),\n totalPages: z.number(),\n });\n\n// ============================================\n// User Schemas\n// ============================================\n\nexport const userSchema = z.object({\n id: idSchema,\n email: z.string().email(),\n name: z.string().min(1).max(100),\n ...timestampsSchema.shape,\n});\n\nexport const createUserSchema = userSchema.omit({\n id: true,\n createdAt: true,\n updatedAt: true,\n});\n\nexport const updateUserSchema = createUserSchema.partial();\n\n// ============================================\n// Type Exports\n// ============================================\n\nexport type Id = z.infer<typeof idSchema>;\nexport type Timestamps = z.infer<typeof timestampsSchema>;\nexport type Pagination = z.infer<typeof paginationSchema>;\nexport type User = z.infer<typeof userSchema>;\nexport type CreateUser = z.infer<typeof createUserSchema>;\nexport type UpdateUser = z.infer<typeof updateUserSchema>;\n`;\n\n\treturn [\n\t\t{\n\t\t\tpath: 'packages/models/package.json',\n\t\t\tcontent: `${JSON.stringify(packageJson, null, 2)}\\n`,\n\t\t},\n\t\t{\n\t\t\tpath: 'packages/models/tsconfig.json',\n\t\t\tcontent: `${JSON.stringify(tsConfig, null, 2)}\\n`,\n\t\t},\n\t\t{\n\t\t\tpath: 'packages/models/src/index.ts',\n\t\t\tcontent: indexTs,\n\t\t},\n\t];\n}\n","import type {\n\tGeneratedFile,\n\tTemplateConfig,\n\tTemplateOptions,\n} from '../templates/index.js';\n\n/**\n * Generate monorepo root files (pnpm-workspace.yaml, root package.json, etc.)\n */\nexport function generateMonorepoFiles(\n\toptions: TemplateOptions,\n\t_template: TemplateConfig,\n): GeneratedFile[] {\n\tif (!options.monorepo) {\n\t\treturn [];\n\t}\n\n\t// Root package.json for monorepo\n\tconst rootPackageJson = {\n\t\tname: options.name,\n\t\tversion: '0.0.1',\n\t\tprivate: true,\n\t\ttype: 'module',\n\t\tscripts: {\n\t\t\tdev: 'turbo dev',\n\t\t\tbuild: 'turbo build',\n\t\t\ttest: 'turbo test',\n\t\t\t'test:once': 'turbo test:once',\n\t\t\ttypecheck: 'turbo typecheck',\n\t\t\tlint: 'biome lint .',\n\t\t\tfmt: 'biome format . --write',\n\t\t\t'fmt:check': 'biome format .',\n\t\t},\n\t\tdevDependencies: {\n\t\t\t'@biomejs/biome': '~1.9.4',\n\t\t\tturbo: '~2.3.0',\n\t\t\ttypescript: '~5.8.2',\n\t\t\tvitest: '~4.0.0',\n\t\t},\n\t};\n\n\t// pnpm-workspace.yaml - detect folder structure from apiPath\n\tconst apiPathParts = options.apiPath.split('/');\n\tconst appsFolder = apiPathParts[0] || 'apps';\n\n\tconst pnpmWorkspace = `packages:\n - '${appsFolder}/*'\n - 'packages/*'\n`;\n\n\t// Root biome.json\n\tconst biomeConfig = {\n\t\t$schema: 'https://biomejs.dev/schemas/1.9.4/schema.json',\n\t\tvcs: {\n\t\t\tenabled: true,\n\t\t\tclientKind: 'git',\n\t\t\tuseIgnoreFile: true,\n\t\t},\n\t\torganizeImports: {\n\t\t\tenabled: true,\n\t\t},\n\t\tformatter: {\n\t\t\tenabled: true,\n\t\t\tindentStyle: 'space',\n\t\t\tindentWidth: 2,\n\t\t\tlineWidth: 80,\n\t\t},\n\t\tjavascript: {\n\t\t\tformatter: {\n\t\t\t\tquoteStyle: 'single',\n\t\t\t\ttrailingCommas: 'all',\n\t\t\t\tsemicolons: 'always',\n\t\t\t\tarrowParentheses: 'always',\n\t\t\t},\n\t\t},\n\t\tlinter: {\n\t\t\tenabled: true,\n\t\t\trules: {\n\t\t\t\trecommended: true,\n\t\t\t\tcorrectness: {\n\t\t\t\t\tnoUnusedImports: 'error',\n\t\t\t\t\tnoUnusedVariables: 'error',\n\t\t\t\t},\n\t\t\t\tstyle: {\n\t\t\t\t\tnoNonNullAssertion: 'off',\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\tfiles: {\n\t\t\tignore: ['node_modules', 'dist', '.gkm', 'coverage'],\n\t\t},\n\t};\n\n\t// Root turbo.json\n\tconst turboConfig = {\n\t\t$schema: 'https://turbo.build/schema.json',\n\t\ttasks: {\n\t\t\tbuild: {\n\t\t\t\tdependsOn: ['^build'],\n\t\t\t\toutputs: ['dist/**'],\n\t\t\t},\n\t\t\tdev: {\n\t\t\t\tcache: false,\n\t\t\t\tpersistent: true,\n\t\t\t},\n\t\t\ttest: {\n\t\t\t\tdependsOn: ['^build'],\n\t\t\t\tcache: false,\n\t\t\t},\n\t\t\t'test:once': {\n\t\t\t\tdependsOn: ['^build'],\n\t\t\t\toutputs: ['coverage/**'],\n\t\t\t},\n\t\t\ttypecheck: {\n\t\t\t\tdependsOn: ['^build'],\n\t\t\t\toutputs: [],\n\t\t\t},\n\t\t\tlint: {\n\t\t\t\toutputs: [],\n\t\t\t},\n\t\t\tfmt: {\n\t\t\t\toutputs: [],\n\t\t\t},\n\t\t},\n\t};\n\n\t// Root .gitignore\n\tconst gitignore = `# Dependencies\nnode_modules/\n\n# Build output\ndist/\n.gkm/\n\n# Environment\n.env\n.env.local\n.env.*.local\n\n# IDE\n.idea/\n.vscode/\n*.swp\n*.swo\n\n# OS\n.DS_Store\nThumbs.db\n\n# Logs\n*.log\nnpm-debug.log*\nyarn-debug.log*\npnpm-debug.log*\n\n# Test coverage\ncoverage/\n\n# TypeScript cache\n*.tsbuildinfo\n\n# Turbo\n.turbo/\n`;\n\n\t// Root tsconfig.json - base config for all packages\n\tconst tsConfig = {\n\t\tcompilerOptions: {\n\t\t\ttarget: 'ES2022',\n\t\t\tmodule: 'NodeNext',\n\t\t\tmoduleResolution: 'NodeNext',\n\t\t\tlib: ['ES2022'],\n\t\t\tstrict: true,\n\t\t\tesModuleInterop: true,\n\t\t\tskipLibCheck: true,\n\t\t\tforceConsistentCasingInFileNames: true,\n\t\t\tresolveJsonModule: true,\n\t\t\tdeclaration: true,\n\t\t\tdeclarationMap: true,\n\t\t\tcomposite: true,\n\t\t},\n\t\texclude: ['node_modules', 'dist'],\n\t};\n\n\treturn [\n\t\t{\n\t\t\tpath: 'package.json',\n\t\t\tcontent: `${JSON.stringify(rootPackageJson, null, 2)}\\n`,\n\t\t},\n\t\t{\n\t\t\tpath: 'pnpm-workspace.yaml',\n\t\t\tcontent: pnpmWorkspace,\n\t\t},\n\t\t{\n\t\t\tpath: 'tsconfig.json',\n\t\t\tcontent: `${JSON.stringify(tsConfig, null, 2)}\\n`,\n\t\t},\n\t\t{\n\t\t\tpath: 'biome.json',\n\t\t\tcontent: `${JSON.stringify(biomeConfig, null, 2)}\\n`,\n\t\t},\n\t\t{\n\t\t\tpath: 'turbo.json',\n\t\t\tcontent: `${JSON.stringify(turboConfig, null, 2)}\\n`,\n\t\t},\n\t\t{\n\t\t\tpath: '.gitignore',\n\t\t\tcontent: gitignore,\n\t\t},\n\t];\n}\n","import type {\n\tGeneratedFile,\n\tTemplateConfig,\n\tTemplateOptions,\n} from './index.js';\n\nexport const apiTemplate: TemplateConfig = {\n\tname: 'api',\n\tdescription: 'Full API with auth, database, services',\n\n\tdependencies: {\n\t\t'@geekmidas/constructs': 'workspace:*',\n\t\t'@geekmidas/envkit': 'workspace:*',\n\t\t'@geekmidas/logger': 'workspace:*',\n\t\t'@geekmidas/services': 'workspace:*',\n\t\t'@geekmidas/errors': 'workspace:*',\n\t\t'@geekmidas/auth': 'workspace:*',\n\t\thono: '~4.8.2',\n\t\tpino: '~9.6.0',\n\t},\n\n\tdevDependencies: {\n\t\t'@biomejs/biome': '~1.9.4',\n\t\t'@geekmidas/cli': 'workspace:*',\n\t\t'@types/node': '~22.0.0',\n\t\ttsx: '~4.20.0',\n\t\tturbo: '~2.3.0',\n\t\ttypescript: '~5.8.2',\n\t\tvitest: '~4.0.0',\n\t},\n\n\tscripts: {\n\t\tdev: 'gkm dev',\n\t\tbuild: 'gkm build',\n\t\ttest: 'vitest',\n\t\t'test:once': 'vitest run',\n\t\ttypecheck: 'tsc --noEmit',\n\t\tlint: 'biome lint .',\n\t\tfmt: 'biome format . --write',\n\t\t'fmt:check': 'biome format .',\n\t},\n\n\tfiles: (options: TemplateOptions): GeneratedFile[] => {\n\t\tconst { loggerType, routesStructure } = options;\n\n\t\tconst loggerContent = `import { createLogger } from '@geekmidas/logger/${loggerType}';\n\nexport const logger = createLogger();\n`;\n\n\t\t// Get route path based on structure\n\t\tconst getRoutePath = (file: string) => {\n\t\t\tswitch (routesStructure) {\n\t\t\t\tcase 'centralized-endpoints':\n\t\t\t\t\treturn `src/endpoints/${file}`;\n\t\t\t\tcase 'centralized-routes':\n\t\t\t\t\treturn `src/routes/${file}`;\n\t\t\t\tcase 'domain-based': {\n\t\t\t\t\tconst parts = file.split('/');\n\t\t\t\t\tif (parts.length === 1) {\n\t\t\t\t\t\treturn `src/${file.replace('.ts', '')}/routes/index.ts`;\n\t\t\t\t\t}\n\t\t\t\t\treturn `src/${parts[0]}/routes/${parts.slice(1).join('/')}`;\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\n\t\tconst files: GeneratedFile[] = [\n\t\t\t// src/config/env.ts\n\t\t\t{\n\t\t\t\tpath: 'src/config/env.ts',\n\t\t\t\tcontent: `import { EnvironmentParser } from '@geekmidas/envkit';\n\nexport const envParser = new EnvironmentParser(process.env);\n\nexport const config = envParser\n .create((get) => ({\n port: get('PORT').string().transform(Number).default(3000),\n nodeEnv: get('NODE_ENV').string().default('development'),\n jwtSecret: get('JWT_SECRET').string().default('change-me-in-production'),${\n\t\t\toptions.database\n\t\t\t\t? `\n database: {\n url: get('DATABASE_URL').string().default('postgresql://localhost:5432/mydb'),\n },`\n\t\t\t\t: ''\n\t\t}\n }))\n .parse();\n`,\n\t\t\t},\n\n\t\t\t// src/config/logger.ts\n\t\t\t{\n\t\t\t\tpath: 'src/config/logger.ts',\n\t\t\t\tcontent: loggerContent,\n\t\t\t},\n\n\t\t\t// health endpoint\n\t\t\t{\n\t\t\t\tpath: getRoutePath('health.ts'),\n\t\t\t\tcontent: `import { e } from '@geekmidas/constructs/endpoints';\n\nexport default e\n .get('/health')\n .handle(async () => ({\n status: 'ok',\n timestamp: new Date().toISOString(),\n }));\n`,\n\t\t\t},\n\n\t\t\t// users endpoints\n\t\t\t{\n\t\t\t\tpath: getRoutePath('users/list.ts'),\n\t\t\t\tcontent: `import { e } from '@geekmidas/constructs/endpoints';\n\nexport default e\n .get('/users')\n .handle(async () => ({\n users: [\n { id: '1', name: 'Alice' },\n { id: '2', name: 'Bob' },\n ],\n }));\n`,\n\t\t\t},\n\t\t\t{\n\t\t\t\tpath: getRoutePath('users/get.ts'),\n\t\t\t\tcontent: `import { e } from '@geekmidas/constructs/endpoints';\nimport { z } from 'zod';\n\nexport default e\n .get('/users/:id')\n .params(z.object({ id: z.string() }))\n .handle(async ({ params }) => ({\n id: params.id,\n name: 'Alice',\n email: 'alice@example.com',\n }));\n`,\n\t\t\t},\n\t\t];\n\n\t\t// Add database service if enabled\n\t\tif (options.database) {\n\t\t\tfiles.push({\n\t\t\t\tpath: 'src/services/database.ts',\n\t\t\t\tcontent: `import type { Service } from '@geekmidas/services';\nimport { Kysely, PostgresDialect } from 'kysely';\nimport pg from 'pg';\n\n// Define your database schema\nexport interface Database {\n users: {\n id: string;\n name: string;\n email: string;\n created_at: Date;\n };\n}\n\nexport const databaseService = {\n serviceName: 'database' as const,\n async register(envParser) {\n const config = envParser\n .create((get) => ({\n url: get('DATABASE_URL').string(),\n }))\n .parse();\n\n return new Kysely<Database>({\n dialect: new PostgresDialect({\n pool: new pg.Pool({ connectionString: config.url }),\n }),\n });\n },\n} satisfies Service<'database', Kysely<Database>>;\n`,\n\t\t\t});\n\t\t}\n\n\t\t// Add Telescope config if enabled\n\t\tif (options.telescope) {\n\t\t\tfiles.push({\n\t\t\t\tpath: 'src/config/telescope.ts',\n\t\t\t\tcontent: `import { Telescope } from '@geekmidas/telescope';\nimport { InMemoryStorage } from '@geekmidas/telescope/storage/memory';\n\nexport const telescope = new Telescope({\n storage: new InMemoryStorage({ maxEntries: 100 }),\n enabled: process.env.NODE_ENV === 'development',\n});\n`,\n\t\t\t});\n\t\t}\n\n\t\t// Add Studio config if enabled (requires database)\n\t\tif (options.studio && options.database) {\n\t\t\tfiles.push({\n\t\t\t\tpath: 'src/config/studio.ts',\n\t\t\t\tcontent: `import { Direction, InMemoryMonitoringStorage, Studio } from '@geekmidas/studio';\nimport { Kysely, PostgresDialect } from 'kysely';\nimport pg from 'pg';\nimport type { Database } from '../services/database';\nimport { config } from './env';\n\n// Create a Kysely instance for Studio\nconst db = new Kysely<Database>({\n dialect: new PostgresDialect({\n pool: new pg.Pool({ connectionString: config.database.url }),\n }),\n});\n\nexport const studio = new Studio<Database>({\n monitoring: {\n storage: new InMemoryMonitoringStorage({ maxEntries: 100 }),\n },\n data: {\n db,\n cursor: { field: 'id', direction: Direction.Desc },\n },\n enabled: process.env.NODE_ENV === 'development',\n});\n`,\n\t\t\t});\n\t\t}\n\n\t\treturn files;\n\t},\n};\n","import type {\n\tGeneratedFile,\n\tTemplateConfig,\n\tTemplateOptions,\n} from './index.js';\n\nexport const minimalTemplate: TemplateConfig = {\n\tname: 'minimal',\n\tdescription: 'Basic health endpoint',\n\n\tdependencies: {\n\t\t'@geekmidas/constructs': 'workspace:*',\n\t\t'@geekmidas/envkit': 'workspace:*',\n\t\t'@geekmidas/logger': 'workspace:*',\n\t\thono: '~4.8.2',\n\t\tpino: '~9.6.0',\n\t},\n\n\tdevDependencies: {\n\t\t'@biomejs/biome': '~1.9.4',\n\t\t'@geekmidas/cli': 'workspace:*',\n\t\t'@types/node': '~22.0.0',\n\t\ttsx: '~4.20.0',\n\t\tturbo: '~2.3.0',\n\t\ttypescript: '~5.8.2',\n\t\tvitest: '~4.0.0',\n\t},\n\n\tscripts: {\n\t\tdev: 'gkm dev',\n\t\tbuild: 'gkm build',\n\t\ttest: 'vitest',\n\t\t'test:once': 'vitest run',\n\t\ttypecheck: 'tsc --noEmit',\n\t\tlint: 'biome lint .',\n\t\tfmt: 'biome format . --write',\n\t\t'fmt:check': 'biome format .',\n\t},\n\n\tfiles: (options: TemplateOptions): GeneratedFile[] => {\n\t\tconst { loggerType, routesStructure } = options;\n\n\t\tconst loggerContent = `import { createLogger } from '@geekmidas/logger/${loggerType}';\n\nexport const logger = createLogger();\n`;\n\n\t\t// Get route path based on structure\n\t\tconst getRoutePath = (file: string) => {\n\t\t\tswitch (routesStructure) {\n\t\t\t\tcase 'centralized-endpoints':\n\t\t\t\t\treturn `src/endpoints/${file}`;\n\t\t\t\tcase 'centralized-routes':\n\t\t\t\t\treturn `src/routes/${file}`;\n\t\t\t\tcase 'domain-based':\n\t\t\t\t\treturn `src/${file.replace('.ts', '')}/routes/index.ts`;\n\t\t\t}\n\t\t};\n\n\t\tconst files: GeneratedFile[] = [\n\t\t\t// src/config/env.ts\n\t\t\t{\n\t\t\t\tpath: 'src/config/env.ts',\n\t\t\t\tcontent: `import { EnvironmentParser } from '@geekmidas/envkit';\n\nexport const envParser = new EnvironmentParser(process.env);\n\nexport const config = envParser\n .create((get) => ({\n port: get('PORT').string().transform(Number).default(3000),\n nodeEnv: get('NODE_ENV').string().default('development'),\n }))\n .parse();\n`,\n\t\t\t},\n\n\t\t\t// src/config/logger.ts\n\t\t\t{\n\t\t\t\tpath: 'src/config/logger.ts',\n\t\t\t\tcontent: loggerContent,\n\t\t\t},\n\n\t\t\t// health endpoint\n\t\t\t{\n\t\t\t\tpath: getRoutePath('health.ts'),\n\t\t\t\tcontent: `import { e } from '@geekmidas/constructs/endpoints';\n\nexport default e\n .get('/health')\n .handle(async () => ({\n status: 'ok',\n timestamp: new Date().toISOString(),\n }));\n`,\n\t\t\t},\n\t\t];\n\n\t\t// Add database service if enabled\n\t\tif (options.database) {\n\t\t\t// Update env.ts to include database config\n\t\t\tfiles[0] = {\n\t\t\t\tpath: 'src/config/env.ts',\n\t\t\t\tcontent: `import { EnvironmentParser } from '@geekmidas/envkit';\n\nexport const envParser = new EnvironmentParser(process.env);\n\nexport const config = envParser\n .create((get) => ({\n port: get('PORT').string().transform(Number).default(3000),\n nodeEnv: get('NODE_ENV').string().default('development'),\n database: {\n url: get('DATABASE_URL').string().default('postgresql://localhost:5432/mydb'),\n },\n }))\n .parse();\n`,\n\t\t\t};\n\n\t\t\tfiles.push({\n\t\t\t\tpath: 'src/services/database.ts',\n\t\t\t\tcontent: `import type { Service } from '@geekmidas/services';\nimport { Kysely, PostgresDialect } from 'kysely';\nimport pg from 'pg';\n\n// Define your database schema\nexport interface Database {\n // Add your tables here\n}\n\nexport const databaseService = {\n serviceName: 'database' as const,\n async register(envParser) {\n const config = envParser\n .create((get) => ({\n url: get('DATABASE_URL').string(),\n }))\n .parse();\n\n return new Kysely<Database>({\n dialect: new PostgresDialect({\n pool: new pg.Pool({ connectionString: config.url }),\n }),\n });\n },\n} satisfies Service<'database', Kysely<Database>>;\n`,\n\t\t\t});\n\t\t}\n\n\t\t// Add Telescope config if enabled\n\t\tif (options.telescope) {\n\t\t\tfiles.push({\n\t\t\t\tpath: 'src/config/telescope.ts',\n\t\t\t\tcontent: `import { Telescope } from '@geekmidas/telescope';\nimport { InMemoryStorage } from '@geekmidas/telescope/storage/memory';\n\nexport const telescope = new Telescope({\n storage: new InMemoryStorage({ maxEntries: 100 }),\n enabled: process.env.NODE_ENV === 'development',\n});\n`,\n\t\t\t});\n\t\t}\n\n\t\t// Add Studio config if enabled (requires database)\n\t\tif (options.studio && options.database) {\n\t\t\tfiles.push({\n\t\t\t\tpath: 'src/config/studio.ts',\n\t\t\t\tcontent: `import { Direction, InMemoryMonitoringStorage, Studio } from '@geekmidas/studio';\nimport { Kysely, PostgresDialect } from 'kysely';\nimport pg from 'pg';\nimport type { Database } from '../services/database';\nimport { config } from './env';\n\n// Create a Kysely instance for Studio\nconst db = new Kysely<Database>({\n dialect: new PostgresDialect({\n pool: new pg.Pool({ connectionString: config.database.url }),\n }),\n});\n\nexport const studio = new Studio<Database>({\n monitoring: {\n storage: new InMemoryMonitoringStorage({ maxEntries: 100 }),\n },\n data: {\n db,\n cursor: { field: 'id', direction: Direction.Desc },\n },\n enabled: process.env.NODE_ENV === 'development',\n});\n`,\n\t\t\t});\n\t\t}\n\n\t\treturn files;\n\t},\n};\n","import type {\n\tGeneratedFile,\n\tTemplateConfig,\n\tTemplateOptions,\n} from './index.js';\n\nexport const serverlessTemplate: TemplateConfig = {\n\tname: 'serverless',\n\tdescription: 'AWS Lambda handlers',\n\n\tdependencies: {\n\t\t'@geekmidas/constructs': 'workspace:*',\n\t\t'@geekmidas/envkit': 'workspace:*',\n\t\t'@geekmidas/logger': 'workspace:*',\n\t\t'@geekmidas/cloud': 'workspace:*',\n\t\thono: '~4.8.2',\n\t\tpino: '~9.6.0',\n\t},\n\n\tdevDependencies: {\n\t\t'@biomejs/biome': '~1.9.4',\n\t\t'@geekmidas/cli': 'workspace:*',\n\t\t'@types/aws-lambda': '~8.10.92',\n\t\t'@types/node': '~22.0.0',\n\t\ttsx: '~4.20.0',\n\t\tturbo: '~2.3.0',\n\t\ttypescript: '~5.8.2',\n\t\tvitest: '~4.0.0',\n\t},\n\n\tscripts: {\n\t\tdev: 'gkm dev',\n\t\tbuild: 'gkm build --provider aws-apigatewayv2',\n\t\ttest: 'vitest',\n\t\t'test:once': 'vitest run',\n\t\ttypecheck: 'tsc --noEmit',\n\t\tlint: 'biome lint .',\n\t\tfmt: 'biome format . --write',\n\t\t'fmt:check': 'biome format .',\n\t},\n\n\tfiles: (options: TemplateOptions): GeneratedFile[] => {\n\t\tconst { loggerType, routesStructure } = options;\n\n\t\tconst loggerContent = `import { createLogger } from '@geekmidas/logger/${loggerType}';\n\nexport const logger = createLogger();\n`;\n\n\t\t// Get route path based on structure\n\t\tconst getRoutePath = (file: string) => {\n\t\t\tswitch (routesStructure) {\n\t\t\t\tcase 'centralized-endpoints':\n\t\t\t\t\treturn `src/endpoints/${file}`;\n\t\t\t\tcase 'centralized-routes':\n\t\t\t\t\treturn `src/routes/${file}`;\n\t\t\t\tcase 'domain-based':\n\t\t\t\t\treturn `src/${file.replace('.ts', '')}/routes/index.ts`;\n\t\t\t}\n\t\t};\n\n\t\tconst files: GeneratedFile[] = [\n\t\t\t// src/config/env.ts\n\t\t\t{\n\t\t\t\tpath: 'src/config/env.ts',\n\t\t\t\tcontent: `import { EnvironmentParser } from '@geekmidas/envkit';\n\nexport const envParser = new EnvironmentParser(process.env);\n\nexport const config = envParser\n .create((get) => ({\n stage: get('STAGE').string().default('dev'),\n region: get('AWS_REGION').string().default('us-east-1'),${\n\t\t\toptions.database\n\t\t\t\t? `\n database: {\n url: get('DATABASE_URL').string(),\n },`\n\t\t\t\t: ''\n\t\t}\n }))\n .parse();\n`,\n\t\t\t},\n\n\t\t\t// src/config/logger.ts\n\t\t\t{\n\t\t\t\tpath: 'src/config/logger.ts',\n\t\t\t\tcontent: loggerContent,\n\t\t\t},\n\n\t\t\t// health endpoint\n\t\t\t{\n\t\t\t\tpath: getRoutePath('health.ts'),\n\t\t\t\tcontent: `import { e } from '@geekmidas/constructs/endpoints';\n\nexport default e\n .get('/health')\n .handle(async () => ({\n status: 'ok',\n timestamp: new Date().toISOString(),\n region: process.env.AWS_REGION || 'local',\n }));\n`,\n\t\t\t},\n\n\t\t\t// src/functions/hello.ts\n\t\t\t{\n\t\t\t\tpath: 'src/functions/hello.ts',\n\t\t\t\tcontent: `import { f } from '@geekmidas/constructs/functions';\nimport { z } from 'zod';\n\nexport default f\n .input(z.object({ name: z.string() }))\n .output(z.object({ message: z.string() }))\n .handle(async ({ input }) => ({\n message: \\`Hello, \\${input.name}!\\`,\n }));\n`,\n\t\t\t},\n\t\t];\n\n\t\t// Add Telescope config if enabled\n\t\tif (options.telescope) {\n\t\t\tfiles.push({\n\t\t\t\tpath: 'src/config/telescope.ts',\n\t\t\t\tcontent: `import { Telescope } from '@geekmidas/telescope';\nimport { InMemoryStorage } from '@geekmidas/telescope/storage/memory';\n\n// Note: For production Lambda, consider using a persistent storage\nexport const telescope = new Telescope({\n storage: new InMemoryStorage({ maxEntries: 50 }),\n enabled: process.env.STAGE === 'dev',\n});\n`,\n\t\t\t});\n\t\t}\n\n\t\treturn files;\n\t},\n};\n","import type {\n\tGeneratedFile,\n\tTemplateConfig,\n\tTemplateOptions,\n} from './index.js';\n\nexport const workerTemplate: TemplateConfig = {\n\tname: 'worker',\n\tdescription: 'Background job processing',\n\n\tdependencies: {\n\t\t'@geekmidas/constructs': 'workspace:*',\n\t\t'@geekmidas/envkit': 'workspace:*',\n\t\t'@geekmidas/logger': 'workspace:*',\n\t\t'@geekmidas/events': 'workspace:*',\n\t\thono: '~4.8.2',\n\t\tpino: '~9.6.0',\n\t},\n\n\tdevDependencies: {\n\t\t'@biomejs/biome': '~1.9.4',\n\t\t'@geekmidas/cli': 'workspace:*',\n\t\t'@types/node': '~22.0.0',\n\t\ttsx: '~4.20.0',\n\t\tturbo: '~2.3.0',\n\t\ttypescript: '~5.8.2',\n\t\tvitest: '~4.0.0',\n\t},\n\n\tscripts: {\n\t\tdev: 'gkm dev',\n\t\tbuild: 'gkm build',\n\t\ttest: 'vitest',\n\t\t'test:once': 'vitest run',\n\t\ttypecheck: 'tsc --noEmit',\n\t\tlint: 'biome lint .',\n\t\tfmt: 'biome format . --write',\n\t\t'fmt:check': 'biome format .',\n\t},\n\n\tfiles: (options: TemplateOptions): GeneratedFile[] => {\n\t\tconst { loggerType, routesStructure } = options;\n\n\t\tconst loggerContent = `import { createLogger } from '@geekmidas/logger/${loggerType}';\n\nexport const logger = createLogger();\n`;\n\n\t\t// Get route path based on structure\n\t\tconst getRoutePath = (file: string) => {\n\t\t\tswitch (routesStructure) {\n\t\t\t\tcase 'centralized-endpoints':\n\t\t\t\t\treturn `src/endpoints/${file}`;\n\t\t\t\tcase 'centralized-routes':\n\t\t\t\t\treturn `src/routes/${file}`;\n\t\t\t\tcase 'domain-based':\n\t\t\t\t\treturn `src/${file.replace('.ts', '')}/routes/index.ts`;\n\t\t\t}\n\t\t};\n\n\t\tconst files: GeneratedFile[] = [\n\t\t\t// src/config/env.ts\n\t\t\t{\n\t\t\t\tpath: 'src/config/env.ts',\n\t\t\t\tcontent: `import { EnvironmentParser } from '@geekmidas/envkit';\n\nexport const envParser = new EnvironmentParser(process.env);\n\nexport const config = envParser\n .create((get) => ({\n port: get('PORT').string().transform(Number).default(3000),\n nodeEnv: get('NODE_ENV').string().default('development'),\n rabbitmq: {\n url: get('RABBITMQ_URL').string().default('amqp://localhost:5672'),\n },${\n\t\t\toptions.database\n\t\t\t\t? `\n database: {\n url: get('DATABASE_URL').string().default('postgresql://localhost:5432/mydb'),\n },`\n\t\t\t\t: ''\n\t\t}\n }))\n .parse();\n`,\n\t\t\t},\n\n\t\t\t// src/config/logger.ts\n\t\t\t{\n\t\t\t\tpath: 'src/config/logger.ts',\n\t\t\t\tcontent: loggerContent,\n\t\t\t},\n\n\t\t\t// health endpoint\n\t\t\t{\n\t\t\t\tpath: getRoutePath('health.ts'),\n\t\t\t\tcontent: `import { e } from '@geekmidas/constructs/endpoints';\n\nexport default e\n .get('/health')\n .handle(async () => ({\n status: 'ok',\n timestamp: new Date().toISOString(),\n }));\n`,\n\t\t\t},\n\n\t\t\t// src/events/types.ts\n\t\t\t{\n\t\t\t\tpath: 'src/events/types.ts',\n\t\t\t\tcontent: `import type { PublishableMessage } from '@geekmidas/events';\n\n// Define your event types here\nexport type AppEvents =\n | PublishableMessage<'user.created', { userId: string; email: string }>\n | PublishableMessage<'user.updated', { userId: string; changes: Record<string, unknown> }>\n | PublishableMessage<'order.placed', { orderId: string; userId: string; total: number }>;\n`,\n\t\t\t},\n\n\t\t\t// src/subscribers/user-events.ts\n\t\t\t{\n\t\t\t\tpath: 'src/subscribers/user-events.ts',\n\t\t\t\tcontent: `import { s } from '@geekmidas/constructs/subscribers';\nimport type { AppEvents } from '../events/types.js';\n\nexport default s<AppEvents>()\n .events(['user.created', 'user.updated'])\n .handle(async ({ event, logger }) => {\n logger.info({ type: event.type, payload: event.payload }, 'Processing user event');\n\n switch (event.type) {\n case 'user.created':\n // Handle user creation\n logger.info({ userId: event.payload.userId }, 'New user created');\n break;\n case 'user.updated':\n // Handle user update\n logger.info({ userId: event.payload.userId }, 'User updated');\n break;\n }\n });\n`,\n\t\t\t},\n\n\t\t\t// src/crons/cleanup.ts\n\t\t\t{\n\t\t\t\tpath: 'src/crons/cleanup.ts',\n\t\t\t\tcontent: `import { cron } from '@geekmidas/constructs/crons';\n\n// Run every day at midnight\nexport default cron('0 0 * * *')\n .handle(async ({ logger }) => {\n logger.info('Running cleanup job');\n\n // Add your cleanup logic here\n // e.g., delete old sessions, clean up temp files, etc.\n\n logger.info('Cleanup job completed');\n });\n`,\n\t\t\t},\n\t\t];\n\n\t\t// Add Telescope config if enabled\n\t\tif (options.telescope) {\n\t\t\tfiles.push({\n\t\t\t\tpath: 'src/config/telescope.ts',\n\t\t\t\tcontent: `import { Telescope } from '@geekmidas/telescope';\nimport { InMemoryStorage } from '@geekmidas/telescope/storage/memory';\n\nexport const telescope = new Telescope({\n storage: new InMemoryStorage({ maxEntries: 100 }),\n enabled: process.env.NODE_ENV === 'development',\n});\n`,\n\t\t\t});\n\t\t}\n\n\t\treturn files;\n\t},\n};\n","import { apiTemplate } from './api.js';\nimport { minimalTemplate } from './minimal.js';\nimport { serverlessTemplate } from './serverless.js';\nimport { workerTemplate } from './worker.js';\n\n/**\n * OpenAPI output path (fixed, not configurable)\n */\nexport const OPENAPI_OUTPUT_PATH = './.gkm/openapi.ts';\n\n/**\n * Logger implementation type\n */\nexport type LoggerType = 'pino' | 'console';\n\n/**\n * Routes structure pattern\n */\nexport type RoutesStructure =\n\t| 'centralized-endpoints'\n\t| 'centralized-routes'\n\t| 'domain-based';\n\n/**\n * Options collected from user prompts\n */\nexport interface TemplateOptions {\n\tname: string;\n\ttemplate: TemplateName;\n\ttelescope: boolean;\n\tdatabase: boolean;\n\tstudio: boolean;\n\tloggerType: LoggerType;\n\troutesStructure: RoutesStructure;\n\tmonorepo: boolean;\n\t/** Path for the API app in monorepo (e.g., 'apps/api') */\n\tapiPath: string;\n}\n\n/**\n * A file to be generated\n */\nexport interface GeneratedFile {\n\tpath: string;\n\tcontent: string;\n}\n\n/**\n * Template configuration\n */\nexport interface TemplateConfig {\n\tname: TemplateName;\n\tdescription: string;\n\tdependencies: Record<string, string>;\n\tdevDependencies: Record<string, string>;\n\tscripts: Record<string, string>;\n\tfiles: (options: TemplateOptions) => GeneratedFile[];\n}\n\nexport type TemplateName = 'minimal' | 'api' | 'serverless' | 'worker';\n\n/**\n * All available templates\n */\nexport const templates: Record<TemplateName, TemplateConfig> = {\n\tminimal: minimalTemplate,\n\tapi: apiTemplate,\n\tserverless: serverlessTemplate,\n\tworker: workerTemplate,\n};\n\n/**\n * Template choices for prompts\n */\nexport const templateChoices = [\n\t{\n\t\ttitle: 'Minimal',\n\t\tvalue: 'minimal' as TemplateName,\n\t\tdescription: 'Basic health endpoint',\n\t},\n\t{\n\t\ttitle: 'API',\n\t\tvalue: 'api' as TemplateName,\n\t\tdescription: 'Full API with auth, database, services',\n\t},\n\t{\n\t\ttitle: 'Serverless',\n\t\tvalue: 'serverless' as TemplateName,\n\t\tdescription: 'AWS Lambda handlers',\n\t},\n\t{\n\t\ttitle: 'Worker',\n\t\tvalue: 'worker' as TemplateName,\n\t\tdescription: 'Background job processing',\n\t},\n];\n\n/**\n * Logger type choices for prompts\n */\nexport const loggerTypeChoices = [\n\t{\n\t\ttitle: 'Pino',\n\t\tvalue: 'pino' as LoggerType,\n\t\tdescription: 'Fast JSON logger for production (recommended)',\n\t},\n\t{\n\t\ttitle: 'Console',\n\t\tvalue: 'console' as LoggerType,\n\t\tdescription: 'Simple console logger for development',\n\t},\n];\n\n/**\n * Routes structure choices for prompts\n */\nexport const routesStructureChoices = [\n\t{\n\t\ttitle: 'Centralized (endpoints)',\n\t\tvalue: 'centralized-endpoints' as RoutesStructure,\n\t\tdescription: 'src/endpoints/**/*.ts',\n\t},\n\t{\n\t\ttitle: 'Centralized (routes)',\n\t\tvalue: 'centralized-routes' as RoutesStructure,\n\t\tdescription: 'src/routes/**/*.ts',\n\t},\n\t{\n\t\ttitle: 'Domain-based',\n\t\tvalue: 'domain-based' as RoutesStructure,\n\t\tdescription: 'src/**/routes/*.ts (e.g., src/users/routes/list.ts)',\n\t},\n];\n\n/**\n * Get a template by name\n */\nexport function getTemplate(name: TemplateName): TemplateConfig {\n\tconst template = templates[name];\n\tif (!template) {\n\t\tthrow new Error(`Unknown template: ${name}`);\n\t}\n\treturn template;\n}\n","import {\n\ttype GeneratedFile,\n\tOPENAPI_OUTPUT_PATH,\n\ttype TemplateConfig,\n\ttype TemplateOptions,\n} from '../templates/index.js';\n\n/**\n * Generate package.json with dependencies based on template and options\n */\nexport function generatePackageJson(\n\toptions: TemplateOptions,\n\ttemplate: TemplateConfig,\n): GeneratedFile[] {\n\tconst { name, telescope, database, studio, monorepo } = options;\n\n\t// Start with template dependencies\n\tconst dependencies = { ...template.dependencies };\n\tconst devDependencies = { ...template.devDependencies };\n\tconst scripts = { ...template.scripts };\n\n\t// Add optional dependencies based on user choices\n\tif (telescope) {\n\t\tdependencies['@geekmidas/telescope'] = 'workspace:*';\n\t}\n\n\tif (studio) {\n\t\tdependencies['@geekmidas/studio'] = 'workspace:*';\n\t}\n\n\tif (database) {\n\t\tdependencies['@geekmidas/db'] = 'workspace:*';\n\t\tdependencies.kysely = '~0.28.2';\n\t\tdependencies.pg = '~8.16.0';\n\t\tdevDependencies['@types/pg'] = '~8.15.0';\n\t}\n\n\t// Add zod for schema validation (commonly used)\n\tdependencies.zod = '~4.1.0';\n\n\t// For monorepo apps, remove biome/turbo (they're at root) and lint/fmt scripts\n\tif (monorepo) {\n\t\tdelete devDependencies['@biomejs/biome'];\n\t\tdelete devDependencies.turbo;\n\t\tdelete scripts.lint;\n\t\tdelete scripts.fmt;\n\t\tdelete scripts['fmt:check'];\n\n\t\t// Add models package as dependency\n\t\tdependencies[`@${name}/models`] = 'workspace:*';\n\n\t\t// Remove zod from api package (it's in models)\n\t\tdelete dependencies.zod;\n\t}\n\n\t// Sort dependencies alphabetically\n\tconst sortObject = (obj: Record<string, string>) =>\n\t\tObject.fromEntries(\n\t\t\tObject.entries(obj).sort(([a], [b]) => a.localeCompare(b)),\n\t\t);\n\n\t// For monorepo, derive package name from apiPath (e.g., apps/api -> @name/api)\n\tlet packageName = name;\n\tif (monorepo && options.apiPath) {\n\t\tconst pathParts = options.apiPath.split('/');\n\t\tconst appName = pathParts[pathParts.length - 1] || 'api';\n\t\tpackageName = `@${name}/${appName}`;\n\t}\n\n\tconst packageJson = {\n\t\tname: packageName,\n\t\tversion: '0.0.1',\n\t\tprivate: true,\n\t\ttype: 'module',\n\t\texports: {\n\t\t\t'./client': {\n\t\t\t\ttypes: OPENAPI_OUTPUT_PATH,\n\t\t\t\timport: OPENAPI_OUTPUT_PATH,\n\t\t\t},\n\t\t},\n\t\tscripts,\n\t\tdependencies: sortObject(dependencies),\n\t\tdevDependencies: sortObject(devDependencies),\n\t};\n\n\treturn [\n\t\t{\n\t\t\tpath: 'package.json',\n\t\t\tcontent: `${JSON.stringify(packageJson, null, 2)}\\n`,\n\t\t},\n\t];\n}\n","import type {\n\tGeneratedFile,\n\tTemplateConfig,\n\tTemplateOptions,\n} from '../templates/index.js';\n\n/**\n * Generate source files from template\n */\nexport function generateSourceFiles(\n\toptions: TemplateOptions,\n\ttemplate: TemplateConfig,\n): GeneratedFile[] {\n\treturn template.files(options);\n}\n","import { existsSync } from 'node:fs';\nimport { join } from 'node:path';\n\nexport type PackageManager = 'pnpm' | 'npm' | 'yarn' | 'bun';\n\n/**\n * Detect the package manager being used based on lockfiles or npm_config_user_agent\n */\nexport function detectPackageManager(\n\tcwd: string = process.cwd(),\n): PackageManager {\n\t// Check for lockfiles in cwd\n\tif (existsSync(join(cwd, 'pnpm-lock.yaml'))) return 'pnpm';\n\tif (existsSync(join(cwd, 'yarn.lock'))) return 'yarn';\n\tif (existsSync(join(cwd, 'bun.lockb'))) return 'bun';\n\tif (existsSync(join(cwd, 'package-lock.json'))) return 'npm';\n\n\t// Check npm_config_user_agent (set when running via npx/pnpm dlx/etc)\n\tconst userAgent = process.env.npm_config_user_agent || '';\n\tif (userAgent.includes('pnpm')) return 'pnpm';\n\tif (userAgent.includes('yarn')) return 'yarn';\n\tif (userAgent.includes('bun')) return 'bun';\n\n\treturn 'npm';\n}\n\n/**\n * Validate project name for npm package naming conventions\n */\nexport function validateProjectName(name: string): boolean | string {\n\tif (!name) {\n\t\treturn 'Project name is required';\n\t}\n\n\t// Check for valid npm package name characters\n\tif (!/^[a-z0-9-_@/.]+$/i.test(name)) {\n\t\treturn 'Project name can only contain letters, numbers, hyphens, underscores, @, /, and .';\n\t}\n\n\t// Check for reserved names\n\tconst reserved = ['node_modules', '.git', 'package.json', 'src'];\n\tif (reserved.includes(name.toLowerCase())) {\n\t\treturn `\"${name}\" is a reserved name`;\n\t}\n\n\treturn true;\n}\n\n/**\n * Check if a directory already exists at the target path\n */\nexport function checkDirectoryExists(\n\tname: string,\n\tcwd: string = process.cwd(),\n): boolean | string {\n\tconst targetPath = join(cwd, name);\n\tif (existsSync(targetPath)) {\n\t\treturn `Directory \"${name}\" already exists`;\n\t}\n\treturn true;\n}\n\n/**\n * Get the install command for a package manager\n */\nexport function getInstallCommand(pkgManager: PackageManager): string {\n\tswitch (pkgManager) {\n\t\tcase 'pnpm':\n\t\t\treturn 'pnpm install';\n\t\tcase 'yarn':\n\t\t\treturn 'yarn';\n\t\tcase 'bun':\n\t\t\treturn 'bun install';\n\t\tdefault:\n\t\t\treturn 'npm install';\n\t}\n}\n\n/**\n * Get the dev command for a package manager\n */\nexport function getRunCommand(\n\tpkgManager: PackageManager,\n\tscript: string,\n): string {\n\tswitch (pkgManager) {\n\t\tcase 'pnpm':\n\t\t\treturn `pnpm ${script}`;\n\t\tcase 'yarn':\n\t\t\treturn `yarn ${script}`;\n\t\tcase 'bun':\n\t\t\treturn `bun run ${script}`;\n\t\tdefault:\n\t\t\treturn `npm run ${script}`;\n\t}\n}\n","import { execSync } from 'node:child_process';\nimport { mkdir, writeFile } from 'node:fs/promises';\nimport { dirname, join } from 'node:path';\nimport prompts from 'prompts';\nimport { generateConfigFiles } from './generators/config.js';\nimport { generateDockerFiles } from './generators/docker.js';\nimport { generateEnvFiles } from './generators/env.js';\nimport { generateModelsPackage } from './generators/models.js';\nimport { generateMonorepoFiles } from './generators/monorepo.js';\nimport { generatePackageJson } from './generators/package.js';\nimport { generateSourceFiles } from './generators/source.js';\nimport {\n\tgetTemplate,\n\tloggerTypeChoices,\n\troutesStructureChoices,\n\ttype TemplateName,\n\ttype TemplateOptions,\n\ttemplateChoices,\n} from './templates/index.js';\nimport {\n\tcheckDirectoryExists,\n\tdetectPackageManager,\n\tgetInstallCommand,\n\tgetRunCommand,\n\tvalidateProjectName,\n} from './utils.js';\n\nexport interface InitOptions {\n\ttemplate?: TemplateName;\n\tskipInstall?: boolean;\n\tyes?: boolean;\n\tmonorepo?: boolean;\n\tapiPath?: string;\n}\n\n/**\n * Main init command - scaffolds a new project\n */\nexport async function initCommand(\n\tprojectName?: string,\n\toptions: InitOptions = {},\n): Promise<void> {\n\tconst cwd = process.cwd();\n\tconst pkgManager = detectPackageManager(cwd);\n\n\t// Handle Ctrl+C gracefully\n\tprompts.override({});\n\tconst onCancel = () => {\n\t\tprocess.exit(0);\n\t};\n\n\t// Gather answers via prompts\n\tconst answers = await prompts(\n\t\t[\n\t\t\t{\n\t\t\t\ttype: projectName ? null : 'text',\n\t\t\t\tname: 'name',\n\t\t\t\tmessage: 'Project name:',\n\t\t\t\tinitial: 'my-api',\n\t\t\t\tvalidate: (value: string) => {\n\t\t\t\t\tconst nameValid = validateProjectName(value);\n\t\t\t\t\tif (nameValid !== true) return nameValid;\n\t\t\t\t\tconst dirValid = checkDirectoryExists(value, cwd);\n\t\t\t\t\tif (dirValid !== true) return dirValid;\n\t\t\t\t\treturn true;\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\ttype: options.template || options.yes ? null : 'select',\n\t\t\t\tname: 'template',\n\t\t\t\tmessage: 'Template:',\n\t\t\t\tchoices: templateChoices,\n\t\t\t\tinitial: 0,\n\t\t\t},\n\t\t\t{\n\t\t\t\ttype: options.yes ? null : 'confirm',\n\t\t\t\tname: 'telescope',\n\t\t\t\tmessage: 'Include Telescope (debugging dashboard)?',\n\t\t\t\tinitial: true,\n\t\t\t},\n\t\t\t{\n\t\t\t\ttype: options.yes ? null : 'confirm',\n\t\t\t\tname: 'database',\n\t\t\t\tmessage: 'Include database support (Kysely)?',\n\t\t\t\tinitial: true,\n\t\t\t},\n\t\t\t{\n\t\t\t\ttype: (prev) => (options.yes ? null : prev ? 'confirm' : null),\n\t\t\t\tname: 'studio',\n\t\t\t\tmessage: 'Include Studio (database browser)?',\n\t\t\t\tinitial: true,\n\t\t\t},\n\t\t\t{\n\t\t\t\ttype: options.yes ? null : 'select',\n\t\t\t\tname: 'loggerType',\n\t\t\t\tmessage: 'Logger:',\n\t\t\t\tchoices: loggerTypeChoices,\n\t\t\t\tinitial: 0,\n\t\t\t},\n\t\t\t{\n\t\t\t\ttype: options.yes ? null : 'select',\n\t\t\t\tname: 'routesStructure',\n\t\t\t\tmessage: 'Routes structure:',\n\t\t\t\tchoices: routesStructureChoices,\n\t\t\t\tinitial: 0,\n\t\t\t},\n\t\t\t{\n\t\t\t\ttype: options.yes || options.monorepo !== undefined ? null : 'confirm',\n\t\t\t\tname: 'monorepo',\n\t\t\t\tmessage: 'Setup as monorepo?',\n\t\t\t\tinitial: false,\n\t\t\t},\n\t\t\t{\n\t\t\t\ttype: (prev) =>\n\t\t\t\t\t(prev === true || options.monorepo) && !options.apiPath\n\t\t\t\t\t\t? 'text'\n\t\t\t\t\t\t: null,\n\t\t\t\tname: 'apiPath',\n\t\t\t\tmessage: 'API app path:',\n\t\t\t\tinitial: 'apps/api',\n\t\t\t},\n\t\t],\n\t\t{ onCancel },\n\t);\n\n\t// Build final options\n\tconst name = projectName || answers.name;\n\tif (!name) {\n\t\tprocess.exit(1);\n\t}\n\n\t// Validate name if provided via argument\n\tif (projectName) {\n\t\tconst nameValid = validateProjectName(projectName);\n\t\tif (nameValid !== true) {\n\t\t\tprocess.exit(1);\n\t\t}\n\t\tconst dirValid = checkDirectoryExists(projectName, cwd);\n\t\tif (dirValid !== true) {\n\t\t\tprocess.exit(1);\n\t\t}\n\t}\n\n\tconst monorepo =\n\t\toptions.monorepo ?? (options.yes ? false : (answers.monorepo ?? false));\n\tconst database = options.yes ? true : (answers.database ?? true);\n\tconst templateOptions: TemplateOptions = {\n\t\tname,\n\t\ttemplate: options.template || answers.template || 'minimal',\n\t\ttelescope: options.yes ? true : (answers.telescope ?? true),\n\t\tdatabase,\n\t\tstudio: database && (options.yes ? true : (answers.studio ?? true)),\n\t\tloggerType: options.yes ? 'pino' : (answers.loggerType ?? 'pino'),\n\t\troutesStructure: options.yes\n\t\t\t? 'centralized-endpoints'\n\t\t\t: (answers.routesStructure ?? 'centralized-endpoints'),\n\t\tmonorepo,\n\t\tapiPath: monorepo ? (options.apiPath ?? answers.apiPath ?? 'apps/api') : '',\n\t};\n\n\tconst targetDir = join(cwd, name);\n\tconst template = getTemplate(templateOptions.template);\n\n\tconst isMonorepo = templateOptions.monorepo;\n\tconst apiPath = templateOptions.apiPath;\n\n\t// Create project directory\n\tawait mkdir(targetDir, { recursive: true });\n\n\t// For monorepo, app files go in the specified apiPath (e.g., apps/api)\n\tconst appDir = isMonorepo ? join(targetDir, apiPath) : targetDir;\n\tif (isMonorepo) {\n\t\tawait mkdir(appDir, { recursive: true });\n\t}\n\n\t// Collect app files\n\tconst appFiles = [\n\t\t...generatePackageJson(templateOptions, template),\n\t\t...generateConfigFiles(templateOptions, template),\n\t\t...generateEnvFiles(templateOptions, template),\n\t\t...generateSourceFiles(templateOptions, template),\n\t\t...generateDockerFiles(templateOptions, template),\n\t];\n\n\t// Collect root monorepo files (includes packages/models)\n\tconst rootFiles = [\n\t\t...generateMonorepoFiles(templateOptions, template),\n\t\t...generateModelsPackage(templateOptions),\n\t];\n\n\t// Write root files (for monorepo)\n\tfor (const { path, content } of rootFiles) {\n\t\tconst fullPath = join(targetDir, path);\n\t\tawait mkdir(dirname(fullPath), { recursive: true });\n\t\tawait writeFile(fullPath, content);\n\t}\n\n\t// Write app files\n\tfor (const { path, content } of appFiles) {\n\t\tconst fullPath = join(appDir, path);\n\t\tconst _displayPath = isMonorepo ? `${apiPath}/${path}` : path;\n\t\tawait mkdir(dirname(fullPath), { recursive: true });\n\t\tawait writeFile(fullPath, content);\n\t}\n\n\t// Install dependencies\n\tif (!options.skipInstall) {\n\t\ttry {\n\t\t\texecSync(getInstallCommand(pkgManager), {\n\t\t\t\tcwd: targetDir,\n\t\t\t\tstdio: 'inherit',\n\t\t\t});\n\t\t} catch {}\n\n\t\t// Format generated files with biome\n\t\ttry {\n\t\t\texecSync('npx @biomejs/biome format --write --unsafe .', {\n\t\t\t\tcwd: targetDir,\n\t\t\t\tstdio: 'inherit',\n\t\t\t});\n\t\t} catch {\n\t\t\t// Silently ignore format errors\n\t\t}\n\t}\n\n\t// Print next steps\n\tconst _devCommand = getRunCommand(pkgManager, 'dev');\n}\n","import { randomBytes } from 'node:crypto';\nimport type { ComposeServiceName } from '../types';\nimport type { ServiceCredentials, StageSecrets } from './types';\n\n/**\n * Generate a secure random password using URL-safe base64 characters.\n * @param length Password length (default: 32)\n */\nexport function generateSecurePassword(length = 32): string {\n\treturn randomBytes(Math.ceil((length * 3) / 4))\n\t\t.toString('base64url')\n\t\t.slice(0, length);\n}\n\n/** Default service configurations */\nconst SERVICE_DEFAULTS: Record<\n\tComposeServiceName,\n\tOmit<ServiceCredentials, 'password'>\n> = {\n\tpostgres: {\n\t\thost: 'postgres',\n\t\tport: 5432,\n\t\tusername: 'app',\n\t\tdatabase: 'app',\n\t},\n\tredis: {\n\t\thost: 'redis',\n\t\tport: 6379,\n\t\tusername: 'default',\n\t},\n\trabbitmq: {\n\t\thost: 'rabbitmq',\n\t\tport: 5672,\n\t\tusername: 'app',\n\t\tvhost: '/',\n\t},\n};\n\n/**\n * Generate credentials for a specific service.\n */\nexport function generateServiceCredentials(\n\tservice: ComposeServiceName,\n): ServiceCredentials {\n\tconst defaults = SERVICE_DEFAULTS[service];\n\treturn {\n\t\t...defaults,\n\t\tpassword: generateSecurePassword(),\n\t};\n}\n\n/**\n * Generate credentials for multiple services.\n */\nexport function generateServicesCredentials(\n\tservices: ComposeServiceName[],\n): StageSecrets['services'] {\n\tconst result: StageSecrets['services'] = {};\n\n\tfor (const service of services) {\n\t\tresult[service] = generateServiceCredentials(service);\n\t}\n\n\treturn result;\n}\n\n/**\n * Generate connection URL for PostgreSQL.\n */\nexport function generatePostgresUrl(creds: ServiceCredentials): string {\n\tconst { username, password, host, port, database } = creds;\n\treturn `postgresql://${username}:${encodeURIComponent(password)}@${host}:${port}/${database}`;\n}\n\n/**\n * Generate connection URL for Redis.\n */\nexport function generateRedisUrl(creds: ServiceCredentials): string {\n\tconst { password, host, port } = creds;\n\treturn `redis://:${encodeURIComponent(password)}@${host}:${port}`;\n}\n\n/**\n * Generate connection URL for RabbitMQ.\n */\nexport function generateRabbitmqUrl(creds: ServiceCredentials): string {\n\tconst { username, password, host, port, vhost } = creds;\n\tconst encodedVhost = encodeURIComponent(vhost ?? '/');\n\treturn `amqp://${username}:${encodeURIComponent(password)}@${host}:${port}/${encodedVhost}`;\n}\n\n/**\n * Generate connection URLs from service credentials.\n */\nexport function generateConnectionUrls(\n\tservices: StageSecrets['services'],\n): StageSecrets['urls'] {\n\tconst urls: StageSecrets['urls'] = {};\n\n\tif (services.postgres) {\n\t\turls.DATABASE_URL = generatePostgresUrl(services.postgres);\n\t}\n\n\tif (services.redis) {\n\t\turls.REDIS_URL = generateRedisUrl(services.redis);\n\t}\n\n\tif (services.rabbitmq) {\n\t\turls.RABBITMQ_URL = generateRabbitmqUrl(services.rabbitmq);\n\t}\n\n\treturn urls;\n}\n\n/**\n * Create a new StageSecrets object with generated credentials.\n */\nexport function createStageSecrets(\n\tstage: string,\n\tservices: ComposeServiceName[],\n): StageSecrets {\n\tconst now = new Date().toISOString();\n\tconst serviceCredentials = generateServicesCredentials(services);\n\tconst urls = generateConnectionUrls(serviceCredentials);\n\n\treturn {\n\t\tstage,\n\t\tcreatedAt: now,\n\t\tupdatedAt: now,\n\t\tservices: serviceCredentials,\n\t\turls,\n\t\tcustom: {},\n\t};\n}\n\n/**\n * Rotate password for a specific service.\n */\nexport function rotateServicePassword(\n\tsecrets: StageSecrets,\n\tservice: ComposeServiceName,\n): StageSecrets {\n\tconst currentCreds = secrets.services[service];\n\tif (!currentCreds) {\n\t\tthrow new Error(`Service \"${service}\" not configured in secrets`);\n\t}\n\n\tconst newCreds: ServiceCredentials = {\n\t\t...currentCreds,\n\t\tpassword: generateSecurePassword(),\n\t};\n\n\tconst newServices = {\n\t\t...secrets.services,\n\t\t[service]: newCreds,\n\t};\n\n\treturn {\n\t\t...secrets,\n\t\tupdatedAt: new Date().toISOString(),\n\t\tservices: newServices,\n\t\turls: generateConnectionUrls(newServices),\n\t};\n}\n","import { existsSync } from 'node:fs';\nimport { readFile } from 'node:fs/promises';\nimport { loadConfig } from '../config';\nimport type { ComposeServiceName, ComposeServicesConfig } from '../types';\nimport { createStageSecrets, rotateServicePassword } from './generator';\nimport {\n\tmaskPassword,\n\treadStageSecrets,\n\tsecretsExist,\n\tsetCustomSecret,\n\twriteStageSecrets,\n} from './storage';\n\nconst logger = console;\n\nexport interface SecretsInitOptions {\n\tstage: string;\n\tforce?: boolean;\n}\n\nexport interface SecretsSetOptions {\n\tstage: string;\n}\n\nexport interface SecretsShowOptions {\n\tstage: string;\n\treveal?: boolean;\n}\n\nexport interface SecretsRotateOptions {\n\tstage: string;\n\tservice?: ComposeServiceName;\n}\n\nexport interface SecretsImportOptions {\n\tstage: string;\n\t/** Merge with existing secrets (default: true) */\n\tmerge?: boolean;\n}\n\n/**\n * Extract service names from compose config.\n */\nexport function getServicesFromConfig(\n\tservices: ComposeServicesConfig | ComposeServiceName[] | undefined,\n): ComposeServiceName[] {\n\tif (!services) {\n\t\treturn [];\n\t}\n\n\tif (Array.isArray(services)) {\n\t\treturn services;\n\t}\n\n\t// Object format - get keys where value is truthy\n\treturn (Object.entries(services) as [ComposeServiceName, unknown][])\n\t\t.filter(([, config]) => config)\n\t\t.map(([name]) => name);\n}\n\n/**\n * Initialize secrets for a stage.\n * Generates secure random passwords for configured services.\n */\nexport async function secretsInitCommand(\n\toptions: SecretsInitOptions,\n): Promise<void> {\n\tconst { stage, force } = options;\n\n\t// Check if secrets already exist\n\tif (!force && secretsExist(stage)) {\n\t\tlogger.error(\n\t\t\t`Secrets already exist for stage \"${stage}\". Use --force to overwrite.`,\n\t\t);\n\t\tprocess.exit(1);\n\t}\n\n\t// Load config to get services\n\tconst config = await loadConfig();\n\tconst services = getServicesFromConfig(config.docker?.compose?.services);\n\n\tif (services.length === 0) {\n\t\tlogger.warn(\n\t\t\t'No services configured in docker.compose.services. Creating secrets with empty services.',\n\t\t);\n\t}\n\n\t// Generate secrets\n\tconst secrets = createStageSecrets(stage, services);\n\n\t// Write to file\n\tawait writeStageSecrets(secrets);\n\n\tlogger.log(`\\n✓ Secrets initialized for stage \"${stage}\"`);\n\tlogger.log(` Location: .gkm/secrets/${stage}.json`);\n\tlogger.log('\\n Generated credentials for:');\n\n\tfor (const service of services) {\n\t\tlogger.log(` - ${service}`);\n\t}\n\n\tif (secrets.urls.DATABASE_URL) {\n\t\tlogger.log(`\\n DATABASE_URL: ${maskUrl(secrets.urls.DATABASE_URL)}`);\n\t}\n\tif (secrets.urls.REDIS_URL) {\n\t\tlogger.log(` REDIS_URL: ${maskUrl(secrets.urls.REDIS_URL)}`);\n\t}\n\tif (secrets.urls.RABBITMQ_URL) {\n\t\tlogger.log(` RABBITMQ_URL: ${maskUrl(secrets.urls.RABBITMQ_URL)}`);\n\t}\n\n\tlogger.log(`\\n Use \"gkm secrets:show --stage ${stage}\" to view secrets`);\n\tlogger.log(\n\t\t' Use \"gkm secrets:set <KEY> <VALUE> --stage ' +\n\t\t\tstage +\n\t\t\t'\" to add custom secrets',\n\t);\n}\n\n/**\n * Read all data from stdin.\n */\nasync function readStdin(): Promise<string> {\n\tconst chunks: Buffer[] = [];\n\n\tfor await (const chunk of process.stdin) {\n\t\tchunks.push(chunk);\n\t}\n\n\treturn Buffer.concat(chunks).toString('utf-8').trim();\n}\n\n/**\n * Set a custom secret.\n * If value is not provided, reads from stdin.\n */\nexport async function secretsSetCommand(\n\tkey: string,\n\tvalue: string | undefined,\n\toptions: SecretsSetOptions,\n): Promise<void> {\n\tconst { stage } = options;\n\n\t// Read from stdin if value not provided\n\tlet secretValue = value;\n\tif (!secretValue) {\n\t\tif (process.stdin.isTTY) {\n\t\t\tlogger.error(\n\t\t\t\t'No value provided. Use: gkm secrets:set KEY VALUE --stage <stage>',\n\t\t\t);\n\t\t\tlogger.error(\n\t\t\t\t'Or pipe from stdin: echo \"value\" | gkm secrets:set KEY --stage <stage>',\n\t\t\t);\n\t\t\tprocess.exit(1);\n\t\t}\n\t\tsecretValue = await readStdin();\n\t\tif (!secretValue) {\n\t\t\tlogger.error('No value received from stdin');\n\t\t\tprocess.exit(1);\n\t\t}\n\t}\n\n\ttry {\n\t\tawait setCustomSecret(stage, key, secretValue);\n\t\tlogger.log(`\\n✓ Secret \"${key}\" set for stage \"${stage}\"`);\n\t} catch (error) {\n\t\tlogger.error(\n\t\t\terror instanceof Error ? error.message : 'Failed to set secret',\n\t\t);\n\t\tprocess.exit(1);\n\t}\n}\n\n/**\n * Show secrets for a stage.\n */\nexport async function secretsShowCommand(\n\toptions: SecretsShowOptions,\n): Promise<void> {\n\tconst { stage, reveal } = options;\n\n\tconst secrets = await readStageSecrets(stage);\n\n\tif (!secrets) {\n\t\tlogger.error(\n\t\t\t`No secrets found for stage \"${stage}\". Run \"gkm secrets:init --stage ${stage}\" first.`,\n\t\t);\n\t\tprocess.exit(1);\n\t}\n\n\tlogger.log(`\\nSecrets for stage \"${stage}\":`);\n\tlogger.log(` Created: ${secrets.createdAt}`);\n\tlogger.log(` Updated: ${secrets.updatedAt}`);\n\n\t// Show service credentials\n\tlogger.log('\\nService Credentials:');\n\tfor (const [service, creds] of Object.entries(secrets.services)) {\n\t\tif (creds) {\n\t\t\tlogger.log(`\\n ${service}:`);\n\t\t\tlogger.log(` host: ${creds.host}`);\n\t\t\tlogger.log(` port: ${creds.port}`);\n\t\t\tlogger.log(` username: ${creds.username}`);\n\t\t\tlogger.log(\n\t\t\t\t` password: ${reveal ? creds.password : maskPassword(creds.password)}`,\n\t\t\t);\n\t\t\tif (creds.database) {\n\t\t\t\tlogger.log(` database: ${creds.database}`);\n\t\t\t}\n\t\t\tif (creds.vhost) {\n\t\t\t\tlogger.log(` vhost: ${creds.vhost}`);\n\t\t\t}\n\t\t}\n\t}\n\n\t// Show URLs\n\tlogger.log('\\nConnection URLs:');\n\tif (secrets.urls.DATABASE_URL) {\n\t\tlogger.log(\n\t\t\t` DATABASE_URL: ${reveal ? secrets.urls.DATABASE_URL : maskUrl(secrets.urls.DATABASE_URL)}`,\n\t\t);\n\t}\n\tif (secrets.urls.REDIS_URL) {\n\t\tlogger.log(\n\t\t\t` REDIS_URL: ${reveal ? secrets.urls.REDIS_URL : maskUrl(secrets.urls.REDIS_URL)}`,\n\t\t);\n\t}\n\tif (secrets.urls.RABBITMQ_URL) {\n\t\tlogger.log(\n\t\t\t` RABBITMQ_URL: ${reveal ? secrets.urls.RABBITMQ_URL : maskUrl(secrets.urls.RABBITMQ_URL)}`,\n\t\t);\n\t}\n\n\t// Show custom secrets\n\tconst customKeys = Object.keys(secrets.custom);\n\tif (customKeys.length > 0) {\n\t\tlogger.log('\\nCustom Secrets:');\n\t\tfor (const [key, value] of Object.entries(secrets.custom)) {\n\t\t\tlogger.log(` ${key}: ${reveal ? value : maskPassword(value)}`);\n\t\t}\n\t}\n\n\tif (!reveal) {\n\t\tlogger.log('\\nUse --reveal to show actual values');\n\t}\n}\n\n/**\n * Rotate passwords for services.\n */\nexport async function secretsRotateCommand(\n\toptions: SecretsRotateOptions,\n): Promise<void> {\n\tconst { stage, service } = options;\n\n\tconst secrets = await readStageSecrets(stage);\n\n\tif (!secrets) {\n\t\tlogger.error(\n\t\t\t`No secrets found for stage \"${stage}\". Run \"gkm secrets:init --stage ${stage}\" first.`,\n\t\t);\n\t\tprocess.exit(1);\n\t}\n\n\tif (service) {\n\t\t// Rotate specific service\n\t\tif (!secrets.services[service]) {\n\t\t\tlogger.error(`Service \"${service}\" not configured in stage \"${stage}\"`);\n\t\t\tprocess.exit(1);\n\t\t}\n\n\t\tconst updated = rotateServicePassword(secrets, service);\n\t\tawait writeStageSecrets(updated);\n\t\tlogger.log(`\\n✓ Password rotated for ${service} in stage \"${stage}\"`);\n\t} else {\n\t\t// Rotate all services\n\t\tlet updated = secrets;\n\t\tconst services = Object.keys(secrets.services) as ComposeServiceName[];\n\n\t\tfor (const svc of services) {\n\t\t\tupdated = rotateServicePassword(updated, svc);\n\t\t}\n\n\t\tawait writeStageSecrets(updated);\n\t\tlogger.log(\n\t\t\t`\\n✓ Passwords rotated for all services in stage \"${stage}\": ${services.join(', ')}`,\n\t\t);\n\t}\n\n\tlogger.log(`\\nUse \"gkm secrets:show --stage ${stage}\" to view new values`);\n}\n\n/**\n * Import secrets from a JSON file.\n */\nexport async function secretsImportCommand(\n\tfile: string,\n\toptions: SecretsImportOptions,\n): Promise<void> {\n\tconst { stage, merge = true } = options;\n\n\t// Check if file exists\n\tif (!existsSync(file)) {\n\t\tlogger.error(`File not found: ${file}`);\n\t\tprocess.exit(1);\n\t}\n\n\t// Read and parse JSON file\n\tlet importedSecrets: Record<string, string>;\n\ttry {\n\t\tconst content = await readFile(file, 'utf-8');\n\t\timportedSecrets = JSON.parse(content);\n\n\t\t// Validate it's a flat object with string values\n\t\tif (typeof importedSecrets !== 'object' || importedSecrets === null) {\n\t\t\tthrow new Error('JSON must be an object');\n\t\t}\n\n\t\tfor (const [key, value] of Object.entries(importedSecrets)) {\n\t\t\tif (typeof value !== 'string') {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Value for \"${key}\" must be a string, got ${typeof value}`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t} catch (error) {\n\t\tlogger.error(\n\t\t\t`Failed to parse JSON file: ${error instanceof Error ? error.message : 'Invalid JSON'}`,\n\t\t);\n\t\tprocess.exit(1);\n\t}\n\n\t// Check if secrets exist for stage\n\tconst secrets = await readStageSecrets(stage);\n\n\tif (!secrets) {\n\t\tlogger.error(\n\t\t\t`No secrets found for stage \"${stage}\". Run \"gkm secrets:init --stage ${stage}\" first.`,\n\t\t);\n\t\tprocess.exit(1);\n\t}\n\n\t// Merge or replace custom secrets\n\tconst updatedCustom = merge\n\t\t? { ...secrets.custom, ...importedSecrets }\n\t\t: importedSecrets;\n\n\tconst updated = {\n\t\t...secrets,\n\t\tupdatedAt: new Date().toISOString(),\n\t\tcustom: updatedCustom,\n\t};\n\n\tawait writeStageSecrets(updated);\n\n\tconst importedCount = Object.keys(importedSecrets).length;\n\tconst totalCount = Object.keys(updatedCustom).length;\n\n\tlogger.log(`\\n✓ Imported ${importedCount} secrets for stage \"${stage}\"`);\n\n\tif (merge && totalCount > importedCount) {\n\t\tlogger.log(` Total custom secrets: ${totalCount}`);\n\t}\n\n\tlogger.log('\\n Imported keys:');\n\tfor (const key of Object.keys(importedSecrets)) {\n\t\tlogger.log(` - ${key}`);\n\t}\n}\n\n/**\n * Mask password in a URL for display.\n */\nexport function maskUrl(url: string): string {\n\ttry {\n\t\tconst parsed = new URL(url);\n\t\tif (parsed.password) {\n\t\t\tparsed.password = maskPassword(parsed.password);\n\t\t}\n\t\treturn parsed.toString();\n\t} catch {\n\t\treturn url;\n\t}\n}\n","#!/usr/bin/env -S npx tsx\n\nimport { Command } from 'commander';\nimport pkg from '../package.json';\nimport { loginCommand, logoutCommand, whoamiCommand } from './auth';\nimport { buildCommand } from './build/index';\nimport { type DeployProvider, deployCommand } from './deploy/index';\nimport { deployInitCommand, deployListCommand } from './deploy/init';\nimport { devCommand } from './dev/index';\nimport { type DockerOptions, dockerCommand } from './docker/index';\nimport { type InitOptions, initCommand } from './init/index';\nimport { openapiCommand } from './openapi';\nimport { generateReactQueryCommand } from './openapi-react-query';\nimport {\n\tsecretsImportCommand,\n\tsecretsInitCommand,\n\tsecretsRotateCommand,\n\tsecretsSetCommand,\n\tsecretsShowCommand,\n} from './secrets';\nimport type { ComposeServiceName, LegacyProvider, MainProvider } from './types';\n\nconst program = new Command();\n\nprogram\n\t.name('gkm')\n\t.description('GeekMidas backend framework CLI')\n\t.version(pkg.version)\n\t.option('--cwd <path>', 'Change working directory');\n\nprogram\n\t.command('init')\n\t.description('Scaffold a new project')\n\t.argument('[name]', 'Project name')\n\t.option(\n\t\t'--template <template>',\n\t\t'Project template (minimal, api, serverless, worker)',\n\t)\n\t.option('--skip-install', 'Skip dependency installation', false)\n\t.option('-y, --yes', 'Skip prompts, use defaults', false)\n\t.option('--monorepo', 'Setup as monorepo with packages/models', false)\n\t.option('--api-path <path>', 'API app path in monorepo (default: apps/api)')\n\t.action(async (name: string | undefined, options: InitOptions) => {\n\t\ttry {\n\t\t\tconst globalOptions = program.opts();\n\t\t\tif (globalOptions.cwd) {\n\t\t\t\tprocess.chdir(globalOptions.cwd);\n\t\t\t}\n\t\t\tawait initCommand(name, options);\n\t\t} catch (_error) {\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n\nprogram\n\t.command('build')\n\t.description('Build handlers from endpoints, functions, and crons')\n\t.option(\n\t\t'--provider <provider>',\n\t\t'Target provider for generated handlers (aws, server)',\n\t)\n\t.option(\n\t\t'--providers <providers>',\n\t\t'[DEPRECATED] Use --provider instead. Target providers for generated handlers (comma-separated)',\n\t)\n\t.option(\n\t\t'--enable-openapi',\n\t\t'Enable OpenAPI documentation generation for server builds',\n\t)\n\t.option('--production', 'Build for production (no dev tools, bundled output)')\n\t.option('--skip-bundle', 'Skip bundling step in production build')\n\t.option('--stage <stage>', 'Inject encrypted secrets for deployment stage')\n\t.action(\n\t\tasync (options: {\n\t\t\tprovider?: string;\n\t\t\tproviders?: string;\n\t\t\tenableOpenapi?: boolean;\n\t\t\tproduction?: boolean;\n\t\t\tskipBundle?: boolean;\n\t\t\tstage?: string;\n\t\t}) => {\n\t\t\ttry {\n\t\t\t\tconst globalOptions = program.opts();\n\t\t\t\tif (globalOptions.cwd) {\n\t\t\t\t\tprocess.chdir(globalOptions.cwd);\n\t\t\t\t}\n\n\t\t\t\t// Handle new single provider option\n\t\t\t\tif (options.provider) {\n\t\t\t\t\tif (!['aws', 'server'].includes(options.provider)) {\n\t\t\t\t\t\tprocess.exit(1);\n\t\t\t\t\t}\n\t\t\t\t\tawait buildCommand({\n\t\t\t\t\t\tprovider: options.provider as MainProvider,\n\t\t\t\t\t\tenableOpenApi: options.enableOpenapi || false,\n\t\t\t\t\t\tproduction: options.production || false,\n\t\t\t\t\t\tskipBundle: options.skipBundle || false,\n\t\t\t\t\t\tstage: options.stage,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\t// Handle legacy providers option\n\t\t\t\telse if (options.providers) {\n\t\t\t\t\tconst providerList = [\n\t\t\t\t\t\t...new Set(options.providers.split(',').map((p) => p.trim())),\n\t\t\t\t\t] as LegacyProvider[];\n\t\t\t\t\tawait buildCommand({\n\t\t\t\t\t\tproviders: providerList,\n\t\t\t\t\t\tenableOpenApi: options.enableOpenapi || false,\n\t\t\t\t\t\tproduction: options.production || false,\n\t\t\t\t\t\tskipBundle: options.skipBundle || false,\n\t\t\t\t\t\tstage: options.stage,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\t// Default to config-driven build\n\t\t\t\telse {\n\t\t\t\t\tawait buildCommand({\n\t\t\t\t\t\tenableOpenApi: options.enableOpenapi || false,\n\t\t\t\t\t\tproduction: options.production || false,\n\t\t\t\t\t\tskipBundle: options.skipBundle || false,\n\t\t\t\t\t\tstage: options.stage,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t} catch (_error) {\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\t\t},\n\t);\n\nprogram\n\t.command('dev')\n\t.description('Start development server with automatic reload')\n\t.option('-p, --port <port>', 'Port to run the development server on')\n\t.option(\n\t\t'--enable-openapi',\n\t\t'Enable OpenAPI documentation for development server',\n\t\ttrue,\n\t)\n\t.action(async (options: { port?: string; enableOpenapi?: boolean }) => {\n\t\ttry {\n\t\t\tconst globalOptions = program.opts();\n\t\t\tif (globalOptions.cwd) {\n\t\t\t\tprocess.chdir(globalOptions.cwd);\n\t\t\t}\n\n\t\t\tawait devCommand({\n\t\t\t\tport: options.port ? Number.parseInt(options.port, 10) : 3000,\n\t\t\t\tportExplicit: !!options.port,\n\t\t\t\tenableOpenApi: options.enableOpenapi ?? true,\n\t\t\t});\n\t\t} catch (_error) {\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n\nprogram\n\t.command('cron')\n\t.description('Manage cron jobs')\n\t.action(() => {\n\t\tconst globalOptions = program.opts();\n\t\tif (globalOptions.cwd) {\n\t\t\tprocess.chdir(globalOptions.cwd);\n\t\t}\n\t\tprocess.stdout.write('Cron management - coming soon\\n');\n\t});\n\nprogram\n\t.command('function')\n\t.description('Manage serverless functions')\n\t.action(() => {\n\t\tconst globalOptions = program.opts();\n\t\tif (globalOptions.cwd) {\n\t\t\tprocess.chdir(globalOptions.cwd);\n\t\t}\n\t\tprocess.stdout.write('Serverless function management - coming soon\\n');\n\t});\n\nprogram\n\t.command('api')\n\t.description('Manage REST API endpoints')\n\t.action(() => {\n\t\tconst globalOptions = program.opts();\n\t\tif (globalOptions.cwd) {\n\t\t\tprocess.chdir(globalOptions.cwd);\n\t\t}\n\t\tprocess.stdout.write('REST API management - coming soon\\n');\n\t});\n\nprogram\n\t.command('openapi')\n\t.description('Generate OpenAPI specification from endpoints')\n\t.action(async () => {\n\t\ttry {\n\t\t\tconst globalOptions = program.opts();\n\t\t\tif (globalOptions.cwd) {\n\t\t\t\tprocess.chdir(globalOptions.cwd);\n\t\t\t}\n\t\t\tawait openapiCommand({});\n\t\t} catch (_error) {\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n\nprogram\n\t.command('generate:react-query')\n\t.description('Generate React Query hooks from OpenAPI specification')\n\t.option('--input <path>', 'Input OpenAPI spec file path', 'openapi.json')\n\t.option(\n\t\t'--output <path>',\n\t\t'Output file path for generated hooks',\n\t\t'src/api/hooks.ts',\n\t)\n\t.option('--name <name>', 'API name prefix for generated code', 'API')\n\t.action(\n\t\tasync (options: { input?: string; output?: string; name?: string }) => {\n\t\t\ttry {\n\t\t\t\tconst globalOptions = program.opts();\n\t\t\t\tif (globalOptions.cwd) {\n\t\t\t\t\tprocess.chdir(globalOptions.cwd);\n\t\t\t\t}\n\t\t\t\tawait generateReactQueryCommand(options);\n\t\t\t} catch (_error) {\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\t\t},\n\t);\n\nprogram\n\t.command('docker')\n\t.description('Generate Docker deployment files')\n\t.option('--build', 'Build Docker image after generating files')\n\t.option('--push', 'Push image to registry after building')\n\t.option('--tag <tag>', 'Image tag', 'latest')\n\t.option('--registry <registry>', 'Container registry URL')\n\t.option('--slim', 'Use slim Dockerfile (assumes pre-built bundle exists)')\n\t.option('--turbo', 'Use turbo prune for monorepo optimization')\n\t.option('--turbo-package <name>', 'Package name for turbo prune')\n\t.action(async (options: DockerOptions) => {\n\t\ttry {\n\t\t\tconst globalOptions = program.opts();\n\t\t\tif (globalOptions.cwd) {\n\t\t\t\tprocess.chdir(globalOptions.cwd);\n\t\t\t}\n\t\t\tawait dockerCommand(options);\n\t\t} catch (_error) {\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n\nprogram\n\t.command('prepack')\n\t.description('Generate Docker files for production deployment')\n\t.option('--build', 'Build Docker image after generating files')\n\t.option('--push', 'Push image to registry after building')\n\t.option('--tag <tag>', 'Image tag', 'latest')\n\t.option('--registry <registry>', 'Container registry URL')\n\t.option('--slim', 'Build locally first, then use slim Dockerfile')\n\t.option('--skip-bundle', 'Skip bundling step (only with --slim)')\n\t.option('--turbo', 'Use turbo prune for monorepo optimization')\n\t.option('--turbo-package <name>', 'Package name for turbo prune')\n\t.action(\n\t\tasync (options: {\n\t\t\tbuild?: boolean;\n\t\t\tpush?: boolean;\n\t\t\ttag?: string;\n\t\t\tregistry?: string;\n\t\t\tslim?: boolean;\n\t\t\tskipBundle?: boolean;\n\t\t\tturbo?: boolean;\n\t\t\tturboPackage?: string;\n\t\t}) => {\n\t\t\ttry {\n\t\t\t\tconst globalOptions = program.opts();\n\t\t\t\tif (globalOptions.cwd) {\n\t\t\t\t\tprocess.chdir(globalOptions.cwd);\n\t\t\t\t}\n\n\t\t\t\tif (options.slim) {\n\t\t\t\t\tawait buildCommand({\n\t\t\t\t\t\tprovider: 'server',\n\t\t\t\t\t\tproduction: true,\n\t\t\t\t\t\tskipBundle: options.skipBundle,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tawait dockerCommand({\n\t\t\t\t\tbuild: options.build,\n\t\t\t\t\tpush: options.push,\n\t\t\t\t\ttag: options.tag,\n\t\t\t\t\tregistry: options.registry,\n\t\t\t\t\tslim: options.slim,\n\t\t\t\t\tturbo: options.turbo,\n\t\t\t\t\tturboPackage: options.turboPackage,\n\t\t\t\t});\n\t\t\t\tif (options.slim) {\n\t\t\t\t} else {\n\t\t\t\t}\n\n\t\t\t\tif (options.build) {\n\t\t\t\t\tconst tag = options.tag ?? 'latest';\n\t\t\t\t\tconst registry = options.registry;\n\t\t\t\t\tconst _imageRef = registry ? `${registry}/api:${tag}` : `api:${tag}`;\n\t\t\t\t}\n\t\t\t} catch (_error) {\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\t\t},\n\t);\n\n// Secrets management commands\nprogram\n\t.command('secrets:init')\n\t.description('Initialize secrets for a deployment stage')\n\t.requiredOption('--stage <stage>', 'Stage name (e.g., production, staging)')\n\t.option('--force', 'Overwrite existing secrets')\n\t.action(async (options: { stage: string; force?: boolean }) => {\n\t\ttry {\n\t\t\tconst globalOptions = program.opts();\n\t\t\tif (globalOptions.cwd) {\n\t\t\t\tprocess.chdir(globalOptions.cwd);\n\t\t\t}\n\t\t\tawait secretsInitCommand(options);\n\t\t} catch (_error) {\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n\nprogram\n\t.command('secrets:set')\n\t.description('Set a custom secret for a stage')\n\t.argument('<key>', 'Secret key (e.g., API_KEY)')\n\t.argument('[value]', 'Secret value (reads from stdin if omitted)')\n\t.requiredOption('--stage <stage>', 'Stage name')\n\t.action(\n\t\tasync (\n\t\t\tkey: string,\n\t\t\tvalue: string | undefined,\n\t\t\toptions: { stage: string },\n\t\t) => {\n\t\t\ttry {\n\t\t\t\tconst globalOptions = program.opts();\n\t\t\t\tif (globalOptions.cwd) {\n\t\t\t\t\tprocess.chdir(globalOptions.cwd);\n\t\t\t\t}\n\t\t\t\tawait secretsSetCommand(key, value, options);\n\t\t\t} catch (_error) {\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\t\t},\n\t);\n\nprogram\n\t.command('secrets:show')\n\t.description('Show secrets for a stage')\n\t.requiredOption('--stage <stage>', 'Stage name')\n\t.option('--reveal', 'Show actual secret values (not masked)')\n\t.action(async (options: { stage: string; reveal?: boolean }) => {\n\t\ttry {\n\t\t\tconst globalOptions = program.opts();\n\t\t\tif (globalOptions.cwd) {\n\t\t\t\tprocess.chdir(globalOptions.cwd);\n\t\t\t}\n\t\t\tawait secretsShowCommand(options);\n\t\t} catch (_error) {\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n\nprogram\n\t.command('secrets:rotate')\n\t.description('Rotate service passwords')\n\t.requiredOption('--stage <stage>', 'Stage name')\n\t.option(\n\t\t'--service <service>',\n\t\t'Specific service to rotate (postgres, redis, rabbitmq)',\n\t)\n\t.action(async (options: { stage: string; service?: ComposeServiceName }) => {\n\t\ttry {\n\t\t\tconst globalOptions = program.opts();\n\t\t\tif (globalOptions.cwd) {\n\t\t\t\tprocess.chdir(globalOptions.cwd);\n\t\t\t}\n\t\t\tawait secretsRotateCommand(options);\n\t\t} catch (_error) {\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n\nprogram\n\t.command('secrets:import')\n\t.description('Import secrets from a JSON file')\n\t.argument('<file>', 'JSON file path (e.g., secrets.json)')\n\t.requiredOption('--stage <stage>', 'Stage name')\n\t.option('--no-merge', 'Replace all custom secrets instead of merging')\n\t.action(async (file: string, options: { stage: string; merge?: boolean }) => {\n\t\ttry {\n\t\t\tconst globalOptions = program.opts();\n\t\t\tif (globalOptions.cwd) {\n\t\t\t\tprocess.chdir(globalOptions.cwd);\n\t\t\t}\n\t\t\tawait secretsImportCommand(file, options);\n\t\t} catch (_error) {\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n\n// Deploy command\nprogram\n\t.command('deploy')\n\t.description('Deploy application to a provider')\n\t.requiredOption(\n\t\t'--provider <provider>',\n\t\t'Deploy provider (docker, dokploy, aws-lambda)',\n\t)\n\t.requiredOption(\n\t\t'--stage <stage>',\n\t\t'Deployment stage (e.g., production, staging)',\n\t)\n\t.option('--tag <tag>', 'Image tag (default: stage-timestamp)')\n\t.option('--skip-push', 'Skip pushing image to registry')\n\t.option('--skip-build', 'Skip build step (use existing build)')\n\t.action(\n\t\tasync (options: {\n\t\t\tprovider: string;\n\t\t\tstage: string;\n\t\t\ttag?: string;\n\t\t\tskipPush?: boolean;\n\t\t\tskipBuild?: boolean;\n\t\t}) => {\n\t\t\ttry {\n\t\t\t\tconst globalOptions = program.opts();\n\t\t\t\tif (globalOptions.cwd) {\n\t\t\t\t\tprocess.chdir(globalOptions.cwd);\n\t\t\t\t}\n\n\t\t\t\tconst validProviders = ['docker', 'dokploy', 'aws-lambda'];\n\t\t\t\tif (!validProviders.includes(options.provider)) {\n\t\t\t\t\tconsole.error(\n\t\t\t\t\t\t`Invalid provider: ${options.provider}\\n` +\n\t\t\t\t\t\t\t`Valid providers: ${validProviders.join(', ')}`,\n\t\t\t\t\t);\n\t\t\t\t\tprocess.exit(1);\n\t\t\t\t}\n\n\t\t\t\tawait deployCommand({\n\t\t\t\t\tprovider: options.provider as DeployProvider,\n\t\t\t\t\tstage: options.stage,\n\t\t\t\t\ttag: options.tag,\n\t\t\t\t\tskipPush: options.skipPush,\n\t\t\t\t\tskipBuild: options.skipBuild,\n\t\t\t\t});\n\t\t\t} catch (_error) {\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\t\t},\n\t);\n\n// Deploy init command - Initialize Dokploy project and application\nprogram\n\t.command('deploy:init')\n\t.description('Initialize Dokploy deployment (create project and application)')\n\t.option(\n\t\t'--endpoint <url>',\n\t\t'Dokploy server URL (uses stored credentials if logged in)',\n\t)\n\t.requiredOption('--project <name>', 'Project name (creates if not exists)')\n\t.requiredOption('--app <name>', 'Application name')\n\t.option('--project-id <id>', 'Use existing project ID instead of creating')\n\t.option('--registry-id <id>', 'Configure registry for the application')\n\t.action(\n\t\tasync (options: {\n\t\t\tendpoint?: string;\n\t\t\tproject: string;\n\t\t\tapp: string;\n\t\t\tprojectId?: string;\n\t\t\tregistryId?: string;\n\t\t}) => {\n\t\t\ttry {\n\t\t\t\tconst globalOptions = program.opts();\n\t\t\t\tif (globalOptions.cwd) {\n\t\t\t\t\tprocess.chdir(globalOptions.cwd);\n\t\t\t\t}\n\n\t\t\t\tawait deployInitCommand({\n\t\t\t\t\tendpoint: options.endpoint,\n\t\t\t\t\tprojectName: options.project,\n\t\t\t\t\tappName: options.app,\n\t\t\t\t\tprojectId: options.projectId,\n\t\t\t\t\tregistryId: options.registryId,\n\t\t\t\t});\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error(\n\t\t\t\t\terror instanceof Error\n\t\t\t\t\t\t? error.message\n\t\t\t\t\t\t: 'Failed to initialize deployment',\n\t\t\t\t);\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\t\t},\n\t);\n\n// Deploy list command - List Dokploy resources\nprogram\n\t.command('deploy:list')\n\t.description('List Dokploy resources (projects, registries)')\n\t.option(\n\t\t'--endpoint <url>',\n\t\t'Dokploy server URL (uses stored credentials if logged in)',\n\t)\n\t.option('--projects', 'List projects')\n\t.option('--registries', 'List registries')\n\t.action(\n\t\tasync (options: {\n\t\t\tendpoint?: string;\n\t\t\tprojects?: boolean;\n\t\t\tregistries?: boolean;\n\t\t}) => {\n\t\t\ttry {\n\t\t\t\tconst globalOptions = program.opts();\n\t\t\t\tif (globalOptions.cwd) {\n\t\t\t\t\tprocess.chdir(globalOptions.cwd);\n\t\t\t\t}\n\n\t\t\t\tif (options.projects) {\n\t\t\t\t\tawait deployListCommand({\n\t\t\t\t\t\tendpoint: options.endpoint,\n\t\t\t\t\t\tresource: 'projects',\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tif (options.registries) {\n\t\t\t\t\tawait deployListCommand({\n\t\t\t\t\t\tendpoint: options.endpoint,\n\t\t\t\t\t\tresource: 'registries',\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tif (!options.projects && !options.registries) {\n\t\t\t\t\t// Default to listing both\n\t\t\t\t\tawait deployListCommand({\n\t\t\t\t\t\tendpoint: options.endpoint,\n\t\t\t\t\t\tresource: 'projects',\n\t\t\t\t\t});\n\t\t\t\t\tawait deployListCommand({\n\t\t\t\t\t\tendpoint: options.endpoint,\n\t\t\t\t\t\tresource: 'registries',\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error(\n\t\t\t\t\terror instanceof Error ? error.message : 'Failed to list resources',\n\t\t\t\t);\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\t\t},\n\t);\n\n// Login command\nprogram\n\t.command('login')\n\t.description('Authenticate with a deployment service')\n\t.option('--service <service>', 'Service to login to (dokploy)', 'dokploy')\n\t.option('--token <token>', 'API token (will prompt if not provided)')\n\t.option('--endpoint <url>', 'Service endpoint URL')\n\t.action(\n\t\tasync (options: { service: string; token?: string; endpoint?: string }) => {\n\t\t\ttry {\n\t\t\t\tconst globalOptions = program.opts();\n\t\t\t\tif (globalOptions.cwd) {\n\t\t\t\t\tprocess.chdir(globalOptions.cwd);\n\t\t\t\t}\n\n\t\t\t\tif (options.service !== 'dokploy') {\n\t\t\t\t\tconsole.error(\n\t\t\t\t\t\t`Unknown service: ${options.service}. Supported: dokploy`,\n\t\t\t\t\t);\n\t\t\t\t\tprocess.exit(1);\n\t\t\t\t}\n\n\t\t\t\tawait loginCommand({\n\t\t\t\t\tservice: options.service as 'dokploy',\n\t\t\t\t\ttoken: options.token,\n\t\t\t\t\tendpoint: options.endpoint,\n\t\t\t\t});\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error(\n\t\t\t\t\terror instanceof Error ? error.message : 'Failed to login',\n\t\t\t\t);\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\t\t},\n\t);\n\n// Logout command\nprogram\n\t.command('logout')\n\t.description('Remove stored credentials')\n\t.option(\n\t\t'--service <service>',\n\t\t'Service to logout from (dokploy, all)',\n\t\t'dokploy',\n\t)\n\t.action(async (options: { service: string }) => {\n\t\ttry {\n\t\t\tconst globalOptions = program.opts();\n\t\t\tif (globalOptions.cwd) {\n\t\t\t\tprocess.chdir(globalOptions.cwd);\n\t\t\t}\n\n\t\t\tawait logoutCommand({\n\t\t\t\tservice: options.service as 'dokploy' | 'all',\n\t\t\t});\n\t\t} catch (error) {\n\t\t\tconsole.error(\n\t\t\t\terror instanceof Error ? error.message : 'Failed to logout',\n\t\t\t);\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n\n// Whoami command\nprogram\n\t.command('whoami')\n\t.description('Show current authentication status')\n\t.action(async () => {\n\t\ttry {\n\t\t\tconst globalOptions = program.opts();\n\t\t\tif (globalOptions.cwd) {\n\t\t\t\tprocess.chdir(globalOptions.cwd);\n\t\t\t}\n\n\t\t\tawait whoamiCommand();\n\t\t} catch (error) {\n\t\t\tconsole.error(\n\t\t\t\terror instanceof Error ? error.message : 'Failed to get status',\n\t\t\t);\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n\nprogram.parse();\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["options?: CredentialOptions","credentials: StoredCredentials","token: string","endpoint: string","registryId: string","logger","endpoint: string","token: string","DokployApi","prompt","message: string","resolve","err: Error","char: Buffer","options: LoginOptions","options: LogoutOptions","config: GkmConfig","options: BuildOptions","providers: LegacyProvider[]","mainProvider: MainProvider","providersConfig?: ProvidersConfig","providersConfig: ProvidersConfig","config:\n\t\t| boolean\n\t\t| AWSApiGatewayConfig\n\t\t| AWSLambdaConfig\n\t\t| ServerConfig\n\t\t| undefined","ConstructGenerator","context: BuildContext","constructs: GeneratedConstruct<\n\t\t\tCron<any, any, any, any, any, any, any, any>\n\t\t>[]","outputDir: string","options?: GeneratorOptions","logger","cronInfos: CronInfo[]","value: any","sourceFile: string","exportName: string","ConstructGenerator","value: any","context: BuildContext","constructs: GeneratedConstruct<\n\t\t\tFunction<any, any, any, any, any, any, any, any, any, any, any, any>\n\t\t>[]","outputDir: string","options?: GeneratorOptions","logger","functionInfos: FunctionInfo[]","sourceFile: string","exportName: string","ConstructGenerator","value: any","context: BuildContext","constructs: GeneratedConstruct<Subscriber<any, any, any, any, any, any>>[]","outputDir: string","options?: GeneratorOptions","logger","subscriberInfos: SubscriberInfo[]","sourceFile: string","exportName: string","_subscriber: Subscriber<any, any, any, any, any, any>","subscribers: GeneratedConstruct<Subscriber<any, any, any, any, any, any>>[]","exports","logger","envConfig: string | string[] | undefined","cwd: string","loaded: string[]","missing: string[]","port: number","resolve","err: NodeJS.ErrnoException","preferredPort: number","config: GkmConfig['telescope']","isEnabled","telescopeConfig: TelescopeConfig","config: GkmConfig['studio']","studioConfig: StudioConfig","config: GkmConfig['hooks']","cliProduction: boolean","configProduction?: ProductionConfig","config: GkmConfig","options: DevOptions","OPENAPI_OUTPUT_PATH","buildContext: BuildContext","runtime: Runtime","rebuildTimeout: NodeJS.Timeout | null","config: any","context: BuildContext","provider: LegacyProvider","enableOpenApi: boolean","EndpointGenerator","requestedPort: number","portExplicit: boolean","telescope?: NormalizedTelescopeConfig","studio?: NormalizedStudioConfig","logger","outputDir: string","routes: RouteInfo[]","functions: FunctionInfo[]","crons: CronInfo[]","subscribers: SubscriberInfo[]","appInfo: ServerAppInfo","logger","options: BuildOptions","buildContext: BuildContext","EndpointGenerator","result: BuildResult","provider: LegacyProvider","context: BuildContext","rootOutputDir: string","endpointGenerator: EndpointGenerator","functionGenerator: FunctionGenerator","cronGenerator: CronGenerator","subscriberGenerator: SubscriberGenerator","endpoints: GeneratedConstruct<Endpoint<any, any, any, any, any, any>>[]","functions: GeneratedConstruct<Function<any, any, any, any>>[]","crons: GeneratedConstruct<Cron<any, any, any, any>>[]","subscribers: GeneratedConstruct<Subscriber<any, any, any, any, any, any>>[]","enableOpenApi: boolean","skipBundle: boolean","stage?: string","routeMetadata: RouteInfo[]","appInfo: ServerAppInfo","masterKey: string | undefined","DEFAULT_SERVICE_IMAGES: Record<ComposeServiceName, string>","DEFAULT_SERVICE_VERSIONS: Record<ComposeServiceName, string>","serviceName: ComposeServiceName","services: ComposeServicesConfig | ComposeServiceName[]","name","version","options: ComposeOptions","options: Omit<ComposeOptions, 'services'>","LOCKFILES: [string, PackageManager][]","detectPackageManager","cwd: string","pm: PackageManager","commands: Record<PackageManager, string>","options: MultiStageDockerfileOptions","options: DockerTemplateOptions","resolveDockerConfig","config: GkmConfig","logger","options: DockerOptions","result: DockerGeneratedFiles","cwd: string","imageName: string","logger","registry: string | undefined","imageName: string","tag: string","imageRef: string","options: DockerDeployOptions","config: GkmConfig","logger","getApiToken","createApi","endpoint: string","DokployApi","options: DokployDeployOptions","registryOptions: {\n\t\tregistryId?: string;\n\t\tusername?: string;\n\t\tpassword?: string;\n\t\tregistryUrl?: string;\n\t}","envVars: Record<string, string>","logger","providedEndpoint?: string","endpoint: string","DokployApi","config: DokployDeployConfig","cwd: string","newContent: string","options: DeployInitOptions","projectId: string","environmentId: string","options: {\n\tendpoint?: string;\n\tresource: 'projects' | 'registries';\n}","logger","message: string","resolve","char: Buffer","api: DokployApi","projectId: string","environmentId: string | undefined","appName: string","services?: DockerComposeServices","existingUrls?: { DATABASE_URL?: string; REDIS_URL?: string }","serviceUrls: { DATABASE_URL?: string; REDIS_URL?: string }","config: GkmConfig","dockerConfig: { registry?: string; imageName?: string }","stage: string","existingUrls: { DATABASE_URL?: string; REDIS_URL?: string }","DokployApi","environmentId","serviceUrls","environmentId: string","applicationId: string","dokployConfig: DokployDeployConfig","options: DeployOptions","dokployConfig: DokployDeployConfig | undefined","dockerServices: DockerComposeServices | undefined","masterKey: string | undefined","result: DeployResult","options: TemplateOptions","template: TemplateConfig","options: TemplateOptions","template: TemplateConfig","services: string[]","volumes: string[]","options: TemplateOptions","template: TemplateConfig","files: GeneratedFile[]","options: TemplateOptions","options: TemplateOptions","_template: TemplateConfig","apiTemplate: TemplateConfig","options: TemplateOptions","file: string","files: GeneratedFile[]","minimalTemplate: TemplateConfig","options: TemplateOptions","file: string","files: GeneratedFile[]","serverlessTemplate: TemplateConfig","options: TemplateOptions","file: string","files: GeneratedFile[]","workerTemplate: TemplateConfig","options: TemplateOptions","file: string","files: GeneratedFile[]","OPENAPI_OUTPUT_PATH","templates: Record<TemplateName, TemplateConfig>","name: TemplateName","name","options: TemplateOptions","template: TemplateConfig","dependencies","devDependencies","scripts","name","obj: Record<string, string>","OPENAPI_OUTPUT_PATH","options: TemplateOptions","template: TemplateConfig","cwd: string","name: string","name","pkgManager: PackageManager","script: string","projectName?: string","options: InitOptions","value: string","name","templateOptions: TemplateOptions","isMonorepo","SERVICE_DEFAULTS: Record<\n\tComposeServiceName,\n\tOmit<ServiceCredentials, 'password'>\n>","service: ComposeServiceName","services: ComposeServiceName[]","result: StageSecrets['services']","creds: ServiceCredentials","services: StageSecrets['services']","urls: StageSecrets['urls']","stage: string","secrets: StageSecrets","newCreds: ServiceCredentials","services: ComposeServicesConfig | ComposeServiceName[] | undefined","name","options: SecretsInitOptions","chunks: Buffer[]","key: string","value: string | undefined","options: SecretsSetOptions","options: SecretsShowOptions","options: SecretsRotateOptions","file: string","options: SecretsImportOptions","importedSecrets: Record<string, string>","url: string","Command","pkg","name: string | undefined","options: InitOptions","name","options: {\n\t\t\tprovider?: string;\n\t\t\tproviders?: string;\n\t\t\tenableOpenapi?: boolean;\n\t\t\tproduction?: boolean;\n\t\t\tskipBundle?: boolean;\n\t\t\tstage?: string;\n\t\t}","options: { port?: string; enableOpenapi?: boolean }","options: { input?: string; output?: string; name?: string }","options: DockerOptions","options: {\n\t\t\tbuild?: boolean;\n\t\t\tpush?: boolean;\n\t\t\ttag?: string;\n\t\t\tregistry?: string;\n\t\t\tslim?: boolean;\n\t\t\tskipBundle?: boolean;\n\t\t\tturbo?: boolean;\n\t\t\tturboPackage?: string;\n\t\t}","options: { stage: string; force?: boolean }","key: string","value: string | undefined","options: { stage: string }","options: { stage: string; reveal?: boolean }","options: { stage: string; service?: ComposeServiceName }","file: string","options: { stage: string; merge?: boolean }","options: {\n\t\t\tprovider: string;\n\t\t\tstage: string;\n\t\t\ttag?: string;\n\t\t\tskipPush?: boolean;\n\t\t\tskipBuild?: boolean;\n\t\t}","options: {\n\t\t\tendpoint?: string;\n\t\t\tproject: string;\n\t\t\tapp: string;\n\t\t\tprojectId?: string;\n\t\t\tregistryId?: string;\n\t\t}","options: {\n\t\t\tendpoint?: string;\n\t\t\tprojects?: boolean;\n\t\t\tregistries?: boolean;\n\t\t}","options: { service: string; token?: string; endpoint?: string }","options: { service: string }"],"sources":["../package.json","../src/auth/credentials.ts","../src/auth/index.ts","../src/build/providerResolver.ts","../src/generators/CronGenerator.ts","../src/generators/FunctionGenerator.ts","../src/generators/SubscriberGenerator.ts","../src/dev/index.ts","../src/build/manifests.ts","../src/build/index.ts","../src/docker/compose.ts","../src/docker/templates.ts","../src/docker/index.ts","../src/deploy/docker.ts","../src/deploy/dokploy.ts","../src/deploy/init.ts","../src/deploy/index.ts","../src/init/generators/config.ts","../src/init/generators/docker.ts","../src/init/generators/env.ts","../src/init/generators/models.ts","../src/init/generators/monorepo.ts","../src/init/templates/api.ts","../src/init/templates/minimal.ts","../src/init/templates/serverless.ts","../src/init/templates/worker.ts","../src/init/templates/index.ts","../src/init/generators/package.ts","../src/init/generators/source.ts","../src/init/utils.ts","../src/init/index.ts","../src/secrets/generator.ts","../src/secrets/index.ts","../src/index.ts"],"sourcesContent":["{\n\t\"name\": \"@geekmidas/cli\",\n\t\"version\": \"0.14.0\",\n\t\"description\": \"CLI tools for building Lambda handlers, server applications, and generating OpenAPI specs\",\n\t\"private\": false,\n\t\"type\": \"module\",\n\t\"exports\": {\n\t\t\".\": {\n\t\t\t\"types\": \"./dist/index.d.ts\",\n\t\t\t\"import\": \"./dist/index.mjs\",\n\t\t\t\"require\": \"./dist/index.cjs\"\n\t\t},\n\t\t\"./config\": {\n\t\t\t\"types\": \"./dist/config.d.ts\",\n\t\t\t\"import\": \"./dist/config.mjs\",\n\t\t\t\"require\": \"./dist/config.cjs\"\n\t\t},\n\t\t\"./openapi\": {\n\t\t\t\"types\": \"./dist/openapi.d.ts\",\n\t\t\t\"import\": \"./dist/openapi.mjs\",\n\t\t\t\"require\": \"./dist/openapi.cjs\"\n\t\t},\n\t\t\"./openapi-react-query\": {\n\t\t\t\"types\": \"./dist/openapi-react-query.d.ts\",\n\t\t\t\"import\": \"./dist/openapi-react-query.mjs\",\n\t\t\t\"require\": \"./dist/openapi-react-query.cjs\"\n\t\t}\n\t},\n\t\"bin\": {\n\t\t\"gkm\": \"./dist/index.cjs\"\n\t},\n\t\"scripts\": {\n\t\t\"ts\": \"tsc --noEmit --skipLibCheck src/**/*.ts\",\n\t\t\"test\": \"vitest\",\n\t\t\"test:once\": \"vitest run\",\n\t\t\"test:coverage\": \"vitest run --coverage\"\n\t},\n\t\"repository\": {\n\t\t\"type\": \"git\",\n\t\t\"url\": \"https://github.com/geekmidas/toolbox\"\n\t},\n\t\"dependencies\": {\n\t\t\"@apidevtools/swagger-parser\": \"^10.1.0\",\n\t\t\"chokidar\": \"~4.0.3\",\n\t\t\"commander\": \"^12.1.0\",\n\t\t\"dotenv\": \"~17.2.3\",\n\t\t\"fast-glob\": \"^3.3.2\",\n\t\t\"lodash.kebabcase\": \"^4.1.1\",\n\t\t\"openapi-typescript\": \"^7.4.2\",\n\t\t\"prompts\": \"~2.4.2\"\n\t},\n\t\"devDependencies\": {\n\t\t\"@geekmidas/testkit\": \"workspace:*\",\n\t\t\"@types/lodash.kebabcase\": \"^4.1.9\",\n\t\t\"@types/node\": \"~24.9.1\",\n\t\t\"@types/prompts\": \"~2.4.9\",\n\t\t\"typescript\": \"^5.8.2\",\n\t\t\"vitest\": \"^3.2.4\",\n\t\t\"zod\": \"~4.1.13\"\n\t},\n\t\"peerDependencies\": {\n\t\t\"@geekmidas/constructs\": \"workspace:~\",\n\t\t\"@geekmidas/envkit\": \"workspace:~\",\n\t\t\"@geekmidas/logger\": \"workspace:~\",\n\t\t\"@geekmidas/schema\": \"workspace:~\",\n\t\t\"@geekmidas/telescope\": \"workspace:~\"\n\t},\n\t\"peerDependenciesMeta\": {\n\t\t\"@geekmidas/telescope\": {\n\t\t\t\"optional\": true\n\t\t}\n\t}\n}\n","import { existsSync, mkdirSync } from 'node:fs';\nimport { readFile, unlink, writeFile } from 'node:fs/promises';\nimport { homedir } from 'node:os';\nimport { join } from 'node:path';\n\n/**\n * Stored credentials for various services\n */\nexport interface StoredCredentials {\n\tdokploy?: {\n\t\t/** API token */\n\t\ttoken: string;\n\t\t/** Dokploy endpoint URL */\n\t\tendpoint: string;\n\t\t/** Registry ID in Dokploy (for Docker image pulls) */\n\t\tregistryId?: string;\n\t\t/** When the credentials were stored */\n\t\tstoredAt: string;\n\t};\n}\n\n/**\n * Options for credential operations\n */\nexport interface CredentialOptions {\n\t/** Root directory for credentials storage (default: user home directory) */\n\troot?: string;\n}\n\n/**\n * Get the path to the credentials directory\n */\nexport function getCredentialsDir(options?: CredentialOptions): string {\n\tconst root = options?.root ?? homedir();\n\treturn join(root, '.gkm');\n}\n\n/**\n * Get the path to the credentials file\n */\nexport function getCredentialsPath(options?: CredentialOptions): string {\n\treturn join(getCredentialsDir(options), 'credentials.json');\n}\n\n/**\n * Ensure the credentials directory exists\n */\nfunction ensureCredentialsDir(options?: CredentialOptions): void {\n\tconst dir = getCredentialsDir(options);\n\tif (!existsSync(dir)) {\n\t\tmkdirSync(dir, { recursive: true, mode: 0o700 });\n\t}\n}\n\n/**\n * Read stored credentials from disk\n */\nexport async function readCredentials(\n\toptions?: CredentialOptions,\n): Promise<StoredCredentials> {\n\tconst path = getCredentialsPath(options);\n\n\tif (!existsSync(path)) {\n\t\treturn {};\n\t}\n\n\ttry {\n\t\tconst content = await readFile(path, 'utf-8');\n\t\treturn JSON.parse(content) as StoredCredentials;\n\t} catch {\n\t\treturn {};\n\t}\n}\n\n/**\n * Write credentials to disk\n */\nexport async function writeCredentials(\n\tcredentials: StoredCredentials,\n\toptions?: CredentialOptions,\n): Promise<void> {\n\tensureCredentialsDir(options);\n\tconst path = getCredentialsPath(options);\n\n\tawait writeFile(path, JSON.stringify(credentials, null, 2), {\n\t\tmode: 0o600, // Owner read/write only\n\t});\n}\n\n/**\n * Store Dokploy credentials\n */\nexport async function storeDokployCredentials(\n\ttoken: string,\n\tendpoint: string,\n\toptions?: CredentialOptions,\n): Promise<void> {\n\tconst credentials = await readCredentials(options);\n\n\tcredentials.dokploy = {\n\t\ttoken,\n\t\tendpoint,\n\t\tstoredAt: new Date().toISOString(),\n\t};\n\n\tawait writeCredentials(credentials, options);\n}\n\n/**\n * Get stored Dokploy credentials\n */\nexport async function getDokployCredentials(\n\toptions?: CredentialOptions,\n): Promise<{\n\ttoken: string;\n\tendpoint: string;\n\tregistryId?: string;\n} | null> {\n\tconst credentials = await readCredentials(options);\n\n\tif (!credentials.dokploy) {\n\t\treturn null;\n\t}\n\n\treturn {\n\t\ttoken: credentials.dokploy.token,\n\t\tendpoint: credentials.dokploy.endpoint,\n\t\tregistryId: credentials.dokploy.registryId,\n\t};\n}\n\n/**\n * Remove Dokploy credentials\n */\nexport async function removeDokployCredentials(\n\toptions?: CredentialOptions,\n): Promise<boolean> {\n\tconst credentials = await readCredentials(options);\n\n\tif (!credentials.dokploy) {\n\t\treturn false;\n\t}\n\n\tdelete credentials.dokploy;\n\tawait writeCredentials(credentials, options);\n\treturn true;\n}\n\n/**\n * Remove all stored credentials\n */\nexport async function removeAllCredentials(\n\toptions?: CredentialOptions,\n): Promise<void> {\n\tconst path = getCredentialsPath(options);\n\n\tif (existsSync(path)) {\n\t\tawait unlink(path);\n\t}\n}\n\n/**\n * Get Dokploy API token, checking stored credentials first, then environment\n */\nexport async function getDokployToken(\n\toptions?: CredentialOptions,\n): Promise<string | null> {\n\t// First check environment variable (takes precedence)\n\tconst envToken = process.env.DOKPLOY_API_TOKEN;\n\tif (envToken) {\n\t\treturn envToken;\n\t}\n\n\t// Then check stored credentials\n\tconst stored = await getDokployCredentials(options);\n\tif (stored) {\n\t\treturn stored.token;\n\t}\n\n\treturn null;\n}\n\n/**\n * Get Dokploy endpoint from stored credentials\n */\nexport async function getDokployEndpoint(\n\toptions?: CredentialOptions,\n): Promise<string | null> {\n\tconst stored = await getDokployCredentials(options);\n\treturn stored?.endpoint ?? null;\n}\n\n/**\n * Store Dokploy registry ID\n */\nexport async function storeDokployRegistryId(\n\tregistryId: string,\n\toptions?: CredentialOptions,\n): Promise<void> {\n\tconst credentials = await readCredentials(options);\n\n\tif (!credentials.dokploy) {\n\t\tthrow new Error(\n\t\t\t'Dokploy credentials not found. Run \"gkm login --service dokploy\" first.',\n\t\t);\n\t}\n\n\tcredentials.dokploy.registryId = registryId;\n\tawait writeCredentials(credentials, options);\n}\n\n/**\n * Get Dokploy registry ID from stored credentials\n */\nexport async function getDokployRegistryId(\n\toptions?: CredentialOptions,\n): Promise<string | undefined> {\n\tconst stored = await getDokployCredentials(options);\n\treturn stored?.registryId ?? undefined;\n}\n","import { stdin as input, stdout as output } from 'node:process';\nimport * as readline from 'node:readline/promises';\nimport {\n\tgetCredentialsPath,\n\tgetDokployCredentials,\n\tremoveDokployCredentials,\n\tstoreDokployCredentials,\n} from './credentials';\n\nconst logger = console;\n\nexport interface LoginOptions {\n\t/** Service to login to */\n\tservice: 'dokploy';\n\t/** API token (if not provided, will prompt) */\n\ttoken?: string;\n\t/** Endpoint URL */\n\tendpoint?: string;\n}\n\nexport interface LogoutOptions {\n\t/** Service to logout from */\n\tservice?: 'dokploy' | 'all';\n}\n\n/**\n * Validate Dokploy token by making a test API call\n */\nexport async function validateDokployToken(\n\tendpoint: string,\n\ttoken: string,\n): Promise<boolean> {\n\tconst { DokployApi } = await import('../deploy/dokploy-api');\n\tconst api = new DokployApi({ baseUrl: endpoint, token });\n\treturn api.validateToken();\n}\n\n/**\n * Prompt for input (handles both TTY and non-TTY)\n */\nasync function prompt(message: string, hidden = false): Promise<string> {\n\tif (!process.stdin.isTTY) {\n\t\tthrow new Error(\n\t\t\t'Interactive input required. Please provide --token option.',\n\t\t);\n\t}\n\n\tif (hidden) {\n\t\t// For hidden input, use raw mode directly without readline\n\t\tprocess.stdout.write(message);\n\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tlet value = '';\n\n\t\t\tconst cleanup = () => {\n\t\t\t\tprocess.stdin.setRawMode(false);\n\t\t\t\tprocess.stdin.pause();\n\t\t\t\tprocess.stdin.removeListener('data', onData);\n\t\t\t\tprocess.stdin.removeListener('error', onError);\n\t\t\t};\n\n\t\t\tconst onError = (err: Error) => {\n\t\t\t\tcleanup();\n\t\t\t\treject(err);\n\t\t\t};\n\n\t\t\tconst onData = (char: Buffer) => {\n\t\t\t\tconst c = char.toString();\n\n\t\t\t\tif (c === '\\n' || c === '\\r') {\n\t\t\t\t\tcleanup();\n\t\t\t\t\tprocess.stdout.write('\\n');\n\t\t\t\t\tresolve(value);\n\t\t\t\t} else if (c === '\\u0003') {\n\t\t\t\t\t// Ctrl+C\n\t\t\t\t\tcleanup();\n\t\t\t\t\tprocess.stdout.write('\\n');\n\t\t\t\t\tprocess.exit(1);\n\t\t\t\t} else if (c === '\\u007F' || c === '\\b') {\n\t\t\t\t\t// Backspace\n\t\t\t\t\tif (value.length > 0) {\n\t\t\t\t\t\tvalue = value.slice(0, -1);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tvalue += c;\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tprocess.stdin.setRawMode(true);\n\t\t\tprocess.stdin.resume();\n\t\t\tprocess.stdin.on('data', onData);\n\t\t\tprocess.stdin.on('error', onError);\n\t\t});\n\t} else {\n\t\t// For visible input, use readline\n\t\tconst rl = readline.createInterface({ input, output });\n\t\ttry {\n\t\t\treturn await rl.question(message);\n\t\t} finally {\n\t\t\trl.close();\n\t\t}\n\t}\n}\n\n/**\n * Login to a service\n */\nexport async function loginCommand(options: LoginOptions): Promise<void> {\n\tconst { service, token: providedToken, endpoint: providedEndpoint } = options;\n\n\tif (service === 'dokploy') {\n\t\tlogger.log('\\n🔐 Logging in to Dokploy...\\n');\n\n\t\t// Get endpoint\n\t\tlet endpoint = providedEndpoint;\n\t\tif (!endpoint) {\n\t\t\tendpoint = await prompt(\n\t\t\t\t'Dokploy URL (e.g., https://dokploy.example.com): ',\n\t\t\t);\n\t\t}\n\n\t\t// Normalize endpoint (remove trailing slash)\n\t\tendpoint = endpoint.replace(/\\/$/, '');\n\n\t\t// Validate endpoint format\n\t\ttry {\n\t\t\tnew URL(endpoint);\n\t\t} catch {\n\t\t\tlogger.error('Invalid URL format');\n\t\t\tprocess.exit(1);\n\t\t}\n\n\t\t// Get token\n\t\tlet token = providedToken;\n\t\tif (!token) {\n\t\t\tlogger.log(`\\nGenerate a token at: ${endpoint}/settings/profile\\n`);\n\t\t\ttoken = await prompt('API Token: ', true);\n\t\t}\n\n\t\tif (!token) {\n\t\t\tlogger.error('Token is required');\n\t\t\tprocess.exit(1);\n\t\t}\n\n\t\t// Validate token\n\t\tlogger.log('\\nValidating credentials...');\n\t\tconst isValid = await validateDokployToken(endpoint, token);\n\n\t\tif (!isValid) {\n\t\t\tlogger.error(\n\t\t\t\t'\\n✗ Invalid credentials. Please check your token and try again.',\n\t\t\t);\n\t\t\tprocess.exit(1);\n\t\t}\n\n\t\t// Store credentials\n\t\tawait storeDokployCredentials(token, endpoint);\n\n\t\tlogger.log('\\n✓ Successfully logged in to Dokploy!');\n\t\tlogger.log(` Endpoint: ${endpoint}`);\n\t\tlogger.log(` Credentials stored in: ${getCredentialsPath()}`);\n\t\tlogger.log(\n\t\t\t'\\nYou can now use deploy commands without setting DOKPLOY_API_TOKEN.',\n\t\t);\n\t}\n}\n\n/**\n * Logout from a service\n */\nexport async function logoutCommand(options: LogoutOptions): Promise<void> {\n\tconst { service = 'dokploy' } = options;\n\n\tif (service === 'all') {\n\t\tconst dokployRemoved = await removeDokployCredentials();\n\n\t\tif (dokployRemoved) {\n\t\t\tlogger.log('\\n✓ Logged out from all services');\n\t\t} else {\n\t\t\tlogger.log('\\nNo stored credentials found');\n\t\t}\n\t\treturn;\n\t}\n\n\tif (service === 'dokploy') {\n\t\tconst removed = await removeDokployCredentials();\n\n\t\tif (removed) {\n\t\t\tlogger.log('\\n✓ Logged out from Dokploy');\n\t\t} else {\n\t\t\tlogger.log('\\nNo Dokploy credentials found');\n\t\t}\n\t}\n}\n\n/**\n * Show current login status\n */\nexport async function whoamiCommand(): Promise<void> {\n\tlogger.log('\\n📋 Current credentials:\\n');\n\n\tconst dokploy = await getDokployCredentials();\n\n\tif (dokploy) {\n\t\tlogger.log(' Dokploy:');\n\t\tlogger.log(` Endpoint: ${dokploy.endpoint}`);\n\t\tlogger.log(` Token: ${maskToken(dokploy.token)}`);\n\t} else {\n\t\tlogger.log(' Dokploy: Not logged in');\n\t}\n\n\tlogger.log(`\\n Credentials file: ${getCredentialsPath()}`);\n}\n\n/**\n * Mask a token for display\n */\nexport function maskToken(token: string): string {\n\tif (token.length <= 8) {\n\t\treturn '****';\n\t}\n\treturn `${token.slice(0, 4)}...${token.slice(-4)}`;\n}\n\n// Re-export credentials utilities for use in other modules\nexport {\n\tgetDokployCredentials,\n\tgetDokployEndpoint,\n\tgetDokployRegistryId,\n\tgetDokployToken,\n\tstoreDokployCredentials,\n\tstoreDokployRegistryId,\n} from './credentials';\n","import type {\n\tAWSApiGatewayConfig,\n\tAWSLambdaConfig,\n\tBuildOptions,\n\tGkmConfig,\n\tLegacyProvider,\n\tMainProvider,\n\tProvidersConfig,\n\tServerConfig,\n} from '../types';\n\nexport interface ResolvedProviders {\n\tproviders: LegacyProvider[];\n\tenableOpenApi: boolean;\n}\n\n/**\n * Resolves provider configuration from the new simplified system\n * to the internal legacy format for backward compatibility\n */\nexport function resolveProviders(\n\tconfig: GkmConfig,\n\toptions: BuildOptions,\n): ResolvedProviders {\n\tconst providers: LegacyProvider[] = [];\n\tlet enableOpenApi = options.enableOpenApi || false;\n\n\t// Handle legacy providers option (deprecated)\n\tif (options.providers) {\n\t\treturn {\n\t\t\tproviders: options.providers,\n\t\t\tenableOpenApi,\n\t\t};\n\t}\n\n\t// Handle new provider option\n\tif (options.provider) {\n\t\tconst resolvedProviders = resolveMainProvider(\n\t\t\toptions.provider,\n\t\t\tconfig.providers,\n\t\t);\n\t\tproviders.push(...resolvedProviders.providers);\n\t\tenableOpenApi = resolvedProviders.enableOpenApi || enableOpenApi;\n\t}\n\t// Default: build all configured providers\n\telse if (config.providers) {\n\t\tconst resolvedProviders = resolveAllConfiguredProviders(config.providers);\n\t\tproviders.push(...resolvedProviders.providers);\n\t\tenableOpenApi = resolvedProviders.enableOpenApi || enableOpenApi;\n\t}\n\t// Fallback: use default AWS configuration\n\telse {\n\t\tproviders.push('aws-apigatewayv2', 'aws-lambda');\n\t}\n\n\treturn {\n\t\tproviders: [...new Set(providers)], // Remove duplicates\n\t\tenableOpenApi,\n\t};\n}\n\nfunction resolveMainProvider(\n\tmainProvider: MainProvider,\n\tprovidersConfig?: ProvidersConfig,\n): ResolvedProviders {\n\tconst providers: LegacyProvider[] = [];\n\tlet enableOpenApi = false;\n\n\tif (mainProvider === 'aws') {\n\t\tconst awsConfig = providersConfig?.aws;\n\n\t\t// Resolve API Gateway providers\n\t\tif (awsConfig?.apiGateway) {\n\t\t\tif (isEnabled(awsConfig.apiGateway.v1)) {\n\t\t\t\tproviders.push('aws-apigatewayv1');\n\t\t\t}\n\t\t\tif (isEnabled(awsConfig.apiGateway.v2)) {\n\t\t\t\tproviders.push('aws-apigatewayv2');\n\t\t\t}\n\t\t} else {\n\t\t\t// Default: enable v2 if no specific config\n\t\t\tproviders.push('aws-apigatewayv2');\n\t\t}\n\n\t\t// Resolve Lambda providers\n\t\tif (awsConfig?.lambda) {\n\t\t\tif (\n\t\t\t\tisEnabled(awsConfig.lambda.functions) ||\n\t\t\t\tisEnabled(awsConfig.lambda.crons)\n\t\t\t) {\n\t\t\t\tproviders.push('aws-lambda');\n\t\t\t}\n\t\t} else {\n\t\t\t// Default: enable lambda if no specific config\n\t\t\tproviders.push('aws-lambda');\n\t\t}\n\t} else if (mainProvider === 'server') {\n\t\tproviders.push('server');\n\t\tconst serverConfig = providersConfig?.server;\n\n\t\tif (typeof serverConfig === 'object' && serverConfig?.enableOpenApi) {\n\t\t\tenableOpenApi = true;\n\t\t}\n\t}\n\n\treturn { providers, enableOpenApi };\n}\n\nfunction resolveAllConfiguredProviders(\n\tprovidersConfig: ProvidersConfig,\n): ResolvedProviders {\n\tconst providers: LegacyProvider[] = [];\n\tlet enableOpenApi = false;\n\n\t// AWS providers\n\tif (providersConfig.aws) {\n\t\tconst awsProviders = resolveMainProvider('aws', providersConfig);\n\t\tproviders.push(...awsProviders.providers);\n\t}\n\n\t// Server provider\n\tif (providersConfig.server && isEnabled(providersConfig.server)) {\n\t\tproviders.push('server');\n\t\tif (\n\t\t\ttypeof providersConfig.server === 'object' &&\n\t\t\tprovidersConfig.server.enableOpenApi\n\t\t) {\n\t\t\tenableOpenApi = true;\n\t\t}\n\t}\n\n\treturn { providers, enableOpenApi };\n}\n\nfunction isEnabled(\n\tconfig:\n\t\t| boolean\n\t\t| AWSApiGatewayConfig\n\t\t| AWSLambdaConfig\n\t\t| ServerConfig\n\t\t| undefined,\n): boolean {\n\tif (config === undefined) return false;\n\tif (typeof config === 'boolean') return config;\n\treturn config.enabled !== false; // Default to true if enabled is not explicitly false\n}\n\n/**\n * Gets configuration for a specific AWS service\n */\nexport function getAWSServiceConfig<\n\tT extends AWSApiGatewayConfig | AWSLambdaConfig,\n>(\n\tconfig: GkmConfig,\n\tservice: 'apiGateway' | 'lambda',\n\tsubService?: 'v1' | 'v2' | 'functions' | 'crons',\n): T | undefined {\n\tconst awsConfig = config.providers?.aws;\n\tif (!awsConfig) return undefined;\n\n\tif (service === 'apiGateway' && awsConfig.apiGateway) {\n\t\tconst apiConfig = subService\n\t\t\t? awsConfig.apiGateway[subService as 'v1' | 'v2']\n\t\t\t: undefined;\n\t\treturn typeof apiConfig === 'object' ? (apiConfig as T) : undefined;\n\t}\n\n\tif (service === 'lambda' && awsConfig.lambda) {\n\t\tconst lambdaConfig = subService\n\t\t\t? awsConfig.lambda[subService as 'functions' | 'crons']\n\t\t\t: undefined;\n\t\treturn typeof lambdaConfig === 'object' ? (lambdaConfig as T) : undefined;\n\t}\n\n\treturn undefined;\n}\n\n/**\n * Gets server configuration\n */\nexport function getServerConfig(config: GkmConfig): ServerConfig | undefined {\n\tconst serverConfig = config.providers?.server;\n\treturn typeof serverConfig === 'object' ? serverConfig : undefined;\n}\n","import { mkdir, writeFile } from 'node:fs/promises';\nimport { dirname, join, relative } from 'node:path';\nimport { Cron } from '@geekmidas/constructs/crons';\nimport type { BuildContext } from '../build/types';\nimport type { CronInfo } from '../types';\nimport {\n\tConstructGenerator,\n\ttype GeneratedConstruct,\n\ttype GeneratorOptions,\n} from './Generator';\n\nexport class CronGenerator extends ConstructGenerator<\n\tCron<any, any, any, any, any, any, any, any>,\n\tCronInfo[]\n> {\n\tasync build(\n\t\tcontext: BuildContext,\n\t\tconstructs: GeneratedConstruct<\n\t\t\tCron<any, any, any, any, any, any, any, any>\n\t\t>[],\n\t\toutputDir: string,\n\t\toptions?: GeneratorOptions,\n\t): Promise<CronInfo[]> {\n\t\tconst provider = options?.provider || 'aws-lambda';\n\t\tconst logger = console;\n\t\tconst cronInfos: CronInfo[] = [];\n\n\t\tif (constructs.length === 0 || provider !== 'aws-lambda') {\n\t\t\treturn cronInfos;\n\t\t}\n\n\t\t// Create crons subdirectory\n\t\tconst cronsDir = join(outputDir, 'crons');\n\t\tawait mkdir(cronsDir, { recursive: true });\n\n\t\t// Generate cron handlers\n\t\tfor (const { key, construct, path } of constructs) {\n\t\t\tconst handlerFile = await this.generateCronHandler(\n\t\t\t\tcronsDir,\n\t\t\t\tpath.relative,\n\t\t\t\tkey,\n\t\t\t\tcontext,\n\t\t\t);\n\n\t\t\tcronInfos.push({\n\t\t\t\tname: key,\n\t\t\t\thandler: relative(process.cwd(), handlerFile).replace(\n\t\t\t\t\t/\\.ts$/,\n\t\t\t\t\t'.handler',\n\t\t\t\t),\n\t\t\t\tschedule: construct.schedule || 'rate(1 hour)',\n\t\t\t\ttimeout: construct.timeout,\n\t\t\t\tmemorySize: construct.memorySize,\n\t\t\t\tenvironment: await construct.getEnvironment(),\n\t\t\t});\n\n\t\t\tlogger.log(`Generated cron handler: ${key}`);\n\t\t}\n\n\t\treturn cronInfos;\n\t}\n\n\tisConstruct(\n\t\tvalue: any,\n\t): value is Cron<any, any, any, any, any, any, any, any> {\n\t\treturn Cron.isCron(value);\n\t}\n\n\tprivate async generateCronHandler(\n\t\toutputDir: string,\n\t\tsourceFile: string,\n\t\texportName: string,\n\t\tcontext: BuildContext,\n\t): Promise<string> {\n\t\tconst handlerFileName = `${exportName}.ts`;\n\t\tconst handlerPath = join(outputDir, handlerFileName);\n\n\t\tconst relativePath = relative(dirname(handlerPath), sourceFile);\n\t\tconst importPath = relativePath.replace(/\\.ts$/, '.js');\n\n\t\tconst relativeEnvParserPath = relative(\n\t\t\tdirname(handlerPath),\n\t\t\tcontext.envParserPath,\n\t\t);\n\t\tconst relativeLoggerPath = relative(\n\t\t\tdirname(handlerPath),\n\t\t\tcontext.loggerPath,\n\t\t);\n\n\t\tconst content = `import { AWSScheduledFunction } from '@geekmidas/constructs/crons';\nimport { ${exportName} } from '${importPath}';\nimport ${context.envParserImportPattern} from '${relativeEnvParserPath}';\nimport ${context.loggerImportPattern} from '${relativeLoggerPath}';\n\nconst adapter = new AWSScheduledFunction(envParser, ${exportName});\n\nexport const handler = adapter.handler;\n`;\n\n\t\tawait writeFile(handlerPath, content);\n\t\treturn handlerPath;\n\t}\n}\n","import { mkdir, writeFile } from 'node:fs/promises';\nimport { dirname, join, relative } from 'node:path';\nimport { Function } from '@geekmidas/constructs/functions';\nimport type { BuildContext } from '../build/types';\nimport type { FunctionInfo } from '../types';\nimport {\n\tConstructGenerator,\n\ttype GeneratedConstruct,\n\ttype GeneratorOptions,\n} from './Generator';\n\nexport class FunctionGenerator extends ConstructGenerator<\n\tFunction<any, any, any, any, any, any, any, any, any, any, any, any>,\n\tFunctionInfo[]\n> {\n\tisConstruct(\n\t\tvalue: any,\n\t): value is Function<\n\t\tany,\n\t\tany,\n\t\tany,\n\t\tany,\n\t\tany,\n\t\tany,\n\t\tany,\n\t\tany,\n\t\tany,\n\t\tany,\n\t\tany,\n\t\tany\n\t> {\n\t\treturn Function.isFunction(value);\n\t}\n\n\tasync build(\n\t\tcontext: BuildContext,\n\t\tconstructs: GeneratedConstruct<\n\t\t\tFunction<any, any, any, any, any, any, any, any, any, any, any, any>\n\t\t>[],\n\t\toutputDir: string,\n\t\toptions?: GeneratorOptions,\n\t): Promise<FunctionInfo[]> {\n\t\tconst provider = options?.provider || 'aws-lambda';\n\t\tconst logger = console;\n\t\tconst functionInfos: FunctionInfo[] = [];\n\n\t\tif (constructs.length === 0 || provider !== 'aws-lambda') {\n\t\t\treturn functionInfos;\n\t\t}\n\n\t\t// Create functions subdirectory\n\t\tconst functionsDir = join(outputDir, 'functions');\n\t\tawait mkdir(functionsDir, { recursive: true });\n\n\t\t// Generate function handlers\n\t\tfor (const { key, construct, path } of constructs) {\n\t\t\tconst handlerFile = await this.generateFunctionHandler(\n\t\t\t\tfunctionsDir,\n\t\t\t\tpath.relative,\n\t\t\t\tkey,\n\t\t\t\tcontext,\n\t\t\t);\n\n\t\t\tfunctionInfos.push({\n\t\t\t\tname: key,\n\t\t\t\thandler: relative(process.cwd(), handlerFile).replace(\n\t\t\t\t\t/\\.ts$/,\n\t\t\t\t\t'.handler',\n\t\t\t\t),\n\t\t\t\ttimeout: construct.timeout,\n\t\t\t\tmemorySize: construct.memorySize,\n\t\t\t\tenvironment: await construct.getEnvironment(),\n\t\t\t});\n\n\t\t\tlogger.log(`Generated function handler: ${key}`);\n\t\t}\n\n\t\treturn functionInfos;\n\t}\n\n\tprivate async generateFunctionHandler(\n\t\toutputDir: string,\n\t\tsourceFile: string,\n\t\texportName: string,\n\t\tcontext: BuildContext,\n\t): Promise<string> {\n\t\tconst handlerFileName = `${exportName}.ts`;\n\t\tconst handlerPath = join(outputDir, handlerFileName);\n\n\t\tconst relativePath = relative(dirname(handlerPath), sourceFile);\n\t\tconst importPath = relativePath.replace(/\\.ts$/, '.js');\n\n\t\tconst relativeEnvParserPath = relative(\n\t\t\tdirname(handlerPath),\n\t\t\tcontext.envParserPath,\n\t\t);\n\t\tconst relativeLoggerPath = relative(\n\t\t\tdirname(handlerPath),\n\t\t\tcontext.loggerPath,\n\t\t);\n\n\t\tconst content = `import { AWSLambdaFunction } from '@geekmidas/constructs/functions';\nimport { ${exportName} } from '${importPath}';\nimport ${context.envParserImportPattern} from '${relativeEnvParserPath}';\nimport ${context.loggerImportPattern} from '${relativeLoggerPath}';\n\nconst adapter = new AWSLambdaFunction(envParser, ${exportName});\n\nexport const handler = adapter.handler;\n`;\n\n\t\tawait writeFile(handlerPath, content);\n\t\treturn handlerPath;\n\t}\n}\n","import { mkdir, writeFile } from 'node:fs/promises';\nimport { dirname, join, relative } from 'node:path';\nimport { Subscriber } from '@geekmidas/constructs/subscribers';\nimport type { BuildContext } from '../build/types';\nimport type { SubscriberInfo } from '../types';\nimport {\n\tConstructGenerator,\n\ttype GeneratedConstruct,\n\ttype GeneratorOptions,\n} from './Generator';\n\nexport class SubscriberGenerator extends ConstructGenerator<\n\tSubscriber<any, any, any, any, any, any>,\n\tSubscriberInfo[]\n> {\n\tisConstruct(value: any): value is Subscriber<any, any, any, any, any, any> {\n\t\treturn Subscriber.isSubscriber(value);\n\t}\n\n\tasync build(\n\t\tcontext: BuildContext,\n\t\tconstructs: GeneratedConstruct<Subscriber<any, any, any, any, any, any>>[],\n\t\toutputDir: string,\n\t\toptions?: GeneratorOptions,\n\t): Promise<SubscriberInfo[]> {\n\t\tconst provider = options?.provider || 'aws-lambda';\n\t\tconst logger = console;\n\t\tconst subscriberInfos: SubscriberInfo[] = [];\n\n\t\tif (provider === 'server') {\n\t\t\t// Generate subscribers.ts for server-based polling (even if empty)\n\t\t\tawait this.generateServerSubscribersFile(outputDir, constructs);\n\n\t\t\tlogger.log(\n\t\t\t\t`Generated server subscribers file with ${constructs.length} subscribers (polling mode)`,\n\t\t\t);\n\n\t\t\t// Return empty array as server subscribers don't have individual handlers\n\t\t\treturn subscriberInfos;\n\t\t}\n\n\t\tif (constructs.length === 0) {\n\t\t\treturn subscriberInfos;\n\t\t}\n\n\t\tif (provider !== 'aws-lambda') {\n\t\t\treturn subscriberInfos;\n\t\t}\n\n\t\t// Create subscribers subdirectory\n\t\tconst subscribersDir = join(outputDir, 'subscribers');\n\t\tawait mkdir(subscribersDir, { recursive: true });\n\n\t\t// Generate subscriber handlers\n\t\tfor (const { key, construct, path } of constructs) {\n\t\t\tconst handlerFile = await this.generateSubscriberHandler(\n\t\t\t\tsubscribersDir,\n\t\t\t\tpath.relative,\n\t\t\t\tkey,\n\t\t\t\tconstruct,\n\t\t\t\tcontext,\n\t\t\t);\n\n\t\t\tsubscriberInfos.push({\n\t\t\t\tname: key,\n\t\t\t\thandler: relative(process.cwd(), handlerFile).replace(\n\t\t\t\t\t/\\.ts$/,\n\t\t\t\t\t'.handler',\n\t\t\t\t),\n\t\t\t\tsubscribedEvents: construct.subscribedEvents || [],\n\t\t\t\ttimeout: construct.timeout,\n\t\t\t\tmemorySize: construct.memorySize,\n\t\t\t\tenvironment: await construct.getEnvironment(),\n\t\t\t});\n\n\t\t\tlogger.log(`Generated subscriber handler: ${key}`);\n\t\t}\n\n\t\treturn subscriberInfos;\n\t}\n\n\tprivate async generateSubscriberHandler(\n\t\toutputDir: string,\n\t\tsourceFile: string,\n\t\texportName: string,\n\t\t_subscriber: Subscriber<any, any, any, any, any, any>,\n\t\tcontext: BuildContext,\n\t): Promise<string> {\n\t\tconst handlerFileName = `${exportName}.ts`;\n\t\tconst handlerPath = join(outputDir, handlerFileName);\n\n\t\tconst relativePath = relative(dirname(handlerPath), sourceFile);\n\t\tconst importPath = relativePath.replace(/\\.ts$/, '.js');\n\n\t\tconst relativeEnvParserPath = relative(\n\t\t\tdirname(handlerPath),\n\t\t\tcontext.envParserPath,\n\t\t);\n\n\t\tconst content = `import { AWSLambdaSubscriber } from '@geekmidas/constructs/aws';\nimport { ${exportName} } from '${importPath}';\nimport ${context.envParserImportPattern} from '${relativeEnvParserPath}';\n\nconst adapter = new AWSLambdaSubscriber(envParser, ${exportName});\n\nexport const handler = adapter.handler;\n`;\n\n\t\tawait writeFile(handlerPath, content);\n\t\treturn handlerPath;\n\t}\n\n\tprivate async generateServerSubscribersFile(\n\t\toutputDir: string,\n\t\tsubscribers: GeneratedConstruct<Subscriber<any, any, any, any, any, any>>[],\n\t): Promise<string> {\n\t\t// Ensure output directory exists\n\t\tawait mkdir(outputDir, { recursive: true });\n\n\t\tconst subscribersFileName = 'subscribers.ts';\n\t\tconst subscribersPath = join(outputDir, subscribersFileName);\n\n\t\t// Group imports by file\n\t\tconst importsByFile = new Map<string, string[]>();\n\n\t\tfor (const { path, key } of subscribers) {\n\t\t\tconst relativePath = relative(dirname(subscribersPath), path.relative);\n\t\t\tconst importPath = relativePath.replace(/\\.ts$/, '.js');\n\n\t\t\tif (!importsByFile.has(importPath)) {\n\t\t\t\timportsByFile.set(importPath, []);\n\t\t\t}\n\t\t\timportsByFile.get(importPath)?.push(key);\n\t\t}\n\n\t\t// Generate import statements\n\t\tconst imports = Array.from(importsByFile.entries())\n\t\t\t.map(\n\t\t\t\t([importPath, exports]) =>\n\t\t\t\t\t`import { ${exports.join(', ')} } from '${importPath}';`,\n\t\t\t)\n\t\t\t.join('\\n');\n\n\t\tconst allExportNames = subscribers.map(({ key }) => key);\n\n\t\tconst content = `/**\n * Generated subscribers setup\n *\n * ⚠️ WARNING: This is for LOCAL DEVELOPMENT ONLY\n * This uses event polling which is not suitable for production.\n *\n * For production, use AWS Lambda with SQS/SNS event source mappings.\n * Lambda automatically:\n * - Scales based on queue depth\n * - Handles batch processing and retries\n * - Manages dead letter queues\n * - Provides better cost optimization\n *\n * This polling implementation is useful for:\n * - Local development and testing\n * - Understanding event flow without Lambda deployment\n *\n * Supported connection strings:\n * - sqs://region/account-id/queue-name (SQS queue)\n * - sns://region/account-id/topic-name (SNS topic)\n * - rabbitmq://host:port/queue-name (RabbitMQ)\n * - basic://in-memory (In-memory for testing)\n */\nimport type { EnvironmentParser } from '@geekmidas/envkit';\nimport type { Logger } from '@geekmidas/logger';\nimport { EventConnectionFactory, Subscriber } from '@geekmidas/events';\nimport type { EventConnection, EventSubscriber } from '@geekmidas/events';\nimport { ServiceDiscovery } from '@geekmidas/services';\n${imports}\n\nconst subscribers = [\n ${allExportNames.join(',\\n ')}\n];\n\nconst activeSubscribers: EventSubscriber<any>[] = [];\n\nexport async function setupSubscribers(\n envParser: EnvironmentParser<any>,\n logger: Logger,\n): Promise<void> {\n logger.info('Setting up subscribers in polling mode (local development)');\n\n const config = envParser.create((get) => ({\n connectionString: get('EVENT_SUBSCRIBER_CONNECTION_STRING').string().optional(),\n })).parse();\n\n if (!config.connectionString) {\n logger.warn('EVENT_SUBSCRIBER_CONNECTION_STRING not configured, skipping subscriber setup');\n return;\n }\n\n const serviceDiscovery = ServiceDiscovery.getInstance(envParser);\n\n // Create connection once, outside the loop (more efficient)\n // EventConnectionFactory automatically determines the right connection type\n let connection: EventConnection;\n try {\n connection = await EventConnectionFactory.fromConnectionString(config.connectionString);\n\n const connectionType = new URL(config.connectionString).protocol.replace(':', '');\n logger.info({ connectionType }, 'Created shared event connection');\n } catch (error) {\n logger.error({ error }, 'Failed to create event connection');\n return;\n }\n\n for (const subscriber of subscribers) {\n try {\n // Create subscriber from shared connection\n const eventSubscriber = await Subscriber.fromConnection(connection);\n\n // Register services\n const services = subscriber.services.length > 0\n ? await serviceDiscovery.register(subscriber.services)\n : {};\n\n // Subscribe to events\n const subscribedEvents = subscriber.subscribedEvents || [];\n\n if (subscribedEvents.length === 0) {\n logger.warn({ subscriber: subscriber.constructor.name }, 'Subscriber has no subscribed events, skipping');\n continue;\n }\n\n await eventSubscriber.subscribe(subscribedEvents, async (event) => {\n try {\n // Process single event (batch of 1)\n await subscriber.handler({\n events: [event],\n services: services as any,\n logger: subscriber.logger,\n });\n\n logger.debug({ eventType: event.type }, 'Successfully processed event');\n } catch (error) {\n logger.error({ error, event }, 'Failed to process event');\n // Event will become visible again for retry\n }\n });\n\n activeSubscribers.push(eventSubscriber);\n\n logger.info(\n {\n events: subscribedEvents,\n },\n 'Subscriber started polling'\n );\n } catch (error) {\n logger.error({ error, subscriber: subscriber.constructor.name }, 'Failed to setup subscriber');\n }\n }\n\n // Setup graceful shutdown\n const shutdown = () => {\n logger.info('Stopping all subscribers');\n for (const eventSubscriber of activeSubscribers) {\n connection.stop();\n }\n };\n\n process.on('SIGTERM', shutdown);\n process.on('SIGINT', shutdown);\n}\n`;\n\n\t\tawait writeFile(subscribersPath, content);\n\t\treturn subscribersPath;\n\t}\n}\n","import { type ChildProcess, execSync, spawn } from 'node:child_process';\nimport { existsSync } from 'node:fs';\nimport { mkdir } from 'node:fs/promises';\nimport { createServer } from 'node:net';\nimport { join, resolve } from 'node:path';\nimport chokidar from 'chokidar';\nimport { config as dotenvConfig } from 'dotenv';\nimport fg from 'fast-glob';\nimport { resolveProviders } from '../build/providerResolver';\nimport type {\n\tBuildContext,\n\tNormalizedHooksConfig,\n\tNormalizedProductionConfig,\n\tNormalizedStudioConfig,\n\tNormalizedTelescopeConfig,\n} from '../build/types';\nimport { loadConfig, parseModuleConfig } from '../config';\nimport {\n\tCronGenerator,\n\tEndpointGenerator,\n\tFunctionGenerator,\n\tSubscriberGenerator,\n} from '../generators';\nimport {\n\tgenerateOpenApi,\n\tOPENAPI_OUTPUT_PATH,\n\tresolveOpenApiConfig,\n} from '../openapi';\nimport type {\n\tGkmConfig,\n\tLegacyProvider,\n\tProductionConfig,\n\tRuntime,\n\tServerConfig,\n\tStudioConfig,\n\tTelescopeConfig,\n} from '../types';\n\nconst logger = console;\n\n/**\n * Load environment files\n * @internal Exported for testing\n */\nexport function loadEnvFiles(\n\tenvConfig: string | string[] | undefined,\n\tcwd: string = process.cwd(),\n): { loaded: string[]; missing: string[] } {\n\tconst loaded: string[] = [];\n\tconst missing: string[] = [];\n\n\t// Normalize to array\n\tconst envFiles = envConfig\n\t\t? Array.isArray(envConfig)\n\t\t\t? envConfig\n\t\t\t: [envConfig]\n\t\t: ['.env'];\n\n\t// Load each env file in order (later files override earlier)\n\tfor (const envFile of envFiles) {\n\t\tconst envPath = resolve(cwd, envFile);\n\t\tif (existsSync(envPath)) {\n\t\t\tdotenvConfig({ path: envPath, override: true, quiet: true });\n\t\t\tloaded.push(envFile);\n\t\t} else if (envConfig) {\n\t\t\t// Only report as missing if explicitly configured\n\t\t\tmissing.push(envFile);\n\t\t}\n\t}\n\n\treturn { loaded, missing };\n}\n\n/**\n * Check if a port is available\n * @internal Exported for testing\n */\nexport async function isPortAvailable(port: number): Promise<boolean> {\n\treturn new Promise((resolve) => {\n\t\tconst server = createServer();\n\n\t\tserver.once('error', (err: NodeJS.ErrnoException) => {\n\t\t\tif (err.code === 'EADDRINUSE') {\n\t\t\t\tresolve(false);\n\t\t\t} else {\n\t\t\t\tresolve(false);\n\t\t\t}\n\t\t});\n\n\t\tserver.once('listening', () => {\n\t\t\tserver.close();\n\t\t\tresolve(true);\n\t\t});\n\n\t\tserver.listen(port);\n\t});\n}\n\n/**\n * Find an available port starting from the preferred port\n * @internal Exported for testing\n */\nexport async function findAvailablePort(\n\tpreferredPort: number,\n\tmaxAttempts = 10,\n): Promise<number> {\n\tfor (let i = 0; i < maxAttempts; i++) {\n\t\tconst port = preferredPort + i;\n\t\tif (await isPortAvailable(port)) {\n\t\t\treturn port;\n\t\t}\n\t\tlogger.log(`⚠️ Port ${port} is in use, trying ${port + 1}...`);\n\t}\n\n\tthrow new Error(\n\t\t`Could not find an available port after trying ${maxAttempts} ports starting from ${preferredPort}`,\n\t);\n}\n\n/**\n * Normalize telescope configuration\n * @internal Exported for testing\n */\nexport function normalizeTelescopeConfig(\n\tconfig: GkmConfig['telescope'],\n): NormalizedTelescopeConfig | undefined {\n\tif (config === false) {\n\t\treturn undefined;\n\t}\n\n\t// Handle string path (e.g., './src/config/telescope')\n\tif (typeof config === 'string') {\n\t\tconst { path: telescopePath, importPattern: telescopeImportPattern } =\n\t\t\tparseModuleConfig(config, 'telescope');\n\n\t\treturn {\n\t\t\tenabled: true,\n\t\t\ttelescopePath,\n\t\t\ttelescopeImportPattern,\n\t\t\tpath: '/__telescope',\n\t\t\tignore: [],\n\t\t\trecordBody: true,\n\t\t\tmaxEntries: 1000,\n\t\t\twebsocket: true,\n\t\t};\n\t}\n\n\t// Default to enabled in development mode\n\tconst isEnabled =\n\t\tconfig === true || config === undefined || config.enabled !== false;\n\n\tif (!isEnabled) {\n\t\treturn undefined;\n\t}\n\n\tconst telescopeConfig: TelescopeConfig =\n\t\ttypeof config === 'object' ? config : {};\n\n\treturn {\n\t\tenabled: true,\n\t\tpath: telescopeConfig.path ?? '/__telescope',\n\t\tignore: telescopeConfig.ignore ?? [],\n\t\trecordBody: telescopeConfig.recordBody ?? true,\n\t\tmaxEntries: telescopeConfig.maxEntries ?? 1000,\n\t\twebsocket: telescopeConfig.websocket ?? true,\n\t};\n}\n\n/**\n * Normalize studio configuration\n * @internal Exported for testing\n */\nexport function normalizeStudioConfig(\n\tconfig: GkmConfig['studio'],\n): NormalizedStudioConfig | undefined {\n\tif (config === false) {\n\t\treturn undefined;\n\t}\n\n\t// Handle string path (e.g., './src/config/studio')\n\tif (typeof config === 'string') {\n\t\tconst { path: studioPath, importPattern: studioImportPattern } =\n\t\t\tparseModuleConfig(config, 'studio');\n\n\t\treturn {\n\t\t\tenabled: true,\n\t\t\tstudioPath,\n\t\t\tstudioImportPattern,\n\t\t\tpath: '/__studio',\n\t\t\tschema: 'public',\n\t\t};\n\t}\n\n\t// Default to enabled in development mode\n\tconst isEnabled =\n\t\tconfig === true || config === undefined || config.enabled !== false;\n\n\tif (!isEnabled) {\n\t\treturn undefined;\n\t}\n\n\tconst studioConfig: StudioConfig = typeof config === 'object' ? config : {};\n\n\treturn {\n\t\tenabled: true,\n\t\tpath: studioConfig.path ?? '/__studio',\n\t\tschema: studioConfig.schema ?? 'public',\n\t};\n}\n\n/**\n * Normalize hooks configuration\n * @internal Exported for testing\n */\nexport function normalizeHooksConfig(\n\tconfig: GkmConfig['hooks'],\n): NormalizedHooksConfig | undefined {\n\tif (!config?.server) {\n\t\treturn undefined;\n\t}\n\n\t// Resolve the path (handle .ts extension)\n\tconst serverPath = config.server.endsWith('.ts')\n\t\t? config.server\n\t\t: `${config.server}.ts`;\n\n\tconst resolvedPath = resolve(process.cwd(), serverPath);\n\n\treturn {\n\t\tserverHooksPath: resolvedPath,\n\t};\n}\n\n/**\n * Normalize production configuration\n * @internal Exported for testing\n */\nexport function normalizeProductionConfig(\n\tcliProduction: boolean,\n\tconfigProduction?: ProductionConfig,\n): NormalizedProductionConfig | undefined {\n\t// Production mode is only enabled if --production CLI flag is passed\n\tif (!cliProduction) {\n\t\treturn undefined;\n\t}\n\n\t// Merge CLI flag with config options\n\tconst config = configProduction ?? {};\n\n\treturn {\n\t\tenabled: true,\n\t\tbundle: config.bundle ?? true,\n\t\tminify: config.minify ?? true,\n\t\thealthCheck: config.healthCheck ?? '/health',\n\t\tgracefulShutdown: config.gracefulShutdown ?? true,\n\t\texternal: config.external ?? [],\n\t\tsubscribers: config.subscribers ?? 'exclude',\n\t\topenapi: config.openapi ?? false,\n\t\toptimizedHandlers: config.optimizedHandlers ?? true, // Default to optimized handlers in production\n\t};\n}\n\n/**\n * Get production config from GkmConfig\n * @internal\n */\nexport function getProductionConfigFromGkm(\n\tconfig: GkmConfig,\n): ProductionConfig | undefined {\n\tconst serverConfig = config.providers?.server;\n\tif (typeof serverConfig === 'object') {\n\t\treturn (serverConfig as ServerConfig).production;\n\t}\n\treturn undefined;\n}\n\nexport interface DevOptions {\n\tport?: number;\n\tportExplicit?: boolean;\n\tenableOpenApi?: boolean;\n}\n\nexport async function devCommand(options: DevOptions): Promise<void> {\n\t// Load default .env file BEFORE loading config\n\t// This ensures env vars are available when config and its dependencies are loaded\n\tconst defaultEnv = loadEnvFiles('.env');\n\tif (defaultEnv.loaded.length > 0) {\n\t\tlogger.log(`📦 Loaded env: ${defaultEnv.loaded.join(', ')}`);\n\t}\n\n\tconst config = await loadConfig();\n\n\t// Load any additional env files specified in config\n\tif (config.env) {\n\t\tconst { loaded, missing } = loadEnvFiles(config.env);\n\t\tif (loaded.length > 0) {\n\t\t\tlogger.log(`📦 Loaded env: ${loaded.join(', ')}`);\n\t\t}\n\t\tif (missing.length > 0) {\n\t\t\tlogger.warn(`⚠️ Missing env files: ${missing.join(', ')}`);\n\t\t}\n\t}\n\n\t// Force server provider for dev mode\n\tconst resolved = resolveProviders(config, { provider: 'server' });\n\n\tlogger.log('🚀 Starting development server...');\n\tlogger.log(`Loading routes from: ${config.routes}`);\n\tif (config.functions) {\n\t\tlogger.log(`Loading functions from: ${config.functions}`);\n\t}\n\tif (config.crons) {\n\t\tlogger.log(`Loading crons from: ${config.crons}`);\n\t}\n\tif (config.subscribers) {\n\t\tlogger.log(`Loading subscribers from: ${config.subscribers}`);\n\t}\n\tlogger.log(`Using envParser: ${config.envParser}`);\n\n\t// Parse envParser and logger configuration\n\tconst { path: envParserPath, importPattern: envParserImportPattern } =\n\t\tparseModuleConfig(config.envParser, 'envParser');\n\tconst { path: loggerPath, importPattern: loggerImportPattern } =\n\t\tparseModuleConfig(config.logger, 'logger');\n\n\t// Normalize telescope configuration\n\tconst telescope = normalizeTelescopeConfig(config.telescope);\n\tif (telescope) {\n\t\tlogger.log(`🔭 Telescope enabled at ${telescope.path}`);\n\t}\n\n\t// Normalize studio configuration\n\tconst studio = normalizeStudioConfig(config.studio);\n\tif (studio) {\n\t\tlogger.log(`🗄️ Studio enabled at ${studio.path}`);\n\t}\n\n\t// Normalize hooks configuration\n\tconst hooks = normalizeHooksConfig(config.hooks);\n\tif (hooks) {\n\t\tlogger.log(`🪝 Server hooks enabled from ${config.hooks?.server}`);\n\t}\n\n\t// Resolve OpenAPI configuration\n\tconst openApiConfig = resolveOpenApiConfig(config);\n\t// Enable OpenAPI docs endpoint if either root config or provider config enables it\n\tconst enableOpenApi = openApiConfig.enabled || resolved.enableOpenApi;\n\tif (enableOpenApi) {\n\t\tlogger.log(`📄 OpenAPI output: ${OPENAPI_OUTPUT_PATH}`);\n\t}\n\n\tconst buildContext: BuildContext = {\n\t\tenvParserPath,\n\t\tenvParserImportPattern,\n\t\tloggerPath,\n\t\tloggerImportPattern,\n\t\ttelescope,\n\t\tstudio,\n\t\thooks,\n\t};\n\n\t// Build initial version\n\tawait buildServer(\n\t\tconfig,\n\t\tbuildContext,\n\t\tresolved.providers[0] as LegacyProvider,\n\t\tenableOpenApi,\n\t);\n\n\t// Generate OpenAPI spec on startup\n\tif (enableOpenApi) {\n\t\tawait generateOpenApi(config);\n\t}\n\n\t// Determine runtime (default to node)\n\tconst runtime: Runtime = config.runtime ?? 'node';\n\n\t// Start the dev server\n\tconst devServer = new DevServer(\n\t\tresolved.providers[0] as LegacyProvider,\n\t\toptions.port || 3000,\n\t\toptions.portExplicit ?? false,\n\t\tenableOpenApi,\n\t\ttelescope,\n\t\tstudio,\n\t\truntime,\n\t);\n\n\tawait devServer.start();\n\n\t// Watch for file changes\n\tconst envParserFile = config.envParser.split('#')[0] ?? config.envParser;\n\tconst loggerFile = config.logger.split('#')[0] ?? config.logger;\n\n\t// Get hooks file path for watching\n\tconst hooksFileParts = config.hooks?.server?.split('#');\n\tconst hooksFile = hooksFileParts?.[0];\n\n\tconst watchPatterns = [\n\t\tconfig.routes,\n\t\t...(config.functions ? [config.functions] : []),\n\t\t...(config.crons ? [config.crons] : []),\n\t\t...(config.subscribers ? [config.subscribers] : []),\n\t\t// Add .ts extension if not present for config files\n\t\tenvParserFile.endsWith('.ts') ? envParserFile : `${envParserFile}.ts`,\n\t\tloggerFile.endsWith('.ts') ? loggerFile : `${loggerFile}.ts`,\n\t\t// Add hooks file to watch list\n\t\t...(hooksFile\n\t\t\t? [hooksFile.endsWith('.ts') ? hooksFile : `${hooksFile}.ts`]\n\t\t\t: []),\n\t]\n\t\t.flat()\n\t\t.filter((p): p is string => typeof p === 'string');\n\n\t// Normalize patterns - remove leading ./ when using cwd option\n\tconst normalizedPatterns = watchPatterns.map((p) =>\n\t\tp.startsWith('./') ? p.slice(2) : p,\n\t);\n\n\tlogger.log(`👀 Watching for changes in: ${normalizedPatterns.join(', ')}`);\n\n\t// Resolve glob patterns to actual files (chokidar 4.x doesn't support globs)\n\tconst resolvedFiles = await fg(normalizedPatterns, {\n\t\tcwd: process.cwd(),\n\t\tabsolute: false,\n\t\tonlyFiles: true,\n\t});\n\n\t// Also watch the directories for new files\n\tconst dirsToWatch = [\n\t\t...new Set(\n\t\t\tresolvedFiles.map((f) => {\n\t\t\t\tconst parts = f.split('/');\n\t\t\t\treturn parts.slice(0, -1).join('/');\n\t\t\t}),\n\t\t),\n\t];\n\n\tlogger.log(\n\t\t`📁 Found ${resolvedFiles.length} files in ${dirsToWatch.length} directories`,\n\t);\n\n\tconst watcher = chokidar.watch([...resolvedFiles, ...dirsToWatch], {\n\t\tignored: /(^|[/\\\\])\\../, // ignore dotfiles\n\t\tpersistent: true,\n\t\tignoreInitial: true,\n\t\tcwd: process.cwd(),\n\t});\n\n\twatcher.on('ready', () => {\n\t\tlogger.log('🔍 File watcher ready');\n\t});\n\n\twatcher.on('error', (error) => {\n\t\tlogger.error('❌ Watcher error:', error);\n\t});\n\n\tlet rebuildTimeout: NodeJS.Timeout | null = null;\n\n\twatcher.on('change', async (path) => {\n\t\tlogger.log(`📝 File changed: ${path}`);\n\n\t\t// Debounce rebuilds\n\t\tif (rebuildTimeout) {\n\t\t\tclearTimeout(rebuildTimeout);\n\t\t}\n\n\t\trebuildTimeout = setTimeout(async () => {\n\t\t\ttry {\n\t\t\t\tlogger.log('🔄 Rebuilding...');\n\t\t\t\tawait buildServer(\n\t\t\t\t\tconfig,\n\t\t\t\t\tbuildContext,\n\t\t\t\t\tresolved.providers[0] as LegacyProvider,\n\t\t\t\t\tenableOpenApi,\n\t\t\t\t);\n\n\t\t\t\t// Regenerate OpenAPI if enabled\n\t\t\t\tif (enableOpenApi) {\n\t\t\t\t\tawait generateOpenApi(config, { silent: true });\n\t\t\t\t}\n\n\t\t\t\tlogger.log('✅ Rebuild complete, restarting server...');\n\t\t\t\tawait devServer.restart();\n\t\t\t} catch (error) {\n\t\t\t\tlogger.error('❌ Rebuild failed:', (error as Error).message);\n\t\t\t}\n\t\t}, 300);\n\t});\n\n\t// Handle graceful shutdown\n\tlet isShuttingDown = false;\n\tconst shutdown = () => {\n\t\tif (isShuttingDown) return;\n\t\tisShuttingDown = true;\n\n\t\tlogger.log('\\n🛑 Shutting down...');\n\n\t\t// Use sync-style shutdown to ensure it completes before exit\n\t\tPromise.all([watcher.close(), devServer.stop()])\n\t\t\t.catch((err) => {\n\t\t\t\tlogger.error('Error during shutdown:', err);\n\t\t\t})\n\t\t\t.finally(() => {\n\t\t\t\tprocess.exit(0);\n\t\t\t});\n\t};\n\n\tprocess.on('SIGINT', shutdown);\n\tprocess.on('SIGTERM', shutdown);\n}\n\nasync function buildServer(\n\tconfig: any,\n\tcontext: BuildContext,\n\tprovider: LegacyProvider,\n\tenableOpenApi: boolean,\n): Promise<void> {\n\t// Initialize generators\n\tconst endpointGenerator = new EndpointGenerator();\n\tconst functionGenerator = new FunctionGenerator();\n\tconst cronGenerator = new CronGenerator();\n\tconst subscriberGenerator = new SubscriberGenerator();\n\n\t// Load all constructs\n\tconst [allEndpoints, allFunctions, allCrons, allSubscribers] =\n\t\tawait Promise.all([\n\t\t\tendpointGenerator.load(config.routes),\n\t\t\tconfig.functions ? functionGenerator.load(config.functions) : [],\n\t\t\tconfig.crons ? cronGenerator.load(config.crons) : [],\n\t\t\tconfig.subscribers ? subscriberGenerator.load(config.subscribers) : [],\n\t\t]);\n\n\t// Ensure .gkm directory exists\n\tconst outputDir = join(process.cwd(), '.gkm', provider);\n\tawait mkdir(outputDir, { recursive: true });\n\n\t// Build for server provider\n\tawait Promise.all([\n\t\tendpointGenerator.build(context, allEndpoints, outputDir, {\n\t\t\tprovider,\n\t\t\tenableOpenApi,\n\t\t}),\n\t\tfunctionGenerator.build(context, allFunctions, outputDir, { provider }),\n\t\tcronGenerator.build(context, allCrons, outputDir, { provider }),\n\t\tsubscriberGenerator.build(context, allSubscribers, outputDir, { provider }),\n\t]);\n}\n\nclass DevServer {\n\tprivate serverProcess: ChildProcess | null = null;\n\tprivate isRunning = false;\n\tprivate actualPort: number;\n\n\tconstructor(\n\t\tprivate provider: LegacyProvider,\n\t\tprivate requestedPort: number,\n\t\tprivate portExplicit: boolean,\n\t\tprivate enableOpenApi: boolean,\n\t\tprivate telescope?: NormalizedTelescopeConfig,\n\t\tprivate studio?: NormalizedStudioConfig,\n\t\tprivate runtime: Runtime = 'node',\n\t) {\n\t\tthis.actualPort = requestedPort;\n\t}\n\n\tasync start(): Promise<void> {\n\t\tif (this.isRunning) {\n\t\t\tawait this.stop();\n\t\t}\n\n\t\t// Check port availability\n\t\tif (this.portExplicit) {\n\t\t\t// Port was explicitly specified - throw if unavailable\n\t\t\tconst available = await isPortAvailable(this.requestedPort);\n\t\t\tif (!available) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Port ${this.requestedPort} is already in use. ` +\n\t\t\t\t\t\t`Either stop the process using that port or omit -p/--port to auto-select an available port.`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tthis.actualPort = this.requestedPort;\n\t\t} else {\n\t\t\t// Find an available port starting from the default\n\t\t\tthis.actualPort = await findAvailablePort(this.requestedPort);\n\n\t\t\tif (this.actualPort !== this.requestedPort) {\n\t\t\t\tlogger.log(\n\t\t\t\t\t`ℹ️ Port ${this.requestedPort} was in use, using port ${this.actualPort} instead`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\tconst serverEntryPath = join(\n\t\t\tprocess.cwd(),\n\t\t\t'.gkm',\n\t\t\tthis.provider,\n\t\t\t'server.ts',\n\t\t);\n\n\t\t// Create server entry file\n\t\tawait this.createServerEntry();\n\n\t\tlogger.log(`\\n✨ Starting server on port ${this.actualPort}...`);\n\n\t\t// Start the server using tsx (TypeScript execution)\n\t\t// Use detached: true so we can kill the entire process tree\n\t\tthis.serverProcess = spawn(\n\t\t\t'npx',\n\t\t\t['tsx', serverEntryPath, '--port', this.actualPort.toString()],\n\t\t\t{\n\t\t\t\tstdio: 'inherit',\n\t\t\t\tenv: { ...process.env, NODE_ENV: 'development' },\n\t\t\t\tdetached: true,\n\t\t\t},\n\t\t);\n\n\t\tthis.isRunning = true;\n\n\t\tthis.serverProcess.on('error', (error) => {\n\t\t\tlogger.error('❌ Server error:', error);\n\t\t});\n\n\t\tthis.serverProcess.on('exit', (code, signal) => {\n\t\t\tif (code !== null && code !== 0 && signal !== 'SIGTERM') {\n\t\t\t\tlogger.error(`❌ Server exited with code ${code}`);\n\t\t\t}\n\t\t\tthis.isRunning = false;\n\t\t});\n\n\t\t// Give the server a moment to start\n\t\tawait new Promise((resolve) => setTimeout(resolve, 1000));\n\n\t\tif (this.isRunning) {\n\t\t\tlogger.log(`\\n🎉 Server running at http://localhost:${this.actualPort}`);\n\t\t\tif (this.enableOpenApi) {\n\t\t\t\tlogger.log(\n\t\t\t\t\t`📚 API Docs available at http://localhost:${this.actualPort}/__docs`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (this.telescope) {\n\t\t\t\tlogger.log(\n\t\t\t\t\t`🔭 Telescope available at http://localhost:${this.actualPort}${this.telescope.path}`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (this.studio) {\n\t\t\t\tlogger.log(\n\t\t\t\t\t`🗄️ Studio available at http://localhost:${this.actualPort}${this.studio.path}`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\tasync stop(): Promise<void> {\n\t\tconst port = this.actualPort;\n\n\t\tif (this.serverProcess && this.isRunning) {\n\t\t\tconst pid = this.serverProcess.pid;\n\n\t\t\t// Use SIGKILL directly since the server ignores SIGTERM\n\t\t\tif (pid) {\n\t\t\t\ttry {\n\t\t\t\t\tprocess.kill(-pid, 'SIGKILL');\n\t\t\t\t} catch {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tprocess.kill(pid, 'SIGKILL');\n\t\t\t\t\t} catch {\n\t\t\t\t\t\t// Process might already be dead\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthis.serverProcess = null;\n\t\t\tthis.isRunning = false;\n\t\t}\n\n\t\t// Also kill any processes still holding the port\n\t\tthis.killProcessesOnPort(port);\n\t}\n\n\tprivate killProcessesOnPort(port: number): void {\n\t\ttry {\n\t\t\t// Use lsof to find PIDs on the port and kill them with -9\n\t\t\texecSync(`lsof -ti tcp:${port} | xargs kill -9 2>/dev/null || true`, {\n\t\t\t\tstdio: 'ignore',\n\t\t\t});\n\t\t} catch {\n\t\t\t// Ignore errors - port may already be free\n\t\t}\n\t}\n\n\tasync restart(): Promise<void> {\n\t\tconst portToReuse = this.actualPort;\n\t\tawait this.stop();\n\n\t\t// Wait for port to be released (up to 3 seconds)\n\t\tlet attempts = 0;\n\t\twhile (attempts < 30) {\n\t\t\tif (await isPortAvailable(portToReuse)) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tawait new Promise((resolve) => setTimeout(resolve, 100));\n\t\t\tattempts++;\n\t\t}\n\n\t\t// Force reuse the same port\n\t\tthis.requestedPort = portToReuse;\n\t\tawait this.start();\n\t}\n\n\tprivate async createServerEntry(): Promise<void> {\n\t\tconst { writeFile } = await import('node:fs/promises');\n\t\tconst { relative, dirname } = await import('node:path');\n\n\t\tconst serverPath = join(process.cwd(), '.gkm', this.provider, 'server.ts');\n\n\t\tconst relativeAppPath = relative(\n\t\t\tdirname(serverPath),\n\t\t\tjoin(dirname(serverPath), 'app.js'),\n\t\t);\n\n\t\tconst serveCode =\n\t\t\tthis.runtime === 'bun'\n\t\t\t\t? `Bun.serve({\n port,\n fetch: app.fetch,\n });`\n\t\t\t\t: `const { serve } = await import('@hono/node-server');\n const server = serve({\n fetch: app.fetch,\n port,\n });\n // Inject WebSocket support if available\n const injectWs = (app as any).__injectWebSocket;\n if (injectWs) {\n injectWs(server);\n console.log('🔌 Telescope real-time updates enabled');\n }`;\n\n\t\tconst content = `#!/usr/bin/env node\n/**\n * Development server entry point\n * This file is auto-generated by 'gkm dev'\n */\nimport { createApp } from './${relativeAppPath.startsWith('.') ? relativeAppPath : `./${relativeAppPath}`}';\n\nconst port = process.argv.includes('--port')\n ? Number.parseInt(process.argv[process.argv.indexOf('--port') + 1])\n : 3000;\n\n// createApp is async to support optional WebSocket setup\nconst { app, start } = await createApp(undefined, ${this.enableOpenApi});\n\n// Start the server\nstart({\n port,\n serve: async (app, port) => {\n ${serveCode}\n },\n}).catch((error) => {\n console.error('Failed to start server:', error);\n process.exit(1);\n});\n`;\n\n\t\tawait writeFile(serverPath, content);\n\t}\n}\n","import { mkdir, writeFile } from 'node:fs/promises';\nimport { join, relative } from 'node:path';\nimport type {\n\tCronInfo,\n\tFunctionInfo,\n\tRouteInfo,\n\tSubscriberInfo,\n} from '../types';\n\nconst logger = console;\n\nexport type ManifestProvider = 'aws' | 'server';\n\nexport interface ServerAppInfo {\n\thandler: string;\n\tendpoints: string;\n}\n\nexport async function generateAwsManifest(\n\toutputDir: string,\n\troutes: RouteInfo[],\n\tfunctions: FunctionInfo[],\n\tcrons: CronInfo[],\n\tsubscribers: SubscriberInfo[],\n): Promise<void> {\n\tconst manifestDir = join(outputDir, 'manifest');\n\tawait mkdir(manifestDir, { recursive: true });\n\n\t// Filter out 'ALL' method routes (server-specific)\n\tconst awsRoutes = routes.filter((r) => r.method !== 'ALL');\n\n\tconst content = `export const manifest = {\n routes: ${JSON.stringify(awsRoutes, null, 2)},\n functions: ${JSON.stringify(functions, null, 2)},\n crons: ${JSON.stringify(crons, null, 2)},\n subscribers: ${JSON.stringify(subscribers, null, 2)},\n} as const;\n\n// Derived types\nexport type Route = (typeof manifest.routes)[number];\nexport type Function = (typeof manifest.functions)[number];\nexport type Cron = (typeof manifest.crons)[number];\nexport type Subscriber = (typeof manifest.subscribers)[number];\n\n// Useful union types\nexport type Authorizer = Route['authorizer'];\nexport type HttpMethod = Route['method'];\nexport type RoutePath = Route['path'];\n`;\n\n\tconst manifestPath = join(manifestDir, 'aws.ts');\n\tawait writeFile(manifestPath, content);\n\n\tlogger.log(\n\t\t`Generated AWS manifest with ${awsRoutes.length} routes, ${functions.length} functions, ${crons.length} crons, ${subscribers.length} subscribers`,\n\t);\n\tlogger.log(`Manifest: ${relative(process.cwd(), manifestPath)}`);\n}\n\nexport async function generateServerManifest(\n\toutputDir: string,\n\tappInfo: ServerAppInfo,\n\troutes: RouteInfo[],\n\tsubscribers: SubscriberInfo[],\n): Promise<void> {\n\tconst manifestDir = join(outputDir, 'manifest');\n\tawait mkdir(manifestDir, { recursive: true });\n\n\t// For server, extract route metadata (path, method, authorizer)\n\tconst serverRoutes = routes\n\t\t.filter((r) => r.method !== 'ALL')\n\t\t.map((r) => ({\n\t\t\tpath: r.path,\n\t\t\tmethod: r.method,\n\t\t\tauthorizer: r.authorizer,\n\t\t}));\n\n\t// Server subscribers only need name and events\n\tconst serverSubscribers = subscribers.map((s) => ({\n\t\tname: s.name,\n\t\tsubscribedEvents: s.subscribedEvents,\n\t}));\n\n\tconst content = `export const manifest = {\n app: ${JSON.stringify(appInfo, null, 2)},\n routes: ${JSON.stringify(serverRoutes, null, 2)},\n subscribers: ${JSON.stringify(serverSubscribers, null, 2)},\n} as const;\n\n// Derived types\nexport type Route = (typeof manifest.routes)[number];\nexport type Subscriber = (typeof manifest.subscribers)[number];\n\n// Useful union types\nexport type Authorizer = Route['authorizer'];\nexport type HttpMethod = Route['method'];\nexport type RoutePath = Route['path'];\n`;\n\n\tconst manifestPath = join(manifestDir, 'server.ts');\n\tawait writeFile(manifestPath, content);\n\n\tlogger.log(\n\t\t`Generated server manifest with ${serverRoutes.length} routes, ${serverSubscribers.length} subscribers`,\n\t);\n\tlogger.log(`Manifest: ${relative(process.cwd(), manifestPath)}`);\n}\n","import { mkdir } from 'node:fs/promises';\nimport { join, relative } from 'node:path';\nimport type { Cron } from '@geekmidas/constructs/crons';\nimport type { Endpoint } from '@geekmidas/constructs/endpoints';\nimport type { Function } from '@geekmidas/constructs/functions';\nimport type { Subscriber } from '@geekmidas/constructs/subscribers';\nimport { loadConfig, parseModuleConfig } from '../config';\nimport {\n\tgetProductionConfigFromGkm,\n\tnormalizeHooksConfig,\n\tnormalizeProductionConfig,\n\tnormalizeStudioConfig,\n\tnormalizeTelescopeConfig,\n} from '../dev';\nimport {\n\tCronGenerator,\n\tEndpointGenerator,\n\tFunctionGenerator,\n\ttype GeneratedConstruct,\n\tSubscriberGenerator,\n} from '../generators';\nimport type {\n\tBuildOptions,\n\tBuildResult,\n\tLegacyProvider,\n\tRouteInfo,\n} from '../types';\nimport {\n\tgenerateAwsManifest,\n\tgenerateServerManifest,\n\ttype ServerAppInfo,\n} from './manifests';\nimport { resolveProviders } from './providerResolver';\nimport type { BuildContext } from './types';\n\nconst logger = console;\n\nexport async function buildCommand(\n\toptions: BuildOptions,\n): Promise<BuildResult> {\n\tconst config = await loadConfig();\n\n\t// Resolve providers from new config format\n\tconst resolved = resolveProviders(config, options);\n\n\t// Normalize production configuration\n\tconst productionConfigFromGkm = getProductionConfigFromGkm(config);\n\tconst production = normalizeProductionConfig(\n\t\toptions.production ?? false,\n\t\tproductionConfigFromGkm,\n\t);\n\n\tif (production) {\n\t\tlogger.log(`🏭 Building for PRODUCTION`);\n\t}\n\n\tlogger.log(`Building with providers: ${resolved.providers.join(', ')}`);\n\tlogger.log(`Loading routes from: ${config.routes}`);\n\tif (config.functions) {\n\t\tlogger.log(`Loading functions from: ${config.functions}`);\n\t}\n\tif (config.crons) {\n\t\tlogger.log(`Loading crons from: ${config.crons}`);\n\t}\n\tif (config.subscribers) {\n\t\tlogger.log(`Loading subscribers from: ${config.subscribers}`);\n\t}\n\tlogger.log(`Using envParser: ${config.envParser}`);\n\n\t// Parse envParser and logger configuration\n\tconst { path: envParserPath, importPattern: envParserImportPattern } =\n\t\tparseModuleConfig(config.envParser, 'envParser');\n\tconst { path: loggerPath, importPattern: loggerImportPattern } =\n\t\tparseModuleConfig(config.logger, 'logger');\n\n\t// Normalize telescope configuration (disabled in production)\n\tconst telescope = production\n\t\t? undefined\n\t\t: normalizeTelescopeConfig(config.telescope);\n\tif (telescope) {\n\t\tlogger.log(`🔭 Telescope enabled at ${telescope.path}`);\n\t}\n\n\t// Normalize studio configuration (disabled in production)\n\tconst studio = production ? undefined : normalizeStudioConfig(config.studio);\n\tif (studio) {\n\t\tlogger.log(`🗄️ Studio enabled at ${studio.path}`);\n\t}\n\n\t// Normalize hooks configuration\n\tconst hooks = normalizeHooksConfig(config.hooks);\n\tif (hooks) {\n\t\tlogger.log(`🪝 Server hooks enabled`);\n\t}\n\n\t// Extract docker compose services for env var auto-population\n\tconst services = config.docker?.compose?.services;\n\tconst dockerServices = services\n\t\t? Array.isArray(services)\n\t\t\t? {\n\t\t\t\t\tpostgres: services.includes('postgres'),\n\t\t\t\t\tredis: services.includes('redis'),\n\t\t\t\t\trabbitmq: services.includes('rabbitmq'),\n\t\t\t\t}\n\t\t\t: {\n\t\t\t\t\tpostgres: Boolean(services.postgres),\n\t\t\t\t\tredis: Boolean(services.redis),\n\t\t\t\t\trabbitmq: Boolean(services.rabbitmq),\n\t\t\t\t}\n\t\t: undefined;\n\n\tconst buildContext: BuildContext = {\n\t\tenvParserPath,\n\t\tenvParserImportPattern,\n\t\tloggerPath,\n\t\tloggerImportPattern,\n\t\ttelescope,\n\t\tstudio,\n\t\thooks,\n\t\tproduction,\n\t\tdockerServices,\n\t};\n\n\t// Initialize generators\n\tconst endpointGenerator = new EndpointGenerator();\n\tconst functionGenerator = new FunctionGenerator();\n\tconst cronGenerator = new CronGenerator();\n\tconst subscriberGenerator = new SubscriberGenerator();\n\n\t// Load all constructs in parallel\n\tconst [allEndpoints, allFunctions, allCrons, allSubscribers] =\n\t\tawait Promise.all([\n\t\t\tendpointGenerator.load(config.routes),\n\t\t\tconfig.functions ? functionGenerator.load(config.functions) : [],\n\t\t\tconfig.crons ? cronGenerator.load(config.crons) : [],\n\t\t\tconfig.subscribers ? subscriberGenerator.load(config.subscribers) : [],\n\t\t]);\n\n\tlogger.log(`Found ${allEndpoints.length} endpoints`);\n\tlogger.log(`Found ${allFunctions.length} functions`);\n\tlogger.log(`Found ${allCrons.length} crons`);\n\tlogger.log(`Found ${allSubscribers.length} subscribers`);\n\n\tif (\n\t\tallEndpoints.length === 0 &&\n\t\tallFunctions.length === 0 &&\n\t\tallCrons.length === 0 &&\n\t\tallSubscribers.length === 0\n\t) {\n\t\tlogger.log(\n\t\t\t'No endpoints, functions, crons, or subscribers found to process',\n\t\t);\n\t\treturn {};\n\t}\n\n\t// Ensure .gkm directory exists\n\tconst rootOutputDir = join(process.cwd(), '.gkm');\n\tawait mkdir(rootOutputDir, { recursive: true });\n\n\t// Build for each provider and generate per-provider manifests\n\tlet result: BuildResult = {};\n\tfor (const provider of resolved.providers) {\n\t\tconst providerResult = await buildForProvider(\n\t\t\tprovider,\n\t\t\tbuildContext,\n\t\t\trootOutputDir,\n\t\t\tendpointGenerator,\n\t\t\tfunctionGenerator,\n\t\t\tcronGenerator,\n\t\t\tsubscriberGenerator,\n\t\t\tallEndpoints,\n\t\t\tallFunctions,\n\t\t\tallCrons,\n\t\t\tallSubscribers,\n\t\t\tresolved.enableOpenApi,\n\t\t\toptions.skipBundle ?? false,\n\t\t\toptions.stage,\n\t\t);\n\t\t// Keep the master key from the server provider\n\t\tif (providerResult.masterKey) {\n\t\t\tresult = providerResult;\n\t\t}\n\t}\n\treturn result;\n}\n\nasync function buildForProvider(\n\tprovider: LegacyProvider,\n\tcontext: BuildContext,\n\trootOutputDir: string,\n\tendpointGenerator: EndpointGenerator,\n\tfunctionGenerator: FunctionGenerator,\n\tcronGenerator: CronGenerator,\n\tsubscriberGenerator: SubscriberGenerator,\n\tendpoints: GeneratedConstruct<Endpoint<any, any, any, any, any, any>>[],\n\tfunctions: GeneratedConstruct<Function<any, any, any, any>>[],\n\tcrons: GeneratedConstruct<Cron<any, any, any, any>>[],\n\tsubscribers: GeneratedConstruct<Subscriber<any, any, any, any, any, any>>[],\n\tenableOpenApi: boolean,\n\tskipBundle: boolean,\n\tstage?: string,\n): Promise<BuildResult> {\n\tconst outputDir = join(process.cwd(), '.gkm', provider);\n\n\t// Ensure output directory exists\n\tawait mkdir(outputDir, { recursive: true });\n\n\tlogger.log(`\\nGenerating handlers for provider: ${provider}`);\n\n\t// Build all constructs in parallel\n\tconst [routes, functionInfos, cronInfos, subscriberInfos] = await Promise.all(\n\t\t[\n\t\t\tendpointGenerator.build(context, endpoints, outputDir, {\n\t\t\t\tprovider,\n\t\t\t\tenableOpenApi,\n\t\t\t}),\n\t\t\tfunctionGenerator.build(context, functions, outputDir, { provider }),\n\t\t\tcronGenerator.build(context, crons, outputDir, { provider }),\n\t\t\tsubscriberGenerator.build(context, subscribers, outputDir, { provider }),\n\t\t],\n\t);\n\n\tlogger.log(\n\t\t`Generated ${routes.length} routes, ${functionInfos.length} functions, ${cronInfos.length} crons, ${subscriberInfos.length} subscribers for ${provider}`,\n\t);\n\n\t// Generate provider-specific manifest\n\tif (provider === 'server') {\n\t\t// For server, collect actual route metadata from endpoint constructs\n\t\tconst routeMetadata: RouteInfo[] = await Promise.all(\n\t\t\tendpoints.map(async ({ construct }) => ({\n\t\t\t\tpath: construct._path,\n\t\t\t\tmethod: construct.method,\n\t\t\t\thandler: '', // Not needed for server manifest\n\t\t\t\tauthorizer: construct.authorizer?.name ?? 'none',\n\t\t\t})),\n\t\t);\n\n\t\tconst appInfo: ServerAppInfo = {\n\t\t\thandler: relative(process.cwd(), join(outputDir, 'app.ts')),\n\t\t\tendpoints: relative(process.cwd(), join(outputDir, 'endpoints.ts')),\n\t\t};\n\n\t\tawait generateServerManifest(\n\t\t\trootOutputDir,\n\t\t\tappInfo,\n\t\t\trouteMetadata,\n\t\t\tsubscriberInfos,\n\t\t);\n\n\t\t// Bundle for production if enabled\n\t\tlet masterKey: string | undefined;\n\t\tif (context.production?.bundle && !skipBundle) {\n\t\t\tlogger.log(`\\n📦 Bundling production server...`);\n\t\t\tconst { bundleServer } = await import('./bundler');\n\n\t\t\t// Collect all constructs for environment variable validation\n\t\t\tconst allConstructs = [\n\t\t\t\t...endpoints.map((e) => e.construct),\n\t\t\t\t...functions.map((f) => f.construct),\n\t\t\t\t...crons.map((c) => c.construct),\n\t\t\t\t...subscribers.map((s) => s.construct),\n\t\t\t];\n\n\t\t\t// Get docker compose services for auto-populating env vars\n\t\t\tconst dockerServices = context.dockerServices;\n\n\t\t\tconst bundleResult = await bundleServer({\n\t\t\t\tentryPoint: join(outputDir, 'server.ts'),\n\t\t\t\toutputDir: join(outputDir, 'dist'),\n\t\t\t\tminify: context.production.minify,\n\t\t\t\tsourcemap: false,\n\t\t\t\texternal: context.production.external,\n\t\t\t\tstage,\n\t\t\t\tconstructs: allConstructs,\n\t\t\t\tdockerServices,\n\t\t\t});\n\t\t\tmasterKey = bundleResult.masterKey;\n\t\t\tlogger.log(`✅ Bundle complete: .gkm/server/dist/server.mjs`);\n\n\t\t\t// Display master key if secrets were injected\n\t\t\tif (masterKey) {\n\t\t\t\tlogger.log(`\\n🔐 Secrets encrypted for deployment`);\n\t\t\t\tlogger.log(` Deploy with: GKM_MASTER_KEY=${masterKey}`);\n\t\t\t}\n\t\t}\n\n\t\treturn { masterKey };\n\t} else {\n\t\t// For AWS providers, generate AWS manifest\n\t\tawait generateAwsManifest(\n\t\t\trootOutputDir,\n\t\t\troutes,\n\t\t\tfunctionInfos,\n\t\t\tcronInfos,\n\t\t\tsubscriberInfos,\n\t\t);\n\t}\n\n\treturn {};\n}\n","import type {\n\tComposeServiceName,\n\tComposeServicesConfig,\n\tServiceConfig,\n} from '../types';\n\n/** Default Docker images for services */\nexport const DEFAULT_SERVICE_IMAGES: Record<ComposeServiceName, string> = {\n\tpostgres: 'postgres',\n\tredis: 'redis',\n\trabbitmq: 'rabbitmq',\n};\n\n/** Default Docker image versions for services */\nexport const DEFAULT_SERVICE_VERSIONS: Record<ComposeServiceName, string> = {\n\tpostgres: '16-alpine',\n\tredis: '7-alpine',\n\trabbitmq: '3-management-alpine',\n};\n\nexport interface ComposeOptions {\n\timageName: string;\n\tregistry: string;\n\tport: number;\n\thealthCheckPath: string;\n\t/** Services config - object format or legacy array format */\n\tservices: ComposeServicesConfig | ComposeServiceName[];\n}\n\n/** Get the default full image reference for a service */\nfunction getDefaultImage(serviceName: ComposeServiceName): string {\n\treturn `${DEFAULT_SERVICE_IMAGES[serviceName]}:${DEFAULT_SERVICE_VERSIONS[serviceName]}`;\n}\n\n/** Normalize services config to a consistent format - returns Map of service name to full image reference */\nfunction normalizeServices(\n\tservices: ComposeServicesConfig | ComposeServiceName[],\n): Map<ComposeServiceName, string> {\n\tconst result = new Map<ComposeServiceName, string>();\n\n\tif (Array.isArray(services)) {\n\t\t// Legacy array format - use default images\n\t\tfor (const name of services) {\n\t\t\tresult.set(name, getDefaultImage(name));\n\t\t}\n\t} else {\n\t\t// Object format\n\t\tfor (const [name, config] of Object.entries(services)) {\n\t\t\tconst serviceName = name as ComposeServiceName;\n\t\t\tif (config === true) {\n\t\t\t\t// boolean true - use default image\n\t\t\t\tresult.set(serviceName, getDefaultImage(serviceName));\n\t\t\t} else if (config && typeof config === 'object') {\n\t\t\t\tconst serviceConfig = config as ServiceConfig;\n\t\t\t\tif (serviceConfig.image) {\n\t\t\t\t\t// Full image reference provided\n\t\t\t\t\tresult.set(serviceName, serviceConfig.image);\n\t\t\t\t} else {\n\t\t\t\t\t// Version only - use default image name with custom version\n\t\t\t\t\tconst version =\n\t\t\t\t\t\tserviceConfig.version ?? DEFAULT_SERVICE_VERSIONS[serviceName];\n\t\t\t\t\tresult.set(\n\t\t\t\t\t\tserviceName,\n\t\t\t\t\t\t`${DEFAULT_SERVICE_IMAGES[serviceName]}:${version}`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t\t// false or undefined - skip\n\t\t}\n\t}\n\n\treturn result;\n}\n\n/**\n * Generate docker-compose.yml for production deployment\n */\nexport function generateDockerCompose(options: ComposeOptions): string {\n\tconst { imageName, registry, port, healthCheckPath, services } = options;\n\n\t// Normalize services to Map<name, version>\n\tconst serviceMap = normalizeServices(services);\n\n\tconst imageRef = registry ? `\\${REGISTRY:-${registry}}/` : '';\n\n\tlet yaml = `version: '3.8'\n\nservices:\n api:\n build:\n context: ../..\n dockerfile: .gkm/docker/Dockerfile\n image: ${imageRef}\\${IMAGE_NAME:-${imageName}}:\\${TAG:-latest}\n container_name: ${imageName}\n restart: unless-stopped\n ports:\n - \"\\${PORT:-${port}}:${port}\"\n environment:\n - NODE_ENV=production\n`;\n\n\t// Add environment variables based on services\n\tif (serviceMap.has('postgres')) {\n\t\tyaml += ` - DATABASE_URL=\\${DATABASE_URL:-postgresql://postgres:postgres@postgres:5432/app}\n`;\n\t}\n\n\tif (serviceMap.has('redis')) {\n\t\tyaml += ` - REDIS_URL=\\${REDIS_URL:-redis://redis:6379}\n`;\n\t}\n\n\tif (serviceMap.has('rabbitmq')) {\n\t\tyaml += ` - RABBITMQ_URL=\\${RABBITMQ_URL:-amqp://rabbitmq:5672}\n`;\n\t}\n\n\tyaml += ` healthcheck:\n test: [\"CMD\", \"wget\", \"-q\", \"--spider\", \"http://localhost:${port}${healthCheckPath}\"]\n interval: 30s\n timeout: 3s\n retries: 3\n`;\n\n\t// Add depends_on if there are services\n\tif (serviceMap.size > 0) {\n\t\tyaml += ` depends_on:\n`;\n\t\tfor (const serviceName of serviceMap.keys()) {\n\t\t\tyaml += ` ${serviceName}:\n condition: service_healthy\n`;\n\t\t}\n\t}\n\n\tyaml += ` networks:\n - app-network\n`;\n\n\t// Add service definitions with images\n\tconst postgresImage = serviceMap.get('postgres');\n\tif (postgresImage) {\n\t\tyaml += `\n postgres:\n image: ${postgresImage}\n container_name: postgres\n restart: unless-stopped\n environment:\n POSTGRES_USER: \\${POSTGRES_USER:-postgres}\n POSTGRES_PASSWORD: \\${POSTGRES_PASSWORD:-postgres}\n POSTGRES_DB: \\${POSTGRES_DB:-app}\n volumes:\n - postgres_data:/var/lib/postgresql/data\n healthcheck:\n test: [\"CMD-SHELL\", \"pg_isready -U postgres\"]\n interval: 5s\n timeout: 5s\n retries: 5\n networks:\n - app-network\n`;\n\t}\n\n\tconst redisImage = serviceMap.get('redis');\n\tif (redisImage) {\n\t\tyaml += `\n redis:\n image: ${redisImage}\n container_name: redis\n restart: unless-stopped\n volumes:\n - redis_data:/data\n healthcheck:\n test: [\"CMD\", \"redis-cli\", \"ping\"]\n interval: 5s\n timeout: 5s\n retries: 5\n networks:\n - app-network\n`;\n\t}\n\n\tconst rabbitmqImage = serviceMap.get('rabbitmq');\n\tif (rabbitmqImage) {\n\t\tyaml += `\n rabbitmq:\n image: ${rabbitmqImage}\n container_name: rabbitmq\n restart: unless-stopped\n environment:\n RABBITMQ_DEFAULT_USER: \\${RABBITMQ_USER:-guest}\n RABBITMQ_DEFAULT_PASS: \\${RABBITMQ_PASSWORD:-guest}\n ports:\n - \"15672:15672\" # Management UI\n volumes:\n - rabbitmq_data:/var/lib/rabbitmq\n healthcheck:\n test: [\"CMD\", \"rabbitmq-diagnostics\", \"-q\", \"ping\"]\n interval: 10s\n timeout: 5s\n retries: 5\n networks:\n - app-network\n`;\n\t}\n\n\t// Add volumes\n\tyaml += `\nvolumes:\n`;\n\n\tif (serviceMap.has('postgres')) {\n\t\tyaml += ` postgres_data:\n`;\n\t}\n\n\tif (serviceMap.has('redis')) {\n\t\tyaml += ` redis_data:\n`;\n\t}\n\n\tif (serviceMap.has('rabbitmq')) {\n\t\tyaml += ` rabbitmq_data:\n`;\n\t}\n\n\t// Add networks\n\tyaml += `\nnetworks:\n app-network:\n driver: bridge\n`;\n\n\treturn yaml;\n}\n\n/**\n * Generate a minimal docker-compose.yml for API only\n */\nexport function generateMinimalDockerCompose(\n\toptions: Omit<ComposeOptions, 'services'>,\n): string {\n\tconst { imageName, registry, port, healthCheckPath } = options;\n\n\tconst imageRef = registry ? `\\${REGISTRY:-${registry}}/` : '';\n\n\treturn `version: '3.8'\n\nservices:\n api:\n build:\n context: ../..\n dockerfile: .gkm/docker/Dockerfile\n image: ${imageRef}\\${IMAGE_NAME:-${imageName}}:\\${TAG:-latest}\n container_name: ${imageName}\n restart: unless-stopped\n ports:\n - \"\\${PORT:-${port}}:${port}\"\n environment:\n - NODE_ENV=production\n healthcheck:\n test: [\"CMD\", \"wget\", \"-q\", \"--spider\", \"http://localhost:${port}${healthCheckPath}\"]\n interval: 30s\n timeout: 3s\n retries: 3\n networks:\n - app-network\n\nnetworks:\n app-network:\n driver: bridge\n`;\n}\n","import { existsSync } from 'node:fs';\nimport { dirname, join, parse } from 'node:path';\nimport type { DockerConfig, GkmConfig } from '../types';\n\nexport type PackageManager = 'pnpm' | 'npm' | 'yarn' | 'bun';\n\nexport interface DockerTemplateOptions {\n\timageName: string;\n\tbaseImage: string;\n\tport: number;\n\thealthCheckPath: string;\n\t/** Whether the build is pre-built (slim Dockerfile) or needs building */\n\tprebuilt: boolean;\n\t/** Detected package manager */\n\tpackageManager: PackageManager;\n}\n\nexport interface MultiStageDockerfileOptions extends DockerTemplateOptions {\n\t/** Enable turbo prune for monorepo optimization */\n\tturbo?: boolean;\n\t/** Package name for turbo prune (defaults to current directory name) */\n\tturboPackage?: string;\n}\n\nconst LOCKFILES: [string, PackageManager][] = [\n\t['pnpm-lock.yaml', 'pnpm'],\n\t['bun.lockb', 'bun'],\n\t['yarn.lock', 'yarn'],\n\t['package-lock.json', 'npm'],\n];\n\n/**\n * Detect package manager from lockfiles\n * Walks up the directory tree to find lockfile (for monorepos)\n */\nexport function detectPackageManager(\n\tcwd: string = process.cwd(),\n): PackageManager {\n\tlet dir = cwd;\n\tconst root = parse(dir).root;\n\n\t// Walk up the directory tree\n\twhile (dir !== root) {\n\t\tfor (const [lockfile, pm] of LOCKFILES) {\n\t\t\tif (existsSync(join(dir, lockfile))) {\n\t\t\t\treturn pm;\n\t\t\t}\n\t\t}\n\t\tdir = dirname(dir);\n\t}\n\n\t// Check root directory\n\tfor (const [lockfile, pm] of LOCKFILES) {\n\t\tif (existsSync(join(root, lockfile))) {\n\t\t\treturn pm;\n\t\t}\n\t}\n\n\treturn 'pnpm'; // default\n}\n\n/**\n * Find the lockfile path by walking up the directory tree\n * Returns the full path to the lockfile, or null if not found\n */\nexport function findLockfilePath(cwd: string = process.cwd()): string | null {\n\tlet dir = cwd;\n\tconst root = parse(dir).root;\n\n\t// Walk up the directory tree\n\twhile (dir !== root) {\n\t\tfor (const [lockfile] of LOCKFILES) {\n\t\t\tconst lockfilePath = join(dir, lockfile);\n\t\t\tif (existsSync(lockfilePath)) {\n\t\t\t\treturn lockfilePath;\n\t\t\t}\n\t\t}\n\t\tdir = dirname(dir);\n\t}\n\n\t// Check root directory\n\tfor (const [lockfile] of LOCKFILES) {\n\t\tconst lockfilePath = join(root, lockfile);\n\t\tif (existsSync(lockfilePath)) {\n\t\t\treturn lockfilePath;\n\t\t}\n\t}\n\n\treturn null;\n}\n\n/**\n * Get the lockfile name for a package manager\n */\nexport function getLockfileName(pm: PackageManager): string {\n\tconst lockfileMap: Record<PackageManager, string> = {\n\t\tpnpm: 'pnpm-lock.yaml',\n\t\tnpm: 'package-lock.json',\n\t\tyarn: 'yarn.lock',\n\t\tbun: 'bun.lockb',\n\t};\n\treturn lockfileMap[pm];\n}\n\n/**\n * Check if we're in a monorepo (lockfile is in a parent directory)\n */\nexport function isMonorepo(cwd: string = process.cwd()): boolean {\n\tconst lockfilePath = findLockfilePath(cwd);\n\tif (!lockfilePath) {\n\t\treturn false;\n\t}\n\n\t// Check if lockfile is in a parent directory (not in cwd)\n\tconst lockfileDir = dirname(lockfilePath);\n\treturn lockfileDir !== cwd;\n}\n\n/**\n * Check if turbo.json exists (walks up directory tree)\n */\nexport function hasTurboConfig(cwd: string = process.cwd()): boolean {\n\tlet dir = cwd;\n\tconst root = parse(dir).root;\n\n\twhile (dir !== root) {\n\t\tif (existsSync(join(dir, 'turbo.json'))) {\n\t\t\treturn true;\n\t\t}\n\t\tdir = dirname(dir);\n\t}\n\n\treturn existsSync(join(root, 'turbo.json'));\n}\n\n/**\n * Get install command for turbo builds (without frozen lockfile)\n * Turbo prune creates a subset that may not perfectly match the lockfile\n */\nfunction getTurboInstallCmd(pm: PackageManager): string {\n\tconst commands: Record<PackageManager, string> = {\n\t\tpnpm: 'pnpm install',\n\t\tnpm: 'npm install',\n\t\tyarn: 'yarn install',\n\t\tbun: 'bun install',\n\t};\n\treturn commands[pm];\n}\n\n/**\n * Get package manager specific commands and paths\n */\nfunction getPmConfig(pm: PackageManager) {\n\tconst configs = {\n\t\tpnpm: {\n\t\t\tinstall: 'corepack enable && corepack prepare pnpm@latest --activate',\n\t\t\tlockfile: 'pnpm-lock.yaml',\n\t\t\tfetch: 'pnpm fetch',\n\t\t\tinstallCmd: 'pnpm install --frozen-lockfile --offline',\n\t\t\tcacheTarget: '/root/.local/share/pnpm/store',\n\t\t\tcacheId: 'pnpm',\n\t\t\trun: 'pnpm',\n\t\t\tdlx: 'pnpm dlx',\n\t\t\taddGlobal: 'pnpm add -g',\n\t\t},\n\t\tnpm: {\n\t\t\tinstall: '', // npm comes with node\n\t\t\tlockfile: 'package-lock.json',\n\t\t\tfetch: '', // npm doesn't have fetch\n\t\t\tinstallCmd: 'npm ci',\n\t\t\tcacheTarget: '/root/.npm',\n\t\t\tcacheId: 'npm',\n\t\t\trun: 'npm run',\n\t\t\tdlx: 'npx',\n\t\t\taddGlobal: 'npm install -g',\n\t\t},\n\t\tyarn: {\n\t\t\tinstall: 'corepack enable && corepack prepare yarn@stable --activate',\n\t\t\tlockfile: 'yarn.lock',\n\t\t\tfetch: '', // yarn doesn't have fetch\n\t\t\tinstallCmd: 'yarn install --frozen-lockfile',\n\t\t\tcacheTarget: '/root/.yarn/cache',\n\t\t\tcacheId: 'yarn',\n\t\t\trun: 'yarn',\n\t\t\tdlx: 'yarn dlx',\n\t\t\taddGlobal: 'yarn global add',\n\t\t},\n\t\tbun: {\n\t\t\tinstall: 'npm install -g bun',\n\t\t\tlockfile: 'bun.lockb',\n\t\t\tfetch: '', // bun doesn't have fetch\n\t\t\tinstallCmd: 'bun install --frozen-lockfile',\n\t\t\tcacheTarget: '/root/.bun/install/cache',\n\t\t\tcacheId: 'bun',\n\t\t\trun: 'bun run',\n\t\t\tdlx: 'bunx',\n\t\t\taddGlobal: 'bun add -g',\n\t\t},\n\t};\n\treturn configs[pm];\n}\n\n/**\n * Generate a multi-stage Dockerfile for building from source\n * Optimized for build speed with:\n * - BuildKit cache mounts for package manager store\n * - pnpm fetch for better layer caching (when using pnpm)\n * - Optional turbo prune for monorepos\n */\nexport function generateMultiStageDockerfile(\n\toptions: MultiStageDockerfileOptions,\n): string {\n\tconst {\n\t\tbaseImage,\n\t\tport,\n\t\thealthCheckPath,\n\t\tturbo,\n\t\tturboPackage,\n\t\tpackageManager,\n\t} = options;\n\n\tif (turbo) {\n\t\treturn generateTurboDockerfile({\n\t\t\t...options,\n\t\t\tturboPackage: turboPackage ?? 'api',\n\t\t});\n\t}\n\n\tconst pm = getPmConfig(packageManager);\n\tconst installPm = pm.install\n\t\t? `\\n# Install ${packageManager}\\nRUN ${pm.install}\\n`\n\t\t: '';\n\tconst hasFetch = packageManager === 'pnpm';\n\n\t// pnpm has fetch which allows better caching\n\tconst depsStage = hasFetch\n\t\t? `# Copy lockfile first for better caching\nCOPY ${pm.lockfile} ./\n\n# Fetch dependencies (downloads to virtual store, cached separately)\nRUN --mount=type=cache,id=${pm.cacheId},target=${pm.cacheTarget} \\\\\n ${pm.fetch}\n\n# Copy package.json after fetch\nCOPY package.json ./\n\n# Install from cache (fast - no network needed)\nRUN --mount=type=cache,id=${pm.cacheId},target=${pm.cacheTarget} \\\\\n ${pm.installCmd}`\n\t\t: `# Copy package files\nCOPY package.json ${pm.lockfile} ./\n\n# Install dependencies with cache\nRUN --mount=type=cache,id=${pm.cacheId},target=${pm.cacheTarget} \\\\\n ${pm.installCmd}`;\n\n\treturn `# syntax=docker/dockerfile:1\n# Stage 1: Dependencies\nFROM ${baseImage} AS deps\n\nWORKDIR /app\n${installPm}\n${depsStage}\n\n# Stage 2: Build\nFROM deps AS builder\n\nWORKDIR /app\n\n# Copy source (deps already installed)\nCOPY . .\n\n# Build production server using CLI from npm\nRUN ${pm.dlx} @geekmidas/cli build --provider server --production\n\n# Stage 3: Production\nFROM ${baseImage} AS runner\n\nWORKDIR /app\n\n# Install tini for proper signal handling as PID 1\nRUN apk add --no-cache tini\n\n# Create non-root user\nRUN addgroup --system --gid 1001 nodejs && \\\\\n adduser --system --uid 1001 hono\n\n# Copy bundled server\nCOPY --from=builder --chown=hono:nodejs /app/.gkm/server/dist/server.mjs ./\n\n# Environment\nENV NODE_ENV=production\nENV PORT=${port}\n\n# Health check\nHEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \\\\\n CMD wget -q --spider http://localhost:${port}${healthCheckPath} || exit 1\n\n# Switch to non-root user\nUSER hono\n\nEXPOSE ${port}\n\n# Use tini as entrypoint to handle PID 1 responsibilities\nENTRYPOINT [\"/sbin/tini\", \"--\"]\nCMD [\"node\", \"server.mjs\"]\n`;\n}\n\n/**\n * Generate a Dockerfile optimized for Turbo monorepos\n * Uses turbo prune to create minimal Docker context\n */\nfunction generateTurboDockerfile(options: MultiStageDockerfileOptions): string {\n\tconst { baseImage, port, healthCheckPath, turboPackage, packageManager } =\n\t\toptions;\n\n\tconst pm = getPmConfig(packageManager);\n\tconst installPm = pm.install ? `RUN ${pm.install}` : '';\n\n\t// For turbo builds, we can't use --frozen-lockfile because turbo prune\n\t// creates a subset that may not perfectly match. Use relaxed install.\n\tconst turboInstallCmd = getTurboInstallCmd(packageManager);\n\n\t// Use pnpm dlx for pnpm (avoids global bin dir issues in Docker)\n\tconst turboCmd = packageManager === 'pnpm' ? 'pnpm dlx turbo' : 'npx turbo';\n\n\treturn `# syntax=docker/dockerfile:1\n# Stage 1: Prune monorepo\nFROM ${baseImage} AS pruner\n\nWORKDIR /app\n\n${installPm}\n\nCOPY . .\n\n# Prune to only include necessary packages\nRUN ${turboCmd} prune ${turboPackage} --docker\n\n# Stage 2: Install dependencies\nFROM ${baseImage} AS deps\n\nWORKDIR /app\n\n${installPm}\n\n# Copy pruned lockfile and package.jsons\nCOPY --from=pruner /app/out/${pm.lockfile} ./\nCOPY --from=pruner /app/out/json/ ./\n\n# Install dependencies (no frozen-lockfile since turbo prune creates a subset)\nRUN --mount=type=cache,id=${pm.cacheId},target=${pm.cacheTarget} \\\\\n ${turboInstallCmd}\n\n# Stage 3: Build\nFROM deps AS builder\n\nWORKDIR /app\n\n# Copy pruned source\nCOPY --from=pruner /app/out/full/ ./\n\n# Build production server using CLI from npm\nRUN ${pm.dlx} @geekmidas/cli build --provider server --production\n\n# Stage 4: Production\nFROM ${baseImage} AS runner\n\nWORKDIR /app\n\nRUN apk add --no-cache tini\n\nRUN addgroup --system --gid 1001 nodejs && \\\\\n adduser --system --uid 1001 hono\n\nCOPY --from=builder --chown=hono:nodejs /app/.gkm/server/dist/server.mjs ./\n\nENV NODE_ENV=production\nENV PORT=${port}\n\nHEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \\\\\n CMD wget -q --spider http://localhost:${port}${healthCheckPath} || exit 1\n\nUSER hono\n\nEXPOSE ${port}\n\nENTRYPOINT [\"/sbin/tini\", \"--\"]\nCMD [\"node\", \"server.mjs\"]\n`;\n}\n\n/**\n * Generate a slim Dockerfile for pre-built bundles\n */\nexport function generateSlimDockerfile(options: DockerTemplateOptions): string {\n\tconst { baseImage, port, healthCheckPath } = options;\n\n\treturn `# Slim Dockerfile for pre-built production bundle\nFROM ${baseImage}\n\nWORKDIR /app\n\n# Install tini for proper signal handling as PID 1\n# Handles SIGTERM propagation and zombie process reaping\nRUN apk add --no-cache tini\n\n# Create non-root user\nRUN addgroup --system --gid 1001 nodejs && \\\\\n adduser --system --uid 1001 hono\n\n# Copy pre-built bundle\nCOPY .gkm/server/dist/server.mjs ./\n\n# Environment\nENV NODE_ENV=production\nENV PORT=${port}\n\n# Health check\nHEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \\\\\n CMD wget -q --spider http://localhost:${port}${healthCheckPath} || exit 1\n\n# Switch to non-root user\nUSER hono\n\nEXPOSE ${port}\n\n# Use tini as entrypoint to handle PID 1 responsibilities\nENTRYPOINT [\"/sbin/tini\", \"--\"]\nCMD [\"node\", \"server.mjs\"]\n`;\n}\n\n/**\n * Generate .dockerignore file\n */\nexport function generateDockerignore(): string {\n\treturn `# Dependencies\nnode_modules\n.pnpm-store\n\n# Build output (except what we need)\n.gkm/aws*\n.gkm/server/*.ts\n!.gkm/server/dist\n\n# IDE and editor\n.idea\n.vscode\n*.swp\n*.swo\n\n# Git\n.git\n.gitignore\n\n# Logs\n*.log\nnpm-debug.log*\npnpm-debug.log*\n\n# Test files\n**/*.test.ts\n**/*.spec.ts\n**/__tests__\ncoverage\n\n# Documentation\ndocs\n*.md\n!README.md\n\n# Environment files (handle secrets separately)\n.env\n.env.*\n!.env.example\n\n# Docker files (don't copy recursively)\nDockerfile*\ndocker-compose*\n.dockerignore\n`;\n}\n\n/**\n * Generate docker-entrypoint.sh for custom startup logic\n */\nexport function generateDockerEntrypoint(): string {\n\treturn `#!/bin/sh\nset -e\n\n# Run any custom startup scripts here\n# Example: wait for database\n# until nc -z $DB_HOST $DB_PORT; do\n# echo \"Waiting for database...\"\n# sleep 1\n# done\n\n# Execute the main command\nexec \"$@\"\n`;\n}\n\n/**\n * Resolve Docker configuration from GkmConfig with defaults\n */\nexport function resolveDockerConfig(\n\tconfig: GkmConfig,\n): Required<Omit<DockerConfig, 'compose'>> & Pick<DockerConfig, 'compose'> {\n\tconst docker = config.docker ?? {};\n\n\t// Try to get image name from package.json name\n\tlet defaultImageName = 'api';\n\ttry {\n\t\t// eslint-disable-next-line @typescript-eslint/no-require-imports\n\t\tconst pkg = require(`${process.cwd()}/package.json`);\n\t\tif (pkg.name) {\n\t\t\t// Remove scope and use just the package name\n\t\t\tdefaultImageName = pkg.name.replace(/^@[^/]+\\//, '');\n\t\t}\n\t} catch {\n\t\t// Ignore if package.json doesn't exist\n\t}\n\n\treturn {\n\t\tregistry: docker.registry ?? '',\n\t\timageName: docker.imageName ?? defaultImageName,\n\t\tbaseImage: docker.baseImage ?? 'node:22-alpine',\n\t\tport: docker.port ?? 3000,\n\t\tcompose: docker.compose,\n\t};\n}\n","import { execSync } from 'node:child_process';\nimport { copyFileSync, existsSync, unlinkSync } from 'node:fs';\nimport { mkdir, writeFile } from 'node:fs/promises';\nimport { basename, join } from 'node:path';\nimport { loadConfig } from '../config';\nimport { generateDockerCompose, generateMinimalDockerCompose } from './compose';\nimport {\n\tdetectPackageManager,\n\tfindLockfilePath,\n\tgenerateDockerEntrypoint,\n\tgenerateDockerignore,\n\tgenerateMultiStageDockerfile,\n\tgenerateSlimDockerfile,\n\thasTurboConfig,\n\tisMonorepo,\n\tresolveDockerConfig,\n} from './templates';\n\nexport {\n\tdetectPackageManager,\n\tfindLockfilePath,\n\thasTurboConfig,\n\tisMonorepo,\n} from './templates';\n\nconst logger = console;\n\nexport interface DockerOptions {\n\t/** Build Docker image after generating files */\n\tbuild?: boolean;\n\t/** Push image to registry after building */\n\tpush?: boolean;\n\t/** Image tag (default: 'latest') */\n\ttag?: string;\n\t/** Container registry URL */\n\tregistry?: string;\n\t/** Use slim Dockerfile (requires pre-built bundle from `gkm build --production`) */\n\tslim?: boolean;\n\t/** Enable turbo prune for monorepo optimization */\n\tturbo?: boolean;\n\t/** Package name for turbo prune (defaults to package.json name) */\n\tturboPackage?: string;\n}\n\nexport interface DockerGeneratedFiles {\n\tdockerfile: string;\n\tdockerCompose: string;\n\tdockerignore: string;\n\tentrypoint: string;\n}\n\n/**\n * Docker command implementation\n * Generates Dockerfile, docker-compose.yml, and related files\n *\n * Default: Multi-stage Dockerfile that builds from source inside Docker\n * --slim: Slim Dockerfile that copies pre-built bundle (requires prior build)\n */\nexport async function dockerCommand(\n\toptions: DockerOptions,\n): Promise<DockerGeneratedFiles> {\n\tconst config = await loadConfig();\n\tconst dockerConfig = resolveDockerConfig(config);\n\n\t// Get health check path from production config\n\tconst serverConfig =\n\t\ttypeof config.providers?.server === 'object'\n\t\t\t? config.providers.server\n\t\t\t: undefined;\n\tconst healthCheckPath = serverConfig?.production?.healthCheck ?? '/health';\n\n\t// Determine Dockerfile type\n\t// Default: Multi-stage (builds inside Docker for reproducibility)\n\t// --slim: Requires pre-built bundle\n\tconst useSlim = options.slim === true;\n\n\tif (useSlim) {\n\t\t// Verify pre-built bundle exists for slim mode\n\t\tconst distDir = join(process.cwd(), '.gkm', 'server', 'dist');\n\t\tconst hasBuild = existsSync(join(distDir, 'server.mjs'));\n\n\t\tif (!hasBuild) {\n\t\t\tthrow new Error(\n\t\t\t\t'Slim Dockerfile requires a pre-built bundle. Run `gkm build --provider server --production` first, or omit --slim to use multi-stage build.',\n\t\t\t);\n\t\t}\n\t}\n\n\t// Generate Docker files\n\tconst dockerDir = join(process.cwd(), '.gkm', 'docker');\n\tawait mkdir(dockerDir, { recursive: true });\n\n\t// Detect package manager from lockfiles\n\tconst packageManager = detectPackageManager();\n\tconst inMonorepo = isMonorepo();\n\tconst hasTurbo = hasTurboConfig();\n\n\t// Auto-enable turbo for monorepos with turbo.json\n\tlet useTurbo = options.turbo ?? false;\n\tif (inMonorepo && !useSlim) {\n\t\tif (hasTurbo) {\n\t\t\tuseTurbo = true;\n\t\t\tlogger.log(' Detected monorepo with turbo.json - using turbo prune');\n\t\t} else {\n\t\t\tthrow new Error(\n\t\t\t\t'Monorepo detected but turbo.json not found.\\n\\n' +\n\t\t\t\t\t'Docker builds in monorepos require Turborepo for proper dependency isolation.\\n\\n' +\n\t\t\t\t\t'To fix this:\\n' +\n\t\t\t\t\t' 1. Install turbo: pnpm add -Dw turbo\\n' +\n\t\t\t\t\t' 2. Create turbo.json in your monorepo root\\n' +\n\t\t\t\t\t' 3. Run this command again\\n\\n' +\n\t\t\t\t\t'See: https://turbo.build/repo/docs/guides/tools/docker',\n\t\t\t);\n\t\t}\n\t}\n\n\t// Get the actual package name from package.json for turbo prune\n\tlet turboPackage = options.turboPackage ?? dockerConfig.imageName;\n\tif (useTurbo && !options.turboPackage) {\n\t\ttry {\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-require-imports\n\t\t\tconst pkg = require(`${process.cwd()}/package.json`);\n\t\t\tif (pkg.name) {\n\t\t\t\tturboPackage = pkg.name;\n\t\t\t\tlogger.log(` Turbo package: ${turboPackage}`);\n\t\t\t}\n\t\t} catch {\n\t\t\t// Fall back to imageName\n\t\t}\n\t}\n\n\tconst templateOptions = {\n\t\timageName: dockerConfig.imageName,\n\t\tbaseImage: dockerConfig.baseImage,\n\t\tport: dockerConfig.port,\n\t\thealthCheckPath,\n\t\tprebuilt: useSlim,\n\t\tturbo: useTurbo,\n\t\tturboPackage,\n\t\tpackageManager,\n\t};\n\n\t// Generate Dockerfile\n\tconst dockerfile = useSlim\n\t\t? generateSlimDockerfile(templateOptions)\n\t\t: generateMultiStageDockerfile(templateOptions);\n\n\tconst dockerMode = useSlim ? 'slim' : useTurbo ? 'turbo' : 'multi-stage';\n\n\tconst dockerfilePath = join(dockerDir, 'Dockerfile');\n\tawait writeFile(dockerfilePath, dockerfile);\n\tlogger.log(\n\t\t`Generated: .gkm/docker/Dockerfile (${dockerMode}, ${packageManager})`,\n\t);\n\n\t// Generate docker-compose.yml\n\tconst composeOptions = {\n\t\timageName: dockerConfig.imageName,\n\t\tregistry: options.registry ?? dockerConfig.registry,\n\t\tport: dockerConfig.port,\n\t\thealthCheckPath,\n\t\tservices: dockerConfig.compose?.services ?? {},\n\t};\n\n\t// Check if there are any services configured\n\tconst hasServices = Array.isArray(composeOptions.services)\n\t\t? composeOptions.services.length > 0\n\t\t: Object.keys(composeOptions.services).length > 0;\n\n\tconst dockerCompose = hasServices\n\t\t? generateDockerCompose(composeOptions)\n\t\t: generateMinimalDockerCompose(composeOptions);\n\n\tconst composePath = join(dockerDir, 'docker-compose.yml');\n\tawait writeFile(composePath, dockerCompose);\n\tlogger.log('Generated: .gkm/docker/docker-compose.yml');\n\n\t// Generate .dockerignore in project root (Docker looks for it there)\n\tconst dockerignore = generateDockerignore();\n\tconst dockerignorePath = join(process.cwd(), '.dockerignore');\n\tawait writeFile(dockerignorePath, dockerignore);\n\tlogger.log('Generated: .dockerignore (project root)');\n\n\t// Generate docker-entrypoint.sh\n\tconst entrypoint = generateDockerEntrypoint();\n\tconst entrypointPath = join(dockerDir, 'docker-entrypoint.sh');\n\tawait writeFile(entrypointPath, entrypoint);\n\tlogger.log('Generated: .gkm/docker/docker-entrypoint.sh');\n\n\tconst result: DockerGeneratedFiles = {\n\t\tdockerfile: dockerfilePath,\n\t\tdockerCompose: composePath,\n\t\tdockerignore: dockerignorePath,\n\t\tentrypoint: entrypointPath,\n\t};\n\n\t// Build Docker image if requested\n\tif (options.build) {\n\t\tawait buildDockerImage(dockerConfig.imageName, options);\n\t}\n\n\t// Push Docker image if requested\n\tif (options.push) {\n\t\tawait pushDockerImage(dockerConfig.imageName, options);\n\t}\n\n\treturn result;\n}\n\n/**\n * Ensure lockfile exists in the build context\n * For monorepos, copies from workspace root if needed\n * Returns cleanup function if file was copied\n */\nfunction ensureLockfile(cwd: string): (() => void) | null {\n\tconst lockfilePath = findLockfilePath(cwd);\n\n\tif (!lockfilePath) {\n\t\tlogger.warn(\n\t\t\t'\\n⚠️ No lockfile found. Docker build may fail or use stale dependencies.',\n\t\t);\n\t\treturn null;\n\t}\n\n\tconst lockfileName = basename(lockfilePath);\n\tconst localLockfile = join(cwd, lockfileName);\n\n\t// If lockfile exists locally (same directory), nothing to do\n\tif (lockfilePath === localLockfile) {\n\t\treturn null;\n\t}\n\n\tlogger.log(` Copying ${lockfileName} from monorepo root...`);\n\tcopyFileSync(lockfilePath, localLockfile);\n\n\t// Return cleanup function\n\treturn () => {\n\t\ttry {\n\t\t\tunlinkSync(localLockfile);\n\t\t} catch {\n\t\t\t// Ignore cleanup errors\n\t\t}\n\t};\n}\n\n/**\n * Build Docker image\n * Uses BuildKit for cache mount support\n */\nasync function buildDockerImage(\n\timageName: string,\n\toptions: DockerOptions,\n): Promise<void> {\n\tconst tag = options.tag ?? 'latest';\n\tconst registry = options.registry;\n\n\tconst fullImageName = registry\n\t\t? `${registry}/${imageName}:${tag}`\n\t\t: `${imageName}:${tag}`;\n\n\tlogger.log(`\\n🐳 Building Docker image: ${fullImageName}`);\n\n\tconst cwd = process.cwd();\n\n\t// Ensure lockfile exists (copy from monorepo root if needed)\n\tconst cleanup = ensureLockfile(cwd);\n\n\ttry {\n\t\t// Use BuildKit for cache mount support (required for --mount=type=cache)\n\t\texecSync(\n\t\t\t`DOCKER_BUILDKIT=1 docker build -f .gkm/docker/Dockerfile -t ${fullImageName} .`,\n\t\t\t{\n\t\t\t\tcwd,\n\t\t\t\tstdio: 'inherit',\n\t\t\t\tenv: { ...process.env, DOCKER_BUILDKIT: '1' },\n\t\t\t},\n\t\t);\n\t\tlogger.log(`✅ Docker image built: ${fullImageName}`);\n\t} catch (error) {\n\t\tthrow new Error(\n\t\t\t`Failed to build Docker image: ${error instanceof Error ? error.message : 'Unknown error'}`,\n\t\t);\n\t} finally {\n\t\t// Clean up copied lockfile\n\t\tcleanup?.();\n\t}\n}\n\n/**\n * Push Docker image to registry\n */\nasync function pushDockerImage(\n\timageName: string,\n\toptions: DockerOptions,\n): Promise<void> {\n\tconst tag = options.tag ?? 'latest';\n\tconst registry = options.registry;\n\n\tif (!registry) {\n\t\tthrow new Error(\n\t\t\t'Registry is required to push Docker image. Use --registry or configure docker.registry in gkm.config.ts',\n\t\t);\n\t}\n\n\tconst fullImageName = `${registry}/${imageName}:${tag}`;\n\n\tlogger.log(`\\n🚀 Pushing Docker image: ${fullImageName}`);\n\n\ttry {\n\t\texecSync(`docker push ${fullImageName}`, {\n\t\t\tcwd: process.cwd(),\n\t\t\tstdio: 'inherit',\n\t\t});\n\t\tlogger.log(`✅ Docker image pushed: ${fullImageName}`);\n\t} catch (error) {\n\t\tthrow new Error(\n\t\t\t`Failed to push Docker image: ${error instanceof Error ? error.message : 'Unknown error'}`,\n\t\t);\n\t}\n}\n","import { execSync } from 'node:child_process';\nimport { dirname, join, relative } from 'node:path';\nimport { dockerCommand, findLockfilePath, isMonorepo } from '../docker';\nimport type { DeployResult, DockerDeployConfig } from './types';\n\nconst logger = console;\n\nexport interface DockerDeployOptions {\n\t/** Deployment stage */\n\tstage: string;\n\t/** Image tag */\n\ttag: string;\n\t/** Skip pushing to registry */\n\tskipPush?: boolean;\n\t/** Master key from build */\n\tmasterKey?: string;\n\t/** Docker config from gkm.config */\n\tconfig: DockerDeployConfig;\n}\n\n/**\n * Get the full image reference\n */\nexport function getImageRef(\n\tregistry: string | undefined,\n\timageName: string,\n\ttag: string,\n): string {\n\tif (registry) {\n\t\treturn `${registry}/${imageName}:${tag}`;\n\t}\n\treturn `${imageName}:${tag}`;\n}\n\n/**\n * Build Docker image\n */\nasync function buildImage(imageRef: string): Promise<void> {\n\tlogger.log(`\\n🔨 Building Docker image: ${imageRef}`);\n\n\tconst cwd = process.cwd();\n\tconst inMonorepo = isMonorepo(cwd);\n\n\t// Generate appropriate Dockerfile\n\tif (inMonorepo) {\n\t\tlogger.log(' Generating Dockerfile for monorepo (turbo prune)...');\n\t} else {\n\t\tlogger.log(' Generating Dockerfile...');\n\t}\n\tawait dockerCommand({});\n\n\t// Determine build context and Dockerfile path\n\tlet buildCwd = cwd;\n\tlet dockerfilePath = '.gkm/docker/Dockerfile';\n\n\tif (inMonorepo) {\n\t\t// For monorepos, build from root so turbo prune can access all packages\n\t\tconst lockfilePath = findLockfilePath(cwd);\n\t\tif (lockfilePath) {\n\t\t\tconst monorepoRoot = dirname(lockfilePath);\n\t\t\tconst appRelPath = relative(monorepoRoot, cwd);\n\t\t\tdockerfilePath = join(appRelPath, '.gkm/docker/Dockerfile');\n\t\t\tbuildCwd = monorepoRoot;\n\t\t\tlogger.log(` Building from monorepo root: ${monorepoRoot}`);\n\t\t}\n\t}\n\n\ttry {\n\t\t// Build for linux/amd64 to ensure compatibility with most cloud servers\n\t\texecSync(\n\t\t\t`DOCKER_BUILDKIT=1 docker build --platform linux/amd64 -f ${dockerfilePath} -t ${imageRef} .`,\n\t\t\t{\n\t\t\t\tcwd: buildCwd,\n\t\t\t\tstdio: 'inherit',\n\t\t\t\tenv: { ...process.env, DOCKER_BUILDKIT: '1' },\n\t\t\t},\n\t\t);\n\t\tlogger.log(`✅ Image built: ${imageRef}`);\n\t} catch (error) {\n\t\tthrow new Error(\n\t\t\t`Failed to build Docker image: ${error instanceof Error ? error.message : 'Unknown error'}`,\n\t\t);\n\t}\n}\n\n/**\n * Push Docker image to registry\n */\nasync function pushImage(imageRef: string): Promise<void> {\n\tlogger.log(`\\n☁️ Pushing image: ${imageRef}`);\n\n\ttry {\n\t\texecSync(`docker push ${imageRef}`, {\n\t\t\tcwd: process.cwd(),\n\t\t\tstdio: 'inherit',\n\t\t});\n\t\tlogger.log(`✅ Image pushed: ${imageRef}`);\n\t} catch (error) {\n\t\tthrow new Error(\n\t\t\t`Failed to push Docker image: ${error instanceof Error ? error.message : 'Unknown error'}`,\n\t\t);\n\t}\n}\n\n/**\n * Deploy using Docker (build and optionally push image)\n */\nexport async function deployDocker(\n\toptions: DockerDeployOptions,\n): Promise<DeployResult> {\n\tconst { stage, tag, skipPush, masterKey, config } = options;\n\n\tconst imageName = config.imageName ?? 'app';\n\tconst imageRef = getImageRef(config.registry, imageName, tag);\n\n\t// Build image\n\tawait buildImage(imageRef);\n\n\t// Push to registry if not skipped\n\tif (!skipPush) {\n\t\tif (!config.registry) {\n\t\t\tlogger.warn(\n\t\t\t\t'\\n⚠️ No registry configured. Use --skip-push or configure docker.registry in gkm.config.ts',\n\t\t\t);\n\t\t} else {\n\t\t\tawait pushImage(imageRef);\n\t\t}\n\t}\n\n\t// Output deployment info\n\tlogger.log('\\n✅ Docker deployment ready!');\n\tlogger.log(`\\n📋 Deployment details:`);\n\tlogger.log(` Image: ${imageRef}`);\n\tlogger.log(` Stage: ${stage}`);\n\n\tif (masterKey) {\n\t\tlogger.log(`\\n🔐 Deploy with this environment variable:`);\n\t\tlogger.log(` GKM_MASTER_KEY=${masterKey}`);\n\t\tlogger.log('\\n Example docker run:');\n\t\tlogger.log(` docker run -e GKM_MASTER_KEY=${masterKey} ${imageRef}`);\n\t}\n\n\treturn {\n\t\timageRef,\n\t\tmasterKey,\n\t};\n}\n\n/**\n * Resolve Docker deploy config from gkm config\n */\nexport function resolveDockerConfig(config: GkmConfig): DockerDeployConfig {\n\treturn {\n\t\tregistry: config.docker?.registry,\n\t\timageName: config.docker?.imageName,\n\t};\n}\n","import { getDokployRegistryId, getDokployToken } from '../auth';\nimport { DokployApi } from './dokploy-api';\nimport type { DeployResult, DokployDeployConfig } from './types';\n\nconst logger = console;\n\nexport interface DokployDeployOptions {\n\t/** Deployment stage */\n\tstage: string;\n\t/** Image tag */\n\ttag: string;\n\t/** Image reference */\n\timageRef: string;\n\t/** Master key from build */\n\tmasterKey?: string;\n\t/** Dokploy config from gkm.config */\n\tconfig: DokployDeployConfig;\n}\n\n/**\n * Get the Dokploy API token from stored credentials or environment\n */\nasync function getApiToken(): Promise<string> {\n\tconst token = await getDokployToken();\n\tif (!token) {\n\t\tthrow new Error(\n\t\t\t'Dokploy credentials not found.\\n' +\n\t\t\t\t'Run \"gkm login --service dokploy\" to authenticate, or set DOKPLOY_API_TOKEN.',\n\t\t);\n\t}\n\treturn token;\n}\n\n/**\n * Create a Dokploy API client\n */\nasync function createApi(endpoint: string): Promise<DokployApi> {\n\tconst token = await getApiToken();\n\treturn new DokployApi({ baseUrl: endpoint, token });\n}\n\n/**\n * Deploy to Dokploy\n */\nexport async function deployDokploy(\n\toptions: DokployDeployOptions,\n): Promise<DeployResult> {\n\tconst { stage, imageRef, masterKey, config } = options;\n\n\tlogger.log(`\\n🎯 Deploying to Dokploy...`);\n\tlogger.log(` Endpoint: ${config.endpoint}`);\n\tlogger.log(` Application: ${config.applicationId}`);\n\n\tconst api = await createApi(config.endpoint);\n\n\t// Configure Docker provider with the image\n\tlogger.log(` Configuring Docker image: ${imageRef}`);\n\n\t// Determine registry credentials\n\tconst registryOptions: {\n\t\tregistryId?: string;\n\t\tusername?: string;\n\t\tpassword?: string;\n\t\tregistryUrl?: string;\n\t} = {};\n\n\tif (config.registryId) {\n\t\t// Use registry ID from config\n\t\tregistryOptions.registryId = config.registryId;\n\t\tlogger.log(` Using Dokploy registry: ${config.registryId}`);\n\t} else {\n\t\t// Try stored registry ID from credentials\n\t\tconst storedRegistryId = await getDokployRegistryId();\n\t\tif (storedRegistryId) {\n\t\t\tregistryOptions.registryId = storedRegistryId;\n\t\t\tlogger.log(` Using stored Dokploy registry: ${storedRegistryId}`);\n\t\t} else if (config.registryCredentials) {\n\t\t\t// Use explicit credentials from config\n\t\t\tregistryOptions.username = config.registryCredentials.username;\n\t\t\tregistryOptions.password = config.registryCredentials.password;\n\t\t\tregistryOptions.registryUrl = config.registryCredentials.registryUrl;\n\t\t\tlogger.log(\n\t\t\t\t` Using registry credentials for: ${config.registryCredentials.registryUrl}`,\n\t\t\t);\n\t\t} else {\n\t\t\t// Try environment variables\n\t\t\tconst username = process.env.DOCKER_REGISTRY_USERNAME;\n\t\t\tconst password = process.env.DOCKER_REGISTRY_PASSWORD;\n\t\t\tconst registryUrl = process.env.DOCKER_REGISTRY_URL || config.registry;\n\n\t\t\tif (username && password && registryUrl) {\n\t\t\t\tregistryOptions.username = username;\n\t\t\t\tregistryOptions.password = password;\n\t\t\t\tregistryOptions.registryUrl = registryUrl;\n\t\t\t\tlogger.log(` Using registry credentials from environment`);\n\t\t\t}\n\t\t}\n\t}\n\n\tawait api.saveDockerProvider(config.applicationId, imageRef, registryOptions);\n\tlogger.log(' ✓ Docker provider configured');\n\n\t// Prepare environment variables\n\tconst envVars: Record<string, string> = {};\n\n\tif (masterKey) {\n\t\tenvVars.GKM_MASTER_KEY = masterKey;\n\t}\n\n\t// Update environment if we have variables to set\n\tif (Object.keys(envVars).length > 0) {\n\t\tlogger.log(' Updating environment variables...');\n\n\t\t// Convert env vars to the format Dokploy expects (KEY=VALUE per line)\n\t\tconst envString = Object.entries(envVars)\n\t\t\t.map(([key, value]) => `${key}=${value}`)\n\t\t\t.join('\\n');\n\n\t\tawait api.saveApplicationEnv(config.applicationId, envString);\n\t\tlogger.log(' ✓ Environment variables updated');\n\t}\n\n\t// Trigger deployment\n\tlogger.log(' Triggering deployment...');\n\tawait api.deployApplication(config.applicationId);\n\tlogger.log(' ✓ Deployment triggered');\n\n\tlogger.log('\\n✅ Dokploy deployment initiated!');\n\tlogger.log(`\\n📋 Deployment details:`);\n\tlogger.log(` Image: ${imageRef}`);\n\tlogger.log(` Stage: ${stage}`);\n\tlogger.log(` Application ID: ${config.applicationId}`);\n\n\tif (masterKey) {\n\t\tlogger.log(`\\n🔐 GKM_MASTER_KEY has been set in Dokploy environment`);\n\t}\n\n\t// Construct the probable deployment URL\n\tconst deploymentUrl = `${config.endpoint}/project/${config.projectId}`;\n\tlogger.log(`\\n🔗 View deployment: ${deploymentUrl}`);\n\n\treturn {\n\t\timageRef,\n\t\tmasterKey,\n\t\turl: deploymentUrl,\n\t};\n}\n\n/**\n * Validate Dokploy configuration\n */\nexport function validateDokployConfig(\n\tconfig: Partial<DokployDeployConfig> | undefined,\n): config is DokployDeployConfig {\n\tif (!config) {\n\t\treturn false;\n\t}\n\n\tconst required = ['endpoint', 'projectId', 'applicationId'] as const;\n\tconst missing = required.filter((key) => !config[key]);\n\n\tif (missing.length > 0) {\n\t\tthrow new Error(\n\t\t\t`Missing Dokploy configuration: ${missing.join(', ')}\\n` +\n\t\t\t\t'Configure in gkm.config.ts:\\n' +\n\t\t\t\t' providers: {\\n' +\n\t\t\t\t' dokploy: {\\n' +\n\t\t\t\t\" endpoint: 'https://dokploy.example.com',\\n\" +\n\t\t\t\t\" projectId: 'proj_xxx',\\n\" +\n\t\t\t\t\" applicationId: 'app_xxx',\\n\" +\n\t\t\t\t' },\\n' +\n\t\t\t\t' }',\n\t\t);\n\t}\n\n\treturn true;\n}\n","import { existsSync } from 'node:fs';\nimport { readFile, writeFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport {\n\tgetDokployCredentials,\n\tgetDokployRegistryId,\n\tgetDokployToken,\n\tstoreDokployRegistryId,\n} from '../auth';\nimport { DokployApi } from './dokploy-api';\nimport type { DokployDeployConfig } from './types';\n\nconst logger = console;\n\nexport interface DeployInitOptions {\n\t/** Dokploy endpoint URL (optional if logged in) */\n\tendpoint?: string;\n\t/** Project name (creates new or uses existing) */\n\tprojectName: string;\n\t/** Application name */\n\tappName: string;\n\t/** Use existing project ID instead of creating/finding */\n\tprojectId?: string;\n\t/** Registry ID in Dokploy (optional, uses stored if available) */\n\tregistryId?: string;\n}\n\nexport interface RegistrySetupOptions {\n\t/** Dokploy endpoint URL (optional if logged in) */\n\tendpoint?: string;\n\t/** Registry name (for display in Dokploy) */\n\tregistryName: string;\n\t/** Registry URL (e.g., ghcr.io, docker.io) */\n\tregistryUrl: string;\n\t/** Registry username */\n\tusername: string;\n\t/** Registry password or token */\n\tpassword: string;\n\t/** Image prefix (optional, e.g., org-name) */\n\timagePrefix?: string;\n}\n\n/**\n * Get the Dokploy API token from stored credentials or environment\n */\nasync function getApiToken(): Promise<string> {\n\tconst token = await getDokployToken();\n\tif (!token) {\n\t\tthrow new Error(\n\t\t\t'Dokploy credentials not found.\\n' +\n\t\t\t\t'Run \"gkm login --service dokploy\" to authenticate, or set DOKPLOY_API_TOKEN.',\n\t\t);\n\t}\n\treturn token;\n}\n\n/**\n * Get Dokploy endpoint from options or stored credentials\n */\nasync function getEndpoint(providedEndpoint?: string): Promise<string> {\n\tif (providedEndpoint) {\n\t\treturn providedEndpoint;\n\t}\n\n\tconst stored = await getDokployCredentials();\n\tif (stored) {\n\t\treturn stored.endpoint;\n\t}\n\n\tthrow new Error(\n\t\t'Dokploy endpoint not specified.\\n' +\n\t\t\t'Either run \"gkm login --service dokploy\" first, or provide --endpoint.',\n\t);\n}\n\n/**\n * Create a Dokploy API client\n */\nasync function createApi(endpoint: string): Promise<DokployApi> {\n\tconst token = await getApiToken();\n\treturn new DokployApi({ baseUrl: endpoint, token });\n}\n\n/**\n * Update gkm.config.ts with Dokploy configuration\n */\nexport async function updateConfig(\n\tconfig: DokployDeployConfig,\n\tcwd: string = process.cwd(),\n): Promise<void> {\n\tconst configPath = join(cwd, 'gkm.config.ts');\n\n\tif (!existsSync(configPath)) {\n\t\tlogger.warn(\n\t\t\t'\\n gkm.config.ts not found. Add this configuration manually:\\n',\n\t\t);\n\t\tlogger.log(` providers: {`);\n\t\tlogger.log(` dokploy: {`);\n\t\tlogger.log(` endpoint: '${config.endpoint}',`);\n\t\tlogger.log(` projectId: '${config.projectId}',`);\n\t\tlogger.log(` applicationId: '${config.applicationId}',`);\n\t\tlogger.log(` },`);\n\t\tlogger.log(` },`);\n\t\treturn;\n\t}\n\n\tconst content = await readFile(configPath, 'utf-8');\n\n\t// Check if providers.dokploy already exists\n\tif (content.includes('dokploy:') && content.includes('applicationId:')) {\n\t\tlogger.log('\\n Dokploy config already exists in gkm.config.ts');\n\t\tlogger.log(' Updating with new values...');\n\t}\n\n\t// Build the dokploy config string\n\tconst registryLine = config.registryId\n\t\t? `\\n\\t\\t\\tregistryId: '${config.registryId}',`\n\t\t: '';\n\tconst dokployConfigStr = `dokploy: {\n\t\t\tendpoint: '${config.endpoint}',\n\t\t\tprojectId: '${config.projectId}',\n\t\t\tapplicationId: '${config.applicationId}',${registryLine}\n\t\t}`;\n\n\t// Try to add or update the dokploy config\n\tlet newContent: string;\n\n\tif (content.includes('providers:')) {\n\t\t// Add dokploy to existing providers\n\t\tif (content.includes('dokploy:')) {\n\t\t\t// Update existing dokploy config (handle multi-line with registryId)\n\t\t\tnewContent = content.replace(/dokploy:\\s*\\{[^}]*\\}/s, dokployConfigStr);\n\t\t} else {\n\t\t\t// Add dokploy to providers\n\t\t\tnewContent = content.replace(\n\t\t\t\t/providers:\\s*\\{/,\n\t\t\t\t`providers: {\\n\\t\\t${dokployConfigStr},`,\n\t\t\t);\n\t\t}\n\t} else {\n\t\t// Add providers section before the closing of defineConfig\n\t\tnewContent = content.replace(\n\t\t\t/}\\s*\\)\\s*;?\\s*$/,\n\t\t\t`\n\tproviders: {\n\t\t${dokployConfigStr},\n\t},\n});`,\n\t\t);\n\t}\n\n\tawait writeFile(configPath, newContent);\n\tlogger.log('\\n ✓ Updated gkm.config.ts with Dokploy configuration');\n}\n\n/**\n * Initialize Dokploy deployment configuration\n */\nexport async function deployInitCommand(\n\toptions: DeployInitOptions,\n): Promise<DokployDeployConfig> {\n\tconst {\n\t\tprojectName,\n\t\tappName,\n\t\tprojectId: existingProjectId,\n\t\tregistryId,\n\t} = options;\n\n\tconst endpoint = await getEndpoint(options.endpoint);\n\tconst api = await createApi(endpoint);\n\n\tlogger.log(`\\n🚀 Initializing Dokploy deployment...`);\n\tlogger.log(` Endpoint: ${endpoint}`);\n\n\t// Step 1: Find or create project\n\tlet projectId: string;\n\n\tif (existingProjectId) {\n\t\tprojectId = existingProjectId;\n\t\tlogger.log(`\\n📁 Using existing project: ${projectId}`);\n\t} else {\n\t\tlogger.log(`\\n📁 Looking for project: ${projectName}`);\n\n\t\tconst projects = await api.listProjects();\n\t\tconst existingProject = projects.find(\n\t\t\t(p) => p.name.toLowerCase() === projectName.toLowerCase(),\n\t\t);\n\n\t\tif (existingProject) {\n\t\t\tprojectId = existingProject.projectId;\n\t\t\tlogger.log(` Found existing project: ${projectId}`);\n\t\t} else {\n\t\t\tlogger.log(` Creating new project...`);\n\t\t\tconst result = await api.createProject(projectName);\n\t\t\tprojectId = result.project.projectId;\n\t\t\tlogger.log(` ✓ Created project: ${projectId}`);\n\t\t}\n\t}\n\n\t// Step 2: Get project to find environment\n\tconst project = await api.getProject(projectId);\n\tlet environmentId: string;\n\n\tconst firstEnv = project.environments?.[0];\n\tif (firstEnv) {\n\t\tenvironmentId = firstEnv.environmentId;\n\t} else {\n\t\t// Create a default environment\n\t\tlogger.log(` Creating production environment...`);\n\t\tconst env = await api.createEnvironment(projectId, 'production');\n\t\tenvironmentId = env.environmentId;\n\t}\n\n\t// Step 3: Create application\n\tlogger.log(`\\n📦 Creating application: ${appName}`);\n\tconst application = await api.createApplication(\n\t\tappName,\n\t\tprojectId,\n\t\tenvironmentId,\n\t);\n\tlogger.log(` ✓ Created application: ${application.applicationId}`);\n\n\t// Step 4: Configure registry if provided\n\tif (registryId) {\n\t\tlogger.log(`\\n🔧 Configuring registry: ${registryId}`);\n\t\tawait api.updateApplication(application.applicationId, { registryId });\n\t\tlogger.log(` ✓ Registry configured`);\n\t} else {\n\t\t// List available registries\n\t\ttry {\n\t\t\tconst registries = await api.listRegistries();\n\t\t\tif (registries.length > 0) {\n\t\t\t\tlogger.log(`\\n📋 Available registries:`);\n\t\t\t\tfor (const reg of registries) {\n\t\t\t\t\tlogger.log(\n\t\t\t\t\t\t` - ${reg.registryName}: ${reg.registryUrl} (${reg.registryId})`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tlogger.log(`\\n To use a registry, run with --registry-id <id>`);\n\t\t\t}\n\t\t} catch {\n\t\t\t// Ignore registry listing errors\n\t\t}\n\t}\n\n\t// Step 5: Build config\n\tconst config: DokployDeployConfig = {\n\t\tendpoint,\n\t\tprojectId,\n\t\tapplicationId: application.applicationId,\n\t};\n\n\t// Step 6: Update gkm.config.ts\n\tawait updateConfig(config);\n\n\tlogger.log(`\\n✅ Dokploy deployment initialized!`);\n\tlogger.log(`\\n📋 Configuration:`);\n\tlogger.log(` Project ID: ${projectId}`);\n\tlogger.log(` Application ID: ${application.applicationId}`);\n\tlogger.log(`\\n🔗 View in Dokploy: ${endpoint}/project/${projectId}`);\n\tlogger.log(`\\n📝 Next steps:`);\n\tlogger.log(` 1. Initialize secrets: gkm secrets:init --stage production`);\n\tlogger.log(` 2. Deploy: gkm deploy --provider dokploy --stage production`);\n\n\treturn config;\n}\n\n/**\n * List available Dokploy resources\n */\nexport async function deployListCommand(options: {\n\tendpoint?: string;\n\tresource: 'projects' | 'registries';\n}): Promise<void> {\n\tconst endpoint = await getEndpoint(options.endpoint);\n\tconst api = await createApi(endpoint);\n\n\tconst { resource } = options;\n\n\tif (resource === 'projects') {\n\t\tlogger.log(`\\n📁 Projects in ${endpoint}:`);\n\t\tconst projects = await api.listProjects();\n\n\t\tif (projects.length === 0) {\n\t\t\tlogger.log(' No projects found');\n\t\t\treturn;\n\t\t}\n\n\t\tfor (const project of projects) {\n\t\t\tlogger.log(`\\n ${project.name} (${project.projectId})`);\n\t\t\tif (project.description) {\n\t\t\t\tlogger.log(` ${project.description}`);\n\t\t\t}\n\t\t}\n\t} else if (resource === 'registries') {\n\t\tlogger.log(`\\n🐳 Registries in ${endpoint}:`);\n\t\tconst registries = await api.listRegistries();\n\n\t\tif (registries.length === 0) {\n\t\t\tlogger.log(' No registries configured');\n\t\t\tlogger.log(' Run \"gkm registry:setup\" to configure a registry');\n\t\t\treturn;\n\t\t}\n\n\t\tconst storedRegistryId = await getDokployRegistryId();\n\n\t\tfor (const registry of registries) {\n\t\t\tconst isDefault = registry.registryId === storedRegistryId;\n\t\t\tconst marker = isDefault ? ' (default)' : '';\n\t\t\tlogger.log(\n\t\t\t\t`\\n ${registry.registryName}${marker} (${registry.registryId})`,\n\t\t\t);\n\t\t\tlogger.log(` URL: ${registry.registryUrl}`);\n\t\t\tlogger.log(` Username: ${registry.username}`);\n\t\t\tif (registry.imagePrefix) {\n\t\t\t\tlogger.log(` Prefix: ${registry.imagePrefix}`);\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * Setup a Docker registry in Dokploy\n */\nexport async function registrySetupCommand(\n\toptions: RegistrySetupOptions,\n): Promise<string> {\n\tconst { registryName, registryUrl, username, password, imagePrefix } =\n\t\toptions;\n\n\tconst endpoint = await getEndpoint(options.endpoint);\n\tconst api = await createApi(endpoint);\n\n\tlogger.log(`\\n🐳 Setting up Docker registry in Dokploy...`);\n\tlogger.log(` Endpoint: ${endpoint}`);\n\n\t// Check if registry with same URL already exists\n\tconst existingRegistries = await api.listRegistries();\n\tconst existing = existingRegistries.find(\n\t\t(r) =>\n\t\t\tr.registryUrl === registryUrl ||\n\t\t\tr.registryName.toLowerCase() === registryName.toLowerCase(),\n\t);\n\n\tlet registryId: string;\n\n\tif (existing) {\n\t\tlogger.log(`\\n📋 Found existing registry: ${existing.registryName}`);\n\t\tlogger.log(` Updating credentials...`);\n\n\t\tawait api.updateRegistry(existing.registryId, {\n\t\t\tregistryName,\n\t\t\tusername,\n\t\t\tpassword,\n\t\t\timagePrefix,\n\t\t});\n\n\t\tregistryId = existing.registryId;\n\t\tlogger.log(` ✓ Registry updated: ${registryId}`);\n\t} else {\n\t\tlogger.log(`\\n📦 Creating registry: ${registryName}`);\n\n\t\tconst registry = await api.createRegistry(\n\t\t\tregistryName,\n\t\t\tregistryUrl,\n\t\t\tusername,\n\t\t\tpassword,\n\t\t\t{ imagePrefix },\n\t\t);\n\n\t\tregistryId = registry.registryId;\n\t\tlogger.log(` ✓ Registry created: ${registryId}`);\n\t}\n\n\t// Store registry ID in credentials\n\tawait storeDokployRegistryId(registryId);\n\tlogger.log(`\\n💾 Saved registry ID to ~/.gkm/credentials.json`);\n\n\tlogger.log(`\\n✅ Registry setup complete!`);\n\tlogger.log(`\\n📋 Registry Details:`);\n\tlogger.log(` ID: ${registryId}`);\n\tlogger.log(` Name: ${registryName}`);\n\tlogger.log(` URL: ${registryUrl}`);\n\tlogger.log(` Username: ${username}`);\n\tif (imagePrefix) {\n\t\tlogger.log(` Prefix: ${imagePrefix}`);\n\t}\n\n\tlogger.log(\n\t\t`\\n📝 The registry ID is now stored and will be used automatically`,\n\t);\n\tlogger.log(` when deploying with \"gkm deploy --provider dokploy\"`);\n\n\treturn registryId;\n}\n\n/**\n * Use an existing registry (set as default)\n */\nexport async function registryUseCommand(options: {\n\tendpoint?: string;\n\tregistryId: string;\n}): Promise<void> {\n\tconst { registryId } = options;\n\n\tconst endpoint = await getEndpoint(options.endpoint);\n\tconst api = await createApi(endpoint);\n\n\tlogger.log(`\\n🔧 Setting default registry...`);\n\n\t// Verify the registry exists\n\ttry {\n\t\tconst registry = await api.getRegistry(registryId);\n\t\tlogger.log(` Found registry: ${registry.registryName}`);\n\t} catch {\n\t\tthrow new Error(\n\t\t\t`Registry not found: ${registryId}\\n` +\n\t\t\t\t'Run \"gkm deploy:list registries\" to see available registries.',\n\t\t);\n\t}\n\n\t// Store registry ID in credentials\n\tawait storeDokployRegistryId(registryId);\n\n\tlogger.log(`\\n✅ Default registry set: ${registryId}`);\n\tlogger.log(` This registry will be used for future deployments.`);\n}\n","import { stdin as input, stdout as output } from 'node:process';\nimport * as readline from 'node:readline/promises';\nimport {\n\tgetDokployCredentials,\n\tgetDokployRegistryId,\n\tstoreDokployCredentials,\n\tvalidateDokployToken,\n} from '../auth';\nimport { storeDokployRegistryId } from '../auth/credentials';\nimport { buildCommand } from '../build/index';\nimport { type GkmConfig, loadConfig } from '../config';\nimport { deployDocker, resolveDockerConfig } from './docker';\nimport { deployDokploy } from './dokploy';\nimport { DokployApi } from './dokploy-api';\nimport { updateConfig } from './init';\nimport type {\n\tDeployOptions,\n\tDeployProvider,\n\tDeployResult,\n\tDokployDeployConfig,\n} from './types';\n\nconst logger = console;\n\n/**\n * Prompt for input\n */\nasync function prompt(message: string, hidden = false): Promise<string> {\n\tif (!process.stdin.isTTY) {\n\t\tthrow new Error('Interactive input required. Please configure manually.');\n\t}\n\n\tif (hidden) {\n\t\tprocess.stdout.write(message);\n\t\treturn new Promise((resolve) => {\n\t\t\tlet value = '';\n\t\t\tconst onData = (char: Buffer) => {\n\t\t\t\tconst c = char.toString();\n\t\t\t\tif (c === '\\n' || c === '\\r') {\n\t\t\t\t\tprocess.stdin.setRawMode(false);\n\t\t\t\t\tprocess.stdin.pause();\n\t\t\t\t\tprocess.stdin.removeListener('data', onData);\n\t\t\t\t\tprocess.stdout.write('\\n');\n\t\t\t\t\tresolve(value);\n\t\t\t\t} else if (c === '\\u0003') {\n\t\t\t\t\tprocess.stdin.setRawMode(false);\n\t\t\t\t\tprocess.stdin.pause();\n\t\t\t\t\tprocess.stdout.write('\\n');\n\t\t\t\t\tprocess.exit(1);\n\t\t\t\t} else if (c === '\\u007F' || c === '\\b') {\n\t\t\t\t\tif (value.length > 0) value = value.slice(0, -1);\n\t\t\t\t} else {\n\t\t\t\t\tvalue += c;\n\t\t\t\t}\n\t\t\t};\n\t\t\tprocess.stdin.setRawMode(true);\n\t\t\tprocess.stdin.resume();\n\t\t\tprocess.stdin.on('data', onData);\n\t\t});\n\t}\n\n\tconst rl = readline.createInterface({ input, output });\n\ttry {\n\t\treturn await rl.question(message);\n\t} finally {\n\t\trl.close();\n\t}\n}\n\n/**\n * Docker compose services that can be provisioned\n */\ninterface DockerComposeServices {\n\tpostgres?: boolean;\n\tredis?: boolean;\n\trabbitmq?: boolean;\n}\n\n/**\n * Result of Dokploy setup including provisioned service URLs\n */\ninterface DokploySetupResult {\n\tconfig: DokployDeployConfig;\n\tserviceUrls?: {\n\t\tDATABASE_URL?: string;\n\t\tREDIS_URL?: string;\n\t};\n}\n\n/**\n * Provision docker compose services in Dokploy\n * @internal Exported for testing\n */\nexport async function provisionServices(\n\tapi: DokployApi,\n\tprojectId: string,\n\tenvironmentId: string | undefined,\n\tappName: string,\n\tservices?: DockerComposeServices,\n\texistingUrls?: { DATABASE_URL?: string; REDIS_URL?: string },\n): Promise<{ DATABASE_URL?: string; REDIS_URL?: string } | undefined> {\n\tlogger.log(\n\t\t`\\n🔍 provisionServices called: services=${JSON.stringify(services)}, envId=${environmentId}`,\n\t);\n\tif (!services || !environmentId) {\n\t\tlogger.log(' Skipping: no services or no environmentId');\n\t\treturn undefined;\n\t}\n\n\tconst serviceUrls: { DATABASE_URL?: string; REDIS_URL?: string } = {};\n\n\tif (services.postgres) {\n\t\t// Skip if DATABASE_URL already exists in secrets\n\t\tif (existingUrls?.DATABASE_URL) {\n\t\t\tlogger.log('\\n🐘 PostgreSQL: Already configured (skipping)');\n\t\t} else {\n\t\t\tlogger.log('\\n🐘 Provisioning PostgreSQL...');\n\t\t\tconst postgresName = `${appName}-db`;\n\n\t\t\ttry {\n\t\t\t\t// Generate a random password for the database\n\t\t\t\tconst { randomBytes } = await import('node:crypto');\n\t\t\t\tconst databasePassword = randomBytes(16).toString('hex');\n\n\t\t\t\tconst postgres = await api.createPostgres(\n\t\t\t\t\tpostgresName,\n\t\t\t\t\tprojectId,\n\t\t\t\t\tenvironmentId,\n\t\t\t\t\t{ databasePassword },\n\t\t\t\t);\n\t\t\t\tlogger.log(` ✓ Created PostgreSQL: ${postgres.postgresId}`);\n\n\t\t\t\t// Deploy the database\n\t\t\t\tawait api.deployPostgres(postgres.postgresId);\n\t\t\t\tlogger.log(' ✓ PostgreSQL deployed');\n\n\t\t\t\t// Construct connection URL using internal docker network hostname\n\t\t\t\tserviceUrls.DATABASE_URL = `postgresql://${postgres.databaseUser}:${postgres.databasePassword}@${postgres.appName}:5432/${postgres.databaseName}`;\n\t\t\t\tlogger.log(` ✓ DATABASE_URL configured`);\n\t\t\t} catch (error) {\n\t\t\t\tconst message =\n\t\t\t\t\terror instanceof Error ? error.message : 'Unknown error';\n\t\t\t\tif (\n\t\t\t\t\tmessage.includes('already exists') ||\n\t\t\t\t\tmessage.includes('duplicate')\n\t\t\t\t) {\n\t\t\t\t\tlogger.log(` ℹ PostgreSQL already exists`);\n\t\t\t\t} else {\n\t\t\t\t\tlogger.log(` ⚠ Failed to provision PostgreSQL: ${message}`);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tif (services.redis) {\n\t\t// Skip if REDIS_URL already exists in secrets\n\t\tif (existingUrls?.REDIS_URL) {\n\t\t\tlogger.log('\\n🔴 Redis: Already configured (skipping)');\n\t\t} else {\n\t\t\tlogger.log('\\n🔴 Provisioning Redis...');\n\t\t\tconst redisName = `${appName}-cache`;\n\n\t\t\ttry {\n\t\t\t\t// Generate a random password for Redis\n\t\t\t\tconst { randomBytes } = await import('node:crypto');\n\t\t\t\tconst databasePassword = randomBytes(16).toString('hex');\n\n\t\t\t\tconst redis = await api.createRedis(\n\t\t\t\t\tredisName,\n\t\t\t\t\tprojectId,\n\t\t\t\t\tenvironmentId,\n\t\t\t\t\t{\n\t\t\t\t\t\tdatabasePassword,\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t\tlogger.log(` ✓ Created Redis: ${redis.redisId}`);\n\n\t\t\t\t// Deploy the redis instance\n\t\t\t\tawait api.deployRedis(redis.redisId);\n\t\t\t\tlogger.log(' ✓ Redis deployed');\n\n\t\t\t\t// Construct connection URL\n\t\t\t\tconst password = redis.databasePassword\n\t\t\t\t\t? `:${redis.databasePassword}@`\n\t\t\t\t\t: '';\n\t\t\t\tserviceUrls.REDIS_URL = `redis://${password}${redis.appName}:6379`;\n\t\t\t\tlogger.log(` ✓ REDIS_URL configured`);\n\t\t\t} catch (error) {\n\t\t\t\tconst message =\n\t\t\t\t\terror instanceof Error ? error.message : 'Unknown error';\n\t\t\t\tif (\n\t\t\t\t\tmessage.includes('already exists') ||\n\t\t\t\t\tmessage.includes('duplicate')\n\t\t\t\t) {\n\t\t\t\t\tlogger.log(` ℹ Redis already exists`);\n\t\t\t\t} else {\n\t\t\t\t\tlogger.log(` ⚠ Failed to provision Redis: ${message}`);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn Object.keys(serviceUrls).length > 0 ? serviceUrls : undefined;\n}\n\n/**\n * Ensure Dokploy is fully configured, recovering/creating resources as needed\n */\nasync function ensureDokploySetup(\n\tconfig: GkmConfig,\n\tdockerConfig: { registry?: string; imageName?: string },\n\tstage: string,\n\tservices?: DockerComposeServices,\n): Promise<DokploySetupResult> {\n\tlogger.log('\\n🔧 Checking Dokploy setup...');\n\n\t// Read existing secrets to check if services are already configured\n\tconst { readStageSecrets } = await import('../secrets/storage');\n\tconst existingSecrets = await readStageSecrets(stage);\n\tconst existingUrls: { DATABASE_URL?: string; REDIS_URL?: string } = {\n\t\tDATABASE_URL: existingSecrets?.urls?.DATABASE_URL,\n\t\tREDIS_URL: existingSecrets?.urls?.REDIS_URL,\n\t};\n\n\t// Step 1: Ensure we have Dokploy credentials\n\tlet creds = await getDokployCredentials();\n\n\tif (!creds) {\n\t\tlogger.log(\"\\n📋 Dokploy credentials not found. Let's set them up.\");\n\t\tconst endpoint = await prompt(\n\t\t\t'Dokploy URL (e.g., https://dokploy.example.com): ',\n\t\t);\n\t\tconst normalizedEndpoint = endpoint.replace(/\\/$/, '');\n\n\t\ttry {\n\t\t\tnew URL(normalizedEndpoint);\n\t\t} catch {\n\t\t\tthrow new Error('Invalid URL format');\n\t\t}\n\n\t\tlogger.log(\n\t\t\t`\\nGenerate a token at: ${normalizedEndpoint}/settings/profile\\n`,\n\t\t);\n\t\tconst token = await prompt('API Token: ', true);\n\n\t\tlogger.log('\\nValidating credentials...');\n\t\tconst isValid = await validateDokployToken(normalizedEndpoint, token);\n\t\tif (!isValid) {\n\t\t\tthrow new Error('Invalid credentials. Please check your token.');\n\t\t}\n\n\t\tawait storeDokployCredentials(token, normalizedEndpoint);\n\t\tcreds = { token, endpoint: normalizedEndpoint };\n\t\tlogger.log('✓ Credentials saved');\n\t}\n\n\tconst api = new DokployApi({ baseUrl: creds.endpoint, token: creds.token });\n\n\t// Step 2: Check if we have config in gkm.config.ts\n\tconst existingConfig = config.providers?.dokploy;\n\tif (\n\t\texistingConfig &&\n\t\ttypeof existingConfig !== 'boolean' &&\n\t\texistingConfig.applicationId &&\n\t\texistingConfig.projectId\n\t) {\n\t\tlogger.log('✓ Dokploy config found in gkm.config.ts');\n\n\t\t// Verify the application still exists\n\t\ttry {\n\t\t\tconst projectDetails = await api.getProject(existingConfig.projectId);\n\t\t\tlogger.log('✓ Project verified');\n\n\t\t\t// Get registry ID from config first, then from local storage\n\t\t\tconst storedRegistryId =\n\t\t\t\texistingConfig.registryId ?? (await getDokployRegistryId());\n\n\t\t\t// Get environment ID for service provisioning (match by stage name)\n\t\t\tconst environments = projectDetails.environments ?? [];\n\t\t\tlet environment = environments.find(\n\t\t\t\t(e) => e.name.toLowerCase() === stage.toLowerCase(),\n\t\t\t);\n\n\t\t\t// Create environment if it doesn't exist for this stage\n\t\t\tif (!environment) {\n\t\t\t\tlogger.log(` Creating \"${stage}\" environment...`);\n\t\t\t\tenvironment = await api.createEnvironment(\n\t\t\t\t\texistingConfig.projectId,\n\t\t\t\t\tstage,\n\t\t\t\t);\n\t\t\t\tlogger.log(` ✓ Created environment: ${environment.environmentId}`);\n\t\t\t}\n\n\t\t\tconst environmentId = environment.environmentId;\n\n\t\t\t// Provision services if configured\n\t\t\tlogger.log(\n\t\t\t\t` Services config: ${JSON.stringify(services)}, envId: ${environmentId}`,\n\t\t\t);\n\t\t\tconst serviceUrls = await provisionServices(\n\t\t\t\tapi,\n\t\t\t\texistingConfig.projectId,\n\t\t\t\tenvironmentId,\n\t\t\t\tdockerConfig.imageName || 'app',\n\t\t\t\tservices,\n\t\t\t\texistingUrls,\n\t\t\t);\n\n\t\t\treturn {\n\t\t\t\tconfig: {\n\t\t\t\t\tendpoint: existingConfig.endpoint,\n\t\t\t\t\tprojectId: existingConfig.projectId,\n\t\t\t\t\tapplicationId: existingConfig.applicationId,\n\t\t\t\t\tregistry: existingConfig.registry,\n\t\t\t\t\tregistryId: storedRegistryId ?? undefined,\n\t\t\t\t},\n\t\t\t\tserviceUrls,\n\t\t\t};\n\t\t} catch {\n\t\t\tlogger.log('⚠ Project not found, will recover...');\n\t\t}\n\t}\n\n\t// Step 3: Find or create project\n\tlogger.log('\\n📁 Looking for project...');\n\tconst projectName = dockerConfig.imageName || 'app';\n\tconst projects = await api.listProjects();\n\tlet project = projects.find(\n\t\t(p) => p.name.toLowerCase() === projectName.toLowerCase(),\n\t);\n\n\tlet environmentId: string;\n\n\tif (project) {\n\t\tlogger.log(\n\t\t\t` Found existing project: ${project.name} (${project.projectId})`,\n\t\t);\n\n\t\t// Step 4: Get or create environment for existing project (match by stage)\n\t\tconst projectDetails = await api.getProject(project.projectId);\n\t\tconst environments = projectDetails.environments ?? [];\n\t\tconst matchingEnv = environments.find(\n\t\t\t(e) => e.name.toLowerCase() === stage.toLowerCase(),\n\t\t);\n\t\tif (matchingEnv) {\n\t\t\tenvironmentId = matchingEnv.environmentId;\n\t\t\tlogger.log(` Using environment: ${matchingEnv.name}`);\n\t\t} else {\n\t\t\tlogger.log(` Creating \"${stage}\" environment...`);\n\t\t\tconst env = await api.createEnvironment(project.projectId, stage);\n\t\t\tenvironmentId = env.environmentId;\n\t\t\tlogger.log(` ✓ Created environment: ${stage}`);\n\t\t}\n\t} else {\n\t\tlogger.log(` Creating project: ${projectName}`);\n\t\tconst result = await api.createProject(projectName);\n\t\tproject = result.project;\n\t\t// Rename the default environment to match stage if different\n\t\tif (result.environment.name.toLowerCase() !== stage.toLowerCase()) {\n\t\t\tlogger.log(` Creating \"${stage}\" environment...`);\n\t\t\tconst env = await api.createEnvironment(project.projectId, stage);\n\t\t\tenvironmentId = env.environmentId;\n\t\t} else {\n\t\t\tenvironmentId = result.environment.environmentId;\n\t\t}\n\t\tlogger.log(` ✓ Created project: ${project.projectId}`);\n\t\tlogger.log(` ✓ Using environment: ${stage}`);\n\t}\n\n\t// Step 5: Find or create application\n\tlogger.log('\\n📦 Looking for application...');\n\tconst appName = dockerConfig.imageName || projectName;\n\n\tlet applicationId: string;\n\n\t// Try to find existing app from config\n\tif (\n\t\texistingConfig &&\n\t\ttypeof existingConfig !== 'boolean' &&\n\t\texistingConfig.applicationId\n\t) {\n\t\tapplicationId = existingConfig.applicationId;\n\t\tlogger.log(` Using application from config: ${applicationId}`);\n\t} else {\n\t\t// Create new application\n\t\tlogger.log(` Creating application: ${appName}`);\n\t\tconst app = await api.createApplication(\n\t\t\tappName,\n\t\t\tproject.projectId,\n\t\t\tenvironmentId,\n\t\t);\n\t\tapplicationId = app.applicationId;\n\t\tlogger.log(` ✓ Created application: ${applicationId}`);\n\t}\n\n\t// Step 6: Ensure registry is set up\n\tlogger.log('\\n🐳 Checking registry...');\n\tlet registryId = await getDokployRegistryId();\n\n\tif (registryId) {\n\t\t// Verify stored registry still exists\n\t\ttry {\n\t\t\tconst registry = await api.getRegistry(registryId);\n\t\t\tlogger.log(` Using registry: ${registry.registryName}`);\n\t\t} catch {\n\t\t\tlogger.log(' ⚠ Stored registry not found, clearing...');\n\t\t\tregistryId = undefined;\n\t\t\tawait storeDokployRegistryId('');\n\t\t}\n\t}\n\n\tif (!registryId) {\n\t\tconst registries = await api.listRegistries();\n\n\t\tif (registries.length === 0) {\n\t\t\t// No registries exist\n\t\t\tif (dockerConfig.registry) {\n\t\t\t\tlogger.log(\" No registries found in Dokploy. Let's create one.\");\n\t\t\t\tlogger.log(` Registry URL: ${dockerConfig.registry}`);\n\n\t\t\t\tconst username = await prompt('Registry username: ');\n\t\t\t\tconst password = await prompt('Registry password/token: ', true);\n\n\t\t\t\tconst registry = await api.createRegistry(\n\t\t\t\t\t'Default Registry',\n\t\t\t\t\tdockerConfig.registry,\n\t\t\t\t\tusername,\n\t\t\t\t\tpassword,\n\t\t\t\t);\n\t\t\t\tregistryId = registry.registryId;\n\t\t\t\tawait storeDokployRegistryId(registryId);\n\t\t\t\tlogger.log(` ✓ Registry created: ${registryId}`);\n\t\t\t} else {\n\t\t\t\tlogger.log(\n\t\t\t\t\t' ⚠ No registry configured. Set docker.registry in gkm.config.ts',\n\t\t\t\t);\n\t\t\t}\n\t\t} else {\n\t\t\t// Show available registries and let user select or create new\n\t\t\tlogger.log(' Available registries:');\n\t\t\tregistries.forEach((reg, i) => {\n\t\t\t\tlogger.log(` ${i + 1}. ${reg.registryName} (${reg.registryUrl})`);\n\t\t\t});\n\t\t\tif (dockerConfig.registry) {\n\t\t\t\tlogger.log(` ${registries.length + 1}. Create new registry`);\n\t\t\t}\n\n\t\t\tconst maxOption = dockerConfig.registry\n\t\t\t\t? registries.length + 1\n\t\t\t\t: registries.length;\n\t\t\tconst selection = await prompt(` Select registry (1-${maxOption}): `);\n\t\t\tconst index = parseInt(selection, 10) - 1;\n\n\t\t\tif (index >= 0 && index < registries.length) {\n\t\t\t\t// Selected existing registry\n\t\t\t\tregistryId = registries[index]!.registryId;\n\t\t\t\tawait storeDokployRegistryId(registryId);\n\t\t\t\tlogger.log(` ✓ Selected: ${registries[index]!.registryName}`);\n\t\t\t} else if (dockerConfig.registry && index === registries.length) {\n\t\t\t\t// Create new registry\n\t\t\t\tlogger.log(`\\n Creating new registry...`);\n\t\t\t\tlogger.log(` Registry URL: ${dockerConfig.registry}`);\n\n\t\t\t\tconst username = await prompt(' Registry username: ');\n\t\t\t\tconst password = await prompt(' Registry password/token: ', true);\n\n\t\t\t\tconst registry = await api.createRegistry(\n\t\t\t\t\tdockerConfig.registry.replace(/^https?:\\/\\//, ''),\n\t\t\t\t\tdockerConfig.registry,\n\t\t\t\t\tusername,\n\t\t\t\t\tpassword,\n\t\t\t\t);\n\t\t\t\tregistryId = registry.registryId;\n\t\t\t\tawait storeDokployRegistryId(registryId);\n\t\t\t\tlogger.log(` ✓ Registry created: ${registryId}`);\n\t\t\t} else {\n\t\t\t\tlogger.log(' ⚠ Invalid selection, skipping registry setup');\n\t\t\t}\n\t\t}\n\t}\n\n\t// Step 7: Build and save config\n\tconst dokployConfig: DokployDeployConfig = {\n\t\tendpoint: creds.endpoint,\n\t\tprojectId: project.projectId,\n\t\tapplicationId,\n\t\tregistryId: registryId ?? undefined,\n\t};\n\n\t// Update gkm.config.ts\n\tawait updateConfig(dokployConfig);\n\n\tlogger.log('\\n✅ Dokploy setup complete!');\n\tlogger.log(` Project: ${project.projectId}`);\n\tlogger.log(` Application: ${applicationId}`);\n\tif (registryId) {\n\t\tlogger.log(` Registry: ${registryId}`);\n\t}\n\n\t// Step 8: Provision docker compose services if configured\n\tconst serviceUrls = await provisionServices(\n\t\tapi,\n\t\tproject.projectId,\n\t\tenvironmentId,\n\t\tdockerConfig.imageName || 'app',\n\t\tservices,\n\t\texistingUrls,\n\t);\n\n\treturn {\n\t\tconfig: dokployConfig,\n\t\tserviceUrls,\n\t};\n}\n\n/**\n * Generate image tag from stage and timestamp\n */\nexport function generateTag(stage: string): string {\n\tconst timestamp = new Date().toISOString().replace(/[:.]/g, '-').slice(0, 19);\n\treturn `${stage}-${timestamp}`;\n}\n\n/**\n * Main deploy command\n */\nexport async function deployCommand(\n\toptions: DeployOptions,\n): Promise<DeployResult> {\n\tconst { provider, stage, tag, skipPush, skipBuild } = options;\n\n\tlogger.log(`\\n🚀 Deploying to ${provider}...`);\n\tlogger.log(` Stage: ${stage}`);\n\n\t// Load config\n\tconst config = await loadConfig();\n\n\t// Generate tag if not provided\n\tconst imageTag = tag ?? generateTag(stage);\n\tlogger.log(` Tag: ${imageTag}`);\n\n\t// Resolve docker config for image reference\n\tconst dockerConfig = resolveDockerConfig(config);\n\tconst imageName = dockerConfig.imageName ?? 'app';\n\tconst registry = dockerConfig.registry;\n\tconst imageRef = registry\n\t\t? `${registry}/${imageName}:${imageTag}`\n\t\t: `${imageName}:${imageTag}`;\n\n\t// For Dokploy, set up services BEFORE build so URLs are available\n\tlet dokployConfig: DokployDeployConfig | undefined;\n\tlet finalRegistry = registry;\n\n\tif (provider === 'dokploy') {\n\t\t// Extract docker compose services config\n\t\tconst composeServices = config.docker?.compose?.services;\n\t\tlogger.log(\n\t\t\t`\\n🔍 Docker compose config: ${JSON.stringify(config.docker?.compose)}`,\n\t\t);\n\t\tconst dockerServices: DockerComposeServices | undefined = composeServices\n\t\t\t? Array.isArray(composeServices)\n\t\t\t\t? {\n\t\t\t\t\t\tpostgres: composeServices.includes('postgres'),\n\t\t\t\t\t\tredis: composeServices.includes('redis'),\n\t\t\t\t\t\trabbitmq: composeServices.includes('rabbitmq'),\n\t\t\t\t\t}\n\t\t\t\t: {\n\t\t\t\t\t\tpostgres: Boolean(composeServices.postgres),\n\t\t\t\t\t\tredis: Boolean(composeServices.redis),\n\t\t\t\t\t\trabbitmq: Boolean(composeServices.rabbitmq),\n\t\t\t\t\t}\n\t\t\t: undefined;\n\n\t\t// Ensure Dokploy is fully set up (credentials, project, app, registry, services)\n\t\tconst setupResult = await ensureDokploySetup(\n\t\t\tconfig,\n\t\t\tdockerConfig,\n\t\t\tstage,\n\t\t\tdockerServices,\n\t\t);\n\t\tdokployConfig = setupResult.config;\n\t\tfinalRegistry = dokployConfig.registry ?? dockerConfig.registry;\n\n\t\t// Save provisioned service URLs to secrets before build\n\t\tif (setupResult.serviceUrls) {\n\t\t\tconst { readStageSecrets, writeStageSecrets, initStageSecrets } =\n\t\t\t\tawait import('../secrets/storage');\n\t\t\tlet secrets = await readStageSecrets(stage);\n\n\t\t\t// Create secrets file if it doesn't exist\n\t\t\tif (!secrets) {\n\t\t\t\tlogger.log(` Creating secrets file for stage \"${stage}\"...`);\n\t\t\t\tsecrets = initStageSecrets(stage);\n\t\t\t}\n\n\t\t\tlet updated = false;\n\t\t\tfor (const [key, value] of Object.entries(setupResult.serviceUrls)) {\n\t\t\t\tconst urlKey = key as keyof typeof secrets.urls;\n\t\t\t\tif (value && !secrets.urls[urlKey] && !secrets.custom[key]) {\n\t\t\t\t\tsecrets.urls[urlKey] = value;\n\t\t\t\t\tlogger.log(` Saved ${key} to secrets`);\n\t\t\t\t\tupdated = true;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (updated) {\n\t\t\t\tawait writeStageSecrets(secrets);\n\t\t\t}\n\t\t}\n\t}\n\n\t// Build for production with secrets injection (unless skipped)\n\tlet masterKey: string | undefined;\n\tif (!skipBuild) {\n\t\tlogger.log(`\\n📦 Building for production...`);\n\t\tconst buildResult = await buildCommand({\n\t\t\tprovider: 'server',\n\t\t\tproduction: true,\n\t\t\tstage,\n\t\t});\n\t\tmasterKey = buildResult.masterKey;\n\t} else {\n\t\tlogger.log(`\\n⏭️ Skipping build (--skip-build)`);\n\t}\n\n\t// Deploy based on provider\n\tlet result: DeployResult;\n\n\tswitch (provider) {\n\t\tcase 'docker': {\n\t\t\tresult = await deployDocker({\n\t\t\t\tstage,\n\t\t\t\ttag: imageTag,\n\t\t\t\tskipPush,\n\t\t\t\tmasterKey,\n\t\t\t\tconfig: dockerConfig,\n\t\t\t});\n\t\t\tbreak;\n\t\t}\n\n\t\tcase 'dokploy': {\n\t\t\tif (!dokployConfig) {\n\t\t\t\tthrow new Error('Dokploy config not initialized');\n\t\t\t}\n\t\t\tconst finalImageRef = finalRegistry\n\t\t\t\t? `${finalRegistry}/${imageName}:${imageTag}`\n\t\t\t\t: `${imageName}:${imageTag}`;\n\n\t\t\t// First build and push the Docker image\n\t\t\tawait deployDocker({\n\t\t\t\tstage,\n\t\t\t\ttag: imageTag,\n\t\t\t\tskipPush: false, // Dokploy needs the image in registry\n\t\t\t\tmasterKey,\n\t\t\t\tconfig: {\n\t\t\t\t\tregistry: finalRegistry,\n\t\t\t\t\timageName: dockerConfig.imageName,\n\t\t\t\t},\n\t\t\t});\n\n\t\t\t// Then trigger Dokploy deployment\n\t\t\tresult = await deployDokploy({\n\t\t\t\tstage,\n\t\t\t\ttag: imageTag,\n\t\t\t\timageRef: finalImageRef,\n\t\t\t\tmasterKey,\n\t\t\t\tconfig: dokployConfig,\n\t\t\t});\n\t\t\tbreak;\n\t\t}\n\n\t\tcase 'aws-lambda': {\n\t\t\tlogger.log('\\n⚠️ AWS Lambda deployment is not yet implemented.');\n\t\t\tlogger.log(' Use SST or AWS CDK for Lambda deployments.');\n\t\t\tresult = { imageRef, masterKey };\n\t\t\tbreak;\n\t\t}\n\n\t\tdefault: {\n\t\t\tthrow new Error(\n\t\t\t\t`Unknown deploy provider: ${provider}\\n` +\n\t\t\t\t\t'Supported providers: docker, dokploy, aws-lambda',\n\t\t\t);\n\t\t}\n\t}\n\n\tlogger.log('\\n✅ Deployment complete!');\n\n\treturn result;\n}\n\nexport type { DeployOptions, DeployProvider, DeployResult };\n","import type {\n\tGeneratedFile,\n\tTemplateConfig,\n\tTemplateOptions,\n} from '../templates/index.js';\n\n/**\n * Generate configuration files (gkm.config.ts, tsconfig.json, biome.json, turbo.json)\n */\nexport function generateConfigFiles(\n\toptions: TemplateOptions,\n\ttemplate: TemplateConfig,\n): GeneratedFile[] {\n\tconst { telescope, studio, routesStructure } = options;\n\tconst isServerless = template.name === 'serverless';\n\tconst hasWorker = template.name === 'worker';\n\n\t// Get routes glob pattern based on structure\n\tconst getRoutesGlob = () => {\n\t\tswitch (routesStructure) {\n\t\t\tcase 'centralized-endpoints':\n\t\t\t\treturn './src/endpoints/**/*.ts';\n\t\t\tcase 'centralized-routes':\n\t\t\t\treturn './src/routes/**/*.ts';\n\t\t\tcase 'domain-based':\n\t\t\t\treturn './src/**/routes/*.ts';\n\t\t}\n\t};\n\n\t// Build gkm.config.ts\n\tlet gkmConfig = `import { defineConfig } from '@geekmidas/cli/config';\n\nexport default defineConfig({\n routes: '${getRoutesGlob()}',\n envParser: './src/config/env#envParser',\n logger: './src/config/logger#logger',`;\n\n\tif (isServerless || hasWorker) {\n\t\tgkmConfig += `\n functions: './src/functions/**/*.ts',`;\n\t}\n\n\tif (hasWorker) {\n\t\tgkmConfig += `\n crons: './src/crons/**/*.ts',\n subscribers: './src/subscribers/**/*.ts',`;\n\t}\n\n\tif (telescope) {\n\t\tgkmConfig += `\n telescope: {\n enabled: true,\n path: '/__telescope',\n },`;\n\t}\n\n\tif (studio) {\n\t\tgkmConfig += `\n studio: './src/config/studio#studio',`;\n\t}\n\n\t// Always add openapi config (output path is fixed to .gkm/openapi.ts)\n\tgkmConfig += `\n openapi: {\n enabled: true,\n },`;\n\n\tgkmConfig += `\n});\n`;\n\n\t// Build tsconfig.json - extends root for monorepo, standalone for non-monorepo\n\tconst tsConfig = options.monorepo\n\t\t? {\n\t\t\t\textends: '../../tsconfig.json',\n\t\t\t\tcompilerOptions: {\n\t\t\t\t\toutDir: './dist',\n\t\t\t\t\trootDir: './src',\n\t\t\t\t\tbaseUrl: '.',\n\t\t\t\t\tpaths: {\n\t\t\t\t\t\t[`@${options.name}/*`]: ['../../packages/*/src'],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tinclude: ['src/**/*.ts'],\n\t\t\t\texclude: ['node_modules', 'dist'],\n\t\t\t}\n\t\t: {\n\t\t\t\tcompilerOptions: {\n\t\t\t\t\ttarget: 'ES2022',\n\t\t\t\t\tmodule: 'NodeNext',\n\t\t\t\t\tmoduleResolution: 'NodeNext',\n\t\t\t\t\tlib: ['ES2022'],\n\t\t\t\t\tstrict: true,\n\t\t\t\t\tesModuleInterop: true,\n\t\t\t\t\tskipLibCheck: true,\n\t\t\t\t\tforceConsistentCasingInFileNames: true,\n\t\t\t\t\tresolveJsonModule: true,\n\t\t\t\t\tdeclaration: true,\n\t\t\t\t\tdeclarationMap: true,\n\t\t\t\t\toutDir: './dist',\n\t\t\t\t\trootDir: './src',\n\t\t\t\t},\n\t\t\t\tinclude: ['src/**/*.ts'],\n\t\t\t\texclude: ['node_modules', 'dist'],\n\t\t\t};\n\n\t// Skip biome.json and turbo.json for monorepo (they're at root)\n\tif (options.monorepo) {\n\t\treturn [\n\t\t\t{\n\t\t\t\tpath: 'gkm.config.ts',\n\t\t\t\tcontent: gkmConfig,\n\t\t\t},\n\t\t\t{\n\t\t\t\tpath: 'tsconfig.json',\n\t\t\t\tcontent: `${JSON.stringify(tsConfig, null, 2)}\\n`,\n\t\t\t},\n\t\t];\n\t}\n\n\t// Build biome.json\n\tconst biomeConfig = {\n\t\t$schema: 'https://biomejs.dev/schemas/1.9.4/schema.json',\n\t\tvcs: {\n\t\t\tenabled: true,\n\t\t\tclientKind: 'git',\n\t\t\tuseIgnoreFile: true,\n\t\t},\n\t\torganizeImports: {\n\t\t\tenabled: true,\n\t\t},\n\t\tformatter: {\n\t\t\tenabled: true,\n\t\t\tindentStyle: 'space',\n\t\t\tindentWidth: 2,\n\t\t\tlineWidth: 80,\n\t\t},\n\t\tjavascript: {\n\t\t\tformatter: {\n\t\t\t\tquoteStyle: 'single',\n\t\t\t\ttrailingCommas: 'all',\n\t\t\t\tsemicolons: 'always',\n\t\t\t\tarrowParentheses: 'always',\n\t\t\t},\n\t\t},\n\t\tlinter: {\n\t\t\tenabled: true,\n\t\t\trules: {\n\t\t\t\trecommended: true,\n\t\t\t\tcorrectness: {\n\t\t\t\t\tnoUnusedImports: 'error',\n\t\t\t\t\tnoUnusedVariables: 'error',\n\t\t\t\t},\n\t\t\t\tstyle: {\n\t\t\t\t\tnoNonNullAssertion: 'off',\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\tfiles: {\n\t\t\tignore: ['node_modules', 'dist', '.gkm', 'coverage'],\n\t\t},\n\t};\n\n\t// Build turbo.json\n\tconst turboConfig = {\n\t\t$schema: 'https://turbo.build/schema.json',\n\t\ttasks: {\n\t\t\tbuild: {\n\t\t\t\tdependsOn: ['^build'],\n\t\t\t\toutputs: ['dist/**'],\n\t\t\t},\n\t\t\tdev: {\n\t\t\t\tcache: false,\n\t\t\t\tpersistent: true,\n\t\t\t},\n\t\t\ttest: {\n\t\t\t\tdependsOn: ['^build'],\n\t\t\t\tcache: false,\n\t\t\t},\n\t\t\t'test:once': {\n\t\t\t\tdependsOn: ['^build'],\n\t\t\t\toutputs: ['coverage/**'],\n\t\t\t},\n\t\t\ttypecheck: {\n\t\t\t\tdependsOn: ['^build'],\n\t\t\t\toutputs: [],\n\t\t\t},\n\t\t\tlint: {\n\t\t\t\toutputs: [],\n\t\t\t},\n\t\t\tfmt: {\n\t\t\t\toutputs: [],\n\t\t\t},\n\t\t},\n\t};\n\n\treturn [\n\t\t{\n\t\t\tpath: 'gkm.config.ts',\n\t\t\tcontent: gkmConfig,\n\t\t},\n\t\t{\n\t\t\tpath: 'tsconfig.json',\n\t\t\tcontent: `${JSON.stringify(tsConfig, null, 2)}\\n`,\n\t\t},\n\t\t{\n\t\t\tpath: 'biome.json',\n\t\t\tcontent: `${JSON.stringify(biomeConfig, null, 2)}\\n`,\n\t\t},\n\t\t{\n\t\t\tpath: 'turbo.json',\n\t\t\tcontent: `${JSON.stringify(turboConfig, null, 2)}\\n`,\n\t\t},\n\t];\n}\n","import type {\n\tGeneratedFile,\n\tTemplateConfig,\n\tTemplateOptions,\n} from '../templates/index.js';\n\n/**\n * Generate docker-compose.yml based on template and options\n */\nexport function generateDockerFiles(\n\toptions: TemplateOptions,\n\ttemplate: TemplateConfig,\n): GeneratedFile[] {\n\tconst { database } = options;\n\tconst isServerless = template.name === 'serverless';\n\tconst hasWorker = template.name === 'worker';\n\n\tconst services: string[] = [];\n\tconst volumes: string[] = [];\n\n\t// PostgreSQL database\n\tif (database) {\n\t\tservices.push(` postgres:\n image: postgres:16-alpine\n container_name: ${options.name}-postgres\n restart: unless-stopped\n environment:\n POSTGRES_USER: postgres\n POSTGRES_PASSWORD: postgres\n POSTGRES_DB: ${options.name.replace(/-/g, '_')}_dev\n ports:\n - '5432:5432'\n volumes:\n - postgres_data:/var/lib/postgresql/data\n healthcheck:\n test: ['CMD-SHELL', 'pg_isready -U postgres']\n interval: 5s\n timeout: 5s\n retries: 5`);\n\t\tvolumes.push(' postgres_data:');\n\t}\n\n\t// Redis - different setup for serverless vs standard\n\tif (isServerless) {\n\t\t// Use serverless-redis-http for Lambda compatibility\n\t\tservices.push(` redis:\n image: redis:7-alpine\n container_name: ${options.name}-redis\n restart: unless-stopped\n ports:\n - '6379:6379'\n volumes:\n - redis_data:/data\n healthcheck:\n test: ['CMD', 'redis-cli', 'ping']\n interval: 5s\n timeout: 5s\n retries: 5\n\n serverless-redis:\n image: hiett/serverless-redis-http:latest\n container_name: ${options.name}-serverless-redis\n restart: unless-stopped\n ports:\n - '8079:80'\n environment:\n SRH_MODE: env\n SRH_TOKEN: local_dev_token\n SRH_CONNECTION_STRING: redis://redis:6379\n depends_on:\n redis:\n condition: service_healthy`);\n\t\tvolumes.push(' redis_data:');\n\t} else {\n\t\t// Standard Redis for non-serverless templates\n\t\tservices.push(` redis:\n image: redis:7-alpine\n container_name: ${options.name}-redis\n restart: unless-stopped\n ports:\n - '6379:6379'\n volumes:\n - redis_data:/data\n healthcheck:\n test: ['CMD', 'redis-cli', 'ping']\n interval: 5s\n timeout: 5s\n retries: 5`);\n\t\tvolumes.push(' redis_data:');\n\t}\n\n\t// RabbitMQ for worker template\n\tif (hasWorker) {\n\t\tservices.push(` rabbitmq:\n image: rabbitmq:3-management-alpine\n container_name: ${options.name}-rabbitmq\n restart: unless-stopped\n ports:\n - '5672:5672'\n - '15672:15672'\n environment:\n RABBITMQ_DEFAULT_USER: guest\n RABBITMQ_DEFAULT_PASS: guest\n volumes:\n - rabbitmq_data:/var/lib/rabbitmq\n healthcheck:\n test: ['CMD', 'rabbitmq-diagnostics', 'check_running']\n interval: 10s\n timeout: 5s\n retries: 5`);\n\t\tvolumes.push(' rabbitmq_data:');\n\t}\n\n\t// Build docker-compose.yml\n\tlet dockerCompose = `version: '3.8'\n\nservices:\n${services.join('\\n\\n')}\n`;\n\n\tif (volumes.length > 0) {\n\t\tdockerCompose += `\nvolumes:\n${volumes.join('\\n')}\n`;\n\t}\n\n\treturn [\n\t\t{\n\t\t\tpath: 'docker-compose.yml',\n\t\t\tcontent: dockerCompose,\n\t\t},\n\t];\n}\n","import type {\n\tGeneratedFile,\n\tTemplateConfig,\n\tTemplateOptions,\n} from '../templates/index.js';\n\n/**\n * Generate environment files (.env, .env.example, .env.development, .env.test, .gitignore)\n */\nexport function generateEnvFiles(\n\toptions: TemplateOptions,\n\ttemplate: TemplateConfig,\n): GeneratedFile[] {\n\tconst { database } = options;\n\tconst isServerless = template.name === 'serverless';\n\tconst hasWorker = template.name === 'worker';\n\n\t// Build base env content\n\tlet baseEnv = `# Application\nNODE_ENV=development\nPORT=3000\nLOG_LEVEL=info\n`;\n\n\tif (isServerless) {\n\t\tbaseEnv = `# AWS\nSTAGE=dev\nAWS_REGION=us-east-1\nLOG_LEVEL=info\n`;\n\t}\n\n\tif (database) {\n\t\tbaseEnv += `\n# Database\nDATABASE_URL=postgresql://user:password@localhost:5432/mydb\n`;\n\t}\n\n\tif (hasWorker) {\n\t\tbaseEnv += `\n# Message Queue\nRABBITMQ_URL=amqp://localhost:5672\n`;\n\t}\n\n\tbaseEnv += `\n# Authentication\nJWT_SECRET=your-secret-key-change-in-production\n`;\n\n\t// Development env\n\tlet devEnv = `# Development Environment\nNODE_ENV=development\nPORT=3000\nLOG_LEVEL=debug\n`;\n\n\tif (isServerless) {\n\t\tdevEnv = `# Development Environment\nSTAGE=dev\nAWS_REGION=us-east-1\nLOG_LEVEL=debug\n`;\n\t}\n\n\tif (database) {\n\t\tdevEnv += `\n# Database\nDATABASE_URL=postgresql://postgres:postgres@localhost:5432/mydb_dev\n`;\n\t}\n\n\tif (hasWorker) {\n\t\tdevEnv += `\n# Message Queue\nRABBITMQ_URL=amqp://localhost:5672\n`;\n\t}\n\n\tdevEnv += `\n# Authentication\nJWT_SECRET=dev-secret-not-for-production\n`;\n\n\t// Test env\n\tlet testEnv = `# Test Environment\nNODE_ENV=test\nPORT=3001\nLOG_LEVEL=error\n`;\n\n\tif (isServerless) {\n\t\ttestEnv = `# Test Environment\nSTAGE=test\nAWS_REGION=us-east-1\nLOG_LEVEL=error\n`;\n\t}\n\n\tif (database) {\n\t\ttestEnv += `\n# Database\nDATABASE_URL=postgresql://postgres:postgres@localhost:5432/mydb_test\n`;\n\t}\n\n\tif (hasWorker) {\n\t\ttestEnv += `\n# Message Queue\nRABBITMQ_URL=amqp://localhost:5672\n`;\n\t}\n\n\ttestEnv += `\n# Authentication\nJWT_SECRET=test-secret-not-for-production\n`;\n\n\tconst files: GeneratedFile[] = [\n\t\t{\n\t\t\tpath: '.env.example',\n\t\t\tcontent: baseEnv,\n\t\t},\n\t\t{\n\t\t\tpath: '.env',\n\t\t\tcontent: baseEnv,\n\t\t},\n\t\t{\n\t\t\tpath: '.env.development',\n\t\t\tcontent: devEnv,\n\t\t},\n\t\t{\n\t\t\tpath: '.env.test',\n\t\t\tcontent: testEnv,\n\t\t},\n\t];\n\n\t// Only add .gitignore for non-monorepo (monorepo has it at root)\n\tif (!options.monorepo) {\n\t\tconst gitignore = `# Dependencies\nnode_modules/\n\n# Build output\ndist/\n.gkm/\n\n# Environment\n.env\n.env.local\n.env.*.local\n\n# IDE\n.idea/\n.vscode/\n*.swp\n*.swo\n\n# OS\n.DS_Store\nThumbs.db\n\n# Logs\n*.log\nnpm-debug.log*\nyarn-debug.log*\npnpm-debug.log*\n\n# Test coverage\ncoverage/\n\n# TypeScript cache\n*.tsbuildinfo\n`;\n\t\tfiles.push({\n\t\t\tpath: '.gitignore',\n\t\t\tcontent: gitignore,\n\t\t});\n\t}\n\n\treturn files;\n}\n","import type { GeneratedFile, TemplateOptions } from '../templates/index.js';\n\n/**\n * Generate packages/models for shared Zod schemas (monorepo only)\n */\nexport function generateModelsPackage(\n\toptions: TemplateOptions,\n): GeneratedFile[] {\n\tif (!options.monorepo) {\n\t\treturn [];\n\t}\n\n\t// Package name based on project name\n\tconst packageName = `@${options.name}/models`;\n\n\t// package.json for models\n\tconst packageJson = {\n\t\tname: packageName,\n\t\tversion: '0.0.1',\n\t\tprivate: true,\n\t\ttype: 'module',\n\t\texports: {\n\t\t\t'.': {\n\t\t\t\ttypes: './dist/index.d.ts',\n\t\t\t\timport: './dist/index.js',\n\t\t\t},\n\t\t\t'./*': {\n\t\t\t\ttypes: './dist/*.d.ts',\n\t\t\t\timport: './dist/*.js',\n\t\t\t},\n\t\t},\n\t\tscripts: {\n\t\t\tbuild: 'tsc',\n\t\t\t'build:watch': 'tsc --watch',\n\t\t\ttypecheck: 'tsc --noEmit',\n\t\t},\n\t\tdependencies: {\n\t\t\tzod: '~4.1.0',\n\t\t},\n\t\tdevDependencies: {\n\t\t\ttypescript: '~5.8.2',\n\t\t},\n\t};\n\n\t// tsconfig.json for models - extends root\n\tconst tsConfig = {\n\t\textends: '../../tsconfig.json',\n\t\tcompilerOptions: {\n\t\t\toutDir: './dist',\n\t\t\trootDir: './src',\n\t\t},\n\t\tinclude: ['src/**/*.ts'],\n\t\texclude: ['node_modules', 'dist'],\n\t};\n\n\t// Main index.ts with example schemas\n\tconst indexTs = `import { z } from 'zod';\n\n// ============================================\n// Common Schemas\n// ============================================\n\nexport const idSchema = z.string().uuid();\n\nexport const timestampsSchema = z.object({\n createdAt: z.coerce.date(),\n updatedAt: z.coerce.date(),\n});\n\nexport const paginationSchema = z.object({\n page: z.coerce.number().int().positive().default(1),\n limit: z.coerce.number().int().positive().max(100).default(20),\n});\n\nexport const paginatedResponseSchema = <T extends z.ZodTypeAny>(itemSchema: T) =>\n z.object({\n items: z.array(itemSchema),\n total: z.number(),\n page: z.number(),\n limit: z.number(),\n totalPages: z.number(),\n });\n\n// ============================================\n// User Schemas\n// ============================================\n\nexport const userSchema = z.object({\n id: idSchema,\n email: z.string().email(),\n name: z.string().min(1).max(100),\n ...timestampsSchema.shape,\n});\n\nexport const createUserSchema = userSchema.omit({\n id: true,\n createdAt: true,\n updatedAt: true,\n});\n\nexport const updateUserSchema = createUserSchema.partial();\n\n// ============================================\n// Type Exports\n// ============================================\n\nexport type Id = z.infer<typeof idSchema>;\nexport type Timestamps = z.infer<typeof timestampsSchema>;\nexport type Pagination = z.infer<typeof paginationSchema>;\nexport type User = z.infer<typeof userSchema>;\nexport type CreateUser = z.infer<typeof createUserSchema>;\nexport type UpdateUser = z.infer<typeof updateUserSchema>;\n`;\n\n\treturn [\n\t\t{\n\t\t\tpath: 'packages/models/package.json',\n\t\t\tcontent: `${JSON.stringify(packageJson, null, 2)}\\n`,\n\t\t},\n\t\t{\n\t\t\tpath: 'packages/models/tsconfig.json',\n\t\t\tcontent: `${JSON.stringify(tsConfig, null, 2)}\\n`,\n\t\t},\n\t\t{\n\t\t\tpath: 'packages/models/src/index.ts',\n\t\t\tcontent: indexTs,\n\t\t},\n\t];\n}\n","import type {\n\tGeneratedFile,\n\tTemplateConfig,\n\tTemplateOptions,\n} from '../templates/index.js';\n\n/**\n * Generate monorepo root files (pnpm-workspace.yaml, root package.json, etc.)\n */\nexport function generateMonorepoFiles(\n\toptions: TemplateOptions,\n\t_template: TemplateConfig,\n): GeneratedFile[] {\n\tif (!options.monorepo) {\n\t\treturn [];\n\t}\n\n\t// Root package.json for monorepo\n\tconst rootPackageJson = {\n\t\tname: options.name,\n\t\tversion: '0.0.1',\n\t\tprivate: true,\n\t\ttype: 'module',\n\t\tscripts: {\n\t\t\tdev: 'turbo dev',\n\t\t\tbuild: 'turbo build',\n\t\t\ttest: 'turbo test',\n\t\t\t'test:once': 'turbo test:once',\n\t\t\ttypecheck: 'turbo typecheck',\n\t\t\tlint: 'biome lint .',\n\t\t\tfmt: 'biome format . --write',\n\t\t\t'fmt:check': 'biome format .',\n\t\t},\n\t\tdevDependencies: {\n\t\t\t'@biomejs/biome': '~1.9.4',\n\t\t\tturbo: '~2.3.0',\n\t\t\ttypescript: '~5.8.2',\n\t\t\tvitest: '~4.0.0',\n\t\t},\n\t};\n\n\t// pnpm-workspace.yaml - detect folder structure from apiPath\n\tconst apiPathParts = options.apiPath.split('/');\n\tconst appsFolder = apiPathParts[0] || 'apps';\n\n\tconst pnpmWorkspace = `packages:\n - '${appsFolder}/*'\n - 'packages/*'\n`;\n\n\t// Root biome.json\n\tconst biomeConfig = {\n\t\t$schema: 'https://biomejs.dev/schemas/1.9.4/schema.json',\n\t\tvcs: {\n\t\t\tenabled: true,\n\t\t\tclientKind: 'git',\n\t\t\tuseIgnoreFile: true,\n\t\t},\n\t\torganizeImports: {\n\t\t\tenabled: true,\n\t\t},\n\t\tformatter: {\n\t\t\tenabled: true,\n\t\t\tindentStyle: 'space',\n\t\t\tindentWidth: 2,\n\t\t\tlineWidth: 80,\n\t\t},\n\t\tjavascript: {\n\t\t\tformatter: {\n\t\t\t\tquoteStyle: 'single',\n\t\t\t\ttrailingCommas: 'all',\n\t\t\t\tsemicolons: 'always',\n\t\t\t\tarrowParentheses: 'always',\n\t\t\t},\n\t\t},\n\t\tlinter: {\n\t\t\tenabled: true,\n\t\t\trules: {\n\t\t\t\trecommended: true,\n\t\t\t\tcorrectness: {\n\t\t\t\t\tnoUnusedImports: 'error',\n\t\t\t\t\tnoUnusedVariables: 'error',\n\t\t\t\t},\n\t\t\t\tstyle: {\n\t\t\t\t\tnoNonNullAssertion: 'off',\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\tfiles: {\n\t\t\tignore: ['node_modules', 'dist', '.gkm', 'coverage'],\n\t\t},\n\t};\n\n\t// Root turbo.json\n\tconst turboConfig = {\n\t\t$schema: 'https://turbo.build/schema.json',\n\t\ttasks: {\n\t\t\tbuild: {\n\t\t\t\tdependsOn: ['^build'],\n\t\t\t\toutputs: ['dist/**'],\n\t\t\t},\n\t\t\tdev: {\n\t\t\t\tcache: false,\n\t\t\t\tpersistent: true,\n\t\t\t},\n\t\t\ttest: {\n\t\t\t\tdependsOn: ['^build'],\n\t\t\t\tcache: false,\n\t\t\t},\n\t\t\t'test:once': {\n\t\t\t\tdependsOn: ['^build'],\n\t\t\t\toutputs: ['coverage/**'],\n\t\t\t},\n\t\t\ttypecheck: {\n\t\t\t\tdependsOn: ['^build'],\n\t\t\t\toutputs: [],\n\t\t\t},\n\t\t\tlint: {\n\t\t\t\toutputs: [],\n\t\t\t},\n\t\t\tfmt: {\n\t\t\t\toutputs: [],\n\t\t\t},\n\t\t},\n\t};\n\n\t// Root .gitignore\n\tconst gitignore = `# Dependencies\nnode_modules/\n\n# Build output\ndist/\n.gkm/\n\n# Environment\n.env\n.env.local\n.env.*.local\n\n# IDE\n.idea/\n.vscode/\n*.swp\n*.swo\n\n# OS\n.DS_Store\nThumbs.db\n\n# Logs\n*.log\nnpm-debug.log*\nyarn-debug.log*\npnpm-debug.log*\n\n# Test coverage\ncoverage/\n\n# TypeScript cache\n*.tsbuildinfo\n\n# Turbo\n.turbo/\n`;\n\n\t// Root tsconfig.json - base config for all packages\n\tconst tsConfig = {\n\t\tcompilerOptions: {\n\t\t\ttarget: 'ES2022',\n\t\t\tmodule: 'NodeNext',\n\t\t\tmoduleResolution: 'NodeNext',\n\t\t\tlib: ['ES2022'],\n\t\t\tstrict: true,\n\t\t\tesModuleInterop: true,\n\t\t\tskipLibCheck: true,\n\t\t\tforceConsistentCasingInFileNames: true,\n\t\t\tresolveJsonModule: true,\n\t\t\tdeclaration: true,\n\t\t\tdeclarationMap: true,\n\t\t\tcomposite: true,\n\t\t},\n\t\texclude: ['node_modules', 'dist'],\n\t};\n\n\treturn [\n\t\t{\n\t\t\tpath: 'package.json',\n\t\t\tcontent: `${JSON.stringify(rootPackageJson, null, 2)}\\n`,\n\t\t},\n\t\t{\n\t\t\tpath: 'pnpm-workspace.yaml',\n\t\t\tcontent: pnpmWorkspace,\n\t\t},\n\t\t{\n\t\t\tpath: 'tsconfig.json',\n\t\t\tcontent: `${JSON.stringify(tsConfig, null, 2)}\\n`,\n\t\t},\n\t\t{\n\t\t\tpath: 'biome.json',\n\t\t\tcontent: `${JSON.stringify(biomeConfig, null, 2)}\\n`,\n\t\t},\n\t\t{\n\t\t\tpath: 'turbo.json',\n\t\t\tcontent: `${JSON.stringify(turboConfig, null, 2)}\\n`,\n\t\t},\n\t\t{\n\t\t\tpath: '.gitignore',\n\t\t\tcontent: gitignore,\n\t\t},\n\t];\n}\n","import type {\n\tGeneratedFile,\n\tTemplateConfig,\n\tTemplateOptions,\n} from './index.js';\n\nexport const apiTemplate: TemplateConfig = {\n\tname: 'api',\n\tdescription: 'Full API with auth, database, services',\n\n\tdependencies: {\n\t\t'@geekmidas/constructs': 'workspace:*',\n\t\t'@geekmidas/envkit': 'workspace:*',\n\t\t'@geekmidas/logger': 'workspace:*',\n\t\t'@geekmidas/services': 'workspace:*',\n\t\t'@geekmidas/errors': 'workspace:*',\n\t\t'@geekmidas/auth': 'workspace:*',\n\t\thono: '~4.8.2',\n\t\tpino: '~9.6.0',\n\t},\n\n\tdevDependencies: {\n\t\t'@biomejs/biome': '~1.9.4',\n\t\t'@geekmidas/cli': 'workspace:*',\n\t\t'@types/node': '~22.0.0',\n\t\ttsx: '~4.20.0',\n\t\tturbo: '~2.3.0',\n\t\ttypescript: '~5.8.2',\n\t\tvitest: '~4.0.0',\n\t},\n\n\tscripts: {\n\t\tdev: 'gkm dev',\n\t\tbuild: 'gkm build',\n\t\ttest: 'vitest',\n\t\t'test:once': 'vitest run',\n\t\ttypecheck: 'tsc --noEmit',\n\t\tlint: 'biome lint .',\n\t\tfmt: 'biome format . --write',\n\t\t'fmt:check': 'biome format .',\n\t},\n\n\tfiles: (options: TemplateOptions): GeneratedFile[] => {\n\t\tconst { loggerType, routesStructure } = options;\n\n\t\tconst loggerContent = `import { createLogger } from '@geekmidas/logger/${loggerType}';\n\nexport const logger = createLogger();\n`;\n\n\t\t// Get route path based on structure\n\t\tconst getRoutePath = (file: string) => {\n\t\t\tswitch (routesStructure) {\n\t\t\t\tcase 'centralized-endpoints':\n\t\t\t\t\treturn `src/endpoints/${file}`;\n\t\t\t\tcase 'centralized-routes':\n\t\t\t\t\treturn `src/routes/${file}`;\n\t\t\t\tcase 'domain-based': {\n\t\t\t\t\tconst parts = file.split('/');\n\t\t\t\t\tif (parts.length === 1) {\n\t\t\t\t\t\treturn `src/${file.replace('.ts', '')}/routes/index.ts`;\n\t\t\t\t\t}\n\t\t\t\t\treturn `src/${parts[0]}/routes/${parts.slice(1).join('/')}`;\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\n\t\tconst files: GeneratedFile[] = [\n\t\t\t// src/config/env.ts\n\t\t\t{\n\t\t\t\tpath: 'src/config/env.ts',\n\t\t\t\tcontent: `import { EnvironmentParser } from '@geekmidas/envkit';\n\nexport const envParser = new EnvironmentParser(process.env);\n\nexport const config = envParser\n .create((get) => ({\n port: get('PORT').string().transform(Number).default(3000),\n nodeEnv: get('NODE_ENV').string().default('development'),\n jwtSecret: get('JWT_SECRET').string().default('change-me-in-production'),${\n\t\t\toptions.database\n\t\t\t\t? `\n database: {\n url: get('DATABASE_URL').string().default('postgresql://localhost:5432/mydb'),\n },`\n\t\t\t\t: ''\n\t\t}\n }))\n .parse();\n`,\n\t\t\t},\n\n\t\t\t// src/config/logger.ts\n\t\t\t{\n\t\t\t\tpath: 'src/config/logger.ts',\n\t\t\t\tcontent: loggerContent,\n\t\t\t},\n\n\t\t\t// health endpoint\n\t\t\t{\n\t\t\t\tpath: getRoutePath('health.ts'),\n\t\t\t\tcontent: `import { e } from '@geekmidas/constructs/endpoints';\n\nexport default e\n .get('/health')\n .handle(async () => ({\n status: 'ok',\n timestamp: new Date().toISOString(),\n }));\n`,\n\t\t\t},\n\n\t\t\t// users endpoints\n\t\t\t{\n\t\t\t\tpath: getRoutePath('users/list.ts'),\n\t\t\t\tcontent: `import { e } from '@geekmidas/constructs/endpoints';\n\nexport default e\n .get('/users')\n .handle(async () => ({\n users: [\n { id: '1', name: 'Alice' },\n { id: '2', name: 'Bob' },\n ],\n }));\n`,\n\t\t\t},\n\t\t\t{\n\t\t\t\tpath: getRoutePath('users/get.ts'),\n\t\t\t\tcontent: `import { e } from '@geekmidas/constructs/endpoints';\nimport { z } from 'zod';\n\nexport default e\n .get('/users/:id')\n .params(z.object({ id: z.string() }))\n .handle(async ({ params }) => ({\n id: params.id,\n name: 'Alice',\n email: 'alice@example.com',\n }));\n`,\n\t\t\t},\n\t\t];\n\n\t\t// Add database service if enabled\n\t\tif (options.database) {\n\t\t\tfiles.push({\n\t\t\t\tpath: 'src/services/database.ts',\n\t\t\t\tcontent: `import type { Service } from '@geekmidas/services';\nimport { Kysely, PostgresDialect } from 'kysely';\nimport pg from 'pg';\n\n// Define your database schema\nexport interface Database {\n users: {\n id: string;\n name: string;\n email: string;\n created_at: Date;\n };\n}\n\nexport const databaseService = {\n serviceName: 'database' as const,\n async register(envParser) {\n const config = envParser\n .create((get) => ({\n url: get('DATABASE_URL').string(),\n }))\n .parse();\n\n return new Kysely<Database>({\n dialect: new PostgresDialect({\n pool: new pg.Pool({ connectionString: config.url }),\n }),\n });\n },\n} satisfies Service<'database', Kysely<Database>>;\n`,\n\t\t\t});\n\t\t}\n\n\t\t// Add Telescope config if enabled\n\t\tif (options.telescope) {\n\t\t\tfiles.push({\n\t\t\t\tpath: 'src/config/telescope.ts',\n\t\t\t\tcontent: `import { Telescope } from '@geekmidas/telescope';\nimport { InMemoryStorage } from '@geekmidas/telescope/storage/memory';\n\nexport const telescope = new Telescope({\n storage: new InMemoryStorage({ maxEntries: 100 }),\n enabled: process.env.NODE_ENV === 'development',\n});\n`,\n\t\t\t});\n\t\t}\n\n\t\t// Add Studio config if enabled (requires database)\n\t\tif (options.studio && options.database) {\n\t\t\tfiles.push({\n\t\t\t\tpath: 'src/config/studio.ts',\n\t\t\t\tcontent: `import { Direction, InMemoryMonitoringStorage, Studio } from '@geekmidas/studio';\nimport { Kysely, PostgresDialect } from 'kysely';\nimport pg from 'pg';\nimport type { Database } from '../services/database';\nimport { config } from './env';\n\n// Create a Kysely instance for Studio\nconst db = new Kysely<Database>({\n dialect: new PostgresDialect({\n pool: new pg.Pool({ connectionString: config.database.url }),\n }),\n});\n\nexport const studio = new Studio<Database>({\n monitoring: {\n storage: new InMemoryMonitoringStorage({ maxEntries: 100 }),\n },\n data: {\n db,\n cursor: { field: 'id', direction: Direction.Desc },\n },\n enabled: process.env.NODE_ENV === 'development',\n});\n`,\n\t\t\t});\n\t\t}\n\n\t\treturn files;\n\t},\n};\n","import type {\n\tGeneratedFile,\n\tTemplateConfig,\n\tTemplateOptions,\n} from './index.js';\n\nexport const minimalTemplate: TemplateConfig = {\n\tname: 'minimal',\n\tdescription: 'Basic health endpoint',\n\n\tdependencies: {\n\t\t'@geekmidas/constructs': 'workspace:*',\n\t\t'@geekmidas/envkit': 'workspace:*',\n\t\t'@geekmidas/logger': 'workspace:*',\n\t\thono: '~4.8.2',\n\t\tpino: '~9.6.0',\n\t},\n\n\tdevDependencies: {\n\t\t'@biomejs/biome': '~1.9.4',\n\t\t'@geekmidas/cli': 'workspace:*',\n\t\t'@types/node': '~22.0.0',\n\t\ttsx: '~4.20.0',\n\t\tturbo: '~2.3.0',\n\t\ttypescript: '~5.8.2',\n\t\tvitest: '~4.0.0',\n\t},\n\n\tscripts: {\n\t\tdev: 'gkm dev',\n\t\tbuild: 'gkm build',\n\t\ttest: 'vitest',\n\t\t'test:once': 'vitest run',\n\t\ttypecheck: 'tsc --noEmit',\n\t\tlint: 'biome lint .',\n\t\tfmt: 'biome format . --write',\n\t\t'fmt:check': 'biome format .',\n\t},\n\n\tfiles: (options: TemplateOptions): GeneratedFile[] => {\n\t\tconst { loggerType, routesStructure } = options;\n\n\t\tconst loggerContent = `import { createLogger } from '@geekmidas/logger/${loggerType}';\n\nexport const logger = createLogger();\n`;\n\n\t\t// Get route path based on structure\n\t\tconst getRoutePath = (file: string) => {\n\t\t\tswitch (routesStructure) {\n\t\t\t\tcase 'centralized-endpoints':\n\t\t\t\t\treturn `src/endpoints/${file}`;\n\t\t\t\tcase 'centralized-routes':\n\t\t\t\t\treturn `src/routes/${file}`;\n\t\t\t\tcase 'domain-based':\n\t\t\t\t\treturn `src/${file.replace('.ts', '')}/routes/index.ts`;\n\t\t\t}\n\t\t};\n\n\t\tconst files: GeneratedFile[] = [\n\t\t\t// src/config/env.ts\n\t\t\t{\n\t\t\t\tpath: 'src/config/env.ts',\n\t\t\t\tcontent: `import { EnvironmentParser } from '@geekmidas/envkit';\n\nexport const envParser = new EnvironmentParser(process.env);\n\nexport const config = envParser\n .create((get) => ({\n port: get('PORT').string().transform(Number).default(3000),\n nodeEnv: get('NODE_ENV').string().default('development'),\n }))\n .parse();\n`,\n\t\t\t},\n\n\t\t\t// src/config/logger.ts\n\t\t\t{\n\t\t\t\tpath: 'src/config/logger.ts',\n\t\t\t\tcontent: loggerContent,\n\t\t\t},\n\n\t\t\t// health endpoint\n\t\t\t{\n\t\t\t\tpath: getRoutePath('health.ts'),\n\t\t\t\tcontent: `import { e } from '@geekmidas/constructs/endpoints';\n\nexport default e\n .get('/health')\n .handle(async () => ({\n status: 'ok',\n timestamp: new Date().toISOString(),\n }));\n`,\n\t\t\t},\n\t\t];\n\n\t\t// Add database service if enabled\n\t\tif (options.database) {\n\t\t\t// Update env.ts to include database config\n\t\t\tfiles[0] = {\n\t\t\t\tpath: 'src/config/env.ts',\n\t\t\t\tcontent: `import { EnvironmentParser } from '@geekmidas/envkit';\n\nexport const envParser = new EnvironmentParser(process.env);\n\nexport const config = envParser\n .create((get) => ({\n port: get('PORT').string().transform(Number).default(3000),\n nodeEnv: get('NODE_ENV').string().default('development'),\n database: {\n url: get('DATABASE_URL').string().default('postgresql://localhost:5432/mydb'),\n },\n }))\n .parse();\n`,\n\t\t\t};\n\n\t\t\tfiles.push({\n\t\t\t\tpath: 'src/services/database.ts',\n\t\t\t\tcontent: `import type { Service } from '@geekmidas/services';\nimport { Kysely, PostgresDialect } from 'kysely';\nimport pg from 'pg';\n\n// Define your database schema\nexport interface Database {\n // Add your tables here\n}\n\nexport const databaseService = {\n serviceName: 'database' as const,\n async register(envParser) {\n const config = envParser\n .create((get) => ({\n url: get('DATABASE_URL').string(),\n }))\n .parse();\n\n return new Kysely<Database>({\n dialect: new PostgresDialect({\n pool: new pg.Pool({ connectionString: config.url }),\n }),\n });\n },\n} satisfies Service<'database', Kysely<Database>>;\n`,\n\t\t\t});\n\t\t}\n\n\t\t// Add Telescope config if enabled\n\t\tif (options.telescope) {\n\t\t\tfiles.push({\n\t\t\t\tpath: 'src/config/telescope.ts',\n\t\t\t\tcontent: `import { Telescope } from '@geekmidas/telescope';\nimport { InMemoryStorage } from '@geekmidas/telescope/storage/memory';\n\nexport const telescope = new Telescope({\n storage: new InMemoryStorage({ maxEntries: 100 }),\n enabled: process.env.NODE_ENV === 'development',\n});\n`,\n\t\t\t});\n\t\t}\n\n\t\t// Add Studio config if enabled (requires database)\n\t\tif (options.studio && options.database) {\n\t\t\tfiles.push({\n\t\t\t\tpath: 'src/config/studio.ts',\n\t\t\t\tcontent: `import { Direction, InMemoryMonitoringStorage, Studio } from '@geekmidas/studio';\nimport { Kysely, PostgresDialect } from 'kysely';\nimport pg from 'pg';\nimport type { Database } from '../services/database';\nimport { config } from './env';\n\n// Create a Kysely instance for Studio\nconst db = new Kysely<Database>({\n dialect: new PostgresDialect({\n pool: new pg.Pool({ connectionString: config.database.url }),\n }),\n});\n\nexport const studio = new Studio<Database>({\n monitoring: {\n storage: new InMemoryMonitoringStorage({ maxEntries: 100 }),\n },\n data: {\n db,\n cursor: { field: 'id', direction: Direction.Desc },\n },\n enabled: process.env.NODE_ENV === 'development',\n});\n`,\n\t\t\t});\n\t\t}\n\n\t\treturn files;\n\t},\n};\n","import type {\n\tGeneratedFile,\n\tTemplateConfig,\n\tTemplateOptions,\n} from './index.js';\n\nexport const serverlessTemplate: TemplateConfig = {\n\tname: 'serverless',\n\tdescription: 'AWS Lambda handlers',\n\n\tdependencies: {\n\t\t'@geekmidas/constructs': 'workspace:*',\n\t\t'@geekmidas/envkit': 'workspace:*',\n\t\t'@geekmidas/logger': 'workspace:*',\n\t\t'@geekmidas/cloud': 'workspace:*',\n\t\thono: '~4.8.2',\n\t\tpino: '~9.6.0',\n\t},\n\n\tdevDependencies: {\n\t\t'@biomejs/biome': '~1.9.4',\n\t\t'@geekmidas/cli': 'workspace:*',\n\t\t'@types/aws-lambda': '~8.10.92',\n\t\t'@types/node': '~22.0.0',\n\t\ttsx: '~4.20.0',\n\t\tturbo: '~2.3.0',\n\t\ttypescript: '~5.8.2',\n\t\tvitest: '~4.0.0',\n\t},\n\n\tscripts: {\n\t\tdev: 'gkm dev',\n\t\tbuild: 'gkm build --provider aws-apigatewayv2',\n\t\ttest: 'vitest',\n\t\t'test:once': 'vitest run',\n\t\ttypecheck: 'tsc --noEmit',\n\t\tlint: 'biome lint .',\n\t\tfmt: 'biome format . --write',\n\t\t'fmt:check': 'biome format .',\n\t},\n\n\tfiles: (options: TemplateOptions): GeneratedFile[] => {\n\t\tconst { loggerType, routesStructure } = options;\n\n\t\tconst loggerContent = `import { createLogger } from '@geekmidas/logger/${loggerType}';\n\nexport const logger = createLogger();\n`;\n\n\t\t// Get route path based on structure\n\t\tconst getRoutePath = (file: string) => {\n\t\t\tswitch (routesStructure) {\n\t\t\t\tcase 'centralized-endpoints':\n\t\t\t\t\treturn `src/endpoints/${file}`;\n\t\t\t\tcase 'centralized-routes':\n\t\t\t\t\treturn `src/routes/${file}`;\n\t\t\t\tcase 'domain-based':\n\t\t\t\t\treturn `src/${file.replace('.ts', '')}/routes/index.ts`;\n\t\t\t}\n\t\t};\n\n\t\tconst files: GeneratedFile[] = [\n\t\t\t// src/config/env.ts\n\t\t\t{\n\t\t\t\tpath: 'src/config/env.ts',\n\t\t\t\tcontent: `import { EnvironmentParser } from '@geekmidas/envkit';\n\nexport const envParser = new EnvironmentParser(process.env);\n\nexport const config = envParser\n .create((get) => ({\n stage: get('STAGE').string().default('dev'),\n region: get('AWS_REGION').string().default('us-east-1'),${\n\t\t\toptions.database\n\t\t\t\t? `\n database: {\n url: get('DATABASE_URL').string(),\n },`\n\t\t\t\t: ''\n\t\t}\n }))\n .parse();\n`,\n\t\t\t},\n\n\t\t\t// src/config/logger.ts\n\t\t\t{\n\t\t\t\tpath: 'src/config/logger.ts',\n\t\t\t\tcontent: loggerContent,\n\t\t\t},\n\n\t\t\t// health endpoint\n\t\t\t{\n\t\t\t\tpath: getRoutePath('health.ts'),\n\t\t\t\tcontent: `import { e } from '@geekmidas/constructs/endpoints';\n\nexport default e\n .get('/health')\n .handle(async () => ({\n status: 'ok',\n timestamp: new Date().toISOString(),\n region: process.env.AWS_REGION || 'local',\n }));\n`,\n\t\t\t},\n\n\t\t\t// src/functions/hello.ts\n\t\t\t{\n\t\t\t\tpath: 'src/functions/hello.ts',\n\t\t\t\tcontent: `import { f } from '@geekmidas/constructs/functions';\nimport { z } from 'zod';\n\nexport default f\n .input(z.object({ name: z.string() }))\n .output(z.object({ message: z.string() }))\n .handle(async ({ input }) => ({\n message: \\`Hello, \\${input.name}!\\`,\n }));\n`,\n\t\t\t},\n\t\t];\n\n\t\t// Add Telescope config if enabled\n\t\tif (options.telescope) {\n\t\t\tfiles.push({\n\t\t\t\tpath: 'src/config/telescope.ts',\n\t\t\t\tcontent: `import { Telescope } from '@geekmidas/telescope';\nimport { InMemoryStorage } from '@geekmidas/telescope/storage/memory';\n\n// Note: For production Lambda, consider using a persistent storage\nexport const telescope = new Telescope({\n storage: new InMemoryStorage({ maxEntries: 50 }),\n enabled: process.env.STAGE === 'dev',\n});\n`,\n\t\t\t});\n\t\t}\n\n\t\treturn files;\n\t},\n};\n","import type {\n\tGeneratedFile,\n\tTemplateConfig,\n\tTemplateOptions,\n} from './index.js';\n\nexport const workerTemplate: TemplateConfig = {\n\tname: 'worker',\n\tdescription: 'Background job processing',\n\n\tdependencies: {\n\t\t'@geekmidas/constructs': 'workspace:*',\n\t\t'@geekmidas/envkit': 'workspace:*',\n\t\t'@geekmidas/logger': 'workspace:*',\n\t\t'@geekmidas/events': 'workspace:*',\n\t\thono: '~4.8.2',\n\t\tpino: '~9.6.0',\n\t},\n\n\tdevDependencies: {\n\t\t'@biomejs/biome': '~1.9.4',\n\t\t'@geekmidas/cli': 'workspace:*',\n\t\t'@types/node': '~22.0.0',\n\t\ttsx: '~4.20.0',\n\t\tturbo: '~2.3.0',\n\t\ttypescript: '~5.8.2',\n\t\tvitest: '~4.0.0',\n\t},\n\n\tscripts: {\n\t\tdev: 'gkm dev',\n\t\tbuild: 'gkm build',\n\t\ttest: 'vitest',\n\t\t'test:once': 'vitest run',\n\t\ttypecheck: 'tsc --noEmit',\n\t\tlint: 'biome lint .',\n\t\tfmt: 'biome format . --write',\n\t\t'fmt:check': 'biome format .',\n\t},\n\n\tfiles: (options: TemplateOptions): GeneratedFile[] => {\n\t\tconst { loggerType, routesStructure } = options;\n\n\t\tconst loggerContent = `import { createLogger } from '@geekmidas/logger/${loggerType}';\n\nexport const logger = createLogger();\n`;\n\n\t\t// Get route path based on structure\n\t\tconst getRoutePath = (file: string) => {\n\t\t\tswitch (routesStructure) {\n\t\t\t\tcase 'centralized-endpoints':\n\t\t\t\t\treturn `src/endpoints/${file}`;\n\t\t\t\tcase 'centralized-routes':\n\t\t\t\t\treturn `src/routes/${file}`;\n\t\t\t\tcase 'domain-based':\n\t\t\t\t\treturn `src/${file.replace('.ts', '')}/routes/index.ts`;\n\t\t\t}\n\t\t};\n\n\t\tconst files: GeneratedFile[] = [\n\t\t\t// src/config/env.ts\n\t\t\t{\n\t\t\t\tpath: 'src/config/env.ts',\n\t\t\t\tcontent: `import { EnvironmentParser } from '@geekmidas/envkit';\n\nexport const envParser = new EnvironmentParser(process.env);\n\nexport const config = envParser\n .create((get) => ({\n port: get('PORT').string().transform(Number).default(3000),\n nodeEnv: get('NODE_ENV').string().default('development'),\n rabbitmq: {\n url: get('RABBITMQ_URL').string().default('amqp://localhost:5672'),\n },${\n\t\t\toptions.database\n\t\t\t\t? `\n database: {\n url: get('DATABASE_URL').string().default('postgresql://localhost:5432/mydb'),\n },`\n\t\t\t\t: ''\n\t\t}\n }))\n .parse();\n`,\n\t\t\t},\n\n\t\t\t// src/config/logger.ts\n\t\t\t{\n\t\t\t\tpath: 'src/config/logger.ts',\n\t\t\t\tcontent: loggerContent,\n\t\t\t},\n\n\t\t\t// health endpoint\n\t\t\t{\n\t\t\t\tpath: getRoutePath('health.ts'),\n\t\t\t\tcontent: `import { e } from '@geekmidas/constructs/endpoints';\n\nexport default e\n .get('/health')\n .handle(async () => ({\n status: 'ok',\n timestamp: new Date().toISOString(),\n }));\n`,\n\t\t\t},\n\n\t\t\t// src/events/types.ts\n\t\t\t{\n\t\t\t\tpath: 'src/events/types.ts',\n\t\t\t\tcontent: `import type { PublishableMessage } from '@geekmidas/events';\n\n// Define your event types here\nexport type AppEvents =\n | PublishableMessage<'user.created', { userId: string; email: string }>\n | PublishableMessage<'user.updated', { userId: string; changes: Record<string, unknown> }>\n | PublishableMessage<'order.placed', { orderId: string; userId: string; total: number }>;\n`,\n\t\t\t},\n\n\t\t\t// src/subscribers/user-events.ts\n\t\t\t{\n\t\t\t\tpath: 'src/subscribers/user-events.ts',\n\t\t\t\tcontent: `import { s } from '@geekmidas/constructs/subscribers';\nimport type { AppEvents } from '../events/types.js';\n\nexport default s<AppEvents>()\n .events(['user.created', 'user.updated'])\n .handle(async ({ event, logger }) => {\n logger.info({ type: event.type, payload: event.payload }, 'Processing user event');\n\n switch (event.type) {\n case 'user.created':\n // Handle user creation\n logger.info({ userId: event.payload.userId }, 'New user created');\n break;\n case 'user.updated':\n // Handle user update\n logger.info({ userId: event.payload.userId }, 'User updated');\n break;\n }\n });\n`,\n\t\t\t},\n\n\t\t\t// src/crons/cleanup.ts\n\t\t\t{\n\t\t\t\tpath: 'src/crons/cleanup.ts',\n\t\t\t\tcontent: `import { cron } from '@geekmidas/constructs/crons';\n\n// Run every day at midnight\nexport default cron('0 0 * * *')\n .handle(async ({ logger }) => {\n logger.info('Running cleanup job');\n\n // Add your cleanup logic here\n // e.g., delete old sessions, clean up temp files, etc.\n\n logger.info('Cleanup job completed');\n });\n`,\n\t\t\t},\n\t\t];\n\n\t\t// Add Telescope config if enabled\n\t\tif (options.telescope) {\n\t\t\tfiles.push({\n\t\t\t\tpath: 'src/config/telescope.ts',\n\t\t\t\tcontent: `import { Telescope } from '@geekmidas/telescope';\nimport { InMemoryStorage } from '@geekmidas/telescope/storage/memory';\n\nexport const telescope = new Telescope({\n storage: new InMemoryStorage({ maxEntries: 100 }),\n enabled: process.env.NODE_ENV === 'development',\n});\n`,\n\t\t\t});\n\t\t}\n\n\t\treturn files;\n\t},\n};\n","import { apiTemplate } from './api.js';\nimport { minimalTemplate } from './minimal.js';\nimport { serverlessTemplate } from './serverless.js';\nimport { workerTemplate } from './worker.js';\n\n/**\n * OpenAPI output path (fixed, not configurable)\n */\nexport const OPENAPI_OUTPUT_PATH = './.gkm/openapi.ts';\n\n/**\n * Logger implementation type\n */\nexport type LoggerType = 'pino' | 'console';\n\n/**\n * Routes structure pattern\n */\nexport type RoutesStructure =\n\t| 'centralized-endpoints'\n\t| 'centralized-routes'\n\t| 'domain-based';\n\n/**\n * Options collected from user prompts\n */\nexport interface TemplateOptions {\n\tname: string;\n\ttemplate: TemplateName;\n\ttelescope: boolean;\n\tdatabase: boolean;\n\tstudio: boolean;\n\tloggerType: LoggerType;\n\troutesStructure: RoutesStructure;\n\tmonorepo: boolean;\n\t/** Path for the API app in monorepo (e.g., 'apps/api') */\n\tapiPath: string;\n}\n\n/**\n * A file to be generated\n */\nexport interface GeneratedFile {\n\tpath: string;\n\tcontent: string;\n}\n\n/**\n * Template configuration\n */\nexport interface TemplateConfig {\n\tname: TemplateName;\n\tdescription: string;\n\tdependencies: Record<string, string>;\n\tdevDependencies: Record<string, string>;\n\tscripts: Record<string, string>;\n\tfiles: (options: TemplateOptions) => GeneratedFile[];\n}\n\nexport type TemplateName = 'minimal' | 'api' | 'serverless' | 'worker';\n\n/**\n * All available templates\n */\nexport const templates: Record<TemplateName, TemplateConfig> = {\n\tminimal: minimalTemplate,\n\tapi: apiTemplate,\n\tserverless: serverlessTemplate,\n\tworker: workerTemplate,\n};\n\n/**\n * Template choices for prompts\n */\nexport const templateChoices = [\n\t{\n\t\ttitle: 'Minimal',\n\t\tvalue: 'minimal' as TemplateName,\n\t\tdescription: 'Basic health endpoint',\n\t},\n\t{\n\t\ttitle: 'API',\n\t\tvalue: 'api' as TemplateName,\n\t\tdescription: 'Full API with auth, database, services',\n\t},\n\t{\n\t\ttitle: 'Serverless',\n\t\tvalue: 'serverless' as TemplateName,\n\t\tdescription: 'AWS Lambda handlers',\n\t},\n\t{\n\t\ttitle: 'Worker',\n\t\tvalue: 'worker' as TemplateName,\n\t\tdescription: 'Background job processing',\n\t},\n];\n\n/**\n * Logger type choices for prompts\n */\nexport const loggerTypeChoices = [\n\t{\n\t\ttitle: 'Pino',\n\t\tvalue: 'pino' as LoggerType,\n\t\tdescription: 'Fast JSON logger for production (recommended)',\n\t},\n\t{\n\t\ttitle: 'Console',\n\t\tvalue: 'console' as LoggerType,\n\t\tdescription: 'Simple console logger for development',\n\t},\n];\n\n/**\n * Routes structure choices for prompts\n */\nexport const routesStructureChoices = [\n\t{\n\t\ttitle: 'Centralized (endpoints)',\n\t\tvalue: 'centralized-endpoints' as RoutesStructure,\n\t\tdescription: 'src/endpoints/**/*.ts',\n\t},\n\t{\n\t\ttitle: 'Centralized (routes)',\n\t\tvalue: 'centralized-routes' as RoutesStructure,\n\t\tdescription: 'src/routes/**/*.ts',\n\t},\n\t{\n\t\ttitle: 'Domain-based',\n\t\tvalue: 'domain-based' as RoutesStructure,\n\t\tdescription: 'src/**/routes/*.ts (e.g., src/users/routes/list.ts)',\n\t},\n];\n\n/**\n * Get a template by name\n */\nexport function getTemplate(name: TemplateName): TemplateConfig {\n\tconst template = templates[name];\n\tif (!template) {\n\t\tthrow new Error(`Unknown template: ${name}`);\n\t}\n\treturn template;\n}\n","import {\n\ttype GeneratedFile,\n\tOPENAPI_OUTPUT_PATH,\n\ttype TemplateConfig,\n\ttype TemplateOptions,\n} from '../templates/index.js';\n\n/**\n * Generate package.json with dependencies based on template and options\n */\nexport function generatePackageJson(\n\toptions: TemplateOptions,\n\ttemplate: TemplateConfig,\n): GeneratedFile[] {\n\tconst { name, telescope, database, studio, monorepo } = options;\n\n\t// Start with template dependencies\n\tconst dependencies = { ...template.dependencies };\n\tconst devDependencies = { ...template.devDependencies };\n\tconst scripts = { ...template.scripts };\n\n\t// Add optional dependencies based on user choices\n\tif (telescope) {\n\t\tdependencies['@geekmidas/telescope'] = 'workspace:*';\n\t}\n\n\tif (studio) {\n\t\tdependencies['@geekmidas/studio'] = 'workspace:*';\n\t}\n\n\tif (database) {\n\t\tdependencies['@geekmidas/db'] = 'workspace:*';\n\t\tdependencies.kysely = '~0.28.2';\n\t\tdependencies.pg = '~8.16.0';\n\t\tdevDependencies['@types/pg'] = '~8.15.0';\n\t}\n\n\t// Add zod for schema validation (commonly used)\n\tdependencies.zod = '~4.1.0';\n\n\t// For monorepo apps, remove biome/turbo (they're at root) and lint/fmt scripts\n\tif (monorepo) {\n\t\tdelete devDependencies['@biomejs/biome'];\n\t\tdelete devDependencies.turbo;\n\t\tdelete scripts.lint;\n\t\tdelete scripts.fmt;\n\t\tdelete scripts['fmt:check'];\n\n\t\t// Add models package as dependency\n\t\tdependencies[`@${name}/models`] = 'workspace:*';\n\n\t\t// Remove zod from api package (it's in models)\n\t\tdelete dependencies.zod;\n\t}\n\n\t// Sort dependencies alphabetically\n\tconst sortObject = (obj: Record<string, string>) =>\n\t\tObject.fromEntries(\n\t\t\tObject.entries(obj).sort(([a], [b]) => a.localeCompare(b)),\n\t\t);\n\n\t// For monorepo, derive package name from apiPath (e.g., apps/api -> @name/api)\n\tlet packageName = name;\n\tif (monorepo && options.apiPath) {\n\t\tconst pathParts = options.apiPath.split('/');\n\t\tconst appName = pathParts[pathParts.length - 1] || 'api';\n\t\tpackageName = `@${name}/${appName}`;\n\t}\n\n\tconst packageJson = {\n\t\tname: packageName,\n\t\tversion: '0.0.1',\n\t\tprivate: true,\n\t\ttype: 'module',\n\t\texports: {\n\t\t\t'./client': {\n\t\t\t\ttypes: OPENAPI_OUTPUT_PATH,\n\t\t\t\timport: OPENAPI_OUTPUT_PATH,\n\t\t\t},\n\t\t},\n\t\tscripts,\n\t\tdependencies: sortObject(dependencies),\n\t\tdevDependencies: sortObject(devDependencies),\n\t};\n\n\treturn [\n\t\t{\n\t\t\tpath: 'package.json',\n\t\t\tcontent: `${JSON.stringify(packageJson, null, 2)}\\n`,\n\t\t},\n\t];\n}\n","import type {\n\tGeneratedFile,\n\tTemplateConfig,\n\tTemplateOptions,\n} from '../templates/index.js';\n\n/**\n * Generate source files from template\n */\nexport function generateSourceFiles(\n\toptions: TemplateOptions,\n\ttemplate: TemplateConfig,\n): GeneratedFile[] {\n\treturn template.files(options);\n}\n","import { existsSync } from 'node:fs';\nimport { join } from 'node:path';\n\nexport type PackageManager = 'pnpm' | 'npm' | 'yarn' | 'bun';\n\n/**\n * Detect the package manager being used based on lockfiles or npm_config_user_agent\n */\nexport function detectPackageManager(\n\tcwd: string = process.cwd(),\n): PackageManager {\n\t// Check for lockfiles in cwd\n\tif (existsSync(join(cwd, 'pnpm-lock.yaml'))) return 'pnpm';\n\tif (existsSync(join(cwd, 'yarn.lock'))) return 'yarn';\n\tif (existsSync(join(cwd, 'bun.lockb'))) return 'bun';\n\tif (existsSync(join(cwd, 'package-lock.json'))) return 'npm';\n\n\t// Check npm_config_user_agent (set when running via npx/pnpm dlx/etc)\n\tconst userAgent = process.env.npm_config_user_agent || '';\n\tif (userAgent.includes('pnpm')) return 'pnpm';\n\tif (userAgent.includes('yarn')) return 'yarn';\n\tif (userAgent.includes('bun')) return 'bun';\n\n\treturn 'npm';\n}\n\n/**\n * Validate project name for npm package naming conventions\n */\nexport function validateProjectName(name: string): boolean | string {\n\tif (!name) {\n\t\treturn 'Project name is required';\n\t}\n\n\t// Check for valid npm package name characters\n\tif (!/^[a-z0-9-_@/.]+$/i.test(name)) {\n\t\treturn 'Project name can only contain letters, numbers, hyphens, underscores, @, /, and .';\n\t}\n\n\t// Check for reserved names\n\tconst reserved = ['node_modules', '.git', 'package.json', 'src'];\n\tif (reserved.includes(name.toLowerCase())) {\n\t\treturn `\"${name}\" is a reserved name`;\n\t}\n\n\treturn true;\n}\n\n/**\n * Check if a directory already exists at the target path\n */\nexport function checkDirectoryExists(\n\tname: string,\n\tcwd: string = process.cwd(),\n): boolean | string {\n\tconst targetPath = join(cwd, name);\n\tif (existsSync(targetPath)) {\n\t\treturn `Directory \"${name}\" already exists`;\n\t}\n\treturn true;\n}\n\n/**\n * Get the install command for a package manager\n */\nexport function getInstallCommand(pkgManager: PackageManager): string {\n\tswitch (pkgManager) {\n\t\tcase 'pnpm':\n\t\t\treturn 'pnpm install';\n\t\tcase 'yarn':\n\t\t\treturn 'yarn';\n\t\tcase 'bun':\n\t\t\treturn 'bun install';\n\t\tdefault:\n\t\t\treturn 'npm install';\n\t}\n}\n\n/**\n * Get the dev command for a package manager\n */\nexport function getRunCommand(\n\tpkgManager: PackageManager,\n\tscript: string,\n): string {\n\tswitch (pkgManager) {\n\t\tcase 'pnpm':\n\t\t\treturn `pnpm ${script}`;\n\t\tcase 'yarn':\n\t\t\treturn `yarn ${script}`;\n\t\tcase 'bun':\n\t\t\treturn `bun run ${script}`;\n\t\tdefault:\n\t\t\treturn `npm run ${script}`;\n\t}\n}\n","import { execSync } from 'node:child_process';\nimport { mkdir, writeFile } from 'node:fs/promises';\nimport { dirname, join } from 'node:path';\nimport prompts from 'prompts';\nimport { generateConfigFiles } from './generators/config.js';\nimport { generateDockerFiles } from './generators/docker.js';\nimport { generateEnvFiles } from './generators/env.js';\nimport { generateModelsPackage } from './generators/models.js';\nimport { generateMonorepoFiles } from './generators/monorepo.js';\nimport { generatePackageJson } from './generators/package.js';\nimport { generateSourceFiles } from './generators/source.js';\nimport {\n\tgetTemplate,\n\tloggerTypeChoices,\n\troutesStructureChoices,\n\ttype TemplateName,\n\ttype TemplateOptions,\n\ttemplateChoices,\n} from './templates/index.js';\nimport {\n\tcheckDirectoryExists,\n\tdetectPackageManager,\n\tgetInstallCommand,\n\tgetRunCommand,\n\tvalidateProjectName,\n} from './utils.js';\n\nexport interface InitOptions {\n\ttemplate?: TemplateName;\n\tskipInstall?: boolean;\n\tyes?: boolean;\n\tmonorepo?: boolean;\n\tapiPath?: string;\n}\n\n/**\n * Main init command - scaffolds a new project\n */\nexport async function initCommand(\n\tprojectName?: string,\n\toptions: InitOptions = {},\n): Promise<void> {\n\tconst cwd = process.cwd();\n\tconst pkgManager = detectPackageManager(cwd);\n\n\t// Handle Ctrl+C gracefully\n\tprompts.override({});\n\tconst onCancel = () => {\n\t\tprocess.exit(0);\n\t};\n\n\t// Gather answers via prompts\n\tconst answers = await prompts(\n\t\t[\n\t\t\t{\n\t\t\t\ttype: projectName ? null : 'text',\n\t\t\t\tname: 'name',\n\t\t\t\tmessage: 'Project name:',\n\t\t\t\tinitial: 'my-api',\n\t\t\t\tvalidate: (value: string) => {\n\t\t\t\t\tconst nameValid = validateProjectName(value);\n\t\t\t\t\tif (nameValid !== true) return nameValid;\n\t\t\t\t\tconst dirValid = checkDirectoryExists(value, cwd);\n\t\t\t\t\tif (dirValid !== true) return dirValid;\n\t\t\t\t\treturn true;\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\ttype: options.template || options.yes ? null : 'select',\n\t\t\t\tname: 'template',\n\t\t\t\tmessage: 'Template:',\n\t\t\t\tchoices: templateChoices,\n\t\t\t\tinitial: 0,\n\t\t\t},\n\t\t\t{\n\t\t\t\ttype: options.yes ? null : 'confirm',\n\t\t\t\tname: 'telescope',\n\t\t\t\tmessage: 'Include Telescope (debugging dashboard)?',\n\t\t\t\tinitial: true,\n\t\t\t},\n\t\t\t{\n\t\t\t\ttype: options.yes ? null : 'confirm',\n\t\t\t\tname: 'database',\n\t\t\t\tmessage: 'Include database support (Kysely)?',\n\t\t\t\tinitial: true,\n\t\t\t},\n\t\t\t{\n\t\t\t\ttype: (prev) => (options.yes ? null : prev ? 'confirm' : null),\n\t\t\t\tname: 'studio',\n\t\t\t\tmessage: 'Include Studio (database browser)?',\n\t\t\t\tinitial: true,\n\t\t\t},\n\t\t\t{\n\t\t\t\ttype: options.yes ? null : 'select',\n\t\t\t\tname: 'loggerType',\n\t\t\t\tmessage: 'Logger:',\n\t\t\t\tchoices: loggerTypeChoices,\n\t\t\t\tinitial: 0,\n\t\t\t},\n\t\t\t{\n\t\t\t\ttype: options.yes ? null : 'select',\n\t\t\t\tname: 'routesStructure',\n\t\t\t\tmessage: 'Routes structure:',\n\t\t\t\tchoices: routesStructureChoices,\n\t\t\t\tinitial: 0,\n\t\t\t},\n\t\t\t{\n\t\t\t\ttype: options.yes || options.monorepo !== undefined ? null : 'confirm',\n\t\t\t\tname: 'monorepo',\n\t\t\t\tmessage: 'Setup as monorepo?',\n\t\t\t\tinitial: false,\n\t\t\t},\n\t\t\t{\n\t\t\t\ttype: (prev) =>\n\t\t\t\t\t(prev === true || options.monorepo) && !options.apiPath\n\t\t\t\t\t\t? 'text'\n\t\t\t\t\t\t: null,\n\t\t\t\tname: 'apiPath',\n\t\t\t\tmessage: 'API app path:',\n\t\t\t\tinitial: 'apps/api',\n\t\t\t},\n\t\t],\n\t\t{ onCancel },\n\t);\n\n\t// Build final options\n\tconst name = projectName || answers.name;\n\tif (!name) {\n\t\tprocess.exit(1);\n\t}\n\n\t// Validate name if provided via argument\n\tif (projectName) {\n\t\tconst nameValid = validateProjectName(projectName);\n\t\tif (nameValid !== true) {\n\t\t\tprocess.exit(1);\n\t\t}\n\t\tconst dirValid = checkDirectoryExists(projectName, cwd);\n\t\tif (dirValid !== true) {\n\t\t\tprocess.exit(1);\n\t\t}\n\t}\n\n\tconst monorepo =\n\t\toptions.monorepo ?? (options.yes ? false : (answers.monorepo ?? false));\n\tconst database = options.yes ? true : (answers.database ?? true);\n\tconst templateOptions: TemplateOptions = {\n\t\tname,\n\t\ttemplate: options.template || answers.template || 'minimal',\n\t\ttelescope: options.yes ? true : (answers.telescope ?? true),\n\t\tdatabase,\n\t\tstudio: database && (options.yes ? true : (answers.studio ?? true)),\n\t\tloggerType: options.yes ? 'pino' : (answers.loggerType ?? 'pino'),\n\t\troutesStructure: options.yes\n\t\t\t? 'centralized-endpoints'\n\t\t\t: (answers.routesStructure ?? 'centralized-endpoints'),\n\t\tmonorepo,\n\t\tapiPath: monorepo ? (options.apiPath ?? answers.apiPath ?? 'apps/api') : '',\n\t};\n\n\tconst targetDir = join(cwd, name);\n\tconst template = getTemplate(templateOptions.template);\n\n\tconst isMonorepo = templateOptions.monorepo;\n\tconst apiPath = templateOptions.apiPath;\n\n\t// Create project directory\n\tawait mkdir(targetDir, { recursive: true });\n\n\t// For monorepo, app files go in the specified apiPath (e.g., apps/api)\n\tconst appDir = isMonorepo ? join(targetDir, apiPath) : targetDir;\n\tif (isMonorepo) {\n\t\tawait mkdir(appDir, { recursive: true });\n\t}\n\n\t// Collect app files\n\tconst appFiles = [\n\t\t...generatePackageJson(templateOptions, template),\n\t\t...generateConfigFiles(templateOptions, template),\n\t\t...generateEnvFiles(templateOptions, template),\n\t\t...generateSourceFiles(templateOptions, template),\n\t\t...generateDockerFiles(templateOptions, template),\n\t];\n\n\t// Collect root monorepo files (includes packages/models)\n\tconst rootFiles = [\n\t\t...generateMonorepoFiles(templateOptions, template),\n\t\t...generateModelsPackage(templateOptions),\n\t];\n\n\t// Write root files (for monorepo)\n\tfor (const { path, content } of rootFiles) {\n\t\tconst fullPath = join(targetDir, path);\n\t\tawait mkdir(dirname(fullPath), { recursive: true });\n\t\tawait writeFile(fullPath, content);\n\t}\n\n\t// Write app files\n\tfor (const { path, content } of appFiles) {\n\t\tconst fullPath = join(appDir, path);\n\t\tconst _displayPath = isMonorepo ? `${apiPath}/${path}` : path;\n\t\tawait mkdir(dirname(fullPath), { recursive: true });\n\t\tawait writeFile(fullPath, content);\n\t}\n\n\t// Install dependencies\n\tif (!options.skipInstall) {\n\t\ttry {\n\t\t\texecSync(getInstallCommand(pkgManager), {\n\t\t\t\tcwd: targetDir,\n\t\t\t\tstdio: 'inherit',\n\t\t\t});\n\t\t} catch {}\n\n\t\t// Format generated files with biome\n\t\ttry {\n\t\t\texecSync('npx @biomejs/biome format --write --unsafe .', {\n\t\t\t\tcwd: targetDir,\n\t\t\t\tstdio: 'inherit',\n\t\t\t});\n\t\t} catch {\n\t\t\t// Silently ignore format errors\n\t\t}\n\t}\n\n\t// Print next steps\n\tconst _devCommand = getRunCommand(pkgManager, 'dev');\n}\n","import { randomBytes } from 'node:crypto';\nimport type { ComposeServiceName } from '../types';\nimport type { ServiceCredentials, StageSecrets } from './types';\n\n/**\n * Generate a secure random password using URL-safe base64 characters.\n * @param length Password length (default: 32)\n */\nexport function generateSecurePassword(length = 32): string {\n\treturn randomBytes(Math.ceil((length * 3) / 4))\n\t\t.toString('base64url')\n\t\t.slice(0, length);\n}\n\n/** Default service configurations */\nconst SERVICE_DEFAULTS: Record<\n\tComposeServiceName,\n\tOmit<ServiceCredentials, 'password'>\n> = {\n\tpostgres: {\n\t\thost: 'postgres',\n\t\tport: 5432,\n\t\tusername: 'app',\n\t\tdatabase: 'app',\n\t},\n\tredis: {\n\t\thost: 'redis',\n\t\tport: 6379,\n\t\tusername: 'default',\n\t},\n\trabbitmq: {\n\t\thost: 'rabbitmq',\n\t\tport: 5672,\n\t\tusername: 'app',\n\t\tvhost: '/',\n\t},\n};\n\n/**\n * Generate credentials for a specific service.\n */\nexport function generateServiceCredentials(\n\tservice: ComposeServiceName,\n): ServiceCredentials {\n\tconst defaults = SERVICE_DEFAULTS[service];\n\treturn {\n\t\t...defaults,\n\t\tpassword: generateSecurePassword(),\n\t};\n}\n\n/**\n * Generate credentials for multiple services.\n */\nexport function generateServicesCredentials(\n\tservices: ComposeServiceName[],\n): StageSecrets['services'] {\n\tconst result: StageSecrets['services'] = {};\n\n\tfor (const service of services) {\n\t\tresult[service] = generateServiceCredentials(service);\n\t}\n\n\treturn result;\n}\n\n/**\n * Generate connection URL for PostgreSQL.\n */\nexport function generatePostgresUrl(creds: ServiceCredentials): string {\n\tconst { username, password, host, port, database } = creds;\n\treturn `postgresql://${username}:${encodeURIComponent(password)}@${host}:${port}/${database}`;\n}\n\n/**\n * Generate connection URL for Redis.\n */\nexport function generateRedisUrl(creds: ServiceCredentials): string {\n\tconst { password, host, port } = creds;\n\treturn `redis://:${encodeURIComponent(password)}@${host}:${port}`;\n}\n\n/**\n * Generate connection URL for RabbitMQ.\n */\nexport function generateRabbitmqUrl(creds: ServiceCredentials): string {\n\tconst { username, password, host, port, vhost } = creds;\n\tconst encodedVhost = encodeURIComponent(vhost ?? '/');\n\treturn `amqp://${username}:${encodeURIComponent(password)}@${host}:${port}/${encodedVhost}`;\n}\n\n/**\n * Generate connection URLs from service credentials.\n */\nexport function generateConnectionUrls(\n\tservices: StageSecrets['services'],\n): StageSecrets['urls'] {\n\tconst urls: StageSecrets['urls'] = {};\n\n\tif (services.postgres) {\n\t\turls.DATABASE_URL = generatePostgresUrl(services.postgres);\n\t}\n\n\tif (services.redis) {\n\t\turls.REDIS_URL = generateRedisUrl(services.redis);\n\t}\n\n\tif (services.rabbitmq) {\n\t\turls.RABBITMQ_URL = generateRabbitmqUrl(services.rabbitmq);\n\t}\n\n\treturn urls;\n}\n\n/**\n * Create a new StageSecrets object with generated credentials.\n */\nexport function createStageSecrets(\n\tstage: string,\n\tservices: ComposeServiceName[],\n): StageSecrets {\n\tconst now = new Date().toISOString();\n\tconst serviceCredentials = generateServicesCredentials(services);\n\tconst urls = generateConnectionUrls(serviceCredentials);\n\n\treturn {\n\t\tstage,\n\t\tcreatedAt: now,\n\t\tupdatedAt: now,\n\t\tservices: serviceCredentials,\n\t\turls,\n\t\tcustom: {},\n\t};\n}\n\n/**\n * Rotate password for a specific service.\n */\nexport function rotateServicePassword(\n\tsecrets: StageSecrets,\n\tservice: ComposeServiceName,\n): StageSecrets {\n\tconst currentCreds = secrets.services[service];\n\tif (!currentCreds) {\n\t\tthrow new Error(`Service \"${service}\" not configured in secrets`);\n\t}\n\n\tconst newCreds: ServiceCredentials = {\n\t\t...currentCreds,\n\t\tpassword: generateSecurePassword(),\n\t};\n\n\tconst newServices = {\n\t\t...secrets.services,\n\t\t[service]: newCreds,\n\t};\n\n\treturn {\n\t\t...secrets,\n\t\tupdatedAt: new Date().toISOString(),\n\t\tservices: newServices,\n\t\turls: generateConnectionUrls(newServices),\n\t};\n}\n","import { existsSync } from 'node:fs';\nimport { readFile } from 'node:fs/promises';\nimport { loadConfig } from '../config';\nimport type { ComposeServiceName, ComposeServicesConfig } from '../types';\nimport { createStageSecrets, rotateServicePassword } from './generator';\nimport {\n\tmaskPassword,\n\treadStageSecrets,\n\tsecretsExist,\n\tsetCustomSecret,\n\twriteStageSecrets,\n} from './storage';\n\nconst logger = console;\n\nexport interface SecretsInitOptions {\n\tstage: string;\n\tforce?: boolean;\n}\n\nexport interface SecretsSetOptions {\n\tstage: string;\n}\n\nexport interface SecretsShowOptions {\n\tstage: string;\n\treveal?: boolean;\n}\n\nexport interface SecretsRotateOptions {\n\tstage: string;\n\tservice?: ComposeServiceName;\n}\n\nexport interface SecretsImportOptions {\n\tstage: string;\n\t/** Merge with existing secrets (default: true) */\n\tmerge?: boolean;\n}\n\n/**\n * Extract service names from compose config.\n */\nexport function getServicesFromConfig(\n\tservices: ComposeServicesConfig | ComposeServiceName[] | undefined,\n): ComposeServiceName[] {\n\tif (!services) {\n\t\treturn [];\n\t}\n\n\tif (Array.isArray(services)) {\n\t\treturn services;\n\t}\n\n\t// Object format - get keys where value is truthy\n\treturn (Object.entries(services) as [ComposeServiceName, unknown][])\n\t\t.filter(([, config]) => config)\n\t\t.map(([name]) => name);\n}\n\n/**\n * Initialize secrets for a stage.\n * Generates secure random passwords for configured services.\n */\nexport async function secretsInitCommand(\n\toptions: SecretsInitOptions,\n): Promise<void> {\n\tconst { stage, force } = options;\n\n\t// Check if secrets already exist\n\tif (!force && secretsExist(stage)) {\n\t\tlogger.error(\n\t\t\t`Secrets already exist for stage \"${stage}\". Use --force to overwrite.`,\n\t\t);\n\t\tprocess.exit(1);\n\t}\n\n\t// Load config to get services\n\tconst config = await loadConfig();\n\tconst services = getServicesFromConfig(config.docker?.compose?.services);\n\n\tif (services.length === 0) {\n\t\tlogger.warn(\n\t\t\t'No services configured in docker.compose.services. Creating secrets with empty services.',\n\t\t);\n\t}\n\n\t// Generate secrets\n\tconst secrets = createStageSecrets(stage, services);\n\n\t// Write to file\n\tawait writeStageSecrets(secrets);\n\n\tlogger.log(`\\n✓ Secrets initialized for stage \"${stage}\"`);\n\tlogger.log(` Location: .gkm/secrets/${stage}.json`);\n\tlogger.log('\\n Generated credentials for:');\n\n\tfor (const service of services) {\n\t\tlogger.log(` - ${service}`);\n\t}\n\n\tif (secrets.urls.DATABASE_URL) {\n\t\tlogger.log(`\\n DATABASE_URL: ${maskUrl(secrets.urls.DATABASE_URL)}`);\n\t}\n\tif (secrets.urls.REDIS_URL) {\n\t\tlogger.log(` REDIS_URL: ${maskUrl(secrets.urls.REDIS_URL)}`);\n\t}\n\tif (secrets.urls.RABBITMQ_URL) {\n\t\tlogger.log(` RABBITMQ_URL: ${maskUrl(secrets.urls.RABBITMQ_URL)}`);\n\t}\n\n\tlogger.log(`\\n Use \"gkm secrets:show --stage ${stage}\" to view secrets`);\n\tlogger.log(\n\t\t' Use \"gkm secrets:set <KEY> <VALUE> --stage ' +\n\t\t\tstage +\n\t\t\t'\" to add custom secrets',\n\t);\n}\n\n/**\n * Read all data from stdin.\n */\nasync function readStdin(): Promise<string> {\n\tconst chunks: Buffer[] = [];\n\n\tfor await (const chunk of process.stdin) {\n\t\tchunks.push(chunk);\n\t}\n\n\treturn Buffer.concat(chunks).toString('utf-8').trim();\n}\n\n/**\n * Set a custom secret.\n * If value is not provided, reads from stdin.\n */\nexport async function secretsSetCommand(\n\tkey: string,\n\tvalue: string | undefined,\n\toptions: SecretsSetOptions,\n): Promise<void> {\n\tconst { stage } = options;\n\n\t// Read from stdin if value not provided\n\tlet secretValue = value;\n\tif (!secretValue) {\n\t\tif (process.stdin.isTTY) {\n\t\t\tlogger.error(\n\t\t\t\t'No value provided. Use: gkm secrets:set KEY VALUE --stage <stage>',\n\t\t\t);\n\t\t\tlogger.error(\n\t\t\t\t'Or pipe from stdin: echo \"value\" | gkm secrets:set KEY --stage <stage>',\n\t\t\t);\n\t\t\tprocess.exit(1);\n\t\t}\n\t\tsecretValue = await readStdin();\n\t\tif (!secretValue) {\n\t\t\tlogger.error('No value received from stdin');\n\t\t\tprocess.exit(1);\n\t\t}\n\t}\n\n\ttry {\n\t\tawait setCustomSecret(stage, key, secretValue);\n\t\tlogger.log(`\\n✓ Secret \"${key}\" set for stage \"${stage}\"`);\n\t} catch (error) {\n\t\tlogger.error(\n\t\t\terror instanceof Error ? error.message : 'Failed to set secret',\n\t\t);\n\t\tprocess.exit(1);\n\t}\n}\n\n/**\n * Show secrets for a stage.\n */\nexport async function secretsShowCommand(\n\toptions: SecretsShowOptions,\n): Promise<void> {\n\tconst { stage, reveal } = options;\n\n\tconst secrets = await readStageSecrets(stage);\n\n\tif (!secrets) {\n\t\tlogger.error(\n\t\t\t`No secrets found for stage \"${stage}\". Run \"gkm secrets:init --stage ${stage}\" first.`,\n\t\t);\n\t\tprocess.exit(1);\n\t}\n\n\tlogger.log(`\\nSecrets for stage \"${stage}\":`);\n\tlogger.log(` Created: ${secrets.createdAt}`);\n\tlogger.log(` Updated: ${secrets.updatedAt}`);\n\n\t// Show service credentials\n\tlogger.log('\\nService Credentials:');\n\tfor (const [service, creds] of Object.entries(secrets.services)) {\n\t\tif (creds) {\n\t\t\tlogger.log(`\\n ${service}:`);\n\t\t\tlogger.log(` host: ${creds.host}`);\n\t\t\tlogger.log(` port: ${creds.port}`);\n\t\t\tlogger.log(` username: ${creds.username}`);\n\t\t\tlogger.log(\n\t\t\t\t` password: ${reveal ? creds.password : maskPassword(creds.password)}`,\n\t\t\t);\n\t\t\tif (creds.database) {\n\t\t\t\tlogger.log(` database: ${creds.database}`);\n\t\t\t}\n\t\t\tif (creds.vhost) {\n\t\t\t\tlogger.log(` vhost: ${creds.vhost}`);\n\t\t\t}\n\t\t}\n\t}\n\n\t// Show URLs\n\tlogger.log('\\nConnection URLs:');\n\tif (secrets.urls.DATABASE_URL) {\n\t\tlogger.log(\n\t\t\t` DATABASE_URL: ${reveal ? secrets.urls.DATABASE_URL : maskUrl(secrets.urls.DATABASE_URL)}`,\n\t\t);\n\t}\n\tif (secrets.urls.REDIS_URL) {\n\t\tlogger.log(\n\t\t\t` REDIS_URL: ${reveal ? secrets.urls.REDIS_URL : maskUrl(secrets.urls.REDIS_URL)}`,\n\t\t);\n\t}\n\tif (secrets.urls.RABBITMQ_URL) {\n\t\tlogger.log(\n\t\t\t` RABBITMQ_URL: ${reveal ? secrets.urls.RABBITMQ_URL : maskUrl(secrets.urls.RABBITMQ_URL)}`,\n\t\t);\n\t}\n\n\t// Show custom secrets\n\tconst customKeys = Object.keys(secrets.custom);\n\tif (customKeys.length > 0) {\n\t\tlogger.log('\\nCustom Secrets:');\n\t\tfor (const [key, value] of Object.entries(secrets.custom)) {\n\t\t\tlogger.log(` ${key}: ${reveal ? value : maskPassword(value)}`);\n\t\t}\n\t}\n\n\tif (!reveal) {\n\t\tlogger.log('\\nUse --reveal to show actual values');\n\t}\n}\n\n/**\n * Rotate passwords for services.\n */\nexport async function secretsRotateCommand(\n\toptions: SecretsRotateOptions,\n): Promise<void> {\n\tconst { stage, service } = options;\n\n\tconst secrets = await readStageSecrets(stage);\n\n\tif (!secrets) {\n\t\tlogger.error(\n\t\t\t`No secrets found for stage \"${stage}\". Run \"gkm secrets:init --stage ${stage}\" first.`,\n\t\t);\n\t\tprocess.exit(1);\n\t}\n\n\tif (service) {\n\t\t// Rotate specific service\n\t\tif (!secrets.services[service]) {\n\t\t\tlogger.error(`Service \"${service}\" not configured in stage \"${stage}\"`);\n\t\t\tprocess.exit(1);\n\t\t}\n\n\t\tconst updated = rotateServicePassword(secrets, service);\n\t\tawait writeStageSecrets(updated);\n\t\tlogger.log(`\\n✓ Password rotated for ${service} in stage \"${stage}\"`);\n\t} else {\n\t\t// Rotate all services\n\t\tlet updated = secrets;\n\t\tconst services = Object.keys(secrets.services) as ComposeServiceName[];\n\n\t\tfor (const svc of services) {\n\t\t\tupdated = rotateServicePassword(updated, svc);\n\t\t}\n\n\t\tawait writeStageSecrets(updated);\n\t\tlogger.log(\n\t\t\t`\\n✓ Passwords rotated for all services in stage \"${stage}\": ${services.join(', ')}`,\n\t\t);\n\t}\n\n\tlogger.log(`\\nUse \"gkm secrets:show --stage ${stage}\" to view new values`);\n}\n\n/**\n * Import secrets from a JSON file.\n */\nexport async function secretsImportCommand(\n\tfile: string,\n\toptions: SecretsImportOptions,\n): Promise<void> {\n\tconst { stage, merge = true } = options;\n\n\t// Check if file exists\n\tif (!existsSync(file)) {\n\t\tlogger.error(`File not found: ${file}`);\n\t\tprocess.exit(1);\n\t}\n\n\t// Read and parse JSON file\n\tlet importedSecrets: Record<string, string>;\n\ttry {\n\t\tconst content = await readFile(file, 'utf-8');\n\t\timportedSecrets = JSON.parse(content);\n\n\t\t// Validate it's a flat object with string values\n\t\tif (typeof importedSecrets !== 'object' || importedSecrets === null) {\n\t\t\tthrow new Error('JSON must be an object');\n\t\t}\n\n\t\tfor (const [key, value] of Object.entries(importedSecrets)) {\n\t\t\tif (typeof value !== 'string') {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Value for \"${key}\" must be a string, got ${typeof value}`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t} catch (error) {\n\t\tlogger.error(\n\t\t\t`Failed to parse JSON file: ${error instanceof Error ? error.message : 'Invalid JSON'}`,\n\t\t);\n\t\tprocess.exit(1);\n\t}\n\n\t// Check if secrets exist for stage\n\tconst secrets = await readStageSecrets(stage);\n\n\tif (!secrets) {\n\t\tlogger.error(\n\t\t\t`No secrets found for stage \"${stage}\". Run \"gkm secrets:init --stage ${stage}\" first.`,\n\t\t);\n\t\tprocess.exit(1);\n\t}\n\n\t// Merge or replace custom secrets\n\tconst updatedCustom = merge\n\t\t? { ...secrets.custom, ...importedSecrets }\n\t\t: importedSecrets;\n\n\tconst updated = {\n\t\t...secrets,\n\t\tupdatedAt: new Date().toISOString(),\n\t\tcustom: updatedCustom,\n\t};\n\n\tawait writeStageSecrets(updated);\n\n\tconst importedCount = Object.keys(importedSecrets).length;\n\tconst totalCount = Object.keys(updatedCustom).length;\n\n\tlogger.log(`\\n✓ Imported ${importedCount} secrets for stage \"${stage}\"`);\n\n\tif (merge && totalCount > importedCount) {\n\t\tlogger.log(` Total custom secrets: ${totalCount}`);\n\t}\n\n\tlogger.log('\\n Imported keys:');\n\tfor (const key of Object.keys(importedSecrets)) {\n\t\tlogger.log(` - ${key}`);\n\t}\n}\n\n/**\n * Mask password in a URL for display.\n */\nexport function maskUrl(url: string): string {\n\ttry {\n\t\tconst parsed = new URL(url);\n\t\tif (parsed.password) {\n\t\t\tparsed.password = maskPassword(parsed.password);\n\t\t}\n\t\treturn parsed.toString();\n\t} catch {\n\t\treturn url;\n\t}\n}\n","#!/usr/bin/env -S npx tsx\n\nimport { Command } from 'commander';\nimport pkg from '../package.json';\nimport { loginCommand, logoutCommand, whoamiCommand } from './auth';\nimport { buildCommand } from './build/index';\nimport { type DeployProvider, deployCommand } from './deploy/index';\nimport { deployInitCommand, deployListCommand } from './deploy/init';\nimport { devCommand } from './dev/index';\nimport { type DockerOptions, dockerCommand } from './docker/index';\nimport { type InitOptions, initCommand } from './init/index';\nimport { openapiCommand } from './openapi';\nimport { generateReactQueryCommand } from './openapi-react-query';\nimport {\n\tsecretsImportCommand,\n\tsecretsInitCommand,\n\tsecretsRotateCommand,\n\tsecretsSetCommand,\n\tsecretsShowCommand,\n} from './secrets';\nimport type { ComposeServiceName, LegacyProvider, MainProvider } from './types';\n\nconst program = new Command();\n\nprogram\n\t.name('gkm')\n\t.description('GeekMidas backend framework CLI')\n\t.version(pkg.version)\n\t.option('--cwd <path>', 'Change working directory');\n\nprogram\n\t.command('init')\n\t.description('Scaffold a new project')\n\t.argument('[name]', 'Project name')\n\t.option(\n\t\t'--template <template>',\n\t\t'Project template (minimal, api, serverless, worker)',\n\t)\n\t.option('--skip-install', 'Skip dependency installation', false)\n\t.option('-y, --yes', 'Skip prompts, use defaults', false)\n\t.option('--monorepo', 'Setup as monorepo with packages/models', false)\n\t.option('--api-path <path>', 'API app path in monorepo (default: apps/api)')\n\t.action(async (name: string | undefined, options: InitOptions) => {\n\t\ttry {\n\t\t\tconst globalOptions = program.opts();\n\t\t\tif (globalOptions.cwd) {\n\t\t\t\tprocess.chdir(globalOptions.cwd);\n\t\t\t}\n\t\t\tawait initCommand(name, options);\n\t\t} catch (error) {\n\t\t\tconsole.error(error instanceof Error ? error.message : 'Command failed');\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n\nprogram\n\t.command('build')\n\t.description('Build handlers from endpoints, functions, and crons')\n\t.option(\n\t\t'--provider <provider>',\n\t\t'Target provider for generated handlers (aws, server)',\n\t)\n\t.option(\n\t\t'--providers <providers>',\n\t\t'[DEPRECATED] Use --provider instead. Target providers for generated handlers (comma-separated)',\n\t)\n\t.option(\n\t\t'--enable-openapi',\n\t\t'Enable OpenAPI documentation generation for server builds',\n\t)\n\t.option('--production', 'Build for production (no dev tools, bundled output)')\n\t.option('--skip-bundle', 'Skip bundling step in production build')\n\t.option('--stage <stage>', 'Inject encrypted secrets for deployment stage')\n\t.action(\n\t\tasync (options: {\n\t\t\tprovider?: string;\n\t\t\tproviders?: string;\n\t\t\tenableOpenapi?: boolean;\n\t\t\tproduction?: boolean;\n\t\t\tskipBundle?: boolean;\n\t\t\tstage?: string;\n\t\t}) => {\n\t\t\ttry {\n\t\t\t\tconst globalOptions = program.opts();\n\t\t\t\tif (globalOptions.cwd) {\n\t\t\t\t\tprocess.chdir(globalOptions.cwd);\n\t\t\t\t}\n\n\t\t\t\t// Handle new single provider option\n\t\t\t\tif (options.provider) {\n\t\t\t\t\tif (!['aws', 'server'].includes(options.provider)) {\n\t\t\t\t\t\tprocess.exit(1);\n\t\t\t\t\t}\n\t\t\t\t\tawait buildCommand({\n\t\t\t\t\t\tprovider: options.provider as MainProvider,\n\t\t\t\t\t\tenableOpenApi: options.enableOpenapi || false,\n\t\t\t\t\t\tproduction: options.production || false,\n\t\t\t\t\t\tskipBundle: options.skipBundle || false,\n\t\t\t\t\t\tstage: options.stage,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\t// Handle legacy providers option\n\t\t\t\telse if (options.providers) {\n\t\t\t\t\tconst providerList = [\n\t\t\t\t\t\t...new Set(options.providers.split(',').map((p) => p.trim())),\n\t\t\t\t\t] as LegacyProvider[];\n\t\t\t\t\tawait buildCommand({\n\t\t\t\t\t\tproviders: providerList,\n\t\t\t\t\t\tenableOpenApi: options.enableOpenapi || false,\n\t\t\t\t\t\tproduction: options.production || false,\n\t\t\t\t\t\tskipBundle: options.skipBundle || false,\n\t\t\t\t\t\tstage: options.stage,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\t// Default to config-driven build\n\t\t\t\telse {\n\t\t\t\t\tawait buildCommand({\n\t\t\t\t\t\tenableOpenApi: options.enableOpenapi || false,\n\t\t\t\t\t\tproduction: options.production || false,\n\t\t\t\t\t\tskipBundle: options.skipBundle || false,\n\t\t\t\t\t\tstage: options.stage,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error(\n\t\t\t\t\terror instanceof Error ? error.message : 'Command failed',\n\t\t\t\t);\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\t\t},\n\t);\n\nprogram\n\t.command('dev')\n\t.description('Start development server with automatic reload')\n\t.option('-p, --port <port>', 'Port to run the development server on')\n\t.option(\n\t\t'--enable-openapi',\n\t\t'Enable OpenAPI documentation for development server',\n\t\ttrue,\n\t)\n\t.action(async (options: { port?: string; enableOpenapi?: boolean }) => {\n\t\ttry {\n\t\t\tconst globalOptions = program.opts();\n\t\t\tif (globalOptions.cwd) {\n\t\t\t\tprocess.chdir(globalOptions.cwd);\n\t\t\t}\n\n\t\t\tawait devCommand({\n\t\t\t\tport: options.port ? Number.parseInt(options.port, 10) : 3000,\n\t\t\t\tportExplicit: !!options.port,\n\t\t\t\tenableOpenApi: options.enableOpenapi ?? true,\n\t\t\t});\n\t\t} catch (error) {\n\t\t\tconsole.error(error instanceof Error ? error.message : 'Command failed');\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n\nprogram\n\t.command('cron')\n\t.description('Manage cron jobs')\n\t.action(() => {\n\t\tconst globalOptions = program.opts();\n\t\tif (globalOptions.cwd) {\n\t\t\tprocess.chdir(globalOptions.cwd);\n\t\t}\n\t\tprocess.stdout.write('Cron management - coming soon\\n');\n\t});\n\nprogram\n\t.command('function')\n\t.description('Manage serverless functions')\n\t.action(() => {\n\t\tconst globalOptions = program.opts();\n\t\tif (globalOptions.cwd) {\n\t\t\tprocess.chdir(globalOptions.cwd);\n\t\t}\n\t\tprocess.stdout.write('Serverless function management - coming soon\\n');\n\t});\n\nprogram\n\t.command('api')\n\t.description('Manage REST API endpoints')\n\t.action(() => {\n\t\tconst globalOptions = program.opts();\n\t\tif (globalOptions.cwd) {\n\t\t\tprocess.chdir(globalOptions.cwd);\n\t\t}\n\t\tprocess.stdout.write('REST API management - coming soon\\n');\n\t});\n\nprogram\n\t.command('openapi')\n\t.description('Generate OpenAPI specification from endpoints')\n\t.action(async () => {\n\t\ttry {\n\t\t\tconst globalOptions = program.opts();\n\t\t\tif (globalOptions.cwd) {\n\t\t\t\tprocess.chdir(globalOptions.cwd);\n\t\t\t}\n\t\t\tawait openapiCommand({});\n\t\t} catch (error) {\n\t\t\tconsole.error(error instanceof Error ? error.message : 'Command failed');\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n\nprogram\n\t.command('generate:react-query')\n\t.description('Generate React Query hooks from OpenAPI specification')\n\t.option('--input <path>', 'Input OpenAPI spec file path', 'openapi.json')\n\t.option(\n\t\t'--output <path>',\n\t\t'Output file path for generated hooks',\n\t\t'src/api/hooks.ts',\n\t)\n\t.option('--name <name>', 'API name prefix for generated code', 'API')\n\t.action(\n\t\tasync (options: { input?: string; output?: string; name?: string }) => {\n\t\t\ttry {\n\t\t\t\tconst globalOptions = program.opts();\n\t\t\t\tif (globalOptions.cwd) {\n\t\t\t\t\tprocess.chdir(globalOptions.cwd);\n\t\t\t\t}\n\t\t\t\tawait generateReactQueryCommand(options);\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error(\n\t\t\t\t\terror instanceof Error ? error.message : 'Command failed',\n\t\t\t\t);\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\t\t},\n\t);\n\nprogram\n\t.command('docker')\n\t.description('Generate Docker deployment files')\n\t.option('--build', 'Build Docker image after generating files')\n\t.option('--push', 'Push image to registry after building')\n\t.option('--tag <tag>', 'Image tag', 'latest')\n\t.option('--registry <registry>', 'Container registry URL')\n\t.option('--slim', 'Use slim Dockerfile (assumes pre-built bundle exists)')\n\t.option('--turbo', 'Use turbo prune for monorepo optimization')\n\t.option('--turbo-package <name>', 'Package name for turbo prune')\n\t.action(async (options: DockerOptions) => {\n\t\ttry {\n\t\t\tconst globalOptions = program.opts();\n\t\t\tif (globalOptions.cwd) {\n\t\t\t\tprocess.chdir(globalOptions.cwd);\n\t\t\t}\n\t\t\tawait dockerCommand(options);\n\t\t} catch (error) {\n\t\t\tconsole.error(error instanceof Error ? error.message : 'Command failed');\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n\nprogram\n\t.command('prepack')\n\t.description('Generate Docker files for production deployment')\n\t.option('--build', 'Build Docker image after generating files')\n\t.option('--push', 'Push image to registry after building')\n\t.option('--tag <tag>', 'Image tag', 'latest')\n\t.option('--registry <registry>', 'Container registry URL')\n\t.option('--slim', 'Build locally first, then use slim Dockerfile')\n\t.option('--skip-bundle', 'Skip bundling step (only with --slim)')\n\t.option('--turbo', 'Use turbo prune for monorepo optimization')\n\t.option('--turbo-package <name>', 'Package name for turbo prune')\n\t.action(\n\t\tasync (options: {\n\t\t\tbuild?: boolean;\n\t\t\tpush?: boolean;\n\t\t\ttag?: string;\n\t\t\tregistry?: string;\n\t\t\tslim?: boolean;\n\t\t\tskipBundle?: boolean;\n\t\t\tturbo?: boolean;\n\t\t\tturboPackage?: string;\n\t\t}) => {\n\t\t\ttry {\n\t\t\t\tconst globalOptions = program.opts();\n\t\t\t\tif (globalOptions.cwd) {\n\t\t\t\t\tprocess.chdir(globalOptions.cwd);\n\t\t\t\t}\n\n\t\t\t\tif (options.slim) {\n\t\t\t\t\tawait buildCommand({\n\t\t\t\t\t\tprovider: 'server',\n\t\t\t\t\t\tproduction: true,\n\t\t\t\t\t\tskipBundle: options.skipBundle,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tawait dockerCommand({\n\t\t\t\t\tbuild: options.build,\n\t\t\t\t\tpush: options.push,\n\t\t\t\t\ttag: options.tag,\n\t\t\t\t\tregistry: options.registry,\n\t\t\t\t\tslim: options.slim,\n\t\t\t\t\tturbo: options.turbo,\n\t\t\t\t\tturboPackage: options.turboPackage,\n\t\t\t\t});\n\t\t\t\tif (options.slim) {\n\t\t\t\t} else {\n\t\t\t\t}\n\n\t\t\t\tif (options.build) {\n\t\t\t\t\tconst tag = options.tag ?? 'latest';\n\t\t\t\t\tconst registry = options.registry;\n\t\t\t\t\tconst _imageRef = registry ? `${registry}/api:${tag}` : `api:${tag}`;\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error(\n\t\t\t\t\terror instanceof Error ? error.message : 'Command failed',\n\t\t\t\t);\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\t\t},\n\t);\n\n// Secrets management commands\nprogram\n\t.command('secrets:init')\n\t.description('Initialize secrets for a deployment stage')\n\t.requiredOption('--stage <stage>', 'Stage name (e.g., production, staging)')\n\t.option('--force', 'Overwrite existing secrets')\n\t.action(async (options: { stage: string; force?: boolean }) => {\n\t\ttry {\n\t\t\tconst globalOptions = program.opts();\n\t\t\tif (globalOptions.cwd) {\n\t\t\t\tprocess.chdir(globalOptions.cwd);\n\t\t\t}\n\t\t\tawait secretsInitCommand(options);\n\t\t} catch (error) {\n\t\t\tconsole.error(error instanceof Error ? error.message : 'Command failed');\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n\nprogram\n\t.command('secrets:set')\n\t.description('Set a custom secret for a stage')\n\t.argument('<key>', 'Secret key (e.g., API_KEY)')\n\t.argument('[value]', 'Secret value (reads from stdin if omitted)')\n\t.requiredOption('--stage <stage>', 'Stage name')\n\t.action(\n\t\tasync (\n\t\t\tkey: string,\n\t\t\tvalue: string | undefined,\n\t\t\toptions: { stage: string },\n\t\t) => {\n\t\t\ttry {\n\t\t\t\tconst globalOptions = program.opts();\n\t\t\t\tif (globalOptions.cwd) {\n\t\t\t\t\tprocess.chdir(globalOptions.cwd);\n\t\t\t\t}\n\t\t\t\tawait secretsSetCommand(key, value, options);\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error(\n\t\t\t\t\terror instanceof Error ? error.message : 'Command failed',\n\t\t\t\t);\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\t\t},\n\t);\n\nprogram\n\t.command('secrets:show')\n\t.description('Show secrets for a stage')\n\t.requiredOption('--stage <stage>', 'Stage name')\n\t.option('--reveal', 'Show actual secret values (not masked)')\n\t.action(async (options: { stage: string; reveal?: boolean }) => {\n\t\ttry {\n\t\t\tconst globalOptions = program.opts();\n\t\t\tif (globalOptions.cwd) {\n\t\t\t\tprocess.chdir(globalOptions.cwd);\n\t\t\t}\n\t\t\tawait secretsShowCommand(options);\n\t\t} catch (error) {\n\t\t\tconsole.error(error instanceof Error ? error.message : 'Command failed');\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n\nprogram\n\t.command('secrets:rotate')\n\t.description('Rotate service passwords')\n\t.requiredOption('--stage <stage>', 'Stage name')\n\t.option(\n\t\t'--service <service>',\n\t\t'Specific service to rotate (postgres, redis, rabbitmq)',\n\t)\n\t.action(async (options: { stage: string; service?: ComposeServiceName }) => {\n\t\ttry {\n\t\t\tconst globalOptions = program.opts();\n\t\t\tif (globalOptions.cwd) {\n\t\t\t\tprocess.chdir(globalOptions.cwd);\n\t\t\t}\n\t\t\tawait secretsRotateCommand(options);\n\t\t} catch (error) {\n\t\t\tconsole.error(error instanceof Error ? error.message : 'Command failed');\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n\nprogram\n\t.command('secrets:import')\n\t.description('Import secrets from a JSON file')\n\t.argument('<file>', 'JSON file path (e.g., secrets.json)')\n\t.requiredOption('--stage <stage>', 'Stage name')\n\t.option('--no-merge', 'Replace all custom secrets instead of merging')\n\t.action(async (file: string, options: { stage: string; merge?: boolean }) => {\n\t\ttry {\n\t\t\tconst globalOptions = program.opts();\n\t\t\tif (globalOptions.cwd) {\n\t\t\t\tprocess.chdir(globalOptions.cwd);\n\t\t\t}\n\t\t\tawait secretsImportCommand(file, options);\n\t\t} catch (error) {\n\t\t\tconsole.error(error instanceof Error ? error.message : 'Command failed');\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n\n// Deploy command\nprogram\n\t.command('deploy')\n\t.description('Deploy application to a provider')\n\t.requiredOption(\n\t\t'--provider <provider>',\n\t\t'Deploy provider (docker, dokploy, aws-lambda)',\n\t)\n\t.requiredOption(\n\t\t'--stage <stage>',\n\t\t'Deployment stage (e.g., production, staging)',\n\t)\n\t.option('--tag <tag>', 'Image tag (default: stage-timestamp)')\n\t.option('--skip-push', 'Skip pushing image to registry')\n\t.option('--skip-build', 'Skip build step (use existing build)')\n\t.action(\n\t\tasync (options: {\n\t\t\tprovider: string;\n\t\t\tstage: string;\n\t\t\ttag?: string;\n\t\t\tskipPush?: boolean;\n\t\t\tskipBuild?: boolean;\n\t\t}) => {\n\t\t\ttry {\n\t\t\t\tconst globalOptions = program.opts();\n\t\t\t\tif (globalOptions.cwd) {\n\t\t\t\t\tprocess.chdir(globalOptions.cwd);\n\t\t\t\t}\n\n\t\t\t\tconst validProviders = ['docker', 'dokploy', 'aws-lambda'];\n\t\t\t\tif (!validProviders.includes(options.provider)) {\n\t\t\t\t\tconsole.error(\n\t\t\t\t\t\t`Invalid provider: ${options.provider}\\n` +\n\t\t\t\t\t\t\t`Valid providers: ${validProviders.join(', ')}`,\n\t\t\t\t\t);\n\t\t\t\t\tprocess.exit(1);\n\t\t\t\t}\n\n\t\t\t\tawait deployCommand({\n\t\t\t\t\tprovider: options.provider as DeployProvider,\n\t\t\t\t\tstage: options.stage,\n\t\t\t\t\ttag: options.tag,\n\t\t\t\t\tskipPush: options.skipPush,\n\t\t\t\t\tskipBuild: options.skipBuild,\n\t\t\t\t});\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error(error instanceof Error ? error.message : 'Deploy failed');\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\t\t},\n\t);\n\n// Deploy init command - Initialize Dokploy project and application\nprogram\n\t.command('deploy:init')\n\t.description('Initialize Dokploy deployment (create project and application)')\n\t.option(\n\t\t'--endpoint <url>',\n\t\t'Dokploy server URL (uses stored credentials if logged in)',\n\t)\n\t.requiredOption('--project <name>', 'Project name (creates if not exists)')\n\t.requiredOption('--app <name>', 'Application name')\n\t.option('--project-id <id>', 'Use existing project ID instead of creating')\n\t.option('--registry-id <id>', 'Configure registry for the application')\n\t.action(\n\t\tasync (options: {\n\t\t\tendpoint?: string;\n\t\t\tproject: string;\n\t\t\tapp: string;\n\t\t\tprojectId?: string;\n\t\t\tregistryId?: string;\n\t\t}) => {\n\t\t\ttry {\n\t\t\t\tconst globalOptions = program.opts();\n\t\t\t\tif (globalOptions.cwd) {\n\t\t\t\t\tprocess.chdir(globalOptions.cwd);\n\t\t\t\t}\n\n\t\t\t\tawait deployInitCommand({\n\t\t\t\t\tendpoint: options.endpoint,\n\t\t\t\t\tprojectName: options.project,\n\t\t\t\t\tappName: options.app,\n\t\t\t\t\tprojectId: options.projectId,\n\t\t\t\t\tregistryId: options.registryId,\n\t\t\t\t});\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error(\n\t\t\t\t\terror instanceof Error\n\t\t\t\t\t\t? error.message\n\t\t\t\t\t\t: 'Failed to initialize deployment',\n\t\t\t\t);\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\t\t},\n\t);\n\n// Deploy list command - List Dokploy resources\nprogram\n\t.command('deploy:list')\n\t.description('List Dokploy resources (projects, registries)')\n\t.option(\n\t\t'--endpoint <url>',\n\t\t'Dokploy server URL (uses stored credentials if logged in)',\n\t)\n\t.option('--projects', 'List projects')\n\t.option('--registries', 'List registries')\n\t.action(\n\t\tasync (options: {\n\t\t\tendpoint?: string;\n\t\t\tprojects?: boolean;\n\t\t\tregistries?: boolean;\n\t\t}) => {\n\t\t\ttry {\n\t\t\t\tconst globalOptions = program.opts();\n\t\t\t\tif (globalOptions.cwd) {\n\t\t\t\t\tprocess.chdir(globalOptions.cwd);\n\t\t\t\t}\n\n\t\t\t\tif (options.projects) {\n\t\t\t\t\tawait deployListCommand({\n\t\t\t\t\t\tendpoint: options.endpoint,\n\t\t\t\t\t\tresource: 'projects',\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tif (options.registries) {\n\t\t\t\t\tawait deployListCommand({\n\t\t\t\t\t\tendpoint: options.endpoint,\n\t\t\t\t\t\tresource: 'registries',\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tif (!options.projects && !options.registries) {\n\t\t\t\t\t// Default to listing both\n\t\t\t\t\tawait deployListCommand({\n\t\t\t\t\t\tendpoint: options.endpoint,\n\t\t\t\t\t\tresource: 'projects',\n\t\t\t\t\t});\n\t\t\t\t\tawait deployListCommand({\n\t\t\t\t\t\tendpoint: options.endpoint,\n\t\t\t\t\t\tresource: 'registries',\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error(\n\t\t\t\t\terror instanceof Error ? error.message : 'Failed to list resources',\n\t\t\t\t);\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\t\t},\n\t);\n\n// Login command\nprogram\n\t.command('login')\n\t.description('Authenticate with a deployment service')\n\t.option('--service <service>', 'Service to login to (dokploy)', 'dokploy')\n\t.option('--token <token>', 'API token (will prompt if not provided)')\n\t.option('--endpoint <url>', 'Service endpoint URL')\n\t.action(\n\t\tasync (options: { service: string; token?: string; endpoint?: string }) => {\n\t\t\ttry {\n\t\t\t\tconst globalOptions = program.opts();\n\t\t\t\tif (globalOptions.cwd) {\n\t\t\t\t\tprocess.chdir(globalOptions.cwd);\n\t\t\t\t}\n\n\t\t\t\tif (options.service !== 'dokploy') {\n\t\t\t\t\tconsole.error(\n\t\t\t\t\t\t`Unknown service: ${options.service}. Supported: dokploy`,\n\t\t\t\t\t);\n\t\t\t\t\tprocess.exit(1);\n\t\t\t\t}\n\n\t\t\t\tawait loginCommand({\n\t\t\t\t\tservice: options.service as 'dokploy',\n\t\t\t\t\ttoken: options.token,\n\t\t\t\t\tendpoint: options.endpoint,\n\t\t\t\t});\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error(\n\t\t\t\t\terror instanceof Error ? error.message : 'Failed to login',\n\t\t\t\t);\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\t\t},\n\t);\n\n// Logout command\nprogram\n\t.command('logout')\n\t.description('Remove stored credentials')\n\t.option(\n\t\t'--service <service>',\n\t\t'Service to logout from (dokploy, all)',\n\t\t'dokploy',\n\t)\n\t.action(async (options: { service: string }) => {\n\t\ttry {\n\t\t\tconst globalOptions = program.opts();\n\t\t\tif (globalOptions.cwd) {\n\t\t\t\tprocess.chdir(globalOptions.cwd);\n\t\t\t}\n\n\t\t\tawait logoutCommand({\n\t\t\t\tservice: options.service as 'dokploy' | 'all',\n\t\t\t});\n\t\t} catch (error) {\n\t\t\tconsole.error(\n\t\t\t\terror instanceof Error ? error.message : 'Failed to logout',\n\t\t\t);\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n\n// Whoami command\nprogram\n\t.command('whoami')\n\t.description('Show current authentication status')\n\t.action(async () => {\n\t\ttry {\n\t\t\tconst globalOptions = program.opts();\n\t\t\tif (globalOptions.cwd) {\n\t\t\t\tprocess.chdir(globalOptions.cwd);\n\t\t\t}\n\n\t\t\tawait whoamiCommand();\n\t\t} catch (error) {\n\t\t\tconsole.error(\n\t\t\t\terror instanceof Error ? error.message : 'Failed to get status',\n\t\t\t);\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n\nprogram.parse();\n"],"mappings":"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"}
|