@robota-sdk/agent-cli 3.0.0-beta.73 → 3.0.0-beta.74

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.
@@ -1,4 +1,4 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});let e=require(`node:child_process`),t=require(`@robota-sdk/agent-transport/headless`),n=require(`@robota-sdk/agent-framework`),r=require(`node:util`),i=require(`@robota-sdk/agent-core`),a=require(`@robota-sdk/agent-provider`),o=require(`@robota-sdk/agent-command`),s=require(`@robota-sdk/agent-transport/tui`),c=require(`@robota-sdk/agent-transport`),l=require(`@robota-sdk/agent-executor`),u=require(`@robota-sdk/agent-subagent-runner`),d=require(`node:fs`),f=require(`node:path`);const p=[`plan`,`default`,`acceptEdits`,`bypassPermissions`],m=[`text`,`json`,`stream-json`];function h(){return`
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});let e=require("node:child_process"),t=require("@robota-sdk/agent-transport/headless"),n=require("@robota-sdk/agent-framework"),r=require("node:util"),i=require("@robota-sdk/agent-core"),a=require("@robota-sdk/agent-provider"),o=require("@robota-sdk/agent-command"),s=require("@robota-sdk/agent-transport/tui"),c=require("@robota-sdk/agent-transport"),l=require("@robota-sdk/agent-executor"),u=require("@robota-sdk/agent-subagent-runner"),d=require("node:fs"),f=require("node:path"),p=require("node:readline/promises"),m=require("node:net");const h=[`plan`,`default`,`acceptEdits`,`bypassPermissions`],g=[`text`,`json`,`stream-json`];function _(){return`
2
2
  Usage: robota [options] [-p <prompt>]
3
3
 
4
4
  Options:
@@ -18,13 +18,21 @@ Options:
18
18
  --bare Print mode: output raw text only, no formatting wrapper
19
19
  --configure Run interactive provider configuration
20
20
  --configure-provider <n> Configure a specific provider
21
- --dry-run Plan-only run: show what the agent would do without modifying files
21
+ --allowed-tools <list> Comma-separated tool allowlist (TUI and print mode)
22
+ --denied-tools <list> Comma-separated tool denylist (TUI and print mode)
23
+ --model <model> Model override for this run
24
+ --json-schema <schema> Print mode: instruct the model to respond with JSON matching this schema
25
+ --dry-run Alias for --permission-mode plan (plan only, no execution)
26
+ --reset Delete ~/.robota/settings.json (provider profiles and preferences).
27
+ Asks for confirmation; use --yes to skip
28
+ --yes Skip confirmation prompts (required for --reset in non-TTY)
22
29
  --check-update Check for CLI updates
23
30
  --version Show version number
24
31
  -h, --help Show this help message
25
32
 
26
33
  Commands:
27
34
  robota init Initialize AGENTS.md and .robota/settings.json
35
+ robota diagnose Check setup and print a diagnostics report
28
36
 
29
37
  Examples:
30
38
  robota Start interactive TUI session
@@ -33,17 +41,73 @@ Examples:
33
41
  robota -p "Hello" --output-format json
34
42
  robota -p "Review this diff" --bare Raw output for shell pipelines
35
43
  robota --task-file task.md Run task from file (appended to system prompt)
36
- robota --dry-run "Refactor the auth module" Show plan without modifying files
44
+ robota -p "Refactor the auth module" --dry-run Plan only, no execution
37
45
  robota --continue Resume the last session
38
- `}function g(e){if(e!==void 0){if(!m.includes(e))throw Error(`Invalid --output-format "${e}". Valid: ${m.join(` | `)}`);return e}}function _(e){if(e!==void 0){if(!p.includes(e))throw Error(`Invalid --permission-mode "${e}". Valid: ${p.join(` | `)}`);return e}}function v(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 y={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`},"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 b(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[`permission-mode`]),maxTurns:v(e[`max-turns`]),forkSession:e[`fork-session`]??!1,sessionName:e.name,outputFormat:g(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,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 x(){let{values:e,positionals:t}=(0,r.parseArgs)(y);return b(e,t)}function S(e){if(e===void 0||e===`user`||e===`project-local`)return e;throw Error(`Invalid --settings-scope "${e}". Valid: user | project-local`)}function C(e,t,r,i=(0,a.createDefaultProviderDefinitions)()){let o=(0,n.resolveSettingsPathForScope)(e,S(t.settingsScope));return t.configureProvider?((0,n.applyProviderConfiguration)(o,E(t),{providerDefinitions:i}),r.writeLine(`Provider profile saved to ${o}`),!t.printMode&&t.positional.length===0):t.provider&&t.setCurrent?((0,n.applyProviderSwitch)(t.settingsScope===void 0?(0,n.resolveProviderSettingsWriteTargetPath)(e):o,t.provider,{knownProviders:(0,n.readMergedProviderSettings)(e).providers}),r.writeLine(`Current provider set to ${t.provider}`),!t.printMode&&t.positional.length===0):!1}async function w(e,t,n,r,i=(0,a.createDefaultProviderDefinitions)(),s){await(0,o.ensureProviderConfig)(e,{provider:t.provider,settingsScope:S(t.settingsScope)},n,r,i,{formatError:D,isInteractive:s===void 0?()=>process.stdin.isTTY===!0&&process.stdout.isTTY===!0:()=>s})}async function T(e,t,n,r,i=(0,a.createDefaultProviderDefinitions)()){await(0,o.runProviderStartupSetup)(e,{settingsScope:S(t.settingsScope)},n,r,i)}function E(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 D(e=(0,a.createDefaultProviderDefinitions)()){return[`No provider configuration found.`,"Run `robota --configure` in an interactive terminal, or configure a provider:",`Supported providers: ${(0,i.formatSupportedProviderTypes)(e)}`,...e.map(O)].join(`
39
- `)}function O(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 k(e,t,n){if(e.positional[0]!==`user-local`)return!1;let r=await(0,o.executeUserLocalDirectCommand)({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 A(e){let t=(0,d.readFileSync)(e,`utf-8`);return JSON.parse(t)}function j(e,t){return new Date(t).getTime()-new Date(e).getTime()}function M(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(N(`llm_between_tools`,`tool-end`,`tool-start`,s,r.timestamp,n)):(t.push(N(`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(N(`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(N(`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(N(`llm_final_response`,`tool-end`,`assistant`,s,r.timestamp,n)):t.push(N(`user_to_assistant`,`user`,`assistant`,a,r.timestamp,n)),c++;break}c++}r=c}else r++}return t}function N(e,t,n,r,i,a){return{kind:e,fromType:t,toType:n,fromTimestamp:r,toTimestamp:i,durationMs:j(r,i),turnIndex:a}}function P(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 F(e){let t=M(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:P(t)}}function I(e){return e>=1e3?`${(e/1e3).toFixed(1)}s`:`${e}ms`}function L(e){return new Date(e).toLocaleString(`sv-SE`,{timeZoneName:`short`}).slice(0,16)}function R(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 z(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 B(e){let t=[],{stats:n}=e;if(t.push(`Session: ${e.sessionId}`),t.push(`Created: ${L(e.createdAt)} | cwd: ${e.cwd}`),t.push(``),t.push(`Timing Summary:`),n.llmWaitMs.count>0&&t.push(` LLM API wait ${I(n.llmWaitMs.avg).padStart(8)} avg | ${I(n.llmWaitMs.max).padStart(8)} max`),n.toolExecMs.count>0&&t.push(` Tool execution ${I(n.toolExecMs.avg).padStart(8)} avg | ${I(n.toolExecMs.median).padStart(8)} median`),n.userToAssistantMs.count>0&&t.push(` user → assistant ${I(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} ${R(n).padEnd(32)} ${I(n.durationMs).padStart(8)}`)}return t.push(``),t.push(z(e)),t.join(`
40
- `)}function V(e){let t=[];return t.push(`Analyzed ${e.sessionCount} sessions (${L(e.fromDate)} ~ ${L(e.toDate)})`),t.push(` Avg LLM response: ${I(e.avgLlmResponseMs)}`),t.push(` Avg tool exec: ${I(e.avgToolExecMs)}`),e.maxSingleDelayMs>0&&t.push(` Max single delay: ${I(e.maxSingleDelayMs)} (${e.maxSingleDelaySession}, turn ${e.maxSingleDelayTurn}, ${e.maxSingleDelayKind})`),t.join(`
41
- `)}function H(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 U(e){try{return(0,d.readdirSync)(e).filter(e=>e.endsWith(`.json`)).map(t=>(0,f.join)(e,t)).sort()}catch{return[]}}function W(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 G(e){let t=H(e),r=(0,n.userPaths)().sessions,i=U(r);if(i.length===0&&(process.stderr.write(`No session files found in ${r}\n`),process.exit(1)),t.sessionId!==void 0){let e=i.find(e=>e.includes(t.sessionId));e||(process.stderr.write(`Session not found: ${t.sessionId}\n`),process.exit(1));let n=F(A(e));process.stdout.write(B(n)+`
42
- `);return}if(t.last!==void 0){let e=i.slice(-t.last),n=[];for(let t of e)try{n.push(F(A(t)))}catch{}n.length===0&&(process.stderr.write(`No valid sessions found.
43
- `),process.exit(1));let r=W(n);process.stdout.write(V(r)+`
46
+ `}function v(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 y(e){if(e!==void 0){if(!g.includes(e))throw Error(`Invalid --output-format "${e}". Valid: ${g.join(` | `)}`);return e}}function b(e){if(e!==void 0){if(!h.includes(e))throw Error(`Invalid --permission-mode "${e}". Valid: ${h.join(` | `)}`);return e}}function x(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 S={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`},"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 C(e,t){return{positional:t,help:e.help??!1,printMode:e.p??!1,continueMode:e.continue??!1,resumeId:e.resume,language:e.language,permissionMode:b(e[`permission-mode`]),maxTurns:x(e[`max-turns`]),forkSession:e[`fork-session`]??!1,sessionName:e.name,outputFormat:y(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,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 w(){let{values:e,positionals:t}=(0,r.parseArgs)(S),n=C(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 T(e){if(e===void 0||e===`user`||e===`project-local`)return e;throw Error(`Invalid --settings-scope "${e}". Valid: user | project-local`)}function ee(e,t,r,i=(0,a.createDefaultProviderDefinitions)()){let o=(0,n.resolveSettingsPathForScope)(e,T(t.settingsScope));return t.configureProvider?((0,n.applyProviderConfiguration)(o,D(t),{providerDefinitions:i}),r.writeLine(`Provider profile saved to ${o}`),!t.printMode&&t.positional.length===0):t.provider&&t.setCurrent?((0,n.applyProviderSwitch)(t.settingsScope===void 0?(0,n.resolveProviderSettingsWriteTargetPath)(e):o,t.provider,{knownProviders:(0,n.readMergedProviderSettings)(e).providers}),r.writeLine(`Current provider set to ${t.provider}`),!t.printMode&&t.positional.length===0):!1}async function te(e,t,n,r,i=(0,a.createDefaultProviderDefinitions)(),s){await(0,o.ensureProviderConfig)(e,{provider:t.provider,settingsScope:T(t.settingsScope)},n,r,i,{formatError:O,isInteractive:s===void 0?()=>process.stdin.isTTY===!0&&process.stdout.isTTY===!0:()=>s})}async function E(e,t,n,r,i=(0,a.createDefaultProviderDefinitions)()){await(0,o.runProviderStartupSetup)(e,{settingsScope:T(t.settingsScope)},n,r,i)}function D(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 O(e=(0,a.createDefaultProviderDefinitions)()){return[`No provider configuration found.`,"Run `robota --configure` in an interactive terminal, or configure a provider:",`Supported providers: ${(0,i.formatSupportedProviderTypes)(e)}`,...e.map(k)].join(`
47
+ `)}function k(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 ne(e,t,n){if(e.positional[0]!==`user-local`)return!1;let r=await(0,o.executeUserLocalDirectCommand)({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 A(e){let t=(0,d.readFileSync)(e,`utf-8`);return JSON.parse(t)}function j(e,t){return new Date(t).getTime()-new Date(e).getTime()}function M(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(N(`llm_between_tools`,`tool-end`,`tool-start`,s,r.timestamp,n)):(t.push(N(`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(N(`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(N(`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(N(`llm_final_response`,`tool-end`,`assistant`,s,r.timestamp,n)):t.push(N(`user_to_assistant`,`user`,`assistant`,a,r.timestamp,n)),c++;break}c++}r=c}else r++}return t}function N(e,t,n,r,i,a){return{kind:e,fromType:t,toType:n,fromTimestamp:r,toTimestamp:i,durationMs:j(r,i),turnIndex:a}}function re(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 P(e){let t=M(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:re(t)}}function F(e){return e>=1e3?`${(e/1e3).toFixed(1)}s`:`${e}ms`}function I(e){return new Date(e).toLocaleString(`sv-SE`,{timeZoneName:`short`}).slice(0,16)}function ie(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 L(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 R(e){let t=[],{stats:n}=e;if(t.push(`Session: ${e.sessionId}`),t.push(`Created: ${I(e.createdAt)} | cwd: ${e.cwd}`),t.push(``),t.push(`Timing Summary:`),n.llmWaitMs.count>0&&t.push(` LLM API wait ${F(n.llmWaitMs.avg).padStart(8)} avg | ${F(n.llmWaitMs.max).padStart(8)} max`),n.toolExecMs.count>0&&t.push(` Tool execution ${F(n.toolExecMs.avg).padStart(8)} avg | ${F(n.toolExecMs.median).padStart(8)} median`),n.userToAssistantMs.count>0&&t.push(` user → assistant ${F(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} ${ie(n).padEnd(32)} ${F(n.durationMs).padStart(8)}`)}return t.push(``),t.push(L(e)),t.join(`
48
+ `)}function z(e){let t=[];return t.push(`Analyzed ${e.sessionCount} sessions (${I(e.fromDate)} ~ ${I(e.toDate)})`),t.push(` Avg LLM response: ${F(e.avgLlmResponseMs)}`),t.push(` Avg tool exec: ${F(e.avgToolExecMs)}`),e.maxSingleDelayMs>0&&t.push(` Max single delay: ${F(e.maxSingleDelayMs)} (${e.maxSingleDelaySession}, turn ${e.maxSingleDelayTurn}, ${e.maxSingleDelayKind})`),t.join(`
49
+ `)}function B(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 V(e){try{return(0,d.readdirSync)(e).filter(e=>e.endsWith(`.json`)).map(t=>(0,f.join)(e,t))}catch{return[]}}function H(e){let t=new Map;for(let e of V((0,n.userPaths)().sessions))t.set((0,f.basename)(e),e);for(let r of V((0,n.projectPaths)(e).sessions))t.set((0,f.basename)(r),r);return[...t.entries()].sort((e,t)=>e[0].localeCompare(t[0])).map(([,e])=>e)}function U(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 W(e,t=process.cwd()){let r=B(e),i=H(t);if(i.length===0&&(process.stderr.write(`No session files found in ${(0,n.projectPaths)(t).sessions} or ${(0,n.userPaths)().sessions}\n`),process.exit(1)),r.sessionId!==void 0){let e=i.find(e=>e.includes(r.sessionId));e||(process.stderr.write(`Session not found: ${r.sessionId}\n`),process.exit(1));let t=P(A(e));process.stdout.write(R(t)+`
50
+ `);return}if(r.last!==void 0){let e=i.slice(-r.last),t=[];for(let n of e)try{t.push(P(A(n)))}catch{}t.length===0&&(process.stderr.write(`No valid sessions found.
51
+ `),process.exit(1));let n=U(t);process.stdout.write(z(n)+`
44
52
  `);return}let a=i[i.length-1];a||(process.stderr.write(`No sessions found.
45
- `),process.exit(1));let o=F(A(a));process.stdout.write(B(o)+`
46
- `)}const K=()=>(0,n.readPackageVersion)(require(`url`).pathToFileURL(__filename).href);function q(e){let t=(0,n.resetUserConfig)();t.deleted?e.writeLine(`Deleted ${t.path}`):e.writeLine(`No user settings found.`)}function J(e,t,r,i){let s={settings:{read:()=>(0,n.readSettings)((0,n.getUserSettingsPath)()),write:e=>(0,n.writeSettings)((0,n.getUserSettingsPath)(),e)},plugin:(0,o.createDefaultPluginCommandAdapter)(e)},c=r.providerDefinitions??(0,a.createDefaultProviderDefinitions)();return{commandHostAdapters:s,providerDefinitions:c,commandModules:[...(0,o.createDefaultCommandModules)({cwd:e,providerDefinitions:c,providerSettingsAdapter:{readMergedSettings:()=>(0,n.readMergedProviderSettings)(e),readTargetSettings:()=>(0,n.readSettings)((0,n.resolveProviderSettingsWriteTargetPath)(e)),writeTargetSettings:t=>(0,n.writeSettings)((0,n.resolveProviderSettingsWriteTargetPath)(e),t)}}),...r.commandModules??[]],startupUpdateNoticePromise:(0,n.shouldRunStartupCliUpdateCheck)(t)?(0,n.getStartupCliUpdateNotice)({currentVersion:i}):void 0}}function Y(e,t){let n=(0,d.readFileSync)((0,f.resolve)(e,t),`utf8`).trim();if(n.length===0)throw Error(`Task file is empty: ${t}`);return`Task file (${t}):\n${n}`}function X(e,t){let n=[];if(t.appendSystemPrompt&&n.push(t.appendSystemPrompt),t.taskFile)try{n.push(Y(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(`
53
+ `),process.exit(1));let o=P(A(a));process.stdout.write(R(o)+`
54
+ `)}const G=()=>(0,n.readPackageVersion)(require("url").pathToFileURL(__filename).href);async function K(e){let t=(0,p.createInterface)({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 q(e,t){let r=(0,n.getUserSettingsPath)();if(!(0,d.existsSync)(r))return e.writeLine(`No user settings found.`),0;if(!t.yes){if(!t.isTTY)return e.writeError(`--reset deletes ${r}. Refusing without confirmation in non-interactive mode — pass --yes to proceed.`),1;if(!await(t.confirm??K)(`Delete ${r}? [y/N] `))return e.writeLine(`Reset cancelled.`),1}let i=(0,n.resetUserConfig)();return i.deleted?e.writeLine(`Deleted ${i.path}`):e.writeLine(`No user settings found.`),0}const J={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 Y(){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 ae(e){return{label:`robota version`,status:`ok`,message:e}}function oe(e,t,r){try{let i=(0,n.readProviderSettings)(e,{providerDefinitions:t,env:r}),a=i.source===`env-default`?`env-default via ${i.sourceEnvVar??`environment`}`:`settings profile`,o=i.model===void 0?``:` (${i.model})`;return{label:`API key`,status:`ok`,message:`${i.name}${o} — ${a}`}}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 se(e){try{return JSON.parse((0,d.readFileSync)(e,`utf-8`)),`ok`}catch{return`corrupt`}}function ce(e){let t=(0,n.getProviderSettingsPaths)(e).filter(e=>(0,d.existsSync)(e));return t.length===0?[{label:`Settings file`,status:`warn`,message:`Not found — run: robota --configure`}]:t.map(e=>se(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 le(e){try{let t=JSON.parse((0,d.readFileSync)(e,`utf-8`));return typeof t.currentProvider==`string`?t.currentProvider:void 0}catch{return}}function ue(e){let t=(0,f.join)(e,`.robota`,`settings.json`),n=(0,f.join)(process.env.HOME??``,`.robota`,`settings.json`),r=(0,d.existsSync)(t)?t:(0,d.existsSync)(n)?n:void 0;if(r!==void 0){let e=(le(r)??``).toLowerCase(),t=Object.entries(J).find(([t])=>e.startsWith(t));if(t)return t[1]}return J.anthropic}function de(){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
55
+ Recommendation: use iTerm2 (https://iterm2.com)`}:{label:`Terminal`,status:`ok`,message:e}}function fe(e){let t=`Network (${e.host})`;return new Promise(n=>{let r=Date.now(),i=(0,m.createConnection)({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 pe(e,t={checkNetwork:fe}){e.terminal.writeLine(`
56
+ robota diagnose
57
+ `);let n=ue(e.cwd),r=t.providerDefinitions??(0,a.createDefaultProviderDefinitions)(),i=t.env??process.env,o=[Y(),ae(e.version),oe(e.cwd,r,i),...ce(e.cwd),de(),await t.checkNetwork(n)],s=0,c=0;for(let t of o){let n=t.status===`ok`?`✓`:t.status===`warn`?`⚠`:`✗`,r=t.message.split(`
58
+ `);e.terminal.writeLine(` ${n} ${t.label}: ${r[0]}`);for(let t of r.slice(1))e.terminal.writeLine(` ${t}`);t.status===`fail`&&s++,t.status===`warn`&&c++}return e.terminal.writeLine(``),s===0&&c===0?e.terminal.writeLine(`✓ All checks passed. robota is ready to use.`):s>0?e.terminal.writeLine(`✗ ${s} issue(s) found. Fix the items above to use robota.`):e.terminal.writeLine(`⚠ ${c} warning(s). robota may work but check the items above.`),e.terminal.writeLine(``),s}const X=`robota`,Z={permissions:{allow:[`Read(.robota/**)`,`Read(.claude/**)`,`Read(.agents/**)`],deny:[]}};function me(e){let t=(0,f.join)(e,`settings.json`);if(!(0,d.existsSync)(t))return{};let n=(0,d.readFileSync)(t,`utf8`);try{return JSON.parse(n)}catch{return null}}var he=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 Q(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 he(e);let r=await n.promptFn(`${e} [y/N] `);return r.toLowerCase()===`y`||r.toLowerCase()===`yes`}async function ge(e,r,i={}){r.writeLine(``),r.writeLine(`${X} project initialization`),r.writeLine(`─`.repeat(40));let a={yes:i.yes===!0,ci:i.ci??process.env.CI===`true`,isTTY:i.isTTY??process.stdin.isTTY===!0,promptFn:i.promptFn??t.promptInput,terminal:r},o=(0,n.projectPaths)(e).settings,s=(0,f.dirname)(o),c=(0,f.join)(e,`AGENTS.md`),l=(0,f.join)(e,`.claude`),u=(0,d.existsSync)(l),p=(0,d.existsSync)(o),m=(0,d.existsSync)(c);if(p&&m&&(r.writeLine(``),r.writeLine(`Both AGENTS.md and .robota/settings.json already exist.`),!await Q(`Overwrite existing files?`,!1,a))){r.writeLine(`Init cancelled.`);return}let h={...Z};if(u&&(r.writeLine(``),r.writeLine(`Detected .claude/ directory (Claude Code configuration).`),await Q(`Migrate Claude Code settings to .robota/?`,!1,a))){let e=me(l);if(e===null)r.writeLine(`Warning: .claude/settings.json could not be parsed — skipping migration.`);else{let t=e.permissions;h={...e,permissions:{...typeof e.permissions==`object`&&e.permissions!==null?e.permissions:{},allow:[...Z.permissions.allow,...t?.allow??[]],deny:t?.deny??[]}},r.writeLine(`Settings imported from .claude/settings.json.`)}}(0,d.mkdirSync)(s,{recursive:!0}),(0,d.writeFileSync)(o,JSON.stringify(h,null,2)+`
59
+ `,`utf8`),r.writeLine(``),r.writeLine(`Created: .robota/settings.json`),(0,d.writeFileSync)(c,`# AGENTS.md — Project Agent Guidelines
47
60
 
48
- `):void 0}async function Z(e,n,r,i,a,o,s,c){let l=n.positional.join(` `).trim();if(!l&&!process.stdin.isTTY){let e=[];for await(let t of process.stdin)e.push(t);l=Buffer.concat(e).toString(`utf-8`).trim()}l||(process.stderr.write(`Print mode (-p) requires a prompt argument.
49
- `),process.exit(1));let u=X(e,n),d=new t.HeadlessInteractionChannel({cwd:e,provider:r,outputFormat:n.outputFormat??`text`,permissionMode:n.permissionMode??`bypassPermissions`,maxTurns:n.maxTurns,sessionStore:n.noSessionPersistence?void 0:i,sessionName:n.sessionName,bare:n.bare||void 0,allowedTools:n.allowedTools?n.allowedTools.split(`,`).map(e=>e.trim()).filter(e=>e.length>0):void 0,appendSystemPrompt:u,...n.systemPrompt?{systemPrompt:n.systemPrompt}:{},backgroundTaskRunners:a,subagentRunnerFactory:o,commandModules:s,commandHostAdapters:c});await d.run(l),process.exit(d.getExitCode())}async function Q(r={}){let i;try{i=x()}catch(e){process.stderr.write(`${e instanceof Error?e.message:String(e)}\n`),process.exit(1)}let a=K();if(i.help){process.stdout.write(h());return}if(i.version){process.stdout.write(`robota ${a}\n`);return}if(i.checkUpdate){let e=await(0,n.checkForCliUpdate)({currentVersion:a,force:!0}),t=(0,n.formatCliUpdateCheckMessage)(e);e.status===`error`&&(process.stderr.write(`${t}\n`),process.exit(1)),process.stdout.write(`${t}\n`);return}let d=process.cwd(),f=new t.PrintTerminal;if(i.reset){q(f);return}if(i.positional[0]===`session`&&i.positional[1]===`analyze`){await G(process.argv.slice(4));return}try{if(await k(i,d,f))return}catch(e){f.writeError(e instanceof Error?e.message:String(e)),process.exit(1)}let{commandHostAdapters:p,providerDefinitions:m,commandModules:g,startupUpdateNoticePromise:_}=J(d,i,r,a);if(i.configure){await T(d,i,t.promptInput,f,m);return}if(C(d,i,f,m))return;try{await w(d,i,t.promptInput,f,m)}catch(e){process.stderr.write(`${e instanceof Error?e.message:String(e)}\n`),process.exit(1)}let v=i.provider?{providerOverride:i.provider,providerDefinitions:m}:{providerDefinitions:m},y=(0,n.readProviderSettings)(d,v),b=i.model??y.model,S=(0,n.createProviderFromSettings)(d,i.model,v),E=(0,l.createDefaultBackgroundTaskRunners)(),D=(0,n.projectPaths)(d),O=(0,u.createChildProcessSubagentRunnerFactory)({workerPath:(0,u.getDefaultSubagentWorkerPath)(),providerConfig:{...y,model:b},logsDir:D.logs}),A=(0,n.createProjectSessionStore)(d),j,M=!1;if(i.continueMode?j=(0,n.resolveLatestSessionId)(A,d):i.resumeId!==void 0&&(i.resumeId===``?M=!0:(j=(0,n.resolveSessionIdByIdOrName)(A,i.resumeId),j===void 0&&(process.stderr.write(`Session not found: ${i.resumeId}\n`),process.exit(1)))),i.printMode){await Z(d,i,S,A,E,O,g,p);return}await(0,s.renderApp)({cwd:d,provider:S,providerOverride:i.provider,providerType:y.name,modelId:b,language:i.language,permissionMode:i.permissionMode,maxTurns:i.maxTurns,version:a,sessionStore:i.noSessionPersistence?void 0:A,resumeSessionId:j,showSessionPickerOnStart:M,forkSession:i.forkSession,sessionName:i.sessionName,backgroundTaskRunners:E,subagentRunnerFactory:O,commandModules:g,commandHostAdapters:p,shellExec:t=>(0,e.execSync)(t,{timeout:5e3,encoding:`utf-8`,stdio:`pipe`}).trimEnd(),startupUpdateNotice:_?_.then(e=>e?(0,n.formatCliUpdateNotice)(e):void 0):void 0,transportRegistry:(0,c.createDefaultTransportRegistry)(),cliAdapter:(0,s.createDefaultTuiCliAdapter)({providerDefinitions:m,reloadPluginCommandSource:o.reloadPluginCommandSource}),reloadPluginCommandSource:o.reloadPluginCommandSource,agentName:`robota-cli`}),process.exit(0)}exports.startCli=Q;
61
+ This file guides the AI agent working in this project. Customize it for your project.
62
+
63
+ ## Project Overview
64
+
65
+ <!-- Describe your project's purpose, tech stack, and key conventions -->
66
+
67
+ ## Common Commands
68
+
69
+ \`\`\`bash
70
+ # Install dependencies
71
+ npm install
72
+
73
+ # Run tests
74
+ npm test
75
+
76
+ # Build
77
+ npm run build
78
+ \`\`\`
79
+
80
+ ## Coding Conventions
81
+
82
+ - Language: <!-- e.g. TypeScript strict mode -->
83
+ - Test framework: <!-- e.g. Vitest, Jest -->
84
+ - Linting: <!-- e.g. ESLint with prettier -->
85
+
86
+ ## Important Notes
87
+
88
+ <!-- Anything the agent should know before making changes -->
89
+ `,`utf8`),r.writeLine(`Created: AGENTS.md`),r.writeLine(``),r.writeLine(`Initialization complete.`),r.writeLine(``),r.writeLine(`Next steps:`),r.writeLine(` 1. Edit AGENTS.md to describe your project conventions`),r.writeLine(` 2. Run \`${X} --configure\` to set up your AI provider`),r.writeLine(` 3. Run \`${X}\` to start the assistant`),r.writeLine(``),i.onProviderSetup!==void 0&&(a.isTTY||a.yes||a.ci)&&await Q(`Would you like to set up a provider now?`,!1,a)&&await i.onProviderSetup()}function _e(e=(0,n.userPaths)().onboarded){return!(0,d.existsSync)(e)}function ve(e=(0,n.userPaths)().onboarded){(0,d.mkdirSync)((0,f.dirname)(e),{recursive:!0}),(0,d.writeFileSync)(e,new Date().toISOString())}const ye=`
90
+ ╭─────────────────────────────────────────────────────────────╮
91
+ │ Welcome to ${X}! — AI coding assistant │
92
+ │ │
93
+ │ Try asking: │
94
+ │ "Explain this project structure" │
95
+ │ "Find files with TODO comments" │
96
+ │ "Run tests and analyze failures" │
97
+ │ "What changed recently in git?" │
98
+ │ │
99
+ │ Useful commands: │
100
+ │ /help show all slash commands │
101
+ │ /cost show token usage and estimated cost │
102
+ │ /clear clear conversation history │
103
+ │ │
104
+ │ ${X} diagnose — check your setup │
105
+ ╰─────────────────────────────────────────────────────────────╯
106
+ `;function be(e){e.writeLine(ye)}function $(e){process.platform===`darwin`&&process.env.TERM_PROGRAM===`Apple_Terminal`&&e.writeError(`
107
+ ⚠ macOS Terminal.app detected: CJK/IME input may be unstable.
108
+ Recommended: use iTerm2 (https://iterm2.com) for Korean/Japanese/Chinese input.
109
+ Or use headless mode: robota -p "your prompt"
110
+ `)}function xe(e,t,r,i){let s={settings:{read:()=>(0,n.readSettings)((0,n.getUserSettingsPath)()),write:e=>(0,n.writeSettings)((0,n.getUserSettingsPath)(),e)},plugin:(0,o.createDefaultPluginCommandAdapter)(e)},c=r.providerDefinitions??(0,a.createDefaultProviderDefinitions)();return{commandHostAdapters:s,providerDefinitions:c,commandModules:[...(0,o.createDefaultCommandModules)({cwd:e,providerDefinitions:c,providerSettingsAdapter:{readMergedSettings:()=>(0,n.readMergedProviderSettings)(e),readTargetSettings:()=>(0,n.readSettings)((0,n.resolveProviderSettingsWriteTargetPath)(e)),writeTargetSettings:t=>(0,n.writeSettings)((0,n.resolveProviderSettingsWriteTargetPath)(e),t)}}),...r.commandModules??[]],startupUpdateNoticePromise:(0,n.shouldRunStartupCliUpdateCheck)(t)?(0,n.getStartupCliUpdateNotice)({currentVersion:i}):void 0}}function Se(e,t){let n=(0,d.readFileSync)((0,f.resolve)(e,t),`utf8`).trim();if(n.length===0)throw Error(`Task file is empty: ${t}`);return`Task file (${t}):\n${n}`}function Ce(e,t){let n=[];if(t.appendSystemPrompt&&n.push(t.appendSystemPrompt),t.taskFile)try{n.push(Se(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(`
111
+
112
+ `):void 0}async function we(e,n,r,i,a,o,s,c,l={}){let u=n.positional.join(` `).trim();if(!u&&!process.stdin.isTTY){let e=[];for await(let t of process.stdin)e.push(t);u=Buffer.concat(e).toString(`utf-8`).trim()}u||(process.stderr.write(`Print mode (-p) requires a prompt argument.
113
+ `),process.exit(1));let d=Ce(e,n),f=new t.HeadlessInteractionChannel({cwd:e,provider:r,outputFormat:n.outputFormat??`text`,permissionMode:n.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:v(n.allowedTools),deniedTools:v(n.deniedTools),appendSystemPrompt:d,...n.systemPrompt?{systemPrompt:n.systemPrompt}:{},backgroundTaskRunners:a,subagentRunnerFactory:o,commandModules:s,commandHostAdapters:c});await f.run(u),process.exit(f.getExitCode())}async function Te(r={}){if(process.argv[2]===`session`&&process.argv[3]===`analyze`){await W(process.argv.slice(4),process.cwd());return}let i;try{i=w()}catch(e){process.stderr.write(`${e instanceof Error?e.message:String(e)}\n`),process.exit(1)}let a=G();if(i.help){process.stdout.write(_());return}if(i.version){process.stdout.write(`robota ${a}\n`);return}if(i.checkUpdate){let e=await(0,n.checkForCliUpdate)({currentVersion:a,force:!0}),t=(0,n.formatCliUpdateCheckMessage)(e);e.status===`error`&&(process.stderr.write(`${t}\n`),process.exit(1)),process.stdout.write(`${t}\n`);return}let d=process.cwd(),f=new t.PrintTerminal;if(i.reset){process.exitCode=await q(f,{yes:i.yes,isTTY:process.stdin.isTTY===!0});return}if(i.positional[0]===`diagnose`){let e=await pe({version:a,terminal:f,cwd:d});process.exitCode=+(e>0);return}if(i.positional[0]===`session`&&i.positional[1]===`analyze`){await W(process.argv.slice(4),d);return}try{if(await ne(i,d,f))return}catch(e){f.writeError(e instanceof Error?e.message:String(e)),process.exit(1)}let{commandHostAdapters:p,providerDefinitions:m,commandModules:h,startupUpdateNoticePromise:g}=xe(d,i,r,a);if(i.positional[0]===`init`){try{await ge(d,f,{yes:i.yes,onProviderSetup:async()=>{await E(d,i,t.promptInput,f,m)}})}catch(e){f.writeError(e instanceof Error?e.message:String(e)),process.exit(1)}return}if(i.configure){await E(d,i,t.promptInput,f,m);return}if(ee(d,i,f,m))return;try{await te(d,i,t.promptInput,f,m)}catch(e){process.stderr.write(`${e instanceof Error?e.message:String(e)}\n`),process.exit(e instanceof n.ProviderConfigError&&i.printMode?3:1)}let y=i.provider?{providerOverride:i.provider,providerDefinitions:m}:{providerDefinitions:m},b=(0,n.readProviderSettings)(d,y),x=i.model??b.model;if(b.source===`env-default`&&b.sourceEnvVar!==void 0){let e=`Using ${b.name} (${x}) via ${b.sourceEnvVar} — run \`robota --configure\` to persist a profile.\n`;i.printMode?process.stderr.write(e):f.writeLine(e.trimEnd())}let S=(0,n.createProviderFromSettings)(d,i.model,y),C=(0,l.createDefaultBackgroundTaskRunners)(),T=(0,n.projectPaths)(d),D=(0,u.createChildProcessSubagentRunnerFactory)({workerPath:(0,u.getDefaultSubagentWorkerPath)(),providerConfig:{...b,model:x},logsDir:T.logs}),O=(0,n.createProjectSessionStore)(d),k,A=!1;if(i.continueMode?k=(0,n.resolveLatestSessionId)(O,d):i.resumeId!==void 0&&(i.resumeId===``?A=!0:(k=(0,n.resolveSessionIdByIdOrName)(O,i.resumeId),k===void 0&&(process.stderr.write(`Session not found: ${i.resumeId}\n`),process.exit(1)))),i.printMode){await we(d,i,S,O,C,D,h,p,{resumeSessionId:k,forkSession:i.forkSession});return}$(f),_e()&&(be(f),ve()),await(0,s.renderApp)({cwd:d,provider:S,providerOverride:i.provider,providerType:b.name,modelId:x,language:i.language,permissionMode:i.permissionMode,maxTurns:i.maxTurns,allowedTools:v(i.allowedTools),deniedTools:v(i.deniedTools),version:a,sessionStore:i.noSessionPersistence?void 0:O,resumeSessionId:k,showSessionPickerOnStart:A,forkSession:i.forkSession,sessionName:i.sessionName,backgroundTaskRunners:C,subagentRunnerFactory:D,commandModules:h,commandHostAdapters:p,shellExec:t=>(0,e.execSync)(t,{timeout:5e3,encoding:`utf-8`,stdio:`pipe`}).trimEnd(),startupUpdateNotice:g?g.then(e=>e?(0,n.formatCliUpdateNotice)(e):void 0):void 0,transportRegistry:(0,c.createDefaultTransportRegistry)(),cliAdapter:(0,s.createDefaultTuiCliAdapter)({providerDefinitions:m,reloadPluginCommandSource:o.reloadPluginCommandSource}),reloadPluginCommandSource:o.reloadPluginCommandSource,agentName:`robota-cli`}),process.exit(0)}exports.startCli=Te;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../../src/startup/command-setup.ts","../../src/cli.ts"],"mappings":";;;;UAuBiB,gBAAA;EACf,cAAA,YAA0B,cAAA;EAC1B,mBAAA,YAA+B,mBAAmB;AAAA;;;iBCmB9B,QAAA,CAAS,OAAA,GAAS,gBAAA,GAAwB,OAAO"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../../src/startup/command-setup.ts","../../src/cli.ts"],"mappings":";;;;UAuBiB,gBAAA;EACf,cAAA,YAA0B,cAAA;EAC1B,mBAAA,YAA+B,mBAAmB;AAAA;;;iBCwB9B,QAAA,CAAS,OAAA,GAAS,gBAAA,GAAwB,OAAO"}
@@ -1,4 +1,4 @@
1
- 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{applyProviderConfiguration as i,applyProviderSwitch as a,checkForCliUpdate as o,createProjectSessionStore as s,createProviderFromSettings as c,formatCliUpdateCheckMessage as l,formatCliUpdateNotice as u,getStartupCliUpdateNotice as d,getUserSettingsPath as f,projectPaths as p,readMergedProviderSettings as m,readPackageVersion as h,readProviderSettings as g,readSettings as _,resetUserConfig as v,resolveLatestSessionId as ee,resolveProviderSettingsWriteTargetPath as y,resolveSessionIdByIdOrName as b,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{formatSupportedProviderTypes as E}from"@robota-sdk/agent-core";import{createDefaultProviderDefinitions as D}from"@robota-sdk/agent-provider";import{createDefaultCommandModules as O,createDefaultPluginCommandAdapter as k,ensureProviderConfig as A,executeUserLocalDirectCommand as te,reloadPluginCommandSource as j,runProviderStartupSetup as ne}from"@robota-sdk/agent-command";import{createDefaultTuiCliAdapter as re,renderApp as ie}from"@robota-sdk/agent-transport/tui";import{createDefaultTransportRegistry as ae}from"@robota-sdk/agent-transport";import{createDefaultBackgroundTaskRunners as oe}from"@robota-sdk/agent-executor";import{createChildProcessSubagentRunnerFactory as se,getDefaultSubagentWorkerPath as M}from"@robota-sdk/agent-subagent-runner";import{readFileSync as N,readdirSync as P}from"node:fs";import{join as F,resolve as I}from"node:path";const L=[`plan`,`default`,`acceptEdits`,`bypassPermissions`],R=[`text`,`json`,`stream-json`];function z(){return`
1
+ 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 v,readSettings as y,resetUserConfig as b,resolveLatestSessionId as ee,resolveProviderSettingsWriteTargetPath as x,resolveSessionIdByIdOrName as te,resolveSettingsPathForScope as S,shouldRunStartupCliUpdateCheck as C,userPaths as w,writeSettings as T}from"@robota-sdk/agent-framework";import{parseArgs as E}from"node:util";import{formatSupportedProviderTypes as D}from"@robota-sdk/agent-core";import{createDefaultProviderDefinitions as O}from"@robota-sdk/agent-provider";import{createDefaultCommandModules as k,createDefaultPluginCommandAdapter as ne,ensureProviderConfig as re,executeUserLocalDirectCommand as ie,reloadPluginCommandSource as A,runProviderStartupSetup as ae}from"@robota-sdk/agent-command";import{createDefaultTuiCliAdapter as oe,renderApp as se}from"@robota-sdk/agent-transport/tui";import{createDefaultTransportRegistry as ce}from"@robota-sdk/agent-transport";import{createDefaultBackgroundTaskRunners as le}from"@robota-sdk/agent-executor";import{createChildProcessSubagentRunnerFactory as ue,getDefaultSubagentWorkerPath as de}from"@robota-sdk/agent-subagent-runner";import{existsSync as j,mkdirSync as M,readFileSync as N,readdirSync as fe,writeFileSync as P}from"node:fs";import{basename as F,dirname as I,join as L,resolve as pe}from"node:path";import{createInterface as me}from"node:readline/promises";import{createConnection as he}from"node:net";const R=[`plan`,`default`,`acceptEdits`,`bypassPermissions`],z=[`text`,`json`,`stream-json`];function ge(){return`
2
2
  Usage: robota [options] [-p <prompt>]
3
3
 
4
4
  Options:
@@ -18,13 +18,21 @@ Options:
18
18
  --bare Print mode: output raw text only, no formatting wrapper
19
19
  --configure Run interactive provider configuration
20
20
  --configure-provider <n> Configure a specific provider
21
- --dry-run Plan-only run: show what the agent would do without modifying files
21
+ --allowed-tools <list> Comma-separated tool allowlist (TUI and print mode)
22
+ --denied-tools <list> Comma-separated tool denylist (TUI and print mode)
23
+ --model <model> Model override for this run
24
+ --json-schema <schema> Print mode: instruct the model to respond with JSON matching this schema
25
+ --dry-run Alias for --permission-mode plan (plan only, no execution)
26
+ --reset Delete ~/.robota/settings.json (provider profiles and preferences).
27
+ Asks for confirmation; use --yes to skip
28
+ --yes Skip confirmation prompts (required for --reset in non-TTY)
22
29
  --check-update Check for CLI updates
23
30
  --version Show version number
24
31
  -h, --help Show this help message
25
32
 
26
33
  Commands:
27
34
  robota init Initialize AGENTS.md and .robota/settings.json
35
+ robota diagnose Check setup and print a diagnostics report
28
36
 
29
37
  Examples:
30
38
  robota Start interactive TUI session
@@ -33,18 +41,74 @@ Examples:
33
41
  robota -p "Hello" --output-format json
34
42
  robota -p "Review this diff" --bare Raw output for shell pipelines
35
43
  robota --task-file task.md Run task from file (appended to system prompt)
36
- robota --dry-run "Refactor the auth module" Show plan without modifying files
44
+ robota -p "Refactor the auth module" --dry-run Plan only, no execution
37
45
  robota --continue Resume the last session
38
- `}function B(e){if(e!==void 0){if(!R.includes(e))throw Error(`Invalid --output-format "${e}". Valid: ${R.join(` | `)}`);return e}}function V(e){if(e!==void 0){if(!L.includes(e))throw Error(`Invalid --permission-mode "${e}". Valid: ${L.join(` | `)}`);return e}}function H(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 U={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`},"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 W(e,t){return{positional:t,help:e.help??!1,printMode:e.p??!1,continueMode:e.continue??!1,resumeId:e.resume,language:e.language,permissionMode:V(e[`permission-mode`]),maxTurns:H(e[`max-turns`]),forkSession:e[`fork-session`]??!1,sessionName:e.name,outputFormat:B(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,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 G(){let{values:e,positionals:t}=T(U);return W(e,t)}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 ce(e,t,n,r=D()){let o=x(e,K(t.settingsScope));return t.configureProvider?(i(o,de(t),{providerDefinitions:r}),n.writeLine(`Provider profile saved to ${o}`),!t.printMode&&t.positional.length===0):t.provider&&t.setCurrent?(a(t.settingsScope===void 0?y(e):o,t.provider,{knownProviders:m(e).providers}),n.writeLine(`Current provider set to ${t.provider}`),!t.printMode&&t.positional.length===0):!1}async function le(e,t,n,r,i=D(),a){await A(e,{provider:t.provider,settingsScope:K(t.settingsScope)},n,r,i,{formatError:fe,isInteractive:a===void 0?()=>process.stdin.isTTY===!0&&process.stdout.isTTY===!0:()=>a})}async function ue(e,t,n,r,i=D()){await ne(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 fe(e=D()){return[`No provider configuration found.`,"Run `robota --configure` in an interactive terminal, or configure a provider:",`Supported providers: ${E(e)}`,...e.map(pe)].join(`
39
- `)}function pe(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 me(e,t,n){if(e.positional[0]!==`user-local`)return!1;let r=await te({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=N(e,`utf-8`);return JSON.parse(t)}function he(e,t){return new Date(t).getTime()-new Date(e).getTime()}function ge(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:he(r,i),turnIndex:a}}function _e(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=ge(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:_e(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 ve(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 ye(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 Q(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} ${ve(n).padEnd(32)} ${X(n.durationMs).padStart(8)}`)}return t.push(``),t.push(ye(e)),t.join(`
40
- `)}function be(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(`
41
- `)}function $(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 xe(e){try{return P(e).filter(e=>e.endsWith(`.json`)).map(t=>F(e,t)).sort()}catch{return[]}}function Se(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 Ce(e){let t=$(e),n=C().sessions,r=xe(n);if(r.length===0&&(process.stderr.write(`No session files found in ${n}\n`),process.exit(1)),t.sessionId!==void 0){let e=r.find(e=>e.includes(t.sessionId));e||(process.stderr.write(`Session not found: ${t.sessionId}\n`),process.exit(1));let n=Y(q(e));process.stdout.write(Q(n)+`
42
- `);return}if(t.last!==void 0){let e=r.slice(-t.last),n=[];for(let t of e)try{n.push(Y(q(t)))}catch{}n.length===0&&(process.stderr.write(`No valid sessions found.
43
- `),process.exit(1));let i=Se(n);process.stdout.write(be(i)+`
46
+ `}function B(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 _e(e){if(e!==void 0){if(!z.includes(e))throw Error(`Invalid --output-format "${e}". Valid: ${z.join(` | `)}`);return e}}function ve(e){if(e!==void 0){if(!R.includes(e))throw Error(`Invalid --permission-mode "${e}". Valid: ${R.join(` | `)}`);return e}}function ye(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 be={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`},"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 xe(e,t){return{positional:t,help:e.help??!1,printMode:e.p??!1,continueMode:e.continue??!1,resumeId:e.resume,language:e.language,permissionMode:ve(e[`permission-mode`]),maxTurns:ye(e[`max-turns`]),forkSession:e[`fork-session`]??!1,sessionName:e.name,outputFormat:_e(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,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 Se(){let{values:e,positionals:t}=E(be),n=xe(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 V(e){if(e===void 0||e===`user`||e===`project-local`)return e;throw Error(`Invalid --settings-scope "${e}". Valid: user | project-local`)}function Ce(e,t,n,r=O()){let i=S(e,V(t.settingsScope));return t.configureProvider?(a(i,Te(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?x(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 we(e,t,n,r,i=O(),a){await re(e,{provider:t.provider,settingsScope:V(t.settingsScope)},n,r,i,{formatError:Ee,isInteractive:a===void 0?()=>process.stdin.isTTY===!0&&process.stdout.isTTY===!0:()=>a})}async function H(e,t,n,r,i=O()){await ae(e,{settingsScope:V(t.settingsScope)},n,r,i)}function Te(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 Ee(e=O()){return[`No provider configuration found.`,"Run `robota --configure` in an interactive terminal, or configure a provider:",`Supported providers: ${D(e)}`,...e.map(De)].join(`
47
+ `)}function De(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 Oe(e,t,n){if(e.positional[0]!==`user-local`)return!1;let r=await ie({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 U(e){let t=N(e,`utf-8`);return JSON.parse(t)}function ke(e,t){return new Date(t).getTime()-new Date(e).getTime()}function Ae(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(W(`llm_between_tools`,`tool-end`,`tool-start`,s,r.timestamp,n)):(t.push(W(`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(W(`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(W(`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(W(`llm_final_response`,`tool-end`,`assistant`,s,r.timestamp,n)):t.push(W(`user_to_assistant`,`user`,`assistant`,a,r.timestamp,n)),c++;break}c++}r=c}else r++}return t}function W(e,t,n,r,i,a){return{kind:e,fromType:t,toType:n,fromTimestamp:r,toTimestamp:i,durationMs:ke(r,i),turnIndex:a}}function je(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 G(e){let t=Ae(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:je(t)}}function K(e){return e>=1e3?`${(e/1e3).toFixed(1)}s`:`${e}ms`}function q(e){return new Date(e).toLocaleString(`sv-SE`,{timeZoneName:`short`}).slice(0,16)}function Me(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 Ne(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 J(e){let t=[],{stats:n}=e;if(t.push(`Session: ${e.sessionId}`),t.push(`Created: ${q(e.createdAt)} | cwd: ${e.cwd}`),t.push(``),t.push(`Timing Summary:`),n.llmWaitMs.count>0&&t.push(` LLM API wait ${K(n.llmWaitMs.avg).padStart(8)} avg | ${K(n.llmWaitMs.max).padStart(8)} max`),n.toolExecMs.count>0&&t.push(` Tool execution ${K(n.toolExecMs.avg).padStart(8)} avg | ${K(n.toolExecMs.median).padStart(8)} median`),n.userToAssistantMs.count>0&&t.push(` user → assistant ${K(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} ${Me(n).padEnd(32)} ${K(n.durationMs).padStart(8)}`)}return t.push(``),t.push(Ne(e)),t.join(`
48
+ `)}function Pe(e){let t=[];return t.push(`Analyzed ${e.sessionCount} sessions (${q(e.fromDate)} ~ ${q(e.toDate)})`),t.push(` Avg LLM response: ${K(e.avgLlmResponseMs)}`),t.push(` Avg tool exec: ${K(e.avgToolExecMs)}`),e.maxSingleDelayMs>0&&t.push(` Max single delay: ${K(e.maxSingleDelayMs)} (${e.maxSingleDelaySession}, turn ${e.maxSingleDelayTurn}, ${e.maxSingleDelayKind})`),t.join(`
49
+ `)}function Fe(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 Y(e){try{return fe(e).filter(e=>e.endsWith(`.json`)).map(t=>L(e,t))}catch{return[]}}function Ie(e){let t=new Map;for(let e of Y(w().sessions))t.set(F(e),e);for(let n of Y(h(e).sessions))t.set(F(n),n);return[...t.entries()].sort((e,t)=>e[0].localeCompare(t[0])).map(([,e])=>e)}function Le(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 X(e,t=process.cwd()){let n=Fe(e),r=Ie(t);if(r.length===0&&(process.stderr.write(`No session files found in ${h(t).sessions} or ${w().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=G(U(e));process.stdout.write(J(t)+`
50
+ `);return}if(n.last!==void 0){let e=r.slice(-n.last),t=[];for(let n of e)try{t.push(G(U(n)))}catch{}t.length===0&&(process.stderr.write(`No valid sessions found.
51
+ `),process.exit(1));let i=Le(t);process.stdout.write(Pe(i)+`
44
52
  `);return}let i=r[r.length-1];i||(process.stderr.write(`No sessions found.
45
- `),process.exit(1));let a=Y(q(i));process.stdout.write(Q(a)+`
46
- `)}const we=()=>h(import.meta.url);function Te(e){let t=v();t.deleted?e.writeLine(`Deleted ${t.path}`):e.writeLine(`No user settings found.`)}function Ee(e,t,n,r){let i={settings:{read:()=>_(f()),write:e=>w(f(),e)},plugin:k(e)},a=n.providerDefinitions??D();return{commandHostAdapters:i,providerDefinitions:a,commandModules:[...O({cwd:e,providerDefinitions:a,providerSettingsAdapter:{readMergedSettings:()=>m(e),readTargetSettings:()=>_(y(e)),writeTargetSettings:t=>w(y(e),t)}}),...n.commandModules??[]],startupUpdateNoticePromise:S(t)?d({currentVersion:r}):void 0}}function De(e,t){let n=N(I(e,t),`utf8`).trim();if(n.length===0)throw Error(`Task file is empty: ${t}`);return`Task file (${t}):\n${n}`}function Oe(e,t){let n=[];if(t.appendSystemPrompt&&n.push(t.appendSystemPrompt),t.taskFile)try{n.push(De(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(`
53
+ `),process.exit(1));let a=G(U(i));process.stdout.write(J(a)+`
54
+ `)}const Re=()=>_(import.meta.url);async function ze(e){let t=me({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 Be(e,t){let n=m();if(!j(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??ze)(`Delete ${n}? [y/N] `))return e.writeLine(`Reset cancelled.`),1}let r=b();return r.deleted?e.writeLine(`Deleted ${r.path}`):e.writeLine(`No user settings found.`),0}const Z={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 Ve(){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 He(e){return{label:`robota version`,status:`ok`,message:e}}function Ue(e,t,n){try{let r=v(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 We(e){try{return JSON.parse(N(e,`utf-8`)),`ok`}catch{return`corrupt`}}function Ge(e){let t=f(e).filter(e=>j(e));return t.length===0?[{label:`Settings file`,status:`warn`,message:`Not found — run: robota --configure`}]:t.map(e=>We(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 Ke(e){try{let t=JSON.parse(N(e,`utf-8`));return typeof t.currentProvider==`string`?t.currentProvider:void 0}catch{return}}function qe(e){let t=L(e,`.robota`,`settings.json`),n=L(process.env.HOME??``,`.robota`,`settings.json`),r=j(t)?t:j(n)?n:void 0;if(r!==void 0){let e=(Ke(r)??``).toLowerCase(),t=Object.entries(Z).find(([t])=>e.startsWith(t));if(t)return t[1]}return Z.anthropic}function Je(){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
55
+ Recommendation: use iTerm2 (https://iterm2.com)`}:{label:`Terminal`,status:`ok`,message:e}}function Ye(e){let t=`Network (${e.host})`;return new Promise(n=>{let r=Date.now(),i=he({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 Xe(e,t={checkNetwork:Ye}){e.terminal.writeLine(`
56
+ robota diagnose
57
+ `);let n=qe(e.cwd),r=t.providerDefinitions??O(),i=t.env??process.env,a=[Ve(),He(e.version),Ue(e.cwd,r,i),...Ge(e.cwd),Je(),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(`
58
+ `);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`,Ze={permissions:{allow:[`Read(.robota/**)`,`Read(.claude/**)`,`Read(.agents/**)`],deny:[]}};function Qe(e){let t=L(e,`settings.json`);if(!j(t))return{};let n=N(t,`utf8`);try{return JSON.parse(n)}catch{return null}}var $e=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 $e(e);let r=await n.promptFn(`${e} [y/N] `);return r.toLowerCase()===`y`||r.toLowerCase()===`yes`}async function et(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=I(a),s=L(e,`AGENTS.md`),c=L(e,`.claude`),l=j(c),u=j(a),d=j(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={...Ze};if(l&&(t.writeLine(``),t.writeLine(`Detected .claude/ directory (Claude Code configuration).`),await $(`Migrate Claude Code settings to .robota/?`,!1,i))){let e=Qe(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:[...Ze.permissions.allow,...n?.allow??[]],deny:n?.deny??[]}},t.writeLine(`Settings imported from .claude/settings.json.`)}}M(o,{recursive:!0}),P(a,JSON.stringify(f,null,2)+`
59
+ `,`utf8`),t.writeLine(``),t.writeLine(`Created: .robota/settings.json`),P(s,`# AGENTS.md — Project Agent Guidelines
47
60
 
48
- `):void 0}async function ke(e,n,r,i,a,o,s,c){let l=n.positional.join(` `).trim();if(!l&&!process.stdin.isTTY){let e=[];for await(let t of process.stdin)e.push(t);l=Buffer.concat(e).toString(`utf-8`).trim()}l||(process.stderr.write(`Print mode (-p) requires a prompt argument.
49
- `),process.exit(1));let u=Oe(e,n),d=new t({cwd:e,provider:r,outputFormat:n.outputFormat??`text`,permissionMode:n.permissionMode??`bypassPermissions`,maxTurns:n.maxTurns,sessionStore:n.noSessionPersistence?void 0:i,sessionName:n.sessionName,bare:n.bare||void 0,allowedTools:n.allowedTools?n.allowedTools.split(`,`).map(e=>e.trim()).filter(e=>e.length>0):void 0,appendSystemPrompt:u,...n.systemPrompt?{systemPrompt:n.systemPrompt}:{},backgroundTaskRunners:a,subagentRunnerFactory:o,commandModules:s,commandHostAdapters:c});await d.run(l),process.exit(d.getExitCode())}async function Ae(t={}){let i;try{i=G()}catch(e){process.stderr.write(`${e instanceof Error?e.message:String(e)}\n`),process.exit(1)}let a=we();if(i.help){process.stdout.write(z());return}if(i.version){process.stdout.write(`robota ${a}\n`);return}if(i.checkUpdate){let e=await o({currentVersion:a,force:!0}),t=l(e);e.status===`error`&&(process.stderr.write(`${t}\n`),process.exit(1)),process.stdout.write(`${t}\n`);return}let d=process.cwd(),f=new n;if(i.reset){Te(f);return}if(i.positional[0]===`session`&&i.positional[1]===`analyze`){await Ce(process.argv.slice(4));return}try{if(await me(i,d,f))return}catch(e){f.writeError(e instanceof Error?e.message:String(e)),process.exit(1)}let{commandHostAdapters:m,providerDefinitions:h,commandModules:_,startupUpdateNoticePromise:v}=Ee(d,i,t,a);if(i.configure){await ue(d,i,r,f,h);return}if(ce(d,i,f,h))return;try{await le(d,i,r,f,h)}catch(e){process.stderr.write(`${e instanceof Error?e.message:String(e)}\n`),process.exit(1)}let y=i.provider?{providerOverride:i.provider,providerDefinitions:h}:{providerDefinitions:h},x=g(d,y),S=i.model??x.model,C=c(d,i.model,y),w=oe(),T=p(d),E=se({workerPath:M(),providerConfig:{...x,model:S},logsDir:T.logs}),D=s(d),O,k=!1;if(i.continueMode?O=ee(D,d):i.resumeId!==void 0&&(i.resumeId===``?k=!0:(O=b(D,i.resumeId),O===void 0&&(process.stderr.write(`Session not found: ${i.resumeId}\n`),process.exit(1)))),i.printMode){await ke(d,i,C,D,w,E,_,m);return}await ie({cwd:d,provider:C,providerOverride:i.provider,providerType:x.name,modelId:S,language:i.language,permissionMode:i.permissionMode,maxTurns:i.maxTurns,version:a,sessionStore:i.noSessionPersistence?void 0:D,resumeSessionId:O,showSessionPickerOnStart:k,forkSession:i.forkSession,sessionName:i.sessionName,backgroundTaskRunners:w,subagentRunnerFactory:E,commandModules:_,commandHostAdapters:m,shellExec:t=>e(t,{timeout:5e3,encoding:`utf-8`,stdio:`pipe`}).trimEnd(),startupUpdateNotice:v?v.then(e=>e?u(e):void 0):void 0,transportRegistry:ae(),cliAdapter:re({providerDefinitions:h,reloadPluginCommandSource:j}),reloadPluginCommandSource:j,agentName:`robota-cli`}),process.exit(0)}export{Ae as startCli};
61
+ This file guides the AI agent working in this project. Customize it for your project.
62
+
63
+ ## Project Overview
64
+
65
+ <!-- Describe your project's purpose, tech stack, and key conventions -->
66
+
67
+ ## Common Commands
68
+
69
+ \`\`\`bash
70
+ # Install dependencies
71
+ npm install
72
+
73
+ # Run tests
74
+ npm test
75
+
76
+ # Build
77
+ npm run build
78
+ \`\`\`
79
+
80
+ ## Coding Conventions
81
+
82
+ - Language: <!-- e.g. TypeScript strict mode -->
83
+ - Test framework: <!-- e.g. Vitest, Jest -->
84
+ - Linting: <!-- e.g. ESLint with prettier -->
85
+
86
+ ## Important Notes
87
+
88
+ <!-- Anything the agent should know before making changes -->
89
+ `,`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 tt(e=w().onboarded){return!j(e)}function nt(e=w().onboarded){M(I(e),{recursive:!0}),P(e,new Date().toISOString())}const rt=`
90
+ ╭─────────────────────────────────────────────────────────────╮
91
+ │ Welcome to ${Q}! — AI coding assistant │
92
+ │ │
93
+ │ Try asking: │
94
+ │ "Explain this project structure" │
95
+ │ "Find files with TODO comments" │
96
+ │ "Run tests and analyze failures" │
97
+ │ "What changed recently in git?" │
98
+ │ │
99
+ │ Useful commands: │
100
+ │ /help show all slash commands │
101
+ │ /cost show token usage and estimated cost │
102
+ │ /clear clear conversation history │
103
+ │ │
104
+ │ ${Q} diagnose — check your setup │
105
+ ╰─────────────────────────────────────────────────────────────╯
106
+ `;function it(e){e.writeLine(rt)}function at(e){process.platform===`darwin`&&process.env.TERM_PROGRAM===`Apple_Terminal`&&e.writeError(`
107
+ ⚠ macOS Terminal.app detected: CJK/IME input may be unstable.
108
+ Recommended: use iTerm2 (https://iterm2.com) for Korean/Japanese/Chinese input.
109
+ Or use headless mode: robota -p "your prompt"
110
+ `)}function ot(e,t,n,r){let i={settings:{read:()=>y(m()),write:e=>T(m(),e)},plugin:ne(e)},a=n.providerDefinitions??O();return{commandHostAdapters:i,providerDefinitions:a,commandModules:[...k({cwd:e,providerDefinitions:a,providerSettingsAdapter:{readMergedSettings:()=>g(e),readTargetSettings:()=>y(x(e)),writeTargetSettings:t=>T(x(e),t)}}),...n.commandModules??[]],startupUpdateNoticePromise:C(t)?p({currentVersion:r}):void 0}}function st(e,t){let n=N(pe(e,t),`utf8`).trim();if(n.length===0)throw Error(`Task file is empty: ${t}`);return`Task file (${t}):\n${n}`}function ct(e,t){let n=[];if(t.appendSystemPrompt&&n.push(t.appendSystemPrompt),t.taskFile)try{n.push(st(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(`
111
+
112
+ `):void 0}async function lt(e,n,r,i,a,o,s,c,l={}){let u=n.positional.join(` `).trim();if(!u&&!process.stdin.isTTY){let e=[];for await(let t of process.stdin)e.push(t);u=Buffer.concat(e).toString(`utf-8`).trim()}u||(process.stderr.write(`Print mode (-p) requires a prompt argument.
113
+ `),process.exit(1));let d=ct(e,n),f=new t({cwd:e,provider:r,outputFormat:n.outputFormat??`text`,permissionMode:n.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:B(n.allowedTools),deniedTools:B(n.deniedTools),appendSystemPrompt:d,...n.systemPrompt?{systemPrompt:n.systemPrompt}:{},backgroundTaskRunners:a,subagentRunnerFactory:o,commandModules:s,commandHostAdapters:c});await f.run(u),process.exit(f.getExitCode())}async function ut(t={}){if(process.argv[2]===`session`&&process.argv[3]===`analyze`){await X(process.argv.slice(4),process.cwd());return}let a;try{a=Se()}catch(e){process.stderr.write(`${e instanceof Error?e.message:String(e)}\n`),process.exit(1)}let o=Re();if(a.help){process.stdout.write(ge());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 Be(p,{yes:a.yes,isTTY:process.stdin.isTTY===!0});return}if(a.positional[0]===`diagnose`){let e=await Xe({version:o,terminal:p,cwd:f});process.exitCode=+(e>0);return}if(a.positional[0]===`session`&&a.positional[1]===`analyze`){await X(process.argv.slice(4),f);return}try{if(await Oe(a,f,p))return}catch(e){p.writeError(e instanceof Error?e.message:String(e)),process.exit(1)}let{commandHostAdapters:m,providerDefinitions:g,commandModules:_,startupUpdateNoticePromise:y}=ot(f,a,t,o);if(a.positional[0]===`init`){try{await et(f,p,{yes:a.yes,onProviderSetup:async()=>{await H(f,a,r,p,g)}})}catch(e){p.writeError(e instanceof Error?e.message:String(e)),process.exit(1)}return}if(a.configure){await H(f,a,r,p,g);return}if(Ce(f,a,p,g))return;try{await we(f,a,r,p,g)}catch(e){process.stderr.write(`${e instanceof Error?e.message:String(e)}\n`),process.exit(e instanceof i&&a.printMode?3:1)}let b=a.provider?{providerOverride:a.provider,providerDefinitions:g}:{providerDefinitions:g},x=v(f,b),S=a.model??x.model;if(x.source===`env-default`&&x.sourceEnvVar!==void 0){let e=`Using ${x.name} (${S}) via ${x.sourceEnvVar} — run \`robota --configure\` to persist a profile.\n`;a.printMode?process.stderr.write(e):p.writeLine(e.trimEnd())}let C=l(f,a.model,b),w=le(),T=h(f),E=ue({workerPath:de(),providerConfig:{...x,model:S},logsDir:T.logs}),D=c(f),O,k=!1;if(a.continueMode?O=ee(D,f):a.resumeId!==void 0&&(a.resumeId===``?k=!0:(O=te(D,a.resumeId),O===void 0&&(process.stderr.write(`Session not found: ${a.resumeId}\n`),process.exit(1)))),a.printMode){await lt(f,a,C,D,w,E,_,m,{resumeSessionId:O,forkSession:a.forkSession});return}at(p),tt()&&(it(p),nt()),await se({cwd:f,provider:C,providerOverride:a.provider,providerType:x.name,modelId:S,language:a.language,permissionMode:a.permissionMode,maxTurns:a.maxTurns,allowedTools:B(a.allowedTools),deniedTools:B(a.deniedTools),version:o,sessionStore:a.noSessionPersistence?void 0:D,resumeSessionId:O,showSessionPickerOnStart:k,forkSession:a.forkSession,sessionName:a.sessionName,backgroundTaskRunners:w,subagentRunnerFactory:E,commandModules:_,commandHostAdapters:m,shellExec:t=>e(t,{timeout:5e3,encoding:`utf-8`,stdio:`pipe`}).trimEnd(),startupUpdateNotice:y?y.then(e=>e?d(e):void 0):void 0,transportRegistry:ce(),cliAdapter:oe({providerDefinitions:g,reloadPluginCommandSource:A}),reloadPluginCommandSource:A,agentName:`robota-cli`}),process.exit(0)}export{ut as startCli};
50
114
  //# sourceMappingURL=index.js.map