@robota-sdk/agent-command 3.0.0-beta.84 → 3.0.0-beta.85

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/CHANGELOG.md CHANGED
@@ -1,5 +1,47 @@
1
1
  # @robota-sdk/agent-command
2
2
 
3
+ ## 3.0.0-beta.85
4
+
5
+ ### Patch Changes
6
+
7
+ - 3c1967f: Reloading plugins updates the live session's skill routing and model skill catalogue together
8
+ with command completion. Disabled plugins stop being executable after reload, and unreadable
9
+ settings clear the plugin skill snapshot. Hook changes require a new session.
10
+ - db35dcd: MCP approvals now outlive the process, and an approval takes effect at once. The `robota` CLI keeps
11
+ activation decisions in `~/.robota/mcp-approvals.json` (owner-only) unless the host passes its own
12
+ `mcpApprovalStore`, so an approved server connects at later starts until its definition changes.
13
+ `/mcp approve <server>` now also connects the server in the running session, the way `/mcp reload`
14
+ does, instead of waiting for a restart. A remote server without OAuth therefore connects once
15
+ approved; stdio servers still need a host-supplied authority.
16
+ - 4cee6fb: Report unsupported MCP transports at startup and reload instead of silently skipping them,
17
+ and distinguish plugin MCP declaration inspection from a runtime connection.
18
+ - 043fd27: In `plan` mode the model can no longer save project memory with `/memory add`. The command is auto-approved, so it ran in plan mode while `Write` and `Edit` were denied there. Reading memory, and adding it by hand, still work in plan mode.
19
+ - 6ee8725: A user settings file that does not parse no longer reads as "no plugin is disabled". Plugin settings
20
+ now refuse to read it: no plugin loads (skills, commands, hooks and themes alike), a plugin command
21
+ such as `/plugin enable` fails instead of rewriting the whole settings file with the plugin keys
22
+ alone, and `robota doctor` reports the plugin check as failed while still inspecting each installed
23
+ plugin. The CLI already refuses to start with such a file; this covers a session started later in
24
+ the same process.
25
+ - Updated dependencies [4e11579]
26
+ - Updated dependencies [41cca13]
27
+ - Updated dependencies [193a0bc]
28
+ - Updated dependencies [54e2848]
29
+ - Updated dependencies [3c1967f]
30
+ - Updated dependencies [ada3841]
31
+ - Updated dependencies [5093a30]
32
+ - Updated dependencies [5684612]
33
+ - Updated dependencies [6ee8725]
34
+ - Updated dependencies [6072e9a]
35
+ - Updated dependencies [94b2c87]
36
+ - Updated dependencies [3ab2eca]
37
+ - Updated dependencies [2e07cad]
38
+ - @robota-sdk/agent-framework@3.0.0-beta.85
39
+ - @robota-sdk/agent-core@3.0.0-beta.85
40
+ - @robota-sdk/agent-interface-command@3.0.0-beta.85
41
+ - @robota-sdk/agent-preset@3.0.0-beta.85
42
+ - @robota-sdk/agent-interface-execution@3.0.0-beta.85
43
+ - @robota-sdk/agent-interface-session@3.0.0-beta.85
44
+
3
45
  ## 3.0.0-beta.84
4
46
 
5
47
  ### Patch Changes
@@ -18,7 +18,7 @@ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});let e=require
18
18
  `));case`recover`:return D(t,()=>e.recover(),e=>[`Recovered. New signing key ${E(e.signingKeyId)}; ${e.revokedSigningKeyCount} old signing key(s) revoked.`,`This device (${E(e.deviceId)}) is certified again.`,...e.droppedDeviceCount>0?[`${e.droppedDeviceCount} other device(s) were certified by a retired signing key and must enrol again.`]:[]].join(`
19
19
  `));case`revoke`:return o.length===0?{success:!1,message:`Usage: /devices revoke <device-id>`}:D(t,()=>e.revoke(o),e=>`Revoked ${e.name} (${E(e.deviceId)}). A new roster and revocation list were issued.`);case`add`:return D(t,()=>e.add(),e=>[`Enrolled ${e.name} (${E(e.deviceId)}). A new roster was issued.`,...e.confirmed?[]:["The new device did not confirm it kept its identity; check `/devices` there."]].join(`
20
20
  `));case`join`:return D(t,()=>e.join(o.length>0?{name:o}:{}),e=>[`Joined the devices of user ${E(e.userId)}. This device: ${e.name} (${E(e.deviceId)}).`,...e.keyStorage===void 0?[]:[`Private keys are kept in: ${e.keyStorage}.`]].join(`
21
- `));default:return{success:!1,message:`Unknown argument "${a}". Usage: /devices [list|init [name]|add|join [name]|revoke <device-id>|recover]`}}}var ct=class{name=`devices`;getCommands(){return[et()]}};function lt(e){let t=T(et(),{requiresPermission:!1,lifecycle:`inline`,execute:(t,n)=>st(e,t,n)});return{name:`agent-command-devices`,commandSources:[new ct],systemCommands:[t]}}const ut=3e3;function dt(e,t){return new Promise(n=>{let i=Date.now(),a=(0,r.createConnection)({host:e,port:t}),o=setTimeout(()=>{a.destroy(),n({reachable:!1,error:`timeout (${ut/1e3}s)`})},ut);a.on(`connect`,()=>{clearTimeout(o),a.destroy(),n({reachable:!0,elapsedMs:Date.now()-i})}),a.on(`error`,e=>{clearTimeout(o),n({reachable:!1,error:e.message})})})}function ft(e){if(!(0,n.existsSync)(e))return{exists:!1,isDirectory:!1,writable:!1};let t;try{t=(0,n.statSync)(e)}catch{return{exists:!0,isDirectory:!1,writable:!1}}let r=t.isDirectory(),i=t.mode&511,a=!1;try{(0,n.accessSync)(e,n.constants.W_OK),a=!0}catch{a=!1}return{exists:!0,isDirectory:r,writable:a,mode:i}}function pt(e,t=process.env){let r=e.trim().split(/\s+/)[0];if(r===void 0||r.length===0)return!1;if((0,i.isAbsolute)(r)||r.includes(`/`))return(0,n.existsSync)(r);let a=process.platform===`win32`?[``,`.exe`,`.cmd`,`.bat`]:[``];return(t.PATH??``).split(i.delimiter).filter(e=>e.length>0).some(e=>a.some(t=>(0,n.existsSync)((0,i.join)(e,r+t))))}function mt(e=process.env){return{probeEndpoint:dt,inspectPath:ft,resolveCommand:t=>pt(t,e),ownerOnlyGuarantee:()=>(0,a.ownerOnlyGuarantee)()}}const ht={ok:`✓`,warn:`⚠`,fail:`✗`,"not-configured":`○`,"not-probed":`–`};function gt(e,t){let n=[` ${ht[e.status]} ${e.label} [${e.id}] ${e.status}${e.cause===void 0?``:`: ${e.cause}`}`];e.path!==void 0&&n.push(` path: ${e.path}`);for(let t of e.detail??[])n.push(` ${t}`);if(e.repair!==void 0){let r=t.formatRepairCommand?.(e.repair);n.push(` repair: ${r??`request repair for ${e.repair} through your host`}`)}return n}function _t(e,t){let n=t.productName?.trim();return e.failCount===0&&e.warnCount===0?n?`✓ All checks passed. ${n} is ready to use.`:`✓ All checks passed.`:e.failCount>0?n?`✗ ${e.failCount} issue(s) found. Fix the items above to use ${n}.`:`✗ ${e.failCount} issue(s) found. Fix the items above before use.`:n?`⚠ ${e.warnCount} warning(s). ${n} may work but check the items above.`:`⚠ ${e.warnCount} warning(s). Check the items above.`}function vt(e,t=`Doctor`,n={}){let r=[``,t,``,...e.checks.flatMap(e=>gt(e,n)),``,_t(e,n)];return e.repairable.length>0&&r.push(` repairable: ${e.repairable.join(`, `)} — ${n.repairOffer??`ask your host to apply a repair`}`),r.push(``),r}const O=`[redacted]`,yt=/(\b[a-z][a-z0-9+.-]{0,31}:\/\/)([^\s/@]+)@/gi,bt=/\b(bearer)\s+[A-Za-z0-9._~+/=-]{8,}/gi,xt=/\b(?:sk-[A-Za-z0-9_-]{8,}|AIza[0-9A-Za-z_-]{20,}|ghp_[A-Za-z0-9]{20,}|xox[abprs]-[A-Za-z0-9-]{10,})\b/g,St=/\.\.\."[^"]*"\.\.\./g;function Ct(e){return e.replace(/[.*+?^${}()|[\]\\]/g,`\\$&`)}function wt(e,t=[]){let n=e,r=new Set;for(let e of t)typeof e!=`string`||e.length<4||r.has(e)||(r.add(e),n=n.replace(new RegExp(Ct(e),`g`),O));return n=n.replace(yt,`$1${O}@`),n=n.replace(bt,`$1 ${O}`),n=n.replace(xt,O),n}function Tt(t){return t instanceof e.SettingsParseError?`${t.name}: ${t.filePath} is not valid JSON (see the settings check)`:`${t.name}: ${t.message.replace(St,`…`)}`}function Et(e,t){let n=new Set,r=e=>{if(e!==void 0){if(e.startsWith(`$ENV:`)){let r=t[e.slice(5).trim()];r!==void 0&&n.add(r);return}n.add(e)}};for(let t of e)if(t!==void 0){r(t.provider?.apiKey);for(let e of Object.values(t.providers??{}))r(e.apiKey);for(let e of Object.values(t.env??{}))n.add(e)}return[...n]}function Dt(e){let t=(0,i.basename)((0,i.dirname)(e.kind===`host`?e.path:e.relativePath)).replace(/^\./,``);return`settings.${e.scope}.${t}`}function Ot(e){let t=e.settingsSources.find(t=>t.kind===`host`&&t.path===e.userSettingsPath);return t===void 0?void 0:Dt(t)}function kt(e){let t=e.cause;if(t===void 0)return e.state;switch(t.state){case`unreadable`:return t.errno===void 0?`unreadable`:`unreadable (${t.errno})`;case`invalid-json`:return t.offset===void 0?`invalid-json`:`invalid-json at offset ${t.offset}`;case`schema-invalid`:return`schema-invalid: ${(t.issues??[]).map(e=>`${e.path} (${e.code})`).join(`, `)}`;default:return t.state}}function At(e,t){return e.source.kind===`host`&&e.source.path===t.userSettingsPath&&e.state===`empty`}function jt(e,t){let n=Dt(e.source),r=e.source.kind===`host`?e.source.path:e.source.relativePath;if(e.state===`absent`)return{id:n,label:`Settings layer`,status:`not-configured`,path:r,cause:`absent`};if(e.state===`ok`)return{id:n,label:`Settings layer`,status:`ok`,path:r,cause:`ok`};let i=At(e,t);return{id:n,label:`Settings layer`,status:`fail`,path:r,cause:kt(e),detail:i?[`The file exists but holds nothing; rewriting it as {} loses no content.`]:[`Session start will refuse this configuration. Fix the file at the named path.`],...i?{repair:n}:{}}}function Mt(e){let t=[...e.provenance.map(e=>`${e.key}: ${e.rule} ← ${e.contributors.join(` → `)}`),...e.hookSources.map((e,t)=>`settings hook ${t+1}: ${e.event}/${e.type} ← ${e.source}`)];return e.partial?{id:`settings.merge`,label:`Merged settings`,status:`warn`,cause:`partial — a present layer is broken; session start will refuse this configuration`,detail:t.length===0?[`(no key declared by a healthy layer)`]:t}:{id:`settings.merge`,label:`Merged settings`,status:`ok`,cause:`${e.provenance.length} key(s) from ${e.layers.filter(e=>e.state===`ok`).length} layer(s)`,detail:t.length===0?[`(no settings declared)`]:t}}function Nt(t){let n=(0,e.inspectSettingsLayers)(t.settingsSources);return{inspection:n,checks:[...n.layers.map(e=>jt(e,t)),Mt(n)]}}function Pt(e){let t=e.source===`env-default`?`env-default via ${e.sourceEnvVar??`environment`}`:`settings profile`;return{id:`provider.resolution`,label:`Provider`,status:`ok`,cause:`${e.name} (${e.model}) — ${t}`}}function Ft(e,n){let r=(0,t.findProviderDefinition)(n.providerDefinitions,e.name),i=e.baseURL??r?.defaults?.baseURL;if(i!==void 0)try{let t=new URL(i),n=t.port===``?t.protocol===`http:`?80:443:Number(t.port);return{host:t.hostname,port:n,origin:e.baseURL===void 0?`definition defaults.baseURL`:`profile baseURL`}}catch{return}let a=r?.endpoint;return a===void 0?void 0:{...a,origin:`definition endpoint`}}async function It(e,t,n){let r=Ft(e,t);if(r===void 0)return{id:`provider.reachability`,label:`Provider reachability`,status:`warn`,cause:`not checked: ${e.name} declares no endpoint (no profile baseURL, defaults.baseURL or definition endpoint)`};let i=await n.probeEndpoint(r.host,r.port),a=`${r.host}:${r.port} (${r.origin})`;return i.reachable?{id:`provider.reachability`,label:`Provider reachability`,status:`ok`,cause:`${a} reachable in ${i.elapsedMs??0}ms`}:{id:`provider.reachability`,label:`Provider reachability`,status:`warn`,cause:`${a} unreachable: ${i.error??`connection failed`}`,detail:[`Check proxy settings, firewall, or the profile baseURL.`]}}async function Lt(t,n){let r;try{r=(0,e.readProviderSettings)(t.settingsSources,{providerDefinitions:t.providerDefinitions,env:{...t.env}})}catch(e){return{checks:[{id:`provider.resolution`,label:`Provider`,status:`fail`,cause:Tt(e instanceof Error?e:Error(String(e))),detail:[t.diagnosticGuidance?.providerResolution??`Configure a provider or set its API key environment variable.`]}]}}return{checks:[Pt(r),await It(r,t,n)],...r.apiKey===void 0?{}:{resolvedApiKey:r.apiKey}}}function Rt(e,t){let{root:n,sessions:r}=e.userStorage,i=[t.inspectPath(n),t.inspectPath(r)];return i.some(e=>!e.exists)?`missing`:i.some(e=>!e.isDirectory||!e.writable)?`unwritable`:t.ownerOnlyGuarantee()===`posix-mode`?i.some(e=>e.mode!==void 0&&(e.mode&63)!=0)?`too-open`:`ok`:`mode-not-probed`}function zt(e,t){let{root:n,sessions:r}=e.userStorage,i={id:`storage.user`,label:`User storage`,path:n};switch(Rt(e,t)){case`missing`:return{...i,status:`warn`,cause:`not initialized (created on first write)`,detail:[n,r],repair:`storage.user`};case`unwritable`:return{...i,status:`fail`,cause:`exists but is not a writable directory`,detail:[n,r]};case`too-open`:return{...i,status:`warn`,cause:`not owner-only (mode allows group/other access)`,detail:[n,r],repair:`storage.user`};case`mode-not-probed`:return{...i,status:`not-probed`,cause:`owner-only mode is not asserted on this platform (windows-acl)`};default:return{...i,status:`ok`,cause:`writable, owner-only`}}}function Bt(e,t){if(e.projectAccess.status!==`trusted`)return{id:`storage.project`,label:`Project storage`,status:`not-configured`,cause:`project sources are disabled in an untrusted workspace`};let n=e.projectStorageRoot;if(n===void 0)return{id:`storage.project`,label:`Project storage`,status:`not-configured`,cause:`the host names no project state root`};let r=t.inspectPath(n);return r.exists?r.isDirectory&&r.writable?{id:`storage.project`,label:`Project storage`,status:`ok`,path:n,cause:`writable`}:{id:`storage.project`,label:`Project storage`,status:`fail`,path:n,cause:`exists but is not a writable directory`}:{id:`storage.project`,label:`Project storage`,status:`not-configured`,path:n,cause:`absent (created on first write)`}}function Vt(e){let t=e.projectAccess;if(t.status===`trusted`)return{id:`workspace.trust`,label:`Workspace trust`,status:`ok`,path:t.identity.displayPath,cause:`trusted`};let n=t.cause===void 0?t.trustState:`${t.trustState}: ${t.cause.name}: ${t.cause.message}`;return{id:`workspace.trust`,label:`Workspace trust`,status:t.trustState===`store-unavailable`||t.trustState===`identity-unavailable`?`fail`:`warn`,...t.displayPath===void 0?{}:{path:t.displayPath},cause:n,detail:[e.diagnosticGuidance?.projectTrust??`Project sources are disabled. Approve this workspace with the host.`]}}function Ht(e){let t=new Map,n=!1;for(let r of e.layers)for(let[e,i]of Object.entries(r.settings?.providers??{})){let r=t.get(e);r?.apiKey!==void 0&&i.baseURL!==void 0&&i.baseURL!==r.baseURL&&i.apiKey===void 0&&(n=!0),t.set(e,{baseURL:i.baseURL??r?.baseURL,apiKey:i.apiKey??r?.apiKey})}return n?{id:`provider.security`,label:`Provider security`,status:`warn`,cause:`provider endpoint quarantined; inherited credential removed (credential redacted)`}:void 0}function Ut(e,t,n){let r=Ht(n);return[Vt(e),zt(e,t),Bt(e,t),...r===void 0?[]:[r]]}const Wt=`storage.user`;function Gt(e){let t=Ot(e);return t===void 0?[Wt]:[t,Wt]}function Kt(e,t){return Gt(t).includes(e)}function qt(t,n){let r=(0,e.inspectSettingsLayers)(n.settingsSources).layers.find(e=>Dt(e.source)===t);return r===void 0||r.source.kind!==`host`?{ok:!1,reason:`${t}: no user settings layer in this composition`}:At(r,n)?{ok:!0,plan:{id:t,description:`rewrite the empty user settings file as {}`,path:r.source.path}}:{ok:!1,reason:`${t}: state is ${r.state}; only an empty file is rewritten`}}function Jt(e,t){let n=Rt(e,t),{root:r}=e.userStorage;return n!==`missing`&&n!==`too-open`?{ok:!1,reason:`storage.user: state is ${n}; only a missing or too-open directory is repaired`}:{ok:!0,plan:{id:`storage.user`,description:`create the user store root and its sessions directory as owner-only directories`,path:r}}}function Yt(e,t,n){return Kt(e,t)?e===`storage.user`?Jt(t,n):qt(e,t):{ok:!1,reason:`${e}: not a repairable check (allowlist: ${Gt(t).join(`, `)})`}}async function Xt(t,n,r,i){let o=Yt(t,n,r);if(!o.ok)return{applied:!1,reason:o.reason};if(!await i(o.plan))return{applied:!1,reason:`${t}: repair not confirmed; nothing written`};let s=Yt(t,n,r);if(!s.ok)return{applied:!1,reason:`${s.reason} (state changed before the write)`};if(s.plan.id===`storage.user`){let{root:e,sessions:t}=n.userStorage;(0,a.ensureOwnerOnlyDirectory)(t,{withinRoot:e})}else(0,e.writeSettings)(s.plan.path,{});return{applied:!0,plan:s.plan}}const Zt={"manifest-unreadable":`manifest could not be parsed`,"manifest-invalid":`manifest is not a valid plugin.json (name, version, description required)`,"load-failed":`plugin assets could not be loaded`};function Qt(e){let t=[],n=e.reduce((e,t)=>e+t.loaded.length,0),r=e.filter(e=>e.cacheDirPresent);t.push(r.length===0?{id:`plugins`,label:`Plugins`,status:`not-configured`,cause:`no plugin cache directory`,detail:e.map(e=>e.pluginsDir)}:{id:`plugins`,label:`Plugins`,status:`ok`,cause:`${n} plugin(s) loaded`,detail:r.map(e=>`${e.pluginsDir}: ${e.loaded.length} loaded, ${e.skipped.length} skipped`)});for(let n of e){for(let e of n.skipped)e.reason!==`disabled`&&t.push({id:`plugin.${e.pluginId}`,label:`Plugin`,status:`fail`,path:e.manifestPath,cause:Zt[e.reason]??e.reason,...e.detail===void 0?{}:{detail:[e.detail]}});for(let e of n.hookIssues)t.push({id:`plugin.${e.pluginId}.hooks`,label:`Plugin hooks`,status:`warn`,path:e.hooksPath,cause:`hooks.json fails the hooks schema: ${e.issues.map(e=>`${e.path} (${e.code})`).join(`, `)}`,detail:[`Report-only: the plugin still loads; these hooks may not run.`]})}return t}function $t(t){let n=(0,e.inspectSkillSources)(t.contributionSources,t.skillRoots).roots.filter(e=>e.present),r=n.reduce((e,t)=>e+t.discovered.length,0),i=[n.length===0?{id:`skills`,label:`Skills and commands`,status:`not-configured`,cause:`no skill or command root present`}:{id:`skills`,label:`Skills and commands`,status:`ok`,cause:`${r} discovered`,detail:n.map(e=>`${e.sourceDisplayName}: ${e.root} (${e.discovered.length})`)}];for(let e of n)for(let t of e.skipped)i.push({id:`skill.${t.path}`,label:`Skill definition`,status:t.reason===`frontmatter-invalid`?`fail`:`warn`,path:`${e.sourceDisplayName}: ${t.path}`,cause:t.reason,...t.detail===void 0?{}:{detail:[t.detail]}});return i}function en(e,t){let n=[],r=e=>{if(e!==void 0)for(let t of Object.values(e))for(let e of t??[])for(let t of e.hooks??[])t.type===`command`&&typeof t.command==`string`&&n.push(t.command)};r(e.merged.hooks);for(let e of t)for(let t of e.loaded)r(t.hooks);return n}function tn(e,t,n){let r=en(e,t),i=r.filter(e=>!n.resolveCommand(e));return[r.length===0?{id:`hooks`,label:`Hooks`,status:`not-configured`,cause:`no command hooks configured`}:i.length===0?{id:`hooks`,label:`Hooks`,status:`ok`,cause:`${r.length} command hook(s); every executable resolves`}:{id:`hooks`,label:`Hooks`,status:`warn`,cause:`${i.length} command hook executable(s) not found on PATH`,detail:i.map(e=>e.split(/\s+/)[0]??e)},{id:`hooks.execution`,label:`Hook execution`,status:`not-probed`,cause:`the doctor does not run hooks`}]}function nn(e,t){let n=`mcp.plugin.${e.pluginId}.${e.name}`;if(e.transport===`stdio`&&e.command!==void 0)return t.resolveCommand(e.command)?{id:n,label:`MCP server (plugin)`,status:`ok`,path:e.mcpPath,cause:`stdio command ${e.command} resolves`}:{id:n,label:`MCP server (plugin)`,status:`warn`,path:e.mcpPath,cause:`stdio command ${e.command} not found on PATH`,detail:e.envKeys.length===0?[]:[`env keys: ${e.envKeys.join(`, `)}`]};if(e.transport===`http`&&e.url!==void 0)try{return new URL(e.url),{id:n,label:`MCP server (plugin)`,status:`ok`,path:e.mcpPath,cause:`url ${e.url}`}}catch{return{id:n,label:`MCP server (plugin)`,status:`warn`,path:e.mcpPath,cause:`url is not parseable`}}return{id:n,label:`MCP server (plugin)`,status:`warn`,path:e.mcpPath,cause:`neither command nor url declared`}}function rn(e,t,n){let r=[];if(e.mcpActivation===void 0)r.push({id:`mcp.activation`,label:`MCP activation`,status:`not-configured`,cause:`this CLI composes no MCP activation adapter`});else{let t=e.mcpActivation.list();r.push({id:`mcp.activation`,label:`MCP activation`,status:`ok`,cause:`${t.length} server(s) known`});for(let e of t)r.push({id:`mcp.${e.serverId}`,label:`MCP server`,status:e.allowed?`ok`:`warn`,cause:`${e.status} (${e.source}): ${e.reason}`})}for(let e of t){for(let t of e.mcpServers)r.push(nn(t,n));for(let t of e.mcpFaults)r.push({id:`mcp.plugin.${t.pluginId}`,label:`MCP declaration (plugin)`,status:`warn`,path:t.mcpPath,cause:`.mcp.json ${t.reason}`})}return r.push({id:`mcp.connection`,label:`MCP connection`,status:`not-probed`,cause:`the doctor does not connect to MCP servers`}),r}function an(t,n,r){let i=(0,e.loadHostBundlePluginInspectionFromScopes)(t.pluginsDirs,{settingsPath:t.userSettingsPath});return[...Qt(i),...$t(t),...tn(r,i,n),...rn(t,i,n)]}function on(e,t,n){return{id:e,label:t,status:`fail`,cause:Tt(n)}}async function sn(e,t,n,r){try{return r(await n())}catch(n){return[on(e,t,n instanceof Error?n:Error(String(n)))]}}function cn(e,t){let n=e=>wt(e,t);return{...e,label:n(e.label),...e.path===void 0?{}:{path:n(e.path)},...e.cause===void 0?{}:{cause:n(e.cause)},...e.detail===void 0?{}:{detail:e.detail.map(n)}}}function ln(e){let t=e.filter(e=>e.status===`fail`).length;return{checks:e,failCount:t,warnCount:e.filter(e=>e.status===`warn`).length,repairable:e.flatMap(e=>e.repair===void 0?[]:[e.repair]),exitCode:t===0?0:1}}function un(e){try{let t=Nt(e);return{checks:t.checks,result:t}}catch(e){return{checks:[on(`settings`,`Settings`,e instanceof Error?e:Error(String(e)))]}}}async function dn(e,t){let n=[...e.hostChecks];e.compositionFailure!==void 0&&n.push(e.compositionFailure);let r=un(e);n.push(...r.checks);let i=r.result?.inspection,a=Et((i?.layers??[]).map(e=>e.settings),e.env);return n.push(...await sn(`provider`,`Provider`,()=>Lt(e,t),e=>(e.resolvedApiKey!==void 0&&a.push(e.resolvedApiKey),e.checks))),i!==void 0&&(n.push(...await sn(`storage`,`Storage`,()=>Ut(e,t,i),e=>e)),n.push(...await sn(`extensions`,`Extensions`,()=>an(e,t,i),e=>e))),ln(n.map(e=>cn(e,a)))}function fn(){return{name:`doctor`,displayName:`Doctor`,description:"Diagnose configuration and runtime readiness; `repair <check-id>` applies an allowlisted fix",source:`doctor`,modelInvocable:!1,userInvocable:!0,argumentHint:`[repair <check-id>]`}}var pn=class{name=`doctor`;getCommands(){return[fn()]}};async function mn(e,n){let r=e.getUserInteraction();if(r===void 0)return!1;let i=await r.ask((0,t.confirmAction)(`doctor-repair:${n.id}`,`Repair ${n.id}?`,{description:`${n.description} (${n.path})`,defaultYes:!1}));return i.type===`answer`&&i.values[0]===`yes`}async function hn(e,t,n,r,i){let a=await Xt(e,t,n,e=>mn(r,e));if(!a.applied)return{success:!1,message:a.reason,data:{repair:e,applied:!1}};let o=await dn(t,n),s=o.checks.find(t=>t.id===e);return{success:!0,message:[`Repaired ${e}: ${a.plan.description}.`,...vt(o,`${i.title??`Doctor`} (after repair)`,i)].join(`
21
+ `));default:return{success:!1,message:`Unknown argument "${a}". Usage: /devices [list|init [name]|add|join [name]|revoke <device-id>|recover]`}}}var ct=class{name=`devices`;getCommands(){return[et()]}};function lt(e){let t=T(et(),{requiresPermission:!1,lifecycle:`inline`,execute:(t,n)=>st(e,t,n)});return{name:`agent-command-devices`,commandSources:[new ct],systemCommands:[t]}}const ut=3e3;function dt(e,t){return new Promise(n=>{let i=Date.now(),a=(0,r.createConnection)({host:e,port:t}),o=setTimeout(()=>{a.destroy(),n({reachable:!1,error:`timeout (${ut/1e3}s)`})},ut);a.on(`connect`,()=>{clearTimeout(o),a.destroy(),n({reachable:!0,elapsedMs:Date.now()-i})}),a.on(`error`,e=>{clearTimeout(o),n({reachable:!1,error:e.message})})})}function ft(e){if(!(0,n.existsSync)(e))return{exists:!1,isDirectory:!1,writable:!1};let t;try{t=(0,n.statSync)(e)}catch{return{exists:!0,isDirectory:!1,writable:!1}}let r=t.isDirectory(),i=t.mode&511,a=!1;try{(0,n.accessSync)(e,n.constants.W_OK),a=!0}catch{a=!1}return{exists:!0,isDirectory:r,writable:a,mode:i}}function pt(e,t=process.env){let r=e.trim().split(/\s+/)[0];if(r===void 0||r.length===0)return!1;if((0,i.isAbsolute)(r)||r.includes(`/`))return(0,n.existsSync)(r);let a=process.platform===`win32`?[``,`.exe`,`.cmd`,`.bat`]:[``];return(t.PATH??``).split(i.delimiter).filter(e=>e.length>0).some(e=>a.some(t=>(0,n.existsSync)((0,i.join)(e,r+t))))}function mt(e=process.env){return{probeEndpoint:dt,inspectPath:ft,resolveCommand:t=>pt(t,e),ownerOnlyGuarantee:()=>(0,a.ownerOnlyGuarantee)()}}const ht={ok:`✓`,warn:`⚠`,fail:`✗`,"not-configured":`○`,"not-probed":`–`};function gt(e,t){let n=[` ${ht[e.status]} ${e.label} [${e.id}] ${e.status}${e.cause===void 0?``:`: ${e.cause}`}`];e.path!==void 0&&n.push(` path: ${e.path}`);for(let t of e.detail??[])n.push(` ${t}`);if(e.repair!==void 0){let r=t.formatRepairCommand?.(e.repair);n.push(` repair: ${r??`request repair for ${e.repair} through your host`}`)}return n}function _t(e,t){let n=t.productName?.trim();return e.failCount===0&&e.warnCount===0?n?`✓ All checks passed. ${n} is ready to use.`:`✓ All checks passed.`:e.failCount>0?n?`✗ ${e.failCount} issue(s) found. Fix the items above to use ${n}.`:`✗ ${e.failCount} issue(s) found. Fix the items above before use.`:n?`⚠ ${e.warnCount} warning(s). ${n} may work but check the items above.`:`⚠ ${e.warnCount} warning(s). Check the items above.`}function vt(e,t=`Doctor`,n={}){let r=[``,t,``,...e.checks.flatMap(e=>gt(e,n)),``,_t(e,n)];return e.repairable.length>0&&r.push(` repairable: ${e.repairable.join(`, `)} — ${n.repairOffer??`ask your host to apply a repair`}`),r.push(``),r}const O=`[redacted]`,yt=/(\b[a-z][a-z0-9+.-]{0,31}:\/\/)([^\s/@]+)@/gi,bt=/\b(bearer)\s+[A-Za-z0-9._~+/=-]{8,}/gi,xt=/\b(?:sk-[A-Za-z0-9_-]{8,}|AIza[0-9A-Za-z_-]{20,}|ghp_[A-Za-z0-9]{20,}|xox[abprs]-[A-Za-z0-9-]{10,})\b/g,St=/\.\.\."[^"]*"\.\.\./g;function Ct(e){return e.replace(/[.*+?^${}()|[\]\\]/g,`\\$&`)}function wt(e,t=[]){let n=e,r=new Set;for(let e of t)typeof e!=`string`||e.length<4||r.has(e)||(r.add(e),n=n.replace(new RegExp(Ct(e),`g`),O));return n=n.replace(yt,`$1${O}@`),n=n.replace(bt,`$1 ${O}`),n=n.replace(xt,O),n}function Tt(t){return t instanceof e.SettingsParseError?`${t.name}: ${t.filePath} is not valid JSON (see the settings check)`:`${t.name}: ${t.message.replace(St,`…`)}`}function Et(e,t){let n=new Set,r=e=>{if(e!==void 0){if(e.startsWith(`$ENV:`)){let r=t[e.slice(5).trim()];r!==void 0&&n.add(r);return}n.add(e)}};for(let t of e)if(t!==void 0){r(t.provider?.apiKey);for(let e of Object.values(t.providers??{}))r(e.apiKey);for(let e of Object.values(t.env??{}))n.add(e)}return[...n]}function Dt(e){let t=(0,i.basename)((0,i.dirname)(e.kind===`host`?e.path:e.relativePath)).replace(/^\./,``);return`settings.${e.scope}.${t}`}function Ot(e){let t=e.settingsSources.find(t=>t.kind===`host`&&t.path===e.userSettingsPath);return t===void 0?void 0:Dt(t)}function kt(e){let t=e.cause;if(t===void 0)return e.state;switch(t.state){case`unreadable`:return t.errno===void 0?`unreadable`:`unreadable (${t.errno})`;case`invalid-json`:return t.offset===void 0?`invalid-json`:`invalid-json at offset ${t.offset}`;case`schema-invalid`:return`schema-invalid: ${(t.issues??[]).map(e=>`${e.path} (${e.code})`).join(`, `)}`;default:return t.state}}function At(e,t){return e.source.kind===`host`&&e.source.path===t.userSettingsPath&&e.state===`empty`}function jt(e,t){let n=Dt(e.source),r=e.source.kind===`host`?e.source.path:e.source.relativePath;if(e.state===`absent`)return{id:n,label:`Settings layer`,status:`not-configured`,path:r,cause:`absent`};if(e.state===`ok`)return{id:n,label:`Settings layer`,status:`ok`,path:r,cause:`ok`};let i=At(e,t);return{id:n,label:`Settings layer`,status:`fail`,path:r,cause:kt(e),detail:i?[`The file exists but holds nothing; rewriting it as {} loses no content.`]:[`Session start will refuse this configuration. Fix the file at the named path.`],...i?{repair:n}:{}}}function Mt(e){let t=[...e.provenance.map(e=>`${e.key}: ${e.rule} ← ${e.contributors.join(` → `)}`),...e.hookSources.map((e,t)=>`settings hook ${t+1}: ${e.event}/${e.type} ← ${e.source}`)];return e.partial?{id:`settings.merge`,label:`Merged settings`,status:`warn`,cause:`partial — a present layer is broken; session start will refuse this configuration`,detail:t.length===0?[`(no key declared by a healthy layer)`]:t}:{id:`settings.merge`,label:`Merged settings`,status:`ok`,cause:`${e.provenance.length} key(s) from ${e.layers.filter(e=>e.state===`ok`).length} layer(s)`,detail:t.length===0?[`(no settings declared)`]:t}}function Nt(t){let n=(0,e.inspectSettingsLayers)(t.settingsSources);return{inspection:n,checks:[...n.layers.map(e=>jt(e,t)),Mt(n)]}}function Pt(e){let t=e.source===`env-default`?`env-default via ${e.sourceEnvVar??`environment`}`:`settings profile`;return{id:`provider.resolution`,label:`Provider`,status:`ok`,cause:`${e.name} (${e.model}) — ${t}`}}function Ft(e,n){let r=(0,t.findProviderDefinition)(n.providerDefinitions,e.name),i=e.baseURL??r?.defaults?.baseURL;if(i!==void 0)try{let t=new URL(i),n=t.port===``?t.protocol===`http:`?80:443:Number(t.port);return{host:t.hostname,port:n,origin:e.baseURL===void 0?`definition defaults.baseURL`:`profile baseURL`}}catch{return}let a=r?.endpoint;return a===void 0?void 0:{...a,origin:`definition endpoint`}}async function It(e,t,n){let r=Ft(e,t);if(r===void 0)return{id:`provider.reachability`,label:`Provider reachability`,status:`warn`,cause:`not checked: ${e.name} declares no endpoint (no profile baseURL, defaults.baseURL or definition endpoint)`};let i=await n.probeEndpoint(r.host,r.port),a=`${r.host}:${r.port} (${r.origin})`;return i.reachable?{id:`provider.reachability`,label:`Provider reachability`,status:`ok`,cause:`${a} reachable in ${i.elapsedMs??0}ms`}:{id:`provider.reachability`,label:`Provider reachability`,status:`warn`,cause:`${a} unreachable: ${i.error??`connection failed`}`,detail:[`Check proxy settings, firewall, or the profile baseURL.`]}}async function Lt(t,n){let r;try{r=(0,e.readProviderSettings)(t.settingsSources,{providerDefinitions:t.providerDefinitions,env:{...t.env}})}catch(e){return{checks:[{id:`provider.resolution`,label:`Provider`,status:`fail`,cause:Tt(e instanceof Error?e:Error(String(e))),detail:[t.diagnosticGuidance?.providerResolution??`Configure a provider or set its API key environment variable.`]}]}}return{checks:[Pt(r),await It(r,t,n)],...r.apiKey===void 0?{}:{resolvedApiKey:r.apiKey}}}function Rt(e,t){let{root:n,sessions:r}=e.userStorage,i=[t.inspectPath(n),t.inspectPath(r)];return i.some(e=>!e.exists)?`missing`:i.some(e=>!e.isDirectory||!e.writable)?`unwritable`:t.ownerOnlyGuarantee()===`posix-mode`?i.some(e=>e.mode!==void 0&&(e.mode&63)!=0)?`too-open`:`ok`:`mode-not-probed`}function zt(e,t){let{root:n,sessions:r}=e.userStorage,i={id:`storage.user`,label:`User storage`,path:n};switch(Rt(e,t)){case`missing`:return{...i,status:`warn`,cause:`not initialized (created on first write)`,detail:[n,r],repair:`storage.user`};case`unwritable`:return{...i,status:`fail`,cause:`exists but is not a writable directory`,detail:[n,r]};case`too-open`:return{...i,status:`warn`,cause:`not owner-only (mode allows group/other access)`,detail:[n,r],repair:`storage.user`};case`mode-not-probed`:return{...i,status:`not-probed`,cause:`owner-only mode is not asserted on this platform (windows-acl)`};default:return{...i,status:`ok`,cause:`writable, owner-only`}}}function Bt(e,t){if(e.projectAccess.status!==`trusted`)return{id:`storage.project`,label:`Project storage`,status:`not-configured`,cause:`project sources are disabled in an untrusted workspace`};let n=e.projectStorageRoot;if(n===void 0)return{id:`storage.project`,label:`Project storage`,status:`not-configured`,cause:`the host names no project state root`};let r=t.inspectPath(n);return r.exists?r.isDirectory&&r.writable?{id:`storage.project`,label:`Project storage`,status:`ok`,path:n,cause:`writable`}:{id:`storage.project`,label:`Project storage`,status:`fail`,path:n,cause:`exists but is not a writable directory`}:{id:`storage.project`,label:`Project storage`,status:`not-configured`,path:n,cause:`absent (created on first write)`}}function Vt(e){let t=e.projectAccess;if(t.status===`trusted`)return{id:`workspace.trust`,label:`Workspace trust`,status:`ok`,path:t.identity.displayPath,cause:`trusted`};let n=t.cause===void 0?t.trustState:`${t.trustState}: ${t.cause.name}: ${t.cause.message}`;return{id:`workspace.trust`,label:`Workspace trust`,status:t.trustState===`store-unavailable`||t.trustState===`identity-unavailable`?`fail`:`warn`,...t.displayPath===void 0?{}:{path:t.displayPath},cause:n,detail:[e.diagnosticGuidance?.projectTrust??`Project sources are disabled. Approve this workspace with the host.`]}}function Ht(e){let t=new Map,n=!1;for(let r of e.layers)for(let[e,i]of Object.entries(r.settings?.providers??{})){let r=t.get(e);r?.apiKey!==void 0&&i.baseURL!==void 0&&i.baseURL!==r.baseURL&&i.apiKey===void 0&&(n=!0),t.set(e,{baseURL:i.baseURL??r?.baseURL,apiKey:i.apiKey??r?.apiKey})}return n?{id:`provider.security`,label:`Provider security`,status:`warn`,cause:`provider endpoint quarantined; inherited credential removed (credential redacted)`}:void 0}function Ut(e,t,n){let r=Ht(n);return[Vt(e),zt(e,t),Bt(e,t),...r===void 0?[]:[r]]}const Wt=`storage.user`;function Gt(e){let t=Ot(e);return t===void 0?[Wt]:[t,Wt]}function Kt(e,t){return Gt(t).includes(e)}function qt(t,n){let r=(0,e.inspectSettingsLayers)(n.settingsSources).layers.find(e=>Dt(e.source)===t);return r===void 0||r.source.kind!==`host`?{ok:!1,reason:`${t}: no user settings layer in this composition`}:At(r,n)?{ok:!0,plan:{id:t,description:`rewrite the empty user settings file as {}`,path:r.source.path}}:{ok:!1,reason:`${t}: state is ${r.state}; only an empty file is rewritten`}}function Jt(e,t){let n=Rt(e,t),{root:r}=e.userStorage;return n!==`missing`&&n!==`too-open`?{ok:!1,reason:`storage.user: state is ${n}; only a missing or too-open directory is repaired`}:{ok:!0,plan:{id:`storage.user`,description:`create the user store root and its sessions directory as owner-only directories`,path:r}}}function Yt(e,t,n){return Kt(e,t)?e===`storage.user`?Jt(t,n):qt(e,t):{ok:!1,reason:`${e}: not a repairable check (allowlist: ${Gt(t).join(`, `)})`}}async function Xt(t,n,r,i){let o=Yt(t,n,r);if(!o.ok)return{applied:!1,reason:o.reason};if(!await i(o.plan))return{applied:!1,reason:`${t}: repair not confirmed; nothing written`};let s=Yt(t,n,r);if(!s.ok)return{applied:!1,reason:`${s.reason} (state changed before the write)`};if(s.plan.id===`storage.user`){let{root:e,sessions:t}=n.userStorage;(0,a.ensureOwnerOnlyDirectory)(t,{withinRoot:e})}else(0,e.writeSettings)(s.plan.path,{});return{applied:!0,plan:s.plan}}const Zt={"manifest-unreadable":`manifest could not be parsed`,"manifest-invalid":`manifest is not a valid plugin.json (name, version, description required)`,"load-failed":`plugin assets could not be loaded`};function Qt(e){let t=[],n=e.reduce((e,t)=>e+t.loaded.length,0),r=e.filter(e=>e.cacheDirPresent);t.push(r.length===0?{id:`plugins`,label:`Plugins`,status:`not-configured`,cause:`no plugin cache directory`,detail:e.map(e=>e.pluginsDir)}:{id:`plugins`,label:`Plugins`,status:`ok`,cause:`${n} plugin(s) loaded`,detail:r.map(e=>`${e.pluginsDir}: ${e.loaded.length} loaded, ${e.skipped.length} skipped`)});for(let n of e){for(let e of n.skipped)e.reason!==`disabled`&&t.push({id:`plugin.${e.pluginId}`,label:`Plugin`,status:`fail`,path:e.manifestPath,cause:Zt[e.reason]??e.reason,...e.detail===void 0?{}:{detail:[e.detail]}});for(let e of n.hookIssues)t.push({id:`plugin.${e.pluginId}.hooks`,label:`Plugin hooks`,status:`warn`,path:e.hooksPath,cause:`hooks.json fails the hooks schema: ${e.issues.map(e=>`${e.path} (${e.code})`).join(`, `)}`,detail:[`Report-only: the plugin still loads; these hooks may not run.`]})}return t}function $t(t){let n=(0,e.inspectSkillSources)(t.contributionSources,t.skillRoots).roots.filter(e=>e.present),r=n.reduce((e,t)=>e+t.discovered.length,0),i=[n.length===0?{id:`skills`,label:`Skills and commands`,status:`not-configured`,cause:`no skill or command root present`}:{id:`skills`,label:`Skills and commands`,status:`ok`,cause:`${r} discovered`,detail:n.map(e=>`${e.sourceDisplayName}: ${e.root} (${e.discovered.length})`)}];for(let e of n)for(let t of e.skipped)i.push({id:`skill.${t.path}`,label:`Skill definition`,status:t.reason===`frontmatter-invalid`?`fail`:`warn`,path:`${e.sourceDisplayName}: ${t.path}`,cause:t.reason,...t.detail===void 0?{}:{detail:[t.detail]}});return i}function en(e,t){let n=[],r=e=>{if(e!==void 0)for(let t of Object.values(e))for(let e of t??[])for(let t of e.hooks??[])t.type===`command`&&typeof t.command==`string`&&n.push(t.command)};r(e.merged.hooks);for(let e of t)for(let t of e.loaded)r(t.hooks);return n}function tn(e,t,n){let r=en(e,t),i=r.filter(e=>!n.resolveCommand(e));return[r.length===0?{id:`hooks`,label:`Hooks`,status:`not-configured`,cause:`no command hooks configured`}:i.length===0?{id:`hooks`,label:`Hooks`,status:`ok`,cause:`${r.length} command hook(s); every executable resolves`}:{id:`hooks`,label:`Hooks`,status:`warn`,cause:`${i.length} command hook executable(s) not found on PATH`,detail:i.map(e=>e.split(/\s+/)[0]??e)},{id:`hooks.execution`,label:`Hook execution`,status:`not-probed`,cause:`the doctor does not run hooks`}]}function nn(e,t){let n=`mcp.plugin.${e.pluginId}.${e.name}`,r=[`Declaration only: plugin .mcp.json is not a runtime source. Copy a supported definition to mcpServers in settings, then use /mcp approve <name>.`];if(e.transport===`stdio`&&e.command!==void 0)return t.resolveCommand(e.command)?{id:n,label:`MCP declaration (plugin)`,status:`warn`,path:e.mcpPath,cause:`stdio command ${e.command} resolves`,detail:r}:{id:n,label:`MCP declaration (plugin)`,status:`warn`,path:e.mcpPath,cause:`stdio command ${e.command} not found on PATH`,detail:[...r,...e.envKeys.length===0?[]:[`env keys: ${e.envKeys.join(`, `)}`]]};if(e.transport===`http`&&e.url!==void 0)try{return new URL(e.url),{id:n,label:`MCP declaration (plugin)`,status:`warn`,path:e.mcpPath,cause:`url ${e.url}`,detail:r}}catch{return{id:n,label:`MCP declaration (plugin)`,status:`warn`,path:e.mcpPath,cause:`url is not parseable`,detail:r}}return{id:n,label:`MCP declaration (plugin)`,status:`warn`,path:e.mcpPath,cause:`neither command nor url declared`,detail:r}}function rn(e,t,n){let r=[];if(e.mcpActivation===void 0)r.push({id:`mcp.activation`,label:`MCP activation`,status:`not-configured`,cause:`this CLI composes no MCP activation adapter`});else{let t=e.mcpActivation.list();r.push({id:`mcp.activation`,label:`MCP activation`,status:`ok`,cause:`${t.length} server(s) known`});for(let e of t)r.push({id:`mcp.${e.serverId}`,label:`MCP server`,status:e.allowed?`ok`:`warn`,cause:`${e.status} (${e.source}): ${e.reason}`})}for(let e of t){for(let t of e.mcpServers)r.push(nn(t,n));for(let t of e.mcpFaults)r.push({id:`mcp.plugin.${t.pluginId}`,label:`MCP declaration (plugin)`,status:`warn`,path:t.mcpPath,cause:`.mcp.json ${t.reason}`})}return r.push({id:`mcp.connection`,label:`MCP connection`,status:`not-probed`,cause:`the doctor does not connect to MCP servers`}),r}function an(t,n,r){let i,a;try{i=(0,e.loadHostBundlePluginInspectionFromScopes)(t.pluginsDirs,{settingsPath:t.userSettingsPath})}catch(n){a=n instanceof Error?n.message:String(n),i=(0,e.loadHostBundlePluginInspectionFromScopes)(t.pluginsDirs,{enabledPlugins:{}})}return[...Qt(i).map(e=>a!==void 0&&e.id===`plugins`?{...e,status:`fail`,cause:`no plugin loads: ${a}`}:e),...$t(t),...tn(r,i,n),...rn(t,i,n)]}function on(e,t,n){return{id:e,label:t,status:`fail`,cause:Tt(n)}}async function sn(e,t,n,r){try{return r(await n())}catch(n){return[on(e,t,n instanceof Error?n:Error(String(n)))]}}function cn(e,t){let n=e=>wt(e,t);return{...e,label:n(e.label),...e.path===void 0?{}:{path:n(e.path)},...e.cause===void 0?{}:{cause:n(e.cause)},...e.detail===void 0?{}:{detail:e.detail.map(n)}}}function ln(e){let t=e.filter(e=>e.status===`fail`).length;return{checks:e,failCount:t,warnCount:e.filter(e=>e.status===`warn`).length,repairable:e.flatMap(e=>e.repair===void 0?[]:[e.repair]),exitCode:t===0?0:1}}function un(e){try{let t=Nt(e);return{checks:t.checks,result:t}}catch(e){return{checks:[on(`settings`,`Settings`,e instanceof Error?e:Error(String(e)))]}}}async function dn(e,t){let n=[...e.hostChecks];e.compositionFailure!==void 0&&n.push(e.compositionFailure);let r=un(e);n.push(...r.checks);let i=r.result?.inspection,a=Et((i?.layers??[]).map(e=>e.settings),e.env);return n.push(...await sn(`provider`,`Provider`,()=>Lt(e,t),e=>(e.resolvedApiKey!==void 0&&a.push(e.resolvedApiKey),e.checks))),i!==void 0&&(n.push(...await sn(`storage`,`Storage`,()=>Ut(e,t,i),e=>e)),n.push(...await sn(`extensions`,`Extensions`,()=>an(e,t,i),e=>e))),ln(n.map(e=>cn(e,a)))}function fn(){return{name:`doctor`,displayName:`Doctor`,description:"Diagnose configuration and runtime readiness; `repair <check-id>` applies an allowlisted fix",source:`doctor`,modelInvocable:!1,userInvocable:!0,argumentHint:`[repair <check-id>]`}}var pn=class{name=`doctor`;getCommands(){return[fn()]}};async function mn(e,n){let r=e.getUserInteraction();if(r===void 0)return!1;let i=await r.ask((0,t.confirmAction)(`doctor-repair:${n.id}`,`Repair ${n.id}?`,{description:`${n.description} (${n.path})`,defaultYes:!1}));return i.type===`answer`&&i.values[0]===`yes`}async function hn(e,t,n,r,i){let a=await Xt(e,t,n,e=>mn(r,e));if(!a.applied)return{success:!1,message:a.reason,data:{repair:e,applied:!1}};let o=await dn(t,n),s=o.checks.find(t=>t.id===e);return{success:!0,message:[`Repaired ${e}: ${a.plan.description}.`,...vt(o,`${i.title??`Doctor`} (after repair)`,i)].join(`
22
22
  `),data:{repair:e,applied:!0,status:s?.status,exitCode:o.exitCode}}}async function gn(e,t,n,r,i){let[a,o]=r.trim().split(/\s+/);if(a===`repair`)return o===void 0||o.length===0?{success:!1,message:`Usage: /doctor repair <check-id>`}:hn(o,e,t,n,i);let s=await dn(e,t);return{success:s.failCount===0,message:vt(s,i.title,i).join(`
23
23
  `),data:{failCount:s.failCount,warnCount:s.warnCount,repairable:[...s.repairable]}}}function _n(e,t=mt({...e.env}),n={}){let r=T(fn(),{requiresPermission:!1,lifecycle:`inline`,execute:(r,i)=>gn(e,t,r,i,n)});return{name:`agent-command-doctor`,commandSources:[new pn],systemCommands:[r]}}function vn(){let e=process.env.VISUAL?.trim(),t=process.env.EDITOR?.trim(),n=(e!==void 0&&e.length>0?e:t!==void 0&&t.length>0?t:`vi`).split(/\s+/).filter(e=>e.length>0);return{command:n[0]??`vi`,args:n.slice(1)}}function k(e,t,n){return new Promise((r,i)=>{let a=(0,s.spawn)(e,[...t],{cwd:n,stdio:`inherit`,env:process.env});a.on(`error`,i),a.on(`exit`,(e,t)=>{if(e!==null){r(e);return}if(t){let e=o.constants.signals[t];r(128+(e??0));return}r(0)})})}const yn="Compose a message in $EDITOR (optionally pre-filled with `/editor <text>`), then return it.";async function bn(e,t,r=`agent-editor-`){if(!e.canHandoffTerminal())return{message:`An editor is unavailable here (no interactive terminal).`,success:!1};let a=vn(),s=(0,n.mkdtempSync)((0,i.join)((0,o.tmpdir)(),r)),c=(0,i.join)(s,`message.md`);(0,n.writeFileSync)(c,t??``,`utf8`);try{let t=await e.runWithTerminal(async()=>k(a.command,[...a.args,c],e.getCwd()));if(t!==0)return{message:`Editor exited without saving (code ${t}).`,success:!1,data:{exitCode:t}};let r=(0,n.readFileSync)(c,`utf8`).replace(/\s+$/u,``);return r.length===0?{message:`Editor closed with empty content; nothing composed.`,success:!1}:{message:r,success:!0,data:{content:r}}}finally{(0,n.rmSync)(s,{recursive:!0,force:!0,maxRetries:3,retryDelay:20})}}function xn(){return{name:`editor`,displayName:`Editor`,description:yn,source:`editor`,modelInvocable:!1,runner:`client`,surfaces:[`terminal`]}}function Sn(e){let t=xn();return{name:t.name,displayName:t.displayName,description:t.description,requiresPermission:!1,userInvocable:!0,modelInvocable:!1,runner:t.runner,surfaces:t.surfaces,lifecycle:`inline`,execute:(t,n)=>bn(t,n,e)}}var Cn=class{name=`editor`;getCommands(){return[xn()]}};function wn(e){return{name:`agent-command-editor`,commandSources:[new Cn],systemCommands:[Sn(e)]}}const Tn=`advisorModel`;function En(e){if(e.killSwitch)return`Advisor: disabled by the environment kill switch.`;if(e.target===void 0||!e.enabled)return`Advisor: off. Set one with /advisor <profile> or /advisor <profile>:<model>.`;let t=e.registered?`${e.sessionCalls}/${e.maxCallsPerSession} calls used this session`:`available from the next session`;return`Advisor: ${e.target} (${t}).`}async function Dn(e,t){let n=e.getCommandHostAdapters?.()??{},r=n.advisor;if(r===void 0)return{success:!1,message:`The advisor is not available in this environment.`};let i=t.trim();if(i.length===0){let e=r.status();return{success:!0,message:En(e),data:{advisor:{...e}}}}let a=r.set(i);if(!a.success||a.saved===void 0)return{success:a.success,message:a.message};let o=n.settings;if(o!==void 0&&e.getCommandInvocationSource()===`user`){let e=o.read();if(a.saved===`off`){let{[Tn]:t,...n}=e;o.write(n)}else o.write({...e,[Tn]:a.saved})}return{success:!0,message:a.message,data:{advisor:{...r.status()}}}}function On(){return{name:`advisor`,displayName:`Advisor`,description:`Show, set, or turn off the model the main model can consult for advice`,source:`advisor`,argumentHint:`<profile> | <profile>:<model> | off`,modelInvocable:!1}}function kn(){let e=On();return{name:e.name,displayName:e.displayName,description:e.description,requiresPermission:!1,userInvocable:!0,modelInvocable:!1,argumentHint:e.argumentHint,lifecycle:`inline`,execute:Dn}}var An=class{name=`advisor`;getCommands(){return[On()]}};function jn(){return{name:`agent-command-advisor`,commandSources:[new An],systemCommands:[kn()]}}const Mn=[`auto`,...t.MODEL_EFFORT_VALUES];function Nn(t){return t.disposition===`not-applied`?`This model doesn't support effort levels, so it will use its default.`:`Effort: ${e.EFFORT_LEVEL_LABELS[t.requested]}`}async function Pn(n){let r=n.getUserInteraction();if(r===void 0)return;let i=await r.ask((0,t.selectAction)(`effort`,`Select model effort`,Mn.map(t=>({value:t,label:e.EFFORT_LEVEL_LABELS[t]}))));return(0,e.parseModelEffort)(i.type===`answer`?i.values[0]:void 0,`/effort`)}function Fn(t){let n=t.getCommandHostAdapters?.().effort;if(n!==void 0)return n.getResolution();let r=t.getSession().getModelEffort();return(0,e.resolveModelEffort)({command:r,modelDefault:r===`auto`?`high`:r})}function In(e){return e.getCommandHostAdapters?.()??{}}function Ln(e,t){let n=In(e).settings;if(n===void 0||t===`max`)return;let r=n.read();if(t===`auto`){let{effort:e,...t}=r;n.write(t);return}n.write({...r,effort:t})}async function Rn(t,n){let r;try{r=(0,e.parseModelEffort)(n.trim()||void 0,`/effort`),r===void 0&&(r=await Pn(t))}catch(e){return{message:e instanceof Error?e.message:String(e),success:!1}}let i=Fn(t);if(r===void 0)return{message:Nn(i),success:!0,data:{effort:i}};let a=In(t).effort,o;try{o=a===void 0?(0,e.resolveModelEffort)({command:r,modelDefault:i.effective}):await a.apply(r,t.getSession()),a===void 0&&await t.getSession().applyModelOptions({effort:r}),t.getCommandInvocationSource()===`user`&&Ln(t,r)}catch(e){return{message:`Model effort was not applied: ${e instanceof Error?e.message:String(e)}`,success:!1}}return{message:Nn(o),success:!0,data:{effort:o}}}const zn=`auto | ${t.MODEL_EFFORT_VALUES.join(` | `)}`;function Bn(){return{name:`effort`,displayName:`Model Effort`,description:`Show or change the model effort level`,source:`effort`,argumentHint:zn,modelInvocable:!1}}function Vn(){let e=Bn();return{name:e.name,displayName:e.displayName,description:e.description,requiresPermission:!1,userInvocable:!0,modelInvocable:!1,argumentHint:e.argumentHint,lifecycle:`inline`,execute:Rn}}var Hn=class{name=`effort`;getCommands(){return[Bn()]}};function Un(){return{name:`agent-command-effort`,commandSources:[new Hn],systemCommands:[Vn()]}}async function Wn(n,r){let i=n.getUserInteraction();return i&&!(0,t.isConfirmed)(await i.ask((0,t.confirmAction)(`exit`,`Exit the session?`)))?{success:!0,message:`Exit cancelled.`}:{success:!0,message:`Exit requested.`,hostActions:[(0,e.createSessionExitHostAction)()]}}function Gn(){return{name:`exit`,displayName:`Exit Session`,description:e.EXIT_COMMAND_DESCRIPTION,source:`exit`,modelInvocable:!1}}function Kn(){let e=Gn();return{name:e.name,displayName:e.displayName,description:e.description,requiresPermission:!0,userInvocable:!0,modelInvocable:!1,lifecycle:`inline`,execute:Wn}}var qn=class{name=`exit`;getCommands(){return[Gn()]}};function Jn(){return{name:`agent-command-exit`,commandSources:[new qn],systemCommands:[Kn()]}}const Yn=`none`,A=`--same-dir`;function Xn(e){let t=e.trim().split(/\s+/).filter(e=>e.length>0),n=t.find(e=>e.startsWith(`--`)&&e!==A);if(n!==void 0)return{error:`Unknown option: ${n}\nUsage: /fork [name] [${A}]`};let r=t.filter(e=>e!==A);return{name:r.length>0?r.join(` `):void 0,isolation:t.includes(A)?Yn:`worktree`}}function Zn(e){return e instanceof Error?e.message:String(e)}function Qn(e,t,n){return[`Forked this conversation into "${e}" (${t}), running ${n===Yn?`in this directory`:`in its own worktree`}.`,`The fork is a copy: this session keeps going, and the two are separate records.`,`See its progress with /background list. Attaching from the background panel points this`,`terminal at the copy as it was forked; the fork's own turns stay in its task transcript.`].join(`
24
24
  `)}function $n(e,t,n){let r=n?.(e.sessionId);return`The fork "${e.name}" was written (${e.sessionId}) but its background job could not start: ${t}\n${r===void 0?`Resume the saved session through your host.`:`Resume it in a new terminal with: ${r}`}`}async function er(e,t=``,n){let r=Xn(t);if(`error`in r)return{message:r.error,success:!1};let i=e.getAgentJobCapability();if(!i)return{message:`This session cannot start background jobs, so it cannot run a fork.`,success:!1};let a;try{a=await e.forkSession(r.name===void 0?{}:{name:r.name})}catch(e){return{message:`Could not fork this session: ${Zn(e)}`,success:!1}}try{let e=await i.spawnAgentJob({agentType:`general-purpose`,label:a.name,mode:`background`,prompt:`Continue.`,isolation:r.isolation,resumeSessionId:a.sessionId});return{message:Qn(a.name,e.id,r.isolation),success:!0,data:{sessionId:a.sessionId,name:a.name,taskId:e.id}}}catch(e){return{message:$n(a,Zn(e),n),success:!1}}}function tr(){return{name:`fork`,displayName:`Fork Session`,description:`Copy this conversation into a new background session and keep working here. The fork inherits the whole conversation and the assembled system prompt; it is a copy, so nothing it does reaches this session and it never merges back.`,source:`fork`,modelInvocable:!1,argumentHint:`[name] [--same-dir]`}}function nr(e){let t=tr();return{name:t.name,displayName:t.displayName,description:t.description,requiresPermission:!1,userInvocable:!0,modelInvocable:!1,lifecycle:`inline`,...t.argumentHint===void 0?{}:{argumentHint:t.argumentHint},execute:(t,n)=>er(t,n,e)}}var rr=class{name=`fork`;getCommands(){return[tr()]}};function ir(e){return{name:`agent-command-fork`,commandSources:[new rr],systemCommands:[nr(e)],sessionRequirements:[`agent-runtime`]}}const ar=[`build`,`chore`,`ci`,`docs`,`feat`,`fix`,`perf`,`refactor`,`revert`,`style`,`test`],or=/^([^\s():!]+)(\(([^\s()]+)\))?(!)?: (.*)$/;function sr(e){if(e.trim().length===0)return{ok:!1,reason:`the subject is empty`};if(e.indexOf(`: `)===-1)return{ok:!1,reason:"the subject has no `: ` type separator — the form is `<type>[(scope)][!]: <description>`"};let t=or.exec(e);if(!t)return{ok:!1,reason:"the part before `: ` must be a type word with an optional `(scope)` and `!` — the form is `<type>[(scope)][!]: <description>`"};let n=t[1]??``;if((t[5]??``).trim().length===0)return{ok:!1,reason:"the description after `: ` is empty"};let r=[];return ar.includes(n)||r.push(`type "${n}" is not one of the conventional types (${ar.join(`, `)})`),e.length>72&&r.push(`the subject is ${e.length} characters; 72 is the conventional limit`),e.endsWith(`.`)&&r.push(`the subject ends with a period`),{ok:!0,warnings:r}}function cr(e){let t=e.trim();return t===`-m`?``:(t.startsWith(`-m `)&&(t=t.slice(3).trim()),t.length>=2&&(t.startsWith(`"`)||t.startsWith(`'`))&&t.endsWith(t[0]??``)&&(t=t.slice(1,-1).trim()),t)}function j(e){return{success:!1,message:e,data:{git:`commit`,committed:!1}}}async function lr(e){let n=await e.ask((0,t.textAction)(`git-commit-subject`,`Commit message`,{description:`Conventional Commits form: <type>[(scope)][!]: <description>`,placeholder:`feat: describe the change`}));if(n.type===`answer`)return cr(n.text??n.values[0]??``)}async function ur(t,n){let r=await t.run([`diff`,`--cached`,`--quiet`],{cwd:n});if(r.kind===`failed`||r.exitCode!==0&&r.exitCode!==1)return{staged:!1,result:{success:!1,message:(0,e.gitFailureMessage)(`diff --cached`,r)??`git failed`}};if(r.exitCode===1)return{staged:!0};let i=await t.run(e.GIT_STATUS_ARGS,{cwd:n}),a=(0,e.gitFailureMessage)(`status`,i);if(a!==void 0||i.kind!==`exited`)return{staged:!1,result:{success:!1,message:a??`git status failed`}};let o=(0,e.parseStatusPorcelainV2)(i.stdout);return{staged:!1,result:{success:!1,message:`Nothing is staged (${o.unstaged.length} unstaged, ${o.untracked.length} untracked). Stage files with \`git add\` or \`/shell git add ...\` and run \`/git commit\` again.`,data:{git:`commit`,committed:!1,unstaged:o.unstaged.length,untracked:o.untracked.length}}}}async function dr(e,t){let n=cr(e);if(n.length===0){if(t===void 0)return{result:j("Commit cancelled: a commit message was needed and none could be asked for (no interactive session). Run `/git commit <subject>`.")};let e=await lr(t);if(e===void 0||e.length===0)return{result:j(`Commit cancelled.`)};n=e}return{subject:n}}async function fr(n,r,i,a,o){if(o===void 0)return{confirmed:!1,result:j(`Commit cancelled: a confirmation was needed and none could be asked for (no interactive session).`)};let s=await n.run([`diff`,`--cached`,`--name-status`],{cwd:r}),c=(0,e.gitFailureMessage)(`diff --cached --name-status`,s);if(c!==void 0||s.kind!==`exited`)return{confirmed:!1,result:{success:!1,message:c??`git failed`}};let l=s.stdout.split(`
@@ -40,7 +40,7 @@ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});let e=require
40
40
  `)}`];return t.length===0?{message:i.length===0?`No MCP definitions are registered.`:i[0],success:!0,data:{servers:[],sourceProblems:r}}:{message:[`MCP activation status:\n${t.map(e=>ui(e,n.get(e.serverId))).join(`
41
41
  `)}`,...i].join(`
42
42
 
43
- `),success:!0,data:{servers:t.map(e=>({serverId:e.serverId,...e.displayName===void 0?{}:{displayName:e.displayName},source:e.source,status:e.status,allowed:e.allowed,provenanceId:e.provenanceId,definitionFingerprint:e.definitionFingerprint,securityIdentity:e.securityIdentity,...n.has(e.serverId)?{oauth:n.get(e.serverId)}:{},...e.connection===void 0?{}:{connection:e.connection},...e.connectionFailureReason===void 0?{}:{connectionFailureReason:e.connectionFailureReason},...e.toolNames===void 0?{}:{toolNames:e.toolNames}})),sourceProblems:r}}}async function mi(e,t){let n=t.trim(),r=n.indexOf(` `),i=(r===-1?n:n.slice(0,r)).toLowerCase(),a=r===-1?``:n.slice(r+1).trim();if(i===``||i===`status`||i===`list`){let t=e.getCommandInvocationSource?.();return t===`user`||t===`remote`?pi(N(e)):ai(N(e))}if(i===`login`)return xi(e,a);if(i===`reload`)return gi(e);if(i!==`approve`&&i!==`reject`&&i!==`revoke`&&i!==`logout`)return{message:`Unknown argument. Usage: /mcp [status] | /mcp <approve|reject|revoke|logout> <serverId> | /mcp login <serverId> [--no-browser] | /mcp reload`,success:!1};if(!a)return{message:`Usage: /mcp ${i} <serverId>`,success:!1};let o=N(e);if(!o)return{message:`MCP activation management is not available in this environment.`,success:!0};if(i===`logout`)return hi(o,a);try{let e=await o[i](a);return{message:`MCP server ${a} is now ${e.status}. ${e.reason}`,success:e.status===`approved`||e.status===`rejected`||e.status===`revoked`,data:{serverId:e.serverId,status:e.status,allowed:e.allowed,source:e.source,provenanceId:e.provenanceId,definitionFingerprint:e.definitionFingerprint,securityIdentity:e.securityIdentity}}}catch(e){return{message:e instanceof Error?e.message:String(e),success:!1}}}async function hi(e,t){if(e.oauthLogout===void 0||(await fi(e)).get(t)===void 0)return{message:`MCP server ${t} does not declare OAuth.`,success:!1};let n;try{n=await e.oauthLogout(t)}catch{return{message:`Signing out of MCP server ${t} failed.`,success:!1}}return{message:`${n.removed?`Signed out of MCP server ${t}`:`MCP server ${t} was not signed in`}; ${ci(n)}.`,success:!0,data:{...n}}}async function gi(e){let t=N(e);if(!t)return{message:`MCP activation management is not available in this environment.`,success:!0};if(t.reload===void 0)return{message:`Reloading MCP servers is not available in this environment.`,success:!1};let n=await t.reload(),r=n.tools.length===0?[]:await e.getSession().addTools(n.tools);n.tools.length>0&&n.reloadToken!==void 0&&t.reloadToolsAdded?.(n.reloadToken,r);let i=n.tools.length-r.length;return{message:`Reloaded MCP servers. ${[n.connectedServerIds.length===0?`No server newly connected.`:`Connected: ${n.connectedServerIds.join(`, `)}.`,n.failedServerIds.length===0?void 0:`Still not connected: ${n.failedServerIds.join(`, `)} (see /mcp status).`,i===0?void 0:`${i} of the new tools ${i===1?`was`:`were`} left out: the session already has a tool by that name.`].filter(e=>e!==void 0).join(` `)}`.trim(),success:!0,data:{connectedServerIds:n.connectedServerIds,failedServerIds:n.failedServerIds,tools:[...r]}}}let F=0;function _i(e,t){let n=e.getUserInteraction();if(n!==void 0)return async(e,r)=>{if(r.aborted)return`cancel`;F+=1;let i=await n.ask({id:`mcp-login-browser-${F}`,title:`Sign in to MCP server ${P(t)}`,description:`Your browser will open this URL; if it does not, open it yourself:\n${e.authorizationUrl}\n\nThe sign-in completes on its own once you approve in the browser.`,options:[{value:`open`,label:`Open my browser`},{value:`paste`,label:`Paste the redirect instead (browser on another machine)`},{value:`cancel`,label:`Cancel`}],maxSelect:1,default:{values:[`open`]}});if(i.type!==`answer`||r.aborted)return`cancel`;let a=i.values[0];return a===`open`||a===`paste`?a:`cancel`}}function vi(e,t){let n=e.getUserInteraction();if(n!==void 0)return async(e,r)=>{r.throwIfAborted(),F+=1;let i=await n.ask({id:`mcp-login-redirect-${F}`,title:`Sign in to MCP server ${P(t)}`,description:`Open this URL in a browser:\n${e.authorizationUrl}\n\nAfter you approve, the browser is sent to ${e.redirectUri}, which may not load. Copy the full address from its address bar and paste it here.`,allowFreeText:!0,masked:!0,placeholder:`Redirect URL (not shown)`});if(i.type!==`answer`||i.text===void 0||i.text.trim()===``)throw Error(`No redirect URL was pasted.`);return i.text}}function yi(e){let{serverId:t,failure:n}=e,r=P(t);switch(n){case`not-oauth`:return`MCP server ${t} does not declare OAuth; there is nothing to sign in to.`;case`url-unset`:return`MCP server ${t} has an unset variable in its url.`;case`sign-in-in-progress`:return`A sign-in to MCP server ${t} is already in progress.`;case`prompt-unavailable`:return`Signing in without a browser needs the redirect URL pasted here, and nothing here can ask for it; run robota mcp login ${r} --no-browser in a terminal.`;case`browser-failed`:return`Sign-in to MCP server ${t} failed (browser-failed): no browser could be opened. Run /mcp login ${r} --no-browser to paste the redirect instead.`;default:{let i=n===`token-exchange-failed`&&e.preRegisteredClient?` If its pre-registered client needs a secret, run robota mcp login ${r} --client-secret in a terminal.`:``;return`Sign-in to MCP server ${t} failed (${n??`unexpected-error`}); nothing was changed.${i}`}}}function bi(e,t,n){switch(t){case`connected`:return n===0?`Signed in to MCP server ${e}; it is connected and offers no new tools.`:`Signed in to MCP server ${e}; ${n} of its tools ${n===1?`is`:`are`} available from your next message.`;case`recovered`:return`Signed in to MCP server ${e}; its tools work again.`;case`not-admitted`:return`Signed in to MCP server ${e}, but it is not approved for this session (see /mcp status).`;default:return`Signed in to MCP server ${e}, but it could not connect in this session; the next session connects it.`}}async function xi(e,t){let n=t.split(/\s+/).filter(e=>e!==``),r=n.includes(`--no-browser`),i=n.includes(`--client-secret`),a=n.filter(e=>e!==`--no-browser`&&e!==`--client-secret`),o=a[0];if(a.length!==1||o===void 0||o.startsWith(`-`))return{message:`Usage: /mcp login <serverId> [--no-browser]`,success:!1};let s=P(o);if(i)return{message:`A client secret is never typed into a session. Run robota mcp login ${s} --client-secret in a terminal.`,success:!1};let c=N(e);if(!c)return{message:`MCP activation management is not available in this environment.`,success:!0};if(c.oauthLogin===void 0)return{message:`Signing in is not available in this session; run robota mcp login ${s} in a terminal.`,success:!1};let l=new AbortController,u=vi(e,o),d=r?void 0:_i(e,o),f=await c.oauthLogin({serverId:o,noBrowser:r,signal:l.signal,...u===void 0?{}:{readRedirect:(e,t)=>u(e,t).catch(e=>{throw l.abort(),e})},...d===void 0?{}:{confirmBrowser:async(e,t)=>{let n=await d(e,t);return n===`cancel`&&l.abort(),n}}});if(f.failure!==void 0)return{message:yi(f),success:!1,data:{serverId:o,failure:f.failure}};let p=f.tools.length===0?[]:await e.getSession().addTools(f.tools);f.tools.length>0&&c.oauthToolsAdded?.(o,p);let m=f.tools.length-p.length,h=m===0?``:` ${m} of its tools ${m===1?`was`:`were`} left out: the session already has a tool by that name.`;return{message:`${bi(o,f.connection,p.length)}${h}`,success:!0,data:{serverId:o,connection:f.connection??`not-connected`,tools:[...p],...m===0?{}:{dropped:m}}}}function Si(){return{name:`mcp`,displayName:`MCP activation`,description:`Show each MCP server's trust approval and OAuth sign-in state, or change one server: approve, reject or revoke its trust; sign in to it (login, which connects it in this session) or out of it (logout). Use when an MCP server is not approved, needs a sign-in, or should stop being used. Returns the status list, or what the one action did.`,modelDescription:`Show which MCP servers are configured and why any of them is unavailable. Use it when an MCP server or its tools are missing, a tool call reports that a server needs sign-in or approval, or the user asks about MCP servers. Returns one line per server: its name, activation state, sign-in state, and the command to suggest to the user when the server needs their approval, sign-in or workspace trust. You cannot approve, sign in or sign out yourself.`,argumentHint:`[status] | <approve|reject|revoke|logout> <server> | login <server> [--no-browser]`,source:`mcp-activation`,modelInvocable:!0,runsBare:!0,subcommands:[{name:`status`,description:`Show every MCP server’s name, activation state and sign-in state`,source:`mcp-activation`,modelInvocable:!0},{name:`reload`,description:`Retry connecting every MCP server that is not currently connected`,source:`mcp-activation`,modelInvocable:!1},...[`approve`,`reject`,`revoke`,`login`,`logout`].map(e=>({name:e,description:Ci[e],argumentHint:e===`login`?`<server> [--no-browser]`:`<server>`,source:`mcp-activation`,modelInvocable:!1}))]}}const Ci={approve:`Trust and activate an MCP server`,reject:`Refuse an MCP server`,revoke:`Withdraw an earlier approval`,login:`Sign in to an OAuth MCP server and connect it in this session`,logout:`Sign out of an OAuth MCP server and revoke its tokens`};function wi(){let e=Si();return{name:e.name,displayName:e.displayName,description:e.description,...e.modelDescription===void 0?{}:{modelDescription:e.modelDescription},argumentHint:e.argumentHint,...e.subcommands===void 0?{}:{subcommands:e.subcommands},requiresPermission:!0,modelRequiresPermission:!1,userInvocable:!0,modelInvocable:!0,lifecycle:`inline`,execute:mi}}var Ti=class{name=`mcp-activation`;getCommands(){return[Si()]}};function Ei(){return{name:`agent-command-mcp-activation`,commandSources:[new Ti],systemCommands:[wi()]}}function I(){return{message:e.MEMORY_COMMAND_USAGE,success:!1}}function Di(e){return{message:e instanceof Error?e.message:String(e),success:!1}}function Oi(t){try{return{ok:!0,store:(0,e.createCommandMemoryStores)(t)}}catch(e){return{ok:!1,result:Di(e instanceof Error?e:String(e))}}}async function ki(e){let t=await e.list(),n=t.topics.length>0?t.topics.map(e=>`- ${e.name}: ${e.path}`).join(`
43
+ `),success:!0,data:{servers:t.map(e=>({serverId:e.serverId,...e.displayName===void 0?{}:{displayName:e.displayName},source:e.source,status:e.status,allowed:e.allowed,provenanceId:e.provenanceId,definitionFingerprint:e.definitionFingerprint,securityIdentity:e.securityIdentity,...n.has(e.serverId)?{oauth:n.get(e.serverId)}:{},...e.connection===void 0?{}:{connection:e.connection},...e.connectionFailureReason===void 0?{}:{connectionFailureReason:e.connectionFailureReason},...e.toolNames===void 0?{}:{toolNames:e.toolNames}})),sourceProblems:r}}}async function mi(e,t){let n=t.trim(),r=n.indexOf(` `),i=(r===-1?n:n.slice(0,r)).toLowerCase(),a=r===-1?``:n.slice(r+1).trim();if(i===``||i===`status`||i===`list`){let t=e.getCommandInvocationSource?.();return t===`user`||t===`remote`?pi(N(e)):ai(N(e))}if(i===`login`)return xi(e,a);if(i===`reload`)return gi(e);if(i!==`approve`&&i!==`reject`&&i!==`revoke`&&i!==`logout`)return{message:`Unknown argument. Usage: /mcp [status] | /mcp <approve|reject|revoke|logout> <serverId> | /mcp login <serverId> [--no-browser] | /mcp reload`,success:!1};if(!a)return{message:`Usage: /mcp ${i} <serverId>`,success:!1};let o=N(e);if(!o)return{message:`MCP activation management is not available in this environment.`,success:!0};if(i===`logout`)return hi(o,a);try{let t=await o[i](a),n={message:`MCP server ${a} is now ${t.status}. ${t.reason}`,success:t.status===`approved`||t.status===`rejected`||t.status===`revoked`,data:{serverId:t.serverId,status:t.status,allowed:t.allowed,source:t.source,provenanceId:t.provenanceId,definitionFingerprint:t.definitionFingerprint,securityIdentity:t.securityIdentity}};if(i!==`approve`||t.status!==`approved`||o.reload===void 0)return n;try{let t=await gi(e);return{...n,message:`${n.message} ${t.message}`,data:{...n.data,reload:t.data??{}}}}catch(e){let t=e instanceof Error?e.message:String(e);return{...n,message:`${n.message} Could not connect now: ${t}. Run /mcp reload to retry.`}}}catch(e){return{message:e instanceof Error?e.message:String(e),success:!1}}}async function hi(e,t){if(e.oauthLogout===void 0||(await fi(e)).get(t)===void 0)return{message:`MCP server ${t} does not declare OAuth.`,success:!1};let n;try{n=await e.oauthLogout(t)}catch{return{message:`Signing out of MCP server ${t} failed.`,success:!1}}return{message:`${n.removed?`Signed out of MCP server ${t}`:`MCP server ${t} was not signed in`}; ${ci(n)}.`,success:!0,data:{...n}}}async function gi(e){let t=N(e);if(!t)return{message:`MCP activation management is not available in this environment.`,success:!0};if(t.reload===void 0)return{message:`Reloading MCP servers is not available in this environment.`,success:!1};let n=await t.reload(),r=[];try{r=n.tools.length===0?[]:await e.getSession().addTools(n.tools)}finally{n.reloadToken!==void 0&&t.reloadToolsAdded?.(n.reloadToken,r)}let i=n.tools.length-r.length;return{message:`Reloaded MCP servers. ${[n.connectedServerIds.length===0?`No server newly connected.`:`Connected: ${n.connectedServerIds.join(`, `)}.`,n.failedServerIds.length===0?void 0:`Still not connected: ${n.failedServerIds.join(`, `)} (see /mcp status).`,i===0?void 0:`${i} of the new tools ${i===1?`was`:`were`} left out: the session already has a tool by that name.`].filter(e=>e!==void 0).join(` `)}`.trim(),success:!0,data:{connectedServerIds:n.connectedServerIds,failedServerIds:n.failedServerIds,tools:[...r]}}}let F=0;function _i(e,t){let n=e.getUserInteraction();if(n!==void 0)return async(e,r)=>{if(r.aborted)return`cancel`;F+=1;let i=await n.ask({id:`mcp-login-browser-${F}`,title:`Sign in to MCP server ${P(t)}`,description:`Your browser will open this URL; if it does not, open it yourself:\n${e.authorizationUrl}\n\nThe sign-in completes on its own once you approve in the browser.`,options:[{value:`open`,label:`Open my browser`},{value:`paste`,label:`Paste the redirect instead (browser on another machine)`},{value:`cancel`,label:`Cancel`}],maxSelect:1,default:{values:[`open`]}});if(i.type!==`answer`||r.aborted)return`cancel`;let a=i.values[0];return a===`open`||a===`paste`?a:`cancel`}}function vi(e,t){let n=e.getUserInteraction();if(n!==void 0)return async(e,r)=>{r.throwIfAborted(),F+=1;let i=await n.ask({id:`mcp-login-redirect-${F}`,title:`Sign in to MCP server ${P(t)}`,description:`Open this URL in a browser:\n${e.authorizationUrl}\n\nAfter you approve, the browser is sent to ${e.redirectUri}, which may not load. Copy the full address from its address bar and paste it here.`,allowFreeText:!0,masked:!0,placeholder:`Redirect URL (not shown)`});if(i.type!==`answer`||i.text===void 0||i.text.trim()===``)throw Error(`No redirect URL was pasted.`);return i.text}}function yi(e){let{serverId:t,failure:n}=e,r=P(t);switch(n){case`not-oauth`:return`MCP server ${t} does not declare OAuth; there is nothing to sign in to.`;case`url-unset`:return`MCP server ${t} has an unset variable in its url.`;case`sign-in-in-progress`:return`A sign-in to MCP server ${t} is already in progress.`;case`prompt-unavailable`:return`Signing in without a browser needs the redirect URL pasted here, and nothing here can ask for it; run robota mcp login ${r} --no-browser in a terminal.`;case`browser-failed`:return`Sign-in to MCP server ${t} failed (browser-failed): no browser could be opened. Run /mcp login ${r} --no-browser to paste the redirect instead.`;default:{let i=n===`token-exchange-failed`&&e.preRegisteredClient?` If its pre-registered client needs a secret, run robota mcp login ${r} --client-secret in a terminal.`:``;return`Sign-in to MCP server ${t} failed (${n??`unexpected-error`}); nothing was changed.${i}`}}}function bi(e,t,n){switch(t){case`connected`:return n===0?`Signed in to MCP server ${e}; it is connected and offers no new tools.`:`Signed in to MCP server ${e}; ${n} of its tools ${n===1?`is`:`are`} available from your next message.`;case`recovered`:return`Signed in to MCP server ${e}; its tools work again.`;case`not-admitted`:return`Signed in to MCP server ${e}, but it is not approved for this session (see /mcp status).`;default:return`Signed in to MCP server ${e}, but it could not connect in this session; the next session connects it.`}}async function xi(e,t){let n=t.split(/\s+/).filter(e=>e!==``),r=n.includes(`--no-browser`),i=n.includes(`--client-secret`),a=n.filter(e=>e!==`--no-browser`&&e!==`--client-secret`),o=a[0];if(a.length!==1||o===void 0||o.startsWith(`-`))return{message:`Usage: /mcp login <serverId> [--no-browser]`,success:!1};let s=P(o);if(i)return{message:`A client secret is never typed into a session. Run robota mcp login ${s} --client-secret in a terminal.`,success:!1};let c=N(e);if(!c)return{message:`MCP activation management is not available in this environment.`,success:!0};if(c.oauthLogin===void 0)return{message:`Signing in is not available in this session; run robota mcp login ${s} in a terminal.`,success:!1};let l=new AbortController,u=vi(e,o),d=r?void 0:_i(e,o),f=await c.oauthLogin({serverId:o,noBrowser:r,signal:l.signal,...u===void 0?{}:{readRedirect:(e,t)=>u(e,t).catch(e=>{throw l.abort(),e})},...d===void 0?{}:{confirmBrowser:async(e,t)=>{let n=await d(e,t);return n===`cancel`&&l.abort(),n}}});if(f.failure!==void 0)return{message:yi(f),success:!1,data:{serverId:o,failure:f.failure}};let p=f.tools.length===0?[]:await e.getSession().addTools(f.tools);f.tools.length>0&&c.oauthToolsAdded?.(o,p);let m=f.tools.length-p.length,h=m===0?``:` ${m} of its tools ${m===1?`was`:`were`} left out: the session already has a tool by that name.`;return{message:`${bi(o,f.connection,p.length)}${h}`,success:!0,data:{serverId:o,connection:f.connection??`not-connected`,tools:[...p],...m===0?{}:{dropped:m}}}}function Si(){return{name:`mcp`,displayName:`MCP activation`,description:`Show each MCP server's trust approval and OAuth sign-in state, or change one server: approve, reject or revoke its trust; sign in to it (login, which connects it in this session) or out of it (logout). Use when an MCP server is not approved, needs a sign-in, or should stop being used. Returns the status list, or what the one action did.`,modelDescription:`Show which MCP servers are configured and why any of them is unavailable. Use it when an MCP server or its tools are missing, a tool call reports that a server needs sign-in or approval, or the user asks about MCP servers. Returns one line per server: its name, activation state, sign-in state, and the command to suggest to the user when the server needs their approval, sign-in or workspace trust. You cannot approve, sign in or sign out yourself.`,argumentHint:`[status] | <approve|reject|revoke|logout> <server> | login <server> [--no-browser]`,source:`mcp-activation`,modelInvocable:!0,runsBare:!0,subcommands:[{name:`status`,description:`Show every MCP server’s name, activation state and sign-in state`,source:`mcp-activation`,modelInvocable:!0},{name:`reload`,description:`Retry connecting every MCP server that is not currently connected`,source:`mcp-activation`,modelInvocable:!1},...[`approve`,`reject`,`revoke`,`login`,`logout`].map(e=>({name:e,description:Ci[e],argumentHint:e===`login`?`<server> [--no-browser]`:`<server>`,source:`mcp-activation`,modelInvocable:!1}))]}}const Ci={approve:`Trust and activate an MCP server`,reject:`Refuse an MCP server`,revoke:`Withdraw an earlier approval`,login:`Sign in to an OAuth MCP server and connect it in this session`,logout:`Sign out of an OAuth MCP server and revoke its tokens`};function wi(){let e=Si();return{name:e.name,displayName:e.displayName,description:e.description,...e.modelDescription===void 0?{}:{modelDescription:e.modelDescription},argumentHint:e.argumentHint,...e.subcommands===void 0?{}:{subcommands:e.subcommands},requiresPermission:!0,modelRequiresPermission:!1,userInvocable:!0,modelInvocable:!0,lifecycle:`inline`,execute:mi}}var Ti=class{name=`mcp-activation`;getCommands(){return[Si()]}};function Ei(){return{name:`agent-command-mcp-activation`,commandSources:[new Ti],systemCommands:[wi()]}}function I(){return{message:e.MEMORY_COMMAND_USAGE,success:!1}}function Di(e){return{message:e instanceof Error?e.message:String(e),success:!1}}function Oi(t){try{return{ok:!0,store:(0,e.createCommandMemoryStores)(t)}}catch(e){return{ok:!1,result:Di(e instanceof Error?e:String(e))}}}async function ki(e){let t=await e.list(),n=t.topics.length>0?t.topics.map(e=>`- ${e.name}: ${e.path}`).join(`
44
44
  `):`(none)`;return{message:[`Memory index: ${t.indexPath}`,`Topics directory: ${t.topicsPath}`,`Topics:`,n].join(`
45
45
  `),success:!0,data:{indexPath:t.indexPath,topicsPath:t.topicsPath,topicCount:t.topics.length}}}async function Ai(e,t){if(!t||t===`index`){let t=await e.loadStartupMemory();return{message:t.content||`(empty memory index)`,success:!0,data:{path:t.path,lineCount:t.lineCount,truncated:t.truncated}}}return{message:await e.readTopic(t)||`(empty memory topic: ${t})`,success:!0,data:{topic:t}}}function ji(t){let n=t[1],r=t[2],i=t.slice(3).join(` `).trim();if(!(!n||!(0,e.isCommandMemoryType)(n)||!r||i.length===0))return{type:n,topic:r,text:i}}async function Mi(e){let t=await e.listPending(`pending`);return{message:[`Pending memory candidates:`,...t.length>0?t.map(e=>`- ${e.id} ${e.type}/${e.topic} confidence=${e.confidence}: ${e.text}`):[`(no pending memory candidates)`]].join(`
46
46
  `),success:!0,data:{count:t.length}}}function Ni(t,n){(0,e.recordCommandMemoryEvent)(t,n)}async function Pi(t,n,r){if(!r)return I();try{let{record:i,saved:a}=await(0,e.approvePendingMemoryCandidate)(n,r);return Ni(t,{type:`memory_candidate_approved`,candidateId:i.id,topic:i.topic,reason:`approved-by-user`}),Ni(t,{type:`memory_candidate_saved`,candidateId:i.id,topic:i.topic,reason:a.deduplicated?`deduplicated`:`approved-and-saved`}),{message:a.deduplicated?`Saved memory candidate ${r} was already present in ${a.topicPath}`:`Saved memory candidate ${r} to ${a.topicPath}`,success:!0,data:{id:r,status:i.status,topic:a.topic,topicPath:a.topicPath,deduplicated:a.deduplicated}}}catch(e){return Di(e instanceof Error?e:String(e))}}async function Fi(e,t,n){if(!n)return I();try{let r=await t.markPending(n,`rejected`,`rejected-by-user`);return Ni(e,{type:`memory_candidate_rejected`,candidateId:r.id,topic:r.topic,reason:`rejected-by-user`}),{message:`Rejected memory candidate ${n}`,success:!0,data:{id:n,status:r.status}}}catch(e){return Di(e instanceof Error?e:String(e))}}function Ii(t){let n=(0,e.listCommandUsedMemoryReferences)(t);return{message:[`Used memory references:`,...n.length>0?n.map(e=>{let t=e.truncated?` truncated=true`:``;return`- ${e.topic} score=${e.score}${t}: ${e.path}`}):[`(no memory used in current turn)`]].join(`
@@ -60,7 +60,7 @@ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});let e=require
60
60
  /plan approve approve the plan (edits auto-apply; shell stays confirmed)
61
61
  /plan revert return to drafting (re-blocks edits)`,success:!0};if(r===`status`){let t=e.getPlanState();return t?{message:$a(t),success:!0,data:{phase:t.phase}}:{message:`No plan is active.`,success:!0}}if(r===`approve`){if(!e.getPlanState())return{message:`No plan to approve. Start one with /plan <objective>.`,success:!1};try{let t=e.approvePlan();return{message:`Plan approved — edits will auto-apply; shell steps stay confirmed.\nPhase: ${t.phase}`,success:!0,data:{phase:t.phase}}}catch(e){return{message:e instanceof Error?e.message:String(e),success:!1}}}if(r===`revert`){if(!e.getPlanState())return{message:`No plan to revert.`,success:!1};let t=e.revertPlan();return{message:`Reverted to drafting — edits are blocked again (plan mode).\nPhase: ${t.phase}`,success:!0,data:{phase:t.phase}}}let i;try{i=await e.setPlan(n)}catch(e){return{message:e instanceof Error?e.message:String(e),success:!1}}return{message:`Plan drafted (read-only until approved). Review it, then run /plan approve:\n${i.objective}`,success:!0,data:{planId:i.id}}}function to(){return{name:`plan`,displayName:`Plan Mode`,description:`Draft a reviewable plan, then approve it to unblock edits (plan → review → approve → act).`,source:`plan`,modelInvocable:!1}}function no(){let e=to();return{name:e.name,displayName:e.displayName,description:e.description,requiresPermission:!1,userInvocable:!0,modelInvocable:!1,lifecycle:`inline`,execute:eo}}var ro=class{name=`plan`;getCommands(){return[to()]}};function io(){return{name:`agent-command-plan`,commandSources:[new ro],systemCommands:[no()]}}function ao(e){let t=e.trim().split(/\s+/).filter(e=>e.length>0);return{subcommand:t[0]??``,subArgs:t.slice(1).join(` `).trim()}}function R(e){return{success:!1,message:e}}function oo(t){return(0,e.resolvePluginCommandAdapter)(t)}const so=`Installing and uninstalling plugins runs code on this computer, so it only works from the desktop app or the page opened here — not from a remote device.`;function co(e){return(e.getCommandSurfaceLocality?.()??`local`)===`remote`}async function z(e,t){let n=oo(e);if(n===void 0)return{success:!1,message:`Plugin management is not available.`};try{return{success:!0,message:await t(n)}}catch(e){return{success:!1,message:`Plugin error: ${e instanceof Error?e.message:String(e)}`}}}async function lo(e,t){let{subcommand:n,subArgs:r}=ao(t);return n===`add`&&r.length>0?z(e,async e=>{let t=await e.marketplaceAdd(r);return`Added marketplace: "${t}" (from ${r})\nInstall plugins with: /plugin install <name>@${t}`}):n===`remove`&&r.length>0?z(e,async e=>(await e.marketplaceRemove(r),`Removed marketplace "${r}" and uninstalled its plugins.`)):n===`update`&&r.length>0?z(e,async e=>(await e.marketplaceUpdate(r),`Updated marketplace "${r}".`)):n===`list`?z(e,async e=>{let t=await e.marketplaceList();return t.length===0?`No marketplace sources configured.`:`Marketplace sources:\n${t.map(e=>` ${e.name} (${e.type})`).join(`
62
62
  `)}`}):R(`Usage: /plugin marketplace add <source> | remove <name> | update <name> | list`)}function B(e,t,n,r){return t.length===0?Promise.resolve(R(n)):z(e,e=>Promise.resolve(r(e,t)))}function uo(){return{success:!0,message:`Opening plugin manager...`,uiIntents:[(0,e.createShowPluginManagerIntent)()]}}function fo(e,t){return co(e)?Promise.resolve(R(so)):B(e,t,`Usage: /plugin install <name>@<marketplace>`,async(e,t)=>(await e.install(t),`Installed plugin: ${t}`))}function po(e,t){return co(e)?Promise.resolve(R(so)):B(e,t,`Usage: /plugin uninstall <name>@<marketplace>`,async(e,t)=>(await e.uninstall(t),`Uninstalled plugin: ${t}`))}async function mo(e){let t=oo(e);if(t===void 0)return{success:!0,message:`Plugin management is not available.`,data:{plugins:[]}};try{let e=await t.listInstalled();return{success:!0,message:e.length===0?`No plugins are installed.`:`Installed plugins:\n${e.map(e=>` ${e.name}${e.enabled?``:` (disabled)`} — ${e.description}`).join(`
63
- `)}`,data:{plugins:e}}}catch(e){return{success:!1,message:`Plugin error: ${e instanceof Error?e.message:String(e)}`}}}function ho(e,t){return B(e,t,`Usage: /plugin enable <name>@<marketplace>`,async(e,t)=>(await e.enable(t),`Enabled plugin: ${t}`))}function go(e,t){return B(e,t,`Usage: /plugin disable <name>@<marketplace>`,async(e,t)=>(await e.disable(t),`Disabled plugin: ${t}`))}async function _o(e,t){let{subcommand:n,subArgs:r}=ao(t);switch(n){case``:case`manage`:return uo();case`list`:return mo(e);case`install`:return fo(e,r);case`uninstall`:return po(e,r);case`enable`:return ho(e,r);case`disable`:return go(e,r);case`marketplace`:return lo(e,r);default:return R(`Unknown plugin subcommand: ${n}`)}}async function vo(e,t){return z(e,async e=>{let t=await e.reloadPlugins();return`Reloaded ${t.loadedPluginCount===1?`1 plugin resource`:`${t.loadedPluginCount} plugin resources`}.`}).then(e=>e.success?{...e,data:{...e.data,pluginRegistryReloaded:!0}}:e)}function yo(){return{name:`plugin`,displayName:`Plugins`,description:e.PLUGIN_COMMAND_DESCRIPTION,source:`plugin-manager`,modelInvocable:!1,argumentHint:e.PLUGIN_COMMAND_ARGUMENT_HINT,subcommands:(0,e.buildPluginCommandSubcommands)()}}function bo(){return{name:`reload-plugins`,displayName:`Reload Plugins`,description:e.RELOAD_PLUGINS_COMMAND_DESCRIPTION,source:`plugin-manager`,modelInvocable:!1}}function xo(){let e=yo();return{name:e.name,displayName:e.displayName,description:e.description,requiresPermission:!1,userInvocable:!0,modelInvocable:!1,argumentHint:e.argumentHint,lifecycle:`inline`,subcommands:e.subcommands,execute:_o}}function So(){let e=bo();return{name:e.name,displayName:e.displayName,description:e.description,requiresPermission:!1,userInvocable:!0,modelInvocable:!1,lifecycle:`inline`,execute:vo}}var Co=class{name=`plugin-manager`;getCommands(){return[yo(),bo()]}};function wo(){return{name:`agent-command-plugin`,commandSources:[new Co],systemCommands:[xo(),So()]}}function To(e){return e.getCommandHostAdapters?.().presetRegistry??(0,c.createPresetRegistry)()}function Eo(e){return e.getSession().getActivePresetId()}function Do(e,t){return[`Available presets:`,...t.listPresets().map(t=>`${t.id===e?`* `:` `}${t.id} — ${t.title}: ${t.description}`)].join(`
63
+ `)}`,data:{plugins:e}}}catch(e){return{success:!1,message:`Plugin error: ${e instanceof Error?e.message:String(e)}`}}}function ho(e,t){return B(e,t,`Usage: /plugin enable <name>@<marketplace>`,async(e,t)=>(await e.enable(t),`Enabled plugin: ${t}`))}function go(e,t){return B(e,t,`Usage: /plugin disable <name>@<marketplace>`,async(e,t)=>(await e.disable(t),`Disabled plugin: ${t}`))}async function _o(e,t){let{subcommand:n,subArgs:r}=ao(t);switch(n){case``:case`manage`:return uo();case`list`:return mo(e);case`install`:return fo(e,r);case`uninstall`:return po(e,r);case`enable`:return ho(e,r);case`disable`:return go(e,r);case`marketplace`:return lo(e,r);default:return R(`Unknown plugin subcommand: ${n}`)}}async function vo(e,t){return z(e,async e=>{let t=await e.reloadPlugins();return`Reloaded ${t.loadedPluginCount===1?`1 plugin resource`:`${t.loadedPluginCount} plugin resources`}. Plugin commands and skills are active now; hook changes apply to new sessions.`}).then(e=>({...e,data:{...e.data,pluginRegistryReloaded:!0}}))}function yo(){return{name:`plugin`,displayName:`Plugins`,description:e.PLUGIN_COMMAND_DESCRIPTION,source:`plugin-manager`,modelInvocable:!1,argumentHint:e.PLUGIN_COMMAND_ARGUMENT_HINT,subcommands:(0,e.buildPluginCommandSubcommands)()}}function bo(){return{name:`reload-plugins`,displayName:`Reload Plugins`,description:e.RELOAD_PLUGINS_COMMAND_DESCRIPTION,source:`plugin-manager`,modelInvocable:!1}}function xo(){let e=yo();return{name:e.name,displayName:e.displayName,description:e.description,requiresPermission:!1,userInvocable:!0,modelInvocable:!1,argumentHint:e.argumentHint,lifecycle:`inline`,subcommands:e.subcommands,execute:_o}}function So(){let e=bo();return{name:e.name,displayName:e.displayName,description:e.description,requiresPermission:!1,userInvocable:!0,modelInvocable:!1,lifecycle:`inline`,execute:vo}}var Co=class{name=`plugin-manager`;getCommands(){return[yo(),bo()]}};function wo(){return{name:`agent-command-plugin`,commandSources:[new Co],systemCommands:[xo(),So()]}}function To(e){return e.getCommandHostAdapters?.().presetRegistry??(0,c.createPresetRegistry)()}function Eo(e){return e.getSession().getActivePresetId()}function Do(e,t){return[`Available presets:`,...t.listPresets().map(t=>`${t.id===e?`* `:` `}${t.id} — ${t.title}: ${t.description}`)].join(`
64
64
  `)}function Oo(e,t){return`Unknown preset: ${e}. Available: ${t.listPresets().map(e=>e.id).join(`, `)}`}function ko(e,t){let n=Eo(e);return{message:Do(n,t),success:!0,data:{presets:t.listPresets(),active:n}}}async function Ao(e,n){let r=e.getUserInteraction();if(!r)return;let i=n.listPresets().map(e=>({value:e.id,label:e.id,description:e.description})),a=await r.ask((0,t.selectAction)(`preset`,`Select a preset`,i));return a.type===`answer`?a.values[0]:void 0}async function jo(t,n){let r=To(t),i=n.trim().split(/\s+/)[0];if(i===`list`||(i===void 0||i.length===0)&&(i=await Ao(t,r),i===void 0))return ko(t,r);if(r.getPreset(i)===void 0)return{message:Oo(i,r),success:!1};let a=r.resolvePreset(i),o=await(0,e.applyPresetToSession)(t,i,a),s=o.unknownCommandModules.map(({name:e,kind:t})=>`Preset command-module "${e}" (${t}) matched no module — expected the agent-command-* form; ignored.`);return{message:[`Switched to preset: ${i}`,...s].join(`
65
65
  `),success:!0,data:{preset:i,unknownCommandModules:o.unknownCommandModules}}}function Mo(e=`preset`){return(0,c.createPresetRegistry)().listPresets().map(t=>({name:t.id,description:t.description,source:e}))}function No(){return{name:`preset`,displayName:`Agent Preset`,description:`List presets or switch the active preset`,source:`preset`,argumentHint:`list | <preset-id>`,subcommands:Mo(`preset`),modelInvocable:!1}}function Po(){let e=No();return{name:e.name,displayName:e.displayName,description:e.description,requiresPermission:!1,userInvocable:!0,modelInvocable:!1,argumentHint:e.argumentHint,subcommands:e.subcommands,lifecycle:`inline`,execute:jo}}var Fo=class{name=`preset`;getCommands(){return[No()]}};function Io(){return{name:`agent-command-preset`,commandSources:[new Fo],systemCommands:[Po()]}}function V(e,t,n={}){let r=qo(e,t);return{type:e,steps:Xo(Jo(r),n.initialValues),setupHelpLinks:r.setupHelpLinks??[],stepIndex:0,values:{},existingProfileNames:n.existingProfileNames??[],...n.profileName===void 0?{}:{profileName:n.profileName},...n.setCurrent===void 0?{}:{setCurrent:n.setCurrent}}}function Lo(e){return e.length===0?` No providers are available.`:[` Select provider:`,...e.map((e,t)=>` ${t+1}. ${Uo(e)}`),` Provider [1-${e.length}] (default: 1): `].join(`
66
66
  `)}function Ro(e,n){let r=e.trim(),i=r.length>0?r:`1`,a=Go(i);if(a!==void 0){let e=n[a];if(e!==void 0)return e.type;throw Error(`Provider selection ${i} is out of range. Currently supported: ${(0,t.formatSupportedProviderTypes)(n)}`)}let o=(0,t.findProviderDefinition)(n,i);if(o===void 0)throw Error(`Unknown provider: ${i}. Currently supported: ${(0,t.formatSupportedProviderTypes)(n)}`);return o.type}function H(e){let t=e.steps[e.stepIndex];if(t===void 0)throw Error(`Provider setup step ${e.stepIndex} is out of range`);return t}function zo(e,t){let n=H(e),r=t.trim()||n.defaultValue||``,i=Ko(n,r);if(i!==void 0)return{status:`error`,state:e,message:i};let a={...e,stepIndex:e.stepIndex+1,values:{...e.values,[n.key]:r}};return a.stepIndex<e.steps.length?{status:`next`,state:a}:{status:`complete`,input:Zo(a)}}async function Bo(e,t,n,r={}){let i=V(e,n,r),a=i.steps.length;for(;i.stepIndex<a;){let e=H(i),n=await t(Vo(e,i.setupHelpLinks),e.masked===!0),r=zo(i,n);if(r.status===`complete`)return r.input;if(r.status===`error`)throw Error(r.message);i=r.state}throw Error(`Provider setup flow ended without completion`)}function Vo(e,t=[]){let n=e.defaultValue===void 0?``:` (default: ${e.defaultValue})`,r=Wo(t);return`${r.length>0?`${r}\n`:``} ${e.title}${n}: `}const Ho={"cloud-paid":`[Cloud/Paid]`,"cloud-free":`[Cloud/Free]`,"local-free":`[Local/Free]`};function Uo(e){let t=`${e.category===void 0?``:`${Ho[e.category]??``} `}${e.displayName===void 0?e.type:`${e.displayName} (${e.type})`}`;return e.description===void 0?t:`${t} — ${e.description}`}function Wo(e=[]){return e.length===0?``:e.map(e=>` Setup help: ${Yo(e.kind)}: ${e.label} - ${e.url}`).join(`