@lotagate/cli 0.1.26 → 0.1.27

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/dist/application/agent/bounded-text-accumulator.d.ts +15 -0
  2. package/dist/application/agent/bounded-text-accumulator.js +1 -0
  3. package/dist/application/agent/cli-agent-execution-service.d.ts +1 -1
  4. package/dist/application/agent/cli-agent-execution-service.js +1 -1
  5. package/dist/application/commands/application-command-executor.js +2 -2
  6. package/dist/application/commands/cli-command-services.d.ts +1 -1
  7. package/dist/application/commands/cli-command-services.js +31 -31
  8. package/dist/application/commands/goal-command-handlers.js +6 -6
  9. package/dist/application/commands/memory-command-handler.d.ts +1 -1
  10. package/dist/application/commands/memory-command-handler.js +11 -11
  11. package/dist/application/commands/runtime-command-handlers.js +11 -11
  12. package/dist/application/extensions/plugin-contribution-registry.js +1 -1
  13. package/dist/application/lifecycle/operation-registry.d.ts +11 -0
  14. package/dist/application/lifecycle/operation-registry.js +1 -0
  15. package/dist/application/orchestration/headless-agent-turn.js +3 -3
  16. package/dist/application/protocol/desktop-agent-command.js +1 -3
  17. package/dist/application/protocol/desktop-title-generator.d.ts +5 -0
  18. package/dist/application/protocol/desktop-title-generator.js +3 -0
  19. package/dist/application/protocol/jsonl-agent-command.js +2 -2
  20. package/dist/application/workspace/workspace-file-index.d.ts +2 -2
  21. package/dist/application/workspace/workspace-file-index.js +1 -1
  22. package/dist/domain/auth/auth-profile.d.ts +1 -0
  23. package/dist/domain/auth/auth-profile.js +1 -1
  24. package/dist/domain/runtime/resource-limits.d.ts +9 -0
  25. package/dist/domain/runtime/resource-limits.js +1 -1
  26. package/dist/infrastructure/agent-sdk/tool-calling-model-client.js +1 -1
  27. package/dist/infrastructure/cache/file-cache-store.d.ts +5 -0
  28. package/dist/infrastructure/cache/file-cache-store.js +2 -2
  29. package/dist/infrastructure/clipboard/clipboard-adapter-factory.js +1 -1
  30. package/dist/infrastructure/clipboard/clipboard-process.d.ts +20 -0
  31. package/dist/infrastructure/clipboard/clipboard-process.js +1 -0
  32. package/dist/infrastructure/clipboard/clipboard-text-adapter-factory.js +1 -1
  33. package/dist/infrastructure/clipboard/windows-clipboard-adapter.js +1 -1
  34. package/dist/infrastructure/clipboard/windows-clipboard-text-adapter.js +1 -1
  35. package/dist/infrastructure/credentials/encrypted-file-credential-store.js +2 -2
  36. package/dist/infrastructure/credentials/secret-input.d.ts +1 -1
  37. package/dist/infrastructure/credentials/secret-input.js +3 -3
  38. package/dist/infrastructure/extensions/mcp-runtime.d.ts +2 -0
  39. package/dist/infrastructure/extensions/mcp-runtime.js +1 -1
  40. package/dist/infrastructure/extensions/plugin-agent-discovery.d.ts +3 -1
  41. package/dist/infrastructure/extensions/plugin-agent-discovery.js +1 -1
  42. package/dist/infrastructure/extensions/skill-manager.js +2 -2
  43. package/dist/infrastructure/sessions/file-session-store.d.ts +8 -0
  44. package/dist/infrastructure/sessions/file-session-store.js +4 -4
  45. package/dist/main.js +2 -2
  46. package/dist/presentation/tui/tui-agent-turn-controller.js +1 -1
  47. package/dist/presentation/tui/tui-application.d.ts +2 -0
  48. package/dist/presentation/tui/tui-application.js +3 -3
  49. package/dist/version.d.ts +1 -1
  50. package/dist/version.js +1 -1
  51. package/package.json +8 -8
@@ -0,0 +1,15 @@
1
+ import { CliError } from '../../domain/errors/cli-error.js';
2
+ /** Accumulates model text without allowing a response to exceed its CLI budget. */
3
+ export declare class BoundedTextAccumulator {
4
+ private readonly maxBytes;
5
+ private readonly chunks;
6
+ private bytes;
7
+ constructor(maxBytes?: number);
8
+ get byteLength(): number;
9
+ get isEmpty(): boolean;
10
+ append(content: string): void;
11
+ replace(content: string): void;
12
+ toString(): string;
13
+ }
14
+ export declare function assertTextWithinLimit(content: string, maxBytes?: number): void;
15
+ export declare function modelResponseLimitError(kind: string, maxBytes: number): CliError;
@@ -0,0 +1 @@
1
+ import{CliError as o}from"../../domain/errors/cli-error.js";import{CLI_ERROR_CODES as n}from"../../domain/errors/error-codes.js";import{RESOURCE_LIMITS as r}from"../../domain/runtime/resource-limits.js";class p{maxBytes;chunks=[];bytes=0;constructor(e=r.sessionTextBytes){this.maxBytes=e}get byteLength(){return this.bytes}get isEmpty(){return this.bytes===0}append(e){const s=this.bytes+Buffer.byteLength(e,"utf8");if(s>this.maxBytes)throw i("text",this.maxBytes);this.chunks.push(e),this.bytes=s}replace(e){this.chunks.length=0,this.bytes=0,this.append(e)}toString(){return this.chunks.join("")}}function y(t,e=r.sessionTextBytes){if(Buffer.byteLength(t,"utf8")>e)throw i("text",e)}function i(t,e){return new o(n.MODEL_STREAM_FAILED,"Model response exceeds the CLI response limit.",{category:"model",userMessage:`The model response exceeds the ${e} byte safety limit.`,retryable:!1,details:{kind:"model-response-limit",responseKind:t,maxBytes:e}})}export{p as BoundedTextAccumulator,y as assertTextWithinLimit,i as modelResponseLimitError};
@@ -104,7 +104,7 @@ export interface PreparedCliAgent {
104
104
  readonly run: (request: CliAgentRunRequest) => AsyncIterable<AgentEvent>;
105
105
  }
106
106
  /** Starts MCP warm-up without putting transport details into the conversation. */
107
- export declare function warmMcpRuntime(runtime: CliRuntime, cwd: string): Promise<void>;
107
+ export declare function warmMcpRuntime(runtime: CliRuntime, cwd: string, signal?: AbortSignal): Promise<void>;
108
108
  /**
109
109
  * Composes the CLI-owned capabilities around the public Agent SDK runtime.
110
110
  * The SDK remains responsible for MCP transport, tool dispatch and the agent
@@ -1 +1 @@
1
- import{delegatedWorkerPolicy as we}from"../security/delegated-worker-policy.js";import{PluginContributionRegistry as be}from"../extensions/plugin-contribution-registry.js";import{SkillToolExecutor as xe}from"../../infrastructure/extensions/skill-tool-executor.js";import{LocalFilesystemToolExecutor as he}from"../../infrastructure/filesystem/local-filesystem-tool-executor.js";import{resolveWorkspacePath as ke}from"../../infrastructure/filesystem/path-resolver.js";import{ShellToolExecutor as ve}from"../../infrastructure/shell/shell-tool-executor.js";import{SkillScopeStore as Se}from"../extensions/skill-scope-store.js";import{ToolApprovalService as Ce}from"../security/tool-approval-service.js";import{ToolPolicy as Ae}from"@lotagate/agent-sdk";import{HookRuntime as Ee}from"../../infrastructure/extensions/hook-runtime.js";import{runWithToolHooks as Te}from"./tool-hook-lifecycle.js";import"./capability-profile.js";import{createAgentInstance as Me,createLocalAgentInstance as Pe}from"../../infrastructure/agent-sdk/agent-instance-factory.js";import{createToolCallingCompletionClient as Re}from"../../infrastructure/agent-sdk/tool-calling-completion-client.js";import{buildAgentInputContext as Ie}from"./agent-input-context.js";import{buildToolCatalog as Oe}from"./tool-catalog.js";import{HOST_TOOL_PLUGIN_IDS as re}from"../../domain/extensions/host-tool-plugin-ids.js";import{DefaultCliSubagentService as We}from"../orchestration/cli-subagent-service.js";import{SubagentToolExecutor as Le}from"../orchestration/subagent-tool-executor.js";import{ScopedToolExecutor as F}from"./scoped-tool-executor.js";import{RESOURCE_LIMITS as C}from"../../domain/runtime/resource-limits.js";import{BrowserHostToolExecutor as Fe}from"../protocol/browser-host-tool-executor.js";import{DesktopHostToolExecutor as _e}from"../protocol/desktop-host-tool-executor.js";import{ComputerHostToolExecutor as je}from"../protocol/computer-host-tool-executor.js";import{hostCapabilityAvailable as Be}from"../protocol/desktop-host-capabilities.js";import{BROWSER_INSPECTION_TOOLS as oe,BROWSER_NAVIGATION_TOOLS as ie,COMPUTER_LAUNCH_TOOLS as ae,READ_ONLY_COMPUTER_TOOLS as le}from"../security/tool-policy-registry.js";import{EvidenceLedger as He}from"../intent/evidence-ledger.js";import{EvidenceRecordingToolExecutor as De}from"../intent/evidence-recording-tool-executor.js";import{IntentExecutionGate as Ke}from"../intent/intent-execution-gate.js";import{IntentRunController as ze}from"../intent/intent-run-controller.js";import{createAgentRuntimeContext as Ge}from"./agent-runtime-context.js";import{createAgentGuidance as $e}from"./interactive-agent-guidance.js";import{proposeMemory as Ue}from"../memory/memory-extractor.js";import{assembleMemoryContext as ce}from"../memory/memory-context-assembler.js";import{applyMemoryCapturePolicy as Je}from"../memory/memory-capture-policy.js";import{CliAgentPreparationCache as Ve,loadEffectiveMcpConfig as Ye}from"./cli-agent-preparation-cache.js";async function $n(e,t){const l=await e.projectTrust.inspect(t);if(!await e.projectTrust.isTrusted(l))return;const c=await new be(e.paths.globalConfigDir).resolve(t,!0),i=await Ye(e,t,c.mcpConfig);(await e.mcpRuntime.ensure(l.canonicalPath,i,!0)).release()}async function Ze(e){const t=e.profile==="title-generator",l=e.subagentMode??"research",c=e.profile==="subagent"&&l==="research",i=e.runtime.agentPreparation===void 0?await new Ve().load({runtime:e.runtime,projectRoot:e.projectRoot,executionCwd:e.executionCwd,isTitleGenerator:t,includeMcpConfig:!c}):await e.runtime.agentPreparation.load({runtime:e.runtime,projectRoot:e.projectRoot,executionCwd:e.executionCwd,isTitleGenerator:t,includeMcpConfig:!c}),{identity:r,executionCwd:d,trusted:a,contributions:w,availableSkills:h,projectPolicy:A,project:E,executionConfig:y}=i,k=e.executionPlatform??e.runtime.platform,b=new Se(e.initialSkill===void 0?void 0:{skillName:e.initialSkill.name,allowedTools:e.initialSkill.allowedTools}),P=!(e.profile==="interactive-trusted"||e.profile==="subagent"&&e.prompt!==void 0)&&e.approvalMode==="ask"?"auto":e.approvalMode??"auto",_=t?[]:e.selectedSkills===void 0?h:nn(h,e.selectedSkills),ue=i.mcpConfig,T=a&&!c&&!t?await e.runtime.mcpRuntime.ensure(r.canonicalPath,ue,!0,{...e.mcpLifecycle===void 0?{}:{onEvent:e.mcpLifecycle},reconnect:e.profile!=="headless-safe"}):void 0;try{const M=new he({...e.onWrite===void 0?{}:{onWrite:e.onWrite},...e.toolActivity===void 0?{}:{onActivity:e.toolActivity},...e.subagentWriteScope===void 0?{}:{writeScope:e.subagentWriteScope},logger:e.runtime.logger}),R=new ve({platform:k,toolEnvironment:e.executionBoundary==="sandbox"?"linux-guest":"host",...e.toolActivity===void 0?{}:{onActivity:e.toolActivity},...c?{readOnly:!0}:{},logger:e.runtime.logger}),j=new xe(_,b,e.runtime.logger),B=en(w.plugins),se=e.browserHost===void 0||e.profile==="subagent"||!B.browser?void 0:new Fe({request:e.browserHost,executionBoundary:e.browserExecution==="isolated"?"sandbox":"host",hostFallback:e.hostFallback??"deny",...e.onExecutionFallbackApproval===void 0?{}:{onFallbackApproval:e.onExecutionFallbackApproval},...e.toolActivity===void 0?{}:{onActivity:e.toolActivity}}),H=(n=!1)=>e.desktopHost===void 0?void 0:new _e({request:e.desktopHost,executionBoundary:e.executionBoundary??"host",hostFallback:e.hostFallback??"deny",projectRoot:r.canonicalPath,executionCwd:d,...e.executionWorkspaceId===void 0?{}:{executionWorkspaceId:e.executionWorkspaceId},executionPlatform:k,...n?{readOnly:!0}:{},...e.onWrite===void 0?{}:{onWrite:e.onWrite},...e.onArtifacts===void 0?{}:{onArtifacts:e.onArtifacts},...e.onExecutionFallbackApproval===void 0?{}:{onFallbackApproval:e.onExecutionFallbackApproval},...e.toolActivity===void 0?{}:{onActivity:e.toolActivity}}),D=H(),K=c?H(!0):void 0,z=e.hostCapabilities?.computer,G=z?.operations,me=e.computerHost===void 0||e.profile==="subagent"||!B.computer||!Be(e.hostCapabilities,z)?void 0:new je({request:e.computerHost,...G===void 0?{}:{operations:G},...e.toolActivity===void 0?{}:{onActivity:e.toolActivity}}),fe=D??R,ge=Ne(D,M,R,j,se,me),pe=t?[]:a?c?[new F(K??M,["filesystem.read","filesystem.list","filesystem.exists"]),new F(K??R,["shell.exec"]),new F(j,["skill.list","skill.load"])]:[...ge]:[],$=!t&&a&&e.allowSubagents!==!1?new We({runtime:e.runtime,cwd:d,model:e.model,allowedModels:e.allowedSubagentModels??[e.model],...e.subagentJobs===void 0?{}:{jobs:e.subagentJobs},...e.subagentLifecycle===void 0?{}:{lifecycle:e.subagentLifecycle},createAgent:async({model:n,mode:o,signal:u,writeScope:f,onAction:g,onUsage:m})=>{const s={...e};delete s.onModelComplete,delete s.onSubagentModelComplete,delete s.agentSessionStore,delete s.initialSkill,delete s.contextManagement,delete s.goal,delete s.onIntentLifecycle,delete s.mcpLifecycle;const S=g===void 0?void 0:{start:p=>{g(on(p.toolName,p.label))}},te=e.prompt===void 0||g===void 0?e.prompt:async p=>(g({kind:"approval",label:`Waiting for approval \xB7 ${p.toolName}`}),e.prompt?.(p,u)??!1),L=await Ze({...s,model:n,profile:"subagent",allowSubagents:!1,subagentMode:o,...S===void 0?{}:{toolActivity:S},...te===void 0?{}:{prompt:te},...f===void 0?{}:{subagentWriteScope:f},...m===void 0&&e.onSubagentModelComplete===void 0?{}:{onModelComplete:p=>{m?.(p),e.onSubagentModelComplete?.(p)}}});return{initialize:()=>L.agent.initialize(),run:p=>L.run(p),close:L.close}}}):void 0,ye=t?[]:[...pe,...T===void 0?[]:[T.executor],...$===void 0?[]:[new Le($)]],U=new He,I=new Ke,J=ye.map(n=>new De(n,U,async o=>{const u=I.contractForRun(o.runId);u!==void 0&&await e.onIntentLifecycle?.({type:"intent.evidence",contract:u,evidence:o})})),O=Oe(J),V=e.allowedTools===void 0?void 0:[...new Set(tn(e.allowedTools,O.names))],Y=e.browserAccess==="disabled"?O.names.filter(n=>n.startsWith("browser.")):void 0,Z=a?await e.runtime.workspaceSettings.load(r.canonicalPath):void 0,Q=new Ce({mode:P,trustedProject:a,skillScopes:b,...Z===void 0?{}:{workspacePermissions:Z.permissions},...e.allowedTools===void 0?{}:{desktopToolScopes:e.allowedTools},resolveWorkspaceTarget:ke,...e.prompt===void 0?{}:{prompt:e.prompt},...e.rememberApproval===void 0?{}:{rememberApproval:e.rememberApproval},...e.onApprovalPersistenceFailure===void 0?{}:{onRememberApprovalFailure:e.onApprovalPersistenceFailure},...e.audit===void 0?{}:{audit:e.audit}}).policy(),X={...Q,authorizationRules:[I.policy(),...e.subagentWriteScope===void 0?[]:[we(e.subagentWriteScope)],...Q.authorizationRules??[]]},v=a&&!t?new Ee(fe,{trustedProject:!0,enabled:!0,toolPolicy:new Ae(X)}):void 0,q=v===void 0?[]:[...await v.loadProject(r.canonicalPath),...(await Promise.all(w.plugins.map(n=>v.load(n)))).flat()],W=a?Pe({client:e.client,model:e.model,platform:k,toolExecutors:J,...V===void 0?{}:{allowedTools:V},...Y===void 0?{}:{deniedTools:Y},...e.onModelComplete===void 0?{}:{onModelComplete:e.onModelComplete},...e.contextManagement===void 0?{}:{contextManagement:e.contextManagement},...e.agentSessionStore===void 0?{}:{sessionStore:e.agentSessionStore},...X}):Me({client:e.client,model:e.model,...e.onModelComplete===void 0?{}:{onModelComplete:e.onModelComplete},...e.contextManagement===void 0?{}:{contextManagement:e.contextManagement},...e.agentSessionStore===void 0?{}:{sessionStore:e.agentSessionStore}}),N=n=>{const o=W.run({...n,system:$e(e.profile,e.executionBoundary===void 0?{}:{executionBoundary:e.executionBoundary}),...n.reasoningEffort===void 0&&e.reasoningEffort!==void 0?{reasoningEffort:e.reasoningEffort}:{},cwd:d,workspaceRoot:d,stream:n.stream??!0,limits:{maxIterations:C.agentMaxIterations,maxToolCallsPerTurn:C.agentMaxToolCallsPerTurn,...n.limits??{}}});return q.length===0||v===void 0?o:Te(o,{runner:v,hooks:q,cwd:d,workspaceRoot:d,...n.sessionId===void 0?{}:{sessionId:n.sessionId},...n.signal===void 0?{}:{signal:n.signal},maxResultBytes:C.sessionTextBytes})},ee=Re(e.client),ne=t?void 0:new ze({runAgent:N,client:ee,model:e.model,onIntentFallback:n=>e.runtime.logger?.warn("intent.compilation.fallback",{model:e.model,reason:Xe(n)}),executionGate:I,evidenceLedger:U,maximumCompletionAttempts:C.intentMaxCompletionAttempts,frame:{trusted:a,profile:a?e.profile:an(e.profile),runtime:Ge(k,{cwd:d,workspaceRoot:r.canonicalPath,projectRoot:r.canonicalPath,executionCwd:d}),tools:O.names,skills:a?_.filter(n=>n.enabled&&n.modelInvocable).map(n=>({name:n.skillKey,description:n.description})):[],plugins:a?w.plugins.map(n=>n.name):[],agents:a?w.agents.map(({pluginName:n,definition:o})=>({name:`${n}:${o.name}`,description:o.description})):[],...A===void 0?{}:{projectPolicy:A},...e.goal===void 0?{}:{goal:e.goal},...E===void 0?{}:{project:E}},...y?.config.memoryContext!=="enabled"?{}:{frameFor:async(n,o,u)=>{const f=await Qe(e.runtime,r.canonicalPath,a,n,o.kind,e.client,y?.config.memorySemanticSearch==="enabled"&&typeof y.config.memoryEmbeddingModel=="string"?y.config.memoryEmbeddingModel:void 0,u);return qe(f)?{memory:f}:{}}},...y?.config.memoryContext!=="enabled"?{}:{onTurnOutcome:async({outcome:n,contract:o,evidence:u,input:f,signal:g})=>{if(e.runtime.logger.info("memory.capture.started",{outcome:n,intentKind:o.kind,evidenceCount:u.length}),!a){e.runtime.logger.info("memory.capture.skipped",{outcome:n,intentKind:o.kind,reason:"untrusted-project"});return}if(n==="cancelled"||g?.aborted===!0){e.runtime.logger.info("memory.capture.skipped",{outcome:n,intentKind:o.kind,reason:"cancelled-turn"});return}try{const m=await Ue({client:ee,model:e.model,contract:o,evidence:u,userInput:f,...g===void 0?{}:{signal:g}});if(m===void 0){e.runtime.logger.info("memory.capture.skipped",{outcome:n,intentKind:o.kind,reason:"extractor-no-proposal"});return}if(m.decision==="skip"){e.runtime.logger.info("memory.capture.skipped",{outcome:n,intentKind:o.kind,reason:m.reason,isSave:!1});return}if(de(g))return;const s=Je(m.draft,n,f,u);if(s===void 0){e.runtime.logger.info("memory.capture.skipped",{outcome:n,intentKind:o.kind,reason:"capture-policy"});return}if(de(g))return;const S=await e.runtime.memory.create(r.canonicalPath,s);e.runtime.logger.info("memory.capture.completed",{outcome:n,intentKind:o.kind,recordId:S.id,kind:S.kind,isSave:!0})}catch(m){e.runtime.logger.warn("memory.capture.failed",{reason:m instanceof Error?m.message:String(m),outcome:n,intentKind:o.kind})}}},...e.onIntentLifecycle===void 0?{}:{onLifecycle:e.onIntentLifecycle}});return{agent:W,trusted:a,buildInput:n=>Ie(n,r.canonicalPath,a,{executionCwd:d,includeContent:!1}),close:async()=>{b.clearAll();try{await W.close()}finally{T?.release()}},run:n=>{if(ne!==void 0)return ne.run(n);const{userInput:o,workspaceContext:u,...f}=n;return N(f)}}}catch(M){throw T?.release(),M}}async function Qe(e,t,l,c,i,r,d,a){const w=C.memoryContextRecords;if(!l)return ce([]);if(a?.aborted===!0)throw a.reason??new Error("Memory retrieval was cancelled.");const h=d===void 0?void 0:{model:d,embed:async(E,y)=>{const b=(await r.embeddings.create({model:d,input:[...E],encoding_format:"float"},y===void 0?void 0:{signal:y})).data.slice().sort((x,P)=>x.index-P.index).map(x=>x.embedding);if(b.some(x=>!Array.isArray(x)))throw new Error("Embedding provider returned a non-numeric vector.");return b}},A=await e.memory.relevant(t,{text:c,maximum:w,...i===void 0?{}:{intentKind:i},...h===void 0?{}:{semantic:h},...a===void 0?{}:{signal:a}});return ce(A.slice(0,w))}function de(e){return e?.aborted===!0}function Xe(e){return(e instanceof Error?e.message:String(e)).replace(/Bearer\s+[^\s]+/giu,"Bearer [REDACTED]").replace(/sk-[A-Za-z0-9_-]{8,}/gu,"[REDACTED]").slice(0,512)}function qe(e){return Object.values(e.records).some(t=>t.length>0)}function Ne(e,t,l,c,i,r){return[...e===void 0?[t,l]:[e],c,...i===void 0?[]:[i],...r===void 0?[]:[r]]}function en(e){const t=new Set(e.map(l=>l.name));return{browser:t.has(re.browser),computer:t.has(re.computer)}}function nn(e,t){const l=new Set;for(const i of t){if(l.has(i))throw new Error(`Duplicate automation skill: ${i}`);l.add(i)}const c=new Map(e.map(i=>[i.skillKey,i]));return t.map(i=>{const r=c.get(i);if(r===void 0||!r.enabled||!r.modelInvocable)throw new Error(`Automation skill is unavailable: ${i}`);return r})}function tn(e,t){const l=new Set;for(const c of e){const i=t.filter(r=>rn(c,r));for(const r of i)l.add(r)}return[...l].sort()}function rn(e,t){return e===t?!0:e==="filesystem.read"?t==="filesystem.read"||t==="filesystem.list"||t==="filesystem.exists":e==="filesystem.write"?t==="filesystem.write":e==="terminal.read"||e==="terminal.execute"||e.startsWith("git.")?t==="shell.exec":e==="browser.navigate"?ie.has(t):e==="browser.inspect"?oe.has(t):e==="browser.interact"?t.startsWith("browser.")&&!ie.has(t)&&!oe.has(t):e==="computer.read"?le.has(t):e==="computer.interact"?t.startsWith("computer.")&&!le.has(t)&&!ae.has(t):e==="computer.launch"?ae.has(t):!1}function on(e,t){return{kind:e==="shell.exec"?"shell":"filesystem",label:t}}function an(e){return e==="protocol-safe"?"protocol-safe":"headless-safe"}export{Ne as composeFullToolExecutors,Ze as prepareCliAgent,en as resolveHostToolAvailability,$n as warmMcpRuntime};
1
+ import{delegatedWorkerPolicy as we}from"../security/delegated-worker-policy.js";import{PluginContributionRegistry as be}from"../extensions/plugin-contribution-registry.js";import{SkillToolExecutor as xe}from"../../infrastructure/extensions/skill-tool-executor.js";import{LocalFilesystemToolExecutor as he}from"../../infrastructure/filesystem/local-filesystem-tool-executor.js";import{resolveWorkspacePath as ke}from"../../infrastructure/filesystem/path-resolver.js";import{ShellToolExecutor as ve}from"../../infrastructure/shell/shell-tool-executor.js";import{SkillScopeStore as Se}from"../extensions/skill-scope-store.js";import{ToolApprovalService as Ce}from"../security/tool-approval-service.js";import{ToolPolicy as Ae}from"@lotagate/agent-sdk";import{HookRuntime as Ee}from"../../infrastructure/extensions/hook-runtime.js";import{runWithToolHooks as Te}from"./tool-hook-lifecycle.js";import"./capability-profile.js";import{createAgentInstance as Me,createLocalAgentInstance as Ie}from"../../infrastructure/agent-sdk/agent-instance-factory.js";import{createToolCallingCompletionClient as Pe}from"../../infrastructure/agent-sdk/tool-calling-completion-client.js";import{buildAgentInputContext as Re}from"./agent-input-context.js";import{buildToolCatalog as Oe}from"./tool-catalog.js";import{HOST_TOOL_PLUGIN_IDS as re}from"../../domain/extensions/host-tool-plugin-ids.js";import{DefaultCliSubagentService as We}from"../orchestration/cli-subagent-service.js";import{SubagentToolExecutor as Le}from"../orchestration/subagent-tool-executor.js";import{ScopedToolExecutor as F}from"./scoped-tool-executor.js";import{RESOURCE_LIMITS as C}from"../../domain/runtime/resource-limits.js";import{BrowserHostToolExecutor as Fe}from"../protocol/browser-host-tool-executor.js";import{DesktopHostToolExecutor as _e}from"../protocol/desktop-host-tool-executor.js";import{ComputerHostToolExecutor as je}from"../protocol/computer-host-tool-executor.js";import{hostCapabilityAvailable as Be}from"../protocol/desktop-host-capabilities.js";import{BROWSER_INSPECTION_TOOLS as oe,BROWSER_NAVIGATION_TOOLS as ie,COMPUTER_LAUNCH_TOOLS as ae,READ_ONLY_COMPUTER_TOOLS as le}from"../security/tool-policy-registry.js";import{EvidenceLedger as He}from"../intent/evidence-ledger.js";import{EvidenceRecordingToolExecutor as De}from"../intent/evidence-recording-tool-executor.js";import{IntentExecutionGate as Ke}from"../intent/intent-execution-gate.js";import{IntentRunController as ze}from"../intent/intent-run-controller.js";import{createAgentRuntimeContext as Ge}from"./agent-runtime-context.js";import{createAgentGuidance as $e}from"./interactive-agent-guidance.js";import{proposeMemory as Ue}from"../memory/memory-extractor.js";import{assembleMemoryContext as ce}from"../memory/memory-context-assembler.js";import{applyMemoryCapturePolicy as Je}from"../memory/memory-capture-policy.js";import{CliAgentPreparationCache as Ve,loadEffectiveMcpConfig as Ye}from"./cli-agent-preparation-cache.js";async function $n(e,t,l){l?.throwIfAborted();const c=await e.projectTrust.inspect(t);if(l?.throwIfAborted(),!await e.projectTrust.isTrusted(c))return;const i=await new be(e.paths.globalConfigDir).resolve(t,!0);l?.throwIfAborted();const r=await Ye(e,t,i.mcpConfig),d=await e.mcpRuntime.ensure(c.canonicalPath,r,!0);try{l?.throwIfAborted()}finally{d.release()}}async function Ze(e){const t=e.profile==="title-generator",l=e.subagentMode??"research",c=e.profile==="subagent"&&l==="research",i=e.runtime.agentPreparation===void 0?await new Ve().load({runtime:e.runtime,projectRoot:e.projectRoot,executionCwd:e.executionCwd,isTitleGenerator:t,includeMcpConfig:!c}):await e.runtime.agentPreparation.load({runtime:e.runtime,projectRoot:e.projectRoot,executionCwd:e.executionCwd,isTitleGenerator:t,includeMcpConfig:!c}),{identity:r,executionCwd:d,trusted:a,contributions:w,availableSkills:h,projectPolicy:A,project:E,executionConfig:y}=i,k=e.executionPlatform??e.runtime.platform,b=new Se(e.initialSkill===void 0?void 0:{skillName:e.initialSkill.name,allowedTools:e.initialSkill.allowedTools}),I=!(e.profile==="interactive-trusted"||e.profile==="subagent"&&e.prompt!==void 0)&&e.approvalMode==="ask"?"auto":e.approvalMode??"auto",_=t?[]:e.selectedSkills===void 0?h:nn(h,e.selectedSkills),ue=i.mcpConfig,T=a&&!c&&!t?await e.runtime.mcpRuntime.ensure(r.canonicalPath,ue,!0,{...e.mcpLifecycle===void 0?{}:{onEvent:e.mcpLifecycle},reconnect:e.profile!=="headless-safe"}):void 0;try{const M=new he({...e.onWrite===void 0?{}:{onWrite:e.onWrite},...e.toolActivity===void 0?{}:{onActivity:e.toolActivity},...e.subagentWriteScope===void 0?{}:{writeScope:e.subagentWriteScope},logger:e.runtime.logger}),P=new ve({platform:k,toolEnvironment:e.executionBoundary==="sandbox"?"linux-guest":"host",...e.toolActivity===void 0?{}:{onActivity:e.toolActivity},...c?{readOnly:!0}:{},logger:e.runtime.logger}),j=new xe(_,b,e.runtime.logger),B=en(w.plugins),se=e.browserHost===void 0||e.profile==="subagent"||!B.browser?void 0:new Fe({request:e.browserHost,executionBoundary:e.browserExecution==="isolated"?"sandbox":"host",hostFallback:e.hostFallback??"deny",...e.onExecutionFallbackApproval===void 0?{}:{onFallbackApproval:e.onExecutionFallbackApproval},...e.toolActivity===void 0?{}:{onActivity:e.toolActivity}}),H=(n=!1)=>e.desktopHost===void 0?void 0:new _e({request:e.desktopHost,executionBoundary:e.executionBoundary??"host",hostFallback:e.hostFallback??"deny",projectRoot:r.canonicalPath,executionCwd:d,...e.executionWorkspaceId===void 0?{}:{executionWorkspaceId:e.executionWorkspaceId},executionPlatform:k,...n?{readOnly:!0}:{},...e.onWrite===void 0?{}:{onWrite:e.onWrite},...e.onArtifacts===void 0?{}:{onArtifacts:e.onArtifacts},...e.onExecutionFallbackApproval===void 0?{}:{onFallbackApproval:e.onExecutionFallbackApproval},...e.toolActivity===void 0?{}:{onActivity:e.toolActivity}}),D=H(),K=c?H(!0):void 0,z=e.hostCapabilities?.computer,G=z?.operations,me=e.computerHost===void 0||e.profile==="subagent"||!B.computer||!Be(e.hostCapabilities,z)?void 0:new je({request:e.computerHost,...G===void 0?{}:{operations:G},...e.toolActivity===void 0?{}:{onActivity:e.toolActivity}}),fe=D??P,pe=Ne(D,M,P,j,se,me),ge=t?[]:a?c?[new F(K??M,["filesystem.read","filesystem.list","filesystem.exists"]),new F(K??P,["shell.exec"]),new F(j,["skill.list","skill.load"])]:[...pe]:[],$=!t&&a&&e.allowSubagents!==!1?new We({runtime:e.runtime,cwd:d,model:e.model,allowedModels:e.allowedSubagentModels??[e.model],...e.subagentJobs===void 0?{}:{jobs:e.subagentJobs},...e.subagentLifecycle===void 0?{}:{lifecycle:e.subagentLifecycle},createAgent:async({model:n,mode:o,signal:u,writeScope:f,onAction:p,onUsage:m})=>{const s={...e};delete s.onModelComplete,delete s.onSubagentModelComplete,delete s.agentSessionStore,delete s.initialSkill,delete s.contextManagement,delete s.goal,delete s.onIntentLifecycle,delete s.mcpLifecycle;const S=p===void 0?void 0:{start:g=>{p(on(g.toolName,g.label))}},te=e.prompt===void 0||p===void 0?e.prompt:async g=>(p({kind:"approval",label:`Waiting for approval \xB7 ${g.toolName}`}),e.prompt?.(g,u)??!1),L=await Ze({...s,model:n,profile:"subagent",allowSubagents:!1,subagentMode:o,...S===void 0?{}:{toolActivity:S},...te===void 0?{}:{prompt:te},...f===void 0?{}:{subagentWriteScope:f},...m===void 0&&e.onSubagentModelComplete===void 0?{}:{onModelComplete:g=>{m?.(g),e.onSubagentModelComplete?.(g)}}});return{initialize:()=>L.agent.initialize(),run:g=>L.run(g),close:L.close}}}):void 0,ye=t?[]:[...ge,...T===void 0?[]:[T.executor],...$===void 0?[]:[new Le($)]],U=new He,R=new Ke,J=ye.map(n=>new De(n,U,async o=>{const u=R.contractForRun(o.runId);u!==void 0&&await e.onIntentLifecycle?.({type:"intent.evidence",contract:u,evidence:o})})),O=Oe(J),V=e.allowedTools===void 0?void 0:[...new Set(tn(e.allowedTools,O.names))],Y=e.browserAccess==="disabled"?O.names.filter(n=>n.startsWith("browser.")):void 0,Z=a?await e.runtime.workspaceSettings.load(r.canonicalPath):void 0,Q=new Ce({mode:I,trustedProject:a,skillScopes:b,...Z===void 0?{}:{workspacePermissions:Z.permissions},...e.allowedTools===void 0?{}:{desktopToolScopes:e.allowedTools},resolveWorkspaceTarget:ke,...e.prompt===void 0?{}:{prompt:e.prompt},...e.rememberApproval===void 0?{}:{rememberApproval:e.rememberApproval},...e.onApprovalPersistenceFailure===void 0?{}:{onRememberApprovalFailure:e.onApprovalPersistenceFailure},...e.audit===void 0?{}:{audit:e.audit}}).policy(),X={...Q,authorizationRules:[R.policy(),...e.subagentWriteScope===void 0?[]:[we(e.subagentWriteScope)],...Q.authorizationRules??[]]},v=a&&!t?new Ee(fe,{trustedProject:!0,enabled:!0,toolPolicy:new Ae(X)}):void 0,q=v===void 0?[]:[...await v.loadProject(r.canonicalPath),...(await Promise.all(w.plugins.map(n=>v.load(n)))).flat()],W=a?Ie({client:e.client,model:e.model,platform:k,toolExecutors:J,...V===void 0?{}:{allowedTools:V},...Y===void 0?{}:{deniedTools:Y},...e.onModelComplete===void 0?{}:{onModelComplete:e.onModelComplete},...e.contextManagement===void 0?{}:{contextManagement:e.contextManagement},...e.agentSessionStore===void 0?{}:{sessionStore:e.agentSessionStore},...X}):Me({client:e.client,model:e.model,...e.onModelComplete===void 0?{}:{onModelComplete:e.onModelComplete},...e.contextManagement===void 0?{}:{contextManagement:e.contextManagement},...e.agentSessionStore===void 0?{}:{sessionStore:e.agentSessionStore}}),N=n=>{const o=W.run({...n,system:$e(e.profile,e.executionBoundary===void 0?{}:{executionBoundary:e.executionBoundary}),...n.reasoningEffort===void 0&&e.reasoningEffort!==void 0?{reasoningEffort:e.reasoningEffort}:{},cwd:d,workspaceRoot:d,stream:n.stream??!0,limits:{maxIterations:C.agentMaxIterations,maxToolCallsPerTurn:C.agentMaxToolCallsPerTurn,...n.limits??{}}});return q.length===0||v===void 0?o:Te(o,{runner:v,hooks:q,cwd:d,workspaceRoot:d,...n.sessionId===void 0?{}:{sessionId:n.sessionId},...n.signal===void 0?{}:{signal:n.signal},maxResultBytes:C.sessionTextBytes})},ee=Pe(e.client),ne=t?void 0:new ze({runAgent:N,client:ee,model:e.model,onIntentFallback:n=>e.runtime.logger?.warn("intent.compilation.fallback",{model:e.model,reason:Xe(n)}),executionGate:R,evidenceLedger:U,maximumCompletionAttempts:C.intentMaxCompletionAttempts,frame:{trusted:a,profile:a?e.profile:an(e.profile),runtime:Ge(k,{cwd:d,workspaceRoot:r.canonicalPath,projectRoot:r.canonicalPath,executionCwd:d}),tools:O.names,skills:a?_.filter(n=>n.enabled&&n.modelInvocable).map(n=>({name:n.skillKey,description:n.description})):[],plugins:a?w.plugins.map(n=>n.name):[],agents:a?w.agents.map(({pluginName:n,definition:o})=>({name:`${n}:${o.name}`,description:o.description})):[],...A===void 0?{}:{projectPolicy:A},...e.goal===void 0?{}:{goal:e.goal},...E===void 0?{}:{project:E}},...y?.config.memoryContext!=="enabled"?{}:{frameFor:async(n,o,u)=>{const f=await Qe(e.runtime,r.canonicalPath,a,n,o.kind,e.client,y?.config.memorySemanticSearch==="enabled"&&typeof y.config.memoryEmbeddingModel=="string"?y.config.memoryEmbeddingModel:void 0,u);return qe(f)?{memory:f}:{}}},...y?.config.memoryContext!=="enabled"?{}:{onTurnOutcome:async({outcome:n,contract:o,evidence:u,input:f,signal:p})=>{if(e.runtime.logger.info("memory.capture.started",{outcome:n,intentKind:o.kind,evidenceCount:u.length}),!a){e.runtime.logger.info("memory.capture.skipped",{outcome:n,intentKind:o.kind,reason:"untrusted-project"});return}if(n==="cancelled"||p?.aborted===!0){e.runtime.logger.info("memory.capture.skipped",{outcome:n,intentKind:o.kind,reason:"cancelled-turn"});return}try{const m=await Ue({client:ee,model:e.model,contract:o,evidence:u,userInput:f,...p===void 0?{}:{signal:p}});if(m===void 0){e.runtime.logger.info("memory.capture.skipped",{outcome:n,intentKind:o.kind,reason:"extractor-no-proposal"});return}if(m.decision==="skip"){e.runtime.logger.info("memory.capture.skipped",{outcome:n,intentKind:o.kind,reason:m.reason,isSave:!1});return}if(de(p))return;const s=Je(m.draft,n,f,u);if(s===void 0){e.runtime.logger.info("memory.capture.skipped",{outcome:n,intentKind:o.kind,reason:"capture-policy"});return}if(de(p))return;const S=await e.runtime.memory.create(r.canonicalPath,s);e.runtime.logger.info("memory.capture.completed",{outcome:n,intentKind:o.kind,recordId:S.id,kind:S.kind,isSave:!0})}catch(m){e.runtime.logger.warn("memory.capture.failed",{reason:m instanceof Error?m.message:String(m),outcome:n,intentKind:o.kind})}}},...e.onIntentLifecycle===void 0?{}:{onLifecycle:e.onIntentLifecycle}});return{agent:W,trusted:a,buildInput:n=>Re(n,r.canonicalPath,a,{executionCwd:d,includeContent:!1}),close:async()=>{b.clearAll();try{await W.close()}finally{T?.release()}},run:n=>{if(ne!==void 0)return ne.run(n);const{userInput:o,workspaceContext:u,...f}=n;return N(f)}}}catch(M){throw T?.release(),M}}async function Qe(e,t,l,c,i,r,d,a){const w=C.memoryContextRecords;if(!l)return ce([]);if(a?.aborted===!0)throw a.reason??new Error("Memory retrieval was cancelled.");const h=d===void 0?void 0:{model:d,embed:async(E,y)=>{const b=(await r.embeddings.create({model:d,input:[...E],encoding_format:"float"},y===void 0?void 0:{signal:y})).data.slice().sort((x,I)=>x.index-I.index).map(x=>x.embedding);if(b.some(x=>!Array.isArray(x)))throw new Error("Embedding provider returned a non-numeric vector.");return b}},A=await e.memory.relevant(t,{text:c,maximum:w,...i===void 0?{}:{intentKind:i},...h===void 0?{}:{semantic:h},...a===void 0?{}:{signal:a}});return ce(A.slice(0,w))}function de(e){return e?.aborted===!0}function Xe(e){return(e instanceof Error?e.message:String(e)).replace(/Bearer\s+[^\s]+/giu,"Bearer [REDACTED]").replace(/sk-[A-Za-z0-9_-]{8,}/gu,"[REDACTED]").slice(0,512)}function qe(e){return Object.values(e.records).some(t=>t.length>0)}function Ne(e,t,l,c,i,r){return[...e===void 0?[t,l]:[e],c,...i===void 0?[]:[i],...r===void 0?[]:[r]]}function en(e){const t=new Set(e.map(l=>l.name));return{browser:t.has(re.browser),computer:t.has(re.computer)}}function nn(e,t){const l=new Set;for(const i of t){if(l.has(i))throw new Error(`Duplicate automation skill: ${i}`);l.add(i)}const c=new Map(e.map(i=>[i.skillKey,i]));return t.map(i=>{const r=c.get(i);if(r===void 0||!r.enabled||!r.modelInvocable)throw new Error(`Automation skill is unavailable: ${i}`);return r})}function tn(e,t){const l=new Set;for(const c of e){const i=t.filter(r=>rn(c,r));for(const r of i)l.add(r)}return[...l].sort()}function rn(e,t){return e===t?!0:e==="filesystem.read"?t==="filesystem.read"||t==="filesystem.list"||t==="filesystem.exists":e==="filesystem.write"?t==="filesystem.write":e==="terminal.read"||e==="terminal.execute"||e.startsWith("git.")?t==="shell.exec":e==="browser.navigate"?ie.has(t):e==="browser.inspect"?oe.has(t):e==="browser.interact"?t.startsWith("browser.")&&!ie.has(t)&&!oe.has(t):e==="computer.read"?le.has(t):e==="computer.interact"?t.startsWith("computer.")&&!le.has(t)&&!ae.has(t):e==="computer.launch"?ae.has(t):!1}function on(e,t){return{kind:e==="shell.exec"?"shell":"filesystem",label:t}}function an(e){return e==="protocol-safe"?"protocol-safe":"headless-safe"}export{Ne as composeFullToolExecutors,Ze as prepareCliAgent,en as resolveHostToolAvailability,$n as warmMcpRuntime};
@@ -1,3 +1,3 @@
1
- import{runAgentCommand as a}from"../protocol/jsonl-agent-command.js";import{runAuthCommand as t,runConfigCommand as o,runEffortCommand as m,runHookCommand as d,runMcpCommand as c,runModelCommand as l,runPluginCommand as p,runSkillCommand as s,runTrustCommand as f}from"./cli-command-services.js";import{formatCommandHelp as w}from"./command-presentation.js";import{COMMAND_REGISTRY as C}from"./command-runtime.js";import{runGoalCommand as y}from"./goal-command-handlers.js";import{runChatCommand as g,runExecCommand as P,runSessionCommand as x}from"./runtime-command-handlers.js";import{runMediaCommand as E}from"./media-command-handlers.js";import{runCompletionsCommand as S,runDoctorCommand as I,runInspectCommand as O,runUpdateCommand as b}from"./utility-commands.js";import{runMemoryCommand as M}from"./memory-command-handler.js";import{CLI_VERSION as $}from"../../version.js";const k={help:async(r,n)=>i(r,n.output),version:async(r,n)=>i(r,n.output),config:async(r,n)=>o(r.handlerPositionals,n.runtime.configLoader,n.cwd,n.output),auth:async(r,n)=>t(r.handlerPositionals,r.options,n.runtime,n.cwd,n.output,n.secrets?.apiKey),trust:async(r,n)=>f(r.handlerPositionals,n.runtime,n.cwd,n.output),inspect:async(r,n)=>O(n.runtime,n.cwd,n.output),hook:async(r,n)=>d(r.handlerPositionals,n.runtime,n.cwd,n.output),model:async(r,n)=>l(r.handlerPositionals,n.runtime,n.cwd,n.output),effort:async(r,n)=>m(r.handlerPositionals,n.runtime,n.cwd,n.output),mcp:async(r,n)=>c(r.handlerPositionals,r.options,n.runtime,n.cwd,n.output,u(n),n.signal),plugin:async(r,n)=>p(r.handlerPositionals,r.options,n.runtime,n.cwd,n.output,u(n),n.signal),skill:async(r,n)=>s(r.handlerPositionals,r.options,n.runtime,n.cwd,n.output,u(n),n.signal),session:async(r,n)=>x(r.handlerPositionals,r.options,n.runtime,n.cwd,n.output,n.resumeInteractive,n.signal),goal:async(r,n)=>{if(n.writableOutput===void 0)throw new Error("Goal commands require a writable terminal output.");return y(r.handlerPositionals,r.options,n.runtime,n.cwd,n.writableOutput,n.signal)},memory:async(r,n)=>M(r.handlerPositionals,r.options,n.runtime,n.cwd,n.output),doctor:async(r,n)=>I(n.runtime,n.cwd,n.output),chat:async(r,n)=>g(r.handlerPositionals,n.runtime,n.cwd,n.output,n.signal),exec:async(r,n)=>P(r.handlerPositionals,r.options,n.runtime,n.cwd,n.output,n.signal),media:async(r,n)=>E(r,n.runtime,n.cwd,n.output,n.activity,n.signal),agent:async(r,n)=>{if(n.stdin===void 0||n.writableOutput===void 0)throw new Error("The JSONL agent protocol requires stdin and a writable terminal output.");return a(r.handlerPositionals,n.runtime,n.cwd,n.stdin,n.writableOutput,n.signal)},completions:async(r,n)=>S(r.handlerPositionals,n.output),update:async(r,n)=>b(r.handlerPositionals,n.runtime,n.cwd,n.output)};async function J(r,n){const e=k[r.action.executor];if(e===void 0)throw new Error(`Command ${r.action.id} requires a ${r.surface}-specific executor.`);return e(r,n)}function q(r,n){if(r.action.executor==="help")return n.write(`${w(C,r.surface)}
1
+ import{runAgentCommand as a}from"../protocol/jsonl-agent-command.js";import{runAuthCommand as t,runConfigCommand as m,runEffortCommand as o,runHookCommand as d,runMcpCommand as c,runModelCommand as l,runPluginCommand as p,runSkillCommand as s,runTrustCommand as f}from"./cli-command-services.js";import{formatCommandHelp as w}from"./command-presentation.js";import{COMMAND_REGISTRY as C}from"./command-runtime.js";import{runGoalCommand as y}from"./goal-command-handlers.js";import{runChatCommand as g,runExecCommand as P,runSessionCommand as x}from"./runtime-command-handlers.js";import{runMediaCommand as E}from"./media-command-handlers.js";import{runCompletionsCommand as S,runDoctorCommand as I,runInspectCommand as O,runUpdateCommand as b}from"./utility-commands.js";import{runMemoryCommand as M}from"./memory-command-handler.js";import{CLI_VERSION as $}from"../../version.js";const k={help:async(r,n)=>u(r,n.output),version:async(r,n)=>u(r,n.output),config:async(r,n)=>m(r.handlerPositionals,n.runtime.configLoader,n.cwd,n.output),auth:async(r,n)=>t(r.handlerPositionals,r.options,n.runtime,n.cwd,n.output,n.secrets?.apiKey,n.signal),trust:async(r,n)=>f(r.handlerPositionals,n.runtime,n.cwd,n.output),inspect:async(r,n)=>O(n.runtime,n.cwd,n.output),hook:async(r,n)=>d(r.handlerPositionals,n.runtime,n.cwd,n.output),model:async(r,n)=>l(r.handlerPositionals,n.runtime,n.cwd,n.output),effort:async(r,n)=>o(r.handlerPositionals,n.runtime,n.cwd,n.output),mcp:async(r,n)=>c(r.handlerPositionals,r.options,n.runtime,n.cwd,n.output,i(n),n.signal),plugin:async(r,n)=>p(r.handlerPositionals,r.options,n.runtime,n.cwd,n.output,i(n),n.signal),skill:async(r,n)=>s(r.handlerPositionals,r.options,n.runtime,n.cwd,n.output,i(n),n.signal),session:async(r,n)=>x(r.handlerPositionals,r.options,n.runtime,n.cwd,n.output,n.resumeInteractive,n.signal),goal:async(r,n)=>{if(n.writableOutput===void 0)throw new Error("Goal commands require a writable terminal output.");return y(r.handlerPositionals,r.options,n.runtime,n.cwd,n.writableOutput,n.signal)},memory:async(r,n)=>M(r.handlerPositionals,r.options,n.runtime,n.cwd,n.output,n.signal),doctor:async(r,n)=>I(n.runtime,n.cwd,n.output),chat:async(r,n)=>g(r.handlerPositionals,n.runtime,n.cwd,n.output,n.signal),exec:async(r,n)=>P(r.handlerPositionals,r.options,n.runtime,n.cwd,n.output,n.signal),media:async(r,n)=>E(r,n.runtime,n.cwd,n.output,n.activity,n.signal),agent:async(r,n)=>{if(n.stdin===void 0||n.writableOutput===void 0)throw new Error("The JSONL agent protocol requires stdin and a writable terminal output.");return a(r.handlerPositionals,n.runtime,n.cwd,n.stdin,n.writableOutput,n.signal)},completions:async(r,n)=>S(r.handlerPositionals,n.output),update:async(r,n)=>b(r.handlerPositionals,n.runtime,n.cwd,n.output)};async function J(r,n){const e=k[r.action.executor];if(e===void 0)throw new Error(`Command ${r.action.id} requires a ${r.surface}-specific executor.`);return e(r,n)}function q(r,n){if(r.action.executor==="help")return n.write(`${w(C,r.surface)}
2
2
  `),0;if(r.action.executor==="version")return n.write(`${$}
3
- `),0}function i(r,n){const e=q(r,n);if(e===void 0)throw new Error(`Command ${r.action.id} is not informational.`);return e}function u(r){return r.selectScope===void 0?{}:{selectScope:r.selectScope}}export{J as executeApplicationCommand,q as executeInformationalCommand};
3
+ `),0}function u(r,n){const e=q(r,n);if(e===void 0)throw new Error(`Command ${r.action.id} is not informational.`);return e}function i(r){return r.selectScope===void 0?{}:{selectScope:r.selectScope}}export{J as executeApplicationCommand,q as executeInformationalCommand};
@@ -7,7 +7,7 @@ export interface CommandInteraction {
7
7
  selectScope?: (title: string) => Promise<ExtensionScope | undefined>;
8
8
  }
9
9
  export declare function runConfigCommand(positionals: readonly string[], loader: ConfigLoader, cwd: string, output: CommandOutput): Promise<number>;
10
- export declare function runAuthCommand(positionals: readonly string[], flags: ReadonlyMap<string, string | boolean>, runtime: CliRuntime, cwd: string, output: CommandOutput, desktopApiKey?: string): Promise<number>;
10
+ export declare function runAuthCommand(positionals: readonly string[], flags: ReadonlyMap<string, string | boolean>, runtime: CliRuntime, cwd: string, output: CommandOutput, desktopApiKey?: string, signal?: AbortSignal): Promise<number>;
11
11
  export declare function runTrustCommand(positionals: readonly string[], runtime: CliRuntime, cwd: string, output: CommandOutput): Promise<number>;
12
12
  export declare function runModelCommand(positionals: readonly string[], runtime: CliRuntime, cwd: string, output: CommandOutput): Promise<number>;
13
13
  export declare function runEffortCommand(positionals: readonly string[], runtime: CliRuntime, cwd: string, output: CommandOutput): Promise<number>;
@@ -1,33 +1,33 @@
1
- import j from"node:path";import{AuthenticationService as D}from"../auth/authentication-service.js";import{CONFIGURABLE_KEYS as V,DEFAULT_CONFIG as B,REASONING_EFFORTS as H}from"../../domain/config/config-schema.js";import{requirePositional as S,getFlag as $,requireStringFlag as _}from"./cli-args.js";import{readSecret as Y}from"../../infrastructure/credentials/secret-input.js";import{getModelContextWindow as z}from"../../infrastructure/sdk/model-catalog-adapter.js";import{FileMcpConfigStore as F}from"../../infrastructure/extensions/file-mcp-config-store.js";import{McpRuntime as Q}from"../../infrastructure/extensions/mcp-runtime.js";import{PluginManager as G}from"../../infrastructure/extensions/plugin-manager.js";import{SkillManager as X}from"../../infrastructure/extensions/skill-manager.js";import{SkillInstaller as Z}from"../../infrastructure/extensions/skill-installer.js";import{resolveExtensionSource as ee}from"../../infrastructure/extensions/extension-source-resolver.js";import{resolveSkillRootScopes as te}from"../../infrastructure/extensions/skill-roots.js";import{CompositeMcpConfigStore as oe}from"../../infrastructure/extensions/composite-mcp-config-store.js";import{PluginContributionRegistry as x}from"../extensions/plugin-contribution-registry.js";import{parseExtensionScope as ne,requireExtensionScope as re}from"../../domain/extensions/extension-scope.js";import{CliError as P}from"../../domain/errors/cli-error.js";import{CLI_ERROR_CODES as C}from"../../domain/errors/error-codes.js";import{createHookListResult as J,createMcpListResult as ie,createPluginListResult as ae,createSkillListResult as se,formatExtensionList as v}from"../extensions/extension-list-formatters.js";import{writeExtensionListResult as E}from"../extensions/extension-list-output.js";import{HookRuntime as le}from"../../infrastructure/extensions/hook-runtime.js";import{ShellToolExecutor as ce}from"../../infrastructure/shell/shell-tool-executor.js";import{ToolPolicy as fe}from"@lotagate/agent-sdk";import{formatMcpDetails as de}from"../extensions/extension-list-formatters.js";import{loadExecutionConfig as W}from"../config/execution-config.js";import{redactLogText as K}from"../../infrastructure/logging/log-redactor.js";import{formatCompactTable as R}from"../formatting/compact-table.js";import{formatCompactNumber as pe}from"../formatting/compact-number.js";import{loadModelCatalog as ue}from"../model/model-catalog-service.js";import{describeInstalledPlugin as ge}from"../extensions/plugin-detail-service.js";import{throwIfCommandAborted as w}from"./command-cancellation.js";const we={empty:"No models are available.",maxWidth:160,columns:[{key:"name",header:"Name",width:52,minWidth:16},{key:"category",header:"Model category",width:16,minWidth:8},{key:"contextWindow",header:"Context window",width:14,minWidth:8},{key:"status",header:"Status",width:12,minWidth:6},{key:"detail",header:"Detail",minWidth:6}]};async function ze(s,r,e,o){const t=s[0]??"get";if(t==="path")return o.write(`${JSON.stringify({global:r.platformPaths.globalConfigFile,project:j.join(e,".lotagate")},null,2)}
2
- `),0;if(t==="get"){const l=await r.load(e),n=s[1];return o.write(`${JSON.stringify(n===void 0?l.config:l.config[n]??null,null,2)}
3
- `),0}if(t==="set"){const l=S(s,1,"config key");if(!V.includes(l))throw new P(C.INVALID_ARGUMENT,`Unsupported config key: ${l}`,{category:"arguments",userMessage:`Unsupported configuration key: ${l}.`});return await r.setGlobal(l,ye(S(s,2,"config value"))),0}throw new Error(`Unsupported config action: ${t}`)}async function Qe(s,r,e,o,t,l){const n=s[0]??"status",p=await e.configLoader.load(o,{includeProject:!1}),g=p.config.profile??D.defaultProfileName();if(n==="login"){const i=String($(r,"profile")??g),a=String($(r,"base-url")??p.config.baseUrl??B.baseUrl),d=await e.auth.login({profileName:i,baseUrl:a,apiKey:l??await Y("LotaGate API key: ")});return await e.configLoader.setGlobal("profile",d.name),t.write(`Logged in profile: ${d.name}
4
- `),0}if(n==="list"){const i=await e.auth.list();return t.write(`${R(i.map(a=>({name:a.name,status:a.name===g?"ACTIVE":"READY",detail:K(a.baseUrl)})),{empty:"No authentication profiles."})}
5
- `),0}if(n==="status"){const i=await e.credentialStore.get(g);return t.write(`${JSON.stringify(i===void 0?{authenticated:!1,profile:g}:{authenticated:!0,profile:i.profile.name,baseUrl:i.profile.baseUrl,credentialRef:i.profile.credentialRef},null,2)}
6
- `),0}if(n==="logout"){const i=s[1]??g,a=await e.auth.logout(i);return t.write(`${a?`Logged out profile: ${i}`:`Profile not found: ${i}`}
7
- `),a?0:1}if(n==="use"){const i=S(s,1,"profile name");return await e.auth.requireCredential(i),await e.configLoader.setGlobal("profile",i),t.write(`Active profile: ${i}
8
- `),0}throw new Error(`Unsupported auth action: ${n}`)}async function Xe(s,r,e,o){const t=s[0]??"status";if(t==="list")return o.write(`${R((await r.projectTrust.list()).map(n=>({name:n.canonicalPath,status:"TRUSTED",detail:n.fingerprint})),{empty:"No trusted projects."})}
9
- `),0;const l=await r.projectTrust.inspect(e);if(t==="status")return o.write(`${JSON.stringify({...l,trusted:await r.projectTrust.isTrusted(l)},null,2)}
10
- `),0;if(t==="grant")return await r.projectTrust.grant(l),await r.workspaceSettings.ensureInitialized(l.canonicalPath),o.write(`Trusted project: ${l.canonicalPath}
11
- `),0;if(t==="revoke"){const n=await r.projectTrust.revoke(l);return o.write(`${n?`Revoked project: ${l.canonicalPath}`:"Project was not trusted."}
12
- `),n?0:1}throw new Error(`Unsupported trust action: ${t}`)}async function Ze(s,r,e,o){const t=s[0]??"current",l=await W(r,e);if(t==="current")return o.write(`${JSON.stringify({model:l.config.model,profile:l.config.profile},null,2)}
13
- `),0;if(t==="use"){const n=S(s,1,"model id");return await r.configLoader.setGlobal("model",n),o.write(`Active model: ${n}
14
- `),0}if(t==="list"||t==="refresh"){const n=await ue(r,e,t==="refresh");return o.write(`${R(n.data.map(p=>({name:typeof p.display_name=="string"?p.display_name:p.id,status:p.id===l.config.model?"ACTIVE":"AVAILABLE",...typeof p.owned_by=="string"?{detail:p.owned_by}:{},values:{category:typeof p.model_category=="string"?p.model_category:"-",contextWindow:me(p)}})),we)}
15
- `),0}if(t==="doctor"){const n=l.config.profile??D.defaultProfileName(),p=await r.auth.status(n);return o.write(`${JSON.stringify({profile:n,authenticated:p!==void 0,model:l.config.model,baseUrl:p?.baseUrl??l.config.baseUrl},null,2)}
16
- `),0}throw new Error(`Unsupported model action: ${t}`)}async function et(s,r,e,o){const t=s[0]??"current",l=await W(r,e);if(t==="current")return o.write(`${JSON.stringify({effort:l.config.effort},null,2)}
17
- `),0;if(t==="use"){const n=S(s,1,"effort");if(!H.includes(n))throw new Error(`Unsupported reasoning effort: ${n}`);return await r.configLoader.setGlobal("effort",n),o.write(`Active effort: ${n}
18
- `),0}throw new Error(`Unsupported effort action: ${t}`)}function me(s){const r=z(s);return r===void 0?"-":pe(r)}async function tt(s,r,e,o,t,l={},n){w(n);const p=F.forScope(o,e.paths.globalConfigDir,"project"),g=F.forScope(o,e.paths.globalConfigDir,"user"),i=s[0]??"list";if(i==="list"){const c=await e.projectTrust.inspect(o),h=await e.projectTrust.isTrusted(c),f=await new x(e.paths.globalConfigDir).resolve(o,h),m=ie([{scope:"user",config:await g.list()},{scope:"project",config:await p.list()},...h&&Object.keys(f.mcpConfig).length>0?[{scope:"plugin",config:f.mcpConfig,sourceNames:Object.fromEntries(f.mcpContributions.map(b=>[b.qualifiedName,b.sourceName])),pluginNames:Object.fromEntries(f.mcpContributions.map(b=>[b.qualifiedName,b.pluginName]))}]:[]]);return E(t,m,v(m)),0}if(i==="reload"||i==="doctor"){w(n),i==="reload"&&await e.mcpRuntime.invalidate(o);const c=new Q(()=>new oe([g,p]));try{const h=await e.projectTrust.inspect(o),f=await c.connectConfigured(o,await e.projectTrust.isTrusted(h));return w(n),t.write(`${R(f.map(({serverId:m,status:b,protocolEra:T,protocolVersion:N,error:M})=>({name:m,status:b==="connected"?"OK":b.toUpperCase(),detail:M===void 0?[T,N].filter(Boolean).join(" \xB7 "):K(M.message)})),{empty:"No MCP servers configured."})}
19
- `),f.some(m=>m.status==="failed")?1:0}finally{await c.close()}}const a=S(s,1,"MCP server name"),d=await U(r,l,"MCP server scope",!0);if(d===void 0)throw new Error("MCP server scope was not selected.");const u={store:d==="project"?p:g,scope:d},y=u.store;if(i==="get"){const c=await y.get(a);return t.write(`${de(a,u.scope,c)}
20
- `),0}if(i==="remove"){w(n),await k(e,o,u.scope);const c=await y.remove(a);return c&&await e.mcpRuntime.invalidate(o),e.logger.info("MCP server removal completed.",{name:a,scope:u.scope,removed:c}),t.write(`${c?`Removed MCP server: ${a}`:`MCP server not found: ${a}`}
21
- `),c?0:1}if(i==="enable"||i==="disable")return w(n),await k(e,o,u.scope),await y.setEnabled(a,i==="enable"),await e.mcpRuntime.invalidate(o),e.logger.info("MCP server state changed.",{name:a,scope:u.scope,enabled:i==="enable"}),t.write(`${i==="enable"?"Enabled":"Disabled"} MCP server: ${a}
22
- `),0;if(i==="add"){w(n),await k(e,o,d??"project");const c=String($(r,"type")??"stdio");if(c==="stdio"){const h=_(r,"command"),f=$(r,"args");await y.add(a,{type:"stdio",command:h,...typeof f=="string"?{args:f.split(",").map(m=>m.trim()).filter(Boolean)}:{}})}else if(c==="http"||c==="sse")await y.add(a,{type:c,url:_(r,"url")});else throw new P(C.INVALID_ARGUMENT,`Unsupported MCP type: ${c}`,{category:"arguments",userMessage:"MCP type must be stdio, http, or sse."});return w(n),await e.mcpRuntime.invalidate(o),e.logger.info("MCP server added.",{name:a,scope:d??"project",type:c}),t.write(`Added MCP server successfully: ${a}
23
- `),0}throw new Error(`Unsupported MCP action: ${i}`)}async function ot(s,r,e,o,t,l={},n){w(n);const p=new G(e.paths.pluginsDir),g=new G(j.join(j.resolve(o),".lotagate","plugins")),i=s[0]??"list";if(i==="list"){const f=ae([{scope:"user",plugins:await p.list(void 0,{verifyIntegrity:!1})},{scope:"project",plugins:await g.list(void 0,{verifyIntegrity:!1})}]);return E(t,f,v(f)),0}if(i==="install"){const f=S(s,1,"plugin or skill source"),m=await U(r,l,"Plugin installation scope",!0);if(m===void 0)throw new Error("Plugin installation scope was not selected.");await k(e,o,m);const b=$(r,"sha256"),T=$(r,"signature"),N=$(r,"public-key"),M=m==="project"?g:p,q=m==="project"?j.join(j.resolve(o),".lotagate","skills"):e.paths.skillsDir,O=await ee(f,e.platform,n);try{w(n);const A={...typeof b=="string"?{sha256:b}:{},...typeof T=="string"?{signature:T}:{},...typeof N=="string"?{publicKeyPem:N}:{}},L=await new Z().install(O.directory,q,A);if(L!==void 0)return w(n),e.logger.info("Skill installed.",{name:L.manifest.name,scope:m}),t.write(`Added skill successfully: ${L.manifest.name}
24
- `),0;const I=await M.install(O.directory,A);return w(n),e.logger.info("Plugin installed.",{name:I.manifest.name,scope:m}),t.write(`Added plugin successfully: ${I.manifest.name}
25
- `),0}finally{await O.cleanup()}}const a=S(s,1,"plugin name"),d=await U(r,l,"Plugin scope",!0);if(d===void 0)throw new Error("Plugin scope was not selected.");const u={manager:d==="project"?g:p,scope:d},y=u.manager,h=(await y.list(void 0,{verifyIntegrity:!1})).find(f=>f.manifest.name===a);if(h===void 0)throw new P(C.PLUGIN_NOT_FOUND,`Plugin not found: ${a}`,{category:"extension",userMessage:`Plugin not found: ${a}.`});if(i==="info"){const f=await ge(h,d);return t.writeStructured===void 0?t.write(`${JSON.stringify(f,null,2)}
1
+ import j from"node:path";import{AuthenticationService as D}from"../auth/authentication-service.js";import{CONFIGURABLE_KEYS as V,DEFAULT_CONFIG as B,REASONING_EFFORTS as H}from"../../domain/config/config-schema.js";import{requirePositional as S,getFlag as $,requireStringFlag as _}from"./cli-args.js";import{readSecret as Y}from"../../infrastructure/credentials/secret-input.js";import{getModelContextWindow as z}from"../../infrastructure/sdk/model-catalog-adapter.js";import{FileMcpConfigStore as F}from"../../infrastructure/extensions/file-mcp-config-store.js";import{McpRuntime as Q}from"../../infrastructure/extensions/mcp-runtime.js";import{PluginManager as G}from"../../infrastructure/extensions/plugin-manager.js";import{SkillManager as X}from"../../infrastructure/extensions/skill-manager.js";import{SkillInstaller as Z}from"../../infrastructure/extensions/skill-installer.js";import{resolveExtensionSource as ee}from"../../infrastructure/extensions/extension-source-resolver.js";import{resolveSkillRootScopes as te}from"../../infrastructure/extensions/skill-roots.js";import{CompositeMcpConfigStore as oe}from"../../infrastructure/extensions/composite-mcp-config-store.js";import{PluginContributionRegistry as x}from"../extensions/plugin-contribution-registry.js";import{parseExtensionScope as ne,requireExtensionScope as re}from"../../domain/extensions/extension-scope.js";import{CliError as P}from"../../domain/errors/cli-error.js";import{CLI_ERROR_CODES as C}from"../../domain/errors/error-codes.js";import{createHookListResult as J,createMcpListResult as ie,createPluginListResult as ae,createSkillListResult as se,formatExtensionList as v}from"../extensions/extension-list-formatters.js";import{writeExtensionListResult as E}from"../extensions/extension-list-output.js";import{HookRuntime as le}from"../../infrastructure/extensions/hook-runtime.js";import{ShellToolExecutor as ce}from"../../infrastructure/shell/shell-tool-executor.js";import{ToolPolicy as fe}from"@lotagate/agent-sdk";import{formatMcpDetails as de}from"../extensions/extension-list-formatters.js";import{loadExecutionConfig as W}from"../config/execution-config.js";import{redactLogText as K}from"../../infrastructure/logging/log-redactor.js";import{formatCompactTable as R}from"../formatting/compact-table.js";import{formatCompactNumber as pe}from"../formatting/compact-number.js";import{loadModelCatalog as ue}from"../model/model-catalog-service.js";import{describeInstalledPlugin as ge}from"../extensions/plugin-detail-service.js";import{throwIfCommandAborted as g}from"./command-cancellation.js";const we={empty:"No models are available.",maxWidth:160,columns:[{key:"name",header:"Name",width:52,minWidth:16},{key:"category",header:"Model category",width:16,minWidth:8},{key:"contextWindow",header:"Context window",width:14,minWidth:8},{key:"status",header:"Status",width:12,minWidth:6},{key:"detail",header:"Detail",minWidth:6}]};async function ze(a,r,e,o){const t=a[0]??"get";if(t==="path")return o.write(`${JSON.stringify({global:r.platformPaths.globalConfigFile,project:j.join(e,".lotagate")},null,2)}
2
+ `),0;if(t==="get"){const s=await r.load(e),i=a[1];return o.write(`${JSON.stringify(i===void 0?s.config:s.config[i]??null,null,2)}
3
+ `),0}if(t==="set"){const s=S(a,1,"config key");if(!V.includes(s))throw new P(C.INVALID_ARGUMENT,`Unsupported config key: ${s}`,{category:"arguments",userMessage:`Unsupported configuration key: ${s}.`});return await r.setGlobal(s,ye(S(a,2,"config value"))),0}throw new Error(`Unsupported config action: ${t}`)}async function Qe(a,r,e,o,t,s,i){g(i);const p=a[0]??"status",w=await e.configLoader.load(o,{includeProject:!1}),l=w.config.profile??D.defaultProfileName();if(p==="login"){const n=String($(r,"profile")??l),d=String($(r,"base-url")??w.config.baseUrl??B.baseUrl),u=await e.auth.login({profileName:n,baseUrl:d,apiKey:s??await Y("LotaGate API key: ",process.stdin,process.stderr,i)});return await e.configLoader.setGlobal("profile",u.name),t.write(`Logged in profile: ${u.name}
4
+ `),0}if(p==="list"){const n=await e.auth.list();return t.write(`${R(n.map(d=>({name:d.name,status:d.name===l?"ACTIVE":"READY",detail:K(d.baseUrl)})),{empty:"No authentication profiles."})}
5
+ `),0}if(p==="status"){const n=await e.credentialStore.get(l);return t.write(`${JSON.stringify(n===void 0?{authenticated:!1,profile:l}:{authenticated:!0,profile:n.profile.name,baseUrl:n.profile.baseUrl,credentialRef:n.profile.credentialRef},null,2)}
6
+ `),0}if(p==="logout"){const n=a[1]??l,d=await e.auth.logout(n);return t.write(`${d?`Logged out profile: ${n}`:`Profile not found: ${n}`}
7
+ `),d?0:1}if(p==="use"){const n=S(a,1,"profile name");return await e.auth.requireCredential(n),await e.configLoader.setGlobal("profile",n),t.write(`Active profile: ${n}
8
+ `),0}throw new Error(`Unsupported auth action: ${p}`)}async function Xe(a,r,e,o){const t=a[0]??"status";if(t==="list")return o.write(`${R((await r.projectTrust.list()).map(i=>({name:i.canonicalPath,status:"TRUSTED",detail:i.fingerprint})),{empty:"No trusted projects."})}
9
+ `),0;const s=await r.projectTrust.inspect(e);if(t==="status")return o.write(`${JSON.stringify({...s,trusted:await r.projectTrust.isTrusted(s)},null,2)}
10
+ `),0;if(t==="grant")return await r.projectTrust.grant(s),await r.workspaceSettings.ensureInitialized(s.canonicalPath),o.write(`Trusted project: ${s.canonicalPath}
11
+ `),0;if(t==="revoke"){const i=await r.projectTrust.revoke(s);return o.write(`${i?`Revoked project: ${s.canonicalPath}`:"Project was not trusted."}
12
+ `),i?0:1}throw new Error(`Unsupported trust action: ${t}`)}async function Ze(a,r,e,o){const t=a[0]??"current",s=await W(r,e);if(t==="current")return o.write(`${JSON.stringify({model:s.config.model,profile:s.config.profile},null,2)}
13
+ `),0;if(t==="use"){const i=S(a,1,"model id");return await r.configLoader.setGlobal("model",i),o.write(`Active model: ${i}
14
+ `),0}if(t==="list"||t==="refresh"){const i=await ue(r,e,t==="refresh");return o.write(`${R(i.data.map(p=>({name:typeof p.display_name=="string"?p.display_name:p.id,status:p.id===s.config.model?"ACTIVE":"AVAILABLE",...typeof p.owned_by=="string"?{detail:p.owned_by}:{},values:{category:typeof p.model_category=="string"?p.model_category:"-",contextWindow:me(p)}})),we)}
15
+ `),0}if(t==="doctor"){const i=s.config.profile??D.defaultProfileName(),p=await r.auth.status(i);return o.write(`${JSON.stringify({profile:i,authenticated:p!==void 0,model:s.config.model,baseUrl:p?.baseUrl??s.config.baseUrl},null,2)}
16
+ `),0}throw new Error(`Unsupported model action: ${t}`)}async function et(a,r,e,o){const t=a[0]??"current",s=await W(r,e);if(t==="current")return o.write(`${JSON.stringify({effort:s.config.effort},null,2)}
17
+ `),0;if(t==="use"){const i=S(a,1,"effort");if(!H.includes(i))throw new Error(`Unsupported reasoning effort: ${i}`);return await r.configLoader.setGlobal("effort",i),o.write(`Active effort: ${i}
18
+ `),0}throw new Error(`Unsupported effort action: ${t}`)}function me(a){const r=z(a);return r===void 0?"-":pe(r)}async function tt(a,r,e,o,t,s={},i){g(i);const p=F.forScope(o,e.paths.globalConfigDir,"project"),w=F.forScope(o,e.paths.globalConfigDir,"user"),l=a[0]??"list";if(l==="list"){const c=await e.projectTrust.inspect(o),h=await e.projectTrust.isTrusted(c),f=await new x(e.paths.globalConfigDir).resolve(o,h),m=ie([{scope:"user",config:await w.list()},{scope:"project",config:await p.list()},...h&&Object.keys(f.mcpConfig).length>0?[{scope:"plugin",config:f.mcpConfig,sourceNames:Object.fromEntries(f.mcpContributions.map(b=>[b.qualifiedName,b.sourceName])),pluginNames:Object.fromEntries(f.mcpContributions.map(b=>[b.qualifiedName,b.pluginName]))}]:[]]);return E(t,m,v(m)),0}if(l==="reload"||l==="doctor"){g(i),l==="reload"&&await e.mcpRuntime.invalidate(o);const c=new Q(()=>new oe([w,p]));try{const h=await e.projectTrust.inspect(o),f=await c.connectConfigured(o,await e.projectTrust.isTrusted(h));return g(i),t.write(`${R(f.map(({serverId:m,status:b,protocolEra:T,protocolVersion:N,error:M})=>({name:m,status:b==="connected"?"OK":b.toUpperCase(),detail:M===void 0?[T,N].filter(Boolean).join(" \xB7 "):K(M.message)})),{empty:"No MCP servers configured."})}
19
+ `),f.some(m=>m.status==="failed")?1:0}finally{await c.close()}}const n=S(a,1,"MCP server name"),d=await U(r,s,"MCP server scope",!0);if(d===void 0)throw new Error("MCP server scope was not selected.");const u={store:d==="project"?p:w,scope:d},y=u.store;if(l==="get"){const c=await y.get(n);return t.write(`${de(n,u.scope,c)}
20
+ `),0}if(l==="remove"){g(i),await k(e,o,u.scope);const c=await y.remove(n);return c&&await e.mcpRuntime.invalidate(o),e.logger.info("MCP server removal completed.",{name:n,scope:u.scope,removed:c}),t.write(`${c?`Removed MCP server: ${n}`:`MCP server not found: ${n}`}
21
+ `),c?0:1}if(l==="enable"||l==="disable")return g(i),await k(e,o,u.scope),await y.setEnabled(n,l==="enable"),await e.mcpRuntime.invalidate(o),e.logger.info("MCP server state changed.",{name:n,scope:u.scope,enabled:l==="enable"}),t.write(`${l==="enable"?"Enabled":"Disabled"} MCP server: ${n}
22
+ `),0;if(l==="add"){g(i),await k(e,o,d??"project");const c=String($(r,"type")??"stdio");if(c==="stdio"){const h=_(r,"command"),f=$(r,"args");await y.add(n,{type:"stdio",command:h,...typeof f=="string"?{args:f.split(",").map(m=>m.trim()).filter(Boolean)}:{}})}else if(c==="http"||c==="sse")await y.add(n,{type:c,url:_(r,"url")});else throw new P(C.INVALID_ARGUMENT,`Unsupported MCP type: ${c}`,{category:"arguments",userMessage:"MCP type must be stdio, http, or sse."});return g(i),await e.mcpRuntime.invalidate(o),e.logger.info("MCP server added.",{name:n,scope:d??"project",type:c}),t.write(`Added MCP server successfully: ${n}
23
+ `),0}throw new Error(`Unsupported MCP action: ${l}`)}async function ot(a,r,e,o,t,s={},i){g(i);const p=new G(e.paths.pluginsDir),w=new G(j.join(j.resolve(o),".lotagate","plugins")),l=a[0]??"list";if(l==="list"){const f=ae([{scope:"user",plugins:await p.list(void 0,{verifyIntegrity:!1})},{scope:"project",plugins:await w.list(void 0,{verifyIntegrity:!1})}]);return E(t,f,v(f)),0}if(l==="install"){const f=S(a,1,"plugin or skill source"),m=await U(r,s,"Plugin installation scope",!0);if(m===void 0)throw new Error("Plugin installation scope was not selected.");await k(e,o,m);const b=$(r,"sha256"),T=$(r,"signature"),N=$(r,"public-key"),M=m==="project"?w:p,q=m==="project"?j.join(j.resolve(o),".lotagate","skills"):e.paths.skillsDir,O=await ee(f,e.platform,i);try{g(i);const A={...typeof b=="string"?{sha256:b}:{},...typeof T=="string"?{signature:T}:{},...typeof N=="string"?{publicKeyPem:N}:{}},L=await new Z().install(O.directory,q,A);if(L!==void 0)return g(i),e.logger.info("Skill installed.",{name:L.manifest.name,scope:m}),t.write(`Added skill successfully: ${L.manifest.name}
24
+ `),0;const I=await M.install(O.directory,A);return g(i),e.logger.info("Plugin installed.",{name:I.manifest.name,scope:m}),t.write(`Added plugin successfully: ${I.manifest.name}
25
+ `),0}finally{await O.cleanup()}}const n=S(a,1,"plugin name"),d=await U(r,s,"Plugin scope",!0);if(d===void 0)throw new Error("Plugin scope was not selected.");const u={manager:d==="project"?w:p,scope:d},y=u.manager,h=(await y.list(void 0,{verifyIntegrity:!1})).find(f=>f.manifest.name===n);if(h===void 0)throw new P(C.PLUGIN_NOT_FOUND,`Plugin not found: ${n}`,{category:"extension",userMessage:`Plugin not found: ${n}.`});if(l==="info"){const f=await ge(h,d);return t.writeStructured===void 0?t.write(`${JSON.stringify(f,null,2)}
26
26
  `):t.writeStructured(f,`${JSON.stringify(f,null,2)}
27
- `),0}if(i==="enable"||i==="disable")return w(n),await k(e,o,u.scope),await y.setEnabled(a,i==="enable"),e.logger.info("Plugin state changed.",{name:a,scope:u.scope,enabled:i==="enable"}),t.write(`${i==="enable"?"Enabled":"Disabled"} plugin: ${a}
28
- `),0;if(i==="uninstall"){w(n),await k(e,o,u.scope);const f=await y.uninstall(a);return e.logger.info("Plugin uninstallation completed.",{name:a,scope:u.scope,removed:f}),t.write(`${f?`Uninstalled plugin: ${a}`:`Plugin not found: ${a}`}
29
- `),f?0:1}throw new Error(`Unsupported plugin action: ${i}`)}async function U(s,r,e,o){const t=ne($(s,"scope"));if(t!==void 0)return t;const l=r.selectScope===void 0?void 0:await r.selectScope(e);return l!==void 0?l:o?re(void 0):void 0}async function k(s,r,e){if(e!=="project")return;const o=await s.projectTrust.inspect(r);if(!await s.projectTrust.isTrusted(o))throw new P(C.PROJECT_TRUST_REQUIRED,"Project scope requires trust.",{category:"project",userMessage:"Trust the project before writing project-scoped extensions."})}async function nt(s,r,e,o,t,l={},n){w(n);const p=await e.projectTrust.inspect(o),g=await new x(e.paths.globalConfigDir).resolve(o,await e.projectTrust.isTrusted(p)),i=te(o,e.paths.globalConfigDir,g.skillRoots),a=new X(j.join(e.paths.globalConfigDir,"skills-state.json")),d=s[0]??"list";if(d==="list"){const f=se(await a.listScoped(i,{includeShadowed:!0}));return E(t,f,v(f)),0}const u=S(s,1,"skill name"),y=await U(r,l,"Skill scope",!0);if(y===void 0)throw new Error("Skill scope was not selected.");const c=(await a.listScoped(i,{includeShadowed:!0})).find(f=>f.skillKey===u&&f.scope===y);if(c===void 0)throw new P(C.SKILL_NOT_FOUND,`Skill not found: ${u}`,{category:"extension",userMessage:`Skill not found: ${u}.`});if(d==="remove"&&c.scope!=="user"&&c.scope!=="project")throw new P(C.INVALID_ARGUMENT,`Skill cannot be removed from the ${c.scope} scope: ${u}`,{category:"arguments",userMessage:"Only user- and project-scoped skills can be removed."});const h=c.scope==="project";if((d==="remove"||d==="enable"||d==="disable")&&await k(e,o,h?"project":"user"),d==="info")return t.write(`${JSON.stringify(he(c),null,2)}
30
- `),0;if(d==="enable"||d==="disable")return w(n),await a.setEnabled(c.skillKey,d==="enable",c.statePath),e.logger.info("Skill state changed.",{name:u,scope:c.scope,enabled:d==="enable"}),t.write(`${d==="enable"?"Enabled":"Disabled"} skill: ${u}
31
- `),0;if(d==="remove"){w(n);const f=await a.remove(c.skillKey,c.root,c.statePath);return e.logger.info("Skill removal completed.",{name:u,scope:c.scope,removed:f}),t.write(`${f?`Removed skill: ${u}`:`Skill not found: ${u}`}
27
+ `),0}if(l==="enable"||l==="disable")return g(i),await k(e,o,u.scope),await y.setEnabled(n,l==="enable"),e.logger.info("Plugin state changed.",{name:n,scope:u.scope,enabled:l==="enable"}),t.write(`${l==="enable"?"Enabled":"Disabled"} plugin: ${n}
28
+ `),0;if(l==="uninstall"){g(i),await k(e,o,u.scope);const f=await y.uninstall(n);return e.logger.info("Plugin uninstallation completed.",{name:n,scope:u.scope,removed:f}),t.write(`${f?`Uninstalled plugin: ${n}`:`Plugin not found: ${n}`}
29
+ `),f?0:1}throw new Error(`Unsupported plugin action: ${l}`)}async function U(a,r,e,o){const t=ne($(a,"scope"));if(t!==void 0)return t;const s=r.selectScope===void 0?void 0:await r.selectScope(e);return s!==void 0?s:o?re(void 0):void 0}async function k(a,r,e){if(e!=="project")return;const o=await a.projectTrust.inspect(r);if(!await a.projectTrust.isTrusted(o))throw new P(C.PROJECT_TRUST_REQUIRED,"Project scope requires trust.",{category:"project",userMessage:"Trust the project before writing project-scoped extensions."})}async function nt(a,r,e,o,t,s={},i){g(i);const p=await e.projectTrust.inspect(o),w=await new x(e.paths.globalConfigDir).resolve(o,await e.projectTrust.isTrusted(p)),l=te(o,e.paths.globalConfigDir,w.skillRoots),n=new X(j.join(e.paths.globalConfigDir,"skills-state.json")),d=a[0]??"list";if(d==="list"){const f=se(await n.listScoped(l,{includeShadowed:!0}));return E(t,f,v(f)),0}const u=S(a,1,"skill name"),y=await U(r,s,"Skill scope",!0);if(y===void 0)throw new Error("Skill scope was not selected.");const c=(await n.listScoped(l,{includeShadowed:!0})).find(f=>f.skillKey===u&&f.scope===y);if(c===void 0)throw new P(C.SKILL_NOT_FOUND,`Skill not found: ${u}`,{category:"extension",userMessage:`Skill not found: ${u}.`});if(d==="remove"&&c.scope!=="user"&&c.scope!=="project")throw new P(C.INVALID_ARGUMENT,`Skill cannot be removed from the ${c.scope} scope: ${u}`,{category:"arguments",userMessage:"Only user- and project-scoped skills can be removed."});const h=c.scope==="project";if((d==="remove"||d==="enable"||d==="disable")&&await k(e,o,h?"project":"user"),d==="info")return t.write(`${JSON.stringify(he(c),null,2)}
30
+ `),0;if(d==="enable"||d==="disable")return g(i),await n.setEnabled(c.skillKey,d==="enable",c.statePath),e.logger.info("Skill state changed.",{name:u,scope:c.scope,enabled:d==="enable"}),t.write(`${d==="enable"?"Enabled":"Disabled"} skill: ${u}
31
+ `),0;if(d==="remove"){g(i);const f=await n.remove(c.skillKey,c.root,c.statePath);return e.logger.info("Skill removal completed.",{name:u,scope:c.scope,removed:f}),t.write(`${f?`Removed skill: ${u}`:`Skill not found: ${u}`}
32
32
  `),f?0:1}if(d==="run"){if(!c.enabled)throw new P(C.SKILL_NOT_FOUND,`Skill is disabled: ${u}`,{category:"extension",userMessage:`Skill is disabled: ${u}.`});return t.write(`${c.body}
33
- `),0}throw new Error(`Unsupported skill action: ${d}`)}async function rt(s,r,e,o){const t=s[0]??"list";if(t!=="list")throw new Error(`Unsupported hook action: ${t}`);const l=await r.projectTrust.inspect(e);if(!await r.projectTrust.isTrusted(l)){const a=J([]);return E(o,a,v(a)),0}const n=new le(new ce({platform:r.platform}),{trustedProject:!0,enabled:!0,toolPolicy:new fe}),p=await new x(r.paths.globalConfigDir).resolve(e,!0),g=[...await n.loadProject(l.canonicalPath)];for(const a of p.plugins)g.push(...await n.load(a));const i=J(g);return E(o,i,v(i)),0}function ye(s){return s==="true"?!0:s==="false"?!1:s==="null"?null:s}function he(s){const{root:r,statePath:e,...o}=s;return o}export{Qe as runAuthCommand,ze as runConfigCommand,et as runEffortCommand,rt as runHookCommand,tt as runMcpCommand,Ze as runModelCommand,ot as runPluginCommand,nt as runSkillCommand,Xe as runTrustCommand};
33
+ `),0}throw new Error(`Unsupported skill action: ${d}`)}async function rt(a,r,e,o){const t=a[0]??"list";if(t!=="list")throw new Error(`Unsupported hook action: ${t}`);const s=await r.projectTrust.inspect(e);if(!await r.projectTrust.isTrusted(s)){const n=J([]);return E(o,n,v(n)),0}const i=new le(new ce({platform:r.platform}),{trustedProject:!0,enabled:!0,toolPolicy:new fe}),p=await new x(r.paths.globalConfigDir).resolve(e,!0),w=[...await i.loadProject(s.canonicalPath)];for(const n of p.plugins)w.push(...await i.load(n));const l=J(w);return E(o,l,v(l)),0}function ye(a){return a==="true"?!0:a==="false"?!1:a==="null"?null:a}function he(a){const{root:r,statePath:e,...o}=a;return o}export{Qe as runAuthCommand,ze as runConfigCommand,et as runEffortCommand,rt as runHookCommand,tt as runMcpCommand,Ze as runModelCommand,ot as runPluginCommand,nt as runSkillCommand,Xe as runTrustCommand};
@@ -1,7 +1,7 @@
1
- import{isFlagEnabled as G,requirePositional as v}from"./cli-args.js";import{ProjectSessionAccess as D}from"../session/project-session-access.js";import{AuthenticationService as L}from"../auth/authentication-service.js";import{loadExecutionConfig as P}from"../config/execution-config.js";import{createLotaGateClient as x}from"../../infrastructure/sdk/lotagate-client-factory.js";import{runHeadlessAgentTurn as F}from"../orchestration/headless-agent-turn.js";import{runGoalLoop as q}from"../orchestration/goal-runner.js";import{CliAgentSessionStore as $}from"../agent/agent-session-store.js";import{formatGoalStatus as k}from"../orchestration/goal-output.js";import{parseGoalInput as B}from"../orchestration/goal-input.js";import{CliError as p}from"../../domain/errors/cli-error.js";import{CLI_ERROR_CODES as g}from"../../domain/errors/error-codes.js";import{MODEL_SELECT_HINT as H,TRUST_GRANT_HINT as J}from"./command-hints.js";import{createTurnId as K,recordTurnCompletion as Q,recordTurnFailure as W,recordTurnStart as z}from"../session/session-turn-lifecycle.js";import{createCommandAbortController as V,throwIfCommandAborted as O}from"./command-cancellation.js";async function fe(r,t,e,u,s,c){const i=r[0]??"status";if(i==="run")return M(r.slice(1).join(" ").trim(),t,e,u,s,void 0,c);O(c);const l=v(r,1,"session id"),d=await e.projectTrust.inspect(u);if(await new D(e.sessionStore).require(l,d.fingerprint),i==="status")return N(s,await e.goalStore.get(l),G(t,"json"));if(i==="set"){const n=v([r.slice(2).join(" ")],0,"goal objective"),w=await e.goalStore.replace(l,U(n,t));return N(s,w,G(t,"json"))}if(i==="pause"){const n=await e.goalStore.pause(l);return N(s,n,G(t,"json"))}if(i==="resume"){const n=await e.goalStore.get(l);if(n===void 0)throw new p(g.GOAL_NOT_FOUND,"Goal not found.",{category:"goal",userMessage:"Goal was not found."});return M(n.objective,t,e,u,s,l,c)}if(i==="clear")return await e.goalStore.clear(l),s.write(`Goal cleared.
2
- `),0;throw new Error(`Unsupported goal action: ${i}`)}async function M(r,t,e,u,s,c,i){if(O(i),r.length===0)throw new p(g.MISSING_ARGUMENT,"Missing goal objective.",{category:"arguments",userMessage:"A goal objective is required."});const l=U(r,t),d=await e.projectTrust.inspect(u);if(!await e.projectTrust.isTrusted(d))throw new p(g.PROJECT_TRUST_REQUIRED,"Project trust is required for goals.",{category:"project",userMessage:"Project is not trusted.",hint:J});const n=await P(e,u);if(n.config.model===null)throw new p(g.MODEL_NOT_FOUND,"No model is selected.",{category:"model",userMessage:"No model is selected.",hint:H});const w=n.config.model,T=n.config.profile??L.defaultProfileName(),y=await e.auth.requireCredential(T),a=c===void 0?await e.sessionStore.create({projectFingerprint:d.fingerprint,cwd:d.canonicalPath,model:n.config.model,profile:T,status:"active"}):await e.sessionStore.get(c);if(a===void 0)throw new p(g.SESSION_NOT_FOUND,"Goal session not found.",{category:"session",userMessage:"Goal session was not found."});c===void 0?await e.goalStore.create(a.id,l):await e.goalStore.resume(a.id);const I=x(y.profile,y.apiKey),R=new $,h=V(i),E=h.controller,j=()=>E.abort(new Error("Goal interrupted by user."));process.once("SIGINT",j);try{const f=await q({runtime:e,sessionId:a.id,objective:r,model:w,client:I,signal:E.signal,runTurn:async(C,m,A)=>{const S=K();await z(e.sessionStore,a.id,S,C);try{const o=await e.goalStore.get(a.id),_=await F({runtime:e,cwd:u,model:w,profileName:T,client:I,prompt:C,output:s,sessionId:a.id,agentSessionStore:R,signal:A,turnId:S,...o===void 0?{}:{goal:{objective:o.objective,status:o.status,turns:o.turns,evaluatorRuns:o.evaluatorRuns,tokensUsed:o.usage.totalTokens,...o.tokenBudget===void 0?{}:{tokenBudget:o.tokenBudget},...o.maxTurns===void 0?{}:{maxTurns:o.maxTurns},...o.maxDurationMs===void 0?{}:{maxDurationMs:o.maxDurationMs},...o.lastError===void 0?{}:{lastError:o.lastError},...o.lastEvaluation===void 0?{}:{lastEvaluation:o.lastEvaluation.reason}}},onUsage:m.onUsage,onSubagentUsage:m.onUsage,onSnapshot:m.onSnapshot});return s.write(`
3
- `),await Q(e.sessionStore,a.id,S,_),_}catch(o){throw m.onError(o),await W(e.sessionStore,a.id,S,o,E.signal.aborted),o}}});await e.sessionStore.updateStatus(a.id,f?.status==="completed"?"completed":f?.status==="paused"?"active":"failed"),s.write(`Goal session: ${a.id}
4
- `);const b=f?.status==="paused"&&f.lastError?.startsWith("Goal paused by safety limit:")===!0;return f?.status==="completed"||b?0:1}finally{process.off("SIGINT",j),h.dispose()}}function U(r,t){return B(r,t)}function N(r,t,e){return e?(r.write(`${JSON.stringify(t??null)}
1
+ import{isFlagEnabled as G,requirePositional as O}from"./cli-args.js";import{ProjectSessionAccess as L}from"../session/project-session-access.js";import{AuthenticationService as P}from"../auth/authentication-service.js";import{loadExecutionConfig as x}from"../config/execution-config.js";import{createLotaGateClient as F}from"../../infrastructure/sdk/lotagate-client-factory.js";import{runHeadlessAgentTurn as q}from"../orchestration/headless-agent-turn.js";import{runGoalLoop as $}from"../orchestration/goal-runner.js";import{CliAgentSessionStore as B}from"../agent/agent-session-store.js";import{formatGoalStatus as H}from"../orchestration/goal-output.js";import{parseGoalInput as k}from"../orchestration/goal-input.js";import{CliError as p}from"../../domain/errors/cli-error.js";import{CLI_ERROR_CODES as g}from"../../domain/errors/error-codes.js";import{MODEL_SELECT_HINT as J,TRUST_GRANT_HINT as K}from"./command-hints.js";import{createTurnId as Q,recordTurnCompletion as W,recordTurnFailure as z,recordTurnStart as V}from"../session/session-turn-lifecycle.js";import{createCommandAbortController as X,throwIfCommandAborted as M}from"./command-cancellation.js";async function pe(r,t,e,d,i,c){const n=r[0]??"status";if(n==="run")return U(r.slice(1).join(" ").trim(),t,e,d,i,void 0,c);M(c);const u=O(r,1,"session id"),l=await e.projectTrust.inspect(d);if(await new L(e.sessionStore).require(u,l.fingerprint),n==="status")return N(i,await e.goalStore.get(u),G(t,"json"));if(n==="set"){const a=O([r.slice(2).join(" ")],0,"goal objective"),w=await e.goalStore.replace(u,b(a,t));return N(i,w,G(t,"json"))}if(n==="pause"){const a=await e.goalStore.pause(u);return N(i,a,G(t,"json"))}if(n==="resume"){const a=await e.goalStore.get(u);if(a===void 0)throw new p(g.GOAL_NOT_FOUND,"Goal not found.",{category:"goal",userMessage:"Goal was not found."});return U(a.objective,t,e,d,i,u,c)}if(n==="clear")return await e.goalStore.clear(u),i.write(`Goal cleared.
2
+ `),0;throw new Error(`Unsupported goal action: ${n}`)}async function U(r,t,e,d,i,c,n){if(M(n),r.length===0)throw new p(g.MISSING_ARGUMENT,"Missing goal objective.",{category:"arguments",userMessage:"A goal objective is required."});const u=b(r,t),l=await e.projectTrust.inspect(d);if(!await e.projectTrust.isTrusted(l))throw new p(g.PROJECT_TRUST_REQUIRED,"Project trust is required for goals.",{category:"project",userMessage:"Project is not trusted.",hint:K});const a=await x(e,d);if(a.config.model===null)throw new p(g.MODEL_NOT_FOUND,"No model is selected.",{category:"model",userMessage:"No model is selected.",hint:J});const w=a.config.model,E=a.config.profile??P.defaultProfileName(),y=await e.auth.requireCredential(E),s=c===void 0?await e.sessionStore.create({projectFingerprint:l.fingerprint,cwd:l.canonicalPath,model:a.config.model,profile:E,status:"active"}):await e.sessionStore.get(c);if(s===void 0)throw new p(g.SESSION_NOT_FOUND,"Goal session not found.",{category:"session",userMessage:"Goal session was not found."});c===void 0?await e.goalStore.create(s.id,u):await e.goalStore.resume(s.id);const I=F(y.profile,y.apiKey),R=new B,m=n===void 0?X():void 0,h=m?.controller,A=n??h.signal,j=()=>h?.abort(new Error("Goal interrupted by user."));m!==void 0&&process.once("SIGINT",j);try{const f=await $({runtime:e,sessionId:s.id,objective:r,model:w,client:I,signal:A,runTurn:async(C,S,_)=>{const T=Q();await V(e.sessionStore,s.id,T,C);try{const o=await e.goalStore.get(s.id),v=await q({runtime:e,cwd:d,model:w,profileName:E,client:I,prompt:C,output:i,sessionId:s.id,agentSessionStore:R,signal:_,turnId:T,...o===void 0?{}:{goal:{objective:o.objective,status:o.status,turns:o.turns,evaluatorRuns:o.evaluatorRuns,tokensUsed:o.usage.totalTokens,...o.tokenBudget===void 0?{}:{tokenBudget:o.tokenBudget},...o.maxTurns===void 0?{}:{maxTurns:o.maxTurns},...o.maxDurationMs===void 0?{}:{maxDurationMs:o.maxDurationMs},...o.lastError===void 0?{}:{lastError:o.lastError},...o.lastEvaluation===void 0?{}:{lastEvaluation:o.lastEvaluation.reason}}},onUsage:S.onUsage,onSubagentUsage:S.onUsage,onSnapshot:S.onSnapshot});return i.write(`
3
+ `),await W(e.sessionStore,s.id,T,v),v}catch(o){throw S.onError(o),await z(e.sessionStore,s.id,T,o,_.aborted),o}}});await e.sessionStore.updateStatus(s.id,f?.status==="completed"?"completed":f?.status==="paused"?"active":"failed"),i.write(`Goal session: ${s.id}
4
+ `);const D=f?.status==="paused"&&f.lastError?.startsWith("Goal paused by safety limit:")===!0;return f?.status==="completed"||D?0:1}finally{m!==void 0&&process.off("SIGINT",j),m?.dispose()}}function b(r,t){return k(r,t)}function N(r,t,e){return e?(r.write(`${JSON.stringify(t??null)}
5
5
  `),t===void 0?1:0):t===void 0?(r.write(`No active goal.
6
- `),1):(r.write(`${k(t)}
7
- `),0)}export{fe as runGoalCommand};
6
+ `),1):(r.write(`${H(t)}
7
+ `),0)}export{pe as runGoalCommand};
@@ -26,4 +26,4 @@ export type MemoryCommandPayload = {
26
26
  readonly imported: number;
27
27
  readonly skipped: number;
28
28
  };
29
- export declare function runMemoryCommand(positionals: readonly string[], flags: ReadonlyMap<string, string | boolean>, runtime: CliRuntime, cwd: string, output: CommandOutput): Promise<number>;
29
+ export declare function runMemoryCommand(positionals: readonly string[], flags: ReadonlyMap<string, string | boolean>, runtime: CliRuntime, cwd: string, output: CommandOutput, signal?: AbortSignal): Promise<number>;
@@ -1,12 +1,12 @@
1
- import{isMemoryState as l}from"../../domain/memory/memory.js";import{isMemoryKind as p,MEMORY_KINDS as f}from"../../domain/memory/memory-kinds.js";import{CliError as s}from"../../domain/errors/cli-error.js";import{CLI_ERROR_CODES as d}from"../../domain/errors/error-codes.js";import{assertExternalWriteTarget as $,resolveExternalOutputPath as w,resolveExternalPath as M}from"../../infrastructure/filesystem/path-resolver.js";import{atomicWriteFile as h}from"../../infrastructure/filesystem/atomic-file-store.js";import{readJsonFileBounded as g}from"../../infrastructure/filesystem/bounded-json-reader.js";import{RESOURCE_LIMITS as k}from"../../domain/runtime/resource-limits.js";import{formatCompactTable as v}from"../formatting/compact-table.js";import{getStringFlag as u,isFlagEnabled as R,requirePositional as c,requireStringFlag as E}from"./cli-args.js";async function V(e,r,t,n,a){const i=e[0]??"list";if(i==="list")return I(await t.memory.list(n,T(r)),a);if(i==="forget"){const o=c(e,1,"memory id"),y=await t.memory.forget(n,o);return m(a,{kind:"memory.forget",id:o,forgotten:y},y?`Forgot memory: ${o}
2
- `:`Memory not found: ${o}
3
- `)}if(i==="show")return N(await O(t,n,c(e,1,"memory id")),a);if(i==="clear"){const o=await t.memory.clear(n);return m(a,{kind:"memory.clear",cleared:o},`Cleared ${o} memor${o===1?"y":"ies"}.
4
- `)}if(i==="export")return S(t,n,r,a);if(i==="import")return x(t,n,r,a);throw new s(d.INVALID_ARGUMENT,`Unsupported memory action: ${i}`,{category:"memory",userMessage:`Unsupported memory action: ${i}`})}async function S(e,r,t,n){const a=await e.memory.export(r),i=u(t,"out");if(i===void 0)return m(n,{kind:"memory.export",bundle:a},`${JSON.stringify(a,null,2)}
5
- `);const o=await w(i,{cwd:r});return await $(o),await h(o,`${JSON.stringify(a,null,2)}
6
- `),m(n,{kind:"memory.export",bundle:a,outputPath:o},`Exported ${a.records.length} memories: ${o}
7
- `)}async function x(e,r,t,n){const a=await M(E(t,"file"),{cwd:r}),i=await e.memory.previewImport(await g(a,k.memoryBundleBytes));if(!R(t,"apply"))return m(n,{kind:"memory.import.preview",records:i.records.length},`Validated ${i.records.length} memories. Re-run with --apply to import.
8
- `);const o=await e.memory.import(r,i);return m(n,{kind:"memory.import",...o},`Imported ${o.imported} memories; skipped ${o.skipped}.
9
- `)}function I(e,r){const t=`${v(e.map(n=>({name:n.statement,status:n.kind.toUpperCase(),detail:`${n.id} \xB7 ${n.state} \xB7 ${n.lastRetrievedAt??"never retrieved"}`})),{columns:[{key:"name",header:"Memory",minWidth:4,maxWidth:28},{key:"status",header:"Type",minWidth:4,maxWidth:16},{key:"detail",header:"Details",minWidth:12}],empty:"No memories found."})}
10
- `;return m(r,{kind:"memory.list",items:e},t)}function N(e,r){const t=[`Memory ${e.id}`,`Type: ${e.kind}`,`Statement: ${e.statement}`,`State: ${e.state}`,`Source: ${e.source}`,`Topics: ${e.topics.length===0?"none":e.topics.join(", ")}`,...e.rationale===void 0?[]:[`Rationale: ${e.rationale}`],`Evidence: ${e.evidenceRefs.length===0?"none":e.evidenceRefs.join(", ")}`,`Retrievals: ${e.retrievalCount}${e.lastRetrievedAt===void 0?"":` \xB7 last retrieved ${e.lastRetrievedAt}`}`].join(`
1
+ import{isMemoryState as $}from"../../domain/memory/memory.js";import{isMemoryKind as w,MEMORY_KINDS as l}from"../../domain/memory/memory-kinds.js";import{CliError as s}from"../../domain/errors/cli-error.js";import{CLI_ERROR_CODES as f}from"../../domain/errors/error-codes.js";import{assertExternalWriteTarget as h,resolveExternalOutputPath as M,resolveExternalPath as g}from"../../infrastructure/filesystem/path-resolver.js";import{atomicWriteFile as k}from"../../infrastructure/filesystem/atomic-file-store.js";import{readJsonFileBounded as v}from"../../infrastructure/filesystem/bounded-json-reader.js";import{RESOURCE_LIMITS as R}from"../../domain/runtime/resource-limits.js";import{formatCompactTable as E}from"../formatting/compact-table.js";import{getStringFlag as y,isFlagEnabled as S,requirePositional as p,requireStringFlag as I}from"./cli-args.js";import{throwIfCommandAborted as u}from"./command-cancellation.js";async function J(e,r,t,o,i,d){u(d);const n=e[0]??"list";if(n==="list")return O(await t.memory.list(o,T(r)),i);if(n==="forget"){const a=p(e,1,"memory id"),c=await t.memory.forget(o,a);return m(i,{kind:"memory.forget",id:a,forgotten:c},c?`Forgot memory: ${a}
2
+ `:`Memory not found: ${a}
3
+ `)}if(n==="show")return A(await C(t,o,p(e,1,"memory id")),i);if(n==="clear"){const a=await t.memory.clear(o);return m(i,{kind:"memory.clear",cleared:a},`Cleared ${a} memor${a===1?"y":"ies"}.
4
+ `)}if(n==="export")return x(t,o,r,i);if(n==="import")return N(t,o,r,i,d);throw new s(f.INVALID_ARGUMENT,`Unsupported memory action: ${n}`,{category:"memory",userMessage:`Unsupported memory action: ${n}`})}async function x(e,r,t,o){const i=await e.memory.export(r),d=y(t,"out");if(d===void 0)return m(o,{kind:"memory.export",bundle:i},`${JSON.stringify(i,null,2)}
5
+ `);const n=await M(d,{cwd:r});return await h(n),await k(n,`${JSON.stringify(i,null,2)}
6
+ `),m(o,{kind:"memory.export",bundle:i,outputPath:n},`Exported ${i.records.length} memories: ${n}
7
+ `)}async function N(e,r,t,o,i){const d=await g(I(t,"file"),{cwd:r});u(i);const n=await e.memory.previewImport(await v(d,R.memoryBundleBytes));if(u(i),!S(t,"apply"))return m(o,{kind:"memory.import.preview",records:n.records.length},`Validated ${n.records.length} memories. Re-run with --apply to import.
8
+ `);const a=await e.memory.import(r,n);return u(i),m(o,{kind:"memory.import",...a},`Imported ${a.imported} memories; skipped ${a.skipped}.
9
+ `)}function O(e,r){const t=`${E(e.map(o=>({name:o.statement,status:o.kind.toUpperCase(),detail:`${o.id} \xB7 ${o.state} \xB7 ${o.lastRetrievedAt??"never retrieved"}`})),{columns:[{key:"name",header:"Memory",minWidth:4,maxWidth:28},{key:"status",header:"Type",minWidth:4,maxWidth:16},{key:"detail",header:"Details",minWidth:12}],empty:"No memories found."})}
10
+ `;return m(r,{kind:"memory.list",items:e},t)}function A(e,r){const t=[`Memory ${e.id}`,`Type: ${e.kind}`,`Statement: ${e.statement}`,`State: ${e.state}`,`Source: ${e.source}`,`Topics: ${e.topics.length===0?"none":e.topics.join(", ")}`,...e.rationale===void 0?[]:[`Rationale: ${e.rationale}`],`Evidence: ${e.evidenceRefs.length===0?"none":e.evidenceRefs.join(", ")}`,`Retrievals: ${e.retrievalCount}${e.lastRetrievedAt===void 0?"":` \xB7 last retrieved ${e.lastRetrievedAt}`}`].join(`
11
11
  `).concat(`
12
- `);return m(r,{kind:"memory.show",item:e},t)}function m(e,r,t){return e.writeStructured!==void 0?e.writeStructured(r,t):e.write(t),0}async function O(e,r,t){const n=await e.memory.get(r,t);if(n!==void 0)return n;throw new s(d.MEMORY_NOT_FOUND,`Memory not found: ${t}`,{category:"memory",userMessage:`Memory not found: ${t}`})}function T(e){const r=A(e),t=C(e);return{...r===void 0?{}:{kind:r},...t===void 0?{}:{state:t}}}function A(e){const r=u(e,"kind");if(r!==void 0){if(p(r))return r;throw new s(d.INVALID_ARGUMENT,`Memory kind must be one of: ${f.join(", ")}.`,{category:"memory",userMessage:`Memory kind must be one of: ${f.join(", ")}.`})}}function C(e){const r=u(e,"state");if(r!==void 0){if(l(r))return r;throw new s(d.INVALID_ARGUMENT,"Invalid memory state.",{category:"memory",userMessage:"Memory state must be active, superseded, or expired."})}}export{V as runMemoryCommand};
12
+ `);return m(r,{kind:"memory.show",item:e},t)}function m(e,r,t){return e.writeStructured!==void 0?e.writeStructured(r,t):e.write(t),0}async function C(e,r,t){const o=await e.memory.get(r,t);if(o!==void 0)return o;throw new s(f.MEMORY_NOT_FOUND,`Memory not found: ${t}`,{category:"memory",userMessage:`Memory not found: ${t}`})}function T(e){const r=b(e),t=_(e);return{...r===void 0?{}:{kind:r},...t===void 0?{}:{state:t}}}function b(e){const r=y(e,"kind");if(r!==void 0){if(w(r))return r;throw new s(f.INVALID_ARGUMENT,`Memory kind must be one of: ${l.join(", ")}.`,{category:"memory",userMessage:`Memory kind must be one of: ${l.join(", ")}.`})}}function _(e){const r=y(e,"state");if(r!==void 0){if($(r))return r;throw new s(f.INVALID_ARGUMENT,"Invalid memory state.",{category:"memory",userMessage:"Memory state must be active, superseded, or expired."})}}export{J as runMemoryCommand};
@@ -1,14 +1,14 @@
1
- import{Writable as k}from"node:stream";import{AuthenticationService as M}from"../auth/authentication-service.js";import{ChatService as G}from"../chat/chat-service.js";import{createLotaGateClient as _}from"../../infrastructure/sdk/lotagate-client-factory.js";import{SdkChatCompletionAdapter as F}from"../../infrastructure/sdk/chat-completion-adapter.js";import{CliError as u}from"../../domain/errors/cli-error.js";import{CLI_ERROR_CODES as w}from"../../domain/errors/error-codes.js";import{MODEL_SELECT_HINT as $}from"./command-hints.js";import{createImageAttachment as P,DEFAULT_MAX_IMAGE_BYTES as D,normalizeImage as q}from"../../infrastructure/clipboard/image-normalizer.js";import{readJsonFileBounded as B}from"../../infrastructure/filesystem/bounded-json-reader.js";import{readFileBounded as J}from"../../infrastructure/filesystem/bounded-file-reader.js";import{RESOURCE_LIMITS as T}from"../../domain/runtime/resource-limits.js";import{ProjectSessionAccess as U}from"../session/project-session-access.js";import{compactStoredSession as j}from"../session/session-compaction-service.js";import{requirePositional as z,getFlag as v,isFlagEnabled as N,requireStringFlag as H}from"./cli-args.js";import{resolveExternalPath as W,resolveWorkspacePath as x}from"../../infrastructure/filesystem/path-resolver.js";import{atomicWriteFile as K}from"../../infrastructure/filesystem/atomic-file-store.js";import{loadExecutionConfig as R}from"../config/execution-config.js";import{runHeadlessAgentTurn as V}from"../orchestration/headless-agent-turn.js";import{writeStreamChunk as E}from"./stream-output.js";import{formatCompactTable as X}from"../formatting/compact-table.js";import{createCommandAbortController as L,throwIfCommandAborted as C}from"./command-cancellation.js";async function Se(g,s,o,a,r,d,m){C(m);const i=g[0]??"list",l=await o.projectTrust.inspect(a);if(i==="list"){const t=await o.sessionStore.list(l.fingerprint);return r.write(`${X(t.map(n=>({name:n.name??n.id,status:n.status.toUpperCase(),detail:`${n.id} \xB7 ${n.model??"no model"} \xB7 ${n.updatedAt}`})),{empty:"No sessions found."})}
2
- `),0}if(i==="import"){const t=H(s,"file"),n=await x(t,{cwd:a,workspaceRoot:a}),f=await B(n,T.sessionBundleBytes),c=await o.sessionStore.import(f,l.fingerprint,a);return r.write(`${JSON.stringify(c,null,2)}
3
- `),0}const e=z(g,1,"session id"),p=await new U(o.sessionStore).require(e,l.fingerprint);if(i==="show")return r.write(`${JSON.stringify({metadata:p,transcript:await o.sessionStore.readTranscript(e)},null,2)}
4
- `),0;if(i==="resume"){if(N(s,"interactive")){if(!(r instanceof k))throw new Error("Interactive session resume requires a terminal output stream.");if(d===void 0)throw new Error("Interactive session resume is unavailable in this command host.");return d(e)}return r.write(`${JSON.stringify({metadata:p,transcript:await o.sessionStore.readTranscript(e),resumable:p.status!=="active"},null,2)}
1
+ import{Writable as k}from"node:stream";import{AuthenticationService as M}from"../auth/authentication-service.js";import{ChatService as F}from"../chat/chat-service.js";import{createLotaGateClient as _}from"../../infrastructure/sdk/lotagate-client-factory.js";import{SdkChatCompletionAdapter as P}from"../../infrastructure/sdk/chat-completion-adapter.js";import{CliError as g}from"../../domain/errors/cli-error.js";import{CLI_ERROR_CODES as w}from"../../domain/errors/error-codes.js";import{MODEL_SELECT_HINT as $}from"./command-hints.js";import{createImageAttachment as D,DEFAULT_MAX_IMAGE_BYTES as q,normalizeImage as B}from"../../infrastructure/clipboard/image-normalizer.js";import{readJsonFileBounded as J}from"../../infrastructure/filesystem/bounded-json-reader.js";import{readFileBounded as U}from"../../infrastructure/filesystem/bounded-file-reader.js";import{RESOURCE_LIMITS as N}from"../../domain/runtime/resource-limits.js";import{ProjectSessionAccess as j}from"../session/project-session-access.js";import{compactStoredSession as z}from"../session/session-compaction-service.js";import{requirePositional as H,getFlag as v,isFlagEnabled as E,requireStringFlag as W}from"./cli-args.js";import{resolveExternalPath as K,resolveWorkspacePath as x}from"../../infrastructure/filesystem/path-resolver.js";import{atomicWriteFile as V}from"../../infrastructure/filesystem/atomic-file-store.js";import{loadExecutionConfig as R}from"../config/execution-config.js";import{runHeadlessAgentTurn as X}from"../orchestration/headless-agent-turn.js";import{writeStreamChunk as A}from"./stream-output.js";import{formatCompactTable as Y}from"../formatting/compact-table.js";import{createCommandAbortController as L,throwIfCommandAborted as C}from"./command-cancellation.js";async function Te(u,m,o,a,r,f,p){C(p);const i=u[0]??"list",d=await o.projectTrust.inspect(a);if(i==="list"){const t=await o.sessionStore.list(d.fingerprint);return r.write(`${Y(t.map(n=>({name:n.name??n.id,status:n.status.toUpperCase(),detail:`${n.id} \xB7 ${n.model??"no model"} \xB7 ${n.updatedAt}`})),{empty:"No sessions found."})}
2
+ `),0}if(i==="import"){const t=W(m,"file"),n=await x(t,{cwd:a,workspaceRoot:a}),l=await J(n,N.sessionBundleBytes),c=await o.sessionStore.import(l,d.fingerprint,a);return r.write(`${JSON.stringify(c,null,2)}
3
+ `),0}const e=H(u,1,"session id"),s=await new j(o.sessionStore).require(e,d.fingerprint);if(i==="show")return r.write(`${JSON.stringify({metadata:s,transcript:await o.sessionStore.readTranscript(e)},null,2)}
4
+ `),0;if(i==="resume"){if(E(m,"interactive")){if(!(r instanceof k))throw new Error("Interactive session resume requires a terminal output stream.");if(f===void 0)throw new Error("Interactive session resume is unavailable in this command host.");return f(e)}return r.write(`${JSON.stringify({metadata:s,transcript:await o.sessionStore.readTranscript(e),resumable:s.status!=="active"},null,2)}
5
5
  `),0}if(i==="fork"){const t=await o.sessionStore.fork(e);return r.write(`${JSON.stringify(t,null,2)}
6
- `),0}if(i==="compact"){if(g.length>2)throw new u(w.INVALID_ARGUMENT,"Compaction does not accept a summary.",{category:"session",userMessage:"The compact command does not accept a summary. It summarizes the session automatically."});const t=await j(o,a,e);return r.write(`${t.compacted?`Compacted session: ${e}`:`No conversation to compact: ${e}`}
7
- `),0}if(i==="export"){const t=await o.sessionStore.export(e),n=v(s,"out"),f=`${JSON.stringify(t,null,2)}
8
- `;if(typeof n=="string"&&n.trim().length>0){const c=await x(n,{cwd:a,workspaceRoot:a},!0);await K(c,f),r.write(`Exported session: ${c}
9
- `)}else r.write(f);return 0}if(i==="recover")return r.write(`${JSON.stringify({sessionId:e,recovered:await o.sessionStore.recoverStaleLock(e)})}
6
+ `),0}if(i==="compact"){if(u.length>2)throw new g(w.INVALID_ARGUMENT,"Compaction does not accept a summary.",{category:"session",userMessage:"The compact command does not accept a summary. It summarizes the session automatically."});const t=await z(o,a,e);return r.write(`${t.compacted?`Compacted session: ${e}`:`No conversation to compact: ${e}`}
7
+ `),0}if(i==="export"){const t=await o.sessionStore.export(e),n=v(m,"out"),l=`${JSON.stringify(t,null,2)}
8
+ `;if(typeof n=="string"&&n.trim().length>0){const c=await x(n,{cwd:a,workspaceRoot:a},!0);await V(c,l),r.write(`Exported session: ${c}
9
+ `)}else r.write(l);return 0}if(i==="recover")return r.write(`${JSON.stringify({sessionId:e,recovered:await o.sessionStore.recoverStaleLock(e)})}
10
10
  `),0;if(i==="repair")return r.write(`${JSON.stringify(await o.sessionStore.repair(e))}
11
11
  `),0;if(i==="delete"){await o.executionWorkspaces?.remove(e);const t=await o.sessionStore.delete(e);return r.write(`${t?`Deleted session: ${e}`:`Session not found: ${e}`}
12
- `),t?0:1}throw new Error(`Unsupported session action: ${i}`)}async function Te(g,s,o,a,r){C(r);const d=g.join(" ").trim();if(d.length===0)return a.write('Interactive prompt editor requires a terminal. Run `lotagate` in a terminal or use `lotagate chat "prompt"` for streaming.\n'),0;const m=await R(s,o);if(m.config.model===null)throw new u(w.MODEL_NOT_FOUND,"No model is selected.",{category:"model",userMessage:"No model is selected.",hint:$});const i=m.config.profile??M.defaultProfileName(),l=await s.auth.requireCredential(i),e=_(l.profile,l.apiKey),p=L(r),t=p.controller,n=()=>t.abort();process.once("SIGINT",n);try{const f=new G(new F(e));for await(const c of f.stream(m.config.model,d,{reasoningEffort:m.config.effort,signal:t.signal}))c.type==="delta"&&await E(a,c.content);return await E(a,`
13
- `),0}finally{process.off("SIGINT",n),p.dispose()}}async function Ne(g,s,o,a,r,d){C(d);const m=g.join(" ").trim();if(m.length===0)throw new u(w.MISSING_ARGUMENT,"Missing prompt.",{category:"arguments",userMessage:"A prompt is required for exec."});const i=await R(o,a);if(i.config.model===null)throw new u(w.MODEL_NOT_FOUND,"No model is selected.",{category:"model",userMessage:"No model is selected.",hint:$});const l=i.config.profile??M.defaultProfileName(),e=await o.auth.requireCredential(l),p=v(s,"image"),t=[];let n=0;if(typeof p=="string")for(const[h,O]of p.split(",").map(y=>y.trim()).filter(Boolean).entries()){if(t.length>=T.pendingAttachments)throw new u(w.ATTACHMENT_TOO_LARGE,"Too many images were supplied.",{category:"attachment",userMessage:"Too many images were supplied. Reduce the image list and retry."});const y=await W(O,{cwd:a}),b=await J(y,D);if(b.truncated)throw new u(w.ATTACHMENT_TOO_LARGE,"Image exceeds the supported size.",{category:"attachment",userMessage:"An image exceeds the supported size limit."});const S=q(b.bytes);if(n+=S.bytes.byteLength,n>T.pendingAttachmentTotalBytes)throw new u(w.ATTACHMENT_TOO_LARGE,"Image attachment total exceeds the supported limit.",{category:"attachment",userMessage:"The combined image size is too large. Reduce the image list and retry."});t.push({attachment:P(S,"file",`image-${h+1}`,O),bytes:S.bytes})}const f=N(s,"json")||N(s,"jsonl"),c=L(d),I=c.controller,A=()=>I.abort();process.once("SIGINT",A);try{const h=_(e.profile,e.apiKey);return await V({runtime:o,cwd:a,model:i.config.model,profileName:l,reasoningEffort:i.config.effort,client:h,prompt:m,...t.length===0?{}:{attachments:t},output:r,json:f,signal:I.signal}),f||await E(r,`
14
- `),0}finally{process.off("SIGINT",A),c.dispose()}}export{Te as runChatCommand,Ne as runExecCommand,Se as runSessionCommand};
12
+ `),t?0:1}throw new Error(`Unsupported session action: ${i}`)}async function Ne(u,m,o,a,r){C(r);const f=u.join(" ").trim();if(f.length===0)return a.write('Interactive prompt editor requires a terminal. Run `lotagate` in a terminal or use `lotagate chat "prompt"` for streaming.\n'),0;const p=await R(m,o);if(p.config.model===null)throw new g(w.MODEL_NOT_FOUND,"No model is selected.",{category:"model",userMessage:"No model is selected.",hint:$});const i=p.config.profile??M.defaultProfileName(),d=await m.auth.requireCredential(i),e=_(d.profile,d.apiKey),s=r===void 0?L():void 0,t=s?.controller,n=r??t.signal,l=()=>t?.abort();s!==void 0&&process.once("SIGINT",l);try{const c=new F(new P(e));for await(const h of c.stream(p.config.model,f,{reasoningEffort:p.config.effort,signal:n}))h.type==="delta"&&await A(a,h.content);return await A(a,`
13
+ `),0}finally{s!==void 0&&process.off("SIGINT",l),s?.dispose()}}async function Ee(u,m,o,a,r,f){C(f);const p=u.join(" ").trim();if(p.length===0)throw new g(w.MISSING_ARGUMENT,"Missing prompt.",{category:"arguments",userMessage:"A prompt is required for exec."});const i=await R(o,a);if(i.config.model===null)throw new g(w.MODEL_NOT_FOUND,"No model is selected.",{category:"model",userMessage:"No model is selected.",hint:$});const d=i.config.profile??M.defaultProfileName(),e=await o.auth.requireCredential(d),s=v(m,"image"),t=[];let n=0;if(typeof s=="string")for(const[y,O]of s.split(",").map(S=>S.trim()).filter(Boolean).entries()){if(t.length>=N.pendingAttachments)throw new g(w.ATTACHMENT_TOO_LARGE,"Too many images were supplied.",{category:"attachment",userMessage:"Too many images were supplied. Reduce the image list and retry."});const S=await K(O,{cwd:a}),b=await U(S,q);if(b.truncated)throw new g(w.ATTACHMENT_TOO_LARGE,"Image exceeds the supported size.",{category:"attachment",userMessage:"An image exceeds the supported size limit."});const T=B(b.bytes);if(n+=T.bytes.byteLength,n>N.pendingAttachmentTotalBytes)throw new g(w.ATTACHMENT_TOO_LARGE,"Image attachment total exceeds the supported limit.",{category:"attachment",userMessage:"The combined image size is too large. Reduce the image list and retry."});t.push({attachment:D(T,"file",`image-${y+1}`,O),bytes:T.bytes})}const l=E(m,"json")||E(m,"jsonl"),c=f===void 0?L():void 0,h=c?.controller,G=f??h.signal,I=()=>h?.abort();c!==void 0&&process.once("SIGINT",I);try{const y=_(e.profile,e.apiKey);return await X({runtime:o,cwd:a,model:i.config.model,profileName:d,reasoningEffort:i.config.effort,client:y,prompt:p,...t.length===0?{}:{attachments:t},output:r,json:l,signal:G}),l||await A(r,`
14
+ `),0}finally{c!==void 0&&process.off("SIGINT",I),c?.dispose()}}export{Ne as runChatCommand,Ee as runExecCommand,Te as runSessionCommand};
@@ -1 +1 @@
1
- import a from"node:path";import h from"node:fs/promises";import{createHash as y}from"node:crypto";import{mergeMcpConfigs as w,validateMcpConfig as M}from"../../domain/extensions/mcp-config.js";import{CliError as p}from"../../domain/errors/cli-error.js";import{CLI_ERROR_CODES as d}from"../../domain/errors/error-codes.js";import{PLUGIN_LAYOUT as m}from"../../domain/extensions/plugin-manifest.js";import{PluginManager as C}from"../../infrastructure/extensions/plugin-manager.js";import{readJsonFileBounded as P}from"../../infrastructure/filesystem/bounded-json-reader.js";import{RESOURCE_LIMITS as b}from"../../domain/runtime/resource-limits.js";import{isFileNotFound as _}from"../../infrastructure/filesystem/fs-errors.js";import{PluginAgentDiscovery as $}from"../../infrastructure/extensions/plugin-agent-discovery.js";class G{globalConfigDirectory;constructor(e){this.globalConfigDirectory=e}async resolve(e,i){if(!i)return{plugins:[],skillRoots:[],mcpConfig:{},mcpContributions:[],agents:[]};const s=a.join(this.globalConfigDirectory,"plugins"),f=a.join(e,".lotagate","plugins"),n=I([...await new C(f).list(),...await new C(s).list()]).filter(t=>t.enabled).map(t=>t.manifest),r=await j(n),g=(await Promise.all(n.map(async t=>(await new $().discover(a.join(t.directory,m.agentsDirectory))).map(l=>({pluginName:t.name,definition:l}))))).flat();return{plugins:n,skillRoots:n.map(t=>({root:a.join(t.directory,m.skillsDirectory),pluginName:t.name})),mcpConfig:r.config,mcpContributions:r.contributions,agents:g}}}function I(o){const e=new Set;return o.filter(i=>e.has(i.manifest.name)?!1:(e.add(i.manifest.name),!0))}async function j(o){const e={},i=[];for(const s of o){const f=a.join(s.directory,m.mcpDirectory);let c;try{c=(await h.readdir(f,{withFileTypes:!0})).filter(n=>n.isFile()&&n.name.endsWith(".json")).map(n=>a.join(f,n.name)).sort()}catch(n){if(_(n))continue;throw n}for(const n of c){const r=a.basename(n,".json");if(!/^[a-z0-9][a-z0-9-]{0,63}$/u.test(r))throw u(r);const t=M({[r]:await P(n,b.mcpConfigBytes)})[r];if(t===void 0)throw u(r);const l=v(s.name,r);if(e[l]!==void 0)throw u(l);e[l]=t,i.push({pluginName:s.name,sourceName:r,qualifiedName:l})}}return{config:e,contributions:i}}function v(o,e){const i=o.replace(/^@/u,"").replace("/","_"),s=`plugin_${i}_${e}`;if(s.length<=64)return s;const c=`_${y("sha256").update(`${o}\0${e}`).digest("hex").slice(0,12)}_${e.slice(0,8)}`,n=Math.max(1,57-c.length);return`plugin_${i.slice(0,n)}${c}`}function U(...o){try{return w(...o)}catch(e){if(e instanceof p&&e.code===d.MCP_CONFIG_INVALID){const i=e.message.replace(/^Invalid MCP configuration: /u,"");throw u(i.replace(/\.$/u,"").replace(/^MCP server is defined more than once: /u,""))}throw e}}function u(o){return new p(d.MCP_CONFIG_INVALID,`Multiple MCP contributions define server: ${o}`,{category:"extension",userMessage:`MCP server \`${o}\` is defined more than once. Rename or remove one contribution.`})}export{G as PluginContributionRegistry,j as loadPluginMcpConfig,U as mergeMcpConfigContributions};
1
+ import l from"node:path";import w from"node:fs/promises";import{createHash as M}from"node:crypto";import{mergeMcpConfigs as b,validateMcpConfig as I}from"../../domain/extensions/mcp-config.js";import{CliError as f}from"../../domain/errors/cli-error.js";import{CLI_ERROR_CODES as m}from"../../domain/errors/error-codes.js";import{PLUGIN_LAYOUT as d}from"../../domain/extensions/plugin-manifest.js";import{PluginManager as h}from"../../infrastructure/extensions/plugin-manager.js";import{readJsonFileBounded as P}from"../../infrastructure/filesystem/bounded-json-reader.js";import{RESOURCE_LIMITS as g}from"../../domain/runtime/resource-limits.js";import{isFileNotFound as _}from"../../infrastructure/filesystem/fs-errors.js";import{PluginAgentDiscovery as x}from"../../infrastructure/extensions/plugin-agent-discovery.js";class q{globalConfigDirectory;constructor(e){this.globalConfigDirectory=e}async resolve(e,o){if(!o)return{plugins:[],skillRoots:[],mcpConfig:{},mcpContributions:[],agents:[]};const r=l.join(this.globalConfigDirectory,"plugins"),c=l.join(e,".lotagate","plugins"),n=v([...await new h(c).list(),...await new h(r).list()]).filter(i=>i.enabled).map(i=>i.manifest);if(n.length>g.pluginMaxEnabled)throw new f(m.PLUGIN_MANIFEST_INVALID,"Too many enabled plugins.",{category:"extension",userMessage:"Too many plugins are enabled for this CLI session."});const s=await D(n),u=(await N(n,g.pluginDiscoveryConcurrency,async i=>(await new x().discover(l.join(i.directory,d.agentsDirectory),{maxEntries:g.pluginMaxAgentFiles})).map(C=>({pluginName:i.name,definition:C})))).flat();if(u.length>g.pluginMaxAgentContributions)throw new f(m.PLUGIN_MANIFEST_INVALID,"Too many plugin agent contributions.",{category:"extension",userMessage:"Enabled plugins provide too many agent contributions."});return{plugins:n,skillRoots:n.map(i=>({root:l.join(i.directory,d.skillsDirectory),pluginName:i.name})),mcpConfig:s.config,mcpContributions:s.contributions,agents:u}}}async function N(t,e,o){const r=new Array(t.length);let c=0;const a=async()=>{for(;;){const n=c++;if(n>=t.length)return;r[n]=await o(t[n])}};return await Promise.all(Array.from({length:Math.min(e,t.length)},()=>a())),r}function v(t){const e=new Set;return t.filter(o=>e.has(o.manifest.name)?!1:(e.add(o.manifest.name),!0))}async function D(t){const e={},o=[];for(const r of t){const c=l.join(r.directory,d.mcpDirectory);let a;try{a=(await w.readdir(c,{withFileTypes:!0})).filter(n=>n.isFile()&&n.name.endsWith(".json")).map(n=>l.join(c,n.name)).sort()}catch(n){if(_(n))continue;throw n}for(const n of a){const s=l.basename(n,".json");if(!/^[a-z0-9][a-z0-9-]{0,63}$/u.test(s))throw p(s);const u=I({[s]:await P(n,g.mcpConfigBytes)})[s];if(u===void 0)throw p(s);const i=A(r.name,s);if(e[i]!==void 0)throw p(i);e[i]=u,o.push({pluginName:r.name,sourceName:s,qualifiedName:i})}}return{config:e,contributions:o}}function A(t,e){const o=t.replace(/^@/u,"").replace("/","_"),r=`plugin_${o}_${e}`;if(r.length<=64)return r;const a=`_${M("sha256").update(`${t}\0${e}`).digest("hex").slice(0,12)}_${e.slice(0,8)}`,n=Math.max(1,57-a.length);return`plugin_${o.slice(0,n)}${a}`}function z(...t){try{return b(...t)}catch(e){if(e instanceof f&&e.code===m.MCP_CONFIG_INVALID){const o=e.message.replace(/^Invalid MCP configuration: /u,"");throw p(o.replace(/\.$/u,"").replace(/^MCP server is defined more than once: /u,""))}throw e}}function p(t){return new f(m.MCP_CONFIG_INVALID,`Multiple MCP contributions define server: ${t}`,{category:"extension",userMessage:`MCP server \`${t}\` is defined more than once. Rename or remove one contribution.`})}export{q as PluginContributionRegistry,D as loadPluginMcpConfig,z as mergeMcpConfigContributions};
@@ -0,0 +1,11 @@
1
+ /** Owns cancellable asynchronous work for one application lifecycle. */
2
+ export declare class OperationRegistry {
3
+ private readonly controller;
4
+ private readonly operations;
5
+ private closePromise;
6
+ private closed;
7
+ get signal(): AbortSignal;
8
+ start<T>(operation: (signal: AbortSignal) => Promise<T>): Promise<T>;
9
+ abort(reason?: unknown): void;
10
+ close(reason?: Error): Promise<void>;
11
+ }
@@ -0,0 +1 @@
1
+ class l{controller=new AbortController;operations=new Set;closePromise;closed=!1;get signal(){return this.controller.signal}start(e){if(this.closed)return Promise.reject(new Error("The operation registry is closed."));let o,t;const r=new Promise((s,i)=>{o=s,t=i});this.operations.add(r),r.then(()=>this.operations.delete(r),()=>this.operations.delete(r));try{Promise.resolve(e(this.signal)).then(o,t)}catch(s){t(s)}return r}abort(e){this.controller.signal.aborted||this.controller.abort(e)}async close(e=new Error("The operation registry is closing.")){return this.closePromise!==void 0?this.closePromise:(this.closed=!0,this.abort(e),this.closePromise=Promise.allSettled([...this.operations]).then(()=>{}),this.closePromise)}}export{l as OperationRegistry};
@@ -1,4 +1,4 @@
1
- import{prepareCliAgent as h}from"../agent/cli-agent-execution-service.js";import{AgentRunTracker as w}from"../agent/agent-run-tracker.js";import{CliError as C}from"../../domain/errors/cli-error.js";import{CLI_ERROR_CODES as c}from"../../domain/errors/error-codes.js";import{writeStreamChunk as m}from"../commands/stream-output.js";import{CliTurnEventProjector as S}from"./cli-turn-event-projector.js";import{persistCliTurnEvent as p}from"./cli-turn-persistence.js";import{agentLimitNotice as I,classifyAgentLimit as y}from"../agent/agent-limit.js";import{buildUserMessage as E}from"../../infrastructure/clipboard/image-normalizer.js";import{createContextManagement as x}from"../agent/context-compaction.js";import{persistContextCompaction as M}from"../agent/context-compaction-persistence.js";import{resolveModelContextWindow as b}from"../model/model-context-window.js";import{formatContinuationCheckpoint as v}from"../agent/continuation-checkpoint.js";async function H(e){const s=new w,u=await b(e.runtime,e.model,e.profileName),i=await h({runtime:e.runtime,projectRoot:e.cwd,executionCwd:e.cwd,model:e.model,...e.reasoningEffort===void 0?{}:{reasoningEffort:e.reasoningEffort},client:e.client,profile:"headless-safe",approvalMode:"auto",...e.goal===void 0?{}:{goal:e.goal},...e.agentSessionStore===void 0?{}:{agentSessionStore:e.agentSessionStore},onModelComplete:n=>{s.observeModel(n),n.usage!==void 0&&e.onUsage?.({usage:n.usage,modelCalls:1})},...e.onSubagentUsage===void 0?{}:{onSubagentModelComplete:n=>{n.usage!==void 0&&e.onSubagentUsage?.({usage:n.usage,modelCalls:1})}},contextManagement:x({client:e.client,model:e.model,...u===void 0?{}:{contextWindow:u},onSummaryFailure:n=>e.runtime.logger.warn("Context summarization failed; using fallback summary.",{reason:n instanceof Error?n.message:String(n)}),continuationContext:()=>v({snapshot:s.snapshot(),...e.goal===void 0?{}:{goal:e.goal}})})}),r=[];let d;const g=new S;try{const n=await i.buildInput(e.prompt);if(e.agentSessionStore!==void 0&&e.sessionId!==void 0){const t=await e.runtime.sessionStore.readHistory(e.sessionId);e.agentSessionStore.hydrate(e.sessionId,t.transcript,t.events,n.input)}const l=e.attachments===void 0||e.attachments.length===0?void 0:E(n.input,e.attachments),f=l?.content===null?void 0:l?.content;for await(const t of i.run({input:n.input,userInput:n.userInput,...n.workspaceContext===void 0?{}:{workspaceContext:n.workspaceContext},...f===void 0?{}:{inputContent:f},model:e.model,...e.signal===void 0?{}:{signal:e.signal},...e.sessionId===void 0?{}:{sessionId:e.sessionId}})){s.observe(t);for(const a of g.observe(t)){if(e.sessionId!==void 0)try{await p(e.runtime.sessionStore,e.sessionId,a,{...e.turnId===void 0?{}:{turnId:e.turnId}})}catch(o){e.runtime.logger.warn("Unable to persist agent lifecycle event.",{eventType:a.type,reason:o instanceof Error?o.message:String(o)})}a.type==="assistant.delta"&&r.push(a.content),a.type==="assistant.replaced"&&r.splice(0,r.length,a.content)}if(e.output!==void 0&&e.json?await m(e.output,`${JSON.stringify(t)}
2
- `):t.type==="session.completed"&&r.length===0&&r.push(t.content),t.type==="session.failed"){if(d=y(t.error),d===void 0)throw t.error;break}t.type==="context.compacted"&&e.sessionId!==void 0&&await M(e.runtime,i,e.sessionId,t.metrics,e.turnId)}if(d!==void 0){const t=I(d);r.push(r.length===0?t:`
1
+ import{prepareCliAgent as w}from"../agent/cli-agent-execution-service.js";import{AgentRunTracker as S}from"../agent/agent-run-tracker.js";import{CliError as C}from"../../domain/errors/cli-error.js";import{CLI_ERROR_CODES as c}from"../../domain/errors/error-codes.js";import{writeStreamChunk as m}from"../commands/stream-output.js";import{CliTurnEventProjector as p}from"./cli-turn-event-projector.js";import{persistCliTurnEvent as h}from"./cli-turn-persistence.js";import{agentLimitNotice as y,classifyAgentLimit as I}from"../agent/agent-limit.js";import{buildUserMessage as E}from"../../infrastructure/clipboard/image-normalizer.js";import{createContextManagement as x}from"../agent/context-compaction.js";import{persistContextCompaction as M}from"../agent/context-compaction-persistence.js";import{resolveModelContextWindow as b}from"../model/model-context-window.js";import{formatContinuationCheckpoint as v}from"../agent/continuation-checkpoint.js";import{BoundedTextAccumulator as T}from"../agent/bounded-text-accumulator.js";async function Y(e){const s=new S,u=await b(e.runtime,e.model,e.profileName),i=await w({runtime:e.runtime,projectRoot:e.cwd,executionCwd:e.cwd,model:e.model,...e.reasoningEffort===void 0?{}:{reasoningEffort:e.reasoningEffort},client:e.client,profile:"headless-safe",approvalMode:"auto",...e.goal===void 0?{}:{goal:e.goal},...e.agentSessionStore===void 0?{}:{agentSessionStore:e.agentSessionStore},onModelComplete:t=>{s.observeModel(t),t.usage!==void 0&&e.onUsage?.({usage:t.usage,modelCalls:1})},...e.onSubagentUsage===void 0?{}:{onSubagentModelComplete:t=>{t.usage!==void 0&&e.onSubagentUsage?.({usage:t.usage,modelCalls:1})}},contextManagement:x({client:e.client,model:e.model,...u===void 0?{}:{contextWindow:u},onSummaryFailure:t=>e.runtime.logger.warn("Context summarization failed; using fallback summary.",{reason:t instanceof Error?t.message:String(t)}),continuationContext:()=>v({snapshot:s.snapshot(),...e.goal===void 0?{}:{goal:e.goal}})})}),r=new T;let d;const g=new p;try{const t=await i.buildInput(e.prompt);if(e.agentSessionStore!==void 0&&e.sessionId!==void 0){const n=await e.runtime.sessionStore.readHistory(e.sessionId);e.agentSessionStore.hydrate(e.sessionId,n.transcript,n.events,t.input)}const l=e.attachments===void 0||e.attachments.length===0?void 0:E(t.input,e.attachments),f=l?.content===null?void 0:l?.content;for await(const n of i.run({input:t.input,userInput:t.userInput,...t.workspaceContext===void 0?{}:{workspaceContext:t.workspaceContext},...f===void 0?{}:{inputContent:f},model:e.model,...e.signal===void 0?{}:{signal:e.signal},...e.sessionId===void 0?{}:{sessionId:e.sessionId}})){s.observe(n);for(const a of g.observe(n)){if(e.sessionId!==void 0)try{await h(e.runtime.sessionStore,e.sessionId,a,{...e.turnId===void 0?{}:{turnId:e.turnId}})}catch(o){e.runtime.logger.warn("Unable to persist agent lifecycle event.",{eventType:a.type,reason:o instanceof Error?o.message:String(o)})}a.type==="assistant.delta"&&r.append(a.content),a.type==="assistant.replaced"&&r.replace(a.content)}if(e.output!==void 0&&e.json?await m(e.output,`${JSON.stringify(n)}
2
+ `):n.type==="session.completed"&&r.isEmpty&&r.replace(n.content),n.type==="session.failed"){if(d=I(n.error),d===void 0)throw n.error;break}n.type==="context.compacted"&&e.sessionId!==void 0&&await M(e.runtime,i,e.sessionId,n.metrics,e.turnId)}if(d!==void 0){const n=y(d);r.append(r.isEmpty?n:`
3
3
 
4
- ${t}`),e.sessionId!==void 0&&e.agentSessionStore?.delete(e.sessionId)}if(r.join("").trim().length===0){const a=s.snapshot().toolCalls>0?c.MODEL_EMPTY_FINAL:c.MODEL_PROTOCOL_EMPTY_RESPONSE;throw new C(a,"Agent completed without a final text response.",{category:"model",userMessage:"The model completed without a final text response.",retryable:!0})}return e.output!==void 0&&!e.json&&await m(e.output,r.join("")),r.join("")}finally{e.onSnapshot?.(s.snapshot());try{await i.close()}catch(n){e.runtime.logger.warn("Agent cleanup failed after a completed turn.",{reason:n instanceof Error?n.message:String(n)})}}}export{H as runHeadlessAgentTurn};
4
+ ${n}`),e.sessionId!==void 0&&e.agentSessionStore?.delete(e.sessionId)}if(r.toString().trim().length===0){const a=s.snapshot().toolCalls>0?c.MODEL_EMPTY_FINAL:c.MODEL_PROTOCOL_EMPTY_RESPONSE;throw new C(a,"Agent completed without a final text response.",{category:"model",userMessage:"The model completed without a final text response.",retryable:!0})}return e.output!==void 0&&!e.json&&await m(e.output,r.toString()),r.toString()}finally{e.onSnapshot?.(s.snapshot());try{await i.close()}catch(t){e.runtime.logger.warn("Agent cleanup failed after a completed turn.",{reason:t instanceof Error?t.message:String(t)})}}}export{Y as runHeadlessAgentTurn};