@x-otto/cli 0.0.1-alpha.48 → 0.0.1-alpha.49
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/dist/build-id-DxfuzdUE.js +3 -0
- package/dist/build-id-DxfuzdUE.js.map +1 -0
- package/dist/{command-dispatcher-3YDdxUmQ.js → command-dispatcher-DTOPjtZP.js} +2 -2
- package/dist/{command-dispatcher-3YDdxUmQ.js.map → command-dispatcher-DTOPjtZP.js.map} +1 -1
- package/dist/{feedback-BRLKEYTv.js → feedback-DvWUvSc4.js} +2 -2
- package/dist/{feedback-BRLKEYTv.js.map → feedback-DvWUvSc4.js.map} +1 -1
- package/dist/feedback-DzPLfcfN.js +2 -0
- package/dist/index.js +3 -3
- package/dist/{parse-cli-Db5-pOBi.js → parse-cli-BvcxTK88.js} +2 -2
- package/dist/{parse-cli-Db5-pOBi.js.map → parse-cli-BvcxTK88.js.map} +1 -1
- package/dist/{version-B7PT-AT4.js → version-BrSIyY6s.js} +2 -2
- package/dist/{version-B7PT-AT4.js.map → version-BrSIyY6s.js.map} +1 -1
- package/package.json +17 -17
- package/dist/build-id-fGNO3KbG.js +0 -3
- package/dist/build-id-fGNO3KbG.js.map +0 -1
- package/dist/feedback-CF8BZkwa.js +0 -2
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{n as e,t}from"./build-id-
|
|
2
|
+
import{n as e,t}from"./build-id-DxfuzdUE.js";import{t as n}from"./create-host-app-BXQ8bU-B.js";import{platform as r,release as i}from"node:os";import{execFile as a}from"node:child_process";import{openBrowser as o}from"@x-otto/shared";import{SDK_VERSION as s}from"@x-otto/env";import{promisify as c}from"node:util";const l=c(a);function u(e){let t=e.trim().replace(/\.git$/,``),n=t.match(/^git@[^:]+:(.+)$/);if(n)return n[1];let r=t.match(/^https?:\/\/[^/]+\/(.+)$/);if(r)return r[1]}async function d(e){try{let{stdout:t}=await l(`git`,[`remote`,`get-url`,`origin`],{cwd:e,timeout:5e3});return u(t)}catch{return}}async function f(e){return e.configuredRepo?e.configuredRepo:await d(e.cwd)||e.cliRepoArg}function p(n){return[`- otto version: ${s} (build ${e}, ${t}@dev)`,`- Node: ${process.version}`,`- OS: ${r()} ${process.arch} ${i()}`,`- Model: ${n??`(none configured)`}`].join(`
|
|
3
3
|
`)}function m(e){let t,n,r,i,a,o=!1,s=(t,n)=>{let r=e[t+1];if(r===void 0||r.startsWith(`--`))throw Error(`${n} requires a value`);return r};for(let c=0;c<e.length;c++){let l=e[c];l===`--title`?(t=s(c,`--title`),c++):l===`--reproduce`?(n=s(c,`--reproduce`),c++):l===`--expected`?(r=s(c,`--expected`),c++):l===`--actual`?(i=s(c,`--actual`),c++):l===`--repo`?(a=s(c,`--repo`),c++):l===`--browser`&&(o=!0)}return{title:t,reproduce:n,expected:r,actual:i,repo:a,browser:o}}function h(e){e(`Usage: otto feedback --title <title> [options]
|
|
4
4
|
|
|
5
5
|
Report an issue or send feedback via GitHub (non-interactive — for scripting/CI).
|
|
@@ -18,4 +18,4 @@ Options:
|
|
|
18
18
|
`),1;let n=await f({configuredRepo:s.settings.get(`feedback_repo`),cliRepoArg:a.repo,cwd:t.projectDir??process.cwd()});if(!n)return i(`otto feedback: could not resolve a target repository — pass --repo or set "feedback_repo" in .otto/config.json
|
|
19
19
|
`),1;let c=p(void 0),l={title:a.title,reproduce:a.reproduce,expected:a.expected,actual:a.actual,envInfo:c,repo:n};if(!a.browser&&e.submitIssueViaGh){let t=await e.submitIssueViaGh(l);if(t.ok)return r(`Issue created: ${t.url}\n`),0;i(`otto feedback: gh channel failed (${t.kind}) — falling back to browser\n`)}let u=e.buildIssueUrl?.(l);return u?(o(u),r(`Opened: ${u}\n`),0):(i(`otto feedback: feedback plugin does not support buildIssueUrl
|
|
20
20
|
`),1)}finally{await s.stop()}}export{f as n,g as r,p as t};
|
|
21
|
-
//# sourceMappingURL=feedback-
|
|
21
|
+
//# sourceMappingURL=feedback-DvWUvSc4.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"feedback-
|
|
1
|
+
{"version":3,"file":"feedback-DvWUvSc4.js","names":["BUILD_ID"],"sources":["../src/commands/feedback.ts"],"sourcesContent":["/**\n * /feedback 命令的 TUI 接线层(提交/展示)。\n */\nimport { execFile } from 'node:child_process'\nimport { promisify } from 'node:util'\nimport { platform, release } from 'node:os'\nimport { SDK_VERSION } from '@x-otto/env'\nimport { BUILD_ID, BUILD_BRANCH, BUILD_HASH } from '../build-id'\nimport { createHostApp } from '../create-host-app'\nimport type { App } from '@x-otto/coding'\nimport { openBrowser } from '@x-otto/shared'\n\nconst execFileAsync = promisify(execFile)\n\n/** git remote origin URL → `owner/repo`(支持 `git@github.com:owner/repo.git` 与 `https://github.com/owner/repo.git` 两种形态)。 */\nfunction parseOwnerRepoFromGitUrl(url: string): string | undefined {\n const trimmed = url.trim().replace(/\\.git$/, '')\n const sshMatch = trimmed.match(/^git@[^:]+:(.+)$/)\n if (sshMatch) return sshMatch[1]\n const httpsMatch = trimmed.match(/^https?:\\/\\/[^/]+\\/(.+)$/)\n if (httpsMatch) return httpsMatch[1]\n return undefined\n}\n\n/** `git remote get-url origin` 解析当前工作目录的 owner/repo;非 git 仓库/无 origin 时返回 undefined(fail-soft,不抛出)。 */\nasync function resolveGitRemoteRepo(cwd: string): Promise<string | undefined> {\n try {\n const { stdout } = await execFileAsync('git', ['remote', 'get-url', 'origin'], { cwd, timeout: 5000 })\n return parseOwnerRepoFromGitUrl(stdout)\n } catch {\n return undefined\n }\n}\n\n/**\n * RFC-207 §3.4:目标仓库解析优先级——`feedback_repo` 配置 > git remote 解析 >\n * `--repo` 命令行参数。全部缺失时返回 `undefined`。\n */\nexport async function resolveFeedbackRepo(opts: {\n configuredRepo?: string\n cliRepoArg?: string\n cwd: string\n}): Promise<string | undefined> {\n if (opts.configuredRepo) return opts.configuredRepo\n const fromGit = await resolveGitRemoteRepo(opts.cwd)\n if (fromGit) return fromGit\n return opts.cliRepoArg\n}\n\n/**\n * RFC-207 §3.1 环境信息行(issue body 的\"环境信息\"小节,脱敏——只含版本/运行时/OS/\n * 模型,不含用户路径/环境变量等敏感信息)。\n */\nexport function buildFeedbackEnvInfo(modelId: string | undefined): string {\n return [\n `- otto version: ${SDK_VERSION} (build ${BUILD_ID}, ${BUILD_HASH}@${BUILD_BRANCH})`,\n `- Node: ${process.version}`,\n `- OS: ${platform()} ${process.arch} ${release()}`,\n `- Model: ${modelId ?? '(none configured)'}`,\n ].join('\\n')\n}\n\nexport interface FeedbackCommandDeps {\n stdout?: (s: string) => void\n stderr?: (s: string) => void\n projectDir?: string\n configPath?: string\n /** 测试注入:替代生产装配的 app(真实 App 类型——需要 feedbackRegistry/submitIssueViaGh,\n * 非 ServiceHostPort/AppContext 窄接口能覆盖,同 serve.ts 的 AppContext 注入模式不同)。 */\n app?: App\n}\n\nfunction parseFeedbackArgs(args: string[]): {\n title?: string\n reproduce?: string\n expected?: string\n actual?: string\n repo?: string\n browser: boolean\n} {\n let title: string | undefined\n let reproduce: string | undefined\n let expected: string | undefined\n let actual: string | undefined\n let repo: string | undefined\n let browser = false\n\n const takeValue = (i: number, name: string): string => {\n const raw = args[i + 1]\n if (raw === undefined || raw.startsWith('--')) {\n throw new Error(`${name} requires a value`)\n }\n return raw\n }\n\n for (let i = 0; i < args.length; i++) {\n const arg = args[i]\n if (arg === '--title') { title = takeValue(i, '--title'); i++ }\n else if (arg === '--reproduce') { reproduce = takeValue(i, '--reproduce'); i++ }\n else if (arg === '--expected') { expected = takeValue(i, '--expected'); i++ }\n else if (arg === '--actual') { actual = takeValue(i, '--actual'); i++ }\n else if (arg === '--repo') { repo = takeValue(i, '--repo'); i++ }\n else if (arg === '--browser') { browser = true }\n }\n\n return { title, reproduce, expected, actual, repo, browser }\n}\n\nfunction printFeedbackHelp(stdout: (s: string) => void): void {\n stdout(`Usage: otto feedback --title <title> [options]\n\nReport an issue or send feedback via GitHub (non-interactive — for scripting/CI).\nFor an interactive prompt-driven flow, use the \"/feedback\" command inside otto.\n\nOptions:\n --title <title> Short issue title (required)\n --reproduce <text> Steps to reproduce (optional)\n --expected <text> Expected behavior (optional)\n --actual <text> Actual behavior (optional)\n --repo <owner/repo> Target repository (defaults to feedback_repo config, then git remote origin)\n --browser Skip the gh CLI channel and always use the browser fallback\n --help Show this help\n`)\n}\n\n/**\n * `otto feedback` 非交互顶层子命令(RFC-207 §3.2/§3.4)——CI/脚本化调用场景,\n * `--title`/`--body` 系参数直接传参跳过 TUI openInput 链。复用与 `/feedback` 斜杠\n * 命令相同的核心逻辑(`resolveFeedbackRepo`/`buildFeedbackEnvInfo`)+ 同一个\n * `FeedbackRegistry`/插件实现(`app.feedbackRegistry`),两个入口不重复业务逻辑。\n */\nexport async function runFeedbackCommand(args: string[], deps: FeedbackCommandDeps = {}): Promise<number> {\n const stdout = deps.stdout ?? ((s) => process.stdout.write(s))\n const stderr = deps.stderr ?? ((s) => process.stderr.write(s))\n\n if (args[0] === 'help' || args[0] === '--help') {\n printFeedbackHelp(stdout)\n return 0\n }\n\n let parsed: ReturnType<typeof parseFeedbackArgs>\n try {\n parsed = parseFeedbackArgs(args)\n } catch (error) {\n stderr(`otto feedback: ${error instanceof Error ? error.message : String(error)}\\n`)\n return 1\n }\n\n if (!parsed.title) {\n stderr('otto feedback: --title is required (see --help)\\n')\n return 1\n }\n\n const app =\n deps.app ??\n createHostApp({\n logger: { name: 'otto-feedback', level: 'error', destination: 'stderr' },\n workspaceDir: deps.projectDir,\n projectConfigPath: deps.configPath,\n })\n\n try {\n await app.start()\n } catch (error) {\n stderr(`otto feedback: failed to start app: ${error instanceof Error ? error.message : String(error)}\\n`)\n return 1\n }\n\n try {\n const provider = app.feedbackRegistry.get()\n if (!provider) {\n stderr('otto feedback: feedback plugin is not available (disabled or not installed)\\n')\n return 1\n }\n\n const configuredRepo = app.settings.get('feedback_repo') as string | undefined\n const repo = await resolveFeedbackRepo({ configuredRepo, cliRepoArg: parsed.repo, cwd: deps.projectDir ?? process.cwd() })\n if (!repo) {\n stderr('otto feedback: could not resolve a target repository — pass --repo or set \"feedback_repo\" in .otto/config.json\\n')\n return 1\n }\n\n const envInfo = buildFeedbackEnvInfo(undefined)\n const input = {\n title: parsed.title,\n reproduce: parsed.reproduce,\n expected: parsed.expected,\n actual: parsed.actual,\n envInfo,\n repo,\n }\n\n if (!parsed.browser && provider.submitIssueViaGh) {\n const result = await provider.submitIssueViaGh(input)\n if (result.ok) {\n stdout(`Issue created: ${result.url}\\n`)\n return 0\n }\n stderr(`otto feedback: gh channel failed (${result.kind}) — falling back to browser\\n`)\n }\n\n const url = provider.buildIssueUrl?.(input)\n if (!url) {\n stderr('otto feedback: feedback plugin does not support buildIssueUrl\\n')\n return 1\n }\n openBrowser(url)\n stdout(`Opened: ${url}\\n`)\n return 0\n } finally {\n await app.stop()\n }\n}\n"],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{$ as e,A as t,B as n,C as r,D as i,E as a,F as o,G as s,H as c,I as l,J as u,K as d,L as f,M as p,N as m,O as h,P as g,Q as _,R as v,S as y,T as b,U as x,V as S,W as C,X as w,Y as ee,Z as T,_ as E,at as D,b as O,c as te,d as k,et as A,f as ne,i as j,it as M,j as N,k as P,l as F,m as I,n as re,nt as ie,o as L,p as R,q as ae,r as oe,rt as se,s as z,t as ce,tt as le,u as B,v as ue,w as V,x as de,y as H,z as fe}from"./command-dispatcher-
|
|
2
|
+
import{$ as e,A as t,B as n,C as r,D as i,E as a,F as o,G as s,H as c,I as l,J as u,K as d,L as f,M as p,N as m,O as h,P as g,Q as _,R as v,S as y,T as b,U as x,V as S,W as C,X as w,Y as ee,Z as T,_ as E,at as D,b as O,c as te,d as k,et as A,f as ne,i as j,it as M,j as N,k as P,l as F,m as I,n as re,nt as ie,o as L,p as R,q as ae,r as oe,rt as se,s as z,t as ce,tt as le,u as B,v as ue,w as V,x as de,y as H,z as fe}from"./command-dispatcher-DTOPjtZP.js";import{t as pe}from"./version-BrSIyY6s.js";import{n as U,t as me}from"./parse-cli-BvcxTK88.js";import{t as W}from"./discover-with-bundled-CF8qFP41.js";import{t as he}from"./create-host-app-BXQ8bU-B.js";import{n as G}from"./proxy-evg7ZvoD.js";import{r as ge}from"./registry-BdCcwyGy.js";import{homedir as K}from"node:os";import{execFile as _e,spawn as ve}from"node:child_process";import{SANDBOX_ESCALATION_MARKER as ye,apiCredentialId as be,buildPluginCliRegistry as xe,collectPluginThemePresets as Se,evaluatePluginTrust as Ce,evaluateWorkspaceTrustPrompt as we,expandCommandBody as Te,findPluginCliNameConflict as Ee,globalAgentJobRegistry as q,globalAgentObservability as J,globalProcessRegistry as Y,installEsbuildExitHook as De,installEsbuildSignalBridges as Oe,readTaskOutputTail as ke,resolvePluginCliBin as Ae,resolveSessionTitle as je,spawnPluginCli as Me,trustProject as Ne}from"@x-otto/coding";import{globalAgentJobRegistry as Pe,globalProcessRuntime as Fe,installExitReaper as Ie}from"@x-otto/runtime";import{buildAllowedEnv as Le,checkShellCommand as Re,createLogger as ze,markStartupPhase as Be,rankCandidates as X,setLogLevel as Ve,traceStartupPhase as He,traceStartupPhaseSync as Ue}from"@x-otto/shared";import{BUILD_ID as We,OTTO_HOME as Ge,OTTO_SESSIONS_DIR as Ke,SDK_VERSION as qe,flushEnvWarnings as Je,isShadowModeEnabled as Ye,loadUserIdentity as Xe}from"@x-otto/env";import{dirname as Ze,join as Z,resolve as Qe}from"node:path";import{existsSync as $e}from"node:fs";import{fileURLToPath as et}from"node:url";import{BASH_HISTFILE_SOURCE as tt,COMPACTING_SENTINEL as nt,FISH_HISTFILE_SOURCE as rt,ZSH_HISTFILE_SOURCE as it,createBuiltinThemeRegistry as at,entriesToCommands as ot,formatAgentDiagnosticsText as st,formatTranscriptText as ct,formatTurnTimeline as lt,i18next as Q,isUsingOverage as ut,observationLiveFields as dt,observationRow as ft,parseBashHistory as pt,parseFishHistory as mt,parseZshHistory as ht,promptParentWorkspaceChoice as gt,promptWorkspaceTrust as _t,setMarkdownThemeUserOverrides as vt,subagentEntryStatus as yt}from"@x-otto/tui";import{access as bt,mkdir as xt,readFile as St,readdir as Ct,rename as wt,stat as Tt,unlink as Et,writeFile as Dt}from"node:fs/promises";import{createModelUsabilityGate as Ot}from"@x-otto/ai";import{ScheduleRegistry as kt,SchedulerService as At,createLocalFireOwnership as jt,createRemoteFireOwnership as Mt,createRemoteScheduleStore as Nt,createScheduleStore as Pt,parseCron as Ft}from"@x-otto/schedule";import{SESSION_RESUME_WINDOW_MESSAGES as It,createProjectorState as Lt,projectSessionEvent as Rt,resolveChoiceAnswer as zt,resolveTextAnswer as Bt,sandboxBypassCommand as Vt,shouldShowPulseSurvey as Ht}from"@x-otto/session-contract";function Ut(e=process.stdout){if(process.env.OTTO_TUI_SCOPED_VIEWPORT===`0`&&process.env.OTTO_TUI_CLEAR_ON_EXIT!==`0`&&e.isTTY)try{e.write(`\x1B[2J\x1B[3J\x1B[H`)}catch{}}function Wt(e=process.stdout){if(!e.isTTY)return;let t=e=>{try{e()}catch{}};t(()=>{e.write(`\x1B[?1049l`)}),t(()=>{e.write(`\x1B[?25h`)}),t(()=>{e.write(`\x1B[?1000l\x1B[?1002l\x1B[?1003l\x1B[?1006l`)}),t(()=>{process.stdin.isTTY&&typeof process.stdin.setRawMode==`function`&&process.stdin.setRawMode(!1)})}function Gt(e,t){return e||t}function Kt(e,t){return e===`pin`&&t?`unpin`:e}function qt(e,t){return e===`pause`&&t?`continue`:e}function Jt(e,t,n){let r=e.list().sort((e,t)=>e.name.localeCompare(t.name)),i=r.map(e=>` /${Kt(e.name,t)}${e.aliases?.length?` (${e.aliases.join(`, `)})`:``}`),a=Math.max(...i.map(e=>e.length)),o=[];for(let e=0;e<r.length;e++){let s=r[e],c=n[Kt(s.name,t)]??n[s.name]??s.description;o.push(`${i[e].padEnd(a)} — ${c}`)}return o.push(``,`Prefixes: !<cmd> run shell | @<file> read file`),o}function Yt(e,t,n,r,i=!1,a=!1){return e.list().filter(e=>e.name===`pause`?t||a:!0).map(e=>{let o=qt(Kt(e.name,i),a);return{name:o,description:r?.[o]??r?.[e.name]??e.description,disabled:t&&!n.has(e.name)&&e.name!==`abort`,sortKey:e.name,deprecated:e.deprecated}})}function Xt(e){for(let t of j)t.tuiHidden||t.envGate&&process.env[t.envGate]!==`1`||(e.has(t.name)&&e.unregister(t.name),e.register({name:t.name,description:t.description??t.name,aliases:t.aliases,deprecated:t.deprecated,type:`action`,source:`builtin`,execute:()=>``}))}function Zt(e){let{app:t,getTui:n}=e,r=[],i=()=>{for(let e of r)e();r=[]},a,o,s,c,l,u=()=>{a&&=(clearInterval(a),void 0),o&&=(q.retain(o,!1),void 0),l=void 0},d=()=>{s&&=(clearInterval(s),void 0),c&&=(J?.unpin(c),q.get(c)&&q.retain(c,!1),void 0)};return{clearBgSubs:i,stopBgOutputPoll:u,stopBgSubagentPoll:d,setBgUnsubs:e=>{r=e},handlers:{onBackgroundKill:e=>{if(q.get(e)){q.cancel(e);return}J.abort(e)||Y.kill(e)},onBackgroundApply:e=>{let r=n(),i=e=>r.messages.pushMessage({role:`assistant`,content:[{type:`text`,text:e}]}),a=t.agentJobs.apply(e);if(a.applied){let n=a.forbiddenZone?.length?Q.t(`cmd.bgForbiddenZone`,{count:a.forbiddenZone.length,files:a.forbiddenZone.join(`
|
|
3
3
|
`),id:e}):``;i(Q.t(`cmd.bgJobApplied`,{id:e,message:a.message,zone:n})),a.capabilityTouched&&t.reloadCapabilities().then(e=>{r.plugins.setPluginRegistrations(t.getPluginRegistrations()),r.info.showToast(Q.t(`cmd.titleReload`),Q.t(`cmd.reloadDone`,{mcpTools:e.mcpTools,models:e.models,agents:e.agents,teams:e.teams}))},e=>i(Q.t(`cmd.bgAutoReloadFailed`,{msg:e instanceof Error?e.message:String(e)})))}else{let t=a.conflictPaths.length?Q.t(`cmd.bgConflictFiles`,{joined:a.conflictPaths.join(`
|
|
4
4
|
`)}):``;i(Q.t(`cmd.bgJobIncomplete`,{id:e,status:a.status,message:a.message,conflicts:t}))}},onDelegateSupply:(e,n)=>{t.agentJobs.supply(e,n)},onBackgroundViewOutput:e=>{let t=n(),r=async()=>{let n=e=>{let n=`${e.status}|${e.text}|${e.responseText??``}|${e.diff??``}`;n!==l&&(l=n,t.stores.tasks.setBackgroundOutput(e))},r=q.get(e);if(r){let t=r.status===`running`||r.status===`needs_input`?`running`:r.status===`applied`?`exited`:r.status===`failed`?`failed`:`killed`,i=(r.status===`ready`||r.status===`applied`)&&r.diff?.trim()?r.diff:void 0;n({id:e,command:r.title,status:t,text:ke(r.outputPath,20),prompt:J.get(e)?.prompt,diff:i}),t!==`running`&&u();return}let i=J.get(e);if(i){let t=x(J.getMessages(e)??[]),r=J.getStreamingText(e),a=ct(t,r),o=Date.now(),s=st(ft(i),o),c=lt(J.getTurns(e),o),l=[s.length?s.join(`
|
|
5
5
|
`):``,c.length?c.join(`
|
|
6
6
|
`):``].filter(Boolean).join(`\n${`─`.repeat(40)}\n\n`),d=i.status===`done`?`exited`:i.status===`error`||i.status===`aborted`?`failed`:`running`;n({id:e,command:`@${i.agentName}`,status:d,text:a,messages:t,streamText:r,responseText:l,prompt:i.prompt}),d!==`running`&&u();return}let a=Y.get(e);if(!a){u(),t.stores.tasks.setBackgroundOutput(null);return}let o=a.status===`running`?`running`:a.status===`exited`?`exited`:`killed`,s=``;if(a.logPath)try{s=(await St(a.logPath,`utf-8`)).split(`
|
|
7
7
|
`).slice(-20).join(`
|
|
8
|
-
`).trimEnd()}catch{s=``}n({id:e,command:a.command,status:o,text:s}),o!==`running`&&u()};u(),q.get(e)&&(q.retain(e,!0),o=e),a=setInterval(()=>{r()},500),r()},onBackgroundOutputClose:()=>{u()},onBackgroundSwitch:e=>{let t=n();d();let r=()=>{let n=J?.getMessages(e),r=J?.get(e),i=r?.agentName??``,a=q.get(e);a&&(i=a.title||i);let o=n?x(n):[],s=J?.getTurns(e),c=J?.getStreamingText(e),l=Date.now(),u={id:e,title:i,messages:o,status:a?.status??`running`,diagnostics:r?st(ft(r),l):[],timeline:s?lt(s,l):[],streamText:c};t.panes.switchToSubagentContext(u)};J?.pin(e),q.get(e)&&q.retain(e,!0),c=e,r(),s=setInterval(()=>{r()},500)},onBackgroundDelete:e=>{if(q.get(e)){q.remove(e);return}if(Y.get(e)){Y.remove(e);return}J.remove(e)},onSubagentExit:()=>{d(),n().panes.switchToSubagentContext(null)}}}}const Qt=ze(`@x-otto/cli:theme-preset-wiring`);function $t(e,t){let n={kind:`extension`,extensionId:t.pluginId};return e.register(n,{localId:t.localId,label:t.label,appearance:t.appearance,colors:t.colors,markdown:t.markdown})}function en(e,t){let n=[];for(let r of t)try{n.push($t(e,r))}catch(e){Qt.warn({pluginId:r.pluginId,localId:r.localId,err:String(e)},`theme preset registration failed, skipped`)}return n}function tn(e){let t=at();return en(t,Se(e.activePlugins())),t}function nn(e){let t=e??et(import.meta.url);t=Ze(t);let n=t===`/`?t:`/`;for(;t!==n;){try{if($e(t+`/.git`))return t}catch{}t=Ze(t)}try{if($e(n+`/.git`))return n}catch{}}var rn=class{repoRoot;currentBuildId;checkIntervalMs;onStale;logger;lastNotifiedBuildId=void 0;disposed=!1;timer;activeChild;constructor(e){this.repoRoot=e.repoRoot,this.currentBuildId=e.currentBuildId,this.checkIntervalMs=e.checkIntervalMs??6e5,this.onStale=e.onStale,this.logger=e.logger}start(){this.disposed||this.scheduleNext()}dispose(){if(this.disposed=!0,this.timer&&=(clearTimeout(this.timer),void 0),this.activeChild){try{this.activeChild.kill()}catch{}this.activeChild=void 0}this.lastNotifiedBuildId=void 0}scheduleNext(){this.disposed||(this.timer=setTimeout(()=>{this.timer=void 0,this.performCheck().then(()=>{this.scheduleNext()})},this.checkIntervalMs),this.timer.unref())}performCheck(){return new Promise(e=>{if(this.disposed){e();return}let t=_e(`git`,[`rev-list`,`--count`,`HEAD`],{cwd:this.repoRoot,timeout:5e3},(t,n)=>{if(this.activeChild=void 0,t){this.logger?.warn({err:t instanceof Error?t.message:String(t)},`[stale-build-detector] git rev-list failed`),e();return}let r=n.trim(),i=parseInt(r,10);if(!Number.isFinite(i)){this.logger?.warn({raw:r},`[stale-build-detector] failed to parse git output as number`),e();return}if(i>this.currentBuildId&&i!==this.lastNotifiedBuildId){this.lastNotifiedBuildId=i;try{this.onStale?.(i)}catch(e){this.logger?.warn({err:e instanceof Error?e.message:String(e)},`[stale-build-detector] onStale callback threw`)}}e()});this.activeChild=t,t.on(`error`,()=>{this.activeChild=void 0})})}};function an(e,t,n){return e-t<50?`dedup`:n.shellRunning?`kill-shell`:n.busy?n.stopDialogOpen?`escalate-exit`:`open-stop-dialog`:n.idleCtrlCCount+1>=2?`exit-process`:`hint-exit`}function on(e){let{getTui:t,getSession:n,dispatchAbort:r,clearTodoLayers:i,markUserAborted:a,resetCtrlCCount:o,markRestartRequested:s,stopTui:c,isBusy:l}=e,u=null,d=()=>u!==null&&t()?.info.getCurrentPath()===`/dialog/confirm`,f=()=>{a(),o(),r(),i()},p=e=>{e&&s(),a(),o();try{r()}catch{}c()},m=e=>{if(e===`abort`)return{title:Q.t(`confirm.abortConfirmTitle`),message:Q.t(`confirm.abortConfirmMessage`),confirmLabel:Q.t(`common.abortButton`),extraLabel:Q.t(`common.pauseButton`),onConfirm:()=>{f(),t()?.info.showToast(Q.t(`cmd.titleAborted`),Q.t(`cmd.runAborted`))}};let n=e===`exit-restart`;return{title:n?Q.t(`confirm.exitRestartConfirmTitle`):Q.t(`confirm.exitConfirmTitle`),message:Q.t(`confirm.exitConfirmMessage`),confirmLabel:n?Q.t(`common.abortAndRestartButton`):Q.t(`common.abortAndExitButton`),extraLabel:void 0,onConfirm:()=>{p(n)}}},h=e=>{let r=t();if(!r)return;let i=m(e);u=e,r.modal.openModal({kind:`confirm`,title:i.title,message:i.message,confirmLabel:i.confirmLabel,confirmColor:`amber`,extraLabel:i.extraLabel,extraColor:`accent`,dangerous:!0,onConfirm:()=>{u=null,i.onConfirm()},onCancel:()=>{u=null},onExtra:i.extraLabel?()=>{u=null,n().pauseRun()?t()?.info.showToast(Q.t(`cmd.titlePaused`),Q.t(`cmd.runWillPauseAfterTurn`)):t()?.info.showToast(Q.t(`cmd.titleInfo`),Q.t(`cmd.noRunningTaskToPause`))}:void 0})};return{requestStop:e=>{if(!t()){e===`abort`?f():p(e===`exit-restart`);return}if(e!==`abort`&&!l()){p(e===`exit-restart`);return}h(e)},isStopDialogOpen:d,escalateToExit:()=>{let e=t();!e||!d()||(h(`exit`),e.modal.resolveConfirm(!0))},abortNow:f}}var sn=class{entries=[];filePath;constructor(e,t=Z(Ge,`sessions`)){this.filePath=Z(t,`${e}.history.json`)}list(e){return this.entries.slice(-(e??100))}append(e){e.trim()&&(this.entries.push(e),this.entries.length>100&&(this.entries=this.entries.slice(-100)))}hydrate(e){this.entries=e.slice(-100)}async persist(){if(Ye())return;let e=JSON.stringify(this.entries,null,2),t=`${this.filePath}.tmp`;try{await xt(Ze(this.filePath),{recursive:!0}),await Dt(t,e,`utf-8`),await wt(t,this.filePath)}catch(e){throw await Et(t).catch(()=>{}),e}}async load(){try{let e=await St(this.filePath,`utf-8`),t=JSON.parse(e);return Array.isArray(t)&&t.every(e=>typeof e==`string`)?(this.entries=t.slice(-100),this.entries):[]}catch{return[]}}};const cn={[it]:e=>ht(e),[tt]:e=>pt(e),[rt]:e=>mt(e)};function ln(){let e=process.env.SHELL??``,t=K(),n=process.env.HISTFILE;return e.includes(`fish`)?[{id:rt,path:Z(t,`.local/share/fish/fish_history`)},{id:rt,path:Z(t,`.config/fish/fish_history`)}]:e.includes(`bash`)?[{id:tt,path:n?.startsWith(`~`)?Z(t,n.slice(2)):n??Z(t,`.bash_history`)}]:e.includes(`zsh`)||!e?[{id:it,path:n?.startsWith(`~`)?Z(t,n.slice(2)):n??Z(t,`.zsh_history`)}]:[]}function un(e){let t=e?.sources?.filter(e=>e?.enabled!==!1&&!!e?.id&&!!e?.path);if(t&&t.length>0){let e=K();return t.map(t=>({id:t.id,path:dn(t.path,e)}))}return ln()}function dn(e,t){return e.startsWith(`~/`)?Z(t,e.slice(2)):e===`~`?t:e}async function fn(e){try{return await bt(e),!0}catch{return!1}}async function pn(e,t){let n=cn[e.id];if(!n||!await fn(e.path))return[];try{return n(await St(e.path,`utf8`)).slice(-t)}catch{return[]}}async function mn(e){if(e?.enabled!==!0)return[];let t=e.maxEntries??2e3,n=un(e),r=new Set,i=[];for(let e of n){if(r.has(e.path))continue;r.add(e.path);let n=await pn(e,t);i.push(...n)}return i.slice(-t)}async function hn(e,t){let n=new sn(e.id);return{historyStore:n,inputHistory:await n.load().then(t=>{if(t.length>0)return t;let r=e.session.getInputHistory();return r&&r.length>0?(n.hydrate(r),n.persist().catch(()=>{}),e.session.setInputHistory([]),r):[]}),externalHistoryCommands:t?.enabled===!0?ot(await mn(t)):void 0}}async function gn(e,t,n){if(n){let n=t.settings.get(`model`);if(typeof n==`string`&&n&&e.model?.id!==n){let r=t.modelRegistry.find(n);r&&await t.providerRegistry.hasCredential(r.provider)&&(e.model=r,t.storage.memory?.reconfigure?.({contextWindow:r.contextWindow,maxOutput:r.maxOutputTokens}))}}{let n=t.settings.get(`thinking_level`),r=[`low`,`medium`,`high`,`xhigh`,`max`],i=n===`minimal`?`low`:n;typeof i==`string`&&r.includes(i)&&(e.thinkingLevel=i)}}async function _n(e,t){let n=`__otto_setup__`,r=e.settings.get(`permission_mode`);(r===void 0||r===`auto`)&&await e.settings.update({permission_mode:`confirm`}),e.modelRegistry.getAll().length===0&&e.modelRegistry.register({id:n,name:`Setup required`,provider:`otto`,api:`otto`,baseUrl:``,reasoning:!1,input:[`text`],contextWindow:32e3,maxOutputTokens:4e3});let i=t.continueSession?e.getSession(t.continueSession)??await e.sessionManager.restore(t.continueSession)??void 0:void 0,a=i?i.session.buildContext().messages.filter(e=>{let t=e.role;return t===`user`||t===`assistant`}).length:0,o={value:i?e.sessionManager.consumeCrashGap(i.id):void 0},s=t.continueSession?i?Q.t(`cmd.resumeRestored`,{idShort:t.continueSession.slice(0,8),count:a}):Q.t(`cmd.resumeNotFound`,{id:t.continueSession}):void 0,c=!!(t.continueSession&&i),l=!!(t.model||e.settings.get(`model`)||e.settings.get(`model_slots`)?.default),u={skip:!1},d=await e.hydrateModelCache().catch(()=>new Set),f=e.modelRegistry.getAll().every(e=>e.id===n),p=f?!1:l,m=e.modelRegistry.getAll().find(e=>e.id!==n)??e.modelRegistry.getAll()[0],h=i??await e.createSession({interactive:!0,retryAccelerate:u,...p?{}:{model:m}});await gn(h,e,!!i);let g=p||c,_={get value(){return g},set value(e){g=e}},v={models:e.modelRegistry.getAll().filter(e=>e.id!==n).map(e=>({id:e.id,name:e.name,provider:e.provider,api:e.api,strengths:e.strengths??[],contextWindow:e.contextWindow})),availableModelIds:new Set([...d,...e.getSessionAvailableModels(h.id)]),wasUnconfigured:!1};v.wasUnconfigured=v.availableModelIds.size===0;let y=()=>e.setSessionAvailableModels(h.id,[...v.availableModelIds]);y();let b=new B(k({modelRegistry:e.modelRegistry,authStore:e.authStore,settings:e.settings,selectedModelId:()=>h.model?.id,isModelUsable:Ot(e.authStore,`delegation`),isModelUsableInMainSession:Ot(e.authStore,`main-session`)})),x,S={get value(){return x},set value(e){x=e}},C=async t=>{let r=await e.refreshModels().catch(()=>[]);v.models=e.modelRegistry.getAll().filter(e=>e.id!==n).map(e=>({id:e.id,name:e.name,provider:e.provider,api:e.api,strengths:e.strengths??[],contextWindow:e.contextWindow}));for(let e of r)if(e.status===`ok`)for(let t of e.availableIds??[])v.availableModelIds.add(t);v.models.length>0&&e.modelRegistry.getAll().some(e=>e.id===n)&&e.modelRegistry.unregister(n),y();let i=v.availableModelIds.size===0,a=S.value;a?.stores?.tasks?.setNeedsSetup?.(i);let o=await b.refresh().catch(()=>null);if(o&&a?.stores?.tasks?.setFtueStage?.(o.stage),v.wasUnconfigured&&!i&&(v.wasUnconfigured=!1,a?.info?.showToast?.(Q.t(`cmd.titleSetupReady`),Q.t(`cmd.setupReadyMessage`))),t){let e=r.filter(e=>e.status===`ok`);t(e.length>0?Q.t(`cmd.modelsRefreshed`,{summary:e.map(e=>`${e.provider} ${e.total}`).join(` · `)}):Q.t(`cmd.modelsRefreshedEmpty`))}};return C(),{session:h,startupCrashGapRef:o,resumedNote:s,modelReadyRef:_,registryOnlyPlaceholder:f,firstRealModel:m,modelRefreshState:v,persistAvailable:y,ftueController:b,refreshModelsNow:C,tuiRefBox:S,SETUP_PLACEHOLDER_ID:n,continuedExisting:c,retryAccelerate:u,resumed:i,convoCount:a}}function vn(e){let t=[],n=0,r=``,i=()=>{r&&=(t.push(r),``)};for(;n<e.length;){let t=e[n];if(t===` `||t===` `){i(),n++;continue}if(t===`\\`){n++,n<e.length&&(r+=e[n]),n++;continue}if(t===`"`){n++;let t=yn(e,n,`"`);r+=t.value,n=t.next;continue}if(t===`'`){n++;let t=yn(e,n,`'`,!1);r+=t.value,n=t.next;continue}r+=t,n++}return i(),{tokens:t}}function yn(e,t,n,r=!0){let i=``,a=t;for(;a<e.length;){let t=e[a];if(r&&t===`\\`){a++,a<e.length&&(i+=e[a]),a++;continue}if(t===n)return a++,{value:i,next:a};i+=t,a++}return{value:i,next:a}}function bn(e){let t=e.trim();if(!t.startsWith(`/`)||t===`/`||t.startsWith(`//`))return{isCommand:!1,text:t};let{tokens:n}=vn(t.slice(1));if(n.length===0)return{isCommand:!1,text:t};let[r,...i]=n;return{isCommand:!0,command:r,args:i}}async function xn(e,t){let n=e;for(;n.type===`response`&&n.endReason===`max-tool-turns`&&n.notice;){if(!await t.askBudgetContinue()){t.onBudgetStopped();return}t.beforeContinuationTurn();let e=await t.runTurn(`Continue with the remaining work until the task is complete.`);if(t.onTurnResult(e)===`exit`)return;n=e}}const Sn=[{extensionId:`plugin-browser-use`,reasonKey:`capability.reasonWebApp`,detect:async e=>{let t=await e.packageDependencyNames();return[`react`,`vue`,`next`,`nuxt`,`svelte`,`vite`,`@angular/core`,`express`,`koa`,`fastify`].some(e=>t.has(e))?!0:e.hasFile(`index.html`)}},{extensionId:`plugin-mobile-use`,reasonKey:`capability.reasonMobile`,detect:async e=>{if(await e.hasFile(`AndroidManifest.xml`)||await e.hasFile(`build.gradle`)||await e.hasFile(`build.gradle.kts`)||await e.hasFile(`Info.plist`)||await e.hasFile(`Podfile`))return!0;let t=await e.packageDependencyNames();return t.has(`react-native`)||t.has(`expo`)}},{extensionId:`plugin-schedule`,reasonKey:`capability.reasonSchedule`,detect:async e=>{if(await e.hasFile(`crontab`))return!0;let t=await e.packageDependencyNames();return t.has(`node-cron`)||t.has(`node-schedule`)||t.has(`agenda`)}}];async function Cn(e,t,n=Sn){let r=[];for(let i of n){if(t.has(i.extensionId))continue;let n=!1;try{n=await i.detect(e)}catch{n=!1}n&&r.push({extensionId:i.extensionId,reasonKey:i.reasonKey})}return r}function wn(e,t,n,r){return{ts:r?.ts??Date.now(),sessionId:n,...r?.turn===void 0?{}:{turn:r.turn},kind:`lifecycle`,node:e,payload:t}}function Tn(e){let t=new Map;if(e?.role===`assistant`&&Array.isArray(e.content))for(let n of e.content)n.type===`tool_call`&&t.set(n.id,n);return t}async function En(e,t,n){let r,i=new Set,a=new Map,o=new Set,c=new Map;if(n){let n=await e.loadTailEntries(t,It);r=n.length>0?n[0].seq:0;for(let e of n)e.type===`message`&&i.add(e.seq)}else r=await e.getEntryCount(t);return{async loadEarlier(n=500){if(r<=0)return null;let l=await e.loadEntriesBefore(t,r,n);if(l.length===0)return null;let u=new Map,d=new Set;for(let e of l){if(e.type!==`message`)continue;let t=e.data;if(t?.role===`assistant`)for(let[e,n]of Tn(t))u.set(e,n);else t?.role===`tool_result`&&typeof t.toolCallId==`string`&&d.add(t.toolCallId)}let f=[],p=(e,t)=>({...e,id:`hist-${t}`,seq:t});for(let e of l){if(e.type===`clear`){r=0,f.length=0;continue}if(e.type!==`message`||i.has(e.seq))continue;let t=e.data;if(!t||typeof t.role!=`string`||t.internal)continue;if(t.role===`tool_result`){let n=a.get(t.toolCallId??``)??u.get(t.toolCallId??``);if(n){let r=n.arguments??{};f.push(p({role:`tool`,name:t.toolName||n.name||`tool`,args:C(r),argsObj:r,result:s(t.content),isError:t.isError},e.seq)),o.add(t.toolCallId)}else c.set(t.toolCallId,{toolName:t.toolName,content:t.content,isError:t.isError});continue}if(t.role===`assistant`){let n=Tn(t);if(n.size>0){let r=new Set([...d,...o,...c.keys()]),i=x([t],{resolvedIds:r});for(let t of i)f.push(p(t,e.seq));for(let[t,r]of n){if(d.has(t))continue;let n=c.get(t);if(n){c.delete(t);let i=r.arguments??{};f.push(p({role:`tool`,name:r.name,args:C(i),argsObj:i,result:s(n.content),isError:n.isError??!1},e.seq))}}continue}}let n=x([t]);for(let t of n)f.push(p(t,e.seq))}for(let[e,t]of u)a.set(e,t);return r>0&&(r=l[0].seq),f.length>0?f:null}}}function Dn(e){let{app:t,getTui:n,getTuiRef:r,getSession:i,getCliCtx:a,historyStore:o}=e;return{onCyclePermissionMode:()=>{let e=n(),r=ee(t.getPermissionMode());e.stores.tasks.setPermissionMode(r),e.info.showToast(Q.t(`cmd.titlePermission`),Q.t(`pref.permModeSwitched`,{label:Q.t(`pref.permModeLabel`,{context:r})})),t.setPermissionMode(r)},onHistoryPush:t=>{try{o.hydrate([...t]),o.persist().catch(()=>{})}catch{}e.getPasteBinder?.()?.save(i().id)},onDraftSave:e=>{let n=i(),a=n.session.getDrafts()??[],o=f(void 0,e,a),s=l([...a,o]);n.session.setDrafts(s),t.sessionManager.save(n.id).catch(()=>{}),r()?.stores.tasks.setDrafts(v(s))},onDraftDelete:e=>{let n=i(),a=(n.session.getDrafts()??[]).filter(t=>t.id!==e);n.session.setDrafts(a),t.sessionManager.save(n.id).catch(()=>{}),r()?.stores.tasks.setDrafts(v(a))},onDraftDeleteMany:e=>{let n=i(),a=new Set(e),o=(n.session.getDrafts()??[]).filter(e=>!a.has(e.id));n.session.setDrafts(o),t.sessionManager.save(n.id).catch(()=>{}),r()?.stores.tasks.setDrafts(v(o))},onA2uiAction:(e,t,n)=>{L(`a2ui-action`,n?[e,t,JSON.stringify(n)]:[e,t],a())},onPerfRefresh:()=>{L(`status`,[`perf`],a())},onProxySubmitUrl:e=>{L(`preference`,[`proxy`,e],a())},onProxyToggleEnabled:()=>{L(`preference`,[`proxy`,t.settings.get(`proxy`)?.enabled===!1?`on`:`off`],a())},onProxyClear:()=>{L(`preference`,[`proxy`,`clear`],a())},onProxyTest:()=>{L(`preference`,[`proxy`,`test`],a())}}}function On(e){return{...kn(e),pluginSource:e.pluginSource,intervalSeconds:e.errorRetryIntervalSeconds}}function kn(e){let{msg:t,provider:n,authError:r,isRefreshFailed:i,unsupported:a,rateLimit:o,rateLimitInfo:s,getErrorRetryAttempt:c,incErrorRetryAttempt:l,errorRetryMax:u,retryQueued:d,resetAndRetry:f,cancelRetry:p,switchModelThenRetry:m,goToAuth:h}=e;if(s)return s.resetsAt===void 0?{reason:t,attempt:0,max:u,mode:`manual`,limitType:s.limitType,actions:[{kind:`switchModel`,label:Q.t(`error.switchModel`),run:m},{kind:`retryNow`,label:Q.t(`retry.nowButton`),run:d}],onExpired:()=>{},onCancel:p}:{reason:t,attempt:0,max:u,mode:`resetsAt`,resetsAt:s.resetsAt,limitType:s.limitType,actions:[{kind:`retryNow`,label:Q.t(`error.retryNow`),run:d},{kind:`switchModel`,label:Q.t(`error.switchModel`),run:m}],onExpired:d,onCancel:p};if(r)return{reason:i?Q.t(`cmd.authRefreshFailed`,{ps:n?` (${n})`:``,ls:n?` ${n}`:``}):Q.t(`cmd.authFailed`,{ps:n?` (${n})`:``,ls:n?` ${n}`:``}),attempt:c(),max:u,mode:`manual`,actions:[{kind:`login`,label:Q.t(`model.goToLoginButton`),run:h},{kind:`switchModel`,label:Q.t(`error.switchModel`),run:m},{kind:`retryNow`,label:Q.t(`retry.nowButton`),run:d}],onExpired:()=>{},onCancel:p};if(a)return{reason:Q.t(`cmd.modelNotSupported`),attempt:c(),max:u,mode:`manual`,actions:[{kind:`switchModel`,label:Q.t(`error.switchModel`),run:m},{kind:`retryNow`,label:Q.t(`retry.nowButton`),run:d}],onExpired:()=>{},onCancel:p};let g=l(),_=g>u;return{reason:o?Q.t(`cmd.rateLimitedRetriesExhausted`):Q.t(`cmd.requestFailed`,{msg:t}),attempt:Math.min(g,u),max:u,mode:`auto`,exhausted:_,actions:[{kind:`retryNow`,label:Q.t(`retry.nowButton`),run:_?f:d}],onExpired:_?()=>{}:d,onCancel:p}}function An(e){let{err:n}=e,r=n instanceof Error?n.message:String(n),i=n?.code===`AGENT_ABORTED`||n instanceof Error&&n.name===`AbortError`;if(!(e.submitState.userAborted||i)){let i=e.provider,a=n?.code,o=n?.pluginSource,{authError:s,isRefreshFailed:c,unsupported:l,rateLimit:u,pluginSource:d}=ae(r,a,o),f=e.rateLimitInfoRef.current;e.rateLimitInfoRef.current=void 0;let p=(()=>{let t=e.cliCtx,n=t?.app?.storage?.traceStore,r=t?.state?.session;if(!n||!r)return null;let i=r.session.getTurnCount();return{traceStore:n,sessionId:r.id,...i===void 0?{}:{turn:i}}})(),m=()=>{p&&P(p,{attempt:e.errorRetryAttemptRef.current+1,max:e.ERROR_RETRY_MAX,mode:f?`resetsAt`:s||l?`manual`:`auto`,reason:r.slice(0,120)}),e.retryModeRef.current=!0;let t=e.latestSubmittedPromptRef?.current,n=e.tui.engine.takeLastQueuedFollowUp?.(),i=t!=null&&t.text!==e.text,a=i?t.text:n?.text??e.text,o=i?t.mode:n?.mode??e.mode;a===e.text&&!i&&n==null&&e.retryLastRound?.()||queueMicrotask(()=>e.handleSubmit?.(a,o,`send`))};e.tui.engine.showErrorRetry(On({msg:r,provider:i,authError:s,isRefreshFailed:c,unsupported:l,rateLimit:u,rateLimitInfo:f,pluginSource:d,getErrorRetryAttempt:()=>e.errorRetryAttemptRef.current,incErrorRetryAttempt:()=>++e.errorRetryAttemptRef.current,errorRetryMax:e.ERROR_RETRY_MAX,errorRetryIntervalSeconds:e.ERROR_RETRY_INTERVAL_SECONDS,retryQueued:m,resetAndRetry:()=>{p&&t(p),e.errorRetryAttemptRef.current=0,m()},cancelRetry:()=>{p&&h(p,{attempt:e.errorRetryAttemptRef.current}),e.errorRetryAttemptRef.current=0},switchModelThenRetry:()=>{e.handleModel([],e.cliCtx,{afterSwitch:m})},goToAuth:()=>{e.handleProviderAuth([i??``].filter(Boolean),e.cliCtx)}}))}}function jn(e){return e.trim().length===0}function Mn(e){let{tui:t,app:n,submitState:r}=e;return(e,i=`!!`)=>{let a=e.trim();if(!a)return;let o=Re(a);if(!o.safe){t.info.showToast(Q.t(`cmd.titleShell`),Q.t(`cmd.dangerousBlocked`,{reason:o.reason})),t.messages.pushMessage({role:`assistant`,content:[{type:`text`,text:Q.t(`cmd.dangerousBlockedDetail`,{reason:o.reason,cmd:a})}]});return}t.messages.echoUserInput(`${i} ${a}`),t.shell.startShellExecution(a),r.shellChild=ve(a,{shell:!0,cwd:n.workspaceDir,stdio:[`ignore`,`pipe`,`pipe`],env:Le()}),Fe.registerChild({command:a,args:[],owner:{type:`cli-shell`,id:`!!`},category:`shell`,lifecycle:`evictable`,cwd:n.workspaceDir},r.shellChild),r.shellChild.stdout.on(`data`,e=>{t.shell.appendShellOutput(e.toString(`utf-8`))}),r.shellChild.stderr.on(`data`,e=>{t.shell.appendShellOutput(e.toString(`utf-8`))}),r.shellChild.on(`close`,(e,n)=>{r.shellChild=null,n?t.shell.finishShellExecution(null,void 0,!0):t.shell.finishShellExecution(e)}),r.shellChild.on(`error`,e=>{r.shellChild=null,t.shell.finishShellExecution(null,`\nError: ${e.message}`)})}}function Nn(e){let{agentProcessingRef:t,tui:n,requestStop:r}=e;return(e,i)=>{let a=bn(e);return a.isCommand&&a.command.toLowerCase()===`abort`&&i===`send`?(t.value?r(`abort`):n.info.showToast(Q.t(`cmd.titleInfo`),Q.t(`cmd.noRunningTask`)),!0):!1}}function Pn(e){let{app:t,tui:n}=e;return async e=>{let r=e.trim();if(!r)return;if(!t.storage.autoMemory){n.info.showToast(Q.t(`cmd.titleMemory`),Q.t(`cmd.memoryDisabled`));return}let i=await N(r,process.env.OTTO_MEMORY_LLM_NAMING===`1`?t.completeText:void 0);await t.storage.autoMemory.record(i),n.messages.echoUserInput(`# ${r}`),n.messages.pushMessage({role:`assistant`,content:[{type:`text`,text:Q.t(`cmd.memorySaved`,{name:i.name})}]})}}function Fn(e){let t=e.terminated===!0?Q.t(`shell.askAiTerminated`):e.exitCode===null?Q.t(`shell.unknownError`):Q.t(`shell.exitCode`,{code:e.exitCode}),n=e.output.length>5e4?`${e.output.slice(0,5e4)}\n${Q.t(`shell.truncated`)}`:e.output;return Q.t(`shell.prompt`,{command:e.command,errorLabel:t,output:n})}function In(e,t){let n=e=>`${e.kind}\u0000${e.label}`,r=n(t);return[t,...e.filter(e=>n(e)!==r)].slice(0,5)}function Ln(e){return{label:e.label,value:e.value,kind:e.kind,description:e.description}}function Rn(e){return e.map(e=>({label:e.label,value:e.value,kind:e.kind,description:e.description,source:`recent`}))}async function zn(e){let{app:t,session:n,options:i,tuiRefBox:a,tuiRef:o,turn:s,projState:c,redState:l,isBusyNow:u,dispatchToEngine:d,stopController:f,finishInteractive:p,stopTuiGuarded:m,applyModel:h,ensureModelUsableForPrompt:g,refreshSlashCommands:_,fileCommands:b,modelReady:x,availableModelIds:S,currentModel:C,fmtDisplayModel:w,cfgLang:ee,themeRegistry:T,presetSelection:D,keybindingOverrides:O,continuedExisting:k,convoCount:A,historyStore:ne,inputHistory:j,externalHistoryCommands:M,bg:N,reg:P,slashCommands:ie,interactive:ae,handleExitRef:se,cliCtxRef:z,providerAuthRef:ce,handleAbortInterceptRef:le,runAsyncBashRef:B,runMemoryCaptureRef:ue,allCommandNames:de}=e;ce.current=e=>{I([e],z.current).catch(()=>{})};let H,pe=t.getResilienceConfig().errorRetry.maxAttempts;Be(`startTui() begin`);let U=performance.now(),me=F(await te(t.workspaceDir,{readdir:e=>Ct(e,{withFileTypes:!0})})).map(e=>Q.t(e));return{stdin:process.stdin,stdout:process.stdout,modelName:w(C),needsSetup:S.size===0,promptSuggestions:me,commands:ie,pluginInput:t.pluginInput,isImmediateCommand:e=>u()?oe.has(e):de.has(e),isInterruptCommand:e=>e===`abort`,isAgentBusy:u,isPaused:()=>n.isPaused,initialPath:k&&A>0?`/`:`/home`,shadow:t._shadow,welcome:{cwd:process.cwd(),version:qe,buildId:We,nickname:t.settings.get(`nickname`)||void 0,updateAvailable:void 0},onSessionSelect:e=>{L(`session`,[`resume`,e],z.current)},onInstallCapability:e=>{import(`./command-dispatcher-3YDdxUmQ.js`).then(e=>e.g).then(({runPluginInstall:t})=>t(e,z.current))},onDismissCapabilityRecommendations:()=>{o.value?.stores.tasks.dismissCapabilityRecommendations()},loadHistory:t.sessionRepoRef?.current?await(async()=>{let e=t.sessionRepoRef.current;if(!e)return;let r=await En(e,n.id,!!i.continueSession);return e=>r.loadEarlier(e.limit)})():void 0,language:ee,themeRegistry:T,presetSelection:D,keybindingOverrides:O,permissionMode:t.getPermissionMode(),onFocusChange:e=>t.setTerminalFocus(e),...N.handlers,initialHistory:j,externalHistoryCommands:M,residencyGovernor:t._residencyGovernor,resolveWholeFileDiff:async(e,n)=>{try{return await fe(Qe(t.workspaceDir,e),n)}catch(e){return{error:e instanceof Error?e.message:String(e)}}},initialDrafts:v(n.session.getDrafts()??[]),initialRecentMentions:Rn(t.settings.get(`recent_mentions`)??[]),onSigilSelect:e=>{let n=In(t.settings.get(`recent_mentions`)??[],Ln(e));t.settings.persist({recent_mentions:n}).catch(()=>{}),o.value?.stores.tasks.setRecentMentions(Rn(n))},...Dn({app:t,getTui:()=>a.value,getTuiRef:()=>o.value,getSession:()=>n,getCliCtx:()=>z.current,historyStore:ne,getPasteBinder:()=>z.current.callbacks.pasteBinder}),onQueueSendNow:(e,t)=>{if(t===`memory`){ue.current(e);return}if(t===`bash`||t===`bash_async`){B.current(e,t===`bash`?`!`:`!!`);return}H?.(e,`send`,u()?`steer`:`send`)},onSubmit:H=async(e,i,d)=>{if(s.ctrlCCount=0,d===`action`){await V(e,{currentModelId:n.model?.id,applyModel:h,onSwitchFailed:e=>a.value.info.showToast(Q.t(`cmd.titleModel`),e)}),r(e,{currentEffort:n.thinkingLevel,applyEffort:e=>E(z.current,e),onInvalidLevel:e=>a.value.info.showToast(Q.t(`cmd.titleEffort`),Q.t(`cmd.effortUnknown`,{arg:e,levels:y.join(` / `)}))});return}if(le.current(e,i))return;if(n.isPaused&&n.resumeRun(),d===`steer`&&n.isBusy){s.latestSubmittedPrompt={text:e,mode:i};let t=r(await V(e,{currentModelId:n.model?.id,applyModel:h,onSwitchFailed:e=>a.value.info.showToast(Q.t(`cmd.titleModel`),e)}),{currentEffort:n.thinkingLevel,applyEffort:e=>E(z.current,e),onInvalidLevel:e=>a.value.info.showToast(Q.t(`cmd.titleEffort`),Q.t(`cmd.effortUnknown`,{arg:e,levels:y.join(` / `)}))});if(jn(t))return;let{id:o}=n.steer(t);a.value.pending.setPendingSteer(t,o);return}if(i===`memory`){await ue.current(e);return}if(i===`bash`||i===`bash_async`){B.current(e,i===`bash`?`!`:`!!`);return}let f=bn(e),p=e,m=!1;if(f.isCommand){if(await L(f.command,f.args,z.current))return;t.firePluginActivationEvent?.(`onCommand:${f.command}`);let e=b.find(e=>e.name===f.command);e&&(m=!0,p=await Te(e.body,{args:f.args,workspaceDir:t.workspaceDir}))}let v=f.isCommand&&!m&&re.has(f.command.toLowerCase());if(!v&&!x&&(!f.isCommand||m)){a.value.info.showToast(Q.t(`cmd.titleSetupRequired`),Q.t(`cmd.noModelConfigured`));return}if(c.todoList.length>0&&c.todoList.every(e=>e.status===`done`||e.status===`skipped`||e.status===`failed`)&&(c.todoList=[],a.value.stores.tasks.setTasks([]),n.session.setTodoList([])),u()&&(!f.isCommand||m)){a.value.engine.enqueueFollowUp(e,i),a.value.info.showToast(Q.t(`cmd.titleInfo`),Q.t(`queue.dFollowUpToast`));return}if(!v){if(await g()===`abort`)return;a.value.engine.pushEngineEvent({kind:`agentProcessing`,value:!0}),s.agentProcessing=!0,a.value.plugins.setCommands(_())}if(s.userAborted=!1,p=await V(p,{currentModelId:n.model?.id,applyModel:h,onSwitchFailed:e=>a.value.info.showToast(Q.t(`cmd.titleModel`),e)}),p=r(p,{currentEffort:n.thinkingLevel,applyEffort:e=>E(z.current,e),onInvalidLevel:e=>a.value.info.showToast(Q.t(`cmd.titleEffort`),Q.t(`cmd.effortUnknown`,{arg:e,levels:y.join(` / `)}))}),jn(p))return;s.latestSubmittedPrompt={text:e,mode:i},s.retryMode||(s.errorRetryAttempt=0),s.retryMode=!1,l.lastTasks=c.todoList.slice();let S=r=>{An({err:r,submitState:s,provider:n.model?.provider,rateLimitInfoRef:{get current(){return s.lastRateLimitInfo},set current(e){s.lastRateLimitInfo=e}},retryModeRef:{get current(){return s.retryMode},set current(e){s.retryMode=e}},errorRetryAttemptRef:{get current(){return s.errorRetryAttempt},set current(e){s.errorRetryAttempt=e}},ERROR_RETRY_MAX:pe,ERROR_RETRY_INTERVAL_SECONDS:t.getResilienceConfig().errorRetry.intervalMs/1e3,handleSubmit:H,retryLastRound:()=>{let t=[...n.session.messages()].reverse().find(e=>e.role===`user`);return!t||(Array.isArray(t.content)?t.content.map(e=>e.type===`text`?e.text:``).join(``):String(t.content??``))!==e?!1:(a.value.engine.pushEngineEvent({kind:`agentProcessing`,value:!0}),s.agentProcessing=!0,n.retryLastRound().catch(t=>{if(t?.code===`RETRY_NO_RESUMABLE_ROUND`){queueMicrotask(()=>H?.(e,i,`send`));return}a.value.pending.withdrawPendingEcho(),S(t)}).finally(()=>{s.agentProcessing=!1,a.value.engine.pushEngineEvent({kind:`agentProcessing`,value:!1})}),!0)},latestSubmittedPromptRef:{get current(){return s.latestSubmittedPrompt},set current(e){s.latestSubmittedPrompt=e}},text:e,mode:i,handleModel:R,handleProviderAuth:I,cliCtx:z.current,tui:a.value})};try{p=await t.expandSigilChips(p,{skipPrefixes:new Set([`model`])}),(!f.isCommand||m)&&!s.retryMode&&(a.value.messages.echoUserInput(p,{pending:!0}),a.value.pending.setPendingEcho(p,i),t.settings.get(`first_prompt_submitted_at`)===void 0&&(t.settings.persist({first_prompt_submitted_at:Date.now()}).catch(()=>{}),t.storage.traceStore.append(n.id,wn(`ftue.first_prompt.submitted`,{timeToFirstPromptMs:Math.round(performance.now()-U)},n.id,{turn:n.session.getTurnCount()})).catch(()=>{}),(async()=>{let e=await Cn({hasFile:async e=>{try{return await Tt(Z(t.workspaceDir,e)),!0}catch{return!1}},packageDependencyNames:async()=>{try{let e=await St(Z(t.workspaceDir,`package.json`),`utf-8`),n=JSON.parse(e);return new Set([...Object.keys(n.dependencies??{}),...Object.keys(n.devDependencies??{})])}catch{return new Set}}},new Set(t.activePlugins().map(e=>e.id))).catch(()=>[]);o.value?.stores.tasks.setCapabilityRecommendations(e)})()));let e=p;s.streamedText=!1;let r=await ae.handleInput(e);if(r.type===`exit`){se.current(r);return}if(r.type===`help`){a.value.modal.openModal({kind:`helpViewer`,title:`Help`,lines:Jt(P,n.pinned,Q.t(`cmdDesc`,{returnObjects:!0})),onDismiss:()=>{}});return}r.type!==`noop`&&r.text&&!s.streamedText&&(r.type===`system`&&r.text.length<=80?a.value.info.showToast(Q.t(`cmd.titleInfo`),r.text):a.value.messages.pushMessage({role:`assistant`,content:[{type:`text`,text:r.text}]})),r.type===`response`&&r.endReason&&(a.value.pending.clearPendingEcho(),r.notice&&a.value.info.showToast(Q.t(`cmd.titleInfo`),r.notice)),await xn(r,{runTurn:e=>ae.handleInput(e),onTurnResult:e=>e.type===`exit`?(se.current(e),`exit`):(e.type!==`noop`&&e.type!==`help`&&e.text&&!s.streamedText&&a.value.messages.pushMessage({role:`assistant`,content:[{type:`text`,text:e.text}]}),`continue`),askBudgetContinue:()=>new Promise(e=>{a.value.modal.openModal({kind:`select`,title:Q.t(`budget.exhaustedTitle`),layout:`buttons`,options:[{label:Q.t(`budget.continue`),value:`go`,color:`accent`},{label:Q.t(`budget.stop`),value:`stop`,color:`amber`}],onSelect:t=>e(t===`go`),onCancel:()=>e(!1)})}),onBudgetStopped:()=>{a.value.messages.pushMessage({role:`assistant`,content:[{type:`text`,text:Q.t(`budget.stoppedNote`)}]})},beforeContinuationTurn:()=>{s.streamedText=!1}})}catch(e){a.value.pending.withdrawPendingEcho(),S(e)}finally{s.agentProcessing=!1,s.userAborted=!1,a.value.engine.pushEngineEvent({kind:`agentProcessing`,value:!1}),a.value.plugins.setCommands(_())}},onInterrupt:()=>{let e=Date.now(),t=an(e,s.lastCtrlCTime,{shellRunning:!!s.shellChild,busy:u(),stopDialogOpen:f.isStopDialogOpen(),idleCtrlCCount:s.ctrlCCount});if(t!==`dedup`)switch(s.lastCtrlCTime=e,t){case`kill-shell`:s.shellChild.kill(`SIGTERM`),setTimeout(()=>{s.shellChild&&!s.shellChild.killed&&s.shellChild.kill(`SIGKILL`)},3e3);return;case`open-stop-dialog`:f.requestStop(`abort`);return;case`escalate-exit`:f.escalateToExit();return;case`exit-process`:m();return;case`hint-exit`:s.ctrlCCount++,setTimeout(()=>{s.ctrlCCount=0},800).unref(),a.value.info.showToast(Q.t(`cmd.titleExit`),Q.t(`cmd.pressCtrlCAgain`));return}},onShellAskAi:()=>{let e=o.value?.shell.getShellExecutionSnapshot();if(!e)return;let t=Fn(e);H?.(t,`send`,u()?`steer`:`send`)},onWithdrawPending:(e,t)=>{a.value.pending.withdrawPendingEcho()&&a.value.pending.restoreInputText(e),s.agentProcessing&&(s.userAborted=!0,d({kind:`abort`}),a.value.info.showToast(Q.t(`cmd.titleAborted`),Q.t(`cmd.runAborted`)))},onWithdrawSteer:e=>{n.removeSteer(e)?a.value.pending.withdrawPendingSteer(e):f.requestStop(`abort`)},onStop:()=>{p()}}}var Bn=class{estimate;intervalMs;now;text=``;measuredTokens=0;measuredChars=0;measuredAt=-1/0;constructor(e){this.estimate=e.estimate,this.intervalMs=e.intervalMs??250,this.now=e.now??(()=>Date.now())}reset(){this.text=``,this.measuredTokens=0,this.measuredChars=0,this.measuredAt=-1/0}push(e){if(!e)return;this.text+=e;let t=this.now();t-this.measuredAt>=this.intervalMs&&this.measure(t)}flush(){this.measure(this.now())}tokens(){let e=this.text.length-this.measuredChars;if(e<=0)return this.measuredTokens;let t=this.measuredChars>0?this.measuredTokens/this.measuredChars:.25;return this.measuredTokens+Math.ceil(e*t)}measure(e){this.measuredTokens=this.text?this.estimate(this.text):0,this.measuredChars=this.text.length,this.measuredAt=e}};function Vn(e,t){if(/^(bash|shell|run_command|execute|exec)$/i.test(e)){let e=t?.command;if(e)return e}return JSON.stringify(t??{}).slice(0,300)}async function Hn(e,t){let n=[`● ${t.header} — ${t.askedBy} asks:`,t.background?`\n${t.background}`:``,Q.t(`cmd.grillRecommendation`,{rec:t.recommendation}),t.evidence?.length?Q.t(`cmd.grillEvidence`,{joined:t.evidence.map(e=>` · ${e}`).join(`
|
|
8
|
+
`).trimEnd()}catch{s=``}n({id:e,command:a.command,status:o,text:s}),o!==`running`&&u()};u(),q.get(e)&&(q.retain(e,!0),o=e),a=setInterval(()=>{r()},500),r()},onBackgroundOutputClose:()=>{u()},onBackgroundSwitch:e=>{let t=n();d();let r=()=>{let n=J?.getMessages(e),r=J?.get(e),i=r?.agentName??``,a=q.get(e);a&&(i=a.title||i);let o=n?x(n):[],s=J?.getTurns(e),c=J?.getStreamingText(e),l=Date.now(),u={id:e,title:i,messages:o,status:a?.status??`running`,diagnostics:r?st(ft(r),l):[],timeline:s?lt(s,l):[],streamText:c};t.panes.switchToSubagentContext(u)};J?.pin(e),q.get(e)&&q.retain(e,!0),c=e,r(),s=setInterval(()=>{r()},500)},onBackgroundDelete:e=>{if(q.get(e)){q.remove(e);return}if(Y.get(e)){Y.remove(e);return}J.remove(e)},onSubagentExit:()=>{d(),n().panes.switchToSubagentContext(null)}}}}const Qt=ze(`@x-otto/cli:theme-preset-wiring`);function $t(e,t){let n={kind:`extension`,extensionId:t.pluginId};return e.register(n,{localId:t.localId,label:t.label,appearance:t.appearance,colors:t.colors,markdown:t.markdown})}function en(e,t){let n=[];for(let r of t)try{n.push($t(e,r))}catch(e){Qt.warn({pluginId:r.pluginId,localId:r.localId,err:String(e)},`theme preset registration failed, skipped`)}return n}function tn(e){let t=at();return en(t,Se(e.activePlugins())),t}function nn(e){let t=e??et(import.meta.url);t=Ze(t);let n=t===`/`?t:`/`;for(;t!==n;){try{if($e(t+`/.git`))return t}catch{}t=Ze(t)}try{if($e(n+`/.git`))return n}catch{}}var rn=class{repoRoot;currentBuildId;checkIntervalMs;onStale;logger;lastNotifiedBuildId=void 0;disposed=!1;timer;activeChild;constructor(e){this.repoRoot=e.repoRoot,this.currentBuildId=e.currentBuildId,this.checkIntervalMs=e.checkIntervalMs??6e5,this.onStale=e.onStale,this.logger=e.logger}start(){this.disposed||this.scheduleNext()}dispose(){if(this.disposed=!0,this.timer&&=(clearTimeout(this.timer),void 0),this.activeChild){try{this.activeChild.kill()}catch{}this.activeChild=void 0}this.lastNotifiedBuildId=void 0}scheduleNext(){this.disposed||(this.timer=setTimeout(()=>{this.timer=void 0,this.performCheck().then(()=>{this.scheduleNext()})},this.checkIntervalMs),this.timer.unref())}performCheck(){return new Promise(e=>{if(this.disposed){e();return}let t=_e(`git`,[`rev-list`,`--count`,`HEAD`],{cwd:this.repoRoot,timeout:5e3},(t,n)=>{if(this.activeChild=void 0,t){this.logger?.warn({err:t instanceof Error?t.message:String(t)},`[stale-build-detector] git rev-list failed`),e();return}let r=n.trim(),i=parseInt(r,10);if(!Number.isFinite(i)){this.logger?.warn({raw:r},`[stale-build-detector] failed to parse git output as number`),e();return}if(i>this.currentBuildId&&i!==this.lastNotifiedBuildId){this.lastNotifiedBuildId=i;try{this.onStale?.(i)}catch(e){this.logger?.warn({err:e instanceof Error?e.message:String(e)},`[stale-build-detector] onStale callback threw`)}}e()});this.activeChild=t,t.on(`error`,()=>{this.activeChild=void 0})})}};function an(e,t,n){return e-t<50?`dedup`:n.shellRunning?`kill-shell`:n.busy?n.stopDialogOpen?`escalate-exit`:`open-stop-dialog`:n.idleCtrlCCount+1>=2?`exit-process`:`hint-exit`}function on(e){let{getTui:t,getSession:n,dispatchAbort:r,clearTodoLayers:i,markUserAborted:a,resetCtrlCCount:o,markRestartRequested:s,stopTui:c,isBusy:l}=e,u=null,d=()=>u!==null&&t()?.info.getCurrentPath()===`/dialog/confirm`,f=()=>{a(),o(),r(),i()},p=e=>{e&&s(),a(),o();try{r()}catch{}c()},m=e=>{if(e===`abort`)return{title:Q.t(`confirm.abortConfirmTitle`),message:Q.t(`confirm.abortConfirmMessage`),confirmLabel:Q.t(`common.abortButton`),extraLabel:Q.t(`common.pauseButton`),onConfirm:()=>{f(),t()?.info.showToast(Q.t(`cmd.titleAborted`),Q.t(`cmd.runAborted`))}};let n=e===`exit-restart`;return{title:n?Q.t(`confirm.exitRestartConfirmTitle`):Q.t(`confirm.exitConfirmTitle`),message:Q.t(`confirm.exitConfirmMessage`),confirmLabel:n?Q.t(`common.abortAndRestartButton`):Q.t(`common.abortAndExitButton`),extraLabel:void 0,onConfirm:()=>{p(n)}}},h=e=>{let r=t();if(!r)return;let i=m(e);u=e,r.modal.openModal({kind:`confirm`,title:i.title,message:i.message,confirmLabel:i.confirmLabel,confirmColor:`amber`,extraLabel:i.extraLabel,extraColor:`accent`,dangerous:!0,onConfirm:()=>{u=null,i.onConfirm()},onCancel:()=>{u=null},onExtra:i.extraLabel?()=>{u=null,n().pauseRun()?t()?.info.showToast(Q.t(`cmd.titlePaused`),Q.t(`cmd.runWillPauseAfterTurn`)):t()?.info.showToast(Q.t(`cmd.titleInfo`),Q.t(`cmd.noRunningTaskToPause`))}:void 0})};return{requestStop:e=>{if(!t()){e===`abort`?f():p(e===`exit-restart`);return}if(e!==`abort`&&!l()){p(e===`exit-restart`);return}h(e)},isStopDialogOpen:d,escalateToExit:()=>{let e=t();!e||!d()||(h(`exit`),e.modal.resolveConfirm(!0))},abortNow:f}}var sn=class{entries=[];filePath;constructor(e,t=Z(Ge,`sessions`)){this.filePath=Z(t,`${e}.history.json`)}list(e){return this.entries.slice(-(e??100))}append(e){e.trim()&&(this.entries.push(e),this.entries.length>100&&(this.entries=this.entries.slice(-100)))}hydrate(e){this.entries=e.slice(-100)}async persist(){if(Ye())return;let e=JSON.stringify(this.entries,null,2),t=`${this.filePath}.tmp`;try{await xt(Ze(this.filePath),{recursive:!0}),await Dt(t,e,`utf-8`),await wt(t,this.filePath)}catch(e){throw await Et(t).catch(()=>{}),e}}async load(){try{let e=await St(this.filePath,`utf-8`),t=JSON.parse(e);return Array.isArray(t)&&t.every(e=>typeof e==`string`)?(this.entries=t.slice(-100),this.entries):[]}catch{return[]}}};const cn={[it]:e=>ht(e),[tt]:e=>pt(e),[rt]:e=>mt(e)};function ln(){let e=process.env.SHELL??``,t=K(),n=process.env.HISTFILE;return e.includes(`fish`)?[{id:rt,path:Z(t,`.local/share/fish/fish_history`)},{id:rt,path:Z(t,`.config/fish/fish_history`)}]:e.includes(`bash`)?[{id:tt,path:n?.startsWith(`~`)?Z(t,n.slice(2)):n??Z(t,`.bash_history`)}]:e.includes(`zsh`)||!e?[{id:it,path:n?.startsWith(`~`)?Z(t,n.slice(2)):n??Z(t,`.zsh_history`)}]:[]}function un(e){let t=e?.sources?.filter(e=>e?.enabled!==!1&&!!e?.id&&!!e?.path);if(t&&t.length>0){let e=K();return t.map(t=>({id:t.id,path:dn(t.path,e)}))}return ln()}function dn(e,t){return e.startsWith(`~/`)?Z(t,e.slice(2)):e===`~`?t:e}async function fn(e){try{return await bt(e),!0}catch{return!1}}async function pn(e,t){let n=cn[e.id];if(!n||!await fn(e.path))return[];try{return n(await St(e.path,`utf8`)).slice(-t)}catch{return[]}}async function mn(e){if(e?.enabled!==!0)return[];let t=e.maxEntries??2e3,n=un(e),r=new Set,i=[];for(let e of n){if(r.has(e.path))continue;r.add(e.path);let n=await pn(e,t);i.push(...n)}return i.slice(-t)}async function hn(e,t){let n=new sn(e.id);return{historyStore:n,inputHistory:await n.load().then(t=>{if(t.length>0)return t;let r=e.session.getInputHistory();return r&&r.length>0?(n.hydrate(r),n.persist().catch(()=>{}),e.session.setInputHistory([]),r):[]}),externalHistoryCommands:t?.enabled===!0?ot(await mn(t)):void 0}}async function gn(e,t,n){if(n){let n=t.settings.get(`model`);if(typeof n==`string`&&n&&e.model?.id!==n){let r=t.modelRegistry.find(n);r&&await t.providerRegistry.hasCredential(r.provider)&&(e.model=r,t.storage.memory?.reconfigure?.({contextWindow:r.contextWindow,maxOutput:r.maxOutputTokens}))}}{let n=t.settings.get(`thinking_level`),r=[`low`,`medium`,`high`,`xhigh`,`max`],i=n===`minimal`?`low`:n;typeof i==`string`&&r.includes(i)&&(e.thinkingLevel=i)}}async function _n(e,t){let n=`__otto_setup__`,r=e.settings.get(`permission_mode`);(r===void 0||r===`auto`)&&await e.settings.update({permission_mode:`confirm`}),e.modelRegistry.getAll().length===0&&e.modelRegistry.register({id:n,name:`Setup required`,provider:`otto`,api:`otto`,baseUrl:``,reasoning:!1,input:[`text`],contextWindow:32e3,maxOutputTokens:4e3});let i=t.continueSession?e.getSession(t.continueSession)??await e.sessionManager.restore(t.continueSession)??void 0:void 0,a=i?i.session.buildContext().messages.filter(e=>{let t=e.role;return t===`user`||t===`assistant`}).length:0,o={value:i?e.sessionManager.consumeCrashGap(i.id):void 0},s=t.continueSession?i?Q.t(`cmd.resumeRestored`,{idShort:t.continueSession.slice(0,8),count:a}):Q.t(`cmd.resumeNotFound`,{id:t.continueSession}):void 0,c=!!(t.continueSession&&i),l=!!(t.model||e.settings.get(`model`)||e.settings.get(`model_slots`)?.default),u={skip:!1},d=await e.hydrateModelCache().catch(()=>new Set),f=e.modelRegistry.getAll().every(e=>e.id===n),p=f?!1:l,m=e.modelRegistry.getAll().find(e=>e.id!==n)??e.modelRegistry.getAll()[0],h=i??await e.createSession({interactive:!0,retryAccelerate:u,...p?{}:{model:m}});await gn(h,e,!!i);let g=p||c,_={get value(){return g},set value(e){g=e}},v={models:e.modelRegistry.getAll().filter(e=>e.id!==n).map(e=>({id:e.id,name:e.name,provider:e.provider,api:e.api,strengths:e.strengths??[],contextWindow:e.contextWindow})),availableModelIds:new Set([...d,...e.getSessionAvailableModels(h.id)]),wasUnconfigured:!1};v.wasUnconfigured=v.availableModelIds.size===0;let y=()=>e.setSessionAvailableModels(h.id,[...v.availableModelIds]);y();let b=new B(k({modelRegistry:e.modelRegistry,authStore:e.authStore,settings:e.settings,selectedModelId:()=>h.model?.id,isModelUsable:Ot(e.authStore,`delegation`),isModelUsableInMainSession:Ot(e.authStore,`main-session`)})),x,S={get value(){return x},set value(e){x=e}},C=async t=>{let r=await e.refreshModels().catch(()=>[]);v.models=e.modelRegistry.getAll().filter(e=>e.id!==n).map(e=>({id:e.id,name:e.name,provider:e.provider,api:e.api,strengths:e.strengths??[],contextWindow:e.contextWindow}));for(let e of r)if(e.status===`ok`)for(let t of e.availableIds??[])v.availableModelIds.add(t);v.models.length>0&&e.modelRegistry.getAll().some(e=>e.id===n)&&e.modelRegistry.unregister(n),y();let i=v.availableModelIds.size===0,a=S.value;a?.stores?.tasks?.setNeedsSetup?.(i);let o=await b.refresh().catch(()=>null);if(o&&a?.stores?.tasks?.setFtueStage?.(o.stage),v.wasUnconfigured&&!i&&(v.wasUnconfigured=!1,a?.info?.showToast?.(Q.t(`cmd.titleSetupReady`),Q.t(`cmd.setupReadyMessage`))),t){let e=r.filter(e=>e.status===`ok`);t(e.length>0?Q.t(`cmd.modelsRefreshed`,{summary:e.map(e=>`${e.provider} ${e.total}`).join(` · `)}):Q.t(`cmd.modelsRefreshedEmpty`))}};return C(),{session:h,startupCrashGapRef:o,resumedNote:s,modelReadyRef:_,registryOnlyPlaceholder:f,firstRealModel:m,modelRefreshState:v,persistAvailable:y,ftueController:b,refreshModelsNow:C,tuiRefBox:S,SETUP_PLACEHOLDER_ID:n,continuedExisting:c,retryAccelerate:u,resumed:i,convoCount:a}}function vn(e){let t=[],n=0,r=``,i=()=>{r&&=(t.push(r),``)};for(;n<e.length;){let t=e[n];if(t===` `||t===` `){i(),n++;continue}if(t===`\\`){n++,n<e.length&&(r+=e[n]),n++;continue}if(t===`"`){n++;let t=yn(e,n,`"`);r+=t.value,n=t.next;continue}if(t===`'`){n++;let t=yn(e,n,`'`,!1);r+=t.value,n=t.next;continue}r+=t,n++}return i(),{tokens:t}}function yn(e,t,n,r=!0){let i=``,a=t;for(;a<e.length;){let t=e[a];if(r&&t===`\\`){a++,a<e.length&&(i+=e[a]),a++;continue}if(t===n)return a++,{value:i,next:a};i+=t,a++}return{value:i,next:a}}function bn(e){let t=e.trim();if(!t.startsWith(`/`)||t===`/`||t.startsWith(`//`))return{isCommand:!1,text:t};let{tokens:n}=vn(t.slice(1));if(n.length===0)return{isCommand:!1,text:t};let[r,...i]=n;return{isCommand:!0,command:r,args:i}}async function xn(e,t){let n=e;for(;n.type===`response`&&n.endReason===`max-tool-turns`&&n.notice;){if(!await t.askBudgetContinue()){t.onBudgetStopped();return}t.beforeContinuationTurn();let e=await t.runTurn(`Continue with the remaining work until the task is complete.`);if(t.onTurnResult(e)===`exit`)return;n=e}}const Sn=[{extensionId:`plugin-browser-use`,reasonKey:`capability.reasonWebApp`,detect:async e=>{let t=await e.packageDependencyNames();return[`react`,`vue`,`next`,`nuxt`,`svelte`,`vite`,`@angular/core`,`express`,`koa`,`fastify`].some(e=>t.has(e))?!0:e.hasFile(`index.html`)}},{extensionId:`plugin-mobile-use`,reasonKey:`capability.reasonMobile`,detect:async e=>{if(await e.hasFile(`AndroidManifest.xml`)||await e.hasFile(`build.gradle`)||await e.hasFile(`build.gradle.kts`)||await e.hasFile(`Info.plist`)||await e.hasFile(`Podfile`))return!0;let t=await e.packageDependencyNames();return t.has(`react-native`)||t.has(`expo`)}},{extensionId:`plugin-schedule`,reasonKey:`capability.reasonSchedule`,detect:async e=>{if(await e.hasFile(`crontab`))return!0;let t=await e.packageDependencyNames();return t.has(`node-cron`)||t.has(`node-schedule`)||t.has(`agenda`)}}];async function Cn(e,t,n=Sn){let r=[];for(let i of n){if(t.has(i.extensionId))continue;let n=!1;try{n=await i.detect(e)}catch{n=!1}n&&r.push({extensionId:i.extensionId,reasonKey:i.reasonKey})}return r}function wn(e,t,n,r){return{ts:r?.ts??Date.now(),sessionId:n,...r?.turn===void 0?{}:{turn:r.turn},kind:`lifecycle`,node:e,payload:t}}function Tn(e){let t=new Map;if(e?.role===`assistant`&&Array.isArray(e.content))for(let n of e.content)n.type===`tool_call`&&t.set(n.id,n);return t}async function En(e,t,n){let r,i=new Set,a=new Map,o=new Set,c=new Map;if(n){let n=await e.loadTailEntries(t,It);r=n.length>0?n[0].seq:0;for(let e of n)e.type===`message`&&i.add(e.seq)}else r=await e.getEntryCount(t);return{async loadEarlier(n=500){if(r<=0)return null;let l=await e.loadEntriesBefore(t,r,n);if(l.length===0)return null;let u=new Map,d=new Set;for(let e of l){if(e.type!==`message`)continue;let t=e.data;if(t?.role===`assistant`)for(let[e,n]of Tn(t))u.set(e,n);else t?.role===`tool_result`&&typeof t.toolCallId==`string`&&d.add(t.toolCallId)}let f=[],p=(e,t)=>({...e,id:`hist-${t}`,seq:t});for(let e of l){if(e.type===`clear`){r=0,f.length=0;continue}if(e.type!==`message`||i.has(e.seq))continue;let t=e.data;if(!t||typeof t.role!=`string`||t.internal)continue;if(t.role===`tool_result`){let n=a.get(t.toolCallId??``)??u.get(t.toolCallId??``);if(n){let r=n.arguments??{};f.push(p({role:`tool`,name:t.toolName||n.name||`tool`,args:C(r),argsObj:r,result:s(t.content),isError:t.isError},e.seq)),o.add(t.toolCallId)}else c.set(t.toolCallId,{toolName:t.toolName,content:t.content,isError:t.isError});continue}if(t.role===`assistant`){let n=Tn(t);if(n.size>0){let r=new Set([...d,...o,...c.keys()]),i=x([t],{resolvedIds:r});for(let t of i)f.push(p(t,e.seq));for(let[t,r]of n){if(d.has(t))continue;let n=c.get(t);if(n){c.delete(t);let i=r.arguments??{};f.push(p({role:`tool`,name:r.name,args:C(i),argsObj:i,result:s(n.content),isError:n.isError??!1},e.seq))}}continue}}let n=x([t]);for(let t of n)f.push(p(t,e.seq))}for(let[e,t]of u)a.set(e,t);return r>0&&(r=l[0].seq),f.length>0?f:null}}}function Dn(e){let{app:t,getTui:n,getTuiRef:r,getSession:i,getCliCtx:a,historyStore:o}=e;return{onCyclePermissionMode:()=>{let e=n(),r=ee(t.getPermissionMode());e.stores.tasks.setPermissionMode(r),e.info.showToast(Q.t(`cmd.titlePermission`),Q.t(`pref.permModeSwitched`,{label:Q.t(`pref.permModeLabel`,{context:r})})),t.setPermissionMode(r)},onHistoryPush:t=>{try{o.hydrate([...t]),o.persist().catch(()=>{})}catch{}e.getPasteBinder?.()?.save(i().id)},onDraftSave:e=>{let n=i(),a=n.session.getDrafts()??[],o=f(void 0,e,a),s=l([...a,o]);n.session.setDrafts(s),t.sessionManager.save(n.id).catch(()=>{}),r()?.stores.tasks.setDrafts(v(s))},onDraftDelete:e=>{let n=i(),a=(n.session.getDrafts()??[]).filter(t=>t.id!==e);n.session.setDrafts(a),t.sessionManager.save(n.id).catch(()=>{}),r()?.stores.tasks.setDrafts(v(a))},onDraftDeleteMany:e=>{let n=i(),a=new Set(e),o=(n.session.getDrafts()??[]).filter(e=>!a.has(e.id));n.session.setDrafts(o),t.sessionManager.save(n.id).catch(()=>{}),r()?.stores.tasks.setDrafts(v(o))},onA2uiAction:(e,t,n)=>{L(`a2ui-action`,n?[e,t,JSON.stringify(n)]:[e,t],a())},onPerfRefresh:()=>{L(`status`,[`perf`],a())},onProxySubmitUrl:e=>{L(`preference`,[`proxy`,e],a())},onProxyToggleEnabled:()=>{L(`preference`,[`proxy`,t.settings.get(`proxy`)?.enabled===!1?`on`:`off`],a())},onProxyClear:()=>{L(`preference`,[`proxy`,`clear`],a())},onProxyTest:()=>{L(`preference`,[`proxy`,`test`],a())}}}function On(e){return{...kn(e),pluginSource:e.pluginSource,intervalSeconds:e.errorRetryIntervalSeconds}}function kn(e){let{msg:t,provider:n,authError:r,isRefreshFailed:i,unsupported:a,rateLimit:o,rateLimitInfo:s,getErrorRetryAttempt:c,incErrorRetryAttempt:l,errorRetryMax:u,retryQueued:d,resetAndRetry:f,cancelRetry:p,switchModelThenRetry:m,goToAuth:h}=e;if(s)return s.resetsAt===void 0?{reason:t,attempt:0,max:u,mode:`manual`,limitType:s.limitType,actions:[{kind:`switchModel`,label:Q.t(`error.switchModel`),run:m},{kind:`retryNow`,label:Q.t(`retry.nowButton`),run:d}],onExpired:()=>{},onCancel:p}:{reason:t,attempt:0,max:u,mode:`resetsAt`,resetsAt:s.resetsAt,limitType:s.limitType,actions:[{kind:`retryNow`,label:Q.t(`error.retryNow`),run:d},{kind:`switchModel`,label:Q.t(`error.switchModel`),run:m}],onExpired:d,onCancel:p};if(r)return{reason:i?Q.t(`cmd.authRefreshFailed`,{ps:n?` (${n})`:``,ls:n?` ${n}`:``}):Q.t(`cmd.authFailed`,{ps:n?` (${n})`:``,ls:n?` ${n}`:``}),attempt:c(),max:u,mode:`manual`,actions:[{kind:`login`,label:Q.t(`model.goToLoginButton`),run:h},{kind:`switchModel`,label:Q.t(`error.switchModel`),run:m},{kind:`retryNow`,label:Q.t(`retry.nowButton`),run:d}],onExpired:()=>{},onCancel:p};if(a)return{reason:Q.t(`cmd.modelNotSupported`),attempt:c(),max:u,mode:`manual`,actions:[{kind:`switchModel`,label:Q.t(`error.switchModel`),run:m},{kind:`retryNow`,label:Q.t(`retry.nowButton`),run:d}],onExpired:()=>{},onCancel:p};let g=l(),_=g>u;return{reason:o?Q.t(`cmd.rateLimitedRetriesExhausted`):Q.t(`cmd.requestFailed`,{msg:t}),attempt:Math.min(g,u),max:u,mode:`auto`,exhausted:_,actions:[{kind:`retryNow`,label:Q.t(`retry.nowButton`),run:_?f:d}],onExpired:_?()=>{}:d,onCancel:p}}function An(e){let{err:n}=e,r=n instanceof Error?n.message:String(n),i=n?.code===`AGENT_ABORTED`||n instanceof Error&&n.name===`AbortError`;if(!(e.submitState.userAborted||i)){let i=e.provider,a=n?.code,o=n?.pluginSource,{authError:s,isRefreshFailed:c,unsupported:l,rateLimit:u,pluginSource:d}=ae(r,a,o),f=e.rateLimitInfoRef.current;e.rateLimitInfoRef.current=void 0;let p=(()=>{let t=e.cliCtx,n=t?.app?.storage?.traceStore,r=t?.state?.session;if(!n||!r)return null;let i=r.session.getTurnCount();return{traceStore:n,sessionId:r.id,...i===void 0?{}:{turn:i}}})(),m=()=>{p&&P(p,{attempt:e.errorRetryAttemptRef.current+1,max:e.ERROR_RETRY_MAX,mode:f?`resetsAt`:s||l?`manual`:`auto`,reason:r.slice(0,120)}),e.retryModeRef.current=!0;let t=e.latestSubmittedPromptRef?.current,n=e.tui.engine.takeLastQueuedFollowUp?.(),i=t!=null&&t.text!==e.text,a=i?t.text:n?.text??e.text,o=i?t.mode:n?.mode??e.mode;a===e.text&&!i&&n==null&&e.retryLastRound?.()||queueMicrotask(()=>e.handleSubmit?.(a,o,`send`))};e.tui.engine.showErrorRetry(On({msg:r,provider:i,authError:s,isRefreshFailed:c,unsupported:l,rateLimit:u,rateLimitInfo:f,pluginSource:d,getErrorRetryAttempt:()=>e.errorRetryAttemptRef.current,incErrorRetryAttempt:()=>++e.errorRetryAttemptRef.current,errorRetryMax:e.ERROR_RETRY_MAX,errorRetryIntervalSeconds:e.ERROR_RETRY_INTERVAL_SECONDS,retryQueued:m,resetAndRetry:()=>{p&&t(p),e.errorRetryAttemptRef.current=0,m()},cancelRetry:()=>{p&&h(p,{attempt:e.errorRetryAttemptRef.current}),e.errorRetryAttemptRef.current=0},switchModelThenRetry:()=>{e.handleModel([],e.cliCtx,{afterSwitch:m})},goToAuth:()=>{e.handleProviderAuth([i??``].filter(Boolean),e.cliCtx)}}))}}function jn(e){return e.trim().length===0}function Mn(e){let{tui:t,app:n,submitState:r}=e;return(e,i=`!!`)=>{let a=e.trim();if(!a)return;let o=Re(a);if(!o.safe){t.info.showToast(Q.t(`cmd.titleShell`),Q.t(`cmd.dangerousBlocked`,{reason:o.reason})),t.messages.pushMessage({role:`assistant`,content:[{type:`text`,text:Q.t(`cmd.dangerousBlockedDetail`,{reason:o.reason,cmd:a})}]});return}t.messages.echoUserInput(`${i} ${a}`),t.shell.startShellExecution(a),r.shellChild=ve(a,{shell:!0,cwd:n.workspaceDir,stdio:[`ignore`,`pipe`,`pipe`],env:Le()}),Fe.registerChild({command:a,args:[],owner:{type:`cli-shell`,id:`!!`},category:`shell`,lifecycle:`evictable`,cwd:n.workspaceDir},r.shellChild),r.shellChild.stdout.on(`data`,e=>{t.shell.appendShellOutput(e.toString(`utf-8`))}),r.shellChild.stderr.on(`data`,e=>{t.shell.appendShellOutput(e.toString(`utf-8`))}),r.shellChild.on(`close`,(e,n)=>{r.shellChild=null,n?t.shell.finishShellExecution(null,void 0,!0):t.shell.finishShellExecution(e)}),r.shellChild.on(`error`,e=>{r.shellChild=null,t.shell.finishShellExecution(null,`\nError: ${e.message}`)})}}function Nn(e){let{agentProcessingRef:t,tui:n,requestStop:r}=e;return(e,i)=>{let a=bn(e);return a.isCommand&&a.command.toLowerCase()===`abort`&&i===`send`?(t.value?r(`abort`):n.info.showToast(Q.t(`cmd.titleInfo`),Q.t(`cmd.noRunningTask`)),!0):!1}}function Pn(e){let{app:t,tui:n}=e;return async e=>{let r=e.trim();if(!r)return;if(!t.storage.autoMemory){n.info.showToast(Q.t(`cmd.titleMemory`),Q.t(`cmd.memoryDisabled`));return}let i=await N(r,process.env.OTTO_MEMORY_LLM_NAMING===`1`?t.completeText:void 0);await t.storage.autoMemory.record(i),n.messages.echoUserInput(`# ${r}`),n.messages.pushMessage({role:`assistant`,content:[{type:`text`,text:Q.t(`cmd.memorySaved`,{name:i.name})}]})}}function Fn(e){let t=e.terminated===!0?Q.t(`shell.askAiTerminated`):e.exitCode===null?Q.t(`shell.unknownError`):Q.t(`shell.exitCode`,{code:e.exitCode}),n=e.output.length>5e4?`${e.output.slice(0,5e4)}\n${Q.t(`shell.truncated`)}`:e.output;return Q.t(`shell.prompt`,{command:e.command,errorLabel:t,output:n})}function In(e,t){let n=e=>`${e.kind}\u0000${e.label}`,r=n(t);return[t,...e.filter(e=>n(e)!==r)].slice(0,5)}function Ln(e){return{label:e.label,value:e.value,kind:e.kind,description:e.description}}function Rn(e){return e.map(e=>({label:e.label,value:e.value,kind:e.kind,description:e.description,source:`recent`}))}async function zn(e){let{app:t,session:n,options:i,tuiRefBox:a,tuiRef:o,turn:s,projState:c,redState:l,isBusyNow:u,dispatchToEngine:d,stopController:f,finishInteractive:p,stopTuiGuarded:m,applyModel:h,ensureModelUsableForPrompt:g,refreshSlashCommands:_,fileCommands:b,modelReady:x,availableModelIds:S,currentModel:C,fmtDisplayModel:w,cfgLang:ee,themeRegistry:T,presetSelection:D,keybindingOverrides:O,continuedExisting:k,convoCount:A,historyStore:ne,inputHistory:j,externalHistoryCommands:M,bg:N,reg:P,slashCommands:ie,interactive:ae,handleExitRef:se,cliCtxRef:z,providerAuthRef:ce,handleAbortInterceptRef:le,runAsyncBashRef:B,runMemoryCaptureRef:ue,allCommandNames:de}=e;ce.current=e=>{I([e],z.current).catch(()=>{})};let H,pe=t.getResilienceConfig().errorRetry.maxAttempts;Be(`startTui() begin`);let U=performance.now(),me=F(await te(t.workspaceDir,{readdir:e=>Ct(e,{withFileTypes:!0})})).map(e=>Q.t(e));return{stdin:process.stdin,stdout:process.stdout,modelName:w(C),needsSetup:S.size===0,promptSuggestions:me,commands:ie,pluginInput:t.pluginInput,isImmediateCommand:e=>u()?oe.has(e):de.has(e),isInterruptCommand:e=>e===`abort`,isAgentBusy:u,isPaused:()=>n.isPaused,initialPath:k&&A>0?`/`:`/home`,shadow:t._shadow,welcome:{cwd:process.cwd(),version:qe,buildId:We,nickname:t.settings.get(`nickname`)||void 0,updateAvailable:void 0},onSessionSelect:e=>{L(`session`,[`resume`,e],z.current)},onInstallCapability:e=>{import(`./command-dispatcher-DTOPjtZP.js`).then(e=>e.g).then(({runPluginInstall:t})=>t(e,z.current))},onDismissCapabilityRecommendations:()=>{o.value?.stores.tasks.dismissCapabilityRecommendations()},loadHistory:t.sessionRepoRef?.current?await(async()=>{let e=t.sessionRepoRef.current;if(!e)return;let r=await En(e,n.id,!!i.continueSession);return e=>r.loadEarlier(e.limit)})():void 0,language:ee,themeRegistry:T,presetSelection:D,keybindingOverrides:O,permissionMode:t.getPermissionMode(),onFocusChange:e=>t.setTerminalFocus(e),...N.handlers,initialHistory:j,externalHistoryCommands:M,residencyGovernor:t._residencyGovernor,resolveWholeFileDiff:async(e,n)=>{try{return await fe(Qe(t.workspaceDir,e),n)}catch(e){return{error:e instanceof Error?e.message:String(e)}}},initialDrafts:v(n.session.getDrafts()??[]),initialRecentMentions:Rn(t.settings.get(`recent_mentions`)??[]),onSigilSelect:e=>{let n=In(t.settings.get(`recent_mentions`)??[],Ln(e));t.settings.persist({recent_mentions:n}).catch(()=>{}),o.value?.stores.tasks.setRecentMentions(Rn(n))},...Dn({app:t,getTui:()=>a.value,getTuiRef:()=>o.value,getSession:()=>n,getCliCtx:()=>z.current,historyStore:ne,getPasteBinder:()=>z.current.callbacks.pasteBinder}),onQueueSendNow:(e,t)=>{if(t===`memory`){ue.current(e);return}if(t===`bash`||t===`bash_async`){B.current(e,t===`bash`?`!`:`!!`);return}H?.(e,`send`,u()?`steer`:`send`)},onSubmit:H=async(e,i,d)=>{if(s.ctrlCCount=0,d===`action`){await V(e,{currentModelId:n.model?.id,applyModel:h,onSwitchFailed:e=>a.value.info.showToast(Q.t(`cmd.titleModel`),e)}),r(e,{currentEffort:n.thinkingLevel,applyEffort:e=>E(z.current,e),onInvalidLevel:e=>a.value.info.showToast(Q.t(`cmd.titleEffort`),Q.t(`cmd.effortUnknown`,{arg:e,levels:y.join(` / `)}))});return}if(le.current(e,i))return;if(n.isPaused&&n.resumeRun(),d===`steer`&&n.isBusy){s.latestSubmittedPrompt={text:e,mode:i};let t=r(await V(e,{currentModelId:n.model?.id,applyModel:h,onSwitchFailed:e=>a.value.info.showToast(Q.t(`cmd.titleModel`),e)}),{currentEffort:n.thinkingLevel,applyEffort:e=>E(z.current,e),onInvalidLevel:e=>a.value.info.showToast(Q.t(`cmd.titleEffort`),Q.t(`cmd.effortUnknown`,{arg:e,levels:y.join(` / `)}))});if(jn(t))return;let{id:o}=n.steer(t);a.value.pending.setPendingSteer(t,o);return}if(i===`memory`){await ue.current(e);return}if(i===`bash`||i===`bash_async`){B.current(e,i===`bash`?`!`:`!!`);return}let f=bn(e),p=e,m=!1;if(f.isCommand){if(await L(f.command,f.args,z.current))return;t.firePluginActivationEvent?.(`onCommand:${f.command}`);let e=b.find(e=>e.name===f.command);e&&(m=!0,p=await Te(e.body,{args:f.args,workspaceDir:t.workspaceDir}))}let v=f.isCommand&&!m&&re.has(f.command.toLowerCase());if(!v&&!x&&(!f.isCommand||m)){a.value.info.showToast(Q.t(`cmd.titleSetupRequired`),Q.t(`cmd.noModelConfigured`));return}if(c.todoList.length>0&&c.todoList.every(e=>e.status===`done`||e.status===`skipped`||e.status===`failed`)&&(c.todoList=[],a.value.stores.tasks.setTasks([]),n.session.setTodoList([])),u()&&(!f.isCommand||m)){a.value.engine.enqueueFollowUp(e,i),a.value.info.showToast(Q.t(`cmd.titleInfo`),Q.t(`queue.dFollowUpToast`));return}if(!v){if(await g()===`abort`)return;a.value.engine.pushEngineEvent({kind:`agentProcessing`,value:!0}),s.agentProcessing=!0,a.value.plugins.setCommands(_())}if(s.userAborted=!1,p=await V(p,{currentModelId:n.model?.id,applyModel:h,onSwitchFailed:e=>a.value.info.showToast(Q.t(`cmd.titleModel`),e)}),p=r(p,{currentEffort:n.thinkingLevel,applyEffort:e=>E(z.current,e),onInvalidLevel:e=>a.value.info.showToast(Q.t(`cmd.titleEffort`),Q.t(`cmd.effortUnknown`,{arg:e,levels:y.join(` / `)}))}),jn(p))return;s.latestSubmittedPrompt={text:e,mode:i},s.retryMode||(s.errorRetryAttempt=0),s.retryMode=!1,l.lastTasks=c.todoList.slice();let S=r=>{An({err:r,submitState:s,provider:n.model?.provider,rateLimitInfoRef:{get current(){return s.lastRateLimitInfo},set current(e){s.lastRateLimitInfo=e}},retryModeRef:{get current(){return s.retryMode},set current(e){s.retryMode=e}},errorRetryAttemptRef:{get current(){return s.errorRetryAttempt},set current(e){s.errorRetryAttempt=e}},ERROR_RETRY_MAX:pe,ERROR_RETRY_INTERVAL_SECONDS:t.getResilienceConfig().errorRetry.intervalMs/1e3,handleSubmit:H,retryLastRound:()=>{let t=[...n.session.messages()].reverse().find(e=>e.role===`user`);return!t||(Array.isArray(t.content)?t.content.map(e=>e.type===`text`?e.text:``).join(``):String(t.content??``))!==e?!1:(a.value.engine.pushEngineEvent({kind:`agentProcessing`,value:!0}),s.agentProcessing=!0,n.retryLastRound().catch(t=>{if(t?.code===`RETRY_NO_RESUMABLE_ROUND`){queueMicrotask(()=>H?.(e,i,`send`));return}a.value.pending.withdrawPendingEcho(),S(t)}).finally(()=>{s.agentProcessing=!1,a.value.engine.pushEngineEvent({kind:`agentProcessing`,value:!1})}),!0)},latestSubmittedPromptRef:{get current(){return s.latestSubmittedPrompt},set current(e){s.latestSubmittedPrompt=e}},text:e,mode:i,handleModel:R,handleProviderAuth:I,cliCtx:z.current,tui:a.value})};try{p=await t.expandSigilChips(p,{skipPrefixes:new Set([`model`])}),(!f.isCommand||m)&&!s.retryMode&&(a.value.messages.echoUserInput(p,{pending:!0}),a.value.pending.setPendingEcho(p,i),t.settings.get(`first_prompt_submitted_at`)===void 0&&(t.settings.persist({first_prompt_submitted_at:Date.now()}).catch(()=>{}),t.storage.traceStore.append(n.id,wn(`ftue.first_prompt.submitted`,{timeToFirstPromptMs:Math.round(performance.now()-U)},n.id,{turn:n.session.getTurnCount()})).catch(()=>{}),(async()=>{let e=await Cn({hasFile:async e=>{try{return await Tt(Z(t.workspaceDir,e)),!0}catch{return!1}},packageDependencyNames:async()=>{try{let e=await St(Z(t.workspaceDir,`package.json`),`utf-8`),n=JSON.parse(e);return new Set([...Object.keys(n.dependencies??{}),...Object.keys(n.devDependencies??{})])}catch{return new Set}}},new Set(t.activePlugins().map(e=>e.id))).catch(()=>[]);o.value?.stores.tasks.setCapabilityRecommendations(e)})()));let e=p;s.streamedText=!1;let r=await ae.handleInput(e);if(r.type===`exit`){se.current(r);return}if(r.type===`help`){a.value.modal.openModal({kind:`helpViewer`,title:`Help`,lines:Jt(P,n.pinned,Q.t(`cmdDesc`,{returnObjects:!0})),onDismiss:()=>{}});return}r.type!==`noop`&&r.text&&!s.streamedText&&(r.type===`system`&&r.text.length<=80?a.value.info.showToast(Q.t(`cmd.titleInfo`),r.text):a.value.messages.pushMessage({role:`assistant`,content:[{type:`text`,text:r.text}]})),r.type===`response`&&r.endReason&&(a.value.pending.clearPendingEcho(),r.notice&&a.value.info.showToast(Q.t(`cmd.titleInfo`),r.notice)),await xn(r,{runTurn:e=>ae.handleInput(e),onTurnResult:e=>e.type===`exit`?(se.current(e),`exit`):(e.type!==`noop`&&e.type!==`help`&&e.text&&!s.streamedText&&a.value.messages.pushMessage({role:`assistant`,content:[{type:`text`,text:e.text}]}),`continue`),askBudgetContinue:()=>new Promise(e=>{a.value.modal.openModal({kind:`select`,title:Q.t(`budget.exhaustedTitle`),layout:`buttons`,options:[{label:Q.t(`budget.continue`),value:`go`,color:`accent`},{label:Q.t(`budget.stop`),value:`stop`,color:`amber`}],onSelect:t=>e(t===`go`),onCancel:()=>e(!1)})}),onBudgetStopped:()=>{a.value.messages.pushMessage({role:`assistant`,content:[{type:`text`,text:Q.t(`budget.stoppedNote`)}]})},beforeContinuationTurn:()=>{s.streamedText=!1}})}catch(e){a.value.pending.withdrawPendingEcho(),S(e)}finally{s.agentProcessing=!1,s.userAborted=!1,a.value.engine.pushEngineEvent({kind:`agentProcessing`,value:!1}),a.value.plugins.setCommands(_())}},onInterrupt:()=>{let e=Date.now(),t=an(e,s.lastCtrlCTime,{shellRunning:!!s.shellChild,busy:u(),stopDialogOpen:f.isStopDialogOpen(),idleCtrlCCount:s.ctrlCCount});if(t!==`dedup`)switch(s.lastCtrlCTime=e,t){case`kill-shell`:s.shellChild.kill(`SIGTERM`),setTimeout(()=>{s.shellChild&&!s.shellChild.killed&&s.shellChild.kill(`SIGKILL`)},3e3);return;case`open-stop-dialog`:f.requestStop(`abort`);return;case`escalate-exit`:f.escalateToExit();return;case`exit-process`:m();return;case`hint-exit`:s.ctrlCCount++,setTimeout(()=>{s.ctrlCCount=0},800).unref(),a.value.info.showToast(Q.t(`cmd.titleExit`),Q.t(`cmd.pressCtrlCAgain`));return}},onShellAskAi:()=>{let e=o.value?.shell.getShellExecutionSnapshot();if(!e)return;let t=Fn(e);H?.(t,`send`,u()?`steer`:`send`)},onWithdrawPending:(e,t)=>{a.value.pending.withdrawPendingEcho()&&a.value.pending.restoreInputText(e),s.agentProcessing&&(s.userAborted=!0,d({kind:`abort`}),a.value.info.showToast(Q.t(`cmd.titleAborted`),Q.t(`cmd.runAborted`)))},onWithdrawSteer:e=>{n.removeSteer(e)?a.value.pending.withdrawPendingSteer(e):f.requestStop(`abort`)},onStop:()=>{p()}}}var Bn=class{estimate;intervalMs;now;text=``;measuredTokens=0;measuredChars=0;measuredAt=-1/0;constructor(e){this.estimate=e.estimate,this.intervalMs=e.intervalMs??250,this.now=e.now??(()=>Date.now())}reset(){this.text=``,this.measuredTokens=0,this.measuredChars=0,this.measuredAt=-1/0}push(e){if(!e)return;this.text+=e;let t=this.now();t-this.measuredAt>=this.intervalMs&&this.measure(t)}flush(){this.measure(this.now())}tokens(){let e=this.text.length-this.measuredChars;if(e<=0)return this.measuredTokens;let t=this.measuredChars>0?this.measuredTokens/this.measuredChars:.25;return this.measuredTokens+Math.ceil(e*t)}measure(e){this.measuredTokens=this.text?this.estimate(this.text):0,this.measuredChars=this.text.length,this.measuredAt=e}};function Vn(e,t){if(/^(bash|shell|run_command|execute|exec)$/i.test(e)){let e=t?.command;if(e)return e}return JSON.stringify(t??{}).slice(0,300)}async function Hn(e,t){let n=[`● ${t.header} — ${t.askedBy} asks:`,t.background?`\n${t.background}`:``,Q.t(`cmd.grillRecommendation`,{rec:t.recommendation}),t.evidence?.length?Q.t(`cmd.grillEvidence`,{joined:t.evidence.map(e=>` · ${e}`).join(`
|
|
9
9
|
`)}):``].join(``);e.messages.pushMessage({role:`assistant`,content:[{type:`text`,text:n}]});let r=t.options??[];if(r.length>0){if(r.length<=2&&!t.multiSelect&&t.allowFreeform===!1){let n=await new Promise(n=>{e.modal.openModal({kind:`confirm`,title:t.question,message:r.map(e=>`${e.label}${e.recommended?` (recommended)`:``}: ${e.rationale}`).join(`
|
|
10
10
|
`),confirmLabel:r[0]?.label??Q.t(`cmd.grillOptionYes`),cancelLabel:r[1]?.label??Q.t(`cmd.grillOptionNo`),onConfirm:()=>n(!0),onCancel:()=>n(!1)})})?r[0]?.label:r[1]?.label;return zt(t,n?[n]:[])}let n=await e.modal.openModal({kind:`questions`,title:t.question,questions:[{header:t.header,question:t.question,multiSelect:!!t.multiSelect,freeformInput:t.allowFreeform!==!1,freeformPlaceholder:Q.t(`cmd.grillFreeformPlaceholder`),options:r.map(e=>({label:e.recommended?`${e.label} ★`:e.label,description:e.rationale}))}]});return zt(t,(n?.answers?.[t.header]??[]).map(e=>e.replace(/\s*★$/,``)),n?.freeformText)}return Bt(t,await e.modal.openModal({kind:`input`,title:t.header,description:[t.question],placeholder:Q.t(`cmd.grillAnswerPlaceholder`)}))}function Un(t){let{getSession:r,app:a,tui:o,projState:s,redState:l,recomputeBudget:u,persistEditedFiles:d,persistSubagents:f,persistTurnCount:p,onContextCompacted:m,markStreamed:h}=t,g=null,_=!1,v=!1,y=null,b=null,x=e=>{let t=r(),n=t.session.getTurnCount();i({traceStore:a.storage.traceStore,sessionId:t.id,...n===void 0?{}:{turn:n}},e,`session-event`)},S=e=>{r().session.append({role:`system`,subtype:e,content:e,level:`info`,timestamp:Date.now()})},C=!1,w,ee={currentModel:()=>r().model.id,cacheHitRatio:()=>r().getLastCacheHitRatio(),turnTokens:()=>{let e=r().session.messages(),t=0;for(let n of e)n.role===`assistant`&&n.usage&&(t+=(n.usage.inputTokens??0)+(n.usage.outputTokens??0)+(n.usage.cacheReadTokens??0)+(n.usage.cacheWriteTokens??0));let n=w;if(w=t,!(n==null||t<=n))return t-n}},T,E=!1,D=0,O=0,te=0,k=new Bn({estimate:e}),A=()=>{O=0,te=0,D=0,k.reset()},ne=()=>{u(O+te+k.tokens())},j=0,M={},N=e=>{let t=0,n=0;for(let r of e.split(`
|
|
11
11
|
`))r.startsWith(`+`)&&!r.startsWith(`+++`)?t++:r.startsWith(`-`)&&!r.startsWith(`---`)&&n++;return`+${t}/-${n}`},P=()=>{let e=Y.listForSession(r().id).map(e=>({id:e.id,command:e.command,type:`process`,origin:`main`,status:e.status===`running`?`running`:e.status===`exited`?`exited`:`killed`,port:e.port,startedAt:e.startedAt,exitCode:e.exitCode,detectedService:e.detectedService})),t=new Map(J.list().map(e=>[e.id,e])),n=e=>{let n=t.get(e);return n?dt(n):{}},i=q.listForSession(r().id).map(e=>({id:e.id,command:e.title,type:`agent-session`,origin:e.origin,status:e.status===`running`||e.status===`ready`||e.status===`needs_input`?`running`:e.status===`applied`?`exited`:e.status===`failed`?`failed`:`killed`,agentStatus:e.status,diffStat:e.diff?N(e.diff):void 0,startedAt:e.startedAt,...n(e.id)})),a=new Set(i.map(e=>e.id)),s=J.list().filter(e=>!a.has(e.id)).map(ft),c=[...e,...i,...s];o.stores.tasks.setBackgroundTasks([...c.filter(e=>e.origin===`user`),...c.filter(e=>e.origin!==`user`)])},F=null,I=()=>{F===null&&(F=setTimeout(()=>{F=null,P()},30))},re=()=>{F!==null&&(clearTimeout(F),F=null),P()},ie=[Y.onSpawn(I),Y.onExit(re),q.onSpawn(I),q.onUpdate(I),q.onExit(re),q.onRemove(re),J.subscribe(I)];P();let L;return{bgUnsubs:ie,attachSessionHandler:()=>{L?.(),_=!1,L=r().subscribe(t=>{for(let e of Rt(t,s,ee)){if(e.kind===`prompt.end`){let t=n(e,l),i={turn:s.currentTurn,completedAt:Date.now(),...t},a=r().session.getTurnSummaries()??[];r().session.setTurnSummaries([...a.filter(e=>e.turn!==i.turn),i])}c(e,{pushMessage:o.messages.pushMessage,echoUserInput:o.messages.echoUserInput,pushEngineEvent:o.engine.pushEngineEvent,getNotifyStats:o.info.getNotifyStats,setTasks:(e,t)=>o.stores.tasks.setTasks(e,t),addTurnBoundary:e=>o.stores.tasks.addTurnBoundary(e)},l),e.kind===`tasks.update`&&(r().session.setTodoList(s.todoList),a.sessionManager.save(r().id).catch(()=>{}))}if(t.type===`stream.event`&&t.event?.type===`text_delta`){h();let e=t.event?.delta??``;D+=e.length,k.push(e),o.engine.pushEngineEvent({kind:`outputTokensThisTurn`,n:Math.floor(D/4)}),ne()}if(t.type===`stream.event`&&t.event?.type===`done`){let e=t.event?.providerUsage;if(e!==void 0){let t=e!==null&&ut(e.status,e.overageStatus);if(e===null||e.status===`rejected`&&!t)o.stores.notification.setProviderUsage(null),g=null;else{let t=r().model.provider;a.authStore.getAuthSource(t).then(n=>{if(r().model.provider!==t)return;let i=n===`oauth`?e:null;o.stores.notification.setProviderUsage(i),g=i}).catch(()=>{})}}}switch(t.type){case`turn.start`:D=0,k.reset(),ne(),o.engine.pushEngineEvent({kind:`spinnerMode`,mode:`requesting`});break;case`turn.end`:A(),u();break;case`streaming.start`:o.engine.pushEngineEvent({kind:`spinnerMode`,mode:`responding`}),o.pending.clearPendingEcho();break;case`streaming.end`:o.engine.pushEngineEvent({kind:`spinnerMode`,mode:null}),o.pending.clearPendingEcho();break;case`prompt.start`:A(),O=e(t.text),ne(),o.info.setTopView({session:r().id}),o.panes.clearEditedFiles(),o.plugins.clearSubagents(),j=l.messageIndex,o.info.addContextTurn({turnIndex:s.currentTurn,role:`assistant`,messageCount:0,estimatedTokens:0,compacted:!1,truncated:!1,pruned:!1});break;case`compaction.start`:T=t.messageCount,o.engine.pushEngineEvent({kind:`activeTool`,name:nt});break;case`compaction.end`:{let e=T??t.retainedCount,n=t.retainedCount;o.engine.pushEngineEvent({kind:`activeTool`,name:null}),n<e&&(o.messages.pushMessage({role:`compact_boundary`,before:e,after:n}),o.engine.pushEngineEvent({kind:`compactionLog`,entryKind:`compact`,before:e,after:n,summary:t.summary}),m()),T=void 0,u(void 0,{before:e,after:n});break}case`compaction.reactive.notice`:{let{messagesBefore:e,messagesAfter:n}=t;n<e&&(o.messages.pushMessage({role:`compact_boundary`,before:e,after:n}),o.engine.pushEngineEvent({kind:`compactionLog`,entryKind:`compact`,before:e,after:n,summary:t.summary}),m()),u(void 0,{before:e,after:n});break}case`image.degradation.notice`:t.degradedCount>0&&o.info.showToast(Q.t(`cmd.titleInfo`),Q.t(`cmd.imageDegradationNotice`,{count:t.degradedCount,context:t.trigger===`image-constraint`?`image-constraint`:`other`}));break;case`session.history-capped`:o.messages.pushMessage({role:`history_capped`,removedCount:t.removedCount,trigger:t.trigger,...t.lossy?{lossy:!0}:{}}),o.engine.pushEngineEvent({kind:`compactionLog`,entryKind:`history_capped`,removedCount:t.removedCount});break;case`session.write-lease-denied`:_=!0,o.messages.pushMessage({role:`write_lease_denied`}),o.info.showToast(Q.t(`lease.deniedToastTitle`),Q.t(`lease.deniedToastBody`));break;case`session.write-lease-restored`:_=!1,o.messages.pushMessage({role:`write_lease_restored`}),o.info.showToast(Q.t(`lease.restoredToastTitle`),Q.t(`lease.restoredToastBody`));break;case`session.crash-gap-detected`:o.info.showToast(Q.t(`crashGap.toastTitle`),Q.t(`crashGap.toastBody`,{lostTurns:t.lostTurns}));break;case`run.pause_requested`:v=!0,y={at:Date.now(),toolCount:0},x(`requested`),o.engine.setPauseDialog?.({phase:`requested`,requestedAt:Date.now(),toolCount:0,onCancel:()=>{},onDismiss:()=>{o.engine.setPauseDialog?.(null)}}),b&&clearInterval(b),b=setInterval(()=>{if(!y){clearInterval(b),b=null;return}let e=Math.floor((Date.now()-y.at)/1e3);o.stores.notification.setPausePending({elapsedSec:e,toolCount:y.toolCount})},1e3);break;case`tool.call.end`:{let n=typeof t.resultTokensEstimate==`number`?t.resultTokensEstimate:t.resultText?e(t.resultText):0;n>0&&(te+=n,ne()),y&&(y.toolCount++,o.engine.setPauseDialog?.({phase:`requested`,requestedAt:y.at,toolCount:y.toolCount,onCancel:()=>{},onDismiss:()=>{o.engine.setPauseDialog?.(null)}})),(async()=>{try{let e={role:`tool_result`,name:t.toolCall.name,toolCallId:t.toolCall.id,content:[{type:`text`,text:t.resultText??``}],details:t.details},n=await a.resolveA2uiRendererPayload(e);n&&n.length>0&&o.messages.pushMessage({role:`assistant`,content:[{type:`a2ui`,components:n}]})}catch{}})();break}case`run.paused`:x(`paused`),y?(o.engine.setPauseDialog?.({phase:`active`,requestedAt:y.at,toolCount:y.toolCount,totalToolCount:y.toolCount}),o.messages.pushMessage({role:`run_paused`,toolCount:y.toolCount}),S(`run_paused`),b&&=(clearInterval(b),null),o.stores.notification.setPausePending(null),y=null):(o.messages.pushMessage({role:`run_paused`}),S(`run_paused`)),o.stores.notification.setPaused(!0);break;case`run.pause_cancelled`:x(`cancelled`),o.engine.setPauseDialog?.(null),o.messages.pushMessage({role:`run.pause_cancelled`}),S(`run_pause_cancelled`),b&&=(clearInterval(b),null),o.stores.notification.setPausePending(null),y=null,v=!1;break;case`run.resumed`:x(`resumed`),o.engine.setPauseDialog?.(null),o.messages.pushMessage({role:`run_resumed`}),S(`run_resumed`),b&&=(clearInterval(b),null),o.stores.notification.setPausePending(null),y=null,v=!1,o.stores.notification.setPaused(!1);break;case`steer.consumed`:o.pending.commitPendingSteer(t.id);break;case`image.vision-delegate`:!C&&t.describedCount>0&&(C=!0,o.info.showToast(Q.t(`cmd.titleInfo`),Q.t(`model.visionDelegateToast`,{count:t.describedCount})));break;case`memory.pruned`:E||(E=!0,o.messages.pushMessage({role:`prune_boundary`})),o.engine.pushEngineEvent({kind:`compactionLog`,entryKind:`prune`,tokensSaved:t.tokensSaved,prunedCount:t.prunedCount}),u();break;case`error`:d(),f(),o.pending.withdrawPendingEcho();break;case`prompt.continued`:o.info.showToast(Q.t(`cmd.titleInfo`),Q.t(`cmd.todoGateContinuing`,{round:t.round,cap:t.maxRounds,left:t.incompleteCount}));break;case`prompt.budget.notice`:t.steered&&o.info.showToast(Q.t(`cmd.titleInfo`),Q.t(`cmd.promptBudgetExceeded`,{context:t.dimension,used:t.used,budget:t.budget}));break;case`budget.notice`:t.extended?o.info.showToast(Q.t(`cmd.titleInfo`),Q.t(`cmd.budgetExtended`,{maxTurns:t.maxTurns})):t.steered&&o.info.showToast(Q.t(`cmd.titleInfo`),t.progressDenied?Q.t(`cmd.budgetProgressDenied`):Q.t(`cmd.budgetSteered`,{maxTurns:t.maxTurns}));break;case`progress.stall.notice`:o.info.showToast(Q.t(`cmd.titleInfo`),Q.t(`cmd.progressStallDetected`,{maxRepeat:t.maxRepeat}));break;case`tool.call.mismatch.notice`:t.outcome===`retry`?o.info.showToast(Q.t(`cmd.titleInfo`),Q.t(`cmd.toolCallMismatchRetry`,{retryCount:t.retryCount})):o.info.showToast(Q.t(`cmd.titleError`),Q.t(`cmd.toolCallMismatchTerminated`));break;case`session.cost-budget-exceeded`:o.info.showToast(Q.t(`cmd.titleInfo`),Q.t(`cmd.sessionCostBudgetExceeded`,{used:t.totalCostUSD.toFixed(2),budget:t.budgetUSD.toFixed(2)}));break;case`prompt.end`:A(),o.pending.clearPendingSteers(),u(),o.info.markContextTurns({turnIndex:s.currentTurn,messageCount:Math.max(0,l.messageIndex-j)}),d(),f(),p();{let e=r(),t=je(e.session.metadata().title,e.session.messages(),e.id);o.stores.tasks.setSessionTitle(t),o.lifecycle.setTerminalTitle(t)}if(process.env.OTTO_TUI_DEBUG_NOTIFY_STATS){let e=o.info.getNotifyStats();if(e.coalescedCalls>0){let t=(e.coalescedCalls/Math.max(1,e.coalescedFires)).toFixed(1);console.error(`\x1b[90m\x1b[2m[perf] notify merge ${e.coalescedCalls}→${e.coalescedFires} (${t}x) direct ${e.immediateCalls} flush ${e.flushFires}\x1b[0m`)}}{let e=a.settings.get(`pulse_survey`);a.feedbackRegistry.get()!==void 0&&Ht(s.currentTurn,{enabled:e?.enabled??!0,probability:e?.probability??.05,minTurnGap:e?.min_turn_gap??20,forcedUpgradeActive:o.info.isForcedUpgradeActive()},M)&&(M.lastShownTurn=s.currentTurn,o.stores.notification.setPulseSurvey({phase:`rating`,rating:null,selectedIndex:0,commentText:``,commentOffset:0,onSubmit:(e,t)=>{a.feedbackRegistry.get()?.recordPulseSurvey?.({ts:Date.now(),rating:e,comment:t,sdkVersion:qe,modelId:r().model?.id})},onClose:()=>o.stores.notification.setPulseSurvey(null)}))}break;case`ask.user.required`:{let e=t.question,n=t.requestId;(async()=>{let i=a.inquiryCenter;if(!i.enqueue({id:n,origin:{kind:`session`,sessionId:t.sessionId},question:e}).accepted){r().resolveAskUser(n,{answer:``,acceptedRecommendation:!1,resolvedBy:`human`});return}if(!await i.waitForTurn(n)){r().resolveAskUser(n,{answer:``,acceptedRecommendation:!1,resolvedBy:`human`});return}try{let t=await Hn(o,e);r().resolveAskUser(n,t)}finally{i.release(n)}})();break}case`approval.required`:{if(t.semanticVerdict){let e=Vt(t.description,t.arguments,ye);t.semanticVerdict===`allow`&&e&&a.approveSandboxBypass(e),a.logger?.info?.({approvalId:t.id,verdict:t.semanticVerdict,toolName:t.toolName},`Semantic approval verdict handled (no prompt)`);break}let e=t.toolName===`bash`&&typeof t.arguments?.command==`string`?t.arguments.command:``,n=e?a.bashAlwaysAllowPrefix(e):null;o.modal.requestPermission({tool:t.toolName,input:Vn(t.toolName,t.arguments),risk:t.risk??`medium`,description:t.description,alwaysAllowLabel:n??void 0}).then(e=>{let i=Vt(t.description,t.arguments,ye);e.approved&&i&&a.approveSandboxBypass(i),r().resolveApproval(t.id,e.approved),e.approved&&e.mode===`always`&&(t.toolName===`bash`?n&&a.allowToolAlways(`bash(${n})`,r().id):a.allowToolAlways(t.toolName,r().id))});break}}})},getSessionUnsub:()=>L,getLastProviderUsage:()=>g,isWriteLeaseReadOnly:()=>_,isRunPaused:()=>v}}function Wn(e){let t=(t,n)=>{e.onError?.(t,n)},n=async n=>{let r=e.gateway(),i=e.bridge();if(!(!r||!i))try{let e=await r.getPaste(n);i.hydratePaste({entries:e.entries,nextId:e.nextId})}catch(e){t(`load`,e);try{i.hydratePaste(null)}catch{}}},r=async n=>{let r=e.gateway(),i=e.bridge();if(!(!r||!i))try{let e=i.exportPaste();if(!e)return;await r.setPaste(n,{sessionId:n,entries:e.entries,nextId:e.nextId})}catch(e){t(`save`,e)}};return{load:n,save:r,async switchTo(e,t){e!==t&&(e!==void 0&&await r(e),await n(t))},async fork(n,r){let i=e.gateway(),a=e.bridge();if(!(!i||!a))try{let e=a.exportPaste()??await i.getPaste(n);await i.setPaste(r,{sessionId:r,entries:e.entries,nextId:e.nextId})}catch(e){t(`fork`,e)}}}}function Gn(e){e.setEcosystemSearch(async t=>{try{let{registries:n,warnings:r}=await ge(e).loadAll();return{hits:X(n.flatMap(e=>e.entries.map(t=>({entry:t,registry:e}))).map(e=>({text:e.entry.id,aliases:[e.entry.description,...e.entry.keywords??[]],payload:e})),t.join(` `),{maxResults:8}).map(e=>({id:e.item.payload.entry.id,description:e.item.payload.entry.description,capabilities:e.item.payload.entry.capabilities,sourceName:e.item.payload.registry.sourceName,stale:e.item.payload.registry.stale})),warnings:r}}catch{return}})}function Kn(e){let{app:t,tui:n}=e;t.setMcpStartupCallback(e=>{let r=[`HTTP_PROXY`,`HTTPS_PROXY`,`http_proxy`,`https_proxy`].find(e=>process.env[e]),i=r?process.env[r]:void 0,a=t.settings.get(`proxy`);i&&r&&!a?.url&&(G(i,r),n.info.showToast(Q.t(`proxy.title`),Q.t(`proxy.envDetectedToast`,{source:r,value:i})))})}function qn(e){let{app:t,tui:n,session:r}=e;n.plugins.registerArgumentSuggester(`model`,(e,n=20)=>X(t.modelRegistry.getAll().filter(e=>e.id!==`__otto_setup__`).map(e=>({text:e.id,aliases:[e.name,e.provider],payload:e})),e,{maxResults:n}).map(e=>({name:e.item.payload.id,description:e.item.payload.name})));let i=je(r.session.metadata().title,r.session.messages(),r.id);n.lifecycle.setTerminalTitle(i),n.stores.tasks.setSessionTitle(i)}function Jn(e){let{app:t,tui:n,getScheduler:r}=e;n.plugins.registerArgumentSuggester(`schedule`,(e,t=20)=>{let n=[`remove`,`run`,`enable`,`disable`],i=n.find(t=>e.toLowerCase().startsWith(`${t} `));if(!i)return X([...n,`list`,`add`,`logs`].map(e=>({text:e,aliases:[],payload:e})),e,{maxResults:t}).map(e=>({name:e.item.payload}));let a=r();if(!a)return[];let o=e.slice(i.length+1);return X(a.list().map(e=>({text:e.id,aliases:[e.name],payload:e})),o,{maxResults:t}).map(e=>({name:`${i} ${e.item.payload.id}`,description:e.item.payload.name}))}),n.plugins.registerArgumentSuggester(`replay`,(e,n=20)=>X(t.listSessions().map(e=>({text:e.id,aliases:e.title?[e.title]:[],payload:e})),e,{maxResults:n}).map(e=>({name:e.item.payload.id,description:e.item.payload.title??e.item.payload.id.slice(0,8)}))),n.plugins.registerArgumentSuggester(`session`,(e,n=20)=>{let r=e.toLowerCase().startsWith(`unlock `)?e.slice(7):e;return r===e?X([{name:`fork`,description:`Fork current session into a named branch`},{name:`unlock`,description:`Write-lease diagnostics/force-unlock`},{name:`kill`,description:`Terminate a session`},{name:`inspect`,description:`Read-only remote snapshot preview`},{name:`pin`,description:`Toggle pin state (pinned sort to top of session list)`},{name:`archive`,description:`Toggle archive state`},{name:`resume`,description:`List and switch to an existing session`},{name:`compact`,description:"Compact context now (or `compact log` for details)"},{name:`context`,description:`Show context usage breakdown`}].map(e=>({text:e.name,aliases:[],payload:e})),e,{maxResults:n}).map(e=>({name:e.item.payload.name,description:e.item.payload.description})):X(t.listSessions().map(e=>({text:e.id,aliases:e.title?[e.title]:[],payload:e})),r,{maxResults:n}).map(e=>({name:`unlock ${e.item.payload.id}`,description:e.item.payload.title??e.item.payload.id.slice(0,8)}))}),n.plugins.registerArgumentSuggester(`status`,(e,t=20)=>X([`perf`,`cache`,`diagnose`,`services`].map(e=>({text:e,aliases:[],payload:e})),e,{maxResults:t}).map(e=>({name:e.item.payload}))),n.plugins.registerArgumentSuggester(`preference`,(e,t=20)=>X([`general`,`lang`,`theme`,`keybindings`,`shortcuts`,`proxy`].map(e=>({text:e,aliases:[],payload:e})),e,{maxResults:t}).map(e=>({name:e.item.payload}))),n.plugins.registerArgumentSuggester(`extension`,(e,n=20)=>{let r=e.toLowerCase();if(r.startsWith(`trust plugin `)){let r=e.slice(13);return X(W({cwd:t.workspaceDir??process.cwd(),homedir:K()}).map(e=>({text:e.id,aliases:[],payload:e})),r,{maxResults:n}).map(e=>({name:`trust plugin ${e.item.payload.id}`,description:e.item.payload.scope}))}if(r.startsWith(`trust `)){let t=e.slice(6);return X([`status`,`trust`,`untrust`,`plugin`].map(e=>({text:e,aliases:[],payload:e})),t,{maxResults:n}).map(e=>({name:`trust ${e.item.payload}`}))}if(r.startsWith(`registry `)){let t=e.slice(9);return X([`list`,`add`,`remove`].map(e=>({text:e,aliases:[],payload:e})),t,{maxResults:n}).map(e=>({name:`registry ${e.item.payload}`}))}return X([`trust`,`install`,`registry`,`search`,`update`,`reload`].map(e=>({text:e,aliases:[],payload:e})),e,{maxResults:n}).map(e=>({name:e.item.payload}))}),n.plugins.registerArgumentSuggester(`registry`,(e,n=20)=>{let r=e.toLowerCase().startsWith(`remove `)?e.slice(7):e;return r===e?X([`list`,`add`,`remove`].map(e=>({text:e,aliases:[],payload:e})),e,{maxResults:n}).map(e=>({name:e.item.payload})):X(ge(t).listSources().filter(e=>!e.builtin).map(e=>({text:e.name,aliases:[e.url],payload:e})),r,{maxResults:n}).map(e=>({name:`remove ${e.item.payload.name}`,description:e.item.payload.url}))}),n.plugins.registerArgumentSuggester(`trust`,(e,n=20)=>{let r=e.toLowerCase().startsWith(`plugin `)?e.slice(7):e;return r===e?X([`status`,`trust`,`untrust`,`plugin`].map(e=>({text:e,aliases:[],payload:e})),e,{maxResults:n}).map(e=>({name:e.item.payload})):X(W({cwd:t.workspaceDir??process.cwd(),homedir:K()}).map(e=>({text:e.id,aliases:[],payload:e})),r,{maxResults:n}).map(e=>({name:`plugin ${e.item.payload.id}`,description:e.item.payload.scope}))})}function Yn(e){let t=e[e.length-1];if(t?.type===`message`&&t.message?.role===`user`)return{parentId:t.parentId}}function Xn(e,t){!t||!t.newer||(e.stores.tasks.setUpdateAvailable(t),t.forced?(e.info.pushNotification(Q.t(`cmd.titleUpdate`),Q.t(`cmd.updateNotifForced`,{latest:t.latest,current:t.current}),`version`,`error`),e.stores.tasks.setForcedUpgrade(Q.t(`cmd.updateForcedBanner`,{latest:t.latest,current:t.current})),e.stores.notification.setPulseSurvey(null)):(e.info.pushNotification(Q.t(`cmd.titleUpdate`),Q.t(`cmd.updateNotifAvailable`,{latest:t.latest,current:t.current}),`version`,`info`),e.info.showToast(Q.t(`cmd.titleUpdate`),Q.t(`cmd.updateToast`,{latest:t.latest}))))}async function Zn(e){let{tui:t,options:n,app:r,session:i,projState:a,resumedNote:o,resumed:s,updateCheckPromise:c,bg:l,events:u}=e;if(o&&g({resumedNote:o,isFound:!!s,session:i,projState:a,tui:t}),n.resumePrompt&&s)if(r.memoryGovernor.sample().level===`critical`)t.info.showToast(Q.t(`cmd.titleMemoryPressure`),Q.t(`cmd.memoryPressureResumeAbortedMessage`));else{let e=Yn(i.session.branchEntries());e&&(e.parentId&&i.session.branch(e.parentId),i.prompt(n.resumePrompt).catch(e=>{r.logger.warn({err:e instanceof Error?e.message:String(e)},`[memory-governor] auto-resume prompt failed`),t.info.showToast(Q.t(`cmd.titleError`),Q.t(`cmd.memoryPressureResumeFailedMessage`))}))}c.then(e=>Xn(t,e)),l.setBgUnsubs(u.bgUnsubs),u.attachSessionHandler(),Qn(t,r)}function Qn(e,t){p(n=>{if(n.status!==`needs-input`)return;let r=n.id.slice(0,8),i=t.listSessions().find(e=>e.id===n.id)?.title??r;e.info.pushNotification(`session needs input`,`Background session '${i}' (${r}) requires your input (/resume ${r})`,`system`,`warning`)}),t.hookRegistry.on(`session.deleted`,`rfc234-background-cleanup`,e=>{m(e.sessionId)})}function $n(e){return e.startsWith(`backend/`)?e.slice(8):e}function er(e){let t=()=>({tasks:e.list(),runningTaskIds:[...e.getRunningTaskIds()],isFireOwner:e.isFireOwner(),fireOwnerFailureReason:e.fireOwnerFailureReason()});return{call:async(n,r)=>{let i=$n(n);switch(i){case`schedule.list`:return t();case`schedule.add`:{let t=r;try{let n=e.add({name:t.name,prompt:t.prompt,cronExpression:t.cronExpression,recurring:t.recurring,origin:`user`,target:t.target});return{ok:!0,taskId:n.id,name:n.name,target:n.target}}catch(e){return{ok:!1,error:e instanceof Error?e.message:String(e)}}}case`schedule.update`:{let t=r,n={};return t.name!==void 0&&(n.name=t.name),t.prompt!==void 0&&(n.prompt=t.prompt),t.cronExpression!==void 0&&(n.cronExpression=t.cronExpression),t.enabled!==void 0&&(n.enabled=t.enabled),{ok:e.update(t.taskId,n)}}case`schedule.runNow`:{let{taskId:t}=r;return e.runNow(t),{ok:!0}}case`schedule.toggle`:{let{taskId:t,enabled:n}=r;return{ok:e.update(t,{enabled:n})}}case`schedule.cancel`:{let{taskId:t}=r;return e.cancel(t)}case`schedule.remove`:{let{taskId:t}=r;return{ok:e.remove(t)}}case`schedule.readLogs`:{let{taskId:t,limit:n}=r;return{entries:e.readFireLogs(t,n??20)}}case`schedule.parseCron`:{let{expr:e}=r;try{return{ok:!0,next:Ft(e).toISOString()}}catch(e){return{ok:!1,error:e instanceof Error?e.message:String(e)}}}default:throw Error(`unknown schedule backend method: ${i}`)}},getSnapshot:t}}function tr(e){return t=>{let n=e.value;if(n.id!==t.boundSessionId||n.isPaused||n.status===`archived`)return!1;try{return n.prompt(t.prompt,{streamingBehavior:`followUp`}).catch(()=>{}),!0}catch{return!1}}}function nr(e,t,n,r){let i=e.workspaceRef?.key??`default`,a=new kt,o,s;if(e.storage.remoteSessionConfigured&&r){let e=async()=>({token:r.sessionToken});o=Nt({sessionUrl:r.sessionUrl,getAuth:e,wsKey:i}),s=Mt({sessionUrl:r.sessionUrl,wsKey:i,getAuth:e})}else o=Pt(i),s=jt(i);let c=new At({registry:a,store:o,ownership:s,jobRegistry:Pe,startJob:t=>({id:e.agentJobs.start({title:t.title,prompt:t.prompt,sessionId:t.sessionId,origin:t.origin}).id}),getSessionId:()=>t.value.id,notifySubscriber:(t,n)=>e.notifyPluginServiceSchedule({pluginId:t.pluginId,serviceId:t.serviceId},n),followUpCurrentSession:tr(t),retryBackoffMs:e.getResilienceConfig().schedule.retryBackoffMs});c.start().catch(e=>{console.error(`\x1b[3m\x1b[2m[schedule] scheduler failed to start: ${e instanceof Error?e.message:String(e)}\x1b[0m`)}),z(c),e.setScheduleService(c);let l=er(c);e.panelBackendController.registerInProcessBackend(`plugin-schedule`,l.call);let u=setInterval(()=>{if(!n)return;let e=c.list().map(e=>({id:e.id,name:e.name,prompt:e.prompt,cronExpression:e.cronExpression,enabled:e.enabled,recurring:e.recurring,nextFireAt:e.nextFireAt,lastFiredAt:e.lastFiredAt,lastFireFailed:e.lastFireFailed,lastFireError:e.lastFireError,lastFireCancelled:e.lastFireCancelled}));n.stores.tasks.setScheduleTasks(e)},5e3);return u.unref(),{pollInterval:u,scheduler:c}}function rr(e){let{app:t,session:n,options:r,tui:i,memoryConflictRef:a,turn:o,stopController:s,runAsyncBashRef:c,handleAbortInterceptRef:l,runMemoryCaptureRef:u,schedulePollIntervalRef:d,scheduleServiceRef:f}=e;a&&(a.current=(e,t)=>{i.info.showToast(`Memory Conflict`,`Concurrent edit detected for ${e} — saved to ${t}`)}),Be(`startTui() ready (first frame mounted)`),t.setUserAskRenderer(e=>Hn(i,e));let p=Wn({gateway:()=>t.sessionManager.panelState,bridge:()=>i.pending,onError:(e,n)=>{t.logger?.debug?.({stage:e,error:n},`paste cache binding failed (non-fatal)`)}});Kn({app:t,tui:i}),Gn(t),t.listAllSessions().then(e=>{let t=n.id,r=e.filter(e=>e.status!==`archived`&&(e.entryCount??e.messageCount)>0&&e.id!==t).slice(0,10).map(e=>({id:e.id,title:e.title??e.id.slice(0,8),status:e.id===t?`busy`:`idle-cold`,lastActivityAt:e.updatedAt?new Date(e.updatedAt).toLocaleString():``,isCurrent:e.id===t,isPinned:e.pinned??!1,isArchived:e.status===`archived`,isReadOnly:e.writeLocked??!1}));i.stores.tasks.setSessionList(r)}).catch(()=>{});let{pollInterval:m,scheduler:h}=nr(t,{get value(){return n}},i,r.sessionUrl&&r.sessionToken?{sessionUrl:r.sessionUrl,sessionToken:r.sessionToken}:void 0);return d.current=m,f.current=h,c.current=Mn({tui:i,app:t,submitState:o}),l.current=Nn({agentProcessingRef:{get value(){return o.agentProcessing},set value(e){o.agentProcessing=e}},tui:i,requestStop:e=>s.requestStop(e)}),u.current=Pn({app:t,tui:i}),qn({app:t,tui:i,session:n}),Jn({app:t,tui:i,getScheduler:()=>h}),{pasteBinder:p}}const ir=[`approaching`,`nearing`,`critical`],ar={maxReminders:{approaching:1,nearing:3,critical:1},backoffBaseTurns:4,resetMarginPct:10,approachingMarginPct:10};function $(){return{count:0,lastRemindedTurn:void 0,peakPct:0,active:!1}}function or(e,t,n,r){return e>=n?`critical`:e>=t?`nearing`:e>=t-r?`approaching`:null}function sr(e,t,n,r){return e===`critical`?n:e===`nearing`?t:t-r}function cr(e,t){return t<=1?0:e.backoffBaseTurns*2**(t-2)}var lr=class{config;zones;suppressed=!1;constructor(e={}){this.config={...ar,...e},this.zones={approaching:$(),nearing:$(),critical:$()}}check(e){if(this.suppressed)return null;let{contextPercent:t,pruneLinePct:n,compactLinePct:r,currentTurn:i}=e,a=or(t,n,r,this.config.approachingMarginPct);for(let e of ir)e!==a&&this.zones[e].active&&t<sr(e,n,r,this.config.approachingMarginPct)-this.config.resetMarginPct&&(this.zones[e]=$());if(a===null)return null;let o=this.zones[a];o.lastRemindedTurn!==void 0&&i<o.lastRemindedTurn&&(this.zones[a]=$());let s=this.zones[a];s.active=!0,s.peakPct=Math.max(s.peakPct,t);let c=this.config.maxReminders[a];if(s.count>=c)return null;let l=s.count+1;if(s.lastRemindedTurn!==void 0){let e=cr(this.config,l);if(i-s.lastRemindedTurn<e)return null}return s.count=l,s.lastRemindedTurn=i,{zone:a,pct:Math.round(t)}}onCompacted(){this.zones={approaching:$(),nearing:$(),critical:$()}}suppress(){this.suppressed=!0}snapshot(){return{approaching:{count:this.zones.approaching.count,lastTurn:this.zones.approaching.lastRemindedTurn},nearing:{count:this.zones.nearing.count,lastTurn:this.zones.nearing.lastRemindedTurn},critical:{count:this.zones.critical.count,lastTurn:this.zones.critical.lastRemindedTurn}}}};function ur(e){let{getSession:t,app:n,tui:r,projState:i,contextWindow:a,currentModelId:o}=e,s,c=new lr,l={approaching:e=>Q.t(`cmd.contextPressureApproaching`,{pct:e}),nearing:e=>Q.t(`cmd.contextPressureNearing`,{pct:e}),critical:e=>Q.t(`cmd.contextPressureCritical`,{pct:e})},u=()=>{let e=t(),n=e.session.messages(),r=0,i=0,a=0,o=0,s=!1,c=0,l=0;for(let e=n.length-1;e>=0;e--){let t=n[e]?.usage;t&&(s||=(r=t.inputTokens??0,i=t.outputTokens??0,a=t.cacheReadTokens??0,o=t.cacheWriteTokens??0,!0),n[e]?.role===`assistant`&&(c+=t.inputTokens??0,l+=t.outputTokens??0))}return{sessionId:e.session.id,lastIn:r,lastOut:i,lastCacheRead:a,lastCacheWrite:o,totIn:c,totOut:l,messageCount:n.length}},d=(e,d)=>{let f=e!==void 0,p=f&&s&&s.sessionId===t().session.id?s:u();s=p;let m=d?d.before:1,h=d?d.after/m:1,g=e=>h<1?Math.round(e*h):e,v=n.modelRegistry.find(o.value??``)?.cost,y=v?p.totIn*(v.input??0)+p.totOut*(v.output??0):0,b=_({systemPrompt:t().systemPrompt,tools:t().tools,lastIn:g(p.lastIn),lastOut:g(p.lastOut),lastCacheRead:g(p.lastCacheRead),lastCacheWrite:g(p.lastCacheWrite),contextWindow:a.value,modelName:t().model?.name??``,totIn:p.totIn,totOut:p.totOut,cost:y>0?y:void 0,messageCount:p.messageCount,streamingOutputTokens:e});if(r.stores.budget.setBudget(b),r.stores.context.setBudget(b),!f&&b.contextWindow>0){let e=b.pruneLine/b.contextWindow*100,t=b.compactLine/b.contextWindow*100,n=c.check({contextPercent:b.contextPercent,pruneLinePct:e,compactLinePct:t,currentTurn:i.currentTurn});n&&r.info.pushNotification(Q.t(`cmd.titleContextPressure`),l[n.zone](n.pct),`system`,n.zone===`critical`?`warning`:`info`)}},f=()=>{try{t().session.setEditedFiles(r.messages.getEditedFiles().map(e=>({path:e.path,operation:e.operation,addedLines:e.addedLines,removedLines:e.removedLines,timestamp:e.timestamp,toolCallId:e.toolCallId}))),n.sessionManager.save(t().id).catch(()=>{})}catch(e){console.error(`\x1b[90m\x1b[2m[persist] editedFiles skipped (non-fatal): ${e instanceof Error?e.message:String(e)}\x1b[0m`)}};return{recomputeBudget:d,persistEditedFiles:f,persistSubagents:()=>{try{let e=[...r.plugins.getSubagents().values()].map(e=>({id:e.id,name:e.command||e.id,status:yt(e),startedAt:e.startedAt}));t().session.setSubagents(e),n.sessionManager.save(t().id).catch(()=>{})}catch(e){console.error(`\x1b[90m\x1b[2m[persist] subagents skipped (non-fatal): ${e instanceof Error?e.message:String(e)}\x1b[0m`)}},persistTurnCount:()=>{try{t().session.setTurnCount(i.currentTurn)}catch(e){console.error(`\x1b[90m\x1b[2m[persist] turnCount skipped (non-fatal): ${e instanceof Error?e.message:String(e)}\x1b[0m`)}},editFileCallback:e=>{try{r.stores.tasks.addEditedFile({path:e.path,operation:e.operation,oldContent:e.oldContent,newContent:e.newContent,addedLines:e.addedLines,removedLines:e.removedLines,timestamp:e.timestamp,toolCallId:e.toolCallId})}catch(e){console.error(`\x1b[90m\x1b[2m[panel] addEditedFile skipped (non-fatal): ${e instanceof Error?e.message:String(e)}\x1b[0m`)}f()},onContextCompacted:()=>{c.onCompacted()}}}function dr(e){let{tui:t,app:n,themeRegistry:r,sessionRef:i,interactiveRef:a,regRef:s,slashCommandsRef:c,modelReadyRef:l,currentModelIdRef:u,currentLangRef:d,projState:f,agentProcessingRef:p,modelsRef:m,availableModelIds:h,restartRequestedRef:g,applyModel:_,persistAvailable:v,refreshModelsNow:y,refreshSlashCommands:b,events:x,redState:C,agentMessagesToChatMessages:w,PROVIDER_DISPLAY_NAMES:ee,apiCredentialId:T,onContextCompacted:E}=e;return{tui:t,app:n,state:{get session(){return i.value},set session(e){i.value=e},get interactive(){return a.value},set interactive(e){a.value=e},get reg(){return s.value},set reg(e){s.value=e},get slashCommands(){return c.value},set slashCommands(e){c.value=e},get modelReady(){return l.value},set modelReady(e){l.value=e},get currentModelId(){return u.value},set currentModelId(e){u.value=e},get currentLang(){return d.value},set currentLang(e){d.value=e},get todoList(){return f.todoList},set todoList(e){f.todoList=e},get agentProcessing(){return p.value},set agentProcessing(e){p.value=e},get models(){return m.value},set models(e){m.value=e},get availableModelIds(){return h},get restartRequested(){return g.value},set restartRequested(e){g.value=!!e},themeRegistry:r},callbacks:{applyModel:_,persistAvailable:v,refreshModelsNow:y,registerAllTuiCommands:()=>{Xt(s.value)},refreshSlashCommands:b,attachSessionHandler:()=>x.attachSessionHandler(),restoreSwitchedSession:()=>{f.delegated.clear(),f.todoList=[],f.currentTurn=0,Object.assign(C,S()),t.stores.tasks.setTasks([],void 0),t.panes.clearEditedFiles(),t.plugins.clearSubagents(),o({session:i.value,projState:f,tui:t}),E()},resetCurrentTurn:()=>{f.currentTurn=0},onContextCompacted:E,sessionUnsub:()=>x.getSessionUnsub(),getLastProviderUsage:()=>x.getLastProviderUsage(),isWriteLeaseReadOnly:()=>x.isWriteLeaseReadOnly(),isRunPaused:()=>x.isRunPaused(),agentMessagesToChatMessages:w,PROVIDER_DISPLAY_NAMES:ee,apiCredentialId:T}}}function fr(e){let{session:t,tui:n,retryAccelerate:r,setRateLimitInfo:i,abortNow:a}=e;t.coreAgent.on(`stream.retry`,({attempt:e,maxRetries:t,delayMs:i,reason:o})=>{n.engine.showRetryDialog(e,t,i,r,()=>{n.engine.clearRetryDialog()},o,()=>{a()})}),t.coreAgent.on(`rate.limit.exhausted`,({limitType:e,resetsAt:t})=>{n.engine.clearRetryDialog(),i({limitType:e,resetsAt:t})}),t.coreAgent.on(`lifecycle.tool.completed.crossBoundary`,({toolName:e,result:t})=>{let r=Q.t(`cmd.titleBackgroundTask`),i=t.isError?Q.t(`cmd.lifecycleCrossBoundaryFailed`,{toolName:e}):Q.t(`cmd.lifecycleCrossBoundaryDone`,{toolName:e});n.info.showToast(r,i)})}function pr(e,t){let n=process.env[e];if(!n)return t;let r=Number(n);return Number.isFinite(r)&&r>0?r:t}function mr(e,t){let n=process.env[e];if(!n)return t;let r=Number(n);return Number.isFinite(r)&&r>0&&Number.isInteger(r)?r:t}function hr(e){let{app:t,tui:n,getSession:r,setRestartResumePrompt:i,setRestartMemoryTriggered:a,handleExit:o,onContextCompacted:c,recomputeBudget:l}=e,u=!1,d=0,f,p=!1,m=0,h=!1,g=pr(`OTTO_MEMORY_CRITICAL_NOTIFY_INTERVAL_MS`,18e5),_=mr(`OTTO_MEMORY_CRITICAL_NOTIFY_ESCALATION_CYCLES`,4),v,y=()=>{let e=r();if(e.isBusy){let t=e.session.messages(),n=t[t.length-1];if(n?.role===`user`&&!n.internal){let e=s(n.content);e&&i(e)}}a(!0),o({type:`exit`,restart:!0})},b=()=>{v&&=(clearInterval(v),void 0),m=0,h=!1};t.memoryGovernor.setCallbacks({onWarning:()=>{r().compactNow().then(e=>{e.compacted&&(n.info.showToast(Q.t(`cmd.titleAutoCompact`),Q.t(`compact.edResult`,{before:e.before,after:e.after})),c(),l())}).catch(e=>{let r=e instanceof Error?e.message:String(e);t.logger.warn({err:r},`[memory-governor] compactNow (soft degrade) failed`),n.info.showToast(Q.t(`cmd.titleAutoCompact`),Q.t(`cmd.autoCompactFailed`,{msg:r}))})},onCritical:e=>{if(u){n.info.pushNotification(Q.t(`cmd.titleMemoryPressure`),Q.t(`cmd.memoryPressureMessage`,{usedPct:e.usedPct.toFixed(0)}),`system`,`info`);return}n.info.isFullScreenPaneActive()&&(d++,f??=Date.now(),d<3&&Date.now()-f<300*1e3)||(d=0,p=!0,n.modal.openModal({kind:`confirm`,title:Q.t(`cmd.titleMemoryPressure`),message:Q.t(`cmd.memoryPressureMessage`,{usedPct:e.usedPct.toFixed(0)}),confirmLabel:Q.t(`cmd.memoryPressureRestartNow`),cancelLabel:Q.t(`cmd.memoryPressureRemindLater`),confirmColor:`amber`,extraLabel:Q.t(`cmd.memoryPressureSuppress`),onConfirm:()=>{p=!1,b(),y()},onCancel:()=>{p=!1},onExtra:()=>{p=!1,u=!0}}))},onCriticalDuringGrace:e=>{n.info.pushNotification(Q.t(`cmd.titleMemoryPressure`),Q.t(`cmd.memoryPressureMessage`,{usedPct:e.usedPct.toFixed(0)}),`system`,`warning`)},onCriticalTimeout:e=>{if(p){p=!1,y();return}let i=()=>{m++,n.info.pushNotification(Q.t(`cmd.titleMemoryPressure`),Q.t(`cmd.memoryPressureMessage`,{usedPct:t.memoryGovernor.sample().usedPct.toFixed(0)}),`system`,`warning`),!h&&m>=_&&(h=!0,r().compactNow().catch(e=>{let n=e instanceof Error?e.message:String(e);t.logger.warn({err:n},`[memory-governor] critical-unattended-escalation compactNow failed`)}),t.storage.traceStore?.append(r().id,{ts:Date.now(),sessionId:r().id,kind:`lifecycle`,node:`critical-unattended-escalation`,payload:{usedPct:e.usedPct,cycles:m}}).catch(e=>{t.logger.warn({err:e instanceof Error?e.message:String(e)},`[memory-governor] critical-unattended-escalation trace append failed`)}))};v||(i(),v=setInterval(i,g),v.unref?.())},onLevelChange:e=>{e!==`critical`&&(d=0,f=void 0,b()),n.engine.pushEngineEvent({kind:`perf`,indicatorLevel:e,memory:t.memoryGovernor.sample()})}}),t.fleetMonitor.setCallbacks({onBudgetExceeded:e=>{n.info.pushNotification(Q.t(`cmd.titleFleetBudget`),Q.t(`cmd.fleetBudgetExceeded`,{processCount:e.processCount,totalRssMb:e.totalRssMb}),`system`,`warning`)}})}async function gr(e){let{app:t,options:n,tui:r,tuiRef:i,turn:a,projState:o,redState:s,stopController:c,themeRegistry:l,availableModelIds:u,applyModel:f,refreshSlashCommands:p,retryAccelerate:m,startupCrashGapRef:h,resumedNote:g,resumed:_,updateCheckPromise:v,bg:y,ftueController:b,refreshModelsNow:S,persistAvailable:C,cfgLang:ee,sessionRef:T,interactiveRef:E,regRef:D,slashCommandsRef:O,modelReadyRef:te,currentModelIdRef:k,currentLangRef:A,modelsRef:j,restartRequestedRef:M,restartMemoryTriggeredRef:N,restartResumePromptRef:P,pushBudgetNowRef:F,staleBuildDetectorRef:I,eventsRef:re,cliCtxRef:R,handleExitRef:ae,pasteBinder:oe,contextWindowRef:se}=e;ae.current=e=>{c.requestStop(e.restart?`exit-restart`:`exit`)},n.memoryRestartGrace&&t.memoryGovernor.markRestarted();let z=n.restartGeneration??0;z>=3&&r.info.pushNotification(Q.t(`cmd.titleFleetBudget`),Q.t(`cmd.restartChainDeep`,{generation:z}),`system`,`warning`),r.engine.pushEngineEvent({kind:`perf`,indicatorLevel:t.memoryGovernor.currentLevel,memory:t.memoryGovernor.sample()}),fr({session:T.value,tui:r,retryAccelerate:m,setRateLimitInfo:e=>{a.lastRateLimitInfo=e},abortNow:()=>{c.abortNow()}});let ce=ur({getSession:()=>T.value,app:t,tui:r,projState:o,contextWindow:se,currentModelId:k}),{recomputeBudget:B,persistEditedFiles:ue,persistSubagents:V,persistTurnCount:de,onContextCompacted:H}=ce;F.value=B,B(),t.editFileCallback=ce.editFileCallback,hr({app:t,tui:r,getSession:()=>T.value,setRestartResumePrompt:e=>{P.value=e},setRestartMemoryTriggered:e=>{N.value=e},handleExit:ae.current,onContextCompacted:H,recomputeBudget:B}),t.registerInAppNotificationChannel((e,t,n)=>r.info.pushNotification(e,t,`system`,w(n))),t.setFollowUpPendingProbe(()=>r.engine.hasQueuedFollowUp());let fe=Un({getSession:()=>T.value,app:t,tui:r,projState:o,redState:s,recomputeBudget:B,persistEditedFiles:ue,persistSubagents:V,persistTurnCount:de,onContextCompacted:H,markStreamed:()=>{a.streamedText=!0}});re.value=fe,R.current=dr({tui:r,app:t,themeRegistry:l,sessionRef:T,interactiveRef:E,regRef:D,slashCommandsRef:O,modelReadyRef:te,currentModelIdRef:k,currentLangRef:A,projState:o,agentProcessingRef:{get value(){return a.agentProcessing},set value(e){a.agentProcessing=e}},modelsRef:j,availableModelIds:u,restartRequestedRef:M,applyModel:f,persistAvailable:C,refreshModelsNow:S,refreshSlashCommands:p,events:fe,redState:s,agentMessagesToChatMessages:x,PROVIDER_DISPLAY_NAMES:d,apiCredentialId:be,onContextCompacted:H}),R.current.callbacks.pasteBinder=oe,oe.load(T.value.id),r.plugins.setPluginRegistrations(t.getPluginRegistrations());let pe=await b.refresh();if(i.value?.stores.tasks.setFtueStage(pe.stage),ne(pe)&&ee===`auto`&&!t.settings.get(`has_completed_onboarding`)){let e=await r.modal.openModal({kind:`onboarding`,onLanguagePreview:e=>{let t=e===`auto`?le():e;ie(t),r.lifecycle.setLanguage(t),A.value=t}});if(e.nickname&&t.settings.persist({nickname:e.nickname}).catch(()=>{}),e.language){let n=e.language===`auto`?le():e.language;ie(n),r.lifecycle.setLanguage(n),A.value=n,t.settings.persist({language:e.language}).catch(()=>{})}t.settings.persist({has_completed_onboarding:!0}).catch(()=>{})}pe.recommendation.autoOpen&&L(`setup`,[],R.current);let U=nn();U&&(I.current=new rn({repoRoot:U,currentBuildId:We,logger:t.logger,onStale:e=>{r.info.pushNotification(Q.t(`cmd.titleStaleBuild`),Q.t(`cmd.staleBuildMessage`,{current:We,latest:e}),`system`,`info`)}}),I.current.start()),await Zn({tui:r,options:n,app:t,session:T.value,projState:o,resumedNote:g,resumed:_??void 0,updateCheckPromise:v,bg:y,events:fe}),h.value&&r.info.showToast(Q.t(`crashGap.toastTitle`),Q.t(`crashGap.toastBody`,{lostTurns:h.value.lostTurns}))}async function _r(e,t,n){let r=!1,i=!1,o,s={get value(){return r},set value(e){r=!!e}},c={get value(){return i},set value(e){i=e}},l={get value(){return o},set value(e){o=e}},d;try{let f=await _n(t,{continueSession:e.continueSession,model:e.model,sessionUrl:e.sessionUrl}),p=f.SETUP_PLACEHOLDER_ID,m=f.session,h=f.startupCrashGapRef,g=f.resumedNote,_=f.modelReadyRef,v=_.value,y=f.ftueController,x=f.refreshModelsNow,C=f.modelRefreshState,w=C.availableModelIds,ee=f.persistAvailable,E=C.models,D=f.continuedExisting,te=f.retryAccelerate,k=f.resumed,ne=f.convoCount,j=f.tuiRefBox,M=j,N=v?m.model?.id:void 0,P=t.modelRegistry.getAll().filter(e=>e.id!==p).find(e=>e.id===N)?.contextWindow??0,F={get value(){return P},set value(e){P=e}},I=N,re={get value(){return I},set value(e){I=e}},L=e=>u(t,e,m.thinkingLevel),R,ae={get value(){return R},set value(e){R=e}},z={value:void 0},B={current:void 0},V={value:e},fe=e=>{switch(e.kind){case`steer`:m.steer(e.input);break;case`abort`:W.abort();break;case`pauseAfterTurn`:m.pauseRun();break;case`resumeRun`:m.resumeRun();break}},U=b({modelReady:_,currentModelId:re,contextWindow:F,tuiRef:j,pushBudgetNow:ae,app:t,getSession:()=>m,options:V,fmtDisplayModel:L,onEngineModelAction:fe}),me=a({getSession:()=>m,app:t,tuiRef:j,options:V,fmtDisplayModel:L,applyModel:U,onExitSession:()=>z.value?.(),onLogin:e=>B.current?.(e)}),W=new se(m,{models:E,currentModel:N,onModelChange:U}),{startTui:he}=await import(`@x-otto/tui`),G=W.getRegistry();Xt(G);let ge=T(G,t),K={agentProcessing:!1,ctrlCCount:0,lastCtrlCTime:0,userAborted:!1,shellChild:null,streamedText:!1,retryMode:!1,errorRetryAttempt:0,lastRateLimitInfo:void 0,latestSubmittedPrompt:void 0},_e=()=>Gt(m.isBusy,K.agentProcessing),ve=Yt(G,K.agentProcessing,oe,Q.t(`cmdDesc`,{returnObjects:!0}),m.pinned,m.isPaused),ye=()=>(ve=Yt(G,K.agentProcessing,oe,Q.t(`cmdDesc`,{returnObjects:!0}),m.pinned,m.isPaused),ve);de(t),O(t,w),H(t),ue(t);let be=Lt(),xe=t.settings.get(`language`)??`auto`,Se=xe===`auto`?le():xe,Ce=tn(t),we=t.settings.get(`theme_preset`),Te=t.settings.get(`keybinding_overrides`);ie(Se);let Ee=A({currentVersion:pe(),lastCheck:t.settings.get(`last_update_check`),autoCheck:t.settings.get(`auto_update_check`)!==!1,persistLastCheck:()=>t.settings.persist({last_update_check:Date.now()})}),q={get value(){return m},set value(e){m=e}},J={get value(){return W},set value(e){W=e}},Y={get value(){return G},set value(e){G=e}},De={get value(){return ve},set value(e){ve=e}},Oe={get value(){return Se},set value(e){Se=e}},ke={get value(){return E},set value(e){E=e}};await new Promise(async i=>{let a={current:void 0},o={current:void 0},u={current:void 0},f=!1,p=()=>{if(!f){f=!0;try{d?.clearBgSubs()}catch{}try{d?.stopBgOutputPoll()}catch{}try{d?.stopBgSubagentPoll()}catch{}try{clearInterval(o.current)}catch{}try{u.current.stop()}catch{}try{a.current?.dispose()}catch{}i()}};z.value=p;let b=()=>{setTimeout(p,3e3).unref();try{M.value?.lifecycle.stop()}catch{p()}},C=on({getTui:()=>M.value??null,getSession:()=>m,dispatchAbort:()=>fe({kind:`abort`}),clearTodoLayers:()=>{be.todoList.length!==0&&(be.todoList=[],M.value?.stores.tasks.setTasks([]),m.session.setTodoList([]))},markUserAborted:()=>{K.userAborted=!0},resetCtrlCCount:()=>{K.ctrlCCount=0},markRestartRequested:()=>{r=!0},stopTui:b,isBusy:()=>_e()}),T=ce,{historyStore:E,inputHistory:O,externalHistoryCommands:A}=await hn(m,t.settings.get(`history`)?.external),P=Zt({app:t,session:m,getTui:()=>de});d=P;let ie={current:void 0},R={current:void 0},oe={current:void 0},se={current:void 0},le={current:void 0},ue={value:void 0},V=S(),de=await he(await zn({app:t,session:m,options:e,tuiRefBox:j,tuiRef:M,turn:K,projState:be,redState:V,isBusyNow:_e,dispatchToEngine:fe,stopController:C,finishInteractive:p,stopTuiGuarded:b,applyModel:U,ensureModelUsableForPrompt:me,refreshSlashCommands:ye,fileCommands:ge,modelReady:v,availableModelIds:w,currentModel:N,currentModelId:I,fmtDisplayModel:L,cfgLang:xe,themeRegistry:Ce,presetSelection:we,keybindingOverrides:Te,continuedExisting:D,convoCount:ne,historyStore:E,inputHistory:O,externalHistoryCommands:A,bg:P,bgController:d,reg:G,slashCommands:ve,interactive:W,handleExitRef:le,cliCtxRef:se,providerAuthRef:B,handleAbortInterceptRef:R,runAsyncBashRef:ie,runMemoryCaptureRef:oe,allCommandNames:T}));j.value=de;let{pasteBinder:H}=rr({app:t,session:m,options:e,tui:de,memoryConflictRef:n,turn:K,stopController:C,runAsyncBashRef:ie,handleAbortInterceptRef:R,runMemoryCaptureRef:oe,schedulePollIntervalRef:o,scheduleServiceRef:u});await gr({app:t,options:e,tui:de,tuiRef:M,turn:K,projState:be,redState:V,stopController:C,themeRegistry:Ce,availableModelIds:w,applyModel:U,refreshSlashCommands:ye,retryAccelerate:te,startupCrashGapRef:h,resumedNote:g,resumed:k??void 0,updateCheckPromise:Ee,bg:P,ftueController:y,refreshModelsNow:x,persistAvailable:ee,cfgLang:xe,sessionRef:q,interactiveRef:J,regRef:Y,slashCommandsRef:De,modelReadyRef:_,currentModelIdRef:re,currentLangRef:Oe,modelsRef:ke,restartRequestedRef:s,restartMemoryTriggeredRef:c,restartResumePromptRef:l,pushBudgetNowRef:ae,staleBuildDetectorRef:a,eventsRef:ue,cliCtxRef:se,handleExitRef:le,pasteBinder:H,contextWindowRef:F})});let Ae;if(t.codingSessionPool.autoPersist&&m.session.messages().length>0){let t=e.sessionUrl?` --session-url ${e.sessionUrl}`:``,n=e.sessionToken?` --session-token <redacted>`:``;Ae=`\n\x1b[2m${Q.t(`cmd.resumeContinueLabel`)}\x1b[0motto --continue ${m.id}${t}${n}\n`}return{restart:r?{sessionId:m.id,memoryTriggered:i,resumePrompt:o}:void 0,resumeHint:Ae}}finally{d?.clearBgSubs(),d?.stopBgOutputPoll(),d?.stopBgSubagentPoll()}}async function vr(e){if(e.hasParentWorkspace()){let t=e.parentWorkspaceExisted,n=await gt({parentRoot:t.parentRoot,currentRoot:t.currentRoot,language:e.settings.get(`language`)});n===`exit`&&(process.stdout.write(`
|
|
12
12
|
`),process.exit(0)),n===`use_parent`?await e.adoptParentWorkspace():await e.createLocalWorkspace()}let t=we(e.workspaceDir,{interactive:!0});if(!t.shouldPrompt){e.needsWorkspaceInit()&&await e.confirmWorkspaceInit();return}let n=await _t({root:t.root,language:e.settings.get(`language`)});if(n===`exit`&&(process.stdout.write(`
|
|
13
13
|
`),process.exit(0)),n===`trust`){Ne(t.root),await e.settings.reload(),e.needsWorkspaceInit()&&await e.confirmWorkspaceInit();return}await e.settings.update({permission_mode:`readonly`}),e.needsWorkspaceInit()&&await e.confirmWorkspaceInit()}function yr(e){throw e instanceof Error&&e.message.startsWith(`No model configured`)?Error("No model configured. Run `otto` (interactive) to complete setup — it walks you through: install a provider plugin → /auth → /model. Or authenticate directly with `otto auth login`."):e}async function br(e,t){e.prompt&&await D(await t.createSession({listable:!1}).catch(yr),e.prompt,{tui:!0})}async function xr(e,t){if(e.prompt){let n=await M(await t.createSession({listable:!1}).catch(yr),e.prompt);process.stdout.write(JSON.stringify(n,null,2)+`
|
|
14
|
-
`)}}function Sr(e){vt(e.settings.get(`theme_overrides`)?.markdown)}Be(`cli.ts imports resolved`);const Cr=new Map([[`doctor`,async e=>{let{runDoctorCommand:t}=await import(`./doctor-DXBLkbkP.js`);return t(e.args,{stdout:e.stdout,stderr:e.stderr})}],[`auth`,async e=>{let{runAuthCommand:t}=await import(`./auth-command-D1T16ed-.js`);return t(e.args,{bootstrap:{workspaceDir:e.options.projectDir,projectConfigPath:e.options.configPath,verbose:e.options.verbose},stdout:e.stdout,stderr:e.stderr})}],[`serve`,async e=>{let{runServeCommand:t}=await import(`./serve-Ke0nwN9Y.js`);return t(e.args,{projectDir:e.options.projectDir,configPath:e.options.configPath,modelId:e.options.model,verbose:e.options.verbose})}],[`daemon`,async e=>{let{runDaemonCommand:t}=await import(`./daemon-COESl-zU.js`);return t(e.args,{projectDir:e.options.projectDir,stdout:e.stdout,stderr:e.stderr})}],[`persistenced`,async e=>{let{runPersistenceCommand:t}=await import(`./persistence-CRFhOYx6.js`);return t([`local`,...e.args])}],[`remote-persistence-server`,async e=>{let{runPersistenceCommand:t}=await import(`./persistence-CRFhOYx6.js`);return t([`remote`,...e.args])}],[`persistence`,async e=>{let{runPersistenceCommand:t}=await import(`./persistence-CRFhOYx6.js`);return t(e.args)}],[`observe`,async e=>{let{runObserveCommand:t}=await import(`./observe-Dxfud-t7.js`);return t(e.args)}],[`debug`,async e=>{let{runObserveCommand:t}=await import(`./observe-Dxfud-t7.js`);return t([`debug`,...e.args])}],[`time-travel`,async e=>{let{runObserveCommand:t}=await import(`./observe-Dxfud-t7.js`);return t([`replay`,...e.args])}],[`mcp`,async e=>{let{runMcpCommand:t}=await import(`./mcp-Cm4-OhXI.js`);return t(e.args)}],[`mcp-server`,async e=>{let{runMcpServerCommand:t,buildMcpServerDepsFromApp:n}=await import(`./mcp-server-Dpza3yn2.js`),{createHostApp:r}=await import(`./create-host-app-DG58-vRA.js`),i=r({logger:{name:`otto-mcp-server`,level:`error`,destination:`stderr`},...e.options.projectDir?{workspaceDir:e.options.projectDir}:{},...e.options.model?{modelId:e.options.model}:{}});await i.start();let a=n(i.tools,i.permissionRegistry),o=new AbortController;return process.on(`SIGTERM`,()=>o.abort()),process.on(`SIGINT`,()=>o.abort()),t(e.args,{...a,signal:o.signal,onShutdown:()=>i.stop()})}],[`config`,async e=>{let{runConfigMigrationCommand:t}=await import(`./config-migration-DatflIxs.js`);return t(e.args,{stdout:e.stdout,stderr:e.stderr})}],[`migrate`,async e=>{let{runMigrateCommand:t}=await import(`./migrate-RlBJqJnB.js`);return t(e.args,{stdout:e.stdout,stderr:e.stderr})}],[`extension`,async e=>{let{runExtensionCommand:t}=await import(`./extension-CTyrcdT1.js`);return t(e.args,{stdout:e.stdout,stderr:e.stderr})}],[`ps`,async e=>{let{runPsCommand:t}=await import(`./ps-DiKCLKbs.js`);return t(e.args,{stdout:e.stdout,stderr:e.stderr})}],[`feedback`,async e=>{let{runFeedbackCommand:t}=await import(`./feedback-
|
|
14
|
+
`)}}function Sr(e){vt(e.settings.get(`theme_overrides`)?.markdown)}Be(`cli.ts imports resolved`);const Cr=new Map([[`doctor`,async e=>{let{runDoctorCommand:t}=await import(`./doctor-DXBLkbkP.js`);return t(e.args,{stdout:e.stdout,stderr:e.stderr})}],[`auth`,async e=>{let{runAuthCommand:t}=await import(`./auth-command-D1T16ed-.js`);return t(e.args,{bootstrap:{workspaceDir:e.options.projectDir,projectConfigPath:e.options.configPath,verbose:e.options.verbose},stdout:e.stdout,stderr:e.stderr})}],[`serve`,async e=>{let{runServeCommand:t}=await import(`./serve-Ke0nwN9Y.js`);return t(e.args,{projectDir:e.options.projectDir,configPath:e.options.configPath,modelId:e.options.model,verbose:e.options.verbose})}],[`daemon`,async e=>{let{runDaemonCommand:t}=await import(`./daemon-COESl-zU.js`);return t(e.args,{projectDir:e.options.projectDir,stdout:e.stdout,stderr:e.stderr})}],[`persistenced`,async e=>{let{runPersistenceCommand:t}=await import(`./persistence-CRFhOYx6.js`);return t([`local`,...e.args])}],[`remote-persistence-server`,async e=>{let{runPersistenceCommand:t}=await import(`./persistence-CRFhOYx6.js`);return t([`remote`,...e.args])}],[`persistence`,async e=>{let{runPersistenceCommand:t}=await import(`./persistence-CRFhOYx6.js`);return t(e.args)}],[`observe`,async e=>{let{runObserveCommand:t}=await import(`./observe-Dxfud-t7.js`);return t(e.args)}],[`debug`,async e=>{let{runObserveCommand:t}=await import(`./observe-Dxfud-t7.js`);return t([`debug`,...e.args])}],[`time-travel`,async e=>{let{runObserveCommand:t}=await import(`./observe-Dxfud-t7.js`);return t([`replay`,...e.args])}],[`mcp`,async e=>{let{runMcpCommand:t}=await import(`./mcp-Cm4-OhXI.js`);return t(e.args)}],[`mcp-server`,async e=>{let{runMcpServerCommand:t,buildMcpServerDepsFromApp:n}=await import(`./mcp-server-Dpza3yn2.js`),{createHostApp:r}=await import(`./create-host-app-DG58-vRA.js`),i=r({logger:{name:`otto-mcp-server`,level:`error`,destination:`stderr`},...e.options.projectDir?{workspaceDir:e.options.projectDir}:{},...e.options.model?{modelId:e.options.model}:{}});await i.start();let a=n(i.tools,i.permissionRegistry),o=new AbortController;return process.on(`SIGTERM`,()=>o.abort()),process.on(`SIGINT`,()=>o.abort()),t(e.args,{...a,signal:o.signal,onShutdown:()=>i.stop()})}],[`config`,async e=>{let{runConfigMigrationCommand:t}=await import(`./config-migration-DatflIxs.js`);return t(e.args,{stdout:e.stdout,stderr:e.stderr})}],[`migrate`,async e=>{let{runMigrateCommand:t}=await import(`./migrate-RlBJqJnB.js`);return t(e.args,{stdout:e.stdout,stderr:e.stderr})}],[`extension`,async e=>{let{runExtensionCommand:t}=await import(`./extension-CTyrcdT1.js`);return t(e.args,{stdout:e.stdout,stderr:e.stderr})}],[`ps`,async e=>{let{runPsCommand:t}=await import(`./ps-DiKCLKbs.js`);return t(e.args,{stdout:e.stdout,stderr:e.stderr})}],[`feedback`,async e=>{let{runFeedbackCommand:t}=await import(`./feedback-DzPLfcfN.js`);return t(e.args,{stdout:e.stdout,stderr:e.stderr,projectDir:e.options.projectDir,configPath:e.options.configPath})}],[`export-trajectory`,async e=>{let{runExportTrajectoryCommand:t}=await import(`./export-trajectory-D-BcH0Wt.js`);return t(e.args,{stdout:e.stdout,stderr:e.stderr})}]]);async function wr(e,t,n){let r=W({cwd:n.projectDir,homedir:K()}),i=new Set(me),a=xe(r,i).get(e);if(!a){let t=Ee(r,i,e);return t?(process.stderr.write(`otto: 命令 "${e}" 被多个插件声明(${t.join(`, `)}),已禁用以避免歧义。\n请重命名其中一个插件的 \`contributes.cli.name\` 后重试(编辑对应插件目录的 otto-plugin.json)。\n`),1):void 0}if(Ce(a).gated)return process.stderr.write(`otto: 插件 "${a.id}" 声明了 \`otto ${e}\` 命令但尚未被信任。\n请先在 TUI 内运行 \`/trust plugin ${a.id}\`(或 \`/extension\` 信任该插件)后重试。\n`),1;let o=Ae(a);if(!o)return process.stderr.write(`otto: 插件 "${a.id}" 声明了 \`contributes.cli\` 但找不到可执行入口,请检查其 manifest 的 bin 字段或重新安装该插件。\n`),1;try{return await Me(o,t,a.dir)}catch(e){return process.stderr.write(`otto: 插件 "${a.id}" 的 CLI 命令执行失败:${e instanceof Error?e.message:String(e)}\n`),1}}function Tr(e,t){return e.mode===`interactive`&&!e.verbose&&!t?`fatal`:t}function Er(e,t){return e.mode===`interactive`&&!t?`0`:t}function Dr(e,t,n={}){let r=[];for(let t=0;t<e.length;t++){if(e[t]===`--continue`){t++;continue}e[t].startsWith(`--restart-generation=`)||r.push(e[t])}return[...n.execArgv??[],...r,`--continue`,t,...n.generation===void 0?[]:[`--restart-generation=${n.generation}`],...n.sessionUrl?[`--session-url`,n.sessionUrl]:[],...n.sessionToken?[`--session-token`,n.sessionToken]:[],...n.memoryRestartGrace?[`--memory-restart-grace`]:[],...n.resumePrompt?[`--resume-prompt`,n.resumePrompt]:[]]}async function Or(){process.stdin.on(`error`,e=>{e.code}),De(),Oe();let{options:e,subCommand:t,subCommandArgs:n,unresolvedCommandName:r,unresolvedCommandArgs:i}=U(process.argv);e.shadow&&(process.env.OTTO_SHADOW=`1`);let a=e.verbose?`debug`:e.mode===`interactive`?`fatal`:e.quiet?`error`:`info`;Ve(a);let o=Tr(e,process.env.OTTO_LOG_LEVEL);o&&(process.env.OTTO_LOG_LEVEL=o);let s=Er(e,process.env.OTTO_LOG_STDERR);s&&(process.env.OTTO_LOG_STDERR=s),e.mode===`interactive`&&!e.verbose&&(console.warn=()=>{}),process.env.OTTO_LOG_STDERR===`0`?Je(()=>{}):Je(e=>process.stderr.write(`${e}\n`)),process.on(`beforeExit`,()=>{process.env.OTTO_LOG_STDERR!==`0`&&Je(e=>process.stderr.write(`${e}\n`))});let c=n.split(` `).filter(Boolean),l=Cr.get(t??``);if(l)return l({args:c,options:e,stdout:e=>process.stdout.write(e),stderr:e=>process.stderr.write(e)});if(r){let t=await wr(r,i??[],e);if(t!==void 0)return t}if(e.showHelp){let{getHelpLines:e}=await import(`./parse-cli-BvcxTK88.js`).then(e=>e.r);return process.stdout.write(e().join(`
|
|
15
15
|
`)+`
|
|
16
16
|
`),0}if(!e.prompt&&e.mode!==`interactive`)return process.stderr.write(`otto: no prompt provided. Use --help for usage.
|
|
17
17
|
`),1;let u=await Xe(),d=e.sessionUrl??u?.serviceUrl,f=e.sessionToken??u?.token,p={},m=Ue(`new App() ctor`,()=>he({inspect:e.inspect!==void 0||e.mode===`interactive`,logger:{name:`otto-cli`,level:a,destination:`stderr`},workspaceDir:e.projectDir,workspaceId:e.workspaceId,projectConfigPath:e.configPath,interactive:e.mode===`interactive`,shadow:e.shadow??!1,modelId:e.model,userIdentity:u??void 0,...e.maxToolTurns===void 0?{}:{maxToolTurns:e.maxToolTurns},...e.maxToolTurnExtensions===void 0?{}:{maxToolTurnExtensions:e.maxToolTurnExtensions},...e.promptTokenBudget===void 0?{}:{promptOutputTokenBudget:e.promptTokenBudget},...e.promptTimeBudgetMin===void 0?{}:{promptWallClockBudgetMs:e.promptTimeBudgetMin*6e4},...e.sessionCostBudget===void 0?{}:{sessionCostBudgetUSD:e.sessionCostBudget},...e.noStallDetection?{stallDetection:!1}:e.stallWindowTurns!==void 0&&e.stallRepeatThreshold!==void 0?{stallDetection:{windowTurns:e.stallWindowTurns,repeatThreshold:e.stallRepeatThreshold}}:{},storage:d&&f?{session:{url:d},remote:{getAuth:async()=>({token:f})}}:{session:{dir:Ke}},onMemoryConflict:(e,t)=>p.current?.(e,t)}));await He(`app.start()`,()=>m.start()),m.authStore.on(`credential.persist-deferred`,e=>{e.state===`exhausted`&&console.error(`[otto] ⚠️ 凭据变更无法落盘(${e.attempt} 次重试均失败:${e.reason})。\n 本次会话的新凭据只存在于内存中,退出后会丢失。请检查文件锁/磁盘权限后重启。\n (deferred/recovered 档为诊断信息,仅 exhausted 需告警)`)}),Sr(m),Ie(Fe);let h=!1,g=()=>{h&&(e.mode===`interactive`&&Wt(),process.exit(1)),h=!0,Promise.race([m.stop(),new Promise(e=>setTimeout(e,1e4))]).finally(()=>{e.mode===`interactive`&&(Wt(),Ut()),process.exit(1)})};process.on(`SIGTERM`,g),process.on(`SIGHUP`,g);let _,v=!1,y,b;if(e.attachSession){let t=process.env.OTTO_SERVICE_URL??`http://127.0.0.1:8417`,{runAttach:n}=await import(`./run-attach-DDpMk2_N.js`);return await n({sessionId:e.attachSession,baseUrl:t,token:process.env.OTTO_SERVICE_TOKEN,forceWriteLease:e.forceWriteLease}),0}try{switch(e.mode){case`print`:await br(e,m);break;case`json`:await xr(e,m);break;case`interactive`:{await vr(m);let t=await _r(e,m,p);_=t.restart?.sessionId,v=!!t.restart?.memoryTriggered,y=t.restart?.resumePrompt,t.restart||(b=t.resumeHint);break}}}finally{let t=()=>{};process.on(`SIGINT`,t);let n=setTimeout(()=>{e.mode===`interactive`&&(Wt(),Ut()),process.exit(1)},1e4);try{await m.stop()}finally{clearTimeout(n),process.removeListener(`SIGINT`,t)}}if(_){process.removeListener(`SIGTERM`,g),process.removeListener(`SIGHUP`,g);let t=e.sessionUrl,n=e.sessionToken,r=()=>{},i,a=e=>{try{console.error(`\n[otto] 重启陪跑期父进程异常,终止子会话以避免孤儿挂起:${e instanceof Error?e.stack??e.message:String(e)}`)}catch{}try{i?.kill(`SIGTERM`)}catch{}process.exit(1)};return process.on(`SIGINT`,r),process.on(`SIGTERM`,r),process.on(`uncaughtException`,a),process.on(`unhandledRejection`,a),i=ve(process.execPath,Dr(process.argv.slice(1),_,{sessionUrl:t,sessionToken:n,memoryRestartGrace:v,resumePrompt:y,execArgv:process.execArgv,generation:(e.restartGeneration??0)+1}),{stdio:`inherit`,env:{...process.env}}),i.on(`exit`,(e,t)=>{process.removeListener(`SIGINT`,r),process.removeListener(`SIGTERM`,r),process.removeListener(`uncaughtException`,a),process.removeListener(`unhandledRejection`,a),process.exit(e??(t?1:0))}),0}if(e.mode===`interactive`){if(Ut(),b)try{process.stdout.write(b)}catch{}process.exit(process.exitCode??0)}return 0}Or().then(e=>{e!==0&&(process.exitCode=e)}).catch(e=>{process.stderr.write(`otto: ${e instanceof Error?e.message:String(e)}\n`),process.exitCode=1});export{Or as runCli};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{ot as e}from"./command-dispatcher-
|
|
3
|
-
//# sourceMappingURL=parse-cli-
|
|
2
|
+
import{ot as e}from"./command-dispatcher-DTOPjtZP.js";import{t}from"./version-BrSIyY6s.js";import{resolve as n}from"node:path";var r=e({SUB_COMMAND_NAMES:()=>a,getHelpLines:()=>l,parseCLI:()=>c});function i(e){return e.startsWith(`--`)||/^-[^\s-]/.test(e)}const a=new Set([`run`,`serve`,`daemon`,`doctor`,`config`,`migrate`,`auth`,`observe`,`debug`,`time-travel`,`mcp`,`mcp-server`,`persistenced`,`remote-persistence-server`,`persistence`,`extension`,`ps`,`feedback`,`export-trajectory`]),o=new Map([{flags:[`--print`,`-p`],type:`mode`,value:`print`},{flags:[`--interactive`,`-i`],type:`mode`,value:`interactive`},{flags:[`--json`],type:`mode`,value:`json`},{flags:[`--model`,`-m`],type:`string`,key:`model`},{flags:[`--config`,`-c`],type:`string`,key:`configPath`},{flags:[`--project`,`-d`],type:`path`,key:`projectDir`},{flags:[`--quiet`,`-q`],type:`boolean`,key:`quiet`},{flags:[`--verbose`],type:`boolean`,key:`verbose`},{flags:[`--max-tool-turns`],type:`number`,key:`maxToolTurns`},{flags:[`--max-tool-turn-extensions`],type:`number`,key:`maxToolTurnExtensions`},{flags:[`--prompt-token-budget`],type:`number`,key:`promptTokenBudget`},{flags:[`--prompt-time-budget`],type:`number`,key:`promptTimeBudgetMin`},{flags:[`--session-cost-budget`],type:`number`,key:`sessionCostBudget`},{flags:[`--no-stall-detection`],type:`boolean`,key:`noStallDetection`},{flags:[`--stall-window-turns`],type:`number`,key:`stallWindowTurns`},{flags:[`--stall-repeat-threshold`],type:`number`,key:`stallRepeatThreshold`},{flags:[`--continue`],type:`string`,key:`continueSession`},{flags:[`--attach`],type:`string`,key:`attachSession`},{flags:[`--force-write-lease`],type:`boolean`,key:`forceWriteLease`},{flags:[`--memory-restart-grace`],type:`boolean`,key:`memoryRestartGrace`},{flags:[`--resume-prompt`],type:`string`,key:`resumePrompt`},{flags:[`--session-url`],type:`string`,key:`sessionUrl`},{flags:[`--session-token`],type:`string`,key:`sessionToken`},{flags:[`--id`],type:`string`,key:`workspaceId`},{flags:[`--shadow`],type:`boolean`,key:`shadow`},{flags:[`--help`,`-h`],type:`boolean`,key:`showHelp`},{flags:[`--version`,`-v`],type:`action`,handler:u}].flatMap(e=>e.flags.map(t=>[t,e])));var s=class{i;constructor(e){this.args=e,this.i=0}current(){return this.args[this.i]}next(){return this.args[++this.i]}advance(){this.i++}skip(e){this.i+=e}pos(){return this.i}};function c(e){let t=e.slice(2),r=new s(t),c={mode:`interactive`,projectDir:process.cwd(),verbose:!1,quiet:!1},l=r.current(),u,d=``,f,p;l&&a.has(l)?(u=l,d=t.slice(1).join(` `),r.skip(1),u===`run`&&(c.prompt=t.slice(1).filter(e=>!i(e)).join(` `),c.mode=`print`)):l&&!i(l)&&(f=l,p=t.slice(1));let m=c.prompt?[c.prompt]:[];for(;r.current()!==void 0;){let e=r.current();if(e===`--inspect`){c.inspect=!0,r.advance();continue}if(e?.startsWith(`--inspect=`)){let t=Number(e.slice(10));c.inspect=Number.isInteger(t)&&t>0?t:!0,r.advance();continue}if(e?.startsWith(`--restart-generation=`)){let t=Number(e.slice(21));Number.isInteger(t)&&t>0&&(c.restartGeneration=t),r.advance();continue}let t=o.get(e);if(t){switch(r.advance(),t.type){case`boolean`:c[t.key]=!0;break;case`mode`:c.mode=t.value;break;case`string`:c[t.key]=r.current(),r.advance();break;case`number`:{let e=r.current();if(e===void 0||e.startsWith(`-`))break;let n=Number(e),i=t.key===`maxToolTurnExtensions`;Number.isFinite(n)&&(i?n>=0:n>0)&&(c[t.key]=n),r.advance();continue}case`path`:c[t.key]=n(r.current()??process.cwd()),r.advance();break;case`action`:t.handler();break}continue}e&&!i(e)&&!u&&(c.prompt===void 0&&c.mode===`interactive`&&(c.mode=`print`),m.push(e)),r.advance()}return m.length>0&&(c.prompt=m.join(` `)),{options:c,subCommand:u,subCommandArgs:d,unresolvedCommandName:f,unresolvedCommandArgs:p}}function l(){return[``,`otto - AI 助理命令行工具`,``,`用法:`,` otto [提示词] 使用提示词启动(print 模式)`,` otto 进入交互式 TUI 模式`,` otto --json "query" JSON 输出模式`,``,`选项:`,` -i, --interactive Interactive 模式(默认)`,` -p, --print Print 模式(非交互)`,` --json JSON 输出模式`,` -m, --model <id> 指定模型`,` -c, --config <path> 配置文件路径`,` -d, --project <dir> 项目目录`,` --verbose 输出详细日志`,` -q, --quiet 只输出 error 日志`,` --shadow 影子模式:otto 自有状态(凭据/会话/记忆/教训/配置/trace/日志)本次会话零磁盘写入(不保证 provider 服务端日志与 shell/OS 层痕迹;RFC-345)`,` --max-tool-turns <n> 单个用户回合最大工具回合数(默认 120)`,` --max-tool-turn-extensions <n> 触顶后压缩续跑的扩展次数(默认主会话 3 / 子 agent 0)`,` --prompt-token-budget <n> 单回合输出 token 预算(配置后轮次上限 ×4 退位安全阀;RFC-104)`,` --prompt-time-budget <min> 单回合墙钟时间预算(分钟)`,` --session-cost-budget <usd> 会话累计成本软预算(美元,超过一次性提醒不阻断;RFC-204)`,` --no-stall-detection 关闭早期停滞检测(默认开启;RFC-203)`,` --stall-window-turns <n> 停滞检测滑动窗口大小(需与 --stall-repeat-threshold 同时提供,默认 8)`,` --stall-repeat-threshold <n> 停滞检测同签名重复阈值(需与 --stall-window-turns 同时提供,默认 4)`,` --continue <id> 继续已有会话`,` --session-url <url> 远端会话持久化地址(如 http://host:3001/sessions)`,` --session-token <token> 远端会话持久化 Bearer token`,` --inspect[=port] 启用 Node.js inspector(默认: 9229)`,` -h, --help 显示帮助`,` --version, -v 显示版本`,``,`命令:`,` otto run <prompt> 执行一次性任务`,` otto serve [--port N] [--inspect] [--static <dir>] [--token <t>] 启动 HTTP/WS service(--static 同源托管前端 SPA,--token 启用鉴权)`,` otto doctor [--summary|--json] 环境健康检查(环境/配置/存储状态/连通性)`,` otto auth login <provider> 登录(cursor / anthropic / openai-codex / github-copilot)`,` otto auth status 查看各 provider 凭据来源`,` otto auth logout <provider> 注销并清除凭据`,` otto config export [--project] [-o <path>] 导出配置(RFC-219)`,` otto config import <file> [--dry-run] [--scope global|project] [--no-plugins] [--plugins-only] [--yes] 导入配置`,` otto config restore [--list] 撤销最近一次导入`,` otto migrate export [--no-sessions] [-o <path>] 导出配置+插件清单+会话数据为迁移包(换电脑用)`,` otto migrate import <archive> [--no-sessions] 导入迁移包(目标已有会话数据时跳过会话部分)`,` otto observe <action> <id> 观测面板(summary / timeline / spans)`,` otto observe debug <action> [...] 调试面板(breakpoints / points / state)`,` otto observe replay <action> <id> 时间旅行(checkpoints / scrubber / restore / fork / replay)`,` otto debug <action> [...] (alias: otto observe debug)`,` otto time-travel <action> <id> (alias: otto observe replay)`,` otto mcp login <name> MCP server OAuth 登录`,` otto mcp logout <name> 登出 MCP server`,` otto mcp list 列出已认证的 MCP server`,` otto extension create <name> 生成插件骨架(命令 + 面板 + manifest,开箱即用)`,` otto extension install <name> [--yes] 安装首方/自定义插件(anthropic-provider / deepseek-provider / browser-use / …)`,` otto extension update [name] 检查并重装已过期的已安装 skill/plugin`,` otto persistence local [...flags] 启动独立持久化服务(storage + events + sync)`,` otto persistence remote [...flags] 启动最小化远程持久化服务(5 REST 端点)`,` otto persistenced [...flags] (alias: otto persistence local)`,` otto remote-persistence-server [...flags] (alias: otto persistence remote)`,` otto ps [--sweep] [--include-weak] [--json] 进程群列表与孤儿清扫(SIGTERM only,RFC-196)`,` otto export-trajectory --session <id> --out <path> [--since-seq <n>] 导出会话轨迹 JSONL(RFC-385;默认关)`,``,"面板命令默认连 `otto serve` 实例(http://127.0.0.1:8417,OTTO_SERVICE_URL/--remote 可覆盖)。"]}function u(){process.stdout.write(`otto ${t()}\n`),process.exit(0)}export{c as n,r,a as t};
|
|
3
|
+
//# sourceMappingURL=parse-cli-BvcxTK88.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parse-cli-Db5-pOBi.js","names":[],"sources":["../src/parse-cli.ts"],"sourcesContent":["import { resolve } from 'node:path'\n\nimport type { CLIOptions, RunMode } from './types'\nimport { getVersion } from './version'\n\nexport type SubCommand = 'run' | 'serve' | 'daemon' | 'doctor' | 'config' | 'migrate' | 'auth' | 'observe' | 'debug' | 'time-travel' | 'mcp' | 'mcp-server' | 'persistenced' | 'remote-persistence-server' | 'persistence' | 'extension' | 'ps' | 'feedback' | 'export-trajectory'\n\n/**\n * 真正的 flag 形态判定:`--xxx`、`-x`、`-x=value` 算 flag;\n * `- 文本`(连字符后跟空格)是**合法 prompt 开头**,不是 flag。\n *\n * 真机证据(Terminal-Bench 2.1 评测,2026-08-14):pytorch-model-recovery 任务的\n * instruction 以 \"- You are given a PyTorch state dictionary…\" 开头,旧判定\n * `arg.startsWith('-')` 把它当 flag 吞掉 → promptParts 为空 → otto 输出\n * \"no prompt provided\" → 三次 attempt 全部 0 分且无异常,被误判为模型能力失败。\n * 标准 CLI 语义下 `- ` 开头的参数不是 flag(minimist 同款行为),修复后此类 prompt\n * 正常进入会话。\n */\nfunction looksLikeFlag(arg: string): boolean {\n return arg.startsWith('--') || /^-[^\\s-]/.test(arg)\n}\n\nexport interface ParsedCLI {\n options: CLIOptions\n /** 未命中任何内建子命令时为 `undefined`(而非 `null` 哨兵——与 SUB_COMMAND_NAMES 的\n * 元素类型保持一致,消费方无需 `.filter(n => n !== null)` 剔除哨兵值)。 */\n subCommand: SubCommand | undefined\n subCommandArgs: string\n /**\n * RFC-112 D2:内建 `SUB_COMMAND_NAMES` 未命中的第一个位置参数(候选插件 CLI 命令名,\n * 如 `otto feishu ...` 里的 `\"feishu\"`)。`undefined` 表示第一个参数已命中内建命令,\n * 或压根没有位置参数。**不改变** `options.prompt`/`subCommand` 的既有构建逻辑——\n * 这两者仍然按\"当作 prompt\"的旧行为完整计算好,供插件命令名查无匹配时零改动回退。\n */\n unresolvedCommandName?: string\n /**\n * 与 `unresolvedCommandName` 配对:该候选名之后的**原始** args(未做 flag 过滤,含 `-h`\n * 等字面量),只在插件命令表命中该名字时使用(透传给插件可执行文件)。\n */\n unresolvedCommandArgs?: string[]\n}\n\n/** RFC-112 D2:导出供 `cli.ts` 构建插件 CLI 命令表时用作保留字集合(插件不得覆盖)。 */\nexport const SUB_COMMAND_NAMES = new Set<SubCommand>([\n 'run', 'serve', 'daemon', 'doctor', 'config', 'migrate', 'auth', 'observe', 'debug', 'time-travel', 'mcp', 'mcp-server', 'persistenced', 'remote-persistence-server', 'persistence', 'extension', 'ps', 'feedback', 'export-trajectory',\n])\n\ntype OptionEntry =\n | { flags: string[]; type: 'boolean'; key: keyof CLIOptions }\n | { flags: string[]; type: 'mode'; value: RunMode }\n | { flags: string[]; type: 'string'; key: keyof CLIOptions }\n | { flags: string[]; type: 'number'; key: keyof CLIOptions }\n | { flags: string[]; type: 'path'; key: keyof CLIOptions }\n | { flags: string[]; type: 'action'; handler: () => void }\n\nconst OPTIONS: OptionEntry[] = [\n { flags: ['--print', '-p'], type: 'mode', value: 'print' },\n { flags: ['--interactive', '-i'], type: 'mode', value: 'interactive' },\n { flags: ['--json'], type: 'mode', value: 'json' },\n { flags: ['--model', '-m'], type: 'string', key: 'model' },\n { flags: ['--config', '-c'], type: 'string', key: 'configPath' },\n { flags: ['--project', '-d'], type: 'path', key: 'projectDir' },\n { flags: ['--quiet', '-q'], type: 'boolean', key: 'quiet' },\n { flags: ['--verbose'], type: 'boolean', key: 'verbose' },\n { flags: ['--max-tool-turns'], type: 'number', key: 'maxToolTurns' },\n { flags: ['--max-tool-turn-extensions'], type: 'number', key: 'maxToolTurnExtensions' },\n { flags: ['--prompt-token-budget'], type: 'number', key: 'promptTokenBudget' },\n { flags: ['--prompt-time-budget'], type: 'number', key: 'promptTimeBudgetMin' },\n { flags: ['--session-cost-budget'], type: 'number', key: 'sessionCostBudget' },\n { flags: ['--no-stall-detection'], type: 'boolean', key: 'noStallDetection' },\n { flags: ['--stall-window-turns'], type: 'number', key: 'stallWindowTurns' },\n { flags: ['--stall-repeat-threshold'], type: 'number', key: 'stallRepeatThreshold' },\n { flags: ['--continue'], type: 'string', key: 'continueSession' },\n { flags: ['--attach'], type: 'string', key: 'attachSession' },\n { flags: ['--force-write-lease'], type: 'boolean', key: 'forceWriteLease' },\n // RFC-115 M3(P1-1 修正):仅由 cli.ts 的内存治理触发重启 chaperone 附加,不对外文档化——\n // 区分\"内存压力触发的自动重启\"与\"用户手动 otto --continue\",前者才应起算 D5 宽限期。\n { flags: ['--memory-restart-grace'], type: 'boolean', key: 'memoryRestartGrace' },\n // RFC-115 M4:仅由 cli.ts 的内存治理触发重启 chaperone 附加,不对外文档化——重启前\n // 会话正忙时的续跑原文,子进程启动后自动重新提交为续跑轮。\n { flags: ['--resume-prompt'], type: 'string', key: 'resumePrompt' },\n { flags: ['--session-url'], type: 'string', key: 'sessionUrl' },\n { flags: ['--session-token'], type: 'string', key: 'sessionToken' },\n { flags: ['--id'], type: 'string', key: 'workspaceId' },\n { flags: ['--shadow'], type: 'boolean', key: 'shadow' },\n { flags: ['--help', '-h'], type: 'boolean', key: 'showHelp' },\n { flags: ['--version', '-v'], type: 'action', handler: printVersion },\n]\n\nconst OPTION_LOOKUP: Map<string, OptionEntry> = new Map(\n OPTIONS.flatMap(e => e.flags.map(f => [f, e] as const)),\n)\n\nclass ArgCursor {\n private i: number\n constructor(private args: string[]) {\n this.i = 0\n }\n current(): string | undefined { return this.args[this.i] }\n next(): string | undefined { return this.args[++this.i] }\n advance(): void { this.i++ }\n skip(count: number): void { this.i += count }\n pos(): number { return this.i }\n}\n\nexport function parseCLI(argv: string[]): ParsedCLI {\n const args = argv.slice(2)\n const cursor = new ArgCursor(args)\n\n const options: CLIOptions = {\n mode: 'interactive',\n projectDir: process.cwd(),\n verbose: false,\n quiet: false,\n }\n\n const first = cursor.current()\n let subCommand: SubCommand | undefined\n let subCommandArgs = ''\n let unresolvedCommandName: string | undefined\n let unresolvedCommandArgs: string[] | undefined\n if (first && SUB_COMMAND_NAMES.has(first as SubCommand)) {\n subCommand = first as SubCommand\n subCommandArgs = args.slice(1).join(' ')\n cursor.skip(1)\n\n if (subCommand === 'run') {\n options.prompt = args.slice(1).filter(a => !looksLikeFlag(a)).join(' ')\n options.mode = 'print'\n }\n } else if (first && !looksLikeFlag(first)) {\n // RFC-112 D2:第一个位置参数不是内建命令,也不以 `-` 开头(不是 flag)——\n // 记录为候选插件 CLI 命令名,供 cli.ts 查插件表二次判定;不改变下方现有的\n // \"当作 prompt\" 逻辑(该逻辑仍会照常把 first 纳入 promptParts,回退路径零改动)。\n unresolvedCommandName = first\n unresolvedCommandArgs = args.slice(1)\n }\n\n let promptParts: string[] = options.prompt ? [options.prompt] : []\n\n while (cursor.current() !== undefined) {\n const arg = cursor.current()!\n\n if (arg === '--inspect') {\n options.inspect = true\n cursor.advance()\n continue\n }\n if (arg?.startsWith('--inspect=')) {\n const port = Number(arg.slice('--inspect='.length))\n options.inspect = Number.isInteger(port) && port > 0 ? port : true\n cursor.advance()\n continue\n }\n // RFC-196 M3:重启代际计数(chaperone 重启 spawn 注入,不文档化——内部可观测标记,\n // 供 ≥3 代告警与 otto ps GEN 列展示;不驱动任何行为分支)。\n if (arg?.startsWith('--restart-generation=')) {\n const gen = Number(arg.slice('--restart-generation='.length))\n if (Number.isInteger(gen) && gen > 0) options.restartGeneration = gen\n cursor.advance()\n continue\n }\n\n const entry = OPTION_LOOKUP.get(arg)\n if (entry) {\n cursor.advance()\n switch (entry.type) {\n case 'boolean':\n ;(options as unknown as Record<string, unknown>)[entry.key] = true\n break\n case 'mode':\n options.mode = entry.value\n break\n case 'string':\n ;(options as unknown as Record<string, unknown>)[entry.key] = cursor.current()\n cursor.advance()\n break\n case 'number':\n {\n // 08-13 backlog triage(终局复核修订):flag 末尾缺值时 cursor.current() 是\n // undefined → Number(undefined)=NaN 静默写进配置。改为 fail-closed:非有限\n // 值不写入(等同未传,消费方走默认值)。\n //\n // 0 值策略(复核发现的行为漂移):`maxToolTurnExtensions` 的 0 是**合法语义**\n // ——主会话显式\"禁止压缩续跑\"(缺省 3,agent-session.ts defaultMaxToolTurnExtensions),\n // 被 `>0` 拒绝会静默改回 3。故按 key 白名单允许 0:该 key 允许 `>=0`,\n // 其余 number flag 维持 `>0`(其消费方均无 0 特判,拒绝 0 无行为差异)。\n //\n // 缺值/下一 token 是另一 flag 时(如 `--max-tool-turns --quiet`):值以 `-`\n // 开头视为**未提供**——不写入、**不 advance**(否则会把 --quiet 当值吞掉,\n // 复核确认的 pre-existing 吞 flag 缺陷在此闭合)。number 值恒为正数,不以\n // `-` 开头,故该判定无合法值误伤。\n const raw = cursor.current()\n if (raw === undefined || raw.startsWith('-')) break\n const parsed = Number(raw)\n const allowsZero = entry.key === 'maxToolTurnExtensions'\n if (Number.isFinite(parsed) && (allowsZero ? parsed >= 0 : parsed > 0)) {\n ;(options as unknown as Record<string, unknown>)[entry.key] = parsed\n }\n cursor.advance()\n continue\n }\n case 'path':\n ;(options as unknown as Record<string, unknown>)[entry.key] = resolve(cursor.current() ?? process.cwd())\n cursor.advance()\n break\n case 'action':\n entry.handler()\n break\n }\n continue\n }\n\n if (arg && !looksLikeFlag(arg) && !subCommand) {\n if (options.prompt === undefined && options.mode === 'interactive') {\n options.mode = 'print'\n }\n promptParts.push(arg)\n }\n cursor.advance()\n }\n\n if (promptParts.length > 0) {\n options.prompt = promptParts.join(' ')\n }\n\n return { options, subCommand, subCommandArgs, unresolvedCommandName, unresolvedCommandArgs }\n}\n\n/** 帮助文本行(供 plain-text printHelp 与 TUI InfoDialog 共用)。 */\nexport function getHelpLines(): string[] {\n return [\n '',\n 'otto - AI 助理命令行工具',\n '',\n '用法:',\n ' otto [提示词] 使用提示词启动(print 模式)',\n ' otto 进入交互式 TUI 模式',\n ' otto --json \"query\" JSON 输出模式',\n '',\n '选项:',\n ' -i, --interactive Interactive 模式(默认)',\n ' -p, --print Print 模式(非交互)',\n ' --json JSON 输出模式',\n ' -m, --model <id> 指定模型',\n ' -c, --config <path> 配置文件路径',\n ' -d, --project <dir> 项目目录',\n ' --verbose 输出详细日志',\n ' -q, --quiet 只输出 error 日志',\n ' --shadow 影子模式:otto 自有状态(凭据/会话/记忆/教训/配置/trace/日志)本次会话零磁盘写入(不保证 provider 服务端日志与 shell/OS 层痕迹;RFC-345)',\n ' --max-tool-turns <n> 单个用户回合最大工具回合数(默认 120)',\n ' --max-tool-turn-extensions <n> 触顶后压缩续跑的扩展次数(默认主会话 3 / 子 agent 0)',\n ' --prompt-token-budget <n> 单回合输出 token 预算(配置后轮次上限 ×4 退位安全阀;RFC-104)',\n ' --prompt-time-budget <min> 单回合墙钟时间预算(分钟)',\n ' --session-cost-budget <usd> 会话累计成本软预算(美元,超过一次性提醒不阻断;RFC-204)',\n ' --no-stall-detection 关闭早期停滞检测(默认开启;RFC-203)',\n ' --stall-window-turns <n> 停滞检测滑动窗口大小(需与 --stall-repeat-threshold 同时提供,默认 8)',\n ' --stall-repeat-threshold <n> 停滞检测同签名重复阈值(需与 --stall-window-turns 同时提供,默认 4)',\n ' --continue <id> 继续已有会话',\n ' --session-url <url> 远端会话持久化地址(如 http://host:3001/sessions)',\n ' --session-token <token> 远端会话持久化 Bearer token',\n ' --inspect[=port] 启用 Node.js inspector(默认: 9229)',\n ' -h, --help 显示帮助',\n ' --version, -v 显示版本',\n '',\n '命令:',\n ' otto run <prompt> 执行一次性任务',\n ' otto serve [--port N] [--inspect] [--static <dir>] [--token <t>] 启动 HTTP/WS service(--static 同源托管前端 SPA,--token 启用鉴权)',\n ' otto doctor [--summary|--json] 环境健康检查(环境/配置/存储状态/连通性)',\n ' otto auth login <provider> 登录(cursor / anthropic / openai-codex / github-copilot)',\n ' otto auth status 查看各 provider 凭据来源',\n ' otto auth logout <provider> 注销并清除凭据',\n ' otto config export [--project] [-o <path>] 导出配置(RFC-219)',\n ' otto config import <file> [--dry-run] [--scope global|project] [--no-plugins] [--plugins-only] [--yes] 导入配置',\n ' otto config restore [--list] 撤销最近一次导入',\n ' otto migrate export [--no-sessions] [-o <path>] 导出配置+插件清单+会话数据为迁移包(换电脑用)',\n ' otto migrate import <archive> [--no-sessions] 导入迁移包(目标已有会话数据时跳过会话部分)',\n ' otto observe <action> <id> 观测面板(summary / timeline / spans)',\n ' otto observe debug <action> [...] 调试面板(breakpoints / points / state)',\n ' otto observe replay <action> <id> 时间旅行(checkpoints / scrubber / restore / fork / replay)',\n ' otto debug <action> [...] (alias: otto observe debug)',\n ' otto time-travel <action> <id> (alias: otto observe replay)',\n ' otto mcp login <name> MCP server OAuth 登录',\n ' otto mcp logout <name> 登出 MCP server',\n ' otto mcp list 列出已认证的 MCP server',\n ' otto extension create <name> 生成插件骨架(命令 + 面板 + manifest,开箱即用)',\n ' otto extension install <name> [--yes] 安装首方/自定义插件(anthropic-provider / deepseek-provider / browser-use / …)',\n ' otto extension update [name] 检查并重装已过期的已安装 skill/plugin',\n ' otto persistence local [...flags] 启动独立持久化服务(storage + events + sync)',\n ' otto persistence remote [...flags] 启动最小化远程持久化服务(5 REST 端点)',\n ' otto persistenced [...flags] (alias: otto persistence local)',\n ' otto remote-persistence-server [...flags] (alias: otto persistence remote)',\n ' otto ps [--sweep] [--include-weak] [--json] 进程群列表与孤儿清扫(SIGTERM only,RFC-196)',\n ' otto export-trajectory --session <id> --out <path> [--since-seq <n>] 导出会话轨迹 JSONL(RFC-385;默认关)',\n '',\n '面板命令默认连 `otto serve` 实例(http://127.0.0.1:8417,OTTO_SERVICE_URL/--remote 可覆盖)。',\n ]\n}\n\nfunction printVersion(): void {\n process.stdout.write(`otto ${getVersion()}\\n`)\n process.exit(0)\n}\n"],"mappings":"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SAEjB,EAAY,KAAK,EAAI,EAEvB,EAAO,SAAS,CAOlB,OAJI,EAAY,OAAS,IACvB,EAAQ,OAAS,EAAY,KAAK,IAAI,EAGjC,CAAE,UAAS,aAAY,iBAAgB,wBAAuB,wBAAuB,CAI9F,SAAgB,GAAyB,CACvC,MAAO,CACL,GACA,oBACA,GACA,MACA,8CACA,4CACA,yCACA,GACA,MACA,iDACA,4CACA,wCACA,mCACA,qCACA,mCACA,qCACA,2CACA,yHACA,oDACA,sEACA,uEACA,6CACA,iEACA,qDACA,gFACA,gFACA,qCACA,qEACA,mDACA,6DACA,mCACA,mCACA,GACA,MACA,2CACA,2HACA,0DACA,0FACA,qDACA,2CACA,8DACA,iHACA,4CACA,8EACA,4EACA,oEACA,8EACA,iGACA,+DACA,gEACA,sDACA,gDACA,oDACA,qEACA,gHACA,+DACA,2EACA,gEACA,wEACA,gFACA,kFACA,oGACA,GACA,gFACD,CAGH,SAAS,GAAqB,CAC5B,QAAQ,OAAO,MAAM,QAAQ,GAAY,CAAC,IAAI,CAC9C,QAAQ,KAAK,EAAE"}
|
|
1
|
+
{"version":3,"file":"parse-cli-BvcxTK88.js","names":[],"sources":["../src/parse-cli.ts"],"sourcesContent":["import { resolve } from 'node:path'\n\nimport type { CLIOptions, RunMode } from './types'\nimport { getVersion } from './version'\n\nexport type SubCommand = 'run' | 'serve' | 'daemon' | 'doctor' | 'config' | 'migrate' | 'auth' | 'observe' | 'debug' | 'time-travel' | 'mcp' | 'mcp-server' | 'persistenced' | 'remote-persistence-server' | 'persistence' | 'extension' | 'ps' | 'feedback' | 'export-trajectory'\n\n/**\n * 真正的 flag 形态判定:`--xxx`、`-x`、`-x=value` 算 flag;\n * `- 文本`(连字符后跟空格)是**合法 prompt 开头**,不是 flag。\n *\n * 真机证据(Terminal-Bench 2.1 评测,2026-08-14):pytorch-model-recovery 任务的\n * instruction 以 \"- You are given a PyTorch state dictionary…\" 开头,旧判定\n * `arg.startsWith('-')` 把它当 flag 吞掉 → promptParts 为空 → otto 输出\n * \"no prompt provided\" → 三次 attempt 全部 0 分且无异常,被误判为模型能力失败。\n * 标准 CLI 语义下 `- ` 开头的参数不是 flag(minimist 同款行为),修复后此类 prompt\n * 正常进入会话。\n */\nfunction looksLikeFlag(arg: string): boolean {\n return arg.startsWith('--') || /^-[^\\s-]/.test(arg)\n}\n\nexport interface ParsedCLI {\n options: CLIOptions\n /** 未命中任何内建子命令时为 `undefined`(而非 `null` 哨兵——与 SUB_COMMAND_NAMES 的\n * 元素类型保持一致,消费方无需 `.filter(n => n !== null)` 剔除哨兵值)。 */\n subCommand: SubCommand | undefined\n subCommandArgs: string\n /**\n * RFC-112 D2:内建 `SUB_COMMAND_NAMES` 未命中的第一个位置参数(候选插件 CLI 命令名,\n * 如 `otto feishu ...` 里的 `\"feishu\"`)。`undefined` 表示第一个参数已命中内建命令,\n * 或压根没有位置参数。**不改变** `options.prompt`/`subCommand` 的既有构建逻辑——\n * 这两者仍然按\"当作 prompt\"的旧行为完整计算好,供插件命令名查无匹配时零改动回退。\n */\n unresolvedCommandName?: string\n /**\n * 与 `unresolvedCommandName` 配对:该候选名之后的**原始** args(未做 flag 过滤,含 `-h`\n * 等字面量),只在插件命令表命中该名字时使用(透传给插件可执行文件)。\n */\n unresolvedCommandArgs?: string[]\n}\n\n/** RFC-112 D2:导出供 `cli.ts` 构建插件 CLI 命令表时用作保留字集合(插件不得覆盖)。 */\nexport const SUB_COMMAND_NAMES = new Set<SubCommand>([\n 'run', 'serve', 'daemon', 'doctor', 'config', 'migrate', 'auth', 'observe', 'debug', 'time-travel', 'mcp', 'mcp-server', 'persistenced', 'remote-persistence-server', 'persistence', 'extension', 'ps', 'feedback', 'export-trajectory',\n])\n\ntype OptionEntry =\n | { flags: string[]; type: 'boolean'; key: keyof CLIOptions }\n | { flags: string[]; type: 'mode'; value: RunMode }\n | { flags: string[]; type: 'string'; key: keyof CLIOptions }\n | { flags: string[]; type: 'number'; key: keyof CLIOptions }\n | { flags: string[]; type: 'path'; key: keyof CLIOptions }\n | { flags: string[]; type: 'action'; handler: () => void }\n\nconst OPTIONS: OptionEntry[] = [\n { flags: ['--print', '-p'], type: 'mode', value: 'print' },\n { flags: ['--interactive', '-i'], type: 'mode', value: 'interactive' },\n { flags: ['--json'], type: 'mode', value: 'json' },\n { flags: ['--model', '-m'], type: 'string', key: 'model' },\n { flags: ['--config', '-c'], type: 'string', key: 'configPath' },\n { flags: ['--project', '-d'], type: 'path', key: 'projectDir' },\n { flags: ['--quiet', '-q'], type: 'boolean', key: 'quiet' },\n { flags: ['--verbose'], type: 'boolean', key: 'verbose' },\n { flags: ['--max-tool-turns'], type: 'number', key: 'maxToolTurns' },\n { flags: ['--max-tool-turn-extensions'], type: 'number', key: 'maxToolTurnExtensions' },\n { flags: ['--prompt-token-budget'], type: 'number', key: 'promptTokenBudget' },\n { flags: ['--prompt-time-budget'], type: 'number', key: 'promptTimeBudgetMin' },\n { flags: ['--session-cost-budget'], type: 'number', key: 'sessionCostBudget' },\n { flags: ['--no-stall-detection'], type: 'boolean', key: 'noStallDetection' },\n { flags: ['--stall-window-turns'], type: 'number', key: 'stallWindowTurns' },\n { flags: ['--stall-repeat-threshold'], type: 'number', key: 'stallRepeatThreshold' },\n { flags: ['--continue'], type: 'string', key: 'continueSession' },\n { flags: ['--attach'], type: 'string', key: 'attachSession' },\n { flags: ['--force-write-lease'], type: 'boolean', key: 'forceWriteLease' },\n // RFC-115 M3(P1-1 修正):仅由 cli.ts 的内存治理触发重启 chaperone 附加,不对外文档化——\n // 区分\"内存压力触发的自动重启\"与\"用户手动 otto --continue\",前者才应起算 D5 宽限期。\n { flags: ['--memory-restart-grace'], type: 'boolean', key: 'memoryRestartGrace' },\n // RFC-115 M4:仅由 cli.ts 的内存治理触发重启 chaperone 附加,不对外文档化——重启前\n // 会话正忙时的续跑原文,子进程启动后自动重新提交为续跑轮。\n { flags: ['--resume-prompt'], type: 'string', key: 'resumePrompt' },\n { flags: ['--session-url'], type: 'string', key: 'sessionUrl' },\n { flags: ['--session-token'], type: 'string', key: 'sessionToken' },\n { flags: ['--id'], type: 'string', key: 'workspaceId' },\n { flags: ['--shadow'], type: 'boolean', key: 'shadow' },\n { flags: ['--help', '-h'], type: 'boolean', key: 'showHelp' },\n { flags: ['--version', '-v'], type: 'action', handler: printVersion },\n]\n\nconst OPTION_LOOKUP: Map<string, OptionEntry> = new Map(\n OPTIONS.flatMap(e => e.flags.map(f => [f, e] as const)),\n)\n\nclass ArgCursor {\n private i: number\n constructor(private args: string[]) {\n this.i = 0\n }\n current(): string | undefined { return this.args[this.i] }\n next(): string | undefined { return this.args[++this.i] }\n advance(): void { this.i++ }\n skip(count: number): void { this.i += count }\n pos(): number { return this.i }\n}\n\nexport function parseCLI(argv: string[]): ParsedCLI {\n const args = argv.slice(2)\n const cursor = new ArgCursor(args)\n\n const options: CLIOptions = {\n mode: 'interactive',\n projectDir: process.cwd(),\n verbose: false,\n quiet: false,\n }\n\n const first = cursor.current()\n let subCommand: SubCommand | undefined\n let subCommandArgs = ''\n let unresolvedCommandName: string | undefined\n let unresolvedCommandArgs: string[] | undefined\n if (first && SUB_COMMAND_NAMES.has(first as SubCommand)) {\n subCommand = first as SubCommand\n subCommandArgs = args.slice(1).join(' ')\n cursor.skip(1)\n\n if (subCommand === 'run') {\n options.prompt = args.slice(1).filter(a => !looksLikeFlag(a)).join(' ')\n options.mode = 'print'\n }\n } else if (first && !looksLikeFlag(first)) {\n // RFC-112 D2:第一个位置参数不是内建命令,也不以 `-` 开头(不是 flag)——\n // 记录为候选插件 CLI 命令名,供 cli.ts 查插件表二次判定;不改变下方现有的\n // \"当作 prompt\" 逻辑(该逻辑仍会照常把 first 纳入 promptParts,回退路径零改动)。\n unresolvedCommandName = first\n unresolvedCommandArgs = args.slice(1)\n }\n\n let promptParts: string[] = options.prompt ? [options.prompt] : []\n\n while (cursor.current() !== undefined) {\n const arg = cursor.current()!\n\n if (arg === '--inspect') {\n options.inspect = true\n cursor.advance()\n continue\n }\n if (arg?.startsWith('--inspect=')) {\n const port = Number(arg.slice('--inspect='.length))\n options.inspect = Number.isInteger(port) && port > 0 ? port : true\n cursor.advance()\n continue\n }\n // RFC-196 M3:重启代际计数(chaperone 重启 spawn 注入,不文档化——内部可观测标记,\n // 供 ≥3 代告警与 otto ps GEN 列展示;不驱动任何行为分支)。\n if (arg?.startsWith('--restart-generation=')) {\n const gen = Number(arg.slice('--restart-generation='.length))\n if (Number.isInteger(gen) && gen > 0) options.restartGeneration = gen\n cursor.advance()\n continue\n }\n\n const entry = OPTION_LOOKUP.get(arg)\n if (entry) {\n cursor.advance()\n switch (entry.type) {\n case 'boolean':\n ;(options as unknown as Record<string, unknown>)[entry.key] = true\n break\n case 'mode':\n options.mode = entry.value\n break\n case 'string':\n ;(options as unknown as Record<string, unknown>)[entry.key] = cursor.current()\n cursor.advance()\n break\n case 'number':\n {\n // 08-13 backlog triage(终局复核修订):flag 末尾缺值时 cursor.current() 是\n // undefined → Number(undefined)=NaN 静默写进配置。改为 fail-closed:非有限\n // 值不写入(等同未传,消费方走默认值)。\n //\n // 0 值策略(复核发现的行为漂移):`maxToolTurnExtensions` 的 0 是**合法语义**\n // ——主会话显式\"禁止压缩续跑\"(缺省 3,agent-session.ts defaultMaxToolTurnExtensions),\n // 被 `>0` 拒绝会静默改回 3。故按 key 白名单允许 0:该 key 允许 `>=0`,\n // 其余 number flag 维持 `>0`(其消费方均无 0 特判,拒绝 0 无行为差异)。\n //\n // 缺值/下一 token 是另一 flag 时(如 `--max-tool-turns --quiet`):值以 `-`\n // 开头视为**未提供**——不写入、**不 advance**(否则会把 --quiet 当值吞掉,\n // 复核确认的 pre-existing 吞 flag 缺陷在此闭合)。number 值恒为正数,不以\n // `-` 开头,故该判定无合法值误伤。\n const raw = cursor.current()\n if (raw === undefined || raw.startsWith('-')) break\n const parsed = Number(raw)\n const allowsZero = entry.key === 'maxToolTurnExtensions'\n if (Number.isFinite(parsed) && (allowsZero ? parsed >= 0 : parsed > 0)) {\n ;(options as unknown as Record<string, unknown>)[entry.key] = parsed\n }\n cursor.advance()\n continue\n }\n case 'path':\n ;(options as unknown as Record<string, unknown>)[entry.key] = resolve(cursor.current() ?? process.cwd())\n cursor.advance()\n break\n case 'action':\n entry.handler()\n break\n }\n continue\n }\n\n if (arg && !looksLikeFlag(arg) && !subCommand) {\n if (options.prompt === undefined && options.mode === 'interactive') {\n options.mode = 'print'\n }\n promptParts.push(arg)\n }\n cursor.advance()\n }\n\n if (promptParts.length > 0) {\n options.prompt = promptParts.join(' ')\n }\n\n return { options, subCommand, subCommandArgs, unresolvedCommandName, unresolvedCommandArgs }\n}\n\n/** 帮助文本行(供 plain-text printHelp 与 TUI InfoDialog 共用)。 */\nexport function getHelpLines(): string[] {\n return [\n '',\n 'otto - AI 助理命令行工具',\n '',\n '用法:',\n ' otto [提示词] 使用提示词启动(print 模式)',\n ' otto 进入交互式 TUI 模式',\n ' otto --json \"query\" JSON 输出模式',\n '',\n '选项:',\n ' -i, --interactive Interactive 模式(默认)',\n ' -p, --print Print 模式(非交互)',\n ' --json JSON 输出模式',\n ' -m, --model <id> 指定模型',\n ' -c, --config <path> 配置文件路径',\n ' -d, --project <dir> 项目目录',\n ' --verbose 输出详细日志',\n ' -q, --quiet 只输出 error 日志',\n ' --shadow 影子模式:otto 自有状态(凭据/会话/记忆/教训/配置/trace/日志)本次会话零磁盘写入(不保证 provider 服务端日志与 shell/OS 层痕迹;RFC-345)',\n ' --max-tool-turns <n> 单个用户回合最大工具回合数(默认 120)',\n ' --max-tool-turn-extensions <n> 触顶后压缩续跑的扩展次数(默认主会话 3 / 子 agent 0)',\n ' --prompt-token-budget <n> 单回合输出 token 预算(配置后轮次上限 ×4 退位安全阀;RFC-104)',\n ' --prompt-time-budget <min> 单回合墙钟时间预算(分钟)',\n ' --session-cost-budget <usd> 会话累计成本软预算(美元,超过一次性提醒不阻断;RFC-204)',\n ' --no-stall-detection 关闭早期停滞检测(默认开启;RFC-203)',\n ' --stall-window-turns <n> 停滞检测滑动窗口大小(需与 --stall-repeat-threshold 同时提供,默认 8)',\n ' --stall-repeat-threshold <n> 停滞检测同签名重复阈值(需与 --stall-window-turns 同时提供,默认 4)',\n ' --continue <id> 继续已有会话',\n ' --session-url <url> 远端会话持久化地址(如 http://host:3001/sessions)',\n ' --session-token <token> 远端会话持久化 Bearer token',\n ' --inspect[=port] 启用 Node.js inspector(默认: 9229)',\n ' -h, --help 显示帮助',\n ' --version, -v 显示版本',\n '',\n '命令:',\n ' otto run <prompt> 执行一次性任务',\n ' otto serve [--port N] [--inspect] [--static <dir>] [--token <t>] 启动 HTTP/WS service(--static 同源托管前端 SPA,--token 启用鉴权)',\n ' otto doctor [--summary|--json] 环境健康检查(环境/配置/存储状态/连通性)',\n ' otto auth login <provider> 登录(cursor / anthropic / openai-codex / github-copilot)',\n ' otto auth status 查看各 provider 凭据来源',\n ' otto auth logout <provider> 注销并清除凭据',\n ' otto config export [--project] [-o <path>] 导出配置(RFC-219)',\n ' otto config import <file> [--dry-run] [--scope global|project] [--no-plugins] [--plugins-only] [--yes] 导入配置',\n ' otto config restore [--list] 撤销最近一次导入',\n ' otto migrate export [--no-sessions] [-o <path>] 导出配置+插件清单+会话数据为迁移包(换电脑用)',\n ' otto migrate import <archive> [--no-sessions] 导入迁移包(目标已有会话数据时跳过会话部分)',\n ' otto observe <action> <id> 观测面板(summary / timeline / spans)',\n ' otto observe debug <action> [...] 调试面板(breakpoints / points / state)',\n ' otto observe replay <action> <id> 时间旅行(checkpoints / scrubber / restore / fork / replay)',\n ' otto debug <action> [...] (alias: otto observe debug)',\n ' otto time-travel <action> <id> (alias: otto observe replay)',\n ' otto mcp login <name> MCP server OAuth 登录',\n ' otto mcp logout <name> 登出 MCP server',\n ' otto mcp list 列出已认证的 MCP server',\n ' otto extension create <name> 生成插件骨架(命令 + 面板 + manifest,开箱即用)',\n ' otto extension install <name> [--yes] 安装首方/自定义插件(anthropic-provider / deepseek-provider / browser-use / …)',\n ' otto extension update [name] 检查并重装已过期的已安装 skill/plugin',\n ' otto persistence local [...flags] 启动独立持久化服务(storage + events + sync)',\n ' otto persistence remote [...flags] 启动最小化远程持久化服务(5 REST 端点)',\n ' otto persistenced [...flags] (alias: otto persistence local)',\n ' otto remote-persistence-server [...flags] (alias: otto persistence remote)',\n ' otto ps [--sweep] [--include-weak] [--json] 进程群列表与孤儿清扫(SIGTERM only,RFC-196)',\n ' otto export-trajectory --session <id> --out <path> [--since-seq <n>] 导出会话轨迹 JSONL(RFC-385;默认关)',\n '',\n '面板命令默认连 `otto serve` 实例(http://127.0.0.1:8417,OTTO_SERVICE_URL/--remote 可覆盖)。',\n ]\n}\n\nfunction printVersion(): void {\n process.stdout.write(`otto ${getVersion()}\\n`)\n process.exit(0)\n}\n"],"mappings":"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SAEjB,EAAY,KAAK,EAAI,EAEvB,EAAO,SAAS,CAOlB,OAJI,EAAY,OAAS,IACvB,EAAQ,OAAS,EAAY,KAAK,IAAI,EAGjC,CAAE,UAAS,aAAY,iBAAgB,wBAAuB,wBAAuB,CAI9F,SAAgB,GAAyB,CACvC,MAAO,CACL,GACA,oBACA,GACA,MACA,8CACA,4CACA,yCACA,GACA,MACA,iDACA,4CACA,wCACA,mCACA,qCACA,mCACA,qCACA,2CACA,yHACA,oDACA,sEACA,uEACA,6CACA,iEACA,qDACA,gFACA,gFACA,qCACA,qEACA,mDACA,6DACA,mCACA,mCACA,GACA,MACA,2CACA,2HACA,0DACA,0FACA,qDACA,2CACA,8DACA,iHACA,4CACA,8EACA,4EACA,oEACA,8EACA,iGACA,+DACA,gEACA,sDACA,gDACA,oDACA,qEACA,gHACA,+DACA,2EACA,gEACA,wEACA,gFACA,kFACA,oGACA,GACA,gFACD,CAGH,SAAS,GAAqB,CAC5B,QAAQ,OAAO,MAAM,QAAQ,GAAY,CAAC,IAAI,CAC9C,QAAQ,KAAK,EAAE"}
|