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

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.
@@ -17,5 +17,5 @@ import{t as e}from"./build-id-D7Wf4tQw.js";import{t}from"./version-Cq2kcrXL.js";
17
17
  `,1)[0]??``).replace(/\s+/g,` `).trim(),r=n.split(` `).slice(0,6).join(` `).slice(0,48).trim()||`note`;return{name:r,description:n.slice(0,60).trim()||r,content:t}}const yi=e=>`把下面的笔记归纳成一个简短标题(≤6 词)和一句话描述。严格只按此格式输出:\nTITLE: <标题>\nDESC: <一句话描述>\n\n笔记:\n${e}`;function bi(e){let t=/TITLE:\s*(.+)/i.exec(e)?.[1]?.trim();if(!t)return null;let n=/DESC:\s*(.+)/i.exec(e)?.[1]?.trim();return{name:t.slice(0,60),description:(n||t).slice(0,80)}}async function xi(e,t,n=8e3){let r=vi(e);if(!t)return r;let i=new AbortController,a=setTimeout(()=>i.abort(),n);a.unref?.();try{let n=bi(await t(yi(e),{maxTokens:64,signal:i.signal}));if(n)return{name:n.name,description:n.description,content:r.content}}catch{}finally{clearTimeout(a)}return r}function Si(e,t){return{onViewEntry:async n=>{let r=n.source===`project`?e:t;return r?r.read(n.name):null},onForget:async n=>{let r=n.source===`project`?e:t;r&&await r.forget(n.name)}}}async function Ci(e,t){let n=t.app.storage.autoMemory,r=t.app.userMemory,i=(e[0]??``).toLowerCase(),a=e=>t.tui.messages.pushMessage({role:`assistant`,content:[{type:`text`,text:e}]}),o=(e,n,r)=>t.tui.messages.pushMessage({role:`command_echo`,command:e,status:n,summary:r});if(i===`user`){let i=e.slice(1).join(` `).trim();if(i){let e=vi(i);await r.record(e),o(`/memory user`,`ok`,M.t(`cmd.memoryUserSaved`,{name:e.name}));return}let a=r.getInjection().trim();t.tui.modal.openModal({kind:`memory`,projectIndex:``,userIndex:a,...Si(n,r)});return}if(i===`project`){let e=n?n.getInjection().trim():``;t.tui.modal.openModal({kind:`memory`,projectIndex:e,userIndex:``,...Si(n,r)});return}if(i===`forget`){let t=e.slice(1).join(` `).trim();if(!t){o(`/memory forget`,`warn`,M.t(`cmd.memoryForgetUsage`));return}let i=!1;n&&await n.read(t)!==null&&(await n.forget(t),i=!0),await r.read(t)!==null&&(await r.forget(t),i=!0),o(`/memory forget`,i?`ok`:`error`,i?M.t(`cmd.memoryDeleted`,{name:t}):M.t(`cmd.memoryNotFound`,{name:t}));return}if(e.length>0){let t=e.join(` `).trim(),i=(n?await n.read(t):null)??await r.read(t);i==null?o(`/memory ${t}`,`error`,M.t(`cmd.memoryNotFound`,{name:t})):a(i);return}let s=n?n.getInjection().trim():``,c=r.getInjection().trim();t.tui.modal.openModal({kind:`memory`,projectIndex:s,userIndex:c,...Si(n,r)})}async function wi(e,t){let n=M.t(`cmd.titleCompact`);if((e[0]??``).toLowerCase()===`log`){t.tui.panes.togglePane(`compactionLog`);return}if(!t.app.storage.memory){t.tui.info.showToast(n,M.t(`compact.unavailable`));return}t.tui.info.showToast(n,M.t(`compact.ing`)),t.tui.engine.pushEngineEvent({kind:`agentProcessing`,value:!0});try{let e=await t.state.session.compactNow();e.compacted?(t.tui.info.showToast(n,M.t(`compact.edResult`,{before:e.before,after:e.after})),t.callbacks.onContextCompacted()):t.tui.info.showToast(n,M.t(`compact.noop`))}catch(e){t.tui.info.showToast(n,M.t(`cmd.compactFailed`,{msg:e instanceof Error?e.message:String(e)}))}finally{t.tui.engine.pushEngineEvent({kind:`agentProcessing`,value:!1})}}const Ti=async(e,t)=>{let n=e[0];switch(n){case`memory-sync`:return Ei(e.slice(1),t);default:t.tui.info.showToast(`Workspace`,`/workspace ${n??``} — unknown subcommand. Use: memory-sync [status|enable|disable]`)}};async function Ei(e,t){let n=e[0]??`status`,r=t.app.workspaceRef;if(!r?.root){t.tui.info.showToast(`Workspace memory-sync`,`No local workspace identity yet — cannot configure memory sync.`);return}switch(n){case`status`:{let e=r.memorySyncEnabled===!0;t.tui.info.showToast(`Workspace memory-sync`,e?`Enabled — workspace memory (auto-memory/lessons) syncs to the remote store.`:`Disabled — workspace memory stays local (default).`);return}case`enable`:{if(!t.app.storage.remoteMemoryConfigured){t.tui.info.showToast(`Workspace memory-sync`,`No remote memory service configured (needs --session-url + remote.getAuth) — enabling now would have no effect.`);return}let e=await t.app.setWorkspaceMemorySyncEnabled(!0);t.tui.info.showToast(`Workspace memory-sync`,e?`Enabled. Next memory_record/learn calls will sync to the remote store.`:`Failed to enable — no workspace marker to update.`);return}case`disable`:{let e=await t.app.setWorkspaceMemorySyncEnabled(!1);t.tui.info.showToast(`Workspace memory-sync`,e?`Disabled. Workspace memory now stays local.`:`Failed to disable — no workspace marker to update.`);return}default:t.tui.info.showToast(`Workspace memory-sync`,`/workspace memory-sync ${n} — unknown subcommand. Use: status|enable|disable`)}}async function Di(t,n){let r=n.state.session,i=r.model?.id??M.t(`cmd.aboutModelNotSet`),a=h().length,o=Math.round(y()/(1024*1024*1024)),s=Math.round(g()/(1024*1024)),c=[{kind:`group`,title:M.t(`cmd.aboutGroupVersion`)},{kind:`row`,label:M.t(`cmd.aboutVersion`),value:`${ze} (build ${Le})`},{kind:`row`,label:M.t(`cmd.aboutBranch`),value:`dev`},{kind:`row`,label:M.t(`cmd.aboutCommit`),value:e},{kind:`group`,title:M.t(`cmd.aboutGroupRuntime`)},{kind:`row`,label:M.t(`cmd.aboutRuntime`),value:`Node.js ${process.version} · ${v()} ${m()} · ${ee()}`,tone:`muted`},{kind:`row`,label:M.t(`cmd.aboutCPU`),value:`${a} cores`,tone:`muted`},{kind:`row`,label:M.t(`cmd.aboutMemory`),value:`${o} GB total / ${Math.round(s)} MB free`,tone:`muted`},{kind:`row`,label:M.t(`cmd.aboutShell`),value:process.env.SHELL??`(unknown)`,tone:`muted`},{kind:`row`,label:M.t(`cmd.aboutTerminal`),value:process.env.TERM??`(unknown)`,tone:`muted`},{kind:`group`,title:M.t(`cmd.aboutGroupSession`)},{kind:`row`,label:M.t(`cmd.aboutModel`),value:i,tone:`secondary`}];r.id&&c.push({kind:`row`,label:M.t(`cmd.aboutSession`),value:r.id.slice(0,8)}),c.push({kind:`blank`},{kind:`text`,value:M.t(`cmd.aboutUpdateHint`),tone:`muted`}),n.tui.modal.openModal({kind:`info`,title:M.t(`cmd.titleAbout`),lines:[],dataListEntries:c})}async function Oi(e,t){return e.tui.modal.openModal({kind:`input`,...t})}function ki(e,t,n){return new Promise(r=>{e.tui.modal.openModal({kind:`confirm`,title:t,message:n,onConfirm:()=>r(!0),onCancel:()=>r(!1)})})}async function Ai(e,t){let n=t.app.feedbackRegistry.get();if(!n){t.tui.info.showToast(M.t(`cmd.titleFeedback`),M.t(`cmd.feedbackUnavailable`));return}let r=e.indexOf(`--repo`),i=r>=0?e[r+1]:void 0,a=await d({configuredRepo:t.app.settings.get(`feedback_repo`),cliRepoArg:i,cwd:t.app.workspaceDir});if(!a){t.tui.info.showToast(M.t(`cmd.titleFeedback`),M.t(`cmd.feedbackRepoUnresolved`));return}let o=await Oi(t,{title:M.t(`cmd.feedbackStepTitle`)});if(!o||o.trim().length===0)return;let s=await Oi(t,{title:M.t(`cmd.feedbackStepRepro`)})??void 0,c=await Oi(t,{title:M.t(`cmd.feedbackStepExpected`)})??void 0,l=await Oi(t,{title:M.t(`cmd.feedbackStepActual`)})??void 0,u=f(t.state.session.model?.id),p={title:o.trim(),reproduce:s,expected:c,actual:l,envInfo:u,repo:a},m=[s,c,l].filter(Boolean).join(`
18
18
  `).slice(0,300);if(!await ki(t,M.t(`cmd.feedbackConfirmTitle`),M.t(`cmd.feedbackConfirmMessage`,{title:p.title,bodyPreview:m})))return;if(t.tui.info.showToast(M.t(`cmd.titleFeedback`),M.t(`cmd.feedbackChannelSubmitting`)),n.submitIssueViaGh){let e=await n.submitIssueViaGh(p);if(e.ok){t.tui.info.showToast(M.t(`cmd.titleFeedback`),M.t(`cmd.feedbackCreated`,{url:e.url}));return}}let h=n.buildIssueUrl?.(p);if(!h){t.tui.info.showToast(M.t(`cmd.titleFeedback`),M.t(`cmd.feedbackUnavailable`));return}Fe(h),t.tui.info.showToast(M.t(`cmd.titleFeedback`),M.t(`cmd.feedbackCreated`,{url:h}))}function ji(e,t,n){let r=Te(e,t);if(r)return r;let i=e.split(`/`).pop();if(i)return ue({cwd:t??process.cwd(),homedir:n??_()}).find(e=>e.id===i)?.dir}function Mi(e,t,n){try{let r=ji(e,t,n);if(!r)return;let i=O(r,T),a=ve(A(i,`utf-8`),i);return a?a.codeProviderIds?.[0]??a.contributes?.providers?.[0]?.id??a.contributes?.oauth?.[0]?.id:void 0}catch{return}}function Ni(e,t,n){return!e||t.get(e)?[{label:n.oauth.label,value:`oauth`,detail:n.oauth.detail},{label:n.apiKey.label,value:`key`,detail:n.apiKey.detail}]:[{label:n.apiKey.label,value:`key`,detail:n.apiKey.detail}]}const Pi={provider:`install-provider`,authentication:`connect-provider`,model:`choose-model`,ready:`send-first-prompt`,"first-prompt":`none`};function Fi(e){if(!e.providerInstalled)return`provider`;if((e.connectedProviderIds??[]).length===0)return`authentication`;let t=e.usableModelIds??[];if(t.length===0)return`model`;let n=e.selectedModelId;return!n||!(e.selectedModelUsableInMainSession??t.includes(n))?`model`:e.firstPromptSubmitted?`first-prompt`:`ready`}function Ii(e){let t=Fi(e),n=e.providerCandidates??[],r=e.connectedProviderIds??[],i=e.usableModelIds??[],a=e.firstPromptSubmitted??!1,o=(t===`provider`||t===`authentication`||t===`model`)&&!(e.dismissed??!1);return{stage:t,provider:{installed:e.providerInstalled,candidates:n},authentication:{connectedProviderIds:r},model:{...e.selectedModelId===void 0?{}:{selectedId:e.selectedModelId},usableIds:i},firstPrompt:{submitted:a},recommendation:{action:Pi[t],stage:t,autoOpen:o}}}function Li(e){return e.stage===`ready`||e.stage===`first-prompt`}function Ri(e,t){return e.get(t)===!0}function zi(e){return{personalizationSeen:Ri(e,`has_completed_onboarding`),dismissed:Ri(e,`has_completed_wizard`)||Ri(e,`wizard_dont_show_again`),firstPromptSubmitted:typeof e.get(`first_prompt_submitted_at`)==`number`}}const Bi=`__otto_setup__`;async function Vi(e){let t=zi(e.settings),n=e.listProviders(),r=(await Promise.all(n.map(async t=>({provider:t,source:await e.getAuthSource(t).catch(()=>null)})))).filter(e=>e.source!=null).map(e=>e.provider),i=e.listModels().filter(e=>e.id!==Bi),a=(await Promise.all(i.map(async t=>{try{let{usable:n}=await e.isModelUsable({provider:t.provider,api:t.api});return n?t.id:null}catch{return null}}))).filter(e=>e!==null),o=e.getSelectedModelId(),s=o!==void 0&&o!==Bi?i.find(e=>e.id===o):void 0,c=s&&e.isModelUsableInMainSession?await e.isModelUsableInMainSession({provider:s.provider,api:s.api}).then(({usable:e})=>e).catch(()=>!1):void 0;return Ii({providerInstalled:e.hasProviderPlugin(),...e.providerCandidates?{providerCandidates:e.providerCandidates}:{},connectedProviderIds:r,usableModelIds:a,...o!==void 0&&o!==Bi?{selectedModelId:o}:{},...c===void 0?{}:{selectedModelUsableInMainSession:c},firstPromptSubmitted:t.firstPromptSubmitted,dismissed:t.dismissed})}function Hi(e){return{hasProviderPlugin:()=>e.modelRegistry.hasAnyPluginSourcedModel(),listProviders:()=>e.authStore.listProviders(),getAuthSource:t=>e.authStore.getAuthSource(t),listModels:()=>e.modelRegistry.getAll().map(e=>({id:e.id,provider:e.provider,api:e.api})),isModelUsable:e.isModelUsable,...e.isModelUsableInMainSession?{isModelUsableInMainSession:e.isModelUsableInMainSession}:{},getSelectedModelId:e.selectedModelId,settings:{get:t=>e.settings.get(t)},...e.providerCandidates?{providerCandidates:e.providerCandidates}:{}}}var Ui=class{snapshot=null;listeners=new Set;constructor(e){this.deps=e}current(){return this.snapshot}async refresh(){let e=await Vi(this.deps);this.snapshot=e;for(let t of this.listeners)try{t(e)}catch{}return e}subscribe(e){return this.listeners.add(e),()=>{this.listeners.delete(e)}}};function Wi(e,t){return(e.envKeys??[]).some(e=>{let n=t[e];return typeof n==`string`&&n.trim().length>0})?0:e.supportsOAuth?1:2}function Gi(e,t){return e.map((e,n)=>({provider:e,index:n,rank:Wi(e,t)})).sort((e,t)=>e.rank-t.rank||e.index-t.index).map(e=>e.provider)}function Ki(e){try{let{createRequire:t}=xt(`node:module`),{readFileSync:n}=xt(`node:fs`),{dirname:r,join:i}=xt(`node:path`),a=i(r(t(import.meta.url).resolve(`${e}/package.json`)),`otto-plugin.json`),o=JSON.parse(n(a,`utf8`)).contributes??{},s=(o.providers??[]).map(e=>e.envKey).filter(e=>typeof e==`string`&&e.length>0);return{supportsOAuth:!!o.oauth,envKeys:s}}catch{return{supportsOAuth:!1,envKeys:[]}}}function qi(e){let t=e.map((e,t)=>({model:e,index:t})).sort((e,t)=>Number(t.model.usable)-Number(e.model.usable)||e.index-t.index).map(e=>e.model),n=Ji(t);return t.map(e=>({...e,recommended:e.usable&&e.id===n}))}function Ji(e){return e.find(e=>e.usable)?.id}const Yi={hasReadme:!1,hasPackageManifest:!1,hasTestConfig:!1,isEmpty:!1},Xi=new Set([`node_modules`,`.git`,`.hg`,`.svn`,`.venv`,`venv`,`__pycache__`,`.pytest_cache`,`.mypy_cache`,`.tox`,`dist`,`build`,`.next`,`.nuxt`,`.cache`,`.DS_Store`]),Zi=/^readme(\.(md|markdown|txt|rst))?$/i,Qi=new Set([`package.json`,`pyproject.toml`,`setup.py`,`requirements.txt`,`Cargo.toml`,`go.mod`,`Gemfile`,`composer.json`,`pom.xml`,`build.gradle`,`build.gradle.kts`,`Package.swift`]),$i=/^(jest\.config|vitest\.config|karma\.conf|\.mocharc)(\.(js|ts|mjs|cjs|json))?$/i,ea=new Set([`pytest.ini`,`tox.ini`,`phpunit.xml`,`phpunit.xml.dist`,`setup.cfg`]);async function ta(e,t){let n;try{n=await t.readdir(e)}catch{return Yi}let r=n.filter(e=>!Xi.has(e.name)),i=r.length===0,a=!1,o=!1,s=!1,c=0;for(let e of r)if(c>=2e3||(c++,e.isFile()&&(!a&&Zi.test(e.name)&&(a=!0),!o&&Qi.has(e.name)&&(o=!0),!s&&(ea.has(e.name)||$i.test(e.name))&&(s=!0),a&&o&&s)))break;return{hasReadme:a,hasPackageManifest:o,hasTestConfig:s,isEmpty:i}}function na(e){if(e.isEmpty)return[`suggestion.emptyProject`];let t=[];return e.hasReadme&&t.push(`suggestion.hasReadme`),e.hasPackageManifest&&t.push(`suggestion.hasPackageManifest`),e.hasTestConfig&&t.push(`suggestion.hasTestConfig`),t.length>0?t:[`suggestion.unrecognized`]}const ra=`oxygen-provider`,ia=new Set([`plugin-oxygen`,ra]);async function aa(e){try{let{makeRegistryClient:t}=await import(`./registry-BOX7DaxS.js`),{registries:n}=await t(e.app).loadAll();return n.some(e=>e.entries.some(e=>ia.has(e.id)||e.source===`@x-otto/plugin-oxygen`||e.source.includes(`/plugin-oxygen`)||e.subPath?.endsWith(`plugin-oxygen`)))}catch{return!1}}async function oa(e){let t=e.tui,n=e.app,r=await Vi(Hi({modelRegistry:n.modelRegistry,authStore:n.authStore,settings:n.settings,selectedModelId:()=>e.state.session?.model?.id,isModelUsable:N(n.authStore,`delegation`),isModelUsableInMainSession:N(n.authStore,`main-session`)})),i=n.authStore.listProviders(),a=[];r.provider.installed&&a.push(0),r.authentication.connectedProviderIds.length>0&&a.push(1),r.model.usableIds.length>0&&a.push(2);let s=(()=>{for(let e=0;e<3;e++)if(!a.includes(e))return e;return 3})(),c=await aa(e),l=Object.entries(o).filter(([e,t])=>t.capabilities.includes(`provider`)&&(e!==ra||c)),u={"anthropic-provider":`Claude 全系列 · OAuth 一键登录`,"deepseek-provider":`高性价比 · API-key 接入 · 中文友好`,"openai-codex-provider":`GPT / Codex 系列 · 需要 API key 或 OAuth`,"github-copilot-provider":`订阅即用 · GitHub 账号授权`,"cursor-provider":`Cursor IDE 内置 · 需 Cursor 订阅`,"oxygen-provider":`企业级 · 按组织授权`},d=Gi(l.map(([e,t])=>({id:e,...Ki(t.pkg)})),process.env).map(({id:e})=>({label:e,value:e,detail:u[e]??o[e]?.pkg??e})),f=e=>Ni(e,n.authStore.oauth,{oauth:{label:M.t(`setup.loginOAuth`),detail:`Open browser, complete authorization — no copy-paste needed.`},apiKey:{label:M.t(`setup.loginApiKey`),detail:`Generate a key on your provider dashboard and paste it here.`}}),p=async()=>{let t=await Vi(Hi({modelRegistry:n.modelRegistry,authStore:n.authStore,settings:n.settings,selectedModelId:()=>e.state.session?.model?.id,isModelUsable:N(n.authStore,`delegation`),isModelUsableInMainSession:N(n.authStore,`main-session`)})),r=N(n.authStore,`delegation`),i=new Set(t.model.usableIds),a=n.modelRegistry.getAll().filter(e=>e.id!==`__otto_setup__`);return qi((await Promise.all(a.map(async e=>{let t=i.has(e.id);return t?{model:e,usable:t,reason:void 0}:{model:e,usable:!1,reason:(await r({provider:e.provider,api:e.api}).catch(()=>({usable:!1,reason:`unauthenticated`}))).reason??`unauthenticated`}}))).map(({model:e,usable:t,reason:n})=>({id:e.id,label:e.name,detail:`${e.provider} · ${e.strengths?.join(`, `)??``}`,usable:t,...n?{reason:n}:{}}))).map(e=>({label:e.label,value:e.id,detail:e.detail,recommended:e.recommended,...e.reason?{unusableReason:e.reason}:{}}))},m=await p(),h=i.length===1?i[0]:void 0,g=na(await ta(n.workspaceDir,{readdir:e=>rt(e,{withFileTypes:!0})})).map(e=>M.t(e));t.modal.openModal({kind:`wizard`,title:M.t(`setup.title`),welcomeTitle:M.t(`setup.welcomeTitle`),welcomeGreeting:``,welcomeDescription:M.t(`setup.welcomeDescription`),welcomeDontShowAgainLabel:M.t(`setup.welcomeDontShowAgain`),welcomeStartLabel:M.t(`setup.welcomeStart`),welcomeCancelLabel:M.t(`setup.welcomeCancel`),stepNames:[M.t(`setup.stepNameProvider`),M.t(`setup.stepNameLogin`),M.t(`setup.stepNameModel`),M.t(`setup.stepNameStart`)],stepSubtitles:[M.t(`setup.step1Subtitle`),M.t(`setup.step3Subtitle`),M.t(`setup.step4Subtitle`),M.t(`setup.step5Done`)],initialCompleted:a,initialCurrent:s,providerOptions:d,providerAuthOptions:f,authProviderName:h,modelOptions:m,onRefreshModelOptions:p,examplePrompts:g,workspacePath:n.workspaceDir,async onInstallProvider(t,n){n(`Resolving package…`);try{let{runPluginInstall:r}=await Promise.resolve().then(()=>Wr),i=!1,a=await r(t,e,{autoTrust:!0,onProgress:e=>n(`${e}…`),onPendingCapabilities:()=>{i=!0}}),s=o[t]?.pkg??t;if(!a)return{ok:!1,error:M.t(`setup.installFailed`,{reason:t})};let c=[];try{let{readHighRiskCapabilities:e}=await import(`@x-otto/coding`),t=ji(s);t&&(c=e(t))}catch{}return{ok:!0,providerId:Mi(s),capabilities:c,pendingCapabilities:i}}catch(e){return{ok:!1,error:e instanceof Error?e.message:String(e)}}},async onProviderOAuthStart(t){let r=t||i[0]||n.authStore.listProviders()[0];if(!r)return null;let a=new AbortController;try{let{openBrowser:t}=await import(`@x-otto/shared`),i,o,s,c=n.authStore.login(r,{signal:a.signal,onAuth:e=>{o=e.code,s=e.instructions,e.url&&(i=e.url,e.code||t(e.url))},onProgress:()=>{},onPrompt:async()=>``});return c.catch(()=>{}),await new Promise(e=>setTimeout(e,200)),{authorizationUrl:i??``,code:o,instructions:s,openAgain:()=>{i&&t(i)},poll:async()=>{try{return await Promise.race([c.then(()=>`done`),new Promise(e=>setTimeout(()=>e(`pending`),500))])===`done`?(await e.callbacks.refreshModelsNow(),`done`):`pending`}catch(e){let t=e instanceof Error?e:void 0;if(t?.code===`OAUTH_CANCELLED`)return{status:`error`,reason:`cancelled`};let n=new Set([`ENOTFOUND`,`ECONNREFUSED`,`ECONNRESET`,`ETIMEDOUT`,`EAI_AGAIN`,`EHOSTUNREACH`,`ENETUNREACH`,`UND_ERR_CONNECT_TIMEOUT`]),r=t?.code,i=t?.cause?.code;return r&&n.has(r)||i&&n.has(i)?{status:`error`,reason:`network`}:{status:`error`,reason:`rejected`}}},cancel:()=>{a.abort()}}}catch{return null}},async onSubmitProviderApiKey(t,r){let a=t||i[0]||n.authStore.listProviders()[0];if(!a)return{ok:!1,error:`No provider selected.`};try{return await n.authStore.setCredentialKey(a,r),await n.authStore.save(),await e.callbacks.refreshModelsNow(),{ok:!0}}catch(e){return{ok:!1,error:e instanceof Error?e.message:String(e)}}},onOpenProxySettings(){import(`./proxy-BvdBsB1O.js`).then(({handleProxy:t})=>t([],e)).catch(()=>{})},async onSelectModel(t){if(await e.callbacks.applyModel(t),!e.state.modelReady)throw Error(`Model selected but not ready. Check your credentials and try /model refresh.`)},onComplete(){e.callbacks.refreshModelsNow().catch(()=>{}),n.settings.persist({has_completed_wizard:!0},`global`).catch(()=>{})},onDismiss(){},onDontShowAgain(e){n.settings.persist({wizard_dont_show_again:e},`global`).catch(()=>{})}})}async function sa(e,t){await oa(t)}let ca;function la(e){ca=e}const ua=async(e,t)=>{let n=ca;if(!n){t.tui.info.showToast(`Schedule`,`Schedule system not available`);return}let r=e[0];switch(r){case void 0:return da(t);case`list`:return fa(n,t);case`add`:return pa(e.slice(1),n,t);case`remove`:return ma(e[1],n,t);case`run`:return ha(e[1],n,t);case`enable`:return _a(e[1],!0,n,t);case`disable`:return _a(e[1],!1,n,t);case`logs`:return va(e[1],t);case`cancel`:return ga(e[1],t);default:t.tui.info.showToast(`Schedule`,`/schedule ${r} — unknown subcommand. Use: add|list|remove|run|enable|disable|cancel|logs`)}};async function da(e){let t=(e.app.getPluginPanelRegistrations?.()??[]).find(e=>e.pluginId===`plugin-schedule`);if(!t){e.tui.info.showToast(`Schedule`,`Schedule panel not installed — run "otto extension install plugin-schedule"`);return}e.tui.modal.openModal({kind:`pluginPanel`,panelInfo:{title:t.title,modulePath:t.modulePath,exportName:t.exportName,pluginId:t.pluginId},onClose:()=>{}})}async function fa(e,t){let n=e.list(),r=e.isFireOwner()?[]:e.fireOwnerFailureReason()===`network-error`?[`[read-only — could not reach the remote schedule service; check network/persistenced connectivity]`]:[`[read-only — another terminal holds the fire-ownership lease for this workspace]`];if(n.length===0){t.tui.info.showToast(`Schedule`,r.length>0?`No scheduled tasks. ${r[0]}`:`No scheduled tasks`);return}let i=[];for(let e of n){let t=e.lastFireFailed?`✕`:e.enabled?`◉`:`○`,n=e.recurring?e.cronExpression:`one-shot`,r=new Date(e.nextFireAt).toLocaleString(),a=e.lastFireFailed&&e.lastFireError?` (failed: ${e.lastFireError})`:``;i.push(`${t} ${e.id} ${e.name}${a}`),i.push(` ${n} next: ${r}`)}t.tui.messages.pushMessage({role:`command_echo`,command:`/schedule`,status:r.length>0?`warn`:`ok`,summary:r.length>0?r[0]:`${n.length} 个已排定任务`,detail:i.join(`
19
19
  `)}),t.tui.panes.togglePane?.(`schedulePane`)}async function pa(e,t,n){if(e.length<2){n.tui.info.showToast(`Schedule`,`/schedule add [--once] [--session] <cron> <prompt>`);return}let r=!1,i,a=[...e],o=a.indexOf(`--once`);o!==-1&&(r=!0,a.splice(o,1));let s=a.indexOf(`--session`);if(s!==-1&&(i=`session`,a.splice(s,1)),a.length<2){n.tui.info.showToast(`Schedule`,`Opening schedule panel in create mode`),da(n);return}let c=a[0],l=a.slice(1).join(` `);try{let e=t.add({name:l.slice(0,40),prompt:l,cronExpression:c,recurring:!r,origin:`user`,target:i}),a=r?`one-shot`:`recurring`,o=new Date(e.nextFireAt).toLocaleString(),s=e.target===`session`?` [fires into this conversation]`:``;n.tui.info.showToast(`Schedule`,`${e.id}: ${e.name} (${a})${s} next: ${o}`)}catch(e){n.tui.info.showToast(`Schedule`,`Failed: ${e instanceof Error?e.message:String(e)}`)}}async function ma(e,t,n){if(!e){n.tui.info.showToast(`Schedule`,`/schedule remove <id>`);return}let r=t.remove(e);n.tui.info.showToast(`Schedule`,r?`Removed ${e}`:`Schedule "${e}" not found`)}async function ha(e,t,n){if(!e){n.tui.info.showToast(`Schedule`,`/schedule run <id>`);return}try{t.runNow(e),n.tui.info.showToast(`Schedule`,`Triggering ${e}...`)}catch(e){n.tui.info.showToast(`Schedule`,`Failed: ${e instanceof Error?e.message:String(e)}`)}}async function ga(e,t){let n=ca;if(!n){t.tui.info.showToast(`Schedule`,`Schedule system not available`);return}if(!e){t.tui.info.showToast(`Schedule`,`/schedule cancel <id>`);return}let r=n.cancel(e);r.ok?t.tui.info.showToast(`Schedule`,`Canceled "${e}"`):t.tui.info.showToast(`Schedule`,`Cannot cancel "${e}": ${r.reason??`unknown`}`)}async function _a(e,t,n,r){if(!e){r.tui.info.showToast(`Schedule`,`/schedule ${t?`enable`:`disable`} <id>`);return}let i=n.update(e,{enabled:t});r.tui.info.showToast(`Schedule`,i?`Schedule ${e} ${t?`enabled`:`disabled`}`:`Schedule "${e}" not found`)}async function va(e,t){let n=Ve(Re,`schedule-logs`),r;try{r=Ge(n)}catch{t.tui.info.showToast(`Schedule`,`No schedule logs found`);return}if(e&&(r=r.filter(t=>t.startsWith(e+`-`))),r.length===0){t.tui.info.showToast(`Schedule`,e?`No logs for schedule "${e}"`:`No schedule logs found`);return}r.sort().reverse();let i=r.slice(0,5),a=[];for(let e of i)try{let t=A(Ve(n,e),`utf-8`).trim(),r=e.indexOf(`-`),i=r>0?e.slice(0,r):e;a.push(`${i} ${t}`)}catch{a.push(`${e} (unreadable)`)}let o=r.length-i.length;o>0&&a.push(`... and ${o} more entries`),t.tui.messages.pushMessage({role:`command_echo`,command:`/schedule logs`,summary:`${r.length} 条日志文件`,detail:a.join(`
20
- `)})}function Z(e){return ln(e.state.session.session.getDrafts()??[])}function ya(e,t){e.state.session.session.setDrafts(t),e.app.sessionManager.save(e.state.session.id).catch(()=>{}),e.tui.stores.tasks.setDrafts(Z(e))}const ba=async(e,t)=>{let n=e[0];switch(n){case void 0:case`list`:return xa(e.slice(1),t);case`save`:return Sa(e.slice(1),t);case`load`:return Ca(e.slice(1),t);case`delete`:case`remove`:return wa(e.slice(1),t);default:t.tui.info.showToast(`Draft`,`/draft ${n} — unknown subcommand. Use: save|list|load|delete`)}};async function xa(e,t){let n=Z(t);t.tui.stores.tasks.setDrafts(n),t.tui.panes.togglePane(`draftPane`,!0),n.length===0&&t.tui.info.showToast(`Draft`,`No drafts. Save one with Ctrl+S`)}async function Sa(e,t){if(e.length===0){t.tui.info.showToast(`Draft`,`/draft save <name?> <text>`);return}let[n,...r]=e,i=r.length>0,a=i?n:void 0,o=i?r.join(` `):e.join(` `),s=Z(t),c=dn(a,o,s),l=fn([...s,c]);try{ya(t,l)}catch(e){t.tui.info.showToast(`Draft`,`Save failed: ${e instanceof Error?e.message:String(e)}`);return}t.tui.info.showToast(`Draft`,`Saved "${c.name}"`)}async function Ca(e,t){let n=e.join(` `);if(!n){t.tui.info.showToast(`Draft`,`/draft load <name>`);return}let r=Z(t).find(e=>e.name===n);if(!r){t.tui.info.showToast(`Draft`,`Draft "${n}" not found`);return}t.tui.messages.pushMessage({role:`assistant`,content:[{type:`text`,text:r.text}]})}async function wa(e,t){let n=e.join(` `);if(!n){t.tui.info.showToast(`Draft`,`/draft delete <name>`);return}let r=Z(t),i=r.find(e=>e.name===n);if(!i){t.tui.info.showToast(`Draft`,`Draft "${n}" not found`);return}let a=r.filter(e=>e.id!==i.id);try{ya(t,a)}catch(e){t.tui.info.showToast(`Draft`,`Delete failed: ${e instanceof Error?e.message:String(e)}`);return}t.tui.info.showToast(`Draft`,`Removed "${i.name}"`)}const Ta=async(e,t)=>{let n=e[0];switch(n){case void 0:case`list`:return Ea(t);case`remove`:return Da(e[1],t);case`move`:return Oa(e[1],e[2],t);case`clear`:return ka(t);default:t.tui.info.showToast(`Queue`,`/queue ${n} — unknown subcommand. Use: list|remove|move|clear`)}};async function Ea(e){e.tui.panes.togglePane(`queuePane`,!0)}async function Da(e,t){let n=e?Number.parseInt(e,10):NaN;if(!Number.isInteger(n)||n<1){t.tui.info.showToast(`Queue`,`/queue remove <index> (1-based)`);return}t.tui.panes.removeQueuedAt(n-1),t.tui.info.showToast(`Queue`,`Removed item ${n}`)}async function Oa(e,t,n){let r=e?Number.parseInt(e,10):NaN;if(!Number.isInteger(r)||r<1||t!==`up`&&t!==`down`){n.tui.info.showToast(`Queue`,`/queue move <index> <up|down> (1-based)`);return}let i=t===`down`?1:-1;n.tui.panes.moveQueuedItem(r-1,i),n.tui.info.showToast(`Queue`,`Moved item ${r} ${t}`)}async function ka(e){e.tui.panes.clearQueue(),e.tui.info.showToast(`Queue`,`Queue cleared`)}const Aa=async(e,t)=>{let{session:n,agentProcessing:r}=t.state;if(n.isPaused&&!n.isBusy){n.resumeRun(),t.tui.info.showToast(M.t(`cmd.titleInfo`),M.t(`cmd.runResumedByCommand`)),ja(t);return}if(n.isPaused&&n.isBusy){n.cancelPauseRun()?t.tui.info.showToast(M.t(`cmd.titleInfo`),M.t(`cmd.pauseCancelled`)):(n.resumeRun(),t.tui.info.showToast(M.t(`cmd.titleInfo`),M.t(`cmd.runResumedByCommand`))),ja(t);return}if(r){n.pauseRun()?t.tui.info.showToast(M.t(`cmd.titlePauseRequested`),M.t(`cmd.runWillPauseAfterTurn`)):t.tui.info.showToast(M.t(`cmd.titleInfo`),M.t(`cmd.noRunningTaskToPause`)),ja(t);return}t.tui.info.showToast(M.t(`cmd.titleInfo`),M.t(`cmd.nothingToPause`))};function ja(e){let t=e.callbacks.refreshSlashCommands?.();t&&e.tui.plugins.setCommands(t)}function Ma(e){let t;try{let n=Ue(e,`r`);try{t=Buffer.alloc(512);let e=We(n,t,0,512,0);t=t.subarray(0,e)}finally{He(n)}}catch{return!1}if(t.length===0)return!1;let n=0;for(let e of t){if(e===0)return!0;!(e>=32&&e<127)&&!(e===9||e===10||e===13)&&!(e>=192&&e<=253)&&!(e>=128&&e<=191)&&n++}return n/t.length>.3}function Na(e){return e>=1048576?`${(e/1048576).toFixed(1)} MB`:e>=1024?`${(e/1024).toFixed(1)} KB`:`${e} B`}function Pa(e){let t;try{t=Ge(e)}catch{return[]}let n=[];for(let r of t)try{let t=Ke(O(e,r));n.push({name:r,isDir:t.isDirectory(),size:t.isDirectory()?void 0:t.size})}catch{}return n}function Fa(e){return[...e].sort((e,t)=>e.isDir===t.isDir?e.name.localeCompare(t.name):e.isDir?-1:1)}function Q(e,t,n,r){let i=Fa(Pa(n)),a=Be(t,n),o=a===``?M.t(`cmd.openBrowserSubtitleRoot`):M.t(`cmd.openBrowserSubtitleDir`,{relDir:a}),s=n!==t,c=i.map(e=>({label:e.isDir?`${e.name}/`:e.name,value:e.name,detail:e.isDir?void 0:Na(e.size??0)}));e.tui.modal.openModal({kind:`select`,title:M.t(`cmd.titleOpen`),subtitle:o,searchable:!0,options:c,initialFilter:r.get(n)??``,onFilterChange:e=>{r.set(n,e)},onSelect:i=>{let a=O(n,i),o;try{o=Ke(a).isDirectory()}catch{e.tui.info.showToast(M.t(`cmd.titleOpen`),M.t(`cmd.openNotFound`,{path:i}));return}if(o){Q(e,t,a,r);return}Ia(e,a,i,()=>{Q(e,t,n,r)}).catch(()=>{e.tui.info.showToast(M.t(`cmd.titleOpen`),M.t(`cmd.openNotFound`,{path:i}))})},onCancel:s?()=>Q(e,t,D(n),r):()=>{}})}async function Ia(e,t,n,r){if(Ma(t)){e.tui.info.showToast(M.t(`cmd.titleOpen`),M.t(`cmd.openBinaryRejected`,{path:n}));return}let{content:i,truncated:a}=await Ie(t);e.tui.modal.openModal({kind:`fileViewer`,path:n,content:i,preTruncated:a,onDismiss:r??(()=>{})})}async function La(e,t){let n=t.app.workspaceDir??process.cwd(),r=e.join(` `).trim(),i=new Map;if(!r){Q(t,n,n,i);return}let a=Ve(n,r),o=Be(n,a).startsWith(`..`);if(!k(a)){if(o){t.tui.info.showToast(M.t(`cmd.titleOpen`),M.t(`cmd.openNotFound`,{path:r}));return}let e=D(a);for(;e!==n&&e!==D(e)&&!k(e);)e=D(e);if(k(e)&&Ke(e).isDirectory()){Q(t,n,e,i);return}t.tui.info.showToast(M.t(`cmd.titleOpen`),M.t(`cmd.openNotFound`,{path:r}));return}if(Ke(a).isDirectory()){if(o){t.tui.info.showToast(M.t(`cmd.titleOpen`),M.t(`cmd.openNotFound`,{path:r}));return}Q(t,n,a,i);return}await Ia(t,a,r)}var Ra=bt({DISPATCHABLE_COMMAND_NAMES:()=>Ha,ENGINE_BUILTIN_COMMANDS:()=>Va,HELP_GROUP_ORDER:()=>za,SAFE_COMMAND_NAMES:()=>Ba,SLASH_COMMANDS:()=>$,dispatchSlashCommand:()=>Ua,handleCompact:()=>wi,handleMemory:()=>Ci});const za=[`session`,`model`,`agent`,`debug`,`ui`,`other`],$=[{name:`clear`,handler:wn,engineBuiltin:!0,group:`session`,description:`Clear screen and reset interface state`},{name:`compact`,handler:wi,group:`session`,description:`Compact context now, or /compact log for recent compaction/prune event details`},{name:`memory`,aliases:[`mem`],handler:Ci,group:`session`,description:`Project + user memory: /memory [user|project|<name>|forget <name>]`},{name:`workspace`,handler:Ti,safe:!0,group:`session`,description:`Manage workspace settings: /workspace memory-sync [status|enable|disable] (RFC-164 R-form remote memory sync opt-in)`},{name:`status`,handler:X,safe:!0,engineBuiltin:!0,group:`session`,description:`Session status & diagnostics: /status [perf|context|cache|diagnose|services] (RFC-367)`},{name:`open`,handler:La,safe:!0,group:`session`,description:`Open a file, or browse the current directory to find one: /open [path] (RFC-189)`},{name:`model`,aliases:[`m`],handler:oi,group:`model`,description:`Switch model; /model [<id>|refresh]`},{name:`auth`,aliases:[`login`],handler:Y,group:`model`,description:`Connect a model provider (OAuth or API key); /auth [<provider>]`},{name:`usage`,handler:_i,safe:!0,engineBuiltin:!0,group:`model`,description:`Show provider usage quota snapshot (Anthropic OAuth subscription plans only)`},{name:`logout`,handler:si,group:`model`,description:`Remove stored credentials for a provider; /logout [<provider>]`},{name:`job`,handler:ei,safe:!0,group:`agent`,description:`Start a background agent job: /job <directive> (worktree-isolated, full tools incl. MCP)`},{name:`schedule`,handler:ua,safe:!0,group:`agent`,description:`Manage scheduled tasks: /schedule add|list|remove|run|enable|disable <args>`},{name:`delegates`,handler:$r,safe:!0,group:`agent`,description:`Toggle the Delegates panel (↑↓ select · k kill · o output · a apply)`},{name:`diagnose`,handler:(e,t)=>X([`diagnose`,...e],t),safe:!0,group:`debug`,deprecated:!0,description:`Deprecated: use /status diagnose`},{name:`context`,handler:(e,t)=>X([`context`,...e],t),safe:!0,group:`debug`,deprecated:!0,description:`Deprecated: use /status context`},{name:`perf`,handler:(e,t)=>X([`perf`,...e],t),safe:!0,group:`debug`,deprecated:!0,description:`Deprecated: use /status perf`},{name:`cache-stats`,handler:(e,t)=>X([`cache-stats`,...e],t),safe:!0,group:`debug`,deprecated:!0,description:`Deprecated: use /status cache`},{name:`services`,handler:(e,t)=>X([`services`,...e],t),safe:!0,group:`debug`,deprecated:!0,description:`Deprecated: use /status services`},{name:`gallery`,handler:hi,safe:!0,group:`debug`,envGate:`OTTO_DEV`,description:`Open the TUI component gallery (all component examples; dev only, OTTO_DEV=1)`},{name:`trace-gc`,handler:In,group:`debug`,description:`Trace TTL lifecycle GC: /trace-gc [--ttl-days N] [--apply]. Cleans stale session trace files (not session data). TTL is based on the session's last agent engine activity time, not your last view/interaction time.`},{name:`session-archive-export`,handler:Rn,group:`debug`,description:`Archive-export a cold session: /session-archive-export <sessionId> [--out <path>] [--and-delete]. Exports full session entries as JSON; optional --and-delete removes from DB after checksum verification + confirmation.`},{name:`effort`,handler:(e,t)=>G([`effort`,...e],t),group:`ui`,deprecated:!0,description:`Deprecated: use /preference effort`},{name:`preference`,aliases:[`pref`],handler:G,safe:!0,group:`ui`,description:`Preferences: /preference [general|lang|theme|keybindings|shortcuts|effort|proxy] (RFC-367)`},{name:`trust`,handler:(e,t)=>J([`trust`,...e],t),safe:!0,group:`ui`,deprecated:!0,description:`Deprecated: use /extension trust`},{name:`notification`,aliases:[`notif`],handler:Br,group:`ui`,description:`Toggle the notification center panel (≡ ctrl+n)`},{name:`draft`,handler:ba,safe:!0,group:`ui`,description:`Manage saved drafts (≡ Ctrl+S save, Ctrl+O open panel): /draft [list|save <name?> <text>|load <name>|delete <name>]`},{name:`queue`,handler:Ta,safe:!0,group:`ui`,description:`Open the queued-commands panel (≡ ctrl+q): /queue [list|remove <index>|move <index> <up|down>|clear]`},{name:`keybindings`,aliases:[`kb`],handler:(e,t)=>G([`keybindings`,...e],t),safe:!0,group:`ui`,deprecated:!0,description:`Deprecated: use /preference keybindings`},{name:`shortcuts`,handler:(e,t)=>G([`shortcuts`,...e],t),safe:!0,group:`ui`,deprecated:!0,description:`Deprecated: use /preference shortcuts`},{name:`proxy`,handler:(e,t)=>G([`proxy`,...e],t),group:`ui`,deprecated:!0,description:`Deprecated: use /preference proxy`},{name:`help`,aliases:[`h`,`?`],safe:!0,engineBuiltin:!0,group:`other`,description:`Show available commands`,handler:async(e,t)=>Rr(e,t,$)},{name:`exit`,aliases:[`quit`,`q`],safe:!0,engineBuiltin:!0,group:`other`,tuiHidden:!0,description:`Exit the TUI; /exit --restart to restart into the same session`},{name:`abort`,engineBuiltin:!0,group:`other`,tuiHidden:!0,description:`Abort the current agent run`},{name:`pause`,aliases:[`continue`],handler:Aa,safe:!0,group:`other`,description:`Pause after current turn finishes (toggle with /continue)`},{name:`copy`,engineBuiltin:!0,group:`other`,tuiHidden:!0,description:`Copy last assistant response`},{name:`resume`,handler:En,group:`other`,description:`List and switch to an existing session (--workspace <id>, --archived, --all)`},{name:`rename`,handler:Tn,safe:!0,group:`session`,description:`Set a custom title for the current session (/rename <new title>)`},{name:`a2ui-action`,handler:Fn,safe:!1,group:`session`,description:`Trigger A2UI interactive component action (/a2ui-action btn1 click)`},{name:`reload`,handler:Dn,group:`other`,description:`Hot-reload capabilities (MCP / providers / declarative agents) without restart`},{name:`upgrade`,group:`other`,description:`Check for updates (/upgrade --check for extensions, /upgrade for otto CLI)`,handler:async(e,t)=>{if(e.includes(`--check`)){await Ur(e,t);return}await Lr(e,t)||await Ir(e,t)}},{name:`about`,handler:Di,safe:!0,group:`other`,description:`Show version, build, and environment info (/about)`},{name:`setup`,handler:sa,safe:!0,group:`other`,description:`Show onboarding progress (provider → login → model) with a jump-to-next-step button (/setup)`},{name:`extension`,aliases:[`extensions`,`ext`],handler:J,group:`other`,description:`Manage extensions: /extension [trust|install|registry|search|update] or open panel (RFC-367)`},{name:`install`,handler:(e,t)=>J([`install`,...e],t),safe:!0,group:`other`,deprecated:!0,description:`Deprecated: use /extension install`},{name:`registry`,handler:(e,t)=>J([`registry`,...e],t),safe:!0,group:`other`,deprecated:!0,description:`Deprecated: use /extension registry`},{name:`search`,handler:(e,t)=>J([`search`,...e],t),safe:!0,group:`other`,deprecated:!0,description:`Deprecated: use /extension search`},{name:`permissions`,aliases:[`perms`],handler:Fr,safe:!0,group:`other`,description:`View / clear the always-allow list (/permissions [clear])`},{name:`feedback`,handler:Ai,group:`other`,description:`Report an issue or send feedback via GitHub (/feedback [--repo <owner/repo>])`},{name:`archive`,handler:kn,safe:!0,description:`Toggle archive state (archived disables further input); /archive [<id>]`},{name:`session`,handler:Nn,description:`Session management: /session fork | /session unlock <id> [--force] | /session kill <id> | /session inspect <id>`},{name:`fork`,handler:Bn,safe:!0,description:`Fork current session into a named branch`},{name:`pin`,aliases:[`unpin`],handler:An,safe:!0,description:`Toggle pin state (pinned sessions sort to top of /resume); /pin [<id>...] [--group <name>]`},{name:`history`,aliases:[`hist`],handler:zr,safe:!0,description:`Open history search panel (same panel as Ctrl+R)`},{name:`prompts`,handler:Vr,safe:!0,description:`View prompt log (list of submitted prompts this session)`}],Ba=new Set($.filter(e=>e.safe).flatMap(e=>[e.name,...e.aliases??[]])),Va=new Set($.filter(e=>e.engineBuiltin).flatMap(e=>[e.name,...e.aliases??[]])),Ha=new Set($.filter(e=>e.handler).flatMap(e=>[e.name,...e.aliases??[]]));async function Ua(e,t,n){let r=$.find(t=>t.name===e);return r||=$.find(t=>t.aliases?.includes(e)),r?.handler?(await r.handler(t,n),!0):!1}export{Lt as $,Yn as A,qe as B,W as C,or as D,ar as E,mn as F,nn as G,tt as H,fn as I,F as J,Gt as K,dn as L,yn as M,z as N,Qn as O,pn as P,Wt as Q,ln as R,sr as S,nr as T,I as U,Ye as V,rn as W,qt as X,Kt as Y,Xt as Z,Wr as _,Ra as a,Et as at,fr as b,ta as c,Hi as d,It as et,Li as f,ti as g,Y as h,$ as i,Dt as it,Zn as j,Xn as k,na as l,oi as m,Va as n,At as nt,Ua as o,bt as ot,xi as p,Jt as q,Ba as r,Ot as rt,la as s,Ha as t,kt as tt,Ui as u,_r as v,ir as w,ur as x,lr as y,cn as z};
21
- //# sourceMappingURL=command-dispatcher-ZyrfHgIk.js.map
20
+ `)})}function Z(e){return ln(e.state.session.session.getDrafts()??[])}function ya(e,t){e.state.session.session.setDrafts(t),e.app.sessionManager.save(e.state.session.id).catch(()=>{}),e.tui.stores.tasks.setDrafts(Z(e))}const ba=async(e,t)=>{let n=e[0];switch(n){case void 0:case`list`:return xa(e.slice(1),t);case`save`:return Sa(e.slice(1),t);case`load`:return Ca(e.slice(1),t);case`delete`:case`remove`:return wa(e.slice(1),t);default:t.tui.info.showToast(`Draft`,`/draft ${n} — unknown subcommand. Use: save|list|load|delete`)}};async function xa(e,t){let n=Z(t);t.tui.stores.tasks.setDrafts(n),t.tui.panes.togglePane(`draftPane`,!0),n.length===0&&t.tui.info.showToast(`Draft`,`No drafts. Save one with Ctrl+S`)}async function Sa(e,t){if(e.length===0){t.tui.info.showToast(`Draft`,`/draft save <name?> <text>`);return}let[n,...r]=e,i=r.length>0,a=i?n:void 0,o=i?r.join(` `):e.join(` `),s=Z(t),c=dn(a,o,s),l=fn([...s,c]);try{ya(t,l)}catch(e){t.tui.info.showToast(`Draft`,`Save failed: ${e instanceof Error?e.message:String(e)}`);return}t.tui.info.showToast(`Draft`,`Saved "${c.name}"`)}async function Ca(e,t){let n=e.join(` `);if(!n){t.tui.info.showToast(`Draft`,`/draft load <name>`);return}let r=Z(t).find(e=>e.name===n);if(!r){t.tui.info.showToast(`Draft`,`Draft "${n}" not found`);return}t.tui.messages.pushMessage({role:`assistant`,content:[{type:`text`,text:r.text}]})}async function wa(e,t){let n=e.join(` `);if(!n){t.tui.info.showToast(`Draft`,`/draft delete <name>`);return}let r=Z(t),i=r.find(e=>e.name===n);if(!i){t.tui.info.showToast(`Draft`,`Draft "${n}" not found`);return}let a=r.filter(e=>e.id!==i.id);try{ya(t,a)}catch(e){t.tui.info.showToast(`Draft`,`Delete failed: ${e instanceof Error?e.message:String(e)}`);return}t.tui.info.showToast(`Draft`,`Removed "${i.name}"`)}const Ta=async(e,t)=>{let n=e[0];switch(n){case void 0:case`list`:return Ea(t);case`remove`:return Da(e[1],t);case`move`:return Oa(e[1],e[2],t);case`clear`:return ka(t);default:t.tui.info.showToast(`Queue`,`/queue ${n} — unknown subcommand. Use: list|remove|move|clear`)}};async function Ea(e){e.tui.panes.togglePane(`queuePane`,!0)}async function Da(e,t){let n=e?Number.parseInt(e,10):NaN;if(!Number.isInteger(n)||n<1){t.tui.info.showToast(`Queue`,`/queue remove <index> (1-based)`);return}t.tui.panes.removeQueuedAt(n-1),t.tui.info.showToast(`Queue`,`Removed item ${n}`)}async function Oa(e,t,n){let r=e?Number.parseInt(e,10):NaN;if(!Number.isInteger(r)||r<1||t!==`up`&&t!==`down`){n.tui.info.showToast(`Queue`,`/queue move <index> <up|down> (1-based)`);return}let i=t===`down`?1:-1;n.tui.panes.moveQueuedItem(r-1,i),n.tui.info.showToast(`Queue`,`Moved item ${r} ${t}`)}async function ka(e){e.tui.panes.clearQueue(),e.tui.info.showToast(`Queue`,`Queue cleared`)}const Aa=async(e,t)=>{let{session:n,agentProcessing:r}=t.state;if(n.isPaused&&!n.isBusy){n.resumeRun(),t.tui.info.showToast(M.t(`cmd.titleInfo`),M.t(`cmd.runResumedByCommand`)),ja(t);return}if(n.isPaused&&n.isBusy){n.cancelPauseRun()?t.tui.info.showToast(M.t(`cmd.titleInfo`),M.t(`cmd.pauseCancelled`)):(n.resumeRun(),t.tui.info.showToast(M.t(`cmd.titleInfo`),M.t(`cmd.runResumedByCommand`))),ja(t);return}if(r){n.pauseRun()?t.tui.info.showToast(M.t(`cmd.titlePauseRequested`),M.t(`cmd.runWillPauseAfterTurn`)):t.tui.info.showToast(M.t(`cmd.titleInfo`),M.t(`cmd.noRunningTaskToPause`)),ja(t);return}t.tui.info.showToast(M.t(`cmd.titleInfo`),M.t(`cmd.nothingToPause`))};function ja(e){let t=e.callbacks.refreshSlashCommands?.();t&&e.tui.plugins.setCommands(t)}function Ma(e){let t;try{let n=Ue(e,`r`);try{t=Buffer.alloc(512);let e=We(n,t,0,512,0);t=t.subarray(0,e)}finally{He(n)}}catch{return!1}if(t.length===0)return!1;let n=0;for(let e of t){if(e===0)return!0;!(e>=32&&e<127)&&!(e===9||e===10||e===13)&&!(e>=192&&e<=253)&&!(e>=128&&e<=191)&&n++}return n/t.length>.3}function Na(e){return e>=1048576?`${(e/1048576).toFixed(1)} MB`:e>=1024?`${(e/1024).toFixed(1)} KB`:`${e} B`}function Pa(e){let t;try{t=Ge(e)}catch{return[]}let n=[];for(let r of t)try{let t=Ke(O(e,r));n.push({name:r,isDir:t.isDirectory(),size:t.isDirectory()?void 0:t.size})}catch{}return n}function Fa(e){return[...e].sort((e,t)=>e.isDir===t.isDir?e.name.localeCompare(t.name):e.isDir?-1:1)}function Q(e,t,n,r){let i=Fa(Pa(n)),a=Be(t,n),o=a===``?M.t(`cmd.openBrowserSubtitleRoot`):M.t(`cmd.openBrowserSubtitleDir`,{relDir:a}),s=n!==t,c=i.map(e=>({label:e.isDir?`${e.name}/`:e.name,value:e.name,detail:e.isDir?void 0:Na(e.size??0)}));e.tui.modal.openModal({kind:`select`,title:M.t(`cmd.titleOpen`),subtitle:o,searchable:!0,options:c,initialFilter:r.get(n)??``,onFilterChange:e=>{r.set(n,e)},onSelect:i=>{let a=O(n,i),o;try{o=Ke(a).isDirectory()}catch{e.tui.info.showToast(M.t(`cmd.titleOpen`),M.t(`cmd.openNotFound`,{path:i}));return}if(o){Q(e,t,a,r);return}Ia(e,a,i,()=>{Q(e,t,n,r)}).catch(()=>{e.tui.info.showToast(M.t(`cmd.titleOpen`),M.t(`cmd.openNotFound`,{path:i}))})},onCancel:s?()=>Q(e,t,D(n),r):()=>{}})}async function Ia(e,t,n,r){if(Ma(t)){e.tui.info.showToast(M.t(`cmd.titleOpen`),M.t(`cmd.openBinaryRejected`,{path:n}));return}let{content:i,truncated:a}=await Ie(t);e.tui.modal.openModal({kind:`fileViewer`,path:n,content:i,preTruncated:a,onDismiss:r??(()=>{})})}async function La(e,t){let n=t.app.workspaceDir??process.cwd(),r=e.join(` `).trim(),i=new Map;if(!r){Q(t,n,n,i);return}let a=Ve(n,r),o=Be(n,a).startsWith(`..`);if(!k(a)){if(o){t.tui.info.showToast(M.t(`cmd.titleOpen`),M.t(`cmd.openNotFound`,{path:r}));return}let e=D(a);for(;e!==n&&e!==D(e)&&!k(e);)e=D(e);if(k(e)&&Ke(e).isDirectory()){Q(t,n,e,i);return}t.tui.info.showToast(M.t(`cmd.titleOpen`),M.t(`cmd.openNotFound`,{path:r}));return}if(Ke(a).isDirectory()){if(o){t.tui.info.showToast(M.t(`cmd.titleOpen`),M.t(`cmd.openNotFound`,{path:r}));return}Q(t,n,a,i);return}await Ia(t,a,r)}var Ra=bt({DISPATCHABLE_COMMAND_NAMES:()=>Ha,ENGINE_BUILTIN_COMMANDS:()=>Va,HELP_GROUP_ORDER:()=>za,SAFE_COMMAND_NAMES:()=>Ba,SLASH_COMMANDS:()=>$,dispatchSlashCommand:()=>Ua,handleCompact:()=>wi,handleMemory:()=>Ci});const za=[`session`,`model`,`agent`,`debug`,`ui`,`other`],$=[{name:`clear`,handler:wn,engineBuiltin:!0,group:`session`,description:`Clear screen and reset interface state`},{name:`compact`,handler:wi,group:`session`,description:`Compact context now, or /compact log for recent compaction/prune event details`},{name:`memory`,aliases:[`mem`],handler:Ci,group:`session`,description:`Project + user memory: /memory [user|project|<name>|forget <name>]`},{name:`workspace`,handler:Ti,safe:!0,group:`session`,description:`Manage workspace settings: /workspace memory-sync [status|enable|disable] (RFC-164 R-form remote memory sync opt-in)`},{name:`status`,handler:X,safe:!0,engineBuiltin:!0,group:`session`,description:`Session status & diagnostics: /status [perf|context|cache|diagnose|services] (RFC-367)`},{name:`open`,handler:La,safe:!0,group:`session`,description:`Open a file, or browse the current directory to find one: /open [path] (RFC-189)`},{name:`model`,aliases:[`m`],handler:oi,group:`model`,description:`Switch model; /model [<id>|refresh]`},{name:`auth`,aliases:[`login`],handler:Y,group:`model`,description:`Connect a model provider (OAuth or API key); /auth [<provider>]`},{name:`usage`,handler:_i,safe:!0,engineBuiltin:!0,group:`model`,description:`Show provider usage quota snapshot (Anthropic OAuth subscription plans only)`},{name:`logout`,handler:si,group:`model`,description:`Remove stored credentials for a provider; /logout [<provider>]`},{name:`job`,handler:ei,safe:!0,group:`agent`,description:`Start a background agent job: /job <directive> (worktree-isolated, full tools incl. MCP)`},{name:`schedule`,handler:ua,safe:!0,group:`agent`,description:`Manage scheduled tasks: /schedule add|list|remove|run|enable|disable <args>`},{name:`delegates`,handler:$r,safe:!0,group:`agent`,description:`Toggle the Delegates panel (↑↓ select · k kill · o output · a apply)`},{name:`diagnose`,handler:(e,t)=>X([`diagnose`,...e],t),safe:!0,group:`debug`,deprecated:!0,description:`$1 (deprecated alias)`},{name:`context`,handler:(e,t)=>X([`context`,...e],t),safe:!0,group:`debug`,deprecated:!0,description:`$1 (deprecated alias)`},{name:`perf`,handler:(e,t)=>X([`perf`,...e],t),safe:!0,group:`debug`,deprecated:!0,description:`$1 (deprecated alias)`},{name:`cache-stats`,handler:(e,t)=>X([`cache-stats`,...e],t),safe:!0,group:`debug`,deprecated:!0,description:`$1 (deprecated alias)`},{name:`services`,handler:(e,t)=>X([`services`,...e],t),safe:!0,group:`debug`,deprecated:!0,description:`$1 (deprecated alias)`},{name:`gallery`,handler:hi,safe:!0,group:`debug`,envGate:`OTTO_DEV`,description:`Open the TUI component gallery (all component examples; dev only, OTTO_DEV=1)`},{name:`trace-gc`,handler:In,group:`debug`,description:`Trace TTL lifecycle GC: /trace-gc [--ttl-days N] [--apply]. Cleans stale session trace files (not session data). TTL is based on the session's last agent engine activity time, not your last view/interaction time.`},{name:`session-archive-export`,handler:Rn,group:`debug`,description:`Archive-export a cold session: /session-archive-export <sessionId> [--out <path>] [--and-delete]. Exports full session entries as JSON; optional --and-delete removes from DB after checksum verification + confirmation.`},{name:`effort`,handler:(e,t)=>G([`effort`,...e],t),group:`ui`,deprecated:!0,description:`$1 (deprecated alias)`},{name:`preference`,aliases:[`pref`],handler:G,safe:!0,group:`ui`,description:`Preferences: /preference [general|lang|theme|keybindings|shortcuts|effort|proxy] (RFC-367)`},{name:`trust`,handler:(e,t)=>J([`trust`,...e],t),safe:!0,group:`ui`,deprecated:!0,description:`$1 (deprecated alias)`},{name:`notification`,aliases:[`notif`],handler:Br,group:`ui`,description:`Toggle the notification center panel (≡ ctrl+n)`},{name:`draft`,handler:ba,safe:!0,group:`ui`,description:`Manage saved drafts (≡ Ctrl+S save, Ctrl+O open panel): /draft [list|save <name?> <text>|load <name>|delete <name>]`},{name:`queue`,handler:Ta,safe:!0,group:`ui`,description:`Open the queued-commands panel (≡ ctrl+q): /queue [list|remove <index>|move <index> <up|down>|clear]`},{name:`keybindings`,aliases:[`kb`],handler:(e,t)=>G([`keybindings`,...e],t),safe:!0,group:`ui`,deprecated:!0,description:`$1 (deprecated alias)`},{name:`shortcuts`,handler:(e,t)=>G([`shortcuts`,...e],t),safe:!0,group:`ui`,deprecated:!0,description:`$1 (deprecated alias)`},{name:`proxy`,handler:(e,t)=>G([`proxy`,...e],t),group:`ui`,deprecated:!0,description:`$1 (deprecated alias)`},{name:`help`,aliases:[`h`,`?`],safe:!0,engineBuiltin:!0,group:`other`,description:`Show available commands`,handler:async(e,t)=>Rr(e,t,$)},{name:`exit`,aliases:[`quit`,`q`],safe:!0,engineBuiltin:!0,group:`other`,tuiHidden:!0,description:`Exit the TUI; /exit --restart to restart into the same session`},{name:`abort`,engineBuiltin:!0,group:`other`,tuiHidden:!0,description:`Abort the current agent run`},{name:`pause`,aliases:[`continue`],handler:Aa,safe:!0,group:`other`,description:`Pause after current turn finishes (toggle with /continue)`},{name:`copy`,engineBuiltin:!0,group:`other`,tuiHidden:!0,description:`Copy last assistant response`},{name:`resume`,handler:En,group:`other`,description:`List and switch to an existing session (--workspace <id>, --archived, --all)`},{name:`rename`,handler:Tn,safe:!0,group:`session`,description:`Set a custom title for the current session (/rename <new title>)`},{name:`a2ui-action`,handler:Fn,safe:!1,group:`session`,description:`Trigger A2UI interactive component action (/a2ui-action btn1 click)`},{name:`reload`,handler:Dn,group:`other`,description:`Hot-reload capabilities (MCP / providers / declarative agents) without restart`},{name:`upgrade`,group:`other`,description:`Check for updates (/upgrade --check for extensions, /upgrade for otto CLI)`,handler:async(e,t)=>{if(e.includes(`--check`)){await Ur(e,t);return}await Lr(e,t)||await Ir(e,t)}},{name:`about`,handler:Di,safe:!0,group:`other`,description:`Show version, build, and environment info (/about)`},{name:`setup`,handler:sa,safe:!0,group:`other`,description:`Show onboarding progress (provider → login → model) with a jump-to-next-step button (/setup)`},{name:`extension`,aliases:[`extensions`,`ext`],handler:J,group:`other`,description:`Manage extensions: /extension [trust|install|registry|search|update] or open panel (RFC-367)`},{name:`install`,handler:(e,t)=>J([`install`,...e],t),safe:!0,group:`other`,deprecated:!0,description:`$1 (deprecated alias)`},{name:`registry`,handler:(e,t)=>J([`registry`,...e],t),safe:!0,group:`other`,deprecated:!0,description:`$1 (deprecated alias)`},{name:`search`,handler:(e,t)=>J([`search`,...e],t),safe:!0,group:`other`,deprecated:!0,description:`$1 (deprecated alias)`},{name:`permissions`,aliases:[`perms`],handler:Fr,safe:!0,group:`other`,description:`View / clear the always-allow list (/permissions [clear])`},{name:`feedback`,handler:Ai,group:`other`,description:`Report an issue or send feedback via GitHub (/feedback [--repo <owner/repo>])`},{name:`archive`,handler:kn,safe:!0,description:`Toggle archive state (archived disables further input); /archive [<id>]`},{name:`session`,handler:Nn,description:`Session management: /session fork | /session unlock <id> [--force] | /session kill <id> | /session inspect <id>`},{name:`fork`,handler:Bn,safe:!0,description:`Fork current session into a named branch`},{name:`pin`,aliases:[`unpin`],handler:An,safe:!0,description:`Toggle pin state (pinned sessions sort to top of /resume); /pin [<id>...] [--group <name>]`},{name:`history`,aliases:[`hist`],handler:zr,safe:!0,description:`Open history search panel (same panel as Ctrl+R)`},{name:`prompts`,handler:Vr,safe:!0,description:`View prompt log (list of submitted prompts this session)`}],Ba=new Set($.filter(e=>e.safe).flatMap(e=>[e.name,...e.aliases??[]])),Va=new Set($.filter(e=>e.engineBuiltin).flatMap(e=>[e.name,...e.aliases??[]])),Ha=new Set($.filter(e=>e.handler).flatMap(e=>[e.name,...e.aliases??[]]));async function Ua(e,t,n){let r=$.find(t=>t.name===e);return r||=$.find(t=>t.aliases?.includes(e)),r?.handler?(await r.handler(t,n),!0):!1}export{Lt as $,Yn as A,qe as B,W as C,or as D,ar as E,mn as F,nn as G,tt as H,fn as I,F as J,Gt as K,dn as L,yn as M,z as N,Qn as O,pn as P,Wt as Q,ln as R,sr as S,nr as T,I as U,Ye as V,rn as W,qt as X,Kt as Y,Xt as Z,Wr as _,Ra as a,Et as at,fr as b,ta as c,Hi as d,It as et,Li as f,ti as g,Y as h,$ as i,Dt as it,Zn as j,Xn as k,na as l,oi as m,Va as n,At as nt,Ua as o,bt as ot,xi as p,Jt as q,Ba as r,Ot as rt,la as s,Ha as t,kt as tt,Ui as u,_r as v,ir as w,ur as x,lr as y,cn as z};
21
+ //# sourceMappingURL=command-dispatcher-Ce1esmvV.js.map