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