ketoy-dev 0.1.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.
Files changed (31) hide show
  1. package/LICENSE +17 -0
  2. package/README.md +101 -0
  3. package/SECURITY.md +34 -0
  4. package/dist/ketoy.js +3165 -0
  5. package/dist/ketoy.js.map +1 -0
  6. package/package.json +78 -0
  7. package/skills/ketoy/README.md +50 -0
  8. package/skills/ketoy/SKILL.md +148 -0
  9. package/skills/ketoy/examples/capabilities-stubs.kt +60 -0
  10. package/skills/ketoy/examples/hilt-config.kt +192 -0
  11. package/skills/ketoy/examples/no-hilt-config.kt +101 -0
  12. package/skills/ketoy/examples/todo-screen.kt +156 -0
  13. package/skills/ketoy/guides/build-and-analyze.md +87 -0
  14. package/skills/ketoy/guides/diagnose-errors.md +129 -0
  15. package/skills/ketoy/guides/init-project.md +127 -0
  16. package/skills/ketoy/guides/migrate.md +190 -0
  17. package/skills/ketoy/guides/publish-deferred.md +46 -0
  18. package/skills/ketoy/guides/safe-edits.md +141 -0
  19. package/skills/ketoy/reference/architecture-cheatsheet.md +122 -0
  20. package/skills/ketoy/reference/capabilities.md +122 -0
  21. package/skills/ketoy/reference/forbidden-apis.md +149 -0
  22. package/skills/ketoy/reference/supported-composables.md +80 -0
  23. package/skills/ketoy/reference/supported-constructors.md +57 -0
  24. package/skills/ketoy/reference/supported-modifiers.md +76 -0
  25. package/skills/ketoy/templates/app-build.gradle.kts.tmpl +109 -0
  26. package/skills/ketoy/templates/ketoy-capabilities.json.tmpl +21 -0
  27. package/skills/ketoy/templates/manifest-snippet.xml.tmpl +33 -0
  28. package/templates/HelloKetoyScreen.kt.tmpl +51 -0
  29. package/templates/MainActivity.kt.tmpl +53 -0
  30. package/templates/MyApplication.kt.tmpl +88 -0
  31. package/templates/ketoy-capabilities.json.tmpl +5 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cli.ts","../src/lib/paths.ts","../src/lib/log.ts","../src/lib/errors.ts","../src/lib/ketoy-version.ts","../src/config/store.ts","../src/config/schema.ts","../src/commands/version.ts","../src/commands/auth.ts","../src/providers/registry.ts","../src/commands/config.ts","../src/commands/init/index.ts","../src/commands/init/detect.ts","../src/commands/init/plan.ts","../src/alpha-pins.ts","../src/commands/init/edit.ts","../src/safe-edit/gradle-kts.ts","../src/safe-edit/manifest-xml.ts","../src/safe-edit/gitignore.ts","../src/safe-edit/main-activity-wrap.ts","../src/safe-edit/kotlin-file.ts","../src/safe-edit/version-catalog.ts","../src/safe-edit/agp8-compat.ts","../src/safe-edit/gradle-properties.ts","../src/templates.ts","../src/config/project-state.ts","../src/commands/chat.ts","../src/agent/loop.ts","../src/agent/model.ts","../src/skill/loader.ts","../src/agent/prompts.ts","../src/agent/tools/read-file.ts","../src/agent/tools/paths.ts","../src/agent/tools/write-file.ts","../src/agent/tools/edit-file.ts","../src/safe-edit/diff.ts","../src/agent/tools/grep.ts","../src/agent/tools/glob.ts","../src/agent/tools/bash.ts","../src/agent/tools/analyze-ktx.ts","../src/ktx/reader.ts","../src/agent/tools/skill-file.ts","../src/agent/tools/index.ts","../src/commands/migrate.ts","../src/commands/doctor.ts","../src/commands/build.ts","../src/commands/analyze.ts","../bin/ketoy.ts"],"sourcesContent":["import { Command } from 'commander';\nimport process from 'node:process';\nimport { CLI_VERSION } from './lib/paths.js';\nimport { log } from './lib/log.js';\nimport { KetoyCliError, UserAbortError } from './lib/errors.js';\nimport { runVersionCommand } from './commands/version.js';\nimport { runAuthCommand, listAuthStatus } from './commands/auth.js';\nimport { runConfigList, runConfigGet, runConfigSet } from './commands/config.js';\nimport { runInitCommand } from './commands/init/index.js';\nimport { runChatCommand } from './commands/chat.js';\nimport { runMigrateCommand } from './commands/migrate.js';\nimport { runDoctorCommand } from './commands/doctor.js';\nimport { runBuildCommand } from './commands/build.js';\nimport { runAnalyzeCommand } from './commands/analyze.js';\n\nexport function buildCli(): Command {\n const program = new Command();\n program\n .name('ketoy')\n .description('AI-powered CLI for Ketoy — scaffold, write, migrate, diagnose, and build .ktx bundles.')\n .version(CLI_VERSION, '-v, --version', 'Show CLI + Ketoy target versions');\n\n program\n .command('version')\n .description('Print CLI + Ketoy versions and default model')\n .action(async () => {\n await runVersionCommand();\n });\n\n // ─── auth ───────────────────────────────────────────────────────\n const auth = program\n .command('auth [provider]')\n .description('Configure API credentials for an AI provider (anthropic, openai, google, mistral, groq, xai, openrouter, ollama)')\n .option('--remove', 'Remove the saved credentials for the given provider')\n .option('--list', 'List configured providers without prompting')\n .action(async (provider: string | undefined, opts: { remove?: boolean; list?: boolean }) => {\n if (opts.list) {\n await listAuthStatus();\n return;\n }\n await runAuthCommand({ provider, remove: opts.remove });\n });\n void auth;\n\n // ─── config ─────────────────────────────────────────────────────\n const config = program.command('config').description('Inspect or modify global CLI configuration');\n config\n .command('list')\n .description('Show current configuration')\n .action(async () => {\n await runConfigList();\n });\n config\n .command('get <key>')\n .description('Read a single config value (supports dotted keys like agent.maxSteps)')\n .action(async (key: string) => {\n await runConfigGet(key);\n });\n config\n .command('set <key> <value>')\n .description('Set a config value')\n .action(async (key: string, value: string) => {\n await runConfigSet(key, value);\n });\n\n // ─── init ───────────────────────────────────────────────────────\n program\n .command('init')\n .description('Add Ketoy to the current Android project via surgical edits')\n .option('--hilt', 'Force Hilt-aware setup')\n .option('--no-hilt', 'Force non-Hilt setup')\n .option('--install-screen', 'Install KetoyScreen in MainActivity (replaces setContent body — fresh projects)')\n .option('--no-install-screen', 'Skip MainActivity edit; integrate KetoyScreen manually')\n .option('-y, --yes', 'Skip confirmation prompts', false)\n .option('--dry-run', 'Print the plan without writing any files', false)\n .action(async (opts: { hilt?: boolean; installScreen?: boolean; yes: boolean; dryRun: boolean }) => {\n const hiltOption = opts.hilt === undefined ? null : opts.hilt;\n const installScreenOption = opts.installScreen === undefined ? null : opts.installScreen;\n await runInitCommand(process.cwd(), {\n hilt: hiltOption,\n installKetoyScreen: installScreenOption,\n yes: opts.yes,\n dryRun: opts.dryRun,\n });\n });\n\n // ─── chat ───────────────────────────────────────────────────────\n program\n .command('chat [prompt...]')\n .description('Open an AI-powered Ketoy assistant in the current project')\n .option('-m, --model <id>', 'Override the default model (e.g. openai:gpt-4o)')\n .action(async (prompt: string[] | undefined, opts: { model?: string }) => {\n await runChatCommand({\n projectRoot: process.cwd(),\n model: opts.model,\n initialPrompt: prompt && prompt.length > 0 ? prompt.join(' ') : undefined,\n });\n });\n\n // ─── migrate ────────────────────────────────────────────────────\n program\n .command('migrate <files...>')\n .description('AI-driven per-file migration of Compose source(s) to KBC')\n .option('-m, --model <id>', 'Override the default model')\n .action(async (files: string[], opts: { model?: string }) => {\n await runMigrateCommand({ projectRoot: process.cwd(), files, model: opts.model });\n });\n\n // ─── doctor ─────────────────────────────────────────────────────\n program\n .command('doctor [task]')\n .description('Run a Gradle task, capture output, and ask the agent to diagnose failures')\n .option('-m, --model <id>', 'Override the default model')\n .action(async (task: string | undefined, opts: { model?: string }) => {\n await runDoctorCommand({\n projectRoot: process.cwd(),\n task: task ?? ':app:ketoyBundle --rerun-tasks',\n model: opts.model,\n });\n });\n\n // ─── build ──────────────────────────────────────────────────────\n program\n .command('build')\n .description('Run the Ketoy bundle / Android assemble Gradle task')\n .option('--variant <name>', 'bundle, debug, or release', 'bundle')\n .action(async (opts: { variant: string }) => {\n const variant =\n opts.variant === 'debug' || opts.variant === 'release' || opts.variant === 'bundle'\n ? (opts.variant as 'bundle' | 'debug' | 'release')\n : 'bundle';\n await runBuildCommand({ projectRoot: process.cwd(), variant });\n });\n\n // ─── analyze ────────────────────────────────────────────────────\n program\n .command('analyze <path>')\n .description('Inspect a .ktx bundle')\n .option('--manifest', 'Print adapter / constructor / capability manifests')\n .option('--strings', 'Print the string pool')\n .option('--json', 'Emit JSON instead of human-readable output')\n .action(async (path: string, opts: { manifest?: boolean; strings?: boolean; json?: boolean }) => {\n await runAnalyzeCommand({\n path,\n showManifest: !!opts.manifest,\n showStrings: !!opts.strings,\n json: !!opts.json,\n });\n });\n\n // ─── publish ────────────────────────────────────────────────────\n program\n .command('publish')\n .description('Publish a bundle (deferred until Ketoy backend GA)')\n .action(() => {\n log.warn(\n 'Publishing is deferred until the Ketoy backend ships. Until then, upload `.ktx` files to your CDN directly and consume via KetoyBundleSource.Remote(url).',\n );\n });\n\n return program;\n}\n\nexport async function runCli(argv: readonly string[]): Promise<void> {\n const program = buildCli();\n try {\n await program.parseAsync([...argv]);\n } catch (e) {\n if (e instanceof UserAbortError) {\n log.warn(e.message);\n process.exit(e.exitCode);\n }\n if (e instanceof KetoyCliError) {\n log.error(e.message);\n process.exit(e.exitCode);\n }\n const err = e as Error & { name?: string };\n if (err.name === 'ExitPromptError') {\n log.warn('Aborted.');\n process.exit(130);\n }\n log.error(err.message ?? String(e));\n if (process.env['KETOY_DEBUG']) {\n // eslint-disable-next-line no-console\n console.error(err);\n }\n process.exit(1);\n }\n}\n","import { homedir } from 'node:os';\nimport { join } from 'node:path';\n\nexport const CONFIG_DIR = join(homedir(), '.ketoy-cli');\nexport const CONFIG_FILE = join(CONFIG_DIR, 'config.json');\n\nexport const PROJECT_STATE_DIR = '.ketoy';\nexport const PROJECT_STATE_FILE = join(PROJECT_STATE_DIR, 'state.json');\n\n/**\n * The CLI's own npm package version. Stays in source because it's tied to the\n * tarball that's currently installed. The *Ketoy artifact* version (i.e. the\n * version of `dev.ketoy.vm:*` the CLI scaffolds + targets) is resolved at\n * runtime — see `lib/ketoy-version.ts` and the `getKetoyVersion()` accessor.\n */\nexport const CLI_VERSION = '0.1.0';\n","import pc from 'picocolors';\n\nconst PREFIX = pc.bold(pc.magenta('ketoy'));\n\nexport const log = {\n info(msg: string): void {\n process.stdout.write(`${PREFIX} ${msg}\\n`);\n },\n success(msg: string): void {\n process.stdout.write(`${PREFIX} ${pc.green('✓')} ${msg}\\n`);\n },\n warn(msg: string): void {\n process.stderr.write(`${PREFIX} ${pc.yellow('!')} ${msg}\\n`);\n },\n error(msg: string): void {\n process.stderr.write(`${PREFIX} ${pc.red('✗')} ${msg}\\n`);\n },\n step(n: number, total: number, msg: string): void {\n process.stdout.write(`${PREFIX} ${pc.dim(`[${n}/${total}]`)} ${msg}\\n`);\n },\n detail(msg: string): void {\n process.stdout.write(` ${pc.dim(msg)}\\n`);\n },\n raw(msg: string): void {\n process.stdout.write(msg);\n },\n};\n\nexport { pc };\n","export class KetoyCliError extends Error {\n public readonly exitCode: number;\n constructor(message: string, exitCode = 1) {\n super(message);\n this.name = 'KetoyCliError';\n this.exitCode = exitCode;\n }\n}\n\nexport class UserAbortError extends KetoyCliError {\n constructor(message = 'Aborted by user') {\n super(message, 130);\n this.name = 'UserAbortError';\n }\n}\n\nexport class ConfigError extends KetoyCliError {\n constructor(message: string) {\n super(message, 2);\n this.name = 'ConfigError';\n }\n}\n\nexport class DetectionError extends KetoyCliError {\n constructor(message: string) {\n super(message, 3);\n this.name = 'DetectionError';\n }\n}\n\n/**\n * Raised when the CLI cannot reach a required upstream service (currently\n * only `https://ketoy.dev/v1/version`). The CLI deliberately does not embed\n * a fallback Ketoy version, so this error is fatal for any command that\n * needs to know the target version (init, version banner, agent system\n * prompt). Exit code 4 — distinct from generic errors so scripts can detect\n * \"offline, retry later\" specifically.\n */\nexport class NoInternetError extends KetoyCliError {\n constructor(message: string) {\n super(message, 4);\n this.name = 'NoInternetError';\n }\n}\n","import { NoInternetError, KetoyCliError } from './errors.js';\n\n/**\n * Single source of truth for the Ketoy artifact version (the `dev.ketoy.vm:*`\n * coordinates the CLI scaffolds + targets). Resolved at runtime from the\n * upstream version endpoint — the CLI deliberately does NOT embed a fallback,\n * so the published artifacts always match what `ketoy.dev` advertises.\n *\n * Process-wide memoization: the first caller triggers the fetch; concurrent\n * callers share the same in-flight Promise; every subsequent call in the\n * same process returns the cached resolved value. No disk cache — the user\n * asked for \"don't keep any versions\" semantics, and the endpoint is fast\n * (single CDN-cached plain-text response).\n *\n * Failure mode: `NoInternetError` is thrown. Commands that need the version\n * surface this to the user; commands that don't (e.g. `ketoy config list`,\n * `ketoy analyze`) never call this and stay fully offline-capable.\n */\n\nconst VERSION_URL =\n process.env['KETOY_VERSION_URL'] ?? 'https://ketoy.dev/v1/version';\n\nconst FETCH_TIMEOUT_MS = Number(process.env['KETOY_VERSION_TIMEOUT_MS'] ?? '5000');\n\n// Loose semver guard — accepts `1.2.3`, `0.3.4-alpha`, `1.0.0-rc.1+build.5`.\n// Strict enough to catch HTML error pages / accidental empty bodies; permissive\n// enough that we don't have to ship a full semver parser.\nconst VERSION_RE = /^[0-9]+\\.[0-9]+\\.[0-9]+(?:-[0-9A-Za-z.-]+)?(?:\\+[0-9A-Za-z.-]+)?$/;\n\nlet cached: Promise<string> | null = null;\n\nasync function fetchVersion(): Promise<string> {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), FETCH_TIMEOUT_MS);\n let response: Response;\n try {\n response = await fetch(VERSION_URL, {\n method: 'GET',\n headers: { accept: 'text/plain, application/json;q=0.9' },\n signal: controller.signal,\n });\n } catch (e) {\n const err = e as Error & { code?: string };\n const offline =\n err.name === 'AbortError' ||\n err.code === 'ENOTFOUND' ||\n err.code === 'ECONNREFUSED' ||\n err.code === 'ECONNRESET' ||\n err.code === 'ETIMEDOUT' ||\n /fetch failed|network|getaddrinfo/i.test(err.message);\n if (offline) {\n throw new NoInternetError(\n `No internet — cannot reach ${VERSION_URL}. The Ketoy version is fetched live and not embedded in the CLI; connect to the network and retry. (${err.message})`,\n );\n }\n throw new KetoyCliError(`Failed to fetch Ketoy version from ${VERSION_URL}: ${err.message}`);\n } finally {\n clearTimeout(timer);\n }\n\n if (!response.ok) {\n throw new KetoyCliError(\n `Ketoy version endpoint returned HTTP ${response.status} ${response.statusText} for ${VERSION_URL}.`,\n );\n }\n\n const body = (await response.text()).trim();\n if (!VERSION_RE.test(body)) {\n throw new KetoyCliError(\n `Ketoy version endpoint returned an unexpected body: ${JSON.stringify(body.slice(0, 80))}. Expected a semver string like \"0.3.4-alpha\".`,\n );\n }\n return body;\n}\n\n/**\n * Returns the currently-advertised Ketoy artifact version (e.g. `\"0.3.4-alpha\"`).\n * Memoized for the lifetime of the process. Throws `NoInternetError` if the\n * version endpoint is unreachable.\n */\nexport async function getKetoyVersion(): Promise<string> {\n if (cached !== null) return cached;\n cached = fetchVersion().catch((e) => {\n // Clear the cached rejection so a later command in long-running processes\n // (e.g. `ketoy chat`) can re-attempt once the network is back.\n cached = null;\n throw e;\n });\n return cached;\n}\n\n/** Test-only — reset the in-process memo. */\nexport function __resetKetoyVersionCacheForTests(): void {\n cached = null;\n}\n","import { mkdir, readFile, writeFile, chmod, access } from 'node:fs/promises';\nimport { dirname } from 'node:path';\nimport { CONFIG_DIR, CONFIG_FILE } from '../lib/paths.js';\nimport { ConfigError } from '../lib/errors.js';\nimport { GlobalConfigSchema, type GlobalConfig, type ProviderId } from './schema.js';\n\nlet cached: GlobalConfig | null = null;\n\nasync function fileExists(path: string): Promise<boolean> {\n try {\n await access(path);\n return true;\n } catch {\n return false;\n }\n}\n\nexport async function loadConfig(): Promise<GlobalConfig> {\n if (cached) return cached;\n if (!(await fileExists(CONFIG_FILE))) {\n cached = GlobalConfigSchema.parse({});\n return cached;\n }\n const raw = await readFile(CONFIG_FILE, 'utf-8');\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch (e) {\n throw new ConfigError(`Malformed config at ${CONFIG_FILE}: ${(e as Error).message}`);\n }\n const result = GlobalConfigSchema.safeParse(parsed);\n if (!result.success) {\n throw new ConfigError(`Invalid config at ${CONFIG_FILE}: ${result.error.message}`);\n }\n cached = result.data;\n return cached;\n}\n\nexport async function saveConfig(config: GlobalConfig): Promise<void> {\n await mkdir(dirname(CONFIG_FILE), { recursive: true, mode: 0o700 });\n await writeFile(CONFIG_FILE, JSON.stringify(config, null, 2) + '\\n', {\n encoding: 'utf-8',\n mode: 0o600,\n });\n await chmod(CONFIG_FILE, 0o600).catch(() => undefined);\n cached = config;\n}\n\nexport async function setApiKey(provider: ProviderId, key: string): Promise<void> {\n const config = await loadConfig();\n const updated: GlobalConfig = {\n ...config,\n apiKeys: { ...config.apiKeys, [provider]: key },\n };\n await saveConfig(updated);\n}\n\nexport async function removeApiKey(provider: ProviderId): Promise<void> {\n const config = await loadConfig();\n const { [provider]: _removed, ...rest } = config.apiKeys;\n await saveConfig({ ...config, apiKeys: rest });\n}\n\nexport async function getApiKey(provider: ProviderId): Promise<string | undefined> {\n const config = await loadConfig();\n return config.apiKeys[provider];\n}\n\nexport function getConfigDir(): string {\n return CONFIG_DIR;\n}\n","import { z } from 'zod';\n\nexport const ProviderIdSchema = z.enum([\n 'anthropic',\n 'openai',\n 'google',\n 'mistral',\n 'groq',\n 'xai',\n 'openrouter',\n 'ollama',\n]);\nexport type ProviderId = z.infer<typeof ProviderIdSchema>;\n\nexport const GlobalConfigSchema = z.object({\n model: z.string().default('anthropic:claude-sonnet-4-5'),\n defaultProvider: ProviderIdSchema.default('anthropic'),\n apiKeys: z.record(ProviderIdSchema, z.string()).default({}),\n ollama: z\n .object({\n baseUrl: z.string().default('http://localhost:11434'),\n })\n .default({ baseUrl: 'http://localhost:11434' }),\n agent: z\n .object({\n maxSteps: z.number().int().min(1).max(200).default(50),\n autoApproveReads: z.boolean().default(true),\n autoApproveSafeBash: z.boolean().default(true),\n })\n .default({ maxSteps: 50, autoApproveReads: true, autoApproveSafeBash: true }),\n});\nexport type GlobalConfig = z.infer<typeof GlobalConfigSchema>;\n\nexport const ProjectStateSchema = z.object({\n ketoyVersion: z.string(),\n initRanOn: z.string(),\n hilt: z.boolean(),\n applicationId: z.string(),\n namespace: z.string(),\n packagePath: z.string(),\n bundlePath: z.string(),\n});\nexport type ProjectState = z.infer<typeof ProjectStateSchema>;\n","import { log, pc } from '../lib/log.js';\nimport { CLI_VERSION } from '../lib/paths.js';\nimport { getKetoyVersion } from '../lib/ketoy-version.js';\nimport { loadConfig } from '../config/store.js';\n\nexport async function runVersionCommand(): Promise<void> {\n const config = await loadConfig();\n log.info(`${pc.bold('ketoy')} ${CLI_VERSION}`);\n const ketoyVersion = await getKetoyVersion();\n log.detail(`Ketoy target: ${ketoyVersion}`);\n log.detail(`Default model: ${config.model}`);\n log.detail(`Node: ${process.version}`);\n}\n","import { password, select, input } from '@inquirer/prompts';\nimport { PROVIDERS, parseModelId } from '../providers/registry.js';\nimport {\n loadConfig,\n saveConfig,\n setApiKey,\n removeApiKey,\n getApiKey,\n} from '../config/store.js';\nimport { log, pc } from '../lib/log.js';\nimport { KetoyCliError } from '../lib/errors.js';\nimport type { ProviderId } from '../config/schema.js';\n\nexport async function runAuthCommand(args: {\n provider?: string;\n remove?: boolean;\n}): Promise<void> {\n const providerKeys = Object.keys(PROVIDERS) as ProviderId[];\n\n let provider: ProviderId;\n if (args.provider) {\n if (!providerKeys.includes(args.provider as ProviderId)) {\n throw new KetoyCliError(\n `Unknown provider \"${args.provider}\". Known: ${providerKeys.join(', ')}.`,\n );\n }\n provider = args.provider as ProviderId;\n } else {\n provider = await select<ProviderId>({\n message: 'Choose a provider:',\n choices: providerKeys.map((p) => ({\n name: `${PROVIDERS[p].displayName} (${p})`,\n value: p,\n })),\n });\n }\n\n const info = PROVIDERS[provider];\n\n if (args.remove) {\n await removeApiKey(provider);\n log.success(`Removed credentials for ${info.displayName}.`);\n return;\n }\n\n if (provider === 'ollama') {\n const current = (await loadConfig()).ollama.baseUrl;\n const base = await input({\n message: 'Ollama base URL:',\n default: current,\n });\n const config = await loadConfig();\n await saveConfig({ ...config, ollama: { baseUrl: base } });\n log.success(`Ollama base URL saved: ${base}`);\n return;\n }\n\n log.info(info.apiKeyHelp);\n const existing = await getApiKey(provider);\n if (existing) {\n log.detail(`A key for ${info.displayName} is already saved (ends in …${existing.slice(-4)}).`);\n }\n const key = await password({\n message: `${info.displayName} API key:`,\n mask: '*',\n validate: (v) => (v.trim().length > 0 ? true : 'API key cannot be empty.'),\n });\n await setApiKey(provider, key.trim());\n\n const config = await loadConfig();\n if (config.defaultProvider !== provider) {\n log.info(\n `Tip: run ${pc.bold(`ketoy config set model ${provider}:${info.defaultModel}`)} to use this provider by default.`,\n );\n }\n\n log.success(`Saved ${info.displayName} key to ${pc.dim('~/.ketoy-cli/config.json')} (mode 0600).`);\n}\n\nexport async function listAuthStatus(): Promise<void> {\n const config = await loadConfig();\n const providerKeys = Object.keys(PROVIDERS) as ProviderId[];\n log.info('Provider credentials:');\n for (const p of providerKeys) {\n const info = PROVIDERS[p];\n const key = config.apiKeys[p];\n const status = key ? pc.green(`set (…${key.slice(-4)})`) : pc.dim('not set');\n log.detail(`${info.displayName.padEnd(28)} ${status}`);\n }\n log.detail(`Default model: ${config.model}`);\n try {\n log.detail(`Will use model on next chat: ${parseModelId(config.model).provider}`);\n } catch (e) {\n log.warn(\n `Default model \"${config.model}\" is malformed (${(e as Error).message}). Run \\`ketoy config set model <provider>:<name>\\`.`,\n );\n }\n}\n","import type { ProviderId } from '../config/schema.js';\n\nexport interface ProviderInfo {\n id: ProviderId;\n displayName: string;\n envVar: string;\n apiKeyHelp: string;\n signupUrl: string;\n defaultModel: string;\n sampleModels: string[];\n needsBaseUrl?: boolean;\n}\n\nexport const PROVIDERS: Record<ProviderId, ProviderInfo> = {\n anthropic: {\n id: 'anthropic',\n displayName: 'Anthropic',\n envVar: 'ANTHROPIC_API_KEY',\n apiKeyHelp: 'Get a key at https://console.anthropic.com/settings/keys',\n signupUrl: 'https://console.anthropic.com',\n defaultModel: 'claude-sonnet-4-5',\n sampleModels: [\n 'claude-sonnet-4-5',\n 'claude-opus-4-1',\n 'claude-haiku-4-5',\n ],\n },\n openai: {\n id: 'openai',\n displayName: 'OpenAI',\n envVar: 'OPENAI_API_KEY',\n apiKeyHelp: 'Get a key at https://platform.openai.com/api-keys',\n signupUrl: 'https://platform.openai.com',\n defaultModel: 'gpt-4o',\n sampleModels: ['gpt-4o', 'gpt-4o-mini', 'o1', 'o1-mini'],\n },\n google: {\n id: 'google',\n displayName: 'Google (Gemini)',\n envVar: 'GOOGLE_GENERATIVE_AI_API_KEY',\n apiKeyHelp: 'Get a key at https://aistudio.google.com/apikey',\n signupUrl: 'https://aistudio.google.com',\n defaultModel: 'gemini-2.0-flash-exp',\n sampleModels: ['gemini-2.0-flash-exp', 'gemini-1.5-pro', 'gemini-1.5-flash'],\n },\n mistral: {\n id: 'mistral',\n displayName: 'Mistral',\n envVar: 'MISTRAL_API_KEY',\n apiKeyHelp: 'Get a key at https://console.mistral.ai/api-keys/',\n signupUrl: 'https://console.mistral.ai',\n defaultModel: 'mistral-large-latest',\n sampleModels: ['mistral-large-latest', 'mistral-small-latest', 'codestral-latest'],\n },\n groq: {\n id: 'groq',\n displayName: 'Groq',\n envVar: 'GROQ_API_KEY',\n apiKeyHelp: 'Get a key at https://console.groq.com/keys',\n signupUrl: 'https://console.groq.com',\n defaultModel: 'llama-3.3-70b-versatile',\n sampleModels: ['llama-3.3-70b-versatile', 'llama-3.1-70b-versatile', 'mixtral-8x7b-32768'],\n },\n xai: {\n id: 'xai',\n displayName: 'xAI (Grok)',\n envVar: 'XAI_API_KEY',\n apiKeyHelp: 'Get a key at https://console.x.ai',\n signupUrl: 'https://console.x.ai',\n defaultModel: 'grok-2-latest',\n sampleModels: ['grok-2-latest', 'grok-beta'],\n },\n openrouter: {\n id: 'openrouter',\n displayName: 'OpenRouter (any model)',\n envVar: 'OPENROUTER_API_KEY',\n apiKeyHelp: 'Get a key at https://openrouter.ai/keys',\n signupUrl: 'https://openrouter.ai',\n defaultModel: 'anthropic/claude-sonnet-4',\n sampleModels: [\n 'anthropic/claude-sonnet-4',\n 'openai/gpt-4o',\n 'google/gemini-2.0-flash-exp',\n 'meta-llama/llama-3.1-405b-instruct',\n ],\n },\n ollama: {\n id: 'ollama',\n displayName: 'Ollama (local models)',\n envVar: '',\n apiKeyHelp: 'No API key required — Ollama runs locally. Install at https://ollama.com',\n signupUrl: 'https://ollama.com',\n defaultModel: 'llama3.1:70b',\n sampleModels: ['llama3.1:70b', 'qwen2.5:32b', 'codellama:34b'],\n needsBaseUrl: true,\n },\n};\n\nexport function parseModelId(modelId: string): { provider: ProviderId; name: string } {\n const idx = modelId.indexOf(':');\n if (idx === -1) {\n throw new Error(\n `Invalid model id \"${modelId}\". Use the form \"<provider>:<name>\" — e.g. \"anthropic:claude-sonnet-4-5\".`,\n );\n }\n const providerRaw = modelId.slice(0, idx);\n const name = modelId.slice(idx + 1);\n if (!(providerRaw in PROVIDERS)) {\n throw new Error(\n `Unknown provider \"${providerRaw}\". Known providers: ${Object.keys(PROVIDERS).join(', ')}.`,\n );\n }\n if (!name) {\n throw new Error(`Empty model name in \"${modelId}\". Use \"<provider>:<name>\".`);\n }\n return { provider: providerRaw as ProviderId, name };\n}\n","import { loadConfig, saveConfig } from '../config/store.js';\nimport { GlobalConfigSchema } from '../config/schema.js';\nimport { parseModelId, PROVIDERS } from '../providers/registry.js';\nimport { log, pc } from '../lib/log.js';\nimport { KetoyCliError } from '../lib/errors.js';\n\nexport async function runConfigList(): Promise<void> {\n const config = await loadConfig();\n log.info('Config:');\n log.detail(`model: ${config.model}`);\n log.detail(`defaultProvider: ${config.defaultProvider}`);\n log.detail(`ollama.baseUrl: ${config.ollama.baseUrl}`);\n log.detail(`agent.maxSteps: ${config.agent.maxSteps}`);\n log.detail(`agent.autoApproveReads: ${config.agent.autoApproveReads}`);\n log.detail(`agent.autoApproveSafeBash: ${config.agent.autoApproveSafeBash}`);\n log.detail(`Providers configured: ${Object.keys(config.apiKeys).join(', ') || pc.dim('(none)')}`);\n}\n\n// Block reads/writes of secret-bearing subtrees. `apiKeys` holds plaintext\n// provider credentials; emitting it to stdout from `ketoy config get apiKeys`\n// would leak every saved key into terminal history / screen-shares / CI logs.\n// Use `ketoy auth --list` for redacted status instead.\nconst REDACTED_KEYS = new Set(['apiKeys']);\n\nfunction isRedacted(key: string): boolean {\n const top = key.split('.')[0] ?? '';\n return REDACTED_KEYS.has(top);\n}\n\n// Refuse property names that would mutate Object.prototype on any value JS\n// engine — `__proto__`, `prototype`, `constructor`. The schema parse step\n// rejects pollution downstream, but only AFTER `cursor[part] = {}` has\n// already mutated a shared prototype object in this process.\nconst FORBIDDEN_KEY_PARTS = new Set(['__proto__', 'prototype', 'constructor']);\n\nfunction assertSafeKey(key: string): void {\n for (const part of key.split('.')) {\n if (FORBIDDEN_KEY_PARTS.has(part)) {\n throw new KetoyCliError(`Refusing key \"${key}\" — reserved property name \"${part}\".`);\n }\n }\n}\n\nexport async function runConfigGet(key: string): Promise<void> {\n assertSafeKey(key);\n if (isRedacted(key)) {\n throw new KetoyCliError(\n `Refusing to print \"${key}\" — contains secrets. Use \\`ketoy auth --list\\` for a redacted view.`,\n );\n }\n const config = await loadConfig();\n const value = readByDottedKey(config as unknown as Record<string, unknown>, key);\n if (value === undefined) {\n log.warn(`Unknown config key: ${key}`);\n process.exitCode = 2;\n return;\n }\n log.info(typeof value === 'object' ? JSON.stringify(value, null, 2) : String(value));\n}\n\nexport async function runConfigSet(key: string, value: string): Promise<void> {\n assertSafeKey(key);\n if (isRedacted(key)) {\n throw new KetoyCliError(\n `Refusing to set \"${key}\" directly. Use \\`ketoy auth <provider>\\` to store API keys securely.`,\n );\n }\n const config = await loadConfig();\n const obj = JSON.parse(JSON.stringify(config)) as Record<string, unknown>;\n const parsedValue = coerceValue(key, value);\n writeByDottedKey(obj, key, parsedValue);\n const reparsed = GlobalConfigSchema.parse(obj);\n await saveConfig(reparsed);\n log.success(`Updated ${pc.bold(key)} = ${JSON.stringify(parsedValue)}`);\n}\n\nfunction coerceValue(key: string, value: string): unknown {\n if (key === 'model') {\n parseModelId(value); // validates\n return value;\n }\n if (key === 'defaultProvider') {\n if (!(value in PROVIDERS)) {\n throw new KetoyCliError(\n `Unknown provider \"${value}\". Known: ${Object.keys(PROVIDERS).join(', ')}.`,\n );\n }\n return value;\n }\n if (value === 'true') return true;\n if (value === 'false') return false;\n if (/^-?\\d+$/.test(value)) return Number(value);\n return value;\n}\n\nfunction readByDottedKey(obj: Record<string, unknown>, key: string): unknown {\n return key.split('.').reduce<unknown>((acc, part) => {\n if (acc && typeof acc === 'object' && Object.prototype.hasOwnProperty.call(acc, part)) {\n return (acc as Record<string, unknown>)[part];\n }\n return undefined;\n }, obj);\n}\n\nfunction writeByDottedKey(obj: Record<string, unknown>, key: string, value: unknown): void {\n const parts = key.split('.');\n let cursor = obj;\n for (let i = 0; i < parts.length - 1; i++) {\n const part = parts[i]!;\n if (FORBIDDEN_KEY_PARTS.has(part)) {\n throw new KetoyCliError(`Refusing key \"${key}\" — reserved property name \"${part}\".`);\n }\n const next = cursor[part];\n if (next === undefined || typeof next !== 'object' || next === null) {\n cursor[part] = Object.create(null) as Record<string, unknown>;\n }\n cursor = cursor[part] as Record<string, unknown>;\n }\n const last = parts[parts.length - 1]!;\n if (FORBIDDEN_KEY_PARTS.has(last)) {\n throw new KetoyCliError(`Refusing key \"${key}\" — reserved property name \"${last}\".`);\n }\n cursor[last] = value;\n}\n","import { confirm } from '@inquirer/prompts';\nimport { detectProject } from './detect.js';\nimport { planInit } from './plan.js';\nimport { applyPlan } from './edit.js';\nimport { saveProjectState } from '../../config/project-state.js';\nimport { log, pc } from '../../lib/log.js';\nimport { UserAbortError, DetectionError, KetoyCliError } from '../../lib/errors.js';\nimport { getKetoyVersion } from '../../lib/ketoy-version.js';\nimport { ketoyScreenManualSnippet } from '../../safe-edit/main-activity-wrap.js';\n\nexport interface InitOptions {\n hilt: boolean | null;\n installKetoyScreen: boolean | null;\n yes: boolean;\n dryRun: boolean;\n}\n\nexport async function runInitCommand(projectRoot: string, options: InitOptions): Promise<void> {\n log.info(`Detecting project structure at ${pc.dim(projectRoot)}…`);\n const detection = await detectProject(projectRoot);\n log.detail(\n `namespace=${detection.namespace}, applicationId=${detection.applicationId}, minSdk=${detection.minSdk}`,\n );\n log.detail(`hilt detected in project=${detection.hasHilt}, srcRoot=${detection.packageSrcRoot}`);\n\n // ── Hilt opt-in ─────────────────────────────────────────────────\n //\n // Hilt setup involves @HiltAndroidApp, @Module/@Binds, KetoyHiltModule,\n // KetoyConfigCustomizer wiring, and (commonly) DataStore/HTTP client\n // providers. We don't auto-generate this — too many app-specific\n // decisions. The CLI redirects to `ketoy chat` where the AI agent can\n // produce a Hilt configuration tailored to the user's existing modules.\n\n let useHilt: boolean;\n if (options.hilt !== null) {\n useHilt = options.hilt;\n } else if (detection.hasHilt) {\n log.warn(\n 'Hilt usage detected in the existing project. Ketoy init produces a non-Hilt bootstrap by default.',\n );\n useHilt = await confirm({\n message: 'Generate a Hilt-aware Ketoy setup instead?',\n default: false,\n }).catch(() => false);\n } else {\n useHilt = false;\n }\n\n if (useHilt) {\n log.warn('Hilt setup requires app-specific decisions and is not scaffolded by `ketoy init`.');\n log.info(\n `Run ${pc.bold('ketoy chat')} and ask:\\n` +\n ` ${pc.dim('\"Set up Ketoy with Hilt in this project — wire KetoyCapabilityProvider and the')}\\n` +\n ` ${pc.dim(' config customizer into my existing @Module / @InstallIn(SingletonComponent::class).\"')}\\n` +\n `\\n` +\n `The agent has full access to your build files and existing Hilt modules, and will apply\\n` +\n `surgical, additive edits — the same safety guarantees as \\`ketoy init\\` itself. Aborting init.`,\n );\n throw new UserAbortError('Hilt setup deferred to `ketoy chat`.');\n }\n\n // ── KetoyScreen install opt-in ─────────────────────────────────\n //\n // The wrap replaces the body inside MainActivity's theme block with a\n // KetoyScreen + simple \"Hello Android\" native fallback. Safe on fresh\n // Android Studio scaffolds (the auto-generated Greeting() drops away),\n // destructive on projects with custom UI. Default = ask the user; with\n // `--yes` and no explicit flag, default to NO (the safer non-destructive\n // choice — user can run `ketoy chat` to wire things up later).\n\n let installScreen: boolean;\n if (options.installKetoyScreen !== null) {\n installScreen = options.installKetoyScreen;\n } else if (options.yes) {\n log.warn(\n '--yes without --install-screen / --no-install-screen — defaulting to NOT installing KetoyScreen in MainActivity. Use ketoy chat or the docs to integrate manually.',\n );\n installScreen = false;\n } else {\n log.info('');\n log.info(pc.bold('Install KetoyScreen in MainActivity?'));\n log.detail(pc.green('Recommended') + ' if this is a fresh Android Studio project (the default');\n log.detail('Greeting() UI is replaced with KetoyScreen + a simple Hello Android fallback).');\n log.detail(pc.yellow('Decline') + ' if MainActivity has custom UI you want to keep — instead use');\n log.detail('the docs (https://ketoy.dev/docs) or `ketoy chat` to integrate KetoyScreen by hand.');\n installScreen = await confirm({\n message: 'Replace setContent body with KetoyScreen?',\n default: true,\n }).catch(() => false);\n }\n\n // ── Plan ────────────────────────────────────────────────────────\n const plan = await planInit(detection, { installKetoyScreen: installScreen });\n\n log.info(`Plan — non-Hilt setup, ${plan.actions.length} action(s):`);\n for (const a of plan.actions) {\n const tag = a.highRisk ? pc.yellow(' ⚠') : pc.cyan(' •');\n log.raw(`${tag} ${a.description}\\n`);\n }\n if (plan.warnings.length > 0) {\n log.raw('\\n');\n for (const w of plan.warnings) log.warn(w);\n }\n\n if (detection.minSdk < 26) {\n throw new DetectionError(\n `Ketoy requires minSdk >= 26. Current: ${detection.minSdk}. Update app/build.gradle.kts and re-run.`,\n );\n }\n\n if (options.dryRun) {\n log.info('Dry run — no files were modified.');\n return;\n }\n\n log.raw('\\n');\n if (!options.yes) {\n const ok = await confirm({\n message: `Apply ${plan.actions.length} action(s) to ${detection.appModuleRelative}/?`,\n default: true,\n }).catch(() => false);\n if (!ok) throw new UserAbortError();\n }\n\n log.raw('\\n');\n const result = await applyPlan(projectRoot, plan);\n log.raw('\\n');\n\n if (result.errors.length > 0) {\n log.error(`Init completed with ${result.errors.length} error(s).`);\n } else {\n log.success(`Init complete — ${result.appliedCount} action(s) applied.`);\n }\n\n await saveProjectState(projectRoot, {\n ketoyVersion: await getKetoyVersion(),\n initRanOn: new Date().toISOString(),\n hilt: false,\n applicationId: detection.applicationId,\n namespace: detection.namespace,\n packagePath: detection.packagePath,\n bundlePath: 'app/src/main/assets/ketoy/main.ktx',\n });\n\n log.info('Next steps:');\n log.detail('1. Sync Gradle (Android Studio: File → Sync Project)');\n log.detail('2. ./gradlew :app:assembleDebug # produces the .ktx bundle and the APK');\n if (installScreen) {\n log.detail('3. Install and run — the KBC HelloKetoyScreen renders inside MainActivity');\n log.detail('4. ketoy chat # ask the agent to add screens, capabilities, etc.');\n } else {\n log.detail('3. Integrate KetoyScreen into MainActivity yourself — snippet below');\n log.detail('4. ketoy chat # ask the agent to wire it up if needed');\n log.info('');\n log.info(pc.bold('Manual integration — paste inside your MainActivity setContent { YourAppTheme { … } }:'));\n log.raw('\\n');\n log.raw(\n ketoyScreenManualSnippet({\n packageOfApp: detection.applicationId,\n appClassSimpleName: 'MyApplication',\n entryPoint: 'HelloKetoyScreen',\n bundleAsset: 'ketoy/main.ktx',\n }),\n );\n log.raw('\\n\\n');\n }\n\n if (result.errors.length > 0) {\n throw new KetoyCliError('init completed with errors — see above.');\n }\n}\n","import { readFile, access } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { glob } from 'tinyglobby';\nimport { DetectionError } from '../../lib/errors.js';\n\nexport interface ProjectDetection {\n projectRoot: string;\n appModulePath: string; // absolute path to app module\n appModuleRelative: string; // relative to projectRoot\n buildGradleKtsPath: string;\n manifestPath: string;\n namespace: string;\n applicationId: string;\n minSdk: number;\n packagePath: string; // app/src/main/java/<pkg-path> OR kotlin/<pkg-path>\n packageSrcRoot: 'java' | 'kotlin';\n hasHilt: boolean;\n existingApplicationClassFq: string | null;\n existingMainActivityPath: string | null;\n rootSettingsPath: string;\n rootBuildGradlePath: string | null; // <projectRoot>/build.gradle.kts if present\n versionCatalogPath: string | null; // <projectRoot>/gradle/libs.versions.toml if present\n}\n\nasync function fileExists(p: string): Promise<boolean> {\n try {\n await access(p);\n return true;\n } catch {\n return false;\n }\n}\n\nexport async function detectProject(projectRoot: string): Promise<ProjectDetection> {\n const settingsKts = join(projectRoot, 'settings.gradle.kts');\n const settingsGradle = join(projectRoot, 'settings.gradle');\n const rootSettings = (await fileExists(settingsKts))\n ? settingsKts\n : (await fileExists(settingsGradle))\n ? settingsGradle\n : null;\n if (!rootSettings) {\n throw new DetectionError(\n 'No settings.gradle.kts (or settings.gradle) at the project root. Run from an Android project root.',\n );\n }\n if (rootSettings.endsWith('.gradle')) {\n throw new DetectionError(\n 'Groovy settings.gradle detected — Ketoy requires Kotlin DSL (settings.gradle.kts). Migrate the build files first.',\n );\n }\n\n const appBuildKts = join(projectRoot, 'app', 'build.gradle.kts');\n if (!(await fileExists(appBuildKts))) {\n throw new DetectionError(\n `No app/build.gradle.kts found. Expected the Android app module at ${join(projectRoot, 'app')}.`,\n );\n }\n\n const appBuildSource = await readFile(appBuildKts, 'utf-8');\n const namespace = matchOne(appBuildSource, /namespace\\s*=\\s*\"([\\w.]+)\"/);\n const applicationId = matchOne(appBuildSource, /applicationId\\s*=\\s*\"([\\w.]+)\"/);\n const minSdkRaw = matchOne(appBuildSource, /minSdk\\s*=\\s*(\\d+)/);\n if (!namespace) throw new DetectionError(`Could not read android.namespace from ${appBuildKts}.`);\n if (!applicationId) throw new DetectionError(`Could not read defaultConfig.applicationId from ${appBuildKts}.`);\n if (!minSdkRaw) throw new DetectionError(`Could not read defaultConfig.minSdk from ${appBuildKts}.`);\n const minSdk = Number(minSdkRaw);\n\n const manifestPath = join(projectRoot, 'app', 'src', 'main', 'AndroidManifest.xml');\n if (!(await fileExists(manifestPath))) {\n throw new DetectionError(`Missing AndroidManifest.xml at ${manifestPath}.`);\n }\n\n const packageDotPath = applicationId.replace(/\\./g, '/');\n const kotlinRoot = join(projectRoot, 'app', 'src', 'main', 'kotlin', packageDotPath);\n const javaRoot = join(projectRoot, 'app', 'src', 'main', 'java', packageDotPath);\n let packageSrcRoot: 'kotlin' | 'java';\n let packagePath: string;\n if (await fileExists(kotlinRoot)) {\n packageSrcRoot = 'kotlin';\n packagePath = kotlinRoot;\n } else if (await fileExists(javaRoot)) {\n packageSrcRoot = 'java';\n packagePath = javaRoot;\n } else {\n // Default to kotlin/ if neither exists — we'll create it.\n packageSrcRoot = 'kotlin';\n packagePath = kotlinRoot;\n }\n\n const hasHilt =\n /dagger\\.hilt|hilt\\.android|@HiltAndroidApp/.test(appBuildSource) ||\n (await searchForHilt(projectRoot));\n\n const manifestSource = await readFile(manifestPath, 'utf-8');\n // Scope the regex to the <application> tag only — the activity's\n // android:name attribute lives inside <activity> and must not be\n // mistaken for an Application subclass.\n const appTagMatch = /<application\\b([^>]*)>/.exec(manifestSource);\n const appTagAttrs = appTagMatch ? appTagMatch[1] ?? '' : '';\n const applicationNameAttr = matchOne(appTagAttrs, /android:name\\s*=\\s*\"([.\\w]+)\"/);\n const existingApplicationClassFq = applicationNameAttr\n ? applicationNameAttr.startsWith('.')\n ? applicationId + applicationNameAttr\n : applicationNameAttr\n : null;\n\n const mainActivityCandidates = await glob('app/src/main/{java,kotlin}/**/MainActivity.kt', {\n cwd: projectRoot,\n absolute: true,\n onlyFiles: true,\n });\n const existingMainActivityPath = mainActivityCandidates[0] ?? null;\n\n const rootBuildKts = join(projectRoot, 'build.gradle.kts');\n const rootBuildGradlePath = (await fileExists(rootBuildKts)) ? rootBuildKts : null;\n\n const versionCatalog = join(projectRoot, 'gradle', 'libs.versions.toml');\n const versionCatalogPath = (await fileExists(versionCatalog)) ? versionCatalog : null;\n\n return {\n projectRoot,\n appModulePath: join(projectRoot, 'app'),\n appModuleRelative: 'app',\n buildGradleKtsPath: appBuildKts,\n manifestPath,\n namespace,\n applicationId,\n minSdk,\n packagePath,\n packageSrcRoot,\n hasHilt,\n existingApplicationClassFq,\n existingMainActivityPath,\n rootSettingsPath: rootSettings,\n rootBuildGradlePath,\n versionCatalogPath,\n };\n}\n\nfunction matchOne(source: string, re: RegExp): string | null {\n const m = re.exec(source);\n return m && m[1] !== undefined ? m[1] : null;\n}\n\nasync function searchForHilt(projectRoot: string): Promise<boolean> {\n const matches = await glob('app/src/main/**/*.kt', {\n cwd: projectRoot,\n absolute: true,\n onlyFiles: true,\n });\n for (const f of matches) {\n const content = await readFile(f, 'utf-8').catch(() => '');\n if (/dagger\\.hilt|@HiltAndroidApp/.test(content)) return true;\n }\n return false;\n}\n","import { join, relative } from 'node:path';\nimport { access } from 'node:fs/promises';\nimport { getKetoyVersion } from '../../lib/ketoy-version.js';\n// REMOVABLE (alpha pinning) — see src/alpha-pins.ts header for the deletion checklist.\nimport { ALPHA_PINS } from '../../alpha-pins.js';\nimport type { ProjectDetection } from './detect.js';\n\nexport type InitActionKind =\n | 'insert-plugin'\n | 'append-deps'\n | 'append-block'\n | 'set-manifest-name'\n | 'write-file'\n | 'wrap-main-activity'\n | 'gitignore'\n | 'ensure-toml-plugin'\n | 'insert-plugin-alias'\n | 'bump-java-compatibility'\n // REMOVABLE (alpha pinning) — see src/alpha-pins.ts header.\n | 'pin-alpha-versions'\n | 'agp8-compat'\n | 'ensure-gradle-property';\n\nexport interface InitAction {\n kind: InitActionKind;\n description: string;\n targetRel: string;\n payload?: Record<string, unknown>;\n highRisk?: boolean;\n}\n\nexport interface InitPlan {\n actions: InitAction[];\n warnings: string[];\n}\n\nasync function fileExists(p: string): Promise<boolean> {\n try {\n await access(p);\n return true;\n } catch {\n return false;\n }\n}\n\nconst COMPILER_PLUGIN_ID = 'dev.ketoy.compiler';\nconst APP_CLASS = 'MyApplication';\nconst SCREEN_ENTRY_POINT = 'HelloKetoyScreen';\nconst BUNDLE_ASSET = 'ketoy/main.ktx';\n\nexport interface PlanInitOptions {\n /** Whether to wrap MainActivity's setContent body with KetoyScreen. */\n installKetoyScreen: boolean;\n}\n\nexport async function planInit(\n detection: ProjectDetection,\n planOptions: PlanInitOptions = { installKetoyScreen: true },\n): Promise<InitPlan> {\n const warnings: string[] = [];\n const actions: InitAction[] = [];\n\n // Resolve the target Ketoy version once up-front so every plan entry shares\n // the same string. Throws NoInternetError if the endpoint is unreachable.\n const ketoyVersion = await getKetoyVersion();\n\n if (detection.minSdk < 26) {\n warnings.push(\n `Project minSdk is ${detection.minSdk}; Ketoy requires API 26+. Bump minSdk to 26 (or higher) in app/build.gradle.kts before continuing.`,\n );\n }\n\n const root = detection.projectRoot;\n const appBuildRel = relative(root, detection.buildGradleKtsPath);\n const manifestRel = relative(root, detection.manifestPath);\n const pkg = detection.applicationId;\n const pkgDirRel = relative(root, detection.packagePath);\n\n // ── 0. Alpha-period version pins (REMOVABLE — see src/alpha-pins.ts) ──\n //\n // Ketoy 0.3.x's compiler plugin is bound to specific Kotlin/AGP/Compose\n // BOM versions. Pin the user's `gradle/libs.versions.toml` to those\n // versions if a version catalog is present; otherwise warn.\n const versionCatalogRel = 'gradle/libs.versions.toml';\n const versionCatalogPath = join(root, versionCatalogRel);\n if (await fileExists(versionCatalogPath)) {\n const labels = ALPHA_PINS.map((p) => `${p.label}=${p.required}`).join(', ');\n actions.push({\n kind: 'pin-alpha-versions',\n description: `Pin alpha-required versions in ${versionCatalogRel}: ${labels}`,\n targetRel: versionCatalogRel,\n payload: { pins: ALPHA_PINS },\n highRisk: true,\n });\n } else {\n const labels = ALPHA_PINS.map((p) => `${p.label} ${p.required}`).join(', ');\n warnings.push(\n `No gradle/libs.versions.toml found — verify your project uses ${labels} manually. ` +\n `Ketoy 0.3.x will not build against newer Kotlin/AGP/Compose. This pinning requirement is temporary and goes away with ADR-0004.`,\n );\n }\n\n // ── 0a-bis. android.useAndroidX flag (REMOVABLE — see src/alpha-pins.ts) ──\n //\n // AGP 8.7 enforces the AndroidX flag explicitly when it sees AndroidX\n // dependencies; AS Iguana+ projects often omit it because AGP 9 defaults\n // to true. Set it in gradle.properties so the AGP-8.7-pinned build succeeds.\n actions.push({\n kind: 'ensure-gradle-property',\n description: 'Ensure android.useAndroidX=true in gradle.properties (required by AGP 8.7)',\n targetRel: 'gradle.properties',\n payload: { key: 'android.useAndroidX', value: 'true' },\n highRisk: true,\n });\n actions.push({\n kind: 'ensure-gradle-property',\n description: 'Ensure android.enableJetifier=false in gradle.properties',\n targetRel: 'gradle.properties',\n payload: { key: 'android.enableJetifier', value: 'false' },\n highRisk: true,\n });\n\n // ── 0b. AGP-8.x compatibility (REMOVABLE — see src/alpha-pins.ts) ──\n //\n // AGP 8.7 (the version we pin to for the alpha) doesn't recognise the\n // block-style `compileSdk { version = release(N) ... }` DSL that Android\n // Studio Ladybug+ generates. Rewrite it to `compileSdk = N` so the build\n // accepts AGP 8.x.\n actions.push({\n kind: 'agp8-compat',\n description: `Rewrite block-style compileSdk { ... } in ${appBuildRel} to the AGP-8.x property form (compileSdk = N)`,\n targetRel: appBuildRel,\n highRisk: true,\n });\n\n // ── 0c. Kotlin Android plugin — required for Ketoy to compile Kotlin\n // sources in the app module against pinned Kotlin 2.0.21 + AGP 8.7.\n // Three sub-edits: TOML plugin entry, root build.gradle.kts alias\n // with `apply false`, app build.gradle.kts alias.\n if (detection.versionCatalogPath) {\n actions.push({\n kind: 'ensure-toml-plugin',\n description: `Add kotlin-android plugin to [plugins] in gradle/libs.versions.toml`,\n targetRel: relative(root, detection.versionCatalogPath),\n payload: {\n key: 'kotlin-android',\n id: 'org.jetbrains.kotlin.android',\n versionRef: 'kotlin',\n },\n highRisk: true,\n });\n } else {\n warnings.push(\n 'No gradle/libs.versions.toml found — add the kotlin-android plugin alias manually.',\n );\n }\n\n if (detection.rootBuildGradlePath) {\n actions.push({\n kind: 'insert-plugin-alias',\n description: `Declare alias(libs.plugins.kotlin.android) apply false in root build.gradle.kts`,\n targetRel: relative(root, detection.rootBuildGradlePath),\n payload: {\n aliasPath: 'libs.plugins.kotlin.android',\n applyFalse: true,\n },\n highRisk: true,\n });\n } else {\n warnings.push(\n 'No root build.gradle.kts — add `alias(libs.plugins.kotlin.android) apply false` manually.',\n );\n }\n\n actions.push({\n kind: 'insert-plugin-alias',\n description: `Insert alias(libs.plugins.kotlin.android) into plugins { } in ${appBuildRel}`,\n targetRel: appBuildRel,\n payload: {\n aliasPath: 'libs.plugins.kotlin.android',\n applyFalse: false,\n },\n highRisk: true,\n });\n\n // ── 1. Plugin: id(\"dev.ketoy.compiler\") version \"0.3.4-alpha\" ─────────\n actions.push({\n kind: 'insert-plugin',\n description: `Insert id(\"${COMPILER_PLUGIN_ID}\") version \"${ketoyVersion}\" into plugins { } in ${appBuildRel}`,\n targetRel: appBuildRel,\n payload: { pluginId: COMPILER_PLUGIN_ID, version: ketoyVersion },\n highRisk: true,\n });\n\n // ── 2. Dependencies: BOM + runtime + annotations + capabilities + adapters ─\n const deps = [\n { configuration: 'implementation', notation: `platform(\"dev.ketoy.vm:ketoy-bom:${ketoyVersion}\")` },\n { configuration: 'implementation', notation: `\"dev.ketoy.vm:ketoy-runtime\"` },\n { configuration: 'implementation', notation: `\"dev.ketoy.vm:ketoy-annotations\"` },\n { configuration: 'implementation', notation: `\"dev.ketoy.vm:ketoy-capabilities-core\"` },\n { configuration: 'implementation', notation: `\"dev.ketoy.vm:ketoy-capabilities-navigation\"` },\n { configuration: 'implementation', notation: `\"dev.ketoy.vm:ketoy-adapters-material3\"` },\n ];\n actions.push({\n kind: 'append-deps',\n description: `Append Ketoy ${ketoyVersion} dependencies to dependencies { } in ${appBuildRel}`,\n targetRel: appBuildRel,\n payload: { groupComment: `Ketoy ${ketoyVersion}`, entries: deps },\n highRisk: true,\n });\n\n // ── 3. ketoy { } block ─────────────────────────────────────────────\n const ketoyBlockBody = [\n '// ADR-0003 inline-source app bundle: compile the @KetoyComposable',\n '// closure inside this module into ONE signed .ktx at compileReleaseKotlin.',\n 'exportFromAppModule.set(true)',\n 'bundleId.set(\"main\")',\n 'bundleVariant.set(\"release\")',\n 'capabilityRegistryFile.set(file(\"ketoy-capabilities.json\"))',\n '// minimum host APK versionCode required to activate this bundle.',\n '// 0 = universally compatible (default).',\n 'minAppVersion.set(0)',\n '// Emit source line numbers for the dev overlay.',\n 'debugMode.set(true)',\n '',\n '// Optional: sign the bundle with Ed25519. Generate via:',\n '// openssl genpkey -algorithm Ed25519 -outform DER -out key.der',\n '// tail -c 32 key.der > app/keys/release-private.key',\n '// Without a key the plugin emits an unsigned bundle gracefully.',\n 'val signingKey = file(\"keys/release-private.key\")',\n 'if (signingKey.exists()) {',\n ' signingKeyFile.set(signingKey)',\n '}',\n ].join('\\n');\n actions.push({\n kind: 'append-block',\n description: `Append ketoy { ... } block to ${appBuildRel}`,\n targetRel: appBuildRel,\n payload: { blockName: 'ketoy', body: ketoyBlockBody },\n highRisk: true,\n });\n\n // ── 3b. JVM 17 compatibility — Kotlin 2.0.21 + Compose Compiler 1.5+\n // defaults to JVM target 17. Bump compileOptions if currently lower\n // and add the top-level kotlin { compilerOptions { jvmTarget } } block\n // so `compileReleaseKotlin` targets JVM 17 (the KetoyBC compiler\n // plugin's runtime expectation).\n actions.push({\n kind: 'bump-java-compatibility',\n description: `Set compileOptions.{source,target}Compatibility to JavaVersion.VERSION_17 in ${appBuildRel}`,\n targetRel: appBuildRel,\n payload: { minLevel: 17 },\n highRisk: true,\n });\n\n const kotlinBlockBody = [\n 'compilerOptions {',\n ' jvmTarget.set(org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_17)',\n '}',\n ].join('\\n');\n actions.push({\n kind: 'append-block',\n description: `Append kotlin { compilerOptions { jvmTarget = JVM_17 } } block to ${appBuildRel}`,\n targetRel: appBuildRel,\n payload: { blockName: 'kotlin', body: kotlinBlockBody },\n highRisk: true,\n });\n\n // ── 4. AndroidManifest.xml: android:name ──────────────────────────\n if (detection.existingApplicationClassFq) {\n warnings.push(\n `Existing Application class detected: ${detection.existingApplicationClassFq}. ` +\n `We will NOT touch the manifest's android:name. Integrate the Ketoy runtime + bundle loader bootstrap into your existing Application class manually — see the new ${APP_CLASS}.kt example we will write next to it for the canonical setup.`,\n );\n actions.push({\n kind: 'write-file',\n description: `Create reference ${join(pkgDirRel, `${APP_CLASS}.kt`)} (alongside your existing Application — copy bootstrap code into yours)`,\n targetRel: join(pkgDirRel, `${APP_CLASS}.kt`),\n payload: { template: 'MyApplication.kt.tmpl', vars: { PACKAGE: pkg } },\n });\n } else {\n actions.push({\n kind: 'set-manifest-name',\n description: `Set android:name=\".${APP_CLASS}\" on <application> in ${manifestRel}`,\n targetRel: manifestRel,\n payload: { value: `.${APP_CLASS}` },\n highRisk: true,\n });\n actions.push({\n kind: 'write-file',\n description: `Create ${join(pkgDirRel, `${APP_CLASS}.kt`)} (KetoyRuntime + KetoyConfig + adapter registration + bundle loader)`,\n targetRel: join(pkgDirRel, `${APP_CLASS}.kt`),\n payload: { template: 'MyApplication.kt.tmpl', vars: { PACKAGE: pkg } },\n });\n }\n\n // ── 5. MainActivity ─────────────────────────────────────────────────\n if (detection.existingMainActivityPath) {\n if (planOptions.installKetoyScreen) {\n const maRel = relative(root, detection.existingMainActivityPath);\n actions.push({\n kind: 'wrap-main-activity',\n description: `Install KetoyScreen + simple Hello Android fallback inside the theme block in ${maRel}`,\n targetRel: maRel,\n payload: {\n packageOfApp: pkg,\n appClassSimpleName: APP_CLASS,\n entryPoint: SCREEN_ENTRY_POINT,\n bundleAsset: BUNDLE_ASSET,\n },\n highRisk: true,\n });\n } else {\n warnings.push(\n 'Skipping MainActivity edit (declined). Integrate KetoyScreen manually — see the snippet printed at the end of init, https://ketoy.dev/docs, or run `ketoy chat`.',\n );\n }\n } else if (planOptions.installKetoyScreen) {\n actions.push({\n kind: 'write-file',\n description: `Create ${join(pkgDirRel, 'MainActivity.kt')}`,\n targetRel: join(pkgDirRel, 'MainActivity.kt'),\n payload: { template: 'MainActivity.kt.tmpl', vars: { PACKAGE: pkg } },\n });\n } else {\n warnings.push(\n 'No MainActivity.kt found and KetoyScreen install declined — you must create one manually. See `ketoy chat` or the docs.',\n );\n }\n\n // ── 6. Sample @KetoyComposable screen ──────────────────────────────\n actions.push({\n kind: 'write-file',\n description: `Create ${join(pkgDirRel, `${SCREEN_ENTRY_POINT}.kt`)}`,\n targetRel: join(pkgDirRel, `${SCREEN_ENTRY_POINT}.kt`),\n payload: { template: 'HelloKetoyScreen.kt.tmpl', vars: { PACKAGE: pkg } },\n });\n\n // ── 7. Capability registry JSON ────────────────────────────────────\n actions.push({\n kind: 'write-file',\n description: `Create app/ketoy-capabilities.json`,\n targetRel: 'app/ketoy-capabilities.json',\n payload: { template: 'ketoy-capabilities.json.tmpl', vars: { PACKAGE: pkg } },\n });\n\n // ── 8. .gitignore ──────────────────────────────────────────────────\n actions.push({\n kind: 'gitignore',\n description: 'Add `**/keys/*-private.key` to .gitignore',\n targetRel: '.gitignore',\n payload: { entries: ['**/keys/*-private.key'] },\n });\n\n // Drop write-file actions whose target already exists; convert to warnings.\n const finalActions: InitAction[] = [];\n for (const a of actions) {\n if (a.kind === 'write-file') {\n const abs = join(root, a.targetRel);\n if (await fileExists(abs)) {\n warnings.push(`File already exists, skipping: ${a.targetRel}`);\n continue;\n }\n }\n finalActions.push(a);\n }\n\n return { actions: finalActions, warnings };\n}\n","/**\n * Alpha-period version pins.\n *\n * Ketoy 0.3.x's compiler plugin is built against a specific Kotlin / AGP /\n * Compose BOM combination and won't load against arbitrary newer versions.\n * The alpha requires consumers' `gradle/libs.versions.toml` to declare these\n * EXACT versions:\n *\n * - Kotlin 2.0.21 (compiler plugin pinned here)\n * - AGP 8.7.0 (any 8.x with Kotlin 2.0.21 support)\n * - Compose BOM 2024.10.00\n *\n * These pins are temporary. When Ketoy ships the ADR-0004 embedded-compiler\n * (Phase 12 — Ketoy bundles its own Kotlin compiler internally and decouples\n * from the consumer's), the consumer's Kotlin / Compose / AGP versions\n * become free again, and these pins go away.\n *\n * ─── REMOVAL CHECKLIST (when alpha pinning ends) ─────────────────────────\n * Every removable spot carries this comment:\n *\n * // REMOVABLE (alpha pinning) — see src/alpha-pins.ts header for ...\n *\n * Run `grep -rn \"REMOVABLE (alpha pinning)\" src/` to enumerate them.\n *\n * Concretely:\n * 1. Delete this file (`src/alpha-pins.ts`).\n * 2. Delete `src/safe-edit/agp8-compat.ts` (AGP-8.x compileSdk block-style\n * compatibility transform — no longer needed when AGP isn't pinned).\n * 3. In `src/commands/init/plan.ts`:\n * - remove the `alpha-pins.js` import\n * - remove `'pin-alpha-versions'` and `'agp8-compat'` from the\n * `InitActionKind` union\n * - remove the corresponding action pushes (search for the\n * REMOVABLE comment marker)\n * 4. In `src/commands/init/edit.ts`:\n * - remove imports for `version-catalog.js` and `agp8-compat.js`\n * - remove the `pin-alpha-versions` and `agp8-compat` switch cases\n *\n * `src/safe-edit/version-catalog.ts` can stay — it's a general TOML editor\n * with no alpha-specific logic, useful for any future catalog tweak.\n * ─────────────────────────────────────────────────────────────────────────\n */\n\nexport interface AlphaPin {\n /** Canonical key name we write into [versions] if no alias is found. */\n key: string;\n /** Exact required version. */\n required: string;\n /** Alternate key spellings the user's TOML might already use. */\n aliases: string[];\n /** Human label for plan / log output. */\n label: string;\n}\n\nexport const ALPHA_PINS: readonly AlphaPin[] = [\n // ── Compiler/toolchain ─────────────────────────────────────────────\n {\n key: 'kotlin',\n required: '2.0.21',\n aliases: ['kotlin', 'kotlinVersion'],\n label: 'Kotlin',\n },\n {\n key: 'agp',\n required: '8.13.2',\n aliases: ['agp', 'androidGradlePlugin', 'gradlePlugin'],\n label: 'Android Gradle Plugin',\n },\n {\n key: 'composeBom',\n required: '2024.10.00',\n aliases: ['composeBom', 'compose-bom', 'composeBomVersion'],\n label: 'Jetpack Compose BOM',\n },\n // ── AndroidX libraries — newer releases require AGP 8.9+, which\n // breaks against our pinned AGP. Pin to the latest release that\n // works with AGP 8.13.x. Versions track KetoyVMTest's catalog.\n {\n key: 'coreKtx',\n required: '1.13.1',\n aliases: ['coreKtx', 'core-ktx', 'androidxCoreKtx'],\n label: 'androidx.core:core-ktx',\n },\n {\n key: 'lifecycleRuntimeKtx',\n required: '2.8.6',\n aliases: ['lifecycleRuntimeKtx', 'lifecycle-runtime-ktx', 'androidxLifecycle'],\n label: 'androidx.lifecycle:lifecycle-runtime-ktx',\n },\n {\n key: 'activityCompose',\n required: '1.9.3',\n aliases: ['activityCompose', 'activity-compose', 'androidxActivityCompose'],\n label: 'androidx.activity:activity-compose',\n },\n {\n key: 'junitVersion',\n required: '1.2.1',\n aliases: ['junitVersion', 'androidxJunit', 'androidx-junit', 'androidxJunitExt'],\n label: 'androidx.test.ext:junit',\n },\n {\n key: 'espressoCore',\n required: '3.6.1',\n aliases: ['espressoCore', 'espresso-core', 'androidxEspresso'],\n label: 'androidx.test.espresso:espresso-core',\n },\n];\n\nexport const ALPHA_PIN_DOC_URL = 'https://ketoy.dev/docs/getting-started/#prerequisites';\n","import { mkdir, writeFile } from 'node:fs/promises';\nimport { dirname, join } from 'node:path';\nimport {\n insertPlugin,\n insertPluginAlias,\n appendDependencyGroup,\n appendTopLevelBlock,\n bumpJavaCompatibility,\n type DependencyEntry,\n} from '../../safe-edit/gradle-kts.js';\nimport { setApplicationName } from '../../safe-edit/manifest-xml.js';\nimport { ensureGitignoreEntries } from '../../safe-edit/gitignore.js';\nimport { wrapMainActivityWithKetoyScreen } from '../../safe-edit/main-activity-wrap.js';\n// REMOVABLE (alpha pinning) — see src/alpha-pins.ts header for the deletion checklist.\nimport {\n applyVersionPins,\n ensurePluginEntry,\n type VersionPin,\n} from '../../safe-edit/version-catalog.js';\n// REMOVABLE (alpha pinning) — see src/alpha-pins.ts header for the deletion checklist.\nimport { migrateAgp8AndroidBlock } from '../../safe-edit/agp8-compat.js';\n// REMOVABLE (alpha pinning) — see src/alpha-pins.ts header for the deletion checklist.\nimport { ensureGradleProperty } from '../../safe-edit/gradle-properties.js';\nimport { loadTemplate } from '../../templates.js';\nimport { log, pc } from '../../lib/log.js';\nimport type { InitAction, InitPlan } from './plan.js';\n\nexport interface ApplyResult {\n appliedCount: number;\n skipped: string[];\n errors: string[];\n}\n\nexport async function applyPlan(projectRoot: string, plan: InitPlan): Promise<ApplyResult> {\n const result: ApplyResult = { appliedCount: 0, skipped: [], errors: [] };\n let step = 0;\n const total = plan.actions.length;\n for (const action of plan.actions) {\n step++;\n log.step(step, total, action.description);\n try {\n const ok = await applyAction(projectRoot, action);\n if (ok) result.appliedCount++;\n else result.skipped.push(action.description);\n } catch (e) {\n const msg = `${action.description}: ${(e as Error).message}`;\n result.errors.push(msg);\n log.error(msg);\n }\n }\n return result;\n}\n\nasync function applyAction(projectRoot: string, action: InitAction): Promise<boolean> {\n const target = join(projectRoot, action.targetRel);\n switch (action.kind) {\n case 'insert-plugin': {\n const { pluginId, version } = action.payload as { pluginId: string; version?: string };\n const { changed } = await insertPlugin(target, pluginId, version ? { version } : {});\n if (!changed) log.detail('Already applied; skipping.');\n return changed;\n }\n case 'append-deps': {\n const { groupComment, entries } = action.payload as {\n groupComment: string;\n entries: DependencyEntry[];\n };\n const { changed, addedCount } = await appendDependencyGroup(target, groupComment, entries);\n if (!changed) log.detail('All dependencies already declared; skipping.');\n else log.detail(`Added ${addedCount} dependency entries.`);\n return changed;\n }\n case 'append-block': {\n const { blockName, body } = action.payload as { blockName: string; body: string };\n const { changed } = await appendTopLevelBlock(target, blockName, body);\n if (!changed) log.detail(`${blockName} { } block already present; skipping.`);\n return changed;\n }\n case 'set-manifest-name': {\n const { value } = action.payload as { value: string };\n const { changed, previousValue } = await setApplicationName(target, value);\n if (!changed) log.detail('Already set; skipping.');\n else if (previousValue) log.detail(`Replaced previous value: ${previousValue}`);\n return changed;\n }\n case 'write-file': {\n const { template, vars } = action.payload as { template: string; vars: Record<string, string> };\n const content = await loadTemplate(template, vars);\n await mkdir(dirname(target), { recursive: true });\n await writeFile(target, content, 'utf-8');\n return true;\n }\n case 'wrap-main-activity': {\n const { packageOfApp, appClassSimpleName, entryPoint, bundleAsset } = action.payload as {\n packageOfApp: string;\n appClassSimpleName: string;\n entryPoint: string;\n bundleAsset: string;\n };\n const result = await wrapMainActivityWithKetoyScreen(target, {\n packageOfApp,\n appClassSimpleName,\n entryPoint,\n bundleAsset,\n });\n if (!result.changed) {\n log.detail(result.reason ?? 'No change needed.');\n return false;\n }\n return true;\n }\n case 'gitignore': {\n const { entries } = action.payload as { entries: string[] };\n const { added } = await ensureGitignoreEntries(target, entries);\n if (added.length === 0) {\n log.detail('All entries already present; skipping.');\n return false;\n }\n log.detail(`Added: ${added.join(', ')}`);\n return true;\n }\n case 'ensure-toml-plugin': {\n const { key, id, versionRef } = action.payload as {\n key: string;\n id: string;\n versionRef: string;\n };\n const { changed, reason } = await ensurePluginEntry(target, { key, id, versionRef });\n if (!changed) {\n log.detail(reason ?? 'Already declared; skipping.');\n return false;\n }\n log.detail(`Added: ${key} = { id = \"${id}\", version.ref = \"${versionRef}\" }`);\n return true;\n }\n case 'insert-plugin-alias': {\n const { aliasPath, applyFalse } = action.payload as {\n aliasPath: string;\n applyFalse: boolean;\n };\n const { changed } = await insertPluginAlias(target, aliasPath, { applyFalse });\n if (!changed) {\n log.detail('Already applied; skipping.');\n return false;\n }\n log.detail(`Added: alias(${aliasPath})${applyFalse ? ' apply false' : ''}`);\n return true;\n }\n case 'bump-java-compatibility': {\n const { minLevel } = action.payload as { minLevel: number };\n const { changed, rewrites } = await bumpJavaCompatibility(target, minLevel);\n if (!changed) {\n log.detail(`compileOptions already at JavaVersion.VERSION_${minLevel} or higher; skipping.`);\n return false;\n }\n for (const r of rewrites) log.detail(r);\n return true;\n }\n // REMOVABLE (alpha pinning) — see src/alpha-pins.ts header for the deletion checklist.\n case 'ensure-gradle-property': {\n const { key, value } = action.payload as { key: string; value: string };\n const result = await ensureGradleProperty(target, key, value);\n if (result.conflict) {\n log.detail(\n `${key} already set to \"${result.previousValue}\" — leaving alone (requested \"${value}\"). Verify this is intentional.`,\n );\n return false;\n }\n if (!result.changed) {\n log.detail(`${key}=${value} already set; skipping.`);\n return false;\n }\n log.detail(`Added: ${key}=${value}`);\n return true;\n }\n // REMOVABLE (alpha pinning) — see src/alpha-pins.ts header for the deletion checklist.\n case 'agp8-compat': {\n const { mutations, changed } = await migrateAgp8AndroidBlock(target);\n if (!changed) {\n log.detail('Already in AGP-8.x property form; skipping.');\n return false;\n }\n for (const m of mutations) {\n const minor = m.droppedMinor ? pc.dim(' (dropped minorApiLevel — AGP 8.x has no equivalent)') : '';\n log.detail(`${m.property}: block-style → ${m.property} = ${m.apiLevel}${minor}`);\n }\n return true;\n }\n // REMOVABLE (alpha pinning) — see src/alpha-pins.ts header for the deletion checklist.\n case 'pin-alpha-versions': {\n const { pins } = action.payload as { pins: readonly VersionPin[] };\n const results = await applyVersionPins(target, pins);\n let changed = false;\n for (const r of results) {\n const label = r.label ?? r.key;\n if (r.action === 'unchanged') {\n log.detail(`${label}: already at ${r.required}.`);\n } else if (r.action === 'pinned') {\n changed = true;\n log.detail(`${label}: ${pc.yellow(r.oldValue ?? '?')} → ${pc.green(r.required)}`);\n } else {\n changed = true;\n log.detail(`${label}: added ${r.key} = ${pc.green(r.required)}`);\n }\n }\n return changed;\n }\n default: {\n const exhaustive: never = action.kind;\n throw new Error(`Unhandled action kind: ${String(exhaustive)}`);\n }\n }\n}\n","import { readFile, writeFile } from 'node:fs/promises';\n\n/**\n * Regex-driven surgical editor for `build.gradle.kts`.\n *\n * Kotlin DSL is brace-balanced; we locate the *first* matching top-level block\n * (plugins, dependencies) by scanning braces from the keyword, then insert\n * before the closing brace. Appended blocks always go at file end after a\n * blank line. Every helper is idempotent.\n */\n\nfunction findBlockBounds(source: string, header: RegExp): { open: number; close: number } | null {\n const m = header.exec(source);\n if (!m) return null;\n const headerEnd = m.index + m[0].length;\n // m[0] ends with \"{\"; depth starts at 1.\n let depth = 1;\n let i = headerEnd;\n while (i < source.length && depth > 0) {\n const ch = source[i];\n if (ch === '{') depth++;\n else if (ch === '}') depth--;\n if (depth === 0) return { open: headerEnd, close: i };\n i++;\n }\n return null;\n}\n\nfunction indentationOf(line: string): string {\n const m = /^[ \\t]*/.exec(line);\n return m ? m[0] : '';\n}\n\nfunction insertInsideBlock(source: string, open: number, close: number, body: string): string {\n // Locate the line at `close` to mirror its indentation for the trailing newline.\n const before = source.slice(0, close);\n const after = source.slice(close);\n const lastNewline = before.lastIndexOf('\\n');\n const closingLine = lastNewline >= 0 ? before.slice(lastNewline + 1) : before;\n const baseIndent = indentationOf(closingLine);\n const lineIndent = baseIndent + ' ';\n const indented = body\n .split('\\n')\n .map((l) => (l.length === 0 ? l : lineIndent + l))\n .join('\\n');\n const needsLeadingNewline = lastNewline === -1 || before[before.length - 1] !== '\\n';\n const prefix = needsLeadingNewline ? '\\n' : '';\n return source.slice(0, close) + prefix + indented + '\\n' + baseIndent + after.slice(0);\n}\n\nexport async function pluginIsApplied(path: string, pluginId: string): Promise<boolean> {\n const source = await readFile(path, 'utf-8');\n return new RegExp(`id\\\\s*\\\\(\\\\s*\"${pluginId.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')}\"\\\\s*\\\\)`).test(source);\n}\n\nexport interface InsertPluginOptions {\n /**\n * Optional version string. When supplied, the plugin line is rendered as\n * `id(\"...\") version \"X\"` — required for plugins resolved through the\n * Gradle Plugin Portal rather than a `pluginManagement.includeBuild` /\n * `libs.versions.toml` reference.\n */\n version?: string;\n}\n\nexport async function insertPlugin(\n path: string,\n pluginId: string,\n options: InsertPluginOptions = {},\n): Promise<{ changed: boolean }> {\n const source = await readFile(path, 'utf-8');\n if (new RegExp(`id\\\\s*\\\\(\\\\s*\"${pluginId.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')}\"\\\\s*\\\\)`).test(source)) {\n return { changed: false };\n }\n const bounds = findBlockBounds(source, /\\bplugins\\s*\\{/);\n if (!bounds) {\n throw new Error(`No top-level plugins { } block found in ${path}.`);\n }\n const line = options.version ? `id(\"${pluginId}\") version \"${options.version}\"` : `id(\"${pluginId}\")`;\n const updated = insertInsideBlock(source, bounds.open, bounds.close, line);\n await writeFile(path, updated, 'utf-8');\n return { changed: true };\n}\n\nexport interface DependencyEntry {\n configuration: string;\n notation: string;\n}\n\nexport async function dependenciesAreApplied(\n path: string,\n entries: DependencyEntry[],\n): Promise<boolean[]> {\n const source = await readFile(path, 'utf-8');\n return entries.map((e) => source.includes(e.notation));\n}\n\nexport async function appendDependencyGroup(\n path: string,\n groupComment: string,\n entries: DependencyEntry[],\n): Promise<{ changed: boolean; addedCount: number }> {\n const source = await readFile(path, 'utf-8');\n const bounds = findBlockBounds(source, /\\bdependencies\\s*\\{/);\n if (!bounds) {\n throw new Error(`No top-level dependencies { } block found in ${path}.`);\n }\n const missing = entries.filter((e) => !source.includes(e.notation));\n if (missing.length === 0) return { changed: false, addedCount: 0 };\n\n const lines = [`// ${groupComment}`];\n for (const e of missing) lines.push(`${e.configuration}(${e.notation})`);\n const body = lines.join('\\n');\n const updated = insertInsideBlock(source, bounds.open, bounds.close, body);\n await writeFile(path, updated, 'utf-8');\n return { changed: true, addedCount: missing.length };\n}\n\nexport async function topLevelBlockExists(path: string, blockName: string): Promise<boolean> {\n const source = await readFile(path, 'utf-8');\n return new RegExp(`(^|\\\\n)\\\\s*${blockName}\\\\s*\\\\{`).test(source);\n}\n\nexport async function appendTopLevelBlock(\n path: string,\n blockName: string,\n body: string,\n): Promise<{ changed: boolean }> {\n if (await topLevelBlockExists(path, blockName)) return { changed: false };\n const source = await readFile(path, 'utf-8');\n const trimmed = source.replace(/\\s+$/, '');\n const block = `${blockName} {\\n${body\n .split('\\n')\n .map((l) => (l.length === 0 ? l : ' ' + l))\n .join('\\n')}\\n}\\n`;\n await writeFile(path, trimmed + '\\n\\n' + block, 'utf-8');\n return { changed: true };\n}\n\n/**\n * Read `minSdk` from `defaultConfig { minSdk = N }`. Returns null when not found.\n */\nexport async function readMinSdk(path: string): Promise<number | null> {\n const source = await readFile(path, 'utf-8');\n const m = /minSdk\\s*=\\s*(\\d+)/.exec(source);\n return m ? Number(m[1]) : null;\n}\n\n/**\n * Insert `alias(<aliasPath>)` into the existing `plugins { }` block. When\n * `applyFalse` is true the line is rendered as `alias(<aliasPath>) apply false`\n * — the standard pattern for the root build.gradle.kts where plugins are\n * declared but not applied at root.\n *\n * Idempotent: checks for an existing alias() with the same path.\n */\nexport async function insertPluginAlias(\n path: string,\n aliasPath: string,\n options: { applyFalse?: boolean } = {},\n): Promise<{ changed: boolean }> {\n const source = await readFile(path, 'utf-8');\n const escaped = aliasPath.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n if (new RegExp(`alias\\\\s*\\\\(\\\\s*${escaped}\\\\s*\\\\)`).test(source)) {\n return { changed: false };\n }\n const bounds = findBlockBounds(source, /\\bplugins\\s*\\{/);\n if (!bounds) {\n throw new Error(`No top-level plugins { } block found in ${path}.`);\n }\n const line = options.applyFalse ? `alias(${aliasPath}) apply false` : `alias(${aliasPath})`;\n const updated = insertInsideBlock(source, bounds.open, bounds.close, line);\n await writeFile(path, updated, 'utf-8');\n return { changed: true };\n}\n\nconst JAVA_VERSION_NUM: Record<string, number> = {\n VERSION_1_8: 8,\n VERSION_9: 9,\n VERSION_10: 10,\n VERSION_11: 11,\n VERSION_12: 12,\n VERSION_13: 13,\n VERSION_14: 14,\n VERSION_15: 15,\n VERSION_16: 16,\n VERSION_17: 17,\n VERSION_18: 18,\n VERSION_19: 19,\n VERSION_20: 20,\n VERSION_21: 21,\n};\n\nexport interface JavaCompatBumpResult {\n changed: boolean;\n /** Lines that were rewritten; e.g. ['sourceCompatibility 11→17', ...] */\n rewrites: string[];\n}\n\n/**\n * Bump `compileOptions { sourceCompatibility / targetCompatibility }` to at\n * least the supplied minimum (numeric Java major). User-set values higher\n * than the minimum are preserved. If the `compileOptions { }` block exists\n * without these properties, they're appended.\n */\nexport async function bumpJavaCompatibility(\n path: string,\n minLevel: number,\n): Promise<JavaCompatBumpResult> {\n let source = await readFile(path, 'utf-8');\n const rewrites: string[] = [];\n\n for (const prop of ['sourceCompatibility', 'targetCompatibility'] as const) {\n const re = new RegExp(`(\\\\b${prop}\\\\s*=\\\\s*JavaVersion\\\\.)(VERSION_[\\\\w_]+)`);\n const m = re.exec(source);\n if (m && m[2]) {\n const currentName = m[2];\n const current = JAVA_VERSION_NUM[currentName] ?? null;\n if (current === null || current >= minLevel) continue;\n const newName = `VERSION_${minLevel}`;\n source = source.slice(0, m.index) + m[1] + newName + source.slice(m.index + m[0].length);\n rewrites.push(`${prop} ${currentName} → ${newName}`);\n }\n }\n\n // If the compileOptions block exists but lacks one or both properties,\n // append them. Detection: the block exists but no match was found above.\n const compileOptionsBlock = findBlockBounds(source, /\\bcompileOptions\\s*\\{/);\n if (compileOptionsBlock) {\n for (const prop of ['sourceCompatibility', 'targetCompatibility'] as const) {\n if (!new RegExp(`\\\\b${prop}\\\\s*=`).test(source.slice(compileOptionsBlock.open, compileOptionsBlock.close))) {\n const line = `${prop} = JavaVersion.VERSION_${minLevel}`;\n source = insertInsideBlock(source, compileOptionsBlock.open, compileOptionsBlock.close, line);\n rewrites.push(`added ${prop} = VERSION_${minLevel}`);\n const refreshed = findBlockBounds(source, /\\bcompileOptions\\s*\\{/);\n if (refreshed) {\n compileOptionsBlock.open = refreshed.open;\n compileOptionsBlock.close = refreshed.close;\n }\n }\n }\n }\n\n if (rewrites.length === 0) {\n return { changed: false, rewrites: [] };\n }\n await writeFile(path, source, 'utf-8');\n return { changed: true, rewrites };\n}\n","import { readFile, writeFile } from 'node:fs/promises';\nimport { XMLParser } from 'fast-xml-parser';\n\n/**\n * Surgical edits to AndroidManifest.xml. We avoid full XML re-serialization\n * (which loses comments, ordering, attribute whitespace) — instead use the\n * parser for inspection and apply tag-level regex edits for writes.\n */\n\nexport interface ManifestInspection {\n hasApplicationTag: boolean;\n applicationName: string | null;\n applicationPackage: string | null;\n}\n\nexport async function inspectManifest(path: string): Promise<ManifestInspection> {\n const source = await readFile(path, 'utf-8');\n const parser = new XMLParser({\n ignoreAttributes: false,\n attributeNamePrefix: '',\n allowBooleanAttributes: true,\n });\n const tree = parser.parse(source);\n const manifest = (tree as { manifest?: Record<string, unknown> }).manifest;\n if (!manifest) return { hasApplicationTag: false, applicationName: null, applicationPackage: null };\n\n const application = manifest['application'] as Record<string, unknown> | undefined;\n const name = (application?.['android:name'] as string | undefined) ?? null;\n const pkg = (manifest['package'] as string | undefined) ?? null;\n return { hasApplicationTag: application !== undefined, applicationName: name, applicationPackage: pkg };\n}\n\nexport interface ApplyApplicationNameResult {\n changed: boolean;\n previousValue: string | null;\n}\n\nconst APP_TAG_RE = /<application\\b([^>]*)>/;\n\nexport async function setApplicationName(\n path: string,\n androidName: string,\n): Promise<ApplyApplicationNameResult> {\n const source = await readFile(path, 'utf-8');\n const match = APP_TAG_RE.exec(source);\n if (!match) {\n throw new Error(`No <application> tag found in ${path}.`);\n }\n const tagAttrs = match[1] ?? '';\n const tagStart = match.index;\n const tagEnd = tagStart + match[0].length;\n\n const nameAttr = /\\bandroid:name\\s*=\\s*\"([^\"]*)\"/.exec(tagAttrs);\n if (nameAttr && nameAttr[1] === androidName) {\n return { changed: false, previousValue: nameAttr[1] };\n }\n\n let newAttrs: string;\n let previousValue: string | null;\n if (nameAttr) {\n previousValue = nameAttr[1] ?? null;\n newAttrs = tagAttrs.replace(\n /\\bandroid:name\\s*=\\s*\"[^\"]*\"/,\n `android:name=\"${androidName}\"`,\n );\n } else {\n previousValue = null;\n const trimmed = tagAttrs.replace(/\\s+$/, '');\n newAttrs = `${trimmed.length > 0 ? trimmed : ''}\\n android:name=\"${androidName}\"`;\n }\n const replacement = `<application${newAttrs}>`;\n const updated = source.slice(0, tagStart) + replacement + source.slice(tagEnd);\n await writeFile(path, updated, 'utf-8');\n return { changed: true, previousValue };\n}\n","import { readFile, writeFile, access } from 'node:fs/promises';\n\nasync function fileExists(path: string): Promise<boolean> {\n try {\n await access(path);\n return true;\n } catch {\n return false;\n }\n}\n\nexport async function ensureGitignoreEntries(\n path: string,\n entries: string[],\n): Promise<{ added: string[] }> {\n const exists = await fileExists(path);\n const source = exists ? await readFile(path, 'utf-8') : '';\n const lines = new Set(\n source.split('\\n').map((l) => l.trim()).filter((l) => l.length > 0 && !l.startsWith('#')),\n );\n const added = entries.filter((e) => !lines.has(e.trim()));\n if (added.length === 0) return { added: [] };\n const prefix = source.length === 0 || source.endsWith('\\n') ? '' : '\\n';\n const block = '\\n# Ketoy\\n' + added.join('\\n') + '\\n';\n await writeFile(path, source + prefix + block, 'utf-8');\n return { added };\n}\n","import { readFile, writeFile } from 'node:fs/promises';\nimport { addImport } from './kotlin-file.js';\n\n/**\n * Install `KetoyScreen` into `MainActivity.kt`'s `setContent { … }` block.\n *\n * Locates an existing theme block (matching `<Identifier>Theme { … }`,\n * typical Android Studio scaffold) inside `setContent` and replaces the\n * theme's body with:\n *\n * CompositionLocalProvider(\n * LocalKetoyRuntime provides app.ketoyRuntime,\n * LocalKetoyBundleLoader provides app.ketoyBundleLoader,\n * ) {\n * KetoyScreen(\n * entryPoint = \"...\",\n * bundleSource = KetoyBundleSource.Asset(\"...\"),\n * ) {\n * // simple \"Hello Android\" native fallback\n * }\n * }\n *\n * When no theme block is found, the snippet replaces the `setContent` body\n * directly (no theme wrapper). The user's pre-existing UI inside the theme\n * (e.g. `Scaffold { Greeting(...) }`) is dropped — that's why the init flow\n * gates this behind an opt-in prompt; users with custom MainActivity UI\n * decline and integrate manually.\n *\n * Adds the imports needed by the inserted snippet. Inserts\n * `val app = application as <AppClassName>` after `super.onCreate(...)`.\n *\n * Idempotent: detects the `LocalKetoyRuntime provides app.ketoyRuntime`\n * marker and bails if already wrapped.\n */\nexport interface WrapResult {\n changed: boolean;\n reason?: string;\n}\n\nconst MARKER = 'LocalKetoyRuntime provides app.ketoyRuntime';\n\nexport interface WrapOptions {\n packageOfApp: string;\n appClassSimpleName: string;\n entryPoint: string;\n bundleAsset: string;\n}\n\nexport async function wrapMainActivityWithKetoyScreen(\n path: string,\n options: WrapOptions,\n): Promise<WrapResult> {\n let source = await readFile(path, 'utf-8');\n if (source.includes(MARKER)) {\n return { changed: false, reason: 'Already wrapped' };\n }\n\n const setContentMatch = /setContent\\s*\\{/.exec(source);\n if (!setContentMatch) {\n return { changed: false, reason: 'No setContent { … } block found in MainActivity' };\n }\n const setContentOpen = setContentMatch.index + setContentMatch[0].length;\n const setContentClose = findMatchingBrace(source, setContentOpen);\n if (setContentClose === -1) {\n return { changed: false, reason: 'Could not balance braces in setContent { … }' };\n }\n\n // Detect an existing theme block (e.g. `KetoyCLIAPpTheme { … }`).\n const setContentBody = source.slice(setContentOpen, setContentClose);\n const themeRe = /\\b([A-Z][A-Za-z0-9_]*Theme)\\s*\\{/;\n const themeMatch = themeRe.exec(setContentBody);\n\n if (themeMatch) {\n const themeOpenAbs = setContentOpen + themeMatch.index + themeMatch[0].length;\n const themeCloseAbs = findMatchingBrace(source, themeOpenAbs);\n if (themeCloseAbs === -1) {\n return { changed: false, reason: 'Could not balance theme braces' };\n }\n const themeStartAbs = setContentOpen + themeMatch.index;\n const themeOuterIndent = lineIndentBefore(source, themeStartAbs);\n const themeBodyIndent = themeOuterIndent + ' ';\n const snippet = buildKetoyScreenSnippet(themeBodyIndent, options);\n source =\n source.slice(0, themeOpenAbs) +\n '\\n' +\n snippet +\n '\\n' +\n themeOuterIndent +\n source.slice(themeCloseAbs);\n } else {\n // No theme block — wrap setContent body directly.\n const setContentLineIndent = lineIndentBefore(source, setContentMatch.index);\n const bodyIndent = setContentLineIndent + ' ';\n const snippet = buildKetoyScreenSnippet(bodyIndent, options);\n source =\n source.slice(0, setContentOpen) +\n '\\n' +\n snippet +\n '\\n' +\n setContentLineIndent +\n source.slice(setContentClose);\n }\n\n // Inject `val app = application as <AppClass>` after super.onCreate(...).\n const appAssignment = `val app = application as ${options.appClassSimpleName}`;\n if (!source.includes(appAssignment)) {\n const superMatch = /super\\.onCreate\\s*\\([^)]*\\)\\s*\\n/.exec(source);\n if (superMatch) {\n const insertAt = superMatch.index + superMatch[0].length;\n const indent = lineIndentBefore(source, superMatch.index);\n source = source.slice(0, insertAt) + `${indent}${appAssignment}\\n` + source.slice(insertAt);\n }\n }\n\n await writeFile(path, source, 'utf-8');\n\n const imports = [\n 'androidx.compose.foundation.layout.Arrangement',\n 'androidx.compose.foundation.layout.Column',\n 'androidx.compose.foundation.layout.fillMaxSize',\n 'androidx.compose.material3.Text',\n 'androidx.compose.runtime.CompositionLocalProvider',\n 'androidx.compose.ui.Alignment',\n 'androidx.compose.ui.Modifier',\n 'dev.ketoy.runtime.bundle.KetoyBundleSource',\n 'dev.ketoy.runtime.compose.KetoyScreen',\n 'dev.ketoy.runtime.compose.LocalKetoyBundleLoader',\n 'dev.ketoy.runtime.compose.LocalKetoyRuntime',\n `${options.packageOfApp}.${options.appClassSimpleName}`,\n ];\n for (const imp of imports) {\n await addImport(path, imp);\n }\n return { changed: true };\n}\n\n/** The canonical KetoyScreen snippet — also printed to stdout when the user\n * opts out of the auto-wrap so they can paste it manually. */\nexport function ketoyScreenManualSnippet(options: WrapOptions): string {\n return [\n `// In MainActivity.onCreate:`,\n `val app = application as ${options.appClassSimpleName}`,\n ``,\n `// Inside your existing setContent { <YourAppTheme> { … } } block, replace`,\n `// the theme's body with:`,\n buildKetoyScreenSnippet('', options),\n ].join('\\n');\n}\n\nfunction buildKetoyScreenSnippet(indent: string, options: WrapOptions): string {\n return [\n `${indent}CompositionLocalProvider(`,\n `${indent} LocalKetoyRuntime provides app.ketoyRuntime,`,\n `${indent} LocalKetoyBundleLoader provides app.ketoyBundleLoader,`,\n `${indent}) {`,\n `${indent} KetoyScreen(`,\n `${indent} entryPoint = \"${options.entryPoint}\",`,\n `${indent} bundleSource = KetoyBundleSource.Asset(\"${options.bundleAsset}\"),`,\n `${indent} ) {`,\n `${indent} // Native fallback — rendered when the .ktx bundle is absent,`,\n `${indent} // incompatible, or corrupt. Replace with your own native screen.`,\n `${indent} Column(`,\n `${indent} modifier = Modifier.fillMaxSize(),`,\n `${indent} verticalArrangement = Arrangement.Center,`,\n `${indent} horizontalAlignment = Alignment.CenterHorizontally,`,\n `${indent} ) {`,\n `${indent} Text(\"Hello Android\")`,\n `${indent} }`,\n `${indent} }`,\n `${indent}}`,\n ].join('\\n');\n}\n\nfunction findMatchingBrace(source: string, afterOpen: number): number {\n let depth = 1;\n for (let i = afterOpen; i < source.length; i++) {\n const ch = source[i];\n if (ch === '{') depth++;\n else if (ch === '}') {\n depth--;\n if (depth === 0) return i;\n }\n }\n return -1;\n}\n\nfunction lineIndentBefore(source: string, pos: number): string {\n const lineStart = source.lastIndexOf('\\n', Math.max(0, pos - 1)) + 1;\n const lineUpTo = source.slice(lineStart, pos);\n const m = /^[ \\t]*/.exec(lineUpTo);\n return m ? m[0] : '';\n}\n","import { readFile, writeFile } from 'node:fs/promises';\n\n/**\n * Surgical edits to Kotlin source files: imports, class annotations, fields.\n * Operates via regex on the textual layout — every helper is idempotent.\n */\n\nexport async function addImport(path: string, importStatement: string): Promise<{ changed: boolean }> {\n const source = await readFile(path, 'utf-8');\n const target = `import ${importStatement}`;\n if (new RegExp(`^${target.replace(/\\./g, '\\\\.')}\\\\b`, 'm').test(source)) {\n return { changed: false };\n }\n\n // Insert after the last import; if no imports, after the package line.\n const importBlockRe = /(?:^|\\n)import\\s+[\\w.*]+\\s*$/gm;\n let lastIdx = -1;\n for (let m: RegExpExecArray | null; (m = importBlockRe.exec(source)); ) {\n lastIdx = m.index + m[0].length;\n }\n if (lastIdx >= 0) {\n const updated = source.slice(0, lastIdx) + `\\n${target}` + source.slice(lastIdx);\n await writeFile(path, updated, 'utf-8');\n return { changed: true };\n }\n\n const pkgRe = /^package\\s+[\\w.]+\\s*$/m;\n const pkg = pkgRe.exec(source);\n if (pkg) {\n const insertAt = pkg.index + pkg[0].length;\n const updated = source.slice(0, insertAt) + `\\n\\n${target}` + source.slice(insertAt);\n await writeFile(path, updated, 'utf-8');\n return { changed: true };\n }\n\n await writeFile(path, target + '\\n\\n' + source, 'utf-8');\n return { changed: true };\n}\n\nfunction escapeRegex(s: string): string {\n return s.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n\n/**\n * Add a single annotation immediately above a `class Name` (or `open class`,\n * `abstract class`, etc.) declaration. Skips if the annotation is already\n * present on the class.\n */\nexport async function addClassAnnotation(\n path: string,\n className: string,\n annotation: string,\n): Promise<{ changed: boolean }> {\n const source = await readFile(path, 'utf-8');\n const classRe = new RegExp(\n `(^[^\\\\n]*?\\\\b(?:public\\\\s+|internal\\\\s+|private\\\\s+|abstract\\\\s+|open\\\\s+|sealed\\\\s+|data\\\\s+)*class\\\\s+${escapeRegex(\n className,\n )}\\\\b)`,\n 'm',\n );\n const match = classRe.exec(source);\n if (!match) {\n throw new Error(`class ${className} not found in ${path}.`);\n }\n\n // Walk backward past annotation lines to find existing annotations.\n const start = match.index;\n let scan = start;\n while (scan > 0) {\n const lineEnd = scan - 1;\n const lineStart = source.lastIndexOf('\\n', lineEnd - 1) + 1;\n const line = source.slice(lineStart, lineEnd);\n const trimmed = line.trim();\n if (trimmed.startsWith('@')) {\n if (trimmed.startsWith(annotation)) return { changed: false };\n scan = lineStart;\n continue;\n }\n if (trimmed === '') {\n scan = lineStart;\n continue;\n }\n break;\n }\n\n const indentMatch = /^[ \\t]*/.exec(source.slice(start, start + 40));\n const indent = indentMatch ? indentMatch[0] : '';\n const insert = `${indent}${annotation}\\n`;\n const updated = source.slice(0, start) + insert + source.slice(start);\n await writeFile(path, updated, 'utf-8');\n return { changed: true };\n}\n\n/**\n * Add a field declaration block inside a class body, immediately after the\n * opening `{`. Skips if a probe string (typically the field's lateinit var name)\n * is already present in the file.\n */\nexport async function addClassField(\n path: string,\n className: string,\n fieldBlock: string,\n probe: string,\n): Promise<{ changed: boolean }> {\n const source = await readFile(path, 'utf-8');\n if (source.includes(probe)) return { changed: false };\n\n const classRe = new RegExp(`class\\\\s+${escapeRegex(className)}\\\\b[^{]*\\\\{`);\n const match = classRe.exec(source);\n if (!match) throw new Error(`class ${className} not found in ${path}.`);\n const insertAt = match.index + match[0].length;\n\n const body = fieldBlock\n .split('\\n')\n .map((l) => (l.length === 0 ? l : ' ' + l))\n .join('\\n');\n const updated = source.slice(0, insertAt) + '\\n' + body + '\\n' + source.slice(insertAt);\n await writeFile(path, updated, 'utf-8');\n return { changed: true };\n}\n\nexport async function fileMentions(path: string, needle: string): Promise<boolean> {\n const source = await readFile(path, 'utf-8');\n return source.includes(needle);\n}\n","import { readFile, writeFile } from 'node:fs/promises';\n\n/**\n * Surgical editor for Gradle version catalogs (`gradle/libs.versions.toml`).\n *\n * Operates on the `[versions]` section only. Preserves the rest of the file\n * (libraries, plugins, bundles, comments, ordering) byte-for-byte.\n *\n * General-purpose — no alpha-specific knowledge. The alpha-period pin list\n * lives in `src/alpha-pins.ts`.\n */\n\nexport interface VersionPin {\n /** Canonical TOML key to use if no alias is found in the catalog. */\n key: string;\n /** Required exact version string. */\n required: string;\n /** Alternate key spellings the catalog might already use. First match wins. */\n aliases?: string[];\n /** Human-readable label for log output. */\n label?: string;\n}\n\nexport interface VersionPinResult {\n /** TOML key actually edited or inserted. */\n key: string;\n required: string;\n /** Previous value if the key already existed. */\n oldValue: string | null;\n action: 'pinned' | 'added' | 'unchanged';\n label?: string;\n}\n\ninterface SectionBounds {\n start: number;\n end: number;\n}\n\ninterface KeyMatch {\n key: string;\n value: string;\n indent: string;\n lineStart: number;\n lineEnd: number;\n}\n\n/**\n * Apply each pin to the `[versions]` section. Idempotent: a pin whose value\n * already equals the required version is reported as `unchanged`.\n */\nexport async function applyVersionPins(\n path: string,\n pins: readonly VersionPin[],\n): Promise<VersionPinResult[]> {\n let source = await readFile(path, 'utf-8');\n let section = findVersionsSection(source);\n if (!section) {\n throw new Error(`No [versions] section in ${path}.`);\n }\n\n const results: VersionPinResult[] = [];\n for (const pin of pins) {\n const candidates = pin.aliases ?? [pin.key];\n let found: KeyMatch | null = null;\n for (const k of candidates) {\n const m = findKeyInRange(source, section, k);\n if (m) {\n found = m;\n break;\n }\n }\n if (found) {\n if (found.value === pin.required) {\n results.push({\n key: found.key,\n required: pin.required,\n oldValue: found.value,\n action: 'unchanged',\n label: pin.label,\n });\n continue;\n }\n const newLine = `${found.indent}${found.key} = \"${pin.required}\"`;\n source = source.slice(0, found.lineStart) + newLine + source.slice(found.lineEnd);\n section = findVersionsSection(source) ?? section;\n results.push({\n key: found.key,\n required: pin.required,\n oldValue: found.value,\n action: 'pinned',\n label: pin.label,\n });\n } else {\n // Append at the end of [versions] preserving line orientation.\n const before = source.slice(0, section.end);\n const after = source.slice(section.end);\n const lead = before.endsWith('\\n') ? '' : '\\n';\n const newLine = `${lead}${pin.key} = \"${pin.required}\"\\n`;\n source = before + newLine + after;\n section = findVersionsSection(source) ?? section;\n results.push({\n key: pin.key,\n required: pin.required,\n oldValue: null,\n action: 'added',\n label: pin.label,\n });\n }\n }\n\n await writeFile(path, source, 'utf-8');\n return results;\n}\n\nfunction findVersionsSection(source: string): SectionBounds | null {\n return findSection(source, 'versions');\n}\n\nfunction findSection(source: string, name: string): SectionBounds | null {\n const header = new RegExp(`^\\\\[${escapeRegex(name)}\\\\]\\\\s*$`, 'm').exec(source);\n if (!header) return null;\n const start = header.index + header[0].length;\n // End at the next top-level `[section]` header, or EOF.\n const nextHeaderRe = /\\n\\[[^\\]]+\\]/g;\n nextHeaderRe.lastIndex = start;\n const next = nextHeaderRe.exec(source);\n const end = next ? next.index : source.length;\n return { start, end };\n}\n\n/**\n * Add a single `key = { id = \"...\", version.ref = \"...\" }` entry to the\n * `[plugins]` section of the catalog. Idempotent — checks for an existing\n * declaration of the same plugin id OR the same key.\n */\nexport async function ensurePluginEntry(\n path: string,\n options: { key: string; id: string; versionRef: string },\n): Promise<{ changed: boolean; reason?: string }> {\n let source = await readFile(path, 'utf-8');\n let section = findSection(source, 'plugins');\n if (!section) {\n // No [plugins] section yet — append it at EOF.\n const trimmed = source.replace(/\\s+$/, '');\n const newBlock =\n `\\n\\n[plugins]\\n${options.key} = { id = \"${options.id}\", version.ref = \"${options.versionRef}\" }\\n`;\n await writeFile(path, trimmed + newBlock, 'utf-8');\n return { changed: true };\n }\n const region = source.slice(section.start, section.end);\n // Match either the exact key OR any line containing the target plugin id.\n const idRe = new RegExp(`\\\\bid\\\\s*=\\\\s*\"${escapeRegex(options.id)}\"`);\n const keyRe = new RegExp(`(^|\\\\n)\\\\s*${escapeRegex(options.key)}\\\\s*=`);\n if (idRe.test(region) || keyRe.test(region)) {\n return { changed: false, reason: 'Plugin already declared in [plugins]' };\n }\n const before = source.slice(0, section.end);\n const after = source.slice(section.end);\n const lead = before.endsWith('\\n') ? '' : '\\n';\n const newLine = `${lead}${options.key} = { id = \"${options.id}\", version.ref = \"${options.versionRef}\" }\\n`;\n source = before + newLine + after;\n await writeFile(path, source, 'utf-8');\n return { changed: true };\n}\n\nfunction escapeRegex(s: string): string {\n return s.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n\nfunction findKeyInRange(source: string, section: SectionBounds, key: string): KeyMatch | null {\n const region = source.slice(section.start, section.end);\n const re = new RegExp(\n `(^|\\\\n)([ \\\\t]*)(${escapeRegex(key)})[ \\\\t]*=[ \\\\t]*\"([^\"]*)\"`,\n '',\n );\n const m = re.exec(region);\n if (!m) return null;\n const leadingNl = m[1] ?? '';\n const indent = m[2] ?? '';\n const matchedKey = m[3] ?? '';\n const value = m[4] ?? '';\n // m.index points at start of the match including the leading \\n (if any).\n // The actual line starts after that newline.\n const lineStart = section.start + m.index + leadingNl.length;\n const lineEnd = lineStart + indent.length + matchedKey.length + ' = \"'.length + value.length + 1; // closing quote\n return { key: matchedKey, value, indent, lineStart, lineEnd };\n}\n","import { readFile, writeFile } from 'node:fs/promises';\n\n/**\n * AGP-8.x compatibility transform for `app/build.gradle.kts`.\n *\n * Android Studio Ladybug+ generates the new block-style `compileSdk { … }`\n * DSL introduced in AGP 8.13 / 9.x:\n *\n * compileSdk {\n * version = release(36) {\n * minorApiLevel = 1\n * }\n * }\n *\n * AGP 8.7.0 — the version Ketoy 0.3.x alpha pins to — does NOT know that\n * DSL and fails with:\n *\n * None of the following candidates is applicable:\n * fun <T : Any> Action<in T>.invoke(target: T): Unit\n * fun ArtifactHandler.invoke(configuration: ...): Unit\n * ...\n *\n * This transform converts the block to the legacy property form supported\n * by AGP 8.x:\n *\n * compileSdk = 36\n *\n * `minorApiLevel` is dropped — the concept doesn't exist in AGP 8.x. Same\n * treatment for the parallel `targetSdk { … }` block if present.\n *\n * General-purpose: returns a list of mutations performed so the caller can\n * log them. Idempotent — re-running on already-migrated source is a no-op.\n *\n * REMOVABLE (alpha pinning) — see src/alpha-pins.ts header for the deletion\n * checklist. When alpha pinning ends, AGP returns to the latest stable and\n * this transform becomes unnecessary.\n */\n\nexport interface Agp8Mutation {\n /** The property name that was migrated (`compileSdk`, `targetSdk`). */\n property: 'compileSdk' | 'targetSdk';\n /** The major API level extracted from `release(N)`. */\n apiLevel: number;\n /** True if a `minorApiLevel = N` line was present and dropped. */\n droppedMinor: boolean;\n}\n\nexport interface Agp8Result {\n mutations: Agp8Mutation[];\n changed: boolean;\n}\n\nexport async function migrateAgp8AndroidBlock(path: string): Promise<Agp8Result> {\n const original = await readFile(path, 'utf-8');\n const { source, mutations } = transformSource(original);\n if (mutations.length === 0) {\n return { mutations: [], changed: false };\n }\n await writeFile(path, source, 'utf-8');\n return { mutations, changed: true };\n}\n\n/** Pure transform — exported for testing. */\nexport function transformSource(input: string): { source: string; mutations: Agp8Mutation[] } {\n let source = input;\n const mutations: Agp8Mutation[] = [];\n\n for (const property of ['compileSdk', 'targetSdk'] as const) {\n const result = transformOne(source, property);\n if (result) {\n source = result.source;\n mutations.push(result.mutation);\n }\n }\n\n return { source, mutations };\n}\n\nfunction transformOne(\n source: string,\n property: 'compileSdk' | 'targetSdk',\n): { source: string; mutation: Agp8Mutation } | null {\n // Locate the block-style declaration: `<property>\\s*{`. Bail if it's\n // the legacy property form (`<property>\\s*=\\s*N`).\n const blockHeader = new RegExp(`(^|\\\\n)([ \\\\t]*)${escape(property)}\\\\s*\\\\{`, 'g');\n const match = blockHeader.exec(source);\n if (!match) return null;\n\n const headerStart = match.index + (match[1] ?? '').length;\n const indent = match[2] ?? '';\n const openBraceIdx = match.index + match[0].length - 1;\n const closeBraceIdx = findMatchingBrace(source, openBraceIdx + 1);\n if (closeBraceIdx === -1) return null;\n const body = source.slice(openBraceIdx + 1, closeBraceIdx);\n\n // Extract `version = release(N) [ { ... } ]` — N is the major API level.\n const releaseMatch = /\\brelease\\s*\\(\\s*(\\d+)\\s*\\)/.exec(body);\n if (!releaseMatch) {\n // Could also be `version = preview(\"Baklava\")` etc. — leave alone; the\n // user is on a non-numeric preview and AGP 8.7 won't help them anyway.\n return null;\n }\n const apiLevel = Number(releaseMatch[1]);\n const droppedMinor = /\\bminorApiLevel\\s*=\\s*\\d+/.test(body);\n\n // Replace the whole `<property> { ... }` block with the property form.\n const replacement = `${indent}${property} = ${apiLevel}`;\n const updated = source.slice(0, headerStart) + replacement + source.slice(closeBraceIdx + 1);\n\n return {\n source: updated,\n mutation: { property, apiLevel, droppedMinor },\n };\n}\n\nfunction findMatchingBrace(source: string, after: number): number {\n let depth = 1;\n for (let i = after; i < source.length; i++) {\n const ch = source[i];\n if (ch === '{') depth++;\n else if (ch === '}') {\n depth--;\n if (depth === 0) return i;\n }\n }\n return -1;\n}\n\nfunction escape(s: string): string {\n return s.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n","import { readFile, writeFile, access } from 'node:fs/promises';\n\n/**\n * Surgical editor for `gradle.properties`. Operates on a single key at a\n * time. Idempotent: identical assignment is a no-op, conflicting assignment\n * is reported instead of overwritten (we never silently change a value the\n * user deliberately set).\n */\n\nasync function fileExists(p: string): Promise<boolean> {\n try {\n await access(p);\n return true;\n } catch {\n return false;\n }\n}\n\nexport interface GradlePropertyResult {\n changed: boolean;\n /** Previous value if the key already existed. */\n previousValue: string | null;\n /** Conflict: existing value differs from the requested value. */\n conflict: boolean;\n}\n\nexport async function ensureGradleProperty(\n path: string,\n key: string,\n value: string,\n): Promise<GradlePropertyResult> {\n const escaped = key.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n const exists = await fileExists(path);\n const source = exists ? await readFile(path, 'utf-8') : '';\n const lineRe = new RegExp(`^(${escaped})\\\\s*=\\\\s*(.*)$`, 'm');\n const match = lineRe.exec(source);\n if (match) {\n const currentValue = (match[2] ?? '').trim();\n if (currentValue === value) {\n return { changed: false, previousValue: currentValue, conflict: false };\n }\n return { changed: false, previousValue: currentValue, conflict: true };\n }\n const prefix = source.length === 0 || source.endsWith('\\n') ? '' : '\\n';\n const block = `${prefix}\\n# Ketoy alpha — required for AGP 8.7 compatibility\\n${key}=${value}\\n`;\n await writeFile(path, source + block, 'utf-8');\n return { changed: true, previousValue: null, conflict: false };\n}\n","import { readFile } from 'node:fs/promises';\nimport { dirname, join, resolve } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nlet cachedRoot: string | null = null;\n\nexport async function getTemplatesRoot(): Promise<string> {\n if (cachedRoot) return cachedRoot;\n const here = dirname(fileURLToPath(import.meta.url));\n const candidates = [\n resolve(here, '..', 'templates'),\n resolve(here, '..', '..', 'templates'),\n ];\n for (const c of candidates) {\n try {\n // MyApplication.kt.tmpl is a stable marker — every release ships it.\n await readFile(join(c, 'MyApplication.kt.tmpl'), 'utf-8');\n cachedRoot = c;\n return c;\n } catch {\n // try next candidate\n }\n }\n throw new Error('Could not locate templates directory.');\n}\n\nexport async function loadTemplate(name: string, vars: Record<string, string>): Promise<string> {\n const root = await getTemplatesRoot();\n const raw = await readFile(join(root, name), 'utf-8');\n return Object.entries(vars).reduce(\n (acc, [k, v]) => acc.replaceAll(`{{${k}}}`, v),\n raw,\n );\n}\n","import { mkdir, readFile, writeFile, access } from 'node:fs/promises';\nimport { dirname, join } from 'node:path';\nimport { PROJECT_STATE_FILE, PROJECT_STATE_DIR } from '../lib/paths.js';\nimport { ProjectStateSchema, type ProjectState } from './schema.js';\n\nasync function fileExists(path: string): Promise<boolean> {\n try {\n await access(path);\n return true;\n } catch {\n return false;\n }\n}\n\nexport async function loadProjectState(projectRoot: string): Promise<ProjectState | null> {\n const path = join(projectRoot, PROJECT_STATE_FILE);\n if (!(await fileExists(path))) return null;\n const raw = await readFile(path, 'utf-8');\n const parsed = ProjectStateSchema.safeParse(JSON.parse(raw));\n if (!parsed.success) return null;\n return parsed.data;\n}\n\nexport async function saveProjectState(projectRoot: string, state: ProjectState): Promise<void> {\n const path = join(projectRoot, PROJECT_STATE_FILE);\n await mkdir(dirname(path), { recursive: true });\n await writeFile(path, JSON.stringify(state, null, 2) + '\\n', 'utf-8');\n}\n\nexport function projectStateDirRelative(): string {\n return PROJECT_STATE_DIR;\n}\n","import { input, confirm } from '@inquirer/prompts';\nimport type { CoreMessage } from 'ai';\nimport { runAgent } from '../agent/loop.js';\nimport { log, pc } from '../lib/log.js';\nimport { UserAbortError } from '../lib/errors.js';\n\nexport interface ChatOptions {\n projectRoot: string;\n model: string | undefined;\n initialPrompt: string | undefined;\n}\n\nexport async function runChatCommand(opts: ChatOptions): Promise<void> {\n log.info(pc.bold('Ketoy chat') + pc.dim(' — type your request, /exit to quit, /clear to reset history.'));\n log.detail(`Working dir: ${opts.projectRoot}`);\n if (opts.model) log.detail(`Model override: ${opts.model}`);\n\n let history: CoreMessage[] = [];\n let prompt = opts.initialPrompt;\n\n while (true) {\n let userInput: string;\n if (prompt !== undefined) {\n userInput = prompt;\n prompt = undefined;\n log.raw(`${pc.bold('› ')}${userInput}\\n`);\n } else {\n try {\n userInput = await input({ message: pc.bold('›'), validate: (v) => v.trim().length > 0 });\n } catch (e) {\n if ((e as Error).name === 'ExitPromptError') throw new UserAbortError();\n throw e;\n }\n }\n const trimmed = userInput.trim();\n if (trimmed === '/exit' || trimmed === '/quit') {\n log.info('Bye.');\n return;\n }\n if (trimmed === '/clear') {\n history = [];\n log.info('History cleared.');\n continue;\n }\n if (trimmed === '/help') {\n printHelp();\n continue;\n }\n if (trimmed === '/cost') {\n log.info('Cost tracking is coming in v0.3.x.');\n continue;\n }\n if (trimmed.startsWith('/')) {\n log.warn(`Unknown command: ${trimmed}. Use /help.`);\n continue;\n }\n\n try {\n const result = await runAgent({\n userPrompt: userInput,\n projectRoot: opts.projectRoot,\n modelOverride: opts.model,\n history,\n });\n history = result.history;\n const tot = result.usage.totalTokens;\n const tokenLine = tot\n ? pc.dim(\n `${result.steps} step(s), ${tot} tokens (${result.usage.promptTokens}↑ ${result.usage.completionTokens}↓)`,\n )\n : pc.dim(`${result.steps} step(s)`);\n log.detail(tokenLine);\n } catch (e) {\n log.error((e as Error).message);\n const cont = await confirm({ message: 'Continue chatting?', default: true }).catch(() => false);\n if (!cont) return;\n }\n }\n}\n\nfunction printHelp(): void {\n log.info('Slash commands:');\n log.detail('/exit — quit the chat session');\n log.detail('/clear — clear conversation history');\n log.detail('/help — show this help');\n}\n","import { streamText, type CoreMessage } from 'ai';\nimport { resolveModel } from './model.js';\nimport { buildSystemPrompt } from './prompts.js';\nimport { buildTools } from './tools/index.js';\nimport { loadConfig } from '../config/store.js';\nimport { log, pc } from '../lib/log.js';\n\nexport interface RunAgentOptions {\n userPrompt: string;\n projectRoot: string;\n modelOverride?: string;\n history?: CoreMessage[];\n silent?: boolean;\n}\n\nexport interface RunAgentResult {\n history: CoreMessage[];\n loadedSkillFiles: string[];\n steps: number;\n usage: { promptTokens?: number; completionTokens?: number; totalTokens?: number };\n}\n\nexport async function runAgent(opts: RunAgentOptions): Promise<RunAgentResult> {\n const config = await loadConfig();\n const { model, modelName, providerId } = await resolveModel(opts.modelOverride);\n const { prompt: system, loadedFiles } = await buildSystemPrompt({\n taskHint: opts.userPrompt,\n projectRoot: opts.projectRoot,\n modelName,\n });\n const tools = await buildTools({ projectRoot: opts.projectRoot });\n\n if (!opts.silent) {\n log.detail(\n `model=${providerId}:${modelName} · skill=${loadedFiles.length} file(s) loaded · tools=${\n Object.keys(tools).length\n }`,\n );\n }\n\n const messages: CoreMessage[] = [\n ...(opts.history ?? []),\n { role: 'user', content: opts.userPrompt },\n ];\n\n const result = streamText({\n model,\n system,\n messages,\n tools,\n maxSteps: config.agent.maxSteps,\n onStepFinish: ({ toolCalls, finishReason }) => {\n if (opts.silent) return;\n if (toolCalls && toolCalls.length > 0) {\n for (const tc of toolCalls) {\n log.detail(`${pc.cyan('→')} ${tc.toolName}`);\n }\n }\n if (finishReason && finishReason !== 'stop' && finishReason !== 'tool-calls') {\n log.detail(`finish: ${finishReason}`);\n }\n },\n });\n\n if (!opts.silent) log.raw('\\n');\n for await (const chunk of result.textStream) {\n if (!opts.silent) log.raw(chunk);\n }\n if (!opts.silent) log.raw('\\n\\n');\n\n const response = await result.response;\n const usage = await result.usage;\n const steps = await result.steps;\n\n return {\n history: [...messages, ...response.messages],\n loadedSkillFiles: loadedFiles,\n steps: steps.length,\n usage: {\n promptTokens: usage.promptTokens,\n completionTokens: usage.completionTokens,\n totalTokens: usage.totalTokens,\n },\n };\n}\n","import { createAnthropic } from '@ai-sdk/anthropic';\nimport { createOpenAI } from '@ai-sdk/openai';\nimport { createGoogleGenerativeAI } from '@ai-sdk/google';\nimport { createMistral } from '@ai-sdk/mistral';\nimport { createGroq } from '@ai-sdk/groq';\nimport { createXai } from '@ai-sdk/xai';\nimport { createOpenRouter } from '@openrouter/ai-sdk-provider';\nimport { createOllama } from 'ollama-ai-provider';\nimport type { LanguageModelV1 } from 'ai';\nimport { loadConfig } from '../config/store.js';\nimport { parseModelId, PROVIDERS } from '../providers/registry.js';\nimport { ConfigError } from '../lib/errors.js';\nimport type { ProviderId } from '../config/schema.js';\n\nexport interface ResolvedModel {\n model: LanguageModelV1;\n providerId: ProviderId;\n modelName: string;\n}\n\nexport async function resolveModel(modelIdOverride?: string): Promise<ResolvedModel> {\n const config = await loadConfig();\n const modelId = modelIdOverride ?? config.model;\n const { provider, name } = parseModelId(modelId);\n const info = PROVIDERS[provider];\n const apiKey = config.apiKeys[provider];\n\n if (provider !== 'ollama' && !apiKey) {\n throw new ConfigError(\n `No API key configured for ${info.displayName}. Run: ketoy auth ${provider}`,\n );\n }\n\n switch (provider) {\n case 'anthropic':\n return { model: createAnthropic({ apiKey })(name), providerId: provider, modelName: name };\n case 'openai':\n return { model: createOpenAI({ apiKey })(name), providerId: provider, modelName: name };\n case 'google':\n return {\n model: createGoogleGenerativeAI({ apiKey })(name),\n providerId: provider,\n modelName: name,\n };\n case 'mistral':\n return { model: createMistral({ apiKey })(name), providerId: provider, modelName: name };\n case 'groq':\n return { model: createGroq({ apiKey })(name), providerId: provider, modelName: name };\n case 'xai':\n return { model: createXai({ apiKey })(name), providerId: provider, modelName: name };\n case 'openrouter':\n return {\n model: createOpenRouter({ apiKey: apiKey as string }).chat(name),\n providerId: provider,\n modelName: name,\n };\n case 'ollama':\n return {\n model: createOllama({ baseURL: `${config.ollama.baseUrl}/api` })(name),\n providerId: provider,\n modelName: name,\n };\n default: {\n const exhaustive: never = provider;\n throw new Error(`Unhandled provider: ${String(exhaustive)}`);\n }\n }\n}\n","import { readFile, readdir, stat } from 'node:fs/promises';\nimport { join, dirname, resolve } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\n/**\n * Locate the bundled `skills/ketoy/` directory.\n *\n * Lookup order:\n * 1. KETOY_SKILL_DIR env var (developer override)\n * 2. <package-root>/skills/ketoy/ (npm install layout)\n * 3. <repo-root>/skills/ketoy/ (dev / monorepo layout)\n */\nlet cachedRoot: string | null = null;\n\nasync function dirExists(path: string): Promise<boolean> {\n try {\n const s = await stat(path);\n return s.isDirectory();\n } catch {\n return false;\n }\n}\n\nexport async function getSkillRoot(): Promise<string> {\n if (cachedRoot) return cachedRoot;\n\n const envOverride = process.env['KETOY_SKILL_DIR'];\n if (envOverride && (await dirExists(envOverride))) {\n cachedRoot = resolve(envOverride);\n return cachedRoot;\n }\n\n const here = dirname(fileURLToPath(import.meta.url));\n const candidates = [\n resolve(here, '..', 'skills', 'ketoy'),\n resolve(here, '..', '..', 'skills', 'ketoy'),\n resolve(here, '..', '..', '..', 'skills', 'ketoy'),\n ];\n for (const c of candidates) {\n if (await dirExists(c)) {\n cachedRoot = c;\n return cachedRoot;\n }\n }\n throw new Error(\n `Could not locate the Ketoy skill directory. Set KETOY_SKILL_DIR to override. Tried: ${candidates.join(', ')}`,\n );\n}\n\nexport async function readSkillFile(relName: string): Promise<string | null> {\n const root = await getSkillRoot();\n const normalized = relName.replace(/\\\\/g, '/').replace(/^\\/+/, '');\n if (normalized.includes('..')) return null;\n const path = join(root, normalized);\n try {\n return await readFile(path, 'utf-8');\n } catch {\n return null;\n }\n}\n\nexport async function listSkillFiles(): Promise<string[]> {\n const root = await getSkillRoot();\n const out: string[] = [];\n async function walk(dir: string, prefix: string): Promise<void> {\n const entries = await readdir(dir, { withFileTypes: true });\n for (const e of entries) {\n const full = join(dir, e.name);\n const rel = prefix ? `${prefix}/${e.name}` : e.name;\n if (e.isDirectory()) {\n await walk(full, rel);\n } else if (e.isFile()) {\n out.push(rel);\n }\n }\n }\n await walk(root, '');\n return out.sort();\n}\n\nexport interface SkillContext {\n systemPrompt: string;\n loadedFiles: string[];\n}\n\n/**\n * Build the system prompt by injecting SKILL.md plus any subfiles selected by the task hint.\n * The agent has a `skill_file` tool to load anything else on demand.\n */\nexport async function buildSkillContext(taskHint: string): Promise<SkillContext> {\n const main = await readSkillFile('SKILL.md');\n if (main === null) throw new Error('SKILL.md missing from skill root.');\n\n const lower = taskHint.toLowerCase();\n const toLoad = new Set<string>(['SKILL.md']);\n const add = (name: string) => toLoad.add(name);\n\n if (/\\b(init|scaffold|set up|setup|add ketoy|integrate)\\b/.test(lower)) {\n add('guides/init-project.md');\n add('guides/safe-edits.md');\n }\n if (/\\b(migrate|migration|convert|port)\\b/.test(lower)) {\n add('guides/migrate.md');\n }\n if (/\\b(error|fail|broken|crash|diagnose|fix|why)\\b/.test(lower)) {\n add('guides/diagnose-errors.md');\n }\n if (/\\b(supported|can i use|is there|available|catalog)\\b/.test(lower)) {\n add('reference/supported-composables.md');\n add('reference/forbidden-apis.md');\n }\n if (/\\b(capability|stub|host registry|capabilityregistry|capability id)\\b/.test(lower)) {\n add('reference/capabilities.md');\n }\n if (/\\b(modifier|padding|fillmax)\\b/.test(lower)) {\n add('reference/supported-modifiers.md');\n }\n if (/\\b(bundle|\\.ktx|analyze|inspect|build)\\b/.test(lower)) {\n add('guides/build-and-analyze.md');\n }\n if (toLoad.size === 1) {\n add('reference/architecture-cheatsheet.md');\n }\n\n const parts: string[] = [main];\n const loaded: string[] = ['SKILL.md'];\n for (const name of toLoad) {\n if (name === 'SKILL.md') continue;\n const content = await readSkillFile(name);\n if (content !== null) {\n parts.push(`\\n\\n--- BEGIN ${name} ---\\n\\n${content}\\n\\n--- END ${name} ---\\n`);\n loaded.push(name);\n }\n }\n\n return { systemPrompt: parts.join(''), loadedFiles: loaded };\n}\n","import { CLI_VERSION } from '../lib/paths.js';\nimport { getKetoyVersion } from '../lib/ketoy-version.js';\nimport { buildSkillContext } from '../skill/loader.js';\n\nexport interface SystemPromptOptions {\n taskHint: string;\n projectRoot: string;\n modelName: string;\n}\n\nexport async function buildSystemPrompt(opts: SystemPromptOptions): Promise<{\n prompt: string;\n loadedFiles: string[];\n}> {\n const [{ systemPrompt: skill, loadedFiles }, ketoyVersion] = await Promise.all([\n buildSkillContext(opts.taskHint),\n getKetoyVersion(),\n ]);\n\n const header =\n `You are the Ketoy CLI agent, version ${CLI_VERSION}, targeting Ketoy ${ketoyVersion}.\\n` +\n `You are running on model \"${opts.modelName}\".\\n` +\n `Working directory: ${opts.projectRoot}\\n` +\n `Today: ${new Date().toISOString().slice(0, 10)}\\n` +\n `\\n` +\n `Operating principles:\\n` +\n `- Be specific. Quote real symbol names from the user's tree. Don't paraphrase.\\n` +\n `- Use tools to inspect the user's actual code before answering. Never assume.\\n` +\n `- For multi-step work, state the plan, then execute step by step with intermediate verification.\\n` +\n `- NEVER rewrite existing files in full. Edits to build.gradle.kts, AndroidManifest.xml,\\n` +\n ` MainActivity.kt, Application classes, and settings.gradle.kts MUST be surgical — single-line\\n` +\n ` additions or single-block appends at well-identified anchors. The user has invested work\\n` +\n ` in those files; treat them as sacred.\\n` +\n `- For high-risk file edits, the edit_file tool will show a diff and ask the user. Do not\\n` +\n ` try to bypass this.\\n` +\n `- Refuse whole-project migrations. Migration is per-file, one-shot. Always audit first.\\n` +\n `- Publishing is deferred until the Ketoy backend ships. Don't write publish code.\\n` +\n `\\n` +\n `Tools available:\\n` +\n `- read_file, write_file, edit_file, grep, glob, bash, analyze_ktx, skill_file\\n` +\n `\\n` +\n `The skill below is your operational manual. Treat reference/ as ground truth.\\n` +\n `=== SKILL CONTENT ===\\n\\n`;\n\n return { prompt: header + skill, loadedFiles };\n}\n","import { readFile, stat } from 'node:fs/promises';\nimport { z } from 'zod';\nimport { tool } from 'ai';\nimport { safeJoin } from './paths.js';\n\nconst MAX_BYTES = 256 * 1024;\n\nexport function makeReadFileTool(projectRoot: string) {\n return tool({\n description:\n 'Read a file from the working project. Returns up to 256 KB of UTF-8 text. Use this before editing any file.',\n parameters: z.object({\n path: z.string().describe('Path relative to project root, or absolute under it.'),\n }),\n execute: async ({ path }) => {\n const joined = safeJoin(projectRoot, path);\n if (!joined) return { error: `Refusing to read outside project root: ${path}` };\n const { abs, rel } = joined;\n const st = await stat(abs).catch(() => null);\n if (!st) return { error: `File not found: ${rel}` };\n if (st.isDirectory()) return { error: `Path is a directory: ${rel}` };\n if (st.size > MAX_BYTES) {\n return { error: `File too large (${st.size} bytes, limit ${MAX_BYTES}): ${rel}` };\n }\n const content = await readFile(abs, 'utf-8');\n return { path: rel, bytes: st.size, content };\n },\n });\n}\n","import { isAbsolute, relative, resolve, sep } from 'node:path';\n\n/**\n * Resolve `path` against `projectRoot` and confirm the result stays inside\n * the project tree. Returns `{ abs, rel }` for the cleared path or `null` if\n * the input escapes the root.\n *\n * Why this exists: `resolve()` happily produces paths outside the root when\n * given an absolute path (`/etc/passwd`) or a relative path with enough `..`\n * segments. Relying on `rel.startsWith('..') || rel.startsWith('/')` misses:\n * - Windows-absolute inputs like `C:\\foo` (no leading `/` on the result)\n * - Same-root cousins where rel begins with `..\\` on Windows.\n *\n * The robust check is to compare the resolved absolute path against the\n * resolved project root, both ending with a separator so `/proj/foo-bar`\n * doesn't pass as a prefix of `/proj/foo`.\n */\nexport function safeJoin(\n projectRoot: string,\n path: string,\n): { abs: string; rel: string } | null {\n const rootAbs = resolve(projectRoot);\n const abs = resolve(rootAbs, path);\n if (abs !== rootAbs && !abs.startsWith(rootAbs + sep)) return null;\n const rel = relative(rootAbs, abs);\n // Defensive: should not happen given the prefix check above.\n if (rel.startsWith('..') || isAbsolute(rel)) return null;\n return { abs, rel };\n}\n","import { mkdir, writeFile, access } from 'node:fs/promises';\nimport { dirname } from 'node:path';\nimport { z } from 'zod';\nimport { tool } from 'ai';\nimport { confirm } from '@inquirer/prompts';\nimport { log, pc } from '../../lib/log.js';\nimport { safeJoin } from './paths.js';\n\nasync function fileExists(path: string): Promise<boolean> {\n try {\n await access(path);\n return true;\n } catch {\n return false;\n }\n}\n\nexport function makeWriteFileTool(projectRoot: string, opts: { autoApprove: boolean }) {\n return tool({\n description:\n 'Create a NEW file at the given path. Fails if the file already exists — use edit_file instead. Always prefer surgical edits over creating new files when the user has existing code.',\n parameters: z.object({\n path: z.string().describe('Path relative to project root.'),\n content: z.string().describe('Full UTF-8 file content.'),\n }),\n execute: async ({ path, content }) => {\n const joined = safeJoin(projectRoot, path);\n if (!joined) return { error: `Refusing to write outside project root: ${path}` };\n const { abs, rel } = joined;\n if (await fileExists(abs)) {\n return { error: `File already exists: ${rel}. Use edit_file to modify it.` };\n }\n log.info(`Agent wants to create ${pc.bold(rel)} (${content.length} bytes)`);\n if (!opts.autoApprove) {\n const ok = await confirm({ message: `Create ${rel}?`, default: true });\n if (!ok) return { error: 'User declined.' };\n }\n await mkdir(dirname(abs), { recursive: true });\n await writeFile(abs, content, 'utf-8');\n log.success(`Created ${rel}`);\n return { path: rel, bytes: content.length, created: true };\n },\n });\n}\n","import { readFile, writeFile } from 'node:fs/promises';\nimport { z } from 'zod';\nimport { tool } from 'ai';\nimport { confirm } from '@inquirer/prompts';\nimport { log, pc } from '../../lib/log.js';\nimport { renderUnifiedDiff, isHighRisk } from '../../safe-edit/diff.js';\nimport { safeJoin } from './paths.js';\n\nexport function makeEditFileTool(projectRoot: string, opts: { autoApprove: boolean }) {\n return tool({\n description:\n 'Surgically edit an existing file by replacing exact text. old_string must appear EXACTLY ONCE in the file. For high-risk files (build.gradle.kts, AndroidManifest.xml, MainActivity.kt, Application classes) the user is shown a diff and must confirm. Never use this to rewrite entire files — make minimal, additive edits.',\n parameters: z.object({\n path: z.string().describe('Path relative to project root.'),\n old_string: z.string().describe('Exact text to replace. Must occur once.'),\n new_string: z.string().describe('Replacement text.'),\n }),\n execute: async ({ path, old_string, new_string }) => {\n const joined = safeJoin(projectRoot, path);\n if (!joined) return { error: `Refusing to edit outside project root: ${path}` };\n const { abs, rel } = joined;\n const original = await readFile(abs, 'utf-8').catch(() => null);\n if (original === null) return { error: `File not found: ${rel}` };\n const occurrences = original.split(old_string).length - 1;\n if (occurrences === 0) {\n return { error: `old_string not found in ${rel}. Read the file again and use exact text.` };\n }\n if (occurrences > 1) {\n return {\n error: `old_string occurs ${occurrences} times in ${rel}. Add surrounding context to make it unique.`,\n };\n }\n if (old_string === new_string) {\n return { error: 'old_string and new_string are identical — no edit to perform.' };\n }\n const updated = original.replace(old_string, new_string);\n\n const risky = isHighRisk(rel);\n if (risky || !opts.autoApprove) {\n log.info(`Agent wants to edit ${pc.bold(rel)}${risky ? pc.yellow(' (high-risk file)') : ''}`);\n log.raw(renderUnifiedDiff(original, updated, rel) + '\\n');\n const ok = await confirm({ message: `Apply edit to ${rel}?`, default: !risky });\n if (!ok) return { error: 'User declined the edit.' };\n }\n await writeFile(abs, updated, 'utf-8');\n log.success(`Edited ${rel}`);\n return { path: rel, edited: true };\n },\n });\n}\n","import { pc } from '../lib/log.js';\n\nexport function renderUnifiedDiff(oldText: string, newText: string, label = 'file'): string {\n if (oldText === newText) return pc.dim('(no changes)');\n const oldLines = oldText.split('\\n');\n const newLines = newText.split('\\n');\n\n const out: string[] = [pc.bold(`--- ${label}`), pc.bold(`+++ ${label}`)];\n\n let i = 0;\n let j = 0;\n while (i < oldLines.length || j < newLines.length) {\n if (i < oldLines.length && j < newLines.length && oldLines[i] === newLines[j]) {\n out.push(pc.dim(` ${oldLines[i]}`));\n i++;\n j++;\n continue;\n }\n let aheadOld = i;\n let aheadNew = j;\n while (aheadOld < oldLines.length && aheadNew < newLines.length && oldLines[aheadOld] !== newLines[aheadNew]) {\n aheadOld++;\n aheadNew++;\n }\n for (let k = i; k < aheadOld; k++) out.push(pc.red(`- ${oldLines[k]}`));\n for (let k = j; k < aheadNew; k++) out.push(pc.green(`+ ${newLines[k]}`));\n i = aheadOld;\n j = aheadNew;\n if (i === oldLines.length && j < newLines.length) {\n for (let k = j; k < newLines.length; k++) out.push(pc.green(`+ ${newLines[k]}`));\n break;\n }\n if (j === newLines.length && i < oldLines.length) {\n for (let k = i; k < oldLines.length; k++) out.push(pc.red(`- ${oldLines[k]}`));\n break;\n }\n }\n return out.join('\\n');\n}\n\nconst HIGH_RISK_PATTERNS = [\n /(^|\\/)build\\.gradle\\.kts$/,\n /(^|\\/)settings\\.gradle\\.kts$/,\n /(^|\\/)AndroidManifest\\.xml$/,\n /(^|\\/)MainActivity\\.kt$/,\n /(^|\\/)App\\.kt$/,\n /(^|\\/)Application\\.kt$/,\n /\\/keys\\/.*-private\\.key$/,\n];\n\nexport function isHighRisk(relPath: string): boolean {\n return HIGH_RISK_PATTERNS.some((p) => p.test(relPath));\n}\n","import { z } from 'zod';\nimport { tool } from 'ai';\nimport { glob } from 'tinyglobby';\nimport { readFile } from 'node:fs/promises';\nimport { relative, resolve } from 'node:path';\n\nconst MAX_MATCHES = 200;\nconst MAX_FILE_SIZE = 1024 * 1024;\n\nexport function makeGrepTool(projectRoot: string) {\n return tool({\n description:\n 'Search file contents using a JavaScript regular expression. Returns up to 200 matches with file path + line number + matching line text. Useful for finding usages, imports, FQ names.',\n parameters: z.object({\n pattern: z.string().describe('JavaScript-compatible regex pattern.'),\n glob_pattern: z\n .string()\n .default('**/*.{kt,kts,xml,json,gradle,properties}')\n .describe('Glob to filter files. Default: Android/Kotlin source files.'),\n case_sensitive: z.boolean().default(true),\n }),\n execute: async ({ pattern, glob_pattern, case_sensitive }) => {\n let regex: RegExp;\n try {\n regex = new RegExp(pattern, case_sensitive ? 'g' : 'gi');\n } catch (e) {\n return { error: `Invalid regex: ${(e as Error).message}` };\n }\n const files = await glob(glob_pattern, {\n cwd: projectRoot,\n absolute: true,\n ignore: ['**/node_modules/**', '**/build/**', '**/.gradle/**', '**/dist/**', '**/.git/**'],\n onlyFiles: true,\n });\n const matches: Array<{ file: string; line: number; text: string }> = [];\n for (const abs of files) {\n if (matches.length >= MAX_MATCHES) break;\n const content = await readFile(abs, 'utf-8').catch(() => null);\n if (content === null || content.length > MAX_FILE_SIZE) continue;\n const lines = content.split('\\n');\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n if (line === undefined) continue;\n regex.lastIndex = 0;\n if (regex.test(line)) {\n matches.push({ file: relative(projectRoot, abs), line: i + 1, text: line.trim().slice(0, 300) });\n if (matches.length >= MAX_MATCHES) break;\n }\n }\n }\n return { matchCount: matches.length, matches, truncated: matches.length >= MAX_MATCHES };\n },\n });\n}\n","import { z } from 'zod';\nimport { tool } from 'ai';\nimport { glob } from 'tinyglobby';\nimport { relative } from 'node:path';\n\nconst MAX_RESULTS = 500;\n\nexport function makeGlobTool(projectRoot: string) {\n return tool({\n description: 'List files matching a glob pattern. Returns up to 500 paths. Use for locating files by name.',\n parameters: z.object({\n pattern: z.string().describe('Glob pattern (e.g. \"**/*.kt\", \"app/src/main/**/MainActivity.kt\").'),\n }),\n execute: async ({ pattern }) => {\n const results = await glob(pattern, {\n cwd: projectRoot,\n absolute: true,\n ignore: ['**/node_modules/**', '**/build/**', '**/.gradle/**', '**/dist/**', '**/.git/**'],\n onlyFiles: true,\n });\n const paths = results.slice(0, MAX_RESULTS).map((p) => relative(projectRoot, p));\n return { count: paths.length, paths, truncated: results.length > MAX_RESULTS };\n },\n });\n}\n","import { z } from 'zod';\nimport { tool } from 'ai';\nimport { execa } from 'execa';\nimport { confirm } from '@inquirer/prompts';\nimport { log, pc } from '../../lib/log.js';\n\nconst SAFE_BIN_ALLOWLIST = new Set([\n './gradlew',\n './gradlew.bat',\n 'git',\n 'ls',\n 'cat',\n 'pwd',\n 'find',\n 'echo',\n 'wc',\n 'head',\n 'tail',\n 'grep',\n 'rg',\n 'xxd',\n 'file',\n 'tree',\n]);\n\nconst HARD_DENY = [/rm\\s+-rf\\s+\\//, /:\\(\\)\\s*\\{\\s*:\\s*\\|\\s*:/, /mkfs/i, /dd\\s+if=/i, />\\s*\\/dev\\/sda/];\n\n// Shell metacharacters that chain or redirect commands. Presence of ANY of\n// these disqualifies a command from auto-approval: the first-token allowlist\n// only validates the first program, but `cat foo && rm -rf x` would pass that\n// check while doing arbitrary damage on the rhs of the `&&`. The user must\n// always confirm a compound command explicitly.\nconst COMPOUND_METACHARS = /[;&|`$()<>]|\\$\\(/;\n\nfunction firstToken(command: string): string {\n const trimmed = command.trim();\n return trimmed.split(/\\s+/)[0] ?? '';\n}\n\nfunction isSafe(command: string): boolean {\n for (const pattern of HARD_DENY) if (pattern.test(command)) return false;\n // Compound / chained / redirected commands are never auto-approved, even\n // when the first token looks safe.\n if (COMPOUND_METACHARS.test(command)) return false;\n const tok = firstToken(command);\n return SAFE_BIN_ALLOWLIST.has(tok);\n}\n\nconst MAX_OUTPUT = 32 * 1024;\n\nexport function makeBashTool(projectRoot: string, opts: { autoApproveSafe: boolean }) {\n return tool({\n description:\n 'Run a shell command from the project root. Read-only and gradle commands run without prompting; any other command requires user approval. Output is truncated at 32 KB.',\n parameters: z.object({\n command: z.string().describe('Shell command to execute.'),\n timeout_ms: z.number().int().min(1000).max(900_000).default(120_000),\n }),\n execute: async ({ command, timeout_ms }) => {\n for (const pattern of HARD_DENY) {\n if (pattern.test(command)) return { error: `Refusing destructive command: ${command}` };\n }\n const safe = isSafe(command);\n if (!safe || !opts.autoApproveSafe) {\n log.info(`Agent wants to run: ${pc.bold(command)}`);\n const ok = await confirm({ message: 'Run this command?', default: safe });\n if (!ok) return { error: 'User declined the command.' };\n }\n try {\n const result = await execa(command, {\n cwd: projectRoot,\n shell: true,\n timeout: timeout_ms,\n reject: false,\n all: true,\n });\n const all = (result.all ?? `${result.stdout}\\n${result.stderr}`).slice(0, MAX_OUTPUT);\n return {\n command,\n exitCode: result.exitCode ?? null,\n output: all,\n truncated: (result.all?.length ?? 0) > MAX_OUTPUT,\n timedOut: result.timedOut,\n };\n } catch (e) {\n return { error: `Execution failed: ${(e as Error).message}` };\n }\n },\n });\n}\n","import { z } from 'zod';\nimport { tool } from 'ai';\nimport { readKtxFile } from '../../ktx/reader.js';\nimport { safeJoin } from './paths.js';\n\nexport function makeAnalyzeKtxTool(projectRoot: string) {\n return tool({\n description:\n 'Parse a .ktx bundle and return its structure: format version, sections, manifests (adapter/constructor/capability), function count, entry points, signature status, bundle id. Use to diagnose runtime load errors and verify bundle contents.',\n parameters: z.object({\n path: z\n .string()\n .describe('Path to .ktx file relative to project root (e.g. \"app/src/main/assets/ketoy/main.ktx\").'),\n }),\n execute: async ({ path }) => {\n const joined = safeJoin(projectRoot, path);\n if (!joined) return { error: `Refusing to read outside project root: ${path}` };\n const { abs, rel } = joined;\n try {\n const summary = await readKtxFile(abs);\n return { ...summary, path: rel };\n } catch (e) {\n return { error: `Failed to parse ${rel}: ${(e as Error).message}` };\n }\n },\n });\n}\n","/**\n * Pure-TS .ktx bundle reader.\n *\n * Wire format (CLAUDE.md §Phase 7A/B, BUNDLE_METADATA addition §Audit Pass 3):\n * header[14] = magic[4](\"KTOY\") + formatVersion[2] + minRuntimeVersion[2] + flags[4] + sectionCount[2]\n * sections[count] = sectionType[1] + compressed[1] + uncompressedSize[4] + onDiskSize[4] + payload\n * trailer[64] = Ed25519 signature (zeros when KtxFlags.UNSIGNED set)\n *\n * Compressed sections use Brotli — Node 12+ has built-in support via zlib.brotliDecompressSync.\n */\nimport { readFile } from 'node:fs/promises';\nimport { brotliDecompressSync } from 'node:zlib';\n\nexport const KTX_MAGIC = Buffer.from([0x4b, 0x54, 0x4f, 0x59]);\nexport const SIGNATURE_SIZE = 64;\nexport const HEADER_SIZE = 14;\n\n// Section type IDs — must match ketoy-bundle-format's KtxSectionType.kt\nexport const SECTION_STRING_POOL = 0x01;\nexport const SECTION_MODIFIER_TABLE = 0x02;\nexport const SECTION_ADAPTER_MANIFEST = 0x03;\nexport const SECTION_CONSTRUCTOR_MANIFEST = 0x04;\nexport const SECTION_CAPABILITY_MANIFEST = 0x05;\nexport const SECTION_FUNCTION_TABLE = 0x06;\nexport const SECTION_CODE = 0x07;\nexport const SECTION_DEBUG_INFO = 0x08;\nexport const SECTION_ENTRY_POINTS = 0x09;\nexport const SECTION_BUNDLE_METADATA = 0x0a;\n\nexport const FLAG_DEBUG_INFO_PRESENT = 0x01;\nexport const FLAG_UNSIGNED = 0x02;\n\nexport interface KtxSection {\n type: number;\n typeName: string;\n compressed: boolean;\n uncompressedSize: number;\n onDiskSize: number;\n rawOffset: number;\n payload: Buffer;\n}\n\nexport interface KtxSummary {\n path: string;\n bytes: number;\n formatVersion: number;\n minRuntimeVersion: number;\n flags: number;\n signed: boolean;\n debugInfoFlagSet: boolean;\n sectionCount: number;\n sections: Array<{\n type: number;\n typeName: string;\n compressed: boolean;\n uncompressedSize: number;\n onDiskSize: number;\n }>;\n signature: { present: boolean; hex: string | null };\n stringPool: string[] | null;\n adapterManifest: ManifestEntry[] | null;\n constructorManifest: ManifestEntry[] | null;\n capabilityManifest: ManifestEntry[] | null;\n functionCount: number | null;\n entryPoints: Array<{ name: string; functionIndex: number }> | null;\n modifierTableSize: number | null;\n bundleId: string | null;\n composableCount: number | null;\n viewModelCount: number | null;\n minAppVersion: number | null;\n}\n\nexport interface ManifestEntry {\n id: number;\n name: string;\n required: boolean;\n}\n\nfunction sectionName(type: number): string {\n switch (type) {\n case SECTION_STRING_POOL: return 'STRING_POOL';\n case SECTION_ADAPTER_MANIFEST: return 'ADAPTER_MANIFEST';\n case SECTION_CONSTRUCTOR_MANIFEST: return 'CONSTRUCTOR_MANIFEST';\n case SECTION_CAPABILITY_MANIFEST: return 'CAPABILITY_MANIFEST';\n case SECTION_FUNCTION_TABLE: return 'FUNCTION_TABLE';\n case SECTION_CODE: return 'CODE';\n case SECTION_MODIFIER_TABLE: return 'MODIFIER_TABLE';\n case SECTION_DEBUG_INFO: return 'DEBUG_INFO';\n case SECTION_ENTRY_POINTS: return 'ENTRY_POINTS';\n case SECTION_BUNDLE_METADATA: return 'BUNDLE_METADATA';\n default: return `UNKNOWN(0x${type.toString(16).padStart(2, '0').toUpperCase()})`;\n }\n}\n\nclass Reader {\n private offset = 0;\n constructor(private buf: Buffer) {}\n pos(): number { return this.offset; }\n remaining(): number { return this.buf.length - this.offset; }\n u8(): number {\n if (this.remaining() < 1) throw new Error('Unexpected EOF (u8)');\n const v = this.buf.readUInt8(this.offset);\n this.offset += 1;\n return v;\n }\n u16(): number {\n if (this.remaining() < 2) throw new Error('Unexpected EOF (u16)');\n const v = this.buf.readUInt16BE(this.offset);\n this.offset += 2;\n return v;\n }\n i32(): number {\n if (this.remaining() < 4) throw new Error('Unexpected EOF (i32)');\n const v = this.buf.readInt32BE(this.offset);\n this.offset += 4;\n return v;\n }\n u32(): number {\n if (this.remaining() < 4) throw new Error('Unexpected EOF (u32)');\n const v = this.buf.readUInt32BE(this.offset);\n this.offset += 4;\n return v;\n }\n bytes(n: number): Buffer {\n if (this.remaining() < n) throw new Error(`Unexpected EOF (bytes ${n})`);\n const out = this.buf.subarray(this.offset, this.offset + n);\n this.offset += n;\n return out;\n }\n skip(n: number): void {\n if (this.remaining() < n) throw new Error(`Unexpected EOF (skip ${n})`);\n this.offset += n;\n }\n}\n\nfunction decompressIfNeeded(s: KtxSection): Buffer {\n if (!s.compressed) return s.payload;\n if (s.onDiskSize === s.uncompressedSize) return s.payload;\n return brotliDecompressSync(s.payload);\n}\n\nfunction parseStringPool(payload: Buffer): string[] {\n const r = new Reader(payload);\n const count = r.i32();\n const result: string[] = [];\n for (let i = 0; i < count; i++) {\n const len = r.u16();\n const text = r.bytes(len).toString('utf-8');\n result.push(text);\n }\n return result;\n}\n\nfunction parseManifest(payload: Buffer, pool: string[]): ManifestEntry[] {\n const r = new Reader(payload);\n const count = r.u16();\n const out: ManifestEntry[] = [];\n for (let i = 0; i < count; i++) {\n const id = r.u16();\n const nameIdx = r.u16();\n const required = r.u8() !== 0;\n out.push({ id, name: pool[nameIdx] ?? `?@${nameIdx}`, required });\n }\n return out;\n}\n\nfunction parseFunctionTable(payload: Buffer): { count: number } {\n const r = new Reader(payload);\n // Per KtxWriter.serializeFunctionTable each entry is at least\n // 2+2+2+2+1+2+2 = 13 bytes — but we only need the count for the summary.\n return { count: r.u16() };\n}\n\nfunction parseEntryPoints(payload: Buffer, pool: string[]): Array<{ name: string; functionIndex: number }> {\n const r = new Reader(payload);\n const count = r.u16();\n const out: Array<{ name: string; functionIndex: number }> = [];\n for (let i = 0; i < count; i++) {\n const nameIdx = r.u16();\n const fnIdx = r.u16();\n out.push({ name: pool[nameIdx] ?? `?@${nameIdx}`, functionIndex: fnIdx });\n }\n return out;\n}\n\nfunction parseModifierTable(payload: Buffer): number {\n // Layout per KtxWriter.serializeModifierTable:\n // count(u16) + [entryLen(i32) + entryBytes]*\n // We only need the count for the summary.\n const r = new Reader(payload);\n return r.u16();\n}\n\ninterface BundleMetadata {\n bundleId: string;\n composableCount: number;\n viewModelCount: number;\n minAppVersion: number;\n}\n\nfunction parseBundleMetadata(payload: Buffer, pool: string[]): BundleMetadata {\n const r = new Reader(payload);\n const bundleIdIdx = r.u16();\n const bundleId = pool[bundleIdIdx] ?? '';\n const composableCount = r.u16();\n for (let i = 0; i < composableCount; i++) {\n r.i32(); // functionIndex\n r.u16(); // nameIdx\n const paramCount = r.u16();\n r.skip(paramCount * 2); // paramIdx[u16]*\n r.u8(); // hasDefaults\n r.u8(); // isNativeCapability\n r.u16(); // capabilityId\n }\n const vmCount = r.u16();\n for (let i = 0; i < vmCount; i++) {\n r.u16(); // nameIdx\n r.i32(); // initFunctionIndex\n const eventCount = r.u16();\n for (let j = 0; j < eventCount; j++) { r.u16(); r.i32(); }\n const stateCount = r.u16();\n r.skip(stateCount * 2);\n }\n const minAppVersion = r.remaining() >= 4 ? r.i32() : 0;\n return { bundleId, composableCount, viewModelCount: vmCount, minAppVersion };\n}\n\nexport async function readKtxFile(path: string): Promise<KtxSummary> {\n const buf = await readFile(path);\n return readKtxBuffer(buf, path);\n}\n\nexport function readKtxBuffer(buf: Buffer, path = '<buffer>'): KtxSummary {\n if (buf.length < HEADER_SIZE + SIGNATURE_SIZE) {\n throw new Error(`File too small (${buf.length} bytes) to be a .ktx bundle.`);\n }\n if (buf.subarray(0, 4).compare(KTX_MAGIC) !== 0) {\n throw new Error(`Wrong magic bytes — not a .ktx bundle. Got ${buf.subarray(0, 4).toString('hex')}.`);\n }\n\n const r = new Reader(buf);\n r.skip(4);\n const formatVersion = r.u16();\n const minRuntimeVersion = r.u16();\n const flags = r.u32();\n const sectionCount = r.u16();\n\n const sections: KtxSection[] = [];\n for (let i = 0; i < sectionCount; i++) {\n const type = r.u8();\n const compressed = r.u8() !== 0;\n const uncompressedSize = r.u32();\n const onDiskSize = r.u32();\n const rawOffset = r.pos();\n const payload = r.bytes(onDiskSize);\n sections.push({ type, typeName: sectionName(type), compressed, uncompressedSize, onDiskSize, rawOffset, payload });\n }\n\n const sigOffset = buf.length - SIGNATURE_SIZE;\n if (r.pos() > sigOffset) {\n throw new Error(`Section payloads overrun signature trailer (sections end at ${r.pos()}, sig at ${sigOffset}).`);\n }\n const signatureBytes = buf.subarray(sigOffset);\n const unsigned = (flags & FLAG_UNSIGNED) !== 0;\n const signed = !unsigned && signatureBytes.some((b) => b !== 0);\n\n const pool = sections.find((s) => s.type === SECTION_STRING_POOL);\n const stringPool: string[] | null = pool ? parseStringPool(decompressIfNeeded(pool)) : null;\n\n const safeMan = (type: number): ManifestEntry[] | null => {\n if (!stringPool) return null;\n const s = sections.find((sec) => sec.type === type);\n if (!s) return null;\n return parseManifest(decompressIfNeeded(s), stringPool);\n };\n\n const fnTable = sections.find((s) => s.type === SECTION_FUNCTION_TABLE);\n const functionCount = fnTable ? parseFunctionTable(decompressIfNeeded(fnTable)).count : null;\n\n const entries = sections.find((s) => s.type === SECTION_ENTRY_POINTS);\n const entryPoints = entries && stringPool ? parseEntryPoints(decompressIfNeeded(entries), stringPool) : null;\n\n const modTable = sections.find((s) => s.type === SECTION_MODIFIER_TABLE);\n const modifierTableSize = modTable ? parseModifierTable(decompressIfNeeded(modTable)) : null;\n\n const meta = sections.find((s) => s.type === SECTION_BUNDLE_METADATA);\n const metadata = meta && stringPool ? parseBundleMetadata(decompressIfNeeded(meta), stringPool) : null;\n\n return {\n path,\n bytes: buf.length,\n formatVersion,\n minRuntimeVersion,\n flags,\n signed,\n debugInfoFlagSet: (flags & FLAG_DEBUG_INFO_PRESENT) !== 0,\n sectionCount,\n sections: sections.map((s) => ({\n type: s.type,\n typeName: s.typeName,\n compressed: s.compressed,\n uncompressedSize: s.uncompressedSize,\n onDiskSize: s.onDiskSize,\n })),\n signature: { present: signed, hex: signed ? signatureBytes.toString('hex') : null },\n stringPool,\n adapterManifest: safeMan(SECTION_ADAPTER_MANIFEST),\n constructorManifest: safeMan(SECTION_CONSTRUCTOR_MANIFEST),\n capabilityManifest: safeMan(SECTION_CAPABILITY_MANIFEST),\n functionCount,\n entryPoints,\n modifierTableSize,\n bundleId: metadata?.bundleId ?? null,\n composableCount: metadata?.composableCount ?? null,\n viewModelCount: metadata?.viewModelCount ?? null,\n minAppVersion: metadata?.minAppVersion ?? null,\n };\n}\n","import { z } from 'zod';\nimport { tool } from 'ai';\nimport { readSkillFile, listSkillFiles } from '../../skill/loader.js';\n\nexport function makeSkillFileTool() {\n return tool({\n description:\n 'Read a file from the Ketoy skill (reference/, guides/, examples/, templates/). Useful when the agent needs deeper context than the system prompt carries — e.g. specific capability IDs, modifier patterns, or the migration playbook.',\n parameters: z.object({\n name: z\n .string()\n .describe('Relative skill path, e.g. \"reference/capabilities.md\" or \"examples/todo-screen.kt\".'),\n }),\n execute: async ({ name }) => {\n const available = await listSkillFiles();\n const content = await readSkillFile(name);\n if (content === null) {\n return { error: `Skill file not found: ${name}`, available };\n }\n return { name, content };\n },\n });\n}\n","import type { Tool } from 'ai';\nimport { makeReadFileTool } from './read-file.js';\nimport { makeWriteFileTool } from './write-file.js';\nimport { makeEditFileTool } from './edit-file.js';\nimport { makeGrepTool } from './grep.js';\nimport { makeGlobTool } from './glob.js';\nimport { makeBashTool } from './bash.js';\nimport { makeAnalyzeKtxTool } from './analyze-ktx.js';\nimport { makeSkillFileTool } from './skill-file.js';\nimport { loadConfig } from '../../config/store.js';\n\nexport interface BuildToolsOptions {\n projectRoot: string;\n}\n\nexport async function buildTools(opts: BuildToolsOptions): Promise<Record<string, Tool>> {\n const config = await loadConfig();\n const { projectRoot } = opts;\n return {\n read_file: makeReadFileTool(projectRoot),\n write_file: makeWriteFileTool(projectRoot, { autoApprove: false }),\n edit_file: makeEditFileTool(projectRoot, { autoApprove: false }),\n grep: makeGrepTool(projectRoot),\n glob: makeGlobTool(projectRoot),\n bash: makeBashTool(projectRoot, { autoApproveSafe: config.agent.autoApproveSafeBash }),\n analyze_ktx: makeAnalyzeKtxTool(projectRoot),\n skill_file: makeSkillFileTool(),\n };\n}\n","import { resolve, relative } from 'node:path';\nimport { access } from 'node:fs/promises';\nimport { runAgent } from '../agent/loop.js';\nimport { log, pc } from '../lib/log.js';\nimport { KetoyCliError } from '../lib/errors.js';\n\nexport interface MigrateOptions {\n projectRoot: string;\n files: string[];\n model: string | undefined;\n}\n\nasync function fileExists(p: string): Promise<boolean> {\n try {\n await access(p);\n return true;\n } catch {\n return false;\n }\n}\n\nexport async function runMigrateCommand(opts: MigrateOptions): Promise<void> {\n if (opts.files.length === 0) {\n throw new KetoyCliError('Pass at least one file path to migrate.');\n }\n for (const f of opts.files) {\n const abs = resolve(opts.projectRoot, f);\n if (!(await fileExists(abs))) {\n throw new KetoyCliError(`File not found: ${f}`);\n }\n }\n const list = opts.files.map((f) => relative(opts.projectRoot, resolve(opts.projectRoot, f)));\n log.info(`Migrating ${list.length} file(s) to KBC: ${list.join(', ')}`);\n\n const prompt =\n `Migrate the following Compose source files to Ketoy KBC. Follow the migration playbook in skills/ketoy/guides/migrate.md strictly:\\n\\n` +\n list.map((f) => `- ${f}`).join('\\n') +\n `\\n\\nProcedure (do all steps, do not skip):\\n` +\n `1. Read each file in full.\\n` +\n `2. Audit each: list composables, state holders, side effects, forbidden APIs.\\n` +\n `3. For each unsupported call, propose a capability or alternative.\\n` +\n `4. Show me the migration plan as a checklist and ASK for confirmation before editing.\\n` +\n `5. After I confirm: update Capabilities.kt, ketoy-capabilities.json, and the host CapabilityRegistry; ` +\n `then rewrite each file with @KetoyComposable + @KetoyEntryPoint, replacing forbidden calls with capability calls.\\n` +\n `6. Run \\`./gradlew :app:ketoyBundle --rerun-tasks\\` and resolve any KetoyBC errors.\\n` +\n `7. Report what changed and any items I need to wire up host-side.\\n\\n` +\n `Do not silently rewrite. Use edit_file with surgical changes where files already exist.`;\n\n log.detail(`Sending migration task to agent — this will take several turns.`);\n log.raw('\\n');\n const result = await runAgent({\n userPrompt: prompt,\n projectRoot: opts.projectRoot,\n modelOverride: opts.model,\n });\n log.detail(\n pc.dim(\n `Migration agent finished in ${result.steps} step(s)${\n result.usage.totalTokens ? `, ${result.usage.totalTokens} tokens` : ''\n }.`,\n ),\n );\n}\n","import { execa } from 'execa';\nimport { join } from 'node:path';\nimport { access } from 'node:fs/promises';\nimport { runAgent } from '../agent/loop.js';\nimport { log, pc } from '../lib/log.js';\nimport { KetoyCliError } from '../lib/errors.js';\n\nexport interface DoctorOptions {\n projectRoot: string;\n task: string;\n model: string | undefined;\n}\n\nasync function fileExists(p: string): Promise<boolean> {\n try {\n await access(p);\n return true;\n } catch {\n return false;\n }\n}\n\nexport async function runDoctorCommand(opts: DoctorOptions): Promise<void> {\n const gradlew = process.platform === 'win32' ? join(opts.projectRoot, 'gradlew.bat') : join(opts.projectRoot, 'gradlew');\n if (!(await fileExists(gradlew))) {\n throw new KetoyCliError(`No gradle wrapper found at ${gradlew}.`);\n }\n\n log.info(`Running ${pc.bold(`./gradlew ${opts.task}`)} to capture output…`);\n // Split on whitespace so users can pass multi-word tasks like\n // `:app:ketoyBundle --rerun-tasks` without execa treating it as a single argv element.\n const taskArgs = opts.task.split(/\\s+/).filter((s) => s.length > 0);\n const result = await execa(gradlew, [...taskArgs, '--console=plain', '--stacktrace'], {\n cwd: opts.projectRoot,\n reject: false,\n all: true,\n });\n const fullLog = result.all ?? `${result.stdout}\\n${result.stderr}`;\n const trimmed = fullLog.length > 32 * 1024 ? fullLog.slice(-32 * 1024) : fullLog;\n\n if (result.exitCode === 0) {\n log.success(`Task ${opts.task} succeeded — no errors to diagnose.`);\n return;\n }\n\n log.warn(`Task failed with exit code ${result.exitCode}. Asking the agent to diagnose…`);\n log.raw('\\n');\n\n const prompt =\n `The Gradle task \\`${opts.task}\\` failed. Below is the captured output (last 32 KB).\\n\\n` +\n `Please:\\n` +\n `1. Identify each distinct error (especially \"KetoyBC:\" diagnostics).\\n` +\n `2. For each one, explain the root cause briefly and propose the minimal fix.\\n` +\n `3. Reference the skill (guides/diagnose-errors.md) when relevant.\\n` +\n `4. If a fix requires editing files, ASK before applying — use edit_file for surgical edits only.\\n` +\n `5. If multiple unrelated errors, prioritize the first KBC compile error since later ones often cascade.\\n\\n` +\n `=== BEGIN OUTPUT ===\\n${trimmed}\\n=== END OUTPUT ===`;\n\n await runAgent({\n userPrompt: prompt,\n projectRoot: opts.projectRoot,\n modelOverride: opts.model,\n });\n}\n","import { execa } from 'execa';\nimport { join } from 'node:path';\nimport { access, stat } from 'node:fs/promises';\nimport { log, pc } from '../lib/log.js';\nimport { KetoyCliError } from '../lib/errors.js';\n\nexport interface BuildOptions {\n projectRoot: string;\n variant: 'debug' | 'release' | 'bundle';\n}\n\nasync function fileExists(p: string): Promise<boolean> {\n try {\n await access(p);\n return true;\n } catch {\n return false;\n }\n}\n\nexport async function runBuildCommand(opts: BuildOptions): Promise<void> {\n const gradlew = process.platform === 'win32' ? join(opts.projectRoot, 'gradlew.bat') : join(opts.projectRoot, 'gradlew');\n if (!(await fileExists(gradlew))) {\n throw new KetoyCliError(`No gradle wrapper found at ${gradlew}. Run from the Android project root.`);\n }\n\n // `:app:ketoyBundle` always runs with `--rerun-tasks` so the APK rebuild\n // picks up the latest .ktx. Without it, Gradle's task-output caching keeps\n // the old bundle and the installed APK loads stale KBC.\n const taskArgs: string[] =\n opts.variant === 'bundle'\n ? [':app:ketoyBundle', '--rerun-tasks']\n : opts.variant === 'debug'\n ? [':app:assembleDebug']\n : [':app:assembleRelease'];\n\n log.info(`Running ${pc.bold(`./gradlew ${taskArgs.join(' ')}`)} …`);\n const result = await execa(gradlew, [...taskArgs, '--console=plain'], {\n cwd: opts.projectRoot,\n reject: false,\n stdio: 'inherit',\n });\n\n if (result.exitCode !== 0) {\n throw new KetoyCliError(`Build failed (exit ${result.exitCode}). Run \\`ketoy doctor\\` to analyze.`, result.exitCode ?? 1);\n }\n\n const bundlePath = join(opts.projectRoot, 'app', 'src', 'main', 'assets', 'ketoy', 'main.ktx');\n if (await fileExists(bundlePath)) {\n const s = await stat(bundlePath);\n log.success(`Build succeeded — bundle at ${pc.bold('app/src/main/assets/ketoy/main.ktx')} (${s.size} bytes).`);\n } else {\n log.success('Build succeeded.');\n log.warn('Bundle not found at the expected path. Confirm `ketoy { exportFromAppModule = true }` is set in app/build.gradle.kts.');\n }\n}\n","import { resolve } from 'node:path';\nimport { readKtxFile } from '../ktx/reader.js';\nimport { log, pc } from '../lib/log.js';\nimport { KetoyCliError } from '../lib/errors.js';\n\nexport interface AnalyzeOptions {\n path: string;\n showManifest: boolean;\n showStrings: boolean;\n json: boolean;\n}\n\nexport async function runAnalyzeCommand(opts: AnalyzeOptions): Promise<void> {\n const abs = resolve(process.cwd(), opts.path);\n let summary;\n try {\n summary = await readKtxFile(abs);\n } catch (e) {\n throw new KetoyCliError(`Could not parse ${opts.path}: ${(e as Error).message}`);\n }\n\n if (opts.json) {\n const sanitized = {\n ...summary,\n stringPool: opts.showStrings ? summary.stringPool : null,\n adapterManifest: opts.showManifest ? summary.adapterManifest : null,\n constructorManifest: opts.showManifest ? summary.constructorManifest : null,\n capabilityManifest: opts.showManifest ? summary.capabilityManifest : null,\n };\n log.raw(JSON.stringify(sanitized, null, 2) + '\\n');\n return;\n }\n\n log.info(pc.bold(opts.path));\n log.detail(`bytes: ${summary.bytes.toLocaleString()}`);\n log.detail(`formatVersion: ${summary.formatVersion}`);\n log.detail(`minRuntimeVersion: ${summary.minRuntimeVersion}`);\n log.detail(`flags: 0x${summary.flags.toString(16).padStart(8, '0')}`);\n log.detail(`signed: ${summary.signed ? pc.green('yes') : pc.dim('no')}`);\n if (summary.bundleId !== null) log.detail(`bundleId: ${summary.bundleId || pc.dim('(empty)')}`);\n if (summary.minAppVersion !== null) log.detail(`minAppVersion: ${summary.minAppVersion}`);\n if (summary.functionCount !== null) log.detail(`functions: ${summary.functionCount}`);\n if (summary.composableCount !== null) log.detail(`composables: ${summary.composableCount}`);\n if (summary.viewModelCount !== null) log.detail(`viewModels: ${summary.viewModelCount}`);\n if (summary.modifierTableSize !== null) log.detail(`modifierTable: ${summary.modifierTableSize} entries`);\n\n log.info('Sections:');\n for (const s of summary.sections) {\n const cmp = s.compressed ? pc.cyan(' brotli') : '';\n log.detail(\n `${s.typeName.padEnd(22)} ${String(s.onDiskSize).padStart(8)} on-disk / ${String(s.uncompressedSize).padStart(8)} uncompressed${cmp}`,\n );\n }\n\n if (summary.entryPoints && summary.entryPoints.length > 0) {\n log.info('Entry points:');\n for (const e of summary.entryPoints) log.detail(`${e.name.padEnd(28)} fn#${e.functionIndex}`);\n }\n\n if (opts.showManifest) {\n printManifest('Adapter manifest', summary.adapterManifest);\n printManifest('Constructor manifest', summary.constructorManifest);\n printManifest('Capability manifest', summary.capabilityManifest);\n }\n\n if (opts.showStrings && summary.stringPool) {\n log.info(`String pool (${summary.stringPool.length} entries):`);\n summary.stringPool.forEach((s, i) => {\n log.detail(`[${i}] ${s}`);\n });\n }\n}\n\nfunction printManifest(title: string, entries: Array<{ id: number; name: string; required: boolean }> | null): void {\n if (!entries) return;\n if (entries.length === 0) {\n log.info(`${title}: ${pc.dim('(empty)')}`);\n return;\n }\n log.info(`${title} (${entries.length}):`);\n for (const e of entries) {\n const id = `0x${e.id.toString(16).padStart(4, '0').toUpperCase()}`;\n const req = e.required ? '' : pc.dim(' (optional)');\n log.detail(`${id} ${e.name}${req}`);\n }\n}\n","import { runCli } from '../src/cli.js';\n\nawait runCli(process.argv);\n"],"mappings":"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","names":["process","cached","config","readFile","access","join","fileExists","access","join","readFile","join","access","fileExists","access","join","mkdir","writeFile","dirname","join","readFile","writeFile","readFile","writeFile","readFile","writeFile","readFile","writeFile","readFile","writeFile","readFile","writeFile","readFile","writeFile","access","fileExists","readFile","writeFile","readFile","writeFile","readFile","writeFile","readFile","writeFile","readFile","writeFile","input","findMatchingBrace","readFile","writeFile","access","fileExists","readFile","dirname","join","join","mkdir","dirname","writeFile","mkdir","readFile","writeFile","access","dirname","join","join","mkdir","dirname","writeFile","input","confirm","readFile","join","dirname","resolve","fileURLToPath","cachedRoot","readFile","stat","z","relative","resolve","z","stat","readFile","mkdir","writeFile","access","dirname","z","tool","confirm","fileExists","access","tool","z","confirm","mkdir","dirname","writeFile","readFile","writeFile","z","tool","confirm","tool","z","readFile","confirm","writeFile","z","tool","glob","readFile","relative","z","tool","glob","relative","z","tool","confirm","tool","z","confirm","z","tool","readFile","tool","z","z","tool","tool","z","input","confirm","resolve","relative","access","fileExists","access","resolve","relative","execa","join","access","fileExists","access","join","execa","execa","join","access","stat","fileExists","access","join","execa","stat","resolve","resolve","process"]}