@kalphq/cli 0.0.0-dev-20260513002723 → 0.0.0-dev-20260513005156

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/dist/add-NDU352FV.js +124 -0
  2. package/dist/add-NDU352FV.js.map +1 -0
  3. package/dist/chunk-5ZRVO3TQ.js +70 -0
  4. package/dist/chunk-5ZRVO3TQ.js.map +1 -0
  5. package/dist/{chunk-GW6MLHK7.js → chunk-DHCCSWJN.js} +48 -145
  6. package/dist/chunk-DHCCSWJN.js.map +1 -0
  7. package/dist/{chunk-TNKYKA7N.js → chunk-GNQI376N.js} +118 -18
  8. package/dist/chunk-GNQI376N.js.map +1 -0
  9. package/dist/chunk-NV2IZ4XM.js +102 -0
  10. package/dist/chunk-NV2IZ4XM.js.map +1 -0
  11. package/dist/{chunk-TY5UW4IZ.js → chunk-X56YSZGT.js} +43 -8
  12. package/dist/chunk-X56YSZGT.js.map +1 -0
  13. package/dist/delete-DY5FQAHW.js +127 -0
  14. package/dist/delete-DY5FQAHW.js.map +1 -0
  15. package/dist/{deploy-TX6SP5M4.js → deploy-AD3F3BN7.js} +27 -22
  16. package/dist/deploy-AD3F3BN7.js.map +1 -0
  17. package/dist/{dev-APJ32K2Y.js → dev-X43HHIYV.js} +5 -3
  18. package/dist/{dev-APJ32K2Y.js.map → dev-X43HHIYV.js.map} +1 -1
  19. package/dist/index.js +6 -8
  20. package/dist/index.js.map +1 -1
  21. package/dist/list-4X735L5X.js +90 -0
  22. package/dist/list-4X735L5X.js.map +1 -0
  23. package/dist/{login-DGX55YZ6.js → login-RAN2I7YT.js} +3 -5
  24. package/dist/{login-DGX55YZ6.js.map → login-RAN2I7YT.js.map} +1 -1
  25. package/dist/{push-APZG653E.js → push-RA6GEUV4.js} +21 -10
  26. package/dist/push-RA6GEUV4.js.map +1 -0
  27. package/dist/{secrets-P7ADVLOS.js → secrets-5ZPPASCH.js} +10 -10
  28. package/dist/secrets-5ZPPASCH.js.map +1 -0
  29. package/dist/sync-2NLWWGI2.js +69 -0
  30. package/dist/sync-2NLWWGI2.js.map +1 -0
  31. package/package.json +4 -4
  32. package/dist/add-XTXSSGC5.js +0 -139
  33. package/dist/add-XTXSSGC5.js.map +0 -1
  34. package/dist/chunk-5RODADXW.js +0 -65
  35. package/dist/chunk-5RODADXW.js.map +0 -1
  36. package/dist/chunk-GW6MLHK7.js.map +0 -1
  37. package/dist/chunk-TNKYKA7N.js.map +0 -1
  38. package/dist/chunk-TY5UW4IZ.js.map +0 -1
  39. package/dist/delete-N4OSUK3X.js +0 -145
  40. package/dist/delete-N4OSUK3X.js.map +0 -1
  41. package/dist/deploy-TX6SP5M4.js.map +0 -1
  42. package/dist/link-WZQSR2TM.js +0 -36
  43. package/dist/link-WZQSR2TM.js.map +0 -1
  44. package/dist/list-VMJPWHIH.js +0 -120
  45. package/dist/list-VMJPWHIH.js.map +0 -1
  46. package/dist/push-APZG653E.js.map +0 -1
  47. package/dist/secrets-P7ADVLOS.js.map +0 -1
  48. package/dist/sync-OTO44GQS.js +0 -121
  49. package/dist/sync-OTO44GQS.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/utils/project-state.ts","../src/utils/runtime.ts","../src/utils/ai.ts","../src/utils/project-config.ts","../src/utils/runtime-identity.ts"],"sourcesContent":["import { mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nexport interface ProjectAgentState {\n currentHash: string | null;\n currentVersion: number;\n lastLocalHash: string | null;\n lastRemoteHash: string | null;\n lastPushedAt: string | null;\n localPath: string;\n workerUrl: string | null;\n}\n\nexport interface ProjectState {\n workerUrl: string | null;\n deployedAt: string | null;\n accountId: string | null;\n studioCredentialsFingerprint?: string | null;\n serviceKeyFingerprint?: string | null;\n agents: Record<string, ProjectAgentState>;\n}\n\nconst KALP_DIR = \".kalp\";\nconst STATE_FILE = \"state.json\";\n\nfunction normalizeProjectState(raw: unknown): ProjectState | null {\n if (!raw || typeof raw !== \"object\") return null;\n const value = raw as Record<string, unknown>;\n const workerUrl =\n typeof value.workerUrl === \"string\" && value.workerUrl.length > 0\n ? value.workerUrl\n : null;\n const deployedAt =\n typeof value.deployedAt === \"string\" && value.deployedAt.length > 0\n ? value.deployedAt\n : null;\n const accountId =\n typeof value.accountId === \"string\" && value.accountId.length > 0\n ? value.accountId\n : null;\n const studioCredentialsFingerprint =\n typeof value.studioCredentialsFingerprint === \"string\" &&\n value.studioCredentialsFingerprint.length > 0\n ? value.studioCredentialsFingerprint\n : null;\n const serviceKeyFingerprint =\n typeof value.serviceKeyFingerprint === \"string\" &&\n value.serviceKeyFingerprint.length > 0\n ? value.serviceKeyFingerprint\n : null;\n\n const agents: Record<string, ProjectAgentState> = {};\n const rawAgents =\n value.agents && typeof value.agents === \"object\"\n ? (value.agents as Record<string, unknown>)\n : {};\n\n for (const [name, entry] of Object.entries(rawAgents)) {\n if (!entry || typeof entry !== \"object\") continue;\n const item = entry as Record<string, unknown>;\n if (typeof item.localPath !== \"string\" || item.localPath.length === 0) {\n continue;\n }\n\n const currentVersion =\n typeof item.currentVersion === \"number\" && Number.isFinite(item.currentVersion)\n ? Math.max(0, Math.floor(item.currentVersion))\n : 0;\n\n agents[name] = {\n currentHash: typeof item.currentHash === \"string\" ? item.currentHash : null,\n currentVersion,\n lastLocalHash: typeof item.lastLocalHash === \"string\" ? item.lastLocalHash : null,\n lastRemoteHash:\n typeof item.lastRemoteHash === \"string\" ? item.lastRemoteHash : null,\n lastPushedAt: typeof item.lastPushedAt === \"string\" ? item.lastPushedAt : null,\n localPath: item.localPath,\n workerUrl: typeof item.workerUrl === \"string\" ? item.workerUrl : null,\n };\n }\n\n return {\n workerUrl,\n deployedAt,\n accountId,\n studioCredentialsFingerprint,\n serviceKeyFingerprint,\n agents,\n };\n}\n\nexport async function readProjectState(cwd: string): Promise<ProjectState | null> {\n try {\n const statePath = join(cwd, KALP_DIR, STATE_FILE);\n const content = await readFile(statePath, \"utf-8\");\n return normalizeProjectState(JSON.parse(content));\n } catch {\n return null;\n }\n}\n\nexport async function writeProjectState(\n cwd: string,\n state: ProjectState,\n): Promise<void> {\n const dir = join(cwd, KALP_DIR);\n await mkdir(dir, { recursive: true });\n await writeFile(join(dir, STATE_FILE), `${JSON.stringify(state, null, 2)}\\n`, \"utf-8\");\n}\n","import { createHash } from \"node:crypto\";\nimport {\n access,\n cp,\n mkdir,\n readdir,\n readFile,\n rm,\n stat,\n writeFile,\n} from \"node:fs/promises\";\nimport { basename, dirname, join, resolve } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { deriveLabelFromName } from \"@kalphq/project\";\nimport { getRequiredSecretForProvider, resolveProviderFromConfig } from \"@/utils/ai\";\nimport {\n resolveIdentityAuthRequirements,\n} from \"@/utils/project-config\";\nimport { readProjectState } from \"@/utils/project-state\";\nimport { materializeRuntimeIdentity } from \"@/utils/runtime-identity\";\n\nconst RUNTIME_ROOT = \".kalp\";\nconst RUNTIME_DIR = \"runtime\";\nconst STUDIO_DIR = \"studio\";\nconst WRANGLER_CONFIG_FILE = \"wrangler.jsonc\";\nconst WORKER_ENTRY_FILE = \"worker-entry.js\";\nconst COMPATIBILITY_DATE = \"2026-05-10\";\n\nexport interface RuntimePaths {\n runtimeDir: string;\n studioDir: string;\n workerEntrypointPath: string;\n wranglerConfigPath: string;\n workerName: string;\n}\n\ninterface RuntimeAgentRecord {\n name: string;\n label?: string;\n tags?: string[];\n environment: \"local\" | \"remote\" | \"both\";\n status: \"online\" | \"offline\";\n hash: string | null;\n version: string | null;\n versionNumber: number | null;\n lastRemoteHash: string | null;\n lastLocalHash: string | null;\n workerUrl: string | null;\n localPath: string | null;\n updatedAt: string | null;\n}\n\ninterface RuntimeAgentsSnapshot {\n generatedAt: string;\n projectPath: string;\n workerUrl: string | null;\n mode: \"local\" | \"remote\";\n agents: RuntimeAgentRecord[];\n}\n\nexport interface MaterializeRuntimeOptions {\n mode?: \"local\" | \"remote\";\n}\n\ninterface WranglerConfig {\n $schema: string;\n name: string;\n main: string;\n compatibility_date: string;\n compatibility_flags: string[];\n migrations: Array<{ tag: string; new_sqlite_classes: string[] }>;\n durable_objects: {\n bindings: Array<{ name: string; class_name: string }>;\n };\n kv_namespaces: Array<{ binding: string }>;\n assets: {\n directory: string;\n binding: string;\n run_worker_first: boolean;\n };\n observability: { enabled: boolean };\n upload_source_maps: boolean;\n vars: {\n KALP_ENV: \"local\" | \"remote\";\n };\n secrets: { required: string[] };\n}\n\ninterface RuntimeTemplatePaths {\n studioTemplateDir: string;\n workerEntryPath: string;\n}\n\nfunction sanitizeSegment(input: string): string {\n return input\n .toLowerCase()\n .replace(/^@/, \"\")\n .replace(/\\//g, \"-\")\n .replace(/[^a-z0-9-]/g, \"-\")\n .replace(/-+/g, \"-\")\n .replace(/^-+|-+$/g, \"\");\n}\n\nasync function resolveProjectSlug(cwd: string): Promise<string> {\n const fallback = sanitizeSegment(basename(cwd)) || \"agent\";\n const packageJsonPath = join(cwd, \"package.json\");\n\n try {\n const content = await readFile(packageJsonPath, \"utf-8\");\n const pkg = JSON.parse(content) as { name?: string };\n const name = typeof pkg.name === \"string\" ? pkg.name : \"\";\n const sanitized = sanitizeSegment(name);\n return sanitized || fallback;\n } catch {\n return fallback;\n }\n}\n\nfunction buildWorkerName(slug: string, cwd: string): string {\n const cwdHash = createHash(\"sha1\").update(cwd).digest(\"hex\").slice(0, 8);\n const withPrefix = `kalp-${slug}-${cwdHash}`;\n const maxLen = 63;\n if (withPrefix.length <= maxLen) {\n return withPrefix;\n }\n\n const clipped = withPrefix.slice(0, maxLen).replace(/-+$/g, \"\");\n return clipped || `kalp-${cwdHash}`;\n}\n\nfunction createRuntimeConfig(\n workerName: string,\n mode: \"local\" | \"remote\",\n requiredSecrets: string[],\n): WranglerConfig {\n return {\n $schema: \"node_modules/wrangler/config-schema.json\",\n name: workerName,\n main: `./${WORKER_ENTRY_FILE}`,\n compatibility_date: COMPATIBILITY_DATE,\n compatibility_flags: [\"nodejs_compat\"],\n migrations: [\n {\n tag: \"v1\",\n new_sqlite_classes: [\"AgentDurableObject\"],\n },\n ],\n durable_objects: {\n bindings: [\n {\n name: \"KALP_RUNTIME_CLOUDFLARE\",\n class_name: \"AgentDurableObject\",\n },\n ],\n },\n kv_namespaces: [\n {\n binding: \"KALP_MANIFESTS\",\n },\n ],\n assets: {\n directory: `./${STUDIO_DIR}`,\n binding: \"ASSETS\",\n run_worker_first: true,\n },\n observability: { enabled: true },\n upload_source_maps: true,\n vars: {\n KALP_ENV: mode,\n },\n secrets: {\n required: requiredSecrets,\n },\n };\n}\n\nfunction runtimeTemplateCandidates(): Array<{\n studioTemplateDir: string;\n workerEntryPath: string;\n}> {\n const here = dirname(fileURLToPath(import.meta.url));\n const distTemplateRoot = resolve(here, \"runtime-template\");\n const packageRootTemplate = resolve(here, \"..\", \"runtime-template\");\n const sourceTemplateRoot = resolve(here, \"..\", \"..\", \"runtime-template\");\n const monorepoStudioDist = resolve(\n here,\n \"..\",\n \"..\",\n \"..\",\n \"..\",\n \"apps\",\n \"studio\",\n \"dist\",\n \"client\",\n );\n\n return [\n {\n studioTemplateDir: join(distTemplateRoot, STUDIO_DIR),\n workerEntryPath: join(distTemplateRoot, WORKER_ENTRY_FILE),\n },\n {\n studioTemplateDir: join(packageRootTemplate, STUDIO_DIR),\n workerEntryPath: join(packageRootTemplate, WORKER_ENTRY_FILE),\n },\n {\n studioTemplateDir: join(sourceTemplateRoot, STUDIO_DIR),\n workerEntryPath: join(sourceTemplateRoot, WORKER_ENTRY_FILE),\n },\n {\n studioTemplateDir: monorepoStudioDist,\n workerEntryPath: join(sourceTemplateRoot, WORKER_ENTRY_FILE),\n },\n ];\n}\n\nasync function resolveRuntimeTemplate(): Promise<RuntimeTemplatePaths> {\n for (const candidate of runtimeTemplateCandidates()) {\n try {\n await access(candidate.studioTemplateDir);\n await access(candidate.workerEntryPath);\n return candidate;\n } catch {\n // continue\n }\n }\n\n throw new Error(\n \"Kalp runtime template not found in CLI package. Reinstall @kalphq/cli.\",\n );\n}\n\nfunction createStudioShell(entryScript: string, cssFiles: string[]): string {\n const cssLinks = cssFiles\n .map((file) => ` <link rel=\"stylesheet\" href=\"/studio/assets/${file}\" />`)\n .join(\"\\n\");\n\n return `<!doctype html>\n<html lang=\"en\">\n <head>\n <meta charset=\"UTF-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n <title>Kalp Studio</title>\n${cssLinks}\n </head>\n <body>\n <div id=\"root\"></div>\n <script type=\"module\" src=\"/studio/assets/${entryScript}\"></script>\n </body>\n</html>\n`;\n}\n\nasync function ensureStudioIndex(studioDir: string): Promise<void> {\n const indexPath = join(studioDir, \"index.html\");\n try {\n await access(indexPath);\n return;\n } catch {\n // index.html is missing on some TanStack Start static builds.\n }\n\n const assetsDir = join(studioDir, \"assets\");\n const assetFiles = await readdir(assetsDir);\n const entryScript =\n assetFiles.find((file) => /^index-.*\\.js$/i.test(file)) ??\n assetFiles.find((file) => file.endsWith(\".js\"));\n\n if (!entryScript) {\n throw new Error(\n \"Studio runtime template is missing an entry JS bundle in studio/assets.\",\n );\n }\n\n const cssFiles = assetFiles.filter((file) => file.endsWith(\".css\")).sort();\n const html = createStudioShell(entryScript, cssFiles);\n await writeFile(indexPath, html, \"utf-8\");\n}\n\nexport async function readLocalAgentNames(cwd: string): Promise<string[]> {\n const agentsDir = join(cwd, \"agents\");\n try {\n const entries = await readdir(agentsDir, { withFileTypes: true });\n const names: string[] = [];\n for (const entry of entries) {\n if (!entry.isDirectory()) continue;\n const indexPath = join(agentsDir, entry.name, \"index.ts\");\n const exists = await stat(indexPath)\n .then(() => true)\n .catch(() => false);\n if (exists) names.push(entry.name);\n }\n return names.sort((a, b) => a.localeCompare(b));\n } catch {\n return [];\n }\n}\n\nasync function createAgentsSnapshot(\n cwd: string,\n mode: \"local\" | \"remote\",\n): Promise<RuntimeAgentsSnapshot> {\n const localAgentNames = await readLocalAgentNames(cwd);\n const state = await readProjectState(cwd);\n\n const byName = new Map<string, RuntimeAgentRecord>();\n const stateAgents = state?.agents ?? {};\n\n for (const name of localAgentNames) {\n const localPath = join(cwd, \"agents\", name, \"index.ts\");\n const saved = stateAgents[name];\n const hasRemoteVersion = !!saved?.lastRemoteHash && (saved?.currentVersion ?? 0) > 0;\n\n if (mode === \"remote\" && !hasRemoteVersion) {\n continue;\n }\n\n const resolvedWorkerUrl =\n saved?.workerUrl ??\n (state?.workerUrl ? `${state.workerUrl.replace(/\\/$/, \"\")}/a/${name}` : null);\n const versionNumber =\n typeof saved?.currentVersion === \"number\" && saved.currentVersion > 0\n ? saved.currentVersion\n : null;\n\n byName.set(name, {\n name,\n label: deriveLabelFromName(name),\n tags: [],\n environment:\n mode === \"remote\"\n ? \"remote\"\n : hasRemoteVersion\n ? \"both\"\n : \"local\",\n status: resolvedWorkerUrl ? \"online\" : \"offline\",\n hash: saved?.currentHash ?? null,\n version: versionNumber ? `v${versionNumber}` : null,\n versionNumber,\n lastRemoteHash: saved?.lastRemoteHash ?? null,\n lastLocalHash: saved?.lastLocalHash ?? null,\n workerUrl: resolvedWorkerUrl,\n localPath,\n updatedAt: saved?.lastPushedAt ?? state?.deployedAt ?? null,\n });\n }\n\n if (mode === \"remote\") {\n for (const [name, saved] of Object.entries(stateAgents)) {\n const hasRemoteVersion =\n !!saved.lastRemoteHash && (saved.currentVersion ?? 0) > 0;\n if (!hasRemoteVersion || byName.has(name)) continue;\n\n const localPath = saved.localPath ?? join(cwd, \"agents\", name, \"index.ts\");\n const workerUrl =\n saved.workerUrl ??\n (state?.workerUrl ? `${state.workerUrl.replace(/\\/$/, \"\")}/a/${name}` : null);\n const versionNumber = saved.currentVersion > 0 ? saved.currentVersion : null;\n\n byName.set(name, {\n name,\n label: deriveLabelFromName(name),\n tags: [],\n environment: \"remote\",\n status: workerUrl ? \"online\" : \"offline\",\n hash: saved.currentHash ?? null,\n version: versionNumber ? `v${versionNumber}` : null,\n versionNumber,\n lastRemoteHash: saved.lastRemoteHash ?? null,\n lastLocalHash: saved.lastLocalHash ?? null,\n workerUrl,\n localPath,\n updatedAt: saved.lastPushedAt ?? state?.deployedAt ?? null,\n });\n }\n }\n\n return {\n generatedAt: new Date().toISOString(),\n projectPath: cwd,\n workerUrl: state?.workerUrl ?? null,\n mode,\n agents: Array.from(byName.values()).sort((a, b) => a.name.localeCompare(b.name)),\n };\n}\n\nexport async function writeRuntimeAgentsSnapshot(params: {\n cwd: string;\n runtimeDir: string;\n mode: \"local\" | \"remote\";\n}): Promise<void> {\n const snapshot = await createAgentsSnapshot(params.cwd, params.mode);\n await writeFile(\n join(params.runtimeDir, \"agents.snapshot.json\"),\n `${JSON.stringify(snapshot, null, 2)}\\n`,\n \"utf-8\",\n );\n}\n\nexport async function materializeRuntime(\n cwd: string,\n options: MaterializeRuntimeOptions = {},\n): Promise<RuntimePaths> {\n const mode = options.mode ?? \"remote\";\n const runtimeDir = join(cwd, RUNTIME_ROOT, RUNTIME_DIR);\n const studioDir = join(runtimeDir, STUDIO_DIR);\n const workerEntrypointPath = join(runtimeDir, WORKER_ENTRY_FILE);\n const wranglerConfigPath = join(runtimeDir, WRANGLER_CONFIG_FILE);\n\n const template = await resolveRuntimeTemplate();\n await rm(runtimeDir, { recursive: true, force: true });\n await mkdir(runtimeDir, { recursive: true });\n\n await cp(template.studioTemplateDir, studioDir, { recursive: true });\n await cp(template.workerEntryPath, workerEntrypointPath);\n await ensureStudioIndex(studioDir);\n await writeRuntimeAgentsSnapshot({ cwd, runtimeDir, mode });\n const identity = await materializeRuntimeIdentity({ cwd, runtimeDir });\n\n const projectSlug = await resolveProjectSlug(cwd);\n const workerName = buildWorkerName(projectSlug, cwd);\n const requiredSecrets = new Set<string>([\n \"KALP_SECRET_KEY\",\n \"KALP_STUDIO_PASSWORD\",\n \"KALP_STUDIO_ADMIN_USER\",\n \"KALP_SERVICE_KEY\",\n ]);\n\n try {\n const provider = await resolveProviderFromConfig(cwd);\n requiredSecrets.add(getRequiredSecretForProvider(provider));\n } catch {\n // Ignore provider resolution errors here; deploy preflight handles strict checks.\n }\n\n const identityRequirements = resolveIdentityAuthRequirements(identity.identityConfig);\n for (const requirement of identityRequirements) {\n requiredSecrets.add(requirement.envKey);\n }\n\n const wranglerConfig = createRuntimeConfig(\n workerName,\n mode,\n [...requiredSecrets].sort((a, b) => a.localeCompare(b)),\n );\n await writeFile(\n wranglerConfigPath,\n `${JSON.stringify(wranglerConfig, null, 2)}\\n`,\n \"utf-8\",\n );\n\n return {\n runtimeDir,\n studioDir,\n workerEntrypointPath,\n wranglerConfigPath,\n workerName,\n };\n}\n","import { access, readFile } from \"node:fs/promises\";\nimport { constants } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { createJiti } from \"jiti\";\n\nexport type AIProvider = \"openai\" | \"anthropic\" | \"openrouter\" | \"custom\";\n\nconst PROVIDER_SECRET_MAP: Record<AIProvider, string> = {\n openai: \"OPENAI_API_KEY\",\n anthropic: \"ANTHROPIC_API_KEY\",\n openrouter: \"OPENROUTER_API_KEY\",\n custom: \"CUSTOM_AI_API_KEY\",\n};\n\nfunction parseEnv(content: string): Record<string, string> {\n const env: Record<string, string> = {};\n for (const raw of content.split(/\\r?\\n/g)) {\n const line = raw.trim();\n if (!line || line.startsWith(\"#\")) continue;\n const idx = line.indexOf(\"=\");\n if (idx <= 0) continue;\n env[line.slice(0, idx).trim()] = line.slice(idx + 1);\n }\n return env;\n}\n\nexport async function resolveProviderFromConfig(cwd: string): Promise<AIProvider> {\n const configPath = join(cwd, \"kalp.config.ts\");\n await access(configPath, constants.F_OK);\n const jiti = createJiti(cwd, { interopDefault: true });\n const config = (await jiti.import(configPath)) as\n | { default?: { ai?: { provider?: AIProvider } }; ai?: { provider?: AIProvider } }\n | undefined;\n const provider = config?.default?.ai?.provider ?? config?.ai?.provider ?? \"openai\";\n return provider;\n}\n\nexport async function readDotEnv(cwd: string): Promise<Record<string, string>> {\n const envPath = join(cwd, \".env\");\n const content = await readFile(envPath, \"utf-8\").catch(() => \"\");\n return parseEnv(content);\n}\n\nexport function getRequiredSecretForProvider(provider: AIProvider): string {\n return PROVIDER_SECRET_MAP[provider];\n}\n","import { createJiti } from \"jiti\";\nimport { access } from \"node:fs/promises\";\nimport { constants } from \"node:fs\";\nimport { join, resolve } from \"node:path\";\nimport type { AuthStrategy, IdentityConfig } from \"@kalphq/sdk\";\n\nexport interface LoadedProjectConfig {\n path: string;\n raw: Record<string, unknown>;\n}\n\nexport interface RuntimeIdentityStrategyConfig {\n type: \"jwks\" | \"symmetric\" | \"apiKey\";\n jwksUrl?: string;\n issuer?: string;\n audience?: string;\n secretEnvKey?: string;\n headerName?: string;\n envKey?: string;\n}\n\nexport interface RuntimeIdentityConfig {\n enforceGlobalAuth: boolean;\n identityId: string | null;\n strategy: RuntimeIdentityStrategyConfig | null;\n}\n\nexport interface ProjectConfigAuthRequirement {\n envKey: string;\n reason: string;\n}\n\nfunction normalizeStrategy(\n strategy: AuthStrategy | undefined,\n): RuntimeIdentityStrategyConfig | null {\n if (!strategy) return null;\n if (strategy.type === \"jwks\") {\n return {\n type: \"jwks\",\n jwksUrl: strategy.jwksUrl,\n issuer: strategy.issuer,\n audience: strategy.audience,\n };\n }\n if (strategy.type === \"symmetric\") {\n return {\n type: \"symmetric\",\n secretEnvKey: strategy.secretEnvKey,\n };\n }\n return {\n type: \"apiKey\",\n headerName: strategy.headerName,\n envKey: strategy.envKey,\n };\n}\n\nexport async function loadProjectConfig(cwd: string): Promise<LoadedProjectConfig> {\n const configPath = resolve(join(cwd, \"kalp.config.ts\"));\n await access(configPath, constants.F_OK);\n const jiti = createJiti(cwd, { interopDefault: true });\n const moduleValue = (await jiti.import(configPath)) as\n | { default?: Record<string, unknown> }\n | Record<string, unknown>;\n const raw =\n moduleValue && typeof moduleValue === \"object\" && \"default\" in moduleValue\n ? ((moduleValue.default ?? moduleValue) as Record<string, unknown>)\n : (moduleValue as Record<string, unknown>);\n return { path: configPath, raw };\n}\n\nexport function resolveRuntimeIdentityConfig(\n rawConfig: Record<string, unknown>,\n): RuntimeIdentityConfig {\n const identity =\n rawConfig.identity && typeof rawConfig.identity === \"object\"\n ? (rawConfig.identity as IdentityConfig)\n : undefined;\n const enforceGlobalAuth =\n typeof rawConfig.enforceGlobalAuth === \"boolean\"\n ? rawConfig.enforceGlobalAuth\n : true;\n\n return {\n enforceGlobalAuth,\n identityId:\n identity && typeof identity.id === \"string\" && identity.id.length > 0\n ? identity.id\n : null,\n strategy: normalizeStrategy(identity?.strategy),\n };\n}\n\nexport function resolveIdentityAuthRequirements(\n identity: RuntimeIdentityConfig,\n): ProjectConfigAuthRequirement[] {\n if (!identity.strategy) return [];\n\n if (identity.strategy.type === \"symmetric\") {\n return [\n {\n envKey: identity.strategy.secretEnvKey?.trim() || \"JWT_SIGNING_SECRET\",\n reason: \"symmetric JWT validation\",\n },\n ];\n }\n\n if (identity.strategy.type === \"apiKey\") {\n const envKey = identity.strategy.envKey?.trim();\n if (!envKey) {\n return [\n {\n envKey: \"KALP_API_KEY\",\n reason: \"apiKey strategy (default env key)\",\n },\n ];\n }\n return [{ envKey, reason: \"apiKey strategy\" }];\n }\n\n return [];\n}\n","import { build } from \"esbuild\";\nimport { writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport {\n loadProjectConfig,\n resolveRuntimeIdentityConfig,\n type RuntimeIdentityConfig,\n} from \"@/utils/project-config\";\n\nexport interface MaterializeRuntimeIdentityResult {\n identityConfig: RuntimeIdentityConfig;\n identityConfigPath: string;\n identityMapPath: string;\n}\n\nconst DEFAULT_IDENTITY_MAP_SOURCE = `export default function mapIdentity(payload) {\n const sub =\n payload && typeof payload === \"object\" && typeof payload.sub === \"string\"\n ? payload.sub\n : \"anonymous\";\n return { userId: sub, claims: {} };\n}\n`;\n\nfunction readIdentityMapCandidate(rawConfig: Record<string, unknown>): unknown {\n if (!rawConfig.identity || typeof rawConfig.identity !== \"object\") return null;\n return (rawConfig.identity as Record<string, unknown>).mapIdentity;\n}\n\nfunction assertEdgeSafeSource(mapIdentitySource: string): void {\n const blockedPatterns: Array<{ regex: RegExp; label: string }> = [\n { regex: /\\brequire\\s*\\(/, label: \"require(...)\" },\n { regex: /\\bnode:/, label: \"node:* imports\" },\n { regex: /\\bprocess\\./, label: \"process.*\" },\n { regex: /\\bBuffer\\b/, label: \"Buffer\" },\n { regex: /\\bimport\\s*\\(/, label: \"dynamic import(...)\" },\n ];\n\n const hit = blockedPatterns.find((item) => item.regex.test(mapIdentitySource));\n if (!hit) return;\n\n throw new Error(\n `mapIdentity uses \"${hit.label}\", which is not supported in edge runtime.`,\n );\n}\n\nasync function writeDefaultIdentityMap(identityMapPath: string): Promise<void> {\n await writeFile(identityMapPath, DEFAULT_IDENTITY_MAP_SOURCE, \"utf-8\");\n}\n\nasync function bundleIdentityMap(params: {\n cwd: string;\n mapIdentitySource: string;\n identityMapPath: string;\n}): Promise<void> {\n const { cwd, mapIdentitySource, identityMapPath } = params;\n assertEdgeSafeSource(mapIdentitySource);\n\n const entrySource = `\nconst mapIdentity = (${mapIdentitySource});\nif (typeof mapIdentity !== \"function\") {\n throw new Error(\"identity.mapIdentity must be a function.\");\n}\nexport default mapIdentity;\n`;\n\n try {\n await build({\n absWorkingDir: cwd,\n bundle: true,\n format: \"esm\",\n platform: \"browser\",\n target: [\"es2022\"],\n write: true,\n outfile: identityMapPath,\n logLevel: \"silent\",\n stdin: {\n contents: entrySource,\n resolveDir: cwd,\n sourcefile: \"kalp-identity-map-entry.mjs\",\n loader: \"js\",\n },\n });\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n throw new Error(\n [\n \"Could not bundle identity.mapIdentity for runtime.\",\n \"Please verify:\",\n \" • kalp.config.ts exists and exports default defineConfig(...)\",\n \" • mapIdentity is declared inline and does not capture external variables\",\n \" • mapIdentity does not use Node-specific APIs\",\n \" • kalp.config.ts has no broken imports\",\n `Technical details: ${message}`,\n ].join(\"\\n\"),\n );\n }\n}\n\nexport async function materializeRuntimeIdentity(params: {\n cwd: string;\n runtimeDir: string;\n}): Promise<MaterializeRuntimeIdentityResult> {\n const { cwd, runtimeDir } = params;\n const identityConfigPath = join(runtimeDir, \"identity.config.json\");\n const identityMapPath = join(runtimeDir, \"identity.map.mjs\");\n\n let rawConfig: Record<string, unknown> = {};\n try {\n const loaded = await loadProjectConfig(cwd);\n rawConfig = loaded.raw;\n } catch {\n rawConfig = {};\n }\n\n const identityConfig = resolveRuntimeIdentityConfig(rawConfig);\n await writeFile(\n identityConfigPath,\n `${JSON.stringify(identityConfig, null, 2)}\\n`,\n \"utf-8\",\n );\n\n const mapIdentity = readIdentityMapCandidate(rawConfig);\n if (typeof mapIdentity === \"function\") {\n const mapIdentitySource = mapIdentity.toString();\n if (!mapIdentitySource || /\\[native code\\]/.test(mapIdentitySource)) {\n throw new Error(\n \"Could not serialize identity.mapIdentity. Define it inline in kalp.config.ts as a regular function.\",\n );\n }\n await bundleIdentityMap({\n cwd,\n mapIdentitySource,\n identityMapPath,\n });\n } else {\n await writeDefaultIdentityMap(identityMapPath);\n }\n\n return { identityConfig, identityConfigPath, identityMapPath };\n}\n"],"mappings":"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","names":["access","mkdir","readFile","writeFile","join","resolve","readFile","join","createJiti","access","constants","join","writeFile","join","writeFile","join","join","readFile","resolve","access","writeFile","mkdir"]}
@@ -1,12 +1,58 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
- getCloudflareIdentity
4
- } from "./chunk-5RODADXW.js";
3
+ ensureGlobalConfigDir
4
+ } from "./chunk-FO24J6XL.js";
5
5
 
6
- // src/utils/providers/cloudflare.ts
7
- import { execa } from "execa";
8
- import { mkdtemp, readFile, rm, writeFile } from "fs/promises";
6
+ // src/utils/auth.ts
7
+ import { readFile, writeFile } from "fs/promises";
9
8
  import { join } from "path";
9
+ import { execa } from "execa";
10
+ var AUTH_FILE = async () => join(await ensureGlobalConfigDir(), "auth.json");
11
+ async function getCloudflareIdentity() {
12
+ try {
13
+ const run = async (args) => execa("npx", args, {
14
+ env: { FORCE_COLOR: "0", CLOUDFLARE_OUTPUT_FORMAT: "json" }
15
+ });
16
+ const firstAttempt = await run([
17
+ "wrangler",
18
+ "whoami",
19
+ "--output-format",
20
+ "json"
21
+ ]).catch(() => null);
22
+ if (firstAttempt) {
23
+ return JSON.parse(firstAttempt.stdout);
24
+ }
25
+ const fallback = await run(["wrangler", "whoami", "--json"]);
26
+ return JSON.parse(fallback.stdout);
27
+ } catch {
28
+ return null;
29
+ }
30
+ }
31
+ async function saveAuthConfig(config) {
32
+ const authPath = await AUTH_FILE();
33
+ await writeFile(authPath, JSON.stringify(config, null, 2), "utf-8");
34
+ }
35
+ async function getAuthConfig() {
36
+ try {
37
+ const authPath = await AUTH_FILE();
38
+ const content = await readFile(authPath, "utf-8");
39
+ return JSON.parse(content);
40
+ } catch {
41
+ return null;
42
+ }
43
+ }
44
+ async function requireAuth() {
45
+ const auth = await getAuthConfig();
46
+ if (!auth || new Date(auth.expiresAt).getTime() <= Date.now()) {
47
+ throw new Error("Not authenticated. Run `kalp login` first.");
48
+ }
49
+ return auth;
50
+ }
51
+
52
+ // src/utils/providers/cloudflare.ts
53
+ import { execa as execa2 } from "execa";
54
+ import { mkdtemp, readFile as readFile2, rm, writeFile as writeFile2 } from "fs/promises";
55
+ import { join as join2 } from "path";
10
56
  import { tmpdir } from "os";
11
57
  function parseNamespaceList(stdout) {
12
58
  try {
@@ -21,6 +67,29 @@ function parseNamespaceList(stdout) {
21
67
  }
22
68
  return [];
23
69
  }
70
+ function parseSecretsList(stdout) {
71
+ const trimmed = stdout.trim();
72
+ if (!trimmed) return [];
73
+ try {
74
+ const parsed = JSON.parse(trimmed);
75
+ if (!Array.isArray(parsed)) return [];
76
+ const secrets = [];
77
+ for (const item of parsed) {
78
+ const record = item;
79
+ const name = record.name;
80
+ if (typeof name !== "string" || name.length === 0) continue;
81
+ const type = typeof record.type === "string" ? record.type : void 0;
82
+ if (type) {
83
+ secrets.push({ name, type });
84
+ } else {
85
+ secrets.push({ name });
86
+ }
87
+ }
88
+ return secrets;
89
+ } catch {
90
+ return [];
91
+ }
92
+ }
24
93
  function findWorkerUrl(output) {
25
94
  const match = output.match(/https:\/\/[^\s]+\.workers\.dev/);
26
95
  return match?.[0] ?? null;
@@ -83,7 +152,7 @@ function parseCustomDomainsFromStatusOutput(statusJson) {
83
152
  }
84
153
  async function resolveCustomDomains(params) {
85
154
  const { cwd, configPath, workerName } = params;
86
- const status = await execa(
155
+ const status = await execa2(
87
156
  "npx",
88
157
  [
89
158
  "wrangler",
@@ -99,13 +168,13 @@ async function resolveCustomDomains(params) {
99
168
  ).catch(() => null);
100
169
  const fromStatus = status ? parseCustomDomainsFromStatusOutput(status.stdout) : [];
101
170
  if (fromStatus.length > 0) return fromStatus;
102
- const configText = await readFile(configPath, "utf-8").catch(() => "");
171
+ const configText = await readFile2(configPath, "utf-8").catch(() => "");
103
172
  return extractCustomDomainsFromRoutesConfig(configText);
104
173
  }
105
174
  var cloudflareProvider = {
106
175
  name: "cloudflare",
107
176
  async login() {
108
- await execa("npx", ["wrangler", "login"], { stdio: "inherit" });
177
+ await execa2("npx", ["wrangler", "login"], { stdio: "inherit" });
109
178
  },
110
179
  async whoami() {
111
180
  const identity = await getCloudflareIdentity();
@@ -116,19 +185,48 @@ var cloudflareProvider = {
116
185
  return { provider: "cloudflare", accountId, email };
117
186
  },
118
187
  async putSecret({ cwd, configPath, name, value }) {
119
- await execa(
188
+ await execa2(
120
189
  "npx",
121
190
  ["wrangler", "secret", "put", name, "--config", configPath],
122
191
  { cwd, input: `${value}
123
192
  ` }
124
193
  );
125
194
  },
195
+ async listSecrets({ cwd, configPath }) {
196
+ const jsonAttempt = await execa2(
197
+ "npx",
198
+ [
199
+ "wrangler",
200
+ "secret",
201
+ "list",
202
+ "--config",
203
+ configPath,
204
+ "--format",
205
+ "json"
206
+ ],
207
+ { cwd }
208
+ ).catch(() => null);
209
+ if (jsonAttempt) return parseSecretsList(jsonAttempt.stdout);
210
+ const fallback = await execa2(
211
+ "npx",
212
+ ["wrangler", "secret", "list", "--config", configPath],
213
+ { cwd }
214
+ );
215
+ return parseSecretsList(fallback.stdout);
216
+ },
217
+ async deleteSecret({ cwd, configPath, name }) {
218
+ await execa2(
219
+ "npx",
220
+ ["wrangler", "secret", "delete", name, "--config", configPath],
221
+ { cwd }
222
+ );
223
+ },
126
224
  async deployRuntime({ cwd, configPath, useSecretsFile }) {
127
225
  const args = useSecretsFile ? ["wrangler", "deploy", "--config", configPath, "--secrets-file", ".env"] : ["wrangler", "deploy", "--config", configPath];
128
- const deploy = await execa("npx", args, { cwd });
226
+ const deploy = await execa2("npx", args, { cwd });
129
227
  const rawOutput = [deploy.stdout, deploy.stderr].filter(Boolean).join("\n");
130
228
  const workerUrl = findWorkerUrl(rawOutput);
131
- const configText = await readFile(configPath, "utf-8").catch(() => null);
229
+ const configText = await readFile2(configPath, "utf-8").catch(() => null);
132
230
  const workerName = configText?.match(/"name"\s*:\s*"([^"]+)"/)?.[1];
133
231
  const customDomains = workerName ? await resolveCustomDomains({ cwd, configPath, workerName }).catch(() => []) : [];
134
232
  if (!workerUrl) {
@@ -144,7 +242,7 @@ var cloudflareProvider = {
144
242
  return { workerUrl, customDomains, rawOutput };
145
243
  },
146
244
  async putManifest({ cwd, configPath, key, jsonPath }) {
147
- await execa(
245
+ await execa2(
148
246
  "npx",
149
247
  [
150
248
  "wrangler",
@@ -164,7 +262,7 @@ var cloudflareProvider = {
164
262
  );
165
263
  },
166
264
  async putValue({ cwd, configPath, key, value }) {
167
- await execa(
265
+ await execa2(
168
266
  "npx",
169
267
  [
170
268
  "wrangler",
@@ -183,7 +281,7 @@ var cloudflareProvider = {
183
281
  );
184
282
  },
185
283
  async deleteValue({ cwd, configPath, key }) {
186
- await execa(
284
+ await execa2(
187
285
  "npx",
188
286
  [
189
287
  "wrangler",
@@ -201,7 +299,7 @@ var cloudflareProvider = {
201
299
  );
202
300
  },
203
301
  async getValue({ cwd, configPath, key }) {
204
- const result = await execa(
302
+ const result = await execa2(
205
303
  "npx",
206
304
  [
207
305
  "wrangler",
@@ -221,13 +319,13 @@ var cloudflareProvider = {
221
319
  return output ? output : null;
222
320
  },
223
321
  async listNamespaces({ cwd, configPath }) {
224
- const json = await execa(
322
+ const json = await execa2(
225
323
  "npx",
226
324
  ["wrangler", "kv", "namespace", "list", "--config", configPath, "--json"],
227
325
  { cwd }
228
326
  ).catch(() => null);
229
327
  if (json) return parseNamespaceList(json.stdout);
230
- const plain = await execa(
328
+ const plain = await execa2(
231
329
  "npx",
232
330
  ["wrangler", "kv", "namespace", "list", "--config", configPath],
233
331
  { cwd }
@@ -242,6 +340,8 @@ function resolveProvider() {
242
340
  }
243
341
 
244
342
  export {
343
+ saveAuthConfig,
344
+ requireAuth,
245
345
  resolveProvider
246
346
  };
247
- //# sourceMappingURL=chunk-TNKYKA7N.js.map
347
+ //# sourceMappingURL=chunk-GNQI376N.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/utils/auth.ts","../src/utils/providers/cloudflare.ts","../src/utils/providers/index.ts"],"sourcesContent":["import { readFile, writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { execa } from \"execa\";\nimport { ensureGlobalConfigDir } from \"@/utils/config\";\n\nconst AUTH_FILE = async () => join(await ensureGlobalConfigDir(), \"auth.json\");\n\nexport interface AuthConfig {\n provider: \"cloudflare\";\n accountId: string;\n email: string;\n expiresAt: string;\n}\n\ninterface CloudflareIdentity {\n loggedIn?: boolean;\n email?: string;\n accounts?: Array<{ id?: string; account_tag?: string; name?: string }>;\n}\n\nexport async function getCloudflareIdentity(): Promise<CloudflareIdentity | null> {\n try {\n const run = async (args: string[]) =>\n execa(\"npx\", args, {\n env: { FORCE_COLOR: \"0\", CLOUDFLARE_OUTPUT_FORMAT: \"json\" },\n });\n\n const firstAttempt = await run([\n \"wrangler\",\n \"whoami\",\n \"--output-format\",\n \"json\",\n ]).catch(() => null);\n\n if (firstAttempt) {\n return JSON.parse(firstAttempt.stdout) as CloudflareIdentity;\n }\n\n const fallback = await run([\"wrangler\", \"whoami\", \"--json\"]);\n return JSON.parse(fallback.stdout) as CloudflareIdentity;\n } catch {\n return null;\n }\n}\n\nexport async function saveAuthConfig(config: AuthConfig): Promise<void> {\n const authPath = await AUTH_FILE();\n await writeFile(authPath, JSON.stringify(config, null, 2), \"utf-8\");\n}\n\nexport async function getAuthConfig(): Promise<AuthConfig | null> {\n try {\n const authPath = await AUTH_FILE();\n const content = await readFile(authPath, \"utf-8\");\n return JSON.parse(content) as AuthConfig;\n } catch {\n return null;\n }\n}\n\nexport async function isLoggedIn(): Promise<boolean> {\n const auth = await getAuthConfig();\n if (!auth) return false;\n return new Date(auth.expiresAt).getTime() > Date.now();\n}\n\nexport async function requireAuth(): Promise<AuthConfig> {\n const auth = await getAuthConfig();\n if (!auth || new Date(auth.expiresAt).getTime() <= Date.now()) {\n throw new Error(\"Not authenticated. Run `kalp login` first.\");\n }\n return auth;\n}\n\n/**\n * Backward-compatible helper for legacy commands.\n * Returns a pseudo-token when Cloudflare auth is present.\n */\nexport async function getAuthToken(): Promise<string | null> {\n const auth = await getAuthConfig();\n if (!auth || new Date(auth.expiresAt).getTime() <= Date.now()) {\n return null;\n }\n return `${auth.provider}:${auth.accountId}`;\n}\n","import { execa } from \"execa\";\nimport { mkdtemp, readFile, rm, writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { tmpdir } from \"node:os\";\nimport type { RuntimeProvider, RemoteSecret } from \"@/utils/providers/types\";\nimport { getCloudflareIdentity } from \"@/utils/auth\";\n\nfunction parseNamespaceList(stdout: string): Array<{ id: string; title: string }> {\n try {\n const parsed = JSON.parse(stdout);\n if (Array.isArray(parsed)) {\n return parsed\n .map((item) => ({\n id: String((item as { id?: string }).id ?? \"\"),\n title: String((item as { title?: string }).title ?? \"\"),\n }))\n .filter((item) => !!item.id && !!item.title);\n }\n } catch {}\n return [];\n}\n\nfunction parseSecretsList(stdout: string): RemoteSecret[] {\n const trimmed = stdout.trim();\n if (!trimmed) return [];\n\n try {\n const parsed = JSON.parse(trimmed) as unknown;\n if (!Array.isArray(parsed)) return [];\n const secrets: RemoteSecret[] = [];\n for (const item of parsed) {\n const record = item as Record<string, unknown>;\n const name = record.name;\n if (typeof name !== \"string\" || name.length === 0) continue;\n const type = typeof record.type === \"string\" ? record.type : undefined;\n if (type) {\n secrets.push({ name, type });\n } else {\n secrets.push({ name });\n }\n }\n return secrets;\n } catch {\n return [];\n }\n}\n\nfunction findWorkerUrl(output: string): string | null {\n const match = output.match(/https:\\/\\/[^\\s]+\\.workers\\.dev/);\n return match?.[0] ?? null;\n}\n\nfunction normalizeDomainCandidate(value: string): string | null {\n const trimmed = value.trim();\n if (!trimmed || trimmed.includes(\"@\")) return null;\n\n const fromUrl = trimmed.match(/^https?:\\/\\/([^/\\s]+)/i)?.[1];\n const candidate = (fromUrl ?? trimmed).replace(/^https?:\\/\\//i, \"\").split(\"/\")[0] ?? \"\";\n const host = candidate.replace(/^\\*\\./, \"\").toLowerCase();\n\n if (!host) return null;\n if (host.includes(\"*\")) return null;\n if (host.endsWith(\".workers.dev\")) return null;\n if (host.endsWith(\".pages.dev\")) return null;\n if (!/^[a-z0-9.-]+\\.[a-z]{2,}$/i.test(host)) return null;\n return host;\n}\n\nfunction extractCustomDomainsFromRoutesConfig(configText: string): string[] {\n const routesMatch = configText.match(/\"routes\"\\s*:\\s*(\\[[\\s\\S]*?\\])/);\n if (!routesMatch) return [];\n const serializedRoutes = routesMatch[1];\n if (!serializedRoutes) return [];\n\n try {\n const routes = JSON.parse(serializedRoutes) as Array<{\n pattern?: string;\n custom_domain?: boolean;\n }>;\n if (!Array.isArray(routes)) return [];\n const domains = routes\n .filter((route) => route?.custom_domain === true)\n .map((route) => normalizeDomainCandidate(String(route.pattern ?? \"\")))\n .filter((domain): domain is string => !!domain);\n return [...new Set(domains)];\n } catch {\n return [];\n }\n}\n\nfunction collectDomainsFromStatusNode(\n node: unknown,\n keyHint: string | null,\n out: Set<string>,\n): void {\n if (typeof node === \"string\") {\n if (keyHint && /(domain|route|pattern)/i.test(keyHint)) {\n const normalized = normalizeDomainCandidate(node);\n if (normalized) out.add(normalized);\n }\n return;\n }\n\n if (Array.isArray(node)) {\n for (const item of node) {\n collectDomainsFromStatusNode(item, keyHint, out);\n }\n return;\n }\n\n if (!node || typeof node !== \"object\") return;\n for (const [key, value] of Object.entries(node as Record<string, unknown>)) {\n collectDomainsFromStatusNode(value, key, out);\n }\n}\n\nfunction parseCustomDomainsFromStatusOutput(statusJson: string): string[] {\n try {\n const parsed = JSON.parse(statusJson) as unknown;\n const domains = new Set<string>();\n collectDomainsFromStatusNode(parsed, null, domains);\n return [...domains].sort((a, b) => a.localeCompare(b));\n } catch {\n return [];\n }\n}\n\nasync function resolveCustomDomains(params: {\n cwd: string;\n configPath: string;\n workerName: string;\n}): Promise<string[]> {\n const { cwd, configPath, workerName } = params;\n\n const status = await execa(\n \"npx\",\n [\n \"wrangler\",\n \"deployments\",\n \"status\",\n \"--name\",\n workerName,\n \"--json\",\n \"--config\",\n configPath,\n ],\n { cwd },\n ).catch(() => null);\n\n const fromStatus = status ? parseCustomDomainsFromStatusOutput(status.stdout) : [];\n if (fromStatus.length > 0) return fromStatus;\n\n const configText = await readFile(configPath, \"utf-8\").catch(() => \"\");\n return extractCustomDomainsFromRoutesConfig(configText);\n}\n\nexport const cloudflareProvider: RuntimeProvider = {\n name: \"cloudflare\",\n async login() {\n await execa(\"npx\", [\"wrangler\", \"login\"], { stdio: \"inherit\" });\n },\n async whoami() {\n const identity = await getCloudflareIdentity();\n const account = identity?.accounts?.[0];\n const accountId = account?.id ?? account?.account_tag;\n const email = identity?.email;\n if (!accountId || !email) return null;\n return { provider: \"cloudflare\", accountId, email };\n },\n async putSecret({ cwd, configPath, name, value }) {\n await execa(\n \"npx\",\n [\"wrangler\", \"secret\", \"put\", name, \"--config\", configPath],\n { cwd, input: `${value}\\n` },\n );\n },\n async listSecrets({ cwd, configPath }) {\n const jsonAttempt = await execa(\n \"npx\",\n [\n \"wrangler\",\n \"secret\",\n \"list\",\n \"--config\",\n configPath,\n \"--format\",\n \"json\",\n ],\n { cwd },\n ).catch(() => null);\n if (jsonAttempt) return parseSecretsList(jsonAttempt.stdout);\n\n const fallback = await execa(\n \"npx\",\n [\"wrangler\", \"secret\", \"list\", \"--config\", configPath],\n { cwd },\n );\n return parseSecretsList(fallback.stdout);\n },\n async deleteSecret({ cwd, configPath, name }) {\n await execa(\n \"npx\",\n [\"wrangler\", \"secret\", \"delete\", name, \"--config\", configPath],\n { cwd },\n );\n },\n async deployRuntime({ cwd, configPath, useSecretsFile }) {\n const args = useSecretsFile\n ? [\"wrangler\", \"deploy\", \"--config\", configPath, \"--secrets-file\", \".env\"]\n : [\"wrangler\", \"deploy\", \"--config\", configPath];\n const deploy = await execa(\"npx\", args, { cwd });\n const rawOutput = [deploy.stdout, deploy.stderr].filter(Boolean).join(\"\\n\");\n const workerUrl = findWorkerUrl(rawOutput);\n const configText = await readFile(configPath, \"utf-8\").catch(() => null);\n const workerName = configText?.match(/\"name\"\\s*:\\s*\"([^\"]+)\"/)?.[1];\n const customDomains = workerName\n ? await resolveCustomDomains({ cwd, configPath, workerName }).catch(() => [])\n : [];\n\n if (!workerUrl) {\n if (!workerName) {\n throw new Error(\"Could not resolve runtime URL from deployment output.\");\n }\n return {\n workerUrl: `https://${workerName}.workers.dev`,\n customDomains,\n rawOutput,\n };\n }\n return { workerUrl, customDomains, rawOutput };\n },\n async putManifest({ cwd, configPath, key, jsonPath }) {\n await execa(\n \"npx\",\n [\n \"wrangler\",\n \"kv\",\n \"key\",\n \"put\",\n \"--binding\",\n \"KALP_MANIFESTS\",\n key,\n \"--path\",\n jsonPath,\n \"--remote\",\n \"--config\",\n configPath,\n ],\n { cwd },\n );\n },\n async putValue({ cwd, configPath, key, value }) {\n await execa(\n \"npx\",\n [\n \"wrangler\",\n \"kv\",\n \"key\",\n \"put\",\n \"--binding\",\n \"KALP_MANIFESTS\",\n key,\n value,\n \"--remote\",\n \"--config\",\n configPath,\n ],\n { cwd },\n );\n },\n async deleteValue({ cwd, configPath, key }) {\n await execa(\n \"npx\",\n [\n \"wrangler\",\n \"kv\",\n \"key\",\n \"delete\",\n \"--binding\",\n \"KALP_MANIFESTS\",\n key,\n \"--remote\",\n \"--config\",\n configPath,\n ],\n { cwd },\n );\n },\n async getValue({ cwd, configPath, key }) {\n const result = await execa(\n \"npx\",\n [\n \"wrangler\",\n \"kv\",\n \"key\",\n \"get\",\n \"--binding\",\n \"KALP_MANIFESTS\",\n key,\n \"--remote\",\n \"--config\",\n configPath,\n ],\n { cwd },\n ).catch(() => null);\n const output = result?.stdout?.trim();\n return output ? output : null;\n },\n async listNamespaces({ cwd, configPath }) {\n const json = await execa(\n \"npx\",\n [\"wrangler\", \"kv\", \"namespace\", \"list\", \"--config\", configPath, \"--json\"],\n { cwd },\n ).catch(() => null);\n if (json) return parseNamespaceList(json.stdout);\n const plain = await execa(\n \"npx\",\n [\"wrangler\", \"kv\", \"namespace\", \"list\", \"--config\", configPath],\n { cwd },\n );\n return parseNamespaceList(plain.stdout);\n },\n};\n\nexport async function withTempJsonFile<T>(\n prefix: string,\n payload: unknown,\n fn: (path: string) => Promise<T>,\n): Promise<T> {\n const dir = await mkdtemp(join(tmpdir(), prefix));\n const filePath = join(dir, \"payload.json\");\n await writeFile(filePath, JSON.stringify(payload), \"utf-8\");\n try {\n return await fn(filePath);\n } finally {\n await rm(dir, { recursive: true, force: true });\n }\n}\n","import { cloudflareProvider } from \"@/utils/providers/cloudflare\";\nimport type { RuntimeProvider } from \"@/utils/providers/types\";\n\nexport function resolveProvider(): RuntimeProvider {\n return cloudflareProvider;\n}\n\nexport type {\n RuntimeProvider,\n ProviderIdentity,\n DeployResult,\n RemoteSecret,\n} from \"@/utils/providers/types\";\n"],"mappings":"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","names":["execa","readFile","writeFile","join","execa","readFile"]}
@@ -0,0 +1,102 @@
1
+ #!/usr/bin/env node
2
+
3
+ // src/utils/secret.ts
4
+ import { randomBytes } from "crypto";
5
+ import { readFile, writeFile } from "fs/promises";
6
+ import { join } from "path";
7
+ var SECRET_KEY = "KALP_SECRET_KEY";
8
+ var STUDIO_PASSWORD = "KALP_STUDIO_PASSWORD";
9
+ var STUDIO_ADMIN_USER = "KALP_STUDIO_ADMIN_USER";
10
+ var SERVICE_KEY = "KALP_SERVICE_KEY";
11
+ function escapeRegExp(value) {
12
+ return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
13
+ }
14
+ function parseEnv(content) {
15
+ const result = {};
16
+ for (const line of content.split(/\r?\n/g)) {
17
+ const trimmed = line.trim();
18
+ if (!trimmed || trimmed.startsWith("#")) continue;
19
+ const eqIndex = trimmed.indexOf("=");
20
+ if (eqIndex <= 0) continue;
21
+ const key = trimmed.slice(0, eqIndex).trim();
22
+ const value = trimmed.slice(eqIndex + 1).trim();
23
+ result[key] = value;
24
+ }
25
+ return result;
26
+ }
27
+ function applyEnvUpdates(content, updates) {
28
+ let next = content;
29
+ for (const [key, value] of Object.entries(updates)) {
30
+ const line = `${key}=${value}`;
31
+ const pattern = new RegExp(`^${escapeRegExp(key)}=.*$`, "m");
32
+ if (pattern.test(next)) {
33
+ next = next.replace(pattern, line);
34
+ continue;
35
+ }
36
+ const trimmed = next.trimEnd();
37
+ next = trimmed.length > 0 ? `${trimmed}
38
+ ${line}
39
+ ` : `${line}
40
+ `;
41
+ }
42
+ return next.trimEnd() + "\n";
43
+ }
44
+ async function readEnvFile(cwd) {
45
+ const envPath = join(cwd, ".env");
46
+ try {
47
+ return await readFile(envPath, "utf-8");
48
+ } catch {
49
+ return "";
50
+ }
51
+ }
52
+ async function readDevVarsFile(cwd) {
53
+ const devVarsPath = join(cwd, ".dev.vars");
54
+ try {
55
+ return await readFile(devVarsPath, "utf-8");
56
+ } catch {
57
+ return "";
58
+ }
59
+ }
60
+ function generateStudioPassword() {
61
+ return randomBytes(24).toString("base64url");
62
+ }
63
+ function generateServiceKey() {
64
+ return `kalp_sk_live_${randomBytes(32).toString("base64url")}`;
65
+ }
66
+ async function ensureStudioSecrets(cwd) {
67
+ const envPath = join(cwd, ".env");
68
+ const devVarsPath = join(cwd, ".dev.vars");
69
+ const content = await readEnvFile(cwd);
70
+ const parsed = parseEnv(content);
71
+ const key = parsed[SECRET_KEY]?.trim() || randomBytes(32).toString("hex");
72
+ const studioPassword = parsed[STUDIO_PASSWORD]?.trim() || generateStudioPassword();
73
+ const studioAdminUser = parsed[STUDIO_ADMIN_USER]?.trim() || "admin";
74
+ const serviceKey = parsed[SERVICE_KEY]?.trim() || generateServiceKey();
75
+ const isNew = !parsed[SECRET_KEY]?.trim() || !parsed[STUDIO_PASSWORD]?.trim() || !parsed[STUDIO_ADMIN_USER]?.trim() || !parsed[SERVICE_KEY]?.trim();
76
+ const next = applyEnvUpdates(content, {
77
+ [SECRET_KEY]: key,
78
+ [STUDIO_PASSWORD]: studioPassword,
79
+ [STUDIO_ADMIN_USER]: studioAdminUser,
80
+ [SERVICE_KEY]: serviceKey
81
+ });
82
+ await writeFile(envPath, next, "utf-8");
83
+ const devVarsContent = await readDevVarsFile(cwd);
84
+ const nextDevVars = applyEnvUpdates(devVarsContent, {
85
+ [SECRET_KEY]: key,
86
+ [STUDIO_PASSWORD]: studioPassword,
87
+ [STUDIO_ADMIN_USER]: studioAdminUser,
88
+ [SERVICE_KEY]: serviceKey
89
+ });
90
+ await writeFile(devVarsPath, nextDevVars, "utf-8");
91
+ return { key, studioPassword, studioAdminUser, serviceKey, isNew };
92
+ }
93
+ async function ensureSecretKey(cwd) {
94
+ const secrets = await ensureStudioSecrets(cwd);
95
+ return { key: secrets.key, isNew: secrets.isNew };
96
+ }
97
+
98
+ export {
99
+ ensureStudioSecrets,
100
+ ensureSecretKey
101
+ };
102
+ //# sourceMappingURL=chunk-NV2IZ4XM.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/utils/secret.ts"],"sourcesContent":["import { randomBytes } from \"node:crypto\";\nimport { readFile, writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nexport const SECRET_KEY = \"KALP_SECRET_KEY\";\nexport const STUDIO_PASSWORD = \"KALP_STUDIO_PASSWORD\";\nexport const STUDIO_ADMIN_USER = \"KALP_STUDIO_ADMIN_USER\";\nexport const SERVICE_KEY = \"KALP_SERVICE_KEY\";\n\nfunction escapeRegExp(value: string): string {\n return value.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n\nfunction parseEnv(content: string): Record<string, string> {\n const result: Record<string, string> = {};\n for (const line of content.split(/\\r?\\n/g)) {\n const trimmed = line.trim();\n if (!trimmed || trimmed.startsWith(\"#\")) continue;\n const eqIndex = trimmed.indexOf(\"=\");\n if (eqIndex <= 0) continue;\n const key = trimmed.slice(0, eqIndex).trim();\n const value = trimmed.slice(eqIndex + 1).trim();\n result[key] = value;\n }\n return result;\n}\n\nfunction applyEnvUpdates(content: string, updates: Record<string, string>): string {\n let next = content;\n for (const [key, value] of Object.entries(updates)) {\n const line = `${key}=${value}`;\n const pattern = new RegExp(`^${escapeRegExp(key)}=.*$`, \"m\");\n if (pattern.test(next)) {\n next = next.replace(pattern, line);\n continue;\n }\n const trimmed = next.trimEnd();\n next = trimmed.length > 0 ? `${trimmed}\\n${line}\\n` : `${line}\\n`;\n }\n\n return next.trimEnd() + \"\\n\";\n}\n\nasync function readEnvFile(cwd: string): Promise<string> {\n const envPath = join(cwd, \".env\");\n try {\n return await readFile(envPath, \"utf-8\");\n } catch {\n return \"\";\n }\n}\n\nasync function readDevVarsFile(cwd: string): Promise<string> {\n const devVarsPath = join(cwd, \".dev.vars\");\n try {\n return await readFile(devVarsPath, \"utf-8\");\n } catch {\n return \"\";\n }\n}\n\nfunction generateStudioPassword(): string {\n return randomBytes(24).toString(\"base64url\");\n}\n\nfunction generateServiceKey(): string {\n return `kalp_sk_live_${randomBytes(32).toString(\"base64url\")}`;\n}\n\nexport interface StudioSecrets {\n key: string;\n studioPassword: string;\n studioAdminUser: string;\n serviceKey: string;\n isNew: boolean;\n}\n\nexport async function ensureStudioSecrets(cwd: string): Promise<StudioSecrets> {\n const envPath = join(cwd, \".env\");\n const devVarsPath = join(cwd, \".dev.vars\");\n const content = await readEnvFile(cwd);\n const parsed = parseEnv(content);\n\n const key = parsed[SECRET_KEY]?.trim() || randomBytes(32).toString(\"hex\");\n const studioPassword = parsed[STUDIO_PASSWORD]?.trim() || generateStudioPassword();\n const studioAdminUser = parsed[STUDIO_ADMIN_USER]?.trim() || \"admin\";\n const serviceKey = parsed[SERVICE_KEY]?.trim() || generateServiceKey();\n\n const isNew =\n !parsed[SECRET_KEY]?.trim() ||\n !parsed[STUDIO_PASSWORD]?.trim() ||\n !parsed[STUDIO_ADMIN_USER]?.trim() ||\n !parsed[SERVICE_KEY]?.trim();\n\n const next = applyEnvUpdates(content, {\n [SECRET_KEY]: key,\n [STUDIO_PASSWORD]: studioPassword,\n [STUDIO_ADMIN_USER]: studioAdminUser,\n [SERVICE_KEY]: serviceKey,\n });\n await writeFile(envPath, next, \"utf-8\");\n\n const devVarsContent = await readDevVarsFile(cwd);\n const nextDevVars = applyEnvUpdates(devVarsContent, {\n [SECRET_KEY]: key,\n [STUDIO_PASSWORD]: studioPassword,\n [STUDIO_ADMIN_USER]: studioAdminUser,\n [SERVICE_KEY]: serviceKey,\n });\n await writeFile(devVarsPath, nextDevVars, \"utf-8\");\n\n return { key, studioPassword, studioAdminUser, serviceKey, isNew };\n}\n\nexport async function ensureSecretKey(\n cwd: string,\n): Promise<{ key: string; isNew: boolean }> {\n const secrets = await ensureStudioSecrets(cwd);\n return { key: secrets.key, isNew: secrets.isNew };\n}\n\nexport async function readSecretKey(cwd: string): Promise<string | null> {\n try {\n const envContent = await readEnvFile(cwd);\n const parsed = parseEnv(envContent);\n return parsed[SECRET_KEY] ?? null;\n } catch {\n return null;\n }\n}\n\nexport async function readStudioSecrets(cwd: string): Promise<{\n key: string;\n studioPassword: string;\n studioAdminUser: string;\n serviceKey: string;\n} | null> {\n try {\n const envContent = await readEnvFile(cwd);\n const parsed = parseEnv(envContent);\n const key = parsed[SECRET_KEY]?.trim();\n const studioPassword = parsed[STUDIO_PASSWORD]?.trim();\n const studioAdminUser = parsed[STUDIO_ADMIN_USER]?.trim() || \"admin\";\n const serviceKey = parsed[SERVICE_KEY]?.trim();\n if (!key || !studioPassword || !serviceKey) return null;\n return { key, studioPassword, studioAdminUser, serviceKey };\n } catch {\n return null;\n }\n}\n"],"mappings":"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","names":[]}
@@ -1,9 +1,12 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
+ ensureStudioSecrets
4
+ } from "./chunk-NV2IZ4XM.js";
5
+ import {
6
+ requireAuth,
3
7
  resolveProvider
4
- } from "./chunk-TNKYKA7N.js";
8
+ } from "./chunk-GNQI376N.js";
5
9
  import {
6
- ensureStudioSecrets,
7
10
  getRequiredSecretForProvider,
8
11
  loadProjectConfig,
9
12
  materializeRuntime,
@@ -13,10 +16,7 @@ import {
13
16
  resolveProviderFromConfig,
14
17
  resolveRuntimeIdentityConfig,
15
18
  writeProjectState
16
- } from "./chunk-GW6MLHK7.js";
17
- import {
18
- requireAuth
19
- } from "./chunk-5RODADXW.js";
19
+ } from "./chunk-DHCCSWJN.js";
20
20
 
21
21
  // src/utils/deploy.ts
22
22
  import { readFile, writeFile } from "fs/promises";
@@ -158,7 +158,42 @@ async function runInitialDeploy(cwd) {
158
158
  };
159
159
  }
160
160
 
161
+ // src/utils/deploy-target.ts
162
+ import * as p from "@clack/prompts";
163
+ import pc from "picocolors";
164
+ async function promptDeployTarget(message) {
165
+ const selected = await p.select({
166
+ message,
167
+ options: [
168
+ {
169
+ value: "cloudflare",
170
+ label: "Cloudflare",
171
+ hint: "Available now"
172
+ },
173
+ {
174
+ value: "kalp-cloud",
175
+ label: "Kalp Cloud",
176
+ hint: "Coming soon"
177
+ }
178
+ ]
179
+ });
180
+ if (p.isCancel(selected)) return null;
181
+ return selected;
182
+ }
183
+ function showKalpCloudWaitlist() {
184
+ p.note(
185
+ [
186
+ `${pc.bold("Kalp Cloud is coming soon \u{1F680}")}`,
187
+ pc.dim("Join the waitlist for early access:"),
188
+ pc.cyan("https://usekalp.com/waitlist")
189
+ ].join("\n"),
190
+ "Kalp Cloud"
191
+ );
192
+ }
193
+
161
194
  export {
162
- runInitialDeploy
195
+ runInitialDeploy,
196
+ promptDeployTarget,
197
+ showKalpCloudWaitlist
163
198
  };
164
- //# sourceMappingURL=chunk-TY5UW4IZ.js.map
199
+ //# sourceMappingURL=chunk-X56YSZGT.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/utils/deploy.ts","../src/utils/deploy-target.ts"],"sourcesContent":["import { readFile, writeFile } from \"node:fs/promises\";\nimport { createHash } from \"node:crypto\";\nimport { requireAuth } from \"@/utils/auth\";\nimport { ensureStudioSecrets } from \"@/utils/secret\";\nimport { readProjectState, writeProjectState } from \"@/utils/project-state\";\nimport { materializeRuntime } from \"@/utils/runtime\";\nimport {\n getRequiredSecretForProvider,\n readDotEnv,\n resolveProviderFromConfig,\n} from \"@/utils/ai\";\nimport {\n loadProjectConfig,\n resolveIdentityAuthRequirements,\n resolveRuntimeIdentityConfig,\n} from \"@/utils/project-config\";\nimport { resolveProvider } from \"@/utils/providers\";\n\ninterface RuntimeWranglerConfig {\n name?: string;\n kv_namespaces?: Array<{ binding: string; id?: string }>;\n}\n\ninterface KvNamespaceInfo {\n id: string;\n title: string;\n}\n\nasync function readWranglerConfig(\n configPath: string,\n): Promise<RuntimeWranglerConfig> {\n const text = await readFile(configPath, \"utf-8\");\n return JSON.parse(text) as RuntimeWranglerConfig;\n}\n\nasync function writeWranglerConfig(\n configPath: string,\n config: RuntimeWranglerConfig,\n): Promise<void> {\n await writeFile(configPath, `${JSON.stringify(config, null, 2)}\\n`, \"utf-8\");\n}\n\nfunction deriveKvNamespaceTitle(workerName: string, binding: string): string {\n return `${workerName}-${binding.toLowerCase().replace(/_/g, \"-\")}`;\n}\n\nasync function listKvNamespaces(\n cwd: string,\n configPath: string,\n): Promise<KvNamespaceInfo[]> {\n const provider = resolveProvider();\n const namespaces = await provider.listNamespaces({ cwd, configPath });\n return namespaces.map((item) => ({\n id: item.id,\n title: item.title,\n }));\n}\n\nasync function ensureKvNamespaceBindingId(\n cwd: string,\n configPath: string,\n): Promise<string | null> {\n const config = await readWranglerConfig(configPath);\n const binding = config.kv_namespaces?.find(\n (item) => item.binding === \"KALP_MANIFESTS\",\n );\n\n if (!binding || !config.name) return null;\n if (binding.id) return binding.id;\n\n const expectedTitle = deriveKvNamespaceTitle(config.name, binding.binding);\n const namespaces = await listKvNamespaces(cwd, configPath);\n const existing = namespaces.find((item) => item.title === expectedTitle);\n if (!existing) return null;\n\n binding.id = existing.id;\n await writeWranglerConfig(configPath, config);\n return existing.id;\n}\n\nfunction isNamespaceAlreadyExistsError(output: string): boolean {\n return output.includes(\"[code: 10014]\") && output.includes(\"already exists\");\n}\n\nexport async function runInitialDeploy(cwd: string): Promise<{\n workerUrl: string;\n customDomains: string[];\n accountId: string;\n studioAdminUser: string;\n studioPassword: string;\n serviceKey: string;\n credentialsChanged: boolean;\n serviceKeyChanged: boolean;\n}> {\n const auth = await requireAuth();\n const loadedConfig = await loadProjectConfig(cwd);\n const identityConfig = resolveRuntimeIdentityConfig(loadedConfig.raw);\n const identitySecretRequirements = resolveIdentityAuthRequirements(identityConfig);\n const aiProvider = await resolveProviderFromConfig(cwd);\n const requiredProviderSecret = getRequiredSecretForProvider(aiProvider);\n const secrets = await ensureStudioSecrets(cwd);\n const envMap = await readDotEnv(cwd);\n const providerSecretValue = envMap[requiredProviderSecret]?.trim();\n if (!providerSecretValue) {\n throw new Error(\n `Missing required secret ${requiredProviderSecret} for provider \"${aiProvider}\". Add it to .env before deploy.`,\n );\n }\n\n const resolvedIdentitySecrets = identitySecretRequirements.map((requirement) => {\n const value = envMap[requirement.envKey]?.trim();\n if (!value) {\n throw new Error(\n `Missing required secret ${requirement.envKey} for ${requirement.reason}. Add it to .env before deploy.`,\n );\n }\n return { name: requirement.envKey, value };\n });\n\n const runtimeProvider = resolveProvider();\n const runtime = await materializeRuntime(cwd);\n let secretSyncFailed = false;\n const secretEntries = [\n [\"KALP_SECRET_KEY\", secrets.key],\n [\"KALP_STUDIO_PASSWORD\", secrets.studioPassword],\n [\"KALP_STUDIO_ADMIN_USER\", secrets.studioAdminUser],\n [\"KALP_SERVICE_KEY\", secrets.serviceKey],\n [requiredProviderSecret, providerSecretValue],\n ...resolvedIdentitySecrets.map((item) => [item.name, item.value] as const),\n ];\n const dedupedSecrets = new Map<string, string>();\n for (const [name, value] of secretEntries) {\n dedupedSecrets.set(name, value);\n }\n\n for (const [name, value] of dedupedSecrets.entries()) {\n try {\n await runtimeProvider.putSecret({\n cwd,\n configPath: runtime.wranglerConfigPath,\n name,\n value,\n });\n } catch {\n secretSyncFailed = true;\n break;\n }\n }\n\n await ensureKvNamespaceBindingId(cwd, runtime.wranglerConfigPath).catch(\n () => null,\n );\n\n let deploy = await runtimeProvider\n .deployRuntime({\n cwd,\n configPath: runtime.wranglerConfigPath,\n useSecretsFile: secretSyncFailed,\n })\n .catch((error) => error);\n if (deploy instanceof Error) {\n const combined = deploy.message;\n if (isNamespaceAlreadyExistsError(combined)) {\n await ensureKvNamespaceBindingId(cwd, runtime.wranglerConfigPath);\n deploy = await runtimeProvider.deployRuntime({\n cwd,\n configPath: runtime.wranglerConfigPath,\n useSecretsFile: secretSyncFailed,\n });\n } else {\n throw deploy;\n }\n }\n\n const workerUrl = deploy.workerUrl;\n const customDomains = deploy.customDomains ?? [];\n\n const existingState = await readProjectState(cwd);\n\n const credentialsFingerprint = createHash(\"sha256\")\n .update(`${secrets.studioAdminUser}:${secrets.studioPassword}`)\n .digest(\"hex\");\n const credentialsChanged =\n existingState?.studioCredentialsFingerprint !== credentialsFingerprint;\n const serviceKeyFingerprint = createHash(\"sha256\")\n .update(secrets.serviceKey)\n .digest(\"hex\");\n const serviceKeyChanged =\n existingState?.serviceKeyFingerprint !== serviceKeyFingerprint;\n\n await writeProjectState(cwd, {\n workerUrl,\n deployedAt: new Date().toISOString(),\n accountId: auth.accountId,\n studioCredentialsFingerprint: credentialsFingerprint,\n serviceKeyFingerprint,\n agents: existingState?.agents ?? {},\n });\n\n return {\n workerUrl,\n customDomains,\n accountId: auth.accountId,\n studioAdminUser: secrets.studioAdminUser,\n studioPassword: secrets.studioPassword,\n serviceKey: secrets.serviceKey,\n credentialsChanged,\n serviceKeyChanged,\n };\n}\n","import * as p from \"@clack/prompts\";\nimport pc from \"picocolors\";\n\nexport type DeployTarget = \"cloudflare\" | \"kalp-cloud\";\n\nexport async function promptDeployTarget(message: string): Promise<DeployTarget | null> {\n const selected = await p.select({\n message,\n options: [\n {\n value: \"cloudflare\",\n label: \"Cloudflare\",\n hint: \"Available now\",\n },\n {\n value: \"kalp-cloud\",\n label: \"Kalp Cloud\",\n hint: \"Coming soon\",\n },\n ],\n });\n\n if (p.isCancel(selected)) return null;\n return selected as DeployTarget;\n}\n\nexport function showKalpCloudWaitlist(): void {\n p.note(\n [\n `${pc.bold(\"Kalp Cloud is coming soon 🚀\")}`,\n pc.dim(\"Join the waitlist for early access:\"),\n pc.cyan(\"https://usekalp.com/waitlist\"),\n ].join(\"\\n\"),\n \"Kalp Cloud\",\n );\n}\n"],"mappings":"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","names":[]}