@x-otto/cli 0.0.1-alpha.21 → 0.0.1-alpha.23

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,21 +0,0 @@
1
- #!/usr/bin/env node
2
- import{t as e}from"./build-id-D7Wf4tQw.js";import{t}from"./version-Cq2kcrXL.js";import{t as n}from"./discover-with-bundled-CF8qFP41.js";import{n as r,r as i,t as a}from"./service-client-Cr4sxDVM.js";import{n as o}from"./extension-DLFCUBJr.js";import{t as s}from"./proxy-evg7ZvoD.js";import{i as c}from"./install-DlVJRHRT.js";import{n as l,t as u}from"./registry-BdCcwyGy.js";import{n as d,t as f}from"./feedback-DuTIx3-K.js";import{createRequire as p}from"node:module";import{arch as m,cpus as h,freemem as g,homedir as _,platform as v,release as ee,totalmem as y}from"node:os";import{execFile as b,execSync as te,spawn as x,spawnSync as S}from"node:child_process";import{DEFAULT_WORKSPACE_KEY as ne,INDUCTOR_PLUGIN_ID as C,InstallManager as w,PLUGIN_MANIFEST_FILENAME as T,POINT as re,buildExtensionContext as ie,checkUpgrades as ae,collectPluginPerfMetrics as oe,defaultPostInstallExecutor as se,detectProjectConfigGating as ce,discoverFileCommands as le,discoverPlugins as ue,dispatch as de,evaluateClaudeTrust as fe,evaluatePluginTrust as pe,findWorkspaceRoot as me,getLastAssistantText as E,grantPluginCapabilities as he,installPluginFromPackage as ge,openTarget as _e,parsePluginManifest as ve,readHighRiskCapabilities as ye,readPluginLogTail as be,readSkillLoopStatus as xe,recordPluginInstalled as Se,recordPluginUninstalled as Ce,resolveActions as we,resolvePackageDir as Te,resolveSessionTitle as Ee,runPluginScript as De,scanInstalledVersions as Oe,trustPlugin as ke,trustProject as Ae,uninstall as je,untrustPlugin as Me,untrustProject as Ne}from"@x-otto/coding";import{checkShellCommand as Pe,openBrowser as Fe,readFileCapped as Ie}from"@x-otto/shared";import{BUILD_ID as Le,OTTO_HOME as Re,SDK_VERSION as ze}from"@x-otto/env";import{dirname as D,join as O,relative as Be,resolve as Ve}from"node:path";import{closeSync as He,existsSync as k,openSync as Ue,readFileSync as A,readSync as We,readdirSync as Ge,statSync as Ke}from"node:fs";import{FIGURES as j,buildTurnSummary as qe,createBuiltinThemeRegistry as Je,createReducerState as Ye,deriveTurnBoundaries as Xe,detectLanguage as Ze,formatProviderUsageLimitTypeFull as Qe,i18next as M,initI18n as $e,insertTurnSummaries as et,reduceToTui as tt}from"@x-otto/tui";import{readFile as nt,readdir as rt,stat as it,unlink as at}from"node:fs/promises";import{createBuiltinCommands as ot}from"@x-otto/tui/compat";import{MaxToolTurnsError as st,PromptBudgetExceededError as ct}from"@x-otto/agent";import{DEFAULT_COMPACTION_CONFIG as lt,DEFAULT_PRUNE_CONFIG as ut,estimateTokensHeuristic as dt,resolveContextSize as ft}from"@x-otto/memory";import{classifyAuthErrorType as pt,computeCacheHitRatio as mt,createModelUsabilityGate as N,getProviderDescriptor as ht,getToolCallsByAssistantMessage as gt,isAuthError as _t}from"@x-otto/ai";import{promisify as vt}from"node:util";var yt=Object.defineProperty,bt=(e,t)=>{let n={};for(var r in e)yt(n,r,{get:e[r],enumerable:!0});return t||yt(n,Symbol.toStringTag,{value:`Module`}),n},xt=p(import.meta.url);function St(e){return`⚠ 已达工具回合上限(${e.extensions>0?`约 ${e.effectiveMaxTurns} 次(含 ${e.extensions} 次自动扩展,每次 ${e.maxTurns})`:`${e.maxTurns} 次`}),提前停止——任务可能未完成。\n 重试可加 --max-tool-turns <n>(每轮预算,实际上限 ≈ n×${1+e.extensions};如 --max-tool-turns ${e.maxTurns*2})。\n 注:配置了 --prompt-token-budget 时轮次窗口自动 ×4(此处报的是放大后的有效值)。`}function Ct(e,t){let n=E(e.session.messages())||t.partialText,r=St(t);return n?`${n}\n${r}`:r}function wt(e){let t=e.dimension===`tokens`?`输出 token 预算 ${e.used}/${e.budget}`:`时间预算 ${Math.round(e.used/1e3)}s/${Math.round(e.budget/1e3)}s`;return`⚠ 已达本回合${e.dimension===`tokens`?`输出 token`:`墙钟时间`}预算(${t}),提前停止——任务可能未完成。\n 重试可加 ${e.dimension===`tokens`?`--prompt-token-budget <n>`:`--prompt-time-budget <分钟>`} 提升预算。`}function Tt(e,t){let n=E(e.session.messages())||t.partialText,r=wt(t);return n?`${n}\n${r}`:r}async function Et(e,t,n={}){let{writer:r,tui:i=!1,tuiOptions:a,onTurnEnd:o}=typeof n==`function`?{writer:n}:n,s=r??(e=>process.stdout.write(`${e}\n`)),c=Date.now();try{await e.prompt(t)}catch(t){if(t instanceof st||t instanceof ct){let n=t instanceof ct,r=n?wt(t):St(t);o?.(n?`budget-exceeded`:`max-tool-turns`,r);let l=o?E(e.session.messages())||t.partialText:n?Tt(e,t):Ct(e,t);if(i){let{printMessages:t}=await import(`@x-otto/tui`);t(e.session.messages(),{...a,startTime:c,contextWindow:0}),s(l)}else s(l);return l}throw t}if(o&&e.budgetSteeredThisPrompt&&o(`max-tool-turns`,`⚠ 已达工具回合上限——已自动收尾本回合(任务可能未全部完成,可继续指示我,或加 --max-tool-turns 提升预算)。`),i){let{printMessages:t}=await import(`@x-otto/tui`),n=e.session.messages();return t(n,{...a,startTime:c,contextWindow:e.model.contextWindow??0}),E(n)}let l=E(e.session.messages());return s(l),l}async function Dt(e,t){try{await e.prompt(t)}catch(t){if(t instanceof st)return{sessionId:e.id,status:`max_turns`,messageCount:e.session.messages().length,response:E(e.session.messages())||t.partialText};if(t instanceof ct)return{sessionId:e.id,status:`budget_exceeded`,messageCount:e.session.messages().length,response:E(e.session.messages())||t.partialText};throw t}return{sessionId:e.id,status:e.status,messageCount:e.session.messages().length,response:E(e.session.messages())}}var Ot=class{commandRegistry;modelList=[];currentModelId;onModelChange;constructor(e,t={}){this.session=e,this.modelList=t.models??[],this.currentModelId=t.currentModel,this.onModelChange=t.onModelChange,this.commandRegistry=ot()}getRegistry(){return this.commandRegistry}abort(){this.session.abort()}async handleInput(e){if(this.session.status===`archived`)return{type:`system`,text:`此会话已归档(archived),无法发送新消息。使用 /resume 切换到其他会话。`};let t=e.trim();if(t.length===0)return{type:`noop`};if(t.startsWith(`!`)){let e=t.slice(1).trim();if(!e)return{type:`system`,text:`Usage: !<shell command>`};let n=Pe(e);if(!n.safe)return{type:`system`,text:`Refusing to execute dangerous command (${n.reason}): ${e}\nUse the bash tool via the agent for privileged operations.`};let r,i=!1;try{r=te(e,{encoding:`utf-8`,timeout:3e4,cwd:this.session.workspaceDir,maxBuffer:1024*1024})}catch(e){let t=e;r=t.stderr||t.stdout||t.message||String(e),i=!0}return r=r.trimEnd(),this.session.session.append({role:`system`,subtype:`local_command`,level:i?`error`:`info`,content:r||`(no output)`,timestamp:Date.now()}),{type:`response`,text:r||`(no output)`}}if(t.startsWith(`@`)){let e=t.slice(1).trim();return e?{type:`response`,text:await Et(this.session,`Read and analyze the file: ${e}`,{writer:()=>{}})}:{type:`system`,text:`Usage: @<file-path>`}}if(!t.startsWith(`/`)){let e,n;return{type:`response`,text:await Et(this.session,t,{writer:()=>{},onTurnEnd:(t,r)=>{e=t,n=r}}),endReason:e,notice:n}}let[n,...r]=t.slice(1).split(/\s+/);if(!n){let{showCommandPalette:e}=await import(`@x-otto/tui`),t=await e(this.commandRegistry.list(),process.stdin,process.stdout);if(!t.command)return{type:`noop`};let n=this.commandRegistry.get(t.command);if(!n)return{type:`noop`};let r=await n.execute(t.args,{signal:new AbortController().signal,width:process.stdout.columns??80,models:this.modelList,currentModel:this.currentModelId,onModelChange:this.onModelChange});return this._handleCommandResult(r)}let i=r.join(` `),a=this.commandRegistry.find(n);if(!a)return{type:`system`,text:`Unknown command: /${n}. Try /help.`};let o=await a.execute(i,{signal:new AbortController().signal,width:process.stdout.columns??80,models:this.modelList,currentModel:this.currentModelId,onModelChange:this.onModelChange});return this._handleCommandResult(o)}_handleCommandResult(e){if(typeof e==`string`)return{type:`system`,text:e};switch(e.kind){case`exit`:return{type:`exit`,restart:e.restart};case`help`:return{type:`help`};case`clear`:return this.session.clearTurnPanels(),this.session.clearContext(),process.stdout.write(`\x1B[2J\x1B[H`),{type:`noop`};case`abort`:return this.session.abort(),{type:`system`,text:`Aborted current run.`};case`status`:return{type:`system`,text:`Session: ${this.session.id} | Status: ${this.session.status}`};case`copy`:return{type:`system`,text:`Copy not yet available in CLI mode.`};case`model`:return this.onModelChange?(this.onModelChange(e.modelId).then(e=>{process.stdout.write(e+`
3
- `)}).catch(e=>{process.stdout.write(`Model switch failed: ${e instanceof Error?e.message:String(e)}\n`)}),{type:`system`,text:`Switching to ${e.modelId}...`}):{type:`system`,text:`Model switching not available.`}}}};function kt(){return Ze()}function At(e=`auto`){let t=e===`auto`?Ze():e;return $e(t),t}async function jt(e){try{let t=new AbortController,n=setTimeout(()=>t.abort(),5e3),r=await fetch(`https://registry.npmjs.org/%40x-otto%2Fcli/latest`,{signal:t.signal});if(clearTimeout(n),!r.ok)return null;let i=(await r.json())?.version??``;return i?{latest:i,current:e,newer:Mt(i,e)>0}:null}catch{return null}}function Mt(e,t){let n=Nt(e),r=Nt(t);if(!n||!r)return 0;for(let e=0;e<3;e++)if(n[e]!==r[e])return n[e]-r[e];return 0}function Nt(e){let t=/(\d+)\.(\d+)\.(\d+)/.exec(e);return t?[Number(t[1]),Number(t[2]),Number(t[3])]:null}async function Pt(){return new Promise(e=>{try{let t=x(process.platform===`win32`?`npm.cmd`:`npm`,[`install`,`-g`,`@x-otto/cli@latest`],{stdio:`inherit`,shell:!0});t.on(`error`,t=>{e({ok:!1,error:t.message})}),t.on(`exit`,t=>{if(t!==0){e({ok:!1,error:`npm install exited with code ${t}`});return}e({ok:!0})})}catch(t){e({ok:!1,error:t.message})}})}function Ft(e){return e?Date.now()-e>216e5:!0}async function It(e){let t=process.env.OTTO_UPGRADE_MOCK;if(t){let e=t===`force`;return{latest:e?`2.0.0`:`0.2.0`,current:`0.0.1`,newer:!0,forced:e}}return!e.autoCheck||!Ft(e.lastCheck)?null:jt(e.currentVersion).then(async t=>t&&(e.persistLastCheck().catch(()=>{}),t.newer)?{...t,forced:!1}:null).catch(()=>null)}const Lt=dt;let Rt,zt;function Bt(e){let t=e.map(e=>e.name).sort().join(`,`);if(Rt!==void 0&&zt===t)return Rt;let n=e=>typeof e==`function`?`[fn]`:typeof e==`string`?e:``;return Rt=Lt(JSON.stringify(e.map(e=>({name:e.name,description:n(e.description),parameters:e.parameters})))),zt=t,Rt}let Vt,Ht;function Ut(e){return Vt!==void 0&&Ht===e?Vt:(Vt=Lt(e),Ht=e,Vt)}function Wt(e){let{systemPrompt:t,tools:n,lastIn:r,lastOut:i,lastCacheRead:a,lastCacheWrite:o,contextWindow:s,modelName:c=``,totIn:l=r,totOut:u=i,cost:d,messageCount:f=0,streamingOutputTokens:p=0}=e,m=Ut(t)+Bt(n),h=a+o+r+i+p,g=Math.max(0,h-m),_=Math.max(0,s-m-g),v=ft(ut.trigger,s),ee=ft(lt.trigger,s);return{modelName:c,contextWindow:s,contextPercent:s>0?h/s*100:0,overheadTokens:m,messageTokens:g,messageCount:f,totalUsed:h,free:_,pruneLine:v,compactLine:ee,lastInput:r,lastOutput:i,totalInput:l,totalOutput:u,cost:d,live:p>0}}const Gt={openai:`OpenAI`};function Kt(e){let t=[`confirm`,`auto`,`bypass`];return t[(t.indexOf(e)+1)%t.length]??`confirm`}function qt(e){return e===`error`?`error`:e===`approval_required`||e===`input_required`?`warning`:`info`}function Jt(e,t,n){let r=t===void 0?void 0:{code:t},i=r!==void 0&&_t(r),a=i&&pt(r)===`refresh-failed`;return{authError:i||/\b401\b|authentication|unauthorized|api[\s_-]?key|invalid.*key/i.test(e),isRefreshFailed:a,unsupported:/model_not_supported|not\s+supported|invalid.*model|model.*invalid/i.test(e),rateLimit:/\b429\b|rate.limit|rate_limit|exceed.*rate/i.test(e),pluginSource:n}}function P(e){return e?e.toLowerCase()===`xhigh`?`XHigh`:e.charAt(0).toUpperCase()+e.slice(1):``}function Yt(e,t,n){return e?`${t.on} ${n.on}`:`${t.off} ${n.off}`}function F(e,t,n){if(!t)return`(no model)`;let r=P(n),i=r?`${t}·${r}`:t,a=e.modelRegistry.find(t)?.contextWindow;return a?`${i} (${a>=1e6?`${(a/1e6).toFixed(1)}M`:`${Math.round(a/1e3)}K`})`:i}function Xt(e,t){let n=[...le(t.workspaceDir,t.activePlugins()),...t.computedPluginCommands()];for(let t of n)e.has(t.name)||e.register({name:t.name,description:t.description??`Project command (.claude/.otto)`,aliases:void 0,type:`action`,source:`builtin`,execute:()=>``});return n}function Zt(e){return{id:e.id,type:`function`,function:{name:e.name,arguments:JSON.stringify(e.arguments)}}}function Qt(e){return{type:`thinking`,thinking:e.text}}function $t(e){return{type:`text`,text:e.text}}function en(e){return{type:`a2ui`,version:e.version,components:e.components}}function tn(e){let t=[],n=[];for(let r of e)switch(r.type){case`text`:r.text.trim()&&t.push($t(r));break;case`thinking`:r.text.trim()&&t.push(Qt(r));break;case`tool_call`:n.push(Zt(r));break;case`a2ui`:t.push(en(r));break}return{content:t,toolCalls:n}}function nn(e){return typeof e==`string`?e.trim():e.filter(e=>e.type===`text`).map(e=>e.text).join(``).trim()}function rn(e){if(Object.keys(e).length===0)return;let t=e.command??e.path??e.file_path??e.pattern??e.query;return typeof t==`string`?t:JSON.stringify(e)}function I(e,t){let n=new Map,r=new Set;if(t?.toolCalls)for(let[e,r]of t.toolCalls)n.set(e,r);if(t?.resolvedIds)for(let e of t.resolvedIds)r.add(e);for(let t of e){let e=t;if(e?.role===`assistant`&&Array.isArray(e.content))for(let t of e.content)t.type===`tool_call`&&n.set(t.id,t);else e?.role===`tool_result`&&r.add(e.toolCallId)}let i=[];for(let t of e){let e=t;if(!(!e||typeof e.role!=`string`)&&!e.internal){if(e.role===`user`){let t=nn(e.content);t&&i.push({role:`user`,content:t});continue}if(e.role===`assistant`){let{content:t}=tn(e.content??[]);t.length>0&&i.push({role:`assistant`,content:t});for(let t of e.content??[])t.type===`tool_call`&&!r.has(t.id)&&i.push({role:`tool`,name:t.name,args:rn(t.arguments),argsObj:t.arguments,result:void 0,isError:!1});continue}if(e.role===`tool_result`){let t=n.get(e.toolCallId),r=t?.arguments??{};i.push({role:`tool`,name:e.toolName||t?.name||`tool`,args:rn(r),argsObj:r,result:nn(e.content),isError:e.isError});continue}if(e.role===`system_notification`){let t=e;i.push({role:`tool_completion`,content:t.content,isError:t.isError??!1});continue}if(e.role===`system`){let t=e,n=typeof t.content==`string`?t.content:``;if(t.subtype===`model_switch`){i.push({role:`model_switch`,label:n});continue}if(t.subtype===`effort_switch`){i.push({role:`effort_switch`,label:n});continue}if(t.subtype===`run_paused`||t.subtype===`run_resumed`||t.subtype===`run_pause_cancelled`){i.push({role:t.subtype,label:n});continue}continue}}}return i}const an=vt(b);function on(e,t,n){for(let r of e){if(r.role!==`assistant`)continue;let e=gt(r);for(let r of e){if(r.id!==t)continue;let e=r.arguments;if(n===`edit`)return{oldContent:typeof e.oldContent==`string`?e.oldContent:void 0,newContent:typeof e.newContent==`string`?e.newContent:void 0};if(n===`write`)return{newContent:typeof e.content==`string`?e.content:void 0}}}return{}}function sn(e,t){let n=D(e),r=e=>{let t=S(`git`,[...e],{cwd:n,timeout:5e3,encoding:`utf-8`,maxBuffer:10*1024*1024});return t.status===0?t.stdout:null},i;if(t!==`delete`)try{i=A(e,`utf-8`)}catch{}let a,o=r([`ls-files`,`--full-name`,`--`,e]);if(o&&o.trim()){let e=r([`show`,`HEAD:${o.trim()}`]);e!==null&&(a=e)}return{oldContent:a,newContent:i}}async function cn(e,t){let n=D(e),r=async e=>{try{let{stdout:t}=await an(`git`,[...e],{cwd:n,encoding:`utf-8`,maxBuffer:10485760,signal:AbortSignal.timeout(5e3)});return{ok:!0,stdout:t}}catch{return{ok:!1,stdout:null}}},i;if(t!==`delete`)try{i=await nt(e,`utf-8`)}catch{}let a,o=await r([`ls-files`,`--full-name`,`--`,e]);if(!o.ok)return t===`edit`?{error:`not a git repository (or git unavailable)`,newContent:i}:{oldContent:a,newContent:i};if(o.stdout&&o.stdout.trim()){let e=await r([`show`,`HEAD:${o.stdout.trim()}`]);e.ok&&e.stdout!==null&&(a=e.stdout)}return{oldContent:a,newContent:i}}function ln(e){return[...e].sort((e,t)=>t.savedAt-e.savedAt)}function un(e,t){if(e!=null&&e.trim().length>0)return e.trim();let n=new Set(t.map(e=>e.name)),r=t.length+1,i=`draft-${r}`;for(;n.has(i);)r++,i=`draft-${r}`;return i}function dn(e,t,n){let r=Date.now();return{id:`${r.toString(36)}-${Math.random().toString(36).slice(2,6)}`,name:un(e,n),text:t,savedAt:r}}function fn(e){return e.length<=50?[...e]:e.slice(-50)}function L(e){let t=I(e.session.visibleMessages()),n=e.session.getTurnSummaries();return!n||n.length===0?t:et(t,n,e.session.getTurnCount()??t.filter(e=>e.role===`user`).length)}function pn(e){let{resumedNote:t,isFound:n,session:r,projState:i,tui:a}=e,o=L(r);a.messages.pushMessages(o),n&&o.length>0&&a.info.setTopView({session:r.id}),a.info.showToast(n?M.t(`cmd.titleSessionResumed`):M.t(`cmd.titleSession`),t.replace(/^↻ /,``)),mn({session:r,projState:i,tui:a,chatMsgs:o})}function mn(e){let{session:t,projState:n,tui:r}=e,i=e.chatMsgs??L(t);try{let e=t.session.getTodoList();e&&e.length>0&&!e.every(e=>e.status===`done`||e.status===`skipped`||e.status===`failed`)?(n.todoList=e.map(e=>({id:e.id,title:e.title,status:e.status,turn:e.turn})),r.stores.tasks.setTasks(e.map(e=>({id:e.id??``,title:e.title??``,status:e.status||`pending`,turn:e.turn})),void 0)):e&&e.length>0&&(t.session.setTodoList([]),r.info.showToast(M.t(`cmd.titleSession`),M.t(`cmd.resumeTodosAllDone`)));{let e=t.session.getTurnCount(),a=i.filter(e=>e.role===`user`).length,o=e??a;o>0&&(r.stores.tasks.setTurnBoundaries(Xe(i,o)),n.currentTurn=o)}let a=t.session.getEditedFiles();if(a&&a.length>0){let e=t.session.messages();r.stores.tasks.setEditedFiles(a.map(t=>{let n=t.operation,r=t.toolCallId?on(e,t.toolCallId,n):{};return r.oldContent===void 0&&r.newContent===void 0&&(r=sn(t.path,n)),{path:t.path,operation:n,addedLines:t.addedLines,removedLines:t.removedLines,timestamp:t.timestamp,turnId:t.turnId,toolCallId:t.toolCallId,oldContent:r.oldContent,newContent:r.newContent}}))}let o=t.session.getSubagents();if(o&&o.length>0)for(let e of o)r.plugins.addSubagent({id:e.id,name:e.name,status:e.status,startedAt:e.startedAt});r.stores.tasks.setDrafts(ln(t.session.getDrafts()??[]))}catch(e){console.error(`\x1b[90m\x1b[2m[resume] panel state restore skipped (non-fatal): ${e instanceof Error?e.message:String(e)}\x1b[0m`)}}const R=new Map;function hn(e){return R.get(e)}function z(e){R.delete(e);let t=V.get(e);t&&(clearTimeout(t),V.delete(e))}function gn(){return[...R.values()]}function B(e,t,n){let r={id:e,transcript:I(t),streaming:``,status:n?`busy`:`idle`,lastActivityAt:Date.now()};return R.set(e,r),r}function _n(e,t){let n=R.get(e);n&&(n.transcript=I(t),n.lastActivityAt=Date.now())}const vn=new Set;function yn(e){return vn.add(e),()=>{vn.delete(e)}}const V=new Map;function bn(e){let t=V.get(e.id);t&&clearTimeout(t),V.set(e.id,setTimeout(()=>{V.delete(e.id);for(let t of vn)t(e)},300))}function xn(e,t){let n=``,r=t=>{e.status!==t&&(e.status=t,bn(e))};return[i=>{if(i.type===`stream.event`&&i.event?.type===`text_delta`){n+=i.event.delta,e.streaming=n,e.lastActivityAt=Date.now();return}if(i.type===`prompt.end`){e.streaming=``,n=``,r(`idle`),_n(e.id,t());return}if(i.type===`error`){e.streaming=``,n=``,r(`idle`),e.lastActivityAt=Date.now();return}if(i.type===`approval.required`||i.type===`ask.user.required`){e.status=`needs-input`,e.pendingGate={type:i.type,id:String(i.id??``),data:i.data??{}},e.lastActivityAt=Date.now(),bn(e);return}},()=>e]}function Sn(e){let t=[`session ${e.session.id}`,`status ${e.session.status} · ${e.session.messageCount} messages · cursor ${e.cursor}`,`authority host=${e.authority.hostname} pid=${e.authority.pid}`];if(e.session.messages.length>0){t.push(`recent:`);for(let n of e.session.messages.slice(-3))t.push(` · ${typeof n==`object`&&n&&`role`in n?String(n.role):`message`} … ${JSON.stringify(n).slice(0,120)}`)}else t.push(`(无历史消息)`);return t.join(`
4
- `)}async function Cn(e,t){let n=e.join(` `).trim();if(!n){t.tui.info.showToast(`/session inspect`,"Usage: /session inspect <sessionId> —— peek a session running on `otto serve` (read-only snapshot)");return}let o=i(process.env.OTTO_SERVICE_URL??`http://127.0.0.1:8417`,globalThis.fetch,{token:process.env.OTTO_SERVICE_TOKEN}),s;try{s=await o.fetchSnapshot(n)}catch(e){if(e instanceof r){t.tui.info.showToast(`/session inspect`,`无法连接 otto serve:${e.message} —— 先 \`otto serve\`(或指定 --remote/OTTO_SERVICE_URL)`);return}if(e instanceof a){t.tui.info.showToast(`/session inspect`,`拉取 snapshot 失败:${e.message}`);return}t.tui.info.showToast(`/session inspect`,`查看失败:${e instanceof Error?e.message:String(e)}`);return}t.tui.messages.pushMessage({role:`assistant`,content:[{type:`text`,text:`[session inspect]\n${Sn(s)}`}]}),t.tui.info.showToast(`/session inspect`,`已查看会话 ${s.session.id}(只读快照;如需实时参与该会话请用 otto --attach ${s.session.id})`)}async function wn(e,t){t.state.session.isBusy&&t.tui.info.showToast(`/clear`,`Aborting current task before clearing…`),t.state.todoList=[],t.callbacks.resetCurrentTurn(),t.callbacks.onContextCompacted(),t.state.session.clearTurnPanels(),await t.state.session.clearContext(),t.tui.lifecycle.clearSession();let n=t.state.session.model;n&&t.tui.stores.tasks.setModelName(F(t.app,n.id,t.state.session.thinkingLevel));let r=n?.contextWindow??2e5,i=Wt({systemPrompt:t.state.session.systemPrompt,tools:t.state.session.tools,lastIn:0,lastOut:0,lastCacheRead:0,lastCacheWrite:0,contextWindow:r,modelName:n?.name??``,totIn:0,totOut:0});t.tui.stores.budget.setBudget(i),t.tui.stores.context.setBudget(i),t.tui.info.showToast(M.t(`cmd.titleCleared`),M.t(`cmd.clearedDone`))}async function Tn(e,t){let n=e.join(` `).replace(/\s+/g,` `).trim();if(!n){t.tui.info.showToast(`/rename`,`Usage: /rename <new title>`);return}t.state.session.renameSession(n),t.tui.lifecycle.setTerminalTitle(n),t.tui.stores.tasks.setSessionTitle(n),t.tui.info.showToast(`✎`,n)}async function En(e,t){let n,r,i=!1;for(let t=0;t<e.length;t++)e[t]===`--workspace`&&t+1<e.length?r=e[++t]:e[t]===`--archived`?i=!0:e[t].startsWith(`--`)||(n=e[t]);let a=r?{workspaceId:r}:void 0,o=await t.app.listAllSessions(a),s=o.filter(e=>e.status===`archived`).length,c=n?o:o.filter(e=>i?e.status===`archived`:e.status!==`archived`).filter(e=>(e.entryCount??e.messageCount)>0),l=(e,t,n)=>e.tui.info.showToast(t,n),u=async e=>{if(e===t.state.session.id){l(t,M.t(`cmd.titleResume`),M.t(`cmd.resumeAlreadyOn`));return}let n=t.app.getSession(e)??await t.app.sessionManager.restore(e);if(!n){l(t,M.t(`cmd.titleResume`),M.t(`cmd.resumeSessionNotFound`,{idShort:e.slice(0,8)}));return}let r=t.state.session;if(t.state.session.isBusy){let[e]=xn(B(r.id,r.session.messages(),!0),()=>r.session.messages()),n=t.state.session.subscribe(t=>{e(t),(t.type===`prompt.end`||t.type===`error`)&&n()})}else B(r.id,r.session.messages(),!1);await t.callbacks.pasteBinder?.switchTo(r.id,n.id),t.callbacks.sessionUnsub?.(),t.state.session=n,t.state.interactive=new Ot(n,{models:t.state.models,currentModel:n.model?.id,onModelChange:t.callbacks.applyModel}),t.state.reg=t.state.interactive.getRegistry(),t.callbacks.registerAllTuiCommands(),t.state.slashCommands=t.callbacks.refreshSlashCommands(),t.tui.plugins.setCommands(t.state.slashCommands),t.callbacks.attachSessionHandler();let i=n.model?.id;i?(t.state.currentModelId=i,t.state.modelReady=!0,t.tui.stores.tasks.setModelName(F(t.app,i,t.state.session.thinkingLevel))):(t.state.currentModelId=void 0,t.state.modelReady=!1,t.tui.stores.tasks.setModelName(`(no model)`)),t.tui.lifecycle.clearSession();let a=hn(n.id);if(a)t.tui.messages.pushMessages(a.transcript),z(n.id);else{let e=L(n);t.tui.messages.pushMessages(e)}t.callbacks.restoreSwitchedSession(),t.tui.info.setTopView({session:n.id}),l(t,M.t(`cmd.titleResume`),M.t(`cmd.resumeSwitched`,{idShort:e.slice(0,8),count:n.session.messages().length}))};if(n){let e=c.find(e=>e.id===n);if(e){await u(e.id);return}let r=c.find(e=>e.id.startsWith(n));if(r){await u(r.id);return}let i=c.find(e=>e.id.includes(n));if(i){await u(i.id);return}l(t,M.t(`cmd.titleResume`),M.t(`cmd.sessionNoMatch`,{arg:n}));return}if(c.length===0){l(t,M.t(`cmd.titleResume`),M.t(`cmd.resumeNoSaved`));return}let d=t.state.session.id,f=c.some(e=>e.pinned);function p(e){if(!e.pinned)return`￿`;let t=e.pinGroup?.trim();return t?`\u0001${t.toLowerCase()}`:`\0`}let m=[...c].sort((e,t)=>{let n=p(e).localeCompare(p(t));if(n!==0)return n;let r=e.updatedAt?.getTime()??e.createdAt.getTime();return(t.updatedAt?.getTime()??t.createdAt.getTime())-r});function h(e){if(f)return e.pinned?e.pinGroup?.trim()||M.t(`cmd.resumeDefaultPinGroup`):M.t(`cmd.resumeRecentGroup`)}function g(e){if(!e)return``;let t=Math.max(0,Math.floor((Date.now()-e.getTime())/1e3));return t<10?M.t(`cmd.agoJustNow`):t<60?M.t(`cmd.agoSeconds`,{n:t}):t<3600?M.t(`cmd.agoMinutes`,{n:Math.floor(t/60)}):t<86400?M.t(`cmd.agoHours`,{n:Math.floor(t/3600)}):M.t(`cmd.agoDays`,{n:Math.floor(t/86400)})}let _=c[0]?.updatedAt?g(c[0].updatedAt):`—`,v=c.reduce((e,t)=>e+(t.messageCount??0),0),ee=r?` [workspace: ${r}]`:``,y=[!i&&s>0?M.t(`cmd.resumeArchivedHiddenHint`,{count:s}):``].filter(Boolean),b=y.length>0?` ${y.join(` `)}`:``,te=new Map(gn().map(e=>[e.id,e])),x=0,S=0,ne=e=>{if(e.id===d)return``;let n=te.get(e.id);return n?n.status===`busy`?(x++,`● ${M.t(`cmd.resumeStatusBusy`)} · `):n.status===`needs-input`?(S++,`● ${M.t(`cmd.resumeStatusNeedsInput`)} · `):`· ${M.t(`cmd.resumeStatusIdle`)} · `:t.app.getSession(e.id)?.isBusy?(x++,`● ${M.t(`cmd.resumeStatusBusy`)} · `):``},C=[x>0?`${x} ${M.t(`cmd.resumeStatusBusy`)}`:``,S>0?`${S} ${M.t(`cmd.resumeStatusNeedsInput`)}`:``].filter(Boolean).join(`, `),w=C?` · ${C}`:``,T=M.t(`cmd.resumeSubtitle`,{sessions:c.length,msgs:v,recent:_})+w+b,re=i?M.t(`cmd.resumeArchivedOnlyTitle`,{n:c.length}):M.t(`cmd.resumeSelectTitle`,{n:c.length});t.tui.modal.openModal({kind:`select`,title:re+ee,subtitle:T,searchable:!0,maxVisible:13,options:m.map(e=>{let t=e.id===d?`●`:` `,n=e.pinned?M.t(`cmd.resumePinnedPrefix`):``,r=e.title||e.id.slice(0,8),i=e.status===`archived`?M.t(`cmd.resumeArchivedSuffix`):``,a=e.writeLocked?M.t(`cmd.resumeReadOnlySuffix`):``,o=`${n}${r}${i}`,s=g(e.updatedAt),c=[ne(e).trim(),s,M.t(`welcome.msgCountLabel`,{count:e.messageCount??0}),a.trim()].filter(Boolean);return{label:`${t} ${o}`,trailingLabel:c.join(` · `),value:e.id,searchText:o,group:h(e)}}),detailPlacement:`inline`,onSelect:e=>{u(e).catch(e=>l(t,M.t(`cmd.titleResume`),M.t(`cmd.resumeFailed`,{msg:e instanceof Error?e.message:String(e)})))},onCancel:()=>{}})}async function Dn(e,t){t.app.reloadCapabilities().then(e=>{t.tui.plugins.setPluginRegistrations(t.app.getPluginRegistrations()),t.tui.info.showToast(M.t(`cmd.titleReload`),M.t(`cmd.reloadDone`,{mcpTools:e.mcpTools,models:e.models,agents:e.agents,teams:e.teams}))},e=>t.tui.messages.pushMessage({role:`command_echo`,command:`/reload`,status:`error`,summary:M.t(`cmd.reloadFailed`,{msg:e instanceof Error?e.message:String(e)})}))}async function On(e,t){let n=t.app.diagnoser.propose();if(n.length===0){t.tui.info.showToast(M.t(`cmd.titleDiagnose`),M.t(`cmd.diagnoseNone`));return}let r=n.map((e,t)=>M.t(`cmd.diagnoseLine`,{n:t+1,signalKind:e.evidence.signalKind,count:e.evidence.count,directive:e.directive}));t.tui.messages.pushMessage({role:`command_echo`,command:`/diagnose`,status:`warn`,summary:M.t(`cmd.diagnoseSummary`,{count:n.length}),detail:r.join(`
5
- `)})}async function kn(e,t){let n=e[0];if(n){let e=t.app.listSessions(),r=e.find(e=>e.id===n)??e.find(e=>e.id.startsWith(n))??e.find(e=>e.id.includes(n));if(!r){t.tui.info.showToast(M.t(`cmd.titleArchive`),M.t(`cmd.sessionNoMatch`,{arg:n}));return}if(r.status===`archived`){let e=t.app.getSession(r.id);if(!e){t.tui.info.showToast(M.t(`cmd.titleUnarchive`),M.t(`cmd.unarchiveNotLoaded`,{idShort:r.id.slice(0,8)}));return}e.unarchive(),t.tui.info.showToast(M.t(`cmd.titleUnarchive`),M.t(`cmd.unarchiveDone`,{idShort:r.id.slice(0,8),title:r.title??``}));return}if(!await t.app.archiveSession(r.id)){t.tui.info.showToast(M.t(`cmd.titleArchive`),M.t(`cmd.archiveCannot`,{idShort:r.id.slice(0,8)}));return}t.tui.info.showToast(M.t(`cmd.titleArchive`),M.t(`cmd.archiveDone`,{idShort:r.id.slice(0,8),title:r.title??``}));return}let r=t.state.session;if(r.status===`archived`){r.unarchive(),t.tui.info.showToast(M.t(`cmd.titleUnarchive`),M.t(`cmd.unarchiveDone`,{idShort:r.id.slice(0,8),title:r.title??``}));return}r.archive(),t.tui.info.showToast(M.t(`cmd.titleArchive`),M.t(`cmd.archiveDone`,{idShort:r.id.slice(0,8),title:r.title??``}))}async function An(e,t){let n,r=[];for(let i=0;i<e.length;i++)if(e[i]===`--group`){let r=e[i+1];if(r===void 0||r.startsWith(`--`)){t.tui.info.showToast(M.t(`cmd.titlePin`),M.t(`cmd.pinGroupMissingValue`));return}n=r,i++}else r.push(e[i]);if(r.length===0&&n===void 0){let e=t.state.session;e.pinned?(e.unpin(),t.tui.info.showToast(M.t(`cmd.titleUnpin`),M.t(`cmd.unpinDone`,{idShort:e.id.slice(0,8),title:e.title??``}))):(e.pin(),t.tui.info.showToast(M.t(`cmd.titlePin`),M.t(`cmd.pinDone`,{idShort:e.id.slice(0,8),title:e.title??``}))),H(t);return}if(r.length===0){jn(t.state.session.id,n,t),H(t);return}if(r.length===1){jn(r[0],n,t),H(t);return}let i=t.app.listSessions(),a=0,o=[];for(let e of r){let r=i.find(t=>t.id===e)??i.find(t=>t.id.startsWith(e))??i.find(t=>t.id.includes(e));if(!r){o.push(e.slice(0,8));continue}let s=t.app.getSession(r.id);if(!s){o.push(r.id.slice(0,8));continue}s.pin(n),a++}t.tui.info.showToast(M.t(`cmd.titlePin`),M.t(`cmd.pinBatchSummary`,{seg:o.length>0?`${a} pinned (${o.length} not found: ${o.join(`, `)})`:`${a} pinned`})),H(t)}function H(e){let t=e.callbacks.refreshSlashCommands();e.tui.plugins.setCommands(t)}function jn(e,t,n){if(e===n.state.session.id){Mn(n.state.session,t,n);return}let r=n.app.listSessions(),i=r.find(t=>t.id===e)??r.find(t=>t.id.startsWith(e))??r.find(t=>t.id.includes(e));if(!i){n.tui.info.showToast(M.t(`cmd.titlePin`),M.t(`cmd.sessionNoMatch`,{arg:e}));return}let a=n.app.getSession(i.id);if(!a){n.tui.info.showToast(M.t(`cmd.titlePin`),M.t(`cmd.pinNotLoaded`,{idShort:i.id.slice(0,8)}));return}Mn(a,t,n)}function Mn(e,t,n){let r=e.id.slice(0,8),i=e.title??``;if(e.pinned){if(t===void 0||(e.pinGroup??``).toLowerCase()===t.toLowerCase()){e.unpin(),n.tui.info.showToast(M.t(`cmd.titleUnpin`),M.t(`cmd.unpinDone`,{idShort:r,title:i}));return}e.pin(t),n.tui.info.showToast(M.t(`cmd.titlePin`),M.t(`cmd.pinGroupDone`,{idShort:r,title:i,group:t}));return}e.pin(t),t===void 0?n.tui.info.showToast(M.t(`cmd.titlePin`),M.t(`cmd.pinDone`,{idShort:r,title:i})):n.tui.info.showToast(M.t(`cmd.titlePin`),M.t(`cmd.pinGroupDone`,{idShort:r,title:i,group:t}))}async function Nn(e,t){let n=e[0];if(n===`fork`){await Pn(e.slice(1),t);return}if(n===`kill`){await zn(e.slice(1),t);return}if(n===`inspect`){await Cn(e.slice(1),t);return}if(n!==`unlock`){t.tui.info.showToast(M.t(`cmd.titleSessionCmd`),`Usage: /session fork | /session unlock <id> [--force] | /session kill <id> | /session inspect <id>`);return}let r=e.slice(1),i=r.includes(`--force`),a=r.find(e=>e!==`--force`);if(!a){t.tui.info.showToast(M.t(`cmd.titleSessionUnlock`),M.t(`cmd.unlockUsage`));return}let o=t.app.sessionManager.inspectSessionWriteLease(a),s=a.slice(0,8);if(!o.locked){t.tui.info.showToast(M.t(`cmd.titleSessionUnlock`),M.t(`cmd.unlockNotLocked`,{idShort:s}));return}let c=o.alive===!0?M.t(`cmd.unlockAliveConfirmed`):o.alive===!1?M.t(`cmd.unlockDeadConfirmed`):M.t(`cmd.unlockUnknownAlive`),l=Math.round((o.mtimeAgoMs??0)/1e3);if(!i){t.tui.messages.pushMessage({role:`command_echo`,command:`/session unlock`,summary:M.t(`cmd.unlockInspect`,{idShort:s,pid:o.pid,hostname:o.hostname,aliveLabel:c,mtimeAgoSec:l})});return}if(o.alive===!0){o.mtimeAgoMs!==void 0&&o.mtimeAgoMs>6e4&&t.tui.messages.pushMessage({role:`command_echo`,command:`/session unlock --force`,status:`warn`,summary:M.t(`cmd.unlockHungWarning`,{idShort:s})}),t.tui.modal.openModal({kind:`confirm`,title:M.t(`cmd.unlockConfirmTitle`),message:M.t(`cmd.unlockConfirmMessage`,{idShort:s,pid:o.pid,hostname:o.hostname}),confirmLabel:M.t(`cmd.unlockConfirmLabel`),cancelLabel:M.t(`cmd.unlockCancelLabel`),dangerous:!0,onConfirm:()=>{t.app.sessionManager.forceReleaseSessionWriteLease(a),t.tui.info.showToast(M.t(`cmd.titleSessionUnlock`),M.t(`cmd.unlockForcedDone`,{idShort:s}))},onCancel:()=>{t.tui.info.showToast(M.t(`cmd.titleSessionUnlock`),M.t(`cmd.unlockCancelled`))}});return}(o.mtimeAgoMs??0)<5e3&&t.tui.messages.pushMessage({role:`command_echo`,command:`/session unlock --force`,status:`warn`,summary:M.t(`cmd.unlockRecentReleaseHint`,{idShort:s})}),t.app.sessionManager.forceReleaseSessionWriteLease(a),t.tui.info.showToast(M.t(`cmd.titleSessionUnlock`),M.t(`cmd.unlockForcedDone`,{idShort:s}))}async function Pn(e,t){let n=t.state.session.id,r=await t.app.sessionManager.forkSession(n);if(!r){t.tui.info.showToast(M.t(`cmd.titleSessionFork`),M.t(`cmd.forkFailed`));return}let i=t.state.session;if(t.state.session.isBusy){let[e]=xn(B(i.id,i.session.messages(),!0),()=>i.session.messages()),n=t.state.session.subscribe(t=>{e(t),(t.type===`prompt.end`||t.type===`error`)&&n()})}else B(i.id,i.session.messages(),!1);t.callbacks.sessionUnsub?.(),t.state.session=r,t.state.interactive=new Ot(r,{models:t.state.models,currentModel:r.model?.id,onModelChange:t.callbacks.applyModel}),t.state.reg=t.state.interactive.getRegistry(),t.callbacks.registerAllTuiCommands(),t.state.slashCommands=t.callbacks.refreshSlashCommands(),t.tui.plugins.setCommands(t.state.slashCommands),t.callbacks.attachSessionHandler();let a=r.model?.id;a?(t.state.currentModelId=a,t.state.modelReady=!0,t.tui.stores.tasks.setModelName(F(t.app,a,t.state.session.thinkingLevel))):(t.state.currentModelId=void 0,t.state.modelReady=!1,t.tui.stores.tasks.setModelName(`(no model)`)),t.tui.lifecycle.clearSession();let o=L(r);t.tui.messages.pushMessages(o),t.callbacks.restoreSwitchedSession(),t.tui.info.setTopView({session:r.id}),t.tui.info.showToast(M.t(`cmd.titleSessionFork`),M.t(`cmd.forkSuccess`,{idShort:r.id.slice(0,8)}))}async function Fn(e,t){let n=e[0],r=e[1];if(!n||!r){t.tui.info.showToast(`a2ui`,`Usage: /a2ui-action <componentId> <action> [payload-json]`);return}let i;if(e[2])try{i=JSON.parse(e.slice(2).join(` `))}catch{t.tui.info.showToast(`a2ui`,`Invalid JSON payload`);return}let a=t.state.session;a.session.emit({type:`a2ui.action`,sessionId:a.id,componentId:n,action:r,payload:i});let o=`[a2ui action] component="${n}" action="${r}"${i?` payload=${JSON.stringify(i)}`:``}`;a.session.prompt(o).catch(e=>{t.tui.info.showToast(`a2ui`,`Action failed: ${e instanceof Error?e.message:String(e)}`)})}async function In(e,t){let n=90,r=e.indexOf(`--ttl-days`);if(r>=0&&r+1<e.length){let t=parseInt(e[r+1],10);!isNaN(t)&&t>0&&(n=t)}let i=e.find(e=>e.startsWith(`--ttl-days=`));if(i){let e=parseInt(i.split(`=`)[1],10);!isNaN(e)&&e>0&&(n=e)}let a=e.includes(`--apply`),o=t.app.sessionStorageDir;if(!o){t.tui.info.showToast(`trace-gc`,`当前后端不支持 trace 文件管理(非本地磁盘存储)`);return}let s=await t.app.listAllSessions(),c=Date.now()-n*24*60*60*1e3,l=s.filter(e=>!((e.updatedAt?e.updatedAt.getTime():0)>=c||e.status===`archived`||e.pinned)),u=O(o,`trace`),d=[];for(let e of l){let t=O(u,`${encodeURIComponent(e.id)}.jsonl`);try{let n=await it(t);d.push({session:e,path:t,size:n.size})}catch{}}if(!a){if(d.length===0){t.tui.info.showToast(`trace-gc`,`TTL ${n} 天:没有符合条件的 trace 文件`);return}let e=d.reduce((e,t)=>e+t.size,0),r=`TTL: ${n} 天 | 候选会话: ${d.length} | 预估回收: ${Ln(e)}`,i=[`会话 ID 大小 最后活跃 标题`,...d.map(e=>` ${e.session.id.slice(0,8)} ${Ln(e.size).padStart(9)} ${e.session.updatedAt?e.session.updatedAt.toISOString().slice(0,10):`未知`} ${(e.session.title??``).slice(0,60)}`),``,`TTL 基于会话最后一次持久化活动时间(agent 引擎产生新内容的时间),`,`可能与你最后一次查看/交互该会话的时间不同。`,``,`添加 --apply 参数以实际删除这些 trace 文件。`];t.tui.messages.pushMessage({role:`command_echo`,command:`/trace-gc --dry-run`,summary:r,detail:i.join(`
6
- `)});return}if(d.length===0){t.tui.info.showToast(`trace-gc`,`TTL ${n} 天:没有需要清理的 trace 文件`);return}let f=0,p=0,m=[];for(let e of d)try{await at(e.path),f++,p+=e.size}catch(t){m.push(`${e.session.id.slice(0,8)}: ${t instanceof Error?t.message:String(t)}`)}let h=`已清理 ${f}/${d.length} 个会话的 trace 文件,回收 ${Ln(p)}`;f>0?t.tui.info.showToast(`trace-gc`,h+(m.length>0?`\n失败:${m.join(`; `)}`:``)):m.length>0&&t.tui.messages.pushMessage({role:`command_echo`,command:`/trace-gc --apply`,status:`error`,summary:h,detail:`失败:${m.join(`; `)}`})}function Ln(e){return e>=1073741824?`${(e/1073741824).toFixed(1)} GB`:e>=1048576?`${(e/1048576).toFixed(1)} MB`:e>=1024?`${(e/1024).toFixed(1)} KB`:`${e} B`}async function Rn(e,t){let n=e[0];if(!n||n.startsWith(`--`)){t.tui.info.showToast(`archive-export`,`用法: /session-archive-export <sessionId> [--out <path>] [--and-delete]`);return}let r=e.includes(`--and-delete`),i,a=e.indexOf(`--out`);if(a>=0&&a+1<e.length){let t=e[a+1];t.startsWith(`--`)||(i=t)}let o=(await t.app.listAllSessions()).find(e=>e.id.startsWith(n)&&e.status!==`archived`);if(!o){t.tui.info.showToast(`archive-export`,`找不到 ID 前缀为 "${n}" 的活跃会话`);return}let s=o.id,c=s.slice(0,8),l=o.title??c,u=t.app.sessionStorageDir;if(!i&&!u){t.tui.info.showToast(`archive-export`,`当前后端不支持自动选择导出路径,请提供 --out <path>`);return}let d=i??O(u,`archives`,`${s}.json`),f;try{f=await t.app.exportSessionArchive(s,d)}catch(e){let n=e instanceof Error?e.message:String(e);t.tui.messages.pushMessage({role:`command_echo`,command:`/session-archive-export`,status:`error`,summary:`导出失败:${n}`});return}if(!r){t.tui.info.showToast(`archive-export`,`已导出 ${l}(${f.entryCount} entries, sha256=${f.checksum.slice(0,12)})→ ${f.path}`);return}let p=t.app.sessionManager.inspectSessionWriteLease(s);if(p.locked&&p.alive!==!1){let e=p.alive===!0?`(确认存活)`:`(无法判断存活)`,n=p.pid==null?``:`(pid=${p.pid},hostname=${p.hostname??`?`}${e})`;t.tui.messages.pushMessage({role:`command_echo`,command:`/session-archive-export --and-delete`,status:`error`,summary:`会话 ${c} 仍被其他 otto 进程占用${n},无法归档删除`,detail:`仅导出请去掉 --and-delete。`});return}t.tui.modal.openModal({kind:`confirm`,title:`确认删除会话`,message:`确认删除会话「${l}」(${c})?此操作不可逆,且会同步清理 trace/checkpoint。`,confirmLabel:`确认删除`,cancelLabel:`取消`,dangerous:!0,onConfirm:async()=>{try{await t.app.removeSession(s),t.tui.info.showToast(`archive-export`,`已归档并删除 ${l}(${f.entryCount} entries)→ ${f.path}`)}catch(e){let n=e instanceof Error?e.message:String(e);t.tui.messages.pushMessage({role:`command_echo`,command:`/session-archive-export --and-delete`,status:`error`,summary:`删除失败:${n}`,detail:`导出文件仍保存于 ${f.path}`})}},onCancel:()=>{t.tui.info.showToast(`archive-export`,`已取消删除。导出文件仍保存于 ${f.path}`)}})}async function zn(e,t){let n=e[0];if(!n){t.tui.info.showToast(`session kill`,`Usage: /session kill <session-id>`);return}let r=t.app.listSessions(),i=r.find(e=>e.id===n)??r.find(e=>e.id.startsWith(n))??r.find(e=>e.id.includes(n));if(!i){t.tui.info.showToast(`session kill`,M.t(`cmd.sessionNoMatch`,{arg:n}));return}if(i.id===t.state.session.id){t.tui.info.showToast(`session kill`,`Cannot kill the current foreground session. /resume to another session first.`);return}let a=t.app.getSession(i.id);if(!a){z(i.id),t.tui.info.showToast(`session kill`,`Removed stale session ${i.id.slice(0,8)} from background.`);return}a.abort(),z(i.id),await t.app.removeSession(i.id),t.tui.info.showToast(`session kill`,`Killed session ${i.id.slice(0,8)}${i.title?` (${i.title})`:``}.`)}async function Bn(e,t){let n=t.state.session.id,r=t.state.session.session.metadata().title?.trim()||n.slice(0,8),i=await t.app.sessionManager.forkSession(n);if(!i){t.tui.info.showToast(M.t(`cmd.titleSessionFork`),M.t(`cmd.forkFailed`));return}let a=`${r} (fork)`,o=(await t.tui.modal.openModal({kind:`input`,title:M.t(`cmd.forkNameTitle`),placeholder:a,defaultValue:a})??``).trim()||a;i.renameSession(o);let s=t.state.session;if(t.state.session.isBusy){let[e]=xn(B(s.id,s.session.messages(),!0),()=>s.session.messages()),n=t.state.session.subscribe(t=>{e(t),(t.type===`prompt.end`||t.type===`error`)&&n()})}else B(s.id,s.session.messages(),!1);await t.callbacks.pasteBinder?.fork(s.id,i.id),t.callbacks.sessionUnsub?.(),t.state.session=i,t.state.interactive=new Ot(i,{models:t.state.models,currentModel:i.model?.id,onModelChange:t.callbacks.applyModel}),t.state.reg=t.state.interactive.getRegistry(),t.callbacks.registerAllTuiCommands(),t.state.slashCommands=t.callbacks.refreshSlashCommands(),t.tui.plugins.setCommands(t.state.slashCommands),t.callbacks.attachSessionHandler();let c=i.model?.id;c?(t.state.currentModelId=c,t.state.modelReady=!0,t.tui.stores.tasks.setModelName(F(t.app,c,t.state.session.thinkingLevel))):(t.state.currentModelId=void 0,t.state.modelReady=!1,t.tui.stores.tasks.setModelName(`(no model)`)),t.tui.lifecycle.clearSession();let l=L(i);t.tui.messages.pushMessages(l),t.callbacks.restoreSwitchedSession(),t.tui.info.setTopView({session:i.id}),t.tui.stores.tasks.setSessionTitle(o),t.tui.lifecycle.setTerminalTitle(o),t.tui.info.showToast(M.t(`cmd.titleSessionFork`),M.t(`cmd.forkSuccessNamed`,{title:o}))}function Vn(e){switch(e){case`global`:return M.t(`cmd.scopeGlobal`);case`repository`:return M.t(`cmd.scopeRepository`);default:return M.t(`cmd.scopeProject`)}}function Hn(e,t,n){return{workspaceDir:e.app.workspaceDir,workspaceRoot:t===`repository`?me(e.app.workspaceDir):void 0,global:t===`global`,dryRun:n}}async function Un(e){let{name:t,type:n,scope:r,ctx:i,onDone:a}=e,o=i.app.settings.get(`mcp_servers`),s=await je(t,n,Hn(i,r,!0),()=>o,async()=>{});if(!s.success){i.tui.info.showToast(M.t(`cmd.titleUninstall`),M.t(`cmd.uninstallFailed`,{err:s.error??M.t(`cmd.unknownError`)})),a?.();return}let c=s.plan??[];i.tui.modal.openModal({kind:`confirm`,title:M.t(`cmd.uninstallConfirmTitle`,{type:n,name:t}),message:[M.t(`cmd.uninstallConfirmScope`,{scopeLabel:Vn(r)}),...c].join(`
7
- `),confirmLabel:M.t(`cmd.uninstallConfirmYes`),dangerous:!0,onConfirm:()=>{Wn(e)},onCancel:()=>a?.()})}async function Wn(e){let{name:t,type:n,scope:r,ctx:i,onDone:a}=e,o=i.app.settings.get(`mcp_servers`),s=await je(t,n,Hn(i,r,!1),()=>o,async e=>{await i.app.settings.persist({mcp_servers:e})});if(!s.success){i.tui.info.showToast(M.t(`cmd.titleUninstall`),M.t(`cmd.uninstallFailed`,{err:s.error??M.t(`cmd.unknownError`)})),a?.();return}i.tui.info.showToast(M.t(`cmd.titleUninstall`),M.t(`cmd.uninstalled`,{type:n,name:t,scope:Vn(r)})),n===`plugin`&&await Ce(i.app.settings,t);try{await i.app.reloadCapabilities(),i.tui.plugins.setPluginRegistrations(i.app.getPluginRegistrations()),n===`plugin`&&i.app.pluginModuleManager.emitMonitorEvent({type:`plugin.uninstalled`,pluginId:t}),i.tui.info.showToast(M.t(`cmd.titleUninstall`),M.t(`cmd.uninstallRefreshed`))}catch(e){i.tui.messages.pushMessage({role:`command_echo`,command:`/extension`,status:`error`,summary:M.t(`cmd.uninstalledRefreshErr`,{err:e instanceof Error?e.message:String(e)})})}a?.()}async function Gn(e,t){let n=t.app.settings.get(`keybinding_overrides`),r=()=>{t.tui.info.showToast(M.t(`cmd.keybindTitle`),M.t(`cmd.keybindSavedRestartHint`))};t.tui.modal.openModal({kind:`keybindingPanel`,overrides:n,onSave:(e,n,i)=>{let a=t.app.settings.get(`keybinding_overrides`)??{};t.app.settings.persist({keybinding_overrides:{...a,[e]:n}},i),r()},onSaveReplace:(e,n)=>{let i={...t.app.settings.get(`keybinding_overrides`)??{}};for(let t of e)i[t.commandId]=t.predicate;t.app.settings.persist({keybinding_overrides:i},n),r()},onReset:e=>{let n=t.app.settings.get(`keybinding_overrides`);if(!n||!(e in n))return;let{[e]:i,...a}=n;t.app.settings.persist({keybinding_overrides:a}),r()},onResetAll:()=>{t.app.settings.persist({keybinding_overrides:{}}),r()}})}function U(e,t,n){let r={ts:Date.now(),sessionId:e.sessionId,...e.turn===void 0?{}:{turn:e.turn},kind:`lifecycle`,node:t,payload:n};e.traceStore.append(e.sessionId,r).catch(()=>{})}function Kn(e,t,n){let{tui:r,session:i,traceStore:a}=e,o=t===`model`?`model_switch`:`effort_switch`,s=t===`model`?`model.switch`:`effort.change`;r.messages.pushMessage({role:o,label:n.label}),i.session.append({role:`system`,subtype:o,content:n.label,level:`info`,timestamp:Date.now()});let c=i.session.getTurnCount(),l={ts:Date.now(),sessionId:i.id,...c===void 0?{}:{turn:c},kind:`lifecycle`,node:s,payload:{from:n.from??null,to:n.to,label:n.label}};a.append(i.id,l).catch(()=>{})}function qn(e,t){Kn(e,`model`,t)}function Jn(e,t){Kn(e,`effort`,t)}function Yn(e,t){U(e,`retry.queued`,{attempt:t.attempt,max:t.max,...t.mode===void 0?{}:{mode:t.mode},...t.reason===void 0?{}:{reason:t.reason}})}function Xn(e,t){U(e,`retry.cancelled`,{attempt:t.attempt})}function Zn(e){U(e,`retry.reset`,{})}function Qn(e,t,n){U(e,`pause.${t}`,{...n===void 0?{}:{source:n}})}const $n=(e,t,n)=>{let r=P(n),i=r?`${e}·${r}`:e;return t?`${i} (${t>=1e6?`${(t/1e6).toFixed(1)}M`:`${Math.round(t/1e3)}K`})`:i},W=[`low`,`medium`,`high`,`xhigh`,`max`];function er(e,t){return[t,...e.filter(e=>e!==t)].slice(0,5)}function tr(e){let t=/\[@model:((?:\\\]|[^\]])+)\]/g,n=[];return{text:e.replace(t,(e,t)=>(n.push(t.replace(/\\\]/g,`]`)),``)).replace(/\n{3,}/g,`
8
-
9
- `).trim(),modelIds:n}}async function nr(e,t){let n=tr(e),r=n.modelIds.at(-1);if(r&&r!==t.currentModelId){let e=await t.applyModel(r);e.includes(`not in registry`)&&t.onSwitchFailed?.(e)}return n.text}function rr(e){let t=/\[@effort:((?:\\\]|[^\]])+)\]/g,n=[];return{text:e.replace(t,(e,t)=>(n.push(t.replace(/\\\]/g,`]`)),``)).replace(/\n{3,}/g,`
10
-
11
- `).trim(),levels:n}}function ir(e,t){let n=rr(e),r=n.levels.at(-1);return r&&(W.includes(r)?r!==t.currentEffort&&t.applyEffort(r):t.onInvalidLevel?.(r)),n.text}function ar(e){let{modelReady:t,currentModelId:n,contextWindow:r,tuiRef:i,pushBudgetNow:a,app:o,getSession:s,options:c,fmtDisplayModel:l,onEngineModelAction:u}=e;return async(e,d)=>{let f=s(),p=f.model?.id;c.value&&(c.value.model=e),n.value=e;let m=o.modelRegistry.find(e);if(m&&m.id===`__otto_setup__`)return`Model "${e}" is a setup placeholder — pick a real model with /model first.`;if(d?.persist!==!1)try{let t={model:e},n=o.settings.get(`model_slots`);n&&(t.model_slots={...n,default:e}),m&&(t.recent_models=er(o.settings.get(`recent_models`)??[],e)),await o.settings.persist(t)}catch{}if(m){if(f.model=m,t.value=!0,e!==p&&(o.syncSessionToolsFor(f.id),qn({tui:i.value??{messages:{pushMessage:()=>{}}},session:f,traceStore:o.storage.traceStore},{from:p,to:m.id,label:$n(m.id,m.contextWindow,f.thinkingLevel)})),m.api.includes(`:`)&&o.firePluginActivationEvent?.(`onProvider:${m.api}`),u?.({kind:`setModel`,modelId:e}),i.value?.stores.tasks.setModelName($n(m.id,m.contextWindow,f.thinkingLevel)),i.value?.engine.pushEngineEvent({kind:`maxOutputTokens`,n:m.maxOutputTokens}),o.authStore?.getAuthSource?o.authStore.getAuthSource(m.provider).then(e=>{e!==`oauth`&&i.value?.stores.notification.setProviderUsage(null)}).catch(()=>{i.value?.stores.notification.setProviderUsage(null)}):i.value?.stores.notification.setProviderUsage(null),e!==p&&o.storage.memory?.reconfigure){o.storage.memory.reconfigure({contextWindow:m.contextWindow,maxOutput:m.maxOutputTokens});try{let e=f.session.buildContext(),t=await o.storage.memory.ensureFitsWindow?.(e.messages,f.id);if(t?.compacted&&t.summary&&t.replacement){f.session.recordCompaction(t.summary,t.replacement),u?.({kind:`recordCompaction`,summary:t.summary,replacement:t.replacement});let e=m.contextWindow>=1e6?`${(m.contextWindow/1e6).toFixed(1)}M`:`${Math.round(m.contextWindow/1e3)}k`;i.value?.info.showToast(M.t(`cmd.titleModel`),M.t(`cmd.modelCompactedFor`,{window:e}))}}catch(e){console.error(`\x1b[3m\x1b[2m[model-switch] compaction skipped: ${e instanceof Error?e.message:String(e)}\x1b[0m`)}}return r.value=m.contextWindow,a.value?.(),e!==p&&!d?.silent&&i.value?.info.showToast(M.t(`cmd.titleModel`),M.t(`model.switchedTo`,{label:l(e)})),`Model → ${e} (active next turn).`}return f.model&&(i.value?.stores.tasks.setModelName($n(f.model.id,f.model.contextWindow,f.thinkingLevel)),i.value?.engine.pushEngineEvent({kind:`maxOutputTokens`,n:f.model.maxOutputTokens})),`Model "${e}" not in registry — switch NOT applied (still ${f.model?.id??`unset`}). Check the id or /auth the provider.`}}function or(e){let{getSession:t,app:n,tuiRef:r,options:i,fmtDisplayModel:a,applyModel:o}=e,s=!1,c=N(n.authStore,`delegation`),l=N(n.authStore,`main-session`);return async()=>{if(s)return;s=!0;let u=t().model;if(!u)return;let d=async e=>{try{return(await c(e)).usable}catch{return!1}},f=async e=>{try{return(await l(e)).usable}catch{return!1}},p=i.value?.model??n.settings.get(`model`);if(typeof p!=`string`||!p)return;let m=n.modelRegistry.find(p);if(m&&await f(m)){m.id!==u.id&&await o(m.id);return}let h=m?M.t(`model.reasonUnauthenticated`,{provider:m.provider}):M.t(`model.reasonNotFound`),g=u;if(!await f(u)){let e=n.modelRegistry.getAll().filter(e=>e.id!==`__otto_setup__`),t;for(let n of e)if(await d(n)){t=n;break}t??=e[0],t&&(g=t)}let _=g.id;r.value?.modal.openModal({kind:`confirm`,title:M.t(`model.title`),message:[`${a(p)} → ${a(g.id)}`,``,h,``,M.t(`model.hint`)],confirmLabel:M.t(`model.permanent`),extraLabel:M.t(`model.login`),cancelLabel:M.t(`model.dismiss`),onConfirm:()=>{o(_,{persist:!0})},onExtra:()=>{e.onLogin&&m?.provider?e.onLogin(m.provider):r.value?.info.showToast(M.t(`model.login`),M.t(`model.fallbackLoginToast`,{provider:m?.provider??``}))},onCancel:()=>{e.onExitSession?.()}})}}function sr(e){let t=e=>e.replace(/]/g,`\\]`),n=()=>{e.pluginInput.unregisterBySource(`extensions`);let n=e.extensions.list().filter(e=>e.category===`agent`||e.category===`skill`||e.category===`mcp`).map(e=>({label:`@${e.name}`,value:`[@${e.category}:${t(e.name)}]`,description:e.description||e.category,kind:e.category,source:`extensions`}));n.length&&e.pluginInput.register(n)};return n(),{refreshSigilExtensions:n}}function cr(e){let t=e.trim().split(`
12
- `)[0].replace(/\s+/g,` `).trim();return t.length>40?`${t.slice(0,39)}…`:t}function lr(e){e.pluginInput.unregisterBySource(`shortcut`);let t=(e.settings.get(`shortcuts`)??[]).map(e=>({label:`@${e.name}`,value:`[@shortcut:${e.name.replace(/]/g,`\\]`)}]`,description:cr(e.text),kind:`shortcut`,source:`shortcut`}));t.length&&e.pluginInput.register(t)}function ur(e,t){let n=e.modelRegistry.getAll();if(n.length===0)return;let r=e=>e>=1e6?`${(e/1e6).toFixed(1)}M`:e>=1e3?`${Math.round(e/1e3)}k`:``,i=n.filter(e=>t.has(e.id)).sort((e,t)=>e.name.localeCompare(t.name)).map(e=>{let t=r(e.contextWindow),n=[];e.strengths&&e.strengths.length>0&&n.push(...e.strengths),t&&n.push(t);let i=n.length>0?`${e.provider} · ${n.join(` · `)}`:e.provider;return{label:e.name,value:`[@model:${e.id.replace(/]/g,`\\]`)}]`,description:i,kind:`model`,source:`builtin`}});e.pluginInput.unregisterBySource(`builtin-model`),e.pluginInput.register(i)}const dr={low:`cmd.effortDescLow`,medium:`cmd.effortDescMedium`,high:`cmd.effortDescHigh`,xhigh:`cmd.effortDescXhigh`,max:`cmd.effortDescMax`};function fr(e){let t=W.map(e=>({label:P(e),value:`[@effort:${e}]`,description:M.t(dr[e]??`cmd.effortDescLow`),kind:`effort`,source:`builtin-effort`}));e.pluginInput.unregisterBySource(`builtin-effort`),e.pluginInput.register(t)}async function pr(e,t){t.tui.modal.openModal({kind:`shortcutsPanel`,shortcuts:t.app.getShortcuts(),onSave:(e,n,r)=>{t.app.saveShortcut(e,n,r).then(()=>lr(t.app)).catch(e=>{t.tui.info.showToast(`Shortcuts`,`Save failed: ${e instanceof Error?e.message:String(e)}`)})},onDelete:e=>{t.app.deleteShortcut(e).then(()=>lr(t.app)).catch(e=>{t.tui.info.showToast(`Shortcuts`,`Delete failed: ${e instanceof Error?e.message:String(e)}`)})}})}const mr={low:{label:`Low`,desc:`节约 Token,快速响应`,intensity:.2},medium:{label:`Medium`,desc:`平衡速度与推理质量`,intensity:.4},high:{label:`High`,desc:`深度推理,延迟较高`,intensity:.6},xhigh:{label:`XHigh`,desc:`更长推理链,更全面思考`,intensity:.8},max:{label:`Max`,desc:`全力推理,最慢但最深入`,intensity:1}};function hr(e){let t=Math.round(e*8);return`━`.repeat(Math.max(0,t))+`╌`.repeat(Math.max(0,8-t))}async function gr(e,t){let n=e[0]?.toLowerCase();if(n&&W.includes(n)){_r(t,n);return}if(n){t.tui.info.showToast(M.t(`cmd.titleEffort`),M.t(`cmd.effortUnknown`,{arg:n,levels:W.join(` / `)}));return}let r=t.state.session.thinkingLevel;t.tui.modal.openModal({kind:`select`,title:M.t(`cmd.selectEffortTitle`),options:W.map(e=>{let t=mr[e],n=e===r,i=hr(t.intensity);return{label:t.label,value:e,detail:`${i} ${t.desc}${n?` · 当前`:``}`}}),onSelect:e=>_r(t,e),onCancel:()=>{}})}function _r(e,t){let n=e.state.session,r=n.thinkingLevel;n.thinkingLevel=t,e.app.settings.persist({thinking_level:t}),r!==t&&Jn({tui:e.tui,session:n,traceStore:e.app.storage.traceStore},{from:r,to:t,label:P(t)}),n.model?.id&&e.tui.stores.tasks.setModelName(F(e.app,n.model.id,t)),e.tui.info.showToast(M.t(`cmd.titleEffort`),t)}async function G(e,t){let n=e[0]?.toLowerCase();if(n===`general`||n===`gen`){K(t);return}if(n===`lang`||n===`language`){kr(e.slice(1),t);return}if(n===`theme`){Ar(e.slice(1),t);return}if(n===`keybindings`||n===`kb`){Gn(e.slice(1),t);return}if(n===`shortcuts`){pr(e.slice(1),t);return}if(n===`effort`){gr(e.slice(1),t);return}if(n===`proxy`){s(e.slice(1),t);return}if(n){t.tui.info.showToast(M.t(`cmd.titlePreference`),M.t(`cmd.preferenceUsage`));return}vr(t)}function vr(e,t){let n=e.app.settings,r=n.get(`language`),i=r===`zh`?`中文 (zh)`:r===`en`?`English (en)`:`Auto`,a=e.state.themeRegistry??Je(),o=n.get(`theme_preset`)??{},c=a.get(o.dark??`dark`)?.label??o.dark??`dark`;e.tui.modal.openModal({kind:`select`,title:M.t(`cmd.titlePreference`),detailPlacement:`inline`,options:[{label:M.t(`cmd.prefOptionGeneral`),value:`general`,detail:M.t(`cmd.prefDescGeneral`)},{label:M.t(`cmd.prefOptionLang`),trailingLabel:i,value:`lang`,detail:M.t(`cmd.prefDescLang`)},{label:M.t(`cmd.prefOptionTheme`),trailingLabel:c,value:`theme`,detail:M.t(`cmd.prefDescTheme`)},{label:`Keybindings`,value:`keybindings`,detail:`Browse, search, remap, reset shortcuts`},{label:`Shortcuts`,value:`shortcuts`,detail:`Manage custom @ text shortcuts`},{label:`Effort`,value:`effort`,detail:`Switch reasoning effort (low|medium|high|xhigh|max)`},{label:`Proxy`,value:`proxy`,detail:`Configure HTTP proxy`}],defaultSelectedValue:t,onSelect:t=>{t===`general`?K(e):t===`lang`?kr([],e):t===`theme`?Ar([],e):t===`keybindings`?Gn([],e):t===`shortcuts`?pr([],e):t===`effort`?gr([],e):t===`proxy`&&s([],e)},onCancel:()=>{}})}let yr;function K(e,t,n,r){let i=e.app.settings,a=i.get(`notification`),o=i.get(`nickname`)??``,s=a?.on_completion!==!1,c=a?.sound===!0,l=i.get(`auto_update_check`)!==!1,u=i.get(`skill_loop`)?.enabled===!0,d=e.app.activePlugins().some(e=>e.id===C),f={on:j.toggleOn,off:j.toggleOff},p={on:M.t(`cmd.toggleOn`),off:M.t(`cmd.toggleOff`)},m=e=>Yt(e,f,p);e.tui.modal.openModal({kind:`select`,title:M.t(`cmd.selectGeneralTitle`),detailPlacement:`inline`,subtitle:t,replace:r,options:[{label:M.t(`cmd.genNickname`),trailingLabel:o||`—`,value:`nickname`,detail:M.t(`cmd.genNicknameDesc`)},{label:M.t(`cmd.genCompletionNotice`),trailingLabel:m(s),value:`completion`,detail:M.t(`cmd.genCompletionNoticeDesc`)},{label:M.t(`cmd.genSound`),trailingLabel:m(c),value:`sound`,detail:M.t(`cmd.genSoundDesc`)},{label:M.t(`cmd.genUpdateCheck`),trailingLabel:m(l),value:`updateCheck`,detail:M.t(`cmd.genUpdateCheckDesc`)},{label:M.t(`cmd.genSkillLoop`),trailingLabel:d?m(u):M.t(`cmd.genSkillLoopMissing`),value:`skillLoopPanel`,detail:M.t(`cmd.genSkillLoopEntryDesc`)}],defaultSelectedValue:n??yr,onHighlight:e=>{yr=e},onSelect:t=>{if(t===`nickname`){br(e);return}if(t===`skillLoopPanel`){q(e);return}Or(e,t)},onCancel:()=>{vr(e,`general`)}})}async function br(e){let t=await e.tui.modal.openModal({kind:`input`,title:M.t(`cmd.genNicknameInputTitle`),placeholder:M.t(`cmd.genNicknamePlaceholder`)});if(t==null){K(e);return}let n=t.trim();await e.app.settings.persist({nickname:n}),K(e,M.t(`cmd.genSaved`))}const xr=[4,6,12,20];function Sr(e){let t=typeof e==`number`?e:6,n=xr.includes(t)?`genSkillLoopThr${t}`:``;return n?M.t(`cmd.${n}`):String(t)}function Cr(e){let t=e.app.settings,n=t.get(`skill_loop`)?.min_messages??6;e.tui.modal.openModal({kind:`select`,title:M.t(`cmd.genSkillLoopThresholdTitle`),detailPlacement:`inline`,options:xr.map(e=>({label:M.t(`cmd.genSkillLoopThr${e}`),value:String(e),detail:M.t(`cmd.genSkillLoopThr${e}Desc`),trailingLabel:e===n?j.toggleOn:void 0})),onSelect:n=>{(async()=>{let r={...t.get(`skill_loop`)??{}};r.min_messages=Number(n),await t.persist({skill_loop:r}),q(e,M.t(`cmd.genSaved`),`threshold`)})()},onCancel:()=>{q(e,void 0,`threshold`)}})}const wr=[3,14,30,365];function Tr(e){let t=typeof e==`number`?e:14;return wr.includes(t)?M.t(`cmd.genSkillLoopCd${t}`):M.t(`cmd.genSkillLoopCdDays`,{n:t})}function Er(e){let t=e.app.settings,n=t.get(`skill_loop`)?.dismiss_cooldown_days??14;e.tui.modal.openModal({kind:`select`,title:M.t(`cmd.genSkillLoopCooldownTitle`),detailPlacement:`inline`,options:wr.map(e=>({label:M.t(`cmd.genSkillLoopCd${e}`),value:String(e),detail:M.t(`cmd.genSkillLoopCd${e}Desc`),trailingLabel:e===n?j.toggleOn:void 0})),onSelect:n=>{(async()=>{let r={...t.get(`skill_loop`)??{}};r.dismiss_cooldown_days=Number(n),await t.persist({skill_loop:r}),q(e,M.t(`cmd.genSaved`),`cooldown`)})()},onCancel:()=>{q(e,void 0,`cooldown`)}})}function q(e,t,n){let r=e.app.settings,i=r.get(`skill_loop`)?.enabled===!0,a=e.app.activePlugins().some(e=>e.id===C),o={on:j.toggleOn,off:j.toggleOff},s={on:M.t(`cmd.toggleOn`),off:M.t(`cmd.toggleOff`)};if(!a){e.tui.modal.openModal({kind:`select`,title:M.t(`cmd.skillLoopPanelTitle`),detailPlacement:`inline`,subtitle:M.t(`cmd.genSkillLoopMissingHint`),options:[{label:M.t(`cmd.genSkillLoopMissing`),value:`noop`,detail:``}],onSelect:()=>{K(e,void 0,`skillLoopPanel`)},onCancel:()=>{K(e,void 0,`skillLoopPanel`)}});return}e.tui.modal.openModal({kind:`select`,title:M.t(`cmd.skillLoopPanelTitle`),detailPlacement:`inline`,subtitle:t,defaultSelectedValue:n,options:[{label:M.t(`cmd.skillLoopOnOff`),trailingLabel:Yt(i,o,s),value:`toggle`,detail:M.t(`cmd.genSkillLoopEntryDesc`)},...i?[{label:M.t(`cmd.genSkillLoopThreshold`),trailingLabel:Sr(r.get(`skill_loop`)?.min_messages),value:`threshold`,detail:M.t(`cmd.genSkillLoopThresholdDesc`)},{label:M.t(`cmd.genSkillLoopCooldown`),trailingLabel:Tr(r.get(`skill_loop`)?.dismiss_cooldown_days),value:`cooldown`,detail:M.t(`cmd.genSkillLoopCooldownDesc`)},{label:M.t(`cmd.genSkillLoopStatus`),value:`status`,detail:M.t(`cmd.genSkillLoopStatusDesc`)}]:[]],onSelect:t=>{if(t===`threshold`){Cr(e);return}if(t===`cooldown`){Er(e);return}if(t===`status`){Dr(e);return}(async()=>{let t={...r.get(`skill_loop`)??{}},n=t.enabled!==!0;t.enabled=n,await r.persist({skill_loop:t}),q(e,n?M.t(`cmd.genSkillLoopOn`):M.t(`cmd.genSkillLoopOff`),`toggle`)})()},onCancel:()=>{K(e,void 0,`skillLoopPanel`)}})}function Dr(e){let t=e.app.settings,n=e.app.activePlugins().some(e=>e.id===C),r=xe({workspaceKey:e.app.workspaceRef?.key??ne,now:Date.now(),cooldownDays:t.get(`skill_loop`)?.dismiss_cooldown_days,pluginInstalled:n}),i=e=>M.t(`cmd.skillLoopStatusCount`,{n:e}),a=[];if(!n)a.push({label:M.t(`cmd.skillLoopStatusNotInstalled`),value:`noop`,detail:M.t(`cmd.genSkillLoopMissingHint`)});else{a.push({label:M.t(`cmd.skillLoopStatusEpisodes`),trailingLabel:i(r.episodeCount),value:`noop`,detail:M.t(`cmd.skillLoopStatusSuccess`)+` `+i(r.successCount)},{label:M.t(`cmd.skillLoopStatusPending`),trailingLabel:i(r.pendingCount),value:`noop`,detail:i(r.candidateCount)+` `+M.t(`cmd.skillLoopStatusCandidates`)+` · `+i(r.coolingCount)+` `+M.t(`cmd.skillLoopStatusCooling`)});for(let e of r.pending)a.push({label:e.taskSignature,trailingLabel:M.t(`cmd.skillLoopStatusTimes`,{n:e.size}),value:`noop`,detail:M.t(`cmd.skillLoopStatusGroupPending`)});for(let e of r.recentSignatures)a.push({label:e,value:`noop`,detail:M.t(`cmd.skillLoopStatusGroupRecent`)})}let o=r.episodeCount===0?`cmd.skillLoopStatusEmpty`:{"no-episodes":`cmd.skillLoopStatusHintNoEpisodes`,"not-enough-successes":`cmd.skillLoopStatusHintNotEnough`,"no-cluster-yet":`cmd.skillLoopStatusHintNoCluster`}[r.nextProposalHint??``]??``;e.tui.modal.openModal({kind:`select`,title:M.t(`cmd.skillLoopStatusTitle`),detailPlacement:`inline`,subtitle:o?M.t(o):void 0,options:a,onSelect:()=>{q(e,void 0,`status`)},onCancel:()=>{q(e,void 0,`status`)}})}async function Or(e,t){let n=e.app.settings;if(t===`updateCheck`){let r=n.get(`auto_update_check`)!==!1;await n.persist({auto_update_check:!r}),K(e,M.t(`cmd.genSaved`),t,!0);return}let r={...n.get(`notification`)??{}};t===`completion`?r.on_completion=r.on_completion===!1:t===`sound`&&(r.sound=r.sound!==!0),await n.persist({notification:r}),K(e,M.t(`cmd.genSaved`),t,!0)}function kr(e,t){let n=e[0]?.toLowerCase();if(n===`en`||n===`zh`||n===`auto`){Nr(t,n);return}if(n){t.tui.info.showToast(M.t(`cmd.titlePreference`),M.t(`pref.languageUsage`));return}t.tui.modal.openModal({kind:`select`,title:M.t(`cmd.selectLanguageTitle`),detailPlacement:`inline`,options:[{label:`中文 (zh)`,value:`zh`,detail:M.t(`cmd.langDescZh`)},{label:`English (en)`,value:`en`,detail:M.t(`cmd.langDescEn`)},{label:`Auto`,value:`auto`,detail:M.t(`cmd.langDescAuto`)}],onSelect:e=>Nr(t,e),onCancel:()=>{vr(t,`lang`)}})}function Ar(e,t){jr(t)}function jr(e){let t=e.state.themeRegistry??Je(),n=e.app.settings.get(`theme_preset`)??{},r=t.get(n.dark??`dark`)??t.get(`dark`),i=t.get(n.light??`light`)??t.get(`light`);e.tui.modal.openModal({kind:`select`,title:M.t(`cmd.prefOptionTheme`),detailPlacement:`inline`,options:[{label:M.t(`cmd.themeDarkPresetOption`),value:`preset-dark`,detail:M.t(`cmd.themeDarkPresetDesc`),trailingLabel:r?.label},{label:M.t(`cmd.themeLightPresetOption`),value:`preset-light`,detail:M.t(`cmd.themeLightPresetDesc`),trailingLabel:i?.label}],onSelect:t=>{if(t===`preset-dark`){Mr(e,`dark`);return}if(t===`preset-light`){Mr(e,`light`);return}},onCancel:()=>{vr(e,`theme`)}})}function Mr(e,t){let n=e.state.themeRegistry??Je(),r=e.app.settings.get(`theme_preset`)??{},i=r[t]??t,a=[...n.list().filter(e=>e.appearance===t).map(e=>({label:e.label,value:e.id,detail:e.source.kind===`builtin`?M.t(`cmd.themePresetBuiltin`):M.t(`cmd.themePresetFromExtension`,{id:e.source.extensionId}),trailingLabel:e.id===i?`✓`:void 0})),{label:M.t(`cmd.themePresetReset`),value:`__reset__`,detail:M.t(`cmd.themePresetResetDesc`)}],o=n=>{let i={...r};n===void 0?delete i[t]:i[t]=n,e.tui.lifecycle.setPresetSelection?.(i)},s=()=>{e.tui.lifecycle.setPresetSelection?.(r)};e.tui.modal.openModal({kind:`select`,title:t===`dark`?M.t(`cmd.themePresetTitleDark`):M.t(`cmd.themePresetTitleLight`),options:a,onHighlight:e=>{o(e===`__reset__`?void 0:e)},onSelect:i=>{let a=i===`__reset__`?void 0:i,o={...r};a===void 0?delete o[t]:o[t]=a,e.tui.lifecycle.setPresetSelection?.(o),e.app.settings.persist({theme_preset:o},`global`);let s=a===void 0?t===`dark`?n.get(`dark`)?.label:n.get(`light`)?.label:n.get(a)?.label;e.tui.info.showToast(M.t(`cmd.titlePreference`),M.t(`cmd.themePresetSaved`,{label:s??a??t}))},onCancel:()=>{s(),e.tui.info.showToast(M.t(`cmd.titlePreference`),M.t(`cmd.selectCancelled`))}})}function Nr(e,t){e.state.currentLang=e.tui.lifecycle.setLanguage(t),At(t),e.tui.plugins.setCommands(e.callbacks.refreshSlashCommands()),e.app.settings.persist({language:t}),e.tui.info.showToast(M.t(`cmd.titleLanguage`),M.t(`pref.languageSwitched`,{l:e.state.currentLang,name:e.state.currentLang===`zh`?`中文`:`English`}))}async function Pr(e,t){let r=t.app.workspaceDir??process.cwd(),i=e[0]?.toLowerCase()??`status`;if(i===`plugin`){let i=e[1]?.toLowerCase()===`untrust`,a=i?e[2]:e[1];if(!a){t.tui.info.showToast(M.t(`cmd.titlePlugin`),M.t(`cmd.pluginUsage`,{seg:(i?`untrust`:`trust`)==`untrust`?`untrust `:``}));return}let o=n({cwd:r,homedir:_()}).find(e=>e.id===a);if(!o){t.tui.info.showToast(M.t(`cmd.titlePlugin`),M.t(`cmd.pluginNotFound`,{id:a}));return}if(i){try{Me(o.dir)}catch(e){t.tui.info.showToast(M.t(`cmd.titlePlugin`),`撤销信任失败,权限未收回:${e instanceof Error?e.message:String(e)}`);return}t.tui.info.showToast(M.t(`cmd.titlePlugin`),M.t(`cmd.pluginUntrusted`,{id:a}))}else Xr(t,o);return}if(i===`trust`){Ae(r),t.tui.info.showToast(M.t(`cmd.titleCompat`),M.t(`cmd.compatTrusting`)),t.app.reloadCapabilities().then(e=>{t.tui.plugins.setPluginRegistrations(t.app.getPluginRegistrations()),t.tui.info.showToast(M.t(`cmd.titleCompat`),M.t(`cmd.compatTrusted`,{count:e.mcpTools}))},e=>t.tui.info.showToast(M.t(`cmd.titleCompat`),M.t(`cmd.compatReloadFailed`,{err:e instanceof Error?e.message:String(e)})));return}if(i===`untrust`){Ne(r),t.tui.info.showToast(M.t(`cmd.titleCompat`),M.t(`cmd.compatUntrusted`));return}let a=fe(r),o=ce(r,{interactive:!0}),s=[];if(a.surface.any){let e=[a.surface.mcpJson?`.mcp.json`:null,a.surface.commands?`.claude/commands`:null].filter(Boolean),t=a.trusted?M.t(`cmd.compatTrustedLabel`):M.t(`cmd.compatUntrustedLabel`);s.push(`${e.join(M.t(`cmd.listSep`))} ${t}`)}if(o.highRiskKeys.length>0){let e=o.highRiskKeys.join(M.t(`cmd.listSep`));s.push(o.gated?M.t(`cmd.compatConfigGated`,{keys:e}):M.t(`cmd.compatConfigActive`,{keys:e}))}let c=n({cwd:r,homedir:_()}).filter(e=>e.scope===`project`||e.scope===`repository`);for(let e of c){let t=pe(e);if(!t.surface.any)continue;let n=t.gated?M.t(`cmd.compatUntrustedLabel`):M.t(`cmd.compatTrustedLabel`);s.push(`plugin:${e.id} ${n}${t.gated?` → /trust plugin ${e.id}`:``}`)}if(s.length===0){t.tui.info.showToast(M.t(`cmd.titleCompat`),M.t(`cmd.compatNone`));return}o.gated?t.tui.modal.openModal({kind:`info`,title:M.t(`cmd.titleCompat`),lines:s}):t.tui.info.showToast(M.t(`cmd.titleCompat`),s.join(`
13
- `))}async function Fr(e,t){let n=e[0];if(n===`clear`){t.app.clearSessionAlwaysAllow(t.state.session.id),t.tui.info.showToast(M.t(`cmd.titlePermissions`),M.t(`cmd.permsCleared`));return}if(n===`add`||n===`remove`){let r=e.slice(1).join(` `).trim();if(!r){t.tui.info.showToast(M.t(`cmd.titlePermissions`),M.t(`cmd.permsManageHint`));return}if(n===`add`){if(!t.app.isWellFormedAllowEntry(r)){t.tui.info.showToast(M.t(`cmd.titlePermissions`),M.t(`cmd.permsInvalidEntry`,{entry:r}));return}await t.app.allowToolAlways(r),t.tui.info.showToast(M.t(`cmd.titlePermissions`),M.t(`cmd.permsAdded`,{entry:r}))}else{let e=await t.app.disallowToolAlways(r);t.tui.info.showToast(M.t(`cmd.titlePermissions`),e?M.t(`cmd.permsRemoved`,{entry:r}):M.t(`cmd.permsNotFound`,{entry:r}))}return}let r=t.app.getSessionAlwaysAllow(t.state.session.id),i=t.app.settings.get(`permission_always_allow`)??[],a=(e,t)=>`${e} ${t.length?t.join(`, `):M.t(`cmd.permsEmpty`)}`;t.tui.modal.openModal({kind:`permissions`,lines:[a(M.t(`cmd.permsSessionLabel`),r),a(M.t(`cmd.permsProjectLabel`),i),``,M.t(`cmd.permsClearHint`),M.t(`cmd.permsManageHint`)]})}async function Ir(e,n){let r=t();n.tui.info.showToast(M.t(`cmd.titleUpgrade`),M.t(`cmd.upgradeChecking`,{current:r}));let i=await jt(r);if(!i){n.tui.modal.openModal({kind:`info`,title:M.t(`cmd.titleUpgrade`),lines:[M.t(`cmd.upgradeNoNetwork`)]});return}if(!i.newer){n.tui.info.showToast(M.t(`cmd.titleUpgrade`),M.t(`cmd.upgradeLatest`,{current:r}));return}n.tui.modal.openModal({kind:`info`,title:M.t(`cmd.titleUpgrade`),lines:M.t(`cmd.upgradeAvailableLines`,{returnObjects:!0,current:r,latest:i.latest})})}async function Lr(e,t){if(!e.includes(`--force`))return!1;t.tui.info.showToast(M.t(`cmd.titleUpgrade`),M.t(`cmd.upgrading`));let{ok:n,error:r}=await Pt();return n?(t.state.restartRequested=!0,t.tui.lifecycle.stop(),!0):(t.tui.info.showToast(M.t(`cmd.titleUpgrade`),M.t(`cmd.upgradeFailed`,{err:r??M.t(`cmd.unknownError`)})),!0)}async function Rr(e,t,n){let r=M.t(`cmdDesc`,{returnObjects:!0}),i={session:M.t(`cmd.helpGroupSession`),model:M.t(`cmd.helpGroupModel`),agent:M.t(`cmd.helpGroupAgent`),debug:M.t(`cmd.helpGroupDebug`),ui:M.t(`cmd.helpGroupUi`),other:M.t(`cmd.helpGroupOther`)},a=[];for(let e of za){let t=n.filter(t=>t.group===e&&!t.tuiHidden);if(t.length!==0)for(let n of t){let t=n.aliases?.length?[n.name,...n.aliases].map(e=>`/${e}`).join(`, `):`/${n.name}`;a.push({label:t,value:n.name,detail:r[n.name]??n.description??void 0,group:i[e],searchText:[n.name,...n.aliases??[]].join(` `)})}}let o=`${M.t(`cmd.helpPrefixes`)} !<cmd> ${M.t(`cmd.helpPrefixShell`)} · @<file> ${M.t(`cmd.helpPrefixFile`)}`;t.tui.modal.openModal({kind:`select`,title:M.t(`cmd.titleCommands`),subtitle:o,searchable:!0,options:a,onSelect:e=>{Ua(e,[],t)},onCancel:()=>{}})}async function zr(e,t){t.tui.panes.togglePane(`history`)}async function Br(e,t){t.tui.panes.togglePane(`notifications`)}async function Vr(e,t){t.tui.panes.togglePane(`prompts`)}async function Hr(e,t){t.tui.panes.setServices(!0)}async function Ur(e,t){t.tui.info.showToast(M.t(`cmd.titleUpgrade`),M.t(`cmd.upgradeCheckScanning`));try{let e=Oe({workspaceDir:t.app.workspaceDir,workspaceRoot:me(t.app.workspaceDir),scope:`all`});if(e.length===0){t.tui.info.showToast(M.t(`cmd.titleUpgrade`),M.t(`cmd.upgradeCheckNoVersioned`));return}let n=await ae(e),r=[],i=0;for(let e of n){let t=`[${e.type}]`;e.error?r.push(`${t} ${e.name} v${e.installed} — ${e.error}`):e.newer?(i++,r.push(M.t(`cmd.upgradeCheckLineUpdate`,{tag:t,name:e.name,installed:e.installed,latest:e.latest??``}))):r.push(M.t(`cmd.upgradeCheckLineLatest`,{tag:t,name:e.name,installed:e.installed}))}i>0&&(r.push(``),r.push(M.t(`cmd.upgradeCheckSummary`,{count:i}))),t.tui.modal.openModal({kind:`info`,title:M.t(`cmd.titleUpgradeCheck`),lines:r})}catch(e){t.tui.info.showToast(M.t(`cmd.titleUpgrade`),M.t(`cmd.upgradeCheckFailed`,{err:e instanceof Error?e.message:String(e)}))}}var Wr=bt({confirmHighRiskCapabilities:()=>Zr,formatPluginContributionsSummary:()=>Jr,handleDelegatesToggle:()=>$r,handleExtension:()=>J,handleJobStart:()=>ei,pluginCapabilityLabel:()=>Yr,promptPluginTrust:()=>Xr,runPluginInstall:()=>Qr});function Gr(e){return!e.endsWith(O(`.claude`,`skills`))}function Kr(e,t){return Gr(t)?e===`project`?`project`:e===`global`?`global`:null:null}function qr(e,t){let n={project:`project`,global:`global`,plugin:`plugin`,inline:`inline`}[e]??e;return t?`${n} (${t})`:n}function Jr(e){let t=[];return e.providerApis>0&&t.push(`provider(${e.providerApis})`),e.tools>0&&t.push(`tools(${e.tools})`),e.renderers>0&&t.push(`renderers(${e.renderers})`),e.statusItems>0&&t.push(`statusItems(${e.statusItems})`),e.fileViewers&&e.fileViewers>0&&t.push(`fileViewers(${e.fileViewers})`),t.length?t.join(`, `):void 0}function Yr(e){switch(e){case`provider`:return M.t(`cmd.pluginCapabilityProvider`);case`tools`:return M.t(`cmd.pluginCapabilityTools`);case`tui.renderer`:return M.t(`cmd.pluginCapabilityTuiRenderer`);case`network`:return M.t(`cmd.pluginCapabilityNetwork`);case`wire-protocol`:return M.t(`cmd.pluginCapabilityWireProtocol`);case`a2ui.component`:return M.t(`cmd.pluginCapabilityA2uiComponent`);case`panel.backend`:return M.t(`cmd.pluginCapabilityPanelBackend`);case`input.resolver`:return M.t(`cmd.pluginCapabilityInputResolver`);case`a2ui.renderer`:return M.t(`cmd.pluginCapabilityA2uiRenderer`);default:return}}function Xr(e,t){let n=pe(t),r=n.pendingCapabilities,i=()=>{ke(t.dir),r.length>0&&he(t.dir,r),e.tui.info.showToast(M.t(`cmd.titlePlugin`),M.t(`cmd.pluginTrusting`,{id:t.id})),e.app.reloadCapabilities().then(n=>{e.tui.plugins.setPluginRegistrations(e.app.getPluginRegistrations()),e.tui.info.showToast(M.t(`cmd.titlePlugin`),M.t(`cmd.pluginTrusted`,{id:t.id,count:n.mcpTools}))},t=>e.tui.info.showToast(M.t(`cmd.titlePlugin`),M.t(`cmd.compatReloadFailed`,{err:t instanceof Error?t.message:String(t)})))},a=n.surface;if(!a.any&&r.length===0){i();return}let o=[M.t(`cmd.pluginTrustConfirmIntro`)];if(a.mcpJson&&o.push(`• ${M.t(`cmd.pluginSurfaceMcp`)}`),a.commands&&o.push(`• ${M.t(`cmd.pluginSurfaceCommands`)}`),a.scripts&&o.push(`• ${M.t(`cmd.pluginSurfaceScripts`)}`),a.panels&&o.push(`• ${M.t(`cmd.pluginSurfacePanels`)}`),a.skills&&o.push(`• ${M.t(`cmd.pluginSurfaceSkills`)}`),a.agents&&o.push(`• ${M.t(`cmd.pluginSurfaceAgents`)}`),r.length>0){o.push(``,M.t(`cmd.pluginCapabilityIntro`));for(let e of r){let t=Yr(e);t&&o.push(`• ${t}`)}}o.push(``,M.t(`cmd.pluginTrustConfirmHint`)),e.tui.modal.openModal({kind:`select`,title:M.t(`cmd.pluginTrustConfirmTitle`,{id:t.id}),subtitle:o.join(`
14
- `),layout:`buttons`,options:[{label:M.t(`cmd.pluginTrustConfirmAction`),value:`trust`,color:`accent`},{label:M.t(`cmd.commonCancel`),value:`cancel`,color:`gray`}],onSelect:e=>{e===`trust`&&i()},onCancel:()=>{}})}async function Zr(e,t,n){if(t.length===0)return!0;let r=[M.t(`cmd.pluginCapabilityIntro`)];for(let e of t){let t=Yr(e);t&&r.push(`• ${t}`)}return new Promise(t=>{n.tui.modal.openModal({kind:`select`,title:M.t(`cmd.pluginInstallConfirmTitle`,{name:e}),subtitle:r.join(`
15
- `),layout:`buttons`,options:[{label:M.t(`cmd.pluginInstallConfirmAction`),value:`install`,color:`accent`},{label:M.t(`cmd.commonCancel`),value:`cancel`,color:`gray`}],onSelect:e=>t(e===`install`),onCancel:()=>t(!1)})})}async function Qr(e,t,n){let r=n?.autoTrust??!1,i=n?.onProgress,a=n?.onPendingCapabilities;if(e.includes(`..`)||e.startsWith(`/`)||e.startsWith(`./`)||e.startsWith(`~/`))return r||t.tui.info.showToast(M.t(`cmd.titleInstall`),M.t(`cmd.pluginInstallInvalidName`,{name:e})),!1;let s=o[e]?.pkg??e,c=Te(s),l;if(!c)try{i?.(`Downloading from npm registry`);let e=await new w().install(s,{global:!0,as:`plugin`,postInstallExecutor:se});e.success&&e.targetPath?(c=e.targetPath,l={id:e.name??s,dir:e.targetPath,created:!0,compileWarnings:[],version:e.manifest?.version}):r||t.tui.info.showToast(M.t(`cmd.titleInstall`),M.t(`cmd.pluginInstallFailed`,{err:e.error??`未知错误`}))}catch(e){r||t.tui.info.showToast(M.t(`cmd.titleInstall`),M.t(`cmd.pluginInstallFailed`,{err:e instanceof Error?e.message:String(e)}))}if(!c)return r||t.tui.info.showToast(M.t(`cmd.titleInstall`),M.t(`cmd.pluginInstallNotFound`,{pkg:s})),!1;let u=ye(c);if(!r&&!await Zr(e,u,t))return t.tui.info.showToast(M.t(`cmd.titleInstall`),M.t(`cmd.pluginInstallCancelled`)),!1;let d;if(l)d=l;else try{i?.(`Installing plugin`),d=await ge({pkg:s})}catch(e){return r||t.tui.info.showToast(M.t(`cmd.titleInstall`),M.t(`cmd.pluginInstallFailed`,{err:e instanceof Error?e.message:String(e)})),!1}r||t.tui.info.showToast(M.t(`cmd.titleInstall`),M.t(`cmd.pluginInstalled`,{seg:d.created?`Installed ${d.id}`:`${d.id} already up to date`})),await Se(t.app.settings,{id:d.id,source:`npm`,sourceSpec:s,version:d.version,scope:`global`,capabilities:u}),t.app.pluginModuleManager.emitMonitorEvent({type:`plugin.installed`,pluginId:d.id});for(let e of d.compileWarnings)r||t.tui.info.showToast(M.t(`cmd.titleInstall`),M.t(`cmd.pluginInstallFailed`,{err:e}));u.length>0&&(i?.(`Authorizing capabilities`),ke(d.dir),he(d.dir,u));try{i?.(`Reloading capabilities`),(await t.app.reloadCapabilities()).pendingProviderCapabilities.includes(d.id)&&(r||t.tui.info.showToast(M.t(`cmd.titleInstall`),M.t(`cmd.pluginInstallPendingCaps`,{id:d.id})),a?.(d.id))}catch(e){r||t.tui.info.showToast(M.t(`cmd.titleInstall`),M.t(`cmd.compatReloadFailed`,{err:e instanceof Error?e.message:String(e)}))}if(await t.callbacks.refreshModelsNow().catch(()=>{}),e===`plugin-feishu-use`){try{let{launchFeishuSetup:e}=await import(`./feishu-setup-B6ETf-8Y.js`);await e(t)}catch{}return!0}if(!r){await new Promise(e=>setImmediate(e));let{handleModel:e}=await Promise.resolve().then(()=>ti);await e([],t)}return!0}async function $r(e,t){t.tui.panes.togglePane(`backgroundTasks`)}async function ei(e,t){let n=e.join(` `);if(!n){t.tui.info.showToast(M.t(`cmd.titleJob`),M.t(`cmd.jobUsage`));return}let r=/^revert\s+(\S+)$/.exec(n);if(r){let e=r[1],n=t.app.agentJobs.revert(e);if(n.applied)t.tui.info.showToast(M.t(`cmd.titleReverted`),M.t(`cmd.jobReverted`,{id:e,msg:n.message}));else{let r=n.conflictPaths.length?M.t(`cmd.jobConflictFiles`,{joinedPaths:n.conflictPaths.join(`
16
- `)}):``;t.tui.messages.pushMessage({role:`command_echo`,command:`/go revert ${e}`,status:`error`,summary:M.t(`cmd.jobRevertFailed`,{id:e,status:n.status,msg:n.message,conflicts:r})})}return}try{let e=t.app.agentJobs.start({title:n.slice(0,60),prompt:n,sessionId:t.state.session.id,origin:`user`});t.tui.info.showToast(M.t(`cmd.titleDelegated`),M.t(`cmd.delegated`,{title:e.title}))}catch(e){t.tui.messages.pushMessage({role:`command_echo`,command:`/go`,status:`error`,summary:M.t(`cmd.delegateFailed`,{err:e instanceof Error?e.message:String(e)})})}}async function J(e,t){let r=e[0]?.toLowerCase();if(r===`trust`)return Pr(e.slice(1),t);if(r===`install`)return c(e.slice(1),t);if(r===`registry`)return u(e.slice(1),t);if(r===`search`)return l(e.slice(1),t);if(r===`update`)return Ur([`--check`],t);let i=(e,n)=>t.tui.info.showToast(e,n),a=e=>t.tui.messages.pushMessage({role:`command_echo`,command:`/extension`,status:`error`,summary:e}),o=()=>{let e=t.app.extensions.list(),n=t.app.getGlobalMenuItems?.()??[],r=new Map(n.map(e=>[e.id,e.command]));t.tui.modal.openModal({kind:`extensionsList`,entries:e.map(e=>({category:e.category,id:e.id,name:e.name,enabled:e.enabled,description:e.description,applies:e.applies})),menuContributions:[{id:`__discover__`,title:`Discover plugins (search registries)…`},...n.map(e=>({id:e.id,title:e.title}))],onSelect:e=>{if(!e)return;if(e===`contrib:__discover__`){s();return}if(e.startsWith(`contrib:`)){let n=e.slice(8),a=r.get(n);if(!a)return;de(a,{open:e=>_e(e),runCommand:async(e,n)=>{let{dispatchSlashCommand:r}=await Promise.resolve().then(()=>Ra);await r(e,n?n.split(/\s+/).filter(Boolean):[],t)}}).catch(e=>i(M.t(`cmd.titlePlugin`),e instanceof Error?e.message:String(e)));return}let n=e.indexOf(`:`);p(e.slice(0,n),e.slice(n+1))},onCancel:()=>{}})},s=async()=>{let e=await t.tui.modal.openModal({kind:`input`,title:`Discover plugins`,description:[`搜索已注册 registry(/registry list 查看源;/registry add 注册第三方源)`],placeholder:`keyword… (e.g. weather / oauth / provider)`});if(!e?.trim()){o();return}let{searchRegistries:n}=await import(`./registry-BOX7DaxS.js`),{hits:r,warnings:a}=await n(t,e.trim());if(r.length===0){i(M.t(`cmd.titlePlugin`),`No registry entries match '${e.trim()}'${a.length?` (${a.length} source warning)`:``}`),o();return}t.tui.modal.openModal({kind:`select`,title:`Discover: '${e.trim()}' (${r.length})`,subtitle:a.length>0?`⚠ ${a.join(` · `)}`:void 0,options:r.map((e,t)=>({label:`${e.entry.id} (${e.entry.type}) [${(e.entry.capabilities??[]).join(`, `)||`-`}] @${e.sourceName}${e.stale?` (stale)`:``}`,description:e.entry.description,value:String(t)})),onSelect:e=>{let n=r[Number(e)];if(!n)return;let a=[`--as`,n.entry.type,...n.entry.subPath?[`--sub-path`,n.entry.subPath]:[],n.entry.source];(async()=>{let{dispatchSlashCommand:e}=await Promise.resolve().then(()=>Ra);await e(`extension`,[`install`,...a],t)})().catch(e=>i(M.t(`cmd.titlePlugin`),e instanceof Error?e.message:String(e)))},onCancel:()=>o()})},d=e=>{let n=t.app.skillRegistry?.get(e);if(!n){o();return}let r=n.status!==`disabled`,s=n.definition.metadata,c=[{kind:`group`,title:M.t(`cmd.extSkillGroupOverview`)},{kind:`row`,label:M.t(`cmd.extSkillLabelDesc`),value:s.description||`—`},{kind:`row`,label:M.t(`cmd.extSkillLabelStatus`),value:n.status,tone:n.status===`error`||n.status===`disabled`?`error`:`success`},{kind:`row`,label:M.t(`cmd.extSkillLabelSource`),value:M.t(`cmd.extSkillSourceLabel`,{seg:qr(n.source.type,n.source.id)}),tone:`muted`},...Gr(n.source.root)?[]:[{kind:`text`,value:M.t(`cmd.extSkillManagedExternally`,{root:n.source.root}),tone:`muted`}],{kind:`group`,title:M.t(`cmd.extSkillGroupTrigger`)},{kind:`row`,label:M.t(`cmd.extSkillLabelTriggerMode`),value:s.trigger===`manual`?M.t(`cmd.extSkillTriggerManual`):M.t(`cmd.extSkillTriggerAuto`)},...s.priority===void 0?[]:[{kind:`row`,label:M.t(`cmd.extSkillLabelPriority`),value:String(s.priority)}],{kind:`group`,title:M.t(`cmd.extSkillGroupDependencies`)},{kind:`row`,label:M.t(`cmd.extSkillLabelDependencies`),value:s.dependencies?.length?s.dependencies.join(`, `):M.t(`cmd.extSkillNoDependencies`),tone:s.dependencies?.length?void 0:`muted`},{kind:`group`,title:M.t(`cmd.extSkillGroupTags`)},{kind:`row`,label:M.t(`cmd.extSkillLabelTags`),value:s.tags?.length?s.tags.join(`, `):M.t(`cmd.extSkillNoTags`),tone:s.tags?.length?void 0:`muted`}];n.status===`error`&&n.error&&c.push({kind:`group`,title:M.t(`cmd.extSkillGroupError`)},{kind:`text`,value:n.error,tone:`error`}),t.tui.modal.openModal({kind:`extensionDetail`,title:M.t(`cmd.extSkillTitle`,{name:e,state:r?`enabled`:`disabled`}),meta:`skill · ${n.source.type}`,metaStatus:{label:r?M.t(`cmd.extEnableLabel`):M.t(`cmd.extDisableLabel`),enabled:r},actions:[{label:r?M.t(`cmd.extDisableLabel`):M.t(`cmd.extEnableLabel`),value:`toggle`,color:r?`amber`:`green`},{label:M.t(`cmd.extViewFullTextLabel`),value:`view-full-text`,color:`gray`},...Kr(n.source.type,n.source.root)?[{label:M.t(`cmd.uninstallActionLabel`),value:`uninstall`,color:`red`}]:[]],dataListEntries:c,fullText:{title:M.t(`cmd.extSkillFullTextTitle`,{name:e}),content:n.definition.body||M.t(`cmd.extSkillNoBody`)},onAction:async s=>{if(s===`toggle`){try{await t.app.extensions.setEnabled(`skill`,e,!r),i(M.t(`cmd.titleExtension`),M.t(`cmd.extToggled`,{name:e,verb:r?`Disabled`:`Enabled`,seg:` — applies next turn`}))}catch(e){a(M.t(`cmd.extToggleFailed`,{err:e instanceof Error?e.message:String(e)}))}d(e);return}if(s===`uninstall`){let r=Kr(n.source.type,n.source.root);if(!r)return;await Un({name:e,type:`skill`,scope:r,ctx:t,onDone:()=>o()})}},onClose:()=>o()})},f=e=>{let n=t.app.declarativeAgentProfiles.find(t=>t.name===e);if(!n){o();return}let r=!new Set(t.app.settings.get(`disabled_agents`)??[]).has(e),s=[{kind:`group`,title:M.t(`cmd.extAgentGroupOverview`)},{kind:`row`,label:M.t(`cmd.extAgentLabelDesc`),value:n.description||`—`},{kind:`row`,label:M.t(`cmd.extAgentLabelStatus`),value:r?M.t(`cmd.extEnableLabel`):M.t(`cmd.extDisableLabel`),tone:r?`success`:`error`},{kind:`group`,title:M.t(`cmd.extAgentGroupCapabilities`)},{kind:`row`,label:M.t(`cmd.extAgentLabelTaskTypes`),value:n.taskTypes.length?n.taskTypes.join(`, `):M.t(`cmd.extAgentNoTaskTypes`),tone:n.taskTypes.length?void 0:`muted`},{kind:`row`,label:M.t(`cmd.extAgentLabelCapabilities`),value:n.capabilities.length?n.capabilities.join(`, `):M.t(`cmd.extAgentNoCapabilities`),tone:n.capabilities.length?void 0:`muted`},{kind:`group`,title:M.t(`cmd.extAgentGroupTools`)},{kind:`row`,label:M.t(`cmd.extAgentLabelDefaultTools`),value:n.defaultTools?.length?n.defaultTools.join(`, `):M.t(`cmd.extAgentAllTools`),tone:n.defaultTools?.length?void 0:`muted`},{kind:`row`,label:M.t(`cmd.extAgentLabelDisallowedTools`),value:n.disallowedTools?.length?n.disallowedTools.join(`, `):M.t(`cmd.extAgentNoDisallowedTools`),tone:n.disallowedTools?.length?void 0:`muted`},{kind:`group`,title:M.t(`cmd.extAgentGroupExecution`)},{kind:`row`,label:M.t(`cmd.extAgentLabelPromptMode`),value:n.promptMode??`append`,tone:`muted`},...n.preferredModelTier?[{kind:`row`,label:M.t(`cmd.extAgentLabelModelTier`),value:n.preferredModelTier}]:[],{kind:`row`,label:M.t(`cmd.extAgentLabelAllowSubagents`),value:n.allowSubagents?M.t(`cmd.extEnableLabel`):M.t(`cmd.extDisableLabel`),tone:n.allowSubagents?void 0:`muted`}];t.tui.modal.openModal({kind:`extensionDetail`,title:M.t(`cmd.extAgentTitle`,{name:e,state:r?`enabled`:`disabled`}),meta:`agent`,metaStatus:{label:r?M.t(`cmd.extEnableLabel`):M.t(`cmd.extDisableLabel`),enabled:r},actions:[{label:r?M.t(`cmd.extDisableLabel`):M.t(`cmd.extEnableLabel`),value:`toggle`,color:r?`amber`:`green`},{label:M.t(`cmd.extViewFullTextLabel`),value:`view-full-text`,color:`gray`}],dataListEntries:s,fullText:{title:M.t(`cmd.extAgentFullTextTitle`,{name:e}),content:n.systemPromptTemplate||M.t(`cmd.extSkillNoBody`)},onAction:async n=>{if(n===`toggle`){try{await t.app.extensions.setEnabled(`agent`,e,!r),i(M.t(`cmd.titleExtension`),M.t(`cmd.extToggled`,{name:e,verb:r?`Disabled`:`Enabled`,seg:` — applies next turn`}))}catch(e){a(M.t(`cmd.extToggleFailed`,{err:e instanceof Error?e.message:String(e)}))}f(e)}},onClose:()=>o()})},p=(e,n)=>{let r=t.app.extensions.list().find(t=>t.category===e&&t.id===n);if(!r){o();return}let s={label:r.enabled?M.t(`cmd.extDisableLabel`):M.t(`cmd.extEnableLabel`),value:`toggle`};if(e===`mcp`){let c=t.app.mcpManager?.getServerInfos().find(e=>e.name===n),l=r.enabled?c?String(c.status):`disconnected`:`disabled`;t.tui.modal.openModal({kind:`select`,title:M.t(`cmd.extMcpTitle`,{name:r.name,status:l}),options:[{label:M.t(`cmd.extReconnectLabel`),value:`reconnect`},s,...r.readonly?[]:[{label:M.t(`cmd.uninstallActionLabel`),value:`uninstall`}]],onSelect:async s=>{if(s===`toggle`){try{await t.app.extensions.setEnabled(r.category,n,!r.enabled),i(M.t(`cmd.titleExtension`),M.t(`cmd.extToggled`,{name:r.name,verb:r.enabled?`Disabled`:`Enabled`,seg:``}))}catch(e){a(M.t(`cmd.extToggleFailed`,{err:e instanceof Error?e.message:String(e)}))}p(e,n);return}if(s===`reconnect`){let r=t.app.mcpManager,o=(t.app.settings.get(`mcp_servers`)??{})[n];if(!r||!o){i(M.t(`cmd.titleExtension`),M.t(`cmd.extReconnectUnavailable`,{id:n})),p(e,n);return}try{await r.disconnect(n).catch(()=>{}),await r.connect(n,o),i(M.t(`cmd.titleExtension`),M.t(`cmd.extReconnected`,{id:n}))}catch(e){a(M.t(`cmd.extReconnectFailed`,{id:n,err:e instanceof Error?e.message:String(e)}))}p(e,n);return}if(s===`uninstall`){await Un({name:n,type:`mcp`,scope:`project`,ctx:t,onDone:()=>o()});return}},onCancel:()=>o()})}else e===`plugin`?m(n,r.enabled,r.name,r.description):e===`skill`?d(n):e===`agent`?f(n):t.tui.modal.openModal({kind:`select`,title:M.t(`cmd.extItemTitle`,{name:r.name}),options:[s],onSelect:async o=>{if(o===`toggle`){try{await t.app.extensions.setEnabled(r.category,n,!r.enabled),i(M.t(`cmd.titleExtension`),M.t(`cmd.extToggled`,{name:r.name,verb:r.enabled?`Disabled`:`Enabled`,seg:r.applies===`live`?``:` — applies next turn`}))}catch(e){a(M.t(`cmd.extToggleFailed`,{err:e instanceof Error?e.message:String(e)}))}p(e,n);return}},onCancel:()=>o()})},m=(e,r,s,c,l)=>{let u=t.app.workspaceDir??process.cwd(),d=n({cwd:u,homedir:_()}).find(t=>t.id===e);if(!d){o();return}let f=pe(d),p=f.surface.any?f.gated?M.t(`cmd.extPluginUntrusted`):f.pendingCapabilities.length>0?M.t(`cmd.extPluginCapabilityPending`,{caps:f.pendingCapabilities.join(`, `)}):M.t(`cmd.extPluginTrusted`):M.t(`cmd.extPluginNoSurface`),h=f.surface,g=[[h.mcpJson,`mcp`],[h.commands,`commands`],[h.scripts,`scripts`],[h.panels,`panels`],[h.skills,`skills`],[h.agents,`agents`]].filter(([e])=>e).map(([,e])=>e),v=g.length?` ${g.join(`, `)}`:` —`,ee=(t.app.getPluginPanelRegistrations?.()??[]).filter(t=>t.pluginId===e),y=Jr({providerApis:t.app.providerRegistry.getApisBySource(e).length,tools:t.app.toolRegistry.getAll().filter(t=>t.metadata.source===e).length,renderers:t.app.getPluginRenderers().filter(t=>t.pluginId===e).length,statusItems:t.app.getPluginStatusItems().filter(t=>t.id.startsWith(`${e}:`)).length,fileViewers:(t.app.getPluginFileViewers?.()??[]).filter(t=>t.pluginId===e).length}),b=d.scope===`builtin`?[]:[{label:r?M.t(`cmd.extDisableLabel`):M.t(`cmd.extEnableLabel`),value:`toggle`,color:r?`amber`:`green`}];if(f.surface.any&&(d.scope===`project`||d.scope===`repository`||f.pendingCapabilities.length>0)){let e=d.scope===`project`||d.scope===`repository`?!f.trusted:f.pendingCapabilities.length>0;b.push({label:e?M.t(`cmd.extPluginTrustLabel`):M.t(`cmd.extPluginUntrustLabel`),value:e?`trust`:`untrust`,color:e?`accent`:`gray`})}b.push({label:M.t(`cmd.extReloadLabel`),value:`reload`}),d.scope!==`builtin`&&b.push({label:M.t(`cmd.uninstallActionLabel`),value:`uninstall`,color:`red`});let te=ie(d,{"extension.id":e,"extension.enabled":r,"extension.trusted":f.trusted,"extension.scope":d.scope,"extension.category":`plugin`}),x=d.manifest.contributes,S=we(re.extensionDetailActions,x?.menus,x?.actions,te),ne=new Map(S.map(e=>[e.id,e.command]));for(let e of S){let n=`${d.id}:action.${e.id}.title`,r=t.app.i18nRegistry.t(n),i=r===n?e.title:r;b.push({label:i,value:`contrib:${e.id}`,color:e.color})}let C={open:e=>_e(e),runCommand:async(e,n)=>{let{dispatchSlashCommand:r}=await Promise.resolve().then(()=>Ra);await r(e,n?n.split(/\s+/).filter(Boolean):[],t)},runScript:async e=>{if(pe(d).gated){i(M.t(`cmd.titlePlugin`),M.t(`cmd.extPluginUntrusted`));return}await De(d,e)}},w=ee[0];w&&t.app.firePluginActivationEvent?.(`onView:${w.id}`);let T;if(e===`plugin-feishu-use`){let e=O(u,`.otto`,`feishu-use.json`),t=!1;try{if(k(e)){let n=JSON.parse(A(e,`utf8`));if(n.app_id){t=!0;let r=typeof n.app_id==`string`&&n.app_id.length>12?n.app_id.slice(0,8)+`***`+n.app_id.slice(-4):String(n.app_id),i=Array.isArray(n.allowed_chats)?n.allowed_chats.length:0,a=Array.isArray(n.trusted_chats)?n.trusted_chats.length:0,o=d.scope===`user`?`全局`:d.scope===`repository`?`仓库`:`项目`;T=[{kind:`row`,label:`App ID`,value:r},{kind:`row`,label:`消息白名单`,value:i>0?`${i} 个`:`空 — 拒绝所有消息`,tone:i>0?void 0:`warning`},...a>0?[{kind:`row`,label:`可信任 chat`,value:`${a} 个`}]:[],{kind:`row`,label:`配置`,value:`${o}级 · ${e}`,tone:`muted`}]}}}catch{}t||(T=[{kind:`text`,value:`未配置 — 点击 [重新配置] 引导设置`,tone:`warning`},{kind:`row`,label:`预期配置路径`,value:e,tone:`muted`}]),b.push({label:`重新配置`,value:`feishu-reconfigure`,color:`amber`})}let ae=()=>{let n=t.app.pluginHealthTracker?.query(e)??{hookTimeouts:0,toolTimeouts:0},r=be(e);return{healthStats:{hookTimeouts:n.hookTimeouts,toolTimeouts:n.toolTimeouts,lastError:n.lastError},logEntries:r.map(e=>({ts:e.ts,level:e.level,msg:e.msg}))}},oe=[{kind:`group`,title:M.t(`cmd.extPluginGroupTitle`)},{kind:`row`,label:M.t(`cmd.extPluginLabelDesc`),value:c},{kind:`row`,label:M.t(`cmd.extPluginLabelScope`),value:d.scope},{kind:`row`,label:M.t(`cmd.extPluginLabelTrust`),value:p},{kind:`row`,label:M.t(`cmd.extPluginLabelSurfaces`),value:v.trim()||`—`},...y?[{kind:`row`,label:M.t(`cmd.extPluginLabelContributions`),value:y}]:[],{kind:`row`,label:M.t(`cmd.extPluginLabelStatus`),value:r?M.t(`cmd.extEnableLabel`):M.t(`cmd.extDisableLabel`),tone:r?`success`:`error`}],se=l?[{kind:`text`,value:l.message,tone:l.kind===`success`?`success`:`error`}]:[];t.tui.modal.openModal({kind:`extensionDetail`,title:M.t(`cmd.extPluginTitle`,{name:s,state:r?`enabled`:`disabled`}),meta:`plugin · ${d.scope}`,metaStatus:{label:r?M.t(`cmd.extEnableLabel`):M.t(`cmd.extDisableLabel`),enabled:r},metaSuffix:p,actions:b,panelInfo:w?{title:w.title,modulePath:w.modulePath,exportName:w.exportName,pluginId:e}:void 0,dataListEntries:[...se,...T??oe],...ae(),onRefresh:()=>m(e,r,s,c),onAction:async n=>{if(n.startsWith(`contrib:`)){let t=ne.get(n.slice(8));if(t)try{await de(t,C)}catch(e){a(M.t(`cmd.extToggleFailed`,{err:e instanceof Error?e.message:String(e)}))}m(e,r,s,c)}else if(n===`trust`)Xr(t,d);else if(n===`untrust`){try{Me(d.dir)}catch(t){m(e,r,s,c,{kind:`error`,message:`撤销信任失败,权限未收回:${t instanceof Error?t.message:String(t)}`});return}t.app.reloadCapabilities?.().then(()=>{t.tui.plugins.setPluginRegistrations(t.app.getPluginRegistrations())}).finally(()=>{m(e,r,s,c,{kind:`success`,message:M.t(`cmd.pluginUntrusted`,{id:e})})})}else if(n===`toggle`)try{await t.app.extensions.setEnabled(`plugin`,e,!r);try{await t.app.reloadCapabilities(),m(e,!r,s,c,{kind:`success`,message:M.t(`cmd.extToggled`,{name:s,verb:r?`Disabled`:`Enabled`,seg:``})})}catch(t){m(e,!r,s,c,{kind:`error`,message:M.t(`cmd.extToggleReloadFailed`,{verb:r?`Disabled`:`Enabled`,name:s,err:t instanceof Error?t.message:String(t)})})}}catch(t){m(e,r,s,c,{kind:`error`,message:M.t(`cmd.extToggleFailed`,{err:t instanceof Error?t.message:String(t)})})}else if(n===`feishu-reconfigure`)try{let{launchFeishuSetup:e}=await import(`./feishu-setup-B6ETf-8Y.js`);await e(t),i(`plugin-feishu-use`,`配置完成。`)}catch(e){a(`feishu-use 配置向导失败:${e instanceof Error?e.message:String(e)}`)}else n===`reload`?t.app.reloadCapabilities?.().then(t=>{m(e,r,s,c,{kind:`success`,message:M.t(`cmd.pluginTrusted`,{id:e,count:t.mcpTools})})}).catch(t=>{m(e,r,s,c,{kind:`error`,message:M.t(`cmd.compatReloadFailed`,{err:t instanceof Error?t.message:String(t)})})}):n===`uninstall`&&await Un({name:e,type:`plugin`,scope:d.scope===`project`||d.scope===`repository`?d.scope:`global`,ctx:t,onDone:()=>o()})},onClose:()=>o()})};o()}var ti=bt({handleLogout:()=>si,handleModel:()=>oi,handleProviderAuth:()=>Y,handleServiceLogin:()=>ci,handleServiceLogout:()=>li});const ni=`__otto_model_login__`,ri=`__otto_model_setkey__`,ii=`__otto_model_grant_capability__`,ai=`__otto_model_install_plugin__`;async function oi(e,t,n){let r=e[0];if(r===`refresh`||r===`--refresh`){let e=await t.app.refreshModels();t.state.models=t.app.modelRegistry.getAll().filter(e=>e.id!==`__otto_setup__`).map(e=>({id:e.id,name:e.name,provider:e.provider,api:e.api,strengths:e.strengths??[],contextWindow:e.contextWindow}));for(let n of e)for(let e of n.availableIds??[])t.state.availableModelIds.add(e);t.callbacks.persistAvailable();let n=Math.max(...e.map(e=>e.provider.length),0),r=e=>e.padEnd(n),i={},a=e.map((e,t)=>e.status===`ok`?(i[t]=`success`,M.t(`cmd.modelRefreshLineOk`,{provider:r(e.provider),added:e.added,kept:e.kept,total:e.total})):e.status===`skipped`&&e.reason===`not authenticated`?(i[t]=`muted`,M.t(`cmd.modelRefreshLineMuted`,{provider:r(e.provider),reason:M.t(`cmd.modelRefreshReasonNotAuthenticated`)})):e.reason?.includes(`capability not granted`)?(i[t]=`warning`,M.t(`cmd.modelRefreshLineWarning`,{provider:r(e.provider),reason:M.t(`cmd.modelRefreshReasonPendingCapability`)})):(i[t]=`warning`,M.t(`cmd.modelRefreshLineErr`,{provider:r(e.provider),status:e.status,reason:e.reason}))),o=e.some(e=>e.status===`skipped`&&e.reason?.includes(`capability not granted`));t.tui.modal.openModal({kind:`info`,title:M.t(`cmd.titleModels`),lines:[...a,``,M.t(`cmd.modelRefreshHint`)],action:o?{kind:`extension`,run:()=>{J([],t)}}:void 0,lineTones:i});return}if(r){let e=t.state.models.find(e=>e.id===r||e.name===r);if(!e){let e=r.includes(`/`)?r.split(`/`)[0]:r;if(!t.state.models.some(t=>t.provider.toLowerCase()===e.toLowerCase())&&/^[a-z0-9][\w-]*$/i.test(e)){t.tui.modal.openModal({kind:`select`,title:M.t(`cmd.modelDelegateProviderTitle`,{cand:e}),options:[{label:M.t(`cmd.modelDelegateProviderYes`,{cand:e}),value:`yes`},{label:M.t(`cmd.commonNo`),value:`no`}],onSelect:n=>{if(n!==`yes`)return;let r=`为 "${e}" 实现一个 provider 适配器:参照 packages/ai/src 下现有 provider 的实现,接 model-fetch 的 resolveModelsRequest、注册进 provider/model registry,并写测试跑绿。`;try{t.app.agentJobs.start({title:`write provider: ${e}`,prompt:r,sessionId:t.state.session.id,origin:`user`}),t.tui.info.showToast(M.t(`cmd.titleDelegated`),M.t(`cmd.modelProviderDelegated`,{cand:e}))}catch(e){t.tui.messages.pushMessage({role:`command_echo`,command:`/model`,status:`error`,summary:M.t(`cmd.delegateFailed`,{err:e instanceof Error?e.message:String(e)})})}},onCancel:()=>{}});return}t.tui.info.showToast(M.t(`cmd.titleModel`),M.t(`cmd.modelNotFoundUse`,{arg:r}));return}t.tui.info.showToast(M.t(`cmd.titleModel`),await t.callbacks.applyModel(e.id)),t.state.session.model?.id===e.id&&n?.afterSwitch?.();return}t.state.models=t.app.modelRegistry.getAll().filter(e=>e.id!==`__otto_setup__`).map(e=>({id:e.id,name:e.name,provider:e.provider,api:e.api,strengths:e.strengths??[],contextWindow:e.contextWindow}));let i=e=>t.state.availableModelIds.has(e),a=[...new Set(t.state.models.map(e=>t.callbacks.apiCredentialId(e.api??``,e.provider)))],o=new Map(await Promise.all(a.map(async e=>[e,await t.app.authStore.getAuthSource(e).catch(()=>null)]))),s=e=>{let n=t.callbacks.apiCredentialId(e.api??``,e.provider),r=o.get(n);if(!r)return``;let i=M.t(`pref.authModeLabel`,{context:r});return`${i===r?``:` · `}${i}`},c=[...t.state.models].sort((e,t)=>Number(i(t.id))-Number(i(e.id))||e.provider.localeCompare(t.provider)||e.name.localeCompare(t.name)),l=c.length>0?Math.max(...c.map(e=>e.name.length),8):8,u=e=>e?e>=1e6?`${(e/1e6).toFixed(1)}M`:`${Math.round(e/1e3)}k`:``,d=e=>{let n=i(e.id),r=e.id===t.state.currentModelId?`●`:` `,a=u(e.contextWindow),o=`${r} ${e.name.padEnd(l)}`+(a?` ${a}`:``),c=[s(e).replace(/^ · /,``),e.strengths.length>0?e.strengths.join(`/`):``].filter(Boolean).join(` `);return{isAvail:n,label:o,detail:c&&` ${c}`}},f=t.app.settings.get(`recent_models`)??[],p=new Map(t.state.models.map(e=>[e.id,e])),m=f.map(e=>p.get(e)).filter(e=>e!==void 0).map(e=>{let{isAvail:t,label:n,detail:r}=d(e);return{label:n,value:e.id,disabled:!t,group:M.t(`cmd.modelRecentGroup`),detail:r||void 0,searchText:e.name}}),h=t.state.availableModelIds.size===0,g=!t.app.modelRegistry.hasAnyPluginSourcedModel()&&h,_=(t.app.pendingProviderCapabilities??[]).length,v=[];g&&_>0?(v.push(M.t(`model.noProviderPlugin`)),v.push(M.t(`model.pendingCapabilities`,{count:_}))):g?v.push(M.t(`model.noProviderPlugin`)):h&&v.push(M.t(`model.noneAvailable`)),!g&&_>0&&v.push(M.t(`model.pendingCapabilities`,{count:_})),t.tui.modal.openModal({kind:`select`,searchable:!0,maxVisible:13,title:h?M.t(`cmd.modelSelectTitle`):M.t(`cmd.modelSelectTitleAvail`),subtitle:v.length>0?v.join(` · `):void 0,subtitleTone:_>0?`warning`:`default`,subtitleActions:g||h||_>0?[...g?[{label:M.t(`model.goInstallPlugin`),value:ai}]:h?[{label:M.t(`model.goLogin`),value:ni},{label:M.t(`model.setKey`),value:ri}]:[],..._>0?[{label:M.t(`model.goGrantCapability`),value:ii}]:[]]:void 0,options:[...m,...c.map(e=>{let{isAvail:t,label:n,detail:r}=d(e);return{label:n,value:e.id,disabled:!t,group:e.provider,detail:r||void 0,searchText:e.name}})],onSelect:async e=>{if(e===ni){await Y([],t,{method:`oauth`});return}if(e===ri){await Y([],t,{method:`key`});return}if(e===ii){await J([],t);return}if(e===ai){let{EXTENSION_ALIASES:e}=await import(`./extension-I87MkZYp.js`),{runPluginInstall:n}=await Promise.resolve().then(()=>Wr),r=Object.entries(e).filter(([,e])=>e.capabilities.includes(`provider`)).map(([e])=>({label:e,value:e}));if(r.length===1){await n(r[0].value,t);return}t.tui.modal.openModal({kind:`select`,title:M.t(`cmd.modelSelectTitle`),options:r.map(e=>({label:e.label,value:e.value})),onSelect:async e=>{await n(e,t)},onCancel:()=>{}});return}t.tui.info.showToast(M.t(`cmd.titleModel`),await t.callbacks.applyModel(e)),t.state.session.model?.id===e&&n?.afterSwitch?.()}})}async function Y(e,t,n){if(e.includes(`--service`))return ci(e,t);let r=t.app.authStore,i=e=>new Promise(n=>t.tui.modal.openModal({kind:`select`,...e,title:e.title??M.t(`cmd.commonSelect`),detailPlacement:`inline`,onSelect:n,onCancel:()=>n(null)})),a=r.listProviders();if(a.length===0){t.tui.info.showToast(M.t(`cmd.titleLogin`),M.t(`cmd.loginNoProviders`));return}let o=e[0]||null,s=e=>r.oauth.get(e)?.name??ht(e)?.name??t.callbacks.PROVIDER_DISPLAY_NAMES[e]??e,c=e=>s(e),l=e=>e?M.t(`pref.authModeLabel`,{context:e}):M.t(`cmd.loginNotSet`),u=(e,t)=>{let n=l(t);return s(e).toLowerCase()===e.toLowerCase()?n:`[${e}] · ${n}`};if(!o){let e=await Promise.all(a.map(e=>r.getAuthSource(e)));o=await i({title:M.t(`cmd.loginPickProvider`),options:a.map((t,n)=>({label:c(t),value:t,detail:u(t,e[n]??null)}))})}if(!o)return;let d=r.oauth.get(o)?.name??o,f=!!r.oauth.get(o),p=`key`;if(n?.method)p=n.method===`oauth`&&f?`oauth`:`key`;else if(f){let e=await i({title:M.t(`cmd.loginAuthMethod`,{name:d}),options:[{label:M.t(`cmd.loginMethodOauth`),value:`oauth`},{label:M.t(`cmd.loginMethodKey`),value:`key`}]});if(!e)return;p=e}if(p===`key`){let e=await t.tui.modal.openModal({kind:`input`,title:M.t(`cmd.loginKeyTitle`,{provider:o}),placeholder:M.t(`cmd.loginKeyPlaceholder`),mask:!0});if(!e||!e.trim()){t.tui.info.showToast(M.t(`cmd.titleLogin`),M.t(`cmd.loginCancelledNoKey`));return}await r.setCredentialKey(o,e.trim()),await r.save(),t.tui.info.showToast(M.t(`cmd.titleLogin`),M.t(`cmd.loginKeySaved`,{provider:o})),await t.callbacks.refreshModelsNow(e=>t.tui.info.showToast(M.t(`cmd.titleModels`),e));return}try{let e={};await r.login(o,{onAuth:n=>{if(e=n,n.url)if(Fe(n.url))t.tui.info.showToast(M.t(`cmd.titleLogin`),M.t(`cmd.loginOauthBrowserOpened`));else{let e=[M.t(`cmd.loginOauthUrlAuthorize`),`\n${n.url}`];n.instructions&&e.push(`\n${n.instructions}`),t.tui.modal.openModal({kind:`info`,title:M.t(`cmd.loginOauthTitle`,{provider:o}),lines:e})}if(n.code){let e=[M.t(`cmd.loginOauthCodeIntro`)];n.url&&e.push(`\n${n.url}`),e.push(`\n${M.t(`cmd.loginOauthCode`,{code:n.code})}`),n.instructions&&e.push(`\n${n.instructions}`),t.tui.modal.openModal({kind:`info`,title:M.t(`cmd.loginOauthTitle`,{provider:o}),lines:e})}},onProgress:e=>t.tui.info.showToast(M.t(`cmd.titleLogin`),e),onPrompt:async e=>await t.tui.modal.openModal({kind:`input`,title:e.message,placeholder:e.placeholder})??``,onManualCode:async n=>{let r=[];return e.url&&(r.push(M.t(`cmd.loginOauthUrlAuthorize`)),r.push(` `),r.push(e.url)),e.instructions&&(r.length>0&&r.push(` `),r.push(e.instructions)),await t.tui.modal.openModal({kind:`input`,title:M.t(`cmd.loginOauthPasteCode`,{provider:o}),description:r.length>0?r:void 0,placeholder:`code#state`,signal:n,actionButton:e.url?{label:M.t(`cmd.loginOauthOpenBrowserButton`),onPress:()=>{Fe(e.url)&&t.tui.info.showToast(M.t(`cmd.titleLogin`),M.t(`cmd.loginOauthBrowserOpened`))}}:void 0})??``}}),t.tui.info.showToast(M.t(`cmd.titleLogin`),M.t(`cmd.loginSuccess`,{provider:o})),await t.callbacks.refreshModelsNow(e=>t.tui.info.showToast(M.t(`cmd.titleModels`),e))}catch(e){t.tui.messages.pushMessage({role:`command_echo`,command:`/auth`,status:`error`,summary:M.t(`cmd.loginFailed`,{msg:e.message})})}}async function si(e,t){if(e.includes(`--service`))return li(e,t);let n=t.app.authStore,r=e[0]||null;if(!r){let e=n.listProviders(),i=await Promise.all(e.map(e=>n.getAuthSource(e))),a=e.filter((e,t)=>i[t]===`oauth`||i[t]===`api_key`);if(a.length===0){t.tui.info.showToast(M.t(`cmd.titleLogout`),M.t(`cmd.logoutNoStored`));return}r=await new Promise(r=>t.tui.modal.openModal({kind:`select`,title:M.t(`cmd.logoutPickProvider`),detailPlacement:`inline`,options:a.map(r=>{let a=n.oauth.get(r)?.name??ht(r)?.name??t.callbacks.PROVIDER_DISPLAY_NAMES[r]??r,o=i[e.indexOf(r)];return{label:a.toLowerCase()===r.toLowerCase()?a:`${a} [${r}]`,value:r,detail:o?M.t(`pref.authModeLabel`,{context:o}):void 0}}),onSelect:r,onCancel:()=>r(null)}))}r&&(await n.logout(r),t.tui.info.showToast(M.t(`cmd.titleLogout`),M.t(`cmd.logoutSuccess`,{provider:r})))}async function ci(e,t){let n=e.indexOf(`--service`),r=e.indexOf(`--token`);if(n===-1||r===-1){t.tui.info.showToast(M.t(`cmd.titleLogin`),M.t(`cmd.serviceLoginUsage`));return}let i=e[n+1],a=e[r+1];if(!i||!a){t.tui.info.showToast(M.t(`cmd.titleLogin`),M.t(`cmd.serviceLoginNeedValues`));return}let o=i.replace(/\/+$/,``);try{let e=await fetch(`${o}/auth/login`,{method:`POST`,headers:{Authorization:`Bearer ${a}`,Accept:`application/json`}});if(!e.ok){let n=(await e.json().catch(()=>({}))).error??e.statusText;t.tui.info.showToast(M.t(`cmd.titleLogin`),M.t(`cmd.serviceLoginFailed`,{err:String(n)}));return}let n=await e.json();if(typeof n.user_id!=`string`||typeof n.token!=`string`){t.tui.info.showToast(M.t(`cmd.titleLogin`),M.t(`cmd.serviceLoginBadResponse`));return}let{OTTO_IDENTITY_PATH:r,isShadowModeEnabled:i}=await import(`@x-otto/env`);if(i()){t.tui.info.showToast(M.t(`cmd.titleLogin`),M.t(`cmd.serviceLoginSuccess`,{url:o,user:n.user_id.slice(0,12)}));return}let{mkdir:s}=await import(`node:fs/promises`),{dirname:c}=await import(`node:path`),{atomicWriteFile:l}=await import(`@x-otto/persistence`),u={userId:n.user_id,token:n.token,serviceUrl:o,loginAt:Date.now()};await s(c(r),{recursive:!0}),await l(r,JSON.stringify(u,null,2)),t.tui.info.showToast(M.t(`cmd.titleLogin`),M.t(`cmd.serviceLoginSuccess`,{url:o,user:n.user_id.slice(0,12)}))}catch(e){t.tui.info.showToast(M.t(`cmd.titleLogin`),M.t(`cmd.serviceLoginFailed`,{err:e instanceof Error?e.message:String(e)}))}}async function li(e,t){try{let{OTTO_IDENTITY_PATH:e}=await import(`@x-otto/env`),{unlink:n}=await import(`node:fs/promises`);await n(e),t.tui.info.showToast(M.t(`cmd.titleLogout`),M.t(`cmd.serviceLogoutRemoved`))}catch(e){if(e.code===`ENOENT`){t.tui.info.showToast(M.t(`cmd.titleLogout`),M.t(`cmd.serviceLogoutNotFound`));return}t.tui.info.showToast(M.t(`cmd.titleLogout`),M.t(`cmd.serviceLogoutFailed`,{err:e instanceof Error?e.message:String(e)}))}}async function X(e,t){let n=e[0]?.toLowerCase();if(n===`perf`)return pi(e.slice(1),t);if(n===`context`)return ui(e.slice(1),t);if(n===`cache`||n===`cache-stats`)return mi(e.slice(1),t);if(n===`diagnose`)return On(e.slice(1),t);if(n===`services`)return Hr(e.slice(1),t);let r=t.state.session,i=r.session,a=i.messages(),o=0;for(let e=a.length-1;e>=0;e--){let t=a[e]?.usage;if(a[e]?.role===`assistant`&&t){o=(t.cacheReadTokens??0)+(t.cacheWriteTokens??0)+(t.inputTokens??0)+(t.outputTokens??0);break}}let s=r.model?.contextWindow,c=s&&s>0?Math.round(o/s*100):void 0,l=a.reduce((e,t)=>e+(t.usage?.outputTokens??0),0),u=Ee(i.metadata().title,i.messages(),r.id),d=t.callbacks.isWriteLeaseReadOnly(),f=[{kind:`row`,label:M.t(`cmd.statusRowTitle`),value:u},{kind:`row`,label:M.t(`cmd.statusRowSessionId`),value:r.id.slice(0,8)},{kind:`row`,label:M.t(`cmd.statusRowModel`),value:r.model?.id??M.t(`cmd.statusModelUnset`)},{kind:`row`,label:M.t(`cmd.statusRowMsgs`),value:String(a.length)},{kind:`row`,label:M.t(`cmd.statusRowOccupancy`),value:M.t(`cmd.statusValueOccupancy`,{occ:o.toLocaleString(),window:s?.toLocaleString()??`N/A`,seg:c===void 0?``:` (${c}%)`})},{kind:`row`,label:M.t(`cmd.statusRowCumOutput`),value:l.toLocaleString()},{kind:`row`,label:M.t(`cmd.statusRowWriteAccess`),value:d?M.t(`cmd.statusValueWriteLeaseReadOnly`):M.t(`cmd.statusValueWriteLeaseOk`),tone:d?`warning`:void 0}];t.callbacks.isRunPaused()&&f.push({kind:`blank`},{kind:`text`,value:M.t(`cmd.statusLineRunPaused`),tone:`warning`}),t.tui.modal.openModal({kind:`info`,title:M.t(`cmd.titleStatus`),lines:[],dataListEntries:f})}async function ui(e,t){let n=t.state.session,r=n.model,i=r?.contextWindow??2e5,a=n.session.messages(),o=0,s=0,c=0,l=0,u=0,d=0,f=!1;for(let e=a.length-1;e>=0;e--){if(a[e]?.role!==`assistant`||!a[e]?.usage)continue;let t=a[e].usage;u+=t.inputTokens??0,d+=t.outputTokens??0,f||=(o=t.inputTokens??0,s=t.outputTokens??0,c=t.cacheReadTokens??0,l=t.cacheWriteTokens??0,!0)}let p=Wt({systemPrompt:n.systemPrompt,tools:n.tools,lastIn:o,lastOut:s,lastCacheRead:c,lastCacheWrite:l,contextWindow:i,modelName:r?.name??r?.id??``,totIn:u,totOut:d,messageCount:a.length});t.tui.stores.budget.setBudget(p),t.tui.stores.context.setBudget(p),t.tui.modal.openModal({kind:`context`})}function di(){let e=process.env.OTTO_NOTIFY_COALESCE_WARN_RATIO,t=e?Number(e):NaN;return Number.isFinite(t)&&t>=1?t:1.5}function fi(e,t){return t===0?`healthy`:e<di()?`warning`:`healthy`}async function pi(e,t){t.tui.engine.pushEngineEvent({kind:`perf`,memory:t.app.memoryGovernor.sample()});let n=t.tui.info.getNotifyStats(),r=n.coalescedCalls/Math.max(1,n.coalescedFires);t.tui.engine.pushEngineEvent({kind:`perf`,notify:{coalescedCalls:n.coalescedCalls,coalescedFires:n.coalescedFires,immediateCalls:n.immediateCalls,flushFires:n.flushFires,coalesceRatio:r,alert:fi(r,n.coalescedCalls)}});let i=t.app.activePlugins();try{let e=await oe(i,void 0,e=>t.app.pluginHealthTracker.recordToolTimeout(e));t.tui.engine.pushEngineEvent({kind:`perf`,pluginMetrics:e})}catch(e){t.app.logger.warn({err:e instanceof Error?e.message:String(e)},`[perf] collectPluginPerfMetrics failed`),t.tui.engine.pushEngineEvent({kind:`perf`,pluginMetrics:[]})}t.tui.panes.togglePane(`perf`)}async function mi(e,t){let n=t.state.session.getCostSummary(),r=n.perModel.map(e=>{let t={inputTokens:e.inputTokens,outputTokens:0,cacheReadTokens:e.cacheReadTokens,cacheWriteTokens:e.cacheWriteTokens};return{modelId:e.modelId,modelName:e.modelName,cacheReadTokens:e.cacheReadTokens,cacheWriteTokens:e.cacheWriteTokens,inputTokens:e.inputTokens,hitRatio:mt(t,e.api)}}),i=r.some(e=>e.hitRatio!==null),a={inputTokens:n.totalInputTokens,outputTokens:0,cacheReadTokens:n.totalCacheReadTokens,cacheWriteTokens:n.totalCacheWriteTokens},o=i?mt(a):null;t.tui.stores.cache.setView({lastTurnHitRatio:t.state.session.getLastCacheHitRatio(),sessionHitRatio:o,totalCacheReadTokens:n.totalCacheReadTokens,totalCacheWriteTokens:n.totalCacheWriteTokens,totalInputTokens:n.totalInputTokens,totalCostUSD:n.totalCostUSD>0?n.totalCostUSD:void 0,perModel:r}),t.tui.panes.togglePane(`cacheStats`)}async function hi(e,t){if(process.env.OTTO_DEV!==`1`){t.tui.info.showToast(`Gallery`,`Set OTTO_DEV=1 to enable the component gallery.`);return}t.tui.panes.togglePane(`gallery`)}function gi(e){return new Date(e*1e3).toLocaleString()}async function _i(e,t){let n=t.state.session.model?.provider;if((n?await t.app.authStore.getAuthSource(n).catch(()=>null):null)!==`oauth`){t.tui.modal.openModal({kind:`info`,title:M.t(`cmd.titleUsage`),lines:[M.t(`cmd.usageNotSubscription`)]});return}let r=t.callbacks.getLastProviderUsage();if(!r){t.tui.modal.openModal({kind:`info`,title:M.t(`cmd.titleUsage`),lines:[M.t(`cmd.usageNoSnapshotYet`)]});return}let i=[],a=n===`anthropic`;if(r.limitType&&i.push(M.t(`cmd.usageLineType`,{type:Qe(r.limitType)})),(a||r.usedPercent!==void 0)&&i.push(M.t(`cmd.usageLineStatus`,{status:r.status})),r.usedPercent!==void 0&&i.push(M.t(`cmd.usageLinePercent`,{pct:Math.round(r.usedPercent)})),r.resetsAt!==void 0&&i.push(M.t(`cmd.usageLineResetsAt`,{when:gi(r.resetsAt)})),r.standardLimits){let e=r.standardLimits;i.push(M.t(`cmd.usageLineStandardLimits`,{reqR:e.remainingRequests??0,reqL:e.limitRequests??0,tokRk:(e.remainingTokens??0)/1e3|0,tokLk:(e.limitTokens??0)/1e3|0,reset:Math.round(Math.max(e.resetRequestsMs??0,e.resetTokensMs??0)/1e3)}))}!a&&r.limitType===void 0&&(i.push(``),i.push(M.t(`cmd.usageSubPoolNotInHeaders`))),t.tui.modal.openModal({kind:`info`,title:M.t(`cmd.titleUsage`),lines:i})}function vi(e){let t=e.trim(),n=(t.split(`
17
- `,1)[0]??``).replace(/\s+/g,` `).trim(),r=n.split(` `).slice(0,6).join(` `).slice(0,48).trim()||`note`;return{name:r,description:n.slice(0,60).trim()||r,content:t}}const yi=e=>`把下面的笔记归纳成一个简短标题(≤6 词)和一句话描述。严格只按此格式输出:\nTITLE: <标题>\nDESC: <一句话描述>\n\n笔记:\n${e}`;function bi(e){let t=/TITLE:\s*(.+)/i.exec(e)?.[1]?.trim();if(!t)return null;let n=/DESC:\s*(.+)/i.exec(e)?.[1]?.trim();return{name:t.slice(0,60),description:(n||t).slice(0,80)}}async function xi(e,t,n=8e3){let r=vi(e);if(!t)return r;let i=new AbortController,a=setTimeout(()=>i.abort(),n);a.unref?.();try{let n=bi(await t(yi(e),{maxTokens:64,signal:i.signal}));if(n)return{name:n.name,description:n.description,content:r.content}}catch{}finally{clearTimeout(a)}return r}function Si(e,t){return{onViewEntry:async n=>{let r=n.source===`project`?e:t;return r?r.read(n.name):null},onForget:async n=>{let r=n.source===`project`?e:t;r&&await r.forget(n.name)}}}async function Ci(e,t){let n=t.app.storage.autoMemory,r=t.app.userMemory,i=(e[0]??``).toLowerCase(),a=e=>t.tui.messages.pushMessage({role:`assistant`,content:[{type:`text`,text:e}]}),o=(e,n,r)=>t.tui.messages.pushMessage({role:`command_echo`,command:e,status:n,summary:r});if(i===`user`){let i=e.slice(1).join(` `).trim();if(i){let e=vi(i);await r.record(e),o(`/memory user`,`ok`,M.t(`cmd.memoryUserSaved`,{name:e.name}));return}let a=r.getInjection().trim();t.tui.modal.openModal({kind:`memory`,projectIndex:``,userIndex:a,...Si(n,r)});return}if(i===`project`){let e=n?n.getInjection().trim():``;t.tui.modal.openModal({kind:`memory`,projectIndex:e,userIndex:``,...Si(n,r)});return}if(i===`forget`){let t=e.slice(1).join(` `).trim();if(!t){o(`/memory forget`,`warn`,M.t(`cmd.memoryForgetUsage`));return}let i=!1;n&&await n.read(t)!==null&&(await n.forget(t),i=!0),await r.read(t)!==null&&(await r.forget(t),i=!0),o(`/memory forget`,i?`ok`:`error`,i?M.t(`cmd.memoryDeleted`,{name:t}):M.t(`cmd.memoryNotFound`,{name:t}));return}if(e.length>0){let t=e.join(` `).trim(),i=(n?await n.read(t):null)??await r.read(t);i==null?o(`/memory ${t}`,`error`,M.t(`cmd.memoryNotFound`,{name:t})):a(i);return}let s=n?n.getInjection().trim():``,c=r.getInjection().trim();t.tui.modal.openModal({kind:`memory`,projectIndex:s,userIndex:c,...Si(n,r)})}async function wi(e,t){let n=M.t(`cmd.titleCompact`);if((e[0]??``).toLowerCase()===`log`){t.tui.panes.togglePane(`compactionLog`);return}if(!t.app.storage.memory){t.tui.info.showToast(n,M.t(`compact.unavailable`));return}t.tui.info.showToast(n,M.t(`compact.ing`)),t.tui.engine.pushEngineEvent({kind:`agentProcessing`,value:!0});try{let e=await t.state.session.compactNow();e.compacted?(t.tui.info.showToast(n,M.t(`compact.edResult`,{before:e.before,after:e.after})),t.callbacks.onContextCompacted()):t.tui.info.showToast(n,M.t(`compact.noop`))}catch(e){t.tui.info.showToast(n,M.t(`cmd.compactFailed`,{msg:e instanceof Error?e.message:String(e)}))}finally{t.tui.engine.pushEngineEvent({kind:`agentProcessing`,value:!1})}}const Ti=async(e,t)=>{let n=e[0];switch(n){case`memory-sync`:return Ei(e.slice(1),t);default:t.tui.info.showToast(`Workspace`,`/workspace ${n??``} — unknown subcommand. Use: memory-sync [status|enable|disable]`)}};async function Ei(e,t){let n=e[0]??`status`,r=t.app.workspaceRef;if(!r?.root){t.tui.info.showToast(`Workspace memory-sync`,`No local workspace identity yet — cannot configure memory sync.`);return}switch(n){case`status`:{let e=r.memorySyncEnabled===!0;t.tui.info.showToast(`Workspace memory-sync`,e?`Enabled — workspace memory (auto-memory/lessons) syncs to the remote store.`:`Disabled — workspace memory stays local (default).`);return}case`enable`:{if(!t.app.storage.remoteMemoryConfigured){t.tui.info.showToast(`Workspace memory-sync`,`No remote memory service configured (needs --session-url + remote.getAuth) — enabling now would have no effect.`);return}let e=await t.app.setWorkspaceMemorySyncEnabled(!0);t.tui.info.showToast(`Workspace memory-sync`,e?`Enabled. Next memory_record/learn calls will sync to the remote store.`:`Failed to enable — no workspace marker to update.`);return}case`disable`:{let e=await t.app.setWorkspaceMemorySyncEnabled(!1);t.tui.info.showToast(`Workspace memory-sync`,e?`Disabled. Workspace memory now stays local.`:`Failed to disable — no workspace marker to update.`);return}default:t.tui.info.showToast(`Workspace memory-sync`,`/workspace memory-sync ${n} — unknown subcommand. Use: status|enable|disable`)}}async function Di(t,n){let r=n.state.session,i=r.model?.id??M.t(`cmd.aboutModelNotSet`),a=h().length,o=Math.round(y()/(1024*1024*1024)),s=Math.round(g()/(1024*1024)),c=[{kind:`group`,title:M.t(`cmd.aboutGroupVersion`)},{kind:`row`,label:M.t(`cmd.aboutVersion`),value:`${ze} (build ${Le})`},{kind:`row`,label:M.t(`cmd.aboutBranch`),value:`dev`},{kind:`row`,label:M.t(`cmd.aboutCommit`),value:e},{kind:`group`,title:M.t(`cmd.aboutGroupRuntime`)},{kind:`row`,label:M.t(`cmd.aboutRuntime`),value:`Node.js ${process.version} · ${v()} ${m()} · ${ee()}`,tone:`muted`},{kind:`row`,label:M.t(`cmd.aboutCPU`),value:`${a} cores`,tone:`muted`},{kind:`row`,label:M.t(`cmd.aboutMemory`),value:`${o} GB total / ${Math.round(s)} MB free`,tone:`muted`},{kind:`row`,label:M.t(`cmd.aboutShell`),value:process.env.SHELL??`(unknown)`,tone:`muted`},{kind:`row`,label:M.t(`cmd.aboutTerminal`),value:process.env.TERM??`(unknown)`,tone:`muted`},{kind:`group`,title:M.t(`cmd.aboutGroupSession`)},{kind:`row`,label:M.t(`cmd.aboutModel`),value:i,tone:`secondary`}];r.id&&c.push({kind:`row`,label:M.t(`cmd.aboutSession`),value:r.id.slice(0,8)}),c.push({kind:`blank`},{kind:`text`,value:M.t(`cmd.aboutUpdateHint`),tone:`muted`}),n.tui.modal.openModal({kind:`info`,title:M.t(`cmd.titleAbout`),lines:[],dataListEntries:c})}async function Oi(e,t){return e.tui.modal.openModal({kind:`input`,...t})}function ki(e,t,n){return new Promise(r=>{e.tui.modal.openModal({kind:`confirm`,title:t,message:n,onConfirm:()=>r(!0),onCancel:()=>r(!1)})})}async function Ai(e,t){let n=t.app.feedbackRegistry.get();if(!n){t.tui.info.showToast(M.t(`cmd.titleFeedback`),M.t(`cmd.feedbackUnavailable`));return}let r=e.indexOf(`--repo`),i=r>=0?e[r+1]:void 0,a=await d({configuredRepo:t.app.settings.get(`feedback_repo`),cliRepoArg:i,cwd:t.app.workspaceDir});if(!a){t.tui.info.showToast(M.t(`cmd.titleFeedback`),M.t(`cmd.feedbackRepoUnresolved`));return}let o=await Oi(t,{title:M.t(`cmd.feedbackStepTitle`)});if(!o||o.trim().length===0)return;let s=await Oi(t,{title:M.t(`cmd.feedbackStepRepro`)})??void 0,c=await Oi(t,{title:M.t(`cmd.feedbackStepExpected`)})??void 0,l=await Oi(t,{title:M.t(`cmd.feedbackStepActual`)})??void 0,u=f(t.state.session.model?.id),p={title:o.trim(),reproduce:s,expected:c,actual:l,envInfo:u,repo:a},m=[s,c,l].filter(Boolean).join(`
18
- `).slice(0,300);if(!await ki(t,M.t(`cmd.feedbackConfirmTitle`),M.t(`cmd.feedbackConfirmMessage`,{title:p.title,bodyPreview:m})))return;if(t.tui.info.showToast(M.t(`cmd.titleFeedback`),M.t(`cmd.feedbackChannelSubmitting`)),n.submitIssueViaGh){let e=await n.submitIssueViaGh(p);if(e.ok){t.tui.info.showToast(M.t(`cmd.titleFeedback`),M.t(`cmd.feedbackCreated`,{url:e.url}));return}}let h=n.buildIssueUrl?.(p);if(!h){t.tui.info.showToast(M.t(`cmd.titleFeedback`),M.t(`cmd.feedbackUnavailable`));return}Fe(h),t.tui.info.showToast(M.t(`cmd.titleFeedback`),M.t(`cmd.feedbackCreated`,{url:h}))}function ji(e,t,n){let r=Te(e,t);if(r)return r;let i=e.split(`/`).pop();if(i)return ue({cwd:t??process.cwd(),homedir:n??_()}).find(e=>e.id===i)?.dir}function Mi(e,t,n){try{let r=ji(e,t,n);if(!r)return;let i=O(r,T),a=ve(A(i,`utf-8`),i);return a?a.codeProviderIds?.[0]??a.contributes?.providers?.[0]?.id??a.contributes?.oauth?.[0]?.id:void 0}catch{return}}function Ni(e,t,n){return!e||t.get(e)?[{label:n.oauth.label,value:`oauth`,detail:n.oauth.detail},{label:n.apiKey.label,value:`key`,detail:n.apiKey.detail}]:[{label:n.apiKey.label,value:`key`,detail:n.apiKey.detail}]}const Pi={provider:`install-provider`,authentication:`connect-provider`,model:`choose-model`,ready:`send-first-prompt`,"first-prompt":`none`};function Fi(e){if(!e.providerInstalled)return`provider`;if((e.connectedProviderIds??[]).length===0)return`authentication`;let t=e.usableModelIds??[];if(t.length===0)return`model`;let n=e.selectedModelId;return!n||!(e.selectedModelUsableInMainSession??t.includes(n))?`model`:e.firstPromptSubmitted?`first-prompt`:`ready`}function Ii(e){let t=Fi(e),n=e.providerCandidates??[],r=e.connectedProviderIds??[],i=e.usableModelIds??[],a=e.firstPromptSubmitted??!1,o=(t===`provider`||t===`authentication`||t===`model`)&&!(e.dismissed??!1);return{stage:t,provider:{installed:e.providerInstalled,candidates:n},authentication:{connectedProviderIds:r},model:{...e.selectedModelId===void 0?{}:{selectedId:e.selectedModelId},usableIds:i},firstPrompt:{submitted:a},recommendation:{action:Pi[t],stage:t,autoOpen:o}}}function Li(e){return e.stage===`ready`||e.stage===`first-prompt`}function Ri(e,t){return e.get(t)===!0}function zi(e){return{personalizationSeen:Ri(e,`has_completed_onboarding`),dismissed:Ri(e,`has_completed_wizard`)||Ri(e,`wizard_dont_show_again`),firstPromptSubmitted:typeof e.get(`first_prompt_submitted_at`)==`number`}}const Bi=`__otto_setup__`;async function Vi(e){let t=zi(e.settings),n=e.listProviders(),r=(await Promise.all(n.map(async t=>({provider:t,source:await e.getAuthSource(t).catch(()=>null)})))).filter(e=>e.source!=null).map(e=>e.provider),i=e.listModels().filter(e=>e.id!==Bi),a=(await Promise.all(i.map(async t=>{try{let{usable:n}=await e.isModelUsable({provider:t.provider,api:t.api});return n?t.id:null}catch{return null}}))).filter(e=>e!==null),o=e.getSelectedModelId(),s=o!==void 0&&o!==Bi?i.find(e=>e.id===o):void 0,c=s&&e.isModelUsableInMainSession?await e.isModelUsableInMainSession({provider:s.provider,api:s.api}).then(({usable:e})=>e).catch(()=>!1):void 0;return Ii({providerInstalled:e.hasProviderPlugin(),...e.providerCandidates?{providerCandidates:e.providerCandidates}:{},connectedProviderIds:r,usableModelIds:a,...o!==void 0&&o!==Bi?{selectedModelId:o}:{},...c===void 0?{}:{selectedModelUsableInMainSession:c},firstPromptSubmitted:t.firstPromptSubmitted,dismissed:t.dismissed})}function Hi(e){return{hasProviderPlugin:()=>e.modelRegistry.hasAnyPluginSourcedModel(),listProviders:()=>e.authStore.listProviders(),getAuthSource:t=>e.authStore.getAuthSource(t),listModels:()=>e.modelRegistry.getAll().map(e=>({id:e.id,provider:e.provider,api:e.api})),isModelUsable:e.isModelUsable,...e.isModelUsableInMainSession?{isModelUsableInMainSession:e.isModelUsableInMainSession}:{},getSelectedModelId:e.selectedModelId,settings:{get:t=>e.settings.get(t)},...e.providerCandidates?{providerCandidates:e.providerCandidates}:{}}}var Ui=class{snapshot=null;listeners=new Set;constructor(e){this.deps=e}current(){return this.snapshot}async refresh(){let e=await Vi(this.deps);this.snapshot=e;for(let t of this.listeners)try{t(e)}catch{}return e}subscribe(e){return this.listeners.add(e),()=>{this.listeners.delete(e)}}};function Wi(e,t){return(e.envKeys??[]).some(e=>{let n=t[e];return typeof n==`string`&&n.trim().length>0})?0:e.supportsOAuth?1:2}function Gi(e,t){return e.map((e,n)=>({provider:e,index:n,rank:Wi(e,t)})).sort((e,t)=>e.rank-t.rank||e.index-t.index).map(e=>e.provider)}function Ki(e){try{let{createRequire:t}=xt(`node:module`),{readFileSync:n}=xt(`node:fs`),{dirname:r,join:i}=xt(`node:path`),a=i(r(t(import.meta.url).resolve(`${e}/package.json`)),`otto-plugin.json`),o=JSON.parse(n(a,`utf8`)).contributes??{},s=(o.providers??[]).map(e=>e.envKey).filter(e=>typeof e==`string`&&e.length>0);return{supportsOAuth:!!o.oauth,envKeys:s}}catch{return{supportsOAuth:!1,envKeys:[]}}}function qi(e){let t=e.map((e,t)=>({model:e,index:t})).sort((e,t)=>Number(t.model.usable)-Number(e.model.usable)||e.index-t.index).map(e=>e.model),n=Ji(t);return t.map(e=>({...e,recommended:e.usable&&e.id===n}))}function Ji(e){return e.find(e=>e.usable)?.id}const Yi={hasReadme:!1,hasPackageManifest:!1,hasTestConfig:!1,isEmpty:!1},Xi=new Set([`node_modules`,`.git`,`.hg`,`.svn`,`.venv`,`venv`,`__pycache__`,`.pytest_cache`,`.mypy_cache`,`.tox`,`dist`,`build`,`.next`,`.nuxt`,`.cache`,`.DS_Store`]),Zi=/^readme(\.(md|markdown|txt|rst))?$/i,Qi=new Set([`package.json`,`pyproject.toml`,`setup.py`,`requirements.txt`,`Cargo.toml`,`go.mod`,`Gemfile`,`composer.json`,`pom.xml`,`build.gradle`,`build.gradle.kts`,`Package.swift`]),$i=/^(jest\.config|vitest\.config|karma\.conf|\.mocharc)(\.(js|ts|mjs|cjs|json))?$/i,ea=new Set([`pytest.ini`,`tox.ini`,`phpunit.xml`,`phpunit.xml.dist`,`setup.cfg`]);async function ta(e,t){let n;try{n=await t.readdir(e)}catch{return Yi}let r=n.filter(e=>!Xi.has(e.name)),i=r.length===0,a=!1,o=!1,s=!1,c=0;for(let e of r)if(c>=2e3||(c++,e.isFile()&&(!a&&Zi.test(e.name)&&(a=!0),!o&&Qi.has(e.name)&&(o=!0),!s&&(ea.has(e.name)||$i.test(e.name))&&(s=!0),a&&o&&s)))break;return{hasReadme:a,hasPackageManifest:o,hasTestConfig:s,isEmpty:i}}function na(e){if(e.isEmpty)return[`suggestion.emptyProject`];let t=[];return e.hasReadme&&t.push(`suggestion.hasReadme`),e.hasPackageManifest&&t.push(`suggestion.hasPackageManifest`),e.hasTestConfig&&t.push(`suggestion.hasTestConfig`),t.length>0?t:[`suggestion.unrecognized`]}const ra=`oxygen-provider`,ia=new Set([`plugin-oxygen`,ra]);async function aa(e){try{let{makeRegistryClient:t}=await import(`./registry-BOX7DaxS.js`),{registries:n}=await t(e.app).loadAll();return n.some(e=>e.entries.some(e=>ia.has(e.id)||e.source===`@x-otto/plugin-oxygen`||e.source.includes(`/plugin-oxygen`)||e.subPath?.endsWith(`plugin-oxygen`)))}catch{return!1}}async function oa(e){let t=e.tui,n=e.app,r=await Vi(Hi({modelRegistry:n.modelRegistry,authStore:n.authStore,settings:n.settings,selectedModelId:()=>e.state.session?.model?.id,isModelUsable:N(n.authStore,`delegation`),isModelUsableInMainSession:N(n.authStore,`main-session`)})),i=n.authStore.listProviders(),a=[];r.provider.installed&&a.push(0),r.authentication.connectedProviderIds.length>0&&a.push(1),r.model.usableIds.length>0&&a.push(2);let s=(()=>{for(let e=0;e<3;e++)if(!a.includes(e))return e;return 3})(),c=await aa(e),l=Object.entries(o).filter(([e,t])=>t.capabilities.includes(`provider`)&&(e!==ra||c)),u={"anthropic-provider":`Claude 全系列 · OAuth 一键登录`,"deepseek-provider":`高性价比 · API-key 接入 · 中文友好`,"openai-codex-provider":`GPT / Codex 系列 · 需要 API key 或 OAuth`,"github-copilot-provider":`订阅即用 · GitHub 账号授权`,"cursor-provider":`Cursor IDE 内置 · 需 Cursor 订阅`,"oxygen-provider":`企业级 · 按组织授权`},d=Gi(l.map(([e,t])=>({id:e,...Ki(t.pkg)})),process.env).map(({id:e})=>({label:e,value:e,detail:u[e]??o[e]?.pkg??e})),f=e=>Ni(e,n.authStore.oauth,{oauth:{label:M.t(`setup.loginOAuth`),detail:`Open browser, complete authorization — no copy-paste needed.`},apiKey:{label:M.t(`setup.loginApiKey`),detail:`Generate a key on your provider dashboard and paste it here.`}}),p=async()=>{let t=await Vi(Hi({modelRegistry:n.modelRegistry,authStore:n.authStore,settings:n.settings,selectedModelId:()=>e.state.session?.model?.id,isModelUsable:N(n.authStore,`delegation`),isModelUsableInMainSession:N(n.authStore,`main-session`)})),r=N(n.authStore,`delegation`),i=new Set(t.model.usableIds),a=n.modelRegistry.getAll().filter(e=>e.id!==`__otto_setup__`);return qi((await Promise.all(a.map(async e=>{let t=i.has(e.id);return t?{model:e,usable:t,reason:void 0}:{model:e,usable:!1,reason:(await r({provider:e.provider,api:e.api}).catch(()=>({usable:!1,reason:`unauthenticated`}))).reason??`unauthenticated`}}))).map(({model:e,usable:t,reason:n})=>({id:e.id,label:e.name,detail:`${e.provider} · ${e.strengths?.join(`, `)??``}`,usable:t,...n?{reason:n}:{}}))).map(e=>({label:e.label,value:e.id,detail:e.detail,recommended:e.recommended,...e.reason?{unusableReason:e.reason}:{}}))},m=await p(),h=i.length===1?i[0]:void 0,g=na(await ta(n.workspaceDir,{readdir:e=>rt(e,{withFileTypes:!0})})).map(e=>M.t(e));t.modal.openModal({kind:`wizard`,title:M.t(`setup.title`),welcomeTitle:M.t(`setup.welcomeTitle`),welcomeGreeting:``,welcomeDescription:M.t(`setup.welcomeDescription`),welcomeDontShowAgainLabel:M.t(`setup.welcomeDontShowAgain`),welcomeStartLabel:M.t(`setup.welcomeStart`),welcomeCancelLabel:M.t(`setup.welcomeCancel`),stepNames:[M.t(`setup.stepNameProvider`),M.t(`setup.stepNameLogin`),M.t(`setup.stepNameModel`),M.t(`setup.stepNameStart`)],stepSubtitles:[M.t(`setup.step1Subtitle`),M.t(`setup.step3Subtitle`),M.t(`setup.step4Subtitle`),M.t(`setup.step5Done`)],initialCompleted:a,initialCurrent:s,providerOptions:d,providerAuthOptions:f,authProviderName:h,modelOptions:m,onRefreshModelOptions:p,examplePrompts:g,workspacePath:n.workspaceDir,async onInstallProvider(t,n){n(`Resolving package…`);try{let{runPluginInstall:r}=await Promise.resolve().then(()=>Wr),i=!1,a=await r(t,e,{autoTrust:!0,onProgress:e=>n(`${e}…`),onPendingCapabilities:()=>{i=!0}}),s=o[t]?.pkg??t;if(!a)return{ok:!1,error:M.t(`setup.installFailed`,{reason:t})};let c=[];try{let{readHighRiskCapabilities:e}=await import(`@x-otto/coding`),t=ji(s);t&&(c=e(t))}catch{}return{ok:!0,providerId:Mi(s),capabilities:c,pendingCapabilities:i}}catch(e){return{ok:!1,error:e instanceof Error?e.message:String(e)}}},async onProviderOAuthStart(t){let r=t||i[0]||n.authStore.listProviders()[0];if(!r)return null;let a=new AbortController;try{let{openBrowser:t}=await import(`@x-otto/shared`),i,o,s,c=n.authStore.login(r,{signal:a.signal,onAuth:e=>{o=e.code,s=e.instructions,e.url&&(i=e.url,e.code||t(e.url))},onProgress:()=>{},onPrompt:async()=>``});return c.catch(()=>{}),await new Promise(e=>setTimeout(e,200)),{authorizationUrl:i??``,code:o,instructions:s,openAgain:()=>{i&&t(i)},poll:async()=>{try{return await Promise.race([c.then(()=>`done`),new Promise(e=>setTimeout(()=>e(`pending`),500))])===`done`?(await e.callbacks.refreshModelsNow(),`done`):`pending`}catch(e){let t=e instanceof Error?e:void 0;if(t?.code===`OAUTH_CANCELLED`)return{status:`error`,reason:`cancelled`};let n=new Set([`ENOTFOUND`,`ECONNREFUSED`,`ECONNRESET`,`ETIMEDOUT`,`EAI_AGAIN`,`EHOSTUNREACH`,`ENETUNREACH`,`UND_ERR_CONNECT_TIMEOUT`]),r=t?.code,i=t?.cause?.code;return r&&n.has(r)||i&&n.has(i)?{status:`error`,reason:`network`}:{status:`error`,reason:`rejected`}}},cancel:()=>{a.abort()}}}catch{return null}},async onSubmitProviderApiKey(t,r){let a=t||i[0]||n.authStore.listProviders()[0];if(!a)return{ok:!1,error:`No provider selected.`};try{return await n.authStore.setCredentialKey(a,r),await n.authStore.save(),await e.callbacks.refreshModelsNow(),{ok:!0}}catch(e){return{ok:!1,error:e instanceof Error?e.message:String(e)}}},onOpenProxySettings(){import(`./proxy-BvdBsB1O.js`).then(({handleProxy:t})=>t([],e)).catch(()=>{})},async onSelectModel(t){if(await e.callbacks.applyModel(t),!e.state.modelReady)throw Error(`Model selected but not ready. Check your credentials and try /model refresh.`)},onComplete(){e.callbacks.refreshModelsNow().catch(()=>{}),n.settings.persist({has_completed_wizard:!0},`global`).catch(()=>{})},onDismiss(){},onDontShowAgain(e){n.settings.persist({wizard_dont_show_again:e},`global`).catch(()=>{})}})}async function sa(e,t){await oa(t)}let ca;function la(e){ca=e}const ua=async(e,t)=>{let n=ca;if(!n){t.tui.info.showToast(`Schedule`,`Schedule system not available`);return}let r=e[0];switch(r){case void 0:return da(t);case`list`:return fa(n,t);case`add`:return pa(e.slice(1),n,t);case`remove`:return ma(e[1],n,t);case`run`:return ha(e[1],n,t);case`enable`:return _a(e[1],!0,n,t);case`disable`:return _a(e[1],!1,n,t);case`logs`:return va(e[1],t);case`cancel`:return ga(e[1],t);default:t.tui.info.showToast(`Schedule`,`/schedule ${r} — unknown subcommand. Use: add|list|remove|run|enable|disable|cancel|logs`)}};async function da(e){let t=(e.app.getPluginPanelRegistrations?.()??[]).find(e=>e.pluginId===`plugin-schedule`);if(!t){e.tui.info.showToast(`Schedule`,`Schedule panel not installed — run "otto extension install plugin-schedule"`);return}e.tui.modal.openModal({kind:`pluginPanel`,panelInfo:{title:t.title,modulePath:t.modulePath,exportName:t.exportName,pluginId:t.pluginId},onClose:()=>{}})}async function fa(e,t){let n=e.list(),r=e.isFireOwner()?[]:e.fireOwnerFailureReason()===`network-error`?[`[read-only — could not reach the remote schedule service; check network/persistenced connectivity]`]:[`[read-only — another terminal holds the fire-ownership lease for this workspace]`];if(n.length===0){t.tui.info.showToast(`Schedule`,r.length>0?`No scheduled tasks. ${r[0]}`:`No scheduled tasks`);return}let i=[];for(let e of n){let t=e.lastFireFailed?`✕`:e.enabled?`◉`:`○`,n=e.recurring?e.cronExpression:`one-shot`,r=new Date(e.nextFireAt).toLocaleString(),a=e.lastFireFailed&&e.lastFireError?` (failed: ${e.lastFireError})`:``;i.push(`${t} ${e.id} ${e.name}${a}`),i.push(` ${n} next: ${r}`)}t.tui.messages.pushMessage({role:`command_echo`,command:`/schedule`,status:r.length>0?`warn`:`ok`,summary:r.length>0?r[0]:`${n.length} 个已排定任务`,detail:i.join(`
19
- `)}),t.tui.panes.togglePane?.(`schedulePane`)}async function pa(e,t,n){if(e.length<2){n.tui.info.showToast(`Schedule`,`/schedule add [--once] [--session] <cron> <prompt>`);return}let r=!1,i,a=[...e],o=a.indexOf(`--once`);o!==-1&&(r=!0,a.splice(o,1));let s=a.indexOf(`--session`);if(s!==-1&&(i=`session`,a.splice(s,1)),a.length<2){n.tui.info.showToast(`Schedule`,`Opening schedule panel in create mode`),da(n);return}let c=a[0],l=a.slice(1).join(` `);try{let e=t.add({name:l.slice(0,40),prompt:l,cronExpression:c,recurring:!r,origin:`user`,target:i}),a=r?`one-shot`:`recurring`,o=new Date(e.nextFireAt).toLocaleString(),s=e.target===`session`?` [fires into this conversation]`:``;n.tui.info.showToast(`Schedule`,`${e.id}: ${e.name} (${a})${s} next: ${o}`)}catch(e){n.tui.info.showToast(`Schedule`,`Failed: ${e instanceof Error?e.message:String(e)}`)}}async function ma(e,t,n){if(!e){n.tui.info.showToast(`Schedule`,`/schedule remove <id>`);return}let r=t.remove(e);n.tui.info.showToast(`Schedule`,r?`Removed ${e}`:`Schedule "${e}" not found`)}async function ha(e,t,n){if(!e){n.tui.info.showToast(`Schedule`,`/schedule run <id>`);return}try{t.runNow(e),n.tui.info.showToast(`Schedule`,`Triggering ${e}...`)}catch(e){n.tui.info.showToast(`Schedule`,`Failed: ${e instanceof Error?e.message:String(e)}`)}}async function ga(e,t){let n=ca;if(!n){t.tui.info.showToast(`Schedule`,`Schedule system not available`);return}if(!e){t.tui.info.showToast(`Schedule`,`/schedule cancel <id>`);return}let r=n.cancel(e);r.ok?t.tui.info.showToast(`Schedule`,`Canceled "${e}"`):t.tui.info.showToast(`Schedule`,`Cannot cancel "${e}": ${r.reason??`unknown`}`)}async function _a(e,t,n,r){if(!e){r.tui.info.showToast(`Schedule`,`/schedule ${t?`enable`:`disable`} <id>`);return}let i=n.update(e,{enabled:t});r.tui.info.showToast(`Schedule`,i?`Schedule ${e} ${t?`enabled`:`disabled`}`:`Schedule "${e}" not found`)}async function va(e,t){let n=Ve(Re,`schedule-logs`),r;try{r=Ge(n)}catch{t.tui.info.showToast(`Schedule`,`No schedule logs found`);return}if(e&&(r=r.filter(t=>t.startsWith(e+`-`))),r.length===0){t.tui.info.showToast(`Schedule`,e?`No logs for schedule "${e}"`:`No schedule logs found`);return}r.sort().reverse();let i=r.slice(0,5),a=[];for(let e of i)try{let t=A(Ve(n,e),`utf-8`).trim(),r=e.indexOf(`-`),i=r>0?e.slice(0,r):e;a.push(`${i} ${t}`)}catch{a.push(`${e} (unreadable)`)}let o=r.length-i.length;o>0&&a.push(`... and ${o} more entries`),t.tui.messages.pushMessage({role:`command_echo`,command:`/schedule logs`,summary:`${r.length} 条日志文件`,detail:a.join(`
20
- `)})}function Z(e){return ln(e.state.session.session.getDrafts()??[])}function ya(e,t){e.state.session.session.setDrafts(t),e.app.sessionManager.save(e.state.session.id).catch(()=>{}),e.tui.stores.tasks.setDrafts(Z(e))}const ba=async(e,t)=>{let n=e[0];switch(n){case void 0:case`list`:return xa(e.slice(1),t);case`save`:return Sa(e.slice(1),t);case`load`:return Ca(e.slice(1),t);case`delete`:case`remove`:return wa(e.slice(1),t);default:t.tui.info.showToast(`Draft`,`/draft ${n} — unknown subcommand. Use: save|list|load|delete`)}};async function xa(e,t){let n=Z(t);t.tui.stores.tasks.setDrafts(n),t.tui.panes.togglePane(`draftPane`,!0),n.length===0&&t.tui.info.showToast(`Draft`,`No drafts. Save one with Ctrl+S`)}async function Sa(e,t){if(e.length===0){t.tui.info.showToast(`Draft`,`/draft save <name?> <text>`);return}let[n,...r]=e,i=r.length>0,a=i?n:void 0,o=i?r.join(` `):e.join(` `),s=Z(t),c=dn(a,o,s),l=fn([...s,c]);try{ya(t,l)}catch(e){t.tui.info.showToast(`Draft`,`Save failed: ${e instanceof Error?e.message:String(e)}`);return}t.tui.info.showToast(`Draft`,`Saved "${c.name}"`)}async function Ca(e,t){let n=e.join(` `);if(!n){t.tui.info.showToast(`Draft`,`/draft load <name>`);return}let r=Z(t).find(e=>e.name===n);if(!r){t.tui.info.showToast(`Draft`,`Draft "${n}" not found`);return}t.tui.messages.pushMessage({role:`assistant`,content:[{type:`text`,text:r.text}]})}async function wa(e,t){let n=e.join(` `);if(!n){t.tui.info.showToast(`Draft`,`/draft delete <name>`);return}let r=Z(t),i=r.find(e=>e.name===n);if(!i){t.tui.info.showToast(`Draft`,`Draft "${n}" not found`);return}let a=r.filter(e=>e.id!==i.id);try{ya(t,a)}catch(e){t.tui.info.showToast(`Draft`,`Delete failed: ${e instanceof Error?e.message:String(e)}`);return}t.tui.info.showToast(`Draft`,`Removed "${i.name}"`)}const Ta=async(e,t)=>{let n=e[0];switch(n){case void 0:case`list`:return Ea(t);case`remove`:return Da(e[1],t);case`move`:return Oa(e[1],e[2],t);case`clear`:return ka(t);default:t.tui.info.showToast(`Queue`,`/queue ${n} — unknown subcommand. Use: list|remove|move|clear`)}};async function Ea(e){e.tui.panes.togglePane(`queuePane`,!0)}async function Da(e,t){let n=e?Number.parseInt(e,10):NaN;if(!Number.isInteger(n)||n<1){t.tui.info.showToast(`Queue`,`/queue remove <index> (1-based)`);return}t.tui.panes.removeQueuedAt(n-1),t.tui.info.showToast(`Queue`,`Removed item ${n}`)}async function Oa(e,t,n){let r=e?Number.parseInt(e,10):NaN;if(!Number.isInteger(r)||r<1||t!==`up`&&t!==`down`){n.tui.info.showToast(`Queue`,`/queue move <index> <up|down> (1-based)`);return}let i=t===`down`?1:-1;n.tui.panes.moveQueuedItem(r-1,i),n.tui.info.showToast(`Queue`,`Moved item ${r} ${t}`)}async function ka(e){e.tui.panes.clearQueue(),e.tui.info.showToast(`Queue`,`Queue cleared`)}const Aa=async(e,t)=>{let{session:n,agentProcessing:r}=t.state;if(n.isPaused&&!n.isBusy){n.resumeRun(),t.tui.info.showToast(M.t(`cmd.titleInfo`),M.t(`cmd.runResumedByCommand`)),ja(t);return}if(n.isPaused&&n.isBusy){n.cancelPauseRun()?t.tui.info.showToast(M.t(`cmd.titleInfo`),M.t(`cmd.pauseCancelled`)):(n.resumeRun(),t.tui.info.showToast(M.t(`cmd.titleInfo`),M.t(`cmd.runResumedByCommand`))),ja(t);return}if(r){n.pauseRun()?t.tui.info.showToast(M.t(`cmd.titlePauseRequested`),M.t(`cmd.runWillPauseAfterTurn`)):t.tui.info.showToast(M.t(`cmd.titleInfo`),M.t(`cmd.noRunningTaskToPause`)),ja(t);return}t.tui.info.showToast(M.t(`cmd.titleInfo`),M.t(`cmd.nothingToPause`))};function ja(e){let t=e.callbacks.refreshSlashCommands?.();t&&e.tui.plugins.setCommands(t)}function Ma(e){let t;try{let n=Ue(e,`r`);try{t=Buffer.alloc(512);let e=We(n,t,0,512,0);t=t.subarray(0,e)}finally{He(n)}}catch{return!1}if(t.length===0)return!1;let n=0;for(let e of t){if(e===0)return!0;!(e>=32&&e<127)&&!(e===9||e===10||e===13)&&!(e>=192&&e<=253)&&!(e>=128&&e<=191)&&n++}return n/t.length>.3}function Na(e){return e>=1048576?`${(e/1048576).toFixed(1)} MB`:e>=1024?`${(e/1024).toFixed(1)} KB`:`${e} B`}function Pa(e){let t;try{t=Ge(e)}catch{return[]}let n=[];for(let r of t)try{let t=Ke(O(e,r));n.push({name:r,isDir:t.isDirectory(),size:t.isDirectory()?void 0:t.size})}catch{}return n}function Fa(e){return[...e].sort((e,t)=>e.isDir===t.isDir?e.name.localeCompare(t.name):e.isDir?-1:1)}function Q(e,t,n,r){let i=Fa(Pa(n)),a=Be(t,n),o=a===``?M.t(`cmd.openBrowserSubtitleRoot`):M.t(`cmd.openBrowserSubtitleDir`,{relDir:a}),s=n!==t,c=i.map(e=>({label:e.isDir?`${e.name}/`:e.name,value:e.name,detail:e.isDir?void 0:Na(e.size??0)}));e.tui.modal.openModal({kind:`select`,title:M.t(`cmd.titleOpen`),subtitle:o,searchable:!0,options:c,initialFilter:r.get(n)??``,onFilterChange:e=>{r.set(n,e)},onSelect:i=>{let a=O(n,i),o;try{o=Ke(a).isDirectory()}catch{e.tui.info.showToast(M.t(`cmd.titleOpen`),M.t(`cmd.openNotFound`,{path:i}));return}if(o){Q(e,t,a,r);return}Ia(e,a,i,()=>{Q(e,t,n,r)}).catch(()=>{e.tui.info.showToast(M.t(`cmd.titleOpen`),M.t(`cmd.openNotFound`,{path:i}))})},onCancel:s?()=>Q(e,t,D(n),r):()=>{}})}async function Ia(e,t,n,r){if(Ma(t)){e.tui.info.showToast(M.t(`cmd.titleOpen`),M.t(`cmd.openBinaryRejected`,{path:n}));return}let{content:i,truncated:a}=await Ie(t);e.tui.modal.openModal({kind:`fileViewer`,path:n,content:i,preTruncated:a,onDismiss:r??(()=>{})})}async function La(e,t){let n=t.app.workspaceDir??process.cwd(),r=e.join(` `).trim(),i=new Map;if(!r){Q(t,n,n,i);return}let a=Ve(n,r),o=Be(n,a).startsWith(`..`);if(!k(a)){if(o){t.tui.info.showToast(M.t(`cmd.titleOpen`),M.t(`cmd.openNotFound`,{path:r}));return}let e=D(a);for(;e!==n&&e!==D(e)&&!k(e);)e=D(e);if(k(e)&&Ke(e).isDirectory()){Q(t,n,e,i);return}t.tui.info.showToast(M.t(`cmd.titleOpen`),M.t(`cmd.openNotFound`,{path:r}));return}if(Ke(a).isDirectory()){if(o){t.tui.info.showToast(M.t(`cmd.titleOpen`),M.t(`cmd.openNotFound`,{path:r}));return}Q(t,n,a,i);return}await Ia(t,a,r)}var Ra=bt({DISPATCHABLE_COMMAND_NAMES:()=>Ha,ENGINE_BUILTIN_COMMANDS:()=>Va,HELP_GROUP_ORDER:()=>za,SAFE_COMMAND_NAMES:()=>Ba,SLASH_COMMANDS:()=>$,dispatchSlashCommand:()=>Ua,handleCompact:()=>wi,handleMemory:()=>Ci});const za=[`session`,`model`,`agent`,`debug`,`ui`,`other`],$=[{name:`clear`,handler:wn,engineBuiltin:!0,group:`session`,description:`Clear screen and reset interface state`},{name:`compact`,handler:wi,group:`session`,description:`Compact context now, or /compact log for recent compaction/prune event details`},{name:`memory`,aliases:[`mem`],handler:Ci,group:`session`,description:`Project + user memory: /memory [user|project|<name>|forget <name>]`},{name:`workspace`,handler:Ti,safe:!0,group:`session`,description:`Manage workspace settings: /workspace memory-sync [status|enable|disable] (RFC-164 R-form remote memory sync opt-in)`},{name:`status`,handler:X,safe:!0,engineBuiltin:!0,group:`session`,description:`Session status & diagnostics: /status [perf|context|cache|diagnose|services] (RFC-367)`},{name:`open`,handler:La,safe:!0,group:`session`,description:`Open a file, or browse the current directory to find one: /open [path] (RFC-189)`},{name:`model`,aliases:[`m`],handler:oi,group:`model`,description:`Switch model; /model [<id>|refresh]`},{name:`auth`,aliases:[`login`],handler:Y,group:`model`,description:`Connect a model provider (OAuth or API key); /auth [<provider>]`},{name:`usage`,handler:_i,safe:!0,engineBuiltin:!0,group:`model`,description:`Show provider usage quota snapshot (Anthropic OAuth subscription plans only)`},{name:`logout`,handler:si,group:`model`,description:`Remove stored credentials for a provider; /logout [<provider>]`},{name:`job`,handler:ei,safe:!0,group:`agent`,description:`Start a background agent job: /job <directive> (worktree-isolated, full tools incl. MCP)`},{name:`schedule`,handler:ua,safe:!0,group:`agent`,description:`Manage scheduled tasks: /schedule add|list|remove|run|enable|disable <args>`},{name:`delegates`,handler:$r,safe:!0,group:`agent`,description:`Toggle the Delegates panel (↑↓ select · k kill · o output · a apply)`},{name:`diagnose`,handler:(e,t)=>X([`diagnose`,...e],t),safe:!0,group:`debug`,deprecated:!0,description:`Deprecated: use /status diagnose`},{name:`context`,handler:(e,t)=>X([`context`,...e],t),safe:!0,group:`debug`,deprecated:!0,description:`Deprecated: use /status context`},{name:`perf`,handler:(e,t)=>X([`perf`,...e],t),safe:!0,group:`debug`,deprecated:!0,description:`Deprecated: use /status perf`},{name:`cache-stats`,handler:(e,t)=>X([`cache-stats`,...e],t),safe:!0,group:`debug`,deprecated:!0,description:`Deprecated: use /status cache`},{name:`services`,handler:(e,t)=>X([`services`,...e],t),safe:!0,group:`debug`,deprecated:!0,description:`Deprecated: use /status services`},{name:`gallery`,handler:hi,safe:!0,group:`debug`,envGate:`OTTO_DEV`,description:`Open the TUI component gallery (all component examples; dev only, OTTO_DEV=1)`},{name:`trace-gc`,handler:In,group:`debug`,description:`Trace TTL lifecycle GC: /trace-gc [--ttl-days N] [--apply]. Cleans stale session trace files (not session data). TTL is based on the session's last agent engine activity time, not your last view/interaction time.`},{name:`session-archive-export`,handler:Rn,group:`debug`,description:`Archive-export a cold session: /session-archive-export <sessionId> [--out <path>] [--and-delete]. Exports full session entries as JSON; optional --and-delete removes from DB after checksum verification + confirmation.`},{name:`effort`,handler:(e,t)=>G([`effort`,...e],t),group:`ui`,deprecated:!0,description:`Deprecated: use /preference effort`},{name:`preference`,aliases:[`pref`],handler:G,safe:!0,group:`ui`,description:`Preferences: /preference [general|lang|theme|keybindings|shortcuts|effort|proxy] (RFC-367)`},{name:`trust`,handler:(e,t)=>J([`trust`,...e],t),safe:!0,group:`ui`,deprecated:!0,description:`Deprecated: use /extension trust`},{name:`notification`,aliases:[`notif`],handler:Br,group:`ui`,description:`Toggle the notification center panel (≡ ctrl+n)`},{name:`draft`,handler:ba,safe:!0,group:`ui`,description:`Manage saved drafts (≡ Ctrl+S save, Ctrl+O open panel): /draft [list|save <name?> <text>|load <name>|delete <name>]`},{name:`queue`,handler:Ta,safe:!0,group:`ui`,description:`Open the queued-commands panel (≡ ctrl+q): /queue [list|remove <index>|move <index> <up|down>|clear]`},{name:`keybindings`,aliases:[`kb`],handler:(e,t)=>G([`keybindings`,...e],t),safe:!0,group:`ui`,deprecated:!0,description:`Deprecated: use /preference keybindings`},{name:`shortcuts`,handler:(e,t)=>G([`shortcuts`,...e],t),safe:!0,group:`ui`,deprecated:!0,description:`Deprecated: use /preference shortcuts`},{name:`proxy`,handler:(e,t)=>G([`proxy`,...e],t),group:`ui`,deprecated:!0,description:`Deprecated: use /preference proxy`},{name:`help`,aliases:[`h`,`?`],safe:!0,engineBuiltin:!0,group:`other`,description:`Show available commands`,handler:async(e,t)=>Rr(e,t,$)},{name:`exit`,aliases:[`quit`,`q`],safe:!0,engineBuiltin:!0,group:`other`,tuiHidden:!0,description:`Exit the TUI; /exit --restart to restart into the same session`},{name:`abort`,engineBuiltin:!0,group:`other`,tuiHidden:!0,description:`Abort the current agent run`},{name:`pause`,aliases:[`continue`],handler:Aa,safe:!0,group:`other`,description:`Pause after current turn finishes (toggle with /continue)`},{name:`copy`,engineBuiltin:!0,group:`other`,tuiHidden:!0,description:`Copy last assistant response`},{name:`resume`,handler:En,group:`other`,description:`List and switch to an existing session (--workspace <id>, --archived, --all)`},{name:`rename`,handler:Tn,safe:!0,group:`session`,description:`Set a custom title for the current session (/rename <new title>)`},{name:`a2ui-action`,handler:Fn,safe:!1,group:`session`,description:`Trigger A2UI interactive component action (/a2ui-action btn1 click)`},{name:`reload`,handler:Dn,group:`other`,description:`Hot-reload capabilities (MCP / providers / declarative agents) without restart`},{name:`upgrade`,group:`other`,description:`Check for updates (/upgrade --check for extensions, /upgrade for otto CLI)`,handler:async(e,t)=>{if(e.includes(`--check`)){await Ur(e,t);return}await Lr(e,t)||await Ir(e,t)}},{name:`about`,handler:Di,safe:!0,group:`other`,description:`Show version, build, and environment info (/about)`},{name:`setup`,handler:sa,safe:!0,group:`other`,description:`Show onboarding progress (provider → login → model) with a jump-to-next-step button (/setup)`},{name:`extension`,aliases:[`extensions`,`ext`],handler:J,group:`other`,description:`Manage extensions: /extension [trust|install|registry|search|update] or open panel (RFC-367)`},{name:`install`,handler:(e,t)=>J([`install`,...e],t),safe:!0,group:`other`,deprecated:!0,description:`Deprecated: use /extension install`},{name:`registry`,handler:(e,t)=>J([`registry`,...e],t),safe:!0,group:`other`,deprecated:!0,description:`Deprecated: use /extension registry`},{name:`search`,handler:(e,t)=>J([`search`,...e],t),safe:!0,group:`other`,deprecated:!0,description:`Deprecated: use /extension search`},{name:`permissions`,aliases:[`perms`],handler:Fr,safe:!0,group:`other`,description:`View / clear the always-allow list (/permissions [clear])`},{name:`feedback`,handler:Ai,group:`other`,description:`Report an issue or send feedback via GitHub (/feedback [--repo <owner/repo>])`},{name:`archive`,handler:kn,safe:!0,description:`Toggle archive state (archived disables further input); /archive [<id>]`},{name:`session`,handler:Nn,description:`Session management: /session fork | /session unlock <id> [--force] | /session kill <id> | /session inspect <id>`},{name:`fork`,handler:Bn,safe:!0,description:`Fork current session into a named branch`},{name:`pin`,aliases:[`unpin`],handler:An,safe:!0,description:`Toggle pin state (pinned sessions sort to top of /resume); /pin [<id>...] [--group <name>]`},{name:`history`,aliases:[`hist`],handler:zr,safe:!0,description:`Open history search panel (same panel as Ctrl+R)`},{name:`prompts`,handler:Vr,safe:!0,description:`View prompt log (list of submitted prompts this session)`}],Ba=new Set($.filter(e=>e.safe).flatMap(e=>[e.name,...e.aliases??[]])),Va=new Set($.filter(e=>e.engineBuiltin).flatMap(e=>[e.name,...e.aliases??[]])),Ha=new Set($.filter(e=>e.handler).flatMap(e=>[e.name,...e.aliases??[]]));async function Ua(e,t,n){let r=$.find(t=>t.name===e);return r||=$.find(t=>t.aliases?.includes(e)),r?.handler?(await r.handler(t,n),!0):!1}export{Lt as $,Yn as A,qe as B,W as C,or as D,ar as E,mn as F,nn as G,tt as H,fn as I,F as J,Gt as K,dn as L,yn as M,z as N,Qn as O,pn as P,Wt as Q,ln as R,sr as S,nr as T,I as U,Ye as V,rn as W,qt as X,Kt as Y,Xt as Z,Wr as _,Ra as a,Et as at,fr as b,ta as c,Hi as d,It as et,Li as f,ti as g,Y as h,$ as i,Dt as it,Zn as j,Xn as k,na as l,oi as m,Va as n,At as nt,Ua as o,bt as ot,xi as p,Jt as q,Ba as r,Ot as rt,la as s,Ha as t,kt as tt,Ui as u,_r as v,ir as w,ur as x,lr as y,cn as z};
21
- //# sourceMappingURL=command-dispatcher-ZyrfHgIk.js.map