@robota-sdk/agent-cli 3.0.0-beta.75 → 3.0.0-beta.77
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +661 -21
- package/README.md +28 -24
- package/dist/node/bin.js +18 -19
- package/dist/node/bin.js.map +1 -1
- package/dist/node/index.cjs +17 -18
- package/dist/node/index.d.ts +1 -1
- package/dist/node/index.d.ts.map +1 -1
- package/dist/node/index.js +19 -20
- package/dist/node/index.js.map +1 -1
- package/dist/web/assets/index-LMW0IDmj.js +37 -0
- package/dist/web/index.html +1 -1
- package/package.json +17 -10
package/dist/node/bin.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bin.js","names":[],"sources":["../../src/utils/cli-args.ts","../../src/startup/preset-selection.ts","../../src/startup/provider-startup.ts","../../src/user-local-direct-command.ts","../../src/session-analyzer/parser.ts","../../src/session-analyzer/reporter.ts","../../src/session-analyzer/session-analyze-command.ts","../../src/startup/version.ts","../../src/startup/reset-config.ts","../../src/startup/diagnose-command.ts","../../src/constants.ts","../../src/init/init-command.ts","../../src/startup/first-run.ts","../../src/startup/terminal-check.ts","../../src/startup/command-setup.ts","../../src/startup/append-system-prompt.ts","../../src/modes/print-mode.ts","../../src/cli.ts","../../src/bin.ts"],"sourcesContent":["/**\n * CLI argument parsing and validation.\n * Pure functions — throw on invalid input, no process.* side effects.\n */\n\nimport { parseArgs } from 'node:util';\n\nimport type { TPermissionMode } from '@robota-sdk/agent-core';\n\nconst VALID_MODES: TPermissionMode[] = ['plan', 'default', 'acceptEdits', 'bypassPermissions'];\n\nconst VALID_OUTPUT_FORMATS = ['text', 'json', 'stream-json'] as const;\nexport type TOutputFormat = (typeof VALID_OUTPUT_FORMATS)[number];\n\nexport interface IParsedCliArgs {\n positional: string[];\n help: boolean;\n printMode: boolean;\n continueMode: boolean;\n resumeId: string | undefined;\n language: string | undefined;\n permissionMode: TPermissionMode | undefined;\n maxTurns: number | undefined;\n forkSession: boolean;\n sessionName: string | undefined;\n outputFormat: TOutputFormat | undefined;\n format: string | undefined;\n summary: string | undefined;\n source: string | undefined;\n systemPrompt: string | undefined;\n appendSystemPrompt: string | undefined;\n taskFile: string | undefined;\n version: boolean;\n reset: boolean;\n bare: boolean;\n allowedTools: string | undefined;\n deniedTools: string | undefined;\n model: string | undefined;\n preset: string | undefined;\n noSessionPersistence: boolean;\n jsonSchema: string | undefined;\n configure: boolean;\n configureProvider: string | undefined;\n provider: string | undefined;\n providerType: string | undefined;\n baseURL: string | undefined;\n apiKey: string | undefined;\n apiKeyEnv: string | undefined;\n setCurrent: boolean;\n settingsScope: string | undefined;\n checkUpdate: boolean;\n disableUpdateCheck: boolean;\n dryRun: boolean;\n yes: boolean;\n}\n\n/** Return CLI usage help text. */\nexport function printHelp(): string {\n return `\nUsage: robota [options] [-p <prompt>]\n\nOptions:\n -p <prompt> Run in print (headless) mode with the given prompt\n --output-format <format> Output format: text | json | stream-json (default: text)\n --system-prompt <text> Override the system prompt for this session\n --append-system-prompt <t> Append text to the system prompt\n --language <lang> Language preference (e.g. ko, en)\n --no-session-persistence Disable session persistence for this run\n --permission-mode <mode> Permission mode: plan | default | acceptEdits | bypassPermissions\n --max-turns <n> Maximum agent turns before stopping\n -c, --continue Continue the most recent session\n -r, --resume <id> Resume a session by ID or name\n -n, --name <name> Name for the new session\n --fork-session Fork the current session into a new independent session\n --task-file <path> Read a task prompt from file and append it to the system prompt\n --bare Print mode: output raw text only, no formatting wrapper\n --configure Run interactive provider configuration\n --configure-provider <n> Configure a specific provider\n --allowed-tools <list> Comma-separated tool allowlist (TUI and print mode)\n --denied-tools <list> Comma-separated tool denylist (TUI and print mode)\n --model <model> Model override for this run\n --preset <id> Preset id to apply (default: settings.preset or \"default\")\n --json-schema <schema> Print mode: instruct the model to respond with JSON matching this schema\n --dry-run Alias for --permission-mode plan (plan only, no execution)\n --reset Delete ~/.robota/settings.json (provider profiles and preferences).\n Asks for confirmation; use --yes to skip\n --yes Skip confirmation prompts (required for --reset in non-TTY)\n --check-update Check for CLI updates\n --version Show version number\n -h, --help Show this help message\n\nCommands:\n robota init Initialize AGENTS.md and .robota/settings.json\n robota diagnose Check setup and print a diagnostics report\n\nExamples:\n robota Start interactive TUI session\n robota init Initialize project files\n robota -p \"Hello\" Print mode: send prompt and exit\n robota -p \"Hello\" --output-format json\n robota -p \"Review this diff\" --bare Raw output for shell pipelines\n robota --task-file task.md Run task from file (appended to system prompt)\n robota -p \"Refactor the auth module\" --dry-run Plan only, no execution\n robota --continue Resume the last session\n`;\n}\n\n/** Split a comma-separated tool list into trimmed, non-empty names. */\nexport function parseToolList(value: string | undefined): string[] | undefined {\n if (value === undefined) return undefined;\n const tools = value\n .split(',')\n .map((tool) => tool.trim())\n .filter((tool) => tool.length > 0);\n return tools.length > 0 ? tools : undefined;\n}\n\n/** Validate and return a TOutputFormat from a raw CLI string, or throw on error. */\nexport function parseOutputFormat(raw: string | undefined): TOutputFormat | undefined {\n if (raw === undefined) return undefined;\n if (!(VALID_OUTPUT_FORMATS as readonly string[]).includes(raw)) {\n throw new Error(`Invalid --output-format \"${raw}\". Valid: ${VALID_OUTPUT_FORMATS.join(' | ')}`);\n }\n return raw as TOutputFormat;\n}\n\n/** Validate and return a TPermissionMode from a raw CLI string, or throw on error. */\nexport function parsePermissionMode(raw: string | undefined): TPermissionMode | undefined {\n if (raw === undefined) return undefined;\n if (!VALID_MODES.includes(raw as TPermissionMode)) {\n throw new Error(`Invalid --permission-mode \"${raw}\". Valid: ${VALID_MODES.join(' | ')}`);\n }\n return raw as TPermissionMode;\n}\n\n/** Validate and return a positive integer from a raw CLI string, or throw on error. */\nexport function parseMaxTurns(raw: string | undefined): number | undefined {\n if (raw === undefined) return undefined;\n const n = parseInt(raw, 10);\n if (isNaN(n) || n <= 0) {\n throw new Error(`Invalid --max-turns \"${raw}\". Must be a positive integer.`);\n }\n return n;\n}\n\nconst PARSE_ARGS_CONFIG = {\n allowPositionals: true,\n options: {\n help: { type: 'boolean', short: 'h', default: false },\n p: { type: 'boolean', short: 'p', default: false },\n continue: { type: 'boolean', short: 'c', default: false },\n resume: { type: 'string', short: 'r' },\n language: { type: 'string' },\n 'permission-mode': { type: 'string' },\n 'max-turns': { type: 'string' },\n 'fork-session': { type: 'boolean', default: false },\n name: { type: 'string', short: 'n' },\n 'output-format': { type: 'string' },\n format: { type: 'string' },\n summary: { type: 'string' },\n source: { type: 'string' },\n 'system-prompt': { type: 'string' },\n 'append-system-prompt': { type: 'string' },\n 'task-file': { type: 'string' },\n version: { type: 'boolean', default: false },\n reset: { type: 'boolean', default: false },\n bare: { type: 'boolean', default: false },\n 'allowed-tools': { type: 'string' },\n 'denied-tools': { type: 'string' },\n model: { type: 'string' },\n preset: { type: 'string' },\n 'no-session-persistence': { type: 'boolean', default: false },\n 'json-schema': { type: 'string' },\n configure: { type: 'boolean', default: false },\n 'configure-provider': { type: 'string' },\n provider: { type: 'string' },\n type: { type: 'string' },\n 'base-url': { type: 'string' },\n 'api-key': { type: 'string' },\n 'api-key-env': { type: 'string' },\n 'set-current': { type: 'boolean', default: false },\n 'settings-scope': { type: 'string' },\n 'check-update': { type: 'boolean', default: false },\n 'disable-update-check': { type: 'boolean', default: false },\n 'dry-run': { type: 'boolean', default: false },\n yes: { type: 'boolean', short: 'y', default: false },\n },\n} as const;\n\nfunction mapParsedValues(\n values: ReturnType<typeof parseArgs<typeof PARSE_ARGS_CONFIG>>['values'],\n positionals: string[],\n): IParsedCliArgs {\n return {\n positional: positionals,\n help: values['help'] ?? false,\n printMode: values['p'] ?? false,\n continueMode: values['continue'] ?? false,\n resumeId: values['resume'],\n language: values['language'],\n permissionMode: parsePermissionMode(values['permission-mode']),\n maxTurns: parseMaxTurns(values['max-turns']),\n forkSession: values['fork-session'] ?? false,\n sessionName: values['name'],\n outputFormat: parseOutputFormat(values['output-format']),\n format: values['format'],\n summary: values['summary'],\n source: values['source'],\n systemPrompt: values['system-prompt'],\n appendSystemPrompt: values['append-system-prompt'],\n taskFile: values['task-file'],\n version: values['version'] ?? false,\n reset: values['reset'] ?? false,\n bare: values['bare'] ?? false,\n allowedTools: values['allowed-tools'],\n deniedTools: values['denied-tools'],\n model: values['model'],\n preset: values['preset'],\n noSessionPersistence: values['no-session-persistence'] ?? false,\n jsonSchema: values['json-schema'],\n configure: values['configure'] ?? false,\n configureProvider: values['configure-provider'],\n provider: values['provider'],\n providerType: values['type'],\n baseURL: values['base-url'],\n apiKey: values['api-key'],\n apiKeyEnv: values['api-key-env'],\n setCurrent: values['set-current'] ?? false,\n settingsScope: values['settings-scope'],\n checkUpdate: values['check-update'] ?? false,\n disableUpdateCheck: values['disable-update-check'] ?? false,\n dryRun: values['dry-run'] ?? false,\n yes: values['yes'] ?? false,\n };\n}\n\n/** Parse and validate CLI arguments. */\nexport function parseCliArgs(): IParsedCliArgs {\n const { values, positionals } = parseArgs(PARSE_ARGS_CONFIG);\n const args = mapParsedValues(values, positionals);\n if (args.printMode) {\n if (args.resumeId === '') {\n throw new Error(\n 'Print mode requires an explicit session id: -r <id|name> (the interactive session picker is TUI-only)',\n );\n }\n if (args.noSessionPersistence && (args.continueMode || args.resumeId !== undefined)) {\n throw new Error(\n '--no-session-persistence conflicts with -c/-r (resume needs the session store)',\n );\n }\n }\n if (args.dryRun) {\n if (args.permissionMode !== undefined && args.permissionMode !== 'plan') {\n throw new Error(\n `--dry-run is an alias for --permission-mode plan and conflicts with --permission-mode ${args.permissionMode}`,\n );\n }\n return { ...args, permissionMode: 'plan' };\n }\n return args;\n}\n","/**\n * Preset selection glue — thin shell over `@robota-sdk/agent-preset`.\n * The CLI only selects the preset id and forwards CLI flags as overrides; the\n * precedence merge lives entirely inside `resolvePreset` (agent-preset), never here.\n */\n\nimport { resolvePreset } from '@robota-sdk/agent-preset';\nimport type { TResolvedPresetOptions } from '@robota-sdk/agent-preset';\n\nimport type { IParsedCliArgs } from '../utils/cli-args.js';\n\n/** Pick the preset id: --preset flag > settings.preset > 'default'. Pure selection glue (shell). */\nexport function selectPresetId(\n args: Pick<IParsedCliArgs, 'preset'>,\n settingsPreset: string | undefined,\n): string {\n return args.preset ?? settingsPreset ?? 'default';\n}\n\n/** Build the CLI-flag override set (highest-but-explicit tier) handed to resolvePreset. */\nfunction buildPresetCliOverrides(args: IParsedCliArgs): TResolvedPresetOptions {\n return {\n ...(args.model !== undefined ? { model: args.model } : {}),\n ...(args.systemPrompt !== undefined ? { systemPrompt: args.systemPrompt } : {}),\n ...(args.appendSystemPrompt !== undefined\n ? { appendSystemPrompt: args.appendSystemPrompt }\n : {}),\n ...(args.language !== undefined ? { language: args.language } : {}),\n ...(args.permissionMode !== undefined ? { permissionMode: args.permissionMode } : {}),\n };\n}\n\n/** Resolve the active preset → framework option bundle (merge owned by agent-preset). Throws on unknown id. */\nexport function resolveCliPreset(\n args: IParsedCliArgs,\n settingsPreset: string | undefined,\n): TResolvedPresetOptions {\n return resolvePreset(selectPresetId(args, settingsPreset), {\n cliOverrides: buildPresetCliOverrides(args),\n });\n}\n","import { formatSupportedProviderTypes, type IProviderDefinition } from '@robota-sdk/agent-core';\nimport type { IParsedCliArgs } from '../utils/cli-args.js';\nimport {\n applyProviderConfiguration,\n applyProviderSwitch,\n readMergedProviderSettings,\n resolveProviderSettingsWriteTargetPath,\n resolveSettingsPathForScope,\n} from '@robota-sdk/agent-framework';\nimport type { TSettingsScope } from '@robota-sdk/agent-framework';\nimport { createDefaultProviderDefinitions } from '@robota-sdk/agent-provider';\nimport { type IProviderSetupInput } from '@robota-sdk/agent-framework';\nimport {\n ensureProviderConfig,\n runProviderStartupSetup,\n type TPromptInput,\n} from '@robota-sdk/agent-command';\nimport type { ITerminalOutput } from '@robota-sdk/agent-core';\n\nfunction validateSettingsScope(scope: string | undefined): TSettingsScope | undefined {\n if (scope === undefined || scope === 'user' || scope === 'project-local') {\n return scope as TSettingsScope | undefined;\n }\n throw new Error(`Invalid --settings-scope \"${scope}\". Valid: user | project-local`);\n}\n\nexport function handleProviderConfigurationArgs(\n cwd: string,\n args: IParsedCliArgs,\n terminal: ITerminalOutput,\n providerDefinitions: readonly IProviderDefinition[] = createDefaultProviderDefinitions(),\n): boolean {\n const settingsPath = resolveSettingsPathForScope(cwd, validateSettingsScope(args.settingsScope));\n if (args.configureProvider) {\n applyProviderConfiguration(settingsPath, buildSetupInputFromArgs(args), {\n providerDefinitions,\n });\n terminal.writeLine(`Provider profile saved to ${settingsPath}`);\n return !args.printMode && args.positional.length === 0;\n }\n if (args.provider && args.setCurrent) {\n const switchSettingsPath =\n args.settingsScope === undefined ? resolveProviderSettingsWriteTargetPath(cwd) : settingsPath;\n applyProviderSwitch(switchSettingsPath, args.provider, {\n knownProviders: readMergedProviderSettings(cwd).providers,\n });\n terminal.writeLine(`Current provider set to ${args.provider}`);\n return !args.printMode && args.positional.length === 0;\n }\n return false;\n}\n\nexport async function ensureConfig(\n cwd: string,\n args: IParsedCliArgs,\n promptInput: TPromptInput,\n terminal: ITerminalOutput,\n providerDefinitions: readonly IProviderDefinition[] = createDefaultProviderDefinitions(),\n isInteractive?: boolean,\n): Promise<void> {\n await ensureProviderConfig(\n cwd,\n { provider: args.provider, settingsScope: validateSettingsScope(args.settingsScope) },\n promptInput,\n terminal,\n providerDefinitions,\n {\n formatError: formatMissingProviderConfigMessage,\n isInteractive:\n isInteractive !== undefined\n ? () => isInteractive\n : () => process.stdin.isTTY === true && process.stdout.isTTY === true,\n },\n );\n}\n\nexport async function runInteractiveProviderSetup(\n cwd: string,\n args: IParsedCliArgs,\n promptInput: TPromptInput,\n terminal: ITerminalOutput,\n providerDefinitions: readonly IProviderDefinition[] = createDefaultProviderDefinitions(),\n): Promise<void> {\n await runProviderStartupSetup(\n cwd,\n { settingsScope: validateSettingsScope(args.settingsScope) },\n promptInput,\n terminal,\n providerDefinitions,\n );\n}\n\nfunction buildSetupInputFromArgs(args: IParsedCliArgs): IProviderSetupInput {\n const type = args.providerType ?? args.configureProvider;\n if (!args.configureProvider || !type) {\n throw new Error('--configure-provider requires a provider profile and --type');\n }\n return {\n profile: args.configureProvider,\n type,\n ...(args.model !== undefined && { model: args.model }),\n ...(args.apiKey !== undefined && { apiKey: args.apiKey }),\n ...(args.apiKeyEnv !== undefined && { apiKeyEnv: args.apiKeyEnv }),\n ...(args.baseURL !== undefined && { baseURL: args.baseURL }),\n setCurrent: args.setCurrent,\n };\n}\n\nexport function formatMissingProviderConfigMessage(\n providerDefinitions: readonly IProviderDefinition[] = createDefaultProviderDefinitions(),\n): string {\n return [\n 'No provider configuration found.',\n 'Run `robota --configure` in an interactive terminal, or configure a provider:',\n `Supported providers: ${formatSupportedProviderTypes(providerDefinitions)}`,\n ...providerDefinitions.map(formatConfigureProviderExample),\n ].join('\\n');\n}\n\nfunction formatConfigureProviderExample(definition: IProviderDefinition): string {\n const flags = [\n `robota --configure-provider ${definition.type}`,\n `--type ${definition.type}`,\n ...(definition.defaults?.baseURL !== undefined ? ['--base-url <url>'] : []),\n '--model <model>',\n ...(definition.requiresApiKey === true ? ['--api-key-env <ENV_NAME>'] : []),\n '--set-current',\n ];\n return ` ${flags.join(' ')}`;\n}\n","import { executeUserLocalDirectCommand } from '@robota-sdk/agent-command';\nimport type { ITerminalOutput } from '@robota-sdk/agent-core';\nimport type { IParsedCliArgs } from './utils/cli-args.js';\n\nexport async function runUserLocalDirectCommandIfRequested(\n args: IParsedCliArgs,\n cwd: string,\n terminal: ITerminalOutput,\n): Promise<boolean> {\n if (args.positional[0] !== 'user-local') {\n return false;\n }\n\n const result = await executeUserLocalDirectCommand({\n cwd,\n argv: args.positional.slice(1),\n format: args.format,\n summary: args.summary,\n source: args.source,\n });\n const output = result.message.trimEnd();\n if (!result.success) {\n throw new Error(output);\n }\n terminal.writeLine(output);\n return true;\n}\n","/**\n * Session log parser and timing interval calculator.\n */\n\nimport { readFileSync } from 'node:fs';\n\nimport type {\n ISessionHistoryEntry,\n ISessionRecord,\n ISessionTimingReport,\n ITimingInterval,\n ITimingStats,\n TIntervalKind,\n} from './types.js';\n\nexport function parseSessionFile(filePath: string): ISessionRecord {\n const raw = readFileSync(filePath, 'utf-8');\n return JSON.parse(raw) as ISessionRecord;\n}\n\n/** Calculate gap in milliseconds between two ISO 8601 timestamps. */\nexport function gapMs(from: string, to: string): number {\n return new Date(to).getTime() - new Date(from).getTime();\n}\n\n/**\n * Compute timing intervals from a history entry array.\n *\n * Strategy: scan the timeline turn by turn.\n * A \"turn\" starts with a user message. After user, we expect:\n * - zero or more: tool-start → tool-end cycles\n * - optionally: tool-summary\n * - finally: assistant message\n */\nexport function computeTimingIntervals(history: ISessionHistoryEntry[]): ITimingInterval[] {\n const intervals: ITimingInterval[] = [];\n let turnIndex = 0;\n\n let i = 0;\n while (i < history.length) {\n const entry = history[i];\n if (!entry) {\n i++;\n continue;\n }\n\n if (entry.category === 'chat' && entry.type === 'user') {\n turnIndex++;\n const userTs = entry.timestamp;\n let foundFirstTool = false;\n let lastToolEndTs: string | null = null;\n let j = i + 1;\n\n while (j < history.length) {\n const next = history[j];\n if (!next) {\n j++;\n continue;\n }\n\n if (next.category === 'chat' && next.type === 'user') {\n break;\n }\n\n if (next.category === 'event' && next.type === 'tool-start') {\n if (!foundFirstTool) {\n intervals.push(\n makeInterval(\n 'user_to_first_tool',\n 'user',\n 'tool-start',\n userTs,\n next.timestamp,\n turnIndex,\n ),\n );\n foundFirstTool = true;\n } else if (lastToolEndTs !== null) {\n intervals.push(\n makeInterval(\n 'llm_between_tools',\n 'tool-end',\n 'tool-start',\n lastToolEndTs,\n next.timestamp,\n turnIndex,\n ),\n );\n }\n lastToolEndTs = null;\n j++;\n continue;\n }\n\n if (next.category === 'event' && next.type === 'tool-end') {\n const prev = history[j - 1];\n if (prev && prev.category === 'event' && prev.type === 'tool-start') {\n intervals.push(\n makeInterval(\n 'tool_exec',\n 'tool-start',\n 'tool-end',\n prev.timestamp,\n next.timestamp,\n turnIndex,\n ),\n );\n }\n lastToolEndTs = next.timestamp;\n j++;\n continue;\n }\n\n if (next.category === 'event' && next.type === 'tool-summary') {\n if (lastToolEndTs !== null) {\n intervals.push(\n makeInterval(\n 'llm_final_response',\n 'tool-end',\n 'tool-summary',\n lastToolEndTs,\n next.timestamp,\n turnIndex,\n ),\n );\n }\n j++;\n continue;\n }\n\n if (next.category === 'chat' && next.type === 'assistant') {\n if (!foundFirstTool) {\n intervals.push(\n makeInterval(\n 'user_to_assistant',\n 'user',\n 'assistant',\n userTs,\n next.timestamp,\n turnIndex,\n ),\n );\n } else if (lastToolEndTs !== null) {\n intervals.push(\n makeInterval(\n 'llm_final_response',\n 'tool-end',\n 'assistant',\n lastToolEndTs,\n next.timestamp,\n turnIndex,\n ),\n );\n }\n j++;\n break;\n }\n\n j++;\n }\n\n i = j;\n } else {\n i++;\n }\n }\n\n return intervals;\n}\n\nfunction makeInterval(\n kind: TIntervalKind,\n fromType: string,\n toType: string,\n fromTimestamp: string,\n toTimestamp: string,\n turnIndex: number,\n): ITimingInterval {\n return {\n kind,\n fromType,\n toType,\n fromTimestamp,\n toTimestamp,\n durationMs: gapMs(fromTimestamp, toTimestamp),\n turnIndex,\n };\n}\n\nconst SLOW_THRESHOLD_MS = 10_000;\n\nfunction computeStats(intervals: ITimingInterval[]): ITimingStats {\n const llm = intervals.filter(\n (iv) =>\n iv.kind === 'user_to_first_tool' ||\n iv.kind === 'user_to_assistant' ||\n iv.kind === 'llm_between_tools' ||\n iv.kind === 'llm_final_response',\n );\n const tool = intervals.filter((iv) => iv.kind === 'tool_exec');\n const direct = intervals.filter((iv) => iv.kind === 'user_to_assistant');\n\n const avg = (arr: ITimingInterval[]) =>\n arr.length ? Math.round(arr.reduce((s, iv) => s + iv.durationMs, 0) / arr.length) : 0;\n const max = (arr: ITimingInterval[]) =>\n arr.length ? Math.max(...arr.map((iv) => iv.durationMs)) : 0;\n const median = (arr: ITimingInterval[]) => {\n if (!arr.length) return 0;\n const sorted = [...arr].sort((a, b) => a.durationMs - b.durationMs);\n const mid = Math.floor(sorted.length / 2);\n return sorted.length % 2 === 0\n ? Math.round(((sorted[mid - 1]?.durationMs ?? 0) + (sorted[mid]?.durationMs ?? 0)) / 2)\n : (sorted[mid]?.durationMs ?? 0);\n };\n\n return {\n llmWaitMs: {\n avg: avg(llm),\n max: max(llm),\n total: llm.reduce((s, iv) => s + iv.durationMs, 0),\n count: llm.length,\n },\n toolExecMs: { avg: avg(tool), max: max(tool), median: median(tool), count: tool.length },\n userToAssistantMs: { avg: avg(direct), max: max(direct), count: direct.length },\n };\n}\n\nexport function analyzeSession(record: ISessionRecord): ISessionTimingReport {\n const history = record.history ?? [];\n const intervals = computeTimingIntervals(history);\n const slowIntervals = intervals.filter((iv) => iv.durationMs >= SLOW_THRESHOLD_MS);\n\n return {\n sessionId: record.id,\n cwd: record.cwd,\n createdAt: record.createdAt,\n totalIntervals: intervals.length,\n intervals,\n slowIntervals,\n stats: computeStats(intervals),\n };\n}\n","/**\n * Text report formatter for session timing analysis.\n */\n\nimport type { IAggregateReport, ISessionTimingReport, ITimingInterval } from './types.js';\n\nfunction fmtMs(ms: number): string {\n if (ms >= 1000) return `${(ms / 1000).toFixed(1)}s`;\n return `${ms}ms`;\n}\n\nfunction fmtDate(iso: string): string {\n return new Date(iso).toLocaleString('sv-SE', { timeZoneName: 'short' }).slice(0, 16);\n}\n\nfunction intervalLabel(iv: ITimingInterval): string {\n const map: Record<string, string> = {\n user_to_first_tool: 'user → tool-start',\n user_to_assistant: 'user → assistant',\n tool_exec: 'tool-start → tool-end',\n llm_between_tools: 'tool-end → tool-start',\n llm_final_response: 'tool-end → assistant/summary',\n };\n return map[iv.kind] ?? iv.kind;\n}\n\nfunction verdictLine(report: ISessionTimingReport): string {\n const { stats } = report;\n const totalMs = stats.llmWaitMs.total + stats.toolExecMs.avg * stats.toolExecMs.count;\n if (totalMs === 0) return 'Verdict: No timing data available.';\n const llmPct = Math.round((stats.llmWaitMs.total / totalMs) * 100);\n const toolPct = 100 - llmPct;\n return `Verdict: LLM API wait ${llmPct}% | Code processing ${toolPct}%`;\n}\n\nexport function formatSingleSession(report: ISessionTimingReport): string {\n const lines: string[] = [];\n const { stats } = report;\n\n lines.push(`Session: ${report.sessionId}`);\n lines.push(`Created: ${fmtDate(report.createdAt)} | cwd: ${report.cwd}`);\n lines.push('');\n lines.push('Timing Summary:');\n\n if (stats.llmWaitMs.count > 0) {\n lines.push(\n ` LLM API wait ${fmtMs(stats.llmWaitMs.avg).padStart(8)} avg | ${fmtMs(stats.llmWaitMs.max).padStart(8)} max`,\n );\n }\n if (stats.toolExecMs.count > 0) {\n lines.push(\n ` Tool execution ${fmtMs(stats.toolExecMs.avg).padStart(8)} avg | ${fmtMs(stats.toolExecMs.median).padStart(8)} median`,\n );\n }\n if (stats.userToAssistantMs.count > 0) {\n lines.push(` user → assistant ${fmtMs(stats.userToAssistantMs.avg).padStart(8)} avg`);\n }\n if (stats.llmWaitMs.count === 0 && stats.toolExecMs.count === 0) {\n lines.push(' (no intervals computed — session may have no history)');\n }\n\n if (report.slowIntervals.length > 0) {\n lines.push('');\n lines.push('Slow intervals (>10s):');\n for (const iv of report.slowIntervals) {\n lines.push(\n ` turn ${iv.turnIndex} ${intervalLabel(iv).padEnd(32)} ${fmtMs(iv.durationMs).padStart(8)}`,\n );\n }\n }\n\n lines.push('');\n lines.push(verdictLine(report));\n\n return lines.join('\\n');\n}\n\nexport function formatAggregateReport(aggregate: IAggregateReport): string {\n const lines: string[] = [];\n lines.push(\n `Analyzed ${aggregate.sessionCount} sessions (${fmtDate(aggregate.fromDate)} ~ ${fmtDate(aggregate.toDate)})`,\n );\n lines.push(` Avg LLM response: ${fmtMs(aggregate.avgLlmResponseMs)}`);\n lines.push(` Avg tool exec: ${fmtMs(aggregate.avgToolExecMs)}`);\n if (aggregate.maxSingleDelayMs > 0) {\n lines.push(\n ` Max single delay: ${fmtMs(aggregate.maxSingleDelayMs)} (${aggregate.maxSingleDelaySession}, turn ${aggregate.maxSingleDelayTurn}, ${aggregate.maxSingleDelayKind})`,\n );\n }\n return lines.join('\\n');\n}\n","/**\n * `robota session analyze` command.\n *\n * Usage:\n * robota session analyze — analyze the most recent session\n * robota session analyze --last <n> — aggregate the last N sessions\n * robota session analyze --session <id> — analyze a specific session by ID prefix\n */\n\nimport { readdirSync } from 'node:fs';\nimport { basename, join } from 'node:path';\n\nimport { projectPaths, userPaths } from '@robota-sdk/agent-framework';\n\nimport { analyzeSession, parseSessionFile } from './parser.js';\nimport { formatAggregateReport, formatSingleSession } from './reporter.js';\nimport type { IAggregateReport, ISessionTimingReport } from './types.js';\n\ninterface ISessionAnalyzeArgs {\n last: number | undefined;\n sessionId: string | undefined;\n}\n\nfunction parseSessionAnalyzeArgs(argv: string[]): ISessionAnalyzeArgs {\n let last: number | undefined;\n let sessionId: string | undefined;\n\n for (let i = 0; i < argv.length; i++) {\n if (argv[i] === '--last' && argv[i + 1]) {\n const n = parseInt(argv[i + 1]!, 10);\n if (!isNaN(n) && n > 0) last = n;\n i++;\n } else if (argv[i] === '--session' && argv[i + 1]) {\n sessionId = argv[i + 1];\n i++;\n }\n }\n\n return { last, sessionId };\n}\n\nfunction listSessionFilesIn(sessionsDir: string): string[] {\n try {\n return readdirSync(sessionsDir)\n .filter((f) => f.endsWith('.json'))\n .map((f) => join(sessionsDir, f));\n } catch {\n // allow-fallback: sessions directory may not exist on first run — empty list is correct response\n return [];\n }\n}\n\n/**\n * OBS-001 fix: sessions are persisted to the PROJECT store (`cwd/.robota/sessions`) by both\n * print and TUI modes, while older history may live at the USER level. Read both, de-dupe by\n * file basename (project wins on collision), and sort by basename — session ids are\n * timestamp-prefixed, so lexical order is chronological.\n */\nfunction listSessionFiles(cwd: string): string[] {\n const byName = new Map<string, string>();\n for (const path of listSessionFilesIn(userPaths().sessions)) {\n byName.set(basename(path), path);\n }\n for (const path of listSessionFilesIn(projectPaths(cwd).sessions)) {\n byName.set(basename(path), path);\n }\n return [...byName.entries()].sort((a, b) => a[0].localeCompare(b[0])).map(([, path]) => path);\n}\n\nfunction buildAggregateReport(reports: ISessionTimingReport[]): IAggregateReport {\n const llmIntervals = reports.flatMap((r) =>\n r.intervals.filter(\n (iv) =>\n iv.kind === 'user_to_first_tool' ||\n iv.kind === 'user_to_assistant' ||\n iv.kind === 'llm_between_tools' ||\n iv.kind === 'llm_final_response',\n ),\n );\n const toolIntervals = reports.flatMap((r) => r.intervals.filter((iv) => iv.kind === 'tool_exec'));\n\n const avgLlmResponseMs = llmIntervals.length\n ? Math.round(llmIntervals.reduce((s, iv) => s + iv.durationMs, 0) / llmIntervals.length)\n : 0;\n const avgToolExecMs = toolIntervals.length\n ? Math.round(toolIntervals.reduce((s, iv) => s + iv.durationMs, 0) / toolIntervals.length)\n : 0;\n\n let maxSingleDelayMs = 0;\n let maxSingleDelaySession = '';\n let maxSingleDelayTurn = 0;\n let maxSingleDelayKind = '';\n\n for (const r of reports) {\n for (const iv of r.intervals) {\n if (iv.durationMs > maxSingleDelayMs) {\n maxSingleDelayMs = iv.durationMs;\n maxSingleDelaySession = r.sessionId;\n maxSingleDelayTurn = iv.turnIndex;\n maxSingleDelayKind = iv.kind;\n }\n }\n }\n\n const dates = reports.map((r) => r.createdAt).sort();\n\n return {\n sessionCount: reports.length,\n fromDate: dates[0] ?? '',\n toDate: dates[dates.length - 1] ?? '',\n avgLlmResponseMs,\n avgToolExecMs,\n maxSingleDelayMs,\n maxSingleDelaySession,\n maxSingleDelayTurn,\n maxSingleDelayKind,\n };\n}\n\nexport async function runSessionAnalyze(\n argv: string[],\n cwd: string = process.cwd(),\n): Promise<void> {\n const args = parseSessionAnalyzeArgs(argv);\n const allFiles = listSessionFiles(cwd);\n\n if (allFiles.length === 0) {\n process.stderr.write(\n `No session files found in ${projectPaths(cwd).sessions} or ${userPaths().sessions}\\n`,\n );\n process.exit(1);\n }\n\n if (args.sessionId !== undefined) {\n const matched = allFiles.find((f) => f.includes(args.sessionId!));\n if (!matched) {\n process.stderr.write(`Session not found: ${args.sessionId}\\n`);\n process.exit(1);\n }\n const record = parseSessionFile(matched);\n const report = analyzeSession(record);\n process.stdout.write(formatSingleSession(report) + '\\n');\n return;\n }\n\n if (args.last !== undefined) {\n const files = allFiles.slice(-args.last);\n const reports: ISessionTimingReport[] = [];\n for (const f of files) {\n try {\n reports.push(analyzeSession(parseSessionFile(f)));\n } catch {\n // allow-fallback: corrupted or partial session files are skipped — expected on interrupted writes\n // skip unreadable session files\n }\n }\n if (reports.length === 0) {\n process.stderr.write('No valid sessions found.\\n');\n process.exit(1);\n }\n const aggregate = buildAggregateReport(reports);\n process.stdout.write(formatAggregateReport(aggregate) + '\\n');\n return;\n }\n\n // Default: analyze the most recent session\n const latest = allFiles[allFiles.length - 1];\n if (!latest) {\n process.stderr.write('No sessions found.\\n');\n process.exit(1);\n }\n const record = parseSessionFile(latest);\n const report = analyzeSession(record);\n process.stdout.write(formatSingleSession(report) + '\\n');\n}\n","import { readPackageVersion } from '@robota-sdk/agent-framework';\n\nexport const readVersion = (): string => readPackageVersion(import.meta.url);\n","import { existsSync } from 'node:fs';\nimport { createInterface } from 'node:readline/promises';\n\nimport { getUserSettingsPath, resetUserConfig } from '@robota-sdk/agent-framework';\n\nimport type { ITerminalOutput } from '@robota-sdk/agent-core';\n\nexport interface IResetConfigOptions {\n /** --yes flag: skip the confirmation prompt. */\n yes: boolean;\n /** Whether stdin is a TTY (non-TTY without --yes refuses to delete). */\n isTTY: boolean;\n /** Confirmation prompt (test seam, default: readline y/N on stdin). */\n confirm?: (question: string) => Promise<boolean>;\n}\n\nasync function confirmViaReadline(question: string): Promise<boolean> {\n const rl = createInterface({ input: process.stdin, output: process.stdout });\n try {\n const answer = (await rl.question(question)).trim().toLowerCase();\n return answer === 'y' || answer === 'yes';\n } finally {\n rl.close();\n }\n}\n\n/**\n * CLI-070 confirmation matrix for the destructive `--reset` flag:\n * `--yes` → delete; TTY without `--yes` → y/N prompt (default N);\n * non-TTY without `--yes` → refuse with exit 1, file untouched.\n * Returns the process exit code.\n */\nexport async function runResetConfig(\n terminal: ITerminalOutput,\n options: IResetConfigOptions,\n): Promise<number> {\n const path = getUserSettingsPath();\n if (!existsSync(path)) {\n terminal.writeLine('No user settings found.');\n return 0;\n }\n\n if (!options.yes) {\n if (!options.isTTY) {\n terminal.writeError(\n `--reset deletes ${path}. Refusing without confirmation in non-interactive mode — pass --yes to proceed.`,\n );\n return 1;\n }\n const confirm = options.confirm ?? confirmViaReadline;\n const confirmed = await confirm(`Delete ${path}? [y/N] `);\n if (!confirmed) {\n terminal.writeLine('Reset cancelled.');\n return 1;\n }\n }\n\n const result = resetUserConfig();\n if (result.deleted) {\n terminal.writeLine(`Deleted ${result.path}`);\n } else {\n terminal.writeLine('No user settings found.');\n }\n return 0;\n}\n","import { createConnection } from 'node:net';\nimport { existsSync, readFileSync } from 'node:fs';\nimport { join } from 'node:path';\n\nimport { getProviderSettingsPaths, readProviderSettings } from '@robota-sdk/agent-framework';\nimport { createDefaultProviderDefinitions } from '@robota-sdk/agent-provider';\n\nimport type { IProviderDefinition, ITerminalOutput } from '@robota-sdk/agent-core';\n\nconst PROVIDER_ENDPOINTS: Record<string, { host: string; port: number }> = {\n anthropic: { host: 'api.anthropic.com', port: 443 },\n openai: { host: 'api.openai.com', port: 443 },\n gemini: { host: 'generativelanguage.googleapis.com', port: 443 },\n deepseek: { host: 'api.deepseek.com', port: 443 },\n qwen: { host: 'dashscope.aliyuncs.com', port: 443 },\n};\n\nexport interface IDiagnoseContext {\n version: string;\n terminal: ITerminalOutput;\n cwd: string;\n}\n\nexport interface IDiagnosticCheck {\n label: string;\n status: 'ok' | 'warn' | 'fail';\n message: string;\n}\n\nexport interface IDiagnoseDependencies {\n checkNetwork: (endpoint: { host: string; port: number }) => Promise<IDiagnosticCheck>;\n /** Environment map for provider resolution (test seam, default: process.env). */\n env?: Record<string, string | undefined>;\n /** Provider definitions for resolution (default: the CLI's default set). */\n providerDefinitions?: readonly IProviderDefinition[];\n}\n\nfunction checkNodeVersion(): IDiagnosticCheck {\n const [major] = process.versions.node.split('.').map(Number);\n if (major !== undefined && major >= 22) {\n return { label: 'Node.js version', status: 'ok', message: `v${process.versions.node}` };\n }\n return {\n label: 'Node.js version',\n status: 'fail',\n message: `v${process.versions.node} (requires >=22)\\n nvm: nvm install 22 && nvm use 22\\n Volta: volta install node@22`,\n };\n}\n\nfunction checkCliVersion(version: string): IDiagnosticCheck {\n return { label: 'robota version', status: 'ok', message: version };\n}\n\n/**\n * CLI-067: the API-key check IS the runtime resolution — settings profiles\n * (with `$ENV:` references) first, then env-default synthesis (CLI-066).\n * Diagnose can never disagree with session start again. Never prints key values.\n */\nfunction checkApiKeyResolution(\n cwd: string,\n providerDefinitions: readonly IProviderDefinition[],\n env: Record<string, string | undefined>,\n): IDiagnosticCheck {\n try {\n const config = readProviderSettings(cwd, { providerDefinitions, env });\n const source =\n config.source === 'env-default'\n ? `env-default via ${config.sourceEnvVar ?? 'environment'}`\n : 'settings profile';\n const model = config.model !== undefined ? ` (${config.model})` : '';\n return { label: 'API key', status: 'ok', message: `${config.name}${model} — ${source}` };\n } catch (error) {\n // allow-fallback: resolution failure is the diagnostic finding being reported, not a crash\n const message = error instanceof Error ? error.message : String(error);\n return {\n label: 'API key',\n status: 'fail',\n message: `${message}\\n Set ANTHROPIC_API_KEY or run: robota --configure\\n Get key: https://console.anthropic.com/settings/keys`,\n };\n }\n}\n\nfunction validateJsonFile(filePath: string): 'ok' | 'corrupt' {\n try {\n JSON.parse(readFileSync(filePath, 'utf-8'));\n return 'ok';\n } catch {\n // allow-fallback: corrupt JSON → reported as diagnostic finding, not a crash\n return 'corrupt';\n }\n}\n\n/**\n * CLI-067: every settings file the runtime merge chain reads is validated\n * independently — a corrupt user-level file is flagged even when a valid\n * project file exists. Missing files are not an issue (the API-key check\n * reports actual resolution failures).\n */\nfunction checkSettingsFiles(cwd: string): IDiagnosticCheck[] {\n const existing = getProviderSettingsPaths(cwd).filter((path) => existsSync(path));\n if (existing.length === 0) {\n return [\n {\n label: 'Settings file',\n status: 'warn',\n message: 'Not found — run: robota --configure',\n },\n ];\n }\n return existing.map((path) =>\n validateJsonFile(path) === 'corrupt'\n ? {\n label: 'Settings file',\n status: 'fail' as const,\n message: `${path} — invalid JSON\\n Fix or delete the file, or run: robota --configure`,\n }\n : { label: 'Settings file', status: 'ok' as const, message: path },\n );\n}\n\nfunction tryReadCurrentProvider(settingsPath: string): string | undefined {\n try {\n const doc = JSON.parse(readFileSync(settingsPath, 'utf-8')) as { currentProvider?: string };\n return typeof doc.currentProvider === 'string' ? doc.currentProvider : undefined;\n } catch {\n // allow-fallback: unreadable settings for network check → caller uses default endpoint\n return undefined;\n }\n}\n\nfunction resolveNetworkEndpoint(cwd: string): { host: string; port: number } {\n const settingsPath = join(cwd, '.robota', 'settings.json');\n const homeSettings = join(process.env['HOME'] ?? '', '.robota', 'settings.json');\n const activePath = existsSync(settingsPath)\n ? settingsPath\n : existsSync(homeSettings)\n ? homeSettings\n : undefined;\n if (activePath !== undefined) {\n const providerKey = (tryReadCurrentProvider(activePath) ?? '').toLowerCase();\n const match = Object.entries(PROVIDER_ENDPOINTS).find(([key]) => providerKey.startsWith(key));\n if (match) return match[1];\n }\n return PROVIDER_ENDPOINTS['anthropic']!;\n}\n\nfunction checkTerminal(): IDiagnosticCheck {\n const term = process.env['TERM_PROGRAM'] ?? 'unknown';\n if (process.platform === 'darwin' && term === 'Apple_Terminal') {\n return {\n label: 'Terminal',\n status: 'warn',\n message: `macOS Terminal.app — CJK/IME input may be unstable\\n Recommendation: use iTerm2 (https://iterm2.com)`,\n };\n }\n return { label: 'Terminal', status: 'ok', message: term };\n}\n\nfunction checkNetworkViaSocket(endpoint: {\n host: string;\n port: number;\n}): Promise<IDiagnosticCheck> {\n const label = `Network (${endpoint.host})`;\n return new Promise((resolve) => {\n const start = Date.now();\n const socket = createConnection({ host: endpoint.host, port: endpoint.port });\n const timeout = setTimeout(() => {\n socket.destroy();\n resolve({ label, status: 'fail', message: 'timeout (3s)' });\n }, 3000);\n socket.on('connect', () => {\n clearTimeout(timeout);\n socket.destroy();\n resolve({ label, status: 'ok', message: `reachable (${Date.now() - start}ms)` });\n });\n socket.on('error', (err) => {\n clearTimeout(timeout);\n resolve({\n label,\n status: 'warn',\n message: `${err.message}\\n Check proxy settings or firewall`,\n });\n });\n });\n}\n\n/**\n * Runs every diagnostic check and returns the number of failed checks —\n * the exit-code contract (CLI-067) is 0 when the count is 0, otherwise 1.\n */\nexport async function runDiagnoseCommand(\n ctx: IDiagnoseContext,\n deps: IDiagnoseDependencies = { checkNetwork: checkNetworkViaSocket },\n): Promise<number> {\n ctx.terminal.writeLine('\\nrobota diagnose\\n');\n\n const networkEndpoint = resolveNetworkEndpoint(ctx.cwd);\n const providerDefinitions = deps.providerDefinitions ?? createDefaultProviderDefinitions();\n const env = deps.env ?? process.env;\n\n const checks: IDiagnosticCheck[] = [\n checkNodeVersion(),\n checkCliVersion(ctx.version),\n checkApiKeyResolution(ctx.cwd, providerDefinitions, env),\n ...checkSettingsFiles(ctx.cwd),\n checkTerminal(),\n await deps.checkNetwork(networkEndpoint),\n ];\n\n let failCount = 0;\n let warnCount = 0;\n\n for (const check of checks) {\n const icon = check.status === 'ok' ? '✓' : check.status === 'warn' ? '⚠' : '✗';\n const lines = check.message.split('\\n');\n ctx.terminal.writeLine(` ${icon} ${check.label}: ${lines[0]}`);\n for (const line of lines.slice(1)) {\n ctx.terminal.writeLine(` ${line}`);\n }\n if (check.status === 'fail') failCount++;\n if (check.status === 'warn') warnCount++;\n }\n\n ctx.terminal.writeLine('');\n if (failCount === 0 && warnCount === 0) {\n ctx.terminal.writeLine('✓ All checks passed. robota is ready to use.');\n } else if (failCount > 0) {\n ctx.terminal.writeLine(`✗ ${failCount} issue(s) found. Fix the items above to use robota.`);\n } else {\n ctx.terminal.writeLine(`⚠ ${warnCount} warning(s). robota may work but check the items above.`);\n }\n ctx.terminal.writeLine('');\n return failCount;\n}\n","export const AGENT_CLI_BIN = 'robota';\n","import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\n\nimport { promptInput } from '@robota-sdk/agent-transport/headless';\nimport { projectPaths } from '@robota-sdk/agent-framework';\n\nimport { AGENT_CLI_BIN } from '../constants.js';\n\nimport type { ITerminalOutput } from '@robota-sdk/agent-core';\n\nconst AGENTS_MD_TEMPLATE = `# AGENTS.md — Project Agent Guidelines\n\nThis file guides the AI agent working in this project. Customize it for your project.\n\n## Project Overview\n\n<!-- Describe your project's purpose, tech stack, and key conventions -->\n\n## Common Commands\n\n\\`\\`\\`bash\n# Install dependencies\nnpm install\n\n# Run tests\nnpm test\n\n# Build\nnpm run build\n\\`\\`\\`\n\n## Coding Conventions\n\n- Language: <!-- e.g. TypeScript strict mode -->\n- Test framework: <!-- e.g. Vitest, Jest -->\n- Linting: <!-- e.g. ESLint with prettier -->\n\n## Important Notes\n\n<!-- Anything the agent should know before making changes -->\n`;\n\nconst SETTINGS_TEMPLATE = {\n permissions: {\n allow: ['Read(.robota/**)', 'Read(.claude/**)', 'Read(.agents/**)'],\n deny: [],\n },\n};\n\nfunction readClaudeSettings(claudeDir: string): Record<string, unknown> | null {\n const settingsPath = join(claudeDir, 'settings.json');\n if (!existsSync(settingsPath)) return {};\n const raw = readFileSync(settingsPath, 'utf8');\n try {\n return JSON.parse(raw) as Record<string, unknown>;\n } catch {\n // allow-fallback: malformed settings.json is non-fatal — null signals caller to show warning and skip migration\n return null;\n }\n}\n\n/** A confirmation was required but stdin cannot prompt (non-TTY without --yes). */\nexport class InitPromptUnavailableError extends Error {\n constructor(question: string) {\n super(\n `Cannot ask \"${question}\" in a non-interactive shell. Re-run with --yes to accept the defaults.`,\n );\n this.name = 'InitPromptUnavailableError';\n }\n}\n\nexport interface IInitCommandOptions {\n /** Skip all Y/n prompts and use the documented defaults (non-interactive mode). */\n yes?: boolean;\n /** Called after init completes when the user accepts the provider setup prompt. */\n onProviderSetup?: () => Promise<void>;\n /** Test seam: prompt function (default: transport promptInput). */\n promptFn?: (question: string) => Promise<string>;\n /** Test seam: interactive stdin state (default: process.stdin.isTTY). */\n isTTY?: boolean;\n /** Test seam: CI environment detection (default: process.env.CI === 'true'). */\n ci?: boolean;\n}\n\ninterface IConfirmContext {\n yes: boolean;\n ci: boolean;\n isTTY: boolean;\n promptFn: (question: string) => Promise<string>;\n terminal: ITerminalOutput;\n}\n\n/**\n * Unified Y/n confirmation: --yes/CI apply the documented default without\n * prompting; non-TTY without --yes is a hard error naming the question;\n * otherwise prompt interactively.\n */\nasync function confirm(\n question: string,\n defaultAnswer: boolean,\n ctx: IConfirmContext,\n): Promise<boolean> {\n if (ctx.yes || ctx.ci) {\n ctx.terminal.writeLine(\n `${question} → ${defaultAnswer ? 'Y' : 'N'} (${ctx.yes ? '--yes' : 'CI'}: using default)`,\n );\n return defaultAnswer;\n }\n if (!ctx.isTTY) {\n throw new InitPromptUnavailableError(question);\n }\n const answer = await ctx.promptFn(`${question} [y/N] `);\n return answer.toLowerCase() === 'y' || answer.toLowerCase() === 'yes';\n}\n\nexport async function runInitCommand(\n cwd: string,\n terminal: ITerminalOutput,\n options: IInitCommandOptions = {},\n): Promise<void> {\n terminal.writeLine('');\n terminal.writeLine(`${AGENT_CLI_BIN} project initialization`);\n terminal.writeLine('─'.repeat(40));\n\n const confirmCtx: IConfirmContext = {\n yes: options.yes === true,\n ci: options.ci ?? process.env['CI'] === 'true',\n isTTY: options.isTTY ?? process.stdin.isTTY === true,\n promptFn: options.promptFn ?? promptInput,\n terminal,\n };\n\n const settingsPath = projectPaths(cwd).settings;\n const robotaDir = dirname(settingsPath);\n const agentsMdPath = join(cwd, 'AGENTS.md');\n const claudeDir = join(cwd, '.claude');\n const hasClaudeDir = existsSync(claudeDir);\n\n const hasSettings = existsSync(settingsPath);\n const hasAgentsMd = existsSync(agentsMdPath);\n\n if (hasSettings && hasAgentsMd) {\n terminal.writeLine('');\n terminal.writeLine('Both AGENTS.md and .robota/settings.json already exist.');\n const overwrite = await confirm('Overwrite existing files?', false, confirmCtx);\n if (!overwrite) {\n terminal.writeLine('Init cancelled.');\n return;\n }\n }\n\n let settingsData: Record<string, unknown> = { ...SETTINGS_TEMPLATE };\n\n if (hasClaudeDir) {\n terminal.writeLine('');\n terminal.writeLine('Detected .claude/ directory (Claude Code configuration).');\n const migrate = await confirm('Migrate Claude Code settings to .robota/?', false, confirmCtx);\n if (migrate) {\n const claudeSettings = readClaudeSettings(claudeDir);\n if (claudeSettings === null) {\n terminal.writeLine(\n 'Warning: .claude/settings.json could not be parsed — skipping migration.',\n );\n } else {\n const claudePerms = claudeSettings.permissions as\n | { allow?: string[]; deny?: string[] }\n | undefined;\n settingsData = {\n ...claudeSettings,\n permissions: {\n ...(typeof claudeSettings.permissions === 'object' &&\n claudeSettings.permissions !== null\n ? (claudeSettings.permissions as Record<string, unknown>)\n : {}),\n allow: [...SETTINGS_TEMPLATE.permissions.allow, ...(claudePerms?.allow ?? [])],\n deny: claudePerms?.deny ?? [],\n },\n };\n terminal.writeLine('Settings imported from .claude/settings.json.');\n }\n }\n }\n\n mkdirSync(robotaDir, { recursive: true });\n writeFileSync(settingsPath, JSON.stringify(settingsData, null, 2) + '\\n', 'utf8');\n terminal.writeLine('');\n terminal.writeLine('Created: .robota/settings.json');\n\n writeFileSync(agentsMdPath, AGENTS_MD_TEMPLATE, 'utf8');\n terminal.writeLine('Created: AGENTS.md');\n\n terminal.writeLine('');\n terminal.writeLine('Initialization complete.');\n terminal.writeLine('');\n terminal.writeLine('Next steps:');\n terminal.writeLine(' 1. Edit AGENTS.md to describe your project conventions');\n terminal.writeLine(` 2. Run \\`${AGENT_CLI_BIN} --configure\\` to set up your AI provider`);\n terminal.writeLine(` 3. Run \\`${AGENT_CLI_BIN}\\` to start the assistant`);\n terminal.writeLine('');\n\n // Provider setup is an optional trailing step: init has already completed, so a\n // non-TTY shell skips it (default N) rather than failing a successful init.\n if (\n options.onProviderSetup !== undefined &&\n (confirmCtx.isTTY || confirmCtx.yes || confirmCtx.ci)\n ) {\n const setupNow = await confirm('Would you like to set up a provider now?', false, confirmCtx);\n if (setupNow) {\n await options.onProviderSetup();\n }\n }\n}\n","import { existsSync, mkdirSync, writeFileSync } from 'node:fs';\nimport { dirname } from 'node:path';\n\nimport type { ITerminalOutput } from '@robota-sdk/agent-core';\nimport { userPaths } from '@robota-sdk/agent-framework';\n\nimport { AGENT_CLI_BIN } from '../constants.js';\n\nexport function isFirstRun(markerPath: string = userPaths().onboarded): boolean {\n return !existsSync(markerPath);\n}\n\nexport function markOnboarded(markerPath: string = userPaths().onboarded): void {\n mkdirSync(dirname(markerPath), { recursive: true });\n writeFileSync(markerPath, new Date().toISOString());\n}\n\nconst WELCOME_MESSAGE = `\n╭─────────────────────────────────────────────────────────────╮\n│ Welcome to ${AGENT_CLI_BIN}! — AI coding assistant │\n│ │\n│ Try asking: │\n│ \"Explain this project structure\" │\n│ \"Find files with TODO comments\" │\n│ \"Run tests and analyze failures\" │\n│ \"What changed recently in git?\" │\n│ │\n│ Useful commands: │\n│ /help show all slash commands │\n│ /cost show token usage and estimated cost │\n│ /clear clear conversation history │\n│ │\n│ ${AGENT_CLI_BIN} diagnose — check your setup │\n╰─────────────────────────────────────────────────────────────╯\n`;\n\nexport function printFirstRunWelcome(terminal: ITerminalOutput): void {\n terminal.writeLine(WELCOME_MESSAGE);\n}\n","import type { ITerminalOutput } from '@robota-sdk/agent-core';\n\n/**\n * Emit a non-blocking warning when running on macOS Terminal.app,\n * which has known CJK/IME instability in raw/interactive mode.\n */\nexport function warnIfTerminalAppOnMacOS(terminal: ITerminalOutput): void {\n if (process.platform !== 'darwin') return;\n if (process.env['TERM_PROGRAM'] !== 'Apple_Terminal') return;\n terminal.writeError(\n '\\n⚠ macOS Terminal.app detected: CJK/IME input may be unstable.\\n' +\n ' Recommended: use iTerm2 (https://iterm2.com) for Korean/Japanese/Chinese input.\\n' +\n ' Or use headless mode: robota -p \"your prompt\"\\n',\n );\n}\n","import type { IProviderDefinition } from '@robota-sdk/agent-core';\nimport {\n getStartupCliUpdateNotice,\n getUserSettingsPath,\n readMergedProviderSettings,\n readSettings,\n resolveProviderSettingsWriteTargetPath,\n shouldRunStartupCliUpdateCheck,\n writeSettings,\n} from '@robota-sdk/agent-framework';\nimport type {\n ICliUpdateNotice,\n ICommandHostAdapters,\n ICommandModule,\n TProviderSettingsDocument,\n} from '@robota-sdk/agent-framework';\nimport {\n createDefaultCommandModules,\n createDefaultPluginCommandAdapter,\n} from '@robota-sdk/agent-command';\nimport { createDefaultProviderDefinitions } from '@robota-sdk/agent-provider';\nimport type { IParsedCliArgs } from '../utils/cli-args.js';\n\nexport interface IStartCliOptions {\n commandModules?: readonly ICommandModule[];\n providerDefinitions?: readonly IProviderDefinition[];\n}\n\n/** Preset-resolved command module selection forwarded by the thin-shell CLI. */\nexport interface ICommandModuleSelection {\n /** Whitelist of module names to keep (omitted → all default modules). */\n enabledCommandModules?: readonly string[];\n /** Blacklist of module names to remove after the whitelist (deny > allow). */\n disabledCommandModules?: readonly string[];\n}\n\nexport interface ICliSetup {\n commandHostAdapters: ICommandHostAdapters;\n providerDefinitions: readonly IProviderDefinition[];\n commandModules: readonly ICommandModule[];\n startupUpdateNoticePromise: Promise<ICliUpdateNotice | undefined> | undefined;\n}\n\nexport function buildCommandSetup(\n cwd: string,\n args: IParsedCliArgs,\n options: IStartCliOptions,\n version: string,\n moduleSelection: ICommandModuleSelection = {},\n): ICliSetup {\n const commandHostAdapters: ICommandHostAdapters = {\n settings: {\n read: () => readSettings(getUserSettingsPath()),\n write: (settings) => writeSettings(getUserSettingsPath(), settings),\n },\n plugin: createDefaultPluginCommandAdapter(cwd),\n };\n const providerDefinitions = options.providerDefinitions ?? createDefaultProviderDefinitions();\n const providerSettingsAdapter = {\n readMergedSettings: () => readMergedProviderSettings(cwd),\n readTargetSettings: () =>\n readSettings(resolveProviderSettingsWriteTargetPath(cwd)) as TProviderSettingsDocument,\n writeTargetSettings: (settings: TProviderSettingsDocument) =>\n writeSettings(resolveProviderSettingsWriteTargetPath(cwd), settings),\n };\n const commandModules: readonly ICommandModule[] = [\n ...createDefaultCommandModules({\n cwd,\n providerDefinitions,\n providerSettingsAdapter,\n ...(moduleSelection.enabledCommandModules !== undefined\n ? { enabledCommandModules: moduleSelection.enabledCommandModules }\n : {}),\n ...(moduleSelection.disabledCommandModules !== undefined\n ? { disabledCommandModules: moduleSelection.disabledCommandModules }\n : {}),\n }),\n ...(options.commandModules ?? []),\n ];\n const startupUpdateNoticePromise = shouldRunStartupCliUpdateCheck(args)\n ? getStartupCliUpdateNotice({ currentVersion: version })\n : undefined;\n return { commandHostAdapters, providerDefinitions, commandModules, startupUpdateNoticePromise };\n}\n","import { readFileSync } from 'node:fs';\nimport { resolve } from 'node:path';\nimport type { IParsedCliArgs } from '../utils/cli-args.js';\n\nfunction readTaskFilePrompt(cwd: string, taskFile: string): string {\n const taskPath = resolve(cwd, taskFile);\n const content = readFileSync(taskPath, 'utf8').trim();\n if (content.length === 0) {\n throw new Error(`Task file is empty: ${taskFile}`);\n }\n return `Task file (${taskFile}):\\n${content}`;\n}\n\nexport function buildAppendSystemPrompt(cwd: string, args: IParsedCliArgs): string | undefined {\n const appendParts: string[] = [];\n if (args.appendSystemPrompt) appendParts.push(args.appendSystemPrompt);\n if (args.taskFile) {\n try {\n appendParts.push(readTaskFilePrompt(cwd, args.taskFile));\n } catch (error) {\n // allow-fallback: terminal failure — task file read failure exits process\n process.stderr.write(`${error instanceof Error ? error.message : String(error)}\\n`);\n process.exit(1);\n }\n }\n if (args.jsonSchema)\n appendParts.push(\n `Respond with valid JSON only, matching this JSON schema:\\n${args.jsonSchema}`,\n );\n return appendParts.length > 0 ? appendParts.join('\\n\\n') : undefined;\n}\n","import type { IAIProvider, TPermissionMode } from '@robota-sdk/agent-core';\nimport type { ICommandHostAdapters, ICommandModule } from '@robota-sdk/agent-framework';\nimport type { createProjectSessionStore } from '@robota-sdk/agent-framework';\nimport { HeadlessInteractionChannel } from '@robota-sdk/agent-transport/headless';\nimport type { IBackgroundTaskRunner } from '@robota-sdk/agent-executor';\nimport type { createChildProcessSubagentRunnerFactory } from '@robota-sdk/agent-subagent-runner';\nimport type { IParsedCliArgs } from '../utils/cli-args.js';\nimport { parseToolList } from '../utils/cli-args.js';\nimport { buildAppendSystemPrompt } from '../startup/append-system-prompt.js';\n\nexport interface IPrintModeSessionResolution {\n /** Session id resolved by the CLI from -c/-r (undefined starts a new session). */\n resumeSessionId?: string;\n /** Fork the resumed session into a new independent session (--fork-session). */\n forkSession?: boolean;\n}\n\n/** Preset-resolved identity/persona the thin-shell CLI forwards into the headless session. */\nexport interface IPrintModePresetOptions {\n /** Resolved agent name (preset value, else agent-preset DEFAULT_AGENT_NAME). */\n agentName?: string;\n /** Active preset id selected at startup (PRESET-011 runtime state). Defaults to 'default'. */\n activePresetId?: string;\n /** Resolved preset persona block composed as a `source: 'persona'` system-prompt section. */\n persona?: string;\n /** Resolved preset permission mode (overridden by an explicit CLI --permission-mode flag). */\n permissionMode?: TPermissionMode;\n /** Preset execution capability: activate agent runtime + subagent/background dispatch. */\n enableParallelSubagents?: boolean;\n /** Preset execution capability: run a post-task self-verification step. */\n selfVerification?: boolean;\n}\n\nexport async function runPrintMode(\n cwd: string,\n args: IParsedCliArgs,\n provider: IAIProvider,\n sessionStore: ReturnType<typeof createProjectSessionStore>,\n backgroundTaskRunners: IBackgroundTaskRunner[],\n subagentRunnerFactory: ReturnType<typeof createChildProcessSubagentRunnerFactory>,\n commandModules: readonly ICommandModule[],\n commandHostAdapters: ICommandHostAdapters,\n sessionResolution: IPrintModeSessionResolution = {},\n presetOptions: IPrintModePresetOptions = {},\n): Promise<void> {\n let prompt = args.positional.join(' ').trim();\n\n if (!prompt && !process.stdin.isTTY) {\n const chunks: Buffer[] = [];\n for await (const chunk of process.stdin) {\n chunks.push(chunk as Buffer);\n }\n prompt = Buffer.concat(chunks).toString('utf-8').trim();\n }\n\n if (!prompt) {\n process.stderr.write('Print mode (-p) requires a prompt argument.\\n');\n process.exit(1);\n }\n\n const appendSystemPrompt = buildAppendSystemPrompt(cwd, args);\n\n const channel = new HeadlessInteractionChannel({\n cwd,\n provider,\n outputFormat: args.outputFormat ?? 'text',\n permissionMode: args.permissionMode ?? presetOptions.permissionMode ?? 'bypassPermissions',\n maxTurns: args.maxTurns,\n sessionStore: args.noSessionPersistence ? undefined : sessionStore,\n resumeSessionId: sessionResolution.resumeSessionId,\n forkSession: sessionResolution.forkSession,\n sessionName: args.sessionName,\n bare: args.bare || undefined,\n allowedTools: parseToolList(args.allowedTools),\n deniedTools: parseToolList(args.deniedTools),\n appendSystemPrompt,\n ...(presetOptions.persona !== undefined ? { persona: presetOptions.persona } : {}),\n ...(presetOptions.agentName !== undefined ? { agentName: presetOptions.agentName } : {}),\n ...(presetOptions.activePresetId !== undefined\n ? { activePresetId: presetOptions.activePresetId }\n : {}),\n ...(presetOptions.enableParallelSubagents !== undefined\n ? { enableParallelSubagents: presetOptions.enableParallelSubagents }\n : {}),\n ...(presetOptions.selfVerification !== undefined\n ? { selfVerification: presetOptions.selfVerification }\n : {}),\n ...(args.systemPrompt ? { systemPrompt: args.systemPrompt } : {}),\n backgroundTaskRunners,\n subagentRunnerFactory,\n commandModules,\n commandHostAdapters,\n });\n\n await channel.run(prompt);\n process.exit(channel.getExitCode());\n}\n","/**\n * CLI entry point — pure composition root.\n * Parses arguments and delegates to startup modules, mode runners, and transports.\n */\n\nimport { execSync } from 'node:child_process';\nimport { PrintTerminal, promptInput } from '@robota-sdk/agent-transport/headless';\nimport {\n createProjectSessionStore,\n projectPaths,\n resolveLatestSessionId,\n resolveSessionIdByIdOrName,\n readMergedProviderSettings,\n readProviderSettings,\n createProviderFromSettings,\n checkForCliUpdate,\n formatCliUpdateCheckMessage,\n formatCliUpdateNotice,\n ProviderConfigError,\n readSettings,\n getUserSettingsPath,\n} from '@robota-sdk/agent-framework';\nimport { parseCliArgs, parseToolList, printHelp } from './utils/cli-args.js';\nimport type { IParsedCliArgs } from './utils/cli-args.js';\nimport { resolveCliPreset, selectPresetId } from './startup/preset-selection.js';\nimport { DEFAULT_AGENT_NAME, loadExternalPresets } from '@robota-sdk/agent-preset';\nimport type { TResolvedPresetOptions } from '@robota-sdk/agent-preset';\nimport {\n ensureConfig,\n handleProviderConfigurationArgs,\n runInteractiveProviderSetup,\n} from './startup/provider-startup.js';\nimport { renderApp, createDefaultTuiCliAdapter } from '@robota-sdk/agent-transport/tui';\nimport { createDefaultTransportRegistry } from '@robota-sdk/agent-transport';\nimport { createDefaultBackgroundTaskRunners } from '@robota-sdk/agent-executor';\nimport {\n createChildProcessSubagentRunnerFactory,\n getDefaultSubagentWorkerPath,\n} from '@robota-sdk/agent-subagent-runner';\nimport { reloadPluginCommandSource } from '@robota-sdk/agent-command';\nimport { runUserLocalDirectCommandIfRequested } from './user-local-direct-command.js';\nimport { runSessionAnalyze } from './session-analyzer/session-analyze-command.js';\nimport { readVersion } from './startup/version.js';\nimport { runResetConfig } from './startup/reset-config.js';\nimport { runDiagnoseCommand } from './startup/diagnose-command.js';\nimport { runInitCommand } from './init/init-command.js';\nimport { isFirstRun, markOnboarded, printFirstRunWelcome } from './startup/first-run.js';\nimport { warnIfTerminalAppOnMacOS } from './startup/terminal-check.js';\nimport type { IStartCliOptions } from './startup/command-setup.js';\nimport { buildCommandSetup } from './startup/command-setup.js';\nimport { runPrintMode } from './modes/print-mode.js';\n\nexport type { IStartCliOptions };\n\nexport async function startCli(options: IStartCliOptions = {}): Promise<void> {\n // OBS-001: `session analyze` carries its own flags (--last/--session) that the strict\n // global parser does not know. Intercept it BEFORE parseCliArgs() so those flags reach\n // the subcommand instead of being rejected as \"Unknown option\".\n if (process.argv[2] === 'session' && process.argv[3] === 'analyze') {\n await runSessionAnalyze(process.argv.slice(4), process.cwd());\n return;\n }\n\n let args: IParsedCliArgs;\n try {\n args = parseCliArgs();\n } catch (error) {\n // allow-fallback: argument validation errors are terminal — exit is the correct response\n process.stderr.write(`${error instanceof Error ? error.message : String(error)}\\n`);\n process.exit(1);\n }\n const version = readVersion();\n\n if (args.help) {\n process.stdout.write(printHelp());\n return;\n }\n\n if (args.version) {\n process.stdout.write(`robota ${version}\\n`);\n return;\n }\n\n if (args.checkUpdate) {\n const result = await checkForCliUpdate({ currentVersion: version, force: true });\n const message = formatCliUpdateCheckMessage(result);\n if (result.status === 'error') {\n process.stderr.write(`${message}\\n`);\n process.exit(1);\n }\n process.stdout.write(`${message}\\n`);\n return;\n }\n\n const cwd = process.cwd();\n const terminal = new PrintTerminal();\n\n if (args.reset) {\n // Destructive-action contract (CLI-070): confirm in TTY, require --yes otherwise.\n process.exitCode = await runResetConfig(terminal, {\n yes: args.yes,\n isTTY: process.stdin.isTTY === true,\n });\n return;\n }\n\n if (args.positional[0] === 'diagnose') {\n // Exit contract (CLI-067): 0 = no issues, 1 = one or more failed checks.\n const failCount = await runDiagnoseCommand({ version, terminal, cwd });\n process.exitCode = failCount > 0 ? 1 : 0;\n return;\n }\n\n if (args.positional[0] === 'session' && args.positional[1] === 'analyze') {\n // Normally unreachable — the pre-parse interceptor above handles `session analyze`.\n // Kept as a defensive fallthrough for non-argv invocations.\n await runSessionAnalyze(process.argv.slice(4), cwd);\n return;\n }\n\n try {\n if (await runUserLocalDirectCommandIfRequested(args, cwd, terminal)) {\n return;\n }\n } catch (error) {\n // allow-fallback: user-local command failure is terminal — exit is the correct response\n terminal.writeError(error instanceof Error ? error.message : String(error));\n process.exit(1);\n }\n\n // PRESET-002/004: thin shell — select preset id (flag > settings.preset > 'default') and forward\n // the resolved framework options. The precedence merge + posture mapping lives in\n // agent-preset.resolvePreset; the CLI owns none of that logic. Resolved before command setup so\n // the preset's module-selection delta can reach createDefaultCommandModules.\n const userSettings = readSettings(getUserSettingsPath());\n const settingsPreset = typeof userSettings.preset === 'string' ? userSettings.preset : undefined;\n // PRESET-007: register user-authored external presets (~/.robota/presets/*.json) into the\n // shared registry before resolution so `--preset <id>` and `/preset` can see them. Per-file\n // load/validation problems are non-fatal and surfaced as warnings; the run still proceeds.\n const externalPresetLoad = loadExternalPresets();\n for (const { file, error } of externalPresetLoad.errors) {\n terminal.writeError(`Skipped external preset \"${file}\": ${error}`);\n }\n let resolvedPreset: TResolvedPresetOptions;\n try {\n resolvedPreset = resolveCliPreset(args, settingsPreset);\n } catch (error) {\n // allow-fallback: unknown preset id is terminal — surface available list, exit\n process.stderr.write(`${error instanceof Error ? error.message : String(error)}\\n`);\n process.exit(1);\n }\n // PRESET-011: the selected preset id (same selection glue as resolveCliPreset) becomes the\n // session's runtime active-preset state. Pure state — no option re-application here.\n const selectedPresetId = selectPresetId(args, settingsPreset);\n\n const { commandHostAdapters, providerDefinitions, commandModules, startupUpdateNoticePromise } =\n buildCommandSetup(cwd, args, options, version, {\n ...(resolvedPreset.enabledCommandModules !== undefined\n ? { enabledCommandModules: resolvedPreset.enabledCommandModules }\n : {}),\n ...(resolvedPreset.disabledCommandModules !== undefined\n ? { disabledCommandModules: resolvedPreset.disabledCommandModules }\n : {}),\n });\n\n if (args.positional[0] === 'init') {\n try {\n await runInitCommand(cwd, terminal, {\n yes: args.yes,\n onProviderSetup: async () => {\n await runInteractiveProviderSetup(cwd, args, promptInput, terminal, providerDefinitions);\n },\n });\n } catch (error) {\n // allow-fallback: init prompt failure is terminal — exit is the correct response\n terminal.writeError(error instanceof Error ? error.message : String(error));\n process.exit(1);\n }\n return;\n }\n\n if (args.configure) {\n await runInteractiveProviderSetup(cwd, args, promptInput, terminal, providerDefinitions);\n return;\n }\n\n if (handleProviderConfigurationArgs(cwd, args, terminal, providerDefinitions)) {\n return;\n }\n\n try {\n await ensureConfig(cwd, args, promptInput, terminal, providerDefinitions);\n } catch (error) {\n // allow-fallback: terminal failure — not a silent fallback\n process.stderr.write(`${error instanceof Error ? error.message : String(error)}\\n`);\n // Exit-code contract: provider configuration errors in print mode exit 3 so\n // automation can distinguish \"reconfigure\" from runtime failures (exit 1).\n process.exit(error instanceof ProviderConfigError && args.printMode ? 3 : 1);\n }\n\n const providerOptions = args.provider\n ? { providerOverride: args.provider, providerDefinitions }\n : { providerDefinitions };\n const providerSettings = readProviderSettings(cwd, providerOptions);\n const modelId = resolvedPreset.model ?? providerSettings.model;\n if (providerSettings.source === 'env-default' && providerSettings.sourceEnvVar !== undefined) {\n const notice = `Using ${providerSettings.name} (${modelId}) via ${providerSettings.sourceEnvVar} — run \\`robota --configure\\` to persist a profile.\\n`;\n if (args.printMode) {\n process.stderr.write(notice);\n } else {\n terminal.writeLine(notice.trimEnd());\n }\n }\n const provider = createProviderFromSettings(cwd, resolvedPreset.model, providerOptions);\n const backgroundTaskRunners = createDefaultBackgroundTaskRunners();\n const paths = projectPaths(cwd);\n const subagentRunnerFactory = createChildProcessSubagentRunnerFactory({\n workerPath: getDefaultSubagentWorkerPath(),\n providerConfig: { ...providerSettings, model: modelId },\n logsDir: paths.logs,\n });\n\n const sessionStore = createProjectSessionStore(cwd);\n let resumeSessionId: string | undefined;\n let showSessionPickerOnStart = false;\n\n if (args.continueMode) {\n resumeSessionId = resolveLatestSessionId(sessionStore, cwd);\n } else if (args.resumeId !== undefined) {\n if (args.resumeId === '') {\n showSessionPickerOnStart = true;\n } else {\n resumeSessionId = resolveSessionIdByIdOrName(sessionStore, args.resumeId);\n if (resumeSessionId === undefined) {\n process.stderr.write(`Session not found: ${args.resumeId}\\n`);\n process.exit(1);\n }\n }\n }\n\n if (args.printMode) {\n await runPrintMode(\n cwd,\n args,\n provider,\n sessionStore,\n backgroundTaskRunners,\n subagentRunnerFactory,\n commandModules,\n commandHostAdapters,\n { resumeSessionId, forkSession: args.forkSession },\n {\n agentName: resolvedPreset.agentName ?? DEFAULT_AGENT_NAME,\n activePresetId: selectedPresetId,\n persona: resolvedPreset.persona,\n ...(resolvedPreset.permissionMode !== undefined\n ? { permissionMode: resolvedPreset.permissionMode }\n : {}),\n ...(resolvedPreset.enableParallelSubagents !== undefined\n ? { enableParallelSubagents: resolvedPreset.enableParallelSubagents }\n : {}),\n ...(resolvedPreset.selfVerification !== undefined\n ? { selfVerification: resolvedPreset.selfVerification }\n : {}),\n },\n );\n return;\n }\n\n warnIfTerminalAppOnMacOS(terminal);\n if (isFirstRun()) {\n printFirstRunWelcome(terminal);\n markOnboarded();\n }\n\n await renderApp({\n cwd,\n provider,\n providerOverride: args.provider,\n providerType: providerSettings.name,\n modelId,\n language: args.language,\n permissionMode: args.permissionMode ?? resolvedPreset.permissionMode,\n maxTurns: args.maxTurns,\n allowedTools: parseToolList(args.allowedTools),\n deniedTools: parseToolList(args.deniedTools),\n version,\n sessionStore: args.noSessionPersistence ? undefined : sessionStore,\n resumeSessionId,\n showSessionPickerOnStart,\n forkSession: args.forkSession,\n sessionName: args.sessionName,\n backgroundTaskRunners,\n subagentRunnerFactory,\n commandModules,\n commandHostAdapters,\n shellExec: (command: string) =>\n execSync(command, { timeout: 5000, encoding: 'utf-8', stdio: 'pipe' }).trimEnd(),\n startupUpdateNotice: startupUpdateNoticePromise\n ? startupUpdateNoticePromise.then((n) => (n ? formatCliUpdateNotice(n) : undefined))\n : undefined,\n transportRegistry: createDefaultTransportRegistry(),\n cliAdapter: createDefaultTuiCliAdapter({ providerDefinitions, reloadPluginCommandSource }),\n reloadPluginCommandSource,\n agentName: resolvedPreset.agentName ?? DEFAULT_AGENT_NAME,\n activePresetId: selectedPresetId,\n persona: resolvedPreset.persona,\n ...(resolvedPreset.enableParallelSubagents !== undefined\n ? { enableParallelSubagents: resolvedPreset.enableParallelSubagents }\n : {}),\n ...(resolvedPreset.selfVerification !== undefined\n ? { selfVerification: resolvedPreset.selfVerification }\n : {}),\n });\n process.exit(0);\n}\n","#!/usr/bin/env node\n/**\n * Robota CLI binary entry point.\n *\n * Boots the CLI and handles any uncaught top-level errors gracefully.\n *\n * A Node.js version check (>=22) is injected as a build-time banner in\n * tsdown.config.ts and runs before any module imports are loaded.\n */\nimport { startCli } from './cli.js';\n\n// Last-resort crash prevention for IME-related errors only.\n// Korean IME in raw mode can cause errors that escape React/Ink.\n// Non-IME errors are re-thrown to preserve normal crash behavior.\nprocess.on('uncaughtException', (err) => {\n const msg = err.message ?? '';\n const isLikelyIME =\n msg.includes('string-width') ||\n msg.includes('setCursorPosition') ||\n msg.includes('getStringWidth') ||\n msg.includes('slice') ||\n msg.includes('charCodeAt');\n if (isLikelyIME) {\n process.stderr.write(\n '\\n[robota] CJK/IME input error — this is a known issue with macOS Terminal.app.\\n' +\n ' Workaround: use iTerm2 (https://iterm2.com) or input your prompt in English.\\n' +\n ' Alternatively, use headless mode: robota -p \"your prompt here\"\\n\\n',\n );\n return;\n }\n // Re-throw non-IME errors — let them crash normally\n throw err;\n});\n\nstartCli().catch((err) => {\n const message = err instanceof Error ? err.message : String(err);\n process.stderr.write(message + '\\n');\n process.exit(1);\n});\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"bin.js","names":[],"sources":["../../src/utils/cli-args.ts","../../src/startup/preset-selection.ts","../../src/startup/provider-startup.ts","../../src/process-guards.ts","../../src/user-local-direct-command.ts","../../src/session-analyzer/session-analyze-command.ts","../../src/startup/version.ts","../../src/startup/reset-config.ts","../../src/startup/diagnose-command.ts","../../src/constants.ts","../../src/init/init-command.ts","../../src/startup/first-run.ts","../../src/startup/terminal-check.ts","../../src/startup/command-setup.ts","../../src/startup/append-system-prompt.ts","../../src/modes/print-mode.ts","../../src/cli.ts","../../src/bin.ts"],"sourcesContent":["/**\n * CLI argument parsing and validation.\n * Pure functions — throw on invalid input, no process.* side effects.\n */\n\nimport { parseArgs } from 'node:util';\n\nimport type { TPermissionMode } from '@robota-sdk/agent-core';\n\nconst VALID_MODES: TPermissionMode[] = ['plan', 'default', 'acceptEdits', 'bypassPermissions'];\n\nconst VALID_OUTPUT_FORMATS = ['text', 'json', 'stream-json'] as const;\nexport type TOutputFormat = (typeof VALID_OUTPUT_FORMATS)[number];\n\nexport interface IParsedCliArgs {\n positional: string[];\n help: boolean;\n printMode: boolean;\n continueMode: boolean;\n resumeId: string | undefined;\n language: string | undefined;\n permissionMode: TPermissionMode | undefined;\n maxTurns: number | undefined;\n /** GOAL-001: autonomous objective to pursue headlessly (--goal). */\n goal: string | undefined;\n /** GOAL-001: per-goal turn budget (--goal-max-iterations). */\n goalMaxIterations: number | undefined;\n forkSession: boolean;\n sessionName: string | undefined;\n outputFormat: TOutputFormat | undefined;\n format: string | undefined;\n summary: string | undefined;\n source: string | undefined;\n systemPrompt: string | undefined;\n appendSystemPrompt: string | undefined;\n taskFile: string | undefined;\n version: boolean;\n reset: boolean;\n bare: boolean;\n allowedTools: string | undefined;\n deniedTools: string | undefined;\n model: string | undefined;\n preset: string | undefined;\n noSessionPersistence: boolean;\n jsonSchema: string | undefined;\n configure: boolean;\n configureProvider: string | undefined;\n provider: string | undefined;\n /** INFRA-018: replay a recorded session log instead of calling a model (offline/deterministic). */\n sessionLog: string | undefined;\n providerType: string | undefined;\n baseURL: string | undefined;\n apiKey: string | undefined;\n apiKeyEnv: string | undefined;\n setCurrent: boolean;\n settingsScope: string | undefined;\n checkUpdate: boolean;\n disableUpdateCheck: boolean;\n dryRun: boolean;\n yes: boolean;\n}\n\n/** Return CLI usage help text. */\nexport function printHelp(): string {\n return `\nUsage: robota [options] [-p <prompt>]\n\nOptions:\n -p <prompt> Run in print (headless) mode with the given prompt\n --output-format <format> Output format: text | json | stream-json (default: text)\n --system-prompt <text> Override the system prompt for this session\n --append-system-prompt <t> Append text to the system prompt\n --language <lang> Language preference (e.g. ko, en)\n --no-session-persistence Disable session persistence for this run\n --permission-mode <mode> Permission mode: plan | default | acceptEdits | bypassPermissions\n --max-turns <n> Maximum agent turns before stopping\n -c, --continue Continue the most recent session\n -r, --resume <id> Resume a session by ID or name\n -n, --name <name> Name for the new session\n --fork-session Fork the current session into a new independent session\n --task-file <path> Read a task prompt from file and append it to the system prompt\n --bare Print mode: output raw text only, no formatting wrapper\n --configure Run interactive provider configuration\n --configure-provider <n> Configure a specific provider\n --allowed-tools <list> Comma-separated tool allowlist (TUI and print mode)\n --denied-tools <list> Comma-separated tool denylist (TUI and print mode)\n --model <model> Model override for this run\n --preset <id> Preset id to apply (default: settings.preset or \"default\")\n --json-schema <schema> Print mode: instruct the model to respond with JSON matching this schema\n --dry-run Alias for --permission-mode plan (plan only, no execution)\n --reset Delete ~/.robota/settings.json (provider profiles and preferences).\n Asks for confirmation; use --yes to skip\n --yes Skip confirmation prompts (required for --reset in non-TTY)\n --check-update Check for CLI updates\n --version Show version number\n -h, --help Show this help message\n\nCommands:\n robota init Initialize AGENTS.md and .robota/settings.json\n robota diagnose Check setup and print a diagnostics report\n\nExamples:\n robota Start interactive TUI session\n robota init Initialize project files\n robota -p \"Hello\" Print mode: send prompt and exit\n robota -p \"Hello\" --output-format json\n robota -p \"Review this diff\" --bare Raw output for shell pipelines\n robota --task-file task.md Run task from file (appended to system prompt)\n robota -p \"Refactor the auth module\" --dry-run Plan only, no execution\n robota --continue Resume the last session\n`;\n}\n\n/** Split a comma-separated tool list into trimmed, non-empty names. */\nexport function parseToolList(value: string | undefined): string[] | undefined {\n if (value === undefined) return undefined;\n const tools = value\n .split(',')\n .map((tool) => tool.trim())\n .filter((tool) => tool.length > 0);\n return tools.length > 0 ? tools : undefined;\n}\n\n/** Validate and return a TOutputFormat from a raw CLI string, or throw on error. */\nexport function parseOutputFormat(raw: string | undefined): TOutputFormat | undefined {\n if (raw === undefined) return undefined;\n if (!(VALID_OUTPUT_FORMATS as readonly string[]).includes(raw)) {\n throw new Error(`Invalid --output-format \"${raw}\". Valid: ${VALID_OUTPUT_FORMATS.join(' | ')}`);\n }\n return raw as TOutputFormat;\n}\n\n/** Validate and return a TPermissionMode from a raw CLI string, or throw on error. */\nexport function parsePermissionMode(raw: string | undefined): TPermissionMode | undefined {\n if (raw === undefined) return undefined;\n if (!VALID_MODES.includes(raw as TPermissionMode)) {\n throw new Error(`Invalid --permission-mode \"${raw}\". Valid: ${VALID_MODES.join(' | ')}`);\n }\n return raw as TPermissionMode;\n}\n\n/** Validate and return a positive integer from a raw CLI string, or throw on error. */\nexport function parseMaxTurns(raw: string | undefined): number | undefined {\n if (raw === undefined) return undefined;\n const n = parseInt(raw, 10);\n if (isNaN(n) || n <= 0) {\n throw new Error(`Invalid --max-turns \"${raw}\". Must be a positive integer.`);\n }\n return n;\n}\n\nconst PARSE_ARGS_CONFIG = {\n allowPositionals: true,\n options: {\n help: { type: 'boolean', short: 'h', default: false },\n p: { type: 'boolean', short: 'p', default: false },\n continue: { type: 'boolean', short: 'c', default: false },\n resume: { type: 'string', short: 'r' },\n language: { type: 'string' },\n 'permission-mode': { type: 'string' },\n 'max-turns': { type: 'string' },\n goal: { type: 'string' },\n 'goal-max-iterations': { type: 'string' },\n 'fork-session': { type: 'boolean', default: false },\n name: { type: 'string', short: 'n' },\n 'output-format': { type: 'string' },\n format: { type: 'string' },\n summary: { type: 'string' },\n source: { type: 'string' },\n 'system-prompt': { type: 'string' },\n 'append-system-prompt': { type: 'string' },\n 'task-file': { type: 'string' },\n version: { type: 'boolean', default: false },\n reset: { type: 'boolean', default: false },\n bare: { type: 'boolean', default: false },\n 'allowed-tools': { type: 'string' },\n 'denied-tools': { type: 'string' },\n model: { type: 'string' },\n preset: { type: 'string' },\n 'no-session-persistence': { type: 'boolean', default: false },\n 'json-schema': { type: 'string' },\n configure: { type: 'boolean', default: false },\n 'configure-provider': { type: 'string' },\n provider: { type: 'string' },\n 'session-log': { type: 'string' },\n type: { type: 'string' },\n 'base-url': { type: 'string' },\n 'api-key': { type: 'string' },\n 'api-key-env': { type: 'string' },\n 'set-current': { type: 'boolean', default: false },\n 'settings-scope': { type: 'string' },\n 'check-update': { type: 'boolean', default: false },\n 'disable-update-check': { type: 'boolean', default: false },\n 'dry-run': { type: 'boolean', default: false },\n yes: { type: 'boolean', short: 'y', default: false },\n },\n} as const;\n\nfunction mapParsedValues(\n values: ReturnType<typeof parseArgs<typeof PARSE_ARGS_CONFIG>>['values'],\n positionals: string[],\n): IParsedCliArgs {\n return {\n positional: positionals,\n help: values['help'] ?? false,\n printMode: values['p'] ?? false,\n continueMode: values['continue'] ?? false,\n resumeId: values['resume'],\n language: values['language'],\n permissionMode: parsePermissionMode(values['permission-mode']),\n maxTurns: parseMaxTurns(values['max-turns']),\n goal: values['goal'],\n goalMaxIterations: parseMaxTurns(values['goal-max-iterations']),\n forkSession: values['fork-session'] ?? false,\n sessionName: values['name'],\n outputFormat: parseOutputFormat(values['output-format']),\n format: values['format'],\n summary: values['summary'],\n source: values['source'],\n systemPrompt: values['system-prompt'],\n appendSystemPrompt: values['append-system-prompt'],\n taskFile: values['task-file'],\n version: values['version'] ?? false,\n reset: values['reset'] ?? false,\n bare: values['bare'] ?? false,\n allowedTools: values['allowed-tools'],\n deniedTools: values['denied-tools'],\n model: values['model'],\n preset: values['preset'],\n noSessionPersistence: values['no-session-persistence'] ?? false,\n jsonSchema: values['json-schema'],\n configure: values['configure'] ?? false,\n configureProvider: values['configure-provider'],\n provider: values['provider'],\n sessionLog: values['session-log'],\n providerType: values['type'],\n baseURL: values['base-url'],\n apiKey: values['api-key'],\n apiKeyEnv: values['api-key-env'],\n setCurrent: values['set-current'] ?? false,\n settingsScope: values['settings-scope'],\n checkUpdate: values['check-update'] ?? false,\n disableUpdateCheck: values['disable-update-check'] ?? false,\n dryRun: values['dry-run'] ?? false,\n yes: values['yes'] ?? false,\n };\n}\n\n/** Parse and validate CLI arguments. */\nexport function parseCliArgs(): IParsedCliArgs {\n const { values, positionals } = parseArgs(PARSE_ARGS_CONFIG);\n const args = mapParsedValues(values, positionals);\n if (args.printMode) {\n if (args.resumeId === '') {\n throw new Error(\n 'Print mode requires an explicit session id: -r <id|name> (the interactive session picker is TUI-only)',\n );\n }\n if (args.noSessionPersistence && (args.continueMode || args.resumeId !== undefined)) {\n throw new Error(\n '--no-session-persistence conflicts with -c/-r (resume needs the session store)',\n );\n }\n }\n if (args.dryRun) {\n if (args.permissionMode !== undefined && args.permissionMode !== 'plan') {\n throw new Error(\n `--dry-run is an alias for --permission-mode plan and conflicts with --permission-mode ${args.permissionMode}`,\n );\n }\n return { ...args, permissionMode: 'plan' };\n }\n return args;\n}\n","/**\n * Preset selection glue — thin shell over `@robota-sdk/agent-preset`.\n * The CLI only selects the preset id and forwards CLI flags as overrides; the\n * precedence merge lives entirely inside `resolvePreset` (agent-preset), never here.\n */\n\nimport { resolvePreset } from '@robota-sdk/agent-preset';\nimport type { IResolvedPresetOptions } from '@robota-sdk/agent-preset';\n\nimport type { IParsedCliArgs } from '../utils/cli-args.js';\n\n/** Pick the preset id: --preset flag > settings.preset > 'default'. Pure selection glue (shell). */\nexport function selectPresetId(\n args: Pick<IParsedCliArgs, 'preset'>,\n settingsPreset: string | undefined,\n): string {\n return args.preset ?? settingsPreset ?? 'default';\n}\n\n/** Build the CLI-flag override set (highest-but-explicit tier) handed to resolvePreset. */\nfunction buildPresetCliOverrides(args: IParsedCliArgs): IResolvedPresetOptions {\n return {\n ...(args.model !== undefined ? { model: args.model } : {}),\n ...(args.systemPrompt !== undefined ? { systemPrompt: args.systemPrompt } : {}),\n ...(args.appendSystemPrompt !== undefined\n ? { appendSystemPrompt: args.appendSystemPrompt }\n : {}),\n ...(args.language !== undefined ? { language: args.language } : {}),\n ...(args.permissionMode !== undefined ? { permissionMode: args.permissionMode } : {}),\n };\n}\n\n/** Resolve the active preset → framework option bundle (merge owned by agent-preset). Throws on unknown id. */\nexport function resolveCliPreset(\n args: IParsedCliArgs,\n settingsPreset: string | undefined,\n): IResolvedPresetOptions {\n return resolvePreset(selectPresetId(args, settingsPreset), {\n cliOverrides: buildPresetCliOverrides(args),\n });\n}\n","import { formatSupportedProviderTypes, type IProviderDefinition } from '@robota-sdk/agent-core';\nimport type { IParsedCliArgs } from '../utils/cli-args.js';\nimport {\n applyProviderConfiguration,\n applyProviderSwitch,\n readMergedProviderSettings,\n resolveProviderSettingsWriteTargetPath,\n resolveSettingsPathForScope,\n} from '@robota-sdk/agent-framework';\nimport type { TSettingsScope } from '@robota-sdk/agent-framework';\nimport { createDefaultProviderDefinitions } from '@robota-sdk/agent-provider';\nimport { type IProviderSetupInput } from '@robota-sdk/agent-framework';\nimport {\n ensureProviderConfig,\n runProviderStartupSetup,\n type TPromptInput,\n} from '@robota-sdk/agent-command';\nimport type { ITerminalOutput } from '@robota-sdk/agent-core';\n\nfunction validateSettingsScope(scope: string | undefined): TSettingsScope | undefined {\n if (scope === undefined || scope === 'user' || scope === 'project-local') {\n return scope as TSettingsScope | undefined;\n }\n throw new Error(`Invalid --settings-scope \"${scope}\". Valid: user | project-local`);\n}\n\nexport function handleProviderConfigurationArgs(\n cwd: string,\n args: IParsedCliArgs,\n terminal: ITerminalOutput,\n providerDefinitions: readonly IProviderDefinition[] = createDefaultProviderDefinitions(),\n): boolean {\n const settingsPath = resolveSettingsPathForScope(cwd, validateSettingsScope(args.settingsScope));\n if (args.configureProvider) {\n applyProviderConfiguration(settingsPath, buildSetupInputFromArgs(args), {\n providerDefinitions,\n });\n terminal.writeLine(`Provider profile saved to ${settingsPath}`);\n return !args.printMode && args.positional.length === 0;\n }\n if (args.provider && args.setCurrent) {\n const switchSettingsPath =\n args.settingsScope === undefined ? resolveProviderSettingsWriteTargetPath(cwd) : settingsPath;\n applyProviderSwitch(switchSettingsPath, args.provider, {\n knownProviders: readMergedProviderSettings(cwd).providers,\n });\n terminal.writeLine(`Current provider set to ${args.provider}`);\n return !args.printMode && args.positional.length === 0;\n }\n return false;\n}\n\nexport async function ensureConfig(\n cwd: string,\n args: IParsedCliArgs,\n promptInput: TPromptInput,\n terminal: ITerminalOutput,\n providerDefinitions: readonly IProviderDefinition[] = createDefaultProviderDefinitions(),\n isInteractive?: boolean,\n): Promise<void> {\n await ensureProviderConfig(\n cwd,\n { provider: args.provider, settingsScope: validateSettingsScope(args.settingsScope) },\n promptInput,\n terminal,\n providerDefinitions,\n {\n formatError: formatMissingProviderConfigMessage,\n isInteractive:\n isInteractive !== undefined\n ? () => isInteractive\n : () => process.stdin.isTTY === true && process.stdout.isTTY === true,\n },\n );\n}\n\nexport async function runInteractiveProviderSetup(\n cwd: string,\n args: IParsedCliArgs,\n promptInput: TPromptInput,\n terminal: ITerminalOutput,\n providerDefinitions: readonly IProviderDefinition[] = createDefaultProviderDefinitions(),\n): Promise<void> {\n await runProviderStartupSetup(\n cwd,\n { settingsScope: validateSettingsScope(args.settingsScope) },\n promptInput,\n terminal,\n providerDefinitions,\n );\n}\n\nfunction buildSetupInputFromArgs(args: IParsedCliArgs): IProviderSetupInput {\n const type = args.providerType ?? args.configureProvider;\n if (!args.configureProvider || !type) {\n throw new Error('--configure-provider requires a provider profile and --type');\n }\n return {\n profile: args.configureProvider,\n type,\n ...(args.model !== undefined && { model: args.model }),\n ...(args.apiKey !== undefined && { apiKey: args.apiKey }),\n ...(args.apiKeyEnv !== undefined && { apiKeyEnv: args.apiKeyEnv }),\n ...(args.baseURL !== undefined && { baseURL: args.baseURL }),\n setCurrent: args.setCurrent,\n };\n}\n\nexport function formatMissingProviderConfigMessage(\n providerDefinitions: readonly IProviderDefinition[] = createDefaultProviderDefinitions(),\n): string {\n return [\n 'No provider configuration found.',\n 'Run `robota --configure` in an interactive terminal, or configure a provider:',\n `Supported providers: ${formatSupportedProviderTypes(providerDefinitions)}`,\n ...providerDefinitions.map(formatConfigureProviderExample),\n ].join('\\n');\n}\n\nfunction formatConfigureProviderExample(definition: IProviderDefinition): string {\n const flags = [\n `robota --configure-provider ${definition.type}`,\n `--type ${definition.type}`,\n ...(definition.defaults?.baseURL !== undefined ? ['--base-url <url>'] : []),\n '--model <model>',\n ...(definition.requiresApiKey === true ? ['--api-key-env <ENV_NAME>'] : []),\n '--set-current',\n ];\n return ` ${flags.join(' ')}`;\n}\n","/**\n * Process survival boundary for the interactive TUI (ERR-001 G1).\n *\n * On Node 20+ an unhandled rejection terminates the process, and the previous\n * `uncaughtException` guard re-threw everything non-IME — any async path outside the turn\n * boundary (background tasks, catalog refresh, persistence) hitting a transient network\n * error could kill the whole TUI. In interactive mode the product installs these\n * last-resort guards: the error is routed into the live session (humanized, styled error\n * block, session log) and the process stays alive. Headless/print mode installs nothing\n * and keeps its fail-fast exit-code contract.\n *\n * This is deliberately product-owned (agent-cli), not library-owned — see the Library\n * Neutrality Rule in .agents/project-structure.md. Each async subsystem should still\n * terminate its own promises; this boundary is the last resort, not the primary handler.\n */\n\n/** The surface the guards need from the live TUI channel. */\nexport interface IGuardableChannel {\n getSession(): { reportBackgroundError(error: Error, source?: string): void };\n}\n\nlet liveChannel: IGuardableChannel | null = null;\nlet guardsInstalled = false;\n\n/** bin.ts consults this so its own uncaughtException fallback keeps fail-fast semantics\n * whenever the TUI guards are NOT active (headless/print mode). */\nexport function areTuiProcessGuardsActive(): boolean {\n return guardsInstalled;\n}\n\n/** What bin.ts should do with an uncaught exception. */\nexport type TUncaughtExceptionDecision = 'ime-hint' | 'guard-owned' | 'rethrow';\n\n/** Message signatures of raw-mode CJK/IME errors that escape React/Ink in the TUI. */\nconst IME_ERROR_SIGNATURES = [\n 'string-width',\n 'setCursorPosition',\n 'getStringWidth',\n 'slice',\n 'charCodeAt',\n];\n\n/**\n * Classify an uncaught exception for bin.ts (CORE-020, RUNTIME-34).\n *\n * The IME allowlist applies ONLY while the interactive TUI guards are active — raw-mode\n * IME errors cannot occur outside the TUI, and generic signatures like 'slice'/'charCodeAt'\n * match arbitrary crashes. Headless/print mode therefore always rethrows (fail-fast\n * exit-code contract); in interactive mode non-IME errors are guard-owned (routed into\n * the live session by the installed guards).\n */\nexport function classifyUncaughtException(\n err: Error,\n tuiGuardsActive: boolean,\n): TUncaughtExceptionDecision {\n if (!tuiGuardsActive) return 'rethrow';\n const msg = err.message ?? '';\n const isLikelyIME = IME_ERROR_SIGNATURES.some((signature) => msg.includes(signature));\n return isLikelyIME ? 'ime-hint' : 'guard-owned';\n}\n\n/** Track the current live channel (session switches re-create it). */\nexport function setLiveChannel(channel: IGuardableChannel): void {\n liveChannel = channel;\n}\n\nfunction routeProcessError(error: Error, source: string): void {\n try {\n if (liveChannel) {\n liveChannel.getSession().reportBackgroundError(error, source);\n return;\n }\n } catch {\n // allow-fallback: this guard IS the last-resort boundary — if rendering into the session itself fails, stderr below is the only remaining surface (ERR-001 G1)\n /* fall through to stderr */\n }\n process.stderr.write(`\\n[robota] ${source}: ${error.message}\\n`);\n}\n\n/**\n * Install the interactive-mode guards. Idempotent. Never masks errors silently — every\n * routed error is visible in the transcript (styled block) and the session log.\n */\nexport function installTuiProcessGuards(): void {\n if (guardsInstalled) return;\n guardsInstalled = true;\n\n process.on('unhandledRejection', (reason) => {\n const error = reason instanceof Error ? reason : new Error(String(reason));\n routeProcessError(error, 'unhandled rejection');\n });\n\n // Note: bin.ts installed its IME-aware uncaughtException handler first; it checks\n // areTuiProcessGuardsActive() and defers to this handler instead of re-throwing.\n process.on('uncaughtException', (err) => {\n const error = err instanceof Error ? err : new Error(String(err));\n routeProcessError(error, 'uncaught exception');\n });\n}\n","import { executeUserLocalDirectCommand } from '@robota-sdk/agent-command';\nimport type { ITerminalOutput } from '@robota-sdk/agent-core';\nimport type { IParsedCliArgs } from './utils/cli-args.js';\n\nexport async function runUserLocalDirectCommandIfRequested(\n args: IParsedCliArgs,\n cwd: string,\n terminal: ITerminalOutput,\n): Promise<boolean> {\n if (args.positional[0] !== 'user-local') {\n return false;\n }\n\n const result = await executeUserLocalDirectCommand({\n cwd,\n argv: args.positional.slice(1),\n format: args.format,\n summary: args.summary,\n source: args.source,\n });\n const output = result.message.trimEnd();\n if (!result.success) {\n throw new Error(output);\n }\n terminal.writeLine(output);\n return true;\n}\n","/**\n * `robota session analyze` command — thin CLI wiring around `@robota-sdk/agent-session-analytics`.\n *\n * Usage:\n * robota session analyze — analyze the most recent session\n * robota session analyze --last <n> — aggregate the last N sessions\n * robota session analyze --session <id> — analyze a specific session by ID prefix\n * robota session analyze --usage — token usage broken down by source (which agent /\n * background task burned the most tokens)\n *\n * This file only resolves session stores, parses args, and writes output. All timing analysis and\n * report formatting lives in the analytics package; record loading lives in agent-session (via the\n * agent-framework session-store facades). agent-cli stays a thin shell.\n */\n\nimport {\n createProjectSessionStore,\n createUserSessionStore,\n projectPaths,\n userPaths,\n} from '@robota-sdk/agent-framework';\nimport {\n aggregateReports,\n analyzeSession,\n formatAggregateReport,\n formatSingleSession,\n formatUsageReport,\n summarizeUsageBySource,\n} from '@robota-sdk/agent-session-analytics';\n\nimport type { TSessionAnalysisInput } from '@robota-sdk/agent-session-analytics';\n\ninterface ISessionAnalyzeArgs {\n last: number | undefined;\n sessionId: string | undefined;\n usage: boolean;\n}\n\nfunction parseSessionAnalyzeArgs(argv: string[]): ISessionAnalyzeArgs {\n let last: number | undefined;\n let sessionId: string | undefined;\n let usage = false;\n\n for (let i = 0; i < argv.length; i++) {\n if (argv[i] === '--last' && argv[i + 1]) {\n const n = parseInt(argv[i + 1]!, 10);\n if (!isNaN(n) && n > 0) last = n;\n i++;\n } else if (argv[i] === '--session' && argv[i + 1]) {\n sessionId = argv[i + 1];\n i++;\n } else if (argv[i] === '--usage') {\n usage = true;\n }\n }\n\n return { last, sessionId, usage };\n}\n\n/**\n * Load session records from the user store (`~/.robota/sessions`) and the project store\n * (`cwd/.robota/sessions` + replay logs), de-duped by id (project wins on collision) and sorted by\n * id ascending — session ids are timestamp-prefixed, so lexical order is chronological.\n */\nfunction loadSessionRecords(cwd: string): TSessionAnalysisInput[] {\n const byId = new Map<string, TSessionAnalysisInput>();\n for (const record of createUserSessionStore().list()) {\n byId.set(record.id, record);\n }\n for (const record of createProjectSessionStore(cwd).list()) {\n byId.set(record.id, record);\n }\n return [...byId.values()].sort((a, b) => a.id.localeCompare(b.id));\n}\n\nexport async function runSessionAnalyze(\n argv: string[],\n cwd: string = process.cwd(),\n): Promise<void> {\n const args = parseSessionAnalyzeArgs(argv);\n const records = loadSessionRecords(cwd);\n\n if (records.length === 0) {\n process.stderr.write(\n `No session files found in ${projectPaths(cwd).sessions} or ${userPaths().sessions}\\n`,\n );\n process.exit(1);\n }\n\n if (args.usage) {\n const target =\n args.sessionId !== undefined\n ? records.find((r) => r.id.includes(args.sessionId!))\n : records[records.length - 1];\n if (!target) {\n process.stderr.write(`Session not found${args.sessionId ? `: ${args.sessionId}` : ''}\\n`);\n process.exit(1);\n }\n process.stdout.write(formatUsageReport(summarizeUsageBySource(target)) + '\\n');\n return;\n }\n\n if (args.sessionId !== undefined) {\n const matched = records.find((r) => r.id.includes(args.sessionId!));\n if (!matched) {\n process.stderr.write(`Session not found: ${args.sessionId}\\n`);\n process.exit(1);\n }\n process.stdout.write(formatSingleSession(analyzeSession(matched)) + '\\n');\n return;\n }\n\n if (args.last !== undefined) {\n const reports = records.slice(-args.last).map((r) => analyzeSession(r));\n if (reports.length === 0) {\n process.stderr.write('No valid sessions found.\\n');\n process.exit(1);\n }\n process.stdout.write(formatAggregateReport(aggregateReports(reports)) + '\\n');\n return;\n }\n\n // Default: analyze the most recent session\n const latest = records[records.length - 1];\n if (!latest) {\n process.stderr.write('No sessions found.\\n');\n process.exit(1);\n }\n process.stdout.write(formatSingleSession(analyzeSession(latest)) + '\\n');\n}\n","import { readPackageVersion } from '@robota-sdk/agent-framework';\n\nexport const readVersion = (): string => readPackageVersion(import.meta.url);\n","import { existsSync } from 'node:fs';\nimport { createInterface } from 'node:readline/promises';\n\nimport { getUserSettingsPath, resetUserConfig } from '@robota-sdk/agent-framework';\n\nimport type { ITerminalOutput } from '@robota-sdk/agent-core';\n\nexport interface IResetConfigOptions {\n /** --yes flag: skip the confirmation prompt. */\n yes: boolean;\n /** Whether stdin is a TTY (non-TTY without --yes refuses to delete). */\n isTTY: boolean;\n /** Confirmation prompt (test seam, default: readline y/N on stdin). */\n confirm?: (question: string) => Promise<boolean>;\n}\n\nasync function confirmViaReadline(question: string): Promise<boolean> {\n const rl = createInterface({ input: process.stdin, output: process.stdout });\n try {\n const answer = (await rl.question(question)).trim().toLowerCase();\n return answer === 'y' || answer === 'yes';\n } finally {\n rl.close();\n }\n}\n\n/**\n * CLI-070 confirmation matrix for the destructive `--reset` flag:\n * `--yes` → delete; TTY without `--yes` → y/N prompt (default N);\n * non-TTY without `--yes` → refuse with exit 1, file untouched.\n * Returns the process exit code.\n */\nexport async function runResetConfig(\n terminal: ITerminalOutput,\n options: IResetConfigOptions,\n): Promise<number> {\n const path = getUserSettingsPath();\n if (!existsSync(path)) {\n terminal.writeLine('No user settings found.');\n return 0;\n }\n\n if (!options.yes) {\n if (!options.isTTY) {\n terminal.writeError(\n `--reset deletes ${path}. Refusing without confirmation in non-interactive mode — pass --yes to proceed.`,\n );\n return 1;\n }\n const confirm = options.confirm ?? confirmViaReadline;\n const confirmed = await confirm(`Delete ${path}? [y/N] `);\n if (!confirmed) {\n terminal.writeLine('Reset cancelled.');\n return 1;\n }\n }\n\n const result = resetUserConfig();\n if (result.deleted) {\n terminal.writeLine(`Deleted ${result.path}`);\n } else {\n terminal.writeLine('No user settings found.');\n }\n return 0;\n}\n","import { createConnection } from 'node:net';\nimport { existsSync, readFileSync } from 'node:fs';\nimport { join } from 'node:path';\n\nimport { getProviderSettingsPaths, readProviderSettings } from '@robota-sdk/agent-framework';\nimport { createDefaultProviderDefinitions } from '@robota-sdk/agent-provider';\n\nimport type { IProviderDefinition, ITerminalOutput } from '@robota-sdk/agent-core';\n\nconst PROVIDER_ENDPOINTS: Record<string, { host: string; port: number }> = {\n anthropic: { host: 'api.anthropic.com', port: 443 },\n openai: { host: 'api.openai.com', port: 443 },\n gemini: { host: 'generativelanguage.googleapis.com', port: 443 },\n deepseek: { host: 'api.deepseek.com', port: 443 },\n qwen: { host: 'dashscope.aliyuncs.com', port: 443 },\n};\n\nexport interface IDiagnoseContext {\n version: string;\n terminal: ITerminalOutput;\n cwd: string;\n}\n\nexport interface IDiagnosticCheck {\n label: string;\n status: 'ok' | 'warn' | 'fail';\n message: string;\n}\n\nexport interface IDiagnoseDependencies {\n checkNetwork: (endpoint: { host: string; port: number }) => Promise<IDiagnosticCheck>;\n /** Environment map for provider resolution (test seam, default: process.env). */\n env?: Record<string, string | undefined>;\n /** Provider definitions for resolution (default: the CLI's default set). */\n providerDefinitions?: readonly IProviderDefinition[];\n}\n\nfunction checkNodeVersion(): IDiagnosticCheck {\n const [major] = process.versions.node.split('.').map(Number);\n if (major !== undefined && major >= 22) {\n return { label: 'Node.js version', status: 'ok', message: `v${process.versions.node}` };\n }\n return {\n label: 'Node.js version',\n status: 'fail',\n message: `v${process.versions.node} (requires >=22)\\n nvm: nvm install 22 && nvm use 22\\n Volta: volta install node@22`,\n };\n}\n\nfunction checkCliVersion(version: string): IDiagnosticCheck {\n return { label: 'robota version', status: 'ok', message: version };\n}\n\n/**\n * CLI-067: the API-key check IS the runtime resolution — settings profiles\n * (with `$ENV:` references) first, then env-default synthesis (CLI-066).\n * Diagnose can never disagree with session start again. Never prints key values.\n */\nfunction checkApiKeyResolution(\n cwd: string,\n providerDefinitions: readonly IProviderDefinition[],\n env: Record<string, string | undefined>,\n): IDiagnosticCheck {\n try {\n const config = readProviderSettings(cwd, { providerDefinitions, env });\n const source =\n config.source === 'env-default'\n ? `env-default via ${config.sourceEnvVar ?? 'environment'}`\n : 'settings profile';\n const model = config.model !== undefined ? ` (${config.model})` : '';\n return { label: 'API key', status: 'ok', message: `${config.name}${model} — ${source}` };\n } catch (error) {\n // allow-fallback: resolution failure is the diagnostic finding being reported, not a crash\n const message = error instanceof Error ? error.message : String(error);\n return {\n label: 'API key',\n status: 'fail',\n message: `${message}\\n Set ANTHROPIC_API_KEY or run: robota --configure\\n Get key: https://console.anthropic.com/settings/keys`,\n };\n }\n}\n\nfunction validateJsonFile(filePath: string): 'ok' | 'corrupt' {\n try {\n JSON.parse(readFileSync(filePath, 'utf-8'));\n return 'ok';\n } catch {\n // allow-fallback: corrupt JSON → reported as diagnostic finding, not a crash\n return 'corrupt';\n }\n}\n\n/**\n * CLI-067: every settings file the runtime merge chain reads is validated\n * independently — a corrupt user-level file is flagged even when a valid\n * project file exists. Missing files are not an issue (the API-key check\n * reports actual resolution failures).\n */\nfunction checkSettingsFiles(cwd: string): IDiagnosticCheck[] {\n const existing = getProviderSettingsPaths(cwd).filter((path) => existsSync(path));\n if (existing.length === 0) {\n return [\n {\n label: 'Settings file',\n status: 'warn',\n message: 'Not found — run: robota --configure',\n },\n ];\n }\n return existing.map((path) =>\n validateJsonFile(path) === 'corrupt'\n ? {\n label: 'Settings file',\n status: 'fail' as const,\n message: `${path} — invalid JSON\\n Fix or delete the file, or run: robota --configure`,\n }\n : { label: 'Settings file', status: 'ok' as const, message: path },\n );\n}\n\nfunction tryReadCurrentProvider(settingsPath: string): string | undefined {\n try {\n const doc = JSON.parse(readFileSync(settingsPath, 'utf-8')) as { currentProvider?: string };\n return typeof doc.currentProvider === 'string' ? doc.currentProvider : undefined;\n } catch {\n // allow-fallback: unreadable settings for network check → caller uses default endpoint\n return undefined;\n }\n}\n\nfunction resolveNetworkEndpoint(cwd: string): { host: string; port: number } {\n const settingsPath = join(cwd, '.robota', 'settings.json');\n const homeSettings = join(process.env['HOME'] ?? '', '.robota', 'settings.json');\n const activePath = existsSync(settingsPath)\n ? settingsPath\n : existsSync(homeSettings)\n ? homeSettings\n : undefined;\n if (activePath !== undefined) {\n const providerKey = (tryReadCurrentProvider(activePath) ?? '').toLowerCase();\n const match = Object.entries(PROVIDER_ENDPOINTS).find(([key]) => providerKey.startsWith(key));\n if (match) return match[1];\n }\n return PROVIDER_ENDPOINTS['anthropic']!;\n}\n\nfunction checkTerminal(): IDiagnosticCheck {\n const term = process.env['TERM_PROGRAM'] ?? 'unknown';\n if (process.platform === 'darwin' && term === 'Apple_Terminal') {\n return {\n label: 'Terminal',\n status: 'warn',\n message: `macOS Terminal.app — CJK/IME input may be unstable\\n Recommendation: use iTerm2 (https://iterm2.com)`,\n };\n }\n return { label: 'Terminal', status: 'ok', message: term };\n}\n\nfunction checkNetworkViaSocket(endpoint: {\n host: string;\n port: number;\n}): Promise<IDiagnosticCheck> {\n const label = `Network (${endpoint.host})`;\n return new Promise((resolve) => {\n const start = Date.now();\n const socket = createConnection({ host: endpoint.host, port: endpoint.port });\n const timeout = setTimeout(() => {\n socket.destroy();\n resolve({ label, status: 'fail', message: 'timeout (3s)' });\n }, 3000);\n socket.on('connect', () => {\n clearTimeout(timeout);\n socket.destroy();\n resolve({ label, status: 'ok', message: `reachable (${Date.now() - start}ms)` });\n });\n socket.on('error', (err) => {\n clearTimeout(timeout);\n resolve({\n label,\n status: 'warn',\n message: `${err.message}\\n Check proxy settings or firewall`,\n });\n });\n });\n}\n\n/**\n * Runs every diagnostic check and returns the number of failed checks —\n * the exit-code contract (CLI-067) is 0 when the count is 0, otherwise 1.\n */\nexport async function runDiagnoseCommand(\n ctx: IDiagnoseContext,\n deps: IDiagnoseDependencies = { checkNetwork: checkNetworkViaSocket },\n): Promise<number> {\n ctx.terminal.writeLine('\\nrobota diagnose\\n');\n\n const networkEndpoint = resolveNetworkEndpoint(ctx.cwd);\n const providerDefinitions = deps.providerDefinitions ?? createDefaultProviderDefinitions();\n const env = deps.env ?? process.env;\n\n const checks: IDiagnosticCheck[] = [\n checkNodeVersion(),\n checkCliVersion(ctx.version),\n checkApiKeyResolution(ctx.cwd, providerDefinitions, env),\n ...checkSettingsFiles(ctx.cwd),\n checkTerminal(),\n await deps.checkNetwork(networkEndpoint),\n ];\n\n let failCount = 0;\n let warnCount = 0;\n\n for (const check of checks) {\n const icon = check.status === 'ok' ? '✓' : check.status === 'warn' ? '⚠' : '✗';\n const lines = check.message.split('\\n');\n ctx.terminal.writeLine(` ${icon} ${check.label}: ${lines[0]}`);\n for (const line of lines.slice(1)) {\n ctx.terminal.writeLine(` ${line}`);\n }\n if (check.status === 'fail') failCount++;\n if (check.status === 'warn') warnCount++;\n }\n\n ctx.terminal.writeLine('');\n if (failCount === 0 && warnCount === 0) {\n ctx.terminal.writeLine('✓ All checks passed. robota is ready to use.');\n } else if (failCount > 0) {\n ctx.terminal.writeLine(`✗ ${failCount} issue(s) found. Fix the items above to use robota.`);\n } else {\n ctx.terminal.writeLine(`⚠ ${warnCount} warning(s). robota may work but check the items above.`);\n }\n ctx.terminal.writeLine('');\n return failCount;\n}\n","export const AGENT_CLI_BIN = 'robota';\n","import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\n\nimport { promptInput } from '@robota-sdk/agent-transport/headless';\nimport { projectPaths } from '@robota-sdk/agent-framework';\n\nimport { AGENT_CLI_BIN } from '../constants.js';\n\nimport type { ITerminalOutput } from '@robota-sdk/agent-core';\n\nconst AGENTS_MD_TEMPLATE = `# AGENTS.md — Project Agent Guidelines\n\nThis file guides the AI agent working in this project. Customize it for your project.\n\n## Project Overview\n\n<!-- Describe your project's purpose, tech stack, and key conventions -->\n\n## Common Commands\n\n\\`\\`\\`bash\n# Install dependencies\nnpm install\n\n# Run tests\nnpm test\n\n# Build\nnpm run build\n\\`\\`\\`\n\n## Coding Conventions\n\n- Language: <!-- e.g. TypeScript strict mode -->\n- Test framework: <!-- e.g. Vitest, Jest -->\n- Linting: <!-- e.g. ESLint with prettier -->\n\n## Important Notes\n\n<!-- Anything the agent should know before making changes -->\n`;\n\nconst SETTINGS_TEMPLATE = {\n permissions: {\n allow: ['Read(.robota/**)', 'Read(.claude/**)', 'Read(.agents/**)'],\n deny: [],\n },\n};\n\nfunction readClaudeSettings(claudeDir: string): Record<string, unknown> | null {\n const settingsPath = join(claudeDir, 'settings.json');\n if (!existsSync(settingsPath)) return {};\n const raw = readFileSync(settingsPath, 'utf8');\n try {\n return JSON.parse(raw) as Record<string, unknown>;\n } catch {\n // allow-fallback: malformed settings.json is non-fatal — null signals caller to show warning and skip migration\n return null;\n }\n}\n\n/** A confirmation was required but stdin cannot prompt (non-TTY without --yes). */\nexport class InitPromptUnavailableError extends Error {\n constructor(question: string) {\n super(\n `Cannot ask \"${question}\" in a non-interactive shell. Re-run with --yes to accept the defaults.`,\n );\n this.name = 'InitPromptUnavailableError';\n }\n}\n\nexport interface IInitCommandOptions {\n /** Skip all Y/n prompts and use the documented defaults (non-interactive mode). */\n yes?: boolean;\n /** Called after init completes when the user accepts the provider setup prompt. */\n onProviderSetup?: () => Promise<void>;\n /** Test seam: prompt function (default: transport promptInput). */\n promptFn?: (question: string) => Promise<string>;\n /** Test seam: interactive stdin state (default: process.stdin.isTTY). */\n isTTY?: boolean;\n /** Test seam: CI environment detection (default: process.env.CI === 'true'). */\n ci?: boolean;\n}\n\ninterface IConfirmContext {\n yes: boolean;\n ci: boolean;\n isTTY: boolean;\n promptFn: (question: string) => Promise<string>;\n terminal: ITerminalOutput;\n}\n\n/**\n * Unified Y/n confirmation: --yes/CI apply the documented default without\n * prompting; non-TTY without --yes is a hard error naming the question;\n * otherwise prompt interactively.\n */\nasync function confirm(\n question: string,\n defaultAnswer: boolean,\n ctx: IConfirmContext,\n): Promise<boolean> {\n if (ctx.yes || ctx.ci) {\n ctx.terminal.writeLine(\n `${question} → ${defaultAnswer ? 'Y' : 'N'} (${ctx.yes ? '--yes' : 'CI'}: using default)`,\n );\n return defaultAnswer;\n }\n if (!ctx.isTTY) {\n throw new InitPromptUnavailableError(question);\n }\n const answer = await ctx.promptFn(`${question} [y/N] `);\n return answer.toLowerCase() === 'y' || answer.toLowerCase() === 'yes';\n}\n\nexport async function runInitCommand(\n cwd: string,\n terminal: ITerminalOutput,\n options: IInitCommandOptions = {},\n): Promise<void> {\n terminal.writeLine('');\n terminal.writeLine(`${AGENT_CLI_BIN} project initialization`);\n terminal.writeLine('─'.repeat(40));\n\n const confirmCtx: IConfirmContext = {\n yes: options.yes === true,\n ci: options.ci ?? process.env['CI'] === 'true',\n isTTY: options.isTTY ?? process.stdin.isTTY === true,\n promptFn: options.promptFn ?? promptInput,\n terminal,\n };\n\n const settingsPath = projectPaths(cwd).settings;\n const robotaDir = dirname(settingsPath);\n const agentsMdPath = join(cwd, 'AGENTS.md');\n const claudeDir = join(cwd, '.claude');\n const hasClaudeDir = existsSync(claudeDir);\n\n const hasSettings = existsSync(settingsPath);\n const hasAgentsMd = existsSync(agentsMdPath);\n\n if (hasSettings && hasAgentsMd) {\n terminal.writeLine('');\n terminal.writeLine('Both AGENTS.md and .robota/settings.json already exist.');\n const overwrite = await confirm('Overwrite existing files?', false, confirmCtx);\n if (!overwrite) {\n terminal.writeLine('Init cancelled.');\n return;\n }\n }\n\n let settingsData: Record<string, unknown> = { ...SETTINGS_TEMPLATE };\n\n if (hasClaudeDir) {\n terminal.writeLine('');\n terminal.writeLine('Detected .claude/ directory (Claude Code configuration).');\n const migrate = await confirm('Migrate Claude Code settings to .robota/?', false, confirmCtx);\n if (migrate) {\n const claudeSettings = readClaudeSettings(claudeDir);\n if (claudeSettings === null) {\n terminal.writeLine(\n 'Warning: .claude/settings.json could not be parsed — skipping migration.',\n );\n } else {\n const claudePerms = claudeSettings.permissions as\n | { allow?: string[]; deny?: string[] }\n | undefined;\n settingsData = {\n ...claudeSettings,\n permissions: {\n ...(typeof claudeSettings.permissions === 'object' &&\n claudeSettings.permissions !== null\n ? (claudeSettings.permissions as Record<string, unknown>)\n : {}),\n allow: [...SETTINGS_TEMPLATE.permissions.allow, ...(claudePerms?.allow ?? [])],\n deny: claudePerms?.deny ?? [],\n },\n };\n terminal.writeLine('Settings imported from .claude/settings.json.');\n }\n }\n }\n\n mkdirSync(robotaDir, { recursive: true });\n writeFileSync(settingsPath, JSON.stringify(settingsData, null, 2) + '\\n', 'utf8');\n terminal.writeLine('');\n terminal.writeLine('Created: .robota/settings.json');\n\n writeFileSync(agentsMdPath, AGENTS_MD_TEMPLATE, 'utf8');\n terminal.writeLine('Created: AGENTS.md');\n\n terminal.writeLine('');\n terminal.writeLine('Initialization complete.');\n terminal.writeLine('');\n terminal.writeLine('Next steps:');\n terminal.writeLine(' 1. Edit AGENTS.md to describe your project conventions');\n terminal.writeLine(` 2. Run \\`${AGENT_CLI_BIN} --configure\\` to set up your AI provider`);\n terminal.writeLine(` 3. Run \\`${AGENT_CLI_BIN}\\` to start the assistant`);\n terminal.writeLine('');\n\n // Provider setup is an optional trailing step: init has already completed, so a\n // non-TTY shell skips it (default N) rather than failing a successful init.\n if (\n options.onProviderSetup !== undefined &&\n (confirmCtx.isTTY || confirmCtx.yes || confirmCtx.ci)\n ) {\n const setupNow = await confirm('Would you like to set up a provider now?', false, confirmCtx);\n if (setupNow) {\n await options.onProviderSetup();\n }\n }\n}\n","import { existsSync, mkdirSync, writeFileSync } from 'node:fs';\nimport { dirname } from 'node:path';\n\nimport type { ITerminalOutput } from '@robota-sdk/agent-core';\nimport { userPaths } from '@robota-sdk/agent-framework';\n\nimport { AGENT_CLI_BIN } from '../constants.js';\n\nexport function isFirstRun(markerPath: string = userPaths().onboarded): boolean {\n return !existsSync(markerPath);\n}\n\nexport function markOnboarded(markerPath: string = userPaths().onboarded): void {\n mkdirSync(dirname(markerPath), { recursive: true });\n writeFileSync(markerPath, new Date().toISOString());\n}\n\nconst WELCOME_MESSAGE = `\n╭─────────────────────────────────────────────────────────────╮\n│ Welcome to ${AGENT_CLI_BIN}! — AI coding assistant │\n│ │\n│ Try asking: │\n│ \"Explain this project structure\" │\n│ \"Find files with TODO comments\" │\n│ \"Run tests and analyze failures\" │\n│ \"What changed recently in git?\" │\n│ │\n│ Useful commands: │\n│ /help show all slash commands │\n│ /cost show token usage and estimated cost │\n│ /clear clear conversation history │\n│ │\n│ ${AGENT_CLI_BIN} diagnose — check your setup │\n╰─────────────────────────────────────────────────────────────╯\n`;\n\nexport function printFirstRunWelcome(terminal: ITerminalOutput): void {\n terminal.writeLine(WELCOME_MESSAGE);\n}\n","import type { ITerminalOutput } from '@robota-sdk/agent-core';\n\n/**\n * Emit a non-blocking warning when running on macOS Terminal.app,\n * which has known CJK/IME instability in raw/interactive mode.\n */\nexport function warnIfTerminalAppOnMacOS(terminal: ITerminalOutput): void {\n if (process.platform !== 'darwin') return;\n if (process.env['TERM_PROGRAM'] !== 'Apple_Terminal') return;\n terminal.writeError(\n '\\n⚠ macOS Terminal.app detected: CJK/IME input may be unstable.\\n' +\n ' Recommended: use iTerm2 (https://iterm2.com) for Korean/Japanese/Chinese input.\\n' +\n ' Or use headless mode: robota -p \"your prompt\"\\n',\n );\n}\n","import type { IProviderDefinition } from '@robota-sdk/agent-core';\nimport {\n getStartupCliUpdateNotice,\n getUserSettingsPath,\n readMergedProviderSettings,\n readSettings,\n resolveProviderSettingsWriteTargetPath,\n shouldRunStartupCliUpdateCheck,\n writeSettings,\n} from '@robota-sdk/agent-framework';\nimport type {\n ICliUpdateNotice,\n ICommandHostAdapters,\n ICommandModule,\n TProviderSettingsDocument,\n} from '@robota-sdk/agent-framework';\nimport { createRequire } from 'node:module';\n\nimport {\n createDefaultCommandModules,\n createDefaultPluginCommandAdapter,\n} from '@robota-sdk/agent-command';\nimport { createDefaultProviderDefinitions } from '@robota-sdk/agent-provider';\nimport type { IParsedCliArgs } from '../utils/cli-args.js';\n\n/**\n * Load the optional `/workflows` command module (WORKFLOW-003). The DAG/workflow subsystem is an\n * in-progress track kept out of the published dependency graph, so agent-cli must NOT hard-depend on\n * it — otherwise the published package's `workspace:*` edge resolves to an unpublished version and\n * `npm install @robota-sdk/agent-cli` breaks. `@robota-sdk/agent-command-workflows` is therefore a\n * devDependency, loaded through a guarded `createRequire`: present in the monorepo (and for any user\n * who installs it) → `/workflows` is registered; absent in the default published install → omitted.\n */\nfunction loadOptionalWorkflowsCommandModule(): ICommandModule | undefined {\n try {\n const requireFrom = createRequire(import.meta.url);\n const mod = requireFrom('@robota-sdk/agent-command-workflows') as {\n createWorkflowsCommandModule: () => ICommandModule;\n };\n return mod.createWorkflowsCommandModule();\n } catch {\n // allow-fallback: the workflow subsystem is an optional, unpublished track — its absence just means no /workflows command\n return undefined;\n }\n}\n\nexport interface IStartCliOptions {\n commandModules?: readonly ICommandModule[];\n providerDefinitions?: readonly IProviderDefinition[];\n}\n\n/** Preset-resolved command module selection forwarded by the thin-shell CLI. */\nexport interface ICommandModuleSelection {\n /** Whitelist of module names to keep (omitted → all default modules). */\n enabledCommandModules?: readonly string[];\n /** Blacklist of module names to remove after the whitelist (deny > allow). */\n disabledCommandModules?: readonly string[];\n}\n\nexport interface ICliSetup {\n commandHostAdapters: ICommandHostAdapters;\n providerDefinitions: readonly IProviderDefinition[];\n commandModules: readonly ICommandModule[];\n startupUpdateNoticePromise: Promise<ICliUpdateNotice | undefined> | undefined;\n}\n\nexport function buildCommandSetup(\n cwd: string,\n args: IParsedCliArgs,\n options: IStartCliOptions,\n version: string,\n moduleSelection: ICommandModuleSelection = {},\n): ICliSetup {\n const commandHostAdapters: ICommandHostAdapters = {\n settings: {\n read: () => readSettings(getUserSettingsPath()),\n write: (settings) => writeSettings(getUserSettingsPath(), settings),\n },\n plugin: createDefaultPluginCommandAdapter(cwd),\n };\n const providerDefinitions = options.providerDefinitions ?? createDefaultProviderDefinitions();\n const providerSettingsAdapter = {\n readMergedSettings: () => readMergedProviderSettings(cwd),\n readTargetSettings: () =>\n readSettings(resolveProviderSettingsWriteTargetPath(cwd)) as TProviderSettingsDocument,\n writeTargetSettings: (settings: TProviderSettingsDocument) =>\n writeSettings(resolveProviderSettingsWriteTargetPath(cwd), settings),\n };\n // DAG workflow engine surfaced as `/workflows` (WORKFLOW-003) — optional; omitted from the published\n // CLI whose dependency graph must not include the unpublished DAG chain (see loader doc above).\n const workflowsModule = loadOptionalWorkflowsCommandModule();\n const commandModules: readonly ICommandModule[] = [\n ...createDefaultCommandModules({\n cwd,\n providerDefinitions,\n providerSettingsAdapter,\n ...(moduleSelection.enabledCommandModules !== undefined\n ? { enabledCommandModules: moduleSelection.enabledCommandModules }\n : {}),\n ...(moduleSelection.disabledCommandModules !== undefined\n ? { disabledCommandModules: moduleSelection.disabledCommandModules }\n : {}),\n }),\n ...(workflowsModule ? [workflowsModule] : []),\n ...(options.commandModules ?? []),\n ];\n const startupUpdateNoticePromise = shouldRunStartupCliUpdateCheck(args)\n ? getStartupCliUpdateNotice({ currentVersion: version })\n : undefined;\n return { commandHostAdapters, providerDefinitions, commandModules, startupUpdateNoticePromise };\n}\n","import { readFileSync } from 'node:fs';\nimport { resolve } from 'node:path';\nimport type { IParsedCliArgs } from '../utils/cli-args.js';\n\nfunction readTaskFilePrompt(cwd: string, taskFile: string): string {\n const taskPath = resolve(cwd, taskFile);\n const content = readFileSync(taskPath, 'utf8').trim();\n if (content.length === 0) {\n throw new Error(`Task file is empty: ${taskFile}`);\n }\n return `Task file (${taskFile}):\\n${content}`;\n}\n\nexport function buildAppendSystemPrompt(cwd: string, args: IParsedCliArgs): string | undefined {\n const appendParts: string[] = [];\n if (args.appendSystemPrompt) appendParts.push(args.appendSystemPrompt);\n if (args.taskFile) {\n try {\n appendParts.push(readTaskFilePrompt(cwd, args.taskFile));\n } catch (error) {\n // allow-fallback: terminal failure — task file read failure exits process\n process.stderr.write(`${error instanceof Error ? error.message : String(error)}\\n`);\n process.exit(1);\n }\n }\n if (args.jsonSchema)\n appendParts.push(\n `Respond with valid JSON only, matching this JSON schema:\\n${args.jsonSchema}`,\n );\n return appendParts.length > 0 ? appendParts.join('\\n\\n') : undefined;\n}\n","import type { IAIProvider, TPermissionMode } from '@robota-sdk/agent-core';\nimport type { ICommandHostAdapters, ICommandModule } from '@robota-sdk/agent-framework';\nimport type { createProjectSessionStore } from '@robota-sdk/agent-framework';\nimport { HeadlessInteractionChannel } from '@robota-sdk/agent-transport/headless';\nimport type { IBackgroundTaskRunner } from '@robota-sdk/agent-executor';\nimport type { createChildProcessSubagentRunnerFactory } from '@robota-sdk/agent-subagent-runner';\nimport type { IParsedCliArgs } from '../utils/cli-args.js';\nimport { parseToolList } from '../utils/cli-args.js';\nimport { buildAppendSystemPrompt } from '../startup/append-system-prompt.js';\n\nexport interface IPrintModeSessionResolution {\n /** Session id resolved by the CLI from -c/-r (undefined starts a new session). */\n resumeSessionId?: string;\n /** Fork the resumed session into a new independent session (--fork-session). */\n forkSession?: boolean;\n}\n\n/** Preset-resolved identity/persona the thin-shell CLI forwards into the headless session. */\nexport interface IPrintModePresetOptions {\n /** Resolved agent name (preset value, else agent-preset DEFAULT_AGENT_NAME). */\n agentName?: string;\n /** Active preset id selected at startup (PRESET-011 runtime state). Defaults to 'default'. */\n activePresetId?: string;\n /** Resolved preset persona block composed as a `source: 'persona'` system-prompt section. */\n persona?: string;\n /** Resolved preset permission mode (overridden by an explicit CLI --permission-mode flag). */\n permissionMode?: TPermissionMode;\n /** Preset execution capability: activate agent runtime + subagent/background dispatch. */\n enableParallelSubagents?: boolean;\n /** Preset execution capability: run a post-task self-verification step. */\n selfVerification?: boolean;\n}\n\nexport async function runPrintMode(\n cwd: string,\n args: IParsedCliArgs,\n provider: IAIProvider,\n sessionStore: ReturnType<typeof createProjectSessionStore>,\n backgroundTaskRunners: IBackgroundTaskRunner[],\n subagentRunnerFactory: ReturnType<typeof createChildProcessSubagentRunnerFactory>,\n commandModules: readonly ICommandModule[],\n commandHostAdapters: ICommandHostAdapters,\n sessionResolution: IPrintModeSessionResolution = {},\n presetOptions: IPrintModePresetOptions = {},\n): Promise<void> {\n const goalObjective = args.goal?.trim();\n let prompt = args.positional.join(' ').trim();\n\n if (!goalObjective && !prompt && !process.stdin.isTTY) {\n const chunks: Buffer[] = [];\n for await (const chunk of process.stdin) {\n chunks.push(chunk as Buffer);\n }\n prompt = Buffer.concat(chunks).toString('utf-8').trim();\n }\n\n if (!goalObjective && !prompt) {\n process.stderr.write('Print mode (-p) requires a prompt argument (or --goal <objective>).\\n');\n process.exit(1);\n }\n\n const appendSystemPrompt = buildAppendSystemPrompt(cwd, args);\n\n const channel = new HeadlessInteractionChannel({\n cwd,\n provider,\n outputFormat: args.outputFormat ?? 'text',\n permissionMode: args.permissionMode ?? presetOptions.permissionMode ?? 'bypassPermissions',\n maxTurns: args.maxTurns,\n sessionStore: args.noSessionPersistence ? undefined : sessionStore,\n resumeSessionId: sessionResolution.resumeSessionId,\n forkSession: sessionResolution.forkSession,\n sessionName: args.sessionName,\n bare: args.bare || undefined,\n allowedTools: parseToolList(args.allowedTools),\n deniedTools: parseToolList(args.deniedTools),\n appendSystemPrompt,\n ...(presetOptions.persona !== undefined ? { persona: presetOptions.persona } : {}),\n ...(presetOptions.agentName !== undefined ? { agentName: presetOptions.agentName } : {}),\n ...(presetOptions.activePresetId !== undefined\n ? { activePresetId: presetOptions.activePresetId }\n : {}),\n ...(presetOptions.enableParallelSubagents !== undefined\n ? { enableParallelSubagents: presetOptions.enableParallelSubagents }\n : {}),\n ...(presetOptions.selfVerification !== undefined\n ? { selfVerification: presetOptions.selfVerification }\n : {}),\n ...(args.systemPrompt ? { systemPrompt: args.systemPrompt } : {}),\n backgroundTaskRunners,\n subagentRunnerFactory,\n commandModules,\n commandHostAdapters,\n });\n\n if (goalObjective) {\n await channel.runGoal(\n goalObjective,\n args.goalMaxIterations ? { maxIterations: args.goalMaxIterations } : {},\n );\n } else {\n await channel.run(prompt);\n }\n process.exit(channel.getExitCode());\n}\n","/**\n * CLI entry point — pure composition root.\n * Parses arguments and delegates to startup modules, mode runners, and transports.\n */\n\nimport { execSync } from 'node:child_process';\nimport { createRequire } from 'node:module';\n\nimport { PrintTerminal, promptInput } from '@robota-sdk/agent-transport/headless';\nimport {\n createProjectSessionStore,\n projectPaths,\n resolveLatestSessionId,\n resolveSessionIdByIdOrName,\n readMergedProviderSettings,\n readProviderSettings,\n createProviderFromSettings,\n checkForCliUpdate,\n formatCliUpdateCheckMessage,\n formatCliUpdateNotice,\n ProviderConfigError,\n readSettings,\n getUserSettingsPath,\n} from '@robota-sdk/agent-framework';\nimport { parseCliArgs, parseToolList, printHelp } from './utils/cli-args.js';\nimport type { IParsedCliArgs } from './utils/cli-args.js';\nimport type { IAIProvider } from '@robota-sdk/agent-core';\nimport { resolveCliPreset, selectPresetId } from './startup/preset-selection.js';\nimport { DEFAULT_AGENT_NAME, loadExternalPresets } from '@robota-sdk/agent-preset';\nimport type { IResolvedPresetOptions } from '@robota-sdk/agent-preset';\nimport {\n ensureConfig,\n handleProviderConfigurationArgs,\n runInteractiveProviderSetup,\n} from './startup/provider-startup.js';\nimport { renderApp, createDefaultTuiCliAdapter } from '@robota-sdk/agent-transport-tui';\nimport { installTuiProcessGuards, setLiveChannel } from './process-guards.js';\nimport { TransportRegistry } from '@robota-sdk/agent-transport';\nimport { WsTransport } from '@robota-sdk/agent-transport-ws';\nimport { createDefaultBackgroundTaskRunners } from '@robota-sdk/agent-executor';\nimport {\n createChildProcessSubagentRunnerFactory,\n getDefaultSubagentWorkerPath,\n} from '@robota-sdk/agent-subagent-runner';\nimport { reloadPluginCommandSource } from '@robota-sdk/agent-command';\nimport { runUserLocalDirectCommandIfRequested } from './user-local-direct-command.js';\nimport { runSessionAnalyze } from './session-analyzer/session-analyze-command.js';\nimport { readVersion } from './startup/version.js';\nimport { runResetConfig } from './startup/reset-config.js';\nimport { runDiagnoseCommand } from './startup/diagnose-command.js';\nimport { runInitCommand } from './init/init-command.js';\nimport { isFirstRun, markOnboarded, printFirstRunWelcome } from './startup/first-run.js';\nimport { warnIfTerminalAppOnMacOS } from './startup/terminal-check.js';\nimport type { IStartCliOptions } from './startup/command-setup.js';\nimport { buildCommandSetup } from './startup/command-setup.js';\nimport { runPrintMode } from './modes/print-mode.js';\n\nexport type { IStartCliOptions };\n\n/**\n * Composition-root wiring of the default transport registry. The generic registry lives in\n * `@robota-sdk/agent-transport`; choosing which concrete transports to pre-register is an\n * app-assembly decision, so the CLI (the composition root) wires `WsTransport` here rather than\n * the transport core depending on the ws package.\n */\n/**\n * Load the optional session-log replay provider (INFRA-017). `@robota-sdk/agent-provider-replay` is a\n * dev/test-only package deliberately kept out of the published dependency graph, so `--session-log`\n * replay is a development capability: resolvable in the monorepo (and for anyone who installs the\n * package), and reported as unavailable — never a hard crash — in the default published CLI.\n */\nfunction loadReplayProvider(logFile: string): IAIProvider {\n let mod: { createReplayProviderFromLogFile: (file: string) => IAIProvider };\n try {\n const requireFrom = createRequire(import.meta.url);\n mod = requireFrom('@robota-sdk/agent-provider-replay') as typeof mod;\n } catch {\n throw new Error(\n '--session-log replay requires @robota-sdk/agent-provider-replay, a dev-only package that is not bundled in the published CLI.',\n );\n }\n return mod.createReplayProviderFromLogFile(logFile);\n}\n\nfunction createDefaultTransportRegistry(): TransportRegistry {\n const registry = new TransportRegistry(getUserSettingsPath());\n registry.register(new WsTransport());\n return registry;\n}\n\nexport async function startCli(options: IStartCliOptions = {}): Promise<void> {\n // OBS-001: `session analyze` carries its own flags (--last/--session) that the strict\n // global parser does not know. Intercept it BEFORE parseCliArgs() so those flags reach\n // the subcommand instead of being rejected as \"Unknown option\".\n if (process.argv[2] === 'session' && process.argv[3] === 'analyze') {\n await runSessionAnalyze(process.argv.slice(4), process.cwd());\n return;\n }\n\n let args: IParsedCliArgs;\n try {\n args = parseCliArgs();\n } catch (error) {\n // allow-fallback: argument validation errors are terminal — exit is the correct response\n process.stderr.write(`${error instanceof Error ? error.message : String(error)}\\n`);\n process.exit(1);\n }\n const version = readVersion();\n\n if (args.help) {\n process.stdout.write(printHelp());\n return;\n }\n\n if (args.version) {\n process.stdout.write(`robota ${version}\\n`);\n return;\n }\n\n if (args.checkUpdate) {\n const result = await checkForCliUpdate({ currentVersion: version, force: true });\n const message = formatCliUpdateCheckMessage(result);\n if (result.status === 'error') {\n process.stderr.write(`${message}\\n`);\n process.exit(1);\n }\n process.stdout.write(`${message}\\n`);\n return;\n }\n\n const cwd = process.cwd();\n const terminal = new PrintTerminal();\n\n if (args.reset) {\n // Destructive-action contract (CLI-070): confirm in TTY, require --yes otherwise.\n process.exitCode = await runResetConfig(terminal, {\n yes: args.yes,\n isTTY: process.stdin.isTTY === true,\n });\n return;\n }\n\n if (args.positional[0] === 'diagnose') {\n // Exit contract (CLI-067): 0 = no issues, 1 = one or more failed checks.\n const failCount = await runDiagnoseCommand({ version, terminal, cwd });\n process.exitCode = failCount > 0 ? 1 : 0;\n return;\n }\n\n if (args.positional[0] === 'session' && args.positional[1] === 'analyze') {\n // Normally unreachable — the pre-parse interceptor above handles `session analyze`.\n // Kept as a defensive fallthrough for non-argv invocations.\n await runSessionAnalyze(process.argv.slice(4), cwd);\n return;\n }\n\n try {\n if (await runUserLocalDirectCommandIfRequested(args, cwd, terminal)) {\n return;\n }\n } catch (error) {\n // allow-fallback: user-local command failure is terminal — exit is the correct response\n terminal.writeError(error instanceof Error ? error.message : String(error));\n process.exit(1);\n }\n\n // PRESET-002/004: thin shell — select preset id (flag > settings.preset > 'default') and forward\n // the resolved framework options. The precedence merge + posture mapping lives in\n // agent-preset.resolvePreset; the CLI owns none of that logic. Resolved before command setup so\n // the preset's module-selection delta can reach createDefaultCommandModules.\n const userSettings = readSettings(getUserSettingsPath());\n const settingsPreset = typeof userSettings.preset === 'string' ? userSettings.preset : undefined;\n // PRESET-007: register user-authored external presets (~/.robota/presets/*.json) into the\n // shared registry before resolution so `--preset <id>` and `/preset` can see them. Per-file\n // load/validation problems are non-fatal and surfaced as warnings; the run still proceeds.\n const externalPresetLoad = loadExternalPresets();\n for (const { file, error } of externalPresetLoad.errors) {\n terminal.writeError(`Skipped external preset \"${file}\": ${error}`);\n }\n let resolvedPreset: IResolvedPresetOptions;\n try {\n resolvedPreset = resolveCliPreset(args, settingsPreset);\n } catch (error) {\n // allow-fallback: unknown preset id is terminal — surface available list, exit\n process.stderr.write(`${error instanceof Error ? error.message : String(error)}\\n`);\n process.exit(1);\n }\n // PRESET-011: the selected preset id (same selection glue as resolveCliPreset) becomes the\n // session's runtime active-preset state. Pure state — no option re-application here.\n const selectedPresetId = selectPresetId(args, settingsPreset);\n\n const { commandHostAdapters, providerDefinitions, commandModules, startupUpdateNoticePromise } =\n buildCommandSetup(cwd, args, options, version, {\n ...(resolvedPreset.enabledCommandModules !== undefined\n ? { enabledCommandModules: resolvedPreset.enabledCommandModules }\n : {}),\n ...(resolvedPreset.disabledCommandModules !== undefined\n ? { disabledCommandModules: resolvedPreset.disabledCommandModules }\n : {}),\n });\n\n if (args.positional[0] === 'init') {\n try {\n await runInitCommand(cwd, terminal, {\n yes: args.yes,\n onProviderSetup: async () => {\n await runInteractiveProviderSetup(cwd, args, promptInput, terminal, providerDefinitions);\n },\n });\n } catch (error) {\n // allow-fallback: init prompt failure is terminal — exit is the correct response\n terminal.writeError(error instanceof Error ? error.message : String(error));\n process.exit(1);\n }\n return;\n }\n\n if (args.configure) {\n await runInteractiveProviderSetup(cwd, args, promptInput, terminal, providerDefinitions);\n return;\n }\n\n if (handleProviderConfigurationArgs(cwd, args, terminal, providerDefinitions)) {\n return;\n }\n\n try {\n await ensureConfig(cwd, args, promptInput, terminal, providerDefinitions);\n } catch (error) {\n // allow-fallback: terminal failure — not a silent fallback\n process.stderr.write(`${error instanceof Error ? error.message : String(error)}\\n`);\n // Exit-code contract: provider configuration errors in print mode exit 3 so\n // automation can distinguish \"reconfigure\" from runtime failures (exit 1).\n process.exit(error instanceof ProviderConfigError && args.printMode ? 3 : 1);\n }\n\n const providerOptions = args.provider\n ? { providerOverride: args.provider, providerDefinitions }\n : { providerDefinitions };\n const providerSettings = readProviderSettings(cwd, providerOptions);\n const modelId = resolvedPreset.model ?? providerSettings.model;\n if (providerSettings.source === 'env-default' && providerSettings.sourceEnvVar !== undefined) {\n const notice = `Using ${providerSettings.name} (${modelId}) via ${providerSettings.sourceEnvVar} — run \\`robota --configure\\` to persist a profile.\\n`;\n if (args.printMode) {\n process.stderr.write(notice);\n } else {\n terminal.writeLine(notice.trimEnd());\n }\n }\n // INFRA-018: when a session log is supplied, replay it deterministically instead of calling a\n // model. Provider settings/model still come from the configured profile (no key is ever used —\n // the ReplayProvider answers every call from the recorded log).\n const provider = args.sessionLog\n ? loadReplayProvider(args.sessionLog)\n : createProviderFromSettings(cwd, resolvedPreset.model, providerOptions);\n const backgroundTaskRunners = createDefaultBackgroundTaskRunners();\n const paths = projectPaths(cwd);\n const subagentRunnerFactory = createChildProcessSubagentRunnerFactory({\n workerPath: getDefaultSubagentWorkerPath(),\n providerConfig: { ...providerSettings, model: modelId },\n logsDir: paths.logs,\n });\n\n const sessionStore = createProjectSessionStore(cwd);\n let resumeSessionId: string | undefined;\n let showSessionPickerOnStart = false;\n\n if (args.continueMode) {\n resumeSessionId = resolveLatestSessionId(sessionStore, cwd);\n } else if (args.resumeId !== undefined) {\n if (args.resumeId === '') {\n showSessionPickerOnStart = true;\n } else {\n resumeSessionId = resolveSessionIdByIdOrName(sessionStore, args.resumeId);\n if (resumeSessionId === undefined) {\n process.stderr.write(`Session not found: ${args.resumeId}\\n`);\n process.exit(1);\n }\n }\n }\n\n // GOAL-001: --goal runs an autonomous headless goal even without an explicit -p.\n if (args.printMode || args.goal) {\n await runPrintMode(\n cwd,\n args,\n provider,\n sessionStore,\n backgroundTaskRunners,\n subagentRunnerFactory,\n commandModules,\n commandHostAdapters,\n { resumeSessionId, forkSession: args.forkSession },\n {\n agentName: resolvedPreset.agentName ?? DEFAULT_AGENT_NAME,\n activePresetId: selectedPresetId,\n persona: resolvedPreset.persona,\n ...(resolvedPreset.permissionMode !== undefined\n ? { permissionMode: resolvedPreset.permissionMode }\n : {}),\n ...(resolvedPreset.enableParallelSubagents !== undefined\n ? { enableParallelSubagents: resolvedPreset.enableParallelSubagents }\n : {}),\n ...(resolvedPreset.selfVerification !== undefined\n ? { selfVerification: resolvedPreset.selfVerification }\n : {}),\n },\n );\n return;\n }\n\n warnIfTerminalAppOnMacOS(terminal);\n // ERR-001 G1: interactive mode only — the process must survive transient failures.\n installTuiProcessGuards();\n if (isFirstRun()) {\n printFirstRunWelcome(terminal);\n markOnboarded();\n }\n\n await renderApp({\n onChannelReady: (channel) => setLiveChannel(channel),\n cwd,\n provider,\n providerOverride: args.provider,\n providerType: providerSettings.name,\n modelId,\n language: args.language,\n permissionMode: args.permissionMode ?? resolvedPreset.permissionMode,\n maxTurns: args.maxTurns,\n allowedTools: parseToolList(args.allowedTools),\n deniedTools: parseToolList(args.deniedTools),\n version,\n sessionStore: args.noSessionPersistence ? undefined : sessionStore,\n resumeSessionId,\n showSessionPickerOnStart,\n forkSession: args.forkSession,\n sessionName: args.sessionName,\n backgroundTaskRunners,\n subagentRunnerFactory,\n commandModules,\n commandHostAdapters,\n shellExec: (command: string) =>\n execSync(command, { timeout: 5000, encoding: 'utf-8', stdio: 'pipe' }).trimEnd(),\n startupUpdateNotice: startupUpdateNoticePromise\n ? startupUpdateNoticePromise.then((n) => (n ? formatCliUpdateNotice(n) : undefined))\n : undefined,\n transportRegistry: createDefaultTransportRegistry(),\n cliAdapter: createDefaultTuiCliAdapter({ providerDefinitions, reloadPluginCommandSource }),\n reloadPluginCommandSource,\n agentName: resolvedPreset.agentName ?? DEFAULT_AGENT_NAME,\n activePresetId: selectedPresetId,\n persona: resolvedPreset.persona,\n ...(resolvedPreset.enableParallelSubagents !== undefined\n ? { enableParallelSubagents: resolvedPreset.enableParallelSubagents }\n : {}),\n ...(resolvedPreset.selfVerification !== undefined\n ? { selfVerification: resolvedPreset.selfVerification }\n : {}),\n });\n process.exit(0);\n}\n","#!/usr/bin/env node\n/**\n * Robota CLI binary entry point.\n *\n * Boots the CLI and handles any uncaught top-level errors gracefully.\n *\n * A Node.js version check (>=22) is injected as a build-time banner in\n * tsdown.config.ts and runs before any module imports are loaded.\n */\nimport { startCli } from './cli.js';\nimport { areTuiProcessGuardsActive, classifyUncaughtException } from './process-guards.js';\n\n// Last-resort crash policy (CORE-020, RUNTIME-34): the IME allowlist is scoped to\n// interactive TUI mode only — headless/print mode always rethrows (fail-fast exit-code\n// contract), so generic signatures like 'slice' can never mask a real headless crash.\n// ERR-001 G1: with the TUI guards active, non-IME errors are guard-owned — the guards\n// render them into the live session; re-throwing here would kill the TUI.\nprocess.on('uncaughtException', (err) => {\n const decision = classifyUncaughtException(err, areTuiProcessGuardsActive());\n if (decision === 'ime-hint') {\n process.stderr.write(\n '\\n[robota] CJK/IME input error — this is a known issue with macOS Terminal.app.\\n' +\n ' Workaround: use iTerm2 (https://iterm2.com) or input your prompt in English.\\n' +\n ' Alternatively, use headless mode: robota -p \"your prompt here\"\\n\\n',\n );\n return;\n }\n if (decision === 'guard-owned') return;\n throw err;\n});\n\nstartCli().catch((err) => {\n const message = err instanceof Error ? err.message : String(err);\n process.stderr.write(message + '\\n');\n process.exit(1);\n});\n"],"mappings":"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"}
|