@yuandc/aica 0.1.13 → 0.1.15

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.
@@ -1,5 +1,5 @@
1
- import d from"node:fs";import u from"node:path";import{eventFromAcpSessionUpdate as I,statusFromAcpSessionUpdate as w}from"../../client/acp-events.js";import{contextUsageFromAcpSessionUpdate as b}from"../../client/context-usage.js";import{defaultAcpRuntimePool as A}from"../../client/acp-runtime-pool.js";const M={sessionResume:!0,imageInput:!0,fileAttachment:!0,filesystem:!0,terminal:!0,permissionRequest:!0,configOptions:!0,usage:!0,contextUsage:!0,contextCompaction:!1,plan:!0,diff:!1};class V{id="mimocode";name="MimoCode";capabilities=M;async createSession(e){return new v(e.cwd,e.providerSessionId??null,e.timeoutMs)}}class v{cwd;providerSessionId;defaultTimeoutMs;lease=null;acpSessionResponse=null;statusCallback=null;updateCallback=null;permissionCallback=null;userInputCallback=null;canExecuteTools=!0;abortHandler=null;statusTimeline=[];updates=[];content="";latestContextUsage=null;contextWindow=0;constructor(e,t,s=O()){this.cwd=e,this.providerSessionId=t,this.defaultTimeoutMs=s}async sendPrompt(e){if(!d.existsSync(e.cwd)||!d.statSync(e.cwd).isDirectory())throw new Error(`Project root does not exist or is not a directory: ${e.cwd}`);const t=Date.now();this.statusCallback=e.onStatus??null,this.updateCallback=e.onUpdate??null,this.permissionCallback=e.onPermissionRequest??null,this.userInputCallback=e.onUserInputRequest??null,this.canExecuteTools=e.canExecuteTools!==!1,this.attachAbortSignal(e.signal),this.content="",this.updates.length=0,this.statusTimeline.length=0,this.latestContextUsage=null,this.contextWindow=x(e.contextWindow);let s=null,o=null,n=this.providerSessionId,a;try{this.emitStatus("initializing","MimoCode ACP 启动中","mimo acp");const r=await this.acquireRuntime(e.cwd);this.lease=r,s=r.client,o=r.started,await this.initialize(r),n=await this.establishSession(r,e.cwd),await this.applyConfig(s,n,e),this.emitStatus("thinking","思考中"),a=await s.prompt({sessionId:n,prompt:q(e.prompt,e.promptBlocks)},e.timeoutMs??this.defaultTimeoutMs)}finally{this.abortHandler&&e.signal&&(e.signal.removeEventListener("abort",this.abortHandler),this.abortHandler=null),this.releaseLease()}return this.emitStatus("completed","已完成"),{providerSessionId:n,cliType:"builtin",agentType:"mimo",effectiveConfig:{model:e.model||S(),mode:e.mode||null,configOptionValues:e.configOptionValues??null,command:o.command,processPid:o.child.pid??null,provider:"mimocode",protocol:"acp"},command:o.command,args:o.args,cwd:e.cwd,exitCode:o.child.exitCode,signal:o.child.signalCode,durationMs:Date.now()-t,stdout:s.rpc.stdout,stderr:s.rpc.stderr,content:this.content.trim(),updates:[...this.updates],statusTimeline:[...this.statusTimeline],contextUsage:this.latestContextUsage,promptResponse:a}}async cancel(){this.providerSessionId&&this.lease?.client.cancel(this.providerSessionId)}async close(){this.statusCallback=null,this.updateCallback=null,this.permissionCallback=null,this.userInputCallback=null,this.canExecuteTools=!0,this.abortHandler&&(this.abortHandler=null),this.releaseLease()}async acquireRuntime(e){const t=process.env.ACA_MIMO_COMMAND||"mimo",s=["acp","--cwd",e];return A.acquire({providerId:"mimocode",cwd:e,providerSessionId:this.providerSessionId,command:t,args:s,onSessionUpdate:o=>this.handleSessionUpdate(o),onClientRequest:(o,n)=>this.handleClientRequest(o,n)})}async initialize(e){e.initialized||(await e.client.initialize(6e4),e.markInitialized())}async establishSession(e,t){const s=e.client;if(e.providerSessionId&&e.sessionEstablished)return this.providerSessionId=e.providerSessionId,this.acpSessionResponse=e.sessionResponse,e.providerSessionId;if(this.providerSessionId)try{this.emitStatus("resuming","MimoCode 会话恢复中","session/resume");const a=await s.resumeSession({sessionId:this.providerSessionId,cwd:t},6e4);this.acpSessionResponse=f(a);const r=m(a)||this.providerSessionId;return this.providerSessionId=r,e.setProviderSession({providerSessionId:r,sessionResponse:this.acpSessionResponse}),r}catch(a){try{this.emitStatus("resuming","MimoCode 会话加载中","session/load");const r=await s.loadSession({sessionId:this.providerSessionId,cwd:t},6e4);this.acpSessionResponse=f(r);const c=m(r)||this.providerSessionId;return this.providerSessionId=c,e.setProviderSession({providerSessionId:c,sessionResponse:this.acpSessionResponse}),c}catch{this.appendStderr(`MimoCode resume failed, creating new session: ${p(a)}
2
- `),this.providerSessionId=null}}this.emitStatus("acp","MimoCode 会话创建中","session/new");const o=await s.newSession({cwd:t},12e4);this.acpSessionResponse=f(o);const n=m(o);if(!n)throw new Error("MimoCode ACP session/new did not return sessionId");return this.providerSessionId=n,e.setProviderSession({providerSessionId:n,sessionResponse:this.acpSessionResponse}),n}async applyConfig(e,t,s){const o=h(this.acpSessionResponse,"model")||"model",n=h(this.acpSessionResponse,"mode")||"mode",a=_(s.model||S(),s.configOptionValues,this.acpSessionResponse);a&&await e.setSessionConfigOption({sessionId:t,configId:o,value:a},6e4).catch(c=>{this.appendStderr(`MimoCode model config failed: ${p(c)}
1
+ import d from"node:fs";import u from"node:path";import{contextUsageFromAcpSessionUpdate as I}from"../../client/context-usage.js";import{defaultAcpRuntimePool as w}from"../../client/acp-runtime-pool.js";import{providerEventFromAcpSessionUpdate as b,providerStatusFromAcpSessionUpdate as A}from"../standard-acp-events.js";const M={sessionResume:!0,imageInput:!0,fileAttachment:!0,filesystem:!0,terminal:!0,permissionRequest:!0,configOptions:!0,usage:!0,contextUsage:!0,contextCompaction:!1,plan:!0,diff:!1};class V{id="mimocode";name="MimoCode";capabilities=M;async createSession(e){return new v(e.cwd,e.providerSessionId??null,e.timeoutMs)}}class v{cwd;providerSessionId;defaultTimeoutMs;lease=null;acpSessionResponse=null;statusCallback=null;updateCallback=null;permissionCallback=null;userInputCallback=null;canExecuteTools=!0;abortHandler=null;statusTimeline=[];updates=[];content="";latestContextUsage=null;contextWindow=0;constructor(e,t,s=E()){this.cwd=e,this.providerSessionId=t,this.defaultTimeoutMs=s}async sendPrompt(e){if(!d.existsSync(e.cwd)||!d.statSync(e.cwd).isDirectory())throw new Error(`Project root does not exist or is not a directory: ${e.cwd}`);const t=Date.now();this.statusCallback=e.onStatus??null,this.updateCallback=e.onUpdate??null,this.permissionCallback=e.onPermissionRequest??null,this.userInputCallback=e.onUserInputRequest??null,this.canExecuteTools=e.canExecuteTools!==!1,this.attachAbortSignal(e.signal),this.content="",this.updates.length=0,this.statusTimeline.length=0,this.latestContextUsage=null,this.contextWindow=x(e.contextWindow);let s=null,o=null,n=this.providerSessionId,a;try{this.emitStatus("initializing","MimoCode ACP 启动中","mimo acp");const r=await this.acquireRuntime(e.cwd);this.lease=r,s=r.client,o=r.started,await this.initialize(r),n=await this.establishSession(r,e.cwd),await this.applyConfig(s,n,e),this.emitStatus("thinking","思考中"),a=await s.prompt({sessionId:n,prompt:q(e.prompt,e.promptBlocks)},e.timeoutMs??this.defaultTimeoutMs)}finally{this.abortHandler&&e.signal&&(e.signal.removeEventListener("abort",this.abortHandler),this.abortHandler=null),this.releaseLease()}return this.emitStatus("completed","已完成"),{providerSessionId:n,cliType:"builtin",agentType:"mimo",effectiveConfig:{model:e.model||y(),mode:e.mode||null,configOptionValues:e.configOptionValues??null,command:o.command,processPid:o.child.pid??null,provider:"mimocode",protocol:"acp"},command:o.command,args:o.args,cwd:e.cwd,exitCode:o.child.exitCode,signal:o.child.signalCode,durationMs:Date.now()-t,stdout:s.rpc.stdout,stderr:s.rpc.stderr,content:this.content.trim(),updates:[...this.updates],statusTimeline:[...this.statusTimeline],contextUsage:this.latestContextUsage,promptResponse:a}}async cancel(){this.providerSessionId&&this.lease?.client.cancel(this.providerSessionId)}async close(){this.statusCallback=null,this.updateCallback=null,this.permissionCallback=null,this.userInputCallback=null,this.canExecuteTools=!0,this.abortHandler&&(this.abortHandler=null),this.releaseLease()}async acquireRuntime(e){const t=process.env.ACA_MIMO_COMMAND||"mimo",s=["acp","--cwd",e];return w.acquire({providerId:"mimocode",cwd:e,providerSessionId:this.providerSessionId,command:t,args:s,onSessionUpdate:o=>this.handleSessionUpdate(o),onClientRequest:(o,n)=>this.handleClientRequest(o,n)})}async initialize(e){e.initialized||(await e.client.initialize(6e4),e.markInitialized())}async establishSession(e,t){const s=e.client;if(e.providerSessionId&&e.sessionEstablished)return this.providerSessionId=e.providerSessionId,this.acpSessionResponse=e.sessionResponse,e.providerSessionId;if(this.providerSessionId)try{this.emitStatus("resuming","MimoCode 会话恢复中","session/resume");const a=await s.resumeSession({sessionId:this.providerSessionId,cwd:t},6e4);this.acpSessionResponse=f(a);const r=m(a)||this.providerSessionId;return this.providerSessionId=r,e.setProviderSession({providerSessionId:r,sessionResponse:this.acpSessionResponse}),r}catch(a){try{this.emitStatus("resuming","MimoCode 会话加载中","session/load");const r=await s.loadSession({sessionId:this.providerSessionId,cwd:t},6e4);this.acpSessionResponse=f(r);const c=m(r)||this.providerSessionId;return this.providerSessionId=c,e.setProviderSession({providerSessionId:c,sessionResponse:this.acpSessionResponse}),c}catch{this.appendStderr(`MimoCode resume failed, creating new session: ${p(a)}
2
+ `),this.providerSessionId=null}}this.emitStatus("acp","MimoCode 会话创建中","session/new");const o=await s.newSession({cwd:t},12e4);this.acpSessionResponse=f(o);const n=m(o);if(!n)throw new Error("MimoCode ACP session/new did not return sessionId");return this.providerSessionId=n,e.setProviderSession({providerSessionId:n,sessionResponse:this.acpSessionResponse}),n}async applyConfig(e,t,s){const o=h(this.acpSessionResponse,"model")||"model",n=h(this.acpSessionResponse,"mode")||"mode",a=_(s.model||y(),s.configOptionValues,this.acpSessionResponse);a&&await e.setSessionConfigOption({sessionId:t,configId:o,value:a},6e4).catch(c=>{this.appendStderr(`MimoCode model config failed: ${p(c)}
3
3
  `)});const r=P(s.mode);r&&await e.setSessionMode({sessionId:t,modeId:r},6e4).catch(async()=>{await e.setSessionConfigOption({sessionId:t,configId:n,value:r},6e4).catch(c=>{this.appendStderr(`MimoCode mode config failed: ${p(c)}
4
4
  `)})});for(const[c,g]of Object.entries(s.configOptionValues??{}))["variant","reasoning_effort","effort","model","mode"].includes(c)||await e.setSessionConfigOption({sessionId:t,configId:c,value:g},6e4).catch(C=>{this.appendStderr(`MimoCode config ${c} failed: ${p(C)}
5
- `)})}handleSessionUpdate(e){this.updates.push({method:"session/update",params:e}),this.latestContextUsage=b(e,this.contextWindow)??this.latestContextUsage;const t=I(e);t&&(t.type==="agent_message_chunk"&&(this.content+=t.text??""),this.updateCallback?.(t));const s=w(e);s&&this.emitStatus(s.phase,s.label,s.detail,s.updateType)}async handleClientRequest(e,t){if(!this.canExecuteTools&&(e==="fs/read_text_file"||e==="fs/write_text_file"))throw new Error(`Chat Room role policy disabled tool execution: ${e}`);switch(e){case"fs/read_text_file":return this.readTextFile(t);case"fs/write_text_file":return this.writeTextFile(t);case"session/request_permission":return this.requestPermission(t);case"elicitation/create":case"session/request_user_input":return this.requestUserInput(t);default:throw new Error(`Unsupported ACP client request: ${e}`)}}readTextFile(e){const t=y(this.cwd,l(e,"path")||l(e,"filePath"));return{content:d.readFileSync(t,"utf8")}}writeTextFile(e){const t=y(this.cwd,l(e,"path")||l(e,"filePath")),s=l(e,"content")??l(e,"text")??"";return d.mkdirSync(u.dirname(t),{recursive:!0}),d.writeFileSync(t,s,"utf8"),{}}async requestPermission(e){if(!this.permissionCallback)return{outcome:{outcome:"cancelled"}};const t=e&&typeof e=="object"&&!Array.isArray(e)?e:{},o=(Array.isArray(t.options)?t.options:[]).map((n,a)=>{const r=n&&typeof n=="object"&&!Array.isArray(n)?n:{};return{optionId:String(r.optionId??r.id??a),kind:String(r.kind??r.outcome??"choice"),...typeof r.label=="string"?{label:r.label}:{}}});return this.permissionCallback({requestId:String(t.requestId??t.id??`mimo-permission-${Date.now()}`),params:e,options:o})}async requestUserInput(e){if(!this.userInputCallback)return{outcome:{outcome:"cancelled"}};const t=e&&typeof e=="object"&&!Array.isArray(e)?e:{};return this.userInputCallback({requestId:String(t.requestId??t.id??`mimo-input-${Date.now()}`),prompt:String(t.prompt??t.message??t.question??""),params:e,...typeof t.defaultValue=="string"?{defaultValue:t.defaultValue}:{}})}attachAbortSignal(e){if(e){if(this.abortHandler=()=>{this.cancel()},e.aborted)throw new Error("MimoCode prompt cancelled");e.addEventListener("abort",this.abortHandler,{once:!0})}}emitStatus(e,t,s,o){const n={phase:e,label:t,...s?{detail:s}:{},...o?{updateType:o}:{},atMs:Date.now()},a=this.statusTimeline[this.statusTimeline.length-1];a&&a.phase===n.phase&&a.label===n.label&&a.detail===n.detail&&a.updateType===n.updateType||(this.statusTimeline.push(n),this.statusCallback?.(n))}requireClient(){if(!this.lease)throw new Error("MimoCode ACP client is not started");return this.lease.client}appendStderr(e){const t=this.lease?.client;t&&(t.rpc.stderr+=e)}releaseLease(){this.lease?.release(),this.lease=null}}function m(i){if(!i||typeof i!="object"||Array.isArray(i))return null;const e=i.sessionId;return typeof e=="string"&&e.trim()?e.trim():null}function f(i){return i&&typeof i=="object"&&!Array.isArray(i)?i:null}function x(i){return typeof i=="number"&&Number.isFinite(i)&&i>0?i:0}function h(i,e){const t=i?.configOptions;if(!Array.isArray(t))return null;for(const s of t){if(!s||typeof s!="object"||Array.isArray(s))continue;const o=s;if(o.category===e&&typeof o.id=="string"&&o.id.trim())return o.id.trim()}return null}function _(i,e,t){const s=k(e?.variant,e?.reasoning_effort,e?.effort);if(!s||i.endsWith(`/${s}`))return i;const o=`${i}/${s}`;return T(t,o)?o:i}function T(i,e){const t=i?.configOptions;if(!Array.isArray(t))return!1;for(const s of t){if(!s||typeof s!="object"||Array.isArray(s))continue;const o=s;if(!(o.category!=="model"||!Array.isArray(o.options))&&o.options.some(n=>R(n)===e))return!0}return!1}function R(i){if(typeof i=="string"&&i.trim())return i.trim();if(!i||typeof i!="object"||Array.isArray(i))return null;const e=i;for(const t of["value","id","modelId","model_id"]){const s=e[t];if(typeof s=="string"&&s.trim())return s.trim()}return null}function l(i,e){if(!i||typeof i!="object"||Array.isArray(i))return null;const t=i[e];return typeof t=="string"&&t.trim()?t:null}function y(i,e){if(!e)throw new Error("ACP file request did not include a path");const t=u.resolve(i,e),s=u.resolve(i);if(t!==s&&!t.startsWith(`${s}${u.sep}`))throw new Error(`ACP file request is outside project root: ${e}`);return t}function P(i){const e=String(i||"").trim();return e?["agent","agent-full-access","full-access","bypassPermissions","danger-full-access"].includes(e)?"build":e==="read-only"?"plan":e:null}function k(...i){for(const e of i)if(typeof e=="string"&&e.trim())return e.trim();return null}function p(i){return i instanceof Error?i.message:String(i)}function S(){return process.env.ACA_MIMO_DEFAULT_MODEL||"mimo/mimo-auto"}function q(i,e){return(e?.length?e:[{type:"text",text:i}]).map(s=>s.type==="image"?{type:"image",data:s.data,mimeType:s.mimeType}:{type:"text",text:s.text})}function O(){const i=Number.parseInt(process.env.ACA_MIMO_PROMPT_TIMEOUT_MS??process.env.ACA_ACP_PROMPT_TIMEOUT_MS??"",10);return Number.isInteger(i)&&i>=3e4?i:360*60*1e3}export{V as MimoCodeProvider,M as mimoCodeCapabilities};
5
+ `)})}handleSessionUpdate(e){this.updates.push({method:"session/update",params:e}),this.latestContextUsage=I(e,this.contextWindow)??this.latestContextUsage;const t=b("mimo",e);t&&(t.type==="agent_message_chunk"&&(this.content+=t.text??""),this.updateCallback?.(t));const s=A("mimo",e);s&&this.emitStatus(s.phase,s.label,s.detail,s.updateType)}async handleClientRequest(e,t){if(!this.canExecuteTools&&(e==="fs/read_text_file"||e==="fs/write_text_file"))throw new Error(`Chat Room role policy disabled tool execution: ${e}`);switch(e){case"fs/read_text_file":return this.readTextFile(t);case"fs/write_text_file":return this.writeTextFile(t);case"session/request_permission":return this.requestPermission(t);case"elicitation/create":case"session/request_user_input":return this.requestUserInput(t);default:throw new Error(`Unsupported ACP client request: ${e}`)}}readTextFile(e){const t=S(this.cwd,l(e,"path")||l(e,"filePath"));return{content:d.readFileSync(t,"utf8")}}writeTextFile(e){const t=S(this.cwd,l(e,"path")||l(e,"filePath")),s=l(e,"content")??l(e,"text")??"";return d.mkdirSync(u.dirname(t),{recursive:!0}),d.writeFileSync(t,s,"utf8"),{}}async requestPermission(e){if(!this.permissionCallback)return{outcome:{outcome:"cancelled"}};const t=e&&typeof e=="object"&&!Array.isArray(e)?e:{},o=(Array.isArray(t.options)?t.options:[]).map((n,a)=>{const r=n&&typeof n=="object"&&!Array.isArray(n)?n:{};return{optionId:String(r.optionId??r.id??a),kind:String(r.kind??r.outcome??"choice"),...typeof r.label=="string"?{label:r.label}:{}}});return this.permissionCallback({requestId:String(t.requestId??t.id??`mimo-permission-${Date.now()}`),params:e,options:o})}async requestUserInput(e){if(!this.userInputCallback)return{outcome:{outcome:"cancelled"}};const t=e&&typeof e=="object"&&!Array.isArray(e)?e:{};return this.userInputCallback({requestId:String(t.requestId??t.id??`mimo-input-${Date.now()}`),prompt:String(t.prompt??t.message??t.question??""),params:e,...typeof t.defaultValue=="string"?{defaultValue:t.defaultValue}:{}})}attachAbortSignal(e){if(e){if(this.abortHandler=()=>{this.cancel()},e.aborted)throw new Error("MimoCode prompt cancelled");e.addEventListener("abort",this.abortHandler,{once:!0})}}emitStatus(e,t,s,o){const n={phase:e,label:t,...s?{detail:s}:{},...o?{updateType:o}:{},atMs:Date.now()},a=this.statusTimeline[this.statusTimeline.length-1];a&&a.phase===n.phase&&a.label===n.label&&a.detail===n.detail&&a.updateType===n.updateType||(this.statusTimeline.push(n),this.statusCallback?.(n))}requireClient(){if(!this.lease)throw new Error("MimoCode ACP client is not started");return this.lease.client}appendStderr(e){const t=this.lease?.client;t&&(t.rpc.stderr+=e)}releaseLease(){this.lease?.release(),this.lease=null}}function m(i){if(!i||typeof i!="object"||Array.isArray(i))return null;const e=i.sessionId;return typeof e=="string"&&e.trim()?e.trim():null}function f(i){return i&&typeof i=="object"&&!Array.isArray(i)?i:null}function x(i){return typeof i=="number"&&Number.isFinite(i)&&i>0?i:0}function h(i,e){const t=i?.configOptions;if(!Array.isArray(t))return null;for(const s of t){if(!s||typeof s!="object"||Array.isArray(s))continue;const o=s;if(o.category===e&&typeof o.id=="string"&&o.id.trim())return o.id.trim()}return null}function _(i,e,t){const s=k(e?.variant,e?.reasoning_effort,e?.effort);if(!s||i.endsWith(`/${s}`))return i;const o=`${i}/${s}`;return T(t,o)?o:i}function T(i,e){const t=i?.configOptions;if(!Array.isArray(t))return!1;for(const s of t){if(!s||typeof s!="object"||Array.isArray(s))continue;const o=s;if(!(o.category!=="model"||!Array.isArray(o.options))&&o.options.some(n=>R(n)===e))return!0}return!1}function R(i){if(typeof i=="string"&&i.trim())return i.trim();if(!i||typeof i!="object"||Array.isArray(i))return null;const e=i;for(const t of["value","id","modelId","model_id"]){const s=e[t];if(typeof s=="string"&&s.trim())return s.trim()}return null}function l(i,e){if(!i||typeof i!="object"||Array.isArray(i))return null;const t=i[e];return typeof t=="string"&&t.trim()?t:null}function S(i,e){if(!e)throw new Error("ACP file request did not include a path");const t=u.resolve(i,e),s=u.resolve(i);if(t!==s&&!t.startsWith(`${s}${u.sep}`))throw new Error(`ACP file request is outside project root: ${e}`);return t}function P(i){const e=String(i||"").trim();return e?["agent","agent-full-access","full-access","bypassPermissions","danger-full-access"].includes(e)?"build":e==="read-only"?"plan":e:null}function k(...i){for(const e of i)if(typeof e=="string"&&e.trim())return e.trim();return null}function p(i){return i instanceof Error?i.message:String(i)}function y(){return process.env.ACA_MIMO_DEFAULT_MODEL||"mimo/mimo-auto"}function q(i,e){return(e?.length?e:[{type:"text",text:i}]).map(s=>s.type==="image"?{type:"image",data:s.data,mimeType:s.mimeType}:{type:"text",text:s.text})}function E(){const i=Number.parseInt(process.env.ACA_MIMO_PROMPT_TIMEOUT_MS??process.env.ACA_ACP_PROMPT_TIMEOUT_MS??"",10);return Number.isInteger(i)&&i>=3e4?i:360*60*1e3}export{V as MimoCodeProvider,M as mimoCodeCapabilities};
@@ -1,4 +1,4 @@
1
- import p from"node:fs";import h from"node:path";import{eventFromAcpSessionUpdate as v,statusFromAcpSessionUpdate as x}from"../../client/acp-events.js";import{contextUsageFromAcpSessionUpdate as O}from"../../client/context-usage.js";import{defaultAcpRuntimePool as E}from"../../client/acp-runtime-pool.js";const P={sessionResume:!0,imageInput:!0,fileAttachment:!0,filesystem:!0,terminal:!0,permissionRequest:!0,configOptions:!0,usage:!0,contextUsage:!0,contextCompaction:!1,plan:!0,diff:!0};class V{id="opencode";name="OpenCode";capabilities=P;async createSession(e){return new T(e.cwd,e.providerSessionId??null,e.timeoutMs)}}class T{cwd;providerSessionId;defaultTimeoutMs;lease=null;sessionResponse=null;statusCallback=null;updateCallback=null;permissionCallback=null;userInputCallback=null;canExecuteTools=!0;abortHandler=null;statusTimeline=[];updates=[];content="";latestContextUsage=null;contextWindow=0;resumedExistingSession=!1;constructor(e,t,s=F()){this.cwd=e,this.providerSessionId=t,this.defaultTimeoutMs=s}async sendPrompt(e){if(!p.existsSync(e.cwd)||!p.statSync(e.cwd).isDirectory())throw new Error(`Project root does not exist or is not a directory: ${e.cwd}`);const t=Date.now();this.statusCallback=e.onStatus??null,this.updateCallback=e.onUpdate??null,this.permissionCallback=e.onPermissionRequest??null,this.userInputCallback=e.onUserInputRequest??null,this.canExecuteTools=e.canExecuteTools!==!1,this.attachAbortSignal(e.signal),this.content="",this.updates.length=0,this.statusTimeline.length=0,this.latestContextUsage=null,this.contextWindow=_(e.contextWindow);let s=null,n=null,o=this.providerSessionId,r;try{this.emitStatus("initializing","OpenCode ACP 启动中","opencode acp");const l=await this.acquireRuntime(e.cwd);this.lease=l,s=l.client,n=l.started,await this.initialize(l),o=await this.establishSession(l,e),await this.applyConfig(s,o,e),this.emitStatus("thinking","思考中");const a=U(e.prompt,e.promptBlocks);try{r=await this.promptWithAbort(s,{sessionId:o,prompt:a,timeoutMs:e.timeoutMs??this.defaultTimeoutMs,signal:e.signal})}catch(f){if(!this.resumedExistingSession||!k(f))throw f;this.appendStderr(`OpenCode resumed session rejected session/prompt with Invalid params; creating a fresh session and retrying once.
2
- `),await this.lease?.dispose().catch(()=>{}),this.lease=null,this.providerSessionId=null,this.sessionResponse=null,this.resumedExistingSession=!1,this.emitStatus("resuming","OpenCode 会话已失效,正在新建","session/prompt invalid params");const u=await this.acquireRuntime(e.cwd);this.lease=u,s=u.client,n=u.started,await this.initialize(u),o=await this.establishSession(u,e),await this.applyConfig(s,o,e),this.emitStatus("thinking","思考中"),r=await this.promptWithAbort(s,{sessionId:o,prompt:a,timeoutMs:e.timeoutMs??this.defaultTimeoutMs,signal:e.signal})}}finally{this.abortHandler&&e.signal&&(e.signal.removeEventListener("abort",this.abortHandler),this.abortHandler=null),this.releaseLease()}return this.emitStatus("completed","已完成"),{providerSessionId:o,cliType:"builtin",agentType:"opencode",effectiveConfig:{model:m(e.model)||null,mode:e.mode||null,configOptionValues:e.configOptionValues??null,command:n.command,processPid:n.child.pid??null,provider:"opencode",protocol:"acp"},command:n.command,args:n.args,cwd:e.cwd,exitCode:n.child.exitCode,signal:n.child.signalCode,durationMs:Date.now()-t,stdout:s.rpc.stdout,stderr:s.rpc.stderr,content:this.content.trim(),updates:[...this.updates],statusTimeline:[...this.statusTimeline],contextUsage:this.latestContextUsage,promptResponse:r}}async cancel(){this.providerSessionId&&this.lease?.client.cancel(this.providerSessionId)}async close(){this.statusCallback=null,this.updateCallback=null,this.permissionCallback=null,this.userInputCallback=null,this.canExecuteTools=!0,this.abortHandler&&(this.abortHandler=null),this.releaseLease()}async acquireRuntime(e){const t=process.env.ACA_OPENCODE_COMMAND||"opencode";return E.acquire({providerId:"opencode",cwd:e,providerSessionId:this.providerSessionId,command:t,args:["acp","--cwd",e],onSessionUpdate:s=>this.handleSessionUpdate(s),onClientRequest:(s,n)=>this.handleClientRequest(s,n)})}async initialize(e){e.initialized||(await e.client.initialize(6e4),e.markInitialized())}async establishSession(e,t){const s=e.client,n=q(t);if(this.resumedExistingSession=!1,e.providerSessionId&&e.sessionEstablished){if(S(e.sessionResponse,t.model))return this.providerSessionId=e.providerSessionId,this.sessionResponse=e.sessionResponse,this.resumedExistingSession=!0,e.providerSessionId;this.providerSessionId=null}else if(this.providerSessionId)try{this.emitStatus("resuming","OpenCode 会话恢复中","session/load");const l=await s.loadSession({sessionId:this.providerSessionId,cwd:t.cwd},6e4);if(this.sessionResponse=d(l),S(this.sessionResponse,t.model)){const a=g(l)||this.providerSessionId;return this.providerSessionId=a,e.setProviderSession({providerSessionId:a,sessionResponse:this.sessionResponse}),this.resumedExistingSession=!0,a}this.appendStderr(`OpenCode model changed from ${C(this.sessionResponse)??"unknown"} to ${m(t.model)||"default"}, creating new session
3
- `),this.providerSessionId=null}catch{this.providerSessionId=null}this.emitStatus("acp","OpenCode 会话创建中","session/new");const o=await s.newSession({cwd:t.cwd,config:n},12e4);this.sessionResponse=d(o);const r=g(o);if(!r)throw new Error("OpenCode ACP session/new did not return sessionId");return this.providerSessionId=r,e.setProviderSession({providerSessionId:r,sessionResponse:this.sessionResponse}),r}async applyConfig(e,t,s){const n=w(s.mode);n&&await e.setSessionMode({sessionId:t,modeId:n},6e4).catch(o=>{this.appendStderr(`OpenCode mode config failed: ${y(o)}
4
- `)})}handleSessionUpdate(e){this.updates.push({method:"session/update",params:e}),this.latestContextUsage=O(e,this.contextWindow)??this.latestContextUsage;const t=v(e);t&&(t.type==="agent_message_chunk"&&(this.content+=t.text??""),this.updateCallback?.(t));const s=x(e);s&&this.emitStatus(s.phase,s.label,s.detail,s.updateType)}async handleClientRequest(e,t){if(!this.canExecuteTools&&(e==="fs/read_text_file"||e==="fs/write_text_file"))throw new Error(`Chat Room role policy disabled tool execution: ${e}`);switch(e){case"fs/read_text_file":return this.readTextFile(t);case"fs/write_text_file":return this.writeTextFile(t);case"session/request_permission":return this.requestPermission(t);case"elicitation/create":case"session/request_user_input":return this.requestUserInput(t);default:throw new Error(`Unsupported OpenCode ACP client request: ${e}`)}}readTextFile(e){const t=I(this.cwd,c(e,"path")||c(e,"filePath"));return{content:p.readFileSync(t,"utf8")}}writeTextFile(e){const t=I(this.cwd,c(e,"path")||c(e,"filePath")),s=c(e,"content")??c(e,"text")??"";return p.mkdirSync(h.dirname(t),{recursive:!0}),p.writeFileSync(t,s,"utf8"),{}}attachAbortSignal(e){if(e){if(this.abortHandler=()=>{this.cancel()},e.aborted)throw new Error("OpenCode prompt cancelled");e.addEventListener("abort",this.abortHandler,{once:!0})}}async promptWithAbort(e,t){const s=e.prompt({sessionId:t.sessionId,prompt:t.prompt},t.timeoutMs);if(!t.signal)return s;if(t.signal.aborted)throw await this.lease?.dispose().catch(()=>{}),new Error("OpenCode prompt cancelled");let n=null;const o=new Promise((r,l)=>{n=()=>{e.cancel(t.sessionId),this.lease?.dispose().catch(()=>{}),l(new Error("OpenCode prompt cancelled"))},t.signal?.addEventListener("abort",n,{once:!0})});try{return await Promise.race([s,o])}finally{n&&t.signal.removeEventListener("abort",n)}}async requestPermission(e){if(!this.permissionCallback)return{outcome:{outcome:"cancelled"}};const t=d(e)??{},s=d(t.request)??t,o=(Array.isArray(s.options)?s.options:[]).map((r,l)=>{const a=d(r)??{};return{optionId:String(a.optionId??a.id??l),kind:String(a.kind??a.outcome??"choice"),...typeof a.label=="string"?{label:a.label}:{}}});return this.emitStatus("requestPermission","等待授权",A(s),"session/request_permission"),this.permissionCallback({requestId:String(s.requestId??s.id??`opencode-permission-${Date.now()}`),params:e,options:o})}async requestUserInput(e){if(!this.userInputCallback)return{outcome:{outcome:"cancelled"}};const t=d(e)??{},s=d(t.request)??t;return this.emitStatus("requestPermission","等待输入",M(s),"elicitation/create"),this.userInputCallback({requestId:String(s.requestId??s.id??`opencode-input-${Date.now()}`),prompt:String(s.prompt??s.message??s.question??""),params:e,...typeof s.defaultValue=="string"?{defaultValue:s.defaultValue}:{}})}emitStatus(e,t,s,n){const o={phase:e,label:t,...s?{detail:s}:{},...n?{updateType:n}:{},atMs:Date.now()},r=this.statusTimeline[this.statusTimeline.length-1];r&&r.phase===o.phase&&r.label===o.label&&r.detail===o.detail&&r.updateType===o.updateType||(this.statusTimeline.push(o),this.statusCallback?.(o))}appendStderr(e){const t=this.lease?.client;t&&(t.rpc.stderr+=e)}releaseLease(){this.lease?.release(),this.lease=null}}function g(i){const t=d(i)?.sessionId;return typeof t=="string"&&t.trim()?t.trim():null}function d(i){return i&&typeof i=="object"&&!Array.isArray(i)?i:null}function _(i){return typeof i=="number"&&Number.isFinite(i)&&i>0?i:0}function q(i){const e=m(i.model),t=w(i.mode);return{...R(i.configOptionValues),...e?{model:e}:{},...t?{mode:t}:{}}}function R(i){const e={};for(const[t,s]of Object.entries(i??{}))["model","mode","reasoning_effort","effort","variant"].includes(t)||(e[t]=s);return e}function S(i,e){const t=m(e);if(!t)return!0;const s=C(i);return!s||s===t}function C(i){const t=d(i?.models)?.currentModelId;return typeof t=="string"&&t.trim()?t.trim():null}function w(i){const e=String(i||"").trim();return e?["agent-full-access","full-access","bypassPermissions","danger-full-access"].includes(e)?"build":e==="read-only"?"plan":e:null}function c(i,e){const s=d(i)?.[e];return typeof s=="string"&&s.trim()?s:null}function I(i,e){if(!e)throw new Error("ACP file request did not include a path");const t=h.resolve(i,e),s=h.resolve(i);if(t!==s&&!t.startsWith(`${s}${h.sep}`))throw new Error(`ACP file request is outside project root: ${e}`);return t}function A(i){const e=d(i.params)??i;for(const t of["command","cwd","reason","grantRoot","method"]){const s=e[t];if(typeof s=="string"&&s.trim())return b(s)}}function M(i){for(const e of["prompt","message","question","title"]){const t=i[e];if(typeof t=="string"&&t.trim())return b(t)}}function b(i){const e=i.replace(/\s+/g," ").trim();return e.length>120?`${e.slice(0,117)}...`:e}function y(i){return i instanceof Error?i.message:String(i)}function k(i){return/\binvalid params\b/i.test(y(i))}function U(i,e){return(e?.length?e:[{type:"text",text:i}]).map(s=>s.type==="image"?{type:"image",data:s.data,mimeType:s.mimeType}:{type:"text",text:s.text})}function D(){return process.env.ACA_OPENCODE_DEFAULT_MODEL||""}function m(i){const e=String(i||D()).trim();return e==="default"||e==="opencode-default"?"":e}function F(){const i=Number.parseInt(process.env.ACA_OPENCODE_PROMPT_TIMEOUT_MS??process.env.ACA_ACP_PROMPT_TIMEOUT_MS??"",10);return Number.isInteger(i)&&i>=3e4?i:360*60*1e3}export{V as OpenCodeProvider,P as openCodeCapabilities};
1
+ import p from"node:fs";import h from"node:path";import{contextUsageFromAcpSessionUpdate as y}from"../../client/context-usage.js";import{defaultAcpRuntimePool as x}from"../../client/acp-runtime-pool.js";import{providerEventFromAcpSessionUpdate as E,providerStatusFromAcpSessionUpdate as O}from"../standard-acp-events.js";const P={sessionResume:!0,imageInput:!0,fileAttachment:!0,filesystem:!0,terminal:!0,permissionRequest:!0,configOptions:!0,usage:!0,contextUsage:!0,contextCompaction:!1,plan:!0,diff:!0};class V{id="opencode";name="OpenCode";capabilities=P;async createSession(e){return new T(e.cwd,e.providerSessionId??null,e.timeoutMs)}}class T{cwd;providerSessionId;defaultTimeoutMs;lease=null;sessionResponse=null;statusCallback=null;updateCallback=null;permissionCallback=null;userInputCallback=null;canExecuteTools=!0;abortHandler=null;statusTimeline=[];updates=[];content="";latestContextUsage=null;contextWindow=0;resumedExistingSession=!1;constructor(e,t,s=F()){this.cwd=e,this.providerSessionId=t,this.defaultTimeoutMs=s}async sendPrompt(e){if(!p.existsSync(e.cwd)||!p.statSync(e.cwd).isDirectory())throw new Error(`Project root does not exist or is not a directory: ${e.cwd}`);const t=Date.now();this.statusCallback=e.onStatus??null,this.updateCallback=e.onUpdate??null,this.permissionCallback=e.onPermissionRequest??null,this.userInputCallback=e.onUserInputRequest??null,this.canExecuteTools=e.canExecuteTools!==!1,this.attachAbortSignal(e.signal),this.content="",this.updates.length=0,this.statusTimeline.length=0,this.latestContextUsage=null,this.contextWindow=_(e.contextWindow);let s=null,n=null,o=this.providerSessionId,r;try{this.emitStatus("initializing","OpenCode ACP 启动中","opencode acp");const l=await this.acquireRuntime(e.cwd);this.lease=l,s=l.client,n=l.started,await this.initialize(l),o=await this.establishSession(l,e),await this.applyConfig(s,o,e),this.emitStatus("thinking","思考中");const a=U(e.prompt,e.promptBlocks);try{r=await this.promptWithAbort(s,{sessionId:o,prompt:a,timeoutMs:e.timeoutMs??this.defaultTimeoutMs,signal:e.signal})}catch(f){if(!this.resumedExistingSession||!k(f))throw f;this.appendStderr(`OpenCode resumed session rejected session/prompt with Invalid params; creating a fresh session and retrying once.
2
+ `),await this.lease?.dispose().catch(()=>{}),this.lease=null,this.providerSessionId=null,this.sessionResponse=null,this.resumedExistingSession=!1,this.emitStatus("resuming","OpenCode 会话已失效,正在新建","session/prompt invalid params");const u=await this.acquireRuntime(e.cwd);this.lease=u,s=u.client,n=u.started,await this.initialize(u),o=await this.establishSession(u,e),await this.applyConfig(s,o,e),this.emitStatus("thinking","思考中"),r=await this.promptWithAbort(s,{sessionId:o,prompt:a,timeoutMs:e.timeoutMs??this.defaultTimeoutMs,signal:e.signal})}}finally{this.abortHandler&&e.signal&&(e.signal.removeEventListener("abort",this.abortHandler),this.abortHandler=null),this.releaseLease()}return this.emitStatus("completed","已完成"),{providerSessionId:o,cliType:"builtin",agentType:"opencode",effectiveConfig:{model:m(e.model)||null,mode:e.mode||null,configOptionValues:e.configOptionValues??null,command:n.command,processPid:n.child.pid??null,provider:"opencode",protocol:"acp"},command:n.command,args:n.args,cwd:e.cwd,exitCode:n.child.exitCode,signal:n.child.signalCode,durationMs:Date.now()-t,stdout:s.rpc.stdout,stderr:s.rpc.stderr,content:this.content.trim(),updates:[...this.updates],statusTimeline:[...this.statusTimeline],contextUsage:this.latestContextUsage,promptResponse:r}}async cancel(){this.providerSessionId&&this.lease?.client.cancel(this.providerSessionId)}async close(){this.statusCallback=null,this.updateCallback=null,this.permissionCallback=null,this.userInputCallback=null,this.canExecuteTools=!0,this.abortHandler&&(this.abortHandler=null),this.releaseLease()}async acquireRuntime(e){const t=process.env.ACA_OPENCODE_COMMAND||"opencode";return x.acquire({providerId:"opencode",cwd:e,providerSessionId:this.providerSessionId,command:t,args:["acp","--cwd",e],onSessionUpdate:s=>this.handleSessionUpdate(s),onClientRequest:(s,n)=>this.handleClientRequest(s,n)})}async initialize(e){e.initialized||(await e.client.initialize(6e4),e.markInitialized())}async establishSession(e,t){const s=e.client,n=q(t);if(this.resumedExistingSession=!1,e.providerSessionId&&e.sessionEstablished){if(S(e.sessionResponse,t.model))return this.providerSessionId=e.providerSessionId,this.sessionResponse=e.sessionResponse,this.resumedExistingSession=!0,e.providerSessionId;this.providerSessionId=null}else if(this.providerSessionId)try{this.emitStatus("resuming","OpenCode 会话恢复中","session/load");const l=await s.loadSession({sessionId:this.providerSessionId,cwd:t.cwd},6e4);if(this.sessionResponse=d(l),S(this.sessionResponse,t.model)){const a=g(l)||this.providerSessionId;return this.providerSessionId=a,e.setProviderSession({providerSessionId:a,sessionResponse:this.sessionResponse}),this.resumedExistingSession=!0,a}this.appendStderr(`OpenCode model changed from ${C(this.sessionResponse)??"unknown"} to ${m(t.model)||"default"}, creating new session
3
+ `),this.providerSessionId=null}catch{this.providerSessionId=null}this.emitStatus("acp","OpenCode 会话创建中","session/new");const o=await s.newSession({cwd:t.cwd,config:n},12e4);this.sessionResponse=d(o);const r=g(o);if(!r)throw new Error("OpenCode ACP session/new did not return sessionId");return this.providerSessionId=r,e.setProviderSession({providerSessionId:r,sessionResponse:this.sessionResponse}),r}async applyConfig(e,t,s){const n=w(s.mode);n&&await e.setSessionMode({sessionId:t,modeId:n},6e4).catch(o=>{this.appendStderr(`OpenCode mode config failed: ${v(o)}
4
+ `)})}handleSessionUpdate(e){this.updates.push({method:"session/update",params:e}),this.latestContextUsage=y(e,this.contextWindow)??this.latestContextUsage;const t=E("opencode",e);t&&(t.type==="agent_message_chunk"&&(this.content+=t.text??""),this.updateCallback?.(t));const s=O("opencode",e);s&&this.emitStatus(s.phase,s.label,s.detail,s.updateType)}async handleClientRequest(e,t){if(!this.canExecuteTools&&(e==="fs/read_text_file"||e==="fs/write_text_file"))throw new Error(`Chat Room role policy disabled tool execution: ${e}`);switch(e){case"fs/read_text_file":return this.readTextFile(t);case"fs/write_text_file":return this.writeTextFile(t);case"session/request_permission":return this.requestPermission(t);case"elicitation/create":case"session/request_user_input":return this.requestUserInput(t);default:throw new Error(`Unsupported OpenCode ACP client request: ${e}`)}}readTextFile(e){const t=I(this.cwd,c(e,"path")||c(e,"filePath"));return{content:p.readFileSync(t,"utf8")}}writeTextFile(e){const t=I(this.cwd,c(e,"path")||c(e,"filePath")),s=c(e,"content")??c(e,"text")??"";return p.mkdirSync(h.dirname(t),{recursive:!0}),p.writeFileSync(t,s,"utf8"),{}}attachAbortSignal(e){if(e){if(this.abortHandler=()=>{this.cancel()},e.aborted)throw new Error("OpenCode prompt cancelled");e.addEventListener("abort",this.abortHandler,{once:!0})}}async promptWithAbort(e,t){const s=e.prompt({sessionId:t.sessionId,prompt:t.prompt},t.timeoutMs);if(!t.signal)return s;if(t.signal.aborted)throw await this.lease?.dispose().catch(()=>{}),new Error("OpenCode prompt cancelled");let n=null;const o=new Promise((r,l)=>{n=()=>{e.cancel(t.sessionId),this.lease?.dispose().catch(()=>{}),l(new Error("OpenCode prompt cancelled"))},t.signal?.addEventListener("abort",n,{once:!0})});try{return await Promise.race([s,o])}finally{n&&t.signal.removeEventListener("abort",n)}}async requestPermission(e){if(!this.permissionCallback)return{outcome:{outcome:"cancelled"}};const t=d(e)??{},s=d(t.request)??t,o=(Array.isArray(s.options)?s.options:[]).map((r,l)=>{const a=d(r)??{};return{optionId:String(a.optionId??a.id??l),kind:String(a.kind??a.outcome??"choice"),...typeof a.label=="string"?{label:a.label}:{}}});return this.emitStatus("requestPermission","等待授权",A(s),"session/request_permission"),this.permissionCallback({requestId:String(s.requestId??s.id??`opencode-permission-${Date.now()}`),params:e,options:o})}async requestUserInput(e){if(!this.userInputCallback)return{outcome:{outcome:"cancelled"}};const t=d(e)??{},s=d(t.request)??t;return this.emitStatus("requestPermission","等待输入",M(s),"elicitation/create"),this.userInputCallback({requestId:String(s.requestId??s.id??`opencode-input-${Date.now()}`),prompt:String(s.prompt??s.message??s.question??""),params:e,...typeof s.defaultValue=="string"?{defaultValue:s.defaultValue}:{}})}emitStatus(e,t,s,n){const o={phase:e,label:t,...s?{detail:s}:{},...n?{updateType:n}:{},atMs:Date.now()},r=this.statusTimeline[this.statusTimeline.length-1];r&&r.phase===o.phase&&r.label===o.label&&r.detail===o.detail&&r.updateType===o.updateType||(this.statusTimeline.push(o),this.statusCallback?.(o))}appendStderr(e){const t=this.lease?.client;t&&(t.rpc.stderr+=e)}releaseLease(){this.lease?.release(),this.lease=null}}function g(i){const t=d(i)?.sessionId;return typeof t=="string"&&t.trim()?t.trim():null}function d(i){return i&&typeof i=="object"&&!Array.isArray(i)?i:null}function _(i){return typeof i=="number"&&Number.isFinite(i)&&i>0?i:0}function q(i){const e=m(i.model),t=w(i.mode);return{...R(i.configOptionValues),...e?{model:e}:{},...t?{mode:t}:{}}}function R(i){const e={};for(const[t,s]of Object.entries(i??{}))["model","mode","reasoning_effort","effort","variant"].includes(t)||(e[t]=s);return e}function S(i,e){const t=m(e);if(!t)return!0;const s=C(i);return!s||s===t}function C(i){const t=d(i?.models)?.currentModelId;return typeof t=="string"&&t.trim()?t.trim():null}function w(i){const e=String(i||"").trim();return e?["agent-full-access","full-access","bypassPermissions","danger-full-access"].includes(e)?"build":e==="read-only"?"plan":e:null}function c(i,e){const s=d(i)?.[e];return typeof s=="string"&&s.trim()?s:null}function I(i,e){if(!e)throw new Error("ACP file request did not include a path");const t=h.resolve(i,e),s=h.resolve(i);if(t!==s&&!t.startsWith(`${s}${h.sep}`))throw new Error(`ACP file request is outside project root: ${e}`);return t}function A(i){const e=d(i.params)??i;for(const t of["command","cwd","reason","grantRoot","method"]){const s=e[t];if(typeof s=="string"&&s.trim())return b(s)}}function M(i){for(const e of["prompt","message","question","title"]){const t=i[e];if(typeof t=="string"&&t.trim())return b(t)}}function b(i){const e=i.replace(/\s+/g," ").trim();return e.length>120?`${e.slice(0,117)}...`:e}function v(i){return i instanceof Error?i.message:String(i)}function k(i){return/\binvalid params\b/i.test(v(i))}function U(i,e){return(e?.length?e:[{type:"text",text:i}]).map(s=>s.type==="image"?{type:"image",data:s.data,mimeType:s.mimeType}:{type:"text",text:s.text})}function D(){return process.env.ACA_OPENCODE_DEFAULT_MODEL||""}function m(i){const e=String(i||D()).trim();return e==="default"||e==="opencode-default"?"":e}function F(){const i=Number.parseInt(process.env.ACA_OPENCODE_PROMPT_TIMEOUT_MS??process.env.ACA_ACP_PROMPT_TIMEOUT_MS??"",10);return Number.isInteger(i)&&i>=3e4?i:360*60*1e3}export{V as OpenCodeProvider,P as openCodeCapabilities};
@@ -0,0 +1 @@
1
+ import{eventFromAcpSessionUpdate as g,statusFromAcpSessionUpdate as h}from"../client/acp-events.js";function z(t,n){return g(u(t,n))}function F(t,n){return h(u(t,n))}function u(t,n){const o=y(n);if(!o)return n;const r=o.update,e=w(r);if(!e)return n;const i={...r,sessionUpdate:e};return(e==="tool_call"||e==="tool_call_update")&&I(i,t),e==="plan"&&k(i),(e==="agent_message_chunk"||e==="agent_progress_chunk"||e==="agent_thought_chunk")&&(i.content=x(r.content??r.text??r.delta)),{...o.params,...o.sessionId?{sessionId:o.sessionId}:{},update:i}}function k(t){const n=l(t.plan,t.taskPlan,t.task_plan),o=C(t.entries,t.items,t.steps,t.todos,t.tasks,t.checklist,n?.entries,n?.items,n?.steps,n?.todos,n?.tasks,n?.checklist);o&&!Array.isArray(t.entries)&&(t.entries=o);const r=s(t.planId,t.plan_id,t.taskPlanId,t.task_plan_id,n?.id);r&&!t.planId&&(t.planId=r);const e=s(t.markdown,t.planText,t.plan_text,n?.markdown);e&&!t.markdown&&(t.markdown=e)}function y(t){if(!t||typeof t!="object"||Array.isArray(t))return null;const n=t,o=l(n.update,n.sessionUpdate,n.session_update,n.event,n.notification)??n,r=o===n&&!T(n)?l(n.data,n.payload):o;return r?{params:n,sessionId:s(n.sessionId,n.session_id),update:r}:null}function w(t){const o=s(t.sessionUpdate,t.session_update,t.updateType,t.update_type,t.eventType,t.event,t.type)?.toLowerCase().replace(/[-./ ]+/g,"_");return o?["agent_message_chunk","message_chunk","assistant_message","assistant_text","text_delta"].includes(o)?"agent_message_chunk":["agent_progress_chunk","progress_chunk","progress"].includes(o)?"agent_progress_chunk":["agent_thought_chunk","thought_chunk","reasoning_chunk","reasoning"].includes(o)?"agent_thought_chunk":["tool_call","tool_use","toolcall","tool_use_start","tool_call_start"].includes(o)?"tool_call":["tool_call_update","tool_use_update","toolcall_update","tool_result","tool_call_result","tool_use_result"].includes(o)?"tool_call_update":["plan","plan_update","plan_updated","plan_changed","task_plan","task_plan_update","todo","todo_update","todo_updated","tasks"].includes(o)?"plan":["plan_removed","plan_deleted","todo_removed","todo_deleted"].includes(o)?"plan_removed":o:null}function I(t,n){const o=l(t.tool,t.toolCall,t.tool_call,t.toolUse,t.tool_use,t.data),r=s(t.toolCallId,t.tool_call_id,t.callId,t.call_id,t.itemId,t.item_id,t.id,o?.toolCallId,o?.tool_call_id,o?.id)||`${n}.${Date.now()}`,e=s(t.title,t.name,t.toolName,t.tool_name,o?.title,o?.name,o?.toolName,o?.tool_name),i=s(t.kind,t.toolKind,t.tool_kind,o?.kind,e)||"other",p=s(t.status,t.state,t.phase,o?.status,o?.state)||(t.sessionUpdate==="tool_call"?"in_progress":"completed"),_=m(t.rawInput,t.raw_input,t.input,t.arguments,t.args,t.params,o?.rawInput,o?.raw_input,o?.input,o?.arguments,o?.args,o?.params,U(t)),a=m(t.rawOutput,t.raw_output,t.output,t.result,t.error,t.aggregatedOutput,t.aggregated_output,t.resultText,o?.rawOutput,o?.raw_output,o?.output,o?.result,o?.error);t.toolCallId=r,t.kind=i;const f=A(i,e,_);f&&(t.title=f),t.status=p,_!==void 0&&(t.rawInput=_),a!==void 0&&(t.rawOutput=a),t.content===void 0&&a!==void 0&&(t.content=d(a)),t._meta={...c(t._meta)?t._meta:{},provider_normalized:n}}function A(t,n,o){const r=l(o),e=s(r?.path,r?.filePath,r?.file_path);if(e&&(t.toLowerCase().includes("read")||t.toLowerCase().includes("view")))return`Read file ${e}`;if(e&&t.toLowerCase().includes("list"))return`List files in ${e}`;if(n)return n}function U(t){const n={};for(const o of["command","query","path","filePath","file_path","url","cwd"])t[o]!==void 0&&(n[o]=t[o]);return Object.keys(n).length?n:void 0}function d(t){return typeof t=="string"?{type:"content",content:t}:(Array.isArray(t)||c(t),t)}function x(t){return typeof t=="string"?{type:"text",text:t}:c(t)&&typeof t.text=="string"?t:d(t)}function T(t){return["sessionUpdate","session_update","updateType","update_type","eventType","event","type"].some(n=>t[n]!==void 0)}function l(...t){for(const n of t)if(c(n))return n;return null}function C(...t){return t.find(Array.isArray)}function c(t){return!!(t&&typeof t=="object"&&!Array.isArray(t))}function m(...t){return t.find(n=>n!=null)}function s(...t){for(const n of t)if(typeof n=="string"&&n.trim())return n.trim()}export{u as normalizeProviderSessionUpdate,z as providerEventFromAcpSessionUpdate,F as providerStatusFromAcpSessionUpdate};
@@ -1,5 +1,5 @@
1
- import{execFileSync as E}from"node:child_process";import{randomUUID as M}from"node:crypto";import u from"node:fs";import j from"node:os";import c from"node:path";import{acaServerRequest as h}from"./aca-server-client.js";import{loadAcaConfig as G,upsertLocalProject as L}from"./aca-config.js";import{startLongPollWorker as O}from"./long-poll-worker.js";const H=25e3,g=300,W=3e4;let y=null;function vt(t){return O({run:async()=>{const e=G();if(!e.token)throw new Error("Worker 尚未配置认证令牌");const r=await h("GET",`/api/client/machine-operations/claim?machineId=${encodeURIComponent(e.machineId)}&waitMs=${H}`);if(r.item)try{const o=await B(r.item);await h("POST",`/api/client/machine-operations/${encodeURIComponent(r.item.requestId)}/complete`,{result:o})}catch(o){const n=o instanceof Error?o.message:String(o);t.warn(`machine filesystem request failed request=${r.item.requestId}: ${n}`),await h("POST",`/api/client/machine-operations/${encodeURIComponent(r.item.requestId)}/fail`,{message:n}).catch(()=>{})}},onError:(e,r)=>t.warn(`machine filesystem worker failed, retry in ${r}ms: ${e instanceof Error?e.message:String(e)}`)})}async function B(t){if(t.operation==="filesystem_roots")return et();if(t.operation==="list_directory")return rt({directoryPath:String(t.payload.path||""),includeHidden:t.payload.includeHidden===!0});if(t.operation==="register_project")return ct(t.payload);if(t.operation==="list_project_directory")return U(t.payload);if(t.operation==="get_project_git_status")return z(t.payload);if(t.operation==="get_project_git_diff")return K(t.payload);if(t.operation==="get_project_git_log")return J(t.payload);if(t.operation==="get_project_git_commit")return V(t.payload);throw new Error("不支持的 Machine 文件系统操作。 ")}function U(t){const e=w(String(t.rootPath||"")),r=_(String(t.relativePath||"")),o=ut(e,r,!0),n=Math.max(0,Number(t.offset||0)),s=Math.min(300,Math.max(20,Number(t.limit||200))),i=u.readdirSync(o,{withFileTypes:!0}).filter(l=>!l.isSymbolicLink()).map(l=>({name:l.name,path:dt(e,c.join(o,l.name)),type:l.isDirectory()?"directory":l.isFile()?"file":"other",hidden:l.name.startsWith("."),extension:l.isFile()?c.extname(l.name).slice(1).toLowerCase():""})).filter(l=>l.type!=="other").sort((l,p)=>l.type!==p.type?l.type==="directory"?-1:1:l.name.localeCompare(p.name,void 0,{numeric:!0,sensitivity:"base"})),a=i.slice(n,n+s);return{path:r,rootKind:t.rootKind==="worktree"?"worktree":"project",items:a,total:i.length,nextOffset:n+a.length<i.length?n+a.length:null}}const A=500,S=2*1024*1024,f=2*1024*1024;function z(t){const e=w(String(t.rootPath||""));if(!b(e))return{isRepository:!1,branch:null,files:[],ahead:0,behind:0};const o=d(e,["status","--porcelain=v1","-z","--untracked-files=all","--no-renames"],S).split("\0").filter(Boolean).slice(0,A),n=o.map(a=>Y(a)).filter(a=>!!a),s=x(d(e,["diff","--no-ext-diff","--numstat","-z","--no-renames","HEAD","--","."],S));for(const a of n){const l=s.get(a.path);if(l)a.additions=l.additions,a.deletions=l.deletions;else if(a.status==="untracked"){const p=$(e,a.path);a.additions=p.additions,a.deletions=p.deletions}}const i=tt(e);return{isRepository:!0,branch:q(e),files:n,ahead:i.ahead,behind:i.behind,truncated:o.length>=A}}function K(t){const e=w(String(t.rootPath||"")),r=_(String(t.relativePath||""));if(!r)throw new Error("Diff 文件路径不能为空。");if(!b(e))return{isRepository:!1,path:r,diff:"",additions:0,deletions:0};const o=R(e,r),n=Q(e,r),s=n?d(e,["diff","--no-ext-diff","--unified=80","HEAD","--",r],f):N(e,["diff","--no-ext-diff","--no-index","--unified=80",process.platform==="win32"?"NUL":"/dev/null",o],f),i=n?x(d(e,["diff","--no-ext-diff","--numstat","-z","--no-renames","HEAD","--",r],32*1024)).get(r):$(e,r);return{isRepository:!0,path:r,diff:T(s),additions:i?.additions??0,deletions:i?.deletions??0,truncated:s.length>f}}function J(t){const e=w(String(t.rootPath||""));if(!b(e))return{isRepository:!1,items:[]};if(!Z(e))return{isRepository:!0,items:[]};const r=Math.min(200,Math.max(20,Number(t.limit||100)));return{isRepository:!0,items:d(e,["log",`--max-count=${r}`,"--date=iso-strict","--pretty=format:%H%x1f%h%x1f%an%x1f%ae%x1f%aI%x1f%D%x1f%s%x1f%b%x1e"],S).split("").map(i=>X(i)).filter(i=>!!i),limit:r}}function V(t){const e=w(String(t.rootPath||"")),r=String(t.commit||"").trim();if(!/^[0-9a-f]{7,64}$/i.test(r))throw new Error("Git 提交标识无效。");if(!b(e))return{isRepository:!1,commit:r,diff:"",additions:0,deletions:0};d(e,["cat-file","-e",`${r}^{commit}`],8*1024);const o=d(e,["show","--no-ext-diff","--no-color","--format=","--stat","--patch","--unified=40",r],f),n=[...x(d(e,["show","--no-ext-diff","--numstat","-z","--no-renames","--format=",r],S)).values()];return{isRepository:!0,commit:r,diff:T(o),additions:n.reduce((s,i)=>s+(i.additions||0),0),deletions:n.reduce((s,i)=>s+(i.deletions||0),0),changedFiles:n.length,truncated:o.length>f}}function X(t){const e=t.replace(/^\s+|\s+$/g,"");if(!e)return null;const r=e.split(""),o=String(r[0]||"").trim();return o?{hash:o,shortHash:String(r[1]||o.slice(0,8)).trim(),authorName:String(r[2]||"").trim(),authorEmail:String(r[3]||"").trim(),authoredAt:String(r[4]||"").trim(),refs:String(r[5]||"").trim(),subject:String(r[6]||"").trim(),body:r.slice(7).join("").trim()}:null}function Y(t){if(t.length<4)return null;const e=t[0]||" ",r=t[1]||" ",o=_(t.slice(3));return o?{path:o,status:e==="?"&&r==="?"?"untracked":e==="U"||r==="U"?"conflicted":e==="D"||r==="D"?"deleted":e==="A"||r==="A"?"added":e==="R"||r==="R"?"renamed":"modified",indexStatus:e,worktreeStatus:r,staged:e!==" "&&e!=="?",additions:null,deletions:null}:null}function x(t){const e=new Map;for(const r of t.split("\0")){if(!r)continue;const o=D(r);if(!o||!o.path)continue;const n=_(o.path);n&&e.set(n,{additions:o.additions,deletions:o.deletions})}return e}function $(t,e){const r=R(t,e),n=N(t,["diff","--no-ext-diff","--no-index","--numstat","-z","--",process.platform==="win32"?"NUL":"/dev/null",r],32*1024).split("\0",1)[0]||"",s=D(n);return s?{additions:s.additions,deletions:s.deletions}:{additions:null,deletions:null}}function D(t){const e=t.indexOf(" "),r=e<0?-1:t.indexOf(" ",e+1);if(e<0||r<0)return null;const o=t.slice(0,e),n=t.slice(e+1,r);return{additions:/^\d+$/.test(o)?Number(o):null,deletions:/^\d+$/.test(n)?Number(n):null,path:t.slice(r+1)}}function b(t){try{return d(t,["rev-parse","--is-inside-work-tree"],8*1024).trim()==="true"}catch(e){if(String(e.code||"")==="ENOENT")throw new Error("设备未安装 Git。");return!1}}function Q(t,e){try{return d(t,["ls-files","--error-unmatch","--",e],8*1024),!0}catch{return!1}}function Z(t){try{return d(t,["rev-parse","--verify","HEAD"],8*1024),!0}catch{return!1}}function q(t){try{return d(t,["symbolic-ref","--quiet","--short","HEAD"],8*1024).trim()||null}catch{try{return`HEAD (${d(t,["rev-parse","--short","HEAD"],8*1024).trim()})`}catch{return null}}}function tt(t){try{const e=d(t,["rev-list","--left-right","--count","HEAD...@{upstream}"],8192).trim().split(/\s+/).map(Number);return{ahead:Number.isFinite(e[0])?e[0]:0,behind:Number.isFinite(e[1])?e[1]:0}}catch{return{ahead:0,behind:0}}}function R(t,e){const r=c.resolve(t,...e.split("/")),o=c.relative(t,r);if(o.startsWith("..")||c.isAbsolute(o))throw new Error("Diff 路径超出项目范围。");return r}function d(t,e,r){return E("git",["-C",t,...e],{encoding:"utf8",timeout:2e4,maxBuffer:r,stdio:["ignore","pipe","pipe"]})}function N(t,e,r){try{return d(t,e,r)}catch(o){const n=String(o.stdout||"");if(n)return n;if(Number(o.status)===1)return"";throw o}}function T(t){return t.length<=f?t:`${t.slice(0,f)}
1
+ import{execFileSync as h}from"node:child_process";import{randomUUID as L}from"node:crypto";import l from"node:fs";import k from"node:os";import c from"node:path";import{acaServerRequest as y}from"./aca-server-client.js";import{loadAcaConfig as O,upsertLocalProject as W}from"./aca-config.js";import{startLongPollWorker as B}from"./long-poll-worker.js";const U=25e3,S=300,z=3e4;let b=null;function $t(t){return B({run:async()=>{const e=O();if(!e.token)throw new Error("Worker 尚未配置认证令牌");const r=await y("GET",`/api/client/machine-operations/claim?machineId=${encodeURIComponent(e.machineId)}&waitMs=${U}`);if(r.item)try{const o=await K(r.item);await y("POST",`/api/client/machine-operations/${encodeURIComponent(r.item.requestId)}/complete`,{result:o})}catch(o){const i=o instanceof Error?o.message:String(o);t.warn(`machine filesystem request failed request=${r.item.requestId}: ${i}`),await y("POST",`/api/client/machine-operations/${encodeURIComponent(r.item.requestId)}/fail`,{message:i}).catch(()=>{})}},onError:(e,r)=>t.warn(`machine filesystem worker failed, retry in ${r}ms: ${e instanceof Error?e.message:String(e)}`)})}async function K(t){if(t.operation==="filesystem_roots")return at();if(t.operation==="list_directory")return ct({directoryPath:String(t.payload.path||""),includeHidden:t.payload.includeHidden===!0});if(t.operation==="register_project")return pt(t.payload);if(t.operation==="list_project_directory")return X(t.payload);if(t.operation==="get_project_git_status")return $(t.payload);if(t.operation==="get_project_git_diff")return Y(t.payload);if(t.operation==="get_project_git_log")return Q(t.payload);if(t.operation==="get_project_git_commit")return Z(t.payload);if(t.operation==="get_worktree_status")return P(t.payload);if(t.operation==="commit_worktree")return J(t.payload);if(t.operation==="cleanup_worktree")return V(t.payload);throw new Error("不支持的 Machine 文件系统操作。 ")}function P(t){const e=j(String(t.worktreePath||""));if(!l.existsSync(e))return{exists:!1,isRepository:!1,dirty:!1,changedFiles:0,ahead:0};const r=m(e);if(!p(r))return{exists:!0,isRepository:!1,dirty:rt(r),changedFiles:null,ahead:0};const o=$({rootPath:r}),i=String(t.baseCommit||"").trim(),s=i&&/^[0-9a-f]{7,64}$/i.test(i)?et(r,i):0;return{exists:!0,isRepository:!0,dirty:Array.isArray(o.files)&&o.files.length>0,changedFiles:Array.isArray(o.files)?o.files.length:0,branch:o.branch,ahead:s,files:Array.isArray(o.files)?o.files.slice(0,50):[],truncated:o.truncated===!0}}function J(t){const e=m(String(t.worktreePath||"")),r=String(t.message||"").trim();if(!r)throw new Error("提交说明不能为空。");if(!p(e))throw new Error("当前 Worktree 不是 Git 仓库,无法提交。");h("git",["-C",e,"add","-A"],{stdio:"pipe",timeout:3e4});try{return h("git",["-C",e,"diff","--cached","--quiet"],{stdio:"pipe",timeout:1e4}),{committed:!1,reason:"no_changes",...P(t)}}catch(o){if(Number(o.status)!==1)throw o}return h("git",["-C",e,"commit","-m",r],{stdio:"pipe",timeout:6e4}),{committed:!0,commit:f(e,["rev-parse","HEAD"],8*1024).trim(),...P(t)}}function V(t){const e=j(String(t.worktreePath||"")),r=m(String(t.projectRoot||""));if(d(e)===d(r))throw new Error("不能清理项目主目录。");if(!l.existsSync(e))return{removed:!1,reason:"not_found"};const o=m(e),i=String(t.branchName||"").trim(),s=p(o)&&p(r);if(s){if(h("git",["-C",r,"worktree","remove","--force",o],{stdio:"pipe",timeout:6e4}),t.deleteBranch===!0&&i)try{h("git",["-C",r,"branch","-D",i],{stdio:"pipe",timeout:3e4})}catch(n){const a=String(n.stderr||n);if(!/not found|not exist/i.test(a))throw n}}else l.rmSync(o,{recursive:!0,force:!0,maxRetries:2,retryDelay:200});return{removed:!0,branchDeleted:!!(s&&t.deleteBranch===!0&&i)}}function X(t){const e=m(String(t.rootPath||"")),r=x(String(t.relativePath||"")),o=wt(e,r,!0),i=Math.max(0,Number(t.offset||0)),s=Math.min(300,Math.max(20,Number(t.limit||200))),n=l.readdirSync(o,{withFileTypes:!0}).filter(u=>!u.isSymbolicLink()).map(u=>({name:u.name,path:gt(e,c.join(o,u.name)),type:u.isDirectory()?"directory":u.isFile()?"file":"other",hidden:u.name.startsWith("."),extension:u.isFile()?c.extname(u.name).slice(1).toLowerCase():""})).filter(u=>u.type!=="other").sort((u,g)=>u.type!==g.type?u.type==="directory"?-1:1:u.name.localeCompare(g.name,void 0,{numeric:!0,sensitivity:"base"})),a=n.slice(i,i+s);return{path:r,rootKind:t.rootKind==="worktree"?"worktree":"project",items:a,total:n.length,nextOffset:i+a.length<n.length?i+a.length:null}}const D=500,_=2*1024*1024,w=2*1024*1024;function $(t){const e=m(String(t.rootPath||""));if(!p(e))return{isRepository:!1,branch:null,files:[],ahead:0,behind:0};const o=f(e,["status","--porcelain=v1","-z","--untracked-files=all","--no-renames"],_).split("\0").filter(Boolean).slice(0,D),i=o.map(a=>tt(a)).filter(a=>!!a),s=v(f(e,["diff","--no-ext-diff","--numstat","-z","--no-renames","HEAD","--","."],_));for(const a of i){const u=s.get(a.path);if(u)a.additions=u.additions,a.deletions=u.deletions;else if(a.status==="untracked"){const g=R(e,a.path);a.additions=g.additions,a.deletions=g.deletions}}const n=st(e);return{isRepository:!0,branch:nt(e),files:i,ahead:n.ahead,behind:n.behind,truncated:o.length>=D}}function Y(t){const e=m(String(t.rootPath||"")),r=x(String(t.relativePath||""));if(!r)throw new Error("Diff 文件路径不能为空。");if(!p(e))return{isRepository:!1,path:r,diff:"",additions:0,deletions:0};const o=N(e,r),i=ot(e,r),s=i?f(e,["diff","--no-ext-diff","--unified=80","HEAD","--",r],w):T(e,["diff","--no-ext-diff","--no-index","--unified=80",process.platform==="win32"?"NUL":"/dev/null",o],w),n=i?v(f(e,["diff","--no-ext-diff","--numstat","-z","--no-renames","HEAD","--",r],32*1024)).get(r):R(e,r);return{isRepository:!0,path:r,diff:I(s),additions:n?.additions??0,deletions:n?.deletions??0,truncated:s.length>w}}function Q(t){const e=m(String(t.rootPath||""));if(!p(e))return{isRepository:!1,items:[]};if(!it(e))return{isRepository:!0,items:[]};const r=Math.min(200,Math.max(20,Number(t.limit||100)));return{isRepository:!0,items:f(e,["log",`--max-count=${r}`,"--date=iso-strict","--pretty=format:%H%x1f%h%x1f%an%x1f%ae%x1f%aI%x1f%D%x1f%s%x1f%b%x1e"],_).split("").map(n=>q(n)).filter(n=>!!n),limit:r}}function Z(t){const e=m(String(t.rootPath||"")),r=String(t.commit||"").trim();if(!/^[0-9a-f]{7,64}$/i.test(r))throw new Error("Git 提交标识无效。");if(!p(e))return{isRepository:!1,commit:r,diff:"",additions:0,deletions:0};f(e,["cat-file","-e",`${r}^{commit}`],8*1024);const o=f(e,["show","--no-ext-diff","--no-color","--format=","--stat","--patch","--unified=40",r],w),i=[...v(f(e,["show","--no-ext-diff","--numstat","-z","--no-renames","--format=",r],_)).values()];return{isRepository:!0,commit:r,diff:I(o),additions:i.reduce((s,n)=>s+(n.additions||0),0),deletions:i.reduce((s,n)=>s+(n.deletions||0),0),changedFiles:i.length,truncated:o.length>w}}function q(t){const e=t.replace(/^\s+|\s+$/g,"");if(!e)return null;const r=e.split(""),o=String(r[0]||"").trim();return o?{hash:o,shortHash:String(r[1]||o.slice(0,8)).trim(),authorName:String(r[2]||"").trim(),authorEmail:String(r[3]||"").trim(),authoredAt:String(r[4]||"").trim(),refs:String(r[5]||"").trim(),subject:String(r[6]||"").trim(),body:r.slice(7).join("").trim()}:null}function tt(t){if(t.length<4)return null;const e=t[0]||" ",r=t[1]||" ",o=x(t.slice(3));return o?{path:o,status:e==="?"&&r==="?"?"untracked":e==="U"||r==="U"?"conflicted":e==="D"||r==="D"?"deleted":e==="A"||r==="A"?"added":e==="R"||r==="R"?"renamed":"modified",indexStatus:e,worktreeStatus:r,staged:e!==" "&&e!=="?",additions:null,deletions:null}:null}function v(t){const e=new Map;for(const r of t.split("\0")){if(!r)continue;const o=C(r);if(!o||!o.path)continue;const i=x(o.path);i&&e.set(i,{additions:o.additions,deletions:o.deletions})}return e}function R(t,e){const r=N(t,e),i=T(t,["diff","--no-ext-diff","--no-index","--numstat","-z","--",process.platform==="win32"?"NUL":"/dev/null",r],32*1024).split("\0",1)[0]||"",s=C(i);return s?{additions:s.additions,deletions:s.deletions}:{additions:null,deletions:null}}function C(t){const e=t.indexOf(" "),r=e<0?-1:t.indexOf(" ",e+1);if(e<0||r<0)return null;const o=t.slice(0,e),i=t.slice(e+1,r);return{additions:/^\d+$/.test(o)?Number(o):null,deletions:/^\d+$/.test(i)?Number(i):null,path:t.slice(r+1)}}function p(t){try{return f(t,["rev-parse","--is-inside-work-tree"],8*1024).trim()==="true"}catch(e){if(String(e.code||"")==="ENOENT")throw new Error("设备未安装 Git。");return!1}}function et(t,e){try{const r=f(t,["rev-list","--count",`${e}..HEAD`],8192).trim(),o=Number(r);return Number.isSafeInteger(o)&&o>0?o:0}catch{return 0}}function rt(t){try{return l.readdirSync(t).length>0}catch{return!1}}function ot(t,e){try{return f(t,["ls-files","--error-unmatch","--",e],8*1024),!0}catch{return!1}}function it(t){try{return f(t,["rev-parse","--verify","HEAD"],8*1024),!0}catch{return!1}}function nt(t){try{return f(t,["symbolic-ref","--quiet","--short","HEAD"],8*1024).trim()||null}catch{try{return`HEAD (${f(t,["rev-parse","--short","HEAD"],8*1024).trim()})`}catch{return null}}}function st(t){try{const e=f(t,["rev-list","--left-right","--count","HEAD...@{upstream}"],8192).trim().split(/\s+/).map(Number);return{ahead:Number.isFinite(e[0])?e[0]:0,behind:Number.isFinite(e[1])?e[1]:0}}catch{return{ahead:0,behind:0}}}function N(t,e){const r=c.resolve(t,...e.split("/")),o=c.relative(t,r);if(o.startsWith("..")||c.isAbsolute(o))throw new Error("Diff 路径超出项目范围。");return r}function f(t,e,r){return h("git",["-C",t,...e],{encoding:"utf8",timeout:2e4,maxBuffer:r,stdio:["ignore","pipe","pipe"]})}function T(t,e,r){try{return f(t,e,r)}catch(o){const i=String(o.stdout||"");if(i)return i;if(Number(o.status)===1)return"";throw o}}function I(t){return t.length<=w?t:`${t.slice(0,w)}
2
2
 
3
- [Diff 内容过大,已截断]`}function et(){const t=process.platform,e=P(t);return{platform:t,roots:e}}function rt(t){if(!t.directoryPath.trim())throw new Error("目录路径不能为空。");return process.platform==="win32"?st(t.directoryPath,!!t.includeHidden):it(t.directoryPath,!!t.includeHidden)}function m(t,e=process.platform){const r=e==="win32"?c.win32:c.posix,o=r.normalize(t),n=r.parse(o).root,s=o.length>n.length?o.replace(/[\\/]+$/,""):o;return e==="win32"?s.toLocaleLowerCase("en-US"):s}function ot(){const t=u.realpathSync(j.homedir()),e=[{id:"home",label:"用户目录",path:t,kind:"home",available:!0}];return t!==c.parse(t).root&&e.push({id:"root",label:"文件系统",path:"/",kind:"root",available:!0}),e}function P(t){if(y?.platform===t&&y.expiresAtMs>Date.now())return y.roots;const e=t==="win32"?nt():ot();return y={platform:t,roots:e,expiresAtMs:Date.now()+W},e}function nt(){const t=u.realpathSync.native(j.homedir()),e=new Map;e.set(m(t,"win32"),{id:"home",label:"用户目录",path:t,kind:"home",available:!0});try{const r=["$items = Get-CimInstance Win32_LogicalDisk | ForEach-Object {"," [PSCustomObject]@{ Name = $_.DeviceID; Root = ($_.DeviceID + '\\\\'); DriveType = $_.DriveType; VolumeName = $_.VolumeName }","}","@($items) | ConvertTo-Json -Compress"].join(`
4
- `),o=F(k(r));for(const n of o){const s=String(n.Root||"");if(!s)continue;const i=Number(n.DriveType||0),a=String(n.Name||s.replace(/[\\/]+$/,"")),l=String(n.VolumeName||"").trim();e.set(m(s,"win32"),{id:`drive-${a.replace(/[^a-z0-9]+/gi,"").toLowerCase()}`,label:l?`${l} (${a})`:ht(a,i),path:s,kind:pt(i),available:!0})}}catch{const r=c.win32.parse(t).root;e.set(m(r,"win32"),{id:"drive-system",label:`系统盘 (${r.replace(/\\$/,"")})`,path:r,kind:"fixed",available:!0})}return[...e.values()]}function it(t,e){const r=v(t),n=u.readdirSync(r,{withFileTypes:!0}).filter(i=>i.isDirectory()&&!i.isSymbolicLink()&&(e||!i.name.startsWith("."))),s=n.slice(0,g).map(i=>({name:i.name,path:c.join(r,i.name),kind:"directory",hidden:i.name.startsWith("."),hasChildren:!0}));return s.sort((i,a)=>i.name.localeCompare(a.name,void 0,{numeric:!0,sensitivity:"base"})),C(r,s,n.length>g,"linux")}function st(t,e){const r=v(t),o=["$items = Get-ChildItem -LiteralPath $env:ACA_MACHINE_FS_PATH -Directory -Force -ErrorAction Stop | ForEach-Object {"," [PSCustomObject]@{ Name = $_.Name; FullName = $_.FullName; Attributes = $_.Attributes.ToString() }","}","@($items) | ConvertTo-Json -Compress"].join(`
5
- `),n=F(k(o,{ACA_MACHINE_FS_PATH:r})),s=n.map(i=>{const a=String(i.Attributes||"");return{name:String(i.Name||""),path:String(i.FullName||""),kind:"directory",hidden:/Hidden|System/i.test(a),hasChildren:!0,reparsePoint:/ReparsePoint/i.test(a)}}).filter(i=>i.name&&i.path&&!i.reparsePoint&&(e||!i.hidden)).slice(0,g).sort((i,a)=>i.name.localeCompare(a.name,void 0,{numeric:!0,sensitivity:"base"}));return C(r,s,n.length>g,"win32")}function C(t,e,r,o){const n=o==="win32"?c.win32:c.posix,s=n.parse(t).root,i=m(t,o)===m(s,o)?null:n.dirname(t);return{platform:o,path:t,parentPath:i,breadcrumbs:at(t,o),readable:I(t,u.constants.R_OK),writable:I(t,u.constants.W_OK),items:e,truncated:r}}function at(t,e){const r=e==="win32"?c.win32:c.posix,o=r.parse(t),n=t.slice(o.root.length).split(/[\\/]+/).filter(Boolean),s=[{label:o.root.replace(/[\\/]+$/,"")||o.root,path:o.root}];let i=o.root;for(const a of n)i=r.join(i,a),s.push({label:a,path:i});return s}async function ct(t){const e=String(t.workspaceId||"").trim(),r=String(t.name||"").trim(),o=t.projectType==="chat_room"?"chat_room":"project";if(!e||!r)throw new Error("项目名称和工作区不能为空。");const n=v(String(t.path||""));u.accessSync(n,u.constants.R_OK|u.constants.W_OK);const i=(await h("GET",`/api/projects?workspaceId=${encodeURIComponent(e)}`)).items.find(l=>m(l.root_path)===m(n)),a=i||(await h("POST","/api/projects",{projectId:M(),workspaceId:e,name:r,rootPath:n,source:"aica",projectType:o})).item;return L(lt(a)),{project:a,duplicate:!!i}}function lt(t){return{projectId:t.project_id,workspaceId:t.workspace_id,name:t.name,rootPath:t.root_path}}function v(t){if(!t.trim()||!c.isAbsolute(t))throw new Error("必须选择绝对目录路径。");if(ft(t),!u.statSync(t).isDirectory())throw new Error("选择的路径不是目录。");const r=u.realpathSync.native(t);return mt(r),r}function w(t){if(!t.trim()||!c.isAbsolute(t))throw new Error("项目根目录无效。");const e=u.realpathSync.native(t);if(!u.statSync(e).isDirectory())throw new Error("项目根目录不存在。");return e}function _(t){const e=t.replace(/\\/g,"/").replace(/^\/+|\/+$/g,"");if(!e)return"";if(e.includes("\0")||e.split("/").some(r=>!r||r==="."||r===".."))throw new Error("项目相对路径无效。");return e}function ut(t,e,r){const o=e?c.join(t,...e.split("/")):t,n=u.realpathSync.native(o),s=c.relative(t,n);if(s.startsWith("..")||c.isAbsolute(s))throw new Error("目录超出项目范围。");const i=u.statSync(n);if(r&&!i.isDirectory())throw new Error("请求路径不是目录。");return n}function dt(t,e){return c.relative(t,e).split(c.sep).join("/")}function ft(t){const e=process.platform==="win32"?c.win32:c.posix;if(!P(process.platform).some(o=>{const n=String(o.path||"");if(!n)return!1;const s=e.relative(n,t);return s===""||!s.startsWith("..")&&!e.isAbsolute(s)}))throw new Error("目录不在允许浏览的位置内。")}function mt(t){const e=process.platform==="win32"?c.win32:c.posix;if(!P(process.platform).some(o=>{const n=String(o.path||"");if(!n)return!1;const s=e.relative(n,t);return s===""||!s.startsWith("..")&&!e.isAbsolute(s)}))throw new Error("目录不在允许浏览的位置内。")}function I(t,e){try{return u.accessSync(t,e),!0}catch{return!1}}function k(t,e={}){return E("powershell.exe",["-NoLogo","-NoProfile","-NonInteractive","-Command",t],{encoding:"utf8",windowsHide:!0,timeout:8e3,maxBuffer:4*1024*1024,env:{...process.env,...e}}).replace(/^\uFEFF/,"").trim()}function F(t){if(!t)return[];const e=JSON.parse(t);return Array.isArray(e)?e.filter(r=>!!(r&&typeof r=="object")):e&&typeof e=="object"?[e]:[]}function pt(t){return t===2?"removable":t===3?"fixed":t===4?"network":t===5?"optical":"drive"}function ht(t,e){return e===2?`移动磁盘 (${t})`:e===4?`网络驱动器 (${t})`:e===5?`光驱 (${t})`:`本地磁盘 (${t})`}export{m as comparableMachinePath,V as getProjectGitCommit,K as getProjectGitDiff,J as getProjectGitLog,z as getProjectGitStatus,rt as listMachineDirectory,et as listMachineFilesystemRoots,U as listProjectDirectory,vt as startMachineFilesystemWorkerLoop};
3
+ [Diff 内容过大,已截断]`}function at(){const t=process.platform,e=A(t);return{platform:t,roots:e}}function ct(t){if(!t.directoryPath.trim())throw new Error("目录路径不能为空。");return process.platform==="win32"?dt(t.directoryPath,!!t.includeHidden):ft(t.directoryPath,!!t.includeHidden)}function d(t,e=process.platform){const r=e==="win32"?c.win32:c.posix,o=r.normalize(t),i=r.parse(o).root,s=o.length>i.length?o.replace(/[\\/]+$/,""):o;return e==="win32"?s.toLocaleLowerCase("en-US"):s}function ut(){const t=l.realpathSync(k.homedir()),e=[{id:"home",label:"用户目录",path:t,kind:"home",available:!0}];return t!==c.parse(t).root&&e.push({id:"root",label:"文件系统",path:"/",kind:"root",available:!0}),e}function A(t){if(b?.platform===t&&b.expiresAtMs>Date.now())return b.roots;const e=t==="win32"?lt():ut();return b={platform:t,roots:e,expiresAtMs:Date.now()+z},e}function lt(){const t=l.realpathSync.native(k.homedir()),e=new Map;e.set(d(t,"win32"),{id:"home",label:"用户目录",path:t,kind:"home",available:!0});try{const r=["$items = Get-CimInstance Win32_LogicalDisk | ForEach-Object {"," [PSCustomObject]@{ Name = $_.DeviceID; Root = ($_.DeviceID + '\\\\'); DriveType = $_.DriveType; VolumeName = $_.VolumeName }","}","@($items) | ConvertTo-Json -Compress"].join(`
4
+ `),o=H(M(r));for(const i of o){const s=String(i.Root||"");if(!s)continue;const n=Number(i.DriveType||0),a=String(i.Name||s.replace(/[\\/]+$/,"")),u=String(i.VolumeName||"").trim();e.set(d(s,"win32"),{id:`drive-${a.replace(/[^a-z0-9]+/gi,"").toLowerCase()}`,label:u?`${u} (${a})`:_t(a,n),path:s,kind:bt(n),available:!0})}}catch{const r=c.win32.parse(t).root;e.set(d(r,"win32"),{id:"drive-system",label:`系统盘 (${r.replace(/\\$/,"")})`,path:r,kind:"fixed",available:!0})}return[...e.values()]}function ft(t,e){const r=E(t),i=l.readdirSync(r,{withFileTypes:!0}).filter(n=>n.isDirectory()&&!n.isSymbolicLink()&&(e||!n.name.startsWith("."))),s=i.slice(0,S).map(n=>({name:n.name,path:c.join(r,n.name),kind:"directory",hidden:n.name.startsWith("."),hasChildren:!0}));return s.sort((n,a)=>n.name.localeCompare(a.name,void 0,{numeric:!0,sensitivity:"base"})),F(r,s,i.length>S,"linux")}function dt(t,e){const r=E(t),o=["$items = Get-ChildItem -LiteralPath $env:ACA_MACHINE_FS_PATH -Directory -Force -ErrorAction Stop | ForEach-Object {"," [PSCustomObject]@{ Name = $_.Name; FullName = $_.FullName; Attributes = $_.Attributes.ToString() }","}","@($items) | ConvertTo-Json -Compress"].join(`
5
+ `),i=H(M(o,{ACA_MACHINE_FS_PATH:r})),s=i.map(n=>{const a=String(n.Attributes||"");return{name:String(n.Name||""),path:String(n.FullName||""),kind:"directory",hidden:/Hidden|System/i.test(a),hasChildren:!0,reparsePoint:/ReparsePoint/i.test(a)}}).filter(n=>n.name&&n.path&&!n.reparsePoint&&(e||!n.hidden)).slice(0,S).sort((n,a)=>n.name.localeCompare(a.name,void 0,{numeric:!0,sensitivity:"base"}));return F(r,s,i.length>S,"win32")}function F(t,e,r,o){const i=o==="win32"?c.win32:c.posix,s=i.parse(t).root,n=d(t,o)===d(s,o)?null:i.dirname(t);return{platform:o,path:t,parentPath:n,breadcrumbs:mt(t,o),readable:G(t,l.constants.R_OK),writable:G(t,l.constants.W_OK),items:e,truncated:r}}function mt(t,e){const r=e==="win32"?c.win32:c.posix,o=r.parse(t),i=t.slice(o.root.length).split(/[\\/]+/).filter(Boolean),s=[{label:o.root.replace(/[\\/]+$/,"")||o.root,path:o.root}];let n=o.root;for(const a of i)n=r.join(n,a),s.push({label:a,path:n});return s}async function pt(t){const e=String(t.workspaceId||"").trim(),r=String(t.name||"").trim(),o=t.projectType==="chat_room"?"chat_room":"project";if(!e||!r)throw new Error("项目名称和工作区不能为空。");const i=E(String(t.path||""));l.accessSync(i,l.constants.R_OK|l.constants.W_OK);const n=(await y("GET",`/api/projects?workspaceId=${encodeURIComponent(e)}`)).items.find(u=>d(u.root_path)===d(i)),a=n||(await y("POST","/api/projects",{projectId:L(),workspaceId:e,name:r,rootPath:i,source:"aica",projectType:o})).item;return W(ht(a)),{project:a,duplicate:!!n}}function ht(t){return{projectId:t.project_id,workspaceId:t.workspace_id,name:t.name,rootPath:t.root_path}}function E(t){if(!t.trim()||!c.isAbsolute(t))throw new Error("必须选择绝对目录路径。");if(yt(t),!l.statSync(t).isDirectory())throw new Error("选择的路径不是目录。");const r=l.realpathSync.native(t);return St(r),r}function m(t){const e=j(t),r=l.realpathSync.native(e);if(!l.statSync(r).isDirectory())throw new Error("项目根目录不存在。");return r}function j(t){if(!t.trim()||!c.isAbsolute(t))throw new Error("项目根目录无效。");return c.resolve(t)}function x(t){const e=t.replace(/\\/g,"/").replace(/^\/+|\/+$/g,"");if(!e)return"";if(e.includes("\0")||e.split("/").some(r=>!r||r==="."||r===".."))throw new Error("项目相对路径无效。");return e}function wt(t,e,r){const o=e?c.join(t,...e.split("/")):t,i=l.realpathSync.native(o),s=c.relative(t,i);if(s.startsWith("..")||c.isAbsolute(s))throw new Error("目录超出项目范围。");const n=l.statSync(i);if(r&&!n.isDirectory())throw new Error("请求路径不是目录。");return i}function gt(t,e){return c.relative(t,e).split(c.sep).join("/")}function yt(t){const e=process.platform==="win32"?c.win32:c.posix;if(!A(process.platform).some(o=>{const i=String(o.path||"");if(!i)return!1;const s=e.relative(i,t);return s===""||!s.startsWith("..")&&!e.isAbsolute(s)}))throw new Error("目录不在允许浏览的位置内。")}function St(t){const e=process.platform==="win32"?c.win32:c.posix;if(!A(process.platform).some(o=>{const i=String(o.path||"");if(!i)return!1;const s=e.relative(i,t);return s===""||!s.startsWith("..")&&!e.isAbsolute(s)}))throw new Error("目录不在允许浏览的位置内。")}function G(t,e){try{return l.accessSync(t,e),!0}catch{return!1}}function M(t,e={}){return h("powershell.exe",["-NoLogo","-NoProfile","-NonInteractive","-Command",t],{encoding:"utf8",windowsHide:!0,timeout:8e3,maxBuffer:4*1024*1024,env:{...process.env,...e}}).replace(/^\uFEFF/,"").trim()}function H(t){if(!t)return[];const e=JSON.parse(t);return Array.isArray(e)?e.filter(r=>!!(r&&typeof r=="object")):e&&typeof e=="object"?[e]:[]}function bt(t){return t===2?"removable":t===3?"fixed":t===4?"network":t===5?"optical":"drive"}function _t(t,e){return e===2?`移动磁盘 (${t})`:e===4?`网络驱动器 (${t})`:e===5?`光驱 (${t})`:`本地磁盘 (${t})`}export{V as cleanupWorktree,J as commitWorktree,d as comparableMachinePath,Z as getProjectGitCommit,Y as getProjectGitDiff,Q as getProjectGitLog,$ as getProjectGitStatus,P as getWorktreeStatus,ct as listMachineDirectory,at as listMachineFilesystemRoots,X as listProjectDirectory,$t as startMachineFilesystemWorkerLoop};
@@ -1 +1 @@
1
- import{execFileSync as d}from"node:child_process";import w from"node:crypto";import a from"node:fs";import c from"node:path";import{getAcaHome as f}from"./paths.js";function S(e){const t=e.worktree.worktree_id;if(!t)return{cwd:e.projectRoot,usedWorktree:!1};const s=e.worktree.worktree_path?c.resolve(e.worktree.worktree_path):null;if(e.worktree.worktree_status==="active"&&s&&a.existsSync(s))return{cwd:s,usedWorktree:!0,worktreeId:t,status:"active",baseCommit:e.worktree.worktree_base_commit??null,branchName:e.worktree.worktree_branch_name??null,baseBranch:e.worktree.worktree_base_branch??null};const r=c.resolve(e.projectRoot),l=k(e.projectId??"project"),m=k(e.sessionId),o=c.join(f(),"worktrees",l,m),n=e.worktree.worktree_base_branch||"HEAD",i=e.worktree.worktree_branch_name||`aca/session-${m}`,u=h(r);return a.mkdirSync(c.dirname(o),{recursive:!0}),a.existsSync(o)?{cwd:o,usedWorktree:!0,worktreeId:t,status:"active",baseCommit:u,branchName:i,baseBranch:n,raw:{source:"aca-client",reusedExistingPath:!0,projectRoot:r}}:u?(d("git",["worktree","add","-B",i,o,n],{cwd:r,stdio:"pipe"}),{cwd:o,usedWorktree:!0,worktreeId:t,status:"active",baseCommit:u,branchName:i,baseBranch:n,raw:{source:"aca-client",mode:"git-worktree",projectRoot:r}}):(a.mkdirSync(o,{recursive:!0}),b(r,o),{cwd:o,usedWorktree:!0,worktreeId:t,status:"fallback-directory",baseCommit:null,branchName:i,baseBranch:n,raw:{source:"aca-client",mode:"fallback-directory",projectRoot:r,fallbackReason:"git repository has no commits"}})}function h(e){try{return d("git",["rev-parse","HEAD"],{cwd:e,encoding:"utf8",stdio:"pipe"}).trim()||null}catch{return null}}function b(e,t){a.cpSync(e,t,{recursive:!0,filter:s=>{const r=c.relative(e,s);if(!r)return!0;const l=r.split(c.sep)[0];return![".git","node_modules","dist",".aca",".aica"].includes(l)}})}function k(e){return e.replace(/[^a-zA-Z0-9._-]+/g,"-").slice(0,80)||w.randomUUID()}export{S as prepareLocalWorktree};
1
+ import{execFileSync as m}from"node:child_process";import w from"node:crypto";import a from"node:fs";import s from"node:path";import{getAcaHome as f}from"./paths.js";function S(e){const t=e.worktree.worktree_id;if(!t||e.worktree.worktree_status==="disabled")return{cwd:e.projectRoot,usedWorktree:!1};const c=e.worktree.worktree_path?s.resolve(e.worktree.worktree_path):null;if(e.worktree.worktree_status==="active"&&c&&a.existsSync(c))return{cwd:c,usedWorktree:!0,worktreeId:t,status:"active",baseCommit:e.worktree.worktree_base_commit??null,branchName:e.worktree.worktree_branch_name??null,baseBranch:e.worktree.worktree_base_branch??null};const r=s.resolve(e.projectRoot),l=k(e.projectId??"project"),d=k(e.sessionId),o=s.join(f(),"worktrees",l,d),i=e.worktree.worktree_base_branch||"HEAD",n=e.worktree.worktree_branch_name||`aca/session-${d}`,u=b(r);return a.mkdirSync(s.dirname(o),{recursive:!0}),a.existsSync(o)?{cwd:o,usedWorktree:!0,worktreeId:t,status:"active",baseCommit:u,branchName:n,baseBranch:i,raw:{source:"aca-client",reusedExistingPath:!0,projectRoot:r}}:u?(m("git",["worktree","add","-B",n,o,i],{cwd:r,stdio:"pipe"}),{cwd:o,usedWorktree:!0,worktreeId:t,status:"active",baseCommit:u,branchName:n,baseBranch:i,raw:{source:"aca-client",mode:"git-worktree",projectRoot:r}}):(a.mkdirSync(o,{recursive:!0}),h(r,o),{cwd:o,usedWorktree:!0,worktreeId:t,status:"fallback-directory",baseCommit:null,branchName:n,baseBranch:i,raw:{source:"aca-client",mode:"fallback-directory",projectRoot:r,fallbackReason:"git repository has no commits"}})}function b(e){try{return m("git",["rev-parse","HEAD"],{cwd:e,encoding:"utf8",stdio:"pipe"}).trim()||null}catch{return null}}function h(e,t){a.cpSync(e,t,{recursive:!0,filter:c=>{const r=s.relative(e,c);if(!r)return!0;const l=r.split(s.sep)[0];return![".git","node_modules","dist",".aca",".aica"].includes(l)}})}function k(e){return e.replace(/[^a-zA-Z0-9._-]+/g,"-").slice(0,80)||w.randomUUID()}export{S as prepareLocalWorktree};
@@ -1,2 +1,2 @@
1
1
  #!/usr/bin/env node
2
- import{Command as a}from"commander";import m from"node:path";import{createStartCommand as n}from"./commands/start.js";import{createDaemonCommand as t}from"./commands/daemon.js";import{createWorkerAuthCommand as s}from"./commands/worker-auth.js";import{createWorkerCodexCommand as c}from"./commands/worker-codex.js";import{createWorkerProjectCommand as i}from"./commands/worker-project.js";import{DEFAULT_ACA_SERVER_URL as d}from"./core/aca-config.js";process.env.ACA_DEFAULT_SERVER_URL||=d;async function p(r=process.argv){const o=new a;o.name("aica").description("AICA remote Agent worker").version("0.1.13").enablePositionalOptions(),o.addCommand(n()),o.addCommand(t()),o.addCommand(s()),o.addCommand(i()),o.addCommand(c()),await o.parseAsync(r)}const C=process.argv[1]||"",e=m.basename(C).replace(/\.(?:js|ts|cjs|mjs)$/i,"");(e==="worker-cli"||e==="aica"||e==="aca")&&p().catch(r=>{const o=r instanceof Error?r.message:String(r);console.error(o),process.exitCode=1});export{p as runWorkerCli};
2
+ import{Command as a}from"commander";import m from"node:path";import{createStartCommand as n}from"./commands/start.js";import{createDaemonCommand as t}from"./commands/daemon.js";import{createWorkerAuthCommand as s}from"./commands/worker-auth.js";import{createWorkerCodexCommand as c}from"./commands/worker-codex.js";import{createWorkerProjectCommand as i}from"./commands/worker-project.js";import{DEFAULT_ACA_SERVER_URL as d}from"./core/aca-config.js";process.env.ACA_DEFAULT_SERVER_URL||=d;async function p(r=process.argv){const o=new a;o.name("aica").description("AICA remote Agent worker").version("0.1.15").enablePositionalOptions(),o.addCommand(n()),o.addCommand(t()),o.addCommand(s()),o.addCommand(i()),o.addCommand(c()),await o.parseAsync(r)}const C=process.argv[1]||"",e=m.basename(C).replace(/\.(?:js|ts|cjs|mjs)$/i,"");(e==="worker-cli"||e==="aica"||e==="aca")&&p().catch(r=>{const o=r instanceof Error?r.message:String(r);console.error(o),process.exitCode=1});export{p as runWorkerCli};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yuandc/aica",
3
- "version": "0.1.13",
3
+ "version": "0.1.15",
4
4
  "description": "AICA remote Agent worker",
5
5
  "author": "yuandc",
6
6
  "type": "module",