@x-otto/cli 0.0.1-alpha.53 → 0.0.1-alpha.55
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{auth-command--ky3JspQ.js → auth-command-Cw71Gud0.js} +2 -2
- package/dist/{auth-command--ky3JspQ.js.map → auth-command-Cw71Gud0.js.map} +1 -1
- package/dist/build-id-9kqTcA9R.js +3 -0
- package/dist/build-id-9kqTcA9R.js.map +1 -0
- package/dist/bundled-extensions/plugin-otto-wire-protocols/plugin-dist/meta.json +1 -1
- package/dist/bundled-extensions/plugin-otto-wire-protocols/plugin-dist/plugin.cjs +195 -161
- package/dist/bundled-extensions/plugin-otto-wire-protocols/plugin.ts +4 -0
- package/dist/bundled-extensions/plugin-otto-wire-protocols/src/anthropic-messages.ts +9 -1
- package/dist/bundled-extensions/plugin-otto-wire-protocols/src/openai-completions.ts +11 -1
- package/dist/bundled-extensions/plugin-otto-wire-protocols/src/openai-responses.ts +9 -1
- package/dist/command-dispatcher-W3E5zhWN.js +18 -0
- package/dist/command-dispatcher-W3E5zhWN.js.map +1 -0
- package/dist/create-host-app-_xUKDWy7.js +3 -0
- package/dist/{create-host-app-BtifD7KK.js.map → create-host-app-_xUKDWy7.js.map} +1 -1
- package/dist/{doctor-BAxvhLws.js → doctor-BDEllJgc.js} +2 -2
- package/dist/{doctor-BAxvhLws.js.map → doctor-BDEllJgc.js.map} +1 -1
- package/dist/{feedback-CJVKfI0S.js → feedback-CqTWm_TD.js} +10 -10
- package/dist/{feedback-CJVKfI0S.js.map → feedback-CqTWm_TD.js.map} +1 -1
- package/dist/{feedback-backend-methods-C23Z2suw.js → feedback-backend-methods-3CMRkGoJ.js} +2 -2
- package/dist/{feedback-backend-methods-C23Z2suw.js.map → feedback-backend-methods-3CMRkGoJ.js.map} +1 -1
- package/dist/index.js +7 -7
- package/dist/index.js.map +1 -1
- package/dist/{interactive-schedule-BKiI3Qrw.js → interactive-schedule-D0NOMjB7.js} +2 -2
- package/dist/{interactive-schedule-BKiI3Qrw.js.map → interactive-schedule-D0NOMjB7.js.map} +1 -1
- package/dist/{mcp-server-CfJK4pav.js → mcp-server-kME-VSX4.js} +2 -2
- package/dist/{mcp-server-CfJK4pav.js.map → mcp-server-kME-VSX4.js.map} +1 -1
- package/dist/{parse-cli-B9Go-f6A.js → parse-cli-Byh6vJ3e.js} +2 -2
- package/dist/{parse-cli-B9Go-f6A.js.map → parse-cli-Byh6vJ3e.js.map} +1 -1
- package/dist/schedule-C_uHI2M8.js +5 -0
- package/dist/schedule-C_uHI2M8.js.map +1 -0
- package/dist/{serve-ChSSkjLs.js → serve-Di0fC7-B.js} +2 -2
- package/dist/{serve-ChSSkjLs.js.map → serve-Di0fC7-B.js.map} +1 -1
- package/dist/{version-BL66TSQP.js → version-CHEEY4Vx.js} +2 -2
- package/dist/{version-BL66TSQP.js.map → version-CHEEY4Vx.js.map} +1 -1
- package/package.json +18 -18
- package/dist/build-id-C94zHRXj.js +0 -3
- package/dist/build-id-C94zHRXj.js.map +0 -1
- package/dist/command-dispatcher-CKj6qR-G.js +0 -18
- package/dist/command-dispatcher-CKj6qR-G.js.map +0 -1
- package/dist/create-host-app-BtifD7KK.js +0 -3
- package/dist/schedule-Ke0jwatM.js +0 -5
- package/dist/schedule-Ke0jwatM.js.map +0 -1
|
@@ -19,6 +19,8 @@ import type { WireProtocolFactoryInput } from '@x-otto/provider'
|
|
|
19
19
|
function adaptToOpenAICompletions(input: WireProtocolFactoryInput) {
|
|
20
20
|
return createOpenAICompletionsProvider({
|
|
21
21
|
resolveKey: () => input.resolveAuth().then((a) => a?.token),
|
|
22
|
+
resolveBaseUrl: input.resolveBaseUrl,
|
|
23
|
+
preferResolvedBaseUrl: input.preferResolvedBaseUrl,
|
|
22
24
|
headers: input.headers,
|
|
23
25
|
tokenDerivedHeaders: input.tokenDerivedHeaders,
|
|
24
26
|
logger: input.logger,
|
|
@@ -32,6 +34,7 @@ function adaptToOpenAIResponses(input: WireProtocolFactoryInput) {
|
|
|
32
34
|
return createOpenAIResponsesProvider({
|
|
33
35
|
resolveKey: () => input.resolveAuth().then((a) => a?.token),
|
|
34
36
|
resolveBaseUrl: input.resolveBaseUrl,
|
|
37
|
+
preferResolvedBaseUrl: input.preferResolvedBaseUrl,
|
|
35
38
|
tokenDerivedHeaders: input.tokenDerivedHeaders,
|
|
36
39
|
headers: input.headers,
|
|
37
40
|
logger: input.logger,
|
|
@@ -45,6 +48,7 @@ function adaptToAnthropicMessages(input: WireProtocolFactoryInput) {
|
|
|
45
48
|
return createAnthropicProvider({
|
|
46
49
|
resolveAuth: () => input.resolveAuth(),
|
|
47
50
|
resolveBaseUrl: input.resolveBaseUrl,
|
|
51
|
+
preferResolvedBaseUrl: input.preferResolvedBaseUrl,
|
|
48
52
|
customizeRequest: input.customizeRequest,
|
|
49
53
|
logger: input.logger,
|
|
50
54
|
// RFC-270 缺陷 1(P0):此前这两行缺失——另两个 adapter 都透传了 headers,唯独本
|
|
@@ -605,6 +605,7 @@ export interface AnthropicProviderOptions {
|
|
|
605
605
|
resolveKey?: AnthropicCredentialResolver
|
|
606
606
|
resolveAuth?: AnthropicAuthResolver
|
|
607
607
|
resolveBaseUrl?: AnthropicBaseUrlResolver
|
|
608
|
+
preferResolvedBaseUrl?: boolean
|
|
608
609
|
/**
|
|
609
610
|
* 请求定制点(RFC-140 D-copilot-spoof-split,取代此前的 `enableClaudeCodeSpoof` 布尔开关):
|
|
610
611
|
* `createAnthropicProvider` 是**任意**声明 `wireApi: 'anthropic-messages'` 的插件共用的
|
|
@@ -648,6 +649,7 @@ class AnthropicStream implements ProviderStream {
|
|
|
648
649
|
constructor(
|
|
649
650
|
private readonly resolveCredential?: AnthropicCredentialResolver,
|
|
650
651
|
private readonly baseUrlResolver?: AnthropicBaseUrlResolver,
|
|
652
|
+
private readonly preferResolvedBaseUrl = false,
|
|
651
653
|
private readonly authResolver?: AnthropicAuthResolver,
|
|
652
654
|
/** 见 `AnthropicProviderOptions.customizeRequest` 注释。缺省 = 零定制。 */
|
|
653
655
|
private readonly customizeRequest?: (input: AnthropicRequestCustomizeInput) => AnthropicRequestCustomization,
|
|
@@ -693,7 +695,12 @@ class AnthropicStream implements ProviderStream {
|
|
|
693
695
|
context: StreamContext,
|
|
694
696
|
auth: ResolvedAuth,
|
|
695
697
|
): Promise<{ client: Anthropic; requestParams: Anthropic.MessageStreamParams; baseURL: string }> {
|
|
696
|
-
const baseURL = await resolveProviderBaseUrl(
|
|
698
|
+
const baseURL = await resolveProviderBaseUrl(
|
|
699
|
+
'ANTHROPIC_BASE_URL',
|
|
700
|
+
this.baseUrlResolver,
|
|
701
|
+
model.baseUrl,
|
|
702
|
+
this.preferResolvedBaseUrl,
|
|
703
|
+
)
|
|
697
704
|
// RFC-140 D-copilot-spoof-split:本文件不再判断"是否 oauth 才伪装"——那是具体厂商
|
|
698
705
|
// (如 plugin-anthropic 的 Claude Code 伪装)的业务逻辑,交给 customizeRequest 定制器
|
|
699
706
|
// 自行按 input.auth.mode 判断要不要返回定制内容。未提供定制器 = 零调用零开销。
|
|
@@ -888,6 +895,7 @@ export function createAnthropicProvider(options: AnthropicProviderOptions = {}):
|
|
|
888
895
|
return new AnthropicStream(
|
|
889
896
|
options.resolveKey,
|
|
890
897
|
options.resolveBaseUrl,
|
|
898
|
+
options.preferResolvedBaseUrl,
|
|
891
899
|
options.resolveAuth,
|
|
892
900
|
options.customizeRequest,
|
|
893
901
|
options.logger,
|
|
@@ -36,6 +36,7 @@ import { noopWireProtocolLogger, resolveProviderBaseUrl } from '@x-otto/provider
|
|
|
36
36
|
* RFC-122 D3:支持声明式 `tokenDerivedHeaders`(插件 provider 轴),JWT claim 值提取后注入请求头。
|
|
37
37
|
*/
|
|
38
38
|
export type OpenAICompletionsCredentialResolver = (provider: string) => Promise<string | undefined>
|
|
39
|
+
export type OpenAICompletionsBaseUrlResolver = () => Promise<string | undefined>
|
|
39
40
|
|
|
40
41
|
// RFC-122 D3:TokenDerivedHeader 定义单一真源在 @x-otto/provider(协议中立层,见该包
|
|
41
42
|
// types.ts 头注释)——此前本文件与 openai-responses.ts 各自重复定义一份相同形状,
|
|
@@ -43,6 +44,8 @@ export type OpenAICompletionsCredentialResolver = (provider: string) => Promise<
|
|
|
43
44
|
|
|
44
45
|
export interface OpenAICompletionsProviderOptions {
|
|
45
46
|
resolveKey?: OpenAICompletionsCredentialResolver
|
|
47
|
+
resolveBaseUrl?: OpenAICompletionsBaseUrlResolver
|
|
48
|
+
preferResolvedBaseUrl?: boolean
|
|
46
49
|
/** RFC-122 D3:静态额外 headers(如 vendor 自定义头)。 */
|
|
47
50
|
headers?: Record<string, string>
|
|
48
51
|
/** RFC-122 D3:JWT claim 派生 headers。 */
|
|
@@ -71,6 +74,8 @@ class OpenAICompletionsStream implements ProviderStream {
|
|
|
71
74
|
|
|
72
75
|
constructor(
|
|
73
76
|
private readonly resolveCredential?: OpenAICompletionsCredentialResolver,
|
|
77
|
+
private readonly baseUrlResolver?: OpenAICompletionsBaseUrlResolver,
|
|
78
|
+
private readonly preferResolvedBaseUrl = false,
|
|
74
79
|
private readonly extraHeaders?: Record<string, string>,
|
|
75
80
|
private readonly tokenDerivedHeaders?: TokenDerivedHeader[],
|
|
76
81
|
private readonly logger: WireProtocolLogger = noopWireProtocolLogger,
|
|
@@ -127,7 +132,10 @@ class OpenAICompletionsStream implements ProviderStream {
|
|
|
127
132
|
yield* streamChatCompletions({
|
|
128
133
|
url: `${await resolveProviderBaseUrl(
|
|
129
134
|
model.provider === 'deepseek' ? 'DEEPSEEK_BASE_URL' : 'OPENAI_BASE_URL',
|
|
130
|
-
|
|
135
|
+
this.baseUrlResolver,
|
|
136
|
+
model.baseUrl,
|
|
137
|
+
this.preferResolvedBaseUrl,
|
|
138
|
+
)}/chat/completions`,
|
|
131
139
|
headers,
|
|
132
140
|
body: buildChatCompletionsBody(model, context),
|
|
133
141
|
identity: { api: model.api, provider: model.provider, model: model.id },
|
|
@@ -156,6 +164,8 @@ export function createOpenAICompletionsProvider(
|
|
|
156
164
|
): ProviderStream {
|
|
157
165
|
return new OpenAICompletionsStream(
|
|
158
166
|
options.resolveKey,
|
|
167
|
+
options.resolveBaseUrl,
|
|
168
|
+
options.preferResolvedBaseUrl,
|
|
159
169
|
options.headers,
|
|
160
170
|
options.tokenDerivedHeaders,
|
|
161
171
|
options.logger,
|
|
@@ -361,6 +361,7 @@ class OpenAIResponsesStream implements ProviderStream {
|
|
|
361
361
|
constructor(
|
|
362
362
|
private readonly resolveCredential?: OpenAIResponsesCredentialResolver,
|
|
363
363
|
private readonly baseUrlResolver?: OpenAIResponsesBaseUrlResolver,
|
|
364
|
+
private readonly preferResolvedBaseUrl = false,
|
|
364
365
|
private readonly tokenDerivedHeaders?: TokenDerivedHeader[],
|
|
365
366
|
/**
|
|
366
367
|
* 终局 review 2026-07-10 P1-7:静态额外 headers(如 vendor 自定义头),对齐
|
|
@@ -403,7 +404,12 @@ class OpenAIResponsesStream implements ProviderStream {
|
|
|
403
404
|
}
|
|
404
405
|
|
|
405
406
|
private async resolveBaseUrl(model: Model): Promise<string> {
|
|
406
|
-
return resolveProviderBaseUrl(
|
|
407
|
+
return resolveProviderBaseUrl(
|
|
408
|
+
'OPENAI_BASE_URL',
|
|
409
|
+
this.baseUrlResolver,
|
|
410
|
+
model.baseUrl,
|
|
411
|
+
this.preferResolvedBaseUrl,
|
|
412
|
+
)
|
|
407
413
|
}
|
|
408
414
|
|
|
409
415
|
/**
|
|
@@ -536,6 +542,7 @@ class OpenAIResponsesStream implements ProviderStream {
|
|
|
536
542
|
export interface OpenAIResponsesProviderOptions {
|
|
537
543
|
resolveKey?: OpenAIResponsesCredentialResolver
|
|
538
544
|
resolveBaseUrl?: OpenAIResponsesBaseUrlResolver
|
|
545
|
+
preferResolvedBaseUrl?: boolean
|
|
539
546
|
/** RFC-122 D3:插件声明式 token 派生 header(provider-loader 装载时注入) */
|
|
540
547
|
tokenDerivedHeaders?: TokenDerivedHeader[]
|
|
541
548
|
/**
|
|
@@ -561,6 +568,7 @@ export function createOpenAIResponsesProvider(
|
|
|
561
568
|
return new OpenAIResponsesStream(
|
|
562
569
|
options.resolveKey,
|
|
563
570
|
options.resolveBaseUrl,
|
|
571
|
+
options.preferResolvedBaseUrl,
|
|
564
572
|
options.tokenDerivedHeaders,
|
|
565
573
|
options.headers,
|
|
566
574
|
options.logger,
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import{n as e,t}from"./build-id-9kqTcA9R.js";import{t as n}from"./version-CHEEY4Vx.js";import{t as r}from"./discover-with-bundled-CF8qFP41.js";import{n as i,r as a,t as o}from"./service-client-cfUUP4EE.js";import{n as s}from"./extension-Dpn8gltG.js";import{n as c,t as l}from"./registry-BUvu-es1.js";import{t as u}from"./proxy-CFZDVIwI.js";import{i as d}from"./install-CEPczuet.js";import{t as f}from"./schedule-C_uHI2M8.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 y,totalmem as b}from"node:os";import{execFile as x,execSync as ee,spawn as S,spawnSync as C}from"node:child_process";import{DEFAULT_WORKSPACE_KEY as te,INDUCTOR_PLUGIN_ID as w,PLUGIN_MANIFEST_FILENAME as T,POINT as ne,buildExtensionContext as re,checkUpgrades as ie,collectPluginPerfMetrics as ae,defaultPostInstallExecutor as oe,detectProjectConfigGating as se,discoverFileCommands as ce,discoverPlugins as le,dispatch as ue,evaluateClaudeTrust as de,evaluatePluginTrust as fe,findWorkspaceRoot as pe,getLastAssistantText as E,grantPluginCapabilities as me,grantPluginCapabilitiesWithVersion as he,install as ge,installPluginFromPackage as _e,openTarget as ve,parsePluginManifest as ye,readHighRiskCapabilities as be,readPluginLogTail as xe,readSkillLoopStatus as Se,recordPluginInstalled as Ce,recordPluginUninstalled as we,redactSensitiveFields as Te,resolveActions as Ee,resolvePackageDir as De,resolveSessionTitle as Oe,runPluginScript as ke,scanInstalledVersions as Ae,trustPlugin as je,trustProject as Me,uninstall as Ne,untrustPlugin as Pe,untrustProject as Fe}from"@x-otto/coding";import{checkShellCommand as Ie,openBrowser as Le,readFileCapped as Re}from"@x-otto/shared";import{BUILD_ID as ze,SDK_VERSION as Be}from"@x-otto/env";import{dirname as D,join as O,relative as Ve,resolve as He}from"node:path";import{closeSync as Ue,existsSync as We,openSync as Ge,readFileSync as Ke,readSync as qe,readdirSync as Je,statSync as Ye}from"node:fs";import{ACTION_CHIP_VALUE_SEGMENT as Xe,FIGURES as k,buildTurnSummary as Ze,createBuiltinThemeRegistry as Qe,createReducerState as $e,deriveTurnBoundaries as et,detectLanguage as tt,formatProviderUsageLimitTypeFull as nt,i18next as A,initI18n as rt,insertTurnSummaries as it,reduceToTui as at}from"@x-otto/tui";import{createBuiltinCommands as ot}from"@x-otto/tui/compat";import{MaxToolTurnsError as st,PromptBudgetExceededError as ct}from"@x-otto/agent";import{readFile as lt,readdir as ut,stat as dt,unlink as ft}from"node:fs/promises";import{DEFAULT_COMPACTION_CONFIG as pt,DEFAULT_PRUNE_CONFIG as mt,estimateTokens as ht,resolveContextSize as gt}from"@x-otto/memory";import{classifyAuthErrorType as _t,computeCacheHitRatio as vt,createModelUsabilityGate as j,getProviderDescriptor as M,getToolCallsByAssistantMessage as yt,isAuthError as bt}from"@x-otto/ai";import{promisify as xt}from"node:util";var St=Object.defineProperty,N=(e,t)=>{let n={};for(var r in e)St(n,r,{get:e[r],enumerable:!0});return t||St(n,Symbol.toStringTag,{value:`Module`}),n},Ct=p(import.meta.url);function wt(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 Tt(e,t){let n=E(e.session.messages())||t.partialText,r=wt(t);return n?`${n}\n${r}`:r}function Et(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 Dt(e,t){let n=E(e.session.messages())||t.partialText,r=Et(t);return n?`${n}\n${r}`:r}async function Ot(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?Et(t):wt(t);o?.(n?`budget-exceeded`:`max-tool-turns`,r);let l=o?E(e.session.messages())||t.partialText:n?Dt(e,t):Tt(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 kt(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,ottoVersion:n()};if(t instanceof ct)return{sessionId:e.id,status:`budget_exceeded`,messageCount:e.session.messages().length,response:E(e.session.messages())||t.partialText,ottoVersion:n()};throw t}return{sessionId:e.id,status:e.status,messageCount:e.session.messages().length,response:E(e.session.messages()),ottoVersion:n()}}var P=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=Ie(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=ee(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 Ot(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 Ot(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 At(){return tt()}function jt(e=`auto`){let t=e===`auto`?tt():e;return rt(t),t}const Mt=`@x-otto/cli`;async function Nt(e){let t=process.env.OTTO_UPGRADE_MOCK;if(t){let n=t===`force`,r=/^\d+\.\d+\.\d+/.test(t)?t:n?`2.0.0`:`0.2.0`;return{latest:r,current:e,newer:F(r,Pt(e))>0}}try{let t=new AbortController,n=setTimeout(()=>t.abort(),5e3),r=await fetch(`https://registry.npmjs.org/%40x-otto%2Fcli`,{signal:t.signal});if(clearTimeout(n),!r.ok)return null;let i=(await r.json())?.[`dist-tags`];if(!i)return null;let a=[i.alpha,i.latest].filter(e=>!!e),o=a.length>0?a.reduce((e,t)=>F(t,e)>0?t:e):Object.values(i).reduce((e,t)=>e===null||F(t,e)>0?t:e,null);return o?{latest:o,current:e,newer:F(o,Pt(e))>0}:null}catch{return null}}function Pt(e){let t=/^v?\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?/.exec(e.trim());return t?t[0]:e}function Ft(e){let t=/^v?(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z.-]+))?$/.exec(e.trim());return t?{core:[Number(t[1]),Number(t[2]),Number(t[3])],prerelease:t[4]?t[4].split(`.`):null}:null}function F(e,t){let n=Ft(e),r=Ft(t);if(!n||!r)return 0;for(let e=0;e<3;e++)if(n.core[e]!==r.core[e])return n.core[e]-r.core[e];if(n.prerelease===null&&r.prerelease===null)return 0;if(n.prerelease===null)return 1;if(r.prerelease===null)return-1;let i=Math.max(n.prerelease.length,r.prerelease.length);for(let e=0;e<i;e++){let t=n.prerelease[e],i=r.prerelease[e];if(t===void 0)return-1;if(i===void 0)return 1;if(t===i)continue;let a=/^\d+$/.test(t),o=/^\d+$/.test(i);return a&&o?Number(t)-Number(i):a?-1:o?1:t<i?-1:1}return 0}async function It(e){return new Promise(t=>{try{let n=S(process.platform===`win32`?`npm.cmd`:`npm`,[`install`,`-g`,e?`${Mt}@${e}`:`${Mt}@latest`],{stdio:`inherit`,shell:!0});n.on(`error`,e=>{t({ok:!1,error:e.message})}),n.on(`exit`,e=>{if(e!==0){t({ok:!1,error:`npm install exited with code ${e}`});return}t({ok:!0})})}catch(e){t({ok:!1,error:e.message})}})}function Lt(e){return e?Date.now()-e>216e5:!0}async function Rt(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||!Lt(e.lastCheck)?null:Nt(e.currentVersion).then(async t=>t&&(e.persistLastCheck().catch(()=>{}),t.newer)?{...t,forced:!1}:null).catch(()=>null)}let zt,Bt;function Vt(e){let t=e.map(e=>e.name).sort().join(`,`);if(zt!==void 0&&Bt===t)return zt;let n=e=>typeof e==`function`?`[fn]`:typeof e==`string`?e:``;return zt=ht(JSON.stringify(e.map(e=>({name:e.name,description:n(e.description),parameters:e.parameters})))),Bt=t,zt}let Ht,Ut;function Wt(e){return Ht!==void 0&&Ut===e?Ht:(Ht=ht(e),Ut=e,Ht)}function Gt(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=Wt(t)+Vt(n),h=a+o+r+i+p,g=Math.max(0,h-m),_=Math.max(0,s-m-g),v=gt(mt.trigger,s),y=gt(pt.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:y,lastInput:r,lastOutput:i,totalInput:l,totalOutput:u,cost:d,live:p>0}}const Kt={openai:`OpenAI`};function qt(e){let t=[`confirm`,`auto`,`bypass`];return t[(t.indexOf(e)+1)%t.length]??`confirm`}function Jt(e){return e===`error`?`error`:e===`approval_required`||e===`input_required`?`warning`:`info`}function Yt(e,t,n){let r=t===void 0?void 0:{code:t},i=r!==void 0&&bt(r),a=i&&_t(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 Xt(e){return e?e.toLowerCase()===`xhigh`?`XHigh`:e.charAt(0).toUpperCase()+e.slice(1):``}function Zt(e,t,n){return e?`${t.on} ${n.on}`:`${t.off} ${n.off}`}function I(e,t,n){if(!t)return`(no model)`;let r=Xt(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 Qt(e,t){let n=[...ce(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 $t(e){return{id:e.id,type:`function`,function:{name:e.name,arguments:JSON.stringify(e.arguments)}}}function en(e){return{type:`thinking`,thinking:e.text}}function tn(e){return{type:`text`,text:e.text}}function nn(e){return{type:`a2ui`,version:e.version,components:e.components}}function rn(e){let t=[],n=[];for(let r of e)switch(r.type){case`text`:r.text.trim()&&t.push(tn(r));break;case`thinking`:r.text.trim()&&t.push(en(r));break;case`tool_call`:n.push($t(r));break;case`a2ui`:t.push(nn(r));break}return{content:t,toolCalls:n}}function an(e){return typeof e==`string`?e.trim():e.filter(e=>e.type===`text`).map(e=>e.text).join(``).trim()}function on(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 L(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=an(e.content);t&&i.push({role:`user`,content:t});continue}if(e.role===`assistant`){let{content:t}=rn(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:on(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:on(r),argsObj:r,result:an(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 sn=xt(x);function cn(e,t,n){for(let r of e){if(r.role!==`assistant`)continue;let e=yt(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 ln(e,t){let n=D(e),r=e=>{let t=C(`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=Ke(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 un(e,t){let n=D(e),r=async e=>{try{let{stdout:t}=await sn(`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 lt(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 dn(e){return[...e].sort((e,t)=>t.savedAt-e.savedAt)}function fn(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 pn(e,t,n){let r=Date.now();return{id:`${r.toString(36)}-${Math.random().toString(36).slice(2,6)}`,name:fn(e,n),text:t,savedAt:r}}function mn(e){return e.length<=50?[...e]:e.slice(-50)}function R(e){let t=L(e.session.visibleMessages()),n=e.session.getTurnSummaries();return!n||n.length===0?t:it(t,n,e.session.getTurnCount()??t.filter(e=>e.role===`user`).length)}function hn(e){let{resumedNote:t,isFound:n,session:r,projState:i,tui:a}=e,o=R(r);a.messages.pushMessages(o),n&&o.length>0&&a.info.setTopView({session:r.id}),a.info.showToast(n?A.t(`cmd.titleSessionResumed`):A.t(`cmd.titleSession`),t.replace(/^↻ /,``)),gn({session:r,projState:i,tui:a,chatMsgs:o})}function gn(e){let{session:t,projState:n,tui:r}=e,i=e.chatMsgs??R(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(A.t(`cmd.titleSession`),A.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(et(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?cn(e,t.toolCallId,n):{};return r.oldContent===void 0&&r.newContent===void 0&&(r=ln(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(dn(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 z=new Map;function _n(e){return z.get(e)}function vn(e){z.delete(e);let t=V.get(e);t&&(clearTimeout(t),V.delete(e))}function yn(){return[...z.values()]}function B(e,t,n){let r={id:e,transcript:L(t),streaming:``,status:n?`busy`:`idle`,lastActivityAt:Date.now()};return z.set(e,r),r}function bn(e,t){let n=z.get(e);n&&(n.transcript=L(t),n.lastActivityAt=Date.now())}const xn=new Set;function Sn(e){return xn.add(e),()=>{xn.delete(e)}}const V=new Map;function Cn(e){let t=V.get(e.id);t&&clearTimeout(t),V.set(e.id,setTimeout(()=>{V.delete(e.id);for(let t of xn)t(e)},300))}function H(e,t){let n=``,r=t=>{e.status!==t&&(e.status=t,Cn(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`),bn(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(),Cn(e);return}},()=>e]}function wn(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 Tn(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 r=a(process.env.OTTO_SERVICE_URL??`http://127.0.0.1:8417`,globalThis.fetch,{token:process.env.OTTO_SERVICE_TOKEN}),s;try{s=await r.fetchSnapshot(n)}catch(e){if(e instanceof i){t.tui.info.showToast(`/session inspect`,`无法连接 otto serve:${e.message} —— 先 \`otto serve\`(或指定 --remote/OTTO_SERVICE_URL)`);return}if(e instanceof o){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${wn(s)}`}]}),t.tui.info.showToast(`/session inspect`,`已查看会话 ${s.session.id}(只读快照;如需实时参与该会话请用 otto --attach ${s.session.id})`)}function En(e){let t=e.trim(),n=(t.split(`
|
|
5
|
+
`,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 Dn=e=>`把下面的笔记归纳成一个简短标题(≤6 词)和一句话描述。严格只按此格式输出:\nTITLE: <标题>\nDESC: <一句话描述>\n\n笔记:\n${e}`;function On(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 kn(e,t,n=8e3){let r=En(e);if(!t)return r;let i=new AbortController,a=setTimeout(()=>i.abort(),n);a.unref?.();try{let n=On(await t(Dn(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 An(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 jn(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=En(i);await r.record(e),o(`/memory user`,`ok`,A.t(`cmd.memoryUserSaved`,{name:e.name}));return}let a=r.getInjection().trim();t.tui.modal.openModal({kind:`memory`,projectIndex:``,userIndex:a,...An(n,r)});return}if(i===`project`){let e=n?n.getInjection().trim():``;t.tui.modal.openModal({kind:`memory`,projectIndex:e,userIndex:``,...An(n,r)});return}if(i===`forget`){let t=e.slice(1).join(` `).trim();if(!t){o(`/memory forget`,`warn`,A.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?A.t(`cmd.memoryDeleted`,{name:t}):A.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`,A.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,...An(n,r)})}async function Mn(e,t){let n=A.t(`cmd.titleCompact`);if((e[0]??``).toLowerCase()===`log`){t.tui.panes.togglePane(`compactionLog`);return}if(!t.app.storage.memory){t.tui.info.showToast(n,A.t(`compact.unavailable`));return}t.tui.info.showToast(n,A.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,A.t(`compact.edResult`,{before:e.before,after:e.after})),t.callbacks.onContextCompacted()):t.tui.info.showToast(n,A.t(`compact.noop`))}catch(e){t.tui.info.showToast(n,A.t(`cmd.compactFailed`,{msg:e instanceof Error?e.message:String(e)}))}finally{t.tui.engine.pushEngineEvent({kind:`agentProcessing`,value:!1})}}async function Nn(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(I(t.app,n.id,t.state.session.thinkingLevel));let r=n?.contextWindow??2e5,i=Gt({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(A.t(`cmd.titleCleared`),A.t(`cmd.clearedDone`))}async function Pn(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 Fn(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,A.t(`cmd.titleResume`),A.t(`cmd.resumeAlreadyOn`));return}let n=t.app.getSession(e)??await t.app.sessionManager.restore(e);if(!n){l(t,A.t(`cmd.titleResume`),A.t(`cmd.resumeSessionNotFound`,{idShort:e.slice(0,8)}));return}let r=t.state.session;if(t.state.session.isBusy){let[e]=H(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 P(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(I(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=_n(n.id);if(a)t.tui.messages.pushMessages(a.transcript),vn(n.id);else{let e=R(n);t.tui.messages.pushMessages(e)}t.callbacks.restoreSwitchedSession(),t.tui.info.setTopView({session:n.id}),l(t,A.t(`cmd.titleResume`),A.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,A.t(`cmd.titleResume`),A.t(`cmd.sessionNoMatch`,{arg:n}));return}if(c.length===0){l(t,A.t(`cmd.titleResume`),A.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()||A.t(`cmd.resumeDefaultPinGroup`):A.t(`cmd.resumeRecentGroup`)}function g(e){if(!e)return``;let t=Math.max(0,Math.floor((Date.now()-e.getTime())/1e3));return t<10?A.t(`cmd.agoJustNow`):t<60?A.t(`cmd.agoSeconds`,{n:t}):t<3600?A.t(`cmd.agoMinutes`,{n:Math.floor(t/60)}):t<86400?A.t(`cmd.agoHours`,{n:Math.floor(t/3600)}):A.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),y=r?` [workspace: ${r}]`:``,b=[!i&&s>0?A.t(`cmd.resumeArchivedHiddenHint`,{count:s}):``].filter(Boolean),x=b.length>0?` ${b.join(` `)}`:``,ee=new Map(yn().map(e=>[e.id,e])),S=0,C=0,te=e=>{if(e.id===d)return``;let n=ee.get(e.id);return n?n.status===`busy`?(S++,`● ${A.t(`cmd.resumeStatusBusy`)} · `):n.status===`needs-input`?(C++,`● ${A.t(`cmd.resumeStatusNeedsInput`)} · `):`· ${A.t(`cmd.resumeStatusIdle`)} · `:t.app.getSession(e.id)?.isBusy?(S++,`● ${A.t(`cmd.resumeStatusBusy`)} · `):``},w=[S>0?`${S} ${A.t(`cmd.resumeStatusBusy`)}`:``,C>0?`${C} ${A.t(`cmd.resumeStatusNeedsInput`)}`:``].filter(Boolean).join(`, `),T=w?` · ${w}`:``,ne=A.t(`cmd.resumeSubtitle`,{sessions:c.length,msgs:v,recent:_})+T+x,re=i?A.t(`cmd.resumeArchivedOnlyTitle`,{n:c.length}):A.t(`cmd.resumeSelectTitle`,{n:c.length});t.tui.modal.openModal({kind:`select`,title:re+y,subtitle:ne,searchable:!0,maxVisible:13,options:m.map(e=>{let t=e.id===d?`●`:` `,n=e.pinned?A.t(`cmd.resumePinnedPrefix`):``,r=e.title||e.id.slice(0,8),i=e.status===`archived`?A.t(`cmd.resumeArchivedSuffix`):``,a=e.writeLocked?A.t(`cmd.resumeReadOnlySuffix`):``,o=`${n}${r}${i}`,s=g(e.updatedAt),c=[te(e).trim(),s,A.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,A.t(`cmd.titleResume`),A.t(`cmd.resumeFailed`,{msg:e instanceof Error?e.message:String(e)})))},onCancel:()=>{}})}async function In(e,t){t.app.reloadCapabilities().then(e=>{t.tui.plugins.setPluginRegistrations(t.app.getPluginRegistrations()),t.tui.info.showToast(A.t(`cmd.titleReload`),A.t(`cmd.reloadDone`,{mcpTools:e.mcpTools,models:e.models,agents:e.agents,teams:e.teams}))},e=>t.tui.messages.pushMessage({role:`command_echo`,command:`/extension reload`,status:`error`,summary:A.t(`cmd.reloadFailed`,{msg:e instanceof Error?e.message:String(e)})}))}async function Ln(e,t){let n=t.app.diagnoser.propose();if(n.length===0){t.tui.info.showToast(A.t(`cmd.titleDiagnose`),A.t(`cmd.diagnoseNone`));return}let r=n.map((e,t)=>A.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:A.t(`cmd.diagnoseSummary`,{count:n.length}),detail:r.join(`
|
|
6
|
+
`)})}async function Rn(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(A.t(`cmd.titleArchive`),A.t(`cmd.sessionNoMatch`,{arg:n}));return}if(r.status===`archived`){let e=t.app.getSession(r.id);if(!e){t.tui.info.showToast(A.t(`cmd.titleUnarchive`),A.t(`cmd.unarchiveNotLoaded`,{idShort:r.id.slice(0,8)}));return}e.unarchive(),t.tui.info.showToast(A.t(`cmd.titleUnarchive`),A.t(`cmd.unarchiveDone`,{idShort:r.id.slice(0,8),title:r.title??``}));return}if(!await t.app.archiveSession(r.id)){t.tui.info.showToast(A.t(`cmd.titleArchive`),A.t(`cmd.archiveCannot`,{idShort:r.id.slice(0,8)}));return}t.tui.info.showToast(A.t(`cmd.titleArchive`),A.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(A.t(`cmd.titleUnarchive`),A.t(`cmd.unarchiveDone`,{idShort:r.id.slice(0,8),title:r.title??``}));return}r.archive(),t.tui.info.showToast(A.t(`cmd.titleArchive`),A.t(`cmd.archiveDone`,{idShort:r.id.slice(0,8),title:r.title??``}))}async function zn(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(A.t(`cmd.titlePin`),A.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(A.t(`cmd.titleUnpin`),A.t(`cmd.unpinDone`,{idShort:e.id.slice(0,8),title:e.title??``}))):(e.pin(),t.tui.info.showToast(A.t(`cmd.titlePin`),A.t(`cmd.pinDone`,{idShort:e.id.slice(0,8),title:e.title??``}))),U(t);return}if(r.length===0){Bn(t.state.session.id,n,t),U(t);return}if(r.length===1){Bn(r[0],n,t),U(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(A.t(`cmd.titlePin`),A.t(`cmd.pinBatchSummary`,{seg:o.length>0?`${a} pinned (${o.length} not found: ${o.join(`, `)})`:`${a} pinned`})),U(t)}function U(e){let t=e.callbacks.refreshSlashCommands();e.tui.plugins.setCommands(t)}function Bn(e,t,n){if(e===n.state.session.id){Vn(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(A.t(`cmd.titlePin`),A.t(`cmd.sessionNoMatch`,{arg:e}));return}let a=n.app.getSession(i.id);if(!a){n.tui.info.showToast(A.t(`cmd.titlePin`),A.t(`cmd.pinNotLoaded`,{idShort:i.id.slice(0,8)}));return}Vn(a,t,n)}function Vn(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(A.t(`cmd.titleUnpin`),A.t(`cmd.unpinDone`,{idShort:r,title:i}));return}e.pin(t),n.tui.info.showToast(A.t(`cmd.titlePin`),A.t(`cmd.pinGroupDone`,{idShort:r,title:i,group:t}));return}e.pin(t),t===void 0?n.tui.info.showToast(A.t(`cmd.titlePin`),A.t(`cmd.pinDone`,{idShort:r,title:i})):n.tui.info.showToast(A.t(`cmd.titlePin`),A.t(`cmd.pinGroupDone`,{idShort:r,title:i,group:t}))}async function Hn(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=Gt({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`})}async function W(e,t){let n=e[0];if(n===`fork`){await Un(e.slice(1),t);return}if(n===`kill`){await Yn(e.slice(1),t);return}if(n===`pin`||n===`unpin`){await zn(e.slice(1),t);return}if(n===`archive`||n===`unarchive`){await Rn(e.slice(1),t);return}if(n===`resume`){await Fn(e.slice(1),t);return}if(n===`compact`){await Mn(e.slice(1),t);return}if(n===`context`){await Hn(e.slice(1),t);return}if(n===`inspect`){await Tn(e.slice(1),t);return}if(n===`clear`){await Nn(e.slice(1),t);return}if(n!==`unlock`){let n=e.join(` `).trim();if(!n){t.tui.info.showToast(A.t(`cmd.titleSessionCmd`),`Usage: /session fork | clear | unlock <id> [--force] | kill <id> | inspect <id> | pin [<id>...] | archive [<id>] | resume [<id>] | compact | context | <prompt text>`);return}await Wn(n,t);return}let r=e.slice(1),i=r.includes(`--force`),a=r.find(e=>e!==`--force`);if(!a){t.tui.info.showToast(A.t(`cmd.titleSessionUnlock`),A.t(`cmd.unlockUsage`));return}let o=t.app.sessionManager.inspectSessionWriteLease(a),s=a.slice(0,8);if(!o.locked){t.tui.info.showToast(A.t(`cmd.titleSessionUnlock`),A.t(`cmd.unlockNotLocked`,{idShort:s}));return}let c=o.alive===!0?A.t(`cmd.unlockAliveConfirmed`):o.alive===!1?A.t(`cmd.unlockDeadConfirmed`):A.t(`cmd.unlockUnknownAlive`),l=Math.round((o.mtimeAgoMs??0)/1e3);if(!i){t.tui.messages.pushMessage({role:`command_echo`,command:`/session unlock`,summary:A.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:A.t(`cmd.unlockHungWarning`,{idShort:s})}),t.tui.modal.openModal({kind:`confirm`,title:A.t(`cmd.unlockConfirmTitle`),message:A.t(`cmd.unlockConfirmMessage`,{idShort:s,pid:o.pid,hostname:o.hostname}),confirmLabel:A.t(`cmd.unlockConfirmLabel`),cancelLabel:A.t(`cmd.unlockCancelLabel`),dangerous:!0,onConfirm:()=>{t.app.sessionManager.forceReleaseSessionWriteLease(a),t.tui.info.showToast(A.t(`cmd.titleSessionUnlock`),A.t(`cmd.unlockForcedDone`,{idShort:s}))},onCancel:()=>{t.tui.info.showToast(A.t(`cmd.titleSessionUnlock`),A.t(`cmd.unlockCancelled`))}});return}(o.mtimeAgoMs??0)<5e3&&t.tui.messages.pushMessage({role:`command_echo`,command:`/session unlock --force`,status:`warn`,summary:A.t(`cmd.unlockRecentReleaseHint`,{idShort:s})}),t.app.sessionManager.forceReleaseSessionWriteLease(a),t.tui.info.showToast(A.t(`cmd.titleSessionUnlock`),A.t(`cmd.unlockForcedDone`,{idShort:s}))}async function Un(e,t){let n=t.state.session.id,r=await t.app.sessionManager.forkSession(n);if(!r){t.tui.info.showToast(A.t(`cmd.titleSessionFork`),A.t(`cmd.forkFailed`));return}let i=t.state.session;if(t.state.session.isBusy){let[e]=H(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 P(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(I(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=R(r);t.tui.messages.pushMessages(o),t.callbacks.restoreSwitchedSession(),t.tui.info.setTopView({session:r.id}),t.tui.info.showToast(A.t(`cmd.titleSessionFork`),A.t(`cmd.forkSuccess`,{idShort:r.id.slice(0,8)}))}async function Wn(e,t){let n=t.state.session.model?.id,r=await t.app.createSession({interactive:!0,...n?{modelId:n}:{}}),i=t.state.session;if(t.state.session.isBusy){let[e]=H(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 P(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(I(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(),t.tui.messages.pushMessages([]),t.callbacks.restoreSwitchedSession(),t.tui.info.setTopView({session:r.id});{let n=Oe(r.session.metadata().title,[{role:`user`,content:e}],r.id);t.tui.stores.tasks.setSessionTitle(n),t.tui.lifecycle.setTerminalTitle(n)}t.state.agentProcessing=!0,t.tui.engine.pushEngineEvent({kind:`agentProcessing`,value:!0}),t.tui.messages.echoUserInput(e,{pending:!0}),r.prompt(e).catch(e=>{t.tui.info.showToast(A.t(`cmd.titleSessionCmd`),`Prompt failed: ${e instanceof Error?e.message:String(e)}`)}).finally(()=>{t.state.agentProcessing=!1,t.tui.engine.pushEngineEvent({kind:`agentProcessing`,value:!1})})}async function Gn(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)}`:``}`;t.state.agentProcessing=!0,t.tui.engine.pushEngineEvent({kind:`agentProcessing`,value:!0}),a.session.prompt(o).catch(e=>{t.tui.info.showToast(`a2ui`,`Action failed: ${e instanceof Error?e.message:String(e)}`)}).finally(()=>{t.state.agentProcessing=!1,t.tui.engine.pushEngineEvent({kind:`agentProcessing`,value:!1})})}async function Kn(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 dt(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} | 预估回收: ${qn(e)}`,i=[`会话 ID 大小 最后活跃 标题`,...d.map(e=>` ${e.session.id.slice(0,8)} ${qn(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(`
|
|
7
|
+
`)});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 ft(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 文件,回收 ${qn(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 qn(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 Jn(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 Yn(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`,A.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){vn(i.id),t.tui.info.showToast(`session kill`,`Removed stale session ${i.id.slice(0,8)} from background.`);return}a.abort(),vn(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 Xn(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(A.t(`cmd.titleSessionFork`),A.t(`cmd.forkFailed`));return}let a=`${r} (fork)`,o=(await t.tui.modal.openModal({kind:`input`,title:A.t(`cmd.forkNameTitle`),placeholder:a,defaultValue:a})??``).trim()||a;i.renameSession(o);let s=t.state.session;if(t.state.session.isBusy){let[e]=H(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 P(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(I(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=R(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(A.t(`cmd.titleSessionFork`),A.t(`cmd.forkSuccessNamed`,{title:o}))}function Zn(e){switch(e){case`global`:return A.t(`cmd.scopeGlobal`);case`repository`:return A.t(`cmd.scopeRepository`);default:return A.t(`cmd.scopeProject`)}}function Qn(e,t,n){return{workspaceDir:e.app.workspaceDir,workspaceRoot:t===`repository`?pe(e.app.workspaceDir):void 0,global:t===`global`,dryRun:n}}async function $n(e){let{name:t,type:n,scope:r,ctx:i,onDone:a}=e,o=i.app.settings.get(`mcp_servers`),s=await Ne(t,n,Qn(i,r,!0),()=>o,async()=>{});if(!s.success){i.tui.info.showToast(A.t(`cmd.titleUninstall`),A.t(`cmd.uninstallFailed`,{err:s.error??A.t(`cmd.unknownError`)})),a?.();return}let c=s.plan??[];i.tui.modal.openModal({kind:`confirm`,title:A.t(`cmd.uninstallConfirmTitle`,{type:n,name:t}),message:[A.t(`cmd.uninstallConfirmScope`,{scopeLabel:Zn(r)}),...c].join(`
|
|
8
|
+
`),confirmLabel:A.t(`cmd.uninstallConfirmYes`),dangerous:!0,onConfirm:()=>{er(e)},onCancel:()=>a?.()})}async function er(e){let{name:t,type:n,scope:r,ctx:i,onDone:a}=e,o=i.app.settings.get(`mcp_servers`),s=await Ne(t,n,Qn(i,r,!1),()=>o,async e=>{await i.app.settings.persist({mcp_servers:e})});if(!s.success){i.tui.info.showToast(A.t(`cmd.titleUninstall`),A.t(`cmd.uninstallFailed`,{err:s.error??A.t(`cmd.unknownError`)})),a?.();return}i.tui.info.showToast(A.t(`cmd.titleUninstall`),A.t(`cmd.uninstalled`,{type:n,name:t,scope:Zn(r)})),n===`plugin`&&await we(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(A.t(`cmd.titleUninstall`),A.t(`cmd.uninstallRefreshed`))}catch(e){i.tui.messages.pushMessage({role:`command_echo`,command:`/extension`,status:`error`,summary:A.t(`cmd.uninstalledRefreshErr`,{err:e instanceof Error?e.message:String(e)})})}a?.()}async function tr(e,t){let n=t.app.settings.get(`keybinding_overrides`),r=()=>{t.tui.info.showToast(A.t(`cmd.keybindTitle`),A.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 G(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 nr(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 rr(e,t){nr(e,`model`,t)}function ir(e,t){nr(e,`effort`,t)}function ar(e,t){G(e,`retry.queued`,{attempt:t.attempt,max:t.max,...t.mode===void 0?{}:{mode:t.mode},...t.reason===void 0?{}:{reason:t.reason}})}function or(e,t){G(e,`retry.cancelled`,{attempt:t.attempt})}function sr(e){G(e,`retry.reset`,{})}function cr(e,t,n){G(e,`pause.${t}`,{...n===void 0?{}:{source:n}})}const lr=(e,t,n)=>{let r=Xt(n),i=r?`${e}·${r}`:e;return t?`${i} (${t>=1e6?`${(t/1e6).toFixed(1)}M`:`${Math.round(t/1e3)}K`})`:i},K=[`low`,`medium`,`high`,`xhigh`,`max`];function ur(e,t){return[t,...e.filter(e=>e!==t)].slice(0,5)}function dr(e){let t=new RegExp(String.raw`\[@model:(${Xe}+)\]`,`g`),n=[];return{text:e.replace(t,(e,t)=>(n.push(t.replace(/\\\]/g,`]`)),``)).replace(/\n{3,}/g,`
|
|
9
|
+
|
|
10
|
+
`).trim(),modelIds:n}}async function fr(e,t){let n=dr(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 pr(e){let t=new RegExp(String.raw`\[@effort:(${Xe}+)\]`,`g`),n=[];return{text:e.replace(t,(e,t)=>(n.push(t.replace(/\\\]/g,`]`)),``)).replace(/\n{3,}/g,`
|
|
11
|
+
|
|
12
|
+
`).trim(),levels:n}}function mr(e,t){let n=pr(e),r=n.levels.at(-1);return r&&(K.includes(r)?r!==t.currentEffort&&t.applyEffort(r):t.onInvalidLevel?.(r)),n.text}function hr(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=ur(o.settings.get(`recent_models`)??[],e)),await o.settings.persist(t)}catch{}if(m){if(f.applyModel(m),t.value=!0,e!==p&&(o.syncSessionToolsFor(f.id),rr({tui:i.value??{messages:{pushMessage:()=>{}}},session:f,traceStore:o.storage.traceStore},{from:p,to:m.id,label:lr(m.id,m.contextWindow,f.thinkingLevel)})),m.api.includes(`:`)&&o.firePluginActivationEvent?.(`onProvider:${m.api}`),u?.({kind:`setModel`,modelId:e}),i.value?.stores.tasks.setModelName(lr(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)try{let e=await f.applyModelWithContextFit?.(m);if(e?.compacted){u?.({kind:`recordCompaction`,summary:e.summary??``,replacement:e.replacement??[]});let t=m.contextWindow>=1e6?`${(m.contextWindow/1e6).toFixed(1)}M`:`${Math.round(m.contextWindow/1e3)}k`;i.value?.info.showToast(A.t(`cmd.titleModel`),A.t(`cmd.modelCompactedFor`,{window:t}))}}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(A.t(`cmd.titleModel`),A.t(`model.switchedTo`,{label:l(e)})),`Model → ${e} (active next turn).`}return f.model&&(i.value?.stores.tasks.setModelName(lr(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 gr(e){let{getSession:t,app:n,tuiRef:r,options:i,fmtDisplayModel:a,applyModel:o}=e,s=!1,c=j(n.authStore,`delegation`),l=j(n.authStore,`main-session`);return async()=>{if(s)return`proceed`;s=!0;let u=t().model;if(!u)return`proceed`;let d=async e=>{try{return await c(e)}catch{return{usable:!1,reason:`unauthenticated`}}},f=async e=>{try{return await l(e)}catch{return{usable:!1,reason:`unauthenticated`}}},p=i.value?.model??n.settings.get(`model`);if(typeof p!=`string`||!p)return`proceed`;let m=n.modelRegistry.find(p),h;if(m&&(h=await f(m),h.usable))return m.id!==u.id&&await o(m.id),`proceed`;let g=m?M(m.provider)!==void 0:!0,_=m?M(m.provider)?.env:void 0,v=m?!!n.authStore.oauth.get(m.provider):!1,y=m?g?h?.reason===`intranet-unreachable`?A.t(`model.reasonIntranetUnreachable`,{provider:m.provider}):A.t(`model.reasonUnauthenticated`,{provider:m.provider}):A.t(`model.reasonProviderNotLoaded`,{provider:m.provider}):A.t(`model.reasonNotFound`),b=_?A.t(`model.hintEnvKey`,{provider:m?.provider??``,env:_}):A.t(`model.hint`),x;if((await f(u)).usable)x=u;else for(let e of n.modelRegistry.getAll().filter(e=>e.id!==`__otto_setup__`))if((await d(e)).usable){x=e;break}return r.value?x?await new Promise(t=>{r.value?.modal.openModal({kind:`confirm`,title:A.t(`model.title`),message:[`${a(p)} → ${a(x.id)}`,``,y,``,b],confirmLabel:A.t(`model.permanent`),extraLabel:v?A.t(`model.login`):A.t(`model.setKey`),cancelLabel:A.t(`model.dismiss`),onConfirm:()=>{o(x.id,{persist:!0}).then(()=>t(`proceed`),()=>t(`proceed`))},onExtra:()=>{e.onLogin&&m?.provider?e.onLogin(m.provider):r.value?.info.showToast(A.t(`model.login`),A.t(`model.fallbackLoginToast`,{provider:m?.provider??``})),s=!1,t(`abort`)},onCancel:()=>{e.onExitSession?.(),t(`abort`)}})}):(r.value.modal.openModal({kind:`info`,title:A.t(`model.title`),lines:[a(p),``,y,``,b,``,A.t(`model.noFallback`)],action:m?{kind:`login`,run:()=>e.onLogin?.(m.provider)}:void 0}),s=!1,`abort`):`proceed`}}function _r(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 vr(e){let t=e.trim().split(`
|
|
13
|
+
`)[0].replace(/\s+/g,` `).trim();return t.length>40?`${t.slice(0,39)}…`:t}function yr(e){e.pluginInput.unregisterBySource(`shortcut`);let t=(e.settings.get(`shortcuts`)??[]).map(e=>({label:`@${e.name}`,value:`[@shortcut:${e.name.replace(/]/g,`\\]`)}]`,description:vr(e.text),kind:`shortcut`,source:`shortcut`}));t.length&&e.pluginInput.register(t)}function br(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 xr={low:`cmd.effortDescLow`,medium:`cmd.effortDescMedium`,high:`cmd.effortDescHigh`,xhigh:`cmd.effortDescXhigh`,max:`cmd.effortDescMax`};function Sr(e){let t=K.map(e=>({label:Xt(e),value:`[@effort:${e}]`,description:A.t(xr[e]??`cmd.effortDescLow`),kind:`effort`,source:`builtin-effort`}));e.pluginInput.unregisterBySource(`builtin-effort`),e.pluginInput.register(t)}async function Cr(e,t){t.tui.modal.openModal({kind:`shortcutsPanel`,shortcuts:t.app.getShortcuts(),onSave:(e,n,r)=>{t.app.saveShortcut(e,n,r).then(()=>yr(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(()=>yr(t.app)).catch(e=>{t.tui.info.showToast(`Shortcuts`,`Delete failed: ${e instanceof Error?e.message:String(e)}`)})}})}const wr={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 Tr(e){let t=Math.round(e*8);return`━`.repeat(Math.max(0,t))+`╌`.repeat(Math.max(0,8-t))}async function Er(e,t){let n=e[0]?.toLowerCase();if(n&&K.includes(n)){Dr(t,n);return}if(n){t.tui.info.showToast(A.t(`cmd.titleEffort`),A.t(`cmd.effortUnknown`,{arg:n,levels:K.join(` / `)}));return}let r=t.state.session.thinkingLevel;t.tui.modal.openModal({kind:`select`,title:A.t(`cmd.selectEffortTitle`),options:K.map(e=>{let t=wr[e],n=e===r,i=Tr(t.intensity);return{label:t.label,value:e,detail:`${i} ${t.desc}${n?` · 当前`:``}`}}),onSelect:e=>Dr(t,e),onCancel:()=>{}})}function Dr(e,t){let n=e.state.session,r=n.thinkingLevel;n.applyThinkingLevel(t),e.app.settings.persist({thinking_level:t}),r!==t&&ir({tui:e.tui,session:n,traceStore:e.app.storage.traceStore},{from:r,to:t,label:Xt(t)}),n.model?.id&&e.tui.stores.tasks.setModelName(I(e.app,n.model.id,t)),e.tui.info.showToast(A.t(`cmd.titleEffort`),t)}async function Or(e,t){let n=e[0]?.toLowerCase();if(n===`general`||n===`gen`){q(t);return}if(n===`lang`||n===`language`){Br(e.slice(1),t);return}if(n===`theme`){Vr(e.slice(1),t);return}if(n===`keybindings`||n===`kb`){tr(e.slice(1),t);return}if(n===`shortcuts`){Cr(e.slice(1),t);return}if(n===`proxy`){u(e.slice(1),t);return}if(n){t.tui.info.showToast(A.t(`cmd.titlePreference`),A.t(`cmd.preferenceUsage`));return}kr(t)}function kr(e,t){let n=e.app.settings,r=n.get(`language`),i=r===`zh`?`中文 (zh)`:r===`en`?`English (en)`:`Auto`,a=e.state.themeRegistry??Qe(),o=n.get(`theme_preset`)??{},s=a.get(o.dark??`dark`)?.label??o.dark??`dark`;e.tui.modal.openModal({kind:`select`,title:A.t(`cmd.titlePreference`),detailPlacement:`inline`,options:[{label:A.t(`cmd.prefOptionGeneral`),value:`general`,detail:A.t(`cmd.prefDescGeneral`)},{label:A.t(`cmd.prefOptionLang`),trailingLabel:i,value:`lang`,detail:A.t(`cmd.prefDescLang`)},{label:A.t(`cmd.prefOptionTheme`),trailingLabel:s,value:`theme`,detail:A.t(`cmd.prefDescTheme`)},{label:`Keybindings`,value:`keybindings`,detail:`Browse, search, remap, reset shortcuts`},{label:`Shortcuts`,value:`shortcuts`,detail:`Manage custom @ text shortcuts`},{label:`Proxy`,value:`proxy`,detail:`Configure HTTP proxy`}],defaultSelectedValue:t,onSelect:t=>{t===`general`?q(e):t===`lang`?Br([],e):t===`theme`?Vr([],e):t===`keybindings`?tr([],e):t===`shortcuts`?Cr([],e):t===`proxy`&&u([],e)},onCancel:()=>{}})}let Ar;function q(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===w),f={on:k.toggleOn,off:k.toggleOff},p={on:A.t(`cmd.toggleOn`),off:A.t(`cmd.toggleOff`)},m=e=>Zt(e,f,p);e.tui.modal.openModal({kind:`select`,title:A.t(`cmd.selectGeneralTitle`),detailPlacement:`inline`,subtitle:t,replace:r,options:[{label:A.t(`cmd.genNickname`),trailingLabel:o||`—`,value:`nickname`,detail:A.t(`cmd.genNicknameDesc`)},{label:A.t(`cmd.genCompletionNotice`),trailingLabel:m(s),value:`completion`,detail:A.t(`cmd.genCompletionNoticeDesc`)},{label:A.t(`cmd.genSound`),trailingLabel:m(c),value:`sound`,detail:A.t(`cmd.genSoundDesc`)},{label:A.t(`cmd.genUpdateCheck`),trailingLabel:m(l),value:`updateCheck`,detail:A.t(`cmd.genUpdateCheckDesc`)},{label:A.t(`cmd.genSkillLoop`),trailingLabel:d?m(u):A.t(`cmd.genSkillLoopMissing`),value:`skillLoopPanel`,detail:A.t(`cmd.genSkillLoopEntryDesc`)}],defaultSelectedValue:n??Ar,onHighlight:e=>{Ar=e},onSelect:t=>{if(t===`nickname`){jr(e);return}if(t===`skillLoopPanel`){J(e);return}zr(e,t)},onCancel:()=>{kr(e,`general`)}})}async function jr(e){let t=await e.tui.modal.openModal({kind:`input`,title:A.t(`cmd.genNicknameInputTitle`),placeholder:A.t(`cmd.genNicknamePlaceholder`)});if(t==null){q(e);return}let n=t.trim();await e.app.settings.persist({nickname:n}),q(e,A.t(`cmd.genSaved`))}const Mr=[4,6,12,20];function Nr(e){let t=typeof e==`number`?e:6,n=Mr.includes(t)?`genSkillLoopThr${t}`:``;return n?A.t(`cmd.${n}`):String(t)}function Pr(e){let t=e.app.settings,n=t.get(`skill_loop`)?.min_messages??6;e.tui.modal.openModal({kind:`select`,title:A.t(`cmd.genSkillLoopThresholdTitle`),detailPlacement:`inline`,options:Mr.map(e=>({label:A.t(`cmd.genSkillLoopThr${e}`),value:String(e),detail:A.t(`cmd.genSkillLoopThr${e}Desc`),trailingLabel:e===n?k.toggleOn:void 0})),onSelect:n=>{(async()=>{let r={...t.get(`skill_loop`)??{}};r.min_messages=Number(n),await t.persist({skill_loop:r}),J(e,A.t(`cmd.genSaved`),`threshold`)})()},onCancel:()=>{J(e,void 0,`threshold`)}})}const Fr=[3,14,30,365];function Ir(e){let t=typeof e==`number`?e:14;return Fr.includes(t)?A.t(`cmd.genSkillLoopCd${t}`):A.t(`cmd.genSkillLoopCdDays`,{n:t})}function Lr(e){let t=e.app.settings,n=t.get(`skill_loop`)?.dismiss_cooldown_days??14;e.tui.modal.openModal({kind:`select`,title:A.t(`cmd.genSkillLoopCooldownTitle`),detailPlacement:`inline`,options:Fr.map(e=>({label:A.t(`cmd.genSkillLoopCd${e}`),value:String(e),detail:A.t(`cmd.genSkillLoopCd${e}Desc`),trailingLabel:e===n?k.toggleOn:void 0})),onSelect:n=>{(async()=>{let r={...t.get(`skill_loop`)??{}};r.dismiss_cooldown_days=Number(n),await t.persist({skill_loop:r}),J(e,A.t(`cmd.genSaved`),`cooldown`)})()},onCancel:()=>{J(e,void 0,`cooldown`)}})}function J(e,t,n){let r=e.app.settings,i=r.get(`skill_loop`)?.enabled===!0,a=e.app.activePlugins().some(e=>e.id===w),o={on:k.toggleOn,off:k.toggleOff},s={on:A.t(`cmd.toggleOn`),off:A.t(`cmd.toggleOff`)};if(!a){e.tui.modal.openModal({kind:`select`,title:A.t(`cmd.skillLoopPanelTitle`),detailPlacement:`inline`,subtitle:A.t(`cmd.genSkillLoopMissingHint`),options:[{label:A.t(`cmd.genSkillLoopMissing`),value:`noop`,detail:``}],onSelect:()=>{q(e,void 0,`skillLoopPanel`)},onCancel:()=>{q(e,void 0,`skillLoopPanel`)}});return}e.tui.modal.openModal({kind:`select`,title:A.t(`cmd.skillLoopPanelTitle`),detailPlacement:`inline`,subtitle:t,defaultSelectedValue:n,options:[{label:A.t(`cmd.skillLoopOnOff`),trailingLabel:Zt(i,o,s),value:`toggle`,detail:A.t(`cmd.genSkillLoopEntryDesc`)},...i?[{label:A.t(`cmd.genSkillLoopThreshold`),trailingLabel:Nr(r.get(`skill_loop`)?.min_messages),value:`threshold`,detail:A.t(`cmd.genSkillLoopThresholdDesc`)},{label:A.t(`cmd.genSkillLoopCooldown`),trailingLabel:Ir(r.get(`skill_loop`)?.dismiss_cooldown_days),value:`cooldown`,detail:A.t(`cmd.genSkillLoopCooldownDesc`)},{label:A.t(`cmd.genSkillLoopStatus`),value:`status`,detail:A.t(`cmd.genSkillLoopStatusDesc`)}]:[]],onSelect:t=>{if(t===`threshold`){Pr(e);return}if(t===`cooldown`){Lr(e);return}if(t===`status`){Rr(e);return}(async()=>{let t={...r.get(`skill_loop`)??{}},n=t.enabled!==!0;t.enabled=n,await r.persist({skill_loop:t}),J(e,n?A.t(`cmd.genSkillLoopOn`):A.t(`cmd.genSkillLoopOff`),`toggle`)})()},onCancel:()=>{q(e,void 0,`skillLoopPanel`)}})}function Rr(e){let t=e.app.settings,n=e.app.activePlugins().some(e=>e.id===w),r=Se({workspaceKey:e.app.workspaceRef?.key??te,now:Date.now(),cooldownDays:t.get(`skill_loop`)?.dismiss_cooldown_days,pluginInstalled:n}),i=e=>A.t(`cmd.skillLoopStatusCount`,{n:e}),a=[];if(!n)a.push({label:A.t(`cmd.skillLoopStatusNotInstalled`),value:`noop`,detail:A.t(`cmd.genSkillLoopMissingHint`)});else{a.push({label:A.t(`cmd.skillLoopStatusEpisodes`),trailingLabel:i(r.episodeCount),value:`noop`,detail:A.t(`cmd.skillLoopStatusSuccess`)+` `+i(r.successCount)},{label:A.t(`cmd.skillLoopStatusPending`),trailingLabel:i(r.pendingCount),value:`noop`,detail:i(r.candidateCount)+` `+A.t(`cmd.skillLoopStatusCandidates`)+` · `+i(r.coolingCount)+` `+A.t(`cmd.skillLoopStatusCooling`)});for(let e of r.pending)a.push({label:e.taskSignature,trailingLabel:A.t(`cmd.skillLoopStatusTimes`,{n:e.size}),value:`noop`,detail:A.t(`cmd.skillLoopStatusGroupPending`)});for(let e of r.recentSignatures)a.push({label:e,value:`noop`,detail:A.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:A.t(`cmd.skillLoopStatusTitle`),detailPlacement:`inline`,subtitle:o?A.t(o):void 0,options:a,onSelect:()=>{J(e,void 0,`status`)},onCancel:()=>{J(e,void 0,`status`)}})}async function zr(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}),q(e,A.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}),q(e,A.t(`cmd.genSaved`),t,!0)}function Br(e,t){let n=e[0]?.toLowerCase();if(n===`en`||n===`zh`||n===`auto`){Wr(t,n);return}if(n){t.tui.info.showToast(A.t(`cmd.titlePreference`),A.t(`pref.languageUsage`));return}t.tui.modal.openModal({kind:`select`,title:A.t(`cmd.selectLanguageTitle`),detailPlacement:`inline`,options:[{label:`中文 (zh)`,value:`zh`,detail:A.t(`cmd.langDescZh`)},{label:`English (en)`,value:`en`,detail:A.t(`cmd.langDescEn`)},{label:`Auto`,value:`auto`,detail:A.t(`cmd.langDescAuto`)}],onSelect:e=>Wr(t,e),onCancel:()=>{kr(t,`lang`)}})}function Vr(e,t){Hr(t)}function Hr(e){let t=e.state.themeRegistry??Qe(),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:A.t(`cmd.prefOptionTheme`),detailPlacement:`inline`,options:[{label:A.t(`cmd.themeDarkPresetOption`),value:`preset-dark`,detail:A.t(`cmd.themeDarkPresetDesc`),trailingLabel:r?.label},{label:A.t(`cmd.themeLightPresetOption`),value:`preset-light`,detail:A.t(`cmd.themeLightPresetDesc`),trailingLabel:i?.label}],onSelect:t=>{if(t===`preset-dark`){Ur(e,`dark`);return}if(t===`preset-light`){Ur(e,`light`);return}},onCancel:()=>{kr(e,`theme`)}})}function Ur(e,t){let n=e.state.themeRegistry??Qe(),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`?A.t(`cmd.themePresetBuiltin`):A.t(`cmd.themePresetFromExtension`,{id:e.source.extensionId}),trailingLabel:e.id===i?`✓`:void 0})),{label:A.t(`cmd.themePresetReset`),value:`__reset__`,detail:A.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`?A.t(`cmd.themePresetTitleDark`):A.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(A.t(`cmd.titlePreference`),A.t(`cmd.themePresetSaved`,{label:s??a??t}))},onCancel:()=>{s(),e.tui.info.showToast(A.t(`cmd.titlePreference`),A.t(`cmd.selectCancelled`))}})}function Wr(e,t){e.state.currentLang=e.tui.lifecycle.setLanguage(t),jt(t),e.tui.plugins.setCommands(e.callbacks.refreshSlashCommands()),e.app.settings.persist({language:t}),e.tui.info.showToast(A.t(`cmd.titleLanguage`),A.t(`pref.languageSwitched`,{l:e.state.currentLang,name:e.state.currentLang===`zh`?`中文`:`English`}))}async function Gr(e,t){let n=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(A.t(`cmd.titlePlugin`),A.t(`cmd.pluginUsage`,{seg:(i?`untrust`:`trust`)==`untrust`?`untrust `:``}));return}let o=r({cwd:n,homedir:_()}).find(e=>e.id===a);if(!o){t.tui.info.showToast(A.t(`cmd.titlePlugin`),A.t(`cmd.pluginNotFound`,{id:a}));return}if(i){try{Pe(o.dir)}catch(e){t.tui.info.showToast(A.t(`cmd.titlePlugin`),`撤销信任失败,权限未收回:${e instanceof Error?e.message:String(e)}`);return}t.tui.info.showToast(A.t(`cmd.titlePlugin`),A.t(`cmd.pluginUntrusted`,{id:a}))}else li(t,o);return}if(i===`trust`){Me(n),t.tui.info.showToast(A.t(`cmd.titleCompat`),A.t(`cmd.compatTrusting`)),t.app.reloadCapabilities().then(e=>{t.tui.plugins.setPluginRegistrations(t.app.getPluginRegistrations()),t.tui.info.showToast(A.t(`cmd.titleCompat`),A.t(`cmd.compatTrusted`,{count:e.mcpTools}))},e=>t.tui.info.showToast(A.t(`cmd.titleCompat`),A.t(`cmd.compatReloadFailed`,{err:e instanceof Error?e.message:String(e)})));return}if(i===`untrust`){Fe(n),t.tui.info.showToast(A.t(`cmd.titleCompat`),A.t(`cmd.compatUntrusted`));return}let a=de(n),o=se(n,{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?A.t(`cmd.compatTrustedLabel`):A.t(`cmd.compatUntrustedLabel`);s.push(`${e.join(A.t(`cmd.listSep`))} ${t}`)}if(o.highRiskKeys.length>0){let e=o.highRiskKeys.join(A.t(`cmd.listSep`));s.push(o.gated?A.t(`cmd.compatConfigGated`,{keys:e}):A.t(`cmd.compatConfigActive`,{keys:e}))}let c=r({cwd:n,homedir:_()}).filter(e=>e.scope===`project`||e.scope===`repository`);for(let e of c){let t=fe(e);if(!t.surface.any)continue;let n=t.gated?A.t(`cmd.compatUntrustedLabel`):A.t(`cmd.compatTrustedLabel`);s.push(`plugin:${e.id} ${n}${t.gated?` → /trust plugin ${e.id}`:``}`)}if(s.length===0){t.tui.info.showToast(A.t(`cmd.titleCompat`),A.t(`cmd.compatNone`));return}o.gated?t.tui.modal.openModal({kind:`info`,title:A.t(`cmd.titleCompat`),lines:s}):t.tui.info.showToast(A.t(`cmd.titleCompat`),s.join(`
|
|
14
|
+
`))}async function Kr(e,t){let n=e[0];if(n===`clear`){t.app.clearSessionAlwaysAllow(t.state.session.id),t.tui.info.showToast(A.t(`cmd.titlePermissions`),A.t(`cmd.permsCleared`));return}if(n===`add`||n===`remove`){let r=e.slice(1).join(` `).trim();if(!r){t.tui.info.showToast(A.t(`cmd.titlePermissions`),A.t(`cmd.permsManageHint`));return}if(n===`add`){if(!t.app.isWellFormedAllowEntry(r)){t.tui.info.showToast(A.t(`cmd.titlePermissions`),A.t(`cmd.permsInvalidEntry`,{entry:r}));return}await t.app.allowToolAlways(r),t.tui.info.showToast(A.t(`cmd.titlePermissions`),A.t(`cmd.permsAdded`,{entry:r}))}else{let e=await t.app.disallowToolAlways(r);t.tui.info.showToast(A.t(`cmd.titlePermissions`),e?A.t(`cmd.permsRemoved`,{entry:r}):A.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(`, `):A.t(`cmd.permsEmpty`)}`;t.tui.modal.openModal({kind:`permissions`,lines:[a(A.t(`cmd.permsSessionLabel`),r),a(A.t(`cmd.permsProjectLabel`),i),``,...qr(t),A.t(`cmd.permsClearHint`),A.t(`cmd.permsManageHint`)]})}function qr(e){let t=e.app.getRecentPermissionDecisions?.(e.state.session.id,8)??[];if(t.length===0)return[`${A.t(`cmd.permsRecentLabel`)} ${A.t(`cmd.permsEmpty`)}`,``];let n=e=>{let t=new Date(e),n=e=>String(e).padStart(2,`0`);return`${n(t.getHours())}:${n(t.getMinutes())}:${n(t.getSeconds())}`};return[A.t(`cmd.permsRecentLabel`),...t.map(e=>{let t=e.filePath?` ${e.filePath}`:``;return` ${n(e.timestamp)} ${e.effect.padEnd(5)} ${e.toolName}${t} (${e.policyName})`}),``]}async function Jr(e,t){let r=n();t.tui.info.showToast(A.t(`cmd.titleUpgrade`),A.t(`cmd.upgradeChecking`,{current:r}));let i=await Nt(r);if(!i){t.tui.modal.openModal({kind:`info`,title:A.t(`cmd.titleUpgrade`),lines:[A.t(`cmd.upgradeNoNetwork`)]});return}if(!i.newer){t.tui.info.showToast(A.t(`cmd.titleUpgrade`),A.t(`cmd.upgradeLatest`,{current:r}));return}t.tui.modal.openModal({kind:`select`,title:A.t(`cmd.titleUpgrade`),subtitle:A.t(`cmd.upgradeConfirmSubtitle`,{current:r,latest:i.latest}),subtitleTone:`warning`,layout:`buttons`,options:[{label:A.t(`common.upgradeButton`),value:`upgrade`,color:`accent`},{label:A.t(`common.cancelButton`),value:`cancel`,color:`amber`}],onSelect:e=>{e===`upgrade`&&Yr(t,i.latest)}})}async function Yr(e,t){e.tui.info.showToast(A.t(`cmd.titleUpgrade`),A.t(`cmd.upgrading`));let{ok:n,error:r}=await It(t);if(!n){e.tui.info.showToast(A.t(`cmd.titleUpgrade`),A.t(`cmd.upgradeFailed`,{err:r??A.t(`cmd.unknownError`)}));return}e.state.restartRequested=!0,e.tui.lifecycle.stop()}async function Xr(e,t){if(!e.includes(`--force`))return!1;let r=await Nt(n());return r?r.newer?(await Yr(t,r.latest),!0):(t.tui.info.showToast(A.t(`cmd.titleUpgrade`),A.t(`cmd.upgradeLatest`,{current:n()})),!0):(t.tui.info.showToast(A.t(`cmd.titleUpgrade`),A.t(`cmd.upgradeNoNetwork`)),!0)}async function Zr(e,t,n){let r=A.t(`cmdDesc`,{returnObjects:!0}),i={session:A.t(`cmd.helpGroupSession`),model:A.t(`cmd.helpGroupModel`),agent:A.t(`cmd.helpGroupAgent`),debug:A.t(`cmd.helpGroupDebug`),ui:A.t(`cmd.helpGroupUi`),other:A.t(`cmd.helpGroupOther`)},a=[];for(let e of Ma){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=`${A.t(`cmd.helpPrefixes`)} !<cmd> ${A.t(`cmd.helpPrefixShell`)} · @<file> ${A.t(`cmd.helpPrefixFile`)}`;t.tui.modal.openModal({kind:`select`,title:A.t(`cmd.titleCommands`),subtitle:o,searchable:!0,options:a,onSelect:e=>{Ra(e,[],t)},onCancel:()=>{}})}async function Qr(e,t){t.tui.panes.togglePane(`history`)}async function $r(e,t){t.tui.panes.togglePane(`notifications`)}async function ei(e,t){t.tui.panes.togglePane(`prompts`)}async function ti(e,t){t.tui.panes.setServices(!0)}async function ni(e,t){t.tui.info.showToast(A.t(`cmd.titleUpgrade`),A.t(`cmd.upgradeCheckScanning`));try{let e=Ae({workspaceDir:t.app.workspaceDir,workspaceRoot:pe(t.app.workspaceDir),scope:`all`});if(e.length===0){t.tui.info.showToast(A.t(`cmd.titleUpgrade`),A.t(`cmd.upgradeCheckNoVersioned`));return}let n=await ie(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(A.t(`cmd.upgradeCheckLineUpdate`,{tag:t,name:e.name,installed:e.installed,latest:e.latest??``}))):r.push(A.t(`cmd.upgradeCheckLineLatest`,{tag:t,name:e.name,installed:e.installed}))}i>0&&(r.push(``),r.push(A.t(`cmd.upgradeCheckSummary`,{count:i}))),t.tui.modal.openModal({kind:`info`,title:A.t(`cmd.titleUpgradeCheck`),lines:r})}catch(e){t.tui.info.showToast(A.t(`cmd.titleUpgrade`),A.t(`cmd.upgradeCheckFailed`,{err:e instanceof Error?e.message:String(e)}))}}var ri=N({confirmHighRiskCapabilities:()=>ui,formatPluginContributionsSummary:()=>si,handleDelegatesToggle:()=>fi,handleExtension:()=>Y,handleJobStart:()=>pi,pluginCapabilityLabel:()=>ci,promptPluginTrust:()=>li,runPluginInstall:()=>di});function ii(e){return!e.endsWith(O(`.claude`,`skills`))}function ai(e,t){return ii(t)?e===`project`?`project`:e===`global`?`global`:null:null}function oi(e,t){let n={project:`project`,global:`global`,plugin:`plugin`,inline:`inline`}[e]??e;return t?`${n} (${t})`:n}function si(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 ci(e){switch(e){case`provider`:return A.t(`cmd.pluginCapabilityProvider`);case`tools`:return A.t(`cmd.pluginCapabilityTools`);case`tui.renderer`:return A.t(`cmd.pluginCapabilityTuiRenderer`);case`network`:return A.t(`cmd.pluginCapabilityNetwork`);case`wire-protocol`:return A.t(`cmd.pluginCapabilityWireProtocol`);case`a2ui.component`:return A.t(`cmd.pluginCapabilityA2uiComponent`);case`panel.backend`:return A.t(`cmd.pluginCapabilityPanelBackend`);case`input.resolver`:return A.t(`cmd.pluginCapabilityInputResolver`);case`a2ui.renderer`:return A.t(`cmd.pluginCapabilityA2uiRenderer`);default:return}}function li(e,t){let n=fe(t),r=n.pendingCapabilities,i=()=>{if(je(t.dir),r.length>0){let n=t.manifest.version;n?he(t.dir,r,n):(e.tui.info.showToast(A.t(`cmd.titlePlugin`),`插件 "${t.id}" manifest 无版本字段——授权不绑定版本,后续更新后需重新信任`),me(t.dir,r))}e.tui.info.showToast(A.t(`cmd.titlePlugin`),A.t(`cmd.pluginTrusting`,{id:t.id})),e.app.reloadCapabilities().then(n=>{e.tui.plugins.setPluginRegistrations(e.app.getPluginRegistrations()),e.tui.info.showToast(A.t(`cmd.titlePlugin`),A.t(`cmd.pluginTrusted`,{id:t.id,count:n.mcpTools}))},t=>e.tui.info.showToast(A.t(`cmd.titlePlugin`),A.t(`cmd.compatReloadFailed`,{err:t instanceof Error?t.message:String(t)})))},a=n.surface;if(!a.any&&r.length===0){i();return}let o=[A.t(`cmd.pluginTrustConfirmIntro`)];if(a.mcpJson&&o.push(`• ${A.t(`cmd.pluginSurfaceMcp`)}`),a.commands&&o.push(`• ${A.t(`cmd.pluginSurfaceCommands`)}`),a.scripts&&o.push(`• ${A.t(`cmd.pluginSurfaceScripts`)}`),a.panels&&o.push(`• ${A.t(`cmd.pluginSurfacePanels`)}`),a.skills&&o.push(`• ${A.t(`cmd.pluginSurfaceSkills`)}`),a.agents&&o.push(`• ${A.t(`cmd.pluginSurfaceAgents`)}`),r.length>0){o.push(``,A.t(`cmd.pluginCapabilityIntro`));for(let e of r){let t=ci(e);t&&o.push(`• ${t}`)}}o.push(``,A.t(`cmd.pluginTrustConfirmHint`)),e.tui.modal.openModal({kind:`select`,title:A.t(`cmd.pluginTrustConfirmTitle`,{id:t.id}),subtitle:o.join(`
|
|
15
|
+
`),layout:`buttons`,options:[{label:A.t(`cmd.pluginTrustConfirmAction`),value:`trust`,color:`accent`},{label:A.t(`cmd.commonCancel`),value:`cancel`,color:`gray`}],onSelect:e=>{e===`trust`&&i()},onCancel:()=>{}})}async function ui(e,t,n){if(t.length===0)return!0;let r=[A.t(`cmd.pluginCapabilityIntro`)];for(let e of t){let t=ci(e);t&&r.push(`• ${t}`)}return new Promise(t=>{n.tui.modal.openModal({kind:`select`,title:A.t(`cmd.pluginInstallConfirmTitle`,{name:e}),subtitle:r.join(`
|
|
16
|
+
`),layout:`buttons`,options:[{label:A.t(`cmd.pluginInstallConfirmAction`),value:`install`,color:`accent`},{label:A.t(`cmd.commonCancel`),value:`cancel`,color:`gray`}],onSelect:e=>t(e===`install`),onCancel:()=>t(!1)})})}async function di(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(A.t(`cmd.titleInstall`),A.t(`cmd.pluginInstallInvalidName`,{name:e})),!1;let o=s[e]?.pkg??e,c=De(o),l;if(!c)try{i?.(`Downloading from npm registry`);let e=await ge(o,{global:!0,as:`plugin`,postInstallExecutor:oe});e.success&&e.targetPath?(c=e.targetPath,l={id:e.name??o,dir:e.targetPath,created:!0,compileWarnings:[],version:e.manifest?.version}):r||t.tui.info.showToast(A.t(`cmd.titleInstall`),A.t(`cmd.pluginInstallFailed`,{err:e.error??`未知错误`}))}catch(e){r||t.tui.info.showToast(A.t(`cmd.titleInstall`),A.t(`cmd.pluginInstallFailed`,{err:e instanceof Error?e.message:String(e)}))}if(!c)return r||t.tui.info.showToast(A.t(`cmd.titleInstall`),A.t(`cmd.pluginInstallNotFound`,{pkg:o})),!1;let u=be(c);if(!r&&!await ui(e,u,t))return t.tui.info.showToast(A.t(`cmd.titleInstall`),A.t(`cmd.pluginInstallCancelled`)),!1;let d;if(l)d=l;else try{i?.(`Installing plugin`),d=await _e({pkg:o})}catch(e){return r||t.tui.info.showToast(A.t(`cmd.titleInstall`),A.t(`cmd.pluginInstallFailed`,{err:e instanceof Error?e.message:String(e)})),!1}r||t.tui.info.showToast(A.t(`cmd.titleInstall`),A.t(`cmd.pluginInstalled`,{seg:d.created?`Installed ${d.id}`:`${d.id} already up to date`})),await Ce(t.app.settings,{id:d.id,source:`npm`,sourceSpec:o,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(A.t(`cmd.titleInstall`),A.t(`cmd.pluginInstallFailed`,{err:e}));u.length>0&&(i?.(`Authorizing capabilities`),je(d.dir),d.version?he(d.dir,u,d.version):me(d.dir,u));try{i?.(`Reloading capabilities`),(await t.app.reloadCapabilities()).pendingProviderCapabilities.includes(d.id)&&(r||t.tui.info.showToast(A.t(`cmd.titleInstall`),A.t(`cmd.pluginInstallPendingCaps`,{id:d.id})),a?.(d.id))}catch(e){r||t.tui.info.showToast(A.t(`cmd.titleInstall`),A.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-DbAq_BRH.js`);await e(t)}catch{}return!0}if(!r){await new Promise(e=>setImmediate(e));let{handleModel:e}=await Promise.resolve().then(()=>mi);await e([],t)}return!0}async function fi(e,t){t.tui.panes.togglePane(`backgroundTasks`)}async function pi(e,t){let n=e.join(` `);if(!n){t.tui.info.showToast(A.t(`cmd.titleJob`),A.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(A.t(`cmd.titleReverted`),A.t(`cmd.jobReverted`,{id:e,msg:n.message}));else{let r=n.conflictPaths.length?A.t(`cmd.jobConflictFiles`,{joinedPaths:n.conflictPaths.join(`
|
|
17
|
+
`)}):``;t.tui.messages.pushMessage({role:`command_echo`,command:`/go revert ${e}`,status:`error`,summary:A.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(A.t(`cmd.titleDelegated`),A.t(`cmd.delegated`,{title:e.title}))}catch(e){t.tui.messages.pushMessage({role:`command_echo`,command:`/go`,status:`error`,summary:A.t(`cmd.delegateFailed`,{err:e instanceof Error?e.message:String(e)})})}}async function Y(e,t){let n=e[0]?.toLowerCase();if(n===`trust`)return Gr(e.slice(1),t);if(n===`install`)return d(e.slice(1),t);if(n===`registry`)return l(e.slice(1),t);if(n===`search`)return c(e.slice(1),t);if(n===`update`)return ni([`--check`],t);if(n===`reload`)return In(e.slice(1),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;ue(a,{open:e=>ve(e),runCommand:async(e,n)=>{let{dispatchSlashCommand:r}=await Promise.resolve().then(()=>ja);await r(e,n?n.split(/\s+/).filter(Boolean):[],t)}}).catch(e=>i(A.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-DYHR-ONu.js`),{hits:r,warnings:a}=await n(t,e.trim());if(r.length===0){i(A.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(()=>ja);await e(`extension`,[`install`,...a],t)})().catch(e=>i(A.t(`cmd.titlePlugin`),e instanceof Error?e.message:String(e)))},onCancel:()=>o()})},u=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:A.t(`cmd.extSkillGroupOverview`)},{kind:`row`,label:A.t(`cmd.extSkillLabelDesc`),value:s.description||`—`},{kind:`row`,label:A.t(`cmd.extSkillLabelStatus`),value:n.status,tone:n.status===`error`||n.status===`disabled`?`error`:`success`},{kind:`row`,label:A.t(`cmd.extSkillLabelSource`),value:A.t(`cmd.extSkillSourceLabel`,{seg:oi(n.source.type,n.source.id)}),tone:`muted`},...ii(n.source.root)?[]:[{kind:`text`,value:A.t(`cmd.extSkillManagedExternally`,{root:n.source.root}),tone:`muted`}],{kind:`group`,title:A.t(`cmd.extSkillGroupTrigger`)},{kind:`row`,label:A.t(`cmd.extSkillLabelTriggerMode`),value:s.trigger===`manual`?A.t(`cmd.extSkillTriggerManual`):A.t(`cmd.extSkillTriggerAuto`)},...s.priority===void 0?[]:[{kind:`row`,label:A.t(`cmd.extSkillLabelPriority`),value:String(s.priority)}],{kind:`group`,title:A.t(`cmd.extSkillGroupDependencies`)},{kind:`row`,label:A.t(`cmd.extSkillLabelDependencies`),value:s.dependencies?.length?s.dependencies.join(`, `):A.t(`cmd.extSkillNoDependencies`),tone:s.dependencies?.length?void 0:`muted`},{kind:`group`,title:A.t(`cmd.extSkillGroupTags`)},{kind:`row`,label:A.t(`cmd.extSkillLabelTags`),value:s.tags?.length?s.tags.join(`, `):A.t(`cmd.extSkillNoTags`),tone:s.tags?.length?void 0:`muted`}];n.status===`error`&&n.error&&c.push({kind:`group`,title:A.t(`cmd.extSkillGroupError`)},{kind:`text`,value:n.error,tone:`error`}),t.tui.modal.openModal({kind:`extensionDetail`,title:A.t(`cmd.extSkillTitle`,{name:e,state:r?`enabled`:`disabled`}),meta:`skill · ${n.source.type}`,metaStatus:{label:r?A.t(`cmd.extEnableLabel`):A.t(`cmd.extDisableLabel`),enabled:r},actions:[{label:r?A.t(`cmd.extDisableLabel`):A.t(`cmd.extEnableLabel`),value:`toggle`,color:r?`amber`:`green`},{label:A.t(`cmd.extViewFullTextLabel`),value:`view-full-text`,color:`gray`},...ai(n.source.type,n.source.root)?[{label:A.t(`cmd.uninstallActionLabel`),value:`uninstall`,color:`red`}]:[]],dataListEntries:c,fullText:{title:A.t(`cmd.extSkillFullTextTitle`,{name:e}),content:n.definition.body||A.t(`cmd.extSkillNoBody`)},onAction:async s=>{if(s===`toggle`){try{await t.app.extensions.setEnabled(`skill`,e,!r),i(A.t(`cmd.titleExtension`),A.t(`cmd.extToggled`,{name:e,verb:r?`Disabled`:`Enabled`,seg:` — applies next turn`}))}catch(e){a(A.t(`cmd.extToggleFailed`,{err:e instanceof Error?e.message:String(e)}))}u(e);return}if(s===`uninstall`){let r=ai(n.source.type,n.source.root);if(!r)return;await $n({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:A.t(`cmd.extAgentGroupOverview`)},{kind:`row`,label:A.t(`cmd.extAgentLabelDesc`),value:n.description||`—`},{kind:`row`,label:A.t(`cmd.extAgentLabelStatus`),value:r?A.t(`cmd.extEnableLabel`):A.t(`cmd.extDisableLabel`),tone:r?`success`:`error`},{kind:`group`,title:A.t(`cmd.extAgentGroupCapabilities`)},{kind:`row`,label:A.t(`cmd.extAgentLabelTaskTypes`),value:n.taskTypes.length?n.taskTypes.join(`, `):A.t(`cmd.extAgentNoTaskTypes`),tone:n.taskTypes.length?void 0:`muted`},{kind:`row`,label:A.t(`cmd.extAgentLabelCapabilities`),value:n.capabilities.length?n.capabilities.join(`, `):A.t(`cmd.extAgentNoCapabilities`),tone:n.capabilities.length?void 0:`muted`},{kind:`group`,title:A.t(`cmd.extAgentGroupTools`)},{kind:`row`,label:A.t(`cmd.extAgentLabelDefaultTools`),value:n.defaultTools?.length?n.defaultTools.join(`, `):A.t(`cmd.extAgentAllTools`),tone:n.defaultTools?.length?void 0:`muted`},{kind:`row`,label:A.t(`cmd.extAgentLabelDisallowedTools`),value:n.disallowedTools?.length?n.disallowedTools.join(`, `):A.t(`cmd.extAgentNoDisallowedTools`),tone:n.disallowedTools?.length?void 0:`muted`},{kind:`group`,title:A.t(`cmd.extAgentGroupExecution`)},{kind:`row`,label:A.t(`cmd.extAgentLabelPromptMode`),value:n.promptMode??`append`,tone:`muted`},...n.preferredModelTier?[{kind:`row`,label:A.t(`cmd.extAgentLabelModelTier`),value:n.preferredModelTier}]:[],{kind:`row`,label:A.t(`cmd.extAgentLabelAllowSubagents`),value:n.allowSubagents?A.t(`cmd.extEnableLabel`):A.t(`cmd.extDisableLabel`),tone:n.allowSubagents?void 0:`muted`}];t.tui.modal.openModal({kind:`extensionDetail`,title:A.t(`cmd.extAgentTitle`,{name:e,state:r?`enabled`:`disabled`}),meta:`agent`,metaStatus:{label:r?A.t(`cmd.extEnableLabel`):A.t(`cmd.extDisableLabel`),enabled:r},actions:[{label:r?A.t(`cmd.extDisableLabel`):A.t(`cmd.extEnableLabel`),value:`toggle`,color:r?`amber`:`green`},{label:A.t(`cmd.extViewFullTextLabel`),value:`view-full-text`,color:`gray`}],dataListEntries:s,fullText:{title:A.t(`cmd.extAgentFullTextTitle`,{name:e}),content:n.systemPromptTemplate||A.t(`cmd.extSkillNoBody`)},onAction:async n=>{if(n===`toggle`){try{await t.app.extensions.setEnabled(`agent`,e,!r),i(A.t(`cmd.titleExtension`),A.t(`cmd.extToggled`,{name:e,verb:r?`Disabled`:`Enabled`,seg:` — applies next turn`}))}catch(e){a(A.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?A.t(`cmd.extDisableLabel`):A.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:A.t(`cmd.extMcpTitle`,{name:r.name,status:l}),options:[{label:A.t(`cmd.extReconnectLabel`),value:`reconnect`},s,...r.readonly?[]:[{label:A.t(`cmd.uninstallActionLabel`),value:`uninstall`}]],onSelect:async s=>{if(s===`toggle`){try{await t.app.extensions.setEnabled(r.category,n,!r.enabled),i(A.t(`cmd.titleExtension`),A.t(`cmd.extToggled`,{name:r.name,verb:r.enabled?`Disabled`:`Enabled`,seg:``}))}catch(e){a(A.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(A.t(`cmd.titleExtension`),A.t(`cmd.extReconnectUnavailable`,{id:n})),p(e,n);return}try{await r.disconnect(n).catch(()=>{}),await r.connect(n,o),i(A.t(`cmd.titleExtension`),A.t(`cmd.extReconnected`,{id:n}))}catch(e){a(A.t(`cmd.extReconnectFailed`,{id:n,err:e instanceof Error?e.message:String(e)}))}p(e,n);return}if(s===`uninstall`){await $n({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`?u(n):e===`agent`?f(n):t.tui.modal.openModal({kind:`select`,title:A.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(A.t(`cmd.titleExtension`),A.t(`cmd.extToggled`,{name:r.name,verb:r.enabled?`Disabled`:`Enabled`,seg:r.applies===`live`?``:` — applies next turn`}))}catch(e){a(A.t(`cmd.extToggleFailed`,{err:e instanceof Error?e.message:String(e)}))}p(e,n);return}},onCancel:()=>o()})},m=(e,n,s,c,l)=>{let u=t.app.workspaceDir??process.cwd(),d=r({cwd:u,homedir:_()}).find(t=>t.id===e);if(!d){o();return}let f=fe(d),p=f.surface.any?f.gated?A.t(`cmd.extPluginUntrusted`):f.pendingCapabilities.length>0?A.t(`cmd.extPluginCapabilityPending`,{caps:f.pendingCapabilities.join(`, `)}):A.t(`cmd.extPluginTrusted`):A.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(`, `)}`:` —`,y=(t.app.getPluginPanelRegistrations?.()??[]).filter(t=>t.pluginId===e),b=si({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}),x=d.scope===`builtin`?[]:[{label:n?A.t(`cmd.extDisableLabel`):A.t(`cmd.extEnableLabel`),value:`toggle`,color:n?`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;x.push({label:e?A.t(`cmd.extPluginTrustLabel`):A.t(`cmd.extPluginUntrustLabel`),value:e?`trust`:`untrust`,color:e?`accent`:`gray`})}x.push({label:A.t(`cmd.extReloadLabel`),value:`reload`}),d.scope!==`builtin`&&x.push({label:A.t(`cmd.uninstallActionLabel`),value:`uninstall`,color:`red`});let ee=re(d,{"extension.id":e,"extension.enabled":n,"extension.trusted":f.trusted,"extension.scope":d.scope,"extension.category":`plugin`}),S=d.manifest.contributes,C=Ee(ne.extensionDetailActions,S?.menus,S?.actions,ee),te=new Map(C.map(e=>[e.id,e.command]));for(let e of C){let n=`${d.id}:action.${e.id}.title`,r=t.app.i18nRegistry.t(n),i=r===n?e.title:r;x.push({label:i,value:`contrib:${e.id}`,color:e.color})}let w={open:e=>ve(e),runCommand:async(e,n)=>{let{dispatchSlashCommand:r}=await Promise.resolve().then(()=>ja);await r(e,n?n.split(/\s+/).filter(Boolean):[],t)},runScript:async e=>{if(fe(d).gated){i(A.t(`cmd.titlePlugin`),A.t(`cmd.extPluginUntrusted`));return}await ke(d,e)}},T=y[0];T&&t.app.firePluginActivationEvent?.(`onView:${T.id}`);let ie;if(e===`plugin-feishu-use`){let e=O(u,`.otto`,`feishu-use.json`),t=!1;try{if(We(e)){let n=JSON.parse(Ke(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`?`仓库`:`项目`;ie=[{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||(ie=[{kind:`text`,value:`未配置 — 点击 [重新配置] 引导设置`,tone:`warning`},{kind:`row`,label:`预期配置路径`,value:e,tone:`muted`}]),x.push({label:`重新配置`,value:`feishu-reconfigure`,color:`amber`})}let ae=()=>{let n=t.app.pluginHealthTracker?.query(e)??{hookTimeouts:0,toolTimeouts:0},r=xe(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:A.t(`cmd.extPluginGroupTitle`)},{kind:`row`,label:A.t(`cmd.extPluginLabelDesc`),value:c},{kind:`row`,label:A.t(`cmd.extPluginLabelScope`),value:d.scope},{kind:`row`,label:A.t(`cmd.extPluginLabelTrust`),value:p},{kind:`row`,label:A.t(`cmd.extPluginLabelSurfaces`),value:v.trim()||`—`},...b?[{kind:`row`,label:A.t(`cmd.extPluginLabelContributions`),value:b}]:[],{kind:`row`,label:A.t(`cmd.extPluginLabelStatus`),value:n?A.t(`cmd.extEnableLabel`):A.t(`cmd.extDisableLabel`),tone:n?`success`:`error`}],se=l?[{kind:`text`,value:l.message,tone:l.kind===`success`?`success`:`error`}]:[];t.tui.modal.openModal({kind:`extensionDetail`,title:A.t(`cmd.extPluginTitle`,{name:s,state:n?`enabled`:`disabled`}),meta:`plugin · ${d.scope}`,metaStatus:{label:n?A.t(`cmd.extEnableLabel`):A.t(`cmd.extDisableLabel`),enabled:n},metaSuffix:p,actions:x,panelInfo:T?{title:T.title,modulePath:T.modulePath,exportName:T.exportName,pluginId:e}:void 0,dataListEntries:[...se,...ie??oe],...ae(),...d.manifest.contributes?.config?{configForm:{schema:d.manifest.contributes.config,values:Te(t.app.pluginModuleManager?.getPluginConfig(e,d.manifest.contributes.config)??{}),onEditConfig:async()=>{let r=t.app.pluginModuleManager?.getPluginConfig(e,d.manifest.contributes.config)??{},i=await t.tui.modal.openModal({kind:`input`,title:`Edit config: ${s}`,description:[`Edit JSON configuration (all fields must be valid JSON)`],placeholder:JSON.stringify(r,null,2)});if(i?.trim())try{let r=JSON.parse(i);if(typeof r!=`object`||!r||Array.isArray(r))throw Error(`config must be a JSON object`);await t.app.pluginModuleManager?.updatePluginConfig(e,r),m(e,n,s,c,{kind:`success`,message:`Configuration updated`})}catch(t){m(e,n,s,c,{kind:`error`,message:`Invalid JSON: ${t instanceof Error?t.message:String(t)}`})}}}}:{},onRefresh:()=>m(e,n,s,c),onAction:async r=>{if(r.startsWith(`contrib:`)){let t=te.get(r.slice(8));if(t)try{await ue(t,w)}catch(e){a(A.t(`cmd.extToggleFailed`,{err:e instanceof Error?e.message:String(e)}))}m(e,n,s,c)}else if(r===`trust`)li(t,d);else if(r===`untrust`){try{Pe(d.dir)}catch(t){m(e,n,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,n,s,c,{kind:`success`,message:A.t(`cmd.pluginUntrusted`,{id:e})})})}else if(r===`toggle`)try{await t.app.extensions.setEnabled(`plugin`,e,!n);try{await t.app.reloadCapabilities(),m(e,!n,s,c,{kind:`success`,message:A.t(`cmd.extToggled`,{name:s,verb:n?`Disabled`:`Enabled`,seg:``})})}catch(t){m(e,!n,s,c,{kind:`error`,message:A.t(`cmd.extToggleReloadFailed`,{verb:n?`Disabled`:`Enabled`,name:s,err:t instanceof Error?t.message:String(t)})})}}catch(t){m(e,n,s,c,{kind:`error`,message:A.t(`cmd.extToggleFailed`,{err:t instanceof Error?t.message:String(t)})})}else if(r===`feishu-reconfigure`)try{let{launchFeishuSetup:e}=await import(`./feishu-setup-DbAq_BRH.js`);await e(t),i(`plugin-feishu-use`,`配置完成。`)}catch(e){a(`feishu-use 配置向导失败:${e instanceof Error?e.message:String(e)}`)}else r===`reload`?t.app.reloadCapabilities?.().then(t=>{m(e,n,s,c,{kind:`success`,message:A.t(`cmd.pluginTrusted`,{id:e,count:t.mcpTools})})}).catch(t=>{m(e,n,s,c,{kind:`error`,message:A.t(`cmd.compatReloadFailed`,{err:t instanceof Error?t.message:String(t)})})}):r===`uninstall`&&await $n({name:e,type:`plugin`,scope:d.scope===`project`||d.scope===`repository`?d.scope:`global`,ctx:t,onDone:()=>o()})},onClose:()=>o()})};o()}var mi=N({handleLogout:()=>xi,handleModel:()=>yi,handleProviderAuth:()=>X,handleProviderLogout:()=>bi,handleServiceLogin:()=>Si,handleServiceLogout:()=>Ci});const hi=`__otto_model_login__`,gi=`__otto_model_setkey__`,_i=`__otto_model_grant_capability__`,vi=`__otto_model_install_plugin__`;async function yi(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`,A.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`,A.t(`cmd.modelRefreshLineMuted`,{provider:r(e.provider),reason:A.t(`cmd.modelRefreshReasonNotAuthenticated`)})):e.reason?.includes(`capability not granted`)?(i[t]=`warning`,A.t(`cmd.modelRefreshLineWarning`,{provider:r(e.provider),reason:A.t(`cmd.modelRefreshReasonPendingCapability`)})):(i[t]=`warning`,A.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:A.t(`cmd.titleModels`),lines:[...a,``,A.t(`cmd.modelRefreshHint`)],action:o?{kind:`extension`,run:()=>{Y([],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:A.t(`cmd.modelDelegateProviderTitle`,{cand:e}),options:[{label:A.t(`cmd.modelDelegateProviderYes`,{cand:e}),value:`yes`},{label:A.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(A.t(`cmd.titleDelegated`),A.t(`cmd.modelProviderDelegated`,{cand:e}))}catch(e){t.tui.messages.pushMessage({role:`command_echo`,command:`/model`,status:`error`,summary:A.t(`cmd.delegateFailed`,{err:e instanceof Error?e.message:String(e)})})}},onCancel:()=>{}});return}t.tui.info.showToast(A.t(`cmd.titleModel`),A.t(`cmd.modelNotFoundUse`,{arg:r}));return}t.tui.info.showToast(A.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=A.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:A.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(A.t(`model.noProviderPlugin`)),v.push(A.t(`model.pendingCapabilities`,{count:_}))):g?v.push(A.t(`model.noProviderPlugin`)):h&&v.push(A.t(`model.noneAvailable`)),!g&&_>0&&v.push(A.t(`model.pendingCapabilities`,{count:_})),t.tui.modal.openModal({kind:`select`,searchable:!0,maxVisible:13,title:h?A.t(`cmd.modelSelectTitle`):A.t(`cmd.modelSelectTitleAvail`),subtitle:v.length>0?v.join(` · `):void 0,subtitleTone:_>0?`warning`:`default`,subtitleActions:g||h||_>0?[...g?[{label:A.t(`model.goInstallPlugin`),value:vi}]:h?[{label:A.t(`model.goLogin`),value:hi},{label:A.t(`model.setKey`),value:gi}]:[],..._>0?[{label:A.t(`model.goGrantCapability`),value:_i}]:[]]: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===hi){await X([],t,{method:`oauth`});return}if(e===gi){await X([],t,{method:`key`});return}if(e===_i){await Y([],t);return}if(e===vi){let{EXTENSION_ALIASES:e}=await import(`./extension-CoJqqktf.js`),{runPluginInstall:n}=await Promise.resolve().then(()=>ri),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:A.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(A.t(`cmd.titleModel`),await t.callbacks.applyModel(e)),t.state.session.model?.id===e&&n?.afterSwitch?.()}})}async function X(e,t,n){if(e[0]===`logout`)return bi(e.slice(1),t);if(e.includes(`--service`))return Si(e,t);let r=t.app.authStore,i=e=>new Promise(n=>t.tui.modal.openModal({kind:`select`,...e,title:e.title??A.t(`cmd.commonSelect`),detailPlacement:`inline`,onSelect:n,onCancel:()=>n(null)})),a=r.listProviders();if(a.length===0){t.tui.info.showToast(A.t(`cmd.titleLogin`),A.t(`cmd.loginNoProviders`));return}let o=e[0]||null,s=e=>r.oauth.get(e)?.name??M(e)?.name??t.callbacks.PROVIDER_DISPLAY_NAMES[e]??e,c=e=>s(e),l=e=>e?A.t(`pref.authModeLabel`,{context:e}):A.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:A.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:A.t(`cmd.loginAuthMethod`,{name:d}),options:[{label:A.t(`cmd.loginMethodOauth`),value:`oauth`},{label:A.t(`cmd.loginMethodKey`),value:`key`}]});if(!e)return;p=e}if(p===`key`){let e=await t.tui.modal.openModal({kind:`input`,title:A.t(`cmd.loginKeyTitle`,{provider:o}),placeholder:A.t(`cmd.loginKeyPlaceholder`),mask:!0});if(!e||!e.trim()){t.tui.info.showToast(A.t(`cmd.titleLogin`),A.t(`cmd.loginCancelledNoKey`));return}await r.setCredentialKey(o,e.trim()),await r.save(),t.tui.info.showToast(A.t(`cmd.titleLogin`),A.t(`cmd.loginKeySaved`,{provider:o})),await t.callbacks.refreshModelsNow(e=>t.tui.info.showToast(A.t(`cmd.titleModels`),e));return}try{let e={};await r.login(o,{onAuth:n=>{if(e=n,n.url)if(Le(n.url))t.tui.info.showToast(A.t(`cmd.titleLogin`),A.t(`cmd.loginOauthBrowserOpened`));else{let e=[A.t(`cmd.loginOauthUrlAuthorize`),`\n${n.url}`];n.instructions&&e.push(`\n${n.instructions}`),t.tui.modal.openModal({kind:`info`,title:A.t(`cmd.loginOauthTitle`,{provider:o}),lines:e})}if(n.code){let e=[A.t(`cmd.loginOauthCodeIntro`)];n.url&&e.push(`\n${n.url}`),e.push(`\n${A.t(`cmd.loginOauthCode`,{code:n.code})}`),n.instructions&&e.push(`\n${n.instructions}`),t.tui.modal.openModal({kind:`info`,title:A.t(`cmd.loginOauthTitle`,{provider:o}),lines:e})}},onProgress:e=>t.tui.info.showToast(A.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(A.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:A.t(`cmd.loginOauthPasteCode`,{provider:o}),description:r.length>0?r:void 0,placeholder:`code#state`,signal:n,actionButton:e.url?{label:A.t(`cmd.loginOauthOpenBrowserButton`),onPress:()=>{Le(e.url)&&t.tui.info.showToast(A.t(`cmd.titleLogin`),A.t(`cmd.loginOauthBrowserOpened`))}}:void 0})??``}}),t.tui.info.showToast(A.t(`cmd.titleLogin`),A.t(`cmd.loginSuccess`,{provider:o})),await t.callbacks.refreshModelsNow(e=>t.tui.info.showToast(A.t(`cmd.titleModels`),e))}catch(e){t.tui.messages.pushMessage({role:`command_echo`,command:`/auth`,status:`error`,summary:A.t(`cmd.loginFailed`,{msg:e.message})})}}async function bi(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(A.t(`cmd.titleLogout`),A.t(`cmd.logoutNoStored`));return}r=await new Promise(r=>t.tui.modal.openModal({kind:`select`,title:A.t(`cmd.logoutPickProvider`),detailPlacement:`inline`,options:a.map(r=>{let a=n.oauth.get(r)?.name??M(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?A.t(`pref.authModeLabel`,{context:o}):void 0}}),onSelect:r,onCancel:()=>r(null)}))}r&&(await n.logout(r),t.tui.info.showToast(A.t(`cmd.titleLogout`),A.t(`cmd.logoutSuccess`,{provider:r})))}async function xi(e,t){e[0]&&e[0]!==`--service`||await Ci([],t)}async function Si(e,t){let n=e.indexOf(`--service`),r=e.indexOf(`--token`);if(n===-1||r===-1){t.tui.info.showToast(A.t(`cmd.titleLogin`),A.t(`cmd.serviceLoginUsage`));return}let i=e[n+1],a=e[r+1];if(!i||!a){t.tui.info.showToast(A.t(`cmd.titleLogin`),A.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(A.t(`cmd.titleLogin`),A.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(A.t(`cmd.titleLogin`),A.t(`cmd.serviceLoginBadResponse`));return}let{OTTO_IDENTITY_PATH:r,isShadowModeEnabled:i}=await import(`@x-otto/env`);if(i()){t.tui.info.showToast(A.t(`cmd.titleLogin`),A.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(A.t(`cmd.titleLogin`),A.t(`cmd.serviceLoginSuccess`,{url:o,user:n.user_id.slice(0,12)}))}catch(e){t.tui.info.showToast(A.t(`cmd.titleLogin`),A.t(`cmd.serviceLoginFailed`,{err:e instanceof Error?e.message:String(e)}))}}async function Ci(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(A.t(`cmd.titleLogout`),A.t(`cmd.logoutAccountRemoved`))}catch(e){if(e.code===`ENOENT`){t.tui.info.showToast(A.t(`cmd.titleLogout`),A.t(`cmd.logoutAccountNotFound`));return}t.tui.info.showToast(A.t(`cmd.titleLogout`),A.t(`cmd.logoutAccountFailed`,{err:e instanceof Error?e.message:String(e)}))}}function wi(){let e=process.env.OTTO_NOTIFY_COALESCE_WARN_RATIO,t=e?Number(e):NaN;return Number.isFinite(t)&&t>=1?t:1.5}function Ti(e,t){return t===0?`healthy`:e<wi()?`warning`:`healthy`}async function Ei(e,t){let n=e[0]?.toLowerCase();if(n===`cache`||n===`cache-stats`)return Di(e.slice(1),t);if(n===`diagnose`)return Ln(e.slice(1),t);if(n===`services`)return ti(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=Oe(i.metadata().title,i.messages(),r.id),d=t.callbacks.isWriteLeaseReadOnly();t.tui.engine.pushEngineEvent({kind:`status`,session:{title:u,sessionId:r.id.slice(0,8),modelId:r.model?.id??A.t(`cmd.statusModelUnset`),messageCount:a.length,occupancy:o,contextWindow:s,occupancyPct:c,cumOutput:l,writeLeaseReadOnly:d,isPaused:t.callbacks.isRunPaused()}}),t.tui.engine.pushEngineEvent({kind:`status`,memory:t.app.memoryGovernor.sample()});let f=t.tui.info.getNotifyStats(),p=f.coalescedCalls/Math.max(1,f.coalescedFires);t.tui.engine.pushEngineEvent({kind:`status`,notify:{coalescedCalls:f.coalescedCalls,coalescedFires:f.coalescedFires,immediateCalls:f.immediateCalls,flushFires:f.flushFires,coalesceRatio:p,alert:Ti(p,f.coalescedCalls)}});let m=t.app.activePlugins();try{let e=await ae(m,void 0,e=>t.app.pluginHealthTracker.recordToolTimeout(e));t.tui.engine.pushEngineEvent({kind:`status`,pluginMetrics:e})}catch(e){t.app.logger.warn({err:e instanceof Error?e.message:String(e)},`[status] collectPluginPerfMetrics failed`),t.tui.engine.pushEngineEvent({kind:`status`,pluginMetrics:[]})}t.tui.panes.togglePane(`status`)}async function Di(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:vt(t,e.api)}}),i=r.some(e=>e.hitRatio!==null),a={inputTokens:n.totalInputTokens,outputTokens:0,cacheReadTokens:n.totalCacheReadTokens,cacheWriteTokens:n.totalCacheWriteTokens},o=i?vt(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 Oi(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 ki(e){return new Date(e*1e3).toLocaleString()}async function Ai(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:A.t(`cmd.titleUsage`),lines:[A.t(`cmd.usageNotSubscription`)]});return}let r=t.callbacks.getLastProviderUsage();if(!r){t.tui.modal.openModal({kind:`info`,title:A.t(`cmd.titleUsage`),lines:[A.t(`cmd.usageNoSnapshotYet`)]});return}let i=[],a=n===`anthropic`;if(r.limitType&&i.push(A.t(`cmd.usageLineType`,{type:nt(r.limitType)})),(a||r.usedPercent!==void 0)&&i.push(A.t(`cmd.usageLineStatus`,{status:r.status})),r.usedPercent!==void 0&&i.push(A.t(`cmd.usageLinePercent`,{pct:Math.round(r.usedPercent)})),r.resetsAt!==void 0&&i.push(A.t(`cmd.usageLineResetsAt`,{when:ki(r.resetsAt)})),r.standardLimits){let e=r.standardLimits;i.push(A.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(A.t(`cmd.usageSubPoolNotInHeaders`))),t.tui.modal.openModal({kind:`info`,title:A.t(`cmd.titleUsage`),lines:i})}const ji=async(e,t)=>{let n=e[0];switch(n){case`memory-sync`:return Mi(e.slice(1),t);default:t.tui.info.showToast(`Workspace`,`/workspace ${n??``} — unknown subcommand. Use: memory-sync [status|enable|disable]`)}};async function Mi(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 Ni(n,r){let i=r.state.session,a=i.model?.id??A.t(`cmd.aboutModelNotSet`),o=h().length,s=Math.round(b()/(1024*1024*1024)),c=Math.round(g()/(1024*1024)),l=[{kind:`group`,title:A.t(`cmd.aboutGroupVersion`)},{kind:`row`,label:A.t(`cmd.aboutVersion`),value:`${Be} (build ${ze})`},{kind:`row`,label:A.t(`cmd.aboutBranch`),value:t},{kind:`row`,label:A.t(`cmd.aboutCommit`),value:e},{kind:`group`,title:A.t(`cmd.aboutGroupRuntime`)},{kind:`row`,label:A.t(`cmd.aboutRuntime`),value:`Node.js ${process.version} · ${v()} ${m()} · ${y()}`,tone:`muted`},{kind:`row`,label:A.t(`cmd.aboutCPU`),value:`${o} cores`,tone:`muted`},{kind:`row`,label:A.t(`cmd.aboutMemory`),value:`${s} GB total / ${Math.round(c)} MB free`,tone:`muted`},{kind:`row`,label:A.t(`cmd.aboutShell`),value:process.env.SHELL??`(unknown)`,tone:`muted`},{kind:`row`,label:A.t(`cmd.aboutTerminal`),value:process.env.TERM??`(unknown)`,tone:`muted`},{kind:`group`,title:A.t(`cmd.aboutGroupSession`)},{kind:`row`,label:A.t(`cmd.aboutModel`),value:a,tone:`secondary`}];i.id&&l.push({kind:`row`,label:A.t(`cmd.aboutSession`),value:i.id.slice(0,8)}),l.push({kind:`blank`},{kind:`text`,value:A.t(`cmd.aboutUpdateHint`),tone:`muted`}),r.tui.modal.openModal({kind:`info`,title:A.t(`cmd.titleAbout`),lines:[],dataListEntries:l})}function Pi(e,t,n){let r=De(e,t);if(r)return r;let i=e.split(`/`).pop();if(i)return le({cwd:t??process.cwd(),homedir:n??_()}).find(e=>e.id===i)?.dir}function Fi(e,t,n){try{let r=Pi(e,t,n);if(!r)return;let i=O(r,T),a=ye(Ke(i,`utf-8`),i);return a?a.codeProviderIds?.[0]??a.contributes?.providers?.[0]?.id??a.contributes?.oauth?.[0]?.id:void 0}catch{return}}function Ii(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 Li={provider:`install-provider`,authentication:`connect-provider`,model:`choose-model`,ready:`send-first-prompt`,"first-prompt":`none`};function Ri(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 zi(e){let t=Ri(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:Li[t],stage:t,autoOpen:o}}}function Bi(e){return e.stage===`ready`||e.stage===`first-prompt`}function Vi(e,t){return e.get(t)===!0}function Hi(e){return{personalizationSeen:Vi(e,`has_completed_onboarding`),dismissed:Vi(e,`has_completed_wizard`)||Vi(e,`wizard_dont_show_again`),firstPromptSubmitted:typeof e.get(`first_prompt_submitted_at`)==`number`}}const Ui=`__otto_setup__`;async function Wi(e){let t=Hi(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!==Ui),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!==Ui?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 zi({providerInstalled:e.hasProviderPlugin(),...e.providerCandidates?{providerCandidates:e.providerCandidates}:{},connectedProviderIds:r,usableModelIds:a,...o!==void 0&&o!==Ui?{selectedModelId:o}:{},...c===void 0?{}:{selectedModelUsableInMainSession:c},firstPromptSubmitted:t.firstPromptSubmitted,dismissed:t.dismissed})}function Gi(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 Ki=class{snapshot=null;listeners=new Set;constructor(e){this.deps=e}current(){return this.snapshot}async refresh(){let e=await Wi(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 qi(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 Ji(e,t){return e.map((e,n)=>({provider:e,index:n,rank:qi(e,t)})).sort((e,t)=>e.rank-t.rank||e.index-t.index).map(e=>e.provider)}function Yi(e){try{let{createRequire:t}=Ct(`node:module`),{readFileSync:n}=Ct(`node:fs`),{dirname:r,join:i}=Ct(`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 Xi(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=Zi(t);return t.map(e=>({...e,recommended:e.usable&&e.id===n}))}function Zi(e){return e.find(e=>e.usable)?.id}const Qi={hasReadme:!1,hasPackageManifest:!1,hasTestConfig:!1,isEmpty:!1},$i=new Set([`node_modules`,`.git`,`.hg`,`.svn`,`.venv`,`venv`,`__pycache__`,`.pytest_cache`,`.mypy_cache`,`.tox`,`dist`,`build`,`.next`,`.nuxt`,`.cache`,`.DS_Store`]),ea=/^readme(\.(md|markdown|txt|rst))?$/i,ta=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`]),na=/^(jest\.config|vitest\.config|karma\.conf|\.mocharc)(\.(js|ts|mjs|cjs|json))?$/i,ra=new Set([`pytest.ini`,`tox.ini`,`phpunit.xml`,`phpunit.xml.dist`,`setup.cfg`]);async function ia(e,t){let n;try{n=await t.readdir(e)}catch{return Qi}let r=n.filter(e=>!$i.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&&ea.test(e.name)&&(a=!0),!o&&ta.has(e.name)&&(o=!0),!s&&(ra.has(e.name)||na.test(e.name))&&(s=!0),a&&o&&s)))break;return{hasReadme:a,hasPackageManifest:o,hasTestConfig:s,isEmpty:i}}function aa(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 oa=`oxygen-provider`,sa=new Set([`plugin-oxygen`,oa]);async function ca(e){try{let{makeRegistryClient:t}=await import(`./registry-DYHR-ONu.js`),{registries:n}=await t(e.app).loadAll();return n.some(e=>e.entries.some(e=>sa.has(e.id)||e.source===`@x-otto/plugin-oxygen`||e.source.includes(`/plugin-oxygen`)||e.subPath?.endsWith(`plugin-oxygen`)))}catch{return!1}}async function la(e){let t=e.tui,n=e.app,r=await Wi(Gi({modelRegistry:n.modelRegistry,authStore:n.authStore,settings:n.settings,selectedModelId:()=>e.state.session?.model?.id,isModelUsable:j(n.authStore,`delegation`),isModelUsableInMainSession:j(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 o=(()=>{for(let e=0;e<3;e++)if(!a.includes(e))return e;return 3})(),c=await ca(e),l=Object.entries(s).filter(([e,t])=>t.capabilities.includes(`provider`)&&(e!==oa||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=Ji(l.map(([e,t])=>({id:e,...Yi(t.pkg)})),process.env).map(({id:e})=>({label:e,value:e,detail:u[e]??s[e]?.pkg??e})),f=e=>Ii(e,n.authStore.oauth,{oauth:{label:A.t(`setup.loginOAuth`),detail:`Open browser, complete authorization — no copy-paste needed.`},apiKey:{label:A.t(`setup.loginApiKey`),detail:`Generate a key on your provider dashboard and paste it here.`}}),p=async()=>{let t=await Wi(Gi({modelRegistry:n.modelRegistry,authStore:n.authStore,settings:n.settings,selectedModelId:()=>e.state.session?.model?.id,isModelUsable:j(n.authStore,`delegation`),isModelUsableInMainSession:j(n.authStore,`main-session`)})),r=j(n.authStore,`delegation`),i=new Set(t.model.usableIds),a=n.modelRegistry.getAll().filter(e=>e.id!==`__otto_setup__`);return Xi((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=aa(await ia(n.workspaceDir,{readdir:e=>ut(e,{withFileTypes:!0})})).map(e=>A.t(e));t.modal.openModal({kind:`wizard`,title:A.t(`setup.title`),welcomeTitle:A.t(`setup.welcomeTitle`),welcomeGreeting:``,welcomeDescription:A.t(`setup.welcomeDescription`),welcomeDontShowAgainLabel:A.t(`setup.welcomeDontShowAgain`),welcomeStartLabel:A.t(`setup.welcomeStart`),welcomeCancelLabel:A.t(`setup.welcomeCancel`),stepNames:[A.t(`setup.stepNameProvider`),A.t(`setup.stepNameLogin`),A.t(`setup.stepNameModel`),A.t(`setup.stepNameStart`)],stepSubtitles:[A.t(`setup.step1Subtitle`),A.t(`setup.step3Subtitle`),A.t(`setup.step4Subtitle`),A.t(`setup.step5Done`)],initialCompleted:a,initialCurrent:o,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(()=>ri),i=!1,a=await r(t,e,{autoTrust:!0,onProgress:e=>n(`${e}…`),onPendingCapabilities:()=>{i=!0}}),o=s[t]?.pkg??t;if(!a)return{ok:!1,error:A.t(`setup.installFailed`,{reason:t})};let c=[];try{let{readHighRiskCapabilities:e}=await import(`@x-otto/coding`),t=Pi(o);t&&(c=e(t))}catch{}return{ok:!0,providerId:Fi(o),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-CkSf8ziQ.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 ua(e,t){await la(t)}function Z(e){return dn(e.state.session.session.getDrafts()??[])}function da(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 fa=async(e,t)=>{let n=e[0];switch(n){case void 0:case`list`:return pa(e.slice(1),t);case`save`:return ma(e.slice(1),t);case`load`:return ha(e.slice(1),t);case`delete`:case`remove`:return ga(e.slice(1),t);default:t.tui.info.showToast(`Draft`,`/draft ${n} — unknown subcommand. Use: save|list|load|delete`)}};async function pa(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 ma(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=pn(a,o,s),l=mn([...s,c]);try{da(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 ha(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 ga(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{da(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 _a=async(e,t)=>{let n=e[0];switch(n){case void 0:case`list`:return va(t);case`remove`:return ya(e[1],t);case`move`:return ba(e[1],e[2],t);case`clear`:return xa(t);default:t.tui.info.showToast(`Queue`,`/queue ${n} — unknown subcommand. Use: list|remove|move|clear`)}};async function va(e){e.tui.panes.togglePane(`queuePane`,!0)}async function ya(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 ba(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 xa(e){e.tui.panes.clearQueue(),e.tui.info.showToast(`Queue`,`Queue cleared`)}const Sa=async(e,t)=>{let{session:n,agentProcessing:r}=t.state;if(n.isPaused&&!n.isBusy){n.resumeRun(),t.tui.info.showToast(A.t(`cmd.titleInfo`),A.t(`cmd.runResumedByCommand`)),Ca(t);return}if(n.isPaused&&n.isBusy){n.cancelPauseRun()?t.tui.info.showToast(A.t(`cmd.titleInfo`),A.t(`cmd.pauseCancelled`)):(n.resumeRun(),t.tui.info.showToast(A.t(`cmd.titleInfo`),A.t(`cmd.runResumedByCommand`))),Ca(t);return}if(r){n.pauseRun()?t.tui.info.showToast(A.t(`cmd.titlePauseRequested`),A.t(`cmd.runWillPauseAfterTurn`)):t.tui.info.showToast(A.t(`cmd.titleInfo`),A.t(`cmd.noRunningTaskToPause`)),Ca(t);return}t.tui.info.showToast(A.t(`cmd.titleInfo`),A.t(`cmd.nothingToPause`))};function Ca(e){let t=e.callbacks.refreshSlashCommands?.();t&&e.tui.plugins.setCommands(t)}function wa(e){let t;try{let n=Ge(e,`r`);try{t=Buffer.alloc(512);let e=qe(n,t,0,512,0);t=t.subarray(0,e)}finally{Ue(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 Ta(e){return e>=1048576?`${(e/1048576).toFixed(1)} MB`:e>=1024?`${(e/1024).toFixed(1)} KB`:`${e} B`}function Ea(e){let t;try{t=Je(e)}catch{return[]}let n=[];for(let r of t)try{let t=Ye(O(e,r));n.push({name:r,isDir:t.isDirectory(),size:t.isDirectory()?void 0:t.size})}catch{}return n}function Da(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=Da(Ea(n)),a=Ve(t,n),o=a===``?A.t(`cmd.openBrowserSubtitleRoot`):A.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:Ta(e.size??0)}));e.tui.modal.openModal({kind:`select`,title:A.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=Ye(a).isDirectory()}catch{e.tui.info.showToast(A.t(`cmd.titleOpen`),A.t(`cmd.openNotFound`,{path:i}));return}if(o){Q(e,t,a,r);return}Oa(e,a,i,()=>{Q(e,t,n,r)}).catch(()=>{e.tui.info.showToast(A.t(`cmd.titleOpen`),A.t(`cmd.openNotFound`,{path:i}))})},onCancel:s?()=>Q(e,t,D(n),r):()=>{}})}async function Oa(e,t,n,r){if(wa(t)){e.tui.info.showToast(A.t(`cmd.titleOpen`),A.t(`cmd.openBinaryRejected`,{path:n}));return}let{content:i,truncated:a}=await Re(t);e.tui.modal.openModal({kind:`fileViewer`,path:n,content:i,preTruncated:a,onDismiss:r??(()=>{})})}async function ka(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=He(n,r),o=Ve(n,a).startsWith(`..`);if(!We(a)){if(o){t.tui.info.showToast(A.t(`cmd.titleOpen`),A.t(`cmd.openNotFound`,{path:r}));return}let e=D(a);for(;e!==n&&e!==D(e)&&!We(e);)e=D(e);if(We(e)&&Ye(e).isDirectory()){Q(t,n,e,i);return}t.tui.info.showToast(A.t(`cmd.titleOpen`),A.t(`cmd.openNotFound`,{path:r}));return}if(Ye(a).isDirectory()){if(o){t.tui.info.showToast(A.t(`cmd.titleOpen`),A.t(`cmd.openNotFound`,{path:r}));return}Q(t,n,a,i);return}await Oa(t,a,r)}async function Aa(e,t){t.tui.engine.clearErrorRetry?.();let n=t.state.session;if(!n){t.tui.info.showToast(A.t(`cmd.titleInfo`),A.t(`cmd.retryNoSession`,{defaultValue:`No active session`}));return}if(n.isBusy){t.tui.info.showToast(A.t(`cmd.titleInfo`),A.t(`cmd.retryBusy`,{defaultValue:`Agent 正在运行,无法重试`}));return}if(![...n.session.messages()].reverse().find(e=>e.role===`user`)){t.tui.info.showToast(A.t(`cmd.titleInfo`),A.t(`cmd.retryNoResumable`,{defaultValue:`无可重试的回合——请输入消息`}));return}t.tui.engine.pushEngineEvent({kind:`agentProcessing`,value:!0});try{await n.retryLastRound()}catch(e){if(e?.code===`RETRY_NO_RESUMABLE_ROUND`){t.tui.info.showToast(A.t(`cmd.titleInfo`),A.t(`cmd.retryNoResumable`,{defaultValue:`无可重试的回合——请输入消息`}));return}t.tui.info.showToast(A.t(`cmd.titleInfo`),A.t(`cmd.retryFailed`,{defaultValue:`重试失败:{{err}}`,err:e instanceof Error?e.message:String(e)}))}finally{t.tui.engine.pushEngineEvent({kind:`agentProcessing`,value:!1})}}var ja=N({DISPATCHABLE_COMMAND_NAMES:()=>Fa,ENGINE_BUILTIN_COMMANDS:()=>Pa,HELP_GROUP_ORDER:()=>Ma,SAFE_COMMAND_NAMES:()=>Na,SLASH_COMMANDS:()=>$,buildPluginSlashCommandRegistry:()=>Ia,dispatchSlashCommand:()=>Ra,handleMemory:()=>jn,pluginSlashCommandsToEntries:()=>La});const Ma=[`session`,`model`,`agent`,`debug`,`ui`,`other`],$=[{name:`clear`,handler:Nn,engineBuiltin:!0,group:`session`,tuiHidden:!0,deprecated:!0,description:`/session clear (deprecated alias)`},{name:`compact`,handler:(e,t)=>W([`compact`,...e],t),group:`session`,tuiHidden:!0,deprecated:!0,description:`/session compact (deprecated alias)`},{name:`memory`,aliases:[`mem`],handler:jn,group:`session`,description:`Project + user memory: /memory [user|project|<name>|forget <name>]`},{name:`workspace`,handler:ji,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:Ei,safe:!0,engineBuiltin:!0,group:`session`,description:`Session status & perf: /status [cache|diagnose|services]`},{name:`open`,handler:ka,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:yi,group:`model`,description:`Switch model; /model [<id>|refresh]`},{name:`auth`,aliases:[`login`],handler:X,group:`model`,description:`Connect a model provider (OAuth or API key); /auth [<provider>], /auth logout [<provider>] clears stored credentials`},{name:`usage`,handler:Ai,safe:!0,engineBuiltin:!0,group:`model`,description:`Show provider usage quota snapshot (Anthropic OAuth subscription plans only)`},{name:`logout`,handler:xi,group:`model`,description:`Sign out of your otto account (removes local account identity); /logout`},{name:`job`,handler:pi,safe:!0,group:`agent`,description:`Start a background agent job: /job <directive> (worktree-isolated, full tools incl. MCP)`},{name:`schedule`,handler:f,safe:!0,group:`agent`,description:`Manage scheduled tasks: /schedule add|list|remove|run|enable|disable <args>`},{name:`delegates`,handler:fi,safe:!0,group:`agent`,description:`Toggle the Delegates panel (↑↓ select · k kill · o output · a apply)`},{name:`diagnose`,handler:(e,t)=>Ei([`diagnose`,...e],t),safe:!0,group:`debug`,tuiHidden:!0,deprecated:!0,description:`/status diagnose (deprecated alias)`},{name:`context`,handler:(e,t)=>W([`context`,...e],t),safe:!0,group:`debug`,tuiHidden:!0,deprecated:!0,description:`/session context (deprecated alias)`},{name:`cache-stats`,handler:(e,t)=>Ei([`cache-stats`,...e],t),safe:!0,group:`debug`,tuiHidden:!0,deprecated:!0,description:`/status cache (deprecated alias)`},{name:`services`,handler:(e,t)=>Ei([`services`,...e],t),safe:!0,group:`debug`,tuiHidden:!0,deprecated:!0,description:`/status services (deprecated alias)`},{name:`gallery`,handler:Oi,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:Kn,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:Jn,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:Er,safe:!0,group:`ui`,description:`Switch reasoning effort level (/effort [low|medium|high|xhigh|max])`},{name:`preference`,aliases:[`pref`],handler:Or,safe:!0,group:`ui`,description:`Preferences: /preference [general|lang|theme|keybindings|shortcuts|proxy] (RFC-369)`},{name:`trust`,handler:(e,t)=>Y([`trust`,...e],t),safe:!0,group:`ui`,tuiHidden:!0,deprecated:!0,description:`/extension trust (deprecated alias)`},{name:`notification`,aliases:[`notif`],handler:$r,group:`ui`,description:`Toggle the notification center panel (≡ ctrl+n)`},{name:`draft`,handler:fa,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:_a,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)=>Or([`keybindings`,...e],t),safe:!0,group:`ui`,tuiHidden:!0,deprecated:!0,description:`/preference keybindings (deprecated alias)`},{name:`shortcuts`,handler:(e,t)=>Or([`shortcuts`,...e],t),safe:!0,group:`ui`,tuiHidden:!0,deprecated:!0,description:`/preference shortcuts (deprecated alias)`},{name:`proxy`,handler:(e,t)=>Or([`proxy`,...e],t),group:`ui`,tuiHidden:!0,deprecated:!0,description:`/preference proxy (deprecated alias)`},{name:`help`,aliases:[`h`,`?`],safe:!0,engineBuiltin:!0,group:`other`,description:`Show available commands`,handler:async(e,t)=>Zr(e,t,[...$,...La([...Ia(t.app).values()])])},{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:Sa,safe:!0,group:`other`,description:`Pause after current turn finishes (toggle with /continue)`},{name:`retry`,handler:Aa,safe:!0,group:`other`,description:`Re-send the last prompt to the model (e.g. after switching models or fixing a transient error)`},{name:`copy`,engineBuiltin:!0,group:`other`,tuiHidden:!0,description:`Copy last assistant response`},{name:`resume`,handler:(e,t)=>W([`resume`,...e],t),group:`other`,tuiHidden:!0,deprecated:!0,description:`/session resume (deprecated alias)`},{name:`rename`,handler:Pn,safe:!0,group:`session`,description:`Set a custom title for the current session (/rename <new title>)`},{name:`a2ui-action`,handler:Gn,safe:!1,group:`session`,description:`Trigger A2UI interactive component action (/a2ui-action btn1 click)`},{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 ni(e,t);return}await Xr(e,t)||await Jr(e,t)}},{name:`about`,handler:Ni,safe:!0,group:`other`,description:`Show version, build, and environment info (/about)`},{name:`setup`,handler:ua,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:Y,group:`other`,description:`Manage extensions: /extension [trust|install|registry|search|update|reload] or open panel (RFC-369)`},{name:`install`,handler:(e,t)=>Y([`install`,...e],t),safe:!0,group:`other`,tuiHidden:!0,deprecated:!0,description:`/extension install (deprecated alias)`},{name:`registry`,handler:(e,t)=>Y([`registry`,...e],t),safe:!0,group:`other`,tuiHidden:!0,deprecated:!0,description:`/extension registry (deprecated alias)`},{name:`search`,handler:(e,t)=>Y([`search`,...e],t),safe:!0,group:`other`,tuiHidden:!0,deprecated:!0,description:`/extension search (deprecated alias)`},{name:`permissions`,aliases:[`perms`],handler:Kr,safe:!0,group:`other`,description:`View / clear the always-allow list (/permissions [clear])`},{name:`archive`,aliases:[`unarchive`],handler:(e,t)=>W([`archive`,...e],t),safe:!0,tuiHidden:!0,deprecated:!0,description:`/session archive (deprecated alias)`},{name:`session`,handler:W,description:`Session management: /session [fork|clear|unlock|kill|inspect|pin|archive|resume|compact|context] (RFC-369)`},{name:`fork`,handler:Xn,safe:!0,description:`Fork current session into a named branch`},{name:`pin`,aliases:[`unpin`],handler:(e,t)=>W([`pin`,...e],t),safe:!0,tuiHidden:!0,deprecated:!0,description:`/session pin (deprecated alias)`},{name:`history`,aliases:[`hist`],handler:Qr,safe:!0,description:`Open history search panel (same panel as Ctrl+R)`},{name:`prompts`,handler:ei,safe:!0,description:`View prompt log (list of submitted prompts this session)`}],Na=new Set($.filter(e=>e.safe).flatMap(e=>[e.name,...e.aliases??[]])),Pa=new Set($.filter(e=>e.engineBuiltin).flatMap(e=>[e.name,...e.aliases??[]])),Fa=new Set($.filter(e=>e.handler).flatMap(e=>[e.name,...e.aliases??[]]));function Ia(e){let t=new Set;for(let e of $){t.add(e.name);for(let n of e.aliases??[])t.add(n)}let n=new Map;for(let r of e.pluginSlashCommands?.()??[]){if(t.has(r.name)){console.warn(`[plugin] 插件 "${r.pluginId}" 声明斜杠命令 "/${r.name}" 与内置命令冲突,已忽略(内置优先,RFC-440)`);continue}let e=n.get(r.name);e?e.push(r):n.set(r.name,[r])}let r=new Map;for(let[e,t]of n){if(t.length===1){r.set(e,t[0]);continue}console.warn(`[plugin] 斜杠命令 "/${e}" 被多个插件声明(${t.map(e=>e.pluginId).join(`, `)}),已禁用(fail-closed,RFC-440)`)}return r}function La(e){let t=[`session`,`model`,`agent`,`debug`,`ui`,`other`];return e.map(e=>({name:e.name,group:t.includes(e.group??``)?e.group:`other`,description:e.description}))}async function Ra(e,t,n){let r=$.find(t=>t.name===e);if(r||=$.find(t=>t.aliases?.includes(e)),!r?.handler){let r=Ia(n.app).get(e);return r?(await za(r,t,n),!0):!1}return await r.handler(t,n),!0}async function za(e,t,n){let r=n.tui,i=n.app.getPluginPanelRegistrations?.()??[];try{let{runInProcessCliCommand:a}=await import(`@x-otto/coding`),o=await a(async()=>(await e.handler({args:t,tui:{openInput:e=>r.modal.openModal({kind:`input`,title:e.title,...e.description?{description:e.description}:{},...e.placeholder?{placeholder:e.placeholder}:{}}),confirm:(e,t)=>new Promise(n=>{r.modal.openModal({kind:`confirm`,title:e,message:t,onConfirm:()=>n(!0),onCancel:()=>n(!1)})}),openPluginPanel:e=>(r.modal.openModal({kind:`pluginPanel`,panelInfo:{title:e.title,modulePath:e.modulePath,exportName:e.exportName,pluginId:e.pluginId},onClose:()=>{}}),Promise.resolve()),showToast:(e,t)=>r.info.showToast(e,t)},app:{workspaceDir:n.app.workspaceDir,modelId:n.state.session.model?.id,settings:{get:e=>n.app.settings.get(e)},pluginPanels:i.map(e=>({pluginId:e.pluginId,title:e.title,modulePath:e.modulePath,exportName:e.exportName}))}}),0));o===124?r.info.showToast(`plugin`,`斜杠命令 /${e.name} 执行超时(已停止等待,handler 可能仍在后台运行)`):o!==0&&r.info.showToast(`plugin`,`斜杠命令 /${e.name} 执行失败(handler 抛出异常,详见日志)`)}catch(t){let n=t instanceof Error?t.message:String(t);r.info.showToast(`plugin`,`斜杠命令 /${e.name} 执行失败:${n}`)}}export{ht as $,sr as A,Ze as B,mr as C,cr as D,gr as E,gn as F,an as G,at as H,mn as I,I as J,Kt as K,pn as L,Sn as M,vn as N,or as O,hn as P,Gt as Q,dn as R,K as S,hr as T,L as U,$e as V,on as W,Jt as X,qt as Y,Qt as Z,Dr as _,Ia as a,Ot as at,br as b,ia as c,Gi as d,Rt as et,Bi as f,ri as g,mi as h,$ as i,kt as it,kn as j,ar as k,aa as l,X as m,Pa as n,jt as nt,ja as o,N as ot,yi as p,Yt as q,Na as r,P as rt,Ra as s,Fa as t,At as tt,Ki as u,yr as v,fr as w,_r as x,Sr as y,un as z};
|
|
18
|
+
//# sourceMappingURL=command-dispatcher-W3E5zhWN.js.map
|