aws-runtime-bridge 1.9.168 → 1.9.170
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +53 -0
- package/dist/adapter/AcodeSdkAdapter.d.ts +46 -0
- package/dist/adapter/AcodeSdkAdapter.js +4 -4
- package/dist/adapter/ClaudeSdkAdapter.js +2 -2
- package/dist/adapter/types.d.ts +7 -0
- package/dist/config.d.ts +6 -0
- package/dist/config.js +2 -2
- package/dist/index.js +1 -1
- package/dist/routes/agent-state.d.ts +2 -0
- package/dist/routes/agent-state.js +2 -0
- package/dist/routes/capabilities.js +1 -1
- package/dist/routes/debug-mount.d.ts +2 -0
- package/dist/routes/debug-mount.js +2 -0
- package/dist/routes/mcp.js +1 -1
- package/dist/routes/plugins.js +1 -1
- package/dist/routes/skills.js +1 -1
- package/dist/routes/terminal.js +28 -32
- package/dist/services/acode-bg-manager.d.ts +2 -0
- package/dist/services/agent-capability-sync.js +1 -1
- package/dist/services/debug-mount.d.ts +122 -0
- package/dist/services/debug-mount.js +2 -0
- package/dist/services/desktop-mcp-manager.js +1 -1
- package/dist/services/instance-ai-config-service.js +1 -1
- package/dist/services/instance-features.d.ts +4 -0
- package/dist/services/instance-features.js +1 -1
- package/dist/services/instance-init-service.js +1 -1
- package/dist/services/mcp-deploy.d.ts +31 -0
- package/dist/services/mcp-deploy.js +4 -3
- package/dist/services/mcp-env-injector.d.ts +24 -0
- package/dist/services/mcp-env-injector.js +1 -1
- package/dist/services/mcp-package.d.ts +35 -0
- package/dist/services/mcp-package.js +2 -0
- package/dist/services/mcp-probe-client.d.ts +25 -0
- package/dist/services/mcp-probe-client.js +2 -0
- package/dist/services/panel-env.d.ts +5 -0
- package/dist/services/panel-env.js +1 -1
- package/dist/services/plugin-deployment.d.ts +36 -0
- package/dist/services/plugin-deployment.js +3 -0
- package/dist/services/plugin-event-buffer.js +2 -1
- package/dist/services/plugin-fs.d.ts +5 -0
- package/dist/services/plugin-fs.js +2 -0
- package/dist/services/plugin-handler-adapter.d.ts +7 -0
- package/dist/services/plugin-handler-adapter.js +3 -0
- package/dist/services/plugin-listener-runner.d.ts +18 -0
- package/dist/services/plugin-listener-runner.js +8 -0
- package/dist/services/plugin-loader.d.ts +32 -0
- package/dist/services/plugin-loader.js +2 -0
- package/dist/services/plugin-manager.d.ts +17 -136
- package/dist/services/plugin-manager.js +4 -15
- package/dist/services/plugin-manifest.d.ts +83 -0
- package/dist/services/plugin-manifest.js +2 -0
- package/dist/services/plugin-runtime.d.ts +67 -0
- package/dist/services/plugin-runtime.js +1 -0
- package/dist/services/skill-manager.d.ts +15 -0
- package/dist/services/skill-manager.js +3 -2
- package/dist/types.d.ts +6 -0
- package/dist/utils/mcp-utils.js +1 -1
- package/package/acode/dist/compaction.d.ts +35 -1
- package/package/acode/dist/compaction.js +6 -6
- package/package/acode/dist/plugin-types.d.ts +6 -27
- package/package/acode/dist/runtime.d.ts +37 -0
- package/package/acode/dist/runtime.js +31 -30
- package/package/acode/dist/tool-group-manager.d.ts +10 -0
- package/package/acode/dist/tool-group-manager.js +5 -10
- package/package/acode/dist/types.d.ts +2 -0
- package/package/aws-client-agent-mcp/dist/ability-market-tools.d.ts +18 -0
- package/package/aws-client-agent-mcp/dist/ability-market-tools.js +2 -0
- package/package/aws-client-agent-mcp/dist/agent-client.d.ts +15 -4
- package/package/aws-client-agent-mcp/dist/agent-client.js +1 -1
- package/package/aws-client-agent-mcp/dist/http-client.d.ts +2 -0
- package/package/aws-client-agent-mcp/dist/http-client.js +1 -1
- package/package/aws-client-agent-mcp/dist/mcp-server.d.ts +0 -7
- package/package/aws-client-agent-mcp/dist/mcp-server.js +12 -12
- package/package/aws-client-agent-mcp/dist/mcp-tools.d.ts +3 -0
- package/package/aws-client-agent-mcp/dist/mcp-tools.js +20 -20
- package/package/aws-client-agent-mcp/dist/memory-store.d.ts +1 -1
- package/package/aws-client-agent-mcp/dist/memory-store.js +2 -2
- package/package/aws-client-agent-mcp/dist/memory-tools.js +7 -7
- package/package/aws-client-agent-mcp/dist/tool-groups.js +2 -2
- package/package/aws-client-agent-mcp/dist/types.d.ts +2 -21
- package/package.json +3 -2
- package/dist/services/builtin-commands/create-plugin.md +0 -44
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{execSync as k}from"child_process";import{EventEmitter as y}from"events";import*as p from"fs";import*as c from"path";import{v4 as h}from"uuid";import{registerListenerWakeHook as v,unregisterListenerWakeHook as g}from"../services/browser-session-manager.js";import{injectEffectiveEnvIntoMcpServers as x}from"../services/mcp-env-injector.js";import{getPanelEnvVars as _}from"../services/panel-env.js";import{importBridgeSdkPackage as
|
|
1
|
+
import{execSync as k}from"child_process";import{EventEmitter as y}from"events";import*as p from"fs";import*as c from"path";import{v4 as h}from"uuid";import{registerListenerWakeHook as v,unregisterListenerWakeHook as g}from"../services/browser-session-manager.js";import{injectEffectiveEnvIntoMcpServers as x}from"../services/mcp-env-injector.js";import{getPanelEnvVars as _,getAgentMeta as w}from"../services/panel-env.js";import{importBridgeSdkPackage as C}from"../utils/sdk-package-loader.js";import{IdlePollLoop as b}from"./idle-poll-loop.js";import{MESSAGE_POLLING_IDLE_PROMPT as P}from"./prompts.js";import{getToolActionInfo as f}from"./types.js";class T{constructor(){this.queue=[],this.resolve=null,this.done=!1}enqueue(t){if(!this.done)if(this.resolve){const e=this.resolve;this.resolve=null,e({value:t,done:!1})}else this.queue.push(t)}close(){if(this.done=!0,this.resolve){const t=this.resolve;this.resolve=null,t({value:void 0,done:!0})}}[Symbol.asyncIterator](){return{next:()=>{if(this.queue.length>0){const t=this.queue.shift();if(t!==void 0)return Promise.resolve({value:t,done:!1})}return this.done?Promise.resolve({value:void 0,done:!0}):new Promise(t=>{this.resolve=t})}}}}class N extends y{constructor(){super(...arguments),this.providerId="claude-code",this.displayName="Claude Code",this.sessions=new Map,this.sdkQueries=new Map,this.inputStreams=new Map,this.abortControllers=new Map,this.sdkModule=null,this.pendingPermissions=new Map,this.pendingQuestions=new Map,this.activeToolUseIds=new Map,this.recentToolNames=new Map,this.toolInputBuffers=new Map,this.idleCommands=new Map,this.idleTimers=new Map,this.idlePollLoops=new Map,this.lastActivityAt=new Map,this.sessionAgentIds=new Map,this.listenerWakeHooks=new Map}async startSession(t,e){const i={sessionId:t,status:"starting",messages:[],createdAt:new Date().toISOString(),totalUsage:{inputTokens:0,outputTokens:0}};if(this.sessions.set(t,i),e.agentId&&this.sessionAgentIds.set(t,e.agentId),e.agentId){const o=()=>{this.getIdlePollLoop(t).start()};this.listenerWakeHooks.set(t,o),v(e.agentId,o)}try{const o=await this.loadSdk(),n=new AbortController;this.abortControllers.set(t,n);const a=new T;this.inputStreams.set(t,a);const s=this.buildQueryOptions(t,e,n),r=o.query({prompt:a,options:s});if(this.sdkQueries.set(t,r),this.consumeStream(t,r).catch(l=>{console.error(`[ClaudeSdkAdapter] Stream error for ${t}:`,l)}),await new Promise(l=>setTimeout(l,100)),e.initialPrompt){i.status="starting",this.emit("status-change",t,"starting");const l={id:h(),sessionId:t,role:"user",content:e.initialPrompt,timestamp:new Date().toISOString()};i.messages.push(l),this.emit("conversation-message",t,l);const d=this.parseMessageContent(e.initialPrompt);a.enqueue({type:"user",message:{role:"user",content:d}})}else i.status="waiting_input",this.emit("status-change",t,"waiting_input",{usage:i.totalUsage}),this.idleCommands.has(t)&&this.startIdleDetection(t)}catch(o){e.agentId&&g(e.agentId,this.listenerWakeHooks.get(t)),this.listenerWakeHooks.delete(t);const n=o instanceof Error?o.message:String(o);throw i.status="error",this.emit("status-change",t,"error"),this.emitEvent(t,{type:"error",sessionId:t,timestamp:new Date().toISOString(),data:{text:`Failed to start session: ${n}`}}),o}}async sendMessage(t,e){const i=this.sessions.get(t),o=this.inputStreams.get(t);if(!i||!o)throw new Error(`Session ${t} not found`);if(i.status==="error")throw new Error(`Session ${t} is in error state`);const n={id:h(),sessionId:t,role:"user",content:e,timestamp:new Date().toISOString()};i.messages.push(n),this.emit("conversation-message",t,n),i.status="thinking",this.emit("status-change",t,"thinking");const a=this.parseMessageContent(e);o.enqueue({type:"user",message:{role:"user",content:a}})}parseMessageContent(t){const e=[],i=/\[图片\s*:\s*([^\]\n]+?)\s*\]/gi;let o=0,n=i.exec(t);for(;n!==null;){if(n.index>o){const s=t.slice(o,n.index).trim();s&&e.push({type:"text",text:s})}const a=n[1].trim();a&&e.push({type:"image",source:{type:"url",url:a}}),o=n.index+n[0].length,n=i.exec(t)}if(o<t.length){const a=t.slice(o).trim();a&&e.push({type:"text",text:a})}return e.length===0&&e.push({type:"text",text:t}),e}async sendConfirmation(t,e){const i=this.pendingPermissions.get(t);i&&(e?i.resolve({behavior:"allow",updatedInput:i.toolInput}):i.resolve({behavior:"deny",message:"User denied"}),this.pendingPermissions.delete(t))}async sendQuestionAnswer(t,e){const i=this.pendingQuestions.get(t);if(!i)return;const o=i.toolInput.questions;let n=`\u7528\u6237\u5DF2\u56DE\u7B54\u4E86\u60A8\u7684\u95EE\u9898\uFF1A
|
|
2
2
|
`;Array.isArray(o)?o.forEach((a,s)=>{const r=String(s),l=e[r]||e[a.header||""]||e[a.question]||"\uFF08\u672A\u586B\u5199\uFF09";n+=`\u2022 ${a.header||a.question}\uFF1A${l}
|
|
3
|
-
`}):n+=JSON.stringify(e),i.resolve({behavior:"deny",message:n}),this.pendingQuestions.delete(t)}async abortCurrentTurn(t){const e=this.abortControllers.get(t);e&&e.abort()}async terminateSession(t){const e=this.sessions.get(t),i=this.sdkQueries.get(t),o=this.inputStreams.get(t);if(o&&o.close(),i)try{i.close()}catch{}e&&(e.status="terminated",this.emit("status-change",t,"terminated"),this.emitEvent(t,{type:"session_complete",sessionId:t,timestamp:new Date().toISOString(),data:{exitCode:0}}));const n=this.sessionAgentIds.get(t);n&&g(n,this.listenerWakeHooks.get(t)),this.listenerWakeHooks.delete(t),this.cleanupSession(t)}getConversation(t){return this.sessions.get(t)?.messages??[]}hasSession(t){return this.sessions.has(t)}getProviderSessionId(t){return this.sessions.get(t)?.providerSessionId}getSessionStatus(t){return this.sessions.get(t)?.status}getSessionPid(t){return this.sessions.get(t)?.pid}cleanup(){for(const t of this.sessions.keys())try{this.terminateSession(t)}catch{}this.sessions.clear(),this.sdkQueries.clear(),this.inputStreams.clear(),this.abortControllers.clear(),this.pendingPermissions.clear(),this.pendingQuestions.clear(),this.idleCommands.clear(),this.idleTimers.clear()}setIdleCommands(t,e){this.idleCommands.set(t,e);const i=this.sessions.get(t);i&&i.status==="waiting_input"&&(e.idleInputCommand||e.nonInputCommand)&&this.startIdleDetection(t)}startIdleDetection(t){this.stopIdleDetection(t);const e=this.idleCommands.get(t);if(e?.idleInputCommand){if(this.isMessagePollingIdleCommand(e.idleInputCommand)){this.getIdlePollLoop(t).start();return}this.lastActivityAt.set(t,Date.now()),this.armIdleCheck(t)}}stopIdleDetection(t){this.idlePollLoops.get(t)?.stop();const e=this.idleTimers.get(t);e&&(clearTimeout(e),this.idleTimers.delete(t))}armIdleCheck(t){const e=this.idleTimers.get(t);e&&clearTimeout(e);const i=setTimeout(()=>{this.idleTimers.get(t)===i&&(this.idleTimers.delete(t),this.armIdleCheck(t),this.checkIdleState(t))},500);this.idleTimers.set(t,i)}checkIdleState(t){const e=this.sessions.get(t);if(!e||e.status!=="waiting_input")return;const i=this.idleCommands.get(t);if(!i||!i.idleInputCommand&&!i.nonInputCommand)return;const o=this.lastActivityAt.get(t)||0;if(!(Date.now()-o<1500)&&(this.lastActivityAt.set(t,Date.now()),i.idleInputCommand)){const s=i.idleInputCommand;this.isMessagePollingIdleCommand(s)?this.sendIdlePrompt(t,this.buildMessagePollingIdlePrompt()):this.sendIdlePrompt(t,s)}}sendIdlePrompt(t,e,i){const o=this.inputStreams.get(t);if(!o)return;const n=this.sessions.get(t);n&&!i?.keepWaitingStatus&&(n.status="thinking",this.emit("status-change",t,"thinking")),o.enqueue({type:"user",message:{role:"user",content:[{type:"text",text:e}]}})}isMessagePollingIdleCommand(t){const e=t.trim();if(!e)return!1;const i=e.toLowerCase();return i.includes("poll_message")||i.includes("get_message")||e.includes("\u53D6\u6D88\u606F")}buildMessagePollingIdlePrompt(){return b}getIdlePollLoop(t){const e=this.idlePollLoops.get(t);if(e)return e;const i=new C({getStatus:()=>this.sessions.get(t)?.status,getCommand:()=>this.idleCommands.get(t)?.idleInputCommand,isPollingCommand:o=>this.isMessagePollingIdleCommand(o),preDispatchHook:()=>null,dispatchPollingPrompt:(o,n)=>this.sendIdlePrompt(t,n?o:this.buildMessagePollingIdlePrompt(),{keepWaitingStatus:!0}),dispatchRegularIdleCommand:o=>this.sendIdlePrompt(t,o)});return this.idlePollLoops.set(t,i),i}async sendShortcutInput(t,e){await this.executeIdleCommand(t,e)}async executeIdleCommand(t,e){const i=this.inputStreams.get(t);if(!i)return;const o=/\[(.+?)\]/g;let n=0;const a=[];let s=o.exec(e);for(;s!==null;){s.index>n&&a.push({type:"text",value:e.slice(n,s.index)});const r=s[1];if(r.startsWith("wait:")){const l=parseFloat(r.slice(5));isNaN(l)||a.push({type:"wait",value:l*1e3})}else{const l={enter:"\r",up:"\x1B[A",down:"\x1B[B",left:"\x1B[D",right:"\x1B[C",tab:" ",esc:"\x1B",escape:"\x1B",space:" ","ctrl+c":""};a.push({type:"key",value:l[r.toLowerCase()]||r})}n=s.index+s[0].length,s=o.exec(e)}n<e.length&&a.push({type:"text",value:e.slice(n)});for(const r of a)if(r.type==="wait")await new Promise(l=>setTimeout(l,r.value));else{const l=String(r.value);i.enqueue({type:"user",message:{role:"user",content:[{type:"text",text:l}]}})}}updateActivity(t){this.lastActivityAt.set(t,Date.now()),this.idleTimers.has(t)&&this.armIdleCheck(t)}async resumeSession(t,e,i){const o={sessionId:t,providerSessionId:e,status:"starting",messages:[],createdAt:new Date().toISOString(),totalUsage:{inputTokens:0,outputTokens:0}};this.sessions.set(t,o);try{await this.startSession(t,i),o.providerSessionId=e}catch(n){throw o.status="error",this.emit("status-change",t,"error"),n}}async loadSdk(){if(!this.sdkModule)try{this.sdkModule=await w("@anthropic-ai/claude-agent-sdk")}catch(t){throw new Error(`Failed to load @anthropic-ai/claude-agent-sdk. Please install: npm install @anthropic-ai/claude-agent-sdk. Original error: ${t}`)}return this.sdkModule}findClaudeExecutable(t){const e=this.extractExecutableCommand(t);if(c.isAbsolute(e)&&p.existsSync(e)){const a=this.resolveWindowsWrapper(e);if(a)return a;if(this.isWindowsWrapperPath(e)){console.warn(`[ClaudeSdkAdapter] Skipping wrapper script for Claude Code executable: ${e}`);return}return e}const i=this.resolveExecutableFromPath(e);if(i)return i;if(process.platform==="win32"&&this.shouldUseDefaultClaudeFallbacks(e)){const a=process.env.USERPROFILE||"",s=process.env.LOCALAPPDATA||"",r=process.env.APPDATA||"",l=[c.join(s,"Volta","tools","shared","@anthropic-ai","claude-code","cli.js"),c.join(s,"Volta","tools","image","packages","@anthropic-ai","claude-code","cli.js")];for(const u of l)if(p.existsSync(u))return u;const d=[c.join(r,"npm","node_modules","@anthropic-ai","claude-code","cli.js"),c.join(s,"Programs","claude-code","claude.exe"),c.join(a,".local","bin","claude.exe")];for(const u of d)if(u&&p.existsSync(u))return u}const o=process.env.HOME||"",n=[c.join(o,".local","bin","claude"),c.join(o,".npm-global","bin","claude"),c.join(o,".local","share","mise","shims","claude"),c.join(o,".asdf","shims","claude"),"/opt/homebrew/bin/claude","/usr/local/bin/claude","/usr/bin/claude","/usr/local/lib/node_modules/@anthropic-ai/claude-code/cli.js","/usr/lib/node_modules/@anthropic-ai/claude-code/cli.js",c.join(o,".local","share","volta","tools","shared","@anthropic-ai","claude-code","cli.js"),c.join(o,".volta","tools","shared","@anthropic-ai","claude-code","cli.js")];if(this.shouldUseDefaultClaudeFallbacks(e)){for(const a of n)if(a&&p.existsSync(a))return a}if(this.shouldUseDefaultClaudeFallbacks(e))try{const a=k("npm root -g",{encoding:"utf8",timeout:5e3}).trim(),s=c.join(a,"@anthropic-ai","claude-code","cli.js");if(p.existsSync(s))return s}catch{}console.warn(`[ClaudeSdkAdapter] Claude Code executable not found for command: ${e}`)}extractExecutableCommand(t){const i=((t||"claude").trim()||"claude").match(/^\s*(?:"([^"]+)"|'([^']+)'|(\S+))/);return i?.[1]||i?.[2]||i?.[3]||"claude"}resolveExecutableFromPath(t){const e=process.env.PATH||"";if(!e)return;const i=c.extname(t).length>0,o=process.platform==="win32"?this.getWindowsPathExtensions(i):[""];for(const n of e.split(c.delimiter))if(n)for(const a of o){const s=c.join(n,`${t}${a}`);if(p.existsSync(s)){if(this.isWindowsWrapperPath(s)){const r=this.resolveWindowsWrapper(s);if(r)return r;continue}return s}}}getWindowsPathExtensions(t){return t?[""]:(process.env.PATHEXT||".EXE;.CMD;.BAT;.COM;.PS1").split(";").map(i=>i.trim()).filter(i=>i.length>0)}shouldUseDefaultClaudeFallbacks(t){return["claude","claude-code","claudecode"].includes(t.toLowerCase())}isWindowsWrapperPath(t){const e=c.extname(t).toLowerCase();return[".cmd",".bat",".ps1"].includes(e)}resolveWindowsWrapper(t){if(this.isWindowsWrapperPath(t))return this.resolveCliJsFromWrapper(t)}resolveCliJsFromWrapper(t){try{if(p.readFileSync(t,"utf8").includes("volta run")){const n=c.join(process.env.LOCALAPPDATA||"","Volta","tools","shared","@anthropic-ai","claude-code","cli.js");if(p.existsSync(n))return n}const i=c.dirname(t),o=c.join(i,"node_modules","@anthropic-ai","claude-code","cli.js");if(p.existsSync(o))return o}catch{}}buildQueryOptions(t,e,i){const o={cwd:e.workingDirectory,abortController:i,settingSources:["user","project","local"],includePartialMessages:!0},n=this.findClaudeExecutable(e.command);if(n?o.pathToClaudeCodeExecutable=n:console.warn(`[ClaudeSdkAdapter] \u2605\u2605\u2605 \u8B66\u544A\uFF1A\u672A\u627E\u5230 Claude Code \u53EF\u6267\u884C\u6587\u4EF6 \u2605\u2605\u2605 command="${e.command}"`),e.model&&(o.model=e.model),e.maxTurns&&e.maxTurns>0&&(o.maxTurns=e.maxTurns),e.mcpConfigPath)try{const a=p.readFileSync(e.mcpConfigPath,"utf-8"),s=JSON.parse(a);o.mcpServers={...e.extraMcpServers,...s.mcpServers}}catch{o.mcpServers=e.extraMcpServers||{}}else o.mcpServers=e.extraMcpServers||{};return o.mcpServers&&typeof o.mcpServers=="object"&&x(o.mcpServers,_(e.agentId)),e.allowedTools&&e.allowedTools.length>0?o.allowedTools=e.allowedTools:o.allowedTools=["Read","Write","Edit","Bash","Glob","Grep","WebSearch","WebFetch","Task","NotebookEdit","LSP","Skill","mcp__*"],o.env={...process.env,...e.envOverrides},o.canUseTool=this.createPermissionHandler(t,e.autoAccept),o}createPermissionHandler(t,e){return async(i,o,n)=>i==="AskUserQuestion"||i==="ask_user_question"?new Promise(a=>{this.pendingQuestions.set(t,{resolve:a,toolInput:o}),this.emit("ask-user-question",{sessionId:t,toolCallId:this.activeToolUseIds.get(t)||void 0,questions:o.questions})}):e?{behavior:"allow",updatedInput:o}:new Promise(a=>{this.pendingPermissions.set(t,{resolve:a,toolInput:o}),this.emit("permission-request",{sessionId:t,toolName:i,toolInput:o,permissionPrompt:`Allow ${i}?`})})}async consumeStream(t,e){const i=this.sessions.get(t);if(i)try{for await(const o of e){const n=o;this.handleSdkMessage(t,i,n)}}catch(o){if(this.abortControllers.get(t)?.signal.aborted)return;const n=o instanceof Error?o.message:String(o);this.emitEvent(t,{type:"error",sessionId:t,timestamp:new Date().toISOString(),data:{text:`Stream error: ${n}`}})}}applyUsage(t,e){e&&(Number.isFinite(e.input_tokens)&&(t.totalUsage.inputTokens=Math.max(t.totalUsage.inputTokens,e.input_tokens??0)),Number.isFinite(e.output_tokens)&&(t.totalUsage.outputTokens=Math.max(t.totalUsage.outputTokens,e.output_tokens??0)))}handleSdkMessage(t,e,i){const o=new Date().toISOString();switch(i.type){case"text":i.delta&&(e.status!=="thinking"&&(e.status="thinking",this.emit("status-change",t,"thinking"),this.stopIdleDetection(t)),this.emitEvent(t,{type:"text_delta",sessionId:t,timestamp:o,data:{text:i.delta}}));break;case"thinking":e.status!=="thinking"&&(e.status="thinking",this.emit("status-change",t,"thinking"),this.stopIdleDetection(t)),(i.content||i.delta)&&this.emitEvent(t,{type:"thinking",sessionId:t,timestamp:o,data:{text:i.delta||i.content}});break;case"tool_use":case"tool_use_start":{const n={...f(i.tool_name,i.tool_input),actionId:i.tool_use_id},a=n.actionType==="idle"?"waiting_input":"tool_using";e.status=a;const s=this.extractMcpServerName(i.tool_name||"");this.emit("status-change",t,a,{actionType:n.actionType,actionLabel:n.actionLabel,actionDetail:n.actionDetail,actionId:n.actionId,usage:e.totalUsage,...s?{metadata:{mcpServer:s}}:{}}),n.actionType!=="idle"&&this.stopIdleDetection(t),this.handleToolUse(t,e,i,o)}break;case"tool_result":case"tool_use_end":this.emitEvent(t,{type:"tool_use_end",sessionId:t,timestamp:o,data:{toolName:i.tool_name,toolResult:i.tool_result,isError:i.is_error,toolUseId:i.tool_use_id}});break;case"result":{const n=i.subtype==="success";this.applyUsage(e,i.usage),this.emitEvent(t,{type:"turn_complete",sessionId:t,timestamp:o,data:{usage:e.totalUsage,text:n?i.result:void 0}}),e.status="waiting_input",(()=>{const s=this.idleCommands.get(t);return!!(s?.idleInputCommand&&this.isMessagePollingIdleCommand(s.idleInputCommand))})()?this.emit("status-change",t,"waiting_input",{actionType:"idle",actionLabel:"\u76D1\u542C\u6D88\u606F",actionDetail:"aws-mcp/poll_message",usage:e.totalUsage}):this.emit("status-change",t,"waiting_input",{usage:e.totalUsage}),this.idleCommands.has(t)&&this.startIdleDetection(t)}break;case"system":break;case"assistant":if(this.applyUsage(e,i.message?.usage),i.message?.content){const n=i.message.content.filter(a=>a.type==="text"&&a.text).map(a=>a.text||"").join("");n&&e.messages.push({id:h(),sessionId:t,role:"assistant",content:n,timestamp:o})}break;case"user":i.tool_use_result;break;case"error":e.status="error",this.emit("status-change",t,"error"),this.emitEvent(t,{type:"error",sessionId:t,timestamp:o,data:{text:i.content||"Unknown error"}});break;case"stream_event":this.handleStreamEvent(t,e,i,o);break;default:break}}handleToolUse(t,e,i,o){const n=this.recentToolNames.get(t),a=this.extractToolNameSuffix(i.tool_name||"");if(n&&Date.now()-n.time<3e4&&n.name===a){this.recentToolNames.delete(t),this.activeToolUseIds.delete(t),e.messages.push({id:h(),sessionId:t,role:"tool_use",content:`${i.tool_name}: ${JSON.stringify(i.tool_input).slice(0,100)}`,timestamp:o,toolName:i.tool_name,toolInput:i.tool_input,toolUseId:i.tool_use_id});return}this.recentToolNames.delete(t),this.activeToolUseIds.delete(t);const s=f(i.tool_name,i.tool_input),r=this.extractMcpServerName(i.tool_name||"");this.emitEvent(t,{type:"tool_use_start",sessionId:t,timestamp:o,data:{toolName:i.tool_name,toolInput:i.tool_input,toolUseId:i.tool_use_id,actionType:s.actionType,actionLabel:s.actionLabel,actionDetail:s.actionDetail,...r?{metadata:{mcpServer:r}}:{}}}),e.messages.push({id:h(),sessionId:t,role:"tool_use",content:`${i.tool_name}: ${JSON.stringify(i.tool_input).slice(0,100)}`,timestamp:o,toolName:i.tool_name,toolInput:i.tool_input,toolUseId:i.tool_use_id})}handleStreamEvent(t,e,i,o){const n=i.event;if(n){if(n.type==="content_block_start"){const a=n.content_block;if(a?.type==="tool_use"&&a.name){const s=a.name,r=a.id||`stream_${Date.now()}`;this.activeToolUseIds.set(t,r);const l=this.extractToolNameSuffix(s);this.recentToolNames.set(t,{name:l,time:Date.now()});const d=`${t}:${r}`;this.toolInputBuffers.set(d,"")}}if(n.type==="content_block_delta"&&n.delta?.type==="input_json_delta"&&n.delta.partial_json){const a=this.activeToolUseIds.get(t);if(a){const s=`${t}:${a}`,r=this.toolInputBuffers.get(s)||"";this.toolInputBuffers.set(s,r+n.delta.partial_json)}}if(n.type==="content_block_stop"){const a=this.activeToolUseIds.get(t),s=this.recentToolNames.get(t);if(a&&s){const r=`${t}:${a}`,l=this.toolInputBuffers.get(r)||"";let d;if(l)try{d=JSON.parse(l)}catch{console.warn("[ClaudeSdkAdapter] Failed to parse tool input JSON:",l.slice(0,100))}const u={...f(s.name,d),actionId:a},m=this.extractMcpServerName(s.name);e.status="tool_using",this.emit("status-change",t,"tool_using",{actionType:u.actionType,actionLabel:u.actionLabel,actionDetail:u.actionDetail,actionId:u.actionId,usage:e.totalUsage,...m?{metadata:{mcpServer:m}}:{}}),this.stopIdleDetection(t),this.emitEvent(t,{type:"tool_use_start",sessionId:t,timestamp:o,data:{toolName:s.name,toolInput:d,toolUseId:a,actionType:u.actionType,actionLabel:u.actionLabel,actionDetail:u.actionDetail,actionId:u.actionId,...m?{metadata:{mcpServer:m}}:{}}}),e.messages.push({id:h(),sessionId:t,role:"tool_use",content:`${s.name}: ${l.slice(0,100)}`,timestamp:o,toolName:s.name,toolInput:d,toolUseId:a}),this.toolInputBuffers.delete(r),this.activeToolUseIds.delete(t)}}}}extractMcpServerName(t){if(t.startsWith("mcp__")){const e=t.split("__");if(e.length>=3)return e[1]}}extractToolNameSuffix(t){if(t.includes("__"))return t.split("__").pop()||t;if(t.includes("-mcp__")){const e=t.indexOf("-mcp__");return t.substring(e+6)}return t}emitEvent(t,e){this.emit("event",e)}cleanupSession(t){this.stopIdleDetection(t),this.sessions.delete(t),this.sdkQueries.delete(t),this.inputStreams.delete(t),this.abortControllers.delete(t),this.pendingPermissions.delete(t),this.pendingQuestions.delete(t),this.idleCommands.delete(t),this.idlePollLoops.delete(t),this.sessionAgentIds.delete(t),this.lastActivityAt.delete(t)}}export{$ as ClaudeSdkAdapter};
|
|
3
|
+
`}):n+=JSON.stringify(e),i.resolve({behavior:"deny",message:n}),this.pendingQuestions.delete(t)}async abortCurrentTurn(t){const e=this.abortControllers.get(t);e&&e.abort()}async terminateSession(t){const e=this.sessions.get(t),i=this.sdkQueries.get(t),o=this.inputStreams.get(t);if(o&&o.close(),i)try{i.close()}catch{}e&&(e.status="terminated",this.emit("status-change",t,"terminated"),this.emitEvent(t,{type:"session_complete",sessionId:t,timestamp:new Date().toISOString(),data:{exitCode:0}}));const n=this.sessionAgentIds.get(t);n&&g(n,this.listenerWakeHooks.get(t)),this.listenerWakeHooks.delete(t),this.cleanupSession(t)}getConversation(t){return this.sessions.get(t)?.messages??[]}hasSession(t){return this.sessions.has(t)}getProviderSessionId(t){return this.sessions.get(t)?.providerSessionId}getSessionStatus(t){return this.sessions.get(t)?.status}getSessionPid(t){return this.sessions.get(t)?.pid}cleanup(){for(const t of this.sessions.keys())try{this.terminateSession(t)}catch{}this.sessions.clear(),this.sdkQueries.clear(),this.inputStreams.clear(),this.abortControllers.clear(),this.pendingPermissions.clear(),this.pendingQuestions.clear(),this.idleCommands.clear(),this.idleTimers.clear()}setIdleCommands(t,e){this.idleCommands.set(t,e);const i=this.sessions.get(t);i&&i.status==="waiting_input"&&(e.idleInputCommand||e.nonInputCommand)&&this.startIdleDetection(t)}startIdleDetection(t){this.stopIdleDetection(t);const e=this.idleCommands.get(t);if(e?.idleInputCommand){if(this.isMessagePollingIdleCommand(e.idleInputCommand)){this.getIdlePollLoop(t).start();return}this.lastActivityAt.set(t,Date.now()),this.armIdleCheck(t)}}stopIdleDetection(t){this.idlePollLoops.get(t)?.stop();const e=this.idleTimers.get(t);e&&(clearTimeout(e),this.idleTimers.delete(t))}armIdleCheck(t){const e=this.idleTimers.get(t);e&&clearTimeout(e);const i=setTimeout(()=>{this.idleTimers.get(t)===i&&(this.idleTimers.delete(t),this.armIdleCheck(t),this.checkIdleState(t))},500);this.idleTimers.set(t,i)}checkIdleState(t){const e=this.sessions.get(t);if(!e||e.status!=="waiting_input")return;const i=this.idleCommands.get(t);if(!i||!i.idleInputCommand&&!i.nonInputCommand)return;const o=this.lastActivityAt.get(t)||0;if(!(Date.now()-o<1500)&&(this.lastActivityAt.set(t,Date.now()),i.idleInputCommand)){const s=i.idleInputCommand;this.isMessagePollingIdleCommand(s)?this.sendIdlePrompt(t,this.buildMessagePollingIdlePrompt()):this.sendIdlePrompt(t,s)}}sendIdlePrompt(t,e,i){const o=this.inputStreams.get(t);if(!o)return;const n=this.sessions.get(t);n&&!i?.keepWaitingStatus&&(n.status="thinking",this.emit("status-change",t,"thinking")),o.enqueue({type:"user",message:{role:"user",content:[{type:"text",text:e}]}})}isMessagePollingIdleCommand(t){const e=t.trim();if(!e)return!1;const i=e.toLowerCase();return i.includes("poll_message")||i.includes("get_message")||e.includes("\u53D6\u6D88\u606F")}buildMessagePollingIdlePrompt(){return P}getIdlePollLoop(t){const e=this.idlePollLoops.get(t);if(e)return e;const i=new b({getStatus:()=>this.sessions.get(t)?.status,getCommand:()=>this.idleCommands.get(t)?.idleInputCommand,isPollingCommand:o=>this.isMessagePollingIdleCommand(o),preDispatchHook:()=>null,dispatchPollingPrompt:(o,n)=>this.sendIdlePrompt(t,n?o:this.buildMessagePollingIdlePrompt(),{keepWaitingStatus:!0}),dispatchRegularIdleCommand:o=>this.sendIdlePrompt(t,o)});return this.idlePollLoops.set(t,i),i}async sendShortcutInput(t,e){await this.executeIdleCommand(t,e)}async executeIdleCommand(t,e){const i=this.inputStreams.get(t);if(!i)return;const o=/\[(.+?)\]/g;let n=0;const a=[];let s=o.exec(e);for(;s!==null;){s.index>n&&a.push({type:"text",value:e.slice(n,s.index)});const r=s[1];if(r.startsWith("wait:")){const l=parseFloat(r.slice(5));isNaN(l)||a.push({type:"wait",value:l*1e3})}else{const l={enter:"\r",up:"\x1B[A",down:"\x1B[B",left:"\x1B[D",right:"\x1B[C",tab:" ",esc:"\x1B",escape:"\x1B",space:" ","ctrl+c":""};a.push({type:"key",value:l[r.toLowerCase()]||r})}n=s.index+s[0].length,s=o.exec(e)}n<e.length&&a.push({type:"text",value:e.slice(n)});for(const r of a)if(r.type==="wait")await new Promise(l=>setTimeout(l,r.value));else{const l=String(r.value);i.enqueue({type:"user",message:{role:"user",content:[{type:"text",text:l}]}})}}updateActivity(t){this.lastActivityAt.set(t,Date.now()),this.idleTimers.has(t)&&this.armIdleCheck(t)}async resumeSession(t,e,i){const o={sessionId:t,providerSessionId:e,status:"starting",messages:[],createdAt:new Date().toISOString(),totalUsage:{inputTokens:0,outputTokens:0}};this.sessions.set(t,o);try{await this.startSession(t,i),o.providerSessionId=e}catch(n){throw o.status="error",this.emit("status-change",t,"error"),n}}async loadSdk(){if(!this.sdkModule)try{this.sdkModule=await C("@anthropic-ai/claude-agent-sdk")}catch(t){throw new Error(`Failed to load @anthropic-ai/claude-agent-sdk. Please install: npm install @anthropic-ai/claude-agent-sdk. Original error: ${t}`)}return this.sdkModule}findClaudeExecutable(t){const e=this.extractExecutableCommand(t);if(c.isAbsolute(e)&&p.existsSync(e)){const a=this.resolveWindowsWrapper(e);if(a)return a;if(this.isWindowsWrapperPath(e)){console.warn(`[ClaudeSdkAdapter] Skipping wrapper script for Claude Code executable: ${e}`);return}return e}const i=this.resolveExecutableFromPath(e);if(i)return i;if(process.platform==="win32"&&this.shouldUseDefaultClaudeFallbacks(e)){const a=process.env.USERPROFILE||"",s=process.env.LOCALAPPDATA||"",r=process.env.APPDATA||"",l=[c.join(s,"Volta","tools","shared","@anthropic-ai","claude-code","cli.js"),c.join(s,"Volta","tools","image","packages","@anthropic-ai","claude-code","cli.js")];for(const u of l)if(p.existsSync(u))return u;const d=[c.join(r,"npm","node_modules","@anthropic-ai","claude-code","cli.js"),c.join(s,"Programs","claude-code","claude.exe"),c.join(a,".local","bin","claude.exe")];for(const u of d)if(u&&p.existsSync(u))return u}const o=process.env.HOME||"",n=[c.join(o,".local","bin","claude"),c.join(o,".npm-global","bin","claude"),c.join(o,".local","share","mise","shims","claude"),c.join(o,".asdf","shims","claude"),"/opt/homebrew/bin/claude","/usr/local/bin/claude","/usr/bin/claude","/usr/local/lib/node_modules/@anthropic-ai/claude-code/cli.js","/usr/lib/node_modules/@anthropic-ai/claude-code/cli.js",c.join(o,".local","share","volta","tools","shared","@anthropic-ai","claude-code","cli.js"),c.join(o,".volta","tools","shared","@anthropic-ai","claude-code","cli.js")];if(this.shouldUseDefaultClaudeFallbacks(e)){for(const a of n)if(a&&p.existsSync(a))return a}if(this.shouldUseDefaultClaudeFallbacks(e))try{const a=k("npm root -g",{encoding:"utf8",timeout:5e3}).trim(),s=c.join(a,"@anthropic-ai","claude-code","cli.js");if(p.existsSync(s))return s}catch{}console.warn(`[ClaudeSdkAdapter] Claude Code executable not found for command: ${e}`)}extractExecutableCommand(t){const i=((t||"claude").trim()||"claude").match(/^\s*(?:"([^"]+)"|'([^']+)'|(\S+))/);return i?.[1]||i?.[2]||i?.[3]||"claude"}resolveExecutableFromPath(t){const e=process.env.PATH||"";if(!e)return;const i=c.extname(t).length>0,o=process.platform==="win32"?this.getWindowsPathExtensions(i):[""];for(const n of e.split(c.delimiter))if(n)for(const a of o){const s=c.join(n,`${t}${a}`);if(p.existsSync(s)){if(this.isWindowsWrapperPath(s)){const r=this.resolveWindowsWrapper(s);if(r)return r;continue}return s}}}getWindowsPathExtensions(t){return t?[""]:(process.env.PATHEXT||".EXE;.CMD;.BAT;.COM;.PS1").split(";").map(i=>i.trim()).filter(i=>i.length>0)}shouldUseDefaultClaudeFallbacks(t){return["claude","claude-code","claudecode"].includes(t.toLowerCase())}isWindowsWrapperPath(t){const e=c.extname(t).toLowerCase();return[".cmd",".bat",".ps1"].includes(e)}resolveWindowsWrapper(t){if(this.isWindowsWrapperPath(t))return this.resolveCliJsFromWrapper(t)}resolveCliJsFromWrapper(t){try{if(p.readFileSync(t,"utf8").includes("volta run")){const n=c.join(process.env.LOCALAPPDATA||"","Volta","tools","shared","@anthropic-ai","claude-code","cli.js");if(p.existsSync(n))return n}const i=c.dirname(t),o=c.join(i,"node_modules","@anthropic-ai","claude-code","cli.js");if(p.existsSync(o))return o}catch{}}buildQueryOptions(t,e,i){const o={cwd:e.workingDirectory,abortController:i,settingSources:["user","project","local"],includePartialMessages:!0},n=this.findClaudeExecutable(e.command);if(n?o.pathToClaudeCodeExecutable=n:console.warn(`[ClaudeSdkAdapter] \u2605\u2605\u2605 \u8B66\u544A\uFF1A\u672A\u627E\u5230 Claude Code \u53EF\u6267\u884C\u6587\u4EF6 \u2605\u2605\u2605 command="${e.command}"`),e.model&&(o.model=e.model),e.maxTurns&&e.maxTurns>0&&(o.maxTurns=e.maxTurns),e.mcpConfigPath)try{const a=p.readFileSync(e.mcpConfigPath,"utf-8"),s=JSON.parse(a);o.mcpServers={...e.extraMcpServers,...s.mcpServers}}catch{o.mcpServers=e.extraMcpServers||{}}else o.mcpServers=e.extraMcpServers||{};return o.mcpServers&&typeof o.mcpServers=="object"&&x(o.mcpServers,_(e.agentId),{agentMeta:w(e.agentId)}),e.allowedTools&&e.allowedTools.length>0?o.allowedTools=e.allowedTools:o.allowedTools=["Read","Write","Edit","Bash","Glob","Grep","WebSearch","WebFetch","Task","NotebookEdit","LSP","Skill","mcp__*"],o.env={...process.env,...e.envOverrides},o.canUseTool=this.createPermissionHandler(t,e.autoAccept),o}createPermissionHandler(t,e){return async(i,o,n)=>i==="AskUserQuestion"||i==="ask_user_question"?new Promise(a=>{this.pendingQuestions.set(t,{resolve:a,toolInput:o}),this.emit("ask-user-question",{sessionId:t,toolCallId:this.activeToolUseIds.get(t)||void 0,questions:o.questions})}):e?{behavior:"allow",updatedInput:o}:new Promise(a=>{this.pendingPermissions.set(t,{resolve:a,toolInput:o}),this.emit("permission-request",{sessionId:t,toolName:i,toolInput:o,permissionPrompt:`Allow ${i}?`})})}async consumeStream(t,e){const i=this.sessions.get(t);if(i)try{for await(const o of e){const n=o;this.handleSdkMessage(t,i,n)}}catch(o){if(this.abortControllers.get(t)?.signal.aborted)return;const n=o instanceof Error?o.message:String(o);this.emitEvent(t,{type:"error",sessionId:t,timestamp:new Date().toISOString(),data:{text:`Stream error: ${n}`}})}}applyUsage(t,e){e&&(Number.isFinite(e.input_tokens)&&(t.totalUsage.inputTokens=Math.max(t.totalUsage.inputTokens,e.input_tokens??0)),Number.isFinite(e.output_tokens)&&(t.totalUsage.outputTokens=Math.max(t.totalUsage.outputTokens,e.output_tokens??0)))}handleSdkMessage(t,e,i){const o=new Date().toISOString();switch(i.type){case"text":i.delta&&(e.status!=="thinking"&&(e.status="thinking",this.emit("status-change",t,"thinking"),this.stopIdleDetection(t)),this.emitEvent(t,{type:"text_delta",sessionId:t,timestamp:o,data:{text:i.delta}}));break;case"thinking":e.status!=="thinking"&&(e.status="thinking",this.emit("status-change",t,"thinking"),this.stopIdleDetection(t)),(i.content||i.delta)&&this.emitEvent(t,{type:"thinking",sessionId:t,timestamp:o,data:{text:i.delta||i.content}});break;case"tool_use":case"tool_use_start":{const n={...f(i.tool_name,i.tool_input),actionId:i.tool_use_id},a=n.actionType==="idle"?"waiting_input":"tool_using";e.status=a;const s=this.extractMcpServerName(i.tool_name||"");this.emit("status-change",t,a,{actionType:n.actionType,actionLabel:n.actionLabel,actionDetail:n.actionDetail,actionId:n.actionId,usage:e.totalUsage,...s?{metadata:{mcpServer:s}}:{}}),n.actionType!=="idle"&&this.stopIdleDetection(t),this.handleToolUse(t,e,i,o)}break;case"tool_result":case"tool_use_end":this.emitEvent(t,{type:"tool_use_end",sessionId:t,timestamp:o,data:{toolName:i.tool_name,toolResult:i.tool_result,isError:i.is_error,toolUseId:i.tool_use_id}});break;case"result":{const n=i.subtype==="success";this.applyUsage(e,i.usage),this.emitEvent(t,{type:"turn_complete",sessionId:t,timestamp:o,data:{usage:e.totalUsage,text:n?i.result:void 0}}),e.status="waiting_input",(()=>{const s=this.idleCommands.get(t);return!!(s?.idleInputCommand&&this.isMessagePollingIdleCommand(s.idleInputCommand))})()?this.emit("status-change",t,"waiting_input",{actionType:"idle",actionLabel:"\u76D1\u542C\u6D88\u606F",actionDetail:"aws-mcp/poll_message",usage:e.totalUsage}):this.emit("status-change",t,"waiting_input",{usage:e.totalUsage}),this.idleCommands.has(t)&&this.startIdleDetection(t)}break;case"system":break;case"assistant":if(this.applyUsage(e,i.message?.usage),i.message?.content){const n=i.message.content.filter(a=>a.type==="text"&&a.text).map(a=>a.text||"").join("");n&&e.messages.push({id:h(),sessionId:t,role:"assistant",content:n,timestamp:o})}break;case"user":i.tool_use_result;break;case"error":e.status="error",this.emit("status-change",t,"error"),this.emitEvent(t,{type:"error",sessionId:t,timestamp:o,data:{text:i.content||"Unknown error"}});break;case"stream_event":this.handleStreamEvent(t,e,i,o);break;default:break}}handleToolUse(t,e,i,o){const n=this.recentToolNames.get(t),a=this.extractToolNameSuffix(i.tool_name||"");if(n&&Date.now()-n.time<3e4&&n.name===a){this.recentToolNames.delete(t),this.activeToolUseIds.delete(t),e.messages.push({id:h(),sessionId:t,role:"tool_use",content:`${i.tool_name}: ${JSON.stringify(i.tool_input).slice(0,100)}`,timestamp:o,toolName:i.tool_name,toolInput:i.tool_input,toolUseId:i.tool_use_id});return}this.recentToolNames.delete(t),this.activeToolUseIds.delete(t);const s=f(i.tool_name,i.tool_input),r=this.extractMcpServerName(i.tool_name||"");this.emitEvent(t,{type:"tool_use_start",sessionId:t,timestamp:o,data:{toolName:i.tool_name,toolInput:i.tool_input,toolUseId:i.tool_use_id,actionType:s.actionType,actionLabel:s.actionLabel,actionDetail:s.actionDetail,...r?{metadata:{mcpServer:r}}:{}}}),e.messages.push({id:h(),sessionId:t,role:"tool_use",content:`${i.tool_name}: ${JSON.stringify(i.tool_input).slice(0,100)}`,timestamp:o,toolName:i.tool_name,toolInput:i.tool_input,toolUseId:i.tool_use_id})}handleStreamEvent(t,e,i,o){const n=i.event;if(n){if(n.type==="content_block_start"){const a=n.content_block;if(a?.type==="tool_use"&&a.name){const s=a.name,r=a.id||`stream_${Date.now()}`;this.activeToolUseIds.set(t,r);const l=this.extractToolNameSuffix(s);this.recentToolNames.set(t,{name:l,time:Date.now()});const d=`${t}:${r}`;this.toolInputBuffers.set(d,"")}}if(n.type==="content_block_delta"&&n.delta?.type==="input_json_delta"&&n.delta.partial_json){const a=this.activeToolUseIds.get(t);if(a){const s=`${t}:${a}`,r=this.toolInputBuffers.get(s)||"";this.toolInputBuffers.set(s,r+n.delta.partial_json)}}if(n.type==="content_block_stop"){const a=this.activeToolUseIds.get(t),s=this.recentToolNames.get(t);if(a&&s){const r=`${t}:${a}`,l=this.toolInputBuffers.get(r)||"";let d;if(l)try{d=JSON.parse(l)}catch{console.warn("[ClaudeSdkAdapter] Failed to parse tool input JSON:",l.slice(0,100))}const u={...f(s.name,d),actionId:a},m=this.extractMcpServerName(s.name);e.status="tool_using",this.emit("status-change",t,"tool_using",{actionType:u.actionType,actionLabel:u.actionLabel,actionDetail:u.actionDetail,actionId:u.actionId,usage:e.totalUsage,...m?{metadata:{mcpServer:m}}:{}}),this.stopIdleDetection(t),this.emitEvent(t,{type:"tool_use_start",sessionId:t,timestamp:o,data:{toolName:s.name,toolInput:d,toolUseId:a,actionType:u.actionType,actionLabel:u.actionLabel,actionDetail:u.actionDetail,actionId:u.actionId,...m?{metadata:{mcpServer:m}}:{}}}),e.messages.push({id:h(),sessionId:t,role:"tool_use",content:`${s.name}: ${l.slice(0,100)}`,timestamp:o,toolName:s.name,toolInput:d,toolUseId:a}),this.toolInputBuffers.delete(r),this.activeToolUseIds.delete(t)}}}}extractMcpServerName(t){if(t.startsWith("mcp__")){const e=t.split("__");if(e.length>=3)return e[1]}}extractToolNameSuffix(t){if(t.includes("__"))return t.split("__").pop()||t;if(t.includes("-mcp__")){const e=t.indexOf("-mcp__");return t.substring(e+6)}return t}emitEvent(t,e){this.emit("event",e)}cleanupSession(t){this.stopIdleDetection(t),this.sessions.delete(t),this.sdkQueries.delete(t),this.inputStreams.delete(t),this.abortControllers.delete(t),this.pendingPermissions.delete(t),this.pendingQuestions.delete(t),this.idleCommands.delete(t),this.idlePollLoops.delete(t),this.sessionAgentIds.delete(t),this.lastActivityAt.delete(t)}}export{N as ClaudeSdkAdapter};
|
|
4
4
|
|
package/dist/adapter/types.d.ts
CHANGED
|
@@ -373,6 +373,13 @@ export declare abstract class BaseProviderAdapter extends EventEmitter {
|
|
|
373
373
|
|
|
374
374
|
abstract resetContext?(sessionId: string): Promise<void>;
|
|
375
375
|
|
|
376
|
+
abstract compactContext?(sessionId: string, plan?: {
|
|
377
|
+
pruneCategories?: string[];
|
|
378
|
+
summarize?: boolean;
|
|
379
|
+
}): unknown;
|
|
380
|
+
|
|
381
|
+
abstract getCompactionPreview?(sessionId: string): unknown;
|
|
382
|
+
|
|
376
383
|
abstract terminateSession(sessionId: string): Promise<void>;
|
|
377
384
|
|
|
378
385
|
abstract resumeSession?(sessionId: string, providerSessionId: string, config: AdapterSessionConfig): Promise<void>;
|
package/dist/config.d.ts
CHANGED
|
@@ -74,6 +74,8 @@ export declare function getBridgeTemplatePluginsDir(): string;
|
|
|
74
74
|
|
|
75
75
|
export declare function getBridgeTemplateMcpDir(): string;
|
|
76
76
|
|
|
77
|
+
export declare function getBridgeTemplateMcpPackagesDir(): string;
|
|
78
|
+
|
|
77
79
|
export declare function getBridgeTemplateAgentsDir(): string;
|
|
78
80
|
|
|
79
81
|
export declare function getBridgeInstanceRuntimeDir(agentId: string): string;
|
|
@@ -84,6 +86,10 @@ export declare function getBridgeInstanceSkillsDir(agentId: string): string;
|
|
|
84
86
|
|
|
85
87
|
export declare function getBridgeInstancePluginsDir(agentId: string): string;
|
|
86
88
|
|
|
89
|
+
export declare function getBridgeInstancePrivateSkillsDir(agentId: string): string;
|
|
90
|
+
|
|
91
|
+
export declare function getBridgeInstancePrivateSkillsManifest(agentId: string): string;
|
|
92
|
+
|
|
87
93
|
export declare function getBridgeInstanceMcpExtraFile(agentId: string): string;
|
|
88
94
|
|
|
89
95
|
export declare function getAcodeDataHome(): string;
|
package/dist/config.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import u from"node:fs";import
|
|
1
|
+
import u from"node:fs";import L from"node:net";import{homedir as C}from"node:os";import t from"node:path";import{fileURLToPath as I}from"node:url";import{logger as B}from"./utils/logger.js";function M(e){return String(e??"").replace(/[^a-zA-Z0-9_.-]/g,"_").replace(/^\.+/g,"")}function N(){return String(process.env.AWS_RUNTIME_ENV||"").trim().toLowerCase()==="development"}let S;function h(){if(S!==void 0)return S;const e=t.dirname(I(import.meta.url)),r=t.resolve(e,".."),n=t.resolve(r,".."),o=u.existsSync(t.join(n,".git"))||u.existsSync(t.join(n,"package.json"));return S=t.join(o?n:r,".dev-home"),S}function O(){return String(process.env.AWS_TEST_HOME||"").trim()||String(process.env.AWS_RUNTIME_HOME_DIR||"").trim()||C()}function f(){return N()?String(process.env.AWS_TEST_HOME||"").trim()||String(process.env.AWS_RUNTIME_HOME_DIR||"").trim()||h():O()}const H=18081,j=28081,v=Number(process.env.AWS_RUNTIME_BRIDGE_PORT||(N()?j:H));let R;function W(){return R??v}function k(e){R=e}function X(){R=void 0}function U(e){return new Promise(r=>{const n=L.createServer();n.once("error",o=>{const i=o.code==="EADDRINUSE"||o.code==="EACCES"||o.code==="EPERM";r(!i)}),n.once("listening",()=>{n.close(()=>r(!0))}),n.listen(e)})}async function x(e){return await U({port:e})&&await U({port:e,host:"0.0.0.0"})?e:null}async function w(e,r=20){let n=Math.floor(e);for(let i=0;i<r;i+=1){if(n>=1&&n<=65535){const c=await x(n);if(c!==null)return c}n+=1}return await x(0)??e}async function Z(e=v){const r=await w(e);return k(r),process.env.AWS_RUNTIME_BRIDGE_PORT=String(r),r!==e&&B.warn(`[runtime-bridge] \u9996\u9009\u7AEF\u53E3 ${e} \u5DF2\u88AB\u5360\u7528\uFF0C\u81EA\u52A8\u6539\u7528 ${r} \u542F\u52A8`),r}const d="http://localhost:8080";function m(e){return e==null?void 0:String(e).trim()||void 0}function _(e){const r=m(e);if(!r)return;const n=r.replace(/^((?:https?|wss?):\/\/(?:\[[^\]]+\]|[^/:?#]+):\d+):\d+(?=\/|$)/i,"$1");try{const o=new URL(n);return o.protocol==="ws:"?o.protocol="http:":o.protocol==="wss:"?o.protocol="https:":o.protocol=o.protocol.toLowerCase(),o.hostname=o.hostname.toLowerCase(),o.origin}catch{return n.replace(/\/+$/,"")}}function F(){return t.join(f(),".aws-bridge","config.json")}function y(){return t.join(f(),".aws-bridge","bridge-runtime.properties")}function Q(){const e=y();u.mkdirSync(t.dirname(e),{recursive:!0});const r=[`port=${W()}`,`pid=${process.pid}`,`startedAt=${new Date().toISOString()}`];u.writeFileSync(e,`${r.join(`
|
|
2
2
|
`)}
|
|
3
|
-
`,{encoding:"utf8",mode:384})}function D(){const e=
|
|
3
|
+
`,{encoding:"utf8",mode:384})}function D(){const e=F();try{if(!u.existsSync(e))return[];const r=JSON.parse(u.readFileSync(e,"utf-8")),n=s=>({serverUrl:_(s.serverUrl)||_(s.schedulerBaseUrl),instanceId:m(s.instanceId),instanceName:m(s.instanceName)}),i=(Array.isArray(r.autoRegisterTargets)?r.autoRegisterTargets:[]).filter(s=>!!(s&&typeof s=="object"&&!Array.isArray(s))).map(n).filter(s=>!!s.serverUrl);if(i.length>0)return i;const c=n(r);return c.serverUrl?[c]:[]}catch{return[]}}function b(){const r=D().map(n=>n.serverUrl).filter(n=>!!n);return Array.from(new Set(r))}function ee(){return G(void 0)}function G(e,r,n){const o=_(e);if(o)return{url:o,source:"request",ambiguousTargetUrls:[]};const i=typeof r=="string"?r.trim():"",c=typeof n=="string"?n.trim():"";if(i||c){const A=D();let a;if(i&&(a=A.find(g=>g.instanceId===i)),!a&&c&&(a=A.find(g=>g.instanceName===c)),!a&&i&&!c&&(a=A.find(g=>g.instanceName===i)),a?.serverUrl)return{url:a.serverUrl,source:"instance-id-match",ambiguousTargetUrls:[],instanceId:a.instanceId,instanceName:a.instanceName}}const s=_(process.env.AWS_RUNTIME_SCHEDULER_BASE_URL);if(s)return{url:s,source:"env",ambiguousTargetUrls:[]};const l=b();return l.length===1?{url:l[0]||d,source:"single-auto-register-target",ambiguousTargetUrls:[]}:l.length>1?{url:d,source:"ambiguous-auto-register-targets",ambiguousTargetUrls:l}:{url:d,source:"default",ambiguousTargetUrls:[]}}const te=_(process.env.AWS_RUNTIME_SCHEDULER_BASE_URL)||d,re=process.env.NODE_ENV||"development",ne=process.env.AWS_ALLOW_HOST_FILE_BROWSER==="true",oe=String(process.env.AWS_RUNTIME_CORS_ORIGINS||"http://localhost:3000,http://127.0.0.1:3000,http://localhost:5173,http://127.0.0.1:5173").split(",").map(e=>e.trim()).filter(e=>e.length>0);function ie(){}function se(e){return String(process.env.AWS_RUNTIME_CLAUDE_CONFIG_FILE||"").trim()||t.join(e,".claude","settings.json")}function ce(e){return String(process.env.AWS_RUNTIME_CLAUDE_MCP_CONFIG_FILE||"").trim()||t.join(e,".claude.json")}function ae(e){return String(process.env.AWS_RUNTIME_CLAUDE_SKILLS_DIR||"").trim()||t.join(e,".claude","skills")}function ue(e){return String(process.env.AWS_RUNTIME_OPENCODE_CONFIG_FILE||"").trim()||t.join(e,".config","opencode","opencode.json")}function P(){return t.join(f(),".aws-bridge")}function E(){return t.join(P(),"instance-template")}function pe(){return String(process.env.AWS_RUNTIME_ACODE_CONFIG_FILE||"").trim()||t.join(E(),"config.json")}function le(){return String(process.env.AWS_RUNTIME_ACODE_SKILLS_DIR||"").trim()||t.join(E(),"skills")}function ge(){return String(process.env.AWS_RUNTIME_ACODE_PLUGINS_DIR||"").trim()||t.join(E(),"plugins")}function V(){return t.join(E(),"mcp")}function _e(){return t.join(V(),"packages")}function Ee(){return t.join(E(),"agents")}function p(e){return t.join(P(),"instance-runtime",M(String(e)))}function Se(e){return t.join(p(e),"config.json")}function de(e){return t.join(p(e),"skills")}function Ae(e){return t.join(p(e),"plugins")}function fe(e){return t.join(p(e),"private-skills")}function Re(e){return t.join(p(e),"private-skills.json")}function me(e){return t.join(p(e),"mcp-extra.json")}function Te(){return String(process.env.ACODE_HOME||"").trim()||t.join(O(),".acode")}function Ie(e){return String(process.env.AWS_RUNTIME_CODEX_CONFIG_FILE||"").trim()||t.join(e,".codex","config.toml")}function Ne(e){return String(process.env.AWS_RUNTIME_CODEX_SKILLS_DIR||"").trim()||t.join(e,".codex","skills")}function Oe(e){return String(process.env.AWS_RUNTIME_OPENCODE_SKILLS_DIR||"").trim()||t.join(e,".opencode","skills")}const ve=Number(process.env.AWS_ORPHAN_SCAN_INTERVAL||3e4),Ue=process.env.AWS_ORPHAN_AUTO_CLEAN_MODE||"alert",xe=process.env.AWS_ORPHAN_SCAN_ENABLED!=="false",De=Number(process.env.AWS_ORPHAN_UNRESPONSIVE_TIMEOUT||3e5),Pe=Number(process.env.AWS_ORPHAN_CPU_THRESHOLD||100),Le=Number(process.env.AWS_ORPHAN_MEMORY_THRESHOLD||2048),Ce=process.env.AWS_AUTO_REGISTER==="true",Be=process.env.AWS_TENANT_ID||"",Me=process.env.AWS_USER_KEY||"",he=process.env.AWS_INSTANCE_NAME||"",He=process.env.AWS_PROJECT_NAME||"",je=process.env.AWS_ROLE_NAME||"",We=process.env.AWS_WORKSPACE_PATH||"",ke=process.env.AWS_REGISTER_IP||process.env.AWS_VIRTUAL_IP||"";let T;function we(){if(T!==void 0)return T;let e="unknown";try{const r=t.dirname(I(import.meta.url)),n=t.resolve(r,"..","package.json");u.existsSync(n)&&(e=JSON.parse(u.readFileSync(n,"utf-8")).version||"unknown")}catch{}return T=e,e}export{Ce as AUTO_REGISTER_ENABLED,he as AUTO_REGISTER_INSTANCE_NAME,He as AUTO_REGISTER_PROJECT_NAME,je as AUTO_REGISTER_ROLE_NAME,Be as AUTO_REGISTER_TENANT_ID,Me as AUTO_REGISTER_USER_KEY,ke as AUTO_REGISTER_VIRTUAL_IP,We as AUTO_REGISTER_WORKSPACE_PATH,H as DEFAULT_BRIDGE_PORT,d as DEFAULT_SCHEDULER_BASE_URL,j as DEV_DEFAULT_BRIDGE_PORT,Ue as ORPHAN_AUTO_CLEAN_MODE,Pe as ORPHAN_CPU_THRESHOLD,Le as ORPHAN_MEMORY_THRESHOLD,xe as ORPHAN_SCAN_ENABLED,ve as ORPHAN_SCAN_INTERVAL,De as ORPHAN_UNRESPONSIVE_TIMEOUT,ne as allowHostFileBrowser,oe as allowedCorsOrigins,w as findAvailableListenPort,Te as getAcodeDataHome,W as getActiveBridgeHttpPort,F as getAutoRegisterConfigFilePath,P as getBridgeDataHome,Se as getBridgeInstanceConfigFile,me as getBridgeInstanceMcpExtraFile,Ae as getBridgeInstancePluginsDir,fe as getBridgeInstancePrivateSkillsDir,Re as getBridgeInstancePrivateSkillsManifest,p as getBridgeInstanceRuntimeDir,de as getBridgeInstanceSkillsDir,y as getBridgeRuntimePropertiesFilePath,Ee as getBridgeTemplateAgentsDir,pe as getBridgeTemplateConfigFile,E as getBridgeTemplateDir,V as getBridgeTemplateMcpDir,_e as getBridgeTemplateMcpPackagesDir,ge as getBridgeTemplatePluginsDir,le as getBridgeTemplateSkillsDir,we as getBridgeVersion,se as getClaudeConfigFile,ce as getClaudeMcpConfigFile,ae as getClaudeSkillsDir,Ie as getCodexConfigFile,Ne as getCodexSkillsDir,ue as getOpencodeConfigFile,Oe as getOpencodeSkillsDir,f as getRuntimeHomeDir,O as getUserHomeDir,N as isDevMode,re as nodeEnv,v as port,Z as reserveBridgeListenPort,X as resetActiveBridgeHttpPort,ee as resolveSchedulerBaseUrl,G as resolveSchedulerBaseUrlFrom,te as schedulerBaseUrl,k as setActiveBridgeHttpPort,ie as validateProductionToken,Q as writeBridgeRuntimePropertiesFile};
|
|
4
4
|
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{existsSync as T,readFileSync as D}from"node:fs";import M from"node:os";import S from"node:path";import{pathToFileURL as E}from"node:url";import x from"cors";import P from"express";import{adapterRegistry as F}from"./adapter/index.js";import{attachBrowserWebSocketServer as G}from"./browser/browser-ws-bridge.js";import{getAcodeDataHome as O,getActiveBridgeHttpPort as y,getAutoRegisterConfigFilePath as L,getBridgeDataHome as _,getBridgeRuntimePropertiesFilePath as j,getBridgeTemplateConfigFile as K,reserveBridgeListenPort as N,validateProductionToken as W,writeBridgeRuntimePropertiesFile as H}from"./config.js";import{attachRemoteDesktopWebSocketServer as U}from"./remote-desktop/index.js";import{acodeTodosRouter as z}from"./routes/acode-todos.js";import{aiSourcesRouter as J}from"./routes/ai-sources.js";import{backgroundTasksRouter as Y}from"./routes/background-tasks.js";import{browserListenersRouter as Z}from"./routes/browser-listeners.js";import{browserSessionsRouter as q}from"./routes/browser-sessions.js";import{capabilitiesRouter as Q}from"./routes/capabilities.js";import{computerRouter as V}from"./routes/computer.js";import{dashboardRouter as X}from"./routes/dashboard.js";import{eventsRouter as ee}from"./routes/events.js";import{fileBrowserRouter as re}from"./routes/file-browser.js";import{fileChangeDiffRouter as te}from"./routes/file-change-diff.js";import{fileDiffRollbackRouter as ie}from"./routes/file-diff-rollback.js";import{fileSnapshotRouter as oe}from"./routes/file-snapshot.js";import{gitRouter as ne}from"./routes/git.js";import{instanceRouter as se,setGracefulShutdownFn as ae}from"./routes/instance.js";import{jdksRouter as me}from"./routes/jdks.js";import{launchRouter as ue}from"./routes/launch.js";import{attachLspWebSocketServer as ce}from"./routes/lsp.js";import{ltrRouter as de}from"./routes/ltr.js";import{mcpExtraRouter as ge}from"./routes/mcp-extra.js";import{mcpRouter as pe}from"./routes/mcp.js";import{pluginsRouter as fe}from"./routes/plugins.js";import{processesRouter as le}from"./routes/processes.js";import{propertiesRouter as be}from"./routes/properties.js";import{attachPtyWebSocketServer as he,closeAllPtySessions as we,ptyRouter as Re,ptySessions as Se}from"./routes/pty.js";import{runtimeBindingRouter as Pe,logRuntimeBindingStartupState as ye}from"./routes/runtime-binding.js";import{sessionsRouter as Ie}from"./routes/sessions.js";import{skillsRouter as $e}from"./routes/skills.js";import{subAgentsRouter as ke}from"./routes/sub-agents.js";import{systemMetricsRouter as Ae}from"./routes/system-metrics.js";import{taskContextRouter as Ce}from"./routes/task-context.js";import{terminalRouter as ve,sdkSessions as w}from"./routes/terminal.js";import{ymlRouter as Be}from"./routes/yml.js";import{accessControlMiddleware as Te}from"./services/access-control.js";import{ensureAcodePackageReleased as De,getReleasedAcodeEntryPath as Me}from"./services/acode-package.js";import{getAgentProcessManager as I}from"./services/agent-process-manager.js";import{autoRegister as Ee,unregister as xe,bridgeRestartCleanup as Fe,cancelBackgroundRegisterRetries as Ge}from"./services/auto-register.js";import{ensureAwsClientAgentMcpReleased as Oe}from"./services/aws-client-agent-mcp.js";import{disposeBrowserSessionManager as Le}from"./services/browser-session-manager.js";import{handleCliCommand as _e}from"./services/cli-commands.js";import{disposeDesktopMcpManager as je}from"./services/desktop-mcp-manager.js";import{getLaunchManager as Ke}from"./services/launch-manager.js";import{migrateOldPathsOnStartup as Ne}from"./services/legacy-path-migration.js";import{deliverPendingBridgeLifecycleNotifications as We}from"./services/lifecycle-state.js";import{startOrphanMonitor as He,stopOrphanMonitor as Ue}from"./services/orphan-monitor.js";import{pluginManager as ze}from"./services/plugin-manager.js";import{detectOrphanProcesses as Je}from"./services/process-detector.js";import{buildGracefulShutdownPlan as Ye,shouldCleanupPersistedSessionsOnStartup as Ze}from"./services/runtime-lifecycle-policy.js";import{ensureStartupConfig as qe}from"./services/startup-config-wizard.js";import{subAgentStore as Qe}from"./services/sub-agent-manager-instance.js";import{loadPersistedSessions as $,savePersistedSessions as k}from"./services/terminal-persistence.js";import{stopTunnelClient as Ve}from"./services/tunnel-client.js";import{logger as e}from"./utils/logger.js";const A=await _e();A.handled&&process.exit(A.exitCode),await qe(),W(),Oe(),De(),Ne(),ye(),await N(),H(),e.info(`[runtime-bridge] \u5DF2\u5199\u5165\u8FD0\u884C\u65F6\u914D\u7F6E ${j()}\uFF08port=${y()}\uFF09`),e.info(`[runtime-bridge] ACode \u6570\u636E\u76EE\u5F55(\u7528\u6237): ${O()}`),e.info(`[runtime-bridge] Bridge \u6570\u636E\u76EE\u5F55: ${_()}`),e.info(`[runtime-bridge] \u6A21\u677F\u914D\u7F6E: ${K()}`);async function Xe(){try{if(await Ee())e.info("[runtime-bridge] \u81EA\u52A8\u6CE8\u518C\u6210\u529F");else{const{loadConfig:o}=await import("./services/auto-register.js"),n=o();!!n.userKey&&n.enabled?e.warn("[runtime-bridge] \u81EA\u52A8\u6CE8\u518C\u6682\u65F6\u5931\u8D25\uFF0C\u5C06\u5728\u540E\u53F0\u6301\u7EED\u91CD\u8BD5\u76F4\u5230\u4E0E\u8C03\u5EA6\u4E2D\u5FC3\u5EFA\u7ACB\u8FDE\u63A5"):(e.info("[runtime-bridge] \u81EA\u52A8\u6CE8\u518C\u672A\u914D\u7F6E\uFF0C\u7EE7\u7EED\u542F\u52A8\u670D\u52A1"),e.info(`[runtime-bridge] \u8981\u542F\u7528\u81EA\u52A8\u6CE8\u518C\uFF0C\u8BF7\u521B\u5EFA\u914D\u7F6E\u6587\u4EF6 ${L()}`))}}catch(r){const o=r;e.warn("[runtime-bridge] \u81EA\u52A8\u6CE8\u518C\u51FA\u9519:",o.message)}}Xe().then(()=>er()).then(()=>We()).then(()=>{e.info("[runtime-bridge] Bridge \u751F\u547D\u5468\u671F\u901A\u77E5\u540C\u6B65\u5B8C\u6210")}).catch(r=>{e.warn("[runtime-bridge] \u81EA\u52A8\u6CE8\u518C\u6216\u6E05\u7406\u51FA\u9519:",r)}),import("./services/update-notifier.js").then(({startUpdateNotifier:r})=>r()).catch(r=>{e.warn("[runtime-bridge] \u7248\u672C\u68C0\u67E5\u670D\u52A1\u542F\u52A8\u5931\u8D25:",r.message)});async function er(){try{if(process.env.AWS_BRIDGE_RESTART_CLEANUP!=="true"){e.info("[runtime-bridge] \u8DF3\u8FC7 Bridge \u91CD\u542F\u6E05\u7406\uFF0C\u4FDD\u7559 Agent \u72B6\u6001\u4F9B\u8C03\u5EA6\u4E2D\u5FC3\u6062\u590D");return}const{getRegistrationState:r}=await import("./services/auto-register.js"),o=r();if(!o.registered||!o.instanceId){e.info("[runtime-bridge] \u5B9E\u4F8B\u672A\u6CE8\u518C\uFF0C\u8DF3\u8FC7 Bridge \u91CD\u542F\u6E05\u7406");return}e.info("[runtime-bridge] \u2605 Bridge \u91CD\u542F\u6E05\u7406\u5DF2\u663E\u5F0F\u542F\u7528\uFF0C\u6B63\u5728\u901A\u77E5\u8C03\u5EA6\u4E2D\u5FC3\u6E05\u7406 Agent \u72B6\u6001...");const n=await Fe();n.success?e.info(`[runtime-bridge] \u2605 Bridge \u91CD\u542F\u6E05\u7406\u6210\u529F\uFF0C\u6E05\u7406\u4E86 ${n.agentCount||0} \u4E2A Agent`):e.warn(`[runtime-bridge] \u2605 Bridge \u91CD\u542F\u6E05\u7406\u5931\u8D25: ${n.error}`)}catch(r){const o=r;e.warn("[runtime-bridge] Bridge \u91CD\u542F\u6E05\u7406\u51FA\u9519:",o.message)}}async function rr(){try{const r=await $();if(r.length===0){e.info("[runtime-bridge] \u65E0\u6301\u4E45\u5316\u4F1A\u8BDD\uFF0C\u8DF3\u8FC7\u8FDB\u7A0B\u6CE8\u518C\u8868\u91CD\u5EFA");return}await I().rebuildRegistry(r.map(n=>({agentId:n.agentId,sessionId:n.sessionId,pid:n.pid,workspacePath:n.workspacePath,command:n.command,mode:"sdk"}))),e.info(`[runtime-bridge] \u8FDB\u7A0B\u6CE8\u518C\u8868\u91CD\u5EFA\u5B8C\u6210: ${r.length} \u6761\u8BB0\u5F55`)}catch(r){const o=r;e.warn("[runtime-bridge] \u8FDB\u7A0B\u6CE8\u518C\u8868\u91CD\u5EFA\u5931\u8D25:",o.message)}}rr().catch(r=>{e.warn("[runtime-bridge] \u8FDB\u7A0B\u6CE8\u518C\u8868\u91CD\u5EFA\u5931\u8D25:",r)}),import(E(S.join(Me(),"..","background-command-manager.js")).href).then(async r=>{const o=r.backgroundCommandManager;if(!o||typeof o.reconcileAllAgents!="function"){e.warn("[runtime-bridge] \u540E\u53F0\u547D\u4EE4\u7BA1\u7406\u5668\u4E0D\u53EF\u7528\uFF0C\u8DF3\u8FC7\u542F\u52A8\u5B64\u513F\u5BF9\u8D26");return}const n=await o.reconcileAllAgents();n>0&&e.info(`[runtime-bridge] \u2605 \u542F\u52A8\u5B64\u513F\u5BF9\u8D26\u5B8C\u6210\uFF1A\u4FEE\u590D ${n} \u6761\u540E\u53F0\u547D\u4EE4\u72B6\u6001`)}).catch(r=>{e.warn("[runtime-bridge] \u542F\u52A8\u5B64\u513F\u5BF9\u8D26\u5931\u8D25:",r.message)});async function tr(){try{const r=await import("node:fs/promises"),o=await import("node:path"),n=await import("node:os"),f=o.join(n.tmpdir(),"agentswork-runtime-bridge",".preserve-sessions");let u=!1;try{const t=await r.readFile(f,"utf-8");u=JSON.parse(t).preserveSessions===!0,await r.unlink(f),e.info(`[runtime-bridge] \u2605 \u68C0\u6D4B\u5230\u4FDD\u7559\u4F1A\u8BDD\u6807\u8BB0\uFF0CpreserveSessions=${u}`)}catch{}const a=await $();if(a.length===0){e.info("[runtime-bridge] \u542F\u52A8\u65F6\u65E0\u6301\u4E45\u5316\u4F1A\u8BDD\uFF0C\u65E0\u9700\u68C0\u6D4B\u5B64\u513F\u8FDB\u7A0B");return}if(!Ze(u)){e.info(`[runtime-bridge] \u2605 \u4FDD\u7559 ${a.length} \u4E2A\u6301\u4E45\u5316\u4F1A\u8BDD\u5E76\u91CD\u5EFA\u8FDB\u7A0B\u6CE8\u518C\u8868`),await I().rebuildRegistry(a.map(s=>({agentId:s.agentId,sessionId:s.sessionId,pid:s.pid,workspacePath:s.workspacePath,command:s.command,mode:"sdk"})));return}e.info(`[runtime-bridge] \u2605 \u5DF2\u663E\u5F0F\u542F\u7528\u542F\u52A8\u6E05\u7406\uFF0C\u68C0\u6D4B ${a.length} \u4E2A\u6301\u4E45\u5316\u4F1A\u8BDD\u7684\u5B64\u513F\u8FDB\u7A0B...`);const d=await Je(a.map(t=>({agentId:t.agentId,pid:t.pid,workspacePath:t.workspacePath,command:t.command})));if(d.length>0){e.warn(`[runtime-bridge] \u2605 \u68C0\u6D4B\u5230 ${d.length} \u4E2A\u5B64\u513F\u8FDB\u7A0B\u4ECD\u5728\u8FD0\u884C\uFF1A`);for(const t of d)e.warn(` - agentId=${t.agentId}, pid=${t.process.pid}, command=${t.process.command?.slice(0,50)}`);e.info("[runtime-bridge] \u6B63\u5728\u81EA\u52A8\u6E05\u7406\u6240\u6709\u5B64\u513F\u8FDB\u7A0B...");for(const t of d)try{if(t.process.pid)if(process.platform==="win32"){const{execSync:s}=await import("node:child_process");s(`taskkill /PID ${t.process.pid} /T /F`,{encoding:"utf8",timeout:3e3}),e.info(`[runtime-bridge] \u5DF2\u81EA\u52A8\u7EC8\u6B62\u5B64\u513F\u8FDB\u7A0B: agentId=${t.agentId}, PID=${t.process.pid}`)}else process.kill(t.process.pid,"SIGKILL"),e.info(`[runtime-bridge] \u5DF2\u81EA\u52A8\u7EC8\u6B62\u5B64\u513F\u8FDB\u7A0B: agentId=${t.agentId}, PID=${t.process.pid}`)}catch(s){const c=s;e.warn(`[runtime-bridge] \u81EA\u52A8\u7EC8\u6B62\u5B64\u513F\u8FDB\u7A0B\u5931\u8D25: agentId=${t.agentId}, PID=${t.process.pid}, error=${c.message}`)}await new Promise(t=>setTimeout(t,1e3))}await k([]),e.info(`[runtime-bridge] \u2605 \u542F\u52A8\u6E05\u7406\u5B8C\u6210\uFF0C\u5DF2\u6E05\u7A7A\u6240\u6709\u6301\u4E45\u5316\u4F1A\u8BDD\uFF08\u6E05\u7406\u4E86 ${d.length} \u4E2A\u5B64\u513F\u8FDB\u7A0B\uFF09`)}catch(r){const o=r;e.warn("[runtime-bridge] \u542F\u52A8\u65F6\u5B64\u513F\u8FDB\u7A0B\u68C0\u6D4B\u5931\u8D25:",o.message)}}tr().catch(r=>{e.warn("[runtime-bridge] \u5B64\u513F\u8FDB\u7A0B\u68C0\u6D4B\u51FA\u9519:",r)}),He().catch(r=>{e.warn("[runtime-bridge] \u542F\u52A8\u5B64\u513F\u8FDB\u7A0B\u76D1\u63A7\u5931\u8D25:",r)});const i=P();i.use(Te),i.use(x()),i.use(P.json({limit:"1mb"})),i.use("/runtime",Pe),i.use("/runtime",be),i.use("/runtime",Be),i.use("/runtime",se),i.use("/runtime",$e),i.use("/runtime",pe),i.use("/runtime",Q),i.use("/runtime",ve),i.use("/runtime",Ie),i.use("/runtime",le),i.use("/runtime",ue),i.use("/runtime",me),i.use("/runtime",Ae),i.use("/runtime",ee),i.use("/runtime",ne),i.use("/runtime",oe),i.use("/runtime",z),i.use("/runtime",Y),i.use("/runtime",ke),i.use("/runtime",q),i.use("/runtime",Z),i.use("/runtime",fe),i.use("/runtime",ge),i.use("/runtime",J),i.use("/runtime",Ce),i.use("/runtime",ie),i.use("/runtime",te),i.use("/runtime/computer",V),i.use("/pty",Re),i.use("/",X),i.use("/api/file-browser",re),i.use("/api/ltr",de);function ir(){const r=y(),o=i.listen(r,()=>{e.info(`[runtime-bridge] listening on ${r}`)});return he(o),U(o),G(o),ce(o),o.on("error",n=>{if(n.code==="EADDRINUSE"){e.error(`[runtime-bridge] port ${r} became unavailable after reservation (another process grabbed it concurrently). Set AWS_RUNTIME_BRIDGE_PORT to a free port and restart.`),process.exitCode=1;return}e.error("[runtime-bridge] failed to start server:",n),process.exitCode=1}),o}let C=!1;async function b(r,o,n=!1){if(C){e.info(`[runtime-bridge] \u5DF2\u5728\u5173\u95ED\u4E2D\uFF0C\u5FFD\u7565 ${r}`);return}C=!0,n||R()&&(n=!0,e.info("[runtime-bridge] \u2605 \u68C0\u6D4B\u5230 .preserve-sessions \u6807\u8BB0\u6587\u4EF6\uFF0C\u81EA\u52A8\u5347\u7EA7\u4E3A\u4FDD\u7559\u4F1A\u8BDD\u6A21\u5F0F")),e.info(`[runtime-bridge] \u6536\u5230 ${r} \u4FE1\u53F7\uFF0C\u5F00\u59CB\u4F18\u96C5\u5173\u95ED... (preserveSessions=${n})`);const f=Date.now(),u=Ye(n);try{const a=w.size;if(u.terminateSdkSessions){e.info(`[runtime-bridge] \u6B63\u5728\u505C\u6B62 ${a} \u4E2A SDK \u4F1A\u8BDD...`);for(const[t,s]of w.entries())try{const c=s.providerId||"claude-code",g=F.get(c);let p="";try{const m=g.getSessionPid?.(t);m&&(p=` (PID: ${m})`)}catch{}await g.terminateSession(t),e.info(`[runtime-bridge] SDK \u4F1A\u8BDD ${t} \u5DF2\u7EC8\u6B62${p}`),w.delete(t)}catch(c){const g=c;e.error(`[runtime-bridge] SDK \u4F1A\u8BDD ${t} \u7EC8\u6B62\u5931\u8D25:`,g.message),w.delete(t)}}else e.info(`[runtime-bridge] \u2605 \u4FDD\u7559 ${a} \u4E2A SDK \u4F1A\u8BDD\uFF0C\u4E0D\u5728\u91CD\u542F\u6062\u590D\u573A\u666F\u4E2D\u7EC8\u6B62 Agent \u8FDB\u7A0B`);const l=Se.size;u.closePtySessions?(e.info(`[runtime-bridge] \u6B63\u5728\u505C\u6B62 ${l} \u4E2A PTY \u4F1A\u8BDD...`),we("shutdown")):e.info(`[runtime-bridge] \u2605 \u4FDD\u7559 ${l} \u4E2A PTY \u4F1A\u8BDD\uFF0C\u4E0D\u5728\u91CD\u542F\u6062\u590D\u573A\u666F\u4E2D\u5173\u95ED\u7EC8\u7AEF\u8FDB\u7A0B`);try{const{running:t,stopped:s}=await Ke().stopAll();t>0&&e.info(`[runtime-bridge] \u542F\u52A8\u9879\u8FDB\u7A0B\u5DF2\u505C\u6B62: running=${t}, stopped=${s}`)}catch(t){e.warn("[runtime-bridge] \u505C\u6B62\u542F\u52A8\u9879\u8FDB\u7A0B\u5931\u8D25:",t.message)}e.info("[runtime-bridge] \u6B63\u5728\u505C\u6B62\u5B64\u513F\u8FDB\u7A0B\u76D1\u63A7...");try{const c=(await import("file://"+S.join(__dirname,"..","package","acode","dist","background-command-manager.js")).catch(()=>({backgroundCommandManager:null}))).backgroundCommandManager;c&&(e.info("[runtime-bridge] \u6B63\u5728\u6E05\u7406\u540E\u53F0\u547D\u4EE4..."),await c.disposeAll())}catch(t){e.warn("[runtime-bridge] \u540E\u53F0\u547D\u4EE4\u6E05\u7406\u5931\u8D25: %s",t?.message)}if(Ue(),u.terminateResidualProcesses&&(e.info("[runtime-bridge] \u7B49\u5F85\u8FDB\u7A0B\u5B8C\u5168\u7EC8\u6B62..."),await new Promise(t=>setTimeout(t,1e3))),u.terminateResidualProcesses)try{const{detectOrphanProcesses:t,terminateProcessTree:s}=await import("./services/process-detector.js"),{loadPersistedSessions:c}=await import("./services/terminal-persistence.js"),g=await c();if(g.length>0){const p=await t(g.map(m=>({agentId:m.agentId,pid:m.pid,workspacePath:m.workspacePath,command:m.command})));if(p.length>0){e.warn(`[runtime-bridge] \u68C0\u6D4B\u5230 ${p.length} \u4E2A\u6B8B\u7559\u8FDB\u7A0B\uFF0C\u6B63\u5728\u5F3A\u5236\u7EC8\u6B62...`);for(const m of p)if(m.process.pid){const B=await s(m.process.pid);e.info(`[runtime-bridge] \u5DF2\u5F3A\u5236\u7EC8\u6B62\u6B8B\u7559\u8FDB\u7A0B\u6811\uFF1AagentId=${m.agentId}, PID=${m.process.pid}, \u7EC8\u6B62\u4E86 ${B.terminated} \u4E2A\u8FDB\u7A0B`)}}}}catch(t){const s=t;e.warn("[runtime-bridge] \u6B8B\u7559\u8FDB\u7A0B\u68C0\u67E5\u5931\u8D25:",s.message)}else e.info("[runtime-bridge] \u2605 \u4FDD\u7559\u6A21\u5F0F\u8DF3\u8FC7\u6B8B\u7559\u8FDB\u7A0B\u5F3A\u5236\u7EC8\u6B62\uFF0C\u7B49\u5F85\u8C03\u5EA6\u4E2D\u5FC3\u6062\u590D\u4F1A\u8BDD");if(u.unregisterInstance){e.info("[runtime-bridge] \u6B63\u5728\u6CE8\u9500\u5B9E\u4F8B...");try{await xe()}catch(t){const s=t;e.error("[runtime-bridge] \u6CE8\u9500\u5B9E\u4F8B\u5931\u8D25:",s.message)}}else e.info("[runtime-bridge] \u2605 \u4FDD\u7559\u6A21\u5F0F\u8DF3\u8FC7\u5B9E\u4F8B\u6CE8\u9500\uFF0C\u907F\u514D\u8C03\u5EA6\u4E2D\u5FC3\u5C06 Agent \u6807\u8BB0\u4E3A stopped");if(Ge(),u.stopTunnelClient&&(e.info("[runtime-bridge] \u6B63\u5728\u5173\u95ED\u96A7\u9053\u5BA2\u6237\u7AEF..."),Ve()),u.clearPersistedSessions){e.info("[runtime-bridge] \u6B63\u5728\u6E05\u7A7A\u6301\u4E45\u5316\u4F1A\u8BDD\u72B6\u6001...");try{await k([])}catch(t){const s=t;e.error("[runtime-bridge] \u6E05\u7A7A\u6301\u4E45\u5316\u72B6\u6001\u5931\u8D25:",s.message)}}else e.info("[runtime-bridge] \u2605 \u4FDD\u7559\u6301\u4E45\u5316\u4F1A\u8BDD\u72B6\u6001\uFF08aws-mcp-server \u91CD\u542F\u6062\u590D\u573A\u666F\uFF09");try{await Le(),e.info("[runtime-bridge] browser \u5DE5\u5177\u6808\u5DF2\u6E05\u7406")}catch(t){e.warn("[runtime-bridge] browser \u5DE5\u5177\u6808\u6E05\u7406\u5931\u8D25:",t.message)}try{await je(),e.info("[runtime-bridge] desktop \u5DE5\u5177\u6808\u5DF2\u6E05\u7406")}catch(t){e.warn("[runtime-bridge] desktop \u5DE5\u5177\u6808\u6E05\u7406\u5931\u8D25:",t.message)}try{await ze.stopAll(),e.info("[runtime-bridge] \u63D2\u4EF6\u76D1\u542C\u8FDB\u7A0B\u5DF2\u6E05\u7406")}catch(t){e.warn("[runtime-bridge] \u63D2\u4EF6\u76D1\u542C\u8FDB\u7A0B\u6E05\u7406\u5931\u8D25:",t.message)}const d=Date.now()-f;e.info(`[runtime-bridge] \u4F18\u96C5\u5173\u95ED\u5B8C\u6210 (\u8017\u65F6 ${d}ms)\uFF0C\u505C\u6B62 ${a} SDK \u4F1A\u8BDD`),o.close(()=>{e.info("[runtime-bridge] HTTP \u670D\u52A1\u5668\u5DF2\u5173\u95ED"),process.exit(process.exitCode||0)}),setTimeout(()=>{e.warn("[runtime-bridge] \u4F18\u96C5\u5173\u95ED\u8D85\u65F6\uFF0C\u5F3A\u5236\u9000\u51FA"),process.exit(1)},15e3)}catch(a){const l=a;e.error("[runtime-bridge] \u4F18\u96C5\u5173\u95ED\u8FC7\u7A0B\u4E2D\u53D1\u751F\u9519\u8BEF:",l),process.exit(1)}}Qe.reconcileZombies().then(r=>{r>0&&e.info(`[runtime-bridge] \u5DF2\u6E05\u7406 ${r} \u4E2A\u50F5\u5C38 sub-agent \u8BB0\u5F55`)}).catch(r=>{e.warn("[runtime-bridge] \u6E05\u7406\u50F5\u5C38 sub-agent \u8BB0\u5F55\u5931\u8D25:",r.message)});const h=ir(),v=S.join(M.tmpdir(),"agentswork-runtime-bridge",".preserve-sessions");function R(){try{if(T(v)){const r=D(v,"utf-8");return JSON.parse(r).preserveSessions===!0}}catch{}return!1}ae(async(r,o)=>{await b(r,h,o)}),process.on("SIGTERM",()=>{const r=R();b("SIGTERM",h,r)}),process.on("SIGINT",()=>{const r=R();b("SIGINT",h,r)}),process.platform==="win32"&&process.on("SIGBREAK",()=>{const r=R();b("SIGBREAK",h,r)}),process.on("uncaughtException",r=>{e.error("[runtime-bridge] \u672A\u6355\u83B7\u5F02\u5E38:",r),b("uncaughtException",h)}),process.on("unhandledRejection",r=>{e.error("[runtime-bridge] \u672A\u5904\u7406\u7684 Promise \u62D2\u7EDD:",r)});
|
|
2
|
+
import{existsSync as T,readFileSync as D}from"node:fs";import M from"node:os";import S from"node:path";import{pathToFileURL as E}from"node:url";import x from"cors";import P from"express";import{adapterRegistry as F}from"./adapter/index.js";import{attachBrowserWebSocketServer as G}from"./browser/browser-ws-bridge.js";import{getAcodeDataHome as O,getActiveBridgeHttpPort as y,getAutoRegisterConfigFilePath as L,getBridgeDataHome as _,getBridgeRuntimePropertiesFilePath as j,getBridgeTemplateConfigFile as K,reserveBridgeListenPort as N,validateProductionToken as W,writeBridgeRuntimePropertiesFile as H}from"./config.js";import{attachRemoteDesktopWebSocketServer as U}from"./remote-desktop/index.js";import{acodeTodosRouter as z}from"./routes/acode-todos.js";import{agentStateRouter as J}from"./routes/agent-state.js";import{aiSourcesRouter as Y}from"./routes/ai-sources.js";import{backgroundTasksRouter as Z}from"./routes/background-tasks.js";import{browserListenersRouter as q}from"./routes/browser-listeners.js";import{browserSessionsRouter as Q}from"./routes/browser-sessions.js";import{capabilitiesRouter as V}from"./routes/capabilities.js";import{computerRouter as X}from"./routes/computer.js";import{dashboardRouter as ee}from"./routes/dashboard.js";import{eventsRouter as re}from"./routes/events.js";import{fileBrowserRouter as te}from"./routes/file-browser.js";import{fileChangeDiffRouter as ie}from"./routes/file-change-diff.js";import{fileDiffRollbackRouter as oe}from"./routes/file-diff-rollback.js";import{fileSnapshotRouter as ne}from"./routes/file-snapshot.js";import{gitRouter as se}from"./routes/git.js";import{instanceRouter as ae,setGracefulShutdownFn as me}from"./routes/instance.js";import{jdksRouter as ue}from"./routes/jdks.js";import{launchRouter as ce}from"./routes/launch.js";import{attachLspWebSocketServer as de}from"./routes/lsp.js";import{ltrRouter as ge}from"./routes/ltr.js";import{debugMountRouter as pe}from"./routes/debug-mount.js";import{mcpExtraRouter as fe}from"./routes/mcp-extra.js";import{mcpRouter as le}from"./routes/mcp.js";import{pluginsRouter as be}from"./routes/plugins.js";import{processesRouter as he}from"./routes/processes.js";import{propertiesRouter as we}from"./routes/properties.js";import{attachPtyWebSocketServer as Re,closeAllPtySessions as Se,ptyRouter as Pe,ptySessions as ye}from"./routes/pty.js";import{runtimeBindingRouter as Ie,logRuntimeBindingStartupState as $e}from"./routes/runtime-binding.js";import{sessionsRouter as ke}from"./routes/sessions.js";import{skillsRouter as Ae}from"./routes/skills.js";import{subAgentsRouter as Ce}from"./routes/sub-agents.js";import{systemMetricsRouter as ve}from"./routes/system-metrics.js";import{taskContextRouter as Be}from"./routes/task-context.js";import{terminalRouter as Te,sdkSessions as w}from"./routes/terminal.js";import{ymlRouter as De}from"./routes/yml.js";import{accessControlMiddleware as Me}from"./services/access-control.js";import{ensureAcodePackageReleased as Ee,getReleasedAcodeEntryPath as xe}from"./services/acode-package.js";import{getAgentProcessManager as I}from"./services/agent-process-manager.js";import{autoRegister as Fe,unregister as Ge,bridgeRestartCleanup as Oe,cancelBackgroundRegisterRetries as Le}from"./services/auto-register.js";import{ensureAwsClientAgentMcpReleased as _e}from"./services/aws-client-agent-mcp.js";import{disposeBrowserSessionManager as je}from"./services/browser-session-manager.js";import{handleCliCommand as Ke}from"./services/cli-commands.js";import{disposeDesktopMcpManager as Ne}from"./services/desktop-mcp-manager.js";import{getLaunchManager as We}from"./services/launch-manager.js";import{migrateOldPathsOnStartup as He}from"./services/legacy-path-migration.js";import{deliverPendingBridgeLifecycleNotifications as Ue}from"./services/lifecycle-state.js";import{startOrphanMonitor as ze,stopOrphanMonitor as Je}from"./services/orphan-monitor.js";import{pluginManager as Ye}from"./services/plugin-manager.js";import{detectOrphanProcesses as Ze}from"./services/process-detector.js";import{buildGracefulShutdownPlan as qe,shouldCleanupPersistedSessionsOnStartup as Qe}from"./services/runtime-lifecycle-policy.js";import{ensureStartupConfig as Ve}from"./services/startup-config-wizard.js";import{subAgentStore as Xe}from"./services/sub-agent-manager-instance.js";import{loadPersistedSessions as $,savePersistedSessions as k}from"./services/terminal-persistence.js";import{stopTunnelClient as er}from"./services/tunnel-client.js";import{logger as e}from"./utils/logger.js";const A=await Ke();A.handled&&process.exit(A.exitCode),await Ve(),W(),_e(),Ee(),He(),$e(),await N(),H(),e.info(`[runtime-bridge] \u5DF2\u5199\u5165\u8FD0\u884C\u65F6\u914D\u7F6E ${j()}\uFF08port=${y()}\uFF09`),e.info(`[runtime-bridge] ACode \u6570\u636E\u76EE\u5F55(\u7528\u6237): ${O()}`),e.info(`[runtime-bridge] Bridge \u6570\u636E\u76EE\u5F55: ${_()}`),e.info(`[runtime-bridge] \u6A21\u677F\u914D\u7F6E: ${K()}`);async function rr(){try{if(await Fe())e.info("[runtime-bridge] \u81EA\u52A8\u6CE8\u518C\u6210\u529F");else{const{loadConfig:o}=await import("./services/auto-register.js"),n=o();!!n.userKey&&n.enabled?e.warn("[runtime-bridge] \u81EA\u52A8\u6CE8\u518C\u6682\u65F6\u5931\u8D25\uFF0C\u5C06\u5728\u540E\u53F0\u6301\u7EED\u91CD\u8BD5\u76F4\u5230\u4E0E\u8C03\u5EA6\u4E2D\u5FC3\u5EFA\u7ACB\u8FDE\u63A5"):(e.info("[runtime-bridge] \u81EA\u52A8\u6CE8\u518C\u672A\u914D\u7F6E\uFF0C\u7EE7\u7EED\u542F\u52A8\u670D\u52A1"),e.info(`[runtime-bridge] \u8981\u542F\u7528\u81EA\u52A8\u6CE8\u518C\uFF0C\u8BF7\u521B\u5EFA\u914D\u7F6E\u6587\u4EF6 ${L()}`))}}catch(r){const o=r;e.warn("[runtime-bridge] \u81EA\u52A8\u6CE8\u518C\u51FA\u9519:",o.message)}}rr().then(()=>tr()).then(()=>Ue()).then(()=>{e.info("[runtime-bridge] Bridge \u751F\u547D\u5468\u671F\u901A\u77E5\u540C\u6B65\u5B8C\u6210")}).catch(r=>{e.warn("[runtime-bridge] \u81EA\u52A8\u6CE8\u518C\u6216\u6E05\u7406\u51FA\u9519:",r)}),import("./services/update-notifier.js").then(({startUpdateNotifier:r})=>r()).catch(r=>{e.warn("[runtime-bridge] \u7248\u672C\u68C0\u67E5\u670D\u52A1\u542F\u52A8\u5931\u8D25:",r.message)});async function tr(){try{if(process.env.AWS_BRIDGE_RESTART_CLEANUP!=="true"){e.info("[runtime-bridge] \u8DF3\u8FC7 Bridge \u91CD\u542F\u6E05\u7406\uFF0C\u4FDD\u7559 Agent \u72B6\u6001\u4F9B\u8C03\u5EA6\u4E2D\u5FC3\u6062\u590D");return}const{getRegistrationState:r}=await import("./services/auto-register.js"),o=r();if(!o.registered||!o.instanceId){e.info("[runtime-bridge] \u5B9E\u4F8B\u672A\u6CE8\u518C\uFF0C\u8DF3\u8FC7 Bridge \u91CD\u542F\u6E05\u7406");return}e.info("[runtime-bridge] \u2605 Bridge \u91CD\u542F\u6E05\u7406\u5DF2\u663E\u5F0F\u542F\u7528\uFF0C\u6B63\u5728\u901A\u77E5\u8C03\u5EA6\u4E2D\u5FC3\u6E05\u7406 Agent \u72B6\u6001...");const n=await Oe();n.success?e.info(`[runtime-bridge] \u2605 Bridge \u91CD\u542F\u6E05\u7406\u6210\u529F\uFF0C\u6E05\u7406\u4E86 ${n.agentCount||0} \u4E2A Agent`):e.warn(`[runtime-bridge] \u2605 Bridge \u91CD\u542F\u6E05\u7406\u5931\u8D25: ${n.error}`)}catch(r){const o=r;e.warn("[runtime-bridge] Bridge \u91CD\u542F\u6E05\u7406\u51FA\u9519:",o.message)}}async function ir(){try{const r=await $();if(r.length===0){e.info("[runtime-bridge] \u65E0\u6301\u4E45\u5316\u4F1A\u8BDD\uFF0C\u8DF3\u8FC7\u8FDB\u7A0B\u6CE8\u518C\u8868\u91CD\u5EFA");return}await I().rebuildRegistry(r.map(n=>({agentId:n.agentId,sessionId:n.sessionId,pid:n.pid,workspacePath:n.workspacePath,command:n.command,mode:"sdk"}))),e.info(`[runtime-bridge] \u8FDB\u7A0B\u6CE8\u518C\u8868\u91CD\u5EFA\u5B8C\u6210: ${r.length} \u6761\u8BB0\u5F55`)}catch(r){const o=r;e.warn("[runtime-bridge] \u8FDB\u7A0B\u6CE8\u518C\u8868\u91CD\u5EFA\u5931\u8D25:",o.message)}}ir().catch(r=>{e.warn("[runtime-bridge] \u8FDB\u7A0B\u6CE8\u518C\u8868\u91CD\u5EFA\u5931\u8D25:",r)}),import(E(S.join(xe(),"..","background-command-manager.js")).href).then(async r=>{const o=r.backgroundCommandManager;if(!o||typeof o.reconcileAllAgents!="function"){e.warn("[runtime-bridge] \u540E\u53F0\u547D\u4EE4\u7BA1\u7406\u5668\u4E0D\u53EF\u7528\uFF0C\u8DF3\u8FC7\u542F\u52A8\u5B64\u513F\u5BF9\u8D26");return}const n=await o.reconcileAllAgents();n>0&&e.info(`[runtime-bridge] \u2605 \u542F\u52A8\u5B64\u513F\u5BF9\u8D26\u5B8C\u6210\uFF1A\u4FEE\u590D ${n} \u6761\u540E\u53F0\u547D\u4EE4\u72B6\u6001`)}).catch(r=>{e.warn("[runtime-bridge] \u542F\u52A8\u5B64\u513F\u5BF9\u8D26\u5931\u8D25:",r.message)});async function or(){try{const r=await import("node:fs/promises"),o=await import("node:path"),n=await import("node:os"),f=o.join(n.tmpdir(),"agentswork-runtime-bridge",".preserve-sessions");let u=!1;try{const t=await r.readFile(f,"utf-8");u=JSON.parse(t).preserveSessions===!0,await r.unlink(f),e.info(`[runtime-bridge] \u2605 \u68C0\u6D4B\u5230\u4FDD\u7559\u4F1A\u8BDD\u6807\u8BB0\uFF0CpreserveSessions=${u}`)}catch{}const a=await $();if(a.length===0){e.info("[runtime-bridge] \u542F\u52A8\u65F6\u65E0\u6301\u4E45\u5316\u4F1A\u8BDD\uFF0C\u65E0\u9700\u68C0\u6D4B\u5B64\u513F\u8FDB\u7A0B");return}if(!Qe(u)){e.info(`[runtime-bridge] \u2605 \u4FDD\u7559 ${a.length} \u4E2A\u6301\u4E45\u5316\u4F1A\u8BDD\u5E76\u91CD\u5EFA\u8FDB\u7A0B\u6CE8\u518C\u8868`),await I().rebuildRegistry(a.map(s=>({agentId:s.agentId,sessionId:s.sessionId,pid:s.pid,workspacePath:s.workspacePath,command:s.command,mode:"sdk"})));return}e.info(`[runtime-bridge] \u2605 \u5DF2\u663E\u5F0F\u542F\u7528\u542F\u52A8\u6E05\u7406\uFF0C\u68C0\u6D4B ${a.length} \u4E2A\u6301\u4E45\u5316\u4F1A\u8BDD\u7684\u5B64\u513F\u8FDB\u7A0B...`);const d=await Ze(a.map(t=>({agentId:t.agentId,pid:t.pid,workspacePath:t.workspacePath,command:t.command})));if(d.length>0){e.warn(`[runtime-bridge] \u2605 \u68C0\u6D4B\u5230 ${d.length} \u4E2A\u5B64\u513F\u8FDB\u7A0B\u4ECD\u5728\u8FD0\u884C\uFF1A`);for(const t of d)e.warn(` - agentId=${t.agentId}, pid=${t.process.pid}, command=${t.process.command?.slice(0,50)}`);e.info("[runtime-bridge] \u6B63\u5728\u81EA\u52A8\u6E05\u7406\u6240\u6709\u5B64\u513F\u8FDB\u7A0B...");for(const t of d)try{if(t.process.pid)if(process.platform==="win32"){const{execSync:s}=await import("node:child_process");s(`taskkill /PID ${t.process.pid} /T /F`,{encoding:"utf8",timeout:3e3}),e.info(`[runtime-bridge] \u5DF2\u81EA\u52A8\u7EC8\u6B62\u5B64\u513F\u8FDB\u7A0B: agentId=${t.agentId}, PID=${t.process.pid}`)}else process.kill(t.process.pid,"SIGKILL"),e.info(`[runtime-bridge] \u5DF2\u81EA\u52A8\u7EC8\u6B62\u5B64\u513F\u8FDB\u7A0B: agentId=${t.agentId}, PID=${t.process.pid}`)}catch(s){const c=s;e.warn(`[runtime-bridge] \u81EA\u52A8\u7EC8\u6B62\u5B64\u513F\u8FDB\u7A0B\u5931\u8D25: agentId=${t.agentId}, PID=${t.process.pid}, error=${c.message}`)}await new Promise(t=>setTimeout(t,1e3))}await k([]),e.info(`[runtime-bridge] \u2605 \u542F\u52A8\u6E05\u7406\u5B8C\u6210\uFF0C\u5DF2\u6E05\u7A7A\u6240\u6709\u6301\u4E45\u5316\u4F1A\u8BDD\uFF08\u6E05\u7406\u4E86 ${d.length} \u4E2A\u5B64\u513F\u8FDB\u7A0B\uFF09`)}catch(r){const o=r;e.warn("[runtime-bridge] \u542F\u52A8\u65F6\u5B64\u513F\u8FDB\u7A0B\u68C0\u6D4B\u5931\u8D25:",o.message)}}or().catch(r=>{e.warn("[runtime-bridge] \u5B64\u513F\u8FDB\u7A0B\u68C0\u6D4B\u51FA\u9519:",r)}),ze().catch(r=>{e.warn("[runtime-bridge] \u542F\u52A8\u5B64\u513F\u8FDB\u7A0B\u76D1\u63A7\u5931\u8D25:",r)});const i=P();i.use(Me),i.use(x()),i.use(P.json({limit:"1mb"})),i.use("/runtime",Ie),i.use("/runtime",we),i.use("/runtime",De),i.use("/runtime",ae),i.use("/runtime",Ae),i.use("/runtime",le),i.use("/runtime",V),i.use("/runtime",Te),i.use("/runtime",ke),i.use("/runtime",he),i.use("/runtime",ce),i.use("/runtime",ue),i.use("/runtime",ve),i.use("/runtime",re),i.use("/runtime",se),i.use("/runtime",ne),i.use("/runtime",z),i.use("/runtime",J),i.use("/runtime",Z),i.use("/runtime",Ce),i.use("/runtime",Q),i.use("/runtime",q),i.use("/runtime",be),i.use("/runtime",fe),i.use("/runtime",pe),i.use("/runtime",Y),i.use("/runtime",Be),i.use("/runtime",oe),i.use("/runtime",ie),i.use("/runtime/computer",X),i.use("/pty",Pe),i.use("/",ee),i.use("/api/file-browser",te),i.use("/api/ltr",ge);function nr(){const r=y(),o=i.listen(r,()=>{e.info(`[runtime-bridge] listening on ${r}`)});return Re(o),U(o),G(o),de(o),o.on("error",n=>{if(n.code==="EADDRINUSE"){e.error(`[runtime-bridge] port ${r} became unavailable after reservation (another process grabbed it concurrently). Set AWS_RUNTIME_BRIDGE_PORT to a free port and restart.`),process.exitCode=1;return}e.error("[runtime-bridge] failed to start server:",n),process.exitCode=1}),o}let C=!1;async function b(r,o,n=!1){if(C){e.info(`[runtime-bridge] \u5DF2\u5728\u5173\u95ED\u4E2D\uFF0C\u5FFD\u7565 ${r}`);return}C=!0,n||R()&&(n=!0,e.info("[runtime-bridge] \u2605 \u68C0\u6D4B\u5230 .preserve-sessions \u6807\u8BB0\u6587\u4EF6\uFF0C\u81EA\u52A8\u5347\u7EA7\u4E3A\u4FDD\u7559\u4F1A\u8BDD\u6A21\u5F0F")),e.info(`[runtime-bridge] \u6536\u5230 ${r} \u4FE1\u53F7\uFF0C\u5F00\u59CB\u4F18\u96C5\u5173\u95ED... (preserveSessions=${n})`);const f=Date.now(),u=qe(n);try{const a=w.size;if(u.terminateSdkSessions){e.info(`[runtime-bridge] \u6B63\u5728\u505C\u6B62 ${a} \u4E2A SDK \u4F1A\u8BDD...`);for(const[t,s]of w.entries())try{const c=s.providerId||"claude-code",g=F.get(c);let p="";try{const m=g.getSessionPid?.(t);m&&(p=` (PID: ${m})`)}catch{}await g.terminateSession(t),e.info(`[runtime-bridge] SDK \u4F1A\u8BDD ${t} \u5DF2\u7EC8\u6B62${p}`),w.delete(t)}catch(c){const g=c;e.error(`[runtime-bridge] SDK \u4F1A\u8BDD ${t} \u7EC8\u6B62\u5931\u8D25:`,g.message),w.delete(t)}}else e.info(`[runtime-bridge] \u2605 \u4FDD\u7559 ${a} \u4E2A SDK \u4F1A\u8BDD\uFF0C\u4E0D\u5728\u91CD\u542F\u6062\u590D\u573A\u666F\u4E2D\u7EC8\u6B62 Agent \u8FDB\u7A0B`);const l=ye.size;u.closePtySessions?(e.info(`[runtime-bridge] \u6B63\u5728\u505C\u6B62 ${l} \u4E2A PTY \u4F1A\u8BDD...`),Se("shutdown")):e.info(`[runtime-bridge] \u2605 \u4FDD\u7559 ${l} \u4E2A PTY \u4F1A\u8BDD\uFF0C\u4E0D\u5728\u91CD\u542F\u6062\u590D\u573A\u666F\u4E2D\u5173\u95ED\u7EC8\u7AEF\u8FDB\u7A0B`);try{const{running:t,stopped:s}=await We().stopAll();t>0&&e.info(`[runtime-bridge] \u542F\u52A8\u9879\u8FDB\u7A0B\u5DF2\u505C\u6B62: running=${t}, stopped=${s}`)}catch(t){e.warn("[runtime-bridge] \u505C\u6B62\u542F\u52A8\u9879\u8FDB\u7A0B\u5931\u8D25:",t.message)}e.info("[runtime-bridge] \u6B63\u5728\u505C\u6B62\u5B64\u513F\u8FDB\u7A0B\u76D1\u63A7...");try{const c=(await import("file://"+S.join(__dirname,"..","package","acode","dist","background-command-manager.js")).catch(()=>({backgroundCommandManager:null}))).backgroundCommandManager;c&&(e.info("[runtime-bridge] \u6B63\u5728\u6E05\u7406\u540E\u53F0\u547D\u4EE4..."),await c.disposeAll())}catch(t){e.warn("[runtime-bridge] \u540E\u53F0\u547D\u4EE4\u6E05\u7406\u5931\u8D25: %s",t?.message)}if(Je(),u.terminateResidualProcesses&&(e.info("[runtime-bridge] \u7B49\u5F85\u8FDB\u7A0B\u5B8C\u5168\u7EC8\u6B62..."),await new Promise(t=>setTimeout(t,1e3))),u.terminateResidualProcesses)try{const{detectOrphanProcesses:t,terminateProcessTree:s}=await import("./services/process-detector.js"),{loadPersistedSessions:c}=await import("./services/terminal-persistence.js"),g=await c();if(g.length>0){const p=await t(g.map(m=>({agentId:m.agentId,pid:m.pid,workspacePath:m.workspacePath,command:m.command})));if(p.length>0){e.warn(`[runtime-bridge] \u68C0\u6D4B\u5230 ${p.length} \u4E2A\u6B8B\u7559\u8FDB\u7A0B\uFF0C\u6B63\u5728\u5F3A\u5236\u7EC8\u6B62...`);for(const m of p)if(m.process.pid){const B=await s(m.process.pid);e.info(`[runtime-bridge] \u5DF2\u5F3A\u5236\u7EC8\u6B62\u6B8B\u7559\u8FDB\u7A0B\u6811\uFF1AagentId=${m.agentId}, PID=${m.process.pid}, \u7EC8\u6B62\u4E86 ${B.terminated} \u4E2A\u8FDB\u7A0B`)}}}}catch(t){const s=t;e.warn("[runtime-bridge] \u6B8B\u7559\u8FDB\u7A0B\u68C0\u67E5\u5931\u8D25:",s.message)}else e.info("[runtime-bridge] \u2605 \u4FDD\u7559\u6A21\u5F0F\u8DF3\u8FC7\u6B8B\u7559\u8FDB\u7A0B\u5F3A\u5236\u7EC8\u6B62\uFF0C\u7B49\u5F85\u8C03\u5EA6\u4E2D\u5FC3\u6062\u590D\u4F1A\u8BDD");if(u.unregisterInstance){e.info("[runtime-bridge] \u6B63\u5728\u6CE8\u9500\u5B9E\u4F8B...");try{await Ge()}catch(t){const s=t;e.error("[runtime-bridge] \u6CE8\u9500\u5B9E\u4F8B\u5931\u8D25:",s.message)}}else e.info("[runtime-bridge] \u2605 \u4FDD\u7559\u6A21\u5F0F\u8DF3\u8FC7\u5B9E\u4F8B\u6CE8\u9500\uFF0C\u907F\u514D\u8C03\u5EA6\u4E2D\u5FC3\u5C06 Agent \u6807\u8BB0\u4E3A stopped");if(Le(),u.stopTunnelClient&&(e.info("[runtime-bridge] \u6B63\u5728\u5173\u95ED\u96A7\u9053\u5BA2\u6237\u7AEF..."),er()),u.clearPersistedSessions){e.info("[runtime-bridge] \u6B63\u5728\u6E05\u7A7A\u6301\u4E45\u5316\u4F1A\u8BDD\u72B6\u6001...");try{await k([])}catch(t){const s=t;e.error("[runtime-bridge] \u6E05\u7A7A\u6301\u4E45\u5316\u72B6\u6001\u5931\u8D25:",s.message)}}else e.info("[runtime-bridge] \u2605 \u4FDD\u7559\u6301\u4E45\u5316\u4F1A\u8BDD\u72B6\u6001\uFF08aws-mcp-server \u91CD\u542F\u6062\u590D\u573A\u666F\uFF09");try{await je(),e.info("[runtime-bridge] browser \u5DE5\u5177\u6808\u5DF2\u6E05\u7406")}catch(t){e.warn("[runtime-bridge] browser \u5DE5\u5177\u6808\u6E05\u7406\u5931\u8D25:",t.message)}try{await Ne(),e.info("[runtime-bridge] desktop \u5DE5\u5177\u6808\u5DF2\u6E05\u7406")}catch(t){e.warn("[runtime-bridge] desktop \u5DE5\u5177\u6808\u6E05\u7406\u5931\u8D25:",t.message)}try{await Ye.stopAll(),e.info("[runtime-bridge] \u63D2\u4EF6\u76D1\u542C\u8FDB\u7A0B\u5DF2\u6E05\u7406")}catch(t){e.warn("[runtime-bridge] \u63D2\u4EF6\u76D1\u542C\u8FDB\u7A0B\u6E05\u7406\u5931\u8D25:",t.message)}const d=Date.now()-f;e.info(`[runtime-bridge] \u4F18\u96C5\u5173\u95ED\u5B8C\u6210 (\u8017\u65F6 ${d}ms)\uFF0C\u505C\u6B62 ${a} SDK \u4F1A\u8BDD`),o.close(()=>{e.info("[runtime-bridge] HTTP \u670D\u52A1\u5668\u5DF2\u5173\u95ED"),process.exit(process.exitCode||0)}),setTimeout(()=>{e.warn("[runtime-bridge] \u4F18\u96C5\u5173\u95ED\u8D85\u65F6\uFF0C\u5F3A\u5236\u9000\u51FA"),process.exit(1)},15e3)}catch(a){const l=a;e.error("[runtime-bridge] \u4F18\u96C5\u5173\u95ED\u8FC7\u7A0B\u4E2D\u53D1\u751F\u9519\u8BEF:",l),process.exit(1)}}Xe.reconcileZombies().then(r=>{r>0&&e.info(`[runtime-bridge] \u5DF2\u6E05\u7406 ${r} \u4E2A\u50F5\u5C38 sub-agent \u8BB0\u5F55`)}).catch(r=>{e.warn("[runtime-bridge] \u6E05\u7406\u50F5\u5C38 sub-agent \u8BB0\u5F55\u5931\u8D25:",r.message)});const h=nr(),v=S.join(M.tmpdir(),"agentswork-runtime-bridge",".preserve-sessions");function R(){try{if(T(v)){const r=D(v,"utf-8");return JSON.parse(r).preserveSessions===!0}}catch{}return!1}me(async(r,o)=>{await b(r,h,o)}),process.on("SIGTERM",()=>{const r=R();b("SIGTERM",h,r)}),process.on("SIGINT",()=>{const r=R();b("SIGINT",h,r)}),process.platform==="win32"&&process.on("SIGBREAK",()=>{const r=R();b("SIGBREAK",h,r)}),process.on("uncaughtException",r=>{e.error("[runtime-bridge] \u672A\u6355\u83B7\u5F02\u5E38:",r),b("uncaughtException",h)}),process.on("unhandledRejection",r=>{e.error("[runtime-bridge] \u672A\u5904\u7406\u7684 Promise \u62D2\u7EDD:",r)});
|
|
3
3
|
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{promises as u}from"node:fs";import f from"node:path";import{Router as g}from"express";import{getAcodeDataHome as l}from"../config.js";import{validateToken as m}from"../middleware/auth.js";import{getAcodeBgManager as k}from"../services/acode-bg-manager.js";import{closeBrowserSession as d}from"../services/browser-session-manager.js";import{subAgentManager as c}from"../services/sub-agent-manager-instance.js";import{createLogger as y}from"../utils/logger.js";const i=y("agent-state"),b=g(),p=new Set(["todos","bgTasks","subAgents","browserSessions"]);function w(t){return String(t).replace(/[^a-zA-Z0-9_-]/g,"_")}function S(t){return f.join(l(),"todos",`${w(t)}.json`)}async function T(t){const e=S(t);try{return await u.unlink(e),{ok:!0,count:1}}catch(r){return(typeof r=="object"&&r!==null?Reflect.get(r,"code"):void 0)==="ENOENT"?{ok:!0,count:0}:{ok:!1,error:r.message}}}async function h(t){try{const e=await k();if(!e)return{ok:!0,count:0};const a=(await e.listTasksWithReconcile?.(t,"running")??[]).filter(s=>s.status==="running");if(a.length===0)return{ok:!0,count:0};if(typeof e.killTask!="function")return{ok:!1,error:"background task manager does not support kill"};let o=0;for(const s of a)try{await e.killTask(t,s.taskId),o+=1}catch(n){i.warn(`[agent-state] killTask failed: agentId=${t} taskId=${s.taskId} error=${n?.message}`)}return{ok:!0,count:o}}catch(e){return{ok:!1,error:e?.message}}}async function I(t){try{const e=c.listActiveByParent(t);if(e.length===0)return{ok:!0,count:0};let r=0;for(const a of e)try{await c.abort(a.subId),r+=1}catch(o){i.warn(`[agent-state] abort sub-agent failed: agentId=${t} subId=${a.subId} error=${o?.message}`)}return{ok:!0,count:r}}catch(e){return{ok:!1,error:e?.message}}}async function A(t){try{return await d(t),{ok:!0}}catch(e){return{ok:!1,error:e?.message}}}const $={todos:T,bgTasks:h,subAgents:I,browserSessions:A};b.post("/reset-state",m,async(t,e)=>{const r=String(t.body?.agentId??"").trim();if(!r){e.status(400).json({ok:!1,error:"agentId is required"});return}const o=(Array.isArray(t.body?.items)?t.body.items:[]).map(n=>String(n)).filter(n=>p.has(n)),s={};for(const n of o)s[n]=await $[n](r);i.info(`[agent-state] reset-state: agentId=${r} items=${o.join(",")||"(none)"} results=${JSON.stringify(s)}`),e.json({ok:!0,agentId:r,items:o,results:s})});export{b as agentStateRouter};
|
|
2
|
+
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{Router as
|
|
1
|
+
import{readFileSync as b}from"node:fs";import{Router as S}from"express";import{getBridgeInstanceMcpExtraFile as v}from"../config.js";import{validateToken as M}from"../middleware/auth.js";import{getEffective as N,getEffectiveSource as j}from"../services/capability-config.js";import{mcpDeployManager as w}from"../services/mcp-deploy.js";import{pluginManager as y}from"../services/plugin-manager.js";import{skillManager as k}from"../services/skill-manager.js";import{createLogger as E}from"../utils/logger.js";const h=E("capabilities"),D=S();function n(s){return[...new Set(s.filter(t=>!!t))]}function P(s){try{const t=JSON.parse(b(v(s),"utf8"));return t.servers&&typeof t.servers=="object"?Object.keys(t.servers):[]}catch{return[]}}function l(s,t,r,a={}){const i={};for(const o of r){if(a[o]){i[o]=a[o];continue}i[o]={enabled:N(s,t,o),source:j(s,t,o)}}return i}D.post("/capabilities/state",M,async(s,t)=>{const r=String((s.body??{})?.agentId??"").trim();if(!r){t.status(400).json({ok:!1,error:"agentId is required"});return}try{const i=k.listPrivateSkills(r).filter(e=>e.deployed!==!1).map(e=>e.skillName),o=n([...k.listDeployed().map(e=>e.skillName),...i]),c=P(r),p=n([...w.listDeployed().map(e=>e.name),...c]),m=await y.list(r),f=n([...(await y.listDeployed()).map(e=>e.pluginName),...m.map(e=>e.name)]),u={};for(const e of i)u[e]={enabled:!0,source:"agent"};const d={};for(const e of c)d[e]={enabled:!0,source:"agent"};const g={};for(const e of m)String(e.source||"").startsWith("shared:")||(g[e.name]={enabled:e.enabled,source:"agent"});t.json({ok:!0,agentId:r,skills:l(r,"skills",o,u),mcp:l(r,"mcp",p,d),plugins:l(r,"plugins",f,g),deployedSkills:o,deployedMcp:p,deployedPlugins:f})}catch(a){h.warn("[capabilities/state] \u8BFB\u53D6\u80FD\u529B\u72B6\u6001\u5931\u8D25: %s",a.message),t.status(500).json({ok:!1,error:a.message||"read capability state failed"})}});export{D as capabilitiesRouter};
|
|
2
2
|
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{Router as p}from"express";import{adapterRegistry as k}from"../adapter/index.js";import{validateTokenOrLoopback as a}from"../middleware/auth.js";import{debugMountMcp as l,debugMountPlugin as b,debugUnmountMcp as I,debugUnmountPlugin as y,forgetDebugMount as j,getDebugItemLogs as S,listDebugMounts as c,packageDebugItem as M}from"../services/debug-mount.js";import{createLogger as h}from"../utils/logger.js";import{sdkSessions as f}from"./terminal.js";const w=h("debug-mount"),u=p();function i(e){return(n,t)=>{e(n,t).catch(o=>{w.error("[debug-mount] %s %s \u5931\u8D25: %s",n.method,n.path,o.message),t.headersSent||t.status(500).json({ok:!1,error:o.message})})}}function g(e){return Array.from(f.values()).find(t=>t.agentId===e)?.workspacePath}function m(e){const n=Array.from(f.values()).find(o=>o.agentId===e);if(!n)return;const t=k.get(n.providerId||"claude-code");if(t&&typeof t.debugMountMcpServer=="function"&&typeof t.debugUnmountMcpServer=="function")return t}u.get("/debug-mount/:agentId",a,i(async(e,n)=>{const t=String(e.params.agentId??"").trim();if(!t){n.status(400).json({ok:!1,error:"agentId is required"});return}n.json({ok:!0,agentId:t,mounts:c(t)})})),u.post("/debug-mount/:agentId/list",a,i(async(e,n)=>{const t=String(e.params.agentId??"").trim();if(!t){n.status(400).json({ok:!1,error:"agentId is required"});return}n.json({ok:!0,agentId:t,mounts:c(t)})})),u.post("/debug-mount/:agentId/mcp",a,i(async(e,n)=>{const t=String(e.params.agentId??"").trim();if(!t){n.status(400).json({ok:!1,error:"agentId is required"});return}const o=m(t);if(!o){n.status(400).json({ok:!1,error:`No active SDK session for agentId "${t}"\uFF08MCP \u8C03\u8BD5\u6302\u8F7D\u4EC5\u5BF9\u8FD0\u884C\u4E2D\u7684\u4F1A\u8BDD\u751F\u6548\uFF09`});return}const r=await l(t,g(t),String(e.body?.path??""),o,e.body?.name===void 0?void 0:String(e.body.name));n.status(r.ok?200:400).json(r)})),u.post("/debug-mount/:agentId/plugin",a,i(async(e,n)=>{const t=String(e.params.agentId??"").trim();if(!t){n.status(400).json({ok:!1,error:"agentId is required"});return}const o=await b(t,g(t),String(e.body?.path??""));n.status(o.ok?200:400).json(o)})),u.post("/debug-mount/:agentId/unmount",a,i(async(e,n)=>{const t=String(e.params.agentId??"").trim();if(!t){n.status(400).json({ok:!1,error:"agentId is required"});return}const o=String(e.body?.kind??"").trim().toLowerCase(),r=String(e.body?.name??"").trim();if(o==="plugin"){const s=await y(t,r);n.status(s.ok?200:400).json(s);return}if(o==="mcp"){const s=m(t);if(!s){j(t,"mcp",r),n.status(200).json({ok:!0,kind:"mcp",name:r,mounted:!1,note:"\u5F53\u524D\u65E0\u6D3B\u8DC3\u4F1A\u8BDD\uFF0C\u5DF2\u4ECE\u8C03\u8BD5\u6302\u8F7D\u767B\u8BB0\u79FB\u9664"});return}const d=await I(t,r,s);n.status(d.ok?200:400).json(d);return}n.status(400).json({ok:!1,error:'kind \u987B\u4E3A "mcp" \u6216 "plugin"'})})),u.post("/debug-mount/:agentId/package",a,i(async(e,n)=>{const t=String(e.params.agentId??"").trim();if(!t){n.status(400).json({ok:!1,error:"agentId is required"});return}const o=String(e.body?.kind??"").trim().toLowerCase();if(o!=="mcp"&&o!=="plugin"&&o!=="skill"){n.status(400).json({ok:!1,error:'kind \u987B\u4E3A "mcp"\u3001"plugin" \u6216 "skill"'});return}const r=await M(g(t),String(e.body?.path??""),o);if(!r.ok||!r.bytes){n.status(400).json({ok:!1,kind:r.kind,name:r.name,error:r.error??"\u6253\u5305\u5931\u8D25"});return}n.json({ok:!0,kind:r.kind,name:r.name,fileName:`${r.kind}-${r.name}.zip`,size:r.size,sha256:r.sha256,contentBase64:r.bytes.toString("base64")})})),u.post("/debug-mount/:agentId/logs",a,i(async(e,n)=>{const t=String(e.params.agentId??"").trim();if(!t){n.status(400).json({ok:!1,error:"agentId is required"});return}const o=String(e.body?.kind??"").trim().toLowerCase();if(o!=="mcp"&&o!=="plugin"){n.status(400).json({ok:!1,error:'kind \u987B\u4E3A "mcp" \u6216 "plugin"'});return}const r=String(e.body?.name??"").trim(),s=e.body?.tail===void 0?void 0:Number(e.body.tail),d=await S(t,o,r,s,m(t)??void 0);n.status(d.ok?200:400).json(d)}));export{u as debugMountRouter};
|
|
2
|
+
|
package/dist/routes/mcp.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{Router as y}from"express";import{validateToken as
|
|
1
|
+
import{Router as y}from"express";import{validateToken as a}from"../middleware/auth.js";import{getEffective as f,setDefault as g,setInherited as b,setOverride as j}from"../services/capability-config.js";import{mcpDeployManager as d}from"../services/mcp-deploy.js";import{isBuiltinMcpName as m}from"../services/mcp-env-injector.js";import{probeDeployedMcp as k}from"../services/mcp-probe-client.js";import{getPanelEnvVars as v,getAgentMeta as S}from"../services/panel-env.js";import{sanitizeEnvForChild as h}from"../utils/env-safety.js";import{createLogger as M}from"../utils/logger.js";const I=M("mcp"),i=y();function c(r){return(e,o)=>{r(e,o).catch(t=>{I.error("[mcp] %s %s \u5931\u8D25: %s",e.method,e.path,t.message),o.headersSent||o.status(500).json({ok:!1,error:t.message})})}}function E(r){if(!r||typeof r!="object")return null;const e=r,t={type:String(e.type||e.transport||"stdio").trim().toLowerCase()||"stdio"};e.command!==null&&e.command!==void 0&&String(e.command).trim()&&(t.command=String(e.command).trim()),e.url!==null&&e.url!==void 0&&String(e.url).trim()&&(t.url=String(e.url).trim()),Array.isArray(e.args)&&(t.args=e.args.map(s=>String(s))),e.env&&typeof e.env=="object"&&(t.env=e.env),e.headers&&typeof e.headers=="object"&&(t.headers=e.headers),e.collapsed===!0&&(t.collapsed=!0);const n=e.description===null||e.description===void 0?"":String(e.description).trim();return n&&(t.description=n),t}function C(r){const e={};for(const[o,t]of Object.entries(r))m(o)&&t===!1||(e[o]=t);return e}i.post("/mcp/deployed/list",a,c(async(r,e)=>{const t=d.listDeployed().map(n=>({...n,enabled:f("","mcp",n.name)}));e.json({ok:!0,deployedMcp:t})})),i.get("/mcp/deployed",a,c(async(r,e)=>{const t=d.listDeployed().map(n=>({...n,enabled:f("","mcp",n.name)}));e.json({ok:!0,deployedMcp:t})})),i.post("/mcp/deployed/default",a,c(async(r,e)=>{const o=String((r.body??{})?.name??"").trim();if(!o){e.status(400).json({ok:!1,error:"name is required"});return}const t=String((r.body??{})?.agentId??"").trim(),n=(r.body??{})?.enabled,s=n==null?null:!!n;if(m(o)&&s===!1){e.status(400).json({ok:!1,error:`\u300C${o}\u300D\u662F\u5185\u7F6E\u901A\u8BAF MCP\uFF0C\u6052\u4E3A\u9ED8\u8BA4\u542F\u7528\uFF0C\u4E0D\u53EF\u5173\u95ED`});return}t?j(t,"mcp",o,s):g("mcp",o,s),e.json({ok:!0,name:o,agentId:t,enabled:s})})),i.post("/mcp/deployed/inherited",a,c(async(r,e)=>{const o=String((r.body??{})?.agentId??"").trim();if(!o){e.status(400).json({ok:!1,error:"agentId is required"});return}const t=(r.body??{})?.map,n=t&&typeof t=="object"&&!Array.isArray(t)?C(t):t??null;b(o,"mcp",n),e.json({ok:!0,agentId:o,count:n&&typeof n=="object"?Object.keys(n).length:0})})),i.post("/mcp/deployed/save",a,c(async(r,e)=>{const{name:o,spec:t,defaultEnabled:n,sha256:s}=r.body??{},p=String(o??"").trim();if(!p){e.status(400).json({ok:!1,error:"name is required"});return}const l=E(t);if(!l){e.status(400).json({ok:!1,error:"spec \u975E\u6CD5"});return}if(m(p)){e.status(400).json({ok:!1,error:`\u300C${p}\u300D\u662F\u5185\u7F6E\u901A\u8BAF MCP\uFF0C\u7531\u5B9E\u4F8B\u521D\u59CB\u5316\u81EA\u52A8\u90E8\u7F72\uFF0C\u4E0D\u53EF\u8986\u76D6`});return}const u=d.saveMcp(p,l,n!==!1,s?String(s):void 0);e.status(u.ok?200:400).json(u)})),i.post("/mcp/deployed/remove",a,c(async(r,e)=>{const o=String((r.body??{})?.name??"").trim(),t=d.removeMcp(o);e.status(t.ok?200:400).json(t)})),i.post("/mcp/probe",a,c(async(r,e)=>{const o=r.body??{},t=String(o.name??"").trim();if(!t){e.status(400).json({ok:!1,error:"name is required"});return}if(Object.prototype.hasOwnProperty.call(o,"spec")){e.status(400).json({ok:!1,error:"probe \u53EA\u63A5\u53D7\u5DF2\u90E8\u7F72 MCP \u7684 name\uFF0C\u4E0D\u63A5\u53D7\u8C03\u7528\u65B9\u4F20\u5165 spec"});return}const n=String(o.agentId??"").trim(),s={...n?v(n):{},...h(o.env)},p=await k(t,{effectiveEnv:s,agentMeta:n?S(n):void 0});e.json(p)})),i.post("/mcp/cc-switch/list",a,c(async(r,e)=>{e.json({ok:!0,mcpServers:[],state:{skills:[],mcpServers:[]}})}));export{i as mcpRouter,E as normalizeSpec,C as stripBuiltinMcpDisable};
|
|
2
2
|
|
package/dist/routes/plugins.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{Router as b}from"express";import{raw as I}from"express";import{validateToken as
|
|
1
|
+
import{Router as b}from"express";import{raw as I}from"express";import{validateToken as g,validateTokenOrLoopback as m}from"../middleware/auth.js";import{getEffective as j,setDefault as k,setInherited as S,setOverride as w}from"../services/capability-config.js";import{isValidPluginName as p,pluginManager as u}from"../services/plugin-manager.js";import{createLogger as N}from"../utils/logger.js";const v=N("plugins"),r=b();function i(s){return(e,n)=>{s(e,n).catch(t=>{v.error("[plugins] %s %s \u5931\u8D25: %s",e.method,e.path,t.message),n.headersSent||n.status(500).json({ok:!1,error:t.message})})}}r.get("/plugins/deployed",g,i(async(s,e)=>{const t=(await u.listDeployed()).map(a=>({...a,enabled:j("","plugins",a.pluginName)}));e.json({ok:!0,deployedPlugins:t})})),r.post("/plugins/deployed/default",g,i(async(s,e)=>{const n=String((s.body??{})?.pluginName??"").trim();if(!p(n)){e.status(400).json({ok:!1,error:"pluginName \u975E\u6CD5\uFF08\u987B\u4E3A kebab-case\uFF0C1~64 \u5B57\u7B26\uFF09"});return}const t=String((s.body??{})?.agentId??"").trim(),a=(s.body??{})?.enabled,o=a==null?null:!!a;t?w(t,"plugins",n,o):k("plugins",n,o),e.json({ok:!0,pluginName:n,agentId:t,enabled:o})})),r.post("/plugins/deployed/inherited",g,i(async(s,e)=>{const n=String((s.body??{})?.agentId??"").trim();if(!n){e.status(400).json({ok:!1,error:"agentId is required"});return}const t=(s.body??{})?.map;S(n,"plugins",t??null),e.json({ok:!0,agentId:n,count:Object.keys(t??{}).length})})),r.post("/plugins/deployed/remove",g,i(async(s,e)=>{const n=String((s.body??{})?.pluginName??"").trim();if(!p(n)){e.status(400).json({ok:!1,error:"pluginName \u975E\u6CD5\uFF08\u987B\u4E3A kebab-case\uFF0C1~64 \u5B57\u7B26\uFF09"});return}const t=await u.removeDeployedPlugin(n);e.status(t.ok?200:400).json(t)})),r.get("/plugins/:agentId",g,i(async(s,e)=>{const n=String(s.params.agentId??"").trim();if(!n){e.status(400).json({ok:!1,error:"agentId is required"});return}const t=await u.list(n);e.json({ok:!0,agentId:n,plugins:t})})),r.post("/plugins/:agentId/install",g,i(async(s,e)=>{const n=String(s.params.agentId??"").trim(),t=s.body??{},a=typeof t.source=="string"?t.source:"",o=t.config&&typeof t.config=="object"&&!Array.isArray(t.config)?Object.fromEntries(Object.entries(t.config).filter(d=>typeof d[1]=="string")):void 0;if(!n){e.status(400).json({ok:!1,error:"agentId is required"});return}const c={action:"install",source:a,...o?{config:o}:{}},l=await u.manage(n,c);e.status(l.ok?200:400).json(l)}));function f(s){return[g,i(async(e,n)=>{const t=String(e.params.agentId??"").trim(),a=String(e.params.name??"").trim();if(!t||t==="deployed"||!p(a)){n.status(400).json({ok:!1,error:"agentId \u4E14 name \u987B\u4E3A\u5408\u6CD5\u63D2\u4EF6\u540D\uFF08kebab-case\uFF0C1~64 \u5B57\u7B26\uFF09"});return}const o=await u.manage(t,{action:s,name:a});n.status(o.ok?200:400).json(o)})]}r.post("/plugins/:agentId/:name/reload",...f("reload")),r.post("/plugins/:agentId/:name/enable",...f("enable")),r.post("/plugins/:agentId/:name/disable",...f("disable")),r.delete("/plugins/:agentId/:name",...f("uninstall")),r.get("/plugins/:agentId/:name/logs",g,i(async(s,e)=>{const n=String(s.params.agentId??"").trim(),t=String(s.params.name??"").trim();if(!n||!p(t)){e.status(400).json({ok:!1,error:"agentId \u4E14 name \u987B\u4E3A\u5408\u6CD5\u63D2\u4EF6\u540D\uFF08kebab-case\uFF0C1~64 \u5B57\u7B26\uFF09"});return}const a=await u.getLogs(n,t);e.status(a.ok?200:404).json(a)})),r.get("/plugins/:agentId/commands",g,i(async(s,e)=>{const n=String(s.params.agentId??"").trim();if(!n){e.status(400).json({ok:!1,error:"agentId is required"});return}const t=await u.getPluginCommands(n);e.json({ok:!0,agentId:n,commands:t.map(a=>({name:a.name,description:a.description??"",argumentHint:a.argumentHint??"",sourcePath:a.sourcePath,plugin:a.plugin}))})})),r.get("/plugin-events/:agentId/events",m,i(async(s,e)=>{const n=String(s.params.agentId??"").trim();if(!n){e.status(400).json({ok:!1,error:"agentId is required"});return}const t=Number(s.query.maxPerKey),a=Number.isFinite(t)&&t>0?t:void 0,o=await u.drainEvents(n,{maxPerKey:a});e.json({ok:!0,agentId:n,...o})})),r.post("/plugin-events/:agentId/callback/:plugin",m,i(async(s,e)=>{const n=String(s.params.agentId??"").trim(),t=String(s.params.plugin??"").trim(),a=s.body??{};if(!n||!t){e.status(400).json({ok:!1,error:"agentId and plugin are required"});return}const o=await u.enqueueExternalEvent(n,t,a);e.status(o.ok?200:400).json(o)})),r.post("/plugins/:agentId/private-save",g,i(async(s,e)=>{const n=String(s.params.agentId??"").trim();if(!n){e.status(400).json({ok:!1,error:"agentId is required"});return}const t=s.body??{},a=Buffer.from(String(t.contentBase64??""),"base64");if(a.length===0){e.status(400).json({ok:!1,error:"contentBase64 \u4E3A\u7A7A"});return}const o=String(t.fileName??"plugin.zip"),c=t.config&&typeof t.config=="object"&&!Array.isArray(t.config)?Object.fromEntries(Object.entries(t.config).filter(d=>typeof d[1]=="string")):void 0,l=await u.installFromZip(n,a,o,c);e.status(l.ok?200:400).json(l)})),r.post("/plugins/:agentId/private-remove",g,i(async(s,e)=>{const n=String(s.params.agentId??"").trim(),t=String((s.body??{})?.pluginName??"").trim();if(!n||!p(t)){e.status(400).json({ok:!1,error:"agentId \u4E0E pluginName \u5FC5\u586B\uFF08kebab-case\uFF09"});return}const a=await u.manage(n,{action:"uninstall",name:t});e.status(a.ok?200:400).json(a)})),r.post("/plugins/:agentId/upload",g,I({type:()=>!0,limit:"100mb"}),i(async(s,e)=>{const n=String(s.params.agentId??"").trim();if(!n){e.status(400).json({ok:!1,error:"agentId is required"});return}const t=s.body;if(!Buffer.isBuffer(t)||t.length===0){e.status(400).json({ok:!1,error:"\u7F3A\u5C11 zip \u5185\u5BB9\uFF08raw body, Content-Type: application/zip\uFF09"});return}const a=String(s.query.filename??"plugin.zip");if(!a.toLowerCase().endsWith(".zip")){e.status(400).json({ok:!1,error:"\u4EC5\u652F\u6301 .zip \u63D2\u4EF6\u5305"});return}let o;const c=String(s.query.config??"").trim();if(c)try{const d=JSON.parse(c);if(d&&typeof d=="object"&&!Array.isArray(d))o=Object.fromEntries(Object.entries(d).filter(y=>typeof y[1]=="string"));else{e.status(400).json({ok:!1,error:"config \u5FC5\u987B\u662F JSON \u5BF9\u8C61"});return}}catch{e.status(400).json({ok:!1,error:"config \u4E0D\u662F\u5408\u6CD5\u7684 JSON \u5BF9\u8C61"});return}const l=await u.installFromZip(n,t,a,o);e.status(l.ok?200:400).json(l)}));export{r as pluginsRouter};
|
|
2
2
|
|
package/dist/routes/skills.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{Router as
|
|
1
|
+
import{Router as y}from"express";import{raw as p}from"express";import{validateToken as a}from"../middleware/auth.js";import{getEffective as g,setDefault as S,setInherited as b,setOverride as j}from"../services/capability-config.js";import{skillManager as d,isValidSkillName as m}from"../services/skill-manager.js";import{createLogger as h}from"../utils/logger.js";const v=h("skills"),n=y();function o(t){return(e,s)=>{t(e,s).catch(l=>{v.error("[skills] %s %s \u5931\u8D25: %s",e.method,e.path,l.message),s.headersSent||s.status(500).json({ok:!1,error:l.message})})}}n.post("/skills/deployed/list",a,o(async(t,e)=>{const l=d.listDeployed().map(i=>({...i,enabled:g("","skills",i.skillName)}));e.json({ok:!0,deployedSkills:l})})),n.get("/skills/deployed",a,o(async(t,e)=>{const l=d.listDeployed().map(i=>({...i,enabled:g("","skills",i.skillName)}));e.json({ok:!0,deployedSkills:l})})),n.post("/skills/deployed/default",a,o(async(t,e)=>{const s=String((t.body??{})?.skillName??"").trim();if(!m(s)){e.status(400).json({ok:!1,error:"skillName \u975E\u6CD5"});return}const l=String((t.body??{})?.agentId??"").trim(),i=(t.body??{})?.enabled,r=i==null?null:!!i;l?j(l,"skills",s,r):S("skills",s,r),e.json({ok:!0,skillName:s,agentId:l,enabled:r})})),n.post("/skills/deployed/inherited",a,o(async(t,e)=>{const s=String((t.body??{})?.agentId??"").trim();if(!s){e.status(400).json({ok:!1,error:"agentId is required"});return}const l=(t.body??{})?.map;b(s,"skills",l??null),e.json({ok:!0,agentId:s,count:Object.keys(l??{}).length})})),n.post("/skills/deployed/upload",a,p({type:"application/zip",limit:"200mb"}),o(async(t,e)=>{const s=t.body??{},l=Buffer.isBuffer(s)?s:Buffer.from(s??"");if(!l||l.length===0){e.status(400).json({ok:!1,error:"zip \u5185\u5BB9\u4E3A\u7A7A"});return}const i=String(t.query.filename??t.headers["x-filename"]??"skill.zip"),r=String(t.query.sha256??"").trim()||void 0,k=t.query.defaultEnabled!=="false",u=await d.saveSharedSkill(l,String(i),k,r);e.status(u.ok?200:400).json(u)})),n.post("/skills/deployed/remove",a,o(async(t,e)=>{const s=String((t.body??{})?.skillName??"").trim();if(!m(s)){e.status(400).json({ok:!1,error:"skillName \u975E\u6CD5"});return}const l=await d.removeDeployedSkill(s);e.status(l.ok?200:400).json(l)})),n.post("/skills/private/:agentId/upload",a,p({type:()=>!0,limit:"200mb"}),o(async(t,e)=>{const s=String(t.params.agentId??"").trim();if(!s){e.status(400).json({ok:!1,error:"agentId is required"});return}const l=t.body;if(!Buffer.isBuffer(l)||l.length===0){e.status(400).json({ok:!1,error:"zip \u5185\u5BB9\u4E3A\u7A7A"});return}const i=t.query,r=String(i.filename??t.headers["x-filename"]??"skill.zip"),k=String(i.sha256??"").trim()||void 0,u=String(i.skillName??"").trim()||void 0,f=await d.savePrivateSkill(s,l,r,k,u);e.status(f.ok?200:400).json(f)})),n.post("/skills/private/:agentId/save",a,o(async(t,e)=>{const s=String(t.params.agentId??"").trim();if(!s){e.status(400).json({ok:!1,error:"agentId is required"});return}const l=t.body??{},i=String(l.contentBase64??""),r=Buffer.from(i,"base64");if(r.length===0){e.status(400).json({ok:!1,error:"contentBase64 \u4E3A\u7A7A"});return}const k=String(l.fileName??"skill.zip"),u=String(l.sha256??"").trim()||void 0,f=String(l.skillName??"").trim()||void 0,c=await d.savePrivateSkill(s,r,k,u,f);e.status(c.ok?200:400).json(c)})),n.post("/skills/private/:agentId/remove",a,o(async(t,e)=>{const s=String(t.params.agentId??"").trim(),l=String((t.body??{})?.skillName??"").trim();if(!s||!m(l)){e.status(400).json({ok:!1,error:"agentId \u4E0E skillName \u5FC5\u586B"});return}const i=await d.removePrivateSkill(s,l);e.status(i.ok?200:400).json(i)})),n.post("/skills/private/:agentId/list",a,o(async(t,e)=>{const s=String(t.params.agentId??"").trim();if(!s){e.status(400).json({ok:!1,error:"agentId is required"});return}e.json({ok:!0,agentId:s,privateSkills:d.listPrivateSkills(s)})})),n.post("/skills/cc-switch/list",a,o(async(t,e)=>{e.json({ok:!0,skills:[],state:{skills:[],mcpServers:[]}})}));export{n as skillsRouter};
|
|
2
2
|
|