aws-runtime-bridge 1.9.162 → 1.9.168

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (123) hide show
  1. package/CHANGELOG.md +304 -0
  2. package/dist/adapter/AcodeSdkAdapter.d.ts +31 -3
  3. package/dist/adapter/AcodeSdkAdapter.js +4 -9
  4. package/dist/adapter/ClaudeSdkAdapter.d.ts +2 -0
  5. package/dist/adapter/ClaudeSdkAdapter.js +3 -3
  6. package/dist/adapter/CodexSdkAdapter.d.ts +2 -0
  7. package/dist/adapter/CodexSdkAdapter.js +3 -3
  8. package/dist/adapter/OpencodeSdkAdapter.d.ts +2 -0
  9. package/dist/adapter/OpencodeSdkAdapter.js +3 -3
  10. package/dist/adapter/prompts.d.ts +1 -1
  11. package/dist/adapter/prompts.js +1 -1
  12. package/dist/adapter/types.d.ts +41 -4
  13. package/dist/adapter/types.js +1 -1
  14. package/dist/browser/frame-encode.d.ts +25 -0
  15. package/dist/browser/frame-encode.js +2 -0
  16. package/dist/browser/screencast-differ.d.ts +2 -3
  17. package/dist/browser/screencast-differ.js +1 -1
  18. package/dist/browser/screencast-manager.js +1 -1
  19. package/dist/browser/types.d.ts +5 -1
  20. package/dist/browser/types.js +1 -1
  21. package/dist/desktop/desktop-mcp-client.js +2 -2
  22. package/dist/routes/background-tasks.js +3 -3
  23. package/dist/routes/capabilities.js +1 -1
  24. package/dist/routes/dashboard.d.ts +2 -0
  25. package/dist/routes/dashboard.js +4 -4
  26. package/dist/routes/git.js +22 -22
  27. package/dist/routes/instance.js +1 -1
  28. package/dist/routes/launch.js +10 -10
  29. package/dist/routes/mcp-extra.js +2 -2
  30. package/dist/routes/mcp.d.ts +4 -0
  31. package/dist/routes/mcp.js +1 -1
  32. package/dist/routes/plugins.js +1 -1
  33. package/dist/routes/pty.d.ts +11 -3
  34. package/dist/routes/pty.js +3 -3
  35. package/dist/routes/runtime-binding.js +1 -1
  36. package/dist/routes/sessions.js +1 -1
  37. package/dist/routes/skills.js +1 -1
  38. package/dist/routes/sub-agents.js +8 -8
  39. package/dist/routes/terminal.d.ts +16 -2
  40. package/dist/routes/terminal.js +34 -36
  41. package/dist/services/agent-process-manager.js +1 -1
  42. package/dist/services/agent-pty-manager.js +4 -4
  43. package/dist/services/aws-client-agent-mcp.js +2 -2
  44. package/dist/services/capability-config.d.ts +8 -0
  45. package/dist/services/capability-config.js +2 -2
  46. package/dist/services/desktop-mcp-manager.d.ts +3 -1
  47. package/dist/services/desktop-mcp-manager.js +1 -1
  48. package/dist/services/instance-ai-config-service.js +1 -1
  49. package/dist/services/instance-features.d.ts +10 -0
  50. package/dist/services/instance-features.js +1 -1
  51. package/dist/services/instance-init-service.js +1 -1
  52. package/dist/services/launch-manager.d.ts +9 -1
  53. package/dist/services/launch-manager.js +6 -6
  54. package/dist/services/launch-metrics.d.ts +1 -1
  55. package/dist/services/launch-metrics.js +4 -3
  56. package/dist/services/mcp-deploy.d.ts +4 -0
  57. package/dist/services/mcp-env-injector.d.ts +12 -0
  58. package/dist/services/mcp-env-injector.js +2 -0
  59. package/dist/services/mcp-launch-binding-queue.d.ts +8 -0
  60. package/dist/services/mcp-launch-binding-queue.js +1 -1
  61. package/dist/services/orphan-monitor.js +1 -1
  62. package/dist/services/panel-env.d.ts +6 -2
  63. package/dist/services/panel-env.js +1 -1
  64. package/dist/services/plugin-manager.js +9 -9
  65. package/dist/services/process-detector.d.ts +23 -3
  66. package/dist/services/process-detector.js +13 -13
  67. package/dist/services/runtime-resources-snapshot.d.ts +3 -0
  68. package/dist/services/runtime-resources-snapshot.js +3 -0
  69. package/dist/services/session-output.d.ts +13 -0
  70. package/dist/services/session-output.js +4 -4
  71. package/dist/services/tunnel-client.js +1 -1
  72. package/dist/services/workspace-files.js +1 -1
  73. package/dist/types.d.ts +4 -0
  74. package/dist/utils/env-safety.d.ts +15 -0
  75. package/dist/utils/env-safety.js +2 -0
  76. package/dist/utils/lifecycle-log.d.ts +2 -0
  77. package/dist/utils/lifecycle-log.js +3 -0
  78. package/dist/utils/mcp-utils.js +1 -1
  79. package/package/acode/dist/background-command-manager.js +4 -4
  80. package/package/acode/dist/built-in-file-tools.d.ts +13 -0
  81. package/package/acode/dist/built-in-file-tools.js +2 -2
  82. package/package/acode/dist/builtins/shellCommandPreparation.d.ts +2 -0
  83. package/package/acode/dist/builtins/shellCommandPreparation.js +2 -2
  84. package/package/acode/dist/compaction.d.ts +10 -0
  85. package/package/acode/dist/compaction.js +6 -6
  86. package/package/acode/dist/context-overflow.js +1 -1
  87. package/package/acode/dist/index.d.ts +1 -0
  88. package/package/acode/dist/index.js +1 -1
  89. package/package/acode/dist/mcpToolNames.d.ts +4 -0
  90. package/package/acode/dist/mcpToolNames.js +1 -1
  91. package/package/acode/dist/runtime-environment.d.ts +2 -0
  92. package/package/acode/dist/runtime-environment.js +3 -2
  93. package/package/acode/dist/runtime.d.ts +68 -8
  94. package/package/acode/dist/runtime.js +28 -27
  95. package/package/acode/dist/sub-agent-manager.js +1 -1
  96. package/package/acode/dist/tool-allocation.js +1 -1
  97. package/package/acode/dist/tool-group-manager.d.ts +12 -0
  98. package/package/acode/dist/tool-group-manager.js +8 -4
  99. package/package/acode/dist/types.d.ts +8 -0
  100. package/package/acode/package.json +1 -1
  101. package/package/aws-client-agent-mcp/README.md +1 -0
  102. package/package/aws-client-agent-mcp/dist/agent-client.d.ts +20 -8
  103. package/package/aws-client-agent-mcp/dist/agent-client.js +1 -1
  104. package/package/aws-client-agent-mcp/dist/http-client.d.ts +10 -0
  105. package/package/aws-client-agent-mcp/dist/http-client.js +1 -1
  106. package/package/aws-client-agent-mcp/dist/logger.d.ts +2 -1
  107. package/package/aws-client-agent-mcp/dist/logger.js +2 -2
  108. package/package/aws-client-agent-mcp/dist/mcp-server.d.ts +19 -2
  109. package/package/aws-client-agent-mcp/dist/mcp-server.js +18 -18
  110. package/package/aws-client-agent-mcp/dist/mcp-tools.d.ts +13 -4
  111. package/package/aws-client-agent-mcp/dist/mcp-tools.js +79 -29
  112. package/package/aws-client-agent-mcp/dist/memory-store.d.ts +2 -0
  113. package/package/aws-client-agent-mcp/dist/memory-store.js +3 -3
  114. package/package/aws-client-agent-mcp/dist/message-buffer.js +1 -1
  115. package/package/aws-client-agent-mcp/dist/office/office-workspace.d.ts +15 -0
  116. package/package/aws-client-agent-mcp/dist/office/office-workspace.js +1 -1
  117. package/package/aws-client-agent-mcp/dist/status-reporter.js +1 -1
  118. package/package/aws-client-agent-mcp/dist/tool-groups.d.ts +4 -0
  119. package/package/aws-client-agent-mcp/dist/tool-groups.js +2 -2
  120. package/package/aws-client-agent-mcp/dist/types.d.ts +50 -1
  121. package/package/aws-client-agent-mcp/dist/websocket-client.js +1 -1
  122. package/package/aws-client-agent-mcp/package.json +1 -1
  123. package/package.json +1 -1
@@ -1,54 +1,52 @@
1
- import{spawn as rt}from"node:child_process";import{promises as F}from"node:fs";import ot from"node:os";import B from"node:path";import{TextDecoder as te}from"node:util";import be from"axios";import{Router as st}from"express";import{v4 as it}from"uuid";import{adapterRegistry as k,getToolActionInfo as he,isTransientClipboardPasteFilePath as we,redactTransientClipboardPastePaths as q,registerSdkProviders as at,resolveSdkProviderIdByCommand as ct}from"../adapter/index.js";import{MESSAGE_POLLING_IDLE_PROMPT as Ce}from"../adapter/prompts.js";import{getActiveBridgeHttpPort as ut,getAcodeDataHome as $e}from"../config.js";import{validateToken as I}from"../middleware/auth.js";import{getAgentProcessManager as Ie}from"../services/agent-process-manager.js";import{createAiConfigService as dt}from"../services/ai-config-service.js";import{resolveSchedulerBaseUrlFromToken as Re}from"../services/auto-register.js";import{setChangeCacheRetentionDays as lt}from"../services/change-cache-retention.js";import{getAllPushStats as ft,startHeartbeatScheduler as mt}from"../services/event-delta-pusher.js";import{prepareAcodeInstanceConfig as pt,redactForLog as ne}from"../services/instance-ai-config-service.js";import{setAgentFeatures as gt,setAgentCapabilities as yt,getAgentFeatures as ht,getFeatureState as b,LAUNCH_ITEM_FEATURE_KEY as Ee,HIRE_FEATURE_KEY as De,PENCIL_FEATURE_KEY as Pe,DRAW_FEATURE_KEY as Le,OFFICE_FEATURE_KEY as Oe,COLLABORATION_TASK_FEATURE_KEY as Me,COLLABORATION_MEETING_FEATURE_KEY as Ue,COLLABORATION_DEBUG_FEATURE_KEY as je,COLLABORATION_FILE_HISTORY_FEATURE_KEY as xe}from"../services/instance-features.js";import{enqueueMcpLaunchBinding as It}from"../services/mcp-launch-binding-queue.js";import{setPanelEnvVars as St}from"../services/panel-env.js";import{findClaudeCodeProcesses as At,isProcessRunning as Tt}from"../services/process-detector.js";import{forgetSession as K,onSdkToolUseEnd as _t,onSdkToolUseStart as kt}from"../services/sdk-tool-file-change-recorder.js";import{bridgeEventBuffer as Be,sendOutput as Y,sendQuestionRequest as bt,sendToolAuthRequest as wt,sendStatus as $}from"../services/session-output.js";import{findPersistedSessionByAgentId as Ct,removePersistedSession as H,savePersistedSessions as $t,updatePersistedSessionAutoCommands as Rt,updatePersistedSessionRuntimeState as Et,upsertPersistedSession as Dt}from"../services/terminal-persistence.js";import{getInstanceAiConfigDebugLogger as Pt}from"../utils/instance-ai-config-debug-logger.js";import{logger as f}from"../utils/logger.js";const S=st();function Ne(e){const n=e.header("X-Runtime-Token");return n&&n.trim()?n.trim():(e.header("Authorization")||"").match(/^Bearer\s+(.+)$/i)?.[1]?.trim()||void 0}const p=new Map,Lt=45e3,re=new Map;function Ot(e){if(re.has(e))return;const n=setInterval(()=>{const t=p.get(e);if(!t){M(e);return}const r=t.currentRuntimeStatus;if(r!=="thinking"&&r!=="tool_using"&&r!=="compacting"){M(e);return}$(t.agentId,e,r,void 0,void 0,{runtimeAccessToken:t.runtimeAccessToken,schedulerBaseUrl:t.schedulerBaseUrl}).catch(()=>{})},Lt);re.set(e,n)}function M(e){const n=re.get(e);n&&(clearInterval(n),re.delete(e))}const ve=4e3,Mt=`
1
+ import{spawn as pt}from"node:child_process";import{promises as v}from"node:fs";import gt from"node:os";import j from"node:path";import{TextDecoder as re}from"node:util";import Pe from"axios";import{Router as yt}from"express";import{v4 as ht}from"uuid";import{adapterRegistry as _,getToolActionInfo as be,isTransientClipboardPasteFilePath as Oe,redactTransientClipboardPastePaths as K,registerSdkProviders as It,resolveSdkProviderIdByCommand as St}from"../adapter/index.js";import{MESSAGE_POLLING_IDLE_PROMPT as Le}from"../adapter/prompts.js";import{getActiveBridgeHttpPort as At,getAcodeDataHome as Me}from"../config.js";import{buildResumeContextBlock as Tt}from"@agentswork/acode";import{validateToken as I}from"../middleware/auth.js";import{getAgentProcessManager as ke}from"../services/agent-process-manager.js";import{createAiConfigService as _t}from"../services/ai-config-service.js";import{resolveSchedulerBaseUrlFromToken as Ue}from"../services/auto-register.js";import{setChangeCacheRetentionDays as bt}from"../services/change-cache-retention.js";import{getAllPushStats as kt,startHeartbeatScheduler as Ct}from"../services/event-delta-pusher.js";import{prepareAcodeInstanceConfig as $t,redactForLog as oe}from"../services/instance-ai-config-service.js";import{setAgentFeatures as wt,setAgentCapabilities as Et,setAgentInheritedFeatures as Rt,setAgentCapabilitiesInherited as Dt,getAgentFeatures as Pt,getAgentInheritedFeatures as Ot,getFeatureState as T,LAUNCH_ITEM_FEATURE_KEY as xe,HIRE_FEATURE_KEY as Ne,PENCIL_FEATURE_KEY as je,DRAW_FEATURE_KEY as Be,OFFICE_FEATURE_KEY as Fe,COLLABORATION_TASK_FEATURE_KEY as ve,COLLABORATION_MEETING_FEATURE_KEY as Ke,COLLABORATION_DEBUG_FEATURE_KEY as He,COLLABORATION_FILE_HISTORY_FEATURE_KEY as qe,EMAIL_FEATURE_KEY as ze}from"../services/instance-features.js";import{enqueueMcpLaunchBinding as Lt}from"../services/mcp-launch-binding-queue.js";import{setPanelEnvVars as Mt}from"../services/panel-env.js";import{findClaudeCodeProcesses as Ut,isProcessRunning as xt}from"../services/process-detector.js";import{forgetSession as H,onSdkToolUseEnd as Nt,onSdkToolUseStart as jt}from"../services/sdk-tool-file-change-recorder.js";import{bridgeEventBuffer as We,sendOutput as J,sendQuestionRequest as Bt,sendToolAuthRequest as Ft,sendStatus as E}from"../services/session-output.js";import{findPersistedSessionByAgentId as vt,removePersistedSession as q,savePersistedSessions as Kt,updatePersistedSessionAutoCommands as Ht,updatePersistedSessionRuntimeState as qt,upsertPersistedSession as zt}from"../services/terminal-persistence.js";import{getInstanceAiConfigDebugLogger as Wt}from"../utils/instance-ai-config-debug-logger.js";import{logger as f}from"../utils/logger.js";const S=yt();function Ge(e){const n=e.header("X-Runtime-Token");return n&&n.trim()?n.trim():(e.header("Authorization")||"").match(/^Bearer\s+(.+)$/i)?.[1]?.trim()||void 0}const g=new Map,Gt=45e3,se=new Map;function Xt(e){if(se.has(e))return;const n=setInterval(()=>{const t=g.get(e);if(!t){M(e);return}const r=t.currentRuntimeStatus;if(r!=="thinking"&&r!=="tool_using"&&r!=="compacting"){M(e);return}E(t.agentId,e,r,void 0,void 0,{runtimeAccessToken:t.runtimeAccessToken,schedulerBaseUrl:t.schedulerBaseUrl}).catch(()=>{})},Gt);se.set(e,n)}function M(e){const n=se.get(e);n&&(clearInterval(n),se.delete(e))}const Xe=4e3,Yt=200,Jt=2e3,Ye=24e3,Je=200,Ve=8e3;function Vt(e){if(!Array.isArray(e)||e.length===0)return{snapshot:"",truncated:!1};const n=[];let t=null,r=[];const s=()=>{if(t===null)return;const u=r.join("").trim();if(r=[],!u){t=null;return}const d=t==="user"?"\u7528\u6237":t==="assistant"?"\u52A9\u624B":t;n.push(`\u3010${d}\u3011${ie(u,Jt)}`),t=null};for(const u of e){const d=String(u?.role||"").trim();if(!d||d==="system")continue;if(d==="tool_use"||d==="tool_result"){s();const m=String(u.toolName||"").trim()||"\u672A\u77E5\u5DE5\u5177";if(Qt(m))continue;if(d==="tool_use"){const p=en(String(u.content||""));n.push(`\u3010\u5DE5\u5177\u8C03\u7528\u3011${m}${p?` ${p}`:""}`)}else{const p=ie(String(u.content||"").trim(),Yt);n.push(`\u3010\u5DE5\u5177\u7ED3\u679C\u3011${m}${u.isError?"\uFF08\u5931\u8D25\uFF09":""}${p?`\uFF1A${p}`:""}`)}continue}const l=String(u.content||"");l.trim()&&(t===d||(s(),t=d),r.push(l))}if(s(),n.length===0)return{snapshot:"",truncated:!1};const o=n.join(`
2
+ `);if(o.length<=Ye)return{snapshot:o,truncated:!1};const i=Ye-Ve,a=o.slice(0,Ve),c=o.slice(o.length-i);return{snapshot:`${a}
2
3
 
3
- \u8BF7\u6C42\u4F53:
4
- `;function Fe(e){if(e==null||typeof e!="object"||Array.isArray(e))return;const n=e,t={};return typeof n.model=="string"&&n.model.trim()&&(t.model=n.model.trim()),typeof n.baseURL=="string"&&n.baseURL.trim()&&(t.baseURL=n.baseURL.trim()),typeof n.apiKey=="string"&&n.apiKey.trim()&&(t.apiKey=n.apiKey.trim()),typeof n.effort=="string"&&n.effort.trim()&&(t.effort=n.effort.trim()),t}const Ut=`
4
+ ...\uFF08\u6B64\u5904\u7701\u7565\u4E2D\u6BB5 ${o.length-a.length-c.length} \u5B57\u7B26\u5386\u53F2\uFF09...
5
5
 
6
- \u8BF7\u6C42\u5934:
7
- `,z=new Set;async function jt(e,n){const t=[],r=[],o=B.join(e,".agentswork","memory");try{const c=(await F.readdir(o)).filter(u=>u.endsWith(".json")),d=await Promise.all(c.map(async u=>{try{const l=await F.readFile(B.join(o,u),"utf-8");return JSON.parse(l)}catch{return f.warn("[loadAgentStartupMemories] Failed to parse memory file: %s",B.join(o,u)),null}}));for(const u of d)if(u?.by_uri)for(const l of Object.values(u.by_uri)){const m=l.memory_type||"memory",g=(l.content||"").trim();g&&(m==="recently_memory"?t.push({title:l.title,content:g,uri:l.uri||""}):m==="agent_memory"&&r.push({title:l.title,content:g,uri:l.uri||""}))}}catch{f.debug("[loadAgentStartupMemories] \u65E0\u6CD5\u8BFB\u53D6\u8BB0\u5FC6\u76EE\u5F55: %s",o)}if(t.length===0&&r.length===0&&n?.schedulerBaseUrl&&n?.runtimeAccessToken&&n?.agentId){const a=`${n.schedulerBaseUrl.replace(/\/+$/,"")}/mcp/call`,c={"Content-Type":"application/json","X-Runtime-Token":n.runtimeAccessToken,Authorization:`Bearer ${n.runtimeAccessToken}`},d=["recently_memory","agent_memory"],u=await Promise.allSettled(d.map(l=>fetch(a,{method:"POST",headers:c,body:JSON.stringify({tool:"list_memories",arguments:{agentId:n.agentId,memory_type:l}})}).then(m=>{if(!m.ok)throw new Error(`Server returned ${m.status}`);return m.json()})));for(let l=0;l<u.length;l++){const m=u[l];if(m.status!=="fulfilled")continue;const g=m.value;if(!Array.isArray(g))continue;const T=d[l]==="recently_memory"?t:r;for(const h of g){const y=(h.content||"").trim();y&&T.push({title:h.title,content:y,uri:h.uri||""})}}(t.length>0||r.length>0)&&f.info(`[loadAgentStartupMemories] Loaded ${t.length} task(s) and ${r.length} memory(s) from server for ${n.agentId}`)}const s=10;t.sort((a,c)=>c.uri.localeCompare(a.uri)),r.sort((a,c)=>c.uri.localeCompare(a.uri));const i=[];if(t.length>0){const c=t.slice(0,s).map((d,u)=>`${d.title?`\u3010${d.title}\u3011`:`\u6761\u76EE ${u+1}`}
8
- ${d.content}`);i.push(`\u3010\u77ED\u671F\u8BB0\u5FC6\u3011
6
+ ${c}`,truncated:!0}}function ie(e,n){const t=String(e??"");return t.length<=n?t:`${t.slice(0,n)}...\uFF08\u622A\u65AD ${t.length-n} \u5B57\u7B26\uFF09`}function Qt(e){const n=e.toLowerCase();return n.includes("poll_message")||n.includes("get_message")||n.includes("await_complete")}function Zt(e){if(typeof e!="string"||!e.trim())return Array.isArray(e)&&e.length>0?e:void 0;try{const n=JSON.parse(e);if(!Array.isArray(n)||n.length===0)return;const t=new Set(["system","user","assistant","tool"]),r=1e6,o=n.filter(i=>!!i&&typeof i=="object"&&t.has(String(i.role))).filter(i=>JSON.stringify(i).length<=r).slice(0,5e3);return o.length>0?o:void 0}catch{return}}function en(e){const n=String(e??"").trim();if(!n)return"";let t;try{const s=JSON.parse(n);if(!s||typeof s!="object"||Array.isArray(s))return"";t=s}catch{return ie(n,Je)}const r=[];for(const s of["file_path","path","filePath","pattern","query","command","cmd","url"]){const o=t[s];if(typeof o=="string"&&o.trim()&&r.push(`${s}=${o.trim()}`),r.length>=3)break}if(r.length===0){const s=Object.keys(t).slice(0,5);return s.length>0?`(${s.join(", ")})`:""}return ie(r.join(" "),Je)}function Qe(e){if(e==null||typeof e!="object"||Array.isArray(e))return;const n=e,t={};return typeof n.model=="string"&&n.model.trim()&&(t.model=n.model.trim()),typeof n.baseURL=="string"&&n.baseURL.trim()&&(t.baseURL=n.baseURL.trim()),typeof n.apiKey=="string"&&n.apiKey.trim()&&(t.apiKey=n.apiKey.trim()),typeof n.effort=="string"&&n.effort.trim()&&(t.effort=n.effort.trim()),t}const z=new Set;async function tn(e,n){const t=[],r=[],s=j.join(e,".agentswork","memory");try{const c=(await v.readdir(s)).filter(d=>d.endsWith(".json")),u=await Promise.all(c.map(async d=>{try{const l=await v.readFile(j.join(s,d),"utf-8");return JSON.parse(l)}catch{return f.warn("[loadAgentStartupMemories] Failed to parse memory file: %s",j.join(s,d)),null}}));for(const d of u)if(d?.by_uri)for(const l of Object.values(d.by_uri)){const m=l.memory_type||"memory",p=(l.content||"").trim();p&&(m==="recently_memory"?t.push({title:l.title,content:p,uri:l.uri||""}):m==="agent_memory"&&r.push({title:l.title,content:p,uri:l.uri||""}))}}catch{f.debug("[loadAgentStartupMemories] \u65E0\u6CD5\u8BFB\u53D6\u8BB0\u5FC6\u76EE\u5F55: %s",s)}if(t.length===0&&r.length===0&&n?.schedulerBaseUrl&&n?.runtimeAccessToken&&n?.agentId){const a=`${n.schedulerBaseUrl.replace(/\/+$/,"")}/mcp/call`,c={"Content-Type":"application/json","X-Runtime-Token":n.runtimeAccessToken,Authorization:`Bearer ${n.runtimeAccessToken}`},u=["recently_memory","agent_memory"],d=await Promise.allSettled(u.map(l=>fetch(a,{method:"POST",headers:c,body:JSON.stringify({tool:"list_memories",arguments:{agentId:n.agentId,memory_type:l}})}).then(m=>{if(!m.ok)throw new Error(`Server returned ${m.status}`);return m.json()})));for(let l=0;l<d.length;l++){const m=d[l];if(m.status!=="fulfilled")continue;const p=m.value;if(!Array.isArray(p))continue;const b=u[l]==="recently_memory"?t:r;for(const y of p){const h=(y.content||"").trim();h&&b.push({title:y.title,content:h,uri:y.uri||""})}}(t.length>0||r.length>0)&&f.info(`[loadAgentStartupMemories] Loaded ${t.length} task(s) and ${r.length} memory(s) from server for ${n.agentId}`)}const o=10;t.sort((a,c)=>c.uri.localeCompare(a.uri)),r.sort((a,c)=>c.uri.localeCompare(a.uri));const i=[];if(t.length>0){const c=t.slice(0,o).map((u,d)=>`${u.title?`\u3010${u.title}\u3011`:`\u6761\u76EE ${d+1}`}
7
+ ${u.content}`);i.push(`\u3010\u77ED\u671F\u8BB0\u5FC6\u3011
9
8
  ${c.join(`
10
9
 
11
- `)}`),t.length>s&&i.push(`... \u53CA\u53E6\u5916 ${t.length-s} \u6761\u77ED\u671F\u8BB0\u5FC6`)}if(r.length>0){const c=r.slice(0,s).map(d=>{const u=d.title?`\u3010${d.title}\u3011`:"";return u?`${u}
12
- ${d.content}`:d.content});i.push(`\u3010agent\u8BA4\u77E5\u3011
10
+ `)}`),t.length>o&&i.push(`... \u53CA\u53E6\u5916 ${t.length-o} \u6761\u77ED\u671F\u8BB0\u5FC6`)}if(r.length>0){const c=r.slice(0,o).map(u=>{const d=u.title?`\u3010${u.title}\u3011`:"";return d?`${d}
11
+ ${u.content}`:u.content});i.push(`\u3010agent\u8BA4\u77E5\u3011
13
12
  ${c.join(`
14
13
 
15
- `)}`),r.length>s&&i.push(`... \u53CA\u53E6\u5916 ${r.length-s} \u6761 agent \u8BA4\u77E5`)}if(i.length!==0)return i.join(`
14
+ `)}`),r.length>o&&i.push(`... \u53CA\u53E6\u5916 ${r.length-o} \u6761 agent \u8BA4\u77E5`)}if(i.length!==0)return i.join(`
16
15
 
17
- `)}function xt(e,n){return e!=="acode"?{supported:!1,statusCode:400,error:"context reset without restart is only supported by ACode"}:n?{supported:!0}:{supported:!1,statusCode:500,error:"ACode adapter does not expose resetContext"}}function Bt(e){return e!=="acode"}function Nt(e){const n=typeof e=="object"&&e!==null&&"suppressStatus"in e&&e.suppressStatus===!0,t=typeof e=="object"&&e!==null&&"reason"in e&&typeof e.reason=="string"&&e.reason.trim()?e.reason.trim():void 0;return{statusNotified:!n,reason:t}}function oe(e){const n=e?.usage;if(!n)return;const t=Number.isFinite(n.inputTokens)?n.inputTokens:0,r=Number.isFinite(n.outputTokens)?n.outputTokens:0;if(t<=0&&r<=0&&!n.contextLimit&&!n.maxOutput&&!n.inputLimit&&!n.compactionThreshold)return;const o={inputTokens:t,outputTokens:r,...n.contextLimit?{contextLimit:n.contextLimit}:{},...n.maxOutput?{maxOutput:n.maxOutput}:{},...n.inputLimit?{inputLimit:n.inputLimit}:{},...n.compactionThreshold?{compactionThreshold:n.compactionThreshold}:{},...n.cacheHitTokens?{cacheHitTokens:n.cacheHitTokens}:{},...n.cacheMissTokens?{cacheMissTokens:n.cacheMissTokens}:{}};return process.env.ACODE_TOKEN_DEBUG==="1"&&(o.inputTokens>0||o.outputTokens>0||o.cacheHitTokens!==void 0||o.cacheMissTokens!==void 0)&&f.info(`[TokenDebug][Terminal] resolveStatusChangeUsage: input=${o.inputTokens} output=${o.outputTokens} cacheHit=${o.cacheHitTokens??"(none)"} cacheMiss=${o.cacheMissTokens??"(none)"} actionType=${e?.actionType??"(none)"}`),o}function vt(e,n){const t=String(e||"").trim().toLowerCase(),r=String(n?.actionType||"").trim().toLowerCase();return t==="tool_using"&&r==="idle"?n?{status:"waiting_input",actionInfo:n}:{status:"waiting_input"}:n?{status:e,actionInfo:n}:{status:e}}function Ft(e){return e.restoredActionInfo?.actionType==="idle"||e.currentRuntimeActionType==="idle"&&e.shouldPreservePrevAction||e.status==="waiting_input"&&!e.actionInfo?.actionType}const Q=new Map,qt="utf-8",qe="utf-8",Ke=300,He=6e4;function V(e){return String(e).padStart(2,"0")}function Kt(e,n=new Date){const t=n.getFullYear(),r=V(n.getMonth()+1),o=V(n.getDate()),s=V(n.getHours()),i=V(n.getMinutes()),a=`${t}${r}${o}-${s}${i}${V(n.getSeconds())}-${String(n.getMilliseconds()).padStart(3,"0")}`;return B.join($e(),"cmd-dist",e,`${t}-${r}-${o}`,s,i,`${a}-cmd.out`)}function Ht(e){if(!e)return 0;const n=e.replace(/\r\n/g,`
16
+ `)}function nn(e,n){return e!=="acode"?{supported:!1,statusCode:400,error:"context reset without restart is only supported by ACode"}:n?{supported:!0}:{supported:!1,statusCode:500,error:"ACode adapter does not expose resetContext"}}function rn(e){return e!=="acode"}function on(e){const n=typeof e=="object"&&e!==null&&"suppressStatus"in e&&e.suppressStatus===!0,t=typeof e=="object"&&e!==null&&"reason"in e&&typeof e.reason=="string"&&e.reason.trim()?e.reason.trim():void 0;return{statusNotified:!n,reason:t}}function ae(e){const n=e?.usage;if(!n)return;const t=Number.isFinite(n.inputTokens)?n.inputTokens:0,r=Number.isFinite(n.outputTokens)?n.outputTokens:0;if(t<=0&&r<=0&&!n.contextLimit&&!n.maxOutput&&!n.inputLimit&&!n.compactionThreshold)return;const s={inputTokens:t,outputTokens:r,...n.contextLimit?{contextLimit:n.contextLimit}:{},...n.maxOutput?{maxOutput:n.maxOutput}:{},...n.inputLimit?{inputLimit:n.inputLimit}:{},...n.compactionThreshold?{compactionThreshold:n.compactionThreshold}:{},...n.cacheHitTokens!==void 0?{cacheHitTokens:n.cacheHitTokens}:{},...n.cacheMissTokens!==void 0?{cacheMissTokens:n.cacheMissTokens}:{}};return process.env.ACODE_TOKEN_DEBUG==="1"&&(s.inputTokens>0||s.outputTokens>0||s.cacheHitTokens!==void 0||s.cacheMissTokens!==void 0)&&f.info(`[TokenDebug][Terminal] resolveStatusChangeUsage: input=${s.inputTokens} output=${s.outputTokens} cacheHit=${s.cacheHitTokens??"(none)"} cacheMiss=${s.cacheMissTokens??"(none)"} actionType=${e?.actionType??"(none)"}`),s}function sn(e,n){const t=String(e||"").trim().toLowerCase(),r=String(n?.actionType||"").trim().toLowerCase();return t==="tool_using"&&r==="idle"?n?{status:"waiting_input",actionInfo:n}:{status:"waiting_input"}:n?{status:e,actionInfo:n}:{status:e}}function an(e){return e.restoredActionInfo?.actionType==="idle"||e.currentRuntimeActionType==="idle"&&e.shouldPreservePrevAction||e.status==="waiting_input"&&!e.actionInfo?.actionType}const V=new Map,cn="utf-8",Ze="utf-8",et=300,tt=6e4;function Q(e){return String(e).padStart(2,"0")}function un(e,n=new Date){const t=n.getFullYear(),r=Q(n.getMonth()+1),s=Q(n.getDate()),o=Q(n.getHours()),i=Q(n.getMinutes()),a=`${t}${r}${s}-${o}${i}${Q(n.getSeconds())}-${String(n.getMilliseconds()).padStart(3,"0")}`;return j.join(Me(),"cmd-dist",e,`${t}-${r}-${s}`,o,i,`${a}-cmd.out`)}function dn(e){if(!e)return 0;const n=e.replace(/\r\n/g,`
18
17
  `).replace(/\r/g,`
19
18
  `),t=n.endsWith(`
20
19
  `)?n.slice(0,-1):n;return t?t.split(`
21
- `).length:1}function zt(e,n=Ke){return`\r
20
+ `).length:1}function ln(e,n=et){return`\r
22
21
  [ACode] \u547D\u4EE4\u8F93\u51FA\u8D85\u8FC7 ${n} \u884C\uFF0C\u5B8C\u6574\u8F93\u51FA\u5DF2\u5199\u5165: ${e}\r
23
22
  [ACode] Agent \u53EF\u81EA\u884C\u8BFB\u53D6\u8BE5\u6587\u4EF6\uFF0C\u6216\u5728\u8BE5\u6587\u4EF6\u4E2D\u641C\u7D22\u9700\u8981\u7684\u5185\u5BB9\u3002\r
24
- `}function Wt(e=He){return`\r
23
+ `}function fn(e=tt){return`\r
25
24
  [ACode] \u547D\u4EE4\u8D85\u8FC7 ${Math.round(e/1e3)} \u79D2\u6CA1\u6709\u65B0\u7684\u8F93\u51FA\uFF0C\u5DF2\u505C\u6B62\u6267\u884C\u5E76\u4FDD\u7559\u6B64\u524D\u8F93\u51FA\u3002\r
26
- `}async function ze(e){const n=e.outputPath||Kt(e.agentId,e.startedAt);return e.outputPath=n,await F.mkdir(B.dirname(n),{recursive:!0}),await F.writeFile(n,e.chunks.join(""),"utf-8"),n}function Gt(e){return String(e??"").replace(/\r/g,`
27
- `).trim()}function Xt(e=process.platform,n=process.env){const t=n.AWS_TERMINAL_OUTPUT_ENCODING?.trim();return t||(e==="win32"?qt:qe)}function We(e=Xt()){if(e!=="utf-8")try{return new te(e,{fatal:!1})}catch{return new te(qe,{fatal:!1})}return Yt()}function Yt(){let e=null,n=null,t=null;const r=[];function o(s){try{return new te(s,{fatal:!1})}catch{return new te("utf-8",{fatal:!1})}}return{decode(s,i){if(s!=null&&r.push(s instanceof ArrayBuffer?Buffer.from(s):Buffer.isBuffer(s)?s:Buffer.from(s.buffer,s.byteOffset,s.byteLength)),t==="gb18030")return n||(n=o("gb18030")),n.decode(s,i);e||(e=o("utf-8"));const a=e.decode(s,i);if(t===null&&a.includes("\uFFFD")){t="gb18030",n=o("gb18030");const c=Buffer.concat(r);return n.decode(c)}return t===null&&!i?.stream&&(t="utf-8"),a}}}function se(e,n,t=!1){return t?e.decode():!n||n.length===0?"":e.decode(n,{stream:!0})}function Qt(e){const n=e.trim().match(/^cd(?:\s+(.*))?$/i);if(!n)return;const t=n[1]?.trim();if(!t)return null;const r=t.replace(/^\/d\s+/i,"").trim();return r.startsWith('"')&&r.endsWith('"')||r.startsWith("'")&&r.endsWith("'")?r.slice(1,-1):r}function Vt(e){const n=Q.get(e.sessionId);if(n)return n;const t={currentDirectory:e.workspacePath,runningProcess:null};return Q.set(e.sessionId,t),t}function Ge(e){for(const n of p.values())if(n.agentId===e)return n}async function Jt(e){const n=k.get(e.providerId||"claude-code"),t=ie(n.getSessionStatus(e.sessionId),e.currentRuntimeStatus,e.currentRuntimeActionType);return{sessionId:e.sessionId,status:t,runtimeStatus:t,runtimeActionType:e.currentRuntimeActionType,runtimeActionLabel:e.currentRuntimeActionLabel,runtimeActionDetail:e.currentRuntimeActionDetail,agentId:e.agentId,workspacePath:e.workspacePath,command:e.config.command,mode:"sdk",providerSessionId:n.getProviderSessionId(e.sessionId),reused:!0}}function ie(e,n,t){const r=String(e||"").trim();if(r){const s=String(n||"").trim(),i=String(t||"").trim().toLowerCase();return r.toLowerCase()==="tool_using"&&s.toLowerCase()==="waiting_input"&&i==="idle"?s:r}return String(n||"").trim()||"running"}function Zt(e,n=Tt){return e.pid?n(e.pid)?Ze(e.command)==="acode"?{reusable:!1,reason:"in-process-provider"}:{reusable:!0,reason:"active-pid"}:{reusable:!1,reason:"dead-pid"}:{reusable:!1,reason:"missing-pid"}}function ur(e){const n=Ge(e);if(!n)f.info(`[cleanupSdkSessionByAgentId] No active SDK session found for agentId=${e}, cleaning residual state anyway`);else{const t=n.sessionId;return f.info(`[cleanupSdkSessionByAgentId] Cleaning up SDK session for agentId=${e}, sessionId=${t}`),M(t),p.delete(t),K(t),ae(t),H(t).catch(r=>{f.warn(`[cleanupSdkSessionByAgentId] Failed to remove persisted session for agentId=${e}: ${r}`)}),t}z.has(e)&&(z.delete(e),f.info(`[cleanupSdkSessionByAgentId] Released startingAgents lock for agentId=${e}`))}function ae(e){const n=Q.get(e);if(!n?.runningProcess){Q.delete(e);return}try{n.runningProcess.kill()}catch{}finally{n.runningProcess=null,Q.delete(e)}}function w(e,n){n&&(e.seq+=1,Y(e.agentId,n,e.sessionId,e.seq,void 0,{runtimeAccessToken:e.runtimeAccessToken,schedulerBaseUrl:e.schedulerBaseUrl}).catch(()=>{}))}function Se(e){return`\x1B[36m${e}>\x1B[0m `}function en(e,n){return n==="~"?ot.homedir():B.resolve(e,n)}async function tn(e,n,t){const r=Qt(t);if(r===void 0)return!1;if(r===null)return w(e,`${n.currentDirectory}\r
28
- `),!0;const o=en(n.currentDirectory,r);try{return(await F.stat(o)).isDirectory()?(n.currentDirectory=o,w(e,`${n.currentDirectory}\r
29
- `),!0):(w(e,`cd: not a directory: ${o}\r
30
- `),!0)}catch(s){const i=s instanceof Error?s.message:String(s);return w(e,`cd: ${i}\r
31
- `),!0}}async function nn(e,n){const t=p.get(e);if(!t)throw new Error("SDK session not found");const r=Gt(n),o=Vt(t);if(!r)return{started:!1,cwd:o.currentDirectory};if(o.runningProcess)throw new Error("A terminal command is already running for this session");const s=q(r);if(w(t,`${Se(o.currentDirectory)}${s}\r
32
- `),we(r))return w(t,`[Terminal Warning] \u68C0\u6D4B\u5230\u526A\u8D34\u677F\u4E34\u65F6 paste \u6587\u4EF6\u8DEF\u5F84\uFF0C\u5DF2\u8DF3\u8FC7\u6267\u884C\u3002\u8BF7\u7C98\u8D34\u6587\u4EF6\u5185\u5BB9\u6216\u4F7F\u7528\u663E\u5F0F\u8BFB\u53D6\u547D\u4EE4\u3002\r
33
- `),w(t,Se(o.currentDirectory)),{started:!1,cwd:o.currentDirectory};if(await tn(t,o,r))return{started:!1,cwd:o.currentDirectory};await $(t.agentId,e,"tool_using",{actionType:"bash",actionLabel:"\u7EC8\u7AEF\u547D\u4EE4",actionDetail:s},void 0,{runtimeAccessToken:t.runtimeAccessToken,schedulerBaseUrl:t.schedulerBaseUrl});const a=rt(r,{cwd:o.currentDirectory,shell:!0,env:Xe(t.agentId,t.workspacePath,process.env,t.config.envOverrides)});o.runningProcess=a;const c=We(),d=We(),u=t.providerId==="acode",l={agentId:t.agentId,startedAt:new Date,chunks:[],spilled:!1};let m;const g=()=>{m&&(clearTimeout(m),m=void 0)},T=()=>{g(),m=setTimeout(()=>{o.runningProcess===a&&(w(t,Wt()),a.kill())},He)},h=(y,C=!0)=>{if(y&&(u&&l.chunks.push(y),u&&C&&T(),!(u&&l.spilled))){if(u&&Ht(l.chunks.join(""))>Ke){l.spilled=!0,ze(l).then(R=>{w(t,zt(R))}).catch(R=>{const O=R instanceof Error?R.message:String(R);w(t,`\r
34
- [ACode] \u547D\u4EE4\u8F93\u51FA\u843D\u76D8\u5931\u8D25: ${O}\r
35
- `)});return}w(t,y)}};return u&&T(),a.stdout.on("data",y=>{h(se(c,y))}),a.stderr.on("data",y=>{h(se(d,y))}),a.on("error",y=>{w(t,`\r
36
- [Terminal Error] ${y.message}\r
37
- `)}),a.on("close",(y,C)=>{g(),o.runningProcess=null,h(se(c,void 0,!0),!1),h(se(d,void 0,!0),!1),l.spilled&&ze(l).catch(R=>{const O=R instanceof Error?R.message:String(R);w(t,`\r
38
- [ACode] \u547D\u4EE4\u8F93\u51FA\u6700\u7EC8\u843D\u76D8\u5931\u8D25: ${O}\r
39
- `)}),y&&y!==0?w(t,`\r
40
- [exit ${y}]\r
41
- `):C&&w(t,`\r
42
- [signal ${C}]\r
43
- `),w(t,Se(o.currentDirectory)),$(t.agentId,e,"waiting_input",void 0,void 0,{runtimeAccessToken:t.runtimeAccessToken,schedulerBaseUrl:t.schedulerBaseUrl})}),{started:!0,cwd:o.currentDirectory}}function Xe(e,n,t,r){const o={};for(const[s,i]of Object.entries(t))i!==void 0&&(o[s]=i);if(n&&(o.AWS_WORKSPACE_PATH=String(n)),r)for(const[s,i]of Object.entries(r)){const a=s.trim();if(!a||i===void 0||i===null)continue;const c=String(i).trim();c&&(o[a]=c)}return o.AWS_AGENT_ID=String(e),o.AWS_MCP_CLAIM_LAUNCH_BINDING="true",o.AWS_RUNTIME_BRIDGE_BASE_URL=`http://127.0.0.1:${ut()}`,String(o.ACODE_HOME||"").trim()||(o.ACODE_HOME=$e()),b(e,Ee)!=="disabled"&&(o.AWS_LAUNCH_CONFIG_TOOLS=b(e,Ee)),b(e,De)!=="disabled"&&(o.AWS_HIRE_TOOLS=b(e,De)),b(e,Pe)!=="disabled"&&(o.AWS_PENCIL_TOOLS=b(e,Pe)),b(e,Le)!=="disabled"&&(o.AWS_DRAW_TOOLS=b(e,Le)),b(e,Oe)!=="disabled"&&(o.AWS_OFFICE_TOOLS=b(e,Oe)),b(e,Me)!=="disabled"&&(o.AWS_COLLABORATION_TASK_TOOLS=b(e,Me)),b(e,Ue)!=="disabled"&&(o.AWS_COLLABORATION_MEETING_TOOLS=b(e,Ue)),b(e,je)!=="disabled"&&(o.AWS_COLLABORATION_DEBUG_TOOLS=b(e,je)),b(e,xe)!=="disabled"&&(o.AWS_COLLABORATION_FILE_HISTORY_TOOLS=b(e,xe)),o}function rn(e){const n=e.trim(),t=n[0],r=n[n.length-1];return(t==='"'||t==="'")&&t===r?n.slice(1,-1):n}async function on(e){const n=String(e);if(!we(n))return n;const t=rn(n);return B.isAbsolute(t)?F.readFile(t,"utf-8"):n}function Ye(e,n){const t={};for(const o of[e?.env,n])if(o)for(const[s,i]of Object.entries(o)){const a=s.trim();if(!a||i===void 0||i===null)continue;const c=String(i).trim();c&&(t[a]=c)}const r=t.ANTHROPIC_MODEL?.trim()||t.CODEX_MODEL?.trim()||void 0;return{envOverrides:t,model:r}}async function sn(){try{return await dt().readClaudeCodeConfig()}catch(e){return console.warn(`[Runtime] Failed to read saved ClaudeCode AI config: ${e.message}`),{}}}function an(e){if(e==null)return;const t=(typeof e=="string"?e:JSON.stringify(e,null,2)).trim();if(t)return t.length<=ve?t:`${t.slice(0,ve)}
44
- ...\uFF08\u7ED3\u679C\u8FC7\u957F\uFF0C\u5DF2\u622A\u65AD\uFF09`}function cn(e){try{const n=JSON.parse(e);if(n&&typeof n=="object"&&!Array.isArray(n))return["directMessages","groupMessages","messages"].some(t=>Array.isArray(n[t])&&n[t].length>0)}catch{}return e.trim().length>0}function un(e){if(e.data.actionType==="mcp")return!0;const t=String(e.data.toolName||"").toLowerCase();return t.startsWith("mcp__")||t.includes("-mcp__")||t.includes("mcp_")}function dn(e){if(e.type!=="tool_use_end")return;const n=an(e.data.toolResult??e.data.actionResult);if(!n)return;const t=he(e.data.toolName,e.data.toolInput),r=e.data.actionType||t.actionType;if(r==="idle"){const o=String(e.data.rawToolName||e.data.toolName||"").toLowerCase();if((o.includes("poll_message")||o.includes("get_message"))&&!cn(n))return}return r==="mcp"&&un(e)?{actionType:"mcp",actionLabel:"MCP\u8FD4\u56DE",actionDetail:e.data.actionDetail||e.data.toolName,actionId:e.data.actionId||e.data.toolUseId,actionResult:n}:{actionType:r,actionLabel:e.data.actionLabel||t.actionLabel,actionDetail:e.data.actionDetail||t.actionDetail||e.data.toolName,actionId:e.data.actionId||e.data.toolUseId,actionResult:n}}function ln(e){if(e.type==="ai_request"){const n=e.data.model?` ${e.data.model}`:"",t=e.data.lastUserMessagePreview?`\uFF1A${e.data.lastUserMessagePreview}`:"";return`\r
25
+ `}async function nt(e){const n=e.outputPath||un(e.agentId,e.startedAt);return e.outputPath=n,await v.mkdir(j.dirname(n),{recursive:!0}),await v.writeFile(n,e.chunks.join(""),"utf-8"),n}function mn(e){return String(e??"").replace(/\r/g,`
26
+ `).trim()}function pn(e=process.platform,n=process.env){const t=n.AWS_TERMINAL_OUTPUT_ENCODING?.trim();return t||(e==="win32"?cn:Ze)}function rt(e=pn()){if(e!=="utf-8")try{return new re(e,{fatal:!1})}catch{return new re(Ze,{fatal:!1})}return gn()}function gn(){let e=null,n=null,t=null;const r=[];function s(o){try{return new re(o,{fatal:!1})}catch{return new re("utf-8",{fatal:!1})}}return{decode(o,i){if(o!=null&&r.push(o instanceof ArrayBuffer?Buffer.from(o):Buffer.isBuffer(o)?o:Buffer.from(o.buffer,o.byteOffset,o.byteLength)),t==="gb18030")return n||(n=s("gb18030")),n.decode(o,i);e||(e=s("utf-8"));const a=e.decode(o,i);if(t===null&&a.includes("\uFFFD")){t="gb18030",n=s("gb18030");const c=Buffer.concat(r);return n.decode(c)}return t===null&&!i?.stream&&(t="utf-8"),a}}}function ce(e,n,t=!1){return t?e.decode():!n||n.length===0?"":e.decode(n,{stream:!0})}function yn(e){const n=e.trim().match(/^cd(?:\s+(.*))?$/i);if(!n)return;const t=n[1]?.trim();if(!t)return null;const r=t.replace(/^\/d\s+/i,"").trim();return r.startsWith('"')&&r.endsWith('"')||r.startsWith("'")&&r.endsWith("'")?r.slice(1,-1):r}function hn(e){const n=V.get(e.sessionId);if(n)return n;const t={currentDirectory:e.workspacePath,runningProcess:null};return V.set(e.sessionId,t),t}function ot(e){for(const n of g.values())if(n.agentId===e)return n}async function In(e){const n=_.get(e.providerId||"claude-code"),t=ue(n.getSessionStatus(e.sessionId),e.currentRuntimeStatus,e.currentRuntimeActionType);return{sessionId:e.sessionId,status:t,runtimeStatus:t,runtimeActionType:e.currentRuntimeActionType,runtimeActionLabel:e.currentRuntimeActionLabel,runtimeActionDetail:e.currentRuntimeActionDetail,agentId:e.agentId,workspacePath:e.workspacePath,command:e.config.command,mode:"sdk",providerSessionId:n.getProviderSessionId(e.sessionId),reused:!0}}function ue(e,n,t){const r=String(e||"").trim();if(r){const o=String(n||"").trim(),i=String(t||"").trim().toLowerCase();return r.toLowerCase()==="tool_using"&&o.toLowerCase()==="waiting_input"&&i==="idle"?o:r}return String(n||"").trim()||"running"}async function Sn(e,n=xt){return e.pid?await n(e.pid)?dt(e.command)==="acode"?{reusable:!1,reason:"in-process-provider"}:{reusable:!0,reason:"active-pid"}:{reusable:!1,reason:"dead-pid"}:{reusable:!1,reason:"missing-pid"}}function Er(e){const n=ot(e);if(!n)f.info(`[cleanupSdkSessionByAgentId] No active SDK session found for agentId=${e}, cleaning residual state anyway`);else{const t=n.sessionId;return f.info(`[cleanupSdkSessionByAgentId] Cleaning up SDK session for agentId=${e}, sessionId=${t}`),M(t),g.delete(t),H(t),de(t),q(t).catch(r=>{f.warn(`[cleanupSdkSessionByAgentId] Failed to remove persisted session for agentId=${e}: ${r}`)}),t}z.has(e)&&(z.delete(e),f.info(`[cleanupSdkSessionByAgentId] Released startingAgents lock for agentId=${e}`))}function de(e){const n=V.get(e);if(!n?.runningProcess){V.delete(e);return}try{n.runningProcess.kill()}catch{}finally{n.runningProcess=null,V.delete(e)}}function C(e,n){n&&(e.seq+=1,J(e.agentId,n,e.sessionId,e.seq,void 0,{runtimeAccessToken:e.runtimeAccessToken,schedulerBaseUrl:e.schedulerBaseUrl}).catch(()=>{}))}function Ce(e){return`\x1B[36m${e}>\x1B[0m `}function An(e,n){return n==="~"?gt.homedir():j.resolve(e,n)}async function Tn(e,n,t){const r=yn(t);if(r===void 0)return!1;if(r===null)return C(e,`${n.currentDirectory}\r
27
+ `),!0;const s=An(n.currentDirectory,r);try{return(await v.stat(s)).isDirectory()?(n.currentDirectory=s,C(e,`${n.currentDirectory}\r
28
+ `),!0):(C(e,`cd: not a directory: ${s}\r
29
+ `),!0)}catch(o){const i=o instanceof Error?o.message:String(o);return C(e,`cd: ${i}\r
30
+ `),!0}}async function _n(e,n){const t=g.get(e);if(!t)throw new Error("SDK session not found");const r=mn(n),s=hn(t);if(!r)return{started:!1,cwd:s.currentDirectory};if(s.runningProcess)throw new Error("A terminal command is already running for this session");const o=K(r);if(C(t,`${Ce(s.currentDirectory)}${o}\r
31
+ `),Oe(r))return C(t,`[Terminal Warning] \u68C0\u6D4B\u5230\u526A\u8D34\u677F\u4E34\u65F6 paste \u6587\u4EF6\u8DEF\u5F84\uFF0C\u5DF2\u8DF3\u8FC7\u6267\u884C\u3002\u8BF7\u7C98\u8D34\u6587\u4EF6\u5185\u5BB9\u6216\u4F7F\u7528\u663E\u5F0F\u8BFB\u53D6\u547D\u4EE4\u3002\r
32
+ `),C(t,Ce(s.currentDirectory)),{started:!1,cwd:s.currentDirectory};if(await Tn(t,s,r))return{started:!1,cwd:s.currentDirectory};await E(t.agentId,e,"tool_using",{actionType:"bash",actionLabel:"\u7EC8\u7AEF\u547D\u4EE4",actionDetail:o},void 0,{runtimeAccessToken:t.runtimeAccessToken,schedulerBaseUrl:t.schedulerBaseUrl});const a=pt(r,{cwd:s.currentDirectory,shell:!0,env:st(t.agentId,t.workspacePath,process.env,t.config.envOverrides)});s.runningProcess=a;const c=rt(),u=rt(),d=t.providerId==="acode",l={agentId:t.agentId,startedAt:new Date,chunks:[],spilled:!1};let m;const p=()=>{m&&(clearTimeout(m),m=void 0)},b=()=>{p(),m=setTimeout(()=>{s.runningProcess===a&&(C(t,fn()),a.kill())},tt)},y=(h,$=!0)=>{if(h&&(d&&l.chunks.push(h),d&&$&&b(),!(d&&l.spilled))){if(d&&dn(l.chunks.join(""))>et){l.spilled=!0,nt(l).then(R=>{C(t,ln(R))}).catch(R=>{const D=R instanceof Error?R.message:String(R);C(t,`\r
33
+ [ACode] \u547D\u4EE4\u8F93\u51FA\u843D\u76D8\u5931\u8D25: ${D}\r
34
+ `)});return}C(t,h)}};return d&&b(),a.stdout.on("data",h=>{y(ce(c,h))}),a.stderr.on("data",h=>{y(ce(u,h))}),a.on("error",h=>{C(t,`\r
35
+ [Terminal Error] ${h.message}\r
36
+ `)}),a.on("close",(h,$)=>{p(),s.runningProcess=null,y(ce(c,void 0,!0),!1),y(ce(u,void 0,!0),!1),l.spilled&&nt(l).catch(R=>{const D=R instanceof Error?R.message:String(R);C(t,`\r
37
+ [ACode] \u547D\u4EE4\u8F93\u51FA\u6700\u7EC8\u843D\u76D8\u5931\u8D25: ${D}\r
38
+ `)}),h&&h!==0?C(t,`\r
39
+ [exit ${h}]\r
40
+ `):$&&C(t,`\r
41
+ [signal ${$}]\r
42
+ `),C(t,Ce(s.currentDirectory)),E(t.agentId,e,"waiting_input",void 0,void 0,{runtimeAccessToken:t.runtimeAccessToken,schedulerBaseUrl:t.schedulerBaseUrl})}),{started:!0,cwd:s.currentDirectory}}function st(e,n,t,r,s){const o={};for(const[i,a]of Object.entries(t))a!==void 0&&(o[i]=a);if(n&&(o.AWS_WORKSPACE_PATH=String(n)),s&&String(s).trim()&&(o.AWS_PROJECT_ROOT=String(s).trim()),r)for(const[i,a]of Object.entries(r)){const c=i.trim();if(!c||a===void 0||a===null)continue;const u=String(a).trim();u&&(o[c]=u)}return o.AWS_AGENT_ID=String(e),o.AWS_MCP_CLAIM_LAUNCH_BINDING="true",o.AWS_RUNTIME_BRIDGE_BASE_URL=`http://127.0.0.1:${At()}`,String(o.ACODE_HOME||"").trim()||(o.ACODE_HOME=Me()),T(e,xe)!=="disabled"&&(o.AWS_LAUNCH_CONFIG_TOOLS=T(e,xe)),T(e,Ne)!=="disabled"&&(o.AWS_HIRE_TOOLS=T(e,Ne)),T(e,je)!=="disabled"&&(o.AWS_PENCIL_TOOLS=T(e,je)),T(e,Be)!=="disabled"&&(o.AWS_DRAW_TOOLS=T(e,Be)),T(e,Fe)!=="disabled"&&(o.AWS_OFFICE_TOOLS=T(e,Fe)),T(e,ve)!=="disabled"&&(o.AWS_COLLABORATION_TASK_TOOLS=T(e,ve)),T(e,Ke)!=="disabled"&&(o.AWS_COLLABORATION_MEETING_TOOLS=T(e,Ke)),T(e,He)!=="disabled"&&(o.AWS_COLLABORATION_DEBUG_TOOLS=T(e,He)),T(e,qe)!=="disabled"&&(o.AWS_COLLABORATION_FILE_HISTORY_TOOLS=T(e,qe)),T(e,ze)!=="disabled"&&(o.AWS_EMAIL_TOOLS=T(e,ze)),o}function bn(e){const n=e.trim(),t=n[0],r=n[n.length-1];return(t==='"'||t==="'")&&t===r?n.slice(1,-1):n}async function kn(e){const n=String(e);if(!Oe(n))return n;const t=bn(n);return j.isAbsolute(t)?v.readFile(t,"utf-8"):n}function it(e,n){const t={};for(const s of[e?.env,n])if(s)for(const[o,i]of Object.entries(s)){const a=o.trim();if(!a||i===void 0||i===null)continue;const c=String(i).trim();c&&(t[a]=c)}const r=t.ANTHROPIC_MODEL?.trim()||t.CODEX_MODEL?.trim()||void 0;return{envOverrides:t,model:r}}async function Cn(){try{return await _t().readClaudeCodeConfig()}catch(e){return console.warn(`[Runtime] Failed to read saved ClaudeCode AI config: ${e.message}`),{}}}function $n(e){if(e==null)return;const t=(typeof e=="string"?e:JSON.stringify(e,null,2)).trim();if(t)return t.length<=Xe?t:`${t.slice(0,Xe)}
43
+ ...\uFF08\u7ED3\u679C\u8FC7\u957F\uFF0C\u5DF2\u622A\u65AD\uFF09`}function wn(e){try{const n=JSON.parse(e);if(n&&typeof n=="object"&&!Array.isArray(n))return["directMessages","groupMessages","messages"].some(t=>Array.isArray(n[t])&&n[t].length>0)}catch{}return e.trim().length>0}function En(e){if(e.data.actionType==="mcp")return!0;const t=String(e.data.toolName||"").toLowerCase();return t.startsWith("mcp__")||t.includes("-mcp__")||t.includes("mcp_")}function Rn(e){if(e.type!=="tool_use_end")return;const n=$n(e.data.toolResult??e.data.actionResult);if(!n)return;const t=be(e.data.toolName,e.data.toolInput),r=e.data.actionType||t.actionType;if(r==="idle"){const s=String(e.data.rawToolName||e.data.toolName||"").toLowerCase();if((s.includes("poll_message")||s.includes("get_message"))&&!wn(n))return}return r==="mcp"&&En(e)?{actionType:"mcp",actionLabel:"MCP\u8FD4\u56DE",actionDetail:e.data.actionDetail||e.data.toolName,actionId:e.data.actionId||e.data.toolUseId,actionResult:n,...e.data.parentId?{parentId:e.data.parentId}:{}}:{actionType:r,actionLabel:e.data.actionLabel||t.actionLabel,actionDetail:e.data.actionDetail||t.actionDetail||e.data.toolName,actionId:e.data.actionId||e.data.toolUseId,actionResult:n,...e.data.parentId?{parentId:e.data.parentId}:{}}}function Dn(e){if(e.type==="ai_request"){const n=e.data.model?` ${e.data.model}`:"",t=e.data.lastUserMessagePreview?`\uFF1A${e.data.lastUserMessagePreview}`:"";return`\r
45
44
  [ACode] \u6B63\u5728\u8BF7\u6C42\u6A21\u578B${n}${t}\r
46
45
  `}if(e.type==="text_delta"||e.type==="thinking"||e.type==="command_output")return e.data.text||void 0;if(e.type==="error")return e.data.text?`\r
47
46
  [SDK Error] ${e.data.text}\r
48
- `:void 0}function fn(e){const n=gn(e);return{sourceEventType:e.type,logCategory:"acode",...pn(e),...n?{logLevel:mn(e),logMessage:n}:{}}}function mn(e){return e.type==="error"?"error":e.type==="command_output"&&e.data.stream==="stderr"?"warn":"info"}function pn(e){return e.type!=="command_output"?{}:{...typeof e.data.stream=="string"?{stream:e.data.stream}:{},...typeof e.data.sequence=="number"?{sequence:e.data.sequence}:{},...typeof e.data.cwd=="string"?{cwd:e.data.cwd}:{},...typeof e.data.commandFilePath=="string"?{commandFilePath:e.data.commandFilePath}:{},...typeof e.data.commandLineCount=="number"?{commandLineCount:e.data.commandLineCount}:{}}}function gn(e){if(e.type==="ai_request"){const n=e.data.model||"unknown-model",t=e.data.endpoint?` @ ${e.data.endpoint}`:"",r=typeof e.data.toolCount=="number"?`, tools=${e.data.toolCount}`:"";return`AI request started: ${n}${t}${r}`}if(e.type==="tool_use_start")return Qe(e,"\u5F00\u59CB");if(e.type==="tool_use_end")return Qe(e,"\u5B8C\u6210");if(e.type==="command_output")return In(e);if(e.type==="turn_complete")return`Turn completed${e.data.finishReason?`, finish=${e.data.finishReason}`:""}`;if(e.type==="session_complete")return`Session completed: exitCode=${e.data.exitCode??0}`;if(e.type==="error")return e.data.text||"ACode runtime error"}const yn=/\x1b\[[0-9;?]*[a-zA-Z]/g;function hn(e){return e.replace(yn,"")}function In(e){const n=typeof e.data.stream=="string"?e.data.stream:"mixed",t=typeof e.data.sequence=="number"?` #${e.data.sequence}`:"",r=hn(String(e.data.text||"")).replace(/\s+/g," ").trim(),o=r.length>240?`${r.slice(0,240)}...`:r;return`\u547D\u4EE4\u8F93\u51FA(${n}${t}): ${o||"(empty)"}`}function Qe(e,n){const t=he(e.data.toolName,e.data.toolInput),r=e.data.actionLabel||t.actionLabel||"\u8C03\u7528\u5DE5\u5177",o=Ve(e,t);return o?`${n}${r}: ${o}`:`${n}${r}: ${e.data.actionDetail||e.data.toolName||"tool"}`}function Ve(e,n){const t=e.data.toolInput;return n.actionType==="bash"?Sn(t)||e.data.actionDetail||n.actionDetail:n.actionType==="read_file"||n.actionType==="edit_file"||n.actionType==="write_file"?An(t)||e.data.actionDetail||n.actionDetail:e.data.actionDetail||n.actionDetail}function Sn(e){const n=Ae(e?.command,e?.cmd);if(n)return n;if(Array.isArray(e?.argv)){const t=e.argv.map(r=>String(r??"").trim()).filter(Boolean).join(" ");return t?q(t):void 0}return Ae(e?.args)}function An(e){const n=Je(e?.paths);return n.length>0?n.length===1?n[0]:`${n.length}\u4E2A\u6587\u4EF6: ${n.join(", ")}`:Ae(e?.file_path,e?.filePath,e?.path,e?.target_file,e?.targetFile)}function Ae(...e){for(const n of e){if(typeof n=="string"&&n.trim())return q(n.trim());if(Array.isArray(n)){const t=Je(n)[0];if(t)return t}}}function Je(e){return Array.isArray(e)?e.map(n=>typeof n=="string"?n.trim():"").filter(Boolean).map(n=>q(n)):[]}function Tn(e){if(!(!e||Object.keys(e).length===0))try{const n=q(JSON.stringify(e,null,2));return n.length>8e3?`${n.slice(0,8e3)}
49
- ...\uFF08\u8F93\u5165\u53C2\u6570\u8FC7\u957F\uFF0C\u5DF2\u622A\u65AD\uFF09`:n}catch{return}}function _n(e){const n=[e.model?`\u6A21\u578B: ${e.model}`:void 0,e.endpoint||e.requestUrl?`\u63A5\u53E3: ${e.endpoint||e.requestUrl}`:void 0,e.requestMethod?`\u65B9\u6CD5: ${e.requestMethod}`:void 0,typeof e.stream=="boolean"?`\u6D41\u5F0F: ${e.stream?"\u662F":"\u5426"}`:void 0,typeof e.messageCount=="number"?`\u4E0A\u4E0B\u6587\u6D88\u606F: ${e.messageCount}`:void 0,typeof e.toolCount=="number"?`\u53EF\u7528\u5DE5\u5177: ${e.toolCount}`:void 0,e.lastUserMessagePreview?`\u6700\u540E\u8BF7\u6C42: ${e.lastUserMessagePreview}`:void 0].filter(i=>!!i),t=kn(e.requestHeaders),r=n.join(`
50
- `)||"ACode \u6B63\u5728\u53D1\u9001 AI \u8BF7\u6C42",o=t.length>0?`${Ut}${t.join(`
51
- `)}`:"",s=e.requestBody?`${Mt}${e.requestBody}`:"";return`${r}${o}${s}`}function kn(e){return e?Object.entries(e).map(([n,t])=>`${n}: ${t}`).filter(n=>n.trim().length>0):[]}function bn(e,n){return String(n||"").trim().toLowerCase()!=="waiting_input"?!1:e.type==="thinking"||e.type==="text_delta"}function wn(e,n){if(!bn(e,n)){if(e.type==="ai_request")return{status:"thinking",actionInfo:{actionType:"ai_request",actionLabel:"AI\u8BF7\u6C42",actionDetail:_n(e.data)}};if(e.type==="background_command_completed")return{status:"tool_result",actionInfo:{actionType:"background_command",actionLabel:"\u540E\u53F0\u547D\u4EE4",actionDetail:"background_command_completed"}};if(e.type==="thinking"||e.type==="text_delta")return{status:"thinking"};if(e.type==="tool_use_start"){const t=he(e.data.toolName,e.data.toolInput),r=Ve(e,t),o=Tn(e.data.toolInput);return e.data.actionType==="idle"||t.actionType==="idle"?{status:"waiting_input",actionInfo:{actionType:e.data.actionType||t.actionType,actionLabel:e.data.actionLabel||t.actionLabel,actionDetail:r||e.data.actionDetail||t.actionDetail||e.data.toolName,actionInput:o,actionId:e.data.actionId||e.data.toolUseId}}:{status:"tool_using",actionInfo:{actionType:e.data.actionType||t.actionType,actionLabel:e.data.actionLabel||t.actionLabel,actionDetail:r||e.data.actionDetail||t.actionDetail||e.data.toolName,actionInput:o,actionId:e.data.actionId||e.data.toolUseId}}}if(e.type==="turn_complete")return{status:"waiting_input",actionInfo:e.data.usage?{usage:e.data.usage}:void 0};if(e.type==="error")return{status:"error"};if(e.type==="context_compaction")return{status:"compacting",actionInfo:{actionType:"context_compaction",actionLabel:e.data.actionLabel,actionDetail:e.data.actionDetail,...e.data.actionId?{actionId:e.data.actionId}:{},...e.data.parentId?{parentId:e.data.parentId}:{}}};if(e.type==="runtime_capabilities")return{status:n||"waiting_input",actionInfo:{actionType:"runtime_capabilities",actionLabel:e.data.actionLabel||"\u8FD0\u884C\u65F6\u80FD\u529B",actionDetail:e.data.actionDetail}}}}const U=new Map,ce=new Map,ue=new Map,J=new Map,Cn=20,$n=500,Rn=3e4;async function de(e,n=Rn,t=2){for(let r=0;r<=t;r++){const o=new AbortController;let s;try{const i=e(o.signal);i.catch(()=>{}),await Promise.race([i,new Promise((a,c)=>{s=setTimeout(()=>{o.abort(),c(new Error(`sendOutput timeout after ${n}ms`))},n)})]),s&&clearTimeout(s);return}catch(i){s&&clearTimeout(s);const a=i instanceof Error?i.message:String(i);if(r<t){const c=1e3*(r+1);f.warn(`sendOutput attempt ${r+1}/${t+1} failed (${a}), retrying in ${c}ms...`),await new Promise(d=>setTimeout(d,c));continue}f.warn(`sendOutput failed after ${t+1} attempts (${a}), giving up to unblock serial queue`)}}}function le(e,n){const t=n?`${e}:${n}`:void 0;let r,o;if(t)r=J.get(t),o=t;else{const g=[];for(const[T,h]of J)T.startsWith(e+":")&&h.buffer&&g.push(h.sourceEventType);for(const T of g)le(e,T);return}if(!r||!r.buffer)return;r.timer=null;const s=r.buffer,i=r.seq,a=r.entry,c=r.sourceEventType;r.buffer="",o&&J.delete(o);const d={sourceEventType:c,logCategory:"acode"},u={runtimeAccessToken:a.runtimeAccessToken,schedulerBaseUrl:a.schedulerBaseUrl},m=(U.get(e)??Promise.resolve()).then(()=>de(g=>Y(a.agentId,s,e,i,d,u,g)),()=>de(g=>Y(a.agentId,s,e,i,d,u,g)));U.set(e,m),m.finally(()=>{U.get(e)===m&&U.delete(e)})}function En(e,n){const t=ln(e);if(!t)return;n.seq+=1;const r=n.seq,o=fn(e),s={runtimeAccessToken:n.runtimeAccessToken,schedulerBaseUrl:n.schedulerBaseUrl};if((e.type==="command_output"||e.type==="text_delta"||e.type==="thinking")&&t.length<Cn){const c=`${e.sessionId}:${e.type}`;let d=J.get(c);if(d||(d={buffer:"",seq:0,timer:null,entry:n,sourceEventType:e.type}),d.buffer+=t,d.seq=r,d.entry=n,!d.timer){const u=e.sessionId,l=e.type;d.timer=setTimeout(()=>le(u,l),$n)}J.set(c,d);return}le(e.sessionId);const a=(U.get(e.sessionId)??Promise.resolve()).then(()=>de(c=>Y(n.agentId,t,e.sessionId,r,o,s,c)),()=>de(c=>Y(n.agentId,t,e.sessionId,r,o,s,c)));U.set(e.sessionId,a),a.finally(()=>{U.get(e.sessionId)===a&&U.delete(e.sessionId)})}function Ze(e){return ct(e)}let et=!1;function Dn(){et||(at(k,Pn),mt(),et=!0)}function Pn(e,n){e.on("event",t=>{const r=p.get(t.sessionId);if(r){if(t.type==="tool_use_start"?kt(r.sessionId,t.data.toolUseId||t.data.actionId,t.data.toolInput,t.data.toolName,r.workspacePath):t.type==="tool_use_end"&&_t(t,{sessionId:r.sessionId,agentId:r.agentId,workspacePath:r.workspacePath,providerId:r.providerId}),f.info(`[${n.displayName} Adapter] Event: ${t.type} for session ${t.sessionId}`),!(t.type==="thinking"||t.type==="text_delta"||t.type==="tool_use_start"||t.type==="context_compaction"||t.type==="ai_request")){t.type==="runtime_capabilities"&&t.data.actionDetail&&(r.cachedCapabilitiesActionDetail=t.data.actionDetail);const i=wn(t,r.currentRuntimeStatus);i&&$(r.agentId,t.sessionId,i.status,i.actionInfo,oe(i.actionInfo),{runtimeAccessToken:r.runtimeAccessToken,schedulerBaseUrl:r.schedulerBaseUrl},t.timestamp?new Date(t.timestamp).getTime():void 0,t.type)}En(t,r);const s=dn(t);if(s){const i={runtimeAccessToken:r.runtimeAccessToken,schedulerBaseUrl:r.schedulerBaseUrl},a=t.timestamp?new Date(t.timestamp).getTime():void 0,c=String(t.data?.toolName||"").toLowerCase()==="browser_launch",d=t.type==="tool_use_end"&&String(t.data?.rawToolName||t.data?.toolName||"").toLowerCase().replace(/[_-]/g,"").includes("todowrite");c?(async()=>{for(let l=0;l<3;l++){if(await $(r.agentId,t.sessionId,"tool_result",s,void 0,i,a,t.type)!==void 0)return;l<2&&await new Promise(g=>setTimeout(g,3e3*(l+1)))}})().catch(u=>console.warn("[Runtime] browser_launch sendStatus retry exhausted:",u)):d?(async()=>{for(let l=0;l<3;l++){if(await $(r.agentId,t.sessionId,"tool_result",s,void 0,i,a,t.type)!==void 0)return;l<2&&await new Promise(g=>setTimeout(g,1e3*(l+1)))}})().catch(u=>console.warn("[Runtime] todo_write sendStatus retry exhausted:",u)):$(r.agentId,t.sessionId,"tool_result",s,void 0,i,a,t.type)}}}),e.on("status-change",(t,r,o)=>{const s=p.get(t);if(s){le(t),r==="thinking"||r==="tool_using"||r==="compacting"?Ot(t):M(t);const i=vt(r,o);s.currentRuntimeStatus=i.status;const a=s.currentRuntimeActionDetail??"",c=a.includes("poll_message")||a.includes("get_message"),u=!(i.actionInfo?.actionType==="ai_request")&&(i.status==="thinking"||i.status==="waiting_input")&&(s.currentRuntimeActionType==="idle"||s.currentRuntimeActionType==="mcp")&&c;(i.actionInfo?.actionType||!u)&&(s.currentRuntimeActionType=i.actionInfo?.actionType,s.currentRuntimeActionLabel=i.actionInfo?.actionLabel,s.currentRuntimeActionDetail=i.actionInfo?.actionDetail,s.currentRuntimeActionInput=i.actionInfo?.actionInput),f.info(`[${n.displayName} Adapter] Status changed: ${i.status} for agent ${s.agentId}`,i.actionInfo||""),Et(t,{runtimeStatus:i.status,runtimeActionType:s.currentRuntimeActionType,runtimeActionLabel:s.currentRuntimeActionLabel,runtimeActionDetail:s.currentRuntimeActionDetail});const l=i.actionInfo?.actionType?i.actionInfo:s.currentRuntimeActionType?{actionType:s.currentRuntimeActionType,actionLabel:s.currentRuntimeActionLabel??"",actionDetail:s.currentRuntimeActionDetail,actionInput:s.currentRuntimeActionInput}:void 0;if(i.status==="compacting"){const g=(ce.get(t)??Promise.resolve()).then(async()=>{for(let h=0;h<=2;h++){if(await $(s.agentId,t,i.status,l,oe(i.actionInfo),{runtimeAccessToken:s.runtimeAccessToken,schedulerBaseUrl:s.schedulerBaseUrl})!==void 0)return;h<2&&(f.warn(`[${n.displayName}] compaction sendStatus attempt ${h+1} failed (HTTP), retrying in ${1e3*(h+1)}ms...`),await new Promise(C=>setTimeout(C,1e3*(h+1))))}f.warn(`[${n.displayName}] compaction sendStatus failed after 3 attempts, event may be lost`)}).catch(T=>{f.warn(`[${n.displayName}] compaction status chain error:`,T)});ce.set(t,g),g.finally(()=>{ce.get(t)===g&&ce.delete(t)})}else{const m=u&&!i.actionInfo?.actionType;if(Ft({status:i.status,actionInfo:i.actionInfo,restoredActionInfo:l,currentRuntimeActionType:s.currentRuntimeActionType,shouldPreservePrevAction:u})){const h=(ue.get(t)??Promise.resolve()).then(async()=>{for(let C=0;C<=2;C++){if(await $(s.agentId,t,i.status,m?void 0:l,oe(i.actionInfo),{runtimeAccessToken:s.runtimeAccessToken,schedulerBaseUrl:s.schedulerBaseUrl})!==void 0)return;C<2&&await new Promise(O=>setTimeout(O,1e3*(C+1)))}f.warn(`[${n.displayName}] idle tool sendStatus failed after 3 attempts, status may be stale (frontend will fall back to timeline tool_use event)`)}).catch(y=>{f.warn(`[${n.displayName}] idle status chain error:`,y)});ue.set(t,h),h.finally(()=>{ue.get(t)===h&&ue.delete(t)})}else $(s.agentId,t,i.status,m?void 0:l,oe(i.actionInfo),{runtimeAccessToken:s.runtimeAccessToken,schedulerBaseUrl:s.schedulerBaseUrl})}if(i.status==="waiting_input"&&s.cachedCapabilitiesActionDetail){const m=s.cachedCapabilitiesActionDetail;s.cachedCapabilitiesActionDetail=void 0,f.info(`[${n.displayName} Adapter] Re-sending cached runtime_capabilities for agent ${s.agentId} (session stabilized to waiting_input)`),$(s.agentId,t,"waiting_input",{actionType:"runtime_capabilities",actionLabel:"\u8FD0\u884C\u65F6\u80FD\u529B",actionDetail:m},void 0,{runtimeAccessToken:s.runtimeAccessToken,schedulerBaseUrl:s.schedulerBaseUrl})}}}),e.on("ask-user-question",t=>{const r=p.get(t.sessionId);r&&(f.info(`[${n.displayName} Adapter] AskUserQuestion for agent ${r.agentId}`),bt(r.agentId,t.sessionId,Array.isArray(t.questions)?t.questions:[],{runtimeAccessToken:r.runtimeAccessToken,schedulerBaseUrl:r.schedulerBaseUrl},t.toolCallId))}),e.on("tool-permission-request",t=>{const r=p.get(t.sessionId);r&&t.requestId&&(f.info(`[${n.displayName} Adapter] Tool permission request (${t.capability}) for agent ${r.agentId}`),wt(r.agentId,t.sessionId,{requestId:t.requestId,capability:t.capability,...t.detail||{}},{runtimeAccessToken:r.runtimeAccessToken,schedulerBaseUrl:r.schedulerBaseUrl}))}),e.on("permission-request",t=>{const r=p.get(t.sessionId);if(r){f.info(`[${n.displayName} Adapter] Permission request: ${t.toolName} for agent ${r.agentId}`);const o=t.toolInput?q(JSON.stringify(t.toolInput).slice(0,400)):void 0;$(r.agentId,t.sessionId,"waiting_input",{actionType:"other",actionLabel:"\u6743\u9650\u786E\u8BA4",actionDetail:o||t.toolName},void 0,{runtimeAccessToken:r.runtimeAccessToken,schedulerBaseUrl:r.schedulerBaseUrl})}})}S.post("/start",I,async(e,n)=>{const{agentId:t,workspacePath:r,mode:o="sdk"}=e.body||{};if(!t||!r){n.status(400).json({error:"agentId and workspacePath are required"});return}const s=String(e.body?.schedulerBaseUrl||"").trim()||String(e.header("x-bridge-tunnel-source")||"").trim()||Re(Ne(e))||void 0;It({agentId:String(t),workspacePath:String(r),serverUrl:e.body?.serverUrl||s,runtimeAccessToken:e.body?.runtimeAccessToken,userId:e.body?.userId,schedulerBaseUrl:s}),e.body?.runtimeFeatures!==null&&e.body?.runtimeFeatures!==void 0&&(gt(String(t),e.body.runtimeFeatures),f.info(`[Runtime] agent ${t} \u542F\u52A8\u4E0B\u53D1\u80FD\u529B\u5F00\u5173: ${JSON.stringify(ht(String(t)))}`)),e.body?.capabilities!==void 0&&yt(String(t),e.body.capabilities),e.body?.envVars!==null&&e.body?.envVars!==void 0&&typeof e.body.envVars=="object"&&(St(e.body.envVars),f.info(`[Runtime] agent ${t} \u4E0B\u53D1\u9762\u677F\u73AF\u5883\u53D8\u91CF: ${Object.keys(e.body.envVars).length} \u9879 \u2192 \u684C\u9762\u5DE5\u5177\u5B50\u8FDB\u7A0B`)),e.body?.changeCacheRetentionDays!==void 0&&(lt(e.body.changeCacheRetentionDays),f.info(`[Runtime] agent ${t} \u4E0B\u53D1\u53D8\u66F4\u7F13\u5B58\u4FDD\u7559\u5929\u6570: ${e.body.changeCacheRetentionDays??"\u4E0D\u6E05\u7406"}`)),o&&o!=="sdk"&&console.warn(`[Runtime] Unsupported runtime mode "${o}" requested for agent ${t}; starting SDK session instead.`),await Ln(e,n)});async function Ln(e,n){const{agentId:t,workspacePath:r,command:o,autoAccept:s=!0,initialPrompt:i,systemPrompt:a,globalPrompt:c,rolePrompt:d,memory:u,mcpConfigPath:l,extraMcpServers:m,envOverrides:g,idleInputAutoCommand:T,nonInputAutoCommand:h,model:y,instanceAiConfig:C,subAgentModel:R,subAgentEffort:O,scopeKey:Te,browserAllowPrivate:_e}=e.body||{},W=Pt();W.log({level:"info",category:"launch",message:"startSdkSession: \u6536\u5230\u542F\u52A8\u8BF7\u6C42",source:"bridge",agentId:String(t||"").trim()||void 0,details:{reqBodyKeys:Object.keys(e.body||{}),perInstanceAiConfig:C?ne(C):null,perAgentModel:y??null}});let E=null;const A=String(t||"").trim(),fe=String(e.body?.runtimeAccessToken||"").trim()||void 0,N=String(e.body?.schedulerBaseUrl||"").trim()||String(e.header("x-bridge-tunnel-source")||"").trim()||Re(Ne(e))||void 0;N?f.info(`[startSdkSession] \u56DE\u8C03\u76EE\u6807 server: ${N} (agentId=${A})`):f.warn(`[startSdkSession] \u672A\u89E3\u6790\u5230 schedulerBaseUrl\uFF0C\u5C06\u56DE\u9000\u5230\u9ED8\u8BA4\u5730\u5740 (agentId=${A})`);try{if(Dn(),!A){n.status(400).json({error:"agentId is required"});return}const v=Ge(A);if(v){n.json(await Jt(v));return}const _=await Ct(A);if(_){const D=Zt(_);if(!D.reusable)console.warn(`[Runtime] Ignoring stale persisted SDK session for agentId=${A}, sessionId=${_.sessionId}, reason=${D.reason}`),await H(_.sessionId);else{const P=ie(_.runtimeStatus,_.runtimeStatus,_.runtimeActionType);n.json({sessionId:_.sessionId,status:P,runtimeStatus:P,runtimeActionType:_.runtimeActionType,runtimeActionLabel:_.runtimeActionLabel,runtimeActionDetail:_.runtimeActionDetail,agentId:_.agentId,workspacePath:_.workspacePath,command:_.command,mode:_.mode||"sdk",pid:_.pid,reused:!0,persistedOnly:!0});return}}if(z.has(A)){n.status(409).json({error:"SDK session is already starting for this agent"});return}z.add(A);const L=Ze(o),tt=k.get(L);E=it();const nt=L==="claude-code"?await sn():null,Z=Ye(L==="claude-code"?nt:null,g),G=L==="acode"?y?String(y).trim():void 0:(()=>{const D=y?String(y).trim():void 0,P=Z.model?String(Z.model).trim():void 0;return D||P})();W.log({level:"info",category:"resolve",message:"\u6A21\u578B\u89E3\u6790\u7ED3\u679C",source:"bridge",agentId:A,sessionId:E??void 0,details:{perAgentModel:y??null,globalModel:Z.model??null,resolvedModel:G??null,providerId:L,note:L==="acode"?"adapter handles full priority":"request > global"}});const me={...Z.envOverrides};G&&(me.ANTHROPIC_MODEL=G,me.CODEX_MODEL=G);let X,pe=l;if(L==="acode"){const D=C||{},P=await pt({apiOverrides:Fe(D)??void 0,agentId:A,sessionId:E??void 0,runtimeBridgeBaseUrl:N});X=P.instanceConfig.config,pe=P.perInstanceConfigPath,W.log({level:"info",category:"apply",message:"prepareAcodeInstanceConfig \u5B8C\u6210",source:"bridge",agentId:A,sessionId:E??void 0,details:{sanitizedApiOverrides:(()=>{const x=Fe(D);return x?ne(x):null})(),resolvedInstanceAiConfig:X?ne(X):null,perInstanceConfigPath:pe,instanceConfigSources:P.instanceConfig.source??null}})}let ke=a||void 0,ge,ye,ee;if(L==="acode")if(ge=typeof c=="string"&&c.trim()||void 0,ye=typeof d=="string"&&d.trim()||void 0,typeof u=="string"&&u.trim())ee=u.trim();else{const D=await jt(r,{schedulerBaseUrl:N,runtimeAccessToken:fe,agentId:A});D&&(ee=D,f.info(`[startSdkSession] Auto-loaded memories for ACode agent ${A}`))}else if(typeof c=="string"&&c.trim()||typeof d=="string"&&d.trim()||typeof u=="string"&&u.trim()){const P=[c,d,u,a].filter(x=>typeof x=="string"&&x.trim().length>0).map(x=>x.trim());ke=P.length>0?P.join(`
47
+ `:void 0}function Pn(e){const n=Mn(e);return{sourceEventType:e.type,logCategory:"acode",...Ln(e),...n?{logLevel:On(e),logMessage:n}:{}}}function On(e){return e.type==="error"?"error":e.type==="command_output"&&e.data.stream==="stderr"?"warn":"info"}function Ln(e){return e.type!=="command_output"?{}:{...typeof e.data.stream=="string"?{stream:e.data.stream}:{},...typeof e.data.sequence=="number"?{sequence:e.data.sequence}:{},...typeof e.data.cwd=="string"?{cwd:e.data.cwd}:{},...typeof e.data.commandFilePath=="string"?{commandFilePath:e.data.commandFilePath}:{},...typeof e.data.commandLineCount=="number"?{commandLineCount:e.data.commandLineCount}:{}}}function Mn(e){if(e.type==="ai_request"){const n=e.data.model||"unknown-model",t=e.data.endpoint?` @ ${e.data.endpoint}`:"",r=typeof e.data.toolCount=="number"?`, tools=${e.data.toolCount}`:"";return`AI request started: ${n}${t}${r}`}if(e.type==="tool_use_start")return at(e,"\u5F00\u59CB");if(e.type==="tool_use_end")return at(e,"\u5B8C\u6210");if(e.type==="command_output")return Nn(e);if(e.type==="turn_complete")return`Turn completed${e.data.finishReason?`, finish=${e.data.finishReason}`:""}`;if(e.type==="session_complete")return`Session completed: exitCode=${e.data.exitCode??0}`;if(e.type==="error")return e.data.text||"ACode runtime error"}const Un=/\x1b\[[0-9;?]*[a-zA-Z]/g;function xn(e){return e.replace(Un,"")}function Nn(e){const n=typeof e.data.stream=="string"?e.data.stream:"mixed",t=typeof e.data.sequence=="number"?` #${e.data.sequence}`:"",r=xn(String(e.data.text||"")).replace(/\s+/g," ").trim(),s=r.length>240?`${r.slice(0,240)}...`:r;return`\u547D\u4EE4\u8F93\u51FA(${n}${t}): ${s||"(empty)"}`}function at(e,n){const t=be(e.data.toolName,e.data.toolInput),r=e.data.actionLabel||t.actionLabel||"\u8C03\u7528\u5DE5\u5177",s=ct(e,t);return s?`${n}${r}: ${s}`:`${n}${r}: ${e.data.actionDetail||e.data.toolName||"tool"}`}function ct(e,n){const t=e.data.toolInput;return n.actionType==="bash"?jn(t)||e.data.actionDetail||n.actionDetail:n.actionType==="read_file"||n.actionType==="edit_file"||n.actionType==="write_file"?Bn(t)||e.data.actionDetail||n.actionDetail:e.data.actionDetail||n.actionDetail}function jn(e){const n=$e(e?.command,e?.cmd);if(n)return n;if(Array.isArray(e?.argv)){const t=e.argv.map(r=>String(r??"").trim()).filter(Boolean).join(" ");return t?K(t):void 0}return $e(e?.args)}function Bn(e){const n=ut(e?.paths);return n.length>0?n.length===1?n[0]:`${n.length}\u4E2A\u6587\u4EF6: ${n.join(", ")}`:$e(e?.file_path,e?.filePath,e?.path,e?.target_file,e?.targetFile)}function $e(...e){for(const n of e){if(typeof n=="string"&&n.trim())return K(n.trim());if(Array.isArray(n)){const t=ut(n)[0];if(t)return t}}}function ut(e){return Array.isArray(e)?e.map(n=>typeof n=="string"?n.trim():"").filter(Boolean).map(n=>K(n)):[]}function Fn(e){if(!(!e||Object.keys(e).length===0))try{const n=K(JSON.stringify(e,null,2));return n.length>8e3?`${n.slice(0,8e3)}
48
+ ...\uFF08\u8F93\u5165\u53C2\u6570\u8FC7\u957F\uFF0C\u5DF2\u622A\u65AD\uFF09`:n}catch{return}}function vn(e,n){return String(n||"").trim().toLowerCase()!=="waiting_input"?!1:e.type==="thinking"||e.type==="text_delta"}function Kn(e,n){if(!vn(e,n)){if(e.type==="background_command_completed")return{status:"tool_result",actionInfo:{actionType:"background_command",actionLabel:"\u540E\u53F0\u547D\u4EE4",actionDetail:"background_command_completed"}};if(e.type==="thinking"||e.type==="text_delta")return{status:"thinking"};if(e.type==="tool_use_start"){const t=be(e.data.toolName,e.data.toolInput),r=ct(e,t),s=Fn(e.data.toolInput);return e.data.actionType==="idle"||t.actionType==="idle"?{status:"waiting_input",actionInfo:{actionType:e.data.actionType||t.actionType,actionLabel:e.data.actionLabel||t.actionLabel,actionDetail:r||e.data.actionDetail||t.actionDetail||e.data.toolName,actionInput:s,actionId:e.data.actionId||e.data.toolUseId}}:{status:"tool_using",actionInfo:{actionType:e.data.actionType||t.actionType,actionLabel:e.data.actionLabel||t.actionLabel,actionDetail:r||e.data.actionDetail||t.actionDetail||e.data.toolName,actionInput:s,actionId:e.data.actionId||e.data.toolUseId,...e.data.batchId?{parentId:e.data.batchId}:{}}}}if(e.type==="turn_complete")return{status:"waiting_input",actionInfo:e.data.usage?{usage:e.data.usage}:void 0};if(e.type==="error")return{status:"error"};if(e.type==="context_compaction")return{status:"compacting",actionInfo:{actionType:"context_compaction",actionLabel:e.data.actionLabel,actionDetail:e.data.actionDetail,...e.data.actionId?{actionId:e.data.actionId}:{},...e.data.parentId?{parentId:e.data.parentId}:{}}};if(e.type==="runtime_capabilities")return{status:n||"waiting_input",actionInfo:{actionType:"runtime_capabilities",actionLabel:e.data.actionLabel||"\u8FD0\u884C\u65F6\u80FD\u529B",actionDetail:e.data.actionDetail}};if(e.type==="tool_batch_start"){const t=e.data.batchId;return t?{status:"tool_result",actionInfo:{actionType:"tool_batch",actionLabel:"\u5E76\u884C\u6267\u884C\u5DE5\u5177",actionDetail:e.data.actionDetail,actionId:t}}:void 0}if(e.type==="tool_batch_metrics"){const t=e.data.batchId;return t?{status:"tool_result",actionInfo:{actionType:"tool_batch",actionLabel:"\u5E76\u884C\u6267\u884C\u5DE5\u5177",actionId:t,batchId:t,...e.data.batchMetrics?{batchMetrics:e.data.batchMetrics}:{}}}:void 0}}}const U=new Map,le=new Map,fe=new Map;async function we(e){const{entry:n,sessionId:t,actionInfo:r,timestamp:s,sourceEventType:o,backoffBaseMs:i,label:a}=e,c={runtimeAccessToken:n.runtimeAccessToken,schedulerBaseUrl:n.schedulerBaseUrl},u=3;for(let d=0;d<u;d++){if(await E(n.agentId,t,"tool_result",r,void 0,c,s,o)!==void 0)return;d<u-1&&await new Promise(m=>setTimeout(m,i*(d+1)))}f.warn(`[Runtime] ${a} tool_result sendStatus retry exhausted (result may be lost): agentId=${n.agentId}`)}const Z=new Map,Hn=20,qn=500,zn=3e4;async function me(e,n=zn,t=2){for(let r=0;r<=t;r++){const s=new AbortController;let o;try{const i=e(s.signal);i.catch(()=>{}),await Promise.race([i,new Promise((a,c)=>{o=setTimeout(()=>{s.abort(),c(new Error(`sendOutput timeout after ${n}ms`))},n)})]),o&&clearTimeout(o);return}catch(i){o&&clearTimeout(o);const a=i instanceof Error?i.message:String(i);if(r<t){const c=1e3*(r+1);f.warn(`sendOutput attempt ${r+1}/${t+1} failed (${a}), retrying in ${c}ms...`),await new Promise(u=>setTimeout(u,c));continue}f.warn(`sendOutput failed after ${t+1} attempts (${a}), giving up to unblock serial queue`)}}}function pe(e,n){const t=n?`${e}:${n}`:void 0;let r,s;if(t)r=Z.get(t),s=t;else{const p=[];for(const[b,y]of Z)b.startsWith(e+":")&&y.buffer&&p.push(y.sourceEventType);for(const b of p)pe(e,b);return}if(!r||!r.buffer)return;r.timer=null;const o=r.buffer,i=r.seq,a=r.entry,c=r.sourceEventType;r.buffer="",s&&Z.delete(s);const u={sourceEventType:c,logCategory:"acode"},d={runtimeAccessToken:a.runtimeAccessToken,schedulerBaseUrl:a.schedulerBaseUrl},m=(U.get(e)??Promise.resolve()).then(()=>me(p=>J(a.agentId,o,e,i,u,d,p)),()=>me(p=>J(a.agentId,o,e,i,u,d,p)));U.set(e,m),m.finally(()=>{U.get(e)===m&&U.delete(e)})}function Wn(e,n){const t=Dn(e);if(!t)return;n.seq+=1;const r=n.seq,s=Pn(e),o={runtimeAccessToken:n.runtimeAccessToken,schedulerBaseUrl:n.schedulerBaseUrl};if((e.type==="command_output"||e.type==="text_delta"||e.type==="thinking")&&t.length<Hn){const c=`${e.sessionId}:${e.type}`;let u=Z.get(c);if(u||(u={buffer:"",seq:0,timer:null,entry:n,sourceEventType:e.type}),u.buffer+=t,u.seq=r,u.entry=n,!u.timer){const d=e.sessionId,l=e.type;u.timer=setTimeout(()=>pe(d,l),qn)}Z.set(c,u);return}pe(e.sessionId);const a=(U.get(e.sessionId)??Promise.resolve()).then(()=>me(c=>J(n.agentId,t,e.sessionId,r,s,o,c)),()=>me(c=>J(n.agentId,t,e.sessionId,r,s,o,c)));U.set(e.sessionId,a),a.finally(()=>{U.get(e.sessionId)===a&&U.delete(e.sessionId)})}function dt(e){return St(e)}let lt=!1;function Gn(){lt||(It(_,Xn),Ct(),lt=!0)}function Xn(e,n){e.on("event",t=>{const r=g.get(t.sessionId);if(r){if(t.type==="tool_use_start"?jt(r.sessionId,t.data.toolUseId||t.data.actionId,t.data.toolInput,t.data.toolName,r.workspacePath):t.type==="tool_use_end"&&Nt(t,{sessionId:r.sessionId,agentId:r.agentId,workspacePath:r.workspacePath,providerId:r.providerId}),f.info(`[${n.displayName} Adapter] Event: ${t.type} for session ${t.sessionId}`),!(t.type==="thinking"||t.type==="text_delta"||t.type==="tool_use_start"||t.type==="context_compaction"||t.type==="ai_request"||t.type==="error")){t.type==="runtime_capabilities"&&t.data.actionDetail&&(r.cachedCapabilitiesActionDetail=t.data.actionDetail);const i=Kn(t,r.currentRuntimeStatus);i&&E(r.agentId,t.sessionId,i.status,i.actionInfo,ae(i.actionInfo),{runtimeAccessToken:r.runtimeAccessToken,schedulerBaseUrl:r.schedulerBaseUrl},t.timestamp?new Date(t.timestamp).getTime():void 0,t.type)}Wn(t,r);const o=Rn(t);if(o){const i=t.timestamp?new Date(t.timestamp).getTime():void 0,a=String(t.data?.toolName||"").toLowerCase()==="browser_launch",c=t.type==="tool_use_end"&&String(t.data?.rawToolName||t.data?.toolName||"").toLowerCase().replace(/[_-]/g,"").includes("todowrite");we(a?{entry:r,sessionId:t.sessionId,actionInfo:o,timestamp:i,sourceEventType:t.type,backoffBaseMs:3e3,label:"browser_launch"}:c?{entry:r,sessionId:t.sessionId,actionInfo:o,timestamp:i,sourceEventType:t.type,backoffBaseMs:1e3,label:"todo_write"}:{entry:r,sessionId:t.sessionId,actionInfo:o,timestamp:i,sourceEventType:t.type,backoffBaseMs:1e3,label:"tool_result"})}}}),e.on("status-change",(t,r,s)=>{const o=g.get(t);if(o){pe(t),r==="thinking"||r==="tool_using"||r==="compacting"?Xt(t):M(t);const i=sn(r,s);o.currentRuntimeStatus=i.status;const a=o.currentRuntimeActionDetail??"",c=a.includes("poll_message")||a.includes("get_message"),d=!(i.actionInfo?.actionType==="ai_request")&&(i.status==="thinking"||i.status==="waiting_input")&&(o.currentRuntimeActionType==="idle"||o.currentRuntimeActionType==="mcp")&&c;(i.actionInfo?.actionType||!d)&&(o.currentRuntimeActionType=i.actionInfo?.actionType,o.currentRuntimeActionLabel=i.actionInfo?.actionLabel,o.currentRuntimeActionDetail=i.actionInfo?.actionDetail,o.currentRuntimeActionInput=i.actionInfo?.actionInput),f.info(`[${n.displayName} Adapter] Status changed: ${i.status} for agent ${o.agentId}`,i.actionInfo||""),qt(t,{runtimeStatus:i.status,runtimeActionType:o.currentRuntimeActionType,runtimeActionLabel:o.currentRuntimeActionLabel,runtimeActionDetail:o.currentRuntimeActionDetail});const l=i.actionInfo?.actionType?i.actionInfo:o.currentRuntimeActionType?{actionType:o.currentRuntimeActionType,actionLabel:o.currentRuntimeActionLabel??"",actionDetail:o.currentRuntimeActionDetail,actionInput:o.currentRuntimeActionInput}:void 0;if(i.status==="compacting"){const p=(le.get(t)??Promise.resolve()).then(async()=>{for(let y=0;y<=2;y++){if(await E(o.agentId,t,i.status,l,ae(i.actionInfo),{runtimeAccessToken:o.runtimeAccessToken,schedulerBaseUrl:o.schedulerBaseUrl})!==void 0)return;y<2&&(f.warn(`[${n.displayName}] compaction sendStatus attempt ${y+1} failed (HTTP), retrying in ${1e3*(y+1)}ms...`),await new Promise($=>setTimeout($,1e3*(y+1))))}f.warn(`[${n.displayName}] compaction sendStatus failed after 3 attempts, event may be lost`)}).catch(b=>{f.warn(`[${n.displayName}] compaction status chain error:`,b)});le.set(t,p),p.finally(()=>{le.get(t)===p&&le.delete(t)})}else{const m=d&&!i.actionInfo?.actionType;if(an({status:i.status,actionInfo:i.actionInfo,restoredActionInfo:l,currentRuntimeActionType:o.currentRuntimeActionType,shouldPreservePrevAction:d})){const y=(fe.get(t)??Promise.resolve()).then(async()=>{for(let $=0;$<=2;$++){if(await E(o.agentId,t,i.status,m?void 0:l,ae(i.actionInfo),{runtimeAccessToken:o.runtimeAccessToken,schedulerBaseUrl:o.schedulerBaseUrl})!==void 0)return;$<2&&await new Promise(D=>setTimeout(D,1e3*($+1)))}f.warn(`[${n.displayName}] idle tool sendStatus failed after 3 attempts, status may be stale (frontend will fall back to timeline tool_use event)`)}).catch(h=>{f.warn(`[${n.displayName}] idle status chain error:`,h)});fe.set(t,y),y.finally(()=>{fe.get(t)===y&&fe.delete(t)})}else E(o.agentId,t,i.status,m?void 0:l,ae(i.actionInfo),{runtimeAccessToken:o.runtimeAccessToken,schedulerBaseUrl:o.schedulerBaseUrl})}if(i.status==="waiting_input"&&o.cachedCapabilitiesActionDetail){const m=o.cachedCapabilitiesActionDetail;o.cachedCapabilitiesActionDetail=void 0,f.info(`[${n.displayName} Adapter] Re-sending cached runtime_capabilities for agent ${o.agentId} (session stabilized to waiting_input)`),E(o.agentId,t,"waiting_input",{actionType:"runtime_capabilities",actionLabel:"\u8FD0\u884C\u65F6\u80FD\u529B",actionDetail:m},void 0,{runtimeAccessToken:o.runtimeAccessToken,schedulerBaseUrl:o.schedulerBaseUrl})}}}),e.on("ask-user-question",t=>{const r=g.get(t.sessionId);r&&(f.info(`[${n.displayName} Adapter] AskUserQuestion for agent ${r.agentId}`),Bt(r.agentId,t.sessionId,Array.isArray(t.questions)?t.questions:[],{runtimeAccessToken:r.runtimeAccessToken,schedulerBaseUrl:r.schedulerBaseUrl},t.toolCallId))}),e.on("tool-permission-request",t=>{const r=g.get(t.sessionId);r&&t.requestId&&(f.info(`[${n.displayName} Adapter] Tool permission request (${t.capability}) for agent ${r.agentId}`),Ft(r.agentId,t.sessionId,{requestId:t.requestId,capability:t.capability,...t.detail||{}},{runtimeAccessToken:r.runtimeAccessToken,schedulerBaseUrl:r.schedulerBaseUrl}))}),e.on("permission-request",t=>{const r=g.get(t.sessionId);if(r){f.info(`[${n.displayName} Adapter] Permission request: ${t.toolName} for agent ${r.agentId}`);const s=t.toolInput?K(JSON.stringify(t.toolInput).slice(0,400)):void 0;E(r.agentId,t.sessionId,"waiting_input",{actionType:"other",actionLabel:"\u6743\u9650\u786E\u8BA4",actionDetail:s||t.toolName},void 0,{runtimeAccessToken:r.runtimeAccessToken,schedulerBaseUrl:r.schedulerBaseUrl})}})}S.post("/start",I,async(e,n)=>{const{agentId:t,workspacePath:r,mode:s="sdk"}=e.body||{};if(!t||!r){n.status(400).json({error:"agentId and workspacePath are required"});return}const o=String(e.body?.schedulerBaseUrl||"").trim()||String(e.header("x-bridge-tunnel-source")||"").trim()||Ue(Ge(e))||void 0;Lt({agentId:String(t),workspacePath:String(r),serverUrl:e.body?.serverUrl||o,runtimeAccessToken:e.body?.runtimeAccessToken,userId:e.body?.userId,schedulerBaseUrl:o}),e.body?.runtimeFeatures!==null&&e.body?.runtimeFeatures!==void 0&&(wt(String(t),e.body.runtimeFeatures),f.info(`[Runtime] agent ${t} \u542F\u52A8\u4E0B\u53D1\u80FD\u529B\u5F00\u5173: ${JSON.stringify(Pt(String(t)))}`)),e.body?.inheritedFeatures!==null&&e.body?.inheritedFeatures!==void 0&&(Rt(String(t),e.body.inheritedFeatures),f.info(`[Runtime] agent ${t} \u542F\u52A8\u4E0B\u53D1\u7EE7\u627F\u4E09\u6001\u5C42: ${JSON.stringify(Ot(String(t)))}`)),e.body?.capabilities!==void 0&&Et(String(t),e.body.capabilities),e.body?.capabilitiesInherited!==void 0&&Dt(String(t),e.body.capabilitiesInherited),e.body?.envVars!==null&&e.body?.envVars!==void 0&&typeof e.body.envVars=="object"&&(Mt(String(t),e.body.envVars),f.info(`[Runtime] agent ${t} \u4E0B\u53D1\u6709\u6548\u73AF\u5883\u53D8\u91CF: ${Object.keys(e.body.envVars).length} \u9879 \u2192 \u5DE5\u5177\u5B50\u8FDB\u7A0B + MCP spec`)),e.body?.changeCacheRetentionDays!==void 0&&(bt(e.body.changeCacheRetentionDays),f.info(`[Runtime] agent ${t} \u4E0B\u53D1\u53D8\u66F4\u7F13\u5B58\u4FDD\u7559\u5929\u6570: ${e.body.changeCacheRetentionDays??"\u4E0D\u6E05\u7406"}`)),s&&s!=="sdk"&&console.warn(`[Runtime] Unsupported runtime mode "${s}" requested for agent ${t}; starting SDK session instead.`),await Yn(e,n)});async function Yn(e,n){const{agentId:t,workspacePath:r,command:s,projectRoot:o,autoAccept:i=!0,initialPrompt:a,systemPrompt:c,globalPrompt:u,rolePrompt:d,memory:l,resumeContext:m,resumeTranscript:p,mcpConfigPath:b,extraMcpServers:y,envOverrides:h,idleInputAutoCommand:$,nonInputAutoCommand:R,model:D,instanceAiConfig:ge,subAgentModel:ye,subAgentEffort:he,scopeKey:Ee,browserAllowPrivate:Re}=e.body||{},W=Zt(p);f.info(`[HIBERNATE-IMPORT] \u542F\u52A8\u8BF7\u6C42\u643A\u5E26\u4F11\u7720\u6062\u590D: agentId=${String(t||"").trim()||"?"} resumeContext=${typeof m=="string"?`${m.length}\u5B57`:"\u65E0"} resumeTranscript\u539F\u59CB=${typeof p=="string"?`${p.length}\u5B57`:typeof p} \u89E3\u6790\u7ED3\u679C=${W?`${W.length}\u6761`:"null"}`);const G=Wt();G.log({level:"info",category:"launch",message:"startSdkSession: \u6536\u5230\u542F\u52A8\u8BF7\u6C42",source:"bridge",agentId:String(t||"").trim()||void 0,details:{reqBodyKeys:Object.keys(e.body||{}),perInstanceAiConfig:ge?oe(ge):null,perAgentModel:D??null}});let w=null;const A=String(t||"").trim(),Ie=String(e.body?.runtimeAccessToken||"").trim()||void 0,B=String(e.body?.schedulerBaseUrl||"").trim()||String(e.header("x-bridge-tunnel-source")||"").trim()||Ue(Ge(e))||void 0;B?f.info(`[startSdkSession] \u56DE\u8C03\u76EE\u6807 server: ${B} (agentId=${A})`):f.warn(`[startSdkSession] \u672A\u89E3\u6790\u5230 schedulerBaseUrl\uFF0C\u5C06\u56DE\u9000\u5230\u9ED8\u8BA4\u5730\u5740 (agentId=${A})`);try{if(Gn(),!A){n.status(400).json({error:"agentId is required"});return}const F=ot(A);if(F){n.json(await In(F));return}const k=await vt(A);if(k){const O=await Sn(k);if(!O.reusable)console.warn(`[Runtime] Ignoring stale persisted SDK session for agentId=${A}, sessionId=${k.sessionId}, reason=${O.reason}`),await q(k.sessionId);else{const L=ue(k.runtimeStatus,k.runtimeStatus,k.runtimeActionType);n.json({sessionId:k.sessionId,status:L,runtimeStatus:L,runtimeActionType:k.runtimeActionType,runtimeActionLabel:k.runtimeActionLabel,runtimeActionDetail:k.runtimeActionDetail,agentId:k.agentId,workspacePath:k.workspacePath,command:k.command,mode:k.mode||"sdk",pid:k.pid,reused:!0,persistedOnly:!0});return}}if(z.has(A)){n.status(409).json({error:"SDK session is already starting for this agent"});return}z.add(A);const P=dt(s),ft=_.get(P);w=ht();const mt=P==="claude-code"?await Cn():null,ee=it(P==="claude-code"?mt:null,h),X=P==="acode"?D?String(D).trim():void 0:(()=>{const O=D?String(D).trim():void 0,L=ee.model?String(ee.model).trim():void 0;return O||L})();G.log({level:"info",category:"resolve",message:"\u6A21\u578B\u89E3\u6790\u7ED3\u679C",source:"bridge",agentId:A,sessionId:w??void 0,details:{perAgentModel:D??null,globalModel:ee.model??null,resolvedModel:X??null,providerId:P,note:P==="acode"?"adapter handles full priority":"request > global"}});const Se={...ee.envOverrides};X&&(Se.ANTHROPIC_MODEL=X,Se.CODEX_MODEL=X);let Y,Ae=b;if(P==="acode"){const O=ge||{},L=await $t({apiOverrides:Qe(O)??void 0,agentId:A,sessionId:w??void 0,runtimeBridgeBaseUrl:B});Y=L.instanceConfig.config,Ae=L.perInstanceConfigPath,G.log({level:"info",category:"apply",message:"prepareAcodeInstanceConfig \u5B8C\u6210",source:"bridge",agentId:A,sessionId:w??void 0,details:{sanitizedApiOverrides:(()=>{const N=Qe(O);return N?oe(N):null})(),resolvedInstanceAiConfig:Y?oe(Y):null,perInstanceConfigPath:Ae,instanceConfigSources:L.instanceConfig.source??null}})}let De=c||void 0,Te,_e,te;const ne=typeof m=="string"&&m.trim()?Tt(m):void 0;if(P==="acode")if(Te=typeof u=="string"&&u.trim()||void 0,_e=typeof d=="string"&&d.trim()||void 0,typeof l=="string"&&l.trim())te=l.trim();else{const O=await tn(r,{schedulerBaseUrl:B,runtimeAccessToken:Ie,agentId:A});O&&(te=O,f.info(`[startSdkSession] Auto-loaded memories for ACode agent ${A}`))}else if(typeof u=="string"&&u.trim()||typeof d=="string"&&d.trim()||typeof l=="string"&&l.trim()||ne!==void 0){const L=[u,d,l,ne,c].filter(N=>typeof N=="string"&&N.trim().length>0).map(N=>N.trim());De=L.length>0?L.join(`
52
49
 
53
- `):void 0}const j={command:o||"acode",workingDirectory:r,agentId:A,...Te?{scopeKey:Te}:{},...typeof _e=="boolean"?{browserAllowPrivate:_e}:{},autoAccept:!!s,initialPrompt:i,systemPrompt:ke,...ge!==void 0?{globalPrompt:ge}:{},...ye!==void 0?{rolePrompt:ye}:{},...ee!==void 0?{memory:ee}:{},model:G,mcpConfigPath:pe,...X?{instanceAiConfig:X}:{},...typeof R=="string"&&R.trim()?{subAgentModel:R.trim()}:{},...typeof O=="string"&&O.trim()?{subAgentEffort:O.trim()}:{},extraMcpServers:m||{},envOverrides:Xe(String(t),String(r),process.env,me)};W.log({level:"info",category:"launch",message:"\u4F20\u9012\u7ED9 Adapter \u7684\u5B8C\u6574 AdapterSessionConfig",source:"bridge",agentId:A,sessionId:E,details:{adapterModel:j.model??null,adapterInstanceAiConfig:j.instanceAiConfig?ne(j.instanceAiConfig):null,adapterMcpConfigPath:j.mcpConfigPath??null}}),await W.flush(),p.set(E,{agentId:A,workspacePath:r,sessionId:E,config:j,providerId:L,seq:0,runtimeAccessToken:fe,schedulerBaseUrl:N}),n.json({sessionId:E,status:"starting",runtimeStatus:"starting",agentId:A,workspacePath:r,command:j.command,mode:"sdk"}),On({sessionId:E,agentId:A,config:j,adapter:tt,providerId:L,idleInputAutoCommand:T,nonInputAutoCommand:h,runtimeAccessToken:fe,requestedSchedulerBaseUrl:N})}catch(v){if(E&&(M(E),p.delete(E),K(E)),A&&z.delete(A),!n.headersSent){const _=v instanceof Error?v.message:String(v);n.status(500).json({error:`Failed to start SDK session: ${_}`})}}}async function On(e){const{sessionId:n,agentId:t,config:r,adapter:o,providerId:s,idleInputAutoCommand:i,nonInputAutoCommand:a,runtimeAccessToken:c,requestedSchedulerBaseUrl:d}=e;try{await o.startSession(n,r),o.setIdleCommands?.(n,{idleInputCommand:i||Ce,nonInputCommand:a||""});let u;if(Bt(s))try{if(await new Promise(m=>setTimeout(m,500)),u=o.getSessionPid?.(n),!u){const g=(await At()).find(T=>T.agentId===t||T.cwd===r.workingDirectory||T.command.includes(r.workingDirectory));g&&(u=g.pid,f.info(`[Runtime] Found SDK process PID: ${u} for agentId=${t}`))}}catch(m){console.warn(`[Runtime] Failed to get SDK PID for agentId=${t}:`,m)}const l=ie(o.getSessionStatus(n),p.get(n)?.currentRuntimeStatus,p.get(n)?.currentRuntimeActionType);await Dt({sessionId:n,agentId:t,workspacePath:r.workingDirectory,command:r.command,startedAt:new Date().toISOString(),status:"running",runtimeStatus:l,mode:"sdk",pid:u,providerSessionId:o.getProviderSessionId(n)}),u&&await Ie().startProcess({agentId:t,sessionId:n,pid:u,mode:"sdk",workspacePath:r.workingDirectory,command:r.command}),await Mn({agentId:t,sessionId:n,sdkPid:u,status:l,schedulerBaseUrl:d,runtimeAccessToken:c})}catch(u){M(n),p.delete(n),K(n),await H(n);const l=u instanceof Error?u.message:String(u);console.error(`[Runtime] Background SDK session startup failed for agentId=${t}: ${l}`),await Un({agentId:t,sessionId:n,schedulerBaseUrl:d,runtimeAccessToken:c,errorMessage:l})}finally{z.delete(t)}}async function Mn(e){const{agentId:n,sessionId:t,sdkPid:r,status:o,schedulerBaseUrl:s,runtimeAccessToken:i}=e;if(!s||!i){f.debug(`[Runtime] notifyServerSessionReady skipped: missing schedulerBaseUrl or runtimeAccessToken for agentId=${n}`);return}const a=`${s.replace(/\/+$/,"")}/api/runtime/callback/status`;try{await be.post(a,{agentId:n,sessionId:t,status:o,pid:r},{headers:{"X-Runtime-Token":i,"Content-Type":"application/json"},timeout:5e3}),f.debug(`[Runtime] Notified server session ready: agentId=${n}, sessionId=${t}, status=${o}`)}catch(c){const d=c instanceof Error?c.message:String(c);f.warn(`[Runtime] Failed to notify server session ready: agentId=${n}, error=${d}`)}}async function Un(e){const{agentId:n,sessionId:t,schedulerBaseUrl:r,runtimeAccessToken:o}=e;if(!r||!o)return;const s=`${r.replace(/\/+$/,"")}/api/runtime/callback/status`;try{await be.post(s,{agentId:n,sessionId:t,status:"stopped"},{headers:{"X-Runtime-Token":o,"Content-Type":"application/json"},timeout:5e3}),f.debug(`[Runtime] Notified server session failed: agentId=${n}, sessionId=${t}`)}catch(i){const a=i instanceof Error?i.message:String(i);f.warn(`[Runtime] Failed to notify server session failed: agentId=${n}, error=${a}`)}}S.post("/sdk/message",I,async(e,n)=>{const{sessionId:t,message:r}=e.body||{};if(!t||!r){n.status(400).json({error:"sessionId and message are required"});return}const o=p.get(t);if(!o){n.status(404).json({error:"SDK session not found"});return}try{const s=o.providerId||"claude-code";await k.get(s).sendMessage(t,r),n.json({ok:!0})}catch(s){const i=s instanceof Error?s.message:String(s);n.status(500).json({error:i})}}),S.post("/sdk/answer",I,async(e,n)=>{const{sessionId:t,answers:r}=e.body||{};if(!t||!r){n.status(400).json({error:"sessionId and answers are required"});return}const o=p.get(t);if(!o){n.status(404).json({error:"SDK session not found"});return}try{const s=o.providerId||"claude-code",i=k.get(s);i.sendQuestionAnswer&&await i.sendQuestionAnswer(t,r),n.json({ok:!0})}catch(s){const i=s instanceof Error?s.message:String(s);n.status(500).json({error:i})}}),S.post("/tool-auth/answer",I,async(e,n)=>{const{sessionId:t,requestId:r,allowed:o}=e.body||{};if(!t||!r){n.status(400).json({error:"sessionId and requestId are required"});return}const s=p.get(t);if(!s){n.status(404).json({error:"SDK session not found"});return}try{const i=s.providerId||"claude-code",a=k.get(i);if(!a.submitToolPermissionDecision){n.status(400).json({error:"adapter does not support tool authorization"});return}const c=a.submitToolPermissionDecision(t,String(r),!!o);n.json({ok:!0,existed:c})}catch(i){const a=i instanceof Error?i.message:String(i);n.status(500).json({error:a})}}),S.get("/tool-auth/pending/:sessionId",I,(e,n)=>{const t=e.params.sessionId;if(!t){n.status(400).json({error:"sessionId is required"});return}const r=p.get(t);if(!r){n.status(404).json({error:"SDK session not found"});return}try{const o=r.providerId||"claude-code",i=k.get(o).getPendingToolAuthRequests?.(t)??[];n.json({ok:!0,sessionId:t,agentId:r.agentId,pendingRequests:i,fetchedAt:Date.now()})}catch(o){const s=o instanceof Error?o.message:String(o);n.status(500).json({error:s})}}),S.post("/sdk/confirm",I,async(e,n)=>{const{sessionId:t,accept:r}=e.body||{};if(!t){n.status(400).json({error:"sessionId is required"});return}const o=p.get(t);if(!o){n.status(404).json({error:"SDK session not found"});return}try{const s=o.providerId||"claude-code";await k.get(s).sendConfirmation(t,!!r),n.json({ok:!0})}catch(s){const i=s instanceof Error?s.message:String(s);n.status(500).json({error:i})}}),S.post("/sdk/abort",I,async(e,n)=>{const{sessionId:t}=e.body||{};if(!t){n.status(400).json({error:"sessionId is required"});return}const r=p.get(t);if(!r){n.status(404).json({error:"SDK session not found"});return}try{const o=r.providerId||"claude-code";await k.get(o).abortCurrentTurn(t),n.json({ok:!0})}catch(o){const s=o instanceof Error?o.message:String(o);n.status(500).json({error:s})}}),S.post("/sdk/stop",I,async(e,n)=>{const{sessionId:t}=e.body||{};if(!t){n.status(400).json({error:"sessionId is required"});return}const r=p.get(t);if(!r){n.json({ok:!0,status:"stopped"});return}try{const o=r.providerId||"claude-code",s=k.get(o);s.abortCurrentTurn(t).catch(()=>{}),await s.terminateSession(t),M(t),p.delete(t),K(t),ae(t),await H(t),await Ie().removeProcess(r.agentId),await $(r.agentId,null,"stopped",void 0,void 0,{runtimeAccessToken:r.runtimeAccessToken,schedulerBaseUrl:r.schedulerBaseUrl}),n.json({ok:!0,status:"stopped"})}catch(o){const s=o instanceof Error?o.message:String(o);n.status(500).json({error:s})}}),S.get("/sdk/status/:sessionId",I,(e,n)=>{const t=e.params.sessionId;if(!t){n.status(400).json({error:"sessionId is required"});return}const r=p.get(t);if(!r){n.status(404).json({error:"SDK session not found"});return}try{const o=r.providerId||"claude-code",s=k.get(o),i=s.getSessionStatus(t),a=s.getConversation(t);n.json({sessionId:t,status:i,agentId:r.agentId,workspacePath:r.workspacePath,messageCount:a.length})}catch(o){const s=o instanceof Error?o.message:String(o);n.status(500).json({error:s})}}),S.get("/sdk/capabilities/:sessionId",I,(e,n)=>{const t=e.params.sessionId;if(!t){n.status(400).json({error:"sessionId is required"});return}const r=p.get(t);if(!r){n.status(404).json({error:"SDK session not found"});return}try{const o=r.providerId||"claude-code",i=k.get(o).getCapabilities?.(t)??null;n.json({ok:!0,sessionId:t,agentId:r.agentId,capabilities:i,fetchedAt:Date.now()})}catch(o){const s=o instanceof Error?o.message:String(o);n.status(500).json({error:s})}}),S.get("/sdk/pending-questions/:sessionId",I,(e,n)=>{const t=e.params.sessionId;if(!t){n.status(400).json({error:"sessionId is required"});return}const r=p.get(t);if(!r){n.status(404).json({error:"SDK session not found"});return}try{const o=r.providerId||"claude-code",i=k.get(o).getPendingQuestion?.(t)??null;n.json({ok:!0,sessionId:t,agentId:r.agentId,pendingQuestion:i?{toolCallId:i.toolCallId,questions:i.questions}:null,fetchedAt:Date.now()})}catch(o){const s=o instanceof Error?o.message:String(o);n.status(500).json({error:s})}}),S.post("/command",I,async(e,n)=>{const{sessionId:t,command:r}=e.body||{};if(!t||r===void 0||r===null){n.status(400).json({error:"sessionId and command are required"});return}try{const o=await nn(String(t),r);n.json({ok:!0,mode:"terminal",...o})}catch(o){const s=o instanceof Error?o.message:String(o);n.status(500).json({error:s})}}),S.post("/input",I,async(e,n)=>{const{sessionId:t,input:r,mode:o}=e.body||{};if(!t||r===void 0||r===null){n.status(400).json({error:"sessionId and input are required"});return}const s=p.get(t);if(!s){n.status(404).json({error:"SDK session not found"});return}try{const i=s.providerId||"claude-code",a=k.get(i);if(o==="shortcut"){if(!a.sendShortcutInput){n.status(400).json({error:"shortcut input is not supported by this SDK provider"});return}await a.sendShortcutInput(t,String(r)),n.json({ok:!0,mode:"shortcut"});return}await a.sendMessage(t,await on(r)),n.json({ok:!0,mode:"sdk"})}catch(i){const a=i instanceof Error?i.message:String(i);n.status(500).json({error:a})}}),S.post("/update-auto-commands",I,async(e,n)=>{const{agentId:t,idleInputAutoCommand:r="",nonInputAutoCommand:o=""}=e.body||{},s=String(t||"").trim();if(!s){n.status(400).json({error:"agentId is required"});return}const i=[...p.values()].find(c=>c.agentId===s),a={idleInputCommand:String(r||"").trim()||Ce,nonInputCommand:String(o||"")};try{let c=!1;i&&(k.get(i.providerId||"claude-code").setIdleCommands?.(i.sessionId,a),c=!0);const d=await Rt(s,{idleInputAutoCommand:a.idleInputCommand,nonInputAutoCommand:a.nonInputCommand});n.json({ok:!0,mode:"sdk",sessionUpdated:c,persistedUpdated:d})}catch(c){const d=c instanceof Error?c.message:String(c);n.status(500).json({ok:!1,mode:"sdk",error:d})}}),S.post("/resize",I,(e,n)=>{const{sessionId:t,cols:r,rows:o}=e.body||{};if(!t||!r||!o){n.status(400).json({error:"sessionId, cols, rows are required"});return}if(!p.has(t)){n.status(404).json({error:"SDK session not found"});return}n.json({ok:!0,mode:"sdk",noop:!0,cols:Number(r),rows:Number(o)})}),S.post("/reset-context",I,async(e,n)=>{const{sessionId:t,reason:r}=e.body||{};if(!t){n.status(400).json({error:"sessionId is required"});return}const o=p.get(t);if(!o){n.status(404).json({error:"SDK session not found"});return}const s=o.providerId||"claude-code",i=k.get(s),a=i.resetContext?.bind(i),c=xt(s,!!a);if(!c.supported){n.status(c.statusCode).json({error:c.error});return}if(!a){n.status(500).json({error:"ACode adapter does not expose resetContext"});return}try{await a(String(t));const d=ie(i.getSessionStatus(String(t)),o.currentRuntimeStatus,o.currentRuntimeActionType);n.json({ok:!0,contextReset:!0,sessionId:t,status:d,runtimeStatus:d,agentId:o.agentId,mode:"sdk",providerId:s,reason:typeof r=="string"&&r.trim()?r.trim():void 0})}catch(d){const u=d instanceof Error?d.message:String(d);n.status(500).json({ok:!1,contextReset:!1,mode:"sdk",error:u})}}),S.post("/stop",I,async(e,n)=>{const{sessionId:t}=e.body||{},r=Nt(e.body);if(!t){n.status(400).json({error:"sessionId is required"});return}const o=p.get(t);if(!o){await H(t),n.json({ok:!0,status:"stopped",mode:"none",statusNotified:!1,reason:r.reason});return}const s=o.agentId;try{f.info(`[Runtime] Stopping SDK session ${t}; suppressStatus=${!r.statusNotified}, reason=${r.reason||"unspecified"}`);const i=o.providerId||"claude-code",a=k.get(i);a.abortCurrentTurn(t).catch(()=>{}),await a.terminateSession(t),M(t),p.delete(t),K(t),ae(t),await H(t),await Ie().removeProcess(s),r.statusNotified?await $(s,null,"stopped",void 0,void 0,{runtimeAccessToken:o.runtimeAccessToken,schedulerBaseUrl:o.schedulerBaseUrl}):f.info(`[Runtime] Stopped status notification suppressed for SDK session ${t}; reason=${r.reason||"unspecified"}`),n.json({ok:!0,status:"stopped",mode:"sdk",statusNotified:r.statusNotified,reason:r.reason})}catch(i){const a=i instanceof Error?i.message:String(i);console.error(`[Runtime] Failed to terminate SDK session ${t}:`,a),n.status(500).json({ok:!1,status:"stop_failed",mode:"sdk",error:a})}}),S.post("/stop-all",I,async(e,n)=>{const t=[],r=[];for(const[o,s]of p.entries())try{const i=s.providerId||"claude-code",a=k.get(i);a.abortCurrentTurn(o).catch(()=>{}),await a.terminateSession(o),M(o),p.delete(o),K(o),ae(o),t.push(o),await $(s.agentId,null,"stopped",void 0,void 0,{runtimeAccessToken:s.runtimeAccessToken,schedulerBaseUrl:s.schedulerBaseUrl})}catch(i){const a=i instanceof Error?i.message:String(i);r.push(`SDK ${o}: ${a}`)}try{await $t([]),f.info("[Runtime] \u5DF2\u6E05\u7A7A\u6240\u6709\u6301\u4E45\u5316\u4F1A\u8BDD")}catch(o){const s=o instanceof Error?o.message:String(o);r.push(`Persistence: ${s}`)}n.json({ok:!0,stopped:{sdk:t.length},errors:r.length>0?r:void 0})}),S.get("/events/last/:n",I,(e,n)=>{const t=parseInt(e.params.n,10);if(!Number.isFinite(t)||t<1){n.status(400).json({error:":n must be a positive integer"});return}const r=Be.getLastN(t);n.json({ok:!0,count:r.length,entries:r})}),S.get("/events/since/:index",I,(e,n)=>{const t=parseInt(e.params.index,10);if(!Number.isFinite(t)||t<0){n.status(400).json({error:":index must be a non-negative integer"});return}const r=Be.getSinceIndex(t);n.json({ok:!0,entries:r.entries,nextIndex:r.nextIndex,oldestIndex:r.oldestIndex,dataLoss:r.oldestIndex>t+1})}),S.get("/events/push-stats",I,(e,n)=>{const t=ft();n.json({ok:!0,count:t.length,agents:t})});export{Kt as buildAcodeCommandOutputPath,Ye as buildClaudeCodeLaunchConfig,Xe as buildRuntimeEnv,fn as buildSdkOutputMetadata,dn as buildToolResultTimelineActionInfo,ur as cleanupSdkSessionByAgentId,Ht as countTerminalOutputLines,We as createTerminalOutputDecoder,se as decodeTerminalOutputChunk,Zt as evaluatePersistedSessionReuse,Wt as formatCommandInactivityTimeoutNotice,zt as formatCommandOutputSpilloverNotice,ln as formatSdkOutputEvent,Se as formatTerminalPrompt,Ft as isIdleStatusChangeRetryable,Gt as normalizeTerminalCommandInput,Nt as parseRuntimeStopOptions,Qt as parseTerminalDirectoryChangeTarget,de as raceSendOutputWithRetry,xt as resolveRuntimeContextResetSupport,wn as resolveRuntimeStatusFromProviderEvent,on as resolveSdkInputMessage,Ze as resolveSdkProviderId,ie as resolveSdkSessionDisplayStatus,vt as resolveStatusChangeRuntimeState,oe as resolveStatusChangeUsage,Xt as resolveTerminalOutputEncoding,p as sdkSessions,Bt as shouldProbeSdkProcessPid,S as terminalRouter};
50
+ `):void 0}const x={command:s||"acode",workingDirectory:r,agentId:A,...Ee?{scopeKey:Ee}:{},...typeof Re=="boolean"?{browserAllowPrivate:Re}:{},autoAccept:!!i,initialPrompt:a,systemPrompt:De,...Te!==void 0?{globalPrompt:Te}:{},..._e!==void 0?{rolePrompt:_e}:{},...te!==void 0?{memory:te}:{},...ne!==void 0?{resumeContext:ne}:{},...P==="acode"&&Array.isArray(W)&&W.length>0?{resumeTranscript:W}:{},model:X,mcpConfigPath:Ae,...Y?{instanceAiConfig:Y}:{},...typeof ye=="string"&&ye.trim()?{subAgentModel:ye.trim()}:{},...typeof he=="string"&&he.trim()?{subAgentEffort:he.trim()}:{},extraMcpServers:y||{},envOverrides:st(String(t),String(r),process.env,Se,typeof o=="string"?o:void 0)};G.log({level:"info",category:"launch",message:"\u4F20\u9012\u7ED9 Adapter \u7684\u5B8C\u6574 AdapterSessionConfig",source:"bridge",agentId:A,sessionId:w,details:{adapterModel:x.model??null,adapterInstanceAiConfig:x.instanceAiConfig?oe(x.instanceAiConfig):null,adapterMcpConfigPath:x.mcpConfigPath??null}}),await G.flush(),g.set(w,{agentId:A,workspacePath:r,sessionId:w,config:x,providerId:P,seq:0,runtimeAccessToken:Ie,schedulerBaseUrl:B}),n.json({sessionId:w,status:"starting",runtimeStatus:"starting",agentId:A,workspacePath:r,command:x.command,mode:"sdk"}),Jn({sessionId:w,agentId:A,config:x,adapter:ft,providerId:P,idleInputAutoCommand:$,nonInputAutoCommand:R,runtimeAccessToken:Ie,requestedSchedulerBaseUrl:B})}catch(F){if(w&&(M(w),g.delete(w),H(w)),A&&z.delete(A),!n.headersSent){const k=F instanceof Error?F.message:String(F);n.status(500).json({error:`Failed to start SDK session: ${k}`})}}}async function Jn(e){const{sessionId:n,agentId:t,config:r,adapter:s,providerId:o,idleInputAutoCommand:i,nonInputAutoCommand:a,runtimeAccessToken:c,requestedSchedulerBaseUrl:u}=e;try{await s.startSession(n,r),s.setIdleCommands?.(n,{idleInputCommand:i||Le,nonInputCommand:a||""});let d;if(rn(o))try{if(await new Promise(m=>setTimeout(m,500)),d=s.getSessionPid?.(n),!d){const p=(await Ut()).find(b=>b.agentId===t||b.cwd===r.workingDirectory||b.command.includes(r.workingDirectory));p&&(d=p.pid,f.info(`[Runtime] Found SDK process PID: ${d} for agentId=${t}`))}}catch(m){console.warn(`[Runtime] Failed to get SDK PID for agentId=${t}:`,m)}const l=ue(s.getSessionStatus(n),g.get(n)?.currentRuntimeStatus,g.get(n)?.currentRuntimeActionType);await zt({sessionId:n,agentId:t,workspacePath:r.workingDirectory,command:r.command,startedAt:new Date().toISOString(),status:"running",runtimeStatus:l,mode:"sdk",pid:d,providerSessionId:s.getProviderSessionId(n)}),d&&await ke().startProcess({agentId:t,sessionId:n,pid:d,mode:"sdk",workspacePath:r.workingDirectory,command:r.command}),await Vn({agentId:t,sessionId:n,sdkPid:d,status:l,schedulerBaseUrl:u,runtimeAccessToken:c})}catch(d){M(n),g.delete(n),H(n),await q(n);const l=d instanceof Error?d.message:String(d);console.error(`[Runtime] Background SDK session startup failed for agentId=${t}: ${l}`),await Qn({agentId:t,sessionId:n,schedulerBaseUrl:u,runtimeAccessToken:c,errorMessage:l})}finally{z.delete(t)}}async function Vn(e){const{agentId:n,sessionId:t,sdkPid:r,status:s,schedulerBaseUrl:o,runtimeAccessToken:i}=e;if(!o||!i){f.debug(`[Runtime] notifyServerSessionReady skipped: missing schedulerBaseUrl or runtimeAccessToken for agentId=${n}`);return}const a=`${o.replace(/\/+$/,"")}/api/runtime/callback/status`;try{await Pe.post(a,{agentId:n,sessionId:t,status:s,pid:r},{headers:{"X-Runtime-Token":i,"Content-Type":"application/json"},timeout:5e3}),f.debug(`[Runtime] Notified server session ready: agentId=${n}, sessionId=${t}, status=${s}`)}catch(c){const u=c instanceof Error?c.message:String(c);f.warn(`[Runtime] Failed to notify server session ready: agentId=${n}, error=${u}`)}}async function Qn(e){const{agentId:n,sessionId:t,schedulerBaseUrl:r,runtimeAccessToken:s}=e;if(!r||!s)return;const o=`${r.replace(/\/+$/,"")}/api/runtime/callback/status`;try{await Pe.post(o,{agentId:n,sessionId:t,status:"stopped"},{headers:{"X-Runtime-Token":s,"Content-Type":"application/json"},timeout:5e3}),f.debug(`[Runtime] Notified server session failed: agentId=${n}, sessionId=${t}`)}catch(i){const a=i instanceof Error?i.message:String(i);f.warn(`[Runtime] Failed to notify server session failed: agentId=${n}, error=${a}`)}}S.post("/sdk/message",I,async(e,n)=>{const{sessionId:t,message:r}=e.body||{};if(!t||!r){n.status(400).json({error:"sessionId and message are required"});return}const s=g.get(t);if(!s){n.status(404).json({error:"SDK session not found"});return}try{const o=s.providerId||"claude-code";await _.get(o).sendMessage(t,r),n.json({ok:!0})}catch(o){const i=o instanceof Error?o.message:String(o);n.status(500).json({error:i})}}),S.post("/sdk/answer",I,async(e,n)=>{const{sessionId:t,answers:r}=e.body||{};if(!t||!r){n.status(400).json({error:"sessionId and answers are required"});return}const s=g.get(t);if(!s){n.status(404).json({error:"SDK session not found"});return}try{const o=s.providerId||"claude-code",i=_.get(o);i.sendQuestionAnswer&&await i.sendQuestionAnswer(t,r),n.json({ok:!0})}catch(o){const i=o instanceof Error?o.message:String(o);n.status(500).json({error:i})}}),S.post("/tool-auth/answer",I,async(e,n)=>{const{sessionId:t,requestId:r,allowed:s}=e.body||{};if(!t||!r){n.status(400).json({error:"sessionId and requestId are required"});return}const o=g.get(t);if(!o){n.status(404).json({error:"SDK session not found"});return}try{const i=o.providerId||"claude-code",a=_.get(i);if(!a.submitToolPermissionDecision){n.status(400).json({error:"adapter does not support tool authorization"});return}const c=a.submitToolPermissionDecision(t,String(r),!!s);n.json({ok:!0,existed:c})}catch(i){const a=i instanceof Error?i.message:String(i);n.status(500).json({error:a})}}),S.get("/tool-auth/pending/:sessionId",I,(e,n)=>{const t=e.params.sessionId;if(!t){n.status(400).json({error:"sessionId is required"});return}const r=g.get(t);if(!r){n.status(404).json({error:"SDK session not found"});return}try{const s=r.providerId||"claude-code",i=_.get(s).getPendingToolAuthRequests?.(t)??[];n.json({ok:!0,sessionId:t,agentId:r.agentId,pendingRequests:i,fetchedAt:Date.now()})}catch(s){const o=s instanceof Error?s.message:String(s);n.status(500).json({error:o})}}),S.post("/sdk/confirm",I,async(e,n)=>{const{sessionId:t,accept:r}=e.body||{};if(!t){n.status(400).json({error:"sessionId is required"});return}const s=g.get(t);if(!s){n.status(404).json({error:"SDK session not found"});return}try{const o=s.providerId||"claude-code";await _.get(o).sendConfirmation(t,!!r),n.json({ok:!0})}catch(o){const i=o instanceof Error?o.message:String(o);n.status(500).json({error:i})}}),S.post("/sdk/abort",I,async(e,n)=>{const{sessionId:t}=e.body||{};if(!t){n.status(400).json({error:"sessionId is required"});return}const r=g.get(t);if(!r){n.status(404).json({error:"SDK session not found"});return}try{const s=r.providerId||"claude-code";await _.get(s).abortCurrentTurn(t),n.json({ok:!0})}catch(s){const o=s instanceof Error?s.message:String(s);n.status(500).json({error:o})}}),S.post("/sdk/stop",I,async(e,n)=>{const{sessionId:t}=e.body||{};if(!t){n.status(400).json({error:"sessionId is required"});return}const r=g.get(t);if(!r){n.json({ok:!0,status:"stopped"});return}try{const s=r.providerId||"claude-code",o=_.get(s);o.abortCurrentTurn(t).catch(()=>{}),await o.terminateSession(t),M(t),g.delete(t),H(t),de(t),await q(t),await ke().removeProcess(r.agentId),await E(r.agentId,null,"stopped",void 0,void 0,{runtimeAccessToken:r.runtimeAccessToken,schedulerBaseUrl:r.schedulerBaseUrl}),n.json({ok:!0,status:"stopped"})}catch(s){const o=s instanceof Error?s.message:String(s);n.status(500).json({error:o})}}),S.get("/sdk/snapshot/:sessionId",I,(e,n)=>{const t=e.params.sessionId;if(!t){n.status(400).json({error:"sessionId is required"});return}const r=g.get(t);if(!r){n.status(404).json({error:"SDK session not found"});return}try{const s=r.providerId||"claude-code",o=_.get(s),i=o.getConversation(t),a=Vt(i);let c=null;if(s==="acode"){const d=o;typeof d.exportRawTranscript!="function"?f.warn(`[HIBERNATE-EXPORT] adapter \u65E0 exportRawTranscript \u65B9\u6CD5 \u2014 bridge \u8FDB\u7A0B\u53EF\u80FD\u8FD0\u884C\u7684\u662F\u65E7\u6784\u5EFA\uFF08\u8BF7\u91CD\u542F bridge\uFF09\u3002providerId=${s}`):(c=d.exportRawTranscript?.(t)??null,c===null&&f.warn(`[HIBERNATE-EXPORT] exportRawTranscript \u8FD4\u56DE\u7A7A \u2014 runtime \u53EF\u80FD\u672A\u5B8C\u6210 start() \u6216\u4E0D\u652F\u6301\u3002providerId=${s}`))}else f.info(`[HIBERNATE-EXPORT] provider=${s} \u4E0D\u652F\u6301\u5B8C\u6574\u91CD\u653E\uFF0C\u6309\u4EC5\u6458\u8981\u4F11\u7720`);const u=o.getTotalUsage?.(t);f.info(`[HIBERNATE-EXPORT] \u5FEB\u7167\u5BFC\u51FA: sessionId=${t} agentId=${r.agentId} providerId=${s} messages=${i.length} summaryChars=${a.snapshot.length} truncated=${a.truncated} transcript=${c?`${c.length}\u6761`:"null"} usage=${u?`in=${u.inputTokens??"?"}/out=${u.outputTokens??"?"}`:"null"}`),n.json({sessionId:t,agentId:r.agentId,workspacePath:r.workspacePath,messageCount:i.length,truncated:a.truncated,snapshot:a.snapshot,transcript:c,tokenUsage:u?{inputTokens:u.inputTokens??null,outputTokens:u.outputTokens??null}:null,providerId:s})}catch(s){const o=s instanceof Error?s.message:String(s);n.status(500).json({error:o})}}),S.get("/sdk/status/:sessionId",I,(e,n)=>{const t=e.params.sessionId;if(!t){n.status(400).json({error:"sessionId is required"});return}const r=g.get(t);if(!r){n.status(404).json({error:"SDK session not found"});return}try{const s=r.providerId||"claude-code",o=_.get(s),i=o.getSessionStatus(t),a=o.getConversation(t);n.json({sessionId:t,status:i,agentId:r.agentId,workspacePath:r.workspacePath,messageCount:a.length})}catch(s){const o=s instanceof Error?s.message:String(s);n.status(500).json({error:o})}}),S.get("/sdk/capabilities/:sessionId",I,(e,n)=>{const t=e.params.sessionId;if(!t){n.status(400).json({error:"sessionId is required"});return}const r=g.get(t);if(!r){n.status(404).json({error:"SDK session not found"});return}try{const s=r.providerId||"claude-code",i=_.get(s).getCapabilities?.(t)??null;n.json({ok:!0,sessionId:t,agentId:r.agentId,capabilities:i,fetchedAt:Date.now()})}catch(s){const o=s instanceof Error?s.message:String(s);n.status(500).json({error:o})}}),S.get("/sdk/pending-questions/:sessionId",I,(e,n)=>{const t=e.params.sessionId;if(!t){n.status(400).json({error:"sessionId is required"});return}const r=g.get(t);if(!r){n.status(404).json({error:"SDK session not found"});return}try{const s=r.providerId||"claude-code",i=_.get(s).getPendingQuestion?.(t)??null;n.json({ok:!0,sessionId:t,agentId:r.agentId,pendingQuestion:i?{toolCallId:i.toolCallId,questions:i.questions}:null,fetchedAt:Date.now()})}catch(s){const o=s instanceof Error?s.message:String(s);n.status(500).json({error:o})}}),S.post("/command",I,async(e,n)=>{const{sessionId:t,command:r}=e.body||{};if(!t||r===void 0||r===null){n.status(400).json({error:"sessionId and command are required"});return}try{const s=await _n(String(t),r);n.json({ok:!0,mode:"terminal",...s})}catch(s){const o=s instanceof Error?s.message:String(s);n.status(500).json({error:o})}});function Zn(e,n){if(typeof e!="string"||!e||!n||typeof n!="object")return e;const{userId:t,name:r,type:s}=n,o=typeof t=="string"&&t.trim()?t.trim():"",i=typeof r=="string"&&r.trim()?r.trim():o;if(!o&&!i)return e;const a=typeof s=="string"&&s.trim()?s.trim().toUpperCase():"HUMAN",c=i||o,u=o?`, userId: ${o}`:"";return`\u3010${c}\uFF08${a}${u}\uFF09\u53D1\u6765\u3011
51
+ ${e}`}S.post("/input",I,async(e,n)=>{const{sessionId:t,input:r,mode:s,sender:o}=e.body||{};if(!t||r===void 0||r===null){n.status(400).json({error:"sessionId and input are required"});return}const i=g.get(t);if(!i){n.status(404).json({error:"SDK session not found"});return}try{const a=i.providerId||"claude-code",c=_.get(a);if(s==="shortcut"){if(!c.sendShortcutInput){n.status(400).json({error:"shortcut input is not supported by this SDK provider"});return}await c.sendShortcutInput(t,String(r)),n.json({ok:!0,mode:"shortcut"});return}await c.sendMessage(t,Zn(await kn(r),o)),n.json({ok:!0,mode:"sdk"})}catch(a){const c=a instanceof Error?a.message:String(a);n.status(500).json({error:c})}}),S.post("/update-auto-commands",I,async(e,n)=>{const{agentId:t,idleInputAutoCommand:r="",nonInputAutoCommand:s=""}=e.body||{},o=String(t||"").trim();if(!o){n.status(400).json({error:"agentId is required"});return}const i=[...g.values()].find(c=>c.agentId===o),a={idleInputCommand:String(r||"").trim()||Le,nonInputCommand:String(s||"")};try{let c=!1;i&&(_.get(i.providerId||"claude-code").setIdleCommands?.(i.sessionId,a),c=!0);const u=await Ht(o,{idleInputAutoCommand:a.idleInputCommand,nonInputAutoCommand:a.nonInputCommand});n.json({ok:!0,mode:"sdk",sessionUpdated:c,persistedUpdated:u})}catch(c){const u=c instanceof Error?c.message:String(c);n.status(500).json({ok:!1,mode:"sdk",error:u})}}),S.post("/resize",I,(e,n)=>{const{sessionId:t,cols:r,rows:s}=e.body||{};if(!t||!r||!s){n.status(400).json({error:"sessionId, cols, rows are required"});return}if(!g.has(t)){n.status(404).json({error:"SDK session not found"});return}n.json({ok:!0,mode:"sdk",noop:!0,cols:Number(r),rows:Number(s)})}),S.post("/reset-context",I,async(e,n)=>{const{sessionId:t,reason:r}=e.body||{};if(!t){n.status(400).json({error:"sessionId is required"});return}const s=g.get(t);if(!s){n.status(404).json({error:"SDK session not found"});return}const o=s.providerId||"claude-code",i=_.get(o),a=i.resetContext?.bind(i),c=nn(o,!!a);if(!c.supported){n.status(c.statusCode).json({error:c.error});return}if(!a){n.status(500).json({error:"ACode adapter does not expose resetContext"});return}try{await a(String(t));const u=ue(i.getSessionStatus(String(t)),s.currentRuntimeStatus,s.currentRuntimeActionType);n.json({ok:!0,contextReset:!0,sessionId:t,status:u,runtimeStatus:u,agentId:s.agentId,mode:"sdk",providerId:o,reason:typeof r=="string"&&r.trim()?r.trim():void 0})}catch(u){const d=u instanceof Error?u.message:String(u);n.status(500).json({ok:!1,contextReset:!1,mode:"sdk",error:d})}}),S.post("/stop",I,async(e,n)=>{const{sessionId:t}=e.body||{},r=on(e.body);if(!t){n.status(400).json({error:"sessionId is required"});return}const s=g.get(t);if(!s){await q(t),n.json({ok:!0,status:"stopped",mode:"none",statusNotified:!1,reason:r.reason});return}const o=s.agentId;try{f.info(`[Runtime] Stopping SDK session ${t}; suppressStatus=${!r.statusNotified}, reason=${r.reason||"unspecified"}`);const i=s.providerId||"claude-code",a=_.get(i);a.abortCurrentTurn(t).catch(()=>{}),await a.terminateSession(t),M(t),g.delete(t),H(t),de(t),await q(t),await ke().removeProcess(o),r.statusNotified?await E(o,null,"stopped",void 0,void 0,{runtimeAccessToken:s.runtimeAccessToken,schedulerBaseUrl:s.schedulerBaseUrl}):f.info(`[Runtime] Stopped status notification suppressed for SDK session ${t}; reason=${r.reason||"unspecified"}`),n.json({ok:!0,status:"stopped",mode:"sdk",statusNotified:r.statusNotified,reason:r.reason})}catch(i){const a=i instanceof Error?i.message:String(i);console.error(`[Runtime] Failed to terminate SDK session ${t}:`,a),n.status(500).json({ok:!1,status:"stop_failed",mode:"sdk",error:a})}}),S.post("/stop-all",I,async(e,n)=>{const t=[],r=[];for(const[s,o]of g.entries())try{const i=o.providerId||"claude-code",a=_.get(i);a.abortCurrentTurn(s).catch(()=>{}),await a.terminateSession(s),M(s),g.delete(s),H(s),de(s),t.push(s),await E(o.agentId,null,"stopped",void 0,void 0,{runtimeAccessToken:o.runtimeAccessToken,schedulerBaseUrl:o.schedulerBaseUrl})}catch(i){const a=i instanceof Error?i.message:String(i);r.push(`SDK ${s}: ${a}`)}try{await Kt([]),f.info("[Runtime] \u5DF2\u6E05\u7A7A\u6240\u6709\u6301\u4E45\u5316\u4F1A\u8BDD")}catch(s){const o=s instanceof Error?s.message:String(s);r.push(`Persistence: ${o}`)}n.json({ok:!0,stopped:{sdk:t.length},errors:r.length>0?r:void 0})}),S.get("/events/last/:n",I,(e,n)=>{const t=parseInt(e.params.n,10);if(!Number.isFinite(t)||t<1){n.status(400).json({error:":n must be a positive integer"});return}const r=We.getLastN(t);n.json({ok:!0,count:r.length,entries:r})}),S.get("/events/since/:index",I,(e,n)=>{const t=parseInt(e.params.index,10);if(!Number.isFinite(t)||t<0){n.status(400).json({error:":index must be a non-negative integer"});return}const r=We.getSinceIndex(t);n.json({ok:!0,entries:r.entries,nextIndex:r.nextIndex,oldestIndex:r.oldestIndex,dataLoss:r.oldestIndex>t+1})}),S.get("/events/push-stats",I,(e,n)=>{const t=kt();n.json({ok:!0,count:t.length,agents:t})});export{un as buildAcodeCommandOutputPath,it as buildClaudeCodeLaunchConfig,st as buildRuntimeEnv,Pn as buildSdkOutputMetadata,Rn as buildToolResultTimelineActionInfo,Er as cleanupSdkSessionByAgentId,dn as countTerminalOutputLines,rt as createTerminalOutputDecoder,ce as decodeTerminalOutputChunk,Sn as evaluatePersistedSessionReuse,fn as formatCommandInactivityTimeoutNotice,ln as formatCommandOutputSpilloverNotice,Dn as formatSdkOutputEvent,Ce as formatTerminalPrompt,an as isIdleStatusChangeRetryable,mn as normalizeTerminalCommandInput,Zt as parseResumeTranscript,on as parseRuntimeStopOptions,yn as parseTerminalDirectoryChangeTarget,me as raceSendOutputWithRetry,Vt as renderSessionSnapshot,nn as resolveRuntimeContextResetSupport,Kn as resolveRuntimeStatusFromProviderEvent,kn as resolveSdkInputMessage,dt as resolveSdkProviderId,ue as resolveSdkSessionDisplayStatus,sn as resolveStatusChangeRuntimeState,ae as resolveStatusChangeUsage,pn as resolveTerminalOutputEncoding,g as sdkSessions,rn as shouldProbeSdkProcessPid,S as terminalRouter,Zn as withSenderSignature};
54
52
 
@@ -1,2 +1,2 @@
1
- import{execSync as R}from"node:child_process";import v from"node:os";import{createLogger as A}from"../utils/logger.js";import{isProcessRunning as p,isProcessRunningAsync as b,findClaudeCodeProcesses as w,findOrphanProcessByAgentId as I,terminateProcessTree as u,waitForProcessExit as f,checkProcessHealth as O}from"./process-detector.js";import{getProcessRegistry as M}from"./process-registry.js";import{loadPersistedSessions as $}from"./terminal-persistence.js";const r=A("agent-process-manager");async function x(h,e,s){const t=new Array(h.length);let i=0;const o=Math.min(Math.max(e,1),h.length),a=Array.from({length:o},async()=>{for(;i<h.length;){const d=i++;t[d]=await s(h[d])}});return await Promise.all(a),t}class g{constructor(){this.registry=M()}static getInstance(){return g.instance===null&&(g.instance=new g),g.instance}async startProcess(e){const{agentId:s,sessionId:t,pid:i,mode:o,workspacePath:a,command:d}=e;if(r.info(`[startProcess] Starting process: agentId=${s}, pid=${i}, mode=${o}`),await this.registry.register({agentId:s,sessionId:t,pid:i,mode:o,state:"creating",workspacePath:a,command:d}),r.debug(`[startProcess] Verifying process is running: pid=${i}`),!p(i))throw r.error(`[startProcess] Process not running after registration: agentId=${s}, pid=${i}`),await this.registry.markTerminated(s),new Error(`Process ${i} is not running`);await this.registry.update(s,{state:"running"}),await this.registry.updateHeartbeat(s),r.info(`[startProcess] Process started successfully: agentId=${s}, pid=${i}`)}async discoverAllProcesses(){r.debug("[discoverAllProcesses] Scanning for all agent processes");const e=await w(),s=this.registry.getAll(),t=[],i=new Set(s.map(n=>n.pid)),o=new Set(s.map(n=>n.agentId)),a=new Map(s.map(n=>[n.pid,n]));for(const n of e){const l=i.has(n.pid),P=n.agentId&&o.has(n.agentId),k=a.get(n.pid),m=n.agentId||k?.agentId;if(l||P){const S=s.find(y=>y.pid===n.pid||y.agentId===n.agentId||y.agentId===m);t.push({...n,agentId:m,managementStatus:"managed",sessionId:S?.sessionId})}else m?t.push({...n,agentId:m,managementStatus:"orphan"}):t.push({...n,agentId:m,managementStatus:"unknown"})}const d=s.filter(n=>!t.some(l=>l.pid===n.pid)),c=await x(d,4,async n=>{const l=await b(n.pid);return{pid:n.pid,command:n.command,agentId:n.agentId,managementStatus:l?"managed":"orphan",sessionId:n.sessionId}});return t.push(...c),r.debug(`[discoverAllProcesses] Discovered ${t.length} processes: ${t.filter(n=>n.managementStatus==="managed").length} managed, ${t.filter(n=>n.managementStatus==="orphan").length} orphans, ${t.filter(n=>n.managementStatus==="unknown").length} unknown`),t}async healthCheckAll(){r.debug("[healthCheckAll] Starting health check for all processes");const e=new Map,s=this.registry.getAll(),t=s.map(async i=>{const o=await this.healthCheck(i.agentId);return e.set(i.agentId,o),o});return await Promise.all(t),r.debug(`[healthCheckAll] Completed health check for ${s.length} processes`),e}async healthCheck(e){const s=this.registry.get(e);if(!s)return r.warn(`[healthCheck] Process not found in registry: agentId=${e}`),{pid:-1,agentId:e,alive:!1,cpu:0,memoryMB:0,status:"dead",lastUpdate:new Date};const t=await O(s.pid,e),i={cpu:t.cpu,memoryMB:t.memoryMB,status:t.status};return await this.registry.updateHealth(e,i),t.alive?await this.registry.updateHeartbeat(e):s.state!=="terminated"&&s.state!=="orphaned"&&(r.warn(`[healthCheck] Process died unexpectedly: agentId=${e}, pid=${s.pid}`),await this.registry.markOrphaned(e)),t}async stopProcess(e){const s=this.registry.get(e);if(!s)return{success:!1,agentId:e,pid:-1,level:0,terminated:0,failed:0,message:`Process not found in registry: ${e}`};const{pid:t}=s;if(r.info(`[stopProcess] Stopping process: agentId=${e}, pid=${t}`),!p(t))return r.info(`[stopProcess] Process already stopped: agentId=${e}, pid=${t}`),await this.registry.markTerminated(e),{success:!0,agentId:e,pid:t,level:0,terminated:1,failed:0,message:"Process was already stopped"};if(await this.registry.update(e,{state:"stopping"}),r.debug(`[stopProcess] Level 1: Sending SIGTERM to pid=${t}`),this.sendSigterm(t)&&await f(t,3e3))return await this.registry.markTerminated(e),r.info(`[stopProcess] Process stopped at Level 1: agentId=${e}, pid=${t}`),{success:!0,agentId:e,pid:t,level:1,terminated:1,failed:0,message:"Process terminated with SIGTERM"};if(r.debug(`[stopProcess] Level 2: Force killing pid=${t}`),this.sendForceKill(t)&&await f(t,3e3))return await this.registry.markTerminated(e),r.info(`[stopProcess] Process stopped at Level 2: agentId=${e}, pid=${t}`),{success:!0,agentId:e,pid:t,level:2,terminated:1,failed:0,message:"Process terminated with force kill"};r.debug(`[stopProcess] Level 3: Terminating process tree for pid=${t}`);const a=await u(t);return await f(t,5e3)?(await this.registry.markTerminated(e),r.info(`[stopProcess] Process stopped at Level 3: agentId=${e}, pid=${t}, terminated=${a.terminated}, failed=${a.failed}`),{success:!0,agentId:e,pid:t,level:3,terminated:a.terminated,failed:a.failed,message:`Process tree terminated (${a.terminated} processes)`}):(r.error(`[stopProcess] Level 4: Process is unstoppable: agentId=${e}, pid=${t}`),(p(t)?"still running":"terminated")==="terminated"?(await this.registry.markTerminated(e),{success:!0,agentId:e,pid:t,level:4,terminated:1,failed:0,message:"Process eventually terminated after all escalation levels"}):{success:!1,agentId:e,pid:t,level:4,terminated:a.terminated,failed:a.failed+1,message:"Process could not be terminated - marked as unstoppable"})}sendSigterm(e){try{return process.kill(e,"SIGTERM"),!0}catch(s){return r.debug(`[sendSigterm] Failed to send SIGTERM to ${e}:`,s),!1}}sendForceKill(e){try{return v.platform()==="win32"?R(`taskkill /PID ${e} /F`,{encoding:"utf8",timeout:5e3,windowsHide:!0}):process.kill(e,"SIGKILL"),!0}catch(s){return r.debug(`[sendForceKill] Failed to force kill ${e}:`,s),!1}}async forceKill(e){const s=this.registry.get(e);if(!s)return{success:!1,agentId:e,pid:-1,level:0,terminated:0,failed:0,message:`Process not found in registry: ${e}`};const{pid:t}=s;r.info(`[forceKill] Force killing process: agentId=${e}, pid=${t}`),await this.registry.update(e,{state:"stopping"});const i=await u(t);return await f(t,2e3)?(await this.registry.markTerminated(e),r.info(`[forceKill] Process terminated: agentId=${e}, pid=${t}`),{success:!0,agentId:e,pid:t,level:3,terminated:i.terminated,failed:i.failed,message:`Process force killed (${i.terminated} processes terminated)`}):(r.error(`[forceKill] Process could not be force killed: agentId=${e}, pid=${t}`),{success:!1,agentId:e,pid:t,level:3,terminated:i.terminated,failed:i.failed+1,message:"Force kill failed - process may require manual intervention"})}async reclaimOrphan(e){if(r.info(`[reclaimOrphan] Attempting to reclaim orphan: agentId=${e}`),this.registry.isManaged(e)){const o=this.registry.get(e);return o?(r.info(`[reclaimOrphan] Process already managed: agentId=${e}, pid=${o.pid}`),{success:!0,pid:o.pid,action:"adopted"}):{success:!1,pid:-1,action:"failed"}}const s=await I(e);if(!s)return r.warn(`[reclaimOrphan] No orphan process found: agentId=${e}`),{success:!1,pid:-1,action:"failed"};if(!p(s.pid))return r.warn(`[reclaimOrphan] Orphan process not running: agentId=${e}, pid=${s.pid}`),{success:!1,pid:s.pid,action:"failed"};if(this.registry.isManagedByPid(s.pid)){const o=this.registry.getByPid(s.pid);if(!o)try{const d=(await $()).find(c=>c.agentId===e);return await this.registry.register({agentId:e,sessionId:d?.sessionId||`reclaimed-${Date.now()}`,pid:s.pid,mode:"sdk",state:"running",workspacePath:d?.workspacePath||s.cwd||"",command:s.command||d?.command||"",metadata:{reclaimedAt:new Date().toISOString(),wasOrphan:!0}}),{success:!0,pid:s.pid,action:"adopted"}}catch{return await u(s.pid),{success:!1,pid:s.pid,action:"terminated"}}return r.warn(`[reclaimOrphan] PID already managed by different agent: pid=${s.pid}, existingAgentId=${o.agentId}`),o.agentId===e?{success:!0,pid:s.pid,action:"adopted"}:(r.warn(`[reclaimOrphan] Terminating conflicting orphan: agentId=${e}, pid=${s.pid}`),await u(s.pid),{success:!0,pid:s.pid,action:"terminated"})}const i=(await $()).find(o=>o.agentId===e);try{return await this.registry.register({agentId:e,sessionId:i?.sessionId||`reclaimed-${Date.now()}`,pid:s.pid,mode:"sdk",state:"running",workspacePath:i?.workspacePath||s.cwd||"",command:s.command||i?.command||"",metadata:{reclaimedAt:new Date().toISOString(),wasOrphan:!0}}),r.info(`[reclaimOrphan] Successfully adopted orphan: agentId=${e}, pid=${s.pid}`),{success:!0,pid:s.pid,action:"adopted"}}catch(o){return r.error(`[reclaimOrphan] Failed to adopt orphan: agentId=${e}, pid=${s.pid}`,o),await u(s.pid),{success:!1,pid:s.pid,action:"terminated"}}}async scanAndReclaimAll(){r.info("[scanAndReclaimAll] Scanning for all orphan processes");const e=[],s=await $(),t=await w(),i=new Set(this.registry.getAll().map(a=>a.pid)),o=t.filter(a=>i.has(a.pid)?!1:!!(a.agentId&&!this.registry.isManaged(a.agentId)));r.info(`[scanAndReclaimAll] Found ${o.length} orphan processes`);for(const a of o){if(!a.agentId){r.warn(`[scanAndReclaimAll] Orphan without agentId, terminating: pid=${a.pid}`),await u(a.pid),e.push({agentId:"unknown",pid:a.pid,action:"terminated"});continue}const d=await this.reclaimOrphan(a.agentId);e.push({agentId:a.agentId,pid:d.pid,action:d.action})}for(const a of s)if(a.agentId&&!this.registry.isManaged(a.agentId)&&await I(a.agentId)){const c=await this.reclaimOrphan(a.agentId);e.find(l=>l.agentId===a.agentId)||e.push({agentId:a.agentId,pid:c.pid,action:c.action})}return r.info(`[scanAndReclaimAll] Reclamation complete: ${e.length} processes processed`),e}async markOrphaned(e){return r.info(`[markOrphaned] Marking process as orphaned: agentId=${e}`),await this.registry.markOrphaned(e)}isManaged(e){return this.registry.isManaged(e)}getAllManagedProcesses(){return this.registry.getAll()}getManagedProcessesByState(e){return this.registry.getByState(e)}async getUnmanagedProcesses(){const e=await w(),s=new Set(this.registry.getAll().map(i=>i.pid)),t=new Set(this.registry.getAll().map(i=>i.agentId));return e.filter(i=>!(s.has(i.pid)||i.agentId&&t.has(i.agentId)))}async rebuildRegistry(e){r.info(`[rebuildRegistry] Rebuilding registry from ${e.length} persisted sessions`),await this.registry.clear();for(const t of e){if(!t.pid){r.debug(`[rebuildRegistry] Skipping session without PID: agentId=${t.agentId}`);continue}const i=p(t.pid),o=i?"running":"unknown";try{await this.registry.register({agentId:t.agentId,sessionId:t.sessionId,pid:t.pid,mode:"sdk",state:o,workspacePath:t.workspacePath||"",command:t.command||"",metadata:{rebuiltAt:new Date().toISOString(),wasRunningOnStartup:i}}),r.debug(`[rebuildRegistry] Registered: agentId=${t.agentId}, pid=${t.pid}, state=${o}`)}catch(a){r.warn(`[rebuildRegistry] Failed to register: agentId=${t.agentId}`,a)}}const s=this.registry.getStats();r.info(`[rebuildRegistry] Registry rebuilt: total=${s.total}, running=${s.running}, unknown=${s.unknown}`)}getStats(){return this.registry.getStats()}async cleanupStaleRegistry(){const e=this.registry.getAll();let s=0;for(const t of e)(t.state==="terminated"||t.state==="unknown")&&!p(t.pid)&&(await this.registry.remove(t.agentId),s++,r.debug(`[cleanupStaleRegistry] Removed stale entry: agentId=${t.agentId}, pid=${t.pid}, state=${t.state}`));return s>0&&r.info(`[cleanupStaleRegistry] Cleaned up ${s} stale registry entries`),s}async removeProcess(e){return r.info(`[removeProcess] Removing process from registry: agentId=${e}`),await this.registry.remove(e)}getProcess(e){return this.registry.get(e)}getProcessByPid(e){return this.registry.getByPid(e)}}g.instance=null;function L(){return g.getInstance()}export{g as AgentProcessManager,L as getAgentProcessManager};
1
+ import{execSync as R}from"node:child_process";import v from"node:os";import{createLogger as A}from"../utils/logger.js";import{isProcessRunning as p,isProcessRunningAsync as b,findClaudeCodeProcesses as w,findOrphanProcessByAgentId as I,terminateProcessTree as u,waitForProcessExit as f,checkProcessHealth as O}from"./process-detector.js";import{getProcessRegistry as M}from"./process-registry.js";import{loadPersistedSessions as $}from"./terminal-persistence.js";const r=A("agent-process-manager");async function x(h,e,s){const t=new Array(h.length);let i=0;const o=Math.min(Math.max(e,1),h.length),a=Array.from({length:o},async()=>{for(;i<h.length;){const d=i++;t[d]=await s(h[d])}});return await Promise.all(a),t}class g{constructor(){this.registry=M()}static getInstance(){return g.instance===null&&(g.instance=new g),g.instance}async startProcess(e){const{agentId:s,sessionId:t,pid:i,mode:o,workspacePath:a,command:d}=e;if(r.info(`[startProcess] Starting process: agentId=${s}, pid=${i}, mode=${o}`),await this.registry.register({agentId:s,sessionId:t,pid:i,mode:o,state:"creating",workspacePath:a,command:d}),r.debug(`[startProcess] Verifying process is running: pid=${i}`),!await p(i))throw r.error(`[startProcess] Process not running after registration: agentId=${s}, pid=${i}`),await this.registry.markTerminated(s),new Error(`Process ${i} is not running`);await this.registry.update(s,{state:"running"}),await this.registry.updateHeartbeat(s),r.info(`[startProcess] Process started successfully: agentId=${s}, pid=${i}`)}async discoverAllProcesses(){r.debug("[discoverAllProcesses] Scanning for all agent processes");const e=await w(),s=this.registry.getAll(),t=[],i=new Set(s.map(n=>n.pid)),o=new Set(s.map(n=>n.agentId)),a=new Map(s.map(n=>[n.pid,n]));for(const n of e){const l=i.has(n.pid),P=n.agentId&&o.has(n.agentId),k=a.get(n.pid),m=n.agentId||k?.agentId;if(l||P){const S=s.find(y=>y.pid===n.pid||y.agentId===n.agentId||y.agentId===m);t.push({...n,agentId:m,managementStatus:"managed",sessionId:S?.sessionId})}else m?t.push({...n,agentId:m,managementStatus:"orphan"}):t.push({...n,agentId:m,managementStatus:"unknown"})}const d=s.filter(n=>!t.some(l=>l.pid===n.pid)),c=await x(d,4,async n=>{const l=await b(n.pid);return{pid:n.pid,command:n.command,agentId:n.agentId,managementStatus:l?"managed":"orphan",sessionId:n.sessionId}});return t.push(...c),r.debug(`[discoverAllProcesses] Discovered ${t.length} processes: ${t.filter(n=>n.managementStatus==="managed").length} managed, ${t.filter(n=>n.managementStatus==="orphan").length} orphans, ${t.filter(n=>n.managementStatus==="unknown").length} unknown`),t}async healthCheckAll(){r.debug("[healthCheckAll] Starting health check for all processes");const e=new Map,s=this.registry.getAll(),t=s.map(async i=>{const o=await this.healthCheck(i.agentId);return e.set(i.agentId,o),o});return await Promise.all(t),r.debug(`[healthCheckAll] Completed health check for ${s.length} processes`),e}async healthCheck(e){const s=this.registry.get(e);if(!s)return r.warn(`[healthCheck] Process not found in registry: agentId=${e}`),{pid:-1,agentId:e,alive:!1,cpu:0,memoryMB:0,status:"dead",lastUpdate:new Date};const t=await O(s.pid,e),i={cpu:t.cpu,memoryMB:t.memoryMB,status:t.status};return await this.registry.updateHealth(e,i),t.alive?await this.registry.updateHeartbeat(e):s.state!=="terminated"&&s.state!=="orphaned"&&(r.warn(`[healthCheck] Process died unexpectedly: agentId=${e}, pid=${s.pid}`),await this.registry.markOrphaned(e)),t}async stopProcess(e){const s=this.registry.get(e);if(!s)return{success:!1,agentId:e,pid:-1,level:0,terminated:0,failed:0,message:`Process not found in registry: ${e}`};const{pid:t}=s;if(r.info(`[stopProcess] Stopping process: agentId=${e}, pid=${t}`),!await p(t))return r.info(`[stopProcess] Process already stopped: agentId=${e}, pid=${t}`),await this.registry.markTerminated(e),{success:!0,agentId:e,pid:t,level:0,terminated:1,failed:0,message:"Process was already stopped"};if(await this.registry.update(e,{state:"stopping"}),r.debug(`[stopProcess] Level 1: Sending SIGTERM to pid=${t}`),this.sendSigterm(t)&&await f(t,3e3))return await this.registry.markTerminated(e),r.info(`[stopProcess] Process stopped at Level 1: agentId=${e}, pid=${t}`),{success:!0,agentId:e,pid:t,level:1,terminated:1,failed:0,message:"Process terminated with SIGTERM"};if(r.debug(`[stopProcess] Level 2: Force killing pid=${t}`),this.sendForceKill(t)&&await f(t,3e3))return await this.registry.markTerminated(e),r.info(`[stopProcess] Process stopped at Level 2: agentId=${e}, pid=${t}`),{success:!0,agentId:e,pid:t,level:2,terminated:1,failed:0,message:"Process terminated with force kill"};r.debug(`[stopProcess] Level 3: Terminating process tree for pid=${t}`);const a=await u(t);return await f(t,5e3)?(await this.registry.markTerminated(e),r.info(`[stopProcess] Process stopped at Level 3: agentId=${e}, pid=${t}, terminated=${a.terminated}, failed=${a.failed}`),{success:!0,agentId:e,pid:t,level:3,terminated:a.terminated,failed:a.failed,message:`Process tree terminated (${a.terminated} processes)`}):(r.error(`[stopProcess] Level 4: Process is unstoppable: agentId=${e}, pid=${t}`),(await p(t)?"still running":"terminated")==="terminated"?(await this.registry.markTerminated(e),{success:!0,agentId:e,pid:t,level:4,terminated:1,failed:0,message:"Process eventually terminated after all escalation levels"}):{success:!1,agentId:e,pid:t,level:4,terminated:a.terminated,failed:a.failed+1,message:"Process could not be terminated - marked as unstoppable"})}sendSigterm(e){try{return process.kill(e,"SIGTERM"),!0}catch(s){return r.debug(`[sendSigterm] Failed to send SIGTERM to ${e}:`,s),!1}}sendForceKill(e){try{return v.platform()==="win32"?R(`taskkill /PID ${e} /F`,{encoding:"utf8",timeout:5e3,windowsHide:!0}):process.kill(e,"SIGKILL"),!0}catch(s){return r.debug(`[sendForceKill] Failed to force kill ${e}:`,s),!1}}async forceKill(e){const s=this.registry.get(e);if(!s)return{success:!1,agentId:e,pid:-1,level:0,terminated:0,failed:0,message:`Process not found in registry: ${e}`};const{pid:t}=s;r.info(`[forceKill] Force killing process: agentId=${e}, pid=${t}`),await this.registry.update(e,{state:"stopping"});const i=await u(t);return await f(t,2e3)?(await this.registry.markTerminated(e),r.info(`[forceKill] Process terminated: agentId=${e}, pid=${t}`),{success:!0,agentId:e,pid:t,level:3,terminated:i.terminated,failed:i.failed,message:`Process force killed (${i.terminated} processes terminated)`}):(r.error(`[forceKill] Process could not be force killed: agentId=${e}, pid=${t}`),{success:!1,agentId:e,pid:t,level:3,terminated:i.terminated,failed:i.failed+1,message:"Force kill failed - process may require manual intervention"})}async reclaimOrphan(e){if(r.info(`[reclaimOrphan] Attempting to reclaim orphan: agentId=${e}`),this.registry.isManaged(e)){const o=this.registry.get(e);return o?(r.info(`[reclaimOrphan] Process already managed: agentId=${e}, pid=${o.pid}`),{success:!0,pid:o.pid,action:"adopted"}):{success:!1,pid:-1,action:"failed"}}const s=await I(e);if(!s)return r.warn(`[reclaimOrphan] No orphan process found: agentId=${e}`),{success:!1,pid:-1,action:"failed"};if(!await p(s.pid))return r.warn(`[reclaimOrphan] Orphan process not running: agentId=${e}, pid=${s.pid}`),{success:!1,pid:s.pid,action:"failed"};if(this.registry.isManagedByPid(s.pid)){const o=this.registry.getByPid(s.pid);if(!o)try{const d=(await $()).find(c=>c.agentId===e);return await this.registry.register({agentId:e,sessionId:d?.sessionId||`reclaimed-${Date.now()}`,pid:s.pid,mode:"sdk",state:"running",workspacePath:d?.workspacePath||s.cwd||"",command:s.command||d?.command||"",metadata:{reclaimedAt:new Date().toISOString(),wasOrphan:!0}}),{success:!0,pid:s.pid,action:"adopted"}}catch{return await u(s.pid),{success:!1,pid:s.pid,action:"terminated"}}return r.warn(`[reclaimOrphan] PID already managed by different agent: pid=${s.pid}, existingAgentId=${o.agentId}`),o.agentId===e?{success:!0,pid:s.pid,action:"adopted"}:(r.warn(`[reclaimOrphan] Terminating conflicting orphan: agentId=${e}, pid=${s.pid}`),await u(s.pid),{success:!0,pid:s.pid,action:"terminated"})}const i=(await $()).find(o=>o.agentId===e);try{return await this.registry.register({agentId:e,sessionId:i?.sessionId||`reclaimed-${Date.now()}`,pid:s.pid,mode:"sdk",state:"running",workspacePath:i?.workspacePath||s.cwd||"",command:s.command||i?.command||"",metadata:{reclaimedAt:new Date().toISOString(),wasOrphan:!0}}),r.info(`[reclaimOrphan] Successfully adopted orphan: agentId=${e}, pid=${s.pid}`),{success:!0,pid:s.pid,action:"adopted"}}catch(o){return r.error(`[reclaimOrphan] Failed to adopt orphan: agentId=${e}, pid=${s.pid}`,o),await u(s.pid),{success:!1,pid:s.pid,action:"terminated"}}}async scanAndReclaimAll(){r.info("[scanAndReclaimAll] Scanning for all orphan processes");const e=[],s=await $(),t=await w(),i=new Set(this.registry.getAll().map(a=>a.pid)),o=t.filter(a=>i.has(a.pid)?!1:!!(a.agentId&&!this.registry.isManaged(a.agentId)));r.info(`[scanAndReclaimAll] Found ${o.length} orphan processes`);for(const a of o){if(!a.agentId){r.warn(`[scanAndReclaimAll] Orphan without agentId, terminating: pid=${a.pid}`),await u(a.pid),e.push({agentId:"unknown",pid:a.pid,action:"terminated"});continue}const d=await this.reclaimOrphan(a.agentId);e.push({agentId:a.agentId,pid:d.pid,action:d.action})}for(const a of s)if(a.agentId&&!this.registry.isManaged(a.agentId)&&await I(a.agentId)){const c=await this.reclaimOrphan(a.agentId);e.find(l=>l.agentId===a.agentId)||e.push({agentId:a.agentId,pid:c.pid,action:c.action})}return r.info(`[scanAndReclaimAll] Reclamation complete: ${e.length} processes processed`),e}async markOrphaned(e){return r.info(`[markOrphaned] Marking process as orphaned: agentId=${e}`),await this.registry.markOrphaned(e)}isManaged(e){return this.registry.isManaged(e)}getAllManagedProcesses(){return this.registry.getAll()}getManagedProcessesByState(e){return this.registry.getByState(e)}async getUnmanagedProcesses(){const e=await w(),s=new Set(this.registry.getAll().map(i=>i.pid)),t=new Set(this.registry.getAll().map(i=>i.agentId));return e.filter(i=>!(s.has(i.pid)||i.agentId&&t.has(i.agentId)))}async rebuildRegistry(e){r.info(`[rebuildRegistry] Rebuilding registry from ${e.length} persisted sessions`),await this.registry.clear();for(const t of e){if(!t.pid){r.debug(`[rebuildRegistry] Skipping session without PID: agentId=${t.agentId}`);continue}const i=await p(t.pid),o=i?"running":"unknown";try{await this.registry.register({agentId:t.agentId,sessionId:t.sessionId,pid:t.pid,mode:"sdk",state:o,workspacePath:t.workspacePath||"",command:t.command||"",metadata:{rebuiltAt:new Date().toISOString(),wasRunningOnStartup:i}}),r.debug(`[rebuildRegistry] Registered: agentId=${t.agentId}, pid=${t.pid}, state=${o}`)}catch(a){r.warn(`[rebuildRegistry] Failed to register: agentId=${t.agentId}`,a)}}const s=this.registry.getStats();r.info(`[rebuildRegistry] Registry rebuilt: total=${s.total}, running=${s.running}, unknown=${s.unknown}`)}getStats(){return this.registry.getStats()}async cleanupStaleRegistry(){const e=this.registry.getAll();let s=0;for(const t of e)(t.state==="terminated"||t.state==="unknown")&&!await p(t.pid)&&(await this.registry.remove(t.agentId),s++,r.debug(`[cleanupStaleRegistry] Removed stale entry: agentId=${t.agentId}, pid=${t.pid}, state=${t.state}`));return s>0&&r.info(`[cleanupStaleRegistry] Cleaned up ${s} stale registry entries`),s}async removeProcess(e){return r.info(`[removeProcess] Removing process from registry: agentId=${e}`),await this.registry.remove(e)}getProcess(e){return this.registry.get(e)}getProcessByPid(e){return this.registry.getByPid(e)}}g.instance=null;function L(){return g.getInstance()}export{g as AgentProcessManager,L as getAgentProcessManager};
2
2
 
@@ -1,5 +1,5 @@
1
- import{ptySessions as c,createPtySession as p,closePtySession as l}from"../routes/pty.js";const y=30*60*1e3,g=2e3,u=500;function T(a){const e=a.trimEnd();if(!e)return!1;const t=e.split(`
2
- `).pop()??"";return!!(/[:?]\s*$/.test(t)||/\((?:yes\/no|Y\/N|y\/n)\)/i.test(t)||/\b[Yy]\/?[Nn]\b/.test(t)||/\(press RETURN\)/i.test(t)||/\(press ENTER\)/i.test(t)||/press ENTER[^]*continue/i.test(t))}class M{constructor(){this.cursors=new Map,this.idleTimers=new Map}create(e){const t=e.shell&&e.shell.trim()?e.shell.trim():"auto",s=typeof e.cols=="number"&&e.cols>0?Math.min(e.cols,u):120,r=typeof e.rows=="number"&&e.rows>0?Math.min(e.rows,u):30,i=e.preCommand&&e.preCommand.trim()?e.preCommand:void 0,n=p({workspacePath:e.cwd,shell:t,cols:s,rows:r,preCommand:i,persistent:!0,ownerUserId:e.agentId}),o=c.get(n.id);return this.cursors.set(n.id,0),this.touch(n.id),{id:n.id,pid:o?.ptyProcess.pid}}write(e,t){const s=c.get(e);!s||s.status==="exited"||(s.ptyProcess.write(t.replace(/\n/g,"\r")),this.touch(e))}read(e,t){const s=c.get(e);if(!s)return{status:"closed",exit_code:null,output:"",needs_input:!1,truncated:!1};this.touch(e);const r=s.outputBuffer,i=this.cursors.get(e)??0,n=i>=r.length?"":r.slice(i);this.cursors.set(e,r.length);const o=n.split(`
3
- `),m=Math.min(Math.max(1,t.lines??200),g);let h=o,d=!1;o.length>m&&(h=o.slice(o.length-m),d=!0);const f=s.status==="running"&&T(n);return{status:s.status,exit_code:s.exitCode??null,output:h.join(`
4
- `),needs_input:f,truncated:d}}kill(e){l(e,"agent-kill"),this.cursors.delete(e),this.clearIdle(e)}killByAgent(e){if(!e)return;const t=[];for(const[s,r]of c.entries())r.ownerUserId===e&&t.push(s);for(const s of t){try{l(s,`agent-stop:${e}`)}catch{}this.cursors.delete(s),this.clearIdle(s)}}resize(e,t,s){const r=c.get(e);if(!r)return;const i=typeof t=="number"&&t>0?Math.min(t,u):120,n=typeof s=="number"&&s>0?Math.min(s,u):30;r.ptyProcess.resize(i,n)}touch(e){const t=this.idleTimers.get(e);t&&clearTimeout(t);const s=setTimeout(()=>{l(e,"agent-idle-timeout"),this.cursors.delete(e),this.idleTimers.delete(e)},y);s.unref?.(),this.idleTimers.set(e,s)}clearIdle(e){const t=this.idleTimers.get(e);t&&clearTimeout(t),this.idleTimers.delete(e)}}const E=new M;export{M as AgentPtyManager,E as agentPtyManager,T as detectNeedsInput};
1
+ import{ptySessions as c,createPtySession as p,closePtySession as l,readPtyOutputBuffer as y}from"../routes/pty.js";const g=30*60*1e3,T=2e3,u=500;function M(a){const e=a.trimEnd();if(!e)return!1;const t=e.split(`
2
+ `).pop()??"";return!!(/[:?]\s*$/.test(t)||/\((?:yes\/no|Y\/N|y\/n)\)/i.test(t)||/\b[Yy]\/?[Nn]\b/.test(t)||/\(press RETURN\)/i.test(t)||/\(press ENTER\)/i.test(t)||/press ENTER[^]*continue/i.test(t))}class w{constructor(){this.cursors=new Map,this.idleTimers=new Map}create(e){const t=e.shell&&e.shell.trim()?e.shell.trim():"auto",s=typeof e.cols=="number"&&e.cols>0?Math.min(e.cols,u):120,r=typeof e.rows=="number"&&e.rows>0?Math.min(e.rows,u):30,i=e.preCommand&&e.preCommand.trim()?e.preCommand:void 0,n=p({workspacePath:e.cwd,shell:t,cols:s,rows:r,preCommand:i,persistent:!0,ownerUserId:e.agentId}),o=c.get(n.id);return this.cursors.set(n.id,0),this.touch(n.id),{id:n.id,pid:o?.ptyProcess.pid}}write(e,t){const s=c.get(e);!s||s.status==="exited"||(s.ptyProcess.write(t.replace(/\n/g,"\r")),this.touch(e))}read(e,t){const s=c.get(e);if(!s)return{status:"closed",exit_code:null,output:"",needs_input:!1,truncated:!1};this.touch(e);const r=y(s),i=this.cursors.get(e)??0,n=i>=r.length?"":r.slice(i);this.cursors.set(e,r.length);const o=n.split(`
3
+ `),m=Math.min(Math.max(1,t.lines??200),T);let h=o,d=!1;o.length>m&&(h=o.slice(o.length-m),d=!0);const f=s.status==="running"&&M(n);return{status:s.status,exit_code:s.exitCode??null,output:h.join(`
4
+ `),needs_input:f,truncated:d}}kill(e){l(e,"agent-kill"),this.cursors.delete(e),this.clearIdle(e)}killByAgent(e){if(!e)return;const t=[];for(const[s,r]of c.entries())r.ownerUserId===e&&t.push(s);for(const s of t){try{l(s,`agent-stop:${e}`)}catch{}this.cursors.delete(s),this.clearIdle(s)}}resize(e,t,s){const r=c.get(e);if(!r)return;const i=typeof t=="number"&&t>0?Math.min(t,u):120,n=typeof s=="number"&&s>0?Math.min(s,u):30;r.ptyProcess.resize(i,n)}touch(e){const t=this.idleTimers.get(e);t&&clearTimeout(t);const s=setTimeout(()=>{l(e,"agent-idle-timeout"),this.cursors.delete(e),this.idleTimers.delete(e)},g);s.unref?.(),this.idleTimers.set(e,s)}clearIdle(e){const t=this.idleTimers.get(e);t&&clearTimeout(t),this.idleTimers.delete(e)}}const _=new w;export{w as AgentPtyManager,_ as agentPtyManager,M as detectNeedsInput};
5
5
 
@@ -1,3 +1,3 @@
1
- import{createHash as j}from"node:crypto";import{cpSync as l,existsSync as c,lstatSync as L,mkdirSync as U,readdirSync as b,readFileSync as p,realpathSync as S,rmSync as E,statSync as M,symlinkSync as W,writeFileSync as v}from"node:fs";import t from"node:path";import{fileURLToPath as I}from"node:url";import{getActiveBridgeHttpPort as B,getRuntimeHomeDir as D,isDevMode as H,schedulerBaseUrl as O}from"../config.js";import{logger as i}from"../utils/logger.js";import{loadRuntimeBinding as $}from"./runtime-binding.js";const a=H()?"aws-mcp-dev":"aws-mcp",k=["AWS_PROJECT_NAME","AWS_PROMPT","AWS_ROLE_NAME","AWS_SERVER_URL","AWS_MCP_HTTP_URL","AWS_RUNTIME_BRIDGE_BASE_URL","AWS_HEARTBEAT_INTERVAL","AWS_HEARTBEAT_TIMEOUT","PATH","HOME","USERPROFILE","TMP","TEMP","SystemRoot","COMSPEC","PATHEXT","WINDIR"];function R(){const r=I(import.meta.url);return t.resolve(t.dirname(r),"..","..")}function V(r=R()){return t.join(f(r),"dist","index.js")}function f(r){return t.join(r,"package","aws-client-agent-mcp")}function g(){return t.join(D(),".aws-bridge","mcp")}function le(){return t.join(g(),"dist")}function C(r=g()){return t.join(r,".release.json")}function y(r){try{return JSON.parse(p(r,"utf-8")).version||"unknown"}catch{return"unknown"}}function x(r){return y(t.join(r,"package.json"))}function G(r){return y(t.join(f(r),"package.json"))}function m(r,e){c(r)&&F(r,e)}function F(r,e){if(M(r).isDirectory()){l(r,e,{errorOnExist:!1,force:!0,recursive:!0});return}l(r,e,{errorOnExist:!1,force:!0})}function w(r,e){const n=f(r);m(t.join(n,"package.json"),t.join(e,"package.json")),m(t.join(n,"README.md"),t.join(e,"README.md")),m(t.join(n,"package-lock.json"),t.join(e,"package-lock.json"))}function J(r){if(!c(r))return!0;const e=L(r);return e.isSymbolicLink()||e.isDirectory()}function z(r,e){if(!c(r))return!1;try{return S(r)===S(e)}catch{return!1}}function N(r,e){const n=t.join(r,"node_modules"),o=t.join(e,"node_modules");if(!c(n)){i.warn(`[runtime-bridge] ${a} MCP \u672A\u627E\u5230\u4F9D\u8D56\u76EE\u5F55\uFF0Crelease \u4EA7\u7269\u53EF\u80FD\u65E0\u6CD5\u89E3\u6790\u8FD0\u884C\u65F6\u4F9D\u8D56: ${n}`);return}if(!z(o,n)){if(!J(o)){i.warn(`[runtime-bridge] ${a} MCP \u4F9D\u8D56\u8DEF\u5F84\u5DF2\u5B58\u5728\u4F46\u4E0D\u662F\u76EE\u5F55\u6216\u94FE\u63A5\uFF0C\u5DF2\u4FDD\u7559: ${o}`);return}E(o,{recursive:!0,force:!0}),W(n,o,process.platform==="win32"?"junction":"dir")}}function P(r,e=r){return b(r,{withFileTypes:!0}).flatMap(n=>{const o=t.join(r,n.name);return n.isDirectory()?P(o,e):n.isFile()?[t.relative(e,o).split(t.sep).join("/")]:[]})}function K(r){const e=j("sha256");for(const n of P(r).sort()){const o=t.join(r,...n.split("/")),s=M(o);e.update(n),e.update("\0"),e.update(String(s.size)),e.update("\0"),e.update(p(o)),e.update("\0")}return`sha256:${e.digest("hex")}`}function X(r){try{const e=JSON.parse(p(C(r),"utf-8"));if(typeof e.bridgeVersion=="string"&&typeof e.mcpVersion=="string"&&typeof e.distHash=="string")return{bridgeVersion:e.bridgeVersion,mcpVersion:e.mcpVersion,distHash:e.distHash,releasedAt:typeof e.releasedAt=="string"?e.releasedAt:""}}catch{return null}return null}function Y(r,e,n){return!c(r)||!e||e.bridgeVersion!==n.bridgeVersion||e.mcpVersion!==n.mcpVersion||e.distHash!==n.distHash}function q(r={}){const e=r.packageRoot||R(),n=t.dirname(V(e)),o=t.join(n,"index.js");if(!c(o))return null;if(c(t.join(e,"src")))return i.info(`[runtime-bridge] ${a} MCP \u672C\u5730\u5F00\u53D1\u6A21\u5F0F\uFF0C\u76F4\u63A5\u4F7F\u7528\u9879\u76EE dist: ${o}`),o;const s=r.releasedRoot||g(),u=t.join(s,"dist"),A=t.join(u,"index.js"),_={bridgeVersion:x(e),mcpVersion:G(e),distHash:K(n)},h=X(s);return Y(A,h,_)?(E(u,{recursive:!0,force:!0}),U(s,{recursive:!0}),w(e,s),N(e,s),l(n,u,{errorOnExist:!1,force:!0,recursive:!0}),v(C(s),`${JSON.stringify({..._,releasedAt:r.now?r.now():new Date().toISOString()},null,2)}
2
- `,"utf-8"),i.info(`[runtime-bridge] ${a} MCP \u5DF2\u66F4\u65B0\u5230: ${u}`)):(w(e,s),N(e,s),i.info(`[runtime-bridge] ${a} MCP \u5DF2\u662F\u6700\u65B0: ${u}`)),A}function Q(){return Object.fromEntries(Object.entries(process.env).filter(r=>typeof r[1]=="string"))}function Z(r){return Object.fromEntries(k.flatMap(e=>{const n=r[e];return typeof n=="string"&&n.length>0?[[e,n]]:[]}))}function ee(r){try{const e=JSON.parse(r);if(Array.isArray(e)&&e.every(n=>typeof n=="string"))return e}catch(e){i.warn(`[runtime-bridge] AWS_CLIENT_AGENT_MCP_ARGS \u4E0D\u662F\u5408\u6CD5 JSON\uFF0C\u5DF2\u5FFD\u7565: ${e instanceof Error?e.message:String(e)}`)}return i.warn("[runtime-bridge] AWS_CLIENT_AGENT_MCP_ARGS \u5FC5\u987B\u662F string[] JSON\uFF0C\u5DF2\u5FFD\u7565"),[]}function T(r){const e=r.replace(/^((?:https?|wss?):\/\/(?:\[[^\]]+\]|[^/:?#]+):\d+):\d+(?=\/|$)/i,"$1");try{const n=new URL(e);return n.protocol==="ws:"?n.protocol="http:":n.protocol==="wss:"?n.protocol="https:":n.protocol=n.protocol.toLowerCase(),n.origin}catch{return e.replace(/\/+$/,"")}}function re(r){const e=new URL("/ws/agent",T(r));return e.protocol==="https:"?e.protocol="wss:":e.protocol="ws:",e.toString()}function ne(r){const e=T(r);return new URL("/mcp/call",e).toString()}function te(){const r=String(process.env.AWS_RUNTIME_SCHEDULER_BASE_URL||"").trim();if(r)return r;const e=$(),n=String(e.schedulerBaseUrl||"").trim();return e.status==="paired"&&n?n:O}function pe(r={}){return d(r)}function d(r={}){const e=String(process.env.AWS_CLIENT_AGENT_MCP_COMMAND||"").trim();if(e)return{source:"override",command:e,args:process.env.AWS_CLIENT_AGENT_MCP_ARGS?ee(process.env.AWS_CLIENT_AGENT_MCP_ARGS):[]};const n=r.exists||c,s=(r.release||q)();return s&&n(s)?{source:"bundled",command:process.execPath,args:[s]}:{source:"global",command:"aws-client-agent-mcp",args:[]}}function fe(r){const e=Q(),n=d(),o=te();return{command:n.command,args:n.args,env:{...Z(e),AWS_AGENT_ID:r.agentId,AWS_WORKSPACE_PATH:r.workspacePath,AWS_SERVER_URL:e.AWS_SERVER_URL||re(o),AWS_MCP_HTTP_URL:e.AWS_MCP_HTTP_URL||ne(o),AWS_RUNTIME_BRIDGE_BASE_URL:e.AWS_RUNTIME_BRIDGE_BASE_URL||`http://127.0.0.1:${B()}`,AWS_MCP_CLAIM_LAUNCH_BINDING:e.AWS_MCP_CLAIM_LAUNCH_BINDING||"true"}}}function ge(){const r=d(),e=r.args[0]?`${r.command} ${r.args.join(" ")}`:r.command;if(r.source==="global"){i.warn(`[runtime-bridge] ${a} MCP \u672A\u627E\u5230 bundled \u4EA7\u7269\uFF0C\u542F\u52A8\u65F6\u5C06\u56DE\u9000\u5230 PATH \u547D\u4EE4: ${e}`);return}i.info(`[runtime-bridge] ${a} MCP \u5DF2\u51C6\u5907(${r.source}): ${e}`)}const me="agents-work-studio";function Ae(){const r=d(),e={type:"stdio"};if(r.command&&(e.command=r.command),r.args.length>0&&(e.args=[...r.args]),!e.command)throw new Error("\u5185\u7F6E\u901A\u8BAF MCP \u547D\u4EE4\u89E3\u6790\u5931\u8D25\uFF1A\u672A\u80FD\u5B9A\u4F4D\u53EF\u6267\u884C\u5165\u53E3\uFF08bundled/\u8986\u76D6\u53D8\u91CF/PATH \u5747\u4E0D\u53EF\u7528\uFF09");return e}export{a as AWS_MCP_SERVER_NAME,me as BUILTIN_AWS_MCP_SERVER_NAME,fe as buildAwsMcpServerConfig,Ae as buildBuiltinAwsMcpDeploySpec,ge as ensureAwsClientAgentMcpReleased,d as getAwsClientAgentMcpPreparedInfo,le as getReleasedMcpDistPath,q as releaseBundledAwsClientAgentMcp,pe as resolveAwsClientAgentMcpCommand};
1
+ import{createHash as j}from"node:crypto";import{cpSync as l,existsSync as c,lstatSync as L,mkdirSync as U,readdirSync as b,readFileSync as p,realpathSync as S,rmSync as E,statSync as M,symlinkSync as W,writeFileSync as v}from"node:fs";import t from"node:path";import{fileURLToPath as I}from"node:url";import{getActiveBridgeHttpPort as B,getRuntimeHomeDir as O,isDevMode as D,schedulerBaseUrl as H}from"../config.js";import{logger as i}from"../utils/logger.js";import{loadRuntimeBinding as $}from"./runtime-binding.js";const a=D()?"aws-mcp-dev":"aws-mcp",k=["AWS_PROJECT_NAME","AWS_PROJECT_ROOT","AWS_PROMPT","AWS_ROLE_NAME","AWS_SERVER_URL","AWS_MCP_HTTP_URL","AWS_RUNTIME_BRIDGE_BASE_URL","AWS_HEARTBEAT_INTERVAL","AWS_HEARTBEAT_TIMEOUT","PATH","HOME","USERPROFILE","TMP","TEMP","SystemRoot","COMSPEC","PATHEXT","WINDIR"];function R(){const r=I(import.meta.url);return t.resolve(t.dirname(r),"..","..")}function V(r=R()){return t.join(f(r),"dist","index.js")}function f(r){return t.join(r,"package","aws-client-agent-mcp")}function g(){return t.join(O(),".aws-bridge","mcp")}function le(){return t.join(g(),"dist")}function C(r=g()){return t.join(r,".release.json")}function T(r){try{return JSON.parse(p(r,"utf-8")).version||"unknown"}catch{return"unknown"}}function x(r){return T(t.join(r,"package.json"))}function G(r){return T(t.join(f(r),"package.json"))}function m(r,e){c(r)&&F(r,e)}function F(r,e){if(M(r).isDirectory()){l(r,e,{errorOnExist:!1,force:!0,recursive:!0});return}l(r,e,{errorOnExist:!1,force:!0})}function y(r,e){const n=f(r);m(t.join(n,"package.json"),t.join(e,"package.json")),m(t.join(n,"README.md"),t.join(e,"README.md")),m(t.join(n,"package-lock.json"),t.join(e,"package-lock.json"))}function J(r){if(!c(r))return!0;const e=L(r);return e.isSymbolicLink()||e.isDirectory()}function z(r,e){if(!c(r))return!1;try{return S(r)===S(e)}catch{return!1}}function P(r,e){const n=t.join(r,"node_modules"),o=t.join(e,"node_modules");if(!c(n)){i.warn(`[runtime-bridge] ${a} MCP \u672A\u627E\u5230\u4F9D\u8D56\u76EE\u5F55\uFF0Crelease \u4EA7\u7269\u53EF\u80FD\u65E0\u6CD5\u89E3\u6790\u8FD0\u884C\u65F6\u4F9D\u8D56: ${n}`);return}if(!z(o,n)){if(!J(o)){i.warn(`[runtime-bridge] ${a} MCP \u4F9D\u8D56\u8DEF\u5F84\u5DF2\u5B58\u5728\u4F46\u4E0D\u662F\u76EE\u5F55\u6216\u94FE\u63A5\uFF0C\u5DF2\u4FDD\u7559: ${o}`);return}E(o,{recursive:!0,force:!0}),W(n,o,process.platform==="win32"?"junction":"dir")}}function w(r,e=r){return b(r,{withFileTypes:!0}).flatMap(n=>{const o=t.join(r,n.name);return n.isDirectory()?w(o,e):n.isFile()?[t.relative(e,o).split(t.sep).join("/")]:[]})}function K(r){const e=j("sha256");for(const n of w(r).sort()){const o=t.join(r,...n.split("/")),s=M(o);e.update(n),e.update("\0"),e.update(String(s.size)),e.update("\0"),e.update(p(o)),e.update("\0")}return`sha256:${e.digest("hex")}`}function X(r){try{const e=JSON.parse(p(C(r),"utf-8"));if(typeof e.bridgeVersion=="string"&&typeof e.mcpVersion=="string"&&typeof e.distHash=="string")return{bridgeVersion:e.bridgeVersion,mcpVersion:e.mcpVersion,distHash:e.distHash,releasedAt:typeof e.releasedAt=="string"?e.releasedAt:""}}catch{return null}return null}function Y(r,e,n){return!c(r)||!e||e.bridgeVersion!==n.bridgeVersion||e.mcpVersion!==n.mcpVersion||e.distHash!==n.distHash}function q(r={}){const e=r.packageRoot||R(),n=t.dirname(V(e)),o=t.join(n,"index.js");if(!c(o))return null;if(c(t.join(e,"src")))return i.info(`[runtime-bridge] ${a} MCP \u672C\u5730\u5F00\u53D1\u6A21\u5F0F\uFF0C\u76F4\u63A5\u4F7F\u7528\u9879\u76EE dist: ${o}`),o;const s=r.releasedRoot||g(),u=t.join(s,"dist"),A=t.join(u,"index.js"),_={bridgeVersion:x(e),mcpVersion:G(e),distHash:K(n)},h=X(s);return Y(A,h,_)?(E(u,{recursive:!0,force:!0}),U(s,{recursive:!0}),y(e,s),P(e,s),l(n,u,{errorOnExist:!1,force:!0,recursive:!0}),v(C(s),`${JSON.stringify({..._,releasedAt:r.now?r.now():new Date().toISOString()},null,2)}
2
+ `,"utf-8"),i.info(`[runtime-bridge] ${a} MCP \u5DF2\u66F4\u65B0\u5230: ${u}`)):(y(e,s),P(e,s),i.info(`[runtime-bridge] ${a} MCP \u5DF2\u662F\u6700\u65B0: ${u}`)),A}function Q(){return Object.fromEntries(Object.entries(process.env).filter(r=>typeof r[1]=="string"))}function Z(r){return Object.fromEntries(k.flatMap(e=>{const n=r[e];return typeof n=="string"&&n.length>0?[[e,n]]:[]}))}function ee(r){try{const e=JSON.parse(r);if(Array.isArray(e)&&e.every(n=>typeof n=="string"))return e}catch(e){i.warn(`[runtime-bridge] AWS_CLIENT_AGENT_MCP_ARGS \u4E0D\u662F\u5408\u6CD5 JSON\uFF0C\u5DF2\u5FFD\u7565: ${e instanceof Error?e.message:String(e)}`)}return i.warn("[runtime-bridge] AWS_CLIENT_AGENT_MCP_ARGS \u5FC5\u987B\u662F string[] JSON\uFF0C\u5DF2\u5FFD\u7565"),[]}function N(r){const e=r.replace(/^((?:https?|wss?):\/\/(?:\[[^\]]+\]|[^/:?#]+):\d+):\d+(?=\/|$)/i,"$1");try{const n=new URL(e);return n.protocol==="ws:"?n.protocol="http:":n.protocol==="wss:"?n.protocol="https:":n.protocol=n.protocol.toLowerCase(),n.origin}catch{return e.replace(/\/+$/,"")}}function re(r){const e=new URL("/ws/agent",N(r));return e.protocol==="https:"?e.protocol="wss:":e.protocol="ws:",e.toString()}function ne(r){const e=N(r);return new URL("/mcp/call",e).toString()}function te(){const r=String(process.env.AWS_RUNTIME_SCHEDULER_BASE_URL||"").trim();if(r)return r;const e=$(),n=String(e.schedulerBaseUrl||"").trim();return e.status==="paired"&&n?n:H}function pe(r={}){return d(r)}function d(r={}){const e=String(process.env.AWS_CLIENT_AGENT_MCP_COMMAND||"").trim();if(e)return{source:"override",command:e,args:process.env.AWS_CLIENT_AGENT_MCP_ARGS?ee(process.env.AWS_CLIENT_AGENT_MCP_ARGS):[]};const n=r.exists||c,s=(r.release||q)();return s&&n(s)?{source:"bundled",command:process.execPath,args:[s]}:{source:"global",command:"aws-client-agent-mcp",args:[]}}function fe(r){const e=Q(),n=d(),o=te();return{command:n.command,args:n.args,env:{...Z(e),AWS_AGENT_ID:r.agentId,AWS_WORKSPACE_PATH:r.workspacePath,AWS_SERVER_URL:e.AWS_SERVER_URL||re(o),AWS_MCP_HTTP_URL:e.AWS_MCP_HTTP_URL||ne(o),AWS_RUNTIME_BRIDGE_BASE_URL:e.AWS_RUNTIME_BRIDGE_BASE_URL||`http://127.0.0.1:${B()}`,AWS_MCP_CLAIM_LAUNCH_BINDING:e.AWS_MCP_CLAIM_LAUNCH_BINDING||"true"}}}function ge(){const r=d(),e=r.args[0]?`${r.command} ${r.args.join(" ")}`:r.command;if(r.source==="global"){i.warn(`[runtime-bridge] ${a} MCP \u672A\u627E\u5230 bundled \u4EA7\u7269\uFF0C\u542F\u52A8\u65F6\u5C06\u56DE\u9000\u5230 PATH \u547D\u4EE4: ${e}`);return}i.info(`[runtime-bridge] ${a} MCP \u5DF2\u51C6\u5907(${r.source}): ${e}`)}const me="agents-work-studio";function Ae(){const r=d(),e={type:"stdio"};if(r.command&&(e.command=r.command),r.args.length>0&&(e.args=[...r.args]),!e.command)throw new Error("\u5185\u7F6E\u901A\u8BAF MCP \u547D\u4EE4\u89E3\u6790\u5931\u8D25\uFF1A\u672A\u80FD\u5B9A\u4F4D\u53EF\u6267\u884C\u5165\u53E3\uFF08bundled/\u8986\u76D6\u53D8\u91CF/PATH \u5747\u4E0D\u53EF\u7528\uFF09");return e}export{a as AWS_MCP_SERVER_NAME,me as BUILTIN_AWS_MCP_SERVER_NAME,fe as buildAwsMcpServerConfig,Ae as buildBuiltinAwsMcpDeploySpec,ge as ensureAwsClientAgentMcpReleased,d as getAwsClientAgentMcpPreparedInfo,le as getReleasedMcpDistPath,q as releaseBundledAwsClientAgentMcp,pe as resolveAwsClientAgentMcpCommand};
3
3
 
@@ -6,12 +6,18 @@ export declare function getDefaults(type: CapabilityType): Record<string, boolea
6
6
 
7
7
  export declare function getOverrides(agentId: string, type: CapabilityType): Record<string, boolean>;
8
8
 
9
+ export declare function getInherited(agentId: string, type: CapabilityType): Record<string, boolean>;
10
+
9
11
  export declare function getEffective(agentId: string, type: CapabilityType, name: string, fallback?: boolean): boolean;
10
12
 
13
+ export declare function getEffectiveSource(agentId: string, type: CapabilityType, name: string): "agent" | "inherited" | "bridge" | "deployed" | "default";
14
+
11
15
  export declare function setDefault(type: CapabilityType, name: string, value: boolean | null): boolean;
12
16
 
13
17
  export declare function setOverride(agentId: string, type: CapabilityType, name: string, value: boolean | null): boolean;
14
18
 
19
+ export declare function setInherited(agentId: string, type: CapabilityType, map: Record<string, boolean> | null): boolean;
20
+
15
21
  export declare function listOverrideAgents(type: CapabilityType): string[];
16
22
 
17
23
  export declare function reconcileDefaultsFromDeployed(type: CapabilityType): number;
@@ -19,3 +25,5 @@ export declare function reconcileDefaultsFromDeployed(type: CapabilityType): num
19
25
  export declare function hasAnyDefault(type: CapabilityType): boolean;
20
26
 
21
27
  export declare function getEffectiveMap(agentId: string, type: CapabilityType, names: Iterable<string>): Record<string, boolean>;
28
+
29
+ export declare function setInheritedMap(agentId: string, byType: Partial<Record<CapabilityType, Record<string, boolean>>> | null): CapabilityType[];
@@ -1,3 +1,3 @@
1
- import{existsSync as m,readFileSync as h,readdirSync as j}from"node:fs";import d from"node:path";import{getBridgeTemplateMcpDir as x,getBridgeTemplatePluginsDir as v,getBridgeTemplateSkillsDir as A}from"../config.js";import{atomicWriteFileSync as J,sanitizeAgentId as b}from"../utils/file-utils.js";const M=["skills","mcp","plugins"];function a(e){switch(e){case"skills":return A();case"mcp":return x();case"plugins":return v();default:throw new Error(`\u672A\u77E5\u80FD\u529B\u7C7B\u578B: ${String(e)}`)}}const c=new Map;function W(e,t){t?c.set(e,t):c.delete(e)}function w(e,t){const r=c.get(e);if(r)try{return r()[t]}catch{return}}function l(e){try{if(!m(e))return{};const t=JSON.parse(h(e,"utf8"));return!t||typeof t!="object"||Array.isArray(t)?{}:t}catch{return{}}}function y(e,t){J(e,`${JSON.stringify(t,null,2)}
2
- `)}function s(e,t){const r=t[e];if(!r||typeof r!="object"||Array.isArray(r))return{};const i={};for(const[n,o]of Object.entries(r))n.trim()&&typeof o=="boolean"&&(i[n.trim()]=o);return i}function D(e,t,r,i){const n={...s(t,e)};i==null?delete n[r]:n[r]=i,e[t]=n}function O(e){return d.join(a(e),"config.json")}function S(e,t){return d.join(a(e),"agents",`${b(t)}.json`)}function p(e){return s(e,l(O(e)))}function F(e,t){return e?s(t,l(S(t,e))):{}}function N(e,t,r,i){const o=F(e,t)[r];if(o!==void 0)return o;const u=p(t)[r];if(u!==void 0)return u;if(i!==void 0)return i;const g=w(t,r);return g!==void 0?g:!1}function P(e,t,r){const i=O(e),n=l(i),o=s(e,n);D(n,e,t,r);const f=s(e,n);return JSON.stringify(o)===JSON.stringify(f)?!1:(y(i,n),!0)}function $(e,t,r,i){if(!e)return!1;const n=S(t,e),o=l(n),f=s(t,o);D(o,t,r,i);const u=s(t,o);return JSON.stringify(f)===JSON.stringify(u)?!1:(y(n,o),!0)}function V(e){const t=d.join(a(e),"agents");try{return m(t)?j(t).filter(r=>r.endsWith(".json")&&!r.startsWith(".")).map(r=>r.slice(0,-5)):[]}catch{return[]}}function Y(e){const t=c.get(e);if(!t)return 0;let r=0;const i=p(e),n=t()??{};for(const o of Object.keys(n))o in i||n[o]===!0&&(P(e,o,!1),r++);return r}function z(e){return Object.keys(p(e)).length>0}function C(e,t,r){const i={};for(const n of r)i[n]=N(e,t,n);return i}export{M as CAPABILITY_TYPES,p as getDefaults,N as getEffective,C as getEffectiveMap,F as getOverrides,z as hasAnyDefault,V as listOverrideAgents,Y as reconcileDefaultsFromDeployed,P as setDefault,W as setDeployedDefaultsProvider,$ as setOverride};
1
+ import{existsSync as y,readFileSync as j,readdirSync as F}from"node:fs";import A from"node:path";import{getBridgeTemplateMcpDir as M,getBridgeTemplatePluginsDir as k,getBridgeTemplateSkillsDir as E}from"../config.js";import{atomicWriteFileSync as T,sanitizeAgentId as B}from"../utils/file-utils.js";const x=["skills","mcp","plugins"];function O(e){switch(e){case"skills":return E();case"mcp":return M();case"plugins":return k();default:throw new Error(`\u672A\u77E5\u80FD\u529B\u7C7B\u578B: ${String(e)}`)}}const a=new Map;function C(e,r){r?a.set(e,r):a.delete(e)}function S(e,r){const t=a.get(e);if(t)try{return t()[r]}catch{return}}function v(e){try{if(!y(e))return{};const r=JSON.parse(j(e,"utf8"));return!r||typeof r!="object"||Array.isArray(r)?{}:r}catch{return{}}}function m(e,r){T(e,`${JSON.stringify(r,null,2)}
2
+ `)}function c(e,r){const t=r[e];if(!t||typeof t!="object"||Array.isArray(t))return{};const n={};for(const[i,o]of Object.entries(t))i.trim()&&typeof o=="boolean"&&(n[i.trim()]=o);return n}function L(e,r,t,n){const i={...c(r,e)};n==null?delete i[t]:i[t]=n,e[r]=i}function D(e){try{if(!y(e))return{};const r=JSON.parse(j(e,"utf8"));return!r||typeof r!="object"||Array.isArray(r)?{}:r}catch{return{}}}function d(e,r,t){const n=D(e),i=n[t];return i&&typeof i=="object"&&!Array.isArray(i)?c(r,i):t==="overrides"?c(r,n):{}}function b(e,r,t,n){const i=D(e),o={};for(const f of["overrides","inherited"]){const s=f===t?n:d(e,r,f),h={};for(const u of x){const l=u===r?s:d(e,u,f);h[u]=l}o[f]=h}m(e,o)}function w(e){return A.join(O(e),"config.json")}function p(e,r){return A.join(O(e),"agents",`${B(r)}.json`)}function g(e){return c(e,v(w(e)))}function J(e,r){return e?d(p(r,e),r,"overrides"):{}}function N(e,r){return e?d(p(r,e),r,"inherited"):{}}function P(e,r,t,n){const o=J(e,r)[t];if(o!==void 0)return o;const s=N(e,r)[t];if(s!==void 0)return s;const u=g(r)[t];if(u!==void 0)return u;if(n!==void 0)return n;const l=S(r,t);return l!==void 0?l:!1}function _(e,r,t){return J(e,r)[t]!==void 0?"agent":N(e,r)[t]!==void 0?"inherited":g(r)[t]!==void 0?"bridge":S(r,t)!==void 0?"deployed":"default"}function V(e,r,t){const n=w(e),i=v(n),o=c(e,i);L(i,e,r,t);const f=c(e,i);return JSON.stringify(o)===JSON.stringify(f)?!1:(m(n,i),!0)}function q(e,r,t,n){if(!e)return!1;const i=p(r,e),o=d(i,r,"overrides"),f={...o};return n==null?delete f[t]:f[t]=n,JSON.stringify(o)===JSON.stringify(f)?!1:(b(i,r,"overrides",f),!0)}function W(e,r,t){if(!e)return!1;const n=p(r,e),i=d(n,r,"inherited"),o={};if(t&&typeof t=="object"&&!Array.isArray(t))for(const[f,s]of Object.entries(t))f.trim()&&typeof s=="boolean"&&(o[f.trim()]=s);return JSON.stringify(i)===JSON.stringify(o)?!1:(b(n,r,"inherited",o),!0)}function G(e){const r=A.join(O(e),"agents");try{return y(r)?F(r).filter(t=>t.endsWith(".json")&&!t.startsWith(".")).map(t=>t.slice(0,-5)):[]}catch{return[]}}function H(e){const r=a.get(e);if(!r)return 0;let t=0;const n=g(e),i=r()??{};for(const o of Object.keys(i))o in n||i[o]===!0&&(V(e,o,!1),t++);return t}function K(e){return Object.keys(g(e)).length>0}function Q(e,r,t){const n={};for(const i of t)n[i]=P(e,r,i);return n}function U(e,r){const t=[];if(!e)return t;for(const n of x){const i=r&&typeof r=="object"?r[n]??{}:{};W(e,n,i)&&t.push(n)}return t}export{x as CAPABILITY_TYPES,g as getDefaults,P as getEffective,Q as getEffectiveMap,_ as getEffectiveSource,N as getInherited,J as getOverrides,K as hasAnyDefault,G as listOverrideAgents,H as reconcileDefaultsFromDeployed,V as setDefault,C as setDeployedDefaultsProvider,W as setInherited,U as setInheritedMap,q as setOverride};
3
3
 
@@ -10,6 +10,8 @@ interface DesktopMcpManagerState {
10
10
  binaryPath: string;
11
11
 
12
12
  envSig: string;
13
+
14
+ ownerAgentId?: string;
13
15
  }
14
16
 
15
17
  interface DesktopMcpFailureState {
@@ -28,7 +30,7 @@ export interface DesktopAgentAiInfo {
28
30
 
29
31
  export declare function resolveDesktopMcpBinary(): Promise<string | null>;
30
32
 
31
- export declare function startDesktopMcpManager(): Promise<DesktopMcpManagerState | null>;
33
+ export declare function startDesktopMcpManager(agentId?: string): Promise<DesktopMcpManagerState | null>;
32
34
 
33
35
  export declare function getDesktopTools(agentId: string | undefined, agentAi?: DesktopAgentAiInfo): Promise<ACodeBuiltInToolLike[]>;
34
36