{"version":3,"file":"version-DtFg32hj.mjs","names":[],"sources":["../src/resolve-platform-url.ts","../src/config.ts","../src/project/resolve-cli-root.ts","../src/init/package-manager.ts","../src/version.ts"],"sourcesContent":["import { LOCAL_PLATFORM_ORIGIN, originFromPublicUrl } from \"@keystrokehq/shared\";\n\nexport const DEFAULT_WEB_URL = \"https://keystroke.ai\";\nexport const DEFAULT_PLATFORM_URL = \"https://api.keystroke.ai\";\nexport const LOCAL_WEB_URL = \"http://localhost:3000\";\n\nexport type ResolvePlatformUrlOptions = {\n  platformUrl?: string;\n  /** Used when webUrl does not match a known deployment. */\n  fallback?: string;\n};\n\nfunction webOriginFromUrl(webUrl: string): string {\n  return originFromPublicUrl(webUrl, webUrl.replace(/\\/+$/, \"\"));\n}\n\n/** Known web origins with a fixed platform API — undefined for custom/staging URLs. */\nexport function knownPlatformUrlForWebUrl(webUrl: string): string | undefined {\n  const webOrigin = webOriginFromUrl(webUrl);\n\n  if (webOrigin === LOCAL_WEB_URL || webOrigin === \"http://127.0.0.1:3000\") {\n    return LOCAL_PLATFORM_ORIGIN;\n  }\n\n  if (webOrigin === DEFAULT_WEB_URL) {\n    return DEFAULT_PLATFORM_URL;\n  }\n\n  return undefined;\n}\n\nexport function resolvePlatformUrlForWebUrl(\n  webUrl: string,\n  options: ResolvePlatformUrlOptions = {},\n): string {\n  const explicit = options.platformUrl?.trim();\n  if (explicit) {\n    return explicit.replace(/\\/+$/, \"\");\n  }\n\n  const known = knownPlatformUrlForWebUrl(webUrl);\n  if (known) {\n    return known;\n  }\n\n  const fallback = options.fallback?.trim() || DEFAULT_PLATFORM_URL;\n  return fallback.replace(/\\/+$/, \"\");\n}\n","import Conf from \"conf\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\n\nimport {\n  DEFAULT_PLATFORM_URL,\n  DEFAULT_WEB_URL,\n  knownPlatformUrlForWebUrl,\n  resolvePlatformUrlForWebUrl,\n} from \"./resolve-platform-url\";\n\nexport type ApiTargetMode = \"local\" | \"platform\";\n\nexport type CliConfig = {\n  webUrl: string;\n  platformUrl: string;\n  activeOrganizationId?: string;\n  apiTarget?: ApiTargetMode;\n};\n\nexport function getCliConfigDir(cwd = join(homedir(), \".keystroke\")): string {\n  return cwd;\n}\n\nexport function getConfigDir(config: Conf<CliConfig>): string {\n  return dirname(config.path);\n}\n\nexport function getEffectiveApiTarget(config: Conf<CliConfig>): ApiTargetMode {\n  const explicit = config.get(\"apiTarget\");\n  if (explicit === \"local\" || explicit === \"platform\") {\n    return explicit;\n  }\n\n  if (process.env.KEYSTROKE_API_KEY?.trim()) {\n    return \"platform\";\n  }\n\n  return \"local\";\n}\n\nfunction syncPlatformUrlWithWebUrl(config: Conf<CliConfig>): void {\n  const webUrl = config.get(\"webUrl\");\n  const known = knownPlatformUrlForWebUrl(webUrl);\n  if (!known) {\n    return;\n  }\n\n  const stored = config.get(\"platformUrl\");\n  if (stored !== known) {\n    config.set(\"platformUrl\", known);\n  }\n}\n\nexport function createCliConfig(cwd = getCliConfigDir()): Conf<CliConfig> {\n  const config = new Conf<CliConfig>({\n    projectName: \"keystroke\",\n    cwd,\n    schema: {\n      webUrl: {\n        type: \"string\",\n        default: DEFAULT_WEB_URL,\n      },\n      platformUrl: {\n        type: \"string\",\n        default: DEFAULT_PLATFORM_URL,\n      },\n      activeOrganizationId: {\n        type: \"string\",\n      },\n      apiTarget: {\n        type: \"string\",\n        enum: [\"local\", \"platform\"],\n      },\n    },\n  });\n\n  syncPlatformUrlWithWebUrl(config);\n  return config;\n}\n\nexport function getWebUrl(config: Conf<CliConfig>): string {\n  return config.get(\"webUrl\");\n}\n\nexport function getPlatformUrl(config: Conf<CliConfig>): string {\n  const apiKey = process.env.KEYSTROKE_API_KEY?.trim();\n  const fromEnv = process.env.KEYSTROKE_PLATFORM_URL?.trim();\n  if (apiKey && fromEnv) {\n    return fromEnv.replace(/\\/+$/, \"\");\n  }\n  return resolvePlatformUrlForWebUrl(getWebUrl(config), {\n    fallback: config.get(\"platformUrl\"),\n  });\n}\n","import { existsSync, readFileSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\nfunction isCliPackage(dir: string): boolean {\n  const packageJsonPath = join(dir, \"package.json\");\n  if (!existsSync(packageJsonPath)) {\n    return false;\n  }\n\n  const pkg = JSON.parse(readFileSync(packageJsonPath, \"utf8\")) as { name?: string };\n  return pkg.name === \"@keystrokehq/cli\";\n}\n\nexport function resolveCliRoot(fromModuleUrl: string): string {\n  let dir = dirname(fileURLToPath(fromModuleUrl));\n\n  while (dir !== dirname(dir)) {\n    if (isCliPackage(dir)) {\n      return dir;\n    }\n\n    dir = dirname(dir);\n  }\n\n  throw new Error(\"Could not resolve keystroke CLI package root\");\n}\n","import { spawnSync } from \"node:child_process\";\n\nexport type PackageManager = \"npm\" | \"pnpm\" | \"yarn\" | \"bun\";\n\nconst MANAGERS: PackageManager[] = [\"pnpm\", \"npm\", \"yarn\", \"bun\"];\n\nexport function detectPackageManager(): PackageManager {\n  const userAgent = process.env.npm_config_user_agent ?? \"\";\n\n  for (const manager of MANAGERS) {\n    if (userAgent.startsWith(manager)) {\n      return manager;\n    }\n  }\n\n  if (process.env.PNPM_HOME) {\n    return \"pnpm\";\n  }\n\n  return \"npm\";\n}\n\nexport function resolvePackageManager(explicit?: string): PackageManager {\n  if (!explicit) {\n    return detectPackageManager();\n  }\n\n  const normalized = explicit.trim().toLowerCase();\n  if (!MANAGERS.includes(normalized as PackageManager)) {\n    throw new Error(`Unsupported package manager \"${explicit}\". Use npm, pnpm, yarn, or bun.`);\n  }\n\n  return normalized as PackageManager;\n}\n\n/** Resolve GitHub Packages auth for @keystrokehq/* when NODE_AUTH_TOKEN is unset. */\nexport function resolveGithubPackagesToken(): string | undefined {\n  if (process.env.NODE_AUTH_TOKEN) {\n    return process.env.NODE_AUTH_TOKEN;\n  }\n\n  for (const key of [\"GITHUB_TOKEN\", \"GH_TOKEN\"] as const) {\n    const value = process.env[key];\n    if (value) {\n      return value;\n    }\n  }\n\n  const gh = spawnSync(\"gh\", [\"auth\", \"token\"], { encoding: \"utf8\" });\n  if (gh.status === 0) {\n    const token = gh.stdout.trim();\n    if (token) {\n      return token;\n    }\n  }\n\n  return undefined;\n}\n\nexport function installDependencies(cwd: string, manager: PackageManager): void {\n  const token = resolveGithubPackagesToken();\n  const env = token ? { ...process.env, NODE_AUTH_TOKEN: token } : process.env;\n\n  const result = spawnSync(manager, [\"install\"], {\n    cwd,\n    stdio: \"inherit\",\n    env,\n  });\n\n  if (result.status !== 0) {\n    throw new Error(`${manager} install failed`);\n  }\n}\n\nexport function installPlaygroundDependencies(cwd: string): void {\n  const result = spawnSync(\"pnpm\", [\"install\", \"--ignore-workspace\"], {\n    cwd,\n    stdio: \"inherit\",\n    env: process.env,\n  });\n\n  if (result.status !== 0) {\n    throw new Error(\"pnpm install failed\");\n  }\n}\n\n/**\n * Build every workspace package so the playground's `link:` deps resolve to\n * compiled `dist/`. Without this, `keystroke dev` fails with\n * `ERR_MODULE_NOT_FOUND` against whichever package was never built. Turbo\n * caches, so this is only slow on the first run.\n */\nexport function buildPlaygroundWorkspace(monorepoRoot: string): void {\n  // Build with a clean Node env: the `keystroke-dev` wrapper sets\n  // NODE_OPTIONS=--conditions=development, which would make tsdown/turbo resolve\n  // their own deps to src/ and fail. Dropping NODE_OPTIONS builds to dist/ normally.\n  const { NODE_OPTIONS: _drop, ...buildEnv } = process.env;\n  const result = spawnSync(\"pnpm\", [\"run\", \"build\"], {\n    cwd: monorepoRoot,\n    stdio: \"inherit\",\n    env: buildEnv,\n  });\n\n  if (result.status !== 0) {\n    throw new Error(\"workspace build failed (pnpm run build)\");\n  }\n}\n","import { readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { resolveCliRoot } from \"./project/resolve-cli-root\";\n\nexport function readCliVersion(): string {\n  const packageJsonPath = join(resolveCliRoot(import.meta.url), \"package.json\");\n  const pkg = JSON.parse(readFileSync(packageJsonPath, \"utf8\")) as { version?: string };\n  return pkg.version ?? \"0.0.0\";\n}\n"],"mappings":"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"}