@x-otto/cli 0.0.1-alpha.49 → 0.0.1-alpha.50
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-D1T16ed-.js → auth-command-BYaFM76w.js} +2 -2
- package/dist/{auth-command-D1T16ed-.js.map → auth-command-BYaFM76w.js.map} +1 -1
- package/dist/backend-handler-DUafuNWw.js +3 -0
- package/dist/backend-handler-DUafuNWw.js.map +1 -0
- package/dist/build-id-DjE6eVpQ.js +3 -0
- package/dist/build-id-DjE6eVpQ.js.map +1 -0
- package/dist/bundled-extensions/plugin-feedback/otto-plugin.json +24 -0
- package/dist/bundled-extensions/plugin-feedback/panels/feedback.tsx +348 -0
- package/dist/bundled-extensions/plugin-feedback/panels/panel-host-globals.d.ts +67 -0
- package/dist/bundled-extensions/plugin-feedback/panels-dist/feedback.mjs +257 -0
- package/dist/bundled-extensions/plugin-feedback/plugin-dist/meta.json +1 -0
- package/dist/bundled-extensions/plugin-feedback/plugin-dist/plugin.cjs +11304 -0
- package/dist/bundled-extensions/plugin-feedback/plugin.ts +198 -0
- package/dist/bundled-extensions/plugin-feedback/src/coding-adapter.ts +183 -0
- package/dist/bundled-extensions/plugin-feedback/src/coding-lister.ts +26 -0
- package/dist/bundled-extensions/plugin-feedback/src/github-lister.ts +230 -0
- package/dist/bundled-extensions/plugin-feedback/src/issue-aggregator.ts +109 -0
- package/dist/bundled-extensions/plugin-feedback/src/issue-submitter.ts +241 -0
- package/dist/bundled-extensions/plugin-feedback/src/platform-resolver.ts +76 -0
- package/dist/bundled-extensions/plugin-feedback/src/pulse-survey-sink.ts +114 -0
- package/dist/bundled-extensions/plugin-feedback/src/resolved-sink.ts +163 -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 +605 -725
- package/dist/bundled-extensions/plugin-otto-wire-protocols/src/anthropic-messages.ts +4 -22
- package/dist/bundled-extensions/plugin-otto-wire-protocols/src/openai-completions.ts +5 -5
- package/dist/bundled-extensions/plugin-otto-wire-protocols/src/openai-responses.ts +3 -15
- package/dist/command-dispatcher-BLT8IO4K.js +18 -0
- package/dist/command-dispatcher-BLT8IO4K.js.map +1 -0
- package/dist/create-host-app-CbJ8ptv-.js +3 -0
- package/dist/{create-host-app-BXQ8bU-B.js.map → create-host-app-CbJ8ptv-.js.map} +1 -1
- package/dist/{daemon-base-Y1XI61JY.js → daemon-base-D015ew5y.js} +1 -1
- package/dist/{daemon-base-Y1XI61JY.js.map → daemon-base-D015ew5y.js.map} +1 -1
- package/dist/{doctor-DXBLkbkP.js → doctor-EndB-ycb.js} +3 -3
- package/dist/{doctor-DXBLkbkP.js.map → doctor-EndB-ycb.js.map} +1 -1
- package/dist/{doctor-attach-DEMuyBOk.js → doctor-attach-DEoE7eFx.js} +2 -2
- package/dist/{doctor-attach-DEMuyBOk.js.map → doctor-attach-DEoE7eFx.js.map} +1 -1
- package/dist/{doctor-cdp-CnJUVNOB.js → doctor-cdp-Cj9IFpEP.js} +1 -1
- package/dist/{doctor-cdp-CnJUVNOB.js.map → doctor-cdp-Cj9IFpEP.js.map} +1 -1
- package/dist/{doctor-heap-Eu3LZj-F.js → doctor-heap-SIxiRvL8.js} +2 -2
- package/dist/{doctor-heap-Eu3LZj-F.js.map → doctor-heap-SIxiRvL8.js.map} +1 -1
- package/dist/{doctor-ps-JBgCH77n.js → doctor-ps-DNVOF6yY.js} +2 -2
- package/dist/{doctor-ps-JBgCH77n.js.map → doctor-ps-DNVOF6yY.js.map} +1 -1
- package/dist/extension-CoJqqktf.js +2 -0
- package/dist/extension-Dpn8gltG.js +179 -0
- package/dist/extension-Dpn8gltG.js.map +1 -0
- package/dist/feedback-QcONRnO3.js +30 -0
- package/dist/feedback-QcONRnO3.js.map +1 -0
- package/dist/feedback-backend-methods-BNm38ddr.js +3 -0
- package/dist/feedback-backend-methods-BNm38ddr.js.map +1 -0
- package/dist/{feishu-setup-5ZoxtH0J.js → feishu-setup-DbAq_BRH.js} +1 -1
- package/dist/feishu-setup-DbAq_BRH.js.map +1 -0
- package/dist/{ftue-doctor-recovery-8FeDBFOc.js → ftue-doctor-recovery-CKTMnxM8.js} +1 -1
- package/dist/{ftue-doctor-recovery-8FeDBFOc.js.map → ftue-doctor-recovery-CKTMnxM8.js.map} +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11 -11
- package/dist/index.js.map +1 -1
- package/dist/install-CEPczuet.js +11 -0
- package/dist/install-CEPczuet.js.map +1 -0
- package/dist/install-CG6b6fox.js +2 -0
- package/dist/interactive-schedule-Bv__2Kwc.js +3 -0
- package/dist/interactive-schedule-Bv__2Kwc.js.map +1 -0
- package/dist/{mcp-Cm4-OhXI.js → mcp-DjReRjuu.js} +1 -1
- package/dist/{mcp-Cm4-OhXI.js.map → mcp-DjReRjuu.js.map} +1 -1
- package/dist/{mcp-server-Dpza3yn2.js → mcp-server-Rr__aWO7.js} +3 -3
- package/dist/mcp-server-Rr__aWO7.js.map +1 -0
- package/dist/{migrate-RlBJqJnB.js → migrate-BBi3Txu2.js} +1 -1
- package/dist/{migrate-RlBJqJnB.js.map → migrate-BBi3Txu2.js.map} +1 -1
- package/dist/{observe-Dxfud-t7.js → observe-BqLCpmFD.js} +2 -2
- package/dist/{observe-Dxfud-t7.js.map → observe-BqLCpmFD.js.map} +1 -1
- package/dist/parse-cli-Db8pF_Ya.js +3 -0
- package/dist/parse-cli-Db8pF_Ya.js.map +1 -0
- package/dist/{persistence-CRFhOYx6.js → persistence-BvLRnpfi.js} +2 -2
- package/dist/{persistence-CRFhOYx6.js.map → persistence-BvLRnpfi.js.map} +1 -1
- package/dist/{plugin-assembly-check-DEozmcJ7.js → plugin-assembly-check-BntT5W6H.js} +1 -1
- package/dist/{plugin-assembly-check-DEozmcJ7.js.map → plugin-assembly-check-BntT5W6H.js.map} +1 -1
- package/dist/{proxy-evg7ZvoD.js → proxy-CFZDVIwI.js} +1 -1
- package/dist/proxy-CFZDVIwI.js.map +1 -0
- package/dist/proxy-CkSf8ziQ.js +2 -0
- package/dist/{ps-DiKCLKbs.js → ps-BVKv6rAo.js} +1 -1
- package/dist/{ps-DiKCLKbs.js.map → ps-BVKv6rAo.js.map} +1 -1
- package/dist/{registry-BdCcwyGy.js → registry-BUvu-es1.js} +4 -4
- package/dist/registry-BUvu-es1.js.map +1 -0
- package/dist/registry-DYHR-ONu.js +2 -0
- package/dist/{run-attach-DDpMk2_N.js → run-attach-X35puJ_n.js} +2 -2
- package/dist/{run-attach-DDpMk2_N.js.map → run-attach-X35puJ_n.js.map} +1 -1
- package/dist/schedule-Ke0jwatM.js +5 -0
- package/dist/schedule-Ke0jwatM.js.map +1 -0
- package/dist/serve-K6BOT5K_.js +21 -0
- package/dist/serve-K6BOT5K_.js.map +1 -0
- package/dist/{service-client-Cr4sxDVM.js → service-client-cfUUP4EE.js} +1 -1
- package/dist/{service-client-Cr4sxDVM.js.map → service-client-cfUUP4EE.js.map} +1 -1
- package/dist/{version-BrSIyY6s.js → version-DrCy32wR.js} +2 -2
- package/dist/{version-BrSIyY6s.js.map → version-DrCy32wR.js.map} +1 -1
- package/package.json +16 -13
- package/dist/build-id-DxfuzdUE.js +0 -3
- package/dist/build-id-DxfuzdUE.js.map +0 -1
- package/dist/command-dispatcher-DTOPjtZP.js +0 -21
- package/dist/command-dispatcher-DTOPjtZP.js.map +0 -1
- package/dist/create-host-app-BXQ8bU-B.js +0 -3
- package/dist/create-host-app-DG58-vRA.js +0 -2
- package/dist/extension-CTyrcdT1.js +0 -2
- package/dist/extension-DVEml5IN.js +0 -179
- package/dist/extension-DVEml5IN.js.map +0 -1
- package/dist/feedback-DvWUvSc4.js +0 -21
- package/dist/feedback-DvWUvSc4.js.map +0 -1
- package/dist/feedback-DzPLfcfN.js +0 -2
- package/dist/feishu-setup-5ZoxtH0J.js.map +0 -1
- package/dist/install-DlVJRHRT.js +0 -11
- package/dist/install-DlVJRHRT.js.map +0 -1
- package/dist/install-WCcQ9k9M.js +0 -2
- package/dist/mcp-server-Dpza3yn2.js.map +0 -1
- package/dist/parse-cli-BvcxTK88.js +0 -3
- package/dist/parse-cli-BvcxTK88.js.map +0 -1
- package/dist/proxy-BvdBsB1O.js +0 -2
- package/dist/proxy-evg7ZvoD.js.map +0 -1
- package/dist/registry-BOX7DaxS.js +0 -2
- package/dist/registry-BdCcwyGy.js.map +0 -1
- package/dist/serve-Ke0nwN9Y.js +0 -21
- package/dist/serve-Ke0nwN9Y.js.map +0 -1
|
@@ -41,30 +41,12 @@ import type {
|
|
|
41
41
|
* (红线:绝不 fallback 到 createLogger)。
|
|
42
42
|
*/
|
|
43
43
|
import type { WireProtocolLogger } from '@x-otto/provider'
|
|
44
|
-
|
|
45
|
-
const noopLogger: WireProtocolLogger = { debug: () => {}, info: () => {}, warn: () => {}, error: () => {} }
|
|
44
|
+
import { noopWireProtocolLogger, resolveProviderBaseUrl } from '@x-otto/provider'
|
|
46
45
|
|
|
47
46
|
export type AnthropicCredentialResolver = () => Promise<string | undefined>
|
|
48
47
|
export type AnthropicAuthResolver = () => Promise<ResolvedAuth | undefined>
|
|
49
48
|
export type AnthropicBaseUrlResolver = () => Promise<string | undefined>
|
|
50
49
|
|
|
51
|
-
async function resolveBaseUrl(
|
|
52
|
-
modelBaseUrl: string,
|
|
53
|
-
resolver?: AnthropicBaseUrlResolver,
|
|
54
|
-
): Promise<string> {
|
|
55
|
-
const envUrl = process.env['ANTHROPIC_BASE_URL']
|
|
56
|
-
if (envUrl) {
|
|
57
|
-
return envUrl
|
|
58
|
-
}
|
|
59
|
-
if (resolver) {
|
|
60
|
-
const authUrl = await resolver()
|
|
61
|
-
if (authUrl) {
|
|
62
|
-
return authUrl
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
return modelBaseUrl
|
|
66
|
-
}
|
|
67
|
-
|
|
68
50
|
export function toBudgetTokens(level: string, maxOutputTokens: number): number {
|
|
69
51
|
// RFC-235:Anthropic 是 token 预算型(非 effort 关键字)。otto 档位 → maxOutput 百分比预算。
|
|
70
52
|
// 词表对齐 Claude Code(去 minimal 加 max):low 25% / medium 50% / high 75% / xhigh 90% / max 95%。
|
|
@@ -649,7 +631,7 @@ export interface AnthropicProviderOptions {
|
|
|
649
631
|
tokenDerivedHeaders?: TokenDerivedHeader[]
|
|
650
632
|
/** RFC-270 D3:manifest 显式声明后,允许自定义头覆盖鉴权头(企业网关换鉴权)。 */
|
|
651
633
|
allowAuthHeaderOverride?: boolean
|
|
652
|
-
/** RFC-185 D3:宿主注入的日志端口,缺省 no-op
|
|
634
|
+
/** RFC-185 D3:宿主注入的日志端口,缺省 no-op(`noopWireProtocolLogger`,@x-otto/provider 单例)。 */
|
|
653
635
|
logger?: WireProtocolLogger
|
|
654
636
|
}
|
|
655
637
|
|
|
@@ -669,7 +651,7 @@ class AnthropicStream implements ProviderStream {
|
|
|
669
651
|
private readonly authResolver?: AnthropicAuthResolver,
|
|
670
652
|
/** 见 `AnthropicProviderOptions.customizeRequest` 注释。缺省 = 零定制。 */
|
|
671
653
|
private readonly customizeRequest?: (input: AnthropicRequestCustomizeInput) => AnthropicRequestCustomization,
|
|
672
|
-
private readonly logger: WireProtocolLogger =
|
|
654
|
+
private readonly logger: WireProtocolLogger = noopWireProtocolLogger,
|
|
673
655
|
/** 见 `AnthropicProviderOptions.headers`(RFC-270 缺陷 1 修复)。 */
|
|
674
656
|
private readonly staticHeaders?: Record<string, string>,
|
|
675
657
|
private readonly tokenDerivedHeaders?: TokenDerivedHeader[],
|
|
@@ -711,7 +693,7 @@ class AnthropicStream implements ProviderStream {
|
|
|
711
693
|
context: StreamContext,
|
|
712
694
|
auth: ResolvedAuth,
|
|
713
695
|
): Promise<{ client: Anthropic; requestParams: Anthropic.MessageStreamParams; baseURL: string }> {
|
|
714
|
-
const baseURL = await
|
|
696
|
+
const baseURL = await resolveProviderBaseUrl('ANTHROPIC_BASE_URL', this.baseUrlResolver, model.baseUrl)
|
|
715
697
|
// RFC-140 D-copilot-spoof-split:本文件不再判断"是否 oauth 才伪装"——那是具体厂商
|
|
716
698
|
// (如 plugin-anthropic 的 Claude Code 伪装)的业务逻辑,交给 customizeRequest 定制器
|
|
717
699
|
// 自行按 input.auth.mode 判断要不要返回定制内容。未提供定制器 = 零调用零开销。
|
|
@@ -20,9 +20,7 @@ import type {
|
|
|
20
20
|
WireRequestCustomization,
|
|
21
21
|
WireRequestCustomizeInput,
|
|
22
22
|
} from '@x-otto/provider'
|
|
23
|
-
|
|
24
|
-
/** RFC-185 D3:日志走宿主注入端口,缺省 no-op——插件源码禁 createLogger(防第二单例直写 stderr)。 */
|
|
25
|
-
const noopLogger: WireProtocolLogger = { debug: () => {}, info: () => {}, warn: () => {}, error: () => {} }
|
|
23
|
+
import { noopWireProtocolLogger, resolveProviderBaseUrl } from '@x-otto/provider'
|
|
26
24
|
|
|
27
25
|
/**
|
|
28
26
|
* 通用 OpenAI Chat Completions provider(对标 opencode/pi 的 openai-compatible 基座)。
|
|
@@ -75,7 +73,7 @@ class OpenAICompletionsStream implements ProviderStream {
|
|
|
75
73
|
private readonly resolveCredential?: OpenAICompletionsCredentialResolver,
|
|
76
74
|
private readonly extraHeaders?: Record<string, string>,
|
|
77
75
|
private readonly tokenDerivedHeaders?: TokenDerivedHeader[],
|
|
78
|
-
private readonly logger: WireProtocolLogger =
|
|
76
|
+
private readonly logger: WireProtocolLogger = noopWireProtocolLogger,
|
|
79
77
|
/** 见 `OpenAICompletionsProviderOptions.customizeRequest`。缺省 = 零定制。 */
|
|
80
78
|
private readonly customizeRequest?: (input: WireRequestCustomizeInput) => WireRequestCustomization,
|
|
81
79
|
private readonly allowAuthHeaderOverride?: boolean,
|
|
@@ -127,7 +125,9 @@ class OpenAICompletionsStream implements ProviderStream {
|
|
|
127
125
|
})
|
|
128
126
|
|
|
129
127
|
yield* streamChatCompletions({
|
|
130
|
-
url: `${
|
|
128
|
+
url: `${await resolveProviderBaseUrl(
|
|
129
|
+
model.provider === 'deepseek' ? 'DEEPSEEK_BASE_URL' : 'OPENAI_BASE_URL',
|
|
130
|
+
undefined, model.baseUrl)}/chat/completions`,
|
|
131
131
|
headers,
|
|
132
132
|
body: buildChatCompletionsBody(model, context),
|
|
133
133
|
identity: { api: model.api, provider: model.provider, model: model.id },
|
|
@@ -34,9 +34,7 @@ import type {
|
|
|
34
34
|
WireRequestCustomization,
|
|
35
35
|
WireRequestCustomizeInput,
|
|
36
36
|
} from '@x-otto/provider'
|
|
37
|
-
|
|
38
|
-
/** RFC-185 D3:日志走宿主注入端口,缺省 no-op——插件源码禁 createLogger(防第二单例直写 stderr)。 */
|
|
39
|
-
const noopLogger: WireProtocolLogger = { debug: () => {}, info: () => {}, warn: () => {}, error: () => {} }
|
|
37
|
+
import { noopWireProtocolLogger, resolveProviderBaseUrl } from '@x-otto/provider'
|
|
40
38
|
|
|
41
39
|
export type OpenAIResponsesCredentialResolver = () => Promise<string | undefined>
|
|
42
40
|
export type OpenAIResponsesBaseUrlResolver = () => Promise<string | undefined>
|
|
@@ -373,7 +371,7 @@ class OpenAIResponsesStream implements ProviderStream {
|
|
|
373
371
|
* 补齐此字段后硬编码分支已冗余,随本次一并删除(见下方 buildHeaders)。
|
|
374
372
|
*/
|
|
375
373
|
private readonly staticHeaders?: Record<string, string>,
|
|
376
|
-
private readonly logger: WireProtocolLogger =
|
|
374
|
+
private readonly logger: WireProtocolLogger = noopWireProtocolLogger,
|
|
377
375
|
/** 见 `OpenAIResponsesProviderOptions.customizeRequest`。缺省 = 零定制。 */
|
|
378
376
|
private readonly customizeRequest?: (input: WireRequestCustomizeInput) => WireRequestCustomization,
|
|
379
377
|
private readonly allowAuthHeaderOverride?: boolean,
|
|
@@ -405,17 +403,7 @@ class OpenAIResponsesStream implements ProviderStream {
|
|
|
405
403
|
}
|
|
406
404
|
|
|
407
405
|
private async resolveBaseUrl(model: Model): Promise<string> {
|
|
408
|
-
|
|
409
|
-
if (envUrl) {
|
|
410
|
-
return envUrl
|
|
411
|
-
}
|
|
412
|
-
if (this.baseUrlResolver) {
|
|
413
|
-
const url = await this.baseUrlResolver()
|
|
414
|
-
if (url) {
|
|
415
|
-
return url
|
|
416
|
-
}
|
|
417
|
-
}
|
|
418
|
-
return model.baseUrl
|
|
406
|
+
return resolveProviderBaseUrl('OPENAI_BASE_URL', this.baseUrlResolver, model.baseUrl)
|
|
419
407
|
}
|
|
420
408
|
|
|
421
409
|
/**
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import{t as e}from"./build-id-DjE6eVpQ.js";import{t}from"./version-DrCy32wR.js";import{t as n}from"./discover-with-bundled-CF8qFP41.js";import{n as r,r as i,t as a}from"./service-client-cfUUP4EE.js";import{n as o}from"./extension-Dpn8gltG.js";import{n as s,t as c}from"./registry-BUvu-es1.js";import{t as l}from"./proxy-CFZDVIwI.js";import{i as u}from"./install-CEPczuet.js";import{t as d}from"./schedule-Ke0jwatM.js";import{createRequire as f}from"node:module";import{arch as p,cpus as m,freemem as h,homedir as g,platform as _,release as v,totalmem as y}from"node:os";import{execFile as b,execSync as x,spawn as ee,spawnSync as S}from"node:child_process";import{DEFAULT_WORKSPACE_KEY as C,INDUCTOR_PLUGIN_ID as w,PLUGIN_MANIFEST_FILENAME as te,POINT as ne,buildExtensionContext as re,checkUpgrades as T,collectPluginPerfMetrics as ie,defaultPostInstallExecutor as ae,detectProjectConfigGating as oe,discoverFileCommands as se,discoverPlugins as ce,dispatch as le,evaluateClaudeTrust as ue,evaluatePluginTrust as E,findWorkspaceRoot as de,getLastAssistantText as D,grantPluginCapabilities as fe,grantPluginCapabilitiesWithVersion as pe,install as me,installPluginFromPackage as he,openTarget as ge,parsePluginManifest as _e,readHighRiskCapabilities as ve,readPluginLogTail as ye,readSkillLoopStatus as be,recordPluginInstalled as xe,recordPluginUninstalled as Se,redactSensitiveFields as Ce,resolveActions as we,resolvePackageDir as Te,resolveSessionTitle as Ee,runPluginScript as De,scanInstalledVersions as Oe,trustPlugin as ke,trustProject as Ae,uninstall as je,untrustPlugin as Me,untrustProject as Ne}from"@x-otto/coding";import{checkShellCommand as Pe,openBrowser as Fe,readFileCapped as Ie}from"@x-otto/shared";import{BUILD_ID as Le,SDK_VERSION as Re}from"@x-otto/env";import{dirname as O,join as k,relative as ze,resolve as Be}from"node:path";import{closeSync as Ve,existsSync as A,openSync as He,readFileSync as Ue,readSync as We,readdirSync as Ge,statSync as j}from"node:fs";import{ACTION_CHIP_VALUE_SEGMENT as Ke,FIGURES as M,buildTurnSummary as qe,createBuiltinThemeRegistry as Je,createReducerState as Ye,deriveTurnBoundaries as Xe,detectLanguage as Ze,formatProviderUsageLimitTypeFull as Qe,i18next as N,initI18n as $e,insertTurnSummaries as et,reduceToTui as tt}from"@x-otto/tui";import{createBuiltinCommands as nt}from"@x-otto/tui/compat";import{MaxToolTurnsError as rt,PromptBudgetExceededError as it}from"@x-otto/agent";import{readFile as at,readdir as ot,stat as st,unlink as ct}from"node:fs/promises";import{DEFAULT_COMPACTION_CONFIG as lt,DEFAULT_PRUNE_CONFIG as ut,estimateTokens as dt,resolveContextSize as ft}from"@x-otto/memory";import{classifyAuthErrorType as pt,computeCacheHitRatio as mt,createModelUsabilityGate as P,getProviderDescriptor as ht,getToolCallsByAssistantMessage as gt,isAuthError as _t}from"@x-otto/ai";import{promisify as vt}from"node:util";var yt=Object.defineProperty,bt=(e,t)=>{let n={};for(var r in e)yt(n,r,{get:e[r],enumerable:!0});return t||yt(n,Symbol.toStringTag,{value:`Module`}),n},xt=f(import.meta.url);function St(e){return`⚠ 已达工具回合上限(${e.extensions>0?`约 ${e.effectiveMaxTurns} 次(含 ${e.extensions} 次自动扩展,每次 ${e.maxTurns})`:`${e.maxTurns} 次`}),提前停止——任务可能未完成。\n 重试可加 --max-tool-turns <n>(每轮预算,实际上限 ≈ n×${1+e.extensions};如 --max-tool-turns ${e.maxTurns*2})。\n 注:配置了 --prompt-token-budget 时轮次窗口自动 ×4(此处报的是放大后的有效值)。`}function Ct(e,t){let n=D(e.session.messages())||t.partialText,r=St(t);return n?`${n}\n${r}`:r}function wt(e){let t=e.dimension===`tokens`?`输出 token 预算 ${e.used}/${e.budget}`:`时间预算 ${Math.round(e.used/1e3)}s/${Math.round(e.budget/1e3)}s`;return`⚠ 已达本回合${e.dimension===`tokens`?`输出 token`:`墙钟时间`}预算(${t}),提前停止——任务可能未完成。\n 重试可加 ${e.dimension===`tokens`?`--prompt-token-budget <n>`:`--prompt-time-budget <分钟>`} 提升预算。`}function Tt(e,t){let n=D(e.session.messages())||t.partialText,r=wt(t);return n?`${n}\n${r}`:r}async function Et(e,t,n={}){let{writer:r,tui:i=!1,tuiOptions:a,onTurnEnd:o}=typeof n==`function`?{writer:n}:n,s=r??(e=>process.stdout.write(`${e}\n`)),c=Date.now();try{await e.prompt(t)}catch(t){if(t instanceof rt||t instanceof it){let n=t instanceof it,r=n?wt(t):St(t);o?.(n?`budget-exceeded`:`max-tool-turns`,r);let l=o?D(e.session.messages())||t.partialText:n?Tt(e,t):Ct(e,t);if(i){let{printMessages:t}=await import(`@x-otto/tui`);t(e.session.messages(),{...a,startTime:c,contextWindow:0}),s(l)}else s(l);return l}throw t}if(o&&e.budgetSteeredThisPrompt&&o(`max-tool-turns`,`⚠ 已达工具回合上限——已自动收尾本回合(任务可能未全部完成,可继续指示我,或加 --max-tool-turns 提升预算)。`),i){let{printMessages:t}=await import(`@x-otto/tui`),n=e.session.messages();return t(n,{...a,startTime:c,contextWindow:e.model.contextWindow??0}),D(n)}let l=D(e.session.messages());return s(l),l}async function Dt(e,n){try{await e.prompt(n)}catch(n){if(n instanceof rt)return{sessionId:e.id,status:`max_turns`,messageCount:e.session.messages().length,response:D(e.session.messages())||n.partialText,ottoVersion:t()};if(n instanceof it)return{sessionId:e.id,status:`budget_exceeded`,messageCount:e.session.messages().length,response:D(e.session.messages())||n.partialText,ottoVersion:t()};throw n}return{sessionId:e.id,status:e.status,messageCount:e.session.messages().length,response:D(e.session.messages()),ottoVersion:t()}}var F=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=nt()}getRegistry(){return this.commandRegistry}abort(){this.session.abort()}async handleInput(e){if(this.session.status===`archived`)return{type:`system`,text:`此会话已归档(archived),无法发送新消息。使用 /resume 切换到其他会话。`};let t=e.trim();if(t.length===0)return{type:`noop`};if(t.startsWith(`!`)){let e=t.slice(1).trim();if(!e)return{type:`system`,text:`Usage: !<shell command>`};let n=Pe(e);if(!n.safe)return{type:`system`,text:`Refusing to execute dangerous command (${n.reason}): ${e}\nUse the bash tool via the agent for privileged operations.`};let r,i=!1;try{r=x(e,{encoding:`utf-8`,timeout:3e4,cwd:this.session.workspaceDir,maxBuffer:1024*1024})}catch(e){let t=e;r=t.stderr||t.stdout||t.message||String(e),i=!0}return r=r.trimEnd(),this.session.session.append({role:`system`,subtype:`local_command`,level:i?`error`:`info`,content:r||`(no output)`,timestamp:Date.now()}),{type:`response`,text:r||`(no output)`}}if(t.startsWith(`@`)){let e=t.slice(1).trim();return e?{type:`response`,text:await Et(this.session,`Read and analyze the file: ${e}`,{writer:()=>{}})}:{type:`system`,text:`Usage: @<file-path>`}}if(!t.startsWith(`/`)){let e,n;return{type:`response`,text:await Et(this.session,t,{writer:()=>{},onTurnEnd:(t,r)=>{e=t,n=r}}),endReason:e,notice:n}}let[n,...r]=t.slice(1).split(/\s+/);if(!n){let{showCommandPalette:e}=await import(`@x-otto/tui`),t=await e(this.commandRegistry.list(),process.stdin,process.stdout);if(!t.command)return{type:`noop`};let n=this.commandRegistry.get(t.command);if(!n)return{type:`noop`};let r=await n.execute(t.args,{signal:new AbortController().signal,width:process.stdout.columns??80,models:this.modelList,currentModel:this.currentModelId,onModelChange:this.onModelChange});return this._handleCommandResult(r)}let i=r.join(` `),a=this.commandRegistry.find(n);if(!a)return{type:`system`,text:`Unknown command: /${n}. Try /help.`};let o=await a.execute(i,{signal:new AbortController().signal,width:process.stdout.columns??80,models:this.modelList,currentModel:this.currentModelId,onModelChange:this.onModelChange});return this._handleCommandResult(o)}_handleCommandResult(e){if(typeof e==`string`)return{type:`system`,text:e};switch(e.kind){case`exit`:return{type:`exit`,restart:e.restart};case`help`:return{type:`help`};case`clear`:return this.session.clearTurnPanels(),this.session.clearContext(),process.stdout.write(`\x1B[2J\x1B[H`),{type:`noop`};case`abort`:return this.session.abort(),{type:`system`,text:`Aborted current run.`};case`status`:return{type:`system`,text:`Session: ${this.session.id} | Status: ${this.session.status}`};case`copy`:return{type:`system`,text:`Copy not yet available in CLI mode.`};case`model`:return this.onModelChange?(this.onModelChange(e.modelId).then(e=>{process.stdout.write(e+`
|
|
3
|
+
`)}).catch(e=>{process.stdout.write(`Model switch failed: ${e instanceof Error?e.message:String(e)}\n`)}),{type:`system`,text:`Switching to ${e.modelId}...`}):{type:`system`,text:`Model switching not available.`}}}};function Ot(){return Ze()}function kt(e=`auto`){let t=e===`auto`?Ze():e;return $e(t),t}const At=`@x-otto/cli`;async function jt(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:Pt(r,Mt(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)=>Pt(t,e)>0?t:e):Object.values(i).reduce((e,t)=>e===null||Pt(t,e)>0?t:e,null);return o?{latest:o,current:e,newer:Pt(o,Mt(e))>0}:null}catch{return null}}function Mt(e){let t=/^v?\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?/.exec(e.trim());return t?t[0]:e}function Nt(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 Pt(e,t){let n=Nt(e),r=Nt(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 Ft(e){return new Promise(t=>{try{let n=ee(process.platform===`win32`?`npm.cmd`:`npm`,[`install`,`-g`,e?`${At}@${e}`:`${At}@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 It(e){return e?Date.now()-e>216e5:!0}async function Lt(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||!It(e.lastCheck)?null:jt(e.currentVersion).then(async t=>t&&(e.persistLastCheck().catch(()=>{}),t.newer)?{...t,forced:!1}:null).catch(()=>null)}let Rt,zt;function Bt(e){let t=e.map(e=>e.name).sort().join(`,`);if(Rt!==void 0&&zt===t)return Rt;let n=e=>typeof e==`function`?`[fn]`:typeof e==`string`?e:``;return Rt=dt(JSON.stringify(e.map(e=>({name:e.name,description:n(e.description),parameters:e.parameters})))),zt=t,Rt}let I,Vt;function Ht(e){return I!==void 0&&Vt===e?I:(I=dt(e),Vt=e,I)}function Ut(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=Ht(t)+Bt(n),h=a+o+r+i+p,g=Math.max(0,h-m),_=Math.max(0,s-m-g),v=ft(ut.trigger,s),y=ft(lt.trigger,s);return{modelName:c,contextWindow:s,contextPercent:s>0?h/s*100:0,overheadTokens:m,messageTokens:g,messageCount:f,totalUsed:h,free:_,pruneLine:v,compactLine:y,lastInput:r,lastOutput:i,totalInput:l,totalOutput:u,cost:d,live:p>0}}const Wt={openai:`OpenAI`};function Gt(e){let t=[`confirm`,`auto`,`bypass`];return t[(t.indexOf(e)+1)%t.length]??`confirm`}function Kt(e){return e===`error`?`error`:e===`approval_required`||e===`input_required`?`warning`:`info`}function qt(e,t,n){let r=t===void 0?void 0:{code:t},i=r!==void 0&&_t(r),a=i&&pt(r)===`refresh-failed`;return{authError:i||/\b401\b|authentication|unauthorized|api[\s_-]?key|invalid.*key/i.test(e),isRefreshFailed:a,unsupported:/model_not_supported|not\s+supported|invalid.*model|model.*invalid/i.test(e),rateLimit:/\b429\b|rate.limit|rate_limit|exceed.*rate/i.test(e),pluginSource:n}}function L(e){return e?e.toLowerCase()===`xhigh`?`XHigh`:e.charAt(0).toUpperCase()+e.slice(1):``}function Jt(e,t,n){return e?`${t.on} ${n.on}`:`${t.off} ${n.off}`}function R(e,t,n){if(!t)return`(no model)`;let r=L(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 Yt(e,t){let n=[...se(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 Xt(e){return{id:e.id,type:`function`,function:{name:e.name,arguments:JSON.stringify(e.arguments)}}}function Zt(e){return{type:`thinking`,thinking:e.text}}function Qt(e){return{type:`text`,text:e.text}}function $t(e){return{type:`a2ui`,version:e.version,components:e.components}}function en(e){let t=[],n=[];for(let r of e)switch(r.type){case`text`:r.text.trim()&&t.push(Qt(r));break;case`thinking`:r.text.trim()&&t.push(Zt(r));break;case`tool_call`:n.push(Xt(r));break;case`a2ui`:t.push($t(r));break}return{content:t,toolCalls:n}}function tn(e){return typeof e==`string`?e.trim():e.filter(e=>e.type===`text`).map(e=>e.text).join(``).trim()}function nn(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 z(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=tn(e.content);t&&i.push({role:`user`,content:t});continue}if(e.role===`assistant`){let{content:t}=en(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:nn(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:nn(r),argsObj:r,result:tn(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 rn=vt(b);function an(e,t,n){for(let r of e){if(r.role!==`assistant`)continue;let e=gt(r);for(let r of e){if(r.id!==t)continue;let e=r.arguments;if(n===`edit`)return{oldContent:typeof e.oldContent==`string`?e.oldContent:void 0,newContent:typeof e.newContent==`string`?e.newContent:void 0};if(n===`write`)return{newContent:typeof e.content==`string`?e.content:void 0}}}return{}}function on(e,t){let n=O(e),r=e=>{let t=S(`git`,[...e],{cwd:n,timeout:5e3,encoding:`utf-8`,maxBuffer:10*1024*1024});return t.status===0?t.stdout:null},i;if(t!==`delete`)try{i=Ue(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 sn(e,t){let n=O(e),r=async e=>{try{let{stdout:t}=await rn(`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 at(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 cn(e){return[...e].sort((e,t)=>t.savedAt-e.savedAt)}function ln(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 un(e,t,n){let r=Date.now();return{id:`${r.toString(36)}-${Math.random().toString(36).slice(2,6)}`,name:ln(e,n),text:t,savedAt:r}}function dn(e){return e.length<=50?[...e]:e.slice(-50)}function B(e){let t=z(e.session.visibleMessages()),n=e.session.getTurnSummaries();return!n||n.length===0?t:et(t,n,e.session.getTurnCount()??t.filter(e=>e.role===`user`).length)}function fn(e){let{resumedNote:t,isFound:n,session:r,projState:i,tui:a}=e,o=B(r);a.messages.pushMessages(o),n&&o.length>0&&a.info.setTopView({session:r.id}),a.info.showToast(n?N.t(`cmd.titleSessionResumed`):N.t(`cmd.titleSession`),t.replace(/^↻ /,``)),pn({session:r,projState:i,tui:a,chatMsgs:o})}function pn(e){let{session:t,projState:n,tui:r}=e,i=e.chatMsgs??B(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(N.t(`cmd.titleSession`),N.t(`cmd.resumeTodosAllDone`)));{let e=t.session.getTurnCount(),a=i.filter(e=>e.role===`user`).length,o=e??a;o>0&&(r.stores.tasks.setTurnBoundaries(Xe(i,o)),n.currentTurn=o)}let a=t.session.getEditedFiles();if(a&&a.length>0){let e=t.session.messages();r.stores.tasks.setEditedFiles(a.map(t=>{let n=t.operation,r=t.toolCallId?an(e,t.toolCallId,n):{};return r.oldContent===void 0&&r.newContent===void 0&&(r=on(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(cn(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 V=new Map;function mn(e){return V.get(e)}function H(e){V.delete(e);let t=W.get(e);t&&(clearTimeout(t),W.delete(e))}function hn(){return[...V.values()]}function U(e,t,n){let r={id:e,transcript:z(t),streaming:``,status:n?`busy`:`idle`,lastActivityAt:Date.now()};return V.set(e,r),r}function gn(e,t){let n=V.get(e);n&&(n.transcript=z(t),n.lastActivityAt=Date.now())}const _n=new Set;function vn(e){return _n.add(e),()=>{_n.delete(e)}}const W=new Map;function yn(e){let t=W.get(e.id);t&&clearTimeout(t),W.set(e.id,setTimeout(()=>{W.delete(e.id);for(let t of _n)t(e)},300))}function bn(e,t){let n=``,r=t=>{e.status!==t&&(e.status=t,yn(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`),gn(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(),yn(e);return}},()=>e]}function xn(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 Sn(e,t){let n=e.join(` `).trim();if(!n){t.tui.info.showToast(`/session inspect`,"Usage: /session inspect <sessionId> —— peek a session running on `otto serve` (read-only snapshot)");return}let o=i(process.env.OTTO_SERVICE_URL??`http://127.0.0.1:8417`,globalThis.fetch,{token:process.env.OTTO_SERVICE_TOKEN}),s;try{s=await o.fetchSnapshot(n)}catch(e){if(e instanceof r){t.tui.info.showToast(`/session inspect`,`无法连接 otto serve:${e.message} —— 先 \`otto serve\`(或指定 --remote/OTTO_SERVICE_URL)`);return}if(e instanceof a){t.tui.info.showToast(`/session inspect`,`拉取 snapshot 失败:${e.message}`);return}t.tui.info.showToast(`/session inspect`,`查看失败:${e instanceof Error?e.message:String(e)}`);return}t.tui.messages.pushMessage({role:`assistant`,content:[{type:`text`,text:`[session inspect]\n${xn(s)}`}]}),t.tui.info.showToast(`/session inspect`,`已查看会话 ${s.session.id}(只读快照;如需实时参与该会话请用 otto --attach ${s.session.id})`)}function Cn(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 wn=e=>`把下面的笔记归纳成一个简短标题(≤6 词)和一句话描述。严格只按此格式输出:\nTITLE: <标题>\nDESC: <一句话描述>\n\n笔记:\n${e}`;function Tn(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 En(e,t,n=8e3){let r=Cn(e);if(!t)return r;let i=new AbortController,a=setTimeout(()=>i.abort(),n);a.unref?.();try{let n=Tn(await t(wn(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 Dn(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 On(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=Cn(i);await r.record(e),o(`/memory user`,`ok`,N.t(`cmd.memoryUserSaved`,{name:e.name}));return}let a=r.getInjection().trim();t.tui.modal.openModal({kind:`memory`,projectIndex:``,userIndex:a,...Dn(n,r)});return}if(i===`project`){let e=n?n.getInjection().trim():``;t.tui.modal.openModal({kind:`memory`,projectIndex:e,userIndex:``,...Dn(n,r)});return}if(i===`forget`){let t=e.slice(1).join(` `).trim();if(!t){o(`/memory forget`,`warn`,N.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?N.t(`cmd.memoryDeleted`,{name:t}):N.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`,N.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,...Dn(n,r)})}async function kn(e,t){let n=N.t(`cmd.titleCompact`);if((e[0]??``).toLowerCase()===`log`){t.tui.panes.togglePane(`compactionLog`);return}if(!t.app.storage.memory){t.tui.info.showToast(n,N.t(`compact.unavailable`));return}t.tui.info.showToast(n,N.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,N.t(`compact.edResult`,{before:e.before,after:e.after})),t.callbacks.onContextCompacted()):t.tui.info.showToast(n,N.t(`compact.noop`))}catch(e){t.tui.info.showToast(n,N.t(`cmd.compactFailed`,{msg:e instanceof Error?e.message:String(e)}))}finally{t.tui.engine.pushEngineEvent({kind:`agentProcessing`,value:!1})}}async function An(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(R(t.app,n.id,t.state.session.thinkingLevel));let r=n?.contextWindow??2e5,i=Ut({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(N.t(`cmd.titleCleared`),N.t(`cmd.clearedDone`))}async function jn(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 Mn(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,N.t(`cmd.titleResume`),N.t(`cmd.resumeAlreadyOn`));return}let n=t.app.getSession(e)??await t.app.sessionManager.restore(e);if(!n){l(t,N.t(`cmd.titleResume`),N.t(`cmd.resumeSessionNotFound`,{idShort:e.slice(0,8)}));return}let r=t.state.session;if(t.state.session.isBusy){let[e]=bn(U(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 U(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 F(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(R(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=mn(n.id);if(a)t.tui.messages.pushMessages(a.transcript),H(n.id);else{let e=B(n);t.tui.messages.pushMessages(e)}t.callbacks.restoreSwitchedSession(),t.tui.info.setTopView({session:n.id}),l(t,N.t(`cmd.titleResume`),N.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,N.t(`cmd.titleResume`),N.t(`cmd.sessionNoMatch`,{arg:n}));return}if(c.length===0){l(t,N.t(`cmd.titleResume`),N.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()||N.t(`cmd.resumeDefaultPinGroup`):N.t(`cmd.resumeRecentGroup`)}function g(e){if(!e)return``;let t=Math.max(0,Math.floor((Date.now()-e.getTime())/1e3));return t<10?N.t(`cmd.agoJustNow`):t<60?N.t(`cmd.agoSeconds`,{n:t}):t<3600?N.t(`cmd.agoMinutes`,{n:Math.floor(t/60)}):t<86400?N.t(`cmd.agoHours`,{n:Math.floor(t/3600)}):N.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?N.t(`cmd.resumeArchivedHiddenHint`,{count:s}):``].filter(Boolean),x=b.length>0?` ${b.join(` `)}`:``,ee=new Map(hn().map(e=>[e.id,e])),S=0,C=0,w=e=>{if(e.id===d)return``;let n=ee.get(e.id);return n?n.status===`busy`?(S++,`● ${N.t(`cmd.resumeStatusBusy`)} · `):n.status===`needs-input`?(C++,`● ${N.t(`cmd.resumeStatusNeedsInput`)} · `):`· ${N.t(`cmd.resumeStatusIdle`)} · `:t.app.getSession(e.id)?.isBusy?(S++,`● ${N.t(`cmd.resumeStatusBusy`)} · `):``},te=[S>0?`${S} ${N.t(`cmd.resumeStatusBusy`)}`:``,C>0?`${C} ${N.t(`cmd.resumeStatusNeedsInput`)}`:``].filter(Boolean).join(`, `),ne=te?` · ${te}`:``,re=N.t(`cmd.resumeSubtitle`,{sessions:c.length,msgs:v,recent:_})+ne+x,T=i?N.t(`cmd.resumeArchivedOnlyTitle`,{n:c.length}):N.t(`cmd.resumeSelectTitle`,{n:c.length});t.tui.modal.openModal({kind:`select`,title:T+y,subtitle:re,searchable:!0,maxVisible:13,options:m.map(e=>{let t=e.id===d?`●`:` `,n=e.pinned?N.t(`cmd.resumePinnedPrefix`):``,r=e.title||e.id.slice(0,8),i=e.status===`archived`?N.t(`cmd.resumeArchivedSuffix`):``,a=e.writeLocked?N.t(`cmd.resumeReadOnlySuffix`):``,o=`${n}${r}${i}`,s=g(e.updatedAt),c=[w(e).trim(),s,N.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,N.t(`cmd.titleResume`),N.t(`cmd.resumeFailed`,{msg:e instanceof Error?e.message:String(e)})))},onCancel:()=>{}})}async function Nn(e,t){t.app.reloadCapabilities().then(e=>{t.tui.plugins.setPluginRegistrations(t.app.getPluginRegistrations()),t.tui.info.showToast(N.t(`cmd.titleReload`),N.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:N.t(`cmd.reloadFailed`,{msg:e instanceof Error?e.message:String(e)})}))}async function Pn(e,t){let n=t.app.diagnoser.propose();if(n.length===0){t.tui.info.showToast(N.t(`cmd.titleDiagnose`),N.t(`cmd.diagnoseNone`));return}let r=n.map((e,t)=>N.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:N.t(`cmd.diagnoseSummary`,{count:n.length}),detail:r.join(`
|
|
6
|
+
`)})}async function Fn(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(N.t(`cmd.titleArchive`),N.t(`cmd.sessionNoMatch`,{arg:n}));return}if(r.status===`archived`){let e=t.app.getSession(r.id);if(!e){t.tui.info.showToast(N.t(`cmd.titleUnarchive`),N.t(`cmd.unarchiveNotLoaded`,{idShort:r.id.slice(0,8)}));return}e.unarchive(),t.tui.info.showToast(N.t(`cmd.titleUnarchive`),N.t(`cmd.unarchiveDone`,{idShort:r.id.slice(0,8),title:r.title??``}));return}if(!await t.app.archiveSession(r.id)){t.tui.info.showToast(N.t(`cmd.titleArchive`),N.t(`cmd.archiveCannot`,{idShort:r.id.slice(0,8)}));return}t.tui.info.showToast(N.t(`cmd.titleArchive`),N.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(N.t(`cmd.titleUnarchive`),N.t(`cmd.unarchiveDone`,{idShort:r.id.slice(0,8),title:r.title??``}));return}r.archive(),t.tui.info.showToast(N.t(`cmd.titleArchive`),N.t(`cmd.archiveDone`,{idShort:r.id.slice(0,8),title:r.title??``}))}async function In(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(N.t(`cmd.titlePin`),N.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(N.t(`cmd.titleUnpin`),N.t(`cmd.unpinDone`,{idShort:e.id.slice(0,8),title:e.title??``}))):(e.pin(),t.tui.info.showToast(N.t(`cmd.titlePin`),N.t(`cmd.pinDone`,{idShort:e.id.slice(0,8),title:e.title??``}))),Ln(t);return}if(r.length===0){Rn(t.state.session.id,n,t),Ln(t);return}if(r.length===1){Rn(r[0],n,t),Ln(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(N.t(`cmd.titlePin`),N.t(`cmd.pinBatchSummary`,{seg:o.length>0?`${a} pinned (${o.length} not found: ${o.join(`, `)})`:`${a} pinned`})),Ln(t)}function Ln(e){let t=e.callbacks.refreshSlashCommands();e.tui.plugins.setCommands(t)}function Rn(e,t,n){if(e===n.state.session.id){zn(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(N.t(`cmd.titlePin`),N.t(`cmd.sessionNoMatch`,{arg:e}));return}let a=n.app.getSession(i.id);if(!a){n.tui.info.showToast(N.t(`cmd.titlePin`),N.t(`cmd.pinNotLoaded`,{idShort:i.id.slice(0,8)}));return}zn(a,t,n)}function zn(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(N.t(`cmd.titleUnpin`),N.t(`cmd.unpinDone`,{idShort:r,title:i}));return}e.pin(t),n.tui.info.showToast(N.t(`cmd.titlePin`),N.t(`cmd.pinGroupDone`,{idShort:r,title:i,group:t}));return}e.pin(t),t===void 0?n.tui.info.showToast(N.t(`cmd.titlePin`),N.t(`cmd.pinDone`,{idShort:r,title:i})):n.tui.info.showToast(N.t(`cmd.titlePin`),N.t(`cmd.pinGroupDone`,{idShort:r,title:i,group:t}))}async function Bn(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=Ut({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 G(e,t){let n=e[0];if(n===`fork`){await Vn(e.slice(1),t);return}if(n===`kill`){await qn(e.slice(1),t);return}if(n===`pin`||n===`unpin`){await In(e.slice(1),t);return}if(n===`archive`||n===`unarchive`){await Fn(e.slice(1),t);return}if(n===`resume`){await Mn(e.slice(1),t);return}if(n===`compact`){await kn(e.slice(1),t);return}if(n===`context`){await Bn(e.slice(1),t);return}if(n===`inspect`){await Sn(e.slice(1),t);return}if(n===`clear`){await An(e.slice(1),t);return}if(n!==`unlock`){let n=e.join(` `).trim();if(!n){t.tui.info.showToast(N.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 Hn(n,t);return}let r=e.slice(1),i=r.includes(`--force`),a=r.find(e=>e!==`--force`);if(!a){t.tui.info.showToast(N.t(`cmd.titleSessionUnlock`),N.t(`cmd.unlockUsage`));return}let o=t.app.sessionManager.inspectSessionWriteLease(a),s=a.slice(0,8);if(!o.locked){t.tui.info.showToast(N.t(`cmd.titleSessionUnlock`),N.t(`cmd.unlockNotLocked`,{idShort:s}));return}let c=o.alive===!0?N.t(`cmd.unlockAliveConfirmed`):o.alive===!1?N.t(`cmd.unlockDeadConfirmed`):N.t(`cmd.unlockUnknownAlive`),l=Math.round((o.mtimeAgoMs??0)/1e3);if(!i){t.tui.messages.pushMessage({role:`command_echo`,command:`/session unlock`,summary:N.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:N.t(`cmd.unlockHungWarning`,{idShort:s})}),t.tui.modal.openModal({kind:`confirm`,title:N.t(`cmd.unlockConfirmTitle`),message:N.t(`cmd.unlockConfirmMessage`,{idShort:s,pid:o.pid,hostname:o.hostname}),confirmLabel:N.t(`cmd.unlockConfirmLabel`),cancelLabel:N.t(`cmd.unlockCancelLabel`),dangerous:!0,onConfirm:()=>{t.app.sessionManager.forceReleaseSessionWriteLease(a),t.tui.info.showToast(N.t(`cmd.titleSessionUnlock`),N.t(`cmd.unlockForcedDone`,{idShort:s}))},onCancel:()=>{t.tui.info.showToast(N.t(`cmd.titleSessionUnlock`),N.t(`cmd.unlockCancelled`))}});return}(o.mtimeAgoMs??0)<5e3&&t.tui.messages.pushMessage({role:`command_echo`,command:`/session unlock --force`,status:`warn`,summary:N.t(`cmd.unlockRecentReleaseHint`,{idShort:s})}),t.app.sessionManager.forceReleaseSessionWriteLease(a),t.tui.info.showToast(N.t(`cmd.titleSessionUnlock`),N.t(`cmd.unlockForcedDone`,{idShort:s}))}async function Vn(e,t){let n=t.state.session.id,r=await t.app.sessionManager.forkSession(n);if(!r){t.tui.info.showToast(N.t(`cmd.titleSessionFork`),N.t(`cmd.forkFailed`));return}let i=t.state.session;if(t.state.session.isBusy){let[e]=bn(U(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 U(i.id,i.session.messages(),!1);t.callbacks.sessionUnsub?.(),t.state.session=r,t.state.interactive=new F(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(R(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=B(r);t.tui.messages.pushMessages(o),t.callbacks.restoreSwitchedSession(),t.tui.info.setTopView({session:r.id}),t.tui.info.showToast(N.t(`cmd.titleSessionFork`),N.t(`cmd.forkSuccess`,{idShort:r.id.slice(0,8)}))}async function Hn(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]=bn(U(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 U(i.id,i.session.messages(),!1);t.callbacks.sessionUnsub?.(),t.state.session=r,t.state.interactive=new F(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(R(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=Ee(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(N.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 Un(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 Wn(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=k(o,`trace`),d=[];for(let e of l){let t=k(u,`${encodeURIComponent(e.id)}.jsonl`);try{let n=await st(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} | 预估回收: ${Gn(e)}`,i=[`会话 ID 大小 最后活跃 标题`,...d.map(e=>` ${e.session.id.slice(0,8)} ${Gn(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 ct(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 文件,回收 ${Gn(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 Gn(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 Kn(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??k(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 qn(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`,N.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){H(i.id),t.tui.info.showToast(`session kill`,`Removed stale session ${i.id.slice(0,8)} from background.`);return}a.abort(),H(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 Jn(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(N.t(`cmd.titleSessionFork`),N.t(`cmd.forkFailed`));return}let a=`${r} (fork)`,o=(await t.tui.modal.openModal({kind:`input`,title:N.t(`cmd.forkNameTitle`),placeholder:a,defaultValue:a})??``).trim()||a;i.renameSession(o);let s=t.state.session;if(t.state.session.isBusy){let[e]=bn(U(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 U(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 F(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(R(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=B(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(N.t(`cmd.titleSessionFork`),N.t(`cmd.forkSuccessNamed`,{title:o}))}function Yn(e){switch(e){case`global`:return N.t(`cmd.scopeGlobal`);case`repository`:return N.t(`cmd.scopeRepository`);default:return N.t(`cmd.scopeProject`)}}function Xn(e,t,n){return{workspaceDir:e.app.workspaceDir,workspaceRoot:t===`repository`?de(e.app.workspaceDir):void 0,global:t===`global`,dryRun:n}}async function Zn(e){let{name:t,type:n,scope:r,ctx:i,onDone:a}=e,o=i.app.settings.get(`mcp_servers`),s=await je(t,n,Xn(i,r,!0),()=>o,async()=>{});if(!s.success){i.tui.info.showToast(N.t(`cmd.titleUninstall`),N.t(`cmd.uninstallFailed`,{err:s.error??N.t(`cmd.unknownError`)})),a?.();return}let c=s.plan??[];i.tui.modal.openModal({kind:`confirm`,title:N.t(`cmd.uninstallConfirmTitle`,{type:n,name:t}),message:[N.t(`cmd.uninstallConfirmScope`,{scopeLabel:Yn(r)}),...c].join(`
|
|
8
|
+
`),confirmLabel:N.t(`cmd.uninstallConfirmYes`),dangerous:!0,onConfirm:()=>{Qn(e)},onCancel:()=>a?.()})}async function Qn(e){let{name:t,type:n,scope:r,ctx:i,onDone:a}=e,o=i.app.settings.get(`mcp_servers`),s=await je(t,n,Xn(i,r,!1),()=>o,async e=>{await i.app.settings.persist({mcp_servers:e})});if(!s.success){i.tui.info.showToast(N.t(`cmd.titleUninstall`),N.t(`cmd.uninstallFailed`,{err:s.error??N.t(`cmd.unknownError`)})),a?.();return}i.tui.info.showToast(N.t(`cmd.titleUninstall`),N.t(`cmd.uninstalled`,{type:n,name:t,scope:Yn(r)})),n===`plugin`&&await Se(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(N.t(`cmd.titleUninstall`),N.t(`cmd.uninstallRefreshed`))}catch(e){i.tui.messages.pushMessage({role:`command_echo`,command:`/extension`,status:`error`,summary:N.t(`cmd.uninstalledRefreshErr`,{err:e instanceof Error?e.message:String(e)})})}a?.()}async function $n(e,t){let n=t.app.settings.get(`keybinding_overrides`),r=()=>{t.tui.info.showToast(N.t(`cmd.keybindTitle`),N.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 er(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 tr(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 nr(e,t){tr(e,`model`,t)}function rr(e,t){tr(e,`effort`,t)}function ir(e,t){er(e,`retry.queued`,{attempt:t.attempt,max:t.max,...t.mode===void 0?{}:{mode:t.mode},...t.reason===void 0?{}:{reason:t.reason}})}function ar(e,t){er(e,`retry.cancelled`,{attempt:t.attempt})}function or(e){er(e,`retry.reset`,{})}function sr(e,t,n){er(e,`pause.${t}`,{...n===void 0?{}:{source:n}})}const cr=(e,t,n)=>{let r=L(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 lr(e,t){return[t,...e.filter(e=>e!==t)].slice(0,5)}function ur(e){let t=new RegExp(String.raw`\[@model:(${Ke}+)\]`,`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 dr(e,t){let n=ur(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 fr(e){let t=new RegExp(String.raw`\[@effort:(${Ke}+)\]`,`g`),n=[];return{text:e.replace(t,(e,t)=>(n.push(t.replace(/\\\]/g,`]`)),``)).replace(/\n{3,}/g,`
|
|
11
|
+
|
|
12
|
+
`).trim(),levels:n}}function pr(e,t){let n=fr(e),r=n.levels.at(-1);return r&&(K.includes(r)?r!==t.currentEffort&&t.applyEffort(r):t.onInvalidLevel?.(r)),n.text}function mr(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=lr(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),nr({tui:i.value??{messages:{pushMessage:()=>{}}},session:f,traceStore:o.storage.traceStore},{from:p,to:m.id,label:cr(m.id,m.contextWindow,f.thinkingLevel)})),m.api.includes(`:`)&&o.firePluginActivationEvent?.(`onProvider:${m.api}`),u?.({kind:`setModel`,modelId:e}),i.value?.stores.tasks.setModelName(cr(m.id,m.contextWindow,f.thinkingLevel)),i.value?.engine.pushEngineEvent({kind:`maxOutputTokens`,n:m.maxOutputTokens}),o.authStore?.getAuthSource?o.authStore.getAuthSource(m.provider).then(e=>{e!==`oauth`&&i.value?.stores.notification.setProviderUsage(null)}).catch(()=>{i.value?.stores.notification.setProviderUsage(null)}):i.value?.stores.notification.setProviderUsage(null),e!==p&&o.storage.memory?.reconfigure){o.storage.memory.reconfigure({contextWindow:m.contextWindow,maxOutput:m.maxOutputTokens});try{let e=f.session.buildContext(),t=await o.storage.memory.ensureFitsWindow?.(e.messages,f.id);if(t?.compacted&&t.summary&&t.replacement){f.session.recordCompaction(t.summary,t.replacement),u?.({kind:`recordCompaction`,summary:t.summary,replacement:t.replacement});let e=m.contextWindow>=1e6?`${(m.contextWindow/1e6).toFixed(1)}M`:`${Math.round(m.contextWindow/1e3)}k`;i.value?.info.showToast(N.t(`cmd.titleModel`),N.t(`cmd.modelCompactedFor`,{window:e}))}}catch(e){console.error(`\x1b[3m\x1b[2m[model-switch] compaction skipped: ${e instanceof Error?e.message:String(e)}\x1b[0m`)}}return r.value=m.contextWindow,a.value?.(),e!==p&&!d?.silent&&i.value?.info.showToast(N.t(`cmd.titleModel`),N.t(`model.switchedTo`,{label:l(e)})),`Model → ${e} (active next turn).`}return f.model&&(i.value?.stores.tasks.setModelName(cr(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 hr(e){let{getSession:t,app:n,tuiRef:r,options:i,fmtDisplayModel:a,applyModel:o}=e,s=!1,c=P(n.authStore,`delegation`),l=P(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?ht(m.provider)!==void 0:!0,_=m?ht(m.provider)?.env:void 0,v=m?!!n.authStore.oauth.get(m.provider):!1,y=m?g?h?.reason===`intranet-unreachable`?N.t(`model.reasonIntranetUnreachable`,{provider:m.provider}):N.t(`model.reasonUnauthenticated`,{provider:m.provider}):N.t(`model.reasonProviderNotLoaded`,{provider:m.provider}):N.t(`model.reasonNotFound`),b=_?N.t(`model.hintEnvKey`,{provider:m?.provider??``,env:_}):N.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:N.t(`model.title`),message:[`${a(p)} → ${a(x.id)}`,``,y,``,b],confirmLabel:N.t(`model.permanent`),extraLabel:v?N.t(`model.login`):N.t(`model.setKey`),cancelLabel:N.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(N.t(`model.login`),N.t(`model.fallbackLoginToast`,{provider:m?.provider??``})),s=!1,t(`abort`)},onCancel:()=>{e.onExitSession?.(),t(`abort`)}})}):(r.value.modal.openModal({kind:`info`,title:N.t(`model.title`),lines:[a(p),``,y,``,b,``,N.t(`model.noFallback`)],action:m?{kind:`login`,run:()=>e.onLogin?.(m.provider)}:void 0}),s=!1,`abort`):`proceed`}}function gr(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 _r(e){let t=e.trim().split(`
|
|
13
|
+
`)[0].replace(/\s+/g,` `).trim();return t.length>40?`${t.slice(0,39)}…`:t}function vr(e){e.pluginInput.unregisterBySource(`shortcut`);let t=(e.settings.get(`shortcuts`)??[]).map(e=>({label:`@${e.name}`,value:`[@shortcut:${e.name.replace(/]/g,`\\]`)}]`,description:_r(e.text),kind:`shortcut`,source:`shortcut`}));t.length&&e.pluginInput.register(t)}function yr(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 br={low:`cmd.effortDescLow`,medium:`cmd.effortDescMedium`,high:`cmd.effortDescHigh`,xhigh:`cmd.effortDescXhigh`,max:`cmd.effortDescMax`};function xr(e){let t=K.map(e=>({label:L(e),value:`[@effort:${e}]`,description:N.t(br[e]??`cmd.effortDescLow`),kind:`effort`,source:`builtin-effort`}));e.pluginInput.unregisterBySource(`builtin-effort`),e.pluginInput.register(t)}async function Sr(e,t){t.tui.modal.openModal({kind:`shortcutsPanel`,shortcuts:t.app.getShortcuts(),onSave:(e,n,r)=>{t.app.saveShortcut(e,n,r).then(()=>vr(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(()=>vr(t.app)).catch(e=>{t.tui.info.showToast(`Shortcuts`,`Delete failed: ${e instanceof Error?e.message:String(e)}`)})}})}const Cr={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 wr(e){let t=Math.round(e*8);return`━`.repeat(Math.max(0,t))+`╌`.repeat(Math.max(0,8-t))}async function Tr(e,t){let n=e[0]?.toLowerCase();if(n&&K.includes(n)){Er(t,n);return}if(n){t.tui.info.showToast(N.t(`cmd.titleEffort`),N.t(`cmd.effortUnknown`,{arg:n,levels:K.join(` / `)}));return}let r=t.state.session.thinkingLevel;t.tui.modal.openModal({kind:`select`,title:N.t(`cmd.selectEffortTitle`),options:K.map(e=>{let t=Cr[e],n=e===r,i=wr(t.intensity);return{label:t.label,value:e,detail:`${i} ${t.desc}${n?` · 当前`:``}`}}),onSelect:e=>Er(t,e),onCancel:()=>{}})}function Er(e,t){let n=e.state.session,r=n.thinkingLevel;n.applyThinkingLevel(t),e.app.settings.persist({thinking_level:t}),r!==t&&rr({tui:e.tui,session:n,traceStore:e.app.storage.traceStore},{from:r,to:t,label:L(t)}),n.model?.id&&e.tui.stores.tasks.setModelName(R(e.app,n.model.id,t)),e.tui.info.showToast(N.t(`cmd.titleEffort`),t)}async function Dr(e,t){let n=e[0]?.toLowerCase();if(n===`general`||n===`gen`){q(t);return}if(n===`lang`||n===`language`){zr(e.slice(1),t);return}if(n===`theme`){Br(e.slice(1),t);return}if(n===`keybindings`||n===`kb`){$n(e.slice(1),t);return}if(n===`shortcuts`){Sr(e.slice(1),t);return}if(n===`proxy`){l(e.slice(1),t);return}if(n){t.tui.info.showToast(N.t(`cmd.titlePreference`),N.t(`cmd.preferenceUsage`));return}Or(t)}function Or(e,t){let n=e.app.settings,r=n.get(`language`),i=r===`zh`?`中文 (zh)`:r===`en`?`English (en)`:`Auto`,a=e.state.themeRegistry??Je(),o=n.get(`theme_preset`)??{},s=a.get(o.dark??`dark`)?.label??o.dark??`dark`;e.tui.modal.openModal({kind:`select`,title:N.t(`cmd.titlePreference`),detailPlacement:`inline`,options:[{label:N.t(`cmd.prefOptionGeneral`),value:`general`,detail:N.t(`cmd.prefDescGeneral`)},{label:N.t(`cmd.prefOptionLang`),trailingLabel:i,value:`lang`,detail:N.t(`cmd.prefDescLang`)},{label:N.t(`cmd.prefOptionTheme`),trailingLabel:s,value:`theme`,detail:N.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`?zr([],e):t===`theme`?Br([],e):t===`keybindings`?$n([],e):t===`shortcuts`?Sr([],e):t===`proxy`&&l([],e)},onCancel:()=>{}})}let kr;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:M.toggleOn,off:M.toggleOff},p={on:N.t(`cmd.toggleOn`),off:N.t(`cmd.toggleOff`)},m=e=>Jt(e,f,p);e.tui.modal.openModal({kind:`select`,title:N.t(`cmd.selectGeneralTitle`),detailPlacement:`inline`,subtitle:t,replace:r,options:[{label:N.t(`cmd.genNickname`),trailingLabel:o||`—`,value:`nickname`,detail:N.t(`cmd.genNicknameDesc`)},{label:N.t(`cmd.genCompletionNotice`),trailingLabel:m(s),value:`completion`,detail:N.t(`cmd.genCompletionNoticeDesc`)},{label:N.t(`cmd.genSound`),trailingLabel:m(c),value:`sound`,detail:N.t(`cmd.genSoundDesc`)},{label:N.t(`cmd.genUpdateCheck`),trailingLabel:m(l),value:`updateCheck`,detail:N.t(`cmd.genUpdateCheckDesc`)},{label:N.t(`cmd.genSkillLoop`),trailingLabel:d?m(u):N.t(`cmd.genSkillLoopMissing`),value:`skillLoopPanel`,detail:N.t(`cmd.genSkillLoopEntryDesc`)}],defaultSelectedValue:n??kr,onHighlight:e=>{kr=e},onSelect:t=>{if(t===`nickname`){Ar(e);return}if(t===`skillLoopPanel`){J(e);return}Rr(e,t)},onCancel:()=>{Or(e,`general`)}})}async function Ar(e){let t=await e.tui.modal.openModal({kind:`input`,title:N.t(`cmd.genNicknameInputTitle`),placeholder:N.t(`cmd.genNicknamePlaceholder`)});if(t==null){q(e);return}let n=t.trim();await e.app.settings.persist({nickname:n}),q(e,N.t(`cmd.genSaved`))}const jr=[4,6,12,20];function Mr(e){let t=typeof e==`number`?e:6,n=jr.includes(t)?`genSkillLoopThr${t}`:``;return n?N.t(`cmd.${n}`):String(t)}function Nr(e){let t=e.app.settings,n=t.get(`skill_loop`)?.min_messages??6;e.tui.modal.openModal({kind:`select`,title:N.t(`cmd.genSkillLoopThresholdTitle`),detailPlacement:`inline`,options:jr.map(e=>({label:N.t(`cmd.genSkillLoopThr${e}`),value:String(e),detail:N.t(`cmd.genSkillLoopThr${e}Desc`),trailingLabel:e===n?M.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,N.t(`cmd.genSaved`),`threshold`)})()},onCancel:()=>{J(e,void 0,`threshold`)}})}const Pr=[3,14,30,365];function Fr(e){let t=typeof e==`number`?e:14;return Pr.includes(t)?N.t(`cmd.genSkillLoopCd${t}`):N.t(`cmd.genSkillLoopCdDays`,{n:t})}function Ir(e){let t=e.app.settings,n=t.get(`skill_loop`)?.dismiss_cooldown_days??14;e.tui.modal.openModal({kind:`select`,title:N.t(`cmd.genSkillLoopCooldownTitle`),detailPlacement:`inline`,options:Pr.map(e=>({label:N.t(`cmd.genSkillLoopCd${e}`),value:String(e),detail:N.t(`cmd.genSkillLoopCd${e}Desc`),trailingLabel:e===n?M.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,N.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:M.toggleOn,off:M.toggleOff},s={on:N.t(`cmd.toggleOn`),off:N.t(`cmd.toggleOff`)};if(!a){e.tui.modal.openModal({kind:`select`,title:N.t(`cmd.skillLoopPanelTitle`),detailPlacement:`inline`,subtitle:N.t(`cmd.genSkillLoopMissingHint`),options:[{label:N.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:N.t(`cmd.skillLoopPanelTitle`),detailPlacement:`inline`,subtitle:t,defaultSelectedValue:n,options:[{label:N.t(`cmd.skillLoopOnOff`),trailingLabel:Jt(i,o,s),value:`toggle`,detail:N.t(`cmd.genSkillLoopEntryDesc`)},...i?[{label:N.t(`cmd.genSkillLoopThreshold`),trailingLabel:Mr(r.get(`skill_loop`)?.min_messages),value:`threshold`,detail:N.t(`cmd.genSkillLoopThresholdDesc`)},{label:N.t(`cmd.genSkillLoopCooldown`),trailingLabel:Fr(r.get(`skill_loop`)?.dismiss_cooldown_days),value:`cooldown`,detail:N.t(`cmd.genSkillLoopCooldownDesc`)},{label:N.t(`cmd.genSkillLoopStatus`),value:`status`,detail:N.t(`cmd.genSkillLoopStatusDesc`)}]:[]],onSelect:t=>{if(t===`threshold`){Nr(e);return}if(t===`cooldown`){Ir(e);return}if(t===`status`){Lr(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?N.t(`cmd.genSkillLoopOn`):N.t(`cmd.genSkillLoopOff`),`toggle`)})()},onCancel:()=>{q(e,void 0,`skillLoopPanel`)}})}function Lr(e){let t=e.app.settings,n=e.app.activePlugins().some(e=>e.id===w),r=be({workspaceKey:e.app.workspaceRef?.key??C,now:Date.now(),cooldownDays:t.get(`skill_loop`)?.dismiss_cooldown_days,pluginInstalled:n}),i=e=>N.t(`cmd.skillLoopStatusCount`,{n:e}),a=[];if(!n)a.push({label:N.t(`cmd.skillLoopStatusNotInstalled`),value:`noop`,detail:N.t(`cmd.genSkillLoopMissingHint`)});else{a.push({label:N.t(`cmd.skillLoopStatusEpisodes`),trailingLabel:i(r.episodeCount),value:`noop`,detail:N.t(`cmd.skillLoopStatusSuccess`)+` `+i(r.successCount)},{label:N.t(`cmd.skillLoopStatusPending`),trailingLabel:i(r.pendingCount),value:`noop`,detail:i(r.candidateCount)+` `+N.t(`cmd.skillLoopStatusCandidates`)+` · `+i(r.coolingCount)+` `+N.t(`cmd.skillLoopStatusCooling`)});for(let e of r.pending)a.push({label:e.taskSignature,trailingLabel:N.t(`cmd.skillLoopStatusTimes`,{n:e.size}),value:`noop`,detail:N.t(`cmd.skillLoopStatusGroupPending`)});for(let e of r.recentSignatures)a.push({label:e,value:`noop`,detail:N.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:N.t(`cmd.skillLoopStatusTitle`),detailPlacement:`inline`,subtitle:o?N.t(o):void 0,options:a,onSelect:()=>{J(e,void 0,`status`)},onCancel:()=>{J(e,void 0,`status`)}})}async function Rr(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,N.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,N.t(`cmd.genSaved`),t,!0)}function zr(e,t){let n=e[0]?.toLowerCase();if(n===`en`||n===`zh`||n===`auto`){Ur(t,n);return}if(n){t.tui.info.showToast(N.t(`cmd.titlePreference`),N.t(`pref.languageUsage`));return}t.tui.modal.openModal({kind:`select`,title:N.t(`cmd.selectLanguageTitle`),detailPlacement:`inline`,options:[{label:`中文 (zh)`,value:`zh`,detail:N.t(`cmd.langDescZh`)},{label:`English (en)`,value:`en`,detail:N.t(`cmd.langDescEn`)},{label:`Auto`,value:`auto`,detail:N.t(`cmd.langDescAuto`)}],onSelect:e=>Ur(t,e),onCancel:()=>{Or(t,`lang`)}})}function Br(e,t){Vr(t)}function Vr(e){let t=e.state.themeRegistry??Je(),n=e.app.settings.get(`theme_preset`)??{},r=t.get(n.dark??`dark`)??t.get(`dark`),i=t.get(n.light??`light`)??t.get(`light`);e.tui.modal.openModal({kind:`select`,title:N.t(`cmd.prefOptionTheme`),detailPlacement:`inline`,options:[{label:N.t(`cmd.themeDarkPresetOption`),value:`preset-dark`,detail:N.t(`cmd.themeDarkPresetDesc`),trailingLabel:r?.label},{label:N.t(`cmd.themeLightPresetOption`),value:`preset-light`,detail:N.t(`cmd.themeLightPresetDesc`),trailingLabel:i?.label}],onSelect:t=>{if(t===`preset-dark`){Hr(e,`dark`);return}if(t===`preset-light`){Hr(e,`light`);return}},onCancel:()=>{Or(e,`theme`)}})}function Hr(e,t){let n=e.state.themeRegistry??Je(),r=e.app.settings.get(`theme_preset`)??{},i=r[t]??t,a=[...n.list().filter(e=>e.appearance===t).map(e=>({label:e.label,value:e.id,detail:e.source.kind===`builtin`?N.t(`cmd.themePresetBuiltin`):N.t(`cmd.themePresetFromExtension`,{id:e.source.extensionId}),trailingLabel:e.id===i?`✓`:void 0})),{label:N.t(`cmd.themePresetReset`),value:`__reset__`,detail:N.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`?N.t(`cmd.themePresetTitleDark`):N.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(N.t(`cmd.titlePreference`),N.t(`cmd.themePresetSaved`,{label:s??a??t}))},onCancel:()=>{s(),e.tui.info.showToast(N.t(`cmd.titlePreference`),N.t(`cmd.selectCancelled`))}})}function Ur(e,t){e.state.currentLang=e.tui.lifecycle.setLanguage(t),kt(t),e.tui.plugins.setCommands(e.callbacks.refreshSlashCommands()),e.app.settings.persist({language:t}),e.tui.info.showToast(N.t(`cmd.titleLanguage`),N.t(`pref.languageSwitched`,{l:e.state.currentLang,name:e.state.currentLang===`zh`?`中文`:`English`}))}async function Wr(e,t){let r=t.app.workspaceDir??process.cwd(),i=e[0]?.toLowerCase()??`status`;if(i===`plugin`){let i=e[1]?.toLowerCase()===`untrust`,a=i?e[2]:e[1];if(!a){t.tui.info.showToast(N.t(`cmd.titlePlugin`),N.t(`cmd.pluginUsage`,{seg:(i?`untrust`:`trust`)==`untrust`?`untrust `:``}));return}let o=n({cwd:r,homedir:g()}).find(e=>e.id===a);if(!o){t.tui.info.showToast(N.t(`cmd.titlePlugin`),N.t(`cmd.pluginNotFound`,{id:a}));return}if(i){try{Me(o.dir)}catch(e){t.tui.info.showToast(N.t(`cmd.titlePlugin`),`撤销信任失败,权限未收回:${e instanceof Error?e.message:String(e)}`);return}t.tui.info.showToast(N.t(`cmd.titlePlugin`),N.t(`cmd.pluginUntrusted`,{id:a}))}else ci(t,o);return}if(i===`trust`){Ae(r),t.tui.info.showToast(N.t(`cmd.titleCompat`),N.t(`cmd.compatTrusting`)),t.app.reloadCapabilities().then(e=>{t.tui.plugins.setPluginRegistrations(t.app.getPluginRegistrations()),t.tui.info.showToast(N.t(`cmd.titleCompat`),N.t(`cmd.compatTrusted`,{count:e.mcpTools}))},e=>t.tui.info.showToast(N.t(`cmd.titleCompat`),N.t(`cmd.compatReloadFailed`,{err:e instanceof Error?e.message:String(e)})));return}if(i===`untrust`){Ne(r),t.tui.info.showToast(N.t(`cmd.titleCompat`),N.t(`cmd.compatUntrusted`));return}let a=ue(r),o=oe(r,{interactive:!0}),s=[];if(a.surface.any){let e=[a.surface.mcpJson?`.mcp.json`:null,a.surface.commands?`.claude/commands`:null].filter(Boolean),t=a.trusted?N.t(`cmd.compatTrustedLabel`):N.t(`cmd.compatUntrustedLabel`);s.push(`${e.join(N.t(`cmd.listSep`))} ${t}`)}if(o.highRiskKeys.length>0){let e=o.highRiskKeys.join(N.t(`cmd.listSep`));s.push(o.gated?N.t(`cmd.compatConfigGated`,{keys:e}):N.t(`cmd.compatConfigActive`,{keys:e}))}let c=n({cwd:r,homedir:g()}).filter(e=>e.scope===`project`||e.scope===`repository`);for(let e of c){let t=E(e);if(!t.surface.any)continue;let n=t.gated?N.t(`cmd.compatUntrustedLabel`):N.t(`cmd.compatTrustedLabel`);s.push(`plugin:${e.id} ${n}${t.gated?` → /trust plugin ${e.id}`:``}`)}if(s.length===0){t.tui.info.showToast(N.t(`cmd.titleCompat`),N.t(`cmd.compatNone`));return}o.gated?t.tui.modal.openModal({kind:`info`,title:N.t(`cmd.titleCompat`),lines:s}):t.tui.info.showToast(N.t(`cmd.titleCompat`),s.join(`
|
|
14
|
+
`))}async function Gr(e,t){let n=e[0];if(n===`clear`){t.app.clearSessionAlwaysAllow(t.state.session.id),t.tui.info.showToast(N.t(`cmd.titlePermissions`),N.t(`cmd.permsCleared`));return}if(n===`add`||n===`remove`){let r=e.slice(1).join(` `).trim();if(!r){t.tui.info.showToast(N.t(`cmd.titlePermissions`),N.t(`cmd.permsManageHint`));return}if(n===`add`){if(!t.app.isWellFormedAllowEntry(r)){t.tui.info.showToast(N.t(`cmd.titlePermissions`),N.t(`cmd.permsInvalidEntry`,{entry:r}));return}await t.app.allowToolAlways(r),t.tui.info.showToast(N.t(`cmd.titlePermissions`),N.t(`cmd.permsAdded`,{entry:r}))}else{let e=await t.app.disallowToolAlways(r);t.tui.info.showToast(N.t(`cmd.titlePermissions`),e?N.t(`cmd.permsRemoved`,{entry:r}):N.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(`, `):N.t(`cmd.permsEmpty`)}`;t.tui.modal.openModal({kind:`permissions`,lines:[a(N.t(`cmd.permsSessionLabel`),r),a(N.t(`cmd.permsProjectLabel`),i),``,...Kr(t),N.t(`cmd.permsClearHint`),N.t(`cmd.permsManageHint`)]})}function Kr(e){let t=e.app.getRecentPermissionDecisions?.(e.state.session.id,8)??[];if(t.length===0)return[`${N.t(`cmd.permsRecentLabel`)} ${N.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[N.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 qr(e,n){let r=t();n.tui.info.showToast(N.t(`cmd.titleUpgrade`),N.t(`cmd.upgradeChecking`,{current:r}));let i=await jt(r);if(!i){n.tui.modal.openModal({kind:`info`,title:N.t(`cmd.titleUpgrade`),lines:[N.t(`cmd.upgradeNoNetwork`)]});return}if(!i.newer){n.tui.info.showToast(N.t(`cmd.titleUpgrade`),N.t(`cmd.upgradeLatest`,{current:r}));return}n.tui.modal.openModal({kind:`select`,title:N.t(`cmd.titleUpgrade`),subtitle:N.t(`cmd.upgradeConfirmSubtitle`,{current:r,latest:i.latest}),subtitleTone:`warning`,layout:`buttons`,options:[{label:N.t(`common.upgradeButton`),value:`upgrade`,color:`accent`},{label:N.t(`common.cancelButton`),value:`cancel`,color:`amber`}],onSelect:e=>{e===`upgrade`&&Jr(n,i.latest)}})}async function Jr(e,t){e.tui.info.showToast(N.t(`cmd.titleUpgrade`),N.t(`cmd.upgrading`));let{ok:n,error:r}=await Ft(t);if(!n){e.tui.info.showToast(N.t(`cmd.titleUpgrade`),N.t(`cmd.upgradeFailed`,{err:r??N.t(`cmd.unknownError`)}));return}e.state.restartRequested=!0,e.tui.lifecycle.stop()}async function Yr(e,n){if(!e.includes(`--force`))return!1;let r=await jt(t());return r?r.newer?(await Jr(n,r.latest),!0):(n.tui.info.showToast(N.t(`cmd.titleUpgrade`),N.t(`cmd.upgradeLatest`,{current:t()})),!0):(n.tui.info.showToast(N.t(`cmd.titleUpgrade`),N.t(`cmd.upgradeNoNetwork`)),!0)}async function Xr(e,t,n){let r=N.t(`cmdDesc`,{returnObjects:!0}),i={session:N.t(`cmd.helpGroupSession`),model:N.t(`cmd.helpGroupModel`),agent:N.t(`cmd.helpGroupAgent`),debug:N.t(`cmd.helpGroupDebug`),ui:N.t(`cmd.helpGroupUi`),other:N.t(`cmd.helpGroupOther`)},a=[];for(let e of ja){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=`${N.t(`cmd.helpPrefixes`)} !<cmd> ${N.t(`cmd.helpPrefixShell`)} · @<file> ${N.t(`cmd.helpPrefixFile`)}`;t.tui.modal.openModal({kind:`select`,title:N.t(`cmd.titleCommands`),subtitle:o,searchable:!0,options:a,onSelect:e=>{La(e,[],t)},onCancel:()=>{}})}async function Zr(e,t){t.tui.panes.togglePane(`history`)}async function Qr(e,t){t.tui.panes.togglePane(`notifications`)}async function $r(e,t){t.tui.panes.togglePane(`prompts`)}async function ei(e,t){t.tui.panes.setServices(!0)}async function ti(e,t){t.tui.info.showToast(N.t(`cmd.titleUpgrade`),N.t(`cmd.upgradeCheckScanning`));try{let e=Oe({workspaceDir:t.app.workspaceDir,workspaceRoot:de(t.app.workspaceDir),scope:`all`});if(e.length===0){t.tui.info.showToast(N.t(`cmd.titleUpgrade`),N.t(`cmd.upgradeCheckNoVersioned`));return}let n=await T(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(N.t(`cmd.upgradeCheckLineUpdate`,{tag:t,name:e.name,installed:e.installed,latest:e.latest??``}))):r.push(N.t(`cmd.upgradeCheckLineLatest`,{tag:t,name:e.name,installed:e.installed}))}i>0&&(r.push(``),r.push(N.t(`cmd.upgradeCheckSummary`,{count:i}))),t.tui.modal.openModal({kind:`info`,title:N.t(`cmd.titleUpgradeCheck`),lines:r})}catch(e){t.tui.info.showToast(N.t(`cmd.titleUpgrade`),N.t(`cmd.upgradeCheckFailed`,{err:e instanceof Error?e.message:String(e)}))}}var ni=bt({confirmHighRiskCapabilities:()=>li,formatPluginContributionsSummary:()=>oi,handleDelegatesToggle:()=>di,handleExtension:()=>Y,handleJobStart:()=>fi,pluginCapabilityLabel:()=>si,promptPluginTrust:()=>ci,runPluginInstall:()=>ui});function ri(e){return!e.endsWith(k(`.claude`,`skills`))}function ii(e,t){return ri(t)?e===`project`?`project`:e===`global`?`global`:null:null}function ai(e,t){let n={project:`project`,global:`global`,plugin:`plugin`,inline:`inline`}[e]??e;return t?`${n} (${t})`:n}function oi(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 si(e){switch(e){case`provider`:return N.t(`cmd.pluginCapabilityProvider`);case`tools`:return N.t(`cmd.pluginCapabilityTools`);case`tui.renderer`:return N.t(`cmd.pluginCapabilityTuiRenderer`);case`network`:return N.t(`cmd.pluginCapabilityNetwork`);case`wire-protocol`:return N.t(`cmd.pluginCapabilityWireProtocol`);case`a2ui.component`:return N.t(`cmd.pluginCapabilityA2uiComponent`);case`panel.backend`:return N.t(`cmd.pluginCapabilityPanelBackend`);case`input.resolver`:return N.t(`cmd.pluginCapabilityInputResolver`);case`a2ui.renderer`:return N.t(`cmd.pluginCapabilityA2uiRenderer`);default:return}}function ci(e,t){let n=E(t),r=n.pendingCapabilities,i=()=>{if(ke(t.dir),r.length>0){let n=t.manifest.version;n?pe(t.dir,r,n):(e.tui.info.showToast(N.t(`cmd.titlePlugin`),`插件 "${t.id}" manifest 无版本字段——授权不绑定版本,后续更新后需重新信任`),fe(t.dir,r))}e.tui.info.showToast(N.t(`cmd.titlePlugin`),N.t(`cmd.pluginTrusting`,{id:t.id})),e.app.reloadCapabilities().then(n=>{e.tui.plugins.setPluginRegistrations(e.app.getPluginRegistrations()),e.tui.info.showToast(N.t(`cmd.titlePlugin`),N.t(`cmd.pluginTrusted`,{id:t.id,count:n.mcpTools}))},t=>e.tui.info.showToast(N.t(`cmd.titlePlugin`),N.t(`cmd.compatReloadFailed`,{err:t instanceof Error?t.message:String(t)})))},a=n.surface;if(!a.any&&r.length===0){i();return}let o=[N.t(`cmd.pluginTrustConfirmIntro`)];if(a.mcpJson&&o.push(`• ${N.t(`cmd.pluginSurfaceMcp`)}`),a.commands&&o.push(`• ${N.t(`cmd.pluginSurfaceCommands`)}`),a.scripts&&o.push(`• ${N.t(`cmd.pluginSurfaceScripts`)}`),a.panels&&o.push(`• ${N.t(`cmd.pluginSurfacePanels`)}`),a.skills&&o.push(`• ${N.t(`cmd.pluginSurfaceSkills`)}`),a.agents&&o.push(`• ${N.t(`cmd.pluginSurfaceAgents`)}`),r.length>0){o.push(``,N.t(`cmd.pluginCapabilityIntro`));for(let e of r){let t=si(e);t&&o.push(`• ${t}`)}}o.push(``,N.t(`cmd.pluginTrustConfirmHint`)),e.tui.modal.openModal({kind:`select`,title:N.t(`cmd.pluginTrustConfirmTitle`,{id:t.id}),subtitle:o.join(`
|
|
15
|
+
`),layout:`buttons`,options:[{label:N.t(`cmd.pluginTrustConfirmAction`),value:`trust`,color:`accent`},{label:N.t(`cmd.commonCancel`),value:`cancel`,color:`gray`}],onSelect:e=>{e===`trust`&&i()},onCancel:()=>{}})}async function li(e,t,n){if(t.length===0)return!0;let r=[N.t(`cmd.pluginCapabilityIntro`)];for(let e of t){let t=si(e);t&&r.push(`• ${t}`)}return new Promise(t=>{n.tui.modal.openModal({kind:`select`,title:N.t(`cmd.pluginInstallConfirmTitle`,{name:e}),subtitle:r.join(`
|
|
16
|
+
`),layout:`buttons`,options:[{label:N.t(`cmd.pluginInstallConfirmAction`),value:`install`,color:`accent`},{label:N.t(`cmd.commonCancel`),value:`cancel`,color:`gray`}],onSelect:e=>t(e===`install`),onCancel:()=>t(!1)})})}async function ui(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(N.t(`cmd.titleInstall`),N.t(`cmd.pluginInstallInvalidName`,{name:e})),!1;let s=o[e]?.pkg??e,c=Te(s),l;if(!c)try{i?.(`Downloading from npm registry`);let e=await me(s,{global:!0,as:`plugin`,postInstallExecutor:ae});e.success&&e.targetPath?(c=e.targetPath,l={id:e.name??s,dir:e.targetPath,created:!0,compileWarnings:[],version:e.manifest?.version}):r||t.tui.info.showToast(N.t(`cmd.titleInstall`),N.t(`cmd.pluginInstallFailed`,{err:e.error??`未知错误`}))}catch(e){r||t.tui.info.showToast(N.t(`cmd.titleInstall`),N.t(`cmd.pluginInstallFailed`,{err:e instanceof Error?e.message:String(e)}))}if(!c)return r||t.tui.info.showToast(N.t(`cmd.titleInstall`),N.t(`cmd.pluginInstallNotFound`,{pkg:s})),!1;let u=ve(c);if(!r&&!await li(e,u,t))return t.tui.info.showToast(N.t(`cmd.titleInstall`),N.t(`cmd.pluginInstallCancelled`)),!1;let d;if(l)d=l;else try{i?.(`Installing plugin`),d=await he({pkg:s})}catch(e){return r||t.tui.info.showToast(N.t(`cmd.titleInstall`),N.t(`cmd.pluginInstallFailed`,{err:e instanceof Error?e.message:String(e)})),!1}r||t.tui.info.showToast(N.t(`cmd.titleInstall`),N.t(`cmd.pluginInstalled`,{seg:d.created?`Installed ${d.id}`:`${d.id} already up to date`})),await xe(t.app.settings,{id:d.id,source:`npm`,sourceSpec:s,version:d.version,scope:`global`,capabilities:u}),t.app.pluginModuleManager.emitMonitorEvent({type:`plugin.installed`,pluginId:d.id});for(let e of d.compileWarnings)r||t.tui.info.showToast(N.t(`cmd.titleInstall`),N.t(`cmd.pluginInstallFailed`,{err:e}));u.length>0&&(i?.(`Authorizing capabilities`),ke(d.dir),d.version?pe(d.dir,u,d.version):fe(d.dir,u));try{i?.(`Reloading capabilities`),(await t.app.reloadCapabilities()).pendingProviderCapabilities.includes(d.id)&&(r||t.tui.info.showToast(N.t(`cmd.titleInstall`),N.t(`cmd.pluginInstallPendingCaps`,{id:d.id})),a?.(d.id))}catch(e){r||t.tui.info.showToast(N.t(`cmd.titleInstall`),N.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(()=>pi);await e([],t)}return!0}async function di(e,t){t.tui.panes.togglePane(`backgroundTasks`)}async function fi(e,t){let n=e.join(` `);if(!n){t.tui.info.showToast(N.t(`cmd.titleJob`),N.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(N.t(`cmd.titleReverted`),N.t(`cmd.jobReverted`,{id:e,msg:n.message}));else{let r=n.conflictPaths.length?N.t(`cmd.jobConflictFiles`,{joinedPaths:n.conflictPaths.join(`
|
|
17
|
+
`)}):``;t.tui.messages.pushMessage({role:`command_echo`,command:`/go revert ${e}`,status:`error`,summary:N.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(N.t(`cmd.titleDelegated`),N.t(`cmd.delegated`,{title:e.title}))}catch(e){t.tui.messages.pushMessage({role:`command_echo`,command:`/go`,status:`error`,summary:N.t(`cmd.delegateFailed`,{err:e instanceof Error?e.message:String(e)})})}}async function Y(e,t){let r=e[0]?.toLowerCase();if(r===`trust`)return Wr(e.slice(1),t);if(r===`install`)return u(e.slice(1),t);if(r===`registry`)return c(e.slice(1),t);if(r===`search`)return s(e.slice(1),t);if(r===`update`)return ti([`--check`],t);if(r===`reload`)return Nn(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__`){l();return}if(e.startsWith(`contrib:`)){let n=e.slice(8),a=r.get(n);if(!a)return;le(a,{open:e=>ge(e),runCommand:async(e,n)=>{let{dispatchSlashCommand:r}=await Promise.resolve().then(()=>Aa);await r(e,n?n.split(/\s+/).filter(Boolean):[],t)}}).catch(e=>i(N.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:()=>{}})},l=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(N.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(()=>Aa);await e(`extension`,[`install`,...a],t)})().catch(e=>i(N.t(`cmd.titlePlugin`),e instanceof Error?e.message:String(e)))},onCancel:()=>o()})},d=e=>{let n=t.app.skillRegistry?.get(e);if(!n){o();return}let r=n.status!==`disabled`,s=n.definition.metadata,c=[{kind:`group`,title:N.t(`cmd.extSkillGroupOverview`)},{kind:`row`,label:N.t(`cmd.extSkillLabelDesc`),value:s.description||`—`},{kind:`row`,label:N.t(`cmd.extSkillLabelStatus`),value:n.status,tone:n.status===`error`||n.status===`disabled`?`error`:`success`},{kind:`row`,label:N.t(`cmd.extSkillLabelSource`),value:N.t(`cmd.extSkillSourceLabel`,{seg:ai(n.source.type,n.source.id)}),tone:`muted`},...ri(n.source.root)?[]:[{kind:`text`,value:N.t(`cmd.extSkillManagedExternally`,{root:n.source.root}),tone:`muted`}],{kind:`group`,title:N.t(`cmd.extSkillGroupTrigger`)},{kind:`row`,label:N.t(`cmd.extSkillLabelTriggerMode`),value:s.trigger===`manual`?N.t(`cmd.extSkillTriggerManual`):N.t(`cmd.extSkillTriggerAuto`)},...s.priority===void 0?[]:[{kind:`row`,label:N.t(`cmd.extSkillLabelPriority`),value:String(s.priority)}],{kind:`group`,title:N.t(`cmd.extSkillGroupDependencies`)},{kind:`row`,label:N.t(`cmd.extSkillLabelDependencies`),value:s.dependencies?.length?s.dependencies.join(`, `):N.t(`cmd.extSkillNoDependencies`),tone:s.dependencies?.length?void 0:`muted`},{kind:`group`,title:N.t(`cmd.extSkillGroupTags`)},{kind:`row`,label:N.t(`cmd.extSkillLabelTags`),value:s.tags?.length?s.tags.join(`, `):N.t(`cmd.extSkillNoTags`),tone:s.tags?.length?void 0:`muted`}];n.status===`error`&&n.error&&c.push({kind:`group`,title:N.t(`cmd.extSkillGroupError`)},{kind:`text`,value:n.error,tone:`error`}),t.tui.modal.openModal({kind:`extensionDetail`,title:N.t(`cmd.extSkillTitle`,{name:e,state:r?`enabled`:`disabled`}),meta:`skill · ${n.source.type}`,metaStatus:{label:r?N.t(`cmd.extEnableLabel`):N.t(`cmd.extDisableLabel`),enabled:r},actions:[{label:r?N.t(`cmd.extDisableLabel`):N.t(`cmd.extEnableLabel`),value:`toggle`,color:r?`amber`:`green`},{label:N.t(`cmd.extViewFullTextLabel`),value:`view-full-text`,color:`gray`},...ii(n.source.type,n.source.root)?[{label:N.t(`cmd.uninstallActionLabel`),value:`uninstall`,color:`red`}]:[]],dataListEntries:c,fullText:{title:N.t(`cmd.extSkillFullTextTitle`,{name:e}),content:n.definition.body||N.t(`cmd.extSkillNoBody`)},onAction:async s=>{if(s===`toggle`){try{await t.app.extensions.setEnabled(`skill`,e,!r),i(N.t(`cmd.titleExtension`),N.t(`cmd.extToggled`,{name:e,verb:r?`Disabled`:`Enabled`,seg:` — applies next turn`}))}catch(e){a(N.t(`cmd.extToggleFailed`,{err:e instanceof Error?e.message:String(e)}))}d(e);return}if(s===`uninstall`){let r=ii(n.source.type,n.source.root);if(!r)return;await Zn({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:N.t(`cmd.extAgentGroupOverview`)},{kind:`row`,label:N.t(`cmd.extAgentLabelDesc`),value:n.description||`—`},{kind:`row`,label:N.t(`cmd.extAgentLabelStatus`),value:r?N.t(`cmd.extEnableLabel`):N.t(`cmd.extDisableLabel`),tone:r?`success`:`error`},{kind:`group`,title:N.t(`cmd.extAgentGroupCapabilities`)},{kind:`row`,label:N.t(`cmd.extAgentLabelTaskTypes`),value:n.taskTypes.length?n.taskTypes.join(`, `):N.t(`cmd.extAgentNoTaskTypes`),tone:n.taskTypes.length?void 0:`muted`},{kind:`row`,label:N.t(`cmd.extAgentLabelCapabilities`),value:n.capabilities.length?n.capabilities.join(`, `):N.t(`cmd.extAgentNoCapabilities`),tone:n.capabilities.length?void 0:`muted`},{kind:`group`,title:N.t(`cmd.extAgentGroupTools`)},{kind:`row`,label:N.t(`cmd.extAgentLabelDefaultTools`),value:n.defaultTools?.length?n.defaultTools.join(`, `):N.t(`cmd.extAgentAllTools`),tone:n.defaultTools?.length?void 0:`muted`},{kind:`row`,label:N.t(`cmd.extAgentLabelDisallowedTools`),value:n.disallowedTools?.length?n.disallowedTools.join(`, `):N.t(`cmd.extAgentNoDisallowedTools`),tone:n.disallowedTools?.length?void 0:`muted`},{kind:`group`,title:N.t(`cmd.extAgentGroupExecution`)},{kind:`row`,label:N.t(`cmd.extAgentLabelPromptMode`),value:n.promptMode??`append`,tone:`muted`},...n.preferredModelTier?[{kind:`row`,label:N.t(`cmd.extAgentLabelModelTier`),value:n.preferredModelTier}]:[],{kind:`row`,label:N.t(`cmd.extAgentLabelAllowSubagents`),value:n.allowSubagents?N.t(`cmd.extEnableLabel`):N.t(`cmd.extDisableLabel`),tone:n.allowSubagents?void 0:`muted`}];t.tui.modal.openModal({kind:`extensionDetail`,title:N.t(`cmd.extAgentTitle`,{name:e,state:r?`enabled`:`disabled`}),meta:`agent`,metaStatus:{label:r?N.t(`cmd.extEnableLabel`):N.t(`cmd.extDisableLabel`),enabled:r},actions:[{label:r?N.t(`cmd.extDisableLabel`):N.t(`cmd.extEnableLabel`),value:`toggle`,color:r?`amber`:`green`},{label:N.t(`cmd.extViewFullTextLabel`),value:`view-full-text`,color:`gray`}],dataListEntries:s,fullText:{title:N.t(`cmd.extAgentFullTextTitle`,{name:e}),content:n.systemPromptTemplate||N.t(`cmd.extSkillNoBody`)},onAction:async n=>{if(n===`toggle`){try{await t.app.extensions.setEnabled(`agent`,e,!r),i(N.t(`cmd.titleExtension`),N.t(`cmd.extToggled`,{name:e,verb:r?`Disabled`:`Enabled`,seg:` — applies next turn`}))}catch(e){a(N.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?N.t(`cmd.extDisableLabel`):N.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:N.t(`cmd.extMcpTitle`,{name:r.name,status:l}),options:[{label:N.t(`cmd.extReconnectLabel`),value:`reconnect`},s,...r.readonly?[]:[{label:N.t(`cmd.uninstallActionLabel`),value:`uninstall`}]],onSelect:async s=>{if(s===`toggle`){try{await t.app.extensions.setEnabled(r.category,n,!r.enabled),i(N.t(`cmd.titleExtension`),N.t(`cmd.extToggled`,{name:r.name,verb:r.enabled?`Disabled`:`Enabled`,seg:``}))}catch(e){a(N.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(N.t(`cmd.titleExtension`),N.t(`cmd.extReconnectUnavailable`,{id:n})),p(e,n);return}try{await r.disconnect(n).catch(()=>{}),await r.connect(n,o),i(N.t(`cmd.titleExtension`),N.t(`cmd.extReconnected`,{id:n}))}catch(e){a(N.t(`cmd.extReconnectFailed`,{id:n,err:e instanceof Error?e.message:String(e)}))}p(e,n);return}if(s===`uninstall`){await Zn({name:n,type:`mcp`,scope:`project`,ctx:t,onDone:()=>o()});return}},onCancel:()=>o()})}else e===`plugin`?m(n,r.enabled,r.name,r.description):e===`skill`?d(n):e===`agent`?f(n):t.tui.modal.openModal({kind:`select`,title:N.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(N.t(`cmd.titleExtension`),N.t(`cmd.extToggled`,{name:r.name,verb:r.enabled?`Disabled`:`Enabled`,seg:r.applies===`live`?``:` — applies next turn`}))}catch(e){a(N.t(`cmd.extToggleFailed`,{err:e instanceof Error?e.message:String(e)}))}p(e,n);return}},onCancel:()=>o()})},m=(e,r,s,c,l)=>{let u=t.app.workspaceDir??process.cwd(),d=n({cwd:u,homedir:g()}).find(t=>t.id===e);if(!d){o();return}let f=E(d),p=f.surface.any?f.gated?N.t(`cmd.extPluginUntrusted`):f.pendingCapabilities.length>0?N.t(`cmd.extPluginCapabilityPending`,{caps:f.pendingCapabilities.join(`, `)}):N.t(`cmd.extPluginTrusted`):N.t(`cmd.extPluginNoSurface`),h=f.surface,_=[[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=_.length?` ${_.join(`, `)}`:` —`,y=(t.app.getPluginPanelRegistrations?.()??[]).filter(t=>t.pluginId===e),b=oi({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:r?N.t(`cmd.extDisableLabel`):N.t(`cmd.extEnableLabel`),value:`toggle`,color:r?`amber`:`green`}];if(f.surface.any&&(d.scope===`project`||d.scope===`repository`||f.pendingCapabilities.length>0)){let e=d.scope===`project`||d.scope===`repository`?!f.trusted:f.pendingCapabilities.length>0;x.push({label:e?N.t(`cmd.extPluginTrustLabel`):N.t(`cmd.extPluginUntrustLabel`),value:e?`trust`:`untrust`,color:e?`accent`:`gray`})}x.push({label:N.t(`cmd.extReloadLabel`),value:`reload`}),d.scope!==`builtin`&&x.push({label:N.t(`cmd.uninstallActionLabel`),value:`uninstall`,color:`red`});let ee=re(d,{"extension.id":e,"extension.enabled":r,"extension.trusted":f.trusted,"extension.scope":d.scope,"extension.category":`plugin`}),S=d.manifest.contributes,C=we(ne.extensionDetailActions,S?.menus,S?.actions,ee),w=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 te={open:e=>ge(e),runCommand:async(e,n)=>{let{dispatchSlashCommand:r}=await Promise.resolve().then(()=>Aa);await r(e,n?n.split(/\s+/).filter(Boolean):[],t)},runScript:async e=>{if(E(d).gated){i(N.t(`cmd.titlePlugin`),N.t(`cmd.extPluginUntrusted`));return}await De(d,e)}},T=y[0];T&&t.app.firePluginActivationEvent?.(`onView:${T.id}`);let ie;if(e===`plugin-feishu-use`){let e=k(u,`.otto`,`feishu-use.json`),t=!1;try{if(A(e)){let n=JSON.parse(Ue(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=ye(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:N.t(`cmd.extPluginGroupTitle`)},{kind:`row`,label:N.t(`cmd.extPluginLabelDesc`),value:c},{kind:`row`,label:N.t(`cmd.extPluginLabelScope`),value:d.scope},{kind:`row`,label:N.t(`cmd.extPluginLabelTrust`),value:p},{kind:`row`,label:N.t(`cmd.extPluginLabelSurfaces`),value:v.trim()||`—`},...b?[{kind:`row`,label:N.t(`cmd.extPluginLabelContributions`),value:b}]:[],{kind:`row`,label:N.t(`cmd.extPluginLabelStatus`),value:r?N.t(`cmd.extEnableLabel`):N.t(`cmd.extDisableLabel`),tone:r?`success`:`error`}],se=l?[{kind:`text`,value:l.message,tone:l.kind===`success`?`success`:`error`}]:[];t.tui.modal.openModal({kind:`extensionDetail`,title:N.t(`cmd.extPluginTitle`,{name:s,state:r?`enabled`:`disabled`}),meta:`plugin · ${d.scope}`,metaStatus:{label:r?N.t(`cmd.extEnableLabel`):N.t(`cmd.extDisableLabel`),enabled:r},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:Ce(t.app.pluginModuleManager?.getPluginConfig(e,d.manifest.contributes.config)??{}),onEditConfig:async()=>{let n=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(n,null,2)});if(i?.trim())try{let n=JSON.parse(i);if(typeof n!=`object`||!n||Array.isArray(n))throw Error(`config must be a JSON object`);await t.app.pluginModuleManager?.updatePluginConfig(e,n),m(e,r,s,c,{kind:`success`,message:`Configuration updated`})}catch(t){m(e,r,s,c,{kind:`error`,message:`Invalid JSON: ${t instanceof Error?t.message:String(t)}`})}}}}:{},onRefresh:()=>m(e,r,s,c),onAction:async n=>{if(n.startsWith(`contrib:`)){let t=w.get(n.slice(8));if(t)try{await le(t,te)}catch(e){a(N.t(`cmd.extToggleFailed`,{err:e instanceof Error?e.message:String(e)}))}m(e,r,s,c)}else if(n===`trust`)ci(t,d);else if(n===`untrust`){try{Me(d.dir)}catch(t){m(e,r,s,c,{kind:`error`,message:`撤销信任失败,权限未收回:${t instanceof Error?t.message:String(t)}`});return}t.app.reloadCapabilities?.().then(()=>{t.tui.plugins.setPluginRegistrations(t.app.getPluginRegistrations())}).finally(()=>{m(e,r,s,c,{kind:`success`,message:N.t(`cmd.pluginUntrusted`,{id:e})})})}else if(n===`toggle`)try{await t.app.extensions.setEnabled(`plugin`,e,!r);try{await t.app.reloadCapabilities(),m(e,!r,s,c,{kind:`success`,message:N.t(`cmd.extToggled`,{name:s,verb:r?`Disabled`:`Enabled`,seg:``})})}catch(t){m(e,!r,s,c,{kind:`error`,message:N.t(`cmd.extToggleReloadFailed`,{verb:r?`Disabled`:`Enabled`,name:s,err:t instanceof Error?t.message:String(t)})})}}catch(t){m(e,r,s,c,{kind:`error`,message:N.t(`cmd.extToggleFailed`,{err:t instanceof Error?t.message:String(t)})})}else if(n===`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 n===`reload`?t.app.reloadCapabilities?.().then(t=>{m(e,r,s,c,{kind:`success`,message:N.t(`cmd.pluginTrusted`,{id:e,count:t.mcpTools})})}).catch(t=>{m(e,r,s,c,{kind:`error`,message:N.t(`cmd.compatReloadFailed`,{err:t instanceof Error?t.message:String(t)})})}):n===`uninstall`&&await Zn({name:e,type:`plugin`,scope:d.scope===`project`||d.scope===`repository`?d.scope:`global`,ctx:t,onDone:()=>o()})},onClose:()=>o()})};o()}var pi=bt({handleLogout:()=>bi,handleModel:()=>vi,handleProviderAuth:()=>X,handleProviderLogout:()=>yi,handleServiceLogin:()=>xi,handleServiceLogout:()=>Si});const mi=`__otto_model_login__`,hi=`__otto_model_setkey__`,gi=`__otto_model_grant_capability__`,_i=`__otto_model_install_plugin__`;async function vi(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`,N.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`,N.t(`cmd.modelRefreshLineMuted`,{provider:r(e.provider),reason:N.t(`cmd.modelRefreshReasonNotAuthenticated`)})):e.reason?.includes(`capability not granted`)?(i[t]=`warning`,N.t(`cmd.modelRefreshLineWarning`,{provider:r(e.provider),reason:N.t(`cmd.modelRefreshReasonPendingCapability`)})):(i[t]=`warning`,N.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:N.t(`cmd.titleModels`),lines:[...a,``,N.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:N.t(`cmd.modelDelegateProviderTitle`,{cand:e}),options:[{label:N.t(`cmd.modelDelegateProviderYes`,{cand:e}),value:`yes`},{label:N.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(N.t(`cmd.titleDelegated`),N.t(`cmd.modelProviderDelegated`,{cand:e}))}catch(e){t.tui.messages.pushMessage({role:`command_echo`,command:`/model`,status:`error`,summary:N.t(`cmd.delegateFailed`,{err:e instanceof Error?e.message:String(e)})})}},onCancel:()=>{}});return}t.tui.info.showToast(N.t(`cmd.titleModel`),N.t(`cmd.modelNotFoundUse`,{arg:r}));return}t.tui.info.showToast(N.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=N.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:N.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(N.t(`model.noProviderPlugin`)),v.push(N.t(`model.pendingCapabilities`,{count:_}))):g?v.push(N.t(`model.noProviderPlugin`)):h&&v.push(N.t(`model.noneAvailable`)),!g&&_>0&&v.push(N.t(`model.pendingCapabilities`,{count:_})),t.tui.modal.openModal({kind:`select`,searchable:!0,maxVisible:13,title:h?N.t(`cmd.modelSelectTitle`):N.t(`cmd.modelSelectTitleAvail`),subtitle:v.length>0?v.join(` · `):void 0,subtitleTone:_>0?`warning`:`default`,subtitleActions:g||h||_>0?[...g?[{label:N.t(`model.goInstallPlugin`),value:_i}]:h?[{label:N.t(`model.goLogin`),value:mi},{label:N.t(`model.setKey`),value:hi}]:[],..._>0?[{label:N.t(`model.goGrantCapability`),value:gi}]:[]]: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===mi){await X([],t,{method:`oauth`});return}if(e===hi){await X([],t,{method:`key`});return}if(e===gi){await Y([],t);return}if(e===_i){let{EXTENSION_ALIASES:e}=await import(`./extension-CoJqqktf.js`),{runPluginInstall:n}=await Promise.resolve().then(()=>ni),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:N.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(N.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 yi(e.slice(1),t);if(e.includes(`--service`))return xi(e,t);let r=t.app.authStore,i=e=>new Promise(n=>t.tui.modal.openModal({kind:`select`,...e,title:e.title??N.t(`cmd.commonSelect`),detailPlacement:`inline`,onSelect:n,onCancel:()=>n(null)})),a=r.listProviders();if(a.length===0){t.tui.info.showToast(N.t(`cmd.titleLogin`),N.t(`cmd.loginNoProviders`));return}let o=e[0]||null,s=e=>r.oauth.get(e)?.name??ht(e)?.name??t.callbacks.PROVIDER_DISPLAY_NAMES[e]??e,c=e=>s(e),l=e=>e?N.t(`pref.authModeLabel`,{context:e}):N.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:N.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:N.t(`cmd.loginAuthMethod`,{name:d}),options:[{label:N.t(`cmd.loginMethodOauth`),value:`oauth`},{label:N.t(`cmd.loginMethodKey`),value:`key`}]});if(!e)return;p=e}if(p===`key`){let e=await t.tui.modal.openModal({kind:`input`,title:N.t(`cmd.loginKeyTitle`,{provider:o}),placeholder:N.t(`cmd.loginKeyPlaceholder`),mask:!0});if(!e||!e.trim()){t.tui.info.showToast(N.t(`cmd.titleLogin`),N.t(`cmd.loginCancelledNoKey`));return}await r.setCredentialKey(o,e.trim()),await r.save(),t.tui.info.showToast(N.t(`cmd.titleLogin`),N.t(`cmd.loginKeySaved`,{provider:o})),await t.callbacks.refreshModelsNow(e=>t.tui.info.showToast(N.t(`cmd.titleModels`),e));return}try{let e={};await r.login(o,{onAuth:n=>{if(e=n,n.url)if(Fe(n.url))t.tui.info.showToast(N.t(`cmd.titleLogin`),N.t(`cmd.loginOauthBrowserOpened`));else{let e=[N.t(`cmd.loginOauthUrlAuthorize`),`\n${n.url}`];n.instructions&&e.push(`\n${n.instructions}`),t.tui.modal.openModal({kind:`info`,title:N.t(`cmd.loginOauthTitle`,{provider:o}),lines:e})}if(n.code){let e=[N.t(`cmd.loginOauthCodeIntro`)];n.url&&e.push(`\n${n.url}`),e.push(`\n${N.t(`cmd.loginOauthCode`,{code:n.code})}`),n.instructions&&e.push(`\n${n.instructions}`),t.tui.modal.openModal({kind:`info`,title:N.t(`cmd.loginOauthTitle`,{provider:o}),lines:e})}},onProgress:e=>t.tui.info.showToast(N.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(N.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:N.t(`cmd.loginOauthPasteCode`,{provider:o}),description:r.length>0?r:void 0,placeholder:`code#state`,signal:n,actionButton:e.url?{label:N.t(`cmd.loginOauthOpenBrowserButton`),onPress:()=>{Fe(e.url)&&t.tui.info.showToast(N.t(`cmd.titleLogin`),N.t(`cmd.loginOauthBrowserOpened`))}}:void 0})??``}}),t.tui.info.showToast(N.t(`cmd.titleLogin`),N.t(`cmd.loginSuccess`,{provider:o})),await t.callbacks.refreshModelsNow(e=>t.tui.info.showToast(N.t(`cmd.titleModels`),e))}catch(e){t.tui.messages.pushMessage({role:`command_echo`,command:`/auth`,status:`error`,summary:N.t(`cmd.loginFailed`,{msg:e.message})})}}async function yi(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(N.t(`cmd.titleLogout`),N.t(`cmd.logoutNoStored`));return}r=await new Promise(r=>t.tui.modal.openModal({kind:`select`,title:N.t(`cmd.logoutPickProvider`),detailPlacement:`inline`,options:a.map(r=>{let a=n.oauth.get(r)?.name??ht(r)?.name??t.callbacks.PROVIDER_DISPLAY_NAMES[r]??r,o=i[e.indexOf(r)];return{label:a.toLowerCase()===r.toLowerCase()?a:`${a} [${r}]`,value:r,detail:o?N.t(`pref.authModeLabel`,{context:o}):void 0}}),onSelect:r,onCancel:()=>r(null)}))}r&&(await n.logout(r),t.tui.info.showToast(N.t(`cmd.titleLogout`),N.t(`cmd.logoutSuccess`,{provider:r})))}async function bi(e,t){e[0]&&e[0]!==`--service`||await Si([],t)}async function xi(e,t){let n=e.indexOf(`--service`),r=e.indexOf(`--token`);if(n===-1||r===-1){t.tui.info.showToast(N.t(`cmd.titleLogin`),N.t(`cmd.serviceLoginUsage`));return}let i=e[n+1],a=e[r+1];if(!i||!a){t.tui.info.showToast(N.t(`cmd.titleLogin`),N.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(N.t(`cmd.titleLogin`),N.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(N.t(`cmd.titleLogin`),N.t(`cmd.serviceLoginBadResponse`));return}let{OTTO_IDENTITY_PATH:r,isShadowModeEnabled:i}=await import(`@x-otto/env`);if(i()){t.tui.info.showToast(N.t(`cmd.titleLogin`),N.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(N.t(`cmd.titleLogin`),N.t(`cmd.serviceLoginSuccess`,{url:o,user:n.user_id.slice(0,12)}))}catch(e){t.tui.info.showToast(N.t(`cmd.titleLogin`),N.t(`cmd.serviceLoginFailed`,{err:e instanceof Error?e.message:String(e)}))}}async function Si(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(N.t(`cmd.titleLogout`),N.t(`cmd.logoutAccountRemoved`))}catch(e){if(e.code===`ENOENT`){t.tui.info.showToast(N.t(`cmd.titleLogout`),N.t(`cmd.logoutAccountNotFound`));return}t.tui.info.showToast(N.t(`cmd.titleLogout`),N.t(`cmd.logoutAccountFailed`,{err:e instanceof Error?e.message:String(e)}))}}function Ci(){let e=process.env.OTTO_NOTIFY_COALESCE_WARN_RATIO,t=e?Number(e):NaN;return Number.isFinite(t)&&t>=1?t:1.5}function wi(e,t){return t===0?`healthy`:e<Ci()?`warning`:`healthy`}async function Ti(e,t){let n=e[0]?.toLowerCase();if(n===`cache`||n===`cache-stats`)return Ei(e.slice(1),t);if(n===`diagnose`)return Pn(e.slice(1),t);if(n===`services`)return ei(e.slice(1),t);let r=t.state.session,i=r.session,a=i.messages(),o=0;for(let e=a.length-1;e>=0;e--){let t=a[e]?.usage;if(a[e]?.role===`assistant`&&t){o=(t.cacheReadTokens??0)+(t.cacheWriteTokens??0)+(t.inputTokens??0)+(t.outputTokens??0);break}}let s=r.model?.contextWindow,c=s&&s>0?Math.round(o/s*100):void 0,l=a.reduce((e,t)=>e+(t.usage?.outputTokens??0),0),u=Ee(i.metadata().title,i.messages(),r.id),d=t.callbacks.isWriteLeaseReadOnly();t.tui.engine.pushEngineEvent({kind:`status`,session:{title:u,sessionId:r.id.slice(0,8),modelId:r.model?.id??N.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:wi(p,f.coalescedCalls)}});let m=t.app.activePlugins();try{let e=await ie(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 Ei(e,t){let n=t.state.session.getCostSummary(),r=n.perModel.map(e=>{let t={inputTokens:e.inputTokens,outputTokens:0,cacheReadTokens:e.cacheReadTokens,cacheWriteTokens:e.cacheWriteTokens};return{modelId:e.modelId,modelName:e.modelName,cacheReadTokens:e.cacheReadTokens,cacheWriteTokens:e.cacheWriteTokens,inputTokens:e.inputTokens,hitRatio:mt(t,e.api)}}),i=r.some(e=>e.hitRatio!==null),a={inputTokens:n.totalInputTokens,outputTokens:0,cacheReadTokens:n.totalCacheReadTokens,cacheWriteTokens:n.totalCacheWriteTokens},o=i?mt(a):null;t.tui.stores.cache.setView({lastTurnHitRatio:t.state.session.getLastCacheHitRatio(),sessionHitRatio:o,totalCacheReadTokens:n.totalCacheReadTokens,totalCacheWriteTokens:n.totalCacheWriteTokens,totalInputTokens:n.totalInputTokens,totalCostUSD:n.totalCostUSD>0?n.totalCostUSD:void 0,perModel:r}),t.tui.panes.togglePane(`cacheStats`)}async function Di(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 Oi(e){return new Date(e*1e3).toLocaleString()}async function ki(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:N.t(`cmd.titleUsage`),lines:[N.t(`cmd.usageNotSubscription`)]});return}let r=t.callbacks.getLastProviderUsage();if(!r){t.tui.modal.openModal({kind:`info`,title:N.t(`cmd.titleUsage`),lines:[N.t(`cmd.usageNoSnapshotYet`)]});return}let i=[],a=n===`anthropic`;if(r.limitType&&i.push(N.t(`cmd.usageLineType`,{type:Qe(r.limitType)})),(a||r.usedPercent!==void 0)&&i.push(N.t(`cmd.usageLineStatus`,{status:r.status})),r.usedPercent!==void 0&&i.push(N.t(`cmd.usageLinePercent`,{pct:Math.round(r.usedPercent)})),r.resetsAt!==void 0&&i.push(N.t(`cmd.usageLineResetsAt`,{when:Oi(r.resetsAt)})),r.standardLimits){let e=r.standardLimits;i.push(N.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(N.t(`cmd.usageSubPoolNotInHeaders`))),t.tui.modal.openModal({kind:`info`,title:N.t(`cmd.titleUsage`),lines:i})}const Ai=async(e,t)=>{let n=e[0];switch(n){case`memory-sync`:return ji(e.slice(1),t);default:t.tui.info.showToast(`Workspace`,`/workspace ${n??``} — unknown subcommand. Use: memory-sync [status|enable|disable]`)}};async function ji(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 Mi(t,n){let r=n.state.session,i=r.model?.id??N.t(`cmd.aboutModelNotSet`),a=m().length,o=Math.round(y()/(1024*1024*1024)),s=Math.round(h()/(1024*1024)),c=[{kind:`group`,title:N.t(`cmd.aboutGroupVersion`)},{kind:`row`,label:N.t(`cmd.aboutVersion`),value:`${Re} (build ${Le})`},{kind:`row`,label:N.t(`cmd.aboutBranch`),value:`dev`},{kind:`row`,label:N.t(`cmd.aboutCommit`),value:e},{kind:`group`,title:N.t(`cmd.aboutGroupRuntime`)},{kind:`row`,label:N.t(`cmd.aboutRuntime`),value:`Node.js ${process.version} · ${_()} ${p()} · ${v()}`,tone:`muted`},{kind:`row`,label:N.t(`cmd.aboutCPU`),value:`${a} cores`,tone:`muted`},{kind:`row`,label:N.t(`cmd.aboutMemory`),value:`${o} GB total / ${Math.round(s)} MB free`,tone:`muted`},{kind:`row`,label:N.t(`cmd.aboutShell`),value:process.env.SHELL??`(unknown)`,tone:`muted`},{kind:`row`,label:N.t(`cmd.aboutTerminal`),value:process.env.TERM??`(unknown)`,tone:`muted`},{kind:`group`,title:N.t(`cmd.aboutGroupSession`)},{kind:`row`,label:N.t(`cmd.aboutModel`),value:i,tone:`secondary`}];r.id&&c.push({kind:`row`,label:N.t(`cmd.aboutSession`),value:r.id.slice(0,8)}),c.push({kind:`blank`},{kind:`text`,value:N.t(`cmd.aboutUpdateHint`),tone:`muted`}),n.tui.modal.openModal({kind:`info`,title:N.t(`cmd.titleAbout`),lines:[],dataListEntries:c})}function Ni(e,t,n){let r=Te(e,t);if(r)return r;let i=e.split(`/`).pop();if(i)return ce({cwd:t??process.cwd(),homedir:n??g()}).find(e=>e.id===i)?.dir}function Pi(e,t,n){try{let r=Ni(e,t,n);if(!r)return;let i=k(r,te),a=_e(Ue(i,`utf-8`),i);return a?a.codeProviderIds?.[0]??a.contributes?.providers?.[0]?.id??a.contributes?.oauth?.[0]?.id:void 0}catch{return}}function Fi(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 Ii={provider:`install-provider`,authentication:`connect-provider`,model:`choose-model`,ready:`send-first-prompt`,"first-prompt":`none`};function Li(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 Ri(e){let t=Li(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:Ii[t],stage:t,autoOpen:o}}}function zi(e){return e.stage===`ready`||e.stage===`first-prompt`}function Bi(e,t){return e.get(t)===!0}function Vi(e){return{personalizationSeen:Bi(e,`has_completed_onboarding`),dismissed:Bi(e,`has_completed_wizard`)||Bi(e,`wizard_dont_show_again`),firstPromptSubmitted:typeof e.get(`first_prompt_submitted_at`)==`number`}}const Hi=`__otto_setup__`;async function Ui(e){let t=Vi(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!==Hi),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!==Hi?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 Ri({providerInstalled:e.hasProviderPlugin(),...e.providerCandidates?{providerCandidates:e.providerCandidates}:{},connectedProviderIds:r,usableModelIds:a,...o!==void 0&&o!==Hi?{selectedModelId:o}:{},...c===void 0?{}:{selectedModelUsableInMainSession:c},firstPromptSubmitted:t.firstPromptSubmitted,dismissed:t.dismissed})}function Wi(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 Gi=class{snapshot=null;listeners=new Set;constructor(e){this.deps=e}current(){return this.snapshot}async refresh(){let e=await Ui(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 Ki(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 qi(e,t){return e.map((e,n)=>({provider:e,index:n,rank:Ki(e,t)})).sort((e,t)=>e.rank-t.rank||e.index-t.index).map(e=>e.provider)}function Ji(e){try{let{createRequire:t}=xt(`node:module`),{readFileSync:n}=xt(`node:fs`),{dirname:r,join:i}=xt(`node:path`),a=i(r(t(import.meta.url).resolve(`${e}/package.json`)),`otto-plugin.json`),o=JSON.parse(n(a,`utf8`)).contributes??{},s=(o.providers??[]).map(e=>e.envKey).filter(e=>typeof e==`string`&&e.length>0);return{supportsOAuth:!!o.oauth,envKeys:s}}catch{return{supportsOAuth:!1,envKeys:[]}}}function Yi(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=Xi(t);return t.map(e=>({...e,recommended:e.usable&&e.id===n}))}function Xi(e){return e.find(e=>e.usable)?.id}const Zi={hasReadme:!1,hasPackageManifest:!1,hasTestConfig:!1,isEmpty:!1},Qi=new Set([`node_modules`,`.git`,`.hg`,`.svn`,`.venv`,`venv`,`__pycache__`,`.pytest_cache`,`.mypy_cache`,`.tox`,`dist`,`build`,`.next`,`.nuxt`,`.cache`,`.DS_Store`]),$i=/^readme(\.(md|markdown|txt|rst))?$/i,ea=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`]),ta=/^(jest\.config|vitest\.config|karma\.conf|\.mocharc)(\.(js|ts|mjs|cjs|json))?$/i,na=new Set([`pytest.ini`,`tox.ini`,`phpunit.xml`,`phpunit.xml.dist`,`setup.cfg`]);async function ra(e,t){let n;try{n=await t.readdir(e)}catch{return Zi}let r=n.filter(e=>!Qi.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&&$i.test(e.name)&&(a=!0),!o&&ea.has(e.name)&&(o=!0),!s&&(na.has(e.name)||ta.test(e.name))&&(s=!0),a&&o&&s)))break;return{hasReadme:a,hasPackageManifest:o,hasTestConfig:s,isEmpty:i}}function ia(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 aa=`oxygen-provider`,oa=new Set([`plugin-oxygen`,aa]);async function sa(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=>oa.has(e.id)||e.source===`@x-otto/plugin-oxygen`||e.source.includes(`/plugin-oxygen`)||e.subPath?.endsWith(`plugin-oxygen`)))}catch{return!1}}async function ca(e){let t=e.tui,n=e.app,r=await Ui(Wi({modelRegistry:n.modelRegistry,authStore:n.authStore,settings:n.settings,selectedModelId:()=>e.state.session?.model?.id,isModelUsable:P(n.authStore,`delegation`),isModelUsableInMainSession:P(n.authStore,`main-session`)})),i=n.authStore.listProviders(),a=[];r.provider.installed&&a.push(0),r.authentication.connectedProviderIds.length>0&&a.push(1),r.model.usableIds.length>0&&a.push(2);let s=(()=>{for(let e=0;e<3;e++)if(!a.includes(e))return e;return 3})(),c=await sa(e),l=Object.entries(o).filter(([e,t])=>t.capabilities.includes(`provider`)&&(e!==aa||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=qi(l.map(([e,t])=>({id:e,...Ji(t.pkg)})),process.env).map(({id:e})=>({label:e,value:e,detail:u[e]??o[e]?.pkg??e})),f=e=>Fi(e,n.authStore.oauth,{oauth:{label:N.t(`setup.loginOAuth`),detail:`Open browser, complete authorization — no copy-paste needed.`},apiKey:{label:N.t(`setup.loginApiKey`),detail:`Generate a key on your provider dashboard and paste it here.`}}),p=async()=>{let t=await Ui(Wi({modelRegistry:n.modelRegistry,authStore:n.authStore,settings:n.settings,selectedModelId:()=>e.state.session?.model?.id,isModelUsable:P(n.authStore,`delegation`),isModelUsableInMainSession:P(n.authStore,`main-session`)})),r=P(n.authStore,`delegation`),i=new Set(t.model.usableIds),a=n.modelRegistry.getAll().filter(e=>e.id!==`__otto_setup__`);return Yi((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=ia(await ra(n.workspaceDir,{readdir:e=>ot(e,{withFileTypes:!0})})).map(e=>N.t(e));t.modal.openModal({kind:`wizard`,title:N.t(`setup.title`),welcomeTitle:N.t(`setup.welcomeTitle`),welcomeGreeting:``,welcomeDescription:N.t(`setup.welcomeDescription`),welcomeDontShowAgainLabel:N.t(`setup.welcomeDontShowAgain`),welcomeStartLabel:N.t(`setup.welcomeStart`),welcomeCancelLabel:N.t(`setup.welcomeCancel`),stepNames:[N.t(`setup.stepNameProvider`),N.t(`setup.stepNameLogin`),N.t(`setup.stepNameModel`),N.t(`setup.stepNameStart`)],stepSubtitles:[N.t(`setup.step1Subtitle`),N.t(`setup.step3Subtitle`),N.t(`setup.step4Subtitle`),N.t(`setup.step5Done`)],initialCompleted:a,initialCurrent:s,providerOptions:d,providerAuthOptions:f,authProviderName:h,modelOptions:m,onRefreshModelOptions:p,examplePrompts:g,workspacePath:n.workspaceDir,async onInstallProvider(t,n){n(`Resolving package…`);try{let{runPluginInstall:r}=await Promise.resolve().then(()=>ni),i=!1,a=await r(t,e,{autoTrust:!0,onProgress:e=>n(`${e}…`),onPendingCapabilities:()=>{i=!0}}),s=o[t]?.pkg??t;if(!a)return{ok:!1,error:N.t(`setup.installFailed`,{reason:t})};let c=[];try{let{readHighRiskCapabilities:e}=await import(`@x-otto/coding`),t=Ni(s);t&&(c=e(t))}catch{}return{ok:!0,providerId:Pi(s),capabilities:c,pendingCapabilities:i}}catch(e){return{ok:!1,error:e instanceof Error?e.message:String(e)}}},async onProviderOAuthStart(t){let r=t||i[0]||n.authStore.listProviders()[0];if(!r)return null;let a=new AbortController;try{let{openBrowser:t}=await import(`@x-otto/shared`),i,o,s,c=n.authStore.login(r,{signal:a.signal,onAuth:e=>{o=e.code,s=e.instructions,e.url&&(i=e.url,e.code||t(e.url))},onProgress:()=>{},onPrompt:async()=>``});return c.catch(()=>{}),await new Promise(e=>setTimeout(e,200)),{authorizationUrl:i??``,code:o,instructions:s,openAgain:()=>{i&&t(i)},poll:async()=>{try{return await Promise.race([c.then(()=>`done`),new Promise(e=>setTimeout(()=>e(`pending`),500))])===`done`?(await e.callbacks.refreshModelsNow(),`done`):`pending`}catch(e){let t=e instanceof Error?e:void 0;if(t?.code===`OAUTH_CANCELLED`)return{status:`error`,reason:`cancelled`};let n=new Set([`ENOTFOUND`,`ECONNREFUSED`,`ECONNRESET`,`ETIMEDOUT`,`EAI_AGAIN`,`EHOSTUNREACH`,`ENETUNREACH`,`UND_ERR_CONNECT_TIMEOUT`]),r=t?.code,i=t?.cause?.code;return r&&n.has(r)||i&&n.has(i)?{status:`error`,reason:`network`}:{status:`error`,reason:`rejected`}}},cancel:()=>{a.abort()}}}catch{return null}},async onSubmitProviderApiKey(t,r){let a=t||i[0]||n.authStore.listProviders()[0];if(!a)return{ok:!1,error:`No provider selected.`};try{return await n.authStore.setCredentialKey(a,r),await n.authStore.save(),await e.callbacks.refreshModelsNow(),{ok:!0}}catch(e){return{ok:!1,error:e instanceof Error?e.message:String(e)}}},onOpenProxySettings(){import(`./proxy-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 la(e,t){await ca(t)}function Z(e){return cn(e.state.session.session.getDrafts()??[])}function ua(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 da=async(e,t)=>{let n=e[0];switch(n){case void 0:case`list`:return fa(e.slice(1),t);case`save`:return pa(e.slice(1),t);case`load`:return ma(e.slice(1),t);case`delete`:case`remove`:return ha(e.slice(1),t);default:t.tui.info.showToast(`Draft`,`/draft ${n} — unknown subcommand. Use: save|list|load|delete`)}};async function fa(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 pa(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=un(a,o,s),l=dn([...s,c]);try{ua(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 ma(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 ha(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{ua(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 ga=async(e,t)=>{let n=e[0];switch(n){case void 0:case`list`:return _a(t);case`remove`:return va(e[1],t);case`move`:return ya(e[1],e[2],t);case`clear`:return ba(t);default:t.tui.info.showToast(`Queue`,`/queue ${n} — unknown subcommand. Use: list|remove|move|clear`)}};async function _a(e){e.tui.panes.togglePane(`queuePane`,!0)}async function va(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 ya(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 ba(e){e.tui.panes.clearQueue(),e.tui.info.showToast(`Queue`,`Queue cleared`)}const xa=async(e,t)=>{let{session:n,agentProcessing:r}=t.state;if(n.isPaused&&!n.isBusy){n.resumeRun(),t.tui.info.showToast(N.t(`cmd.titleInfo`),N.t(`cmd.runResumedByCommand`)),Sa(t);return}if(n.isPaused&&n.isBusy){n.cancelPauseRun()?t.tui.info.showToast(N.t(`cmd.titleInfo`),N.t(`cmd.pauseCancelled`)):(n.resumeRun(),t.tui.info.showToast(N.t(`cmd.titleInfo`),N.t(`cmd.runResumedByCommand`))),Sa(t);return}if(r){n.pauseRun()?t.tui.info.showToast(N.t(`cmd.titlePauseRequested`),N.t(`cmd.runWillPauseAfterTurn`)):t.tui.info.showToast(N.t(`cmd.titleInfo`),N.t(`cmd.noRunningTaskToPause`)),Sa(t);return}t.tui.info.showToast(N.t(`cmd.titleInfo`),N.t(`cmd.nothingToPause`))};function Sa(e){let t=e.callbacks.refreshSlashCommands?.();t&&e.tui.plugins.setCommands(t)}function Ca(e){let t;try{let n=He(e,`r`);try{t=Buffer.alloc(512);let e=We(n,t,0,512,0);t=t.subarray(0,e)}finally{Ve(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 wa(e){return e>=1048576?`${(e/1048576).toFixed(1)} MB`:e>=1024?`${(e/1024).toFixed(1)} KB`:`${e} B`}function Ta(e){let t;try{t=Ge(e)}catch{return[]}let n=[];for(let r of t)try{let t=j(k(e,r));n.push({name:r,isDir:t.isDirectory(),size:t.isDirectory()?void 0:t.size})}catch{}return n}function Ea(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=Ea(Ta(n)),a=ze(t,n),o=a===``?N.t(`cmd.openBrowserSubtitleRoot`):N.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:wa(e.size??0)}));e.tui.modal.openModal({kind:`select`,title:N.t(`cmd.titleOpen`),subtitle:o,searchable:!0,options:c,initialFilter:r.get(n)??``,onFilterChange:e=>{r.set(n,e)},onSelect:i=>{let a=k(n,i),o;try{o=j(a).isDirectory()}catch{e.tui.info.showToast(N.t(`cmd.titleOpen`),N.t(`cmd.openNotFound`,{path:i}));return}if(o){Q(e,t,a,r);return}Da(e,a,i,()=>{Q(e,t,n,r)}).catch(()=>{e.tui.info.showToast(N.t(`cmd.titleOpen`),N.t(`cmd.openNotFound`,{path:i}))})},onCancel:s?()=>Q(e,t,O(n),r):()=>{}})}async function Da(e,t,n,r){if(Ca(t)){e.tui.info.showToast(N.t(`cmd.titleOpen`),N.t(`cmd.openBinaryRejected`,{path:n}));return}let{content:i,truncated:a}=await Ie(t);e.tui.modal.openModal({kind:`fileViewer`,path:n,content:i,preTruncated:a,onDismiss:r??(()=>{})})}async function Oa(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=Be(n,r),o=ze(n,a).startsWith(`..`);if(!A(a)){if(o){t.tui.info.showToast(N.t(`cmd.titleOpen`),N.t(`cmd.openNotFound`,{path:r}));return}let e=O(a);for(;e!==n&&e!==O(e)&&!A(e);)e=O(e);if(A(e)&&j(e).isDirectory()){Q(t,n,e,i);return}t.tui.info.showToast(N.t(`cmd.titleOpen`),N.t(`cmd.openNotFound`,{path:r}));return}if(j(a).isDirectory()){if(o){t.tui.info.showToast(N.t(`cmd.titleOpen`),N.t(`cmd.openNotFound`,{path:r}));return}Q(t,n,a,i);return}await Da(t,a,r)}async function ka(e,t){t.tui.engine.clearErrorRetry?.();let n=t.state.session;if(!n){t.tui.info.showToast(N.t(`cmd.titleInfo`),N.t(`cmd.retryNoSession`,{defaultValue:`No active session`}));return}if(n.isBusy){t.tui.info.showToast(N.t(`cmd.titleInfo`),N.t(`cmd.retryBusy`,{defaultValue:`Agent 正在运行,无法重试`}));return}if(![...n.session.messages()].reverse().find(e=>e.role===`user`)){t.tui.info.showToast(N.t(`cmd.titleInfo`),N.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(N.t(`cmd.titleInfo`),N.t(`cmd.retryNoResumable`,{defaultValue:`无可重试的回合——请输入消息`}));return}t.tui.info.showToast(N.t(`cmd.titleInfo`),N.t(`cmd.retryFailed`,{defaultValue:`重试失败:{{err}}`,err:e instanceof Error?e.message:String(e)}))}finally{t.tui.engine.pushEngineEvent({kind:`agentProcessing`,value:!1})}}var Aa=bt({DISPATCHABLE_COMMAND_NAMES:()=>Pa,ENGINE_BUILTIN_COMMANDS:()=>Na,HELP_GROUP_ORDER:()=>ja,SAFE_COMMAND_NAMES:()=>Ma,SLASH_COMMANDS:()=>$,buildPluginSlashCommandRegistry:()=>Fa,dispatchSlashCommand:()=>La,handleMemory:()=>On,pluginSlashCommandsToEntries:()=>Ia});const ja=[`session`,`model`,`agent`,`debug`,`ui`,`other`],$=[{name:`clear`,handler:An,engineBuiltin:!0,group:`session`,tuiHidden:!0,deprecated:!0,description:`/session clear (deprecated alias)`},{name:`compact`,handler:(e,t)=>G([`compact`,...e],t),group:`session`,tuiHidden:!0,deprecated:!0,description:`/session compact (deprecated alias)`},{name:`memory`,aliases:[`mem`],handler:On,group:`session`,description:`Project + user memory: /memory [user|project|<name>|forget <name>]`},{name:`workspace`,handler:Ai,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:Ti,safe:!0,engineBuiltin:!0,group:`session`,description:`Session status & perf: /status [cache|diagnose|services]`},{name:`open`,handler:Oa,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:vi,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:ki,safe:!0,engineBuiltin:!0,group:`model`,description:`Show provider usage quota snapshot (Anthropic OAuth subscription plans only)`},{name:`logout`,handler:bi,group:`model`,description:`Sign out of your otto account (removes local account identity); /logout`},{name:`job`,handler:fi,safe:!0,group:`agent`,description:`Start a background agent job: /job <directive> (worktree-isolated, full tools incl. MCP)`},{name:`schedule`,handler:d,safe:!0,group:`agent`,description:`Manage scheduled tasks: /schedule add|list|remove|run|enable|disable <args>`},{name:`delegates`,handler:di,safe:!0,group:`agent`,description:`Toggle the Delegates panel (↑↓ select · k kill · o output · a apply)`},{name:`diagnose`,handler:(e,t)=>Ti([`diagnose`,...e],t),safe:!0,group:`debug`,tuiHidden:!0,deprecated:!0,description:`/status diagnose (deprecated alias)`},{name:`context`,handler:(e,t)=>G([`context`,...e],t),safe:!0,group:`debug`,tuiHidden:!0,deprecated:!0,description:`/session context (deprecated alias)`},{name:`cache-stats`,handler:(e,t)=>Ti([`cache-stats`,...e],t),safe:!0,group:`debug`,tuiHidden:!0,deprecated:!0,description:`/status cache (deprecated alias)`},{name:`services`,handler:(e,t)=>Ti([`services`,...e],t),safe:!0,group:`debug`,tuiHidden:!0,deprecated:!0,description:`/status services (deprecated alias)`},{name:`gallery`,handler:Di,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:Wn,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:Kn,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:Tr,safe:!0,group:`ui`,description:`Switch reasoning effort level (/effort [low|medium|high|xhigh|max])`},{name:`preference`,aliases:[`pref`],handler:Dr,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:Qr,group:`ui`,description:`Toggle the notification center panel (≡ ctrl+n)`},{name:`draft`,handler:da,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:ga,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)=>Dr([`keybindings`,...e],t),safe:!0,group:`ui`,tuiHidden:!0,deprecated:!0,description:`/preference keybindings (deprecated alias)`},{name:`shortcuts`,handler:(e,t)=>Dr([`shortcuts`,...e],t),safe:!0,group:`ui`,tuiHidden:!0,deprecated:!0,description:`/preference shortcuts (deprecated alias)`},{name:`proxy`,handler:(e,t)=>Dr([`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)=>Xr(e,t,[...$,...Ia([...Fa(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:xa,safe:!0,group:`other`,description:`Pause after current turn finishes (toggle with /continue)`},{name:`retry`,handler:ka,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)=>G([`resume`,...e],t),group:`other`,tuiHidden:!0,deprecated:!0,description:`/session resume (deprecated alias)`},{name:`rename`,handler:jn,safe:!0,group:`session`,description:`Set a custom title for the current session (/rename <new title>)`},{name:`a2ui-action`,handler:Un,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 ti(e,t);return}await Yr(e,t)||await qr(e,t)}},{name:`about`,handler:Mi,safe:!0,group:`other`,description:`Show version, build, and environment info (/about)`},{name:`setup`,handler:la,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:Gr,safe:!0,group:`other`,description:`View / clear the always-allow list (/permissions [clear])`},{name:`archive`,aliases:[`unarchive`],handler:(e,t)=>G([`archive`,...e],t),safe:!0,tuiHidden:!0,deprecated:!0,description:`/session archive (deprecated alias)`},{name:`session`,handler:G,description:`Session management: /session [fork|clear|unlock|kill|inspect|pin|archive|resume|compact|context] (RFC-369)`},{name:`fork`,handler:Jn,safe:!0,description:`Fork current session into a named branch`},{name:`pin`,aliases:[`unpin`],handler:(e,t)=>G([`pin`,...e],t),safe:!0,tuiHidden:!0,deprecated:!0,description:`/session pin (deprecated alias)`},{name:`history`,aliases:[`hist`],handler:Zr,safe:!0,description:`Open history search panel (same panel as Ctrl+R)`},{name:`prompts`,handler:$r,safe:!0,description:`View prompt log (list of submitted prompts this session)`}],Ma=new Set($.filter(e=>e.safe).flatMap(e=>[e.name,...e.aliases??[]])),Na=new Set($.filter(e=>e.engineBuiltin).flatMap(e=>[e.name,...e.aliases??[]])),Pa=new Set($.filter(e=>e.handler).flatMap(e=>[e.name,...e.aliases??[]]));function Fa(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 Ia(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 La(e,t,n){let r=$.find(t=>t.name===e);if(r||=$.find(t=>t.aliases?.includes(e)),!r?.handler){let r=Fa(n.app).get(e);return r?(await Ra(r,t,n),!0):!1}return await r.handler(t,n),!0}async function Ra(e,t,n){let r=n.tui,i=n.app.getPluginPanelRegistrations?.()??[];try{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}))}})}catch(t){let n=t instanceof Error?t.message:String(t);r.info.showToast(`plugin`,`斜杠命令 /${e.name} 执行失败:${n}`)}}export{Lt as $,En as A,Ye as B,dr as C,ar as D,sr as E,dn as F,Wt as G,z as H,un as I,Gt as J,qt as K,cn as L,H as M,fn as N,ir as O,pn as P,dt as Q,sn as R,pr as S,hr as T,nn as U,tt as V,tn as W,Yt as X,Kt as Y,Ut as Z,vr as _,Aa as a,bt as at,gr as b,ia as c,zi as d,Ot as et,vi as f,Er as g,ni as h,$ as i,Et as it,vn as j,or as k,Gi as l,pi as m,Na as n,F as nt,La as o,X as p,R as q,Ma as r,Dt as rt,ra as s,Pa as t,kt as tt,Wi as u,xr as v,mr as w,K as x,yr as y,qe as z};
|
|
18
|
+
//# sourceMappingURL=command-dispatcher-BLT8IO4K.js.map
|