@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.
- package/README.md +1 -1
- package/bin/robota.cjs +0 -8
- package/dist/node/bin.js +78 -14
- package/dist/node/bin.js.map +1 -1
- package/dist/node/index.cjs +77 -13
- package/dist/node/index.d.ts.map +1 -1
- package/dist/node/index.js +77 -13
- package/dist/node/index.js.map +1 -1
- package/dist/web/assets/index-BY1oA5Bi.js +37 -0
- package/dist/web/assets/index-DiahfakU.css +2 -0
- package/dist/web/assets/index-Dt0ve2tr.js +37 -0
- package/dist/web/index.html +13 -0
- package/package.json +20 -20
package/README.md
CHANGED
|
@@ -51,7 +51,7 @@ volta install node@22
|
|
|
51
51
|
## Demo
|
|
52
52
|
|
|
53
53
|
<!-- TODO: Add demo GIF here -->
|
|
54
|
-
<!-- Run `pnpm demo:record` to capture a demo recording — see docs/
|
|
54
|
+
<!-- Run `pnpm demo:record` to capture a demo recording — see docs/DEMO-SCRIPT.md for instructions -->
|
|
55
55
|
|
|
56
56
|

|
|
57
57
|
|
package/bin/robota.cjs
CHANGED
|
@@ -29,14 +29,6 @@ if (nodeMajor < REQUIRED_NODE_MAJOR) {
|
|
|
29
29
|
process.exit(1);
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
if (process.env.TERM_PROGRAM === 'Apple_Terminal') {
|
|
33
|
-
process.stderr.write(
|
|
34
|
-
'\n ⚠️ Warning: macOS Terminal.app detected.\n' +
|
|
35
|
-
' CJK input (Korean/Chinese/Japanese) may cause crashes.\n' +
|
|
36
|
-
' Recommended: use iTerm2 or another terminal emulator.\n\n',
|
|
37
|
-
);
|
|
38
|
-
}
|
|
39
|
-
|
|
40
32
|
// Load ESM main entry only after synchronous checks pass.
|
|
41
33
|
// CJS can dynamic-import ESM in Node.js 12+. This is the only way to load
|
|
42
34
|
// an ESM module from CJS — eslint-disable is intentional and required.
|
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{
|
|
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 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`
|
|
4
4
|
Usage: robota [options] [-p <prompt>]
|
|
5
5
|
|
|
6
6
|
Options:
|
|
@@ -20,13 +20,21 @@ Options:
|
|
|
20
20
|
--bare Print mode: output raw text only, no formatting wrapper
|
|
21
21
|
--configure Run interactive provider configuration
|
|
22
22
|
--configure-provider <n> Configure a specific provider
|
|
23
|
-
--
|
|
23
|
+
--allowed-tools <list> Comma-separated tool allowlist (TUI and print mode)
|
|
24
|
+
--denied-tools <list> Comma-separated tool denylist (TUI and print mode)
|
|
25
|
+
--model <model> Model override for this run
|
|
26
|
+
--json-schema <schema> Print mode: instruct the model to respond with JSON matching this schema
|
|
27
|
+
--dry-run Alias for --permission-mode plan (plan only, no execution)
|
|
28
|
+
--reset Delete ~/.robota/settings.json (provider profiles and preferences).
|
|
29
|
+
Asks for confirmation; use --yes to skip
|
|
30
|
+
--yes Skip confirmation prompts (required for --reset in non-TTY)
|
|
24
31
|
--check-update Check for CLI updates
|
|
25
32
|
--version Show version number
|
|
26
33
|
-h, --help Show this help message
|
|
27
34
|
|
|
28
35
|
Commands:
|
|
29
36
|
robota init Initialize AGENTS.md and .robota/settings.json
|
|
37
|
+
robota diagnose Check setup and print a diagnostics report
|
|
30
38
|
|
|
31
39
|
Examples:
|
|
32
40
|
robota Start interactive TUI session
|
|
@@ -35,24 +43,80 @@ Examples:
|
|
|
35
43
|
robota -p "Hello" --output-format json
|
|
36
44
|
robota -p "Review this diff" --bare Raw output for shell pipelines
|
|
37
45
|
robota --task-file task.md Run task from file (appended to system prompt)
|
|
38
|
-
robota
|
|
46
|
+
robota -p "Refactor the auth module" --dry-run Plan only, no execution
|
|
39
47
|
robota --continue Resume the last session
|
|
40
|
-
`}function B(e){if(e!==void 0){if(!
|
|
41
|
-
`)}function
|
|
42
|
-
`)}function
|
|
43
|
-
`)}function
|
|
44
|
-
`);return}if(
|
|
45
|
-
`),process.exit(1));let i=
|
|
48
|
+
`}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(`
|
|
49
|
+
`)}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(`
|
|
50
|
+
`)}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(`
|
|
51
|
+
`)}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)+`
|
|
52
|
+
`);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.
|
|
53
|
+
`),process.exit(1));let i=Le(t);process.stdout.write(Pe(i)+`
|
|
46
54
|
`);return}let i=r[r.length-1];i||(process.stderr.write(`No sessions found.
|
|
47
|
-
`),process.exit(1));let a=
|
|
48
|
-
`)}const
|
|
55
|
+
`),process.exit(1));let a=G(U(i));process.stdout.write(J(a)+`
|
|
56
|
+
`)}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
|
|
57
|
+
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(`
|
|
58
|
+
robota diagnose
|
|
59
|
+
`);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(`
|
|
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`,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)+`
|
|
61
|
+
`,`utf8`),t.writeLine(``),t.writeLine(`Created: .robota/settings.json`),P(s,`# AGENTS.md — Project Agent Guidelines
|
|
49
62
|
|
|
50
|
-
|
|
51
|
-
|
|
63
|
+
This file guides the AI agent working in this project. Customize it for your project.
|
|
64
|
+
|
|
65
|
+
## Project Overview
|
|
66
|
+
|
|
67
|
+
<!-- Describe your project's purpose, tech stack, and key conventions -->
|
|
68
|
+
|
|
69
|
+
## Common Commands
|
|
70
|
+
|
|
71
|
+
\`\`\`bash
|
|
72
|
+
# Install dependencies
|
|
73
|
+
npm install
|
|
74
|
+
|
|
75
|
+
# Run tests
|
|
76
|
+
npm test
|
|
77
|
+
|
|
78
|
+
# Build
|
|
79
|
+
npm run build
|
|
80
|
+
\`\`\`
|
|
81
|
+
|
|
82
|
+
## Coding Conventions
|
|
83
|
+
|
|
84
|
+
- Language: <!-- e.g. TypeScript strict mode -->
|
|
85
|
+
- Test framework: <!-- e.g. Vitest, Jest -->
|
|
86
|
+
- Linting: <!-- e.g. ESLint with prettier -->
|
|
87
|
+
|
|
88
|
+
## Important Notes
|
|
89
|
+
|
|
90
|
+
<!-- Anything the agent should know before making changes -->
|
|
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&&(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=`
|
|
92
|
+
╭─────────────────────────────────────────────────────────────╮
|
|
93
|
+
│ Welcome to ${Q}! — AI coding assistant │
|
|
94
|
+
│ │
|
|
95
|
+
│ Try asking: │
|
|
96
|
+
│ "Explain this project structure" │
|
|
97
|
+
│ "Find files with TODO comments" │
|
|
98
|
+
│ "Run tests and analyze failures" │
|
|
99
|
+
│ "What changed recently in git?" │
|
|
100
|
+
│ │
|
|
101
|
+
│ Useful commands: │
|
|
102
|
+
│ /help show all slash commands │
|
|
103
|
+
│ /cost show token usage and estimated cost │
|
|
104
|
+
│ /clear clear conversation history │
|
|
105
|
+
│ │
|
|
106
|
+
│ ${Q} diagnose — check your setup │
|
|
107
|
+
╰─────────────────────────────────────────────────────────────╯
|
|
108
|
+
`;function it(e){e.writeLine(rt)}function at(e){process.platform===`darwin`&&process.env.TERM_PROGRAM===`Apple_Terminal`&&e.writeError(`
|
|
109
|
+
⚠ macOS Terminal.app detected: CJK/IME input may be unstable.
|
|
110
|
+
Recommended: use iTerm2 (https://iterm2.com) for Korean/Japanese/Chinese input.
|
|
111
|
+
Or use headless mode: robota -p "your prompt"
|
|
112
|
+
`)}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(`
|
|
113
|
+
|
|
114
|
+
`):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.
|
|
115
|
+
`),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)}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(`
|
|
52
116
|
[robota] CJK/IME input error — this is a known issue with macOS Terminal.app.
|
|
53
117
|
Workaround: use iTerm2 (https://iterm2.com) or input your prompt in English.
|
|
54
118
|
Alternatively, use headless mode: robota -p "your prompt here"
|
|
55
119
|
|
|
56
|
-
`);return}throw e}),
|
|
120
|
+
`);return}throw e}),ut().catch(e=>{let t=e instanceof Error?e.message:String(e);process.stderr.write(t+`
|
|
57
121
|
`),process.exit(1)});export{};
|
|
58
122
|
//# sourceMappingURL=bin.js.map
|