@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/README.md CHANGED
@@ -14,7 +14,7 @@ AI coding assistant CLI built on Robota SDK. Loads AGENTS.md/CLAUDE.md for proje
14
14
  | Multi-provider (Anthropic, OpenAI, Gemini, Qwen…) | ✅ | ❌ | ✅ |
15
15
  | Embed SDK in your own app | ✅ | ❌ | ❌ |
16
16
  | Local models (LM Studio, Ollama via OpenAI API) | ✅ | ❌ | ✅ |
17
- | Open source (MIT) | ✅ | partial | ✅ |
17
+ | Open source (AGPL-3.0) | ✅ | partial | ✅ |
18
18
  | Claude Code config compatible (CLAUDE.md, modes) | ✅ | — | ❌ |
19
19
 
20
20
  ## Embed in Your App
@@ -24,6 +24,7 @@ import { createAgentRuntime } from '@robota-sdk/agent-framework';
24
24
  import { createAnthropicProvider } from '@robota-sdk/agent-provider';
25
25
 
26
26
  const runtime = createAgentRuntime({
27
+ cwd: process.cwd(),
27
28
  provider: createAnthropicProvider({ apiKey: process.env.ANTHROPIC_API_KEY }),
28
29
  });
29
30
  const session = runtime.createSession({ permissionMode: 'bypassPermissions' });
@@ -129,10 +130,12 @@ robota -r <session-id> # Resume session by ID
129
130
  robota --language <lang> # Response language (ko, en, ja, zh)
130
131
  robota --permission-mode <mode> # plan | default | acceptEdits | bypassPermissions
131
132
  robota --max-turns <n> # Limit agentic turns per interaction
133
+ robota --goal "<objective>" # Pursue an autonomous goal headlessly until satisfied or a bound
134
+ robota --goal-max-iterations <n> # Per-goal turn budget (default 25)
132
135
  robota --output-format <fmt> # text | json | stream-json (print mode)
133
136
  robota --system-prompt <text> # Replace system prompt (print mode)
134
137
  robota --append-system-prompt <text> # Append to system prompt (print mode)
135
- robota --model claude-opus-4-7 # Override provider model for this session
138
+ robota --model claude-sonnet-4-6 # Override provider model for this session
136
139
  robota --allowed-tools "Bash,Read" # Whitelist specific tools
137
140
  robota --denied-tools "Bash,Write" # Blacklist specific tools (denied > allowed)
138
141
  robota --reset # Delete user settings and exit
@@ -371,13 +374,14 @@ Typing `/` in the TUI opens an autocomplete popup. Arrow keys navigate, Tab inse
371
374
 
372
375
  ### Tools & Memory
373
376
 
374
- | Command | Description |
375
- | ---------------------- | ---------------------------------------------- |
376
- | `/memory [subcommand]` | Inspect, add, or review project memory entries |
377
- | `/background` | List and control background tasks |
378
- | `/agent` | Run and manage background subagent jobs |
379
- | `/skills [name]` | List registered skills or activate one by name |
380
- | `/plugin [subcommand]` | Plugin management |
377
+ | Command | Description |
378
+ | ---------------------- | -------------------------------------------------------------------- |
379
+ | `/memory [subcommand]` | Inspect, add, or review project memory entries |
380
+ | `/background` | List and control background tasks |
381
+ | `/goal <objective>` | Assign an autonomous goal pursued across turns (`status` / `cancel`) |
382
+ | `/agent` | Run and manage background subagent jobs |
383
+ | `/skills [name]` | List registered skills or activate one by name |
384
+ | `/plugin [subcommand]` | Plugin management |
381
385
 
382
386
  ### Utility
383
387
 
@@ -512,7 +516,7 @@ bin.ts → cli.ts (arg parsing)
512
516
  │ ├── InteractiveSession (SDK)
513
517
  │ ├── CommandRegistry (SDK, re-exported by CLI)
514
518
  │ │ ├── BuiltinCommandSource (SDK, empty by default)
515
- │ │ ├── agent-command-skills (/skills command + virtual skill aliases)
519
+ │ │ ├── agent-command (./skills) (/skills command + virtual skill aliases)
516
520
  │ │ ├── PluginCommandSource (SDK, plugin skills)
517
521
  │ │ └── ICommandModule sources (/help, /compact, ...)
518
522
  │ └── SystemCommandExecutor (SDK)
@@ -531,19 +535,19 @@ bin.ts → cli.ts (arg parsing)
531
535
 
532
536
  ## Dependencies
533
537
 
534
- | Package | Purpose |
535
- | -------------------------------------- | ------------------------------------------ |
536
- | `@robota-sdk/agent-framework` | Session factory, query, config, context |
537
- | `@robota-sdk/agent-core` | Types (TPermissionMode, TToolArgs) |
538
- | `@robota-sdk/agent-transport-headless` | Headless runner for print mode (`-p`) |
539
- | `ink` 7, `react` 19.2+ | TUI rendering |
540
- | `ink-select-input` | Arrow-key selection (permission prompt) |
541
- | `ink-spinner` | Loading spinner |
542
- | `chalk` | Terminal colors |
543
- | `ink-text-input` | Base text input (extended by CjkTextInput) |
544
- | `marked`, `marked-terminal` | Markdown parsing and terminal rendering |
545
- | `cli-highlight` | Syntax highlighting for code blocks |
546
- | `string-width` | Unicode-aware string width (CJK support) |
538
+ | Package | Purpose |
539
+ | -------------------------------------------- | ------------------------------------------ |
540
+ | `@robota-sdk/agent-framework` | Session factory, query, config, context |
541
+ | `@robota-sdk/agent-core` | Types (TPermissionMode, TToolArgs) |
542
+ | `@robota-sdk/agent-transport` (`./headless`) | Headless runner for print mode (`-p`) |
543
+ | `ink` 7, `react` 19.2+ | TUI rendering |
544
+ | `ink-select-input` | Arrow-key selection (permission prompt) |
545
+ | `ink-spinner` | Loading spinner |
546
+ | `chalk` | Terminal colors |
547
+ | `ink-text-input` | Base text input (extended by CjkTextInput) |
548
+ | `marked`, `marked-terminal` | Markdown parsing and terminal rendering |
549
+ | `cli-highlight` | Syntax highlighting for code blocks |
550
+ | `string-width` | Unicode-aware string width (CJK support) |
547
551
 
548
552
  ## Documentation
549
553
 
@@ -551,4 +555,4 @@ See [docs/SPEC.md](./docs/SPEC.md) for the full specification, architecture deta
551
555
 
552
556
  ## License
553
557
 
554
- MIT
558
+ Robota is dual-licensed under the [GNU AGPL-3.0](../../LICENSE) or a [commercial license](../../COMMERCIAL.md). See [LICENSING.md](../../LICENSING.md).
package/dist/node/bin.js CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  ;(function(){var v=parseInt(process.versions.node.split('.')[0],10);if(v<22){process.stderr.write('\n✗ Node.js 22+ is required (current: '+process.version+')\n\nUpgrade:\n nvm: nvm install 22 && nvm use 22\n Volta: volta install node@22\n Download: https://nodejs.org/en/download\n\n');process.exit(1);}})();
3
- import{execSync as e}from"node:child_process";import{HeadlessInteractionChannel as t,PrintTerminal as n,promptInput as r}from"@robota-sdk/agent-transport/headless";import{ProviderConfigError as i,applyProviderConfiguration as a,applyProviderSwitch as o,checkForCliUpdate as s,createProjectSessionStore as c,createProviderFromSettings as l,formatCliUpdateCheckMessage as u,formatCliUpdateNotice as d,getProviderSettingsPaths as f,getStartupCliUpdateNotice as p,getUserSettingsPath as m,projectPaths as h,readMergedProviderSettings as g,readPackageVersion as _,readProviderSettings as ee,readSettings as v,resetUserConfig as y,resolveLatestSessionId as te,resolveProviderSettingsWriteTargetPath as b,resolveSessionIdByIdOrName as ne,resolveSettingsPathForScope as x,shouldRunStartupCliUpdateCheck as S,userPaths as C,writeSettings as w}from"@robota-sdk/agent-framework";import{parseArgs as T}from"node:util";import{DEFAULT_AGENT_NAME as E,loadExternalPresets as re,resolvePreset as D}from"@robota-sdk/agent-preset";import{formatSupportedProviderTypes as O}from"@robota-sdk/agent-core";import{createDefaultProviderDefinitions as k}from"@robota-sdk/agent-provider";import{createDefaultCommandModules as A,createDefaultPluginCommandAdapter as j,ensureProviderConfig as M,executeUserLocalDirectCommand as N,reloadPluginCommandSource as ie,runProviderStartupSetup as P}from"@robota-sdk/agent-command";import{createDefaultTuiCliAdapter as ae,renderApp as oe}from"@robota-sdk/agent-transport/tui";import{createDefaultTransportRegistry as se}from"@robota-sdk/agent-transport";import{createDefaultBackgroundTaskRunners as ce}from"@robota-sdk/agent-executor";import{createChildProcessSubagentRunnerFactory as le,getDefaultSubagentWorkerPath as ue}from"@robota-sdk/agent-subagent-runner";import{existsSync as F,mkdirSync as I,readFileSync as L,readdirSync as de,writeFileSync as R}from"node:fs";import{basename as z,dirname as B,join as V,resolve as fe}from"node:path";import{createInterface as pe}from"node:readline/promises";import{createConnection as me}from"node:net";const H=[`plan`,`default`,`acceptEdits`,`bypassPermissions`],U=[`text`,`json`,`stream-json`];function he(){return`
3
+ import{createRequire as e}from"node:module";import{execSync as t}from"node:child_process";import{HeadlessInteractionChannel as n,PrintTerminal as r,promptInput as i}from"@robota-sdk/agent-transport/headless";import{ProviderConfigError as a,applyProviderConfiguration as o,applyProviderSwitch as s,checkForCliUpdate as c,createProjectSessionStore as l,createProviderFromSettings as u,createUserSessionStore as d,formatCliUpdateCheckMessage as f,formatCliUpdateNotice as p,getProviderSettingsPaths as m,getStartupCliUpdateNotice as h,getUserSettingsPath as g,projectPaths as _,readMergedProviderSettings as v,readPackageVersion as y,readProviderSettings as b,readSettings as x,resetUserConfig as S,resolveLatestSessionId as ee,resolveProviderSettingsWriteTargetPath as C,resolveSessionIdByIdOrName as te,resolveSettingsPathForScope as w,shouldRunStartupCliUpdateCheck as T,userPaths as E,writeSettings as D}from"@robota-sdk/agent-framework";import{parseArgs as O}from"node:util";import{DEFAULT_AGENT_NAME as ne,loadExternalPresets as re,resolvePreset as k}from"@robota-sdk/agent-preset";import{formatSupportedProviderTypes as A}from"@robota-sdk/agent-core";import{createDefaultProviderDefinitions as j}from"@robota-sdk/agent-provider";import{createDefaultCommandModules as ie,createDefaultPluginCommandAdapter as M,ensureProviderConfig as N,executeUserLocalDirectCommand as P,reloadPluginCommandSource as ae,runProviderStartupSetup as F}from"@robota-sdk/agent-command";import{createDefaultTuiCliAdapter as oe,renderApp as se}from"@robota-sdk/agent-transport-tui";import{TransportRegistry as ce}from"@robota-sdk/agent-transport";import{WsTransport as le}from"@robota-sdk/agent-transport-ws";import{createDefaultBackgroundTaskRunners as ue}from"@robota-sdk/agent-executor";import{createChildProcessSubagentRunnerFactory as de,getDefaultSubagentWorkerPath as fe}from"@robota-sdk/agent-subagent-runner";import{aggregateReports as pe,analyzeSession as I,formatAggregateReport as me,formatSingleSession as L,formatUsageReport as he,summarizeUsageBySource as ge}from"@robota-sdk/agent-session-analytics";import{existsSync as R,mkdirSync as z,readFileSync as B,writeFileSync as V}from"node:fs";import{createInterface as _e}from"node:readline/promises";import{createConnection as ve}from"node:net";import{dirname as ye,join as H,resolve as be}from"node:path";const U=[`plan`,`default`,`acceptEdits`,`bypassPermissions`],W=[`text`,`json`,`stream-json`];function xe(){return`
4
4
  Usage: robota [options] [-p <prompt>]
5
5
 
6
6
  Options:
@@ -46,20 +46,19 @@ Examples:
46
46
  robota --task-file task.md Run task from file (appended to system prompt)
47
47
  robota -p "Refactor the auth module" --dry-run Plan only, no execution
48
48
  robota --continue Resume the last session
49
- `}function W(e){if(e===void 0)return;let t=e.split(`,`).map(e=>e.trim()).filter(e=>e.length>0);return t.length>0?t:void 0}function ge(e){if(e!==void 0){if(!U.includes(e))throw Error(`Invalid --output-format "${e}". Valid: ${U.join(` | `)}`);return e}}function _e(e){if(e!==void 0){if(!H.includes(e))throw Error(`Invalid --permission-mode "${e}". Valid: ${H.join(` | `)}`);return e}}function ve(e){if(e===void 0)return;let t=parseInt(e,10);if(isNaN(t)||t<=0)throw Error(`Invalid --max-turns "${e}". Must be a positive integer.`);return t}const ye={allowPositionals:!0,options:{help:{type:`boolean`,short:`h`,default:!1},p:{type:`boolean`,short:`p`,default:!1},continue:{type:`boolean`,short:`c`,default:!1},resume:{type:`string`,short:`r`},language:{type:`string`},"permission-mode":{type:`string`},"max-turns":{type:`string`},"fork-session":{type:`boolean`,default:!1},name:{type:`string`,short:`n`},"output-format":{type:`string`},format:{type:`string`},summary:{type:`string`},source:{type:`string`},"system-prompt":{type:`string`},"append-system-prompt":{type:`string`},"task-file":{type:`string`},version:{type:`boolean`,default:!1},reset:{type:`boolean`,default:!1},bare:{type:`boolean`,default:!1},"allowed-tools":{type:`string`},"denied-tools":{type:`string`},model:{type:`string`},preset:{type:`string`},"no-session-persistence":{type:`boolean`,default:!1},"json-schema":{type:`string`},configure:{type:`boolean`,default:!1},"configure-provider":{type:`string`},provider:{type:`string`},type:{type:`string`},"base-url":{type:`string`},"api-key":{type:`string`},"api-key-env":{type:`string`},"set-current":{type:`boolean`,default:!1},"settings-scope":{type:`string`},"check-update":{type:`boolean`,default:!1},"disable-update-check":{type:`boolean`,default:!1},"dry-run":{type:`boolean`,default:!1},yes:{type:`boolean`,short:`y`,default:!1}}};function be(e,t){return{positional:t,help:e.help??!1,printMode:e.p??!1,continueMode:e.continue??!1,resumeId:e.resume,language:e.language,permissionMode:_e(e[`permission-mode`]),maxTurns:ve(e[`max-turns`]),forkSession:e[`fork-session`]??!1,sessionName:e.name,outputFormat:ge(e[`output-format`]),format:e.format,summary:e.summary,source:e.source,systemPrompt:e[`system-prompt`],appendSystemPrompt:e[`append-system-prompt`],taskFile:e[`task-file`],version:e.version??!1,reset:e.reset??!1,bare:e.bare??!1,allowedTools:e[`allowed-tools`],deniedTools:e[`denied-tools`],model:e.model,preset:e.preset,noSessionPersistence:e[`no-session-persistence`]??!1,jsonSchema:e[`json-schema`],configure:e.configure??!1,configureProvider:e[`configure-provider`],provider:e.provider,providerType:e.type,baseURL:e[`base-url`],apiKey:e[`api-key`],apiKeyEnv:e[`api-key-env`],setCurrent:e[`set-current`]??!1,settingsScope:e[`settings-scope`],checkUpdate:e[`check-update`]??!1,disableUpdateCheck:e[`disable-update-check`]??!1,dryRun:e[`dry-run`]??!1,yes:e.yes??!1}}function xe(){let{values:e,positionals:t}=T(ye),n=be(e,t);if(n.printMode){if(n.resumeId===``)throw Error(`Print mode requires an explicit session id: -r <id|name> (the interactive session picker is TUI-only)`);if(n.noSessionPersistence&&(n.continueMode||n.resumeId!==void 0))throw Error(`--no-session-persistence conflicts with -c/-r (resume needs the session store)`)}if(n.dryRun){if(n.permissionMode!==void 0&&n.permissionMode!==`plan`)throw Error(`--dry-run is an alias for --permission-mode plan and conflicts with --permission-mode ${n.permissionMode}`);return{...n,permissionMode:`plan`}}return n}function G(e,t){return e.preset??t??`default`}function Se(e){return{...e.model===void 0?{}:{model:e.model},...e.systemPrompt===void 0?{}:{systemPrompt:e.systemPrompt},...e.appendSystemPrompt===void 0?{}:{appendSystemPrompt:e.appendSystemPrompt},...e.language===void 0?{}:{language:e.language},...e.permissionMode===void 0?{}:{permissionMode:e.permissionMode}}}function Ce(e,t){return D(G(e,t),{cliOverrides:Se(e)})}function K(e){if(e===void 0||e===`user`||e===`project-local`)return e;throw Error(`Invalid --settings-scope "${e}". Valid: user | project-local`)}function we(e,t,n,r=k()){let i=x(e,K(t.settingsScope));return t.configureProvider?(a(i,De(t),{providerDefinitions:r}),n.writeLine(`Provider profile saved to ${i}`),!t.printMode&&t.positional.length===0):t.provider&&t.setCurrent?(o(t.settingsScope===void 0?b(e):i,t.provider,{knownProviders:g(e).providers}),n.writeLine(`Current provider set to ${t.provider}`),!t.printMode&&t.positional.length===0):!1}async function Te(e,t,n,r,i=k(),a){await M(e,{provider:t.provider,settingsScope:K(t.settingsScope)},n,r,i,{formatError:Oe,isInteractive:a===void 0?()=>process.stdin.isTTY===!0&&process.stdout.isTTY===!0:()=>a})}async function Ee(e,t,n,r,i=k()){await P(e,{settingsScope:K(t.settingsScope)},n,r,i)}function De(e){let t=e.providerType??e.configureProvider;if(!e.configureProvider||!t)throw Error(`--configure-provider requires a provider profile and --type`);return{profile:e.configureProvider,type:t,...e.model!==void 0&&{model:e.model},...e.apiKey!==void 0&&{apiKey:e.apiKey},...e.apiKeyEnv!==void 0&&{apiKeyEnv:e.apiKeyEnv},...e.baseURL!==void 0&&{baseURL:e.baseURL},setCurrent:e.setCurrent}}function Oe(e=k()){return[`No provider configuration found.`,"Run `robota --configure` in an interactive terminal, or configure a provider:",`Supported providers: ${O(e)}`,...e.map(ke)].join(`
50
- `)}function ke(e){return` ${[`robota --configure-provider ${e.type}`,`--type ${e.type}`,...e.defaults?.baseURL===void 0?[]:[`--base-url <url>`],`--model <model>`,...e.requiresApiKey===!0?[`--api-key-env <ENV_NAME>`]:[],`--set-current`].join(` `)}`}async function Ae(e,t,n){if(e.positional[0]!==`user-local`)return!1;let r=await N({cwd:t,argv:e.positional.slice(1),format:e.format,summary:e.summary,source:e.source}),i=r.message.trimEnd();if(!r.success)throw Error(i);return n.writeLine(i),!0}function q(e){let t=L(e,`utf-8`);return JSON.parse(t)}function je(e,t){return new Date(t).getTime()-new Date(e).getTime()}function Me(e){let t=[],n=0,r=0;for(;r<e.length;){let i=e[r];if(!i){r++;continue}if(i.category===`chat`&&i.type===`user`){n++;let a=i.timestamp,o=!1,s=null,c=r+1;for(;c<e.length;){let r=e[c];if(!r){c++;continue}if(r.category===`chat`&&r.type===`user`)break;if(r.category===`event`&&r.type===`tool-start`){o?s!==null&&t.push(J(`llm_between_tools`,`tool-end`,`tool-start`,s,r.timestamp,n)):(t.push(J(`user_to_first_tool`,`user`,`tool-start`,a,r.timestamp,n)),o=!0),s=null,c++;continue}if(r.category===`event`&&r.type===`tool-end`){let i=e[c-1];i&&i.category===`event`&&i.type===`tool-start`&&t.push(J(`tool_exec`,`tool-start`,`tool-end`,i.timestamp,r.timestamp,n)),s=r.timestamp,c++;continue}if(r.category===`event`&&r.type===`tool-summary`){s!==null&&t.push(J(`llm_final_response`,`tool-end`,`tool-summary`,s,r.timestamp,n)),c++;continue}if(r.category===`chat`&&r.type===`assistant`){o?s!==null&&t.push(J(`llm_final_response`,`tool-end`,`assistant`,s,r.timestamp,n)):t.push(J(`user_to_assistant`,`user`,`assistant`,a,r.timestamp,n)),c++;break}c++}r=c}else r++}return t}function J(e,t,n,r,i,a){return{kind:e,fromType:t,toType:n,fromTimestamp:r,toTimestamp:i,durationMs:je(r,i),turnIndex:a}}function Ne(e){let t=e.filter(e=>e.kind===`user_to_first_tool`||e.kind===`user_to_assistant`||e.kind===`llm_between_tools`||e.kind===`llm_final_response`),n=e.filter(e=>e.kind===`tool_exec`),r=e.filter(e=>e.kind===`user_to_assistant`),i=e=>e.length?Math.round(e.reduce((e,t)=>e+t.durationMs,0)/e.length):0,a=e=>e.length?Math.max(...e.map(e=>e.durationMs)):0;return{llmWaitMs:{avg:i(t),max:a(t),total:t.reduce((e,t)=>e+t.durationMs,0),count:t.length},toolExecMs:{avg:i(n),max:a(n),median:(e=>{if(!e.length)return 0;let t=[...e].sort((e,t)=>e.durationMs-t.durationMs),n=Math.floor(t.length/2);return t.length%2==0?Math.round(((t[n-1]?.durationMs??0)+(t[n]?.durationMs??0))/2):t[n]?.durationMs??0})(n),count:n.length},userToAssistantMs:{avg:i(r),max:a(r),count:r.length}}}function Y(e){let t=Me(e.history??[]),n=t.filter(e=>e.durationMs>=1e4);return{sessionId:e.id,cwd:e.cwd,createdAt:e.createdAt,totalIntervals:t.length,intervals:t,slowIntervals:n,stats:Ne(t)}}function X(e){return e>=1e3?`${(e/1e3).toFixed(1)}s`:`${e}ms`}function Z(e){return new Date(e).toLocaleString(`sv-SE`,{timeZoneName:`short`}).slice(0,16)}function Pe(e){return{user_to_first_tool:`user → tool-start`,user_to_assistant:`user → assistant`,tool_exec:`tool-start → tool-end`,llm_between_tools:`tool-end → tool-start`,llm_final_response:`tool-end → assistant/summary`}[e.kind]??e.kind}function Fe(e){let{stats:t}=e,n=t.llmWaitMs.total+t.toolExecMs.avg*t.toolExecMs.count;if(n===0)return`Verdict: No timing data available.`;let r=Math.round(t.llmWaitMs.total/n*100);return`Verdict: LLM API wait ${r}% | Code processing ${100-r}%`}function Ie(e){let t=[],{stats:n}=e;if(t.push(`Session: ${e.sessionId}`),t.push(`Created: ${Z(e.createdAt)} | cwd: ${e.cwd}`),t.push(``),t.push(`Timing Summary:`),n.llmWaitMs.count>0&&t.push(` LLM API wait ${X(n.llmWaitMs.avg).padStart(8)} avg | ${X(n.llmWaitMs.max).padStart(8)} max`),n.toolExecMs.count>0&&t.push(` Tool execution ${X(n.toolExecMs.avg).padStart(8)} avg | ${X(n.toolExecMs.median).padStart(8)} median`),n.userToAssistantMs.count>0&&t.push(` user → assistant ${X(n.userToAssistantMs.avg).padStart(8)} avg`),n.llmWaitMs.count===0&&n.toolExecMs.count===0&&t.push(` (no intervals computed — session may have no history)`),e.slowIntervals.length>0){t.push(``),t.push(`Slow intervals (>10s):`);for(let n of e.slowIntervals)t.push(` turn ${n.turnIndex} ${Pe(n).padEnd(32)} ${X(n.durationMs).padStart(8)}`)}return t.push(``),t.push(Fe(e)),t.join(`
51
- `)}function Le(e){let t=[];return t.push(`Analyzed ${e.sessionCount} sessions (${Z(e.fromDate)} ~ ${Z(e.toDate)})`),t.push(` Avg LLM response: ${X(e.avgLlmResponseMs)}`),t.push(` Avg tool exec: ${X(e.avgToolExecMs)}`),e.maxSingleDelayMs>0&&t.push(` Max single delay: ${X(e.maxSingleDelayMs)} (${e.maxSingleDelaySession}, turn ${e.maxSingleDelayTurn}, ${e.maxSingleDelayKind})`),t.join(`
52
- `)}function Re(e){let t,n;for(let r=0;r<e.length;r++)if(e[r]===`--last`&&e[r+1]){let n=parseInt(e[r+1],10);!isNaN(n)&&n>0&&(t=n),r++}else e[r]===`--session`&&e[r+1]&&(n=e[r+1],r++);return{last:t,sessionId:n}}function ze(e){try{return de(e).filter(e=>e.endsWith(`.json`)).map(t=>V(e,t))}catch{return[]}}function Be(e){let t=new Map;for(let e of ze(C().sessions))t.set(z(e),e);for(let n of ze(h(e).sessions))t.set(z(n),n);return[...t.entries()].sort((e,t)=>e[0].localeCompare(t[0])).map(([,e])=>e)}function Ve(e){let t=e.flatMap(e=>e.intervals.filter(e=>e.kind===`user_to_first_tool`||e.kind===`user_to_assistant`||e.kind===`llm_between_tools`||e.kind===`llm_final_response`)),n=e.flatMap(e=>e.intervals.filter(e=>e.kind===`tool_exec`)),r=t.length?Math.round(t.reduce((e,t)=>e+t.durationMs,0)/t.length):0,i=n.length?Math.round(n.reduce((e,t)=>e+t.durationMs,0)/n.length):0,a=0,o=``,s=0,c=``;for(let t of e)for(let e of t.intervals)e.durationMs>a&&(a=e.durationMs,o=t.sessionId,s=e.turnIndex,c=e.kind);let l=e.map(e=>e.createdAt).sort();return{sessionCount:e.length,fromDate:l[0]??``,toDate:l[l.length-1]??``,avgLlmResponseMs:r,avgToolExecMs:i,maxSingleDelayMs:a,maxSingleDelaySession:o,maxSingleDelayTurn:s,maxSingleDelayKind:c}}async function He(e,t=process.cwd()){let n=Re(e),r=Be(t);if(r.length===0&&(process.stderr.write(`No session files found in ${h(t).sessions} or ${C().sessions}\n`),process.exit(1)),n.sessionId!==void 0){let e=r.find(e=>e.includes(n.sessionId));e||(process.stderr.write(`Session not found: ${n.sessionId}\n`),process.exit(1));let t=Y(q(e));process.stdout.write(Ie(t)+`
53
- `);return}if(n.last!==void 0){let e=r.slice(-n.last),t=[];for(let n of e)try{t.push(Y(q(n)))}catch{}t.length===0&&(process.stderr.write(`No valid sessions found.
54
- `),process.exit(1));let i=Ve(t);process.stdout.write(Le(i)+`
49
+ `}function G(e){if(e===void 0)return;let t=e.split(`,`).map(e=>e.trim()).filter(e=>e.length>0);return t.length>0?t:void 0}function Se(e){if(e!==void 0){if(!W.includes(e))throw Error(`Invalid --output-format "${e}". Valid: ${W.join(` | `)}`);return e}}function Ce(e){if(e!==void 0){if(!U.includes(e))throw Error(`Invalid --permission-mode "${e}". Valid: ${U.join(` | `)}`);return e}}function K(e){if(e===void 0)return;let t=parseInt(e,10);if(isNaN(t)||t<=0)throw Error(`Invalid --max-turns "${e}". Must be a positive integer.`);return t}const we={allowPositionals:!0,options:{help:{type:`boolean`,short:`h`,default:!1},p:{type:`boolean`,short:`p`,default:!1},continue:{type:`boolean`,short:`c`,default:!1},resume:{type:`string`,short:`r`},language:{type:`string`},"permission-mode":{type:`string`},"max-turns":{type:`string`},goal:{type:`string`},"goal-max-iterations":{type:`string`},"fork-session":{type:`boolean`,default:!1},name:{type:`string`,short:`n`},"output-format":{type:`string`},format:{type:`string`},summary:{type:`string`},source:{type:`string`},"system-prompt":{type:`string`},"append-system-prompt":{type:`string`},"task-file":{type:`string`},version:{type:`boolean`,default:!1},reset:{type:`boolean`,default:!1},bare:{type:`boolean`,default:!1},"allowed-tools":{type:`string`},"denied-tools":{type:`string`},model:{type:`string`},preset:{type:`string`},"no-session-persistence":{type:`boolean`,default:!1},"json-schema":{type:`string`},configure:{type:`boolean`,default:!1},"configure-provider":{type:`string`},provider:{type:`string`},"session-log":{type:`string`},type:{type:`string`},"base-url":{type:`string`},"api-key":{type:`string`},"api-key-env":{type:`string`},"set-current":{type:`boolean`,default:!1},"settings-scope":{type:`string`},"check-update":{type:`boolean`,default:!1},"disable-update-check":{type:`boolean`,default:!1},"dry-run":{type:`boolean`,default:!1},yes:{type:`boolean`,short:`y`,default:!1}}};function Te(e,t){return{positional:t,help:e.help??!1,printMode:e.p??!1,continueMode:e.continue??!1,resumeId:e.resume,language:e.language,permissionMode:Ce(e[`permission-mode`]),maxTurns:K(e[`max-turns`]),goal:e.goal,goalMaxIterations:K(e[`goal-max-iterations`]),forkSession:e[`fork-session`]??!1,sessionName:e.name,outputFormat:Se(e[`output-format`]),format:e.format,summary:e.summary,source:e.source,systemPrompt:e[`system-prompt`],appendSystemPrompt:e[`append-system-prompt`],taskFile:e[`task-file`],version:e.version??!1,reset:e.reset??!1,bare:e.bare??!1,allowedTools:e[`allowed-tools`],deniedTools:e[`denied-tools`],model:e.model,preset:e.preset,noSessionPersistence:e[`no-session-persistence`]??!1,jsonSchema:e[`json-schema`],configure:e.configure??!1,configureProvider:e[`configure-provider`],provider:e.provider,sessionLog:e[`session-log`],providerType:e.type,baseURL:e[`base-url`],apiKey:e[`api-key`],apiKeyEnv:e[`api-key-env`],setCurrent:e[`set-current`]??!1,settingsScope:e[`settings-scope`],checkUpdate:e[`check-update`]??!1,disableUpdateCheck:e[`disable-update-check`]??!1,dryRun:e[`dry-run`]??!1,yes:e.yes??!1}}function Ee(){let{values:e,positionals:t}=O(we),n=Te(e,t);if(n.printMode){if(n.resumeId===``)throw Error(`Print mode requires an explicit session id: -r <id|name> (the interactive session picker is TUI-only)`);if(n.noSessionPersistence&&(n.continueMode||n.resumeId!==void 0))throw Error(`--no-session-persistence conflicts with -c/-r (resume needs the session store)`)}if(n.dryRun){if(n.permissionMode!==void 0&&n.permissionMode!==`plan`)throw Error(`--dry-run is an alias for --permission-mode plan and conflicts with --permission-mode ${n.permissionMode}`);return{...n,permissionMode:`plan`}}return n}function q(e,t){return e.preset??t??`default`}function De(e){return{...e.model===void 0?{}:{model:e.model},...e.systemPrompt===void 0?{}:{systemPrompt:e.systemPrompt},...e.appendSystemPrompt===void 0?{}:{appendSystemPrompt:e.appendSystemPrompt},...e.language===void 0?{}:{language:e.language},...e.permissionMode===void 0?{}:{permissionMode:e.permissionMode}}}function Oe(e,t){return k(q(e,t),{cliOverrides:De(e)})}function J(e){if(e===void 0||e===`user`||e===`project-local`)return e;throw Error(`Invalid --settings-scope "${e}". Valid: user | project-local`)}function ke(e,t,n,r=j()){let i=w(e,J(t.settingsScope));return t.configureProvider?(o(i,je(t),{providerDefinitions:r}),n.writeLine(`Provider profile saved to ${i}`),!t.printMode&&t.positional.length===0):t.provider&&t.setCurrent?(s(t.settingsScope===void 0?C(e):i,t.provider,{knownProviders:v(e).providers}),n.writeLine(`Current provider set to ${t.provider}`),!t.printMode&&t.positional.length===0):!1}async function Ae(e,t,n,r,i=j(),a){await N(e,{provider:t.provider,settingsScope:J(t.settingsScope)},n,r,i,{formatError:Me,isInteractive:a===void 0?()=>process.stdin.isTTY===!0&&process.stdout.isTTY===!0:()=>a})}async function Y(e,t,n,r,i=j()){await F(e,{settingsScope:J(t.settingsScope)},n,r,i)}function je(e){let t=e.providerType??e.configureProvider;if(!e.configureProvider||!t)throw Error(`--configure-provider requires a provider profile and --type`);return{profile:e.configureProvider,type:t,...e.model!==void 0&&{model:e.model},...e.apiKey!==void 0&&{apiKey:e.apiKey},...e.apiKeyEnv!==void 0&&{apiKeyEnv:e.apiKeyEnv},...e.baseURL!==void 0&&{baseURL:e.baseURL},setCurrent:e.setCurrent}}function Me(e=j()){return[`No provider configuration found.`,"Run `robota --configure` in an interactive terminal, or configure a provider:",`Supported providers: ${A(e)}`,...e.map(Ne)].join(`
50
+ `)}function Ne(e){return` ${[`robota --configure-provider ${e.type}`,`--type ${e.type}`,...e.defaults?.baseURL===void 0?[]:[`--base-url <url>`],`--model <model>`,...e.requiresApiKey===!0?[`--api-key-env <ENV_NAME>`]:[],`--set-current`].join(` `)}`}let X=null,Z=!1;function Pe(){return Z}const Fe=[`string-width`,`setCursorPosition`,`getStringWidth`,`slice`,`charCodeAt`];function Ie(e,t){if(!t)return`rethrow`;let n=e.message??``;return Fe.some(e=>n.includes(e))?`ime-hint`:`guard-owned`}function Le(e){X=e}function Re(e,t){try{if(X){X.getSession().reportBackgroundError(e,t);return}}catch{}process.stderr.write(`\n[robota] ${t}: ${e.message}\n`)}function ze(){Z||(Z=!0,process.on(`unhandledRejection`,e=>{Re(e instanceof Error?e:Error(String(e)),`unhandled rejection`)}),process.on(`uncaughtException`,e=>{Re(e instanceof Error?e:Error(String(e)),`uncaught exception`)}))}async function Be(e,t,n){if(e.positional[0]!==`user-local`)return!1;let r=await P({cwd:t,argv:e.positional.slice(1),format:e.format,summary:e.summary,source:e.source}),i=r.message.trimEnd();if(!r.success)throw Error(i);return n.writeLine(i),!0}function Ve(e){let t,n,r=!1;for(let i=0;i<e.length;i++)if(e[i]===`--last`&&e[i+1]){let n=parseInt(e[i+1],10);!isNaN(n)&&n>0&&(t=n),i++}else e[i]===`--session`&&e[i+1]?(n=e[i+1],i++):e[i]===`--usage`&&(r=!0);return{last:t,sessionId:n,usage:r}}function He(e){let t=new Map;for(let e of d().list())t.set(e.id,e);for(let n of l(e).list())t.set(n.id,n);return[...t.values()].sort((e,t)=>e.id.localeCompare(t.id))}async function Ue(e,t=process.cwd()){let n=Ve(e),r=He(t);if(r.length===0&&(process.stderr.write(`No session files found in ${_(t).sessions} or ${E().sessions}\n`),process.exit(1)),n.usage){let e=n.sessionId===void 0?r[r.length-1]:r.find(e=>e.id.includes(n.sessionId));e||(process.stderr.write(`Session not found${n.sessionId?`: ${n.sessionId}`:``}\n`),process.exit(1)),process.stdout.write(he(ge(e))+`
51
+ `);return}if(n.sessionId!==void 0){let e=r.find(e=>e.id.includes(n.sessionId));e||(process.stderr.write(`Session not found: ${n.sessionId}\n`),process.exit(1)),process.stdout.write(L(I(e))+`
52
+ `);return}if(n.last!==void 0){let e=r.slice(-n.last).map(e=>I(e));e.length===0&&(process.stderr.write(`No valid sessions found.
53
+ `),process.exit(1)),process.stdout.write(me(pe(e))+`
55
54
  `);return}let i=r[r.length-1];i||(process.stderr.write(`No sessions found.
56
- `),process.exit(1));let a=Y(q(i));process.stdout.write(Ie(a)+`
57
- `)}const Ue=()=>_(import.meta.url);async function We(e){let t=pe({input:process.stdin,output:process.stdout});try{let n=(await t.question(e)).trim().toLowerCase();return n===`y`||n===`yes`}finally{t.close()}}async function Ge(e,t){let n=m();if(!F(n))return e.writeLine(`No user settings found.`),0;if(!t.yes){if(!t.isTTY)return e.writeError(`--reset deletes ${n}. Refusing without confirmation in non-interactive mode — pass --yes to proceed.`),1;if(!await(t.confirm??We)(`Delete ${n}? [y/N] `))return e.writeLine(`Reset cancelled.`),1}let r=y();return r.deleted?e.writeLine(`Deleted ${r.path}`):e.writeLine(`No user settings found.`),0}const Ke={anthropic:{host:`api.anthropic.com`,port:443},openai:{host:`api.openai.com`,port:443},gemini:{host:`generativelanguage.googleapis.com`,port:443},deepseek:{host:`api.deepseek.com`,port:443},qwen:{host:`dashscope.aliyuncs.com`,port:443}};function qe(){let[e]=process.versions.node.split(`.`).map(Number);return e!==void 0&&e>=22?{label:`Node.js version`,status:`ok`,message:`v${process.versions.node}`}:{label:`Node.js version`,status:`fail`,message:`v${process.versions.node} (requires >=22)\n nvm: nvm install 22 && nvm use 22\n Volta: volta install node@22`}}function Je(e){return{label:`robota version`,status:`ok`,message:e}}function Ye(e,t,n){try{let r=ee(e,{providerDefinitions:t,env:n}),i=r.source===`env-default`?`env-default via ${r.sourceEnvVar??`environment`}`:`settings profile`,a=r.model===void 0?``:` (${r.model})`;return{label:`API key`,status:`ok`,message:`${r.name}${a} — ${i}`}}catch(e){return{label:`API key`,status:`fail`,message:`${e instanceof Error?e.message:String(e)}\n Set ANTHROPIC_API_KEY or run: robota --configure\n Get key: https://console.anthropic.com/settings/keys`}}}function Xe(e){try{return JSON.parse(L(e,`utf-8`)),`ok`}catch{return`corrupt`}}function Ze(e){let t=f(e).filter(e=>F(e));return t.length===0?[{label:`Settings file`,status:`warn`,message:`Not found — run: robota --configure`}]:t.map(e=>Xe(e)===`corrupt`?{label:`Settings file`,status:`fail`,message:`${e} — invalid JSON\n Fix or delete the file, or run: robota --configure`}:{label:`Settings file`,status:`ok`,message:e})}function Qe(e){try{let t=JSON.parse(L(e,`utf-8`));return typeof t.currentProvider==`string`?t.currentProvider:void 0}catch{return}}function $e(e){let t=V(e,`.robota`,`settings.json`),n=V(process.env.HOME??``,`.robota`,`settings.json`),r=F(t)?t:F(n)?n:void 0;if(r!==void 0){let e=(Qe(r)??``).toLowerCase(),t=Object.entries(Ke).find(([t])=>e.startsWith(t));if(t)return t[1]}return Ke.anthropic}function et(){let e=process.env.TERM_PROGRAM??`unknown`;return process.platform===`darwin`&&e===`Apple_Terminal`?{label:`Terminal`,status:`warn`,message:`macOS Terminal.app — CJK/IME input may be unstable
58
- Recommendation: use iTerm2 (https://iterm2.com)`}:{label:`Terminal`,status:`ok`,message:e}}function tt(e){let t=`Network (${e.host})`;return new Promise(n=>{let r=Date.now(),i=me({host:e.host,port:e.port}),a=setTimeout(()=>{i.destroy(),n({label:t,status:`fail`,message:`timeout (3s)`})},3e3);i.on(`connect`,()=>{clearTimeout(a),i.destroy(),n({label:t,status:`ok`,message:`reachable (${Date.now()-r}ms)`})}),i.on(`error`,e=>{clearTimeout(a),n({label:t,status:`warn`,message:`${e.message}\n Check proxy settings or firewall`})})})}async function nt(e,t={checkNetwork:tt}){e.terminal.writeLine(`
55
+ `),process.exit(1)),process.stdout.write(L(I(i))+`
56
+ `)}const We=()=>y(import.meta.url);async function Ge(e){let t=_e({input:process.stdin,output:process.stdout});try{let n=(await t.question(e)).trim().toLowerCase();return n===`y`||n===`yes`}finally{t.close()}}async function Ke(e,t){let n=g();if(!R(n))return e.writeLine(`No user settings found.`),0;if(!t.yes){if(!t.isTTY)return e.writeError(`--reset deletes ${n}. Refusing without confirmation in non-interactive mode — pass --yes to proceed.`),1;if(!await(t.confirm??Ge)(`Delete ${n}? [y/N] `))return e.writeLine(`Reset cancelled.`),1}let r=S();return r.deleted?e.writeLine(`Deleted ${r.path}`):e.writeLine(`No user settings found.`),0}const qe={anthropic:{host:`api.anthropic.com`,port:443},openai:{host:`api.openai.com`,port:443},gemini:{host:`generativelanguage.googleapis.com`,port:443},deepseek:{host:`api.deepseek.com`,port:443},qwen:{host:`dashscope.aliyuncs.com`,port:443}};function Je(){let[e]=process.versions.node.split(`.`).map(Number);return e!==void 0&&e>=22?{label:`Node.js version`,status:`ok`,message:`v${process.versions.node}`}:{label:`Node.js version`,status:`fail`,message:`v${process.versions.node} (requires >=22)\n nvm: nvm install 22 && nvm use 22\n Volta: volta install node@22`}}function Ye(e){return{label:`robota version`,status:`ok`,message:e}}function Xe(e,t,n){try{let r=b(e,{providerDefinitions:t,env:n}),i=r.source===`env-default`?`env-default via ${r.sourceEnvVar??`environment`}`:`settings profile`,a=r.model===void 0?``:` (${r.model})`;return{label:`API key`,status:`ok`,message:`${r.name}${a} — ${i}`}}catch(e){return{label:`API key`,status:`fail`,message:`${e instanceof Error?e.message:String(e)}\n Set ANTHROPIC_API_KEY or run: robota --configure\n Get key: https://console.anthropic.com/settings/keys`}}}function Ze(e){try{return JSON.parse(B(e,`utf-8`)),`ok`}catch{return`corrupt`}}function Qe(e){let t=m(e).filter(e=>R(e));return t.length===0?[{label:`Settings file`,status:`warn`,message:`Not found — run: robota --configure`}]:t.map(e=>Ze(e)===`corrupt`?{label:`Settings file`,status:`fail`,message:`${e} — invalid JSON\n Fix or delete the file, or run: robota --configure`}:{label:`Settings file`,status:`ok`,message:e})}function $e(e){try{let t=JSON.parse(B(e,`utf-8`));return typeof t.currentProvider==`string`?t.currentProvider:void 0}catch{return}}function et(e){let t=H(e,`.robota`,`settings.json`),n=H(process.env.HOME??``,`.robota`,`settings.json`),r=R(t)?t:R(n)?n:void 0;if(r!==void 0){let e=($e(r)??``).toLowerCase(),t=Object.entries(qe).find(([t])=>e.startsWith(t));if(t)return t[1]}return qe.anthropic}function tt(){let e=process.env.TERM_PROGRAM??`unknown`;return process.platform===`darwin`&&e===`Apple_Terminal`?{label:`Terminal`,status:`warn`,message:`macOS Terminal.app — CJK/IME input may be unstable
57
+ Recommendation: use iTerm2 (https://iterm2.com)`}:{label:`Terminal`,status:`ok`,message:e}}function nt(e){let t=`Network (${e.host})`;return new Promise(n=>{let r=Date.now(),i=ve({host:e.host,port:e.port}),a=setTimeout(()=>{i.destroy(),n({label:t,status:`fail`,message:`timeout (3s)`})},3e3);i.on(`connect`,()=>{clearTimeout(a),i.destroy(),n({label:t,status:`ok`,message:`reachable (${Date.now()-r}ms)`})}),i.on(`error`,e=>{clearTimeout(a),n({label:t,status:`warn`,message:`${e.message}\n Check proxy settings or firewall`})})})}async function rt(e,t={checkNetwork:nt}){e.terminal.writeLine(`
59
58
  robota diagnose
60
- `);let n=$e(e.cwd),r=t.providerDefinitions??k(),i=t.env??process.env,a=[qe(),Je(e.version),Ye(e.cwd,r,i),...Ze(e.cwd),et(),await t.checkNetwork(n)],o=0,s=0;for(let t of a){let n=t.status===`ok`?`✓`:t.status===`warn`?`⚠`:`✗`,r=t.message.split(`
61
- `);e.terminal.writeLine(` ${n} ${t.label}: ${r[0]}`);for(let t of r.slice(1))e.terminal.writeLine(` ${t}`);t.status===`fail`&&o++,t.status===`warn`&&s++}return e.terminal.writeLine(``),o===0&&s===0?e.terminal.writeLine(`✓ All checks passed. robota is ready to use.`):o>0?e.terminal.writeLine(`✗ ${o} issue(s) found. Fix the items above to use robota.`):e.terminal.writeLine(`⚠ ${s} warning(s). robota may work but check the items above.`),e.terminal.writeLine(``),o}const Q=`robota`,rt={permissions:{allow:[`Read(.robota/**)`,`Read(.claude/**)`,`Read(.agents/**)`],deny:[]}};function it(e){let t=V(e,`settings.json`);if(!F(t))return{};let n=L(t,`utf8`);try{return JSON.parse(n)}catch{return null}}var at=class extends Error{constructor(e){super(`Cannot ask "${e}" in a non-interactive shell. Re-run with --yes to accept the defaults.`),this.name=`InitPromptUnavailableError`}};async function $(e,t,n){if(n.yes||n.ci)return n.terminal.writeLine(`${e} → ${t?`Y`:`N`} (${n.yes?`--yes`:`CI`}: using default)`),t;if(!n.isTTY)throw new at(e);let r=await n.promptFn(`${e} [y/N] `);return r.toLowerCase()===`y`||r.toLowerCase()===`yes`}async function ot(e,t,n={}){t.writeLine(``),t.writeLine(`${Q} project initialization`),t.writeLine(`─`.repeat(40));let i={yes:n.yes===!0,ci:n.ci??process.env.CI===`true`,isTTY:n.isTTY??process.stdin.isTTY===!0,promptFn:n.promptFn??r,terminal:t},a=h(e).settings,o=B(a),s=V(e,`AGENTS.md`),c=V(e,`.claude`),l=F(c),u=F(a),d=F(s);if(u&&d&&(t.writeLine(``),t.writeLine(`Both AGENTS.md and .robota/settings.json already exist.`),!await $(`Overwrite existing files?`,!1,i))){t.writeLine(`Init cancelled.`);return}let f={...rt};if(l&&(t.writeLine(``),t.writeLine(`Detected .claude/ directory (Claude Code configuration).`),await $(`Migrate Claude Code settings to .robota/?`,!1,i))){let e=it(c);if(e===null)t.writeLine(`Warning: .claude/settings.json could not be parsed — skipping migration.`);else{let n=e.permissions;f={...e,permissions:{...typeof e.permissions==`object`&&e.permissions!==null?e.permissions:{},allow:[...rt.permissions.allow,...n?.allow??[]],deny:n?.deny??[]}},t.writeLine(`Settings imported from .claude/settings.json.`)}}I(o,{recursive:!0}),R(a,JSON.stringify(f,null,2)+`
62
- `,`utf8`),t.writeLine(``),t.writeLine(`Created: .robota/settings.json`),R(s,`# AGENTS.md — Project Agent Guidelines
59
+ `);let n=et(e.cwd),r=t.providerDefinitions??j(),i=t.env??process.env,a=[Je(),Ye(e.version),Xe(e.cwd,r,i),...Qe(e.cwd),tt(),await t.checkNetwork(n)],o=0,s=0;for(let t of a){let n=t.status===`ok`?`✓`:t.status===`warn`?`⚠`:`✗`,r=t.message.split(`
60
+ `);e.terminal.writeLine(` ${n} ${t.label}: ${r[0]}`);for(let t of r.slice(1))e.terminal.writeLine(` ${t}`);t.status===`fail`&&o++,t.status===`warn`&&s++}return e.terminal.writeLine(``),o===0&&s===0?e.terminal.writeLine(`✓ All checks passed. robota is ready to use.`):o>0?e.terminal.writeLine(`✗ ${o} issue(s) found. Fix the items above to use robota.`):e.terminal.writeLine(`⚠ ${s} warning(s). robota may work but check the items above.`),e.terminal.writeLine(``),o}const Q=`robota`,it={permissions:{allow:[`Read(.robota/**)`,`Read(.claude/**)`,`Read(.agents/**)`],deny:[]}};function at(e){let t=H(e,`settings.json`);if(!R(t))return{};let n=B(t,`utf8`);try{return JSON.parse(n)}catch{return null}}var ot=class extends Error{constructor(e){super(`Cannot ask "${e}" in a non-interactive shell. Re-run with --yes to accept the defaults.`),this.name=`InitPromptUnavailableError`}};async function $(e,t,n){if(n.yes||n.ci)return n.terminal.writeLine(`${e} → ${t?`Y`:`N`} (${n.yes?`--yes`:`CI`}: using default)`),t;if(!n.isTTY)throw new ot(e);let r=await n.promptFn(`${e} [y/N] `);return r.toLowerCase()===`y`||r.toLowerCase()===`yes`}async function st(e,t,n={}){t.writeLine(``),t.writeLine(`${Q} project initialization`),t.writeLine(`─`.repeat(40));let r={yes:n.yes===!0,ci:n.ci??process.env.CI===`true`,isTTY:n.isTTY??process.stdin.isTTY===!0,promptFn:n.promptFn??i,terminal:t},a=_(e).settings,o=ye(a),s=H(e,`AGENTS.md`),c=H(e,`.claude`),l=R(c),u=R(a),d=R(s);if(u&&d&&(t.writeLine(``),t.writeLine(`Both AGENTS.md and .robota/settings.json already exist.`),!await $(`Overwrite existing files?`,!1,r))){t.writeLine(`Init cancelled.`);return}let f={...it};if(l&&(t.writeLine(``),t.writeLine(`Detected .claude/ directory (Claude Code configuration).`),await $(`Migrate Claude Code settings to .robota/?`,!1,r))){let e=at(c);if(e===null)t.writeLine(`Warning: .claude/settings.json could not be parsed — skipping migration.`);else{let n=e.permissions;f={...e,permissions:{...typeof e.permissions==`object`&&e.permissions!==null?e.permissions:{},allow:[...it.permissions.allow,...n?.allow??[]],deny:n?.deny??[]}},t.writeLine(`Settings imported from .claude/settings.json.`)}}z(o,{recursive:!0}),V(a,JSON.stringify(f,null,2)+`
61
+ `,`utf8`),t.writeLine(``),t.writeLine(`Created: .robota/settings.json`),V(s,`# AGENTS.md — Project Agent Guidelines
63
62
 
64
63
  This file guides the AI agent working in this project. Customize it for your project.
65
64
 
@@ -89,7 +88,7 @@ npm run build
89
88
  ## Important Notes
90
89
 
91
90
  <!-- Anything the agent should know before making changes -->
92
- `,`utf8`),t.writeLine(`Created: AGENTS.md`),t.writeLine(``),t.writeLine(`Initialization complete.`),t.writeLine(``),t.writeLine(`Next steps:`),t.writeLine(` 1. Edit AGENTS.md to describe your project conventions`),t.writeLine(` 2. Run \`${Q} --configure\` to set up your AI provider`),t.writeLine(` 3. Run \`${Q}\` to start the assistant`),t.writeLine(``),n.onProviderSetup!==void 0&&(i.isTTY||i.yes||i.ci)&&await $(`Would you like to set up a provider now?`,!1,i)&&await n.onProviderSetup()}function st(e=C().onboarded){return!F(e)}function ct(e=C().onboarded){I(B(e),{recursive:!0}),R(e,new Date().toISOString())}const lt=`
91
+ `,`utf8`),t.writeLine(`Created: AGENTS.md`),t.writeLine(``),t.writeLine(`Initialization complete.`),t.writeLine(``),t.writeLine(`Next steps:`),t.writeLine(` 1. Edit AGENTS.md to describe your project conventions`),t.writeLine(` 2. Run \`${Q} --configure\` to set up your AI provider`),t.writeLine(` 3. Run \`${Q}\` to start the assistant`),t.writeLine(``),n.onProviderSetup!==void 0&&(r.isTTY||r.yes||r.ci)&&await $(`Would you like to set up a provider now?`,!1,r)&&await n.onProviderSetup()}function ct(e=E().onboarded){return!R(e)}function lt(e=E().onboarded){z(ye(e),{recursive:!0}),V(e,new Date().toISOString())}const ut=`
93
92
  ╭─────────────────────────────────────────────────────────────╮
94
93
  │ Welcome to ${Q}! — AI coding assistant │
95
94
  │ │
@@ -106,18 +105,18 @@ npm run build
106
105
  │ │
107
106
  │ ${Q} diagnose — check your setup │
108
107
  ╰─────────────────────────────────────────────────────────────╯
109
- `;function ut(e){e.writeLine(lt)}function dt(e){process.platform===`darwin`&&process.env.TERM_PROGRAM===`Apple_Terminal`&&e.writeError(`
108
+ `;function dt(e){e.writeLine(ut)}function ft(e){process.platform===`darwin`&&process.env.TERM_PROGRAM===`Apple_Terminal`&&e.writeError(`
110
109
  ⚠ macOS Terminal.app detected: CJK/IME input may be unstable.
111
110
  Recommended: use iTerm2 (https://iterm2.com) for Korean/Japanese/Chinese input.
112
111
  Or use headless mode: robota -p "your prompt"
113
- `)}function ft(e,t,n,r,i={}){let a={settings:{read:()=>v(m()),write:e=>w(m(),e)},plugin:j(e)},o=n.providerDefinitions??k();return{commandHostAdapters:a,providerDefinitions:o,commandModules:[...A({cwd:e,providerDefinitions:o,providerSettingsAdapter:{readMergedSettings:()=>g(e),readTargetSettings:()=>v(b(e)),writeTargetSettings:t=>w(b(e),t)},...i.enabledCommandModules===void 0?{}:{enabledCommandModules:i.enabledCommandModules},...i.disabledCommandModules===void 0?{}:{disabledCommandModules:i.disabledCommandModules}}),...n.commandModules??[]],startupUpdateNoticePromise:S(t)?p({currentVersion:r}):void 0}}function pt(e,t){let n=L(fe(e,t),`utf8`).trim();if(n.length===0)throw Error(`Task file is empty: ${t}`);return`Task file (${t}):\n${n}`}function mt(e,t){let n=[];if(t.appendSystemPrompt&&n.push(t.appendSystemPrompt),t.taskFile)try{n.push(pt(e,t.taskFile))}catch(e){process.stderr.write(`${e instanceof Error?e.message:String(e)}\n`),process.exit(1)}return t.jsonSchema&&n.push(`Respond with valid JSON only, matching this JSON schema:\n${t.jsonSchema}`),n.length>0?n.join(`
112
+ `)}function pt(){try{return e(import.meta.url)(`@robota-sdk/agent-command-workflows`).createWorkflowsCommandModule()}catch{return}}function mt(e,t,n,r,i={}){let a={settings:{read:()=>x(g()),write:e=>D(g(),e)},plugin:M(e)},o=n.providerDefinitions??j(),s={readMergedSettings:()=>v(e),readTargetSettings:()=>x(C(e)),writeTargetSettings:t=>D(C(e),t)},c=pt();return{commandHostAdapters:a,providerDefinitions:o,commandModules:[...ie({cwd:e,providerDefinitions:o,providerSettingsAdapter:s,...i.enabledCommandModules===void 0?{}:{enabledCommandModules:i.enabledCommandModules},...i.disabledCommandModules===void 0?{}:{disabledCommandModules:i.disabledCommandModules}}),...c?[c]:[],...n.commandModules??[]],startupUpdateNoticePromise:T(t)?h({currentVersion:r}):void 0}}function ht(e,t){let n=B(be(e,t),`utf8`).trim();if(n.length===0)throw Error(`Task file is empty: ${t}`);return`Task file (${t}):\n${n}`}function gt(e,t){let n=[];if(t.appendSystemPrompt&&n.push(t.appendSystemPrompt),t.taskFile)try{n.push(ht(e,t.taskFile))}catch(e){process.stderr.write(`${e instanceof Error?e.message:String(e)}\n`),process.exit(1)}return t.jsonSchema&&n.push(`Respond with valid JSON only, matching this JSON schema:\n${t.jsonSchema}`),n.length>0?n.join(`
114
113
 
115
- `):void 0}async function ht(e,n,r,i,a,o,s,c,l={},u={}){let d=n.positional.join(` `).trim();if(!d&&!process.stdin.isTTY){let e=[];for await(let t of process.stdin)e.push(t);d=Buffer.concat(e).toString(`utf-8`).trim()}d||(process.stderr.write(`Print mode (-p) requires a prompt argument.
116
- `),process.exit(1));let f=mt(e,n),p=new t({cwd:e,provider:r,outputFormat:n.outputFormat??`text`,permissionMode:n.permissionMode??u.permissionMode??`bypassPermissions`,maxTurns:n.maxTurns,sessionStore:n.noSessionPersistence?void 0:i,resumeSessionId:l.resumeSessionId,forkSession:l.forkSession,sessionName:n.sessionName,bare:n.bare||void 0,allowedTools:W(n.allowedTools),deniedTools:W(n.deniedTools),appendSystemPrompt:f,...u.persona===void 0?{}:{persona:u.persona},...u.agentName===void 0?{}:{agentName:u.agentName},...u.activePresetId===void 0?{}:{activePresetId:u.activePresetId},...u.enableParallelSubagents===void 0?{}:{enableParallelSubagents:u.enableParallelSubagents},...u.selfVerification===void 0?{}:{selfVerification:u.selfVerification},...n.systemPrompt?{systemPrompt:n.systemPrompt}:{},backgroundTaskRunners:a,subagentRunnerFactory:o,commandModules:s,commandHostAdapters:c});await p.run(d),process.exit(p.getExitCode())}async function gt(t={}){if(process.argv[2]===`session`&&process.argv[3]===`analyze`){await He(process.argv.slice(4),process.cwd());return}let a;try{a=xe()}catch(e){process.stderr.write(`${e instanceof Error?e.message:String(e)}\n`),process.exit(1)}let o=Ue();if(a.help){process.stdout.write(he());return}if(a.version){process.stdout.write(`robota ${o}\n`);return}if(a.checkUpdate){let e=await s({currentVersion:o,force:!0}),t=u(e);e.status===`error`&&(process.stderr.write(`${t}\n`),process.exit(1)),process.stdout.write(`${t}\n`);return}let f=process.cwd(),p=new n;if(a.reset){process.exitCode=await Ge(p,{yes:a.yes,isTTY:process.stdin.isTTY===!0});return}if(a.positional[0]===`diagnose`){let e=await nt({version:o,terminal:p,cwd:f});process.exitCode=+(e>0);return}if(a.positional[0]===`session`&&a.positional[1]===`analyze`){await He(process.argv.slice(4),f);return}try{if(await Ae(a,f,p))return}catch(e){p.writeError(e instanceof Error?e.message:String(e)),process.exit(1)}let g=v(m()),_=typeof g.preset==`string`?g.preset:void 0,y=re();for(let{file:e,error:t}of y.errors)p.writeError(`Skipped external preset "${e}": ${t}`);let b;try{b=Ce(a,_)}catch(e){process.stderr.write(`${e instanceof Error?e.message:String(e)}\n`),process.exit(1)}let x=G(a,_),{commandHostAdapters:S,providerDefinitions:C,commandModules:w,startupUpdateNoticePromise:T}=ft(f,a,t,o,{...b.enabledCommandModules===void 0?{}:{enabledCommandModules:b.enabledCommandModules},...b.disabledCommandModules===void 0?{}:{disabledCommandModules:b.disabledCommandModules}});if(a.positional[0]===`init`){try{await ot(f,p,{yes:a.yes,onProviderSetup:async()=>{await Ee(f,a,r,p,C)}})}catch(e){p.writeError(e instanceof Error?e.message:String(e)),process.exit(1)}return}if(a.configure){await Ee(f,a,r,p,C);return}if(we(f,a,p,C))return;try{await Te(f,a,r,p,C)}catch(e){process.stderr.write(`${e instanceof Error?e.message:String(e)}\n`),process.exit(e instanceof i&&a.printMode?3:1)}let D=a.provider?{providerOverride:a.provider,providerDefinitions:C}:{providerDefinitions:C},O=ee(f,D),k=b.model??O.model;if(O.source===`env-default`&&O.sourceEnvVar!==void 0){let e=`Using ${O.name} (${k}) via ${O.sourceEnvVar} — run \`robota --configure\` to persist a profile.\n`;a.printMode?process.stderr.write(e):p.writeLine(e.trimEnd())}let A=l(f,b.model,D),j=ce(),M=h(f),N=le({workerPath:ue(),providerConfig:{...O,model:k},logsDir:M.logs}),P=c(f),F,I=!1;if(a.continueMode?F=te(P,f):a.resumeId!==void 0&&(a.resumeId===``?I=!0:(F=ne(P,a.resumeId),F===void 0&&(process.stderr.write(`Session not found: ${a.resumeId}\n`),process.exit(1)))),a.printMode){await ht(f,a,A,P,j,N,w,S,{resumeSessionId:F,forkSession:a.forkSession},{agentName:b.agentName??E,activePresetId:x,persona:b.persona,...b.permissionMode===void 0?{}:{permissionMode:b.permissionMode},...b.enableParallelSubagents===void 0?{}:{enableParallelSubagents:b.enableParallelSubagents},...b.selfVerification===void 0?{}:{selfVerification:b.selfVerification}});return}dt(p),st()&&(ut(p),ct()),await oe({cwd:f,provider:A,providerOverride:a.provider,providerType:O.name,modelId:k,language:a.language,permissionMode:a.permissionMode??b.permissionMode,maxTurns:a.maxTurns,allowedTools:W(a.allowedTools),deniedTools:W(a.deniedTools),version:o,sessionStore:a.noSessionPersistence?void 0:P,resumeSessionId:F,showSessionPickerOnStart:I,forkSession:a.forkSession,sessionName:a.sessionName,backgroundTaskRunners:j,subagentRunnerFactory:N,commandModules:w,commandHostAdapters:S,shellExec:t=>e(t,{timeout:5e3,encoding:`utf-8`,stdio:`pipe`}).trimEnd(),startupUpdateNotice:T?T.then(e=>e?d(e):void 0):void 0,transportRegistry:se(),cliAdapter:ae({providerDefinitions:C,reloadPluginCommandSource:ie}),reloadPluginCommandSource:ie,agentName:b.agentName??E,activePresetId:x,persona:b.persona,...b.enableParallelSubagents===void 0?{}:{enableParallelSubagents:b.enableParallelSubagents},...b.selfVerification===void 0?{}:{selfVerification:b.selfVerification}}),process.exit(0)}process.on(`uncaughtException`,e=>{let t=e.message??``;if(t.includes(`string-width`)||t.includes(`setCursorPosition`)||t.includes(`getStringWidth`)||t.includes(`slice`)||t.includes(`charCodeAt`)){process.stderr.write(`
114
+ `):void 0}async function _t(e,t,r,i,a,o,s,c,l={},u={}){let d=t.goal?.trim(),f=t.positional.join(` `).trim();if(!d&&!f&&!process.stdin.isTTY){let e=[];for await(let t of process.stdin)e.push(t);f=Buffer.concat(e).toString(`utf-8`).trim()}!d&&!f&&(process.stderr.write(`Print mode (-p) requires a prompt argument (or --goal <objective>).
115
+ `),process.exit(1));let p=gt(e,t),m=new n({cwd:e,provider:r,outputFormat:t.outputFormat??`text`,permissionMode:t.permissionMode??u.permissionMode??`bypassPermissions`,maxTurns:t.maxTurns,sessionStore:t.noSessionPersistence?void 0:i,resumeSessionId:l.resumeSessionId,forkSession:l.forkSession,sessionName:t.sessionName,bare:t.bare||void 0,allowedTools:G(t.allowedTools),deniedTools:G(t.deniedTools),appendSystemPrompt:p,...u.persona===void 0?{}:{persona:u.persona},...u.agentName===void 0?{}:{agentName:u.agentName},...u.activePresetId===void 0?{}:{activePresetId:u.activePresetId},...u.enableParallelSubagents===void 0?{}:{enableParallelSubagents:u.enableParallelSubagents},...u.selfVerification===void 0?{}:{selfVerification:u.selfVerification},...t.systemPrompt?{systemPrompt:t.systemPrompt}:{},backgroundTaskRunners:a,subagentRunnerFactory:o,commandModules:s,commandHostAdapters:c});d?await m.runGoal(d,t.goalMaxIterations?{maxIterations:t.goalMaxIterations}:{}):await m.run(f),process.exit(m.getExitCode())}function vt(t){let n;try{n=e(import.meta.url)(`@robota-sdk/agent-provider-replay`)}catch{throw Error(`--session-log replay requires @robota-sdk/agent-provider-replay, a dev-only package that is not bundled in the published CLI.`)}return n.createReplayProviderFromLogFile(t)}function yt(){let e=new ce(g());return e.register(new le),e}async function bt(e={}){if(process.argv[2]===`session`&&process.argv[3]===`analyze`){await Ue(process.argv.slice(4),process.cwd());return}let n;try{n=Ee()}catch(e){process.stderr.write(`${e instanceof Error?e.message:String(e)}\n`),process.exit(1)}let o=We();if(n.help){process.stdout.write(xe());return}if(n.version){process.stdout.write(`robota ${o}\n`);return}if(n.checkUpdate){let e=await c({currentVersion:o,force:!0}),t=f(e);e.status===`error`&&(process.stderr.write(`${t}\n`),process.exit(1)),process.stdout.write(`${t}\n`);return}let s=process.cwd(),d=new r;if(n.reset){process.exitCode=await Ke(d,{yes:n.yes,isTTY:process.stdin.isTTY===!0});return}if(n.positional[0]===`diagnose`){let e=await rt({version:o,terminal:d,cwd:s});process.exitCode=+(e>0);return}if(n.positional[0]===`session`&&n.positional[1]===`analyze`){await Ue(process.argv.slice(4),s);return}try{if(await Be(n,s,d))return}catch(e){d.writeError(e instanceof Error?e.message:String(e)),process.exit(1)}let m=x(g()),h=typeof m.preset==`string`?m.preset:void 0,v=re();for(let{file:e,error:t}of v.errors)d.writeError(`Skipped external preset "${e}": ${t}`);let y;try{y=Oe(n,h)}catch(e){process.stderr.write(`${e instanceof Error?e.message:String(e)}\n`),process.exit(1)}let S=q(n,h),{commandHostAdapters:C,providerDefinitions:w,commandModules:T,startupUpdateNoticePromise:E}=mt(s,n,e,o,{...y.enabledCommandModules===void 0?{}:{enabledCommandModules:y.enabledCommandModules},...y.disabledCommandModules===void 0?{}:{disabledCommandModules:y.disabledCommandModules}});if(n.positional[0]===`init`){try{await st(s,d,{yes:n.yes,onProviderSetup:async()=>{await Y(s,n,i,d,w)}})}catch(e){d.writeError(e instanceof Error?e.message:String(e)),process.exit(1)}return}if(n.configure){await Y(s,n,i,d,w);return}if(ke(s,n,d,w))return;try{await Ae(s,n,i,d,w)}catch(e){process.stderr.write(`${e instanceof Error?e.message:String(e)}\n`),process.exit(e instanceof a&&n.printMode?3:1)}let D=n.provider?{providerOverride:n.provider,providerDefinitions:w}:{providerDefinitions:w},O=b(s,D),k=y.model??O.model;if(O.source===`env-default`&&O.sourceEnvVar!==void 0){let e=`Using ${O.name} (${k}) via ${O.sourceEnvVar} — run \`robota --configure\` to persist a profile.\n`;n.printMode?process.stderr.write(e):d.writeLine(e.trimEnd())}let A=n.sessionLog?vt(n.sessionLog):u(s,y.model,D),j=ue(),ie=_(s),M=de({workerPath:fe(),providerConfig:{...O,model:k},logsDir:ie.logs}),N=l(s),P,F=!1;if(n.continueMode?P=ee(N,s):n.resumeId!==void 0&&(n.resumeId===``?F=!0:(P=te(N,n.resumeId),P===void 0&&(process.stderr.write(`Session not found: ${n.resumeId}\n`),process.exit(1)))),n.printMode||n.goal){await _t(s,n,A,N,j,M,T,C,{resumeSessionId:P,forkSession:n.forkSession},{agentName:y.agentName??ne,activePresetId:S,persona:y.persona,...y.permissionMode===void 0?{}:{permissionMode:y.permissionMode},...y.enableParallelSubagents===void 0?{}:{enableParallelSubagents:y.enableParallelSubagents},...y.selfVerification===void 0?{}:{selfVerification:y.selfVerification}});return}ft(d),ze(),ct()&&(dt(d),lt()),await se({onChannelReady:e=>Le(e),cwd:s,provider:A,providerOverride:n.provider,providerType:O.name,modelId:k,language:n.language,permissionMode:n.permissionMode??y.permissionMode,maxTurns:n.maxTurns,allowedTools:G(n.allowedTools),deniedTools:G(n.deniedTools),version:o,sessionStore:n.noSessionPersistence?void 0:N,resumeSessionId:P,showSessionPickerOnStart:F,forkSession:n.forkSession,sessionName:n.sessionName,backgroundTaskRunners:j,subagentRunnerFactory:M,commandModules:T,commandHostAdapters:C,shellExec:e=>t(e,{timeout:5e3,encoding:`utf-8`,stdio:`pipe`}).trimEnd(),startupUpdateNotice:E?E.then(e=>e?p(e):void 0):void 0,transportRegistry:yt(),cliAdapter:oe({providerDefinitions:w,reloadPluginCommandSource:ae}),reloadPluginCommandSource:ae,agentName:y.agentName??ne,activePresetId:S,persona:y.persona,...y.enableParallelSubagents===void 0?{}:{enableParallelSubagents:y.enableParallelSubagents},...y.selfVerification===void 0?{}:{selfVerification:y.selfVerification}}),process.exit(0)}process.on(`uncaughtException`,e=>{let t=Ie(e,Pe());if(t===`ime-hint`){process.stderr.write(`
117
116
  [robota] CJK/IME input error — this is a known issue with macOS Terminal.app.
118
117
  Workaround: use iTerm2 (https://iterm2.com) or input your prompt in English.
119
118
  Alternatively, use headless mode: robota -p "your prompt here"
120
119
 
121
- `);return}throw e}),gt().catch(e=>{let t=e instanceof Error?e.message:String(e);process.stderr.write(t+`
120
+ `);return}if(t!==`guard-owned`)throw e}),bt().catch(e=>{let t=e instanceof Error?e.message:String(e);process.stderr.write(t+`
122
121
  `),process.exit(1)});export{};
123
122
  //# sourceMappingURL=bin.js.map