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

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.
Files changed (93) hide show
  1. package/README.md +65 -65
  2. package/bin/otto.js +6 -0
  3. package/dist/{auth-command-CXAB3_hs.js → auth-command-D1T16ed-.js} +3 -3
  4. package/dist/auth-command-D1T16ed-.js.map +1 -0
  5. package/dist/build-id-D7Wf4tQw.js +3 -0
  6. package/dist/build-id-D7Wf4tQw.js.map +1 -0
  7. package/dist/bundled-extensions/plugin-otto-wire-protocols/plugin-dist/meta.json +1 -1
  8. package/dist/bundled-extensions/plugin-otto-wire-protocols/plugin-dist/plugin.cjs +2085 -18164
  9. package/dist/bundled-extensions/plugin-otto-wire-protocols/src/anthropic-messages.ts +2 -2
  10. package/dist/bundled-extensions/plugin-otto-wire-protocols/src/openai-completions.ts +12 -5
  11. package/dist/bundled-extensions/plugin-otto-wire-protocols/src/openai-responses.ts +4 -1
  12. package/dist/bundled-extensions/plugin-skill-inductor/plugin-dist/meta.json +1 -1
  13. package/dist/bundled-extensions/plugin-skill-inductor/plugin-dist/plugin.cjs +78 -52294
  14. package/dist/bundled-extensions-C3n8jg20.js +3 -0
  15. package/dist/bundled-extensions-C3n8jg20.js.map +1 -0
  16. package/dist/command-dispatcher-ZyrfHgIk.js +21 -0
  17. package/dist/command-dispatcher-ZyrfHgIk.js.map +1 -0
  18. package/dist/create-host-app-BXQ8bU-B.js +3 -0
  19. package/dist/create-host-app-BXQ8bU-B.js.map +1 -0
  20. package/dist/create-host-app-DXII2WTM.js +2 -0
  21. package/dist/discover-with-bundled-B5d4q___.js +2 -0
  22. package/dist/discover-with-bundled-CF8qFP41.js +3 -0
  23. package/dist/discover-with-bundled-CF8qFP41.js.map +1 -0
  24. package/dist/doctor-CuNvDmyA.js +36 -0
  25. package/dist/doctor-CuNvDmyA.js.map +1 -0
  26. package/dist/{extension-BKXIr86F.js → extension-DLFCUBJr.js} +41 -33
  27. package/dist/extension-DLFCUBJr.js.map +1 -0
  28. package/dist/extension-I87MkZYp.js +2 -0
  29. package/dist/feedback-B-d-GV2J.js +2 -0
  30. package/dist/feedback-DuTIx3-K.js +21 -0
  31. package/dist/feedback-DuTIx3-K.js.map +1 -0
  32. package/dist/{feishu-setup-D6vnuNLw.js → feishu-setup-B6ETf-8Y.js} +2 -2
  33. package/dist/{feishu-setup-D6vnuNLw.js.map → feishu-setup-B6ETf-8Y.js.map} +1 -1
  34. package/dist/ftue-doctor-recovery-DeAf8jVo.js +3 -0
  35. package/dist/ftue-doctor-recovery-DeAf8jVo.js.map +1 -0
  36. package/dist/index.d.ts.map +1 -1
  37. package/dist/index.js +10 -12
  38. package/dist/index.js.map +1 -1
  39. package/dist/observe-CZ96Vre9.js +83 -0
  40. package/dist/observe-CZ96Vre9.js.map +1 -0
  41. package/dist/parse-cli-CqocMnXY.js +3 -0
  42. package/dist/parse-cli-CqocMnXY.js.map +1 -0
  43. package/dist/persistence-CTXa-OyC.js +85 -0
  44. package/dist/persistence-CTXa-OyC.js.map +1 -0
  45. package/dist/plugin-assembly-check-C2TephMb.js +3 -0
  46. package/dist/plugin-assembly-check-C2TephMb.js.map +1 -0
  47. package/dist/registry-BOX7DaxS.js +2 -0
  48. package/dist/{registry-D0NONjLv.js → registry-BdCcwyGy.js} +2 -2
  49. package/dist/registry-BdCcwyGy.js.map +1 -0
  50. package/dist/{run-attach-Ci5jYyCa.js → run-attach-CvGCWF_i.js} +2 -2
  51. package/dist/{run-attach-Ci5jYyCa.js.map → run-attach-CvGCWF_i.js.map} +1 -1
  52. package/dist/{serve-pVR6UIT9.js → serve-Dbn3THez.js} +3 -3
  53. package/dist/serve-Dbn3THez.js.map +1 -0
  54. package/dist/{service-client-BLNeugM9.js → service-client-Cr4sxDVM.js} +1 -1
  55. package/dist/{service-client-BLNeugM9.js.map → service-client-Cr4sxDVM.js.map} +1 -1
  56. package/dist/{version-C0qM-qJM.js → version-Cq2kcrXL.js} +2 -2
  57. package/dist/{version-C0qM-qJM.js.map → version-Cq2kcrXL.js.map} +1 -1
  58. package/package.json +5 -5
  59. package/dist/auth-command-CXAB3_hs.js.map +0 -1
  60. package/dist/build-id-BX4QHzM0.js +0 -3
  61. package/dist/build-id-BX4QHzM0.js.map +0 -1
  62. package/dist/command-dispatcher-Vb_AJSAR.js +0 -13
  63. package/dist/command-dispatcher-Vb_AJSAR.js.map +0 -1
  64. package/dist/debug-CiosFwme.js +0 -34
  65. package/dist/debug-CiosFwme.js.map +0 -1
  66. package/dist/discover-with-bundled-CznLjkkw.js +0 -3
  67. package/dist/discover-with-bundled-CznLjkkw.js.map +0 -1
  68. package/dist/doctor-C84-hhEr.js +0 -30
  69. package/dist/doctor-C84-hhEr.js.map +0 -1
  70. package/dist/extension-BKXIr86F.js.map +0 -1
  71. package/dist/extension-CnON6Xum.js +0 -2
  72. package/dist/extension-plugin-Bmqlc6as.js +0 -2
  73. package/dist/extension-plugin-C2Yhv77x.js +0 -7
  74. package/dist/extension-plugin-C2Yhv77x.js.map +0 -1
  75. package/dist/feedback-BES_6ebi.js +0 -21
  76. package/dist/feedback-BES_6ebi.js.map +0 -1
  77. package/dist/feedback-BRbLUn9u.js +0 -2
  78. package/dist/model-auth-DUPFPOjY.js +0 -2
  79. package/dist/model-auth-qY5zeBF7.js +0 -3
  80. package/dist/model-auth-qY5zeBF7.js.map +0 -1
  81. package/dist/observe-CVg-MRM2.js +0 -32
  82. package/dist/observe-CVg-MRM2.js.map +0 -1
  83. package/dist/parse-cli-BCfFgFAC.js +0 -3
  84. package/dist/parse-cli-BCfFgFAC.js.map +0 -1
  85. package/dist/persistenced-CCwHu1Ww.js +0 -36
  86. package/dist/persistenced-CCwHu1Ww.js.map +0 -1
  87. package/dist/registry-B3nfN62q.js +0 -2
  88. package/dist/registry-D0NONjLv.js.map +0 -1
  89. package/dist/remote-persistence-server-B_hONoVR.js +0 -35
  90. package/dist/remote-persistence-server-B_hONoVR.js.map +0 -1
  91. package/dist/serve-pVR6UIT9.js.map +0 -1
  92. package/dist/time-travel-ZozuPPI-.js +0 -21
  93. package/dist/time-travel-ZozuPPI-.js.map +0 -1
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ import{dirname as e,join as t}from"node:path";import{existsSync as n}from"node:fs";import{fileURLToPath as r}from"node:url";function i(){let i=t(e(r(import.meta.url)),`bundled-extensions`);return n(i)?i:``}export{i as t};
3
+ //# sourceMappingURL=bundled-extensions-C3n8jg20.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bundled-extensions-C3n8jg20.js","names":[],"sources":["../src/bundled-extensions.ts"],"sourcesContent":["/**\n * bundled-extensions.ts —— 随 otto 分发的内置扩展目录解析。\n *\n * cli 构建时(scripts/bundle-builtin-extensions.mjs)把内置扩展的编译产物拷进\n * `dist/bundled-extensions/<id>/`。本模块解析该目录,供 `discoverPlugins` 作为\n * 最高优先扫描层传入。\n *\n * ## 为什么在 cli 层解析而不是 plugin 层\n * `@x-otto/plugin` 是库,不该知道 cli 的 dist 布局(反向依赖)。目录位置只有 cli\n * 自己知道(它拥有 `import.meta.url` → dist 的路径)。\n *\n * ## 分布式的可移植性\n * 发布物 = `dist/`(package.json files:[\"dist\"])。本目录与 dist 同级,\n * 打包后相对路径关系保持不变——`import.meta.url` 解析到 dist 内的一个 js,\n * `../bundled-extensions` 即发布物内的扩展目录。\n */\nimport { existsSync } from 'node:fs'\nimport { dirname, join } from 'node:path'\nimport { fileURLToPath } from 'node:url'\n\n/** cli 发布物内内置扩展目录(不存在 = 该发布物没带内置扩展,返回空)。 */\nexport function bundledExtensionsDir(): string {\n // dist 里的这个 js 文件 → dist/bundled-extensions(同目录,非父级——这是 cli 构建\n // 时拷进去的发布物内目录,见 scripts/bundle-builtin-extensions.mjs)。\n const dir = join(dirname(fileURLToPath(import.meta.url)), 'bundled-extensions')\n return existsSync(dir) ? dir : ''\n}\n"],"mappings":";4HAqBA,SAAgB,GAA+B,CAG7C,IAAM,EAAM,EAAK,EAAQ,EAAc,OAAO,KAAK,IAAI,CAAC,CAAE,qBAAqB,CAC/E,OAAO,EAAW,EAAI,CAAG,EAAM"}
@@ -0,0 +1,21 @@
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