aws-runtime-bridge 1.9.172 → 1.9.175

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 (65) hide show
  1. package/CHANGELOG.md +126 -0
  2. package/dist/adapter/AcodeSdkAdapter.d.ts +5 -1
  3. package/dist/adapter/AcodeSdkAdapter.js +3 -3
  4. package/dist/adapter/types.d.ts +2 -0
  5. package/dist/index.js +1 -1
  6. package/dist/routes/bridge-temp-files.d.ts +1 -0
  7. package/dist/routes/bridge-temp-files.js +2 -0
  8. package/dist/routes/dashboard.js +35 -5
  9. package/dist/routes/file-browser.d.ts +4 -10
  10. package/dist/routes/file-browser.js +1 -1
  11. package/dist/routes/git.d.ts +42 -0
  12. package/dist/routes/git.js +34 -34
  13. package/dist/routes/sessions.js +1 -1
  14. package/dist/routes/tech-stack.d.ts +2 -0
  15. package/dist/routes/tech-stack.js +2 -0
  16. package/dist/routes/terminal.js +19 -19
  17. package/dist/services/agent-pty-manager.d.ts +2 -0
  18. package/dist/services/agent-pty-manager.js +5 -4
  19. package/dist/services/agent-startup-memory.js +4 -4
  20. package/dist/services/bridge-temp-files.d.ts +36 -0
  21. package/dist/services/bridge-temp-files.js +2 -0
  22. package/dist/services/fileSnapshotStore.d.ts +9 -0
  23. package/dist/services/fileSnapshotStore.js +1 -1
  24. package/dist/services/gitignore.d.ts +12 -0
  25. package/dist/services/gitignore.js +2 -0
  26. package/dist/services/log-retention.js +1 -1
  27. package/dist/services/open-doc-events.d.ts +21 -0
  28. package/dist/services/open-doc-events.js +2 -0
  29. package/dist/services/open-doc-registry.d.ts +24 -0
  30. package/dist/services/open-doc-registry.js +2 -0
  31. package/dist/services/request-invalid-dump.js +1 -1
  32. package/dist/services/runtime-resources-snapshot.js +2 -2
  33. package/dist/services/snapshot-retention.d.ts +7 -0
  34. package/dist/services/snapshot-retention.js +2 -0
  35. package/dist/services/tech-stack-scanner.d.ts +31 -0
  36. package/dist/services/tech-stack-scanner.js +2 -0
  37. package/dist/services/tunnel-client.d.ts +42 -0
  38. package/dist/services/tunnel-client.js +1 -1
  39. package/dist/services/workspaceTaskChangeWatcher.js +2 -2
  40. package/package/acode/dist/__tests__/summary-request-helper.d.ts +2 -0
  41. package/package/acode/dist/__tests__/summary-request-helper.js +2 -0
  42. package/package/acode/dist/cache-control.d.ts +26 -0
  43. package/package/acode/dist/cache-control.js +2 -0
  44. package/package/acode/dist/compaction.d.ts +35 -5
  45. package/package/acode/dist/compaction.js +19 -17
  46. package/package/acode/dist/microcompact.d.ts +57 -0
  47. package/package/acode/dist/microcompact.js +2 -0
  48. package/package/acode/dist/runtime.d.ts +4 -0
  49. package/package/acode/dist/runtime.js +40 -33
  50. package/package/acode/dist/token-estimator.d.ts +15 -0
  51. package/package/acode/dist/token-estimator.js +2 -0
  52. package/package/acode/dist/types.d.ts +13 -0
  53. package/package/aws-client-agent-mcp/dist/ability-market-tools.js +1 -1
  54. package/package/aws-client-agent-mcp/dist/agent-client.d.ts +15 -2
  55. package/package/aws-client-agent-mcp/dist/agent-client.js +1 -1
  56. package/package/aws-client-agent-mcp/dist/mcp-server.d.ts +5 -0
  57. package/package/aws-client-agent-mcp/dist/mcp-server.js +25 -23
  58. package/package/aws-client-agent-mcp/dist/mcp-tools.js +7 -7
  59. package/package/aws-client-agent-mcp/dist/memory-store.d.ts +21 -2
  60. package/package/aws-client-agent-mcp/dist/memory-store.js +27 -2
  61. package/package/aws-client-agent-mcp/dist/memory-tools.js +13 -9
  62. package/package/aws-client-agent-mcp/dist/server-memory-store.d.ts +1 -1
  63. package/package/aws-client-agent-mcp/dist/server-memory-store.js +1 -1
  64. package/package/aws-client-agent-mcp/dist/types.d.ts +51 -0
  65. package/package.json +1 -1
@@ -1,42 +1,42 @@
1
- import{spawn as ht}from"node:child_process";import{promises as oe}from"node:fs";import At from"node:os";import se from"node:path";import{TextDecoder as ie}from"node:util";import Me from"axios";import{Router as Tt}from"express";import{v4 as _t}from"uuid";import{adapterRegistry as T,getToolActionInfo as Ce,isTransientClipboardPasteFilePath as Ue,redactTransientClipboardPastePaths as F,registerSdkProviders as bt,resolveSdkProviderIdByCommand as kt}from"../adapter/index.js";import{MESSAGE_POLLING_IDLE_PROMPT as xe}from"../adapter/prompts.js";import{getActiveBridgeHttpPort as Ct,getAcodeDataHome as Ne}from"../config.js";import{buildResumeContextBlock as Et}from"@agentswork/acode";import{validateToken as I}from"../middleware/auth.js";import{getAgentProcessManager as Ee}from"../services/agent-process-manager.js";import{loadAgentStartupMemories as wt}from"../services/agent-startup-memory.js";import{createAiConfigService as $t}from"../services/ai-config-service.js";import{resolveSchedulerBaseUrlFromToken as Be}from"../services/auto-register.js";import{setChangeCacheRetentionDays as Rt}from"../services/change-cache-retention.js";import{clearDebugMounts as ae}from"../services/debug-mount.js";import{getAllPushStats as Dt,startHeartbeatScheduler as Ot}from"../services/event-delta-pusher.js";import{prepareAcodeInstanceConfig as Pt,redactForLog as ce}from"../services/instance-ai-config-service.js";import{setLogRetentionDays as Lt}from"../services/log-retention.js";import{setAgentFeatures as Mt,setAgentCapabilities as Ut,setAgentInheritedFeatures as xt,setAgentCapabilitiesInherited as Nt,getAgentFeatures as Bt,getAgentInheritedFeatures as jt,getFeatureState as S,LAUNCH_ITEM_FEATURE_KEY as je,HIRE_FEATURE_KEY as Fe,PENCIL_FEATURE_KEY as Ke,DRAW_FEATURE_KEY as ve,OFFICE_FEATURE_KEY as He,COLLABORATION_TASK_FEATURE_KEY as qe,COLLABORATION_MEETING_FEATURE_KEY as We,COLLABORATION_DEBUG_FEATURE_KEY as ze,COLLABORATION_FILE_HISTORY_FEATURE_KEY as Ge,EMAIL_FEATURE_KEY as Ye,SKILL_INSTALL_FEATURE_KEY as Xe,ABILITY_DEV_FEATURE_KEY as Ve}from"../services/instance-features.js";import{enqueueMcpLaunchBinding as Ft}from"../services/mcp-launch-binding-queue.js";import{setPanelEnvVars as Kt,setAgentMeta as vt}from"../services/panel-env.js";import{findClaudeCodeProcesses as Ht,isProcessRunning as qt}from"../services/process-detector.js";import{forgetSession as K,onSdkToolUseEnd as Wt,onSdkToolUseStart as zt}from"../services/sdk-tool-file-change-recorder.js";import{bridgeEventBuffer as Je,sendOutput as v,sendQuestionRequest as Gt,sendToolAuthRequest as Yt,sendStatus as $}from"../services/session-output.js";import{findPersistedSessionByAgentId as Xt,removePersistedSession as H,savePersistedSessions as Vt,updatePersistedSessionAutoCommands as Jt,updatePersistedSessionRuntimeState as Qt,upsertPersistedSession as Zt}from"../services/terminal-persistence.js";import{getInstanceAiConfigDebugLogger as en}from"../utils/instance-ai-config-debug-logger.js";import{logger as l}from"../utils/logger.js";const h=Tt();function Qe(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 f=new Map,tn=45e3,ue=new Map;function nn(e){if(ue.has(e))return;const n=setInterval(()=>{const t=f.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(()=>{})},tn);ue.set(e,n)}function M(e){const n=ue.get(e);n&&(clearInterval(n),ue.delete(e))}const Ze=4e3,rn=200,on=2e3,et=24e3,tt=200,nt=8e3;function sn(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${de(u,on)}`),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 p=String(u.toolName||"").trim()||"\u672A\u77E5\u5DE5\u5177";if(an(p))continue;if(d==="tool_use"){const g=un(String(u.content||""));n.push(`\u3010\u5DE5\u5177\u8C03\u7528\u3011${p}${g?` ${g}`:""}`)}else{const g=de(String(u.content||"").trim(),rn);n.push(`\u3010\u5DE5\u5177\u7ED3\u679C\u3011${p}${u.isError?"\uFF08\u5931\u8D25\uFF09":""}${g?`\uFF1A${g}`:""}`)}continue}const m=String(u.content||"");m.trim()&&(t===d||(s(),t=d),r.push(m))}if(s(),n.length===0)return{snapshot:"",truncated:!1};const o=n.join(`
2
- `);if(o.length<=et)return{snapshot:o,truncated:!1};const i=et-nt,a=o.slice(0,nt),c=o.slice(o.length-i);return{snapshot:`${a}
1
+ import{spawn as At}from"node:child_process";import{promises as oe}from"node:fs";import Tt from"node:os";import se from"node:path";import{TextDecoder as ie}from"node:util";import{buildResumeContextBlock as _t}from"@agentswork/acode";import xe from"axios";import{Router as bt}from"express";import{v4 as kt}from"uuid";import{adapterRegistry as T,getToolActionInfo as Ce,isTransientClipboardPasteFilePath as Ue,redactTransientClipboardPastePaths as F,registerSdkProviders as Ct,resolveSdkProviderIdByCommand as Et}from"../adapter/index.js";import{MESSAGE_POLLING_IDLE_PROMPT as Ne}from"../adapter/prompts.js";import{getActiveBridgeHttpPort as Rt,getAcodeDataHome as Be}from"../config.js";import{validateToken as I}from"../middleware/auth.js";import{getAgentProcessManager as Ee}from"../services/agent-process-manager.js";import{loadAgentStartupMemories as $t}from"../services/agent-startup-memory.js";import{createAiConfigService as wt}from"../services/ai-config-service.js";import{resolveSchedulerBaseUrlFromToken as je}from"../services/auto-register.js";import{setChangeCacheRetentionDays as Dt}from"../services/change-cache-retention.js";import{clearDebugMounts as ae}from"../services/debug-mount.js";import{getAllPushStats as Ot,startHeartbeatScheduler as Pt}from"../services/event-delta-pusher.js";import{sweepExpiredSnapshots as Lt}from"../services/fileSnapshotStore.js";import{prepareAcodeInstanceConfig as Mt,redactForLog as ce}from"../services/instance-ai-config-service.js";import{setAgentFeatures as xt,setAgentCapabilities as Ut,setAgentInheritedFeatures as Nt,setAgentCapabilitiesInherited as Bt,getAgentFeatures as jt,getAgentInheritedFeatures as Ft,getFeatureState as S,LAUNCH_ITEM_FEATURE_KEY as Fe,HIRE_FEATURE_KEY as ve,PENCIL_FEATURE_KEY as Ke,DRAW_FEATURE_KEY as He,OFFICE_FEATURE_KEY as qe,COLLABORATION_TASK_FEATURE_KEY as We,COLLABORATION_MEETING_FEATURE_KEY as ze,COLLABORATION_DEBUG_FEATURE_KEY as Ge,COLLABORATION_FILE_HISTORY_FEATURE_KEY as Ye,EMAIL_FEATURE_KEY as Xe,SKILL_INSTALL_FEATURE_KEY as Ve,ABILITY_DEV_FEATURE_KEY as Je}from"../services/instance-features.js";import{setLogRetentionDays as vt}from"../services/log-retention.js";import{enqueueMcpLaunchBinding as Kt}from"../services/mcp-launch-binding-queue.js";import{setPanelEnvVars as Ht,setAgentMeta as qt}from"../services/panel-env.js";import{findClaudeCodeProcesses as Wt,isProcessRunning as zt}from"../services/process-detector.js";import{forgetSession as v,onSdkToolUseEnd as Gt,onSdkToolUseStart as Yt}from"../services/sdk-tool-file-change-recorder.js";import{bridgeEventBuffer as Qe,sendOutput as K,sendQuestionRequest as Xt,sendToolAuthRequest as Vt,sendStatus as $}from"../services/session-output.js";import{getSnapshotRetentionDays as Re,setSnapshotRetentionDays as Jt}from"../services/snapshot-retention.js";import{findPersistedSessionByAgentId as Qt,removePersistedSession as H,savePersistedSessions as Zt,updatePersistedSessionAutoCommands as en,updatePersistedSessionRuntimeState as tn,upsertPersistedSession as nn}from"../services/terminal-persistence.js";import{getInstanceAiConfigDebugLogger as rn}from"../utils/instance-ai-config-debug-logger.js";import{logger as l}from"../utils/logger.js";const h=bt();function Ze(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 f=new Map,on=45e3,ue=new Map;function sn(e){if(ue.has(e))return;const n=setInterval(()=>{const t=f.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(()=>{})},on);ue.set(e,n)}function M(e){const n=ue.get(e);n&&(clearInterval(n),ue.delete(e))}const et=4e3,an=200,cn=2e3,tt=24e3,nt=200,rt=8e3;function un(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${de(u,cn)}`),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 p=String(u.toolName||"").trim()||"\u672A\u77E5\u5DE5\u5177";if(dn(p))continue;if(d==="tool_use"){const g=fn(String(u.content||""));n.push(`\u3010\u5DE5\u5177\u8C03\u7528\u3011${p}${g?` ${g}`:""}`)}else{const g=de(String(u.content||"").trim(),an);n.push(`\u3010\u5DE5\u5177\u7ED3\u679C\u3011${p}${u.isError?"\uFF08\u5931\u8D25\uFF09":""}${g?`\uFF1A${g}`:""}`)}continue}const m=String(u.content||"");m.trim()&&(t===d||(s(),t=d),r.push(m))}if(s(),n.length===0)return{snapshot:"",truncated:!1};const o=n.join(`
2
+ `);if(o.length<=tt)return{snapshot:o,truncated:!1};const i=tt-rt,a=o.slice(0,rt),c=o.slice(o.length-i);return{snapshot:`${a}
3
3
 
4
4
  ...\uFF08\u6B64\u5904\u7701\u7565\u4E2D\u6BB5 ${o.length-a.length-c.length} \u5B57\u7B26\u5386\u53F2\uFF09...
5
5
 
6
- ${c}`,truncated:!0}}function de(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 an(e){const n=e.toLowerCase();return n.includes("poll_message")||n.includes("get_message")||n.includes("await_complete")}function cn(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 un(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 de(n,tt)}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 de(r.join(" "),tt)}function rt(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 q=new Set;function dn(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 ln(e){return e!=="acode"}function fn(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 V(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)&&l.info(`[TokenDebug][Terminal] resolveStatusChangeUsage: input=${s.inputTokens} output=${s.outputTokens} cacheHit=${s.cacheHitTokens??"(none)"} cacheMiss=${s.cacheMissTokens??"(none)"} actionType=${e?.actionType??"(none)"}`),s}function mn(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 pn(e){return e.restoredActionInfo?.actionType==="idle"||e.currentRuntimeActionType==="idle"&&e.shouldPreservePrevAction||e.status==="waiting_input"&&!e.actionInfo?.actionType}function gn(e){return e.actionInfo?.actionType?!1:!!e.usage}const J=new Map,yn="utf-8",ot="utf-8",st=300,it=6e4;function Q(e){return String(e).padStart(2,"0")}function Sn(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 se.join(Ne(),"cmd-dist",e,`${t}-${r}-${s}`,o,i,`${a}-cmd.out`)}function In(e){if(!e)return 0;const n=e.replace(/\r\n/g,`
6
+ ${c}`,truncated:!0}}function de(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 dn(e){const n=e.toLowerCase();return n.includes("poll_message")||n.includes("get_message")||n.includes("await_complete")}function ln(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 fn(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 de(n,nt)}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 de(r.join(" "),nt)}function ot(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 q=new Set;function mn(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 pn(e){return e!=="acode"}function gn(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 V(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)&&l.info(`[TokenDebug][Terminal] resolveStatusChangeUsage: input=${s.inputTokens} output=${s.outputTokens} cacheHit=${s.cacheHitTokens??"(none)"} cacheMiss=${s.cacheMissTokens??"(none)"} actionType=${e?.actionType??"(none)"}`),s}function yn(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 Sn(e){return e.restoredActionInfo?.actionType==="idle"||e.currentRuntimeActionType==="idle"&&e.shouldPreservePrevAction||e.status==="waiting_input"&&!e.actionInfo?.actionType}function In(e){return e.actionInfo?.actionType?!1:!!e.usage}const J=new Map,hn="utf-8",st="utf-8",it=300,at=6e4;function Q(e){return String(e).padStart(2,"0")}function An(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 se.join(Be(),"cmd-dist",e,`${t}-${r}-${s}`,o,i,`${a}-cmd.out`)}function Tn(e){if(!e)return 0;const n=e.replace(/\r\n/g,`
7
7
  `).replace(/\r/g,`
8
8
  `),t=n.endsWith(`
9
9
  `)?n.slice(0,-1):n;return t?t.split(`
10
- `).length:1}function hn(e,n=st){return`\r
10
+ `).length:1}function _n(e,n=it){return`\r
11
11
  [ACode] \u547D\u4EE4\u8F93\u51FA\u8D85\u8FC7 ${n} \u884C\uFF0C\u5B8C\u6574\u8F93\u51FA\u5DF2\u5199\u5165: ${e}\r
12
12
  [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
13
- `}function An(e=it){return`\r
13
+ `}function bn(e=at){return`\r
14
14
  [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
15
- `}async function at(e){const n=e.outputPath||Sn(e.agentId,e.startedAt);return e.outputPath=n,await oe.mkdir(se.dirname(n),{recursive:!0}),await oe.writeFile(n,e.chunks.join(""),"utf-8"),n}function Tn(e){return String(e??"").replace(/\r/g,`
16
- `).trim()}function _n(e=process.platform,n=process.env){const t=n.AWS_TERMINAL_OUTPUT_ENCODING?.trim();return t||(e==="win32"?yn:ot)}function ct(e=_n()){if(e!=="utf-8")try{return new ie(e,{fatal:!1})}catch{return new ie(ot,{fatal:!1})}return bn()}function bn(){let e=null,n=null,t=null;const r=[];function s(o){try{return new ie(o,{fatal:!1})}catch{return new ie("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 le(e,n,t=!1){return t?e.decode():!n||n.length===0?"":e.decode(n,{stream:!0})}function kn(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 Cn(e){const n=J.get(e.sessionId);if(n)return n;const t={currentDirectory:e.workspacePath,runningProcess:null};return J.set(e.sessionId,t),t}function ut(e){for(const n of f.values())if(n.agentId===e)return n}async function En(e){const n=T.get(e.providerId||"claude-code"),t=Z(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 Z(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 wn(e,n=qt){return e.pid?await n(e.pid)?gt(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 Hr(e){try{ae(e)}catch(t){l.warn(`[cleanupSdkSessionByAgentId] clear debug mounts failed for agentId=${e}: ${t}`)}const n=ut(e);if(!n)l.info(`[cleanupSdkSessionByAgentId] No active SDK session found for agentId=${e}, cleaning residual state anyway`);else{const t=n.sessionId;return l.info(`[cleanupSdkSessionByAgentId] Cleaning up SDK session for agentId=${e}, sessionId=${t}`),M(t),f.delete(t),K(t),fe(t),H(t).catch(r=>{l.warn(`[cleanupSdkSessionByAgentId] Failed to remove persisted session for agentId=${e}: ${r}`)}),t}q.has(e)&&(q.delete(e),l.info(`[cleanupSdkSessionByAgentId] Released startingAgents lock for agentId=${e}`))}function fe(e){const n=J.get(e);if(!n?.runningProcess){J.delete(e);return}try{n.runningProcess.kill()}catch{}finally{n.runningProcess=null,J.delete(e)}}function C(e,n){n&&(e.seq+=1,v(e.agentId,n,e.sessionId,e.seq,void 0,{runtimeAccessToken:e.runtimeAccessToken,schedulerBaseUrl:e.schedulerBaseUrl}).catch(()=>{}))}function we(e){return`\x1B[36m${e}>\x1B[0m `}function $n(e,n){return n==="~"?At.homedir():se.resolve(e,n)}async function Rn(e,n,t){const r=kn(t);if(r===void 0)return!1;if(r===null)return C(e,`${n.currentDirectory}\r
17
- `),!0;const s=$n(n.currentDirectory,r);try{return(await oe.stat(s)).isDirectory()?(n.currentDirectory=s,C(e,`${n.currentDirectory}\r
15
+ `}async function ct(e){const n=e.outputPath||An(e.agentId,e.startedAt);return e.outputPath=n,await oe.mkdir(se.dirname(n),{recursive:!0}),await oe.writeFile(n,e.chunks.join(""),"utf-8"),n}function kn(e){return String(e??"").replace(/\r/g,`
16
+ `).trim()}function Cn(e=process.platform,n=process.env){const t=n.AWS_TERMINAL_OUTPUT_ENCODING?.trim();return t||(e==="win32"?hn:st)}function ut(e=Cn()){if(e!=="utf-8")try{return new ie(e,{fatal:!1})}catch{return new ie(st,{fatal:!1})}return En()}function En(){let e=null,n=null,t=null;const r=[];function s(o){try{return new ie(o,{fatal:!1})}catch{return new ie("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 le(e,n,t=!1){return t?e.decode():!n||n.length===0?"":e.decode(n,{stream:!0})}function Rn(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 $n(e){const n=J.get(e.sessionId);if(n)return n;const t={currentDirectory:e.workspacePath,runningProcess:null};return J.set(e.sessionId,t),t}function dt(e){for(const n of f.values())if(n.agentId===e)return n}async function wn(e){const n=T.get(e.providerId||"claude-code"),t=Z(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 Z(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 Dn(e,n=zt){return e.pid?await n(e.pid)?yt(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 Yr(e){try{ae(e)}catch(t){l.warn(`[cleanupSdkSessionByAgentId] clear debug mounts failed for agentId=${e}: ${t}`)}const n=dt(e);if(!n)l.info(`[cleanupSdkSessionByAgentId] No active SDK session found for agentId=${e}, cleaning residual state anyway`);else{const t=n.sessionId;return l.info(`[cleanupSdkSessionByAgentId] Cleaning up SDK session for agentId=${e}, sessionId=${t}`),M(t),f.delete(t),v(t),fe(t),H(t).catch(r=>{l.warn(`[cleanupSdkSessionByAgentId] Failed to remove persisted session for agentId=${e}: ${r}`)}),t}q.has(e)&&(q.delete(e),l.info(`[cleanupSdkSessionByAgentId] Released startingAgents lock for agentId=${e}`))}function fe(e){const n=J.get(e);if(!n?.runningProcess){J.delete(e);return}try{n.runningProcess.kill()}catch{}finally{n.runningProcess=null,J.delete(e)}}function C(e,n){n&&(e.seq+=1,K(e.agentId,n,e.sessionId,e.seq,void 0,{runtimeAccessToken:e.runtimeAccessToken,schedulerBaseUrl:e.schedulerBaseUrl}).catch(()=>{}))}function $e(e){return`\x1B[36m${e}>\x1B[0m `}function On(e,n){return n==="~"?Tt.homedir():se.resolve(e,n)}async function Pn(e,n,t){const r=Rn(t);if(r===void 0)return!1;if(r===null)return C(e,`${n.currentDirectory}\r
17
+ `),!0;const s=On(n.currentDirectory,r);try{return(await oe.stat(s)).isDirectory()?(n.currentDirectory=s,C(e,`${n.currentDirectory}\r
18
18
  `),!0):(C(e,`cd: not a directory: ${s}\r
19
19
  `),!0)}catch(o){const i=o instanceof Error?o.message:String(o);return C(e,`cd: ${i}\r
20
- `),!0}}async function Dn(e,n){const t=f.get(e);if(!t)throw new Error("SDK session not found");const r=Tn(n),s=Cn(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=F(r);if(C(t,`${we(s.currentDirectory)}${o}\r
20
+ `),!0}}async function Ln(e,n){const t=f.get(e);if(!t)throw new Error("SDK session not found");const r=kn(n),s=$n(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=F(r);if(C(t,`${$e(s.currentDirectory)}${o}\r
21
21
  `),Ue(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
22
- `),C(t,we(s.currentDirectory)),{started:!1,cwd:s.currentDirectory};if(await Rn(t,s,r))return{started:!1,cwd:s.currentDirectory};await $(t.agentId,e,"tool_using",{actionType:"bash",actionLabel:"\u7EC8\u7AEF\u547D\u4EE4",actionDetail:o},void 0,{runtimeAccessToken:t.runtimeAccessToken,schedulerBaseUrl:t.schedulerBaseUrl});const a=ht(r,{cwd:s.currentDirectory,shell:!0,env:dt(t.agentId,t.workspacePath,process.env,t.config.envOverrides)});s.runningProcess=a;const c=ct(),u=ct(),d=t.providerId==="acode",m={agentId:t.agentId,startedAt:new Date,chunks:[],spilled:!1};let p;const g=()=>{p&&(clearTimeout(p),p=void 0)},k=()=>{g(),p=setTimeout(()=>{s.runningProcess===a&&(C(t,An()),a.kill())},it)},E=(y,L=!0)=>{if(y&&(d&&m.chunks.push(y),d&&L&&k(),!(d&&m.spilled))){if(d&&In(m.chunks.join(""))>st){m.spilled=!0,at(m).then(_=>{C(t,hn(_))}).catch(_=>{const R=_ instanceof Error?_.message:String(_);C(t,`\r
23
- [ACode] \u547D\u4EE4\u8F93\u51FA\u843D\u76D8\u5931\u8D25: ${R}\r
22
+ `),C(t,$e(s.currentDirectory)),{started:!1,cwd:s.currentDirectory};if(await Pn(t,s,r))return{started:!1,cwd:s.currentDirectory};await $(t.agentId,e,"tool_using",{actionType:"bash",actionLabel:"\u7EC8\u7AEF\u547D\u4EE4",actionDetail:o},void 0,{runtimeAccessToken:t.runtimeAccessToken,schedulerBaseUrl:t.schedulerBaseUrl});const a=At(r,{cwd:s.currentDirectory,shell:!0,env:lt(t.agentId,t.workspacePath,process.env,t.config.envOverrides)});s.runningProcess=a;const c=ut(),u=ut(),d=t.providerId==="acode",m={agentId:t.agentId,startedAt:new Date,chunks:[],spilled:!1};let p;const g=()=>{p&&(clearTimeout(p),p=void 0)},k=()=>{g(),p=setTimeout(()=>{s.runningProcess===a&&(C(t,bn()),a.kill())},at)},E=(y,L=!0)=>{if(y&&(d&&m.chunks.push(y),d&&L&&k(),!(d&&m.spilled))){if(d&&Tn(m.chunks.join(""))>it){m.spilled=!0,ct(m).then(_=>{C(t,_n(_))}).catch(_=>{const w=_ instanceof Error?_.message:String(_);C(t,`\r
23
+ [ACode] \u547D\u4EE4\u8F93\u51FA\u843D\u76D8\u5931\u8D25: ${w}\r
24
24
  `)});return}C(t,y)}};return d&&k(),a.stdout.on("data",y=>{E(le(c,y))}),a.stderr.on("data",y=>{E(le(u,y))}),a.on("error",y=>{C(t,`\r
25
25
  [Terminal Error] ${y.message}\r
26
- `)}),a.on("close",(y,L)=>{g(),s.runningProcess=null,E(le(c,void 0,!0),!1),E(le(u,void 0,!0),!1),m.spilled&&at(m).catch(_=>{const R=_ instanceof Error?_.message:String(_);C(t,`\r
27
- [ACode] \u547D\u4EE4\u8F93\u51FA\u6700\u7EC8\u843D\u76D8\u5931\u8D25: ${R}\r
26
+ `)}),a.on("close",(y,L)=>{g(),s.runningProcess=null,E(le(c,void 0,!0),!1),E(le(u,void 0,!0),!1),m.spilled&&ct(m).catch(_=>{const w=_ instanceof Error?_.message:String(_);C(t,`\r
27
+ [ACode] \u547D\u4EE4\u8F93\u51FA\u6700\u7EC8\u843D\u76D8\u5931\u8D25: ${w}\r
28
28
  `)}),y&&y!==0?C(t,`\r
29
29
  [exit ${y}]\r
30
30
  `):L&&C(t,`\r
31
31
  [signal ${L}]\r
32
- `),C(t,we(s.currentDirectory)),$(t.agentId,e,"waiting_input",void 0,void 0,{runtimeAccessToken:t.runtimeAccessToken,schedulerBaseUrl:t.schedulerBaseUrl})}),{started:!0,cwd:s.currentDirectory}}function dt(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:${Ct()}`,String(o.ACODE_HOME||"").trim()||(o.ACODE_HOME=Ne()),S(e,je)!=="disabled"&&(o.AWS_LAUNCH_CONFIG_TOOLS=S(e,je)),S(e,Fe)!=="disabled"&&(o.AWS_HIRE_TOOLS=S(e,Fe)),S(e,Ke)!=="disabled"&&(o.AWS_PENCIL_TOOLS=S(e,Ke)),S(e,ve)!=="disabled"&&(o.AWS_DRAW_TOOLS=S(e,ve)),S(e,He)!=="disabled"&&(o.AWS_OFFICE_TOOLS=S(e,He)),S(e,qe)!=="disabled"&&(o.AWS_COLLABORATION_TASK_TOOLS=S(e,qe)),S(e,We)!=="disabled"&&(o.AWS_COLLABORATION_MEETING_TOOLS=S(e,We)),S(e,ze)!=="disabled"&&(o.AWS_COLLABORATION_DEBUG_TOOLS=S(e,ze)),S(e,Ge)!=="disabled"&&(o.AWS_COLLABORATION_FILE_HISTORY_TOOLS=S(e,Ge)),S(e,Ye)!=="disabled"&&(o.AWS_EMAIL_TOOLS=S(e,Ye)),S(e,Xe)!=="disabled"&&(o.AWS_ABILITY_MARKET_TOOLS=S(e,Xe)),S(e,Ve)!=="disabled"&&(o.AWS_ABILITY_DEV_TOOLS=S(e,Ve)),o}function On(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 Pn(e){const n=String(e);if(!Ue(n))return n;const t=On(n);return se.isAbsolute(t)?oe.readFile(t,"utf-8"):n}function lt(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 Ln(){try{return await $t().readClaudeCodeConfig()}catch(e){return console.warn(`[Runtime] Failed to read saved ClaudeCode AI config: ${e.message}`),{}}}function Mn(e){if(e==null)return;const t=(typeof e=="string"?e:JSON.stringify(e,null,2)).trim();if(t)return t.length<=Ze?t:`${t.slice(0,Ze)}
33
- ...\uFF08\u7ED3\u679C\u8FC7\u957F\uFF0C\u5DF2\u622A\u65AD\uFF09`}function Un(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 xn(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 Nn(e){if(e.type!=="tool_use_end")return;const n=Mn(e.data.toolResult??e.data.actionResult);if(!n)return;const t=Ce(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"))&&!Un(n))return}return r==="mcp"&&xn(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 Bn(e){if(e.type==="ai_request"){const n=e.data.model?` ${e.data.model}`:"",t=e.data.lastUserMessagePreview?`\uFF1A${e.data.lastUserMessagePreview}`:"";return`\r
32
+ `),C(t,$e(s.currentDirectory)),$(t.agentId,e,"waiting_input",void 0,void 0,{runtimeAccessToken:t.runtimeAccessToken,schedulerBaseUrl:t.schedulerBaseUrl})}),{started:!0,cwd:s.currentDirectory}}function lt(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:${Rt()}`,String(o.ACODE_HOME||"").trim()||(o.ACODE_HOME=Be()),S(e,Fe)!=="disabled"&&(o.AWS_LAUNCH_CONFIG_TOOLS=S(e,Fe)),S(e,ve)!=="disabled"&&(o.AWS_HIRE_TOOLS=S(e,ve)),S(e,Ke)!=="disabled"&&(o.AWS_PENCIL_TOOLS=S(e,Ke)),S(e,He)!=="disabled"&&(o.AWS_DRAW_TOOLS=S(e,He)),S(e,qe)!=="disabled"&&(o.AWS_OFFICE_TOOLS=S(e,qe)),S(e,We)!=="disabled"&&(o.AWS_COLLABORATION_TASK_TOOLS=S(e,We)),S(e,ze)!=="disabled"&&(o.AWS_COLLABORATION_MEETING_TOOLS=S(e,ze)),S(e,Ge)!=="disabled"&&(o.AWS_COLLABORATION_DEBUG_TOOLS=S(e,Ge)),S(e,Ye)!=="disabled"&&(o.AWS_COLLABORATION_FILE_HISTORY_TOOLS=S(e,Ye)),S(e,Xe)!=="disabled"&&(o.AWS_EMAIL_TOOLS=S(e,Xe)),S(e,Ve)!=="disabled"&&(o.AWS_ABILITY_MARKET_TOOLS=S(e,Ve)),S(e,Je)!=="disabled"&&(o.AWS_ABILITY_DEV_TOOLS=S(e,Je)),o}function Mn(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 xn(e){const n=String(e);if(!Ue(n))return n;const t=Mn(n);return se.isAbsolute(t)?oe.readFile(t,"utf-8"):n}function ft(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 Un(){try{return await wt().readClaudeCodeConfig()}catch(e){return console.warn(`[Runtime] Failed to read saved ClaudeCode AI config: ${e.message}`),{}}}function Nn(e){if(e==null)return;const t=(typeof e=="string"?e:JSON.stringify(e,null,2)).trim();if(t)return t.length<=et?t:`${t.slice(0,et)}
33
+ ...\uFF08\u7ED3\u679C\u8FC7\u957F\uFF0C\u5DF2\u622A\u65AD\uFF09`}function Bn(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 jn(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 Fn(e){if(e.type!=="tool_use_end")return;const n=Nn(e.data.toolResult??e.data.actionResult);if(!n)return;const t=Ce(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"))&&!Bn(n))return}return r==="mcp"&&jn(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 vn(e){if(e.type==="ai_request"){const n=e.data.model?` ${e.data.model}`:"",t=e.data.lastUserMessagePreview?`\uFF1A${e.data.lastUserMessagePreview}`:"";return`\r
34
34
  [ACode] \u6B63\u5728\u8BF7\u6C42\u6A21\u578B${n}${t}\r
35
35
  `}if(e.type==="text_delta"||e.type==="thinking"||e.type==="compaction_summary"||e.type==="command_output")return e.data.text||void 0;if(e.type==="error")return e.data.text?`\r
36
36
  [SDK Error] ${e.data.text}\r
37
- `:void 0}function jn(e){const n=vn(e);return{sourceEventType:e.type,logCategory:"acode",...Kn(e),...n?{logLevel:Fn(e),logMessage:n}:{}}}function Fn(e){return e.type==="error"?"error":e.type==="command_output"&&e.data.stream==="stderr"?"warn":"info"}function Kn(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 vn(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 ft(e,"\u5F00\u59CB");if(e.type==="tool_use_end")return ft(e,"\u5B8C\u6210");if(e.type==="command_output")return Wn(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 Hn=/\x1b\[[0-9;?]*[a-zA-Z]/g;function qn(e){return e.replace(Hn,"")}function Wn(e){const n=typeof e.data.stream=="string"?e.data.stream:"mixed",t=typeof e.data.sequence=="number"?` #${e.data.sequence}`:"",r=qn(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 ft(e,n){const t=Ce(e.data.toolName,e.data.toolInput),r=e.data.actionLabel||t.actionLabel||"\u8C03\u7528\u5DE5\u5177",s=mt(e,t);return s?`${n}${r}: ${s}`:`${n}${r}: ${e.data.actionDetail||e.data.toolName||"tool"}`}function mt(e,n){const t=e.data.toolInput;return n.actionType==="bash"?zn(t)||e.data.actionDetail||n.actionDetail:n.actionType==="read_file"||n.actionType==="edit_file"||n.actionType==="write_file"?Gn(t)||e.data.actionDetail||n.actionDetail:e.data.actionDetail||n.actionDetail}function zn(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?F(t):void 0}return $e(e?.args)}function Gn(e){const n=pt(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 F(n.trim());if(Array.isArray(n)){const t=pt(n)[0];if(t)return t}}}function pt(e){return Array.isArray(e)?e.map(n=>typeof n=="string"?n.trim():"").filter(Boolean).map(n=>F(n)):[]}function Yn(e){if(!(!e||Object.keys(e).length===0))try{const n=F(JSON.stringify(e,null,2));return n.length>8e3?`${n.slice(0,8e3)}
38
- ...\uFF08\u8F93\u5165\u53C2\u6570\u8FC7\u957F\uFF0C\u5DF2\u622A\u65AD\uFF09`:n}catch{return}}function Xn(e,n){return String(n||"").trim().toLowerCase()!=="waiting_input"?!1:e.type==="thinking"||e.type==="text_delta"}function Vn(e,n){if(!Xn(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=Ce(e.data.toolName,e.data.toolInput),r=mt(e,t),s=Yn(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,me=new Map,pe=new Map;async function Re(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 $(n.agentId,t,"tool_result",r,void 0,c,s,o)!==void 0)return;d<u-1&&await new Promise(p=>setTimeout(p,i*(d+1)))}l.warn(`[Runtime] ${a} tool_result sendStatus retry exhausted (result may be lost): agentId=${n.agentId}`)}const ee=new Map,Jn=20,Qn=500,Zn=3e4;async function ge(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);l.warn(`sendOutput attempt ${r+1}/${t+1} failed (${a}), retrying in ${c}ms...`),await new Promise(u=>setTimeout(u,c));continue}l.warn(`sendOutput failed after ${t+1} attempts (${a}), giving up to unblock serial queue`)}}}async function er(e,n,t,r,s,o){try{await v(e,n,t,r,{...s,sourceEventType:"compaction_summary",skipLocalPersist:!0},o)}catch(i){l.debug("Compaction summary realtime push failed (non-persisted)",{agentId:e,sessionId:t,error:i instanceof Error?i.message:String(i)})}}const ye=new Map,tr=120,nr=120;function rr(e,n,t,r){const s=`${n}:compaction_summary`;let o=ye.get(s);if(o||(o={buffer:"",timer:null,entry:e,sessionId:n,seq:r},ye.set(s,o)),o.buffer+=t,o.seq=r,o.entry=e,o.buffer.length>=tr){De(n);return}o.timer||(o.timer=setTimeout(()=>De(n),nr))}function De(e){const n=`${e}:compaction_summary`,t=ye.get(n);if(!t)return;t.timer&&(clearTimeout(t.timer),t.timer=null);const r=t.buffer;ye.delete(n),r&&er(t.entry.agentId,r,t.sessionId,t.seq,{sourceEventType:"compaction_summary",skipLocalPersist:!0},{runtimeAccessToken:t.entry.runtimeAccessToken,schedulerBaseUrl:t.entry.schedulerBaseUrl})}function Se(e,n){const t=n?`${e}:${n}`:void 0;let r,s;if(t)r=ee.get(t),s=t;else{const g=[];for(const[k,E]of ee)k.startsWith(e+":")&&E.buffer&&g.push(E.sourceEventType);for(const k of g)Se(e,k);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&&ee.delete(s);const u={sourceEventType:c,logCategory:"acode"},d={runtimeAccessToken:a.runtimeAccessToken,schedulerBaseUrl:a.schedulerBaseUrl},p=(U.get(e)??Promise.resolve()).then(()=>ge(g=>v(a.agentId,o,e,i,u,d,g)),()=>ge(g=>v(a.agentId,o,e,i,u,d,g)));U.set(e,p),p.finally(()=>{U.get(e)===p&&U.delete(e)})}function or(e,n){const t=Bn(e);if(!t)return;n.seq+=1;const r=n.seq,s=jn(e),o={runtimeAccessToken:n.runtimeAccessToken,schedulerBaseUrl:n.schedulerBaseUrl};if(e.type==="compaction_summary"){rr(n,e.sessionId,t,r);return}if((e.type==="command_output"||e.type==="text_delta"||e.type==="thinking")&&t.length<Jn){const c=`${e.sessionId}:${e.type}`;let u=ee.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,m=e.type;u.timer=setTimeout(()=>Se(d,m),Qn)}ee.set(c,u);return}Se(e.sessionId);const a=(U.get(e.sessionId)??Promise.resolve()).then(()=>ge(c=>v(n.agentId,t,e.sessionId,r,s,o,c)),()=>ge(c=>v(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 gt(e){return kt(e)}let yt=!1;function sr(){yt||(bt(T,ir),Ot(),yt=!0)}function ir(e,n){e.on("event",t=>{const r=f.get(t.sessionId);if(r){if(t.type==="tool_use_start"?zt(r.sessionId,t.data.toolUseId||t.data.actionId,t.data.toolInput,t.data.toolName,r.workspacePath):t.type==="tool_use_end"&&Wt(t,{sessionId:r.sessionId,agentId:r.agentId,workspacePath:r.workspacePath,providerId:r.providerId}),l.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==="compaction_summary"||t.type==="ai_request"||t.type==="error")){t.type==="runtime_capabilities"&&t.data.actionDetail&&(r.cachedCapabilitiesActionDetail=t.data.actionDetail);const i=Vn(t,r.currentRuntimeStatus);i&&$(r.agentId,t.sessionId,i.status,i.actionInfo,V(i.actionInfo),{runtimeAccessToken:r.runtimeAccessToken,schedulerBaseUrl:r.schedulerBaseUrl},t.timestamp?new Date(t.timestamp).getTime():void 0,t.type)}t.type==="context_compaction"&&De(t.sessionId),or(t,r);const o=Nn(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");Re(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=f.get(t);if(o){Se(t),r==="thinking"||r==="tool_using"||r==="compacting"?nn(t):M(t);const i=mn(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),l.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 m=gn({actionInfo:i.actionInfo,usage:V(i.actionInfo)}),p=m?void 0: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 k=(me.get(t)??Promise.resolve()).then(async()=>{for(let y=0;y<=2;y++){if(await $(o.agentId,t,i.status,p,V(i.actionInfo),{runtimeAccessToken:o.runtimeAccessToken,schedulerBaseUrl:o.schedulerBaseUrl})!==void 0)return;y<2&&(l.warn(`[${n.displayName}] compaction sendStatus attempt ${y+1} failed (HTTP), retrying in ${1e3*(y+1)}ms...`),await new Promise(_=>setTimeout(_,1e3*(y+1))))}l.warn(`[${n.displayName}] compaction sendStatus failed after 3 attempts, event may be lost`)}).catch(E=>{l.warn(`[${n.displayName}] compaction status chain error:`,E)});me.set(t,k),k.finally(()=>{me.get(t)===k&&me.delete(t)})}else{const g=d&&!i.actionInfo?.actionType||m;if(pn({status:i.status,actionInfo:i.actionInfo,restoredActionInfo:p,currentRuntimeActionType:o.currentRuntimeActionType,shouldPreservePrevAction:d})){const y=(pe.get(t)??Promise.resolve()).then(async()=>{for(let _=0;_<=2;_++){if(await $(o.agentId,t,i.status,g?void 0:p,V(i.actionInfo),{runtimeAccessToken:o.runtimeAccessToken,schedulerBaseUrl:o.schedulerBaseUrl})!==void 0)return;_<2&&await new Promise(W=>setTimeout(W,1e3*(_+1)))}l.warn(`[${n.displayName}] idle tool sendStatus failed after 3 attempts, status may be stale (frontend will fall back to timeline tool_use event)`)}).catch(L=>{l.warn(`[${n.displayName}] idle status chain error:`,L)});pe.set(t,y),y.finally(()=>{pe.get(t)===y&&pe.delete(t)})}else $(o.agentId,t,i.status,g?void 0:p,V(i.actionInfo),{runtimeAccessToken:o.runtimeAccessToken,schedulerBaseUrl:o.schedulerBaseUrl})}if(i.status==="waiting_input"&&o.cachedCapabilitiesActionDetail){const g=o.cachedCapabilitiesActionDetail;o.cachedCapabilitiesActionDetail=void 0,l.info(`[${n.displayName} Adapter] Re-sending cached runtime_capabilities for agent ${o.agentId} (session stabilized to waiting_input)`),$(o.agentId,t,"waiting_input",{actionType:"runtime_capabilities",actionLabel:"\u8FD0\u884C\u65F6\u80FD\u529B",actionDetail:g},void 0,{runtimeAccessToken:o.runtimeAccessToken,schedulerBaseUrl:o.schedulerBaseUrl})}}}),e.on("ask-user-question",t=>{const r=f.get(t.sessionId);r&&(l.info(`[${n.displayName} Adapter] AskUserQuestion for agent ${r.agentId}`),Gt(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=f.get(t.sessionId);r&&t.requestId&&(l.info(`[${n.displayName} Adapter] Tool permission request (${t.capability}) for agent ${r.agentId}`),Yt(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=f.get(t.sessionId);if(r){l.info(`[${n.displayName} Adapter] Permission request: ${t.toolName} for agent ${r.agentId}`);const s=t.toolInput?F(JSON.stringify(t.toolInput).slice(0,400)):void 0;$(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})}})}h.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()||Be(Qe(e))||void 0;if(Ft({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&&(Mt(String(t),e.body.runtimeFeatures),l.info(`[Runtime] agent ${t} \u542F\u52A8\u4E0B\u53D1\u80FD\u529B\u5F00\u5173: ${JSON.stringify(Bt(String(t)))}`)),e.body?.inheritedFeatures!==null&&e.body?.inheritedFeatures!==void 0&&(xt(String(t),e.body.inheritedFeatures),l.info(`[Runtime] agent ${t} \u542F\u52A8\u4E0B\u53D1\u7EE7\u627F\u4E09\u6001\u5C42: ${JSON.stringify(jt(String(t)))}`)),e.body?.capabilities!==void 0&&Ut(String(t),e.body.capabilities),e.body?.capabilitiesInherited!==void 0&&Nt(String(t),e.body.capabilitiesInherited),e.body?.envVars!==null&&e.body?.envVars!==void 0&&typeof e.body.envVars=="object"&&(Kt(String(t),e.body.envVars),l.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?.agentMeta!==void 0&&(vt(String(t),e.body.agentMeta),l.info(`[Runtime] agent ${t} \u4E0B\u53D1 agent \u5143\u4FE1\u606F: ${JSON.stringify(e.body.agentMeta)} \u2192 MCP \u4FDD\u7559\u952E\u6CE8\u5165`)),e.body?.changeCacheRetentionDays!==void 0&&(Rt(e.body.changeCacheRetentionDays),l.info(`[Runtime] agent ${t} \u4E0B\u53D1\u53D8\u66F4\u7F13\u5B58\u4FDD\u7559\u5929\u6570: ${e.body.changeCacheRetentionDays??"\u4E0D\u6E05\u7406"}`)),e.body?.logRetentionDays!==void 0){const i=Math.min(Number(e.body.logRetentionDays)||0,7);i>0&&(Lt(i),l.info(`[Runtime] agent ${t} \u4E0B\u53D1\u65E5\u5FD7\u4FDD\u7559\u5929\u6570: ${i}`))}s&&s!=="sdk"&&console.warn(`[Runtime] Unsupported runtime mode "${s}" requested for agent ${t}; starting SDK session instead.`),await ar(e,n)});async function ar(e,n){const{agentId:t,workspacePath:r,command:s,projectRoot:o,autoAccept:i=!0,initialPrompt:a,systemPrompt:c,globalPrompt:u,rolePrompt:d,memory:m,resumeContext:p,resumeTranscript:g,mcpConfigPath:k,extraMcpServers:E,envOverrides:y,idleInputAutoCommand:L,nonInputAutoCommand:_,model:R,instanceAiConfig:W,subAgentModel:Ie,subAgentEffort:he,scopeKey:Oe,browserAllowPrivate:Pe}=e.body||{},z=cn(g);l.info(`[HIBERNATE-IMPORT] \u542F\u52A8\u8BF7\u6C42\u643A\u5E26\u4F11\u7720\u6062\u590D: agentId=${String(t||"").trim()||"?"} resumeContext=${typeof p=="string"?`${p.length}\u5B57`:"\u65E0"} resumeTranscript\u539F\u59CB=${typeof g=="string"?`${g.length}\u5B57`:typeof g} \u89E3\u6790\u7ED3\u679C=${z?`${z.length}\u6761`:"null"}`);const G=en();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:W?ce(W):null,perAgentModel:R??null}});let w=null;const A=String(t||"").trim(),Ae=String(e.body?.runtimeAccessToken||"").trim()||void 0,B=String(e.body?.schedulerBaseUrl||"").trim()||String(e.header("x-bridge-tunnel-source")||"").trim()||Be(Qe(e))||void 0;B?l.info(`[startSdkSession] \u56DE\u8C03\u76EE\u6807 server: ${B} (agentId=${A})`):l.warn(`[startSdkSession] \u672A\u89E3\u6790\u5230 schedulerBaseUrl\uFF0C\u5C06\u56DE\u9000\u5230\u9ED8\u8BA4\u5730\u5740 (agentId=${A})`);try{if(sr(),!A){n.status(400).json({error:"agentId is required"});return}const j=ut(A);if(j){n.json(await En(j));return}const b=await Xt(A);if(b){const O=await wn(b);if(!O.reusable)console.warn(`[Runtime] Ignoring stale persisted SDK session for agentId=${A}, sessionId=${b.sessionId}, reason=${O.reason}`),await H(b.sessionId);else{const P=Z(b.runtimeStatus,b.runtimeStatus,b.runtimeActionType);n.json({sessionId:b.sessionId,status:P,runtimeStatus:P,runtimeActionType:b.runtimeActionType,runtimeActionLabel:b.runtimeActionLabel,runtimeActionDetail:b.runtimeActionDetail,agentId:b.agentId,workspacePath:b.workspacePath,command:b.command,mode:b.mode||"sdk",pid:b.pid,reused:!0,persistedOnly:!0});return}}if(q.has(A)){n.status(409).json({error:"SDK session is already starting for this agent"});return}q.add(A);const D=gt(s),St=T.get(D);w=_t();const It=D==="claude-code"?await Ln():null,te=lt(D==="claude-code"?It:null,y),Y=D==="acode"?R?String(R).trim():void 0:(()=>{const O=R?String(R).trim():void 0,P=te.model?String(te.model).trim():void 0;return O||P})();G.log({level:"info",category:"resolve",message:"\u6A21\u578B\u89E3\u6790\u7ED3\u679C",source:"bridge",agentId:A,sessionId:w??void 0,details:{perAgentModel:R??null,globalModel:te.model??null,resolvedModel:Y??null,providerId:D,note:D==="acode"?"adapter handles full priority":"request > global"}});const Te={...te.envOverrides};Y&&(Te.ANTHROPIC_MODEL=Y,Te.CODEX_MODEL=Y);let X,_e=k;if(D==="acode"){const O=W||{},P=await Pt({apiOverrides:rt(O)??void 0,agentId:A,sessionId:w??void 0,runtimeBridgeBaseUrl:B});X=P.instanceConfig.config,_e=P.perInstanceConfigPath,G.log({level:"info",category:"apply",message:"prepareAcodeInstanceConfig \u5B8C\u6210",source:"bridge",agentId:A,sessionId:w??void 0,details:{sanitizedApiOverrides:(()=>{const N=rt(O);return N?ce(N):null})(),resolvedInstanceAiConfig:X?ce(X):null,perInstanceConfigPath:_e,instanceConfigSources:P.instanceConfig.source??null}})}let Le=c||void 0,be,ke,ne;const re=typeof p=="string"&&p.trim()?Et(p):void 0;if(D==="acode")if(be=typeof u=="string"&&u.trim()||void 0,ke=typeof d=="string"&&d.trim()||void 0,typeof m=="string"&&m.trim())ne=m.trim();else{const O=await wt(r,{schedulerBaseUrl:B,runtimeAccessToken:Ae,agentId:A});O&&(ne=O,l.info(`[startSdkSession] Auto-loaded memories for ACode agent ${A}`))}else if(typeof u=="string"&&u.trim()||typeof d=="string"&&d.trim()||typeof m=="string"&&m.trim()||re!==void 0){const P=[u,d,m,re,c].filter(N=>typeof N=="string"&&N.trim().length>0).map(N=>N.trim());Le=P.length>0?P.join(`
37
+ `:void 0}function Kn(e){const n=Wn(e);return{sourceEventType:e.type,logCategory:"acode",...qn(e),...n?{logLevel:Hn(e),logMessage:n}:{}}}function Hn(e){return e.type==="error"?"error":e.type==="command_output"&&e.data.stream==="stderr"?"warn":"info"}function qn(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 Wn(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 mt(e,"\u5F00\u59CB");if(e.type==="tool_use_end")return mt(e,"\u5B8C\u6210");if(e.type==="command_output")return Yn(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 zn=/\x1b\[[0-9;?]*[a-zA-Z]/g;function Gn(e){return e.replace(zn,"")}function Yn(e){const n=typeof e.data.stream=="string"?e.data.stream:"mixed",t=typeof e.data.sequence=="number"?` #${e.data.sequence}`:"",r=Gn(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 mt(e,n){const t=Ce(e.data.toolName,e.data.toolInput),r=e.data.actionLabel||t.actionLabel||"\u8C03\u7528\u5DE5\u5177",s=pt(e,t);return s?`${n}${r}: ${s}`:`${n}${r}: ${e.data.actionDetail||e.data.toolName||"tool"}`}function pt(e,n){const t=e.data.toolInput;return n.actionType==="bash"?Xn(t)||e.data.actionDetail||n.actionDetail:n.actionType==="read_file"||n.actionType==="edit_file"||n.actionType==="write_file"?Vn(t)||e.data.actionDetail||n.actionDetail:e.data.actionDetail||n.actionDetail}function Xn(e){const n=we(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?F(t):void 0}return we(e?.args)}function Vn(e){const n=gt(e?.paths);return n.length>0?n.length===1?n[0]:`${n.length}\u4E2A\u6587\u4EF6: ${n.join(", ")}`:we(e?.file_path,e?.filePath,e?.path,e?.target_file,e?.targetFile)}function we(...e){for(const n of e){if(typeof n=="string"&&n.trim())return F(n.trim());if(Array.isArray(n)){const t=gt(n)[0];if(t)return t}}}function gt(e){return Array.isArray(e)?e.map(n=>typeof n=="string"?n.trim():"").filter(Boolean).map(n=>F(n)):[]}function Jn(e){if(!(!e||Object.keys(e).length===0))try{const n=F(JSON.stringify(e,null,2));return n.length>8e3?`${n.slice(0,8e3)}
38
+ ...\uFF08\u8F93\u5165\u53C2\u6570\u8FC7\u957F\uFF0C\u5DF2\u622A\u65AD\uFF09`:n}catch{return}}function Qn(e,n){return String(n||"").trim().toLowerCase()!=="waiting_input"?!1:e.type==="thinking"||e.type==="text_delta"}function Zn(e,n){if(!Qn(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=Ce(e.data.toolName,e.data.toolInput),r=pt(e,t),s=Jn(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 x=new Map,me=new Map,pe=new Map;async function De(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 $(n.agentId,t,"tool_result",r,void 0,c,s,o)!==void 0)return;d<u-1&&await new Promise(p=>setTimeout(p,i*(d+1)))}l.warn(`[Runtime] ${a} tool_result sendStatus retry exhausted (result may be lost): agentId=${n.agentId}`)}const ee=new Map,er=20,tr=500,nr=3e4;async function ge(e,n=nr,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);l.warn(`sendOutput attempt ${r+1}/${t+1} failed (${a}), retrying in ${c}ms...`),await new Promise(u=>setTimeout(u,c));continue}l.warn(`sendOutput failed after ${t+1} attempts (${a}), giving up to unblock serial queue`)}}}async function rr(e,n,t,r,s,o){try{await K(e,n,t,r,{...s,sourceEventType:"compaction_summary",skipLocalPersist:!0},o)}catch(i){l.debug("Compaction summary realtime push failed (non-persisted)",{agentId:e,sessionId:t,error:i instanceof Error?i.message:String(i)})}}const ye=new Map,or=120,sr=120;function ir(e,n,t,r){const s=`${n}:compaction_summary`;let o=ye.get(s);if(o||(o={buffer:"",timer:null,entry:e,sessionId:n,seq:r},ye.set(s,o)),o.buffer+=t,o.seq=r,o.entry=e,o.buffer.length>=or){Oe(n);return}o.timer||(o.timer=setTimeout(()=>Oe(n),sr))}function Oe(e){const n=`${e}:compaction_summary`,t=ye.get(n);if(!t)return;t.timer&&(clearTimeout(t.timer),t.timer=null);const r=t.buffer;ye.delete(n),r&&rr(t.entry.agentId,r,t.sessionId,t.seq,{sourceEventType:"compaction_summary",skipLocalPersist:!0},{runtimeAccessToken:t.entry.runtimeAccessToken,schedulerBaseUrl:t.entry.schedulerBaseUrl})}function Se(e,n){const t=n?`${e}:${n}`:void 0;let r,s;if(t)r=ee.get(t),s=t;else{const g=[];for(const[k,E]of ee)k.startsWith(e+":")&&E.buffer&&g.push(E.sourceEventType);for(const k of g)Se(e,k);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&&ee.delete(s);const u={sourceEventType:c,logCategory:"acode"},d={runtimeAccessToken:a.runtimeAccessToken,schedulerBaseUrl:a.schedulerBaseUrl},p=(x.get(e)??Promise.resolve()).then(()=>ge(g=>K(a.agentId,o,e,i,u,d,g)),()=>ge(g=>K(a.agentId,o,e,i,u,d,g)));x.set(e,p),p.finally(()=>{x.get(e)===p&&x.delete(e)})}function ar(e,n){const t=vn(e);if(!t)return;n.seq+=1;const r=n.seq,s=Kn(e),o={runtimeAccessToken:n.runtimeAccessToken,schedulerBaseUrl:n.schedulerBaseUrl};if(e.type==="compaction_summary"){ir(n,e.sessionId,t,r);return}if((e.type==="command_output"||e.type==="text_delta"||e.type==="thinking")&&t.length<er){const c=`${e.sessionId}:${e.type}`;let u=ee.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,m=e.type;u.timer=setTimeout(()=>Se(d,m),tr)}ee.set(c,u);return}Se(e.sessionId);const a=(x.get(e.sessionId)??Promise.resolve()).then(()=>ge(c=>K(n.agentId,t,e.sessionId,r,s,o,c)),()=>ge(c=>K(n.agentId,t,e.sessionId,r,s,o,c)));x.set(e.sessionId,a),a.finally(()=>{x.get(e.sessionId)===a&&x.delete(e.sessionId)})}function yt(e){return Et(e)}let St=!1;function cr(){St||(Ct(T,ur),Pt(),St=!0)}function ur(e,n){e.on("event",t=>{const r=f.get(t.sessionId);if(r){if(t.type==="tool_use_start"?Yt(r.sessionId,t.data.toolUseId||t.data.actionId,t.data.toolInput,t.data.toolName,r.workspacePath):t.type==="tool_use_end"&&Gt(t,{sessionId:r.sessionId,agentId:r.agentId,workspacePath:r.workspacePath,providerId:r.providerId}),l.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==="compaction_summary"||t.type==="ai_request"||t.type==="error")){t.type==="runtime_capabilities"&&t.data.actionDetail&&(r.cachedCapabilitiesActionDetail=t.data.actionDetail);const i=Zn(t,r.currentRuntimeStatus);i&&$(r.agentId,t.sessionId,i.status,i.actionInfo,V(i.actionInfo),{runtimeAccessToken:r.runtimeAccessToken,schedulerBaseUrl:r.schedulerBaseUrl},t.timestamp?new Date(t.timestamp).getTime():void 0,t.type)}t.type==="context_compaction"&&Oe(t.sessionId),ar(t,r);const o=Fn(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");De(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=f.get(t);if(o){Se(t),r==="thinking"||r==="tool_using"||r==="compacting"?sn(t):M(t);const i=yn(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),l.info(`[${n.displayName} Adapter] Status changed: ${i.status} for agent ${o.agentId}`,i.actionInfo||""),tn(t,{runtimeStatus:i.status,runtimeActionType:o.currentRuntimeActionType,runtimeActionLabel:o.currentRuntimeActionLabel,runtimeActionDetail:o.currentRuntimeActionDetail});const m=In({actionInfo:i.actionInfo,usage:V(i.actionInfo)}),p=m?void 0: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 k=(me.get(t)??Promise.resolve()).then(async()=>{for(let y=0;y<=2;y++){if(await $(o.agentId,t,i.status,p,V(i.actionInfo),{runtimeAccessToken:o.runtimeAccessToken,schedulerBaseUrl:o.schedulerBaseUrl})!==void 0)return;y<2&&(l.warn(`[${n.displayName}] compaction sendStatus attempt ${y+1} failed (HTTP), retrying in ${1e3*(y+1)}ms...`),await new Promise(_=>setTimeout(_,1e3*(y+1))))}l.warn(`[${n.displayName}] compaction sendStatus failed after 3 attempts, event may be lost`)}).catch(E=>{l.warn(`[${n.displayName}] compaction status chain error:`,E)});me.set(t,k),k.finally(()=>{me.get(t)===k&&me.delete(t)})}else{const g=d&&!i.actionInfo?.actionType||m;if(Sn({status:i.status,actionInfo:i.actionInfo,restoredActionInfo:p,currentRuntimeActionType:o.currentRuntimeActionType,shouldPreservePrevAction:d})){const y=(pe.get(t)??Promise.resolve()).then(async()=>{for(let _=0;_<=2;_++){if(await $(o.agentId,t,i.status,g?void 0:p,V(i.actionInfo),{runtimeAccessToken:o.runtimeAccessToken,schedulerBaseUrl:o.schedulerBaseUrl})!==void 0)return;_<2&&await new Promise(W=>setTimeout(W,1e3*(_+1)))}l.warn(`[${n.displayName}] idle tool sendStatus failed after 3 attempts, status may be stale (frontend will fall back to timeline tool_use event)`)}).catch(L=>{l.warn(`[${n.displayName}] idle status chain error:`,L)});pe.set(t,y),y.finally(()=>{pe.get(t)===y&&pe.delete(t)})}else $(o.agentId,t,i.status,g?void 0:p,V(i.actionInfo),{runtimeAccessToken:o.runtimeAccessToken,schedulerBaseUrl:o.schedulerBaseUrl})}if(i.status==="waiting_input"&&o.cachedCapabilitiesActionDetail){const g=o.cachedCapabilitiesActionDetail;o.cachedCapabilitiesActionDetail=void 0,l.info(`[${n.displayName} Adapter] Re-sending cached runtime_capabilities for agent ${o.agentId} (session stabilized to waiting_input)`),$(o.agentId,t,"waiting_input",{actionType:"runtime_capabilities",actionLabel:"\u8FD0\u884C\u65F6\u80FD\u529B",actionDetail:g},void 0,{runtimeAccessToken:o.runtimeAccessToken,schedulerBaseUrl:o.schedulerBaseUrl})}}}),e.on("ask-user-question",t=>{const r=f.get(t.sessionId);r&&(l.info(`[${n.displayName} Adapter] AskUserQuestion for agent ${r.agentId}`),Xt(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=f.get(t.sessionId);r&&t.requestId&&(l.info(`[${n.displayName} Adapter] Tool permission request (${t.capability}) for agent ${r.agentId}`),Vt(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=f.get(t.sessionId);if(r){l.info(`[${n.displayName} Adapter] Permission request: ${t.toolName} for agent ${r.agentId}`);const s=t.toolInput?F(JSON.stringify(t.toolInput).slice(0,400)):void 0;$(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})}})}h.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()||je(Ze(e))||void 0;if(Kt({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&&(xt(String(t),e.body.runtimeFeatures),l.info(`[Runtime] agent ${t} \u542F\u52A8\u4E0B\u53D1\u80FD\u529B\u5F00\u5173: ${JSON.stringify(jt(String(t)))}`)),e.body?.inheritedFeatures!==null&&e.body?.inheritedFeatures!==void 0&&(Nt(String(t),e.body.inheritedFeatures),l.info(`[Runtime] agent ${t} \u542F\u52A8\u4E0B\u53D1\u7EE7\u627F\u4E09\u6001\u5C42: ${JSON.stringify(Ft(String(t)))}`)),e.body?.capabilities!==void 0&&Ut(String(t),e.body.capabilities),e.body?.capabilitiesInherited!==void 0&&Bt(String(t),e.body.capabilitiesInherited),e.body?.envVars!==null&&e.body?.envVars!==void 0&&typeof e.body.envVars=="object"&&(Ht(String(t),e.body.envVars),l.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?.agentMeta!==void 0&&(qt(String(t),e.body.agentMeta),l.info(`[Runtime] agent ${t} \u4E0B\u53D1 agent \u5143\u4FE1\u606F: ${JSON.stringify(e.body.agentMeta)} \u2192 MCP \u4FDD\u7559\u952E\u6CE8\u5165`)),e.body?.changeCacheRetentionDays!==void 0&&(Dt(e.body.changeCacheRetentionDays),l.info(`[Runtime] agent ${t} \u4E0B\u53D1\u53D8\u66F4\u7F13\u5B58\u4FDD\u7559\u5929\u6570: ${e.body.changeCacheRetentionDays??"\u4E0D\u6E05\u7406"}`)),e.body?.snapshotRetentionDays!==void 0){const i=Re();Jt(e.body.snapshotRetentionDays),l.info(`[Runtime] agent ${t} \u4E0B\u53D1\u5FEB\u7167\u4FDD\u7559\u5929\u6570: ${e.body.snapshotRetentionDays??"\u4E0D\u6E05\u7406"}`),i!==Re()&&Lt(Re())}if(e.body?.logRetentionDays!==void 0){const i=Math.min(Number(e.body.logRetentionDays)||0,7);i>0&&(vt(i),l.info(`[Runtime] agent ${t} \u4E0B\u53D1\u65E5\u5FD7\u4FDD\u7559\u5929\u6570: ${i}`))}s&&s!=="sdk"&&console.warn(`[Runtime] Unsupported runtime mode "${s}" requested for agent ${t}; starting SDK session instead.`),await dr(e,n)});async function dr(e,n){const{agentId:t,workspacePath:r,command:s,projectRoot:o,autoAccept:i=!0,initialPrompt:a,systemPrompt:c,globalPrompt:u,rolePrompt:d,memory:m,resumeContext:p,resumeTranscript:g,mcpConfigPath:k,extraMcpServers:E,envOverrides:y,idleInputAutoCommand:L,nonInputAutoCommand:_,model:w,instanceAiConfig:W,subAgentModel:Ie,subAgentEffort:he,scopeKey:Pe,browserAllowPrivate:Le}=e.body||{},z=ln(g);l.info(`[HIBERNATE-IMPORT] \u542F\u52A8\u8BF7\u6C42\u643A\u5E26\u4F11\u7720\u6062\u590D: agentId=${String(t||"").trim()||"?"} resumeContext=${typeof p=="string"?`${p.length}\u5B57`:"\u65E0"} resumeTranscript\u539F\u59CB=${typeof g=="string"?`${g.length}\u5B57`:typeof g} \u89E3\u6790\u7ED3\u679C=${z?`${z.length}\u6761`:"null"}`);const G=rn();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:W?ce(W):null,perAgentModel:w??null}});let R=null;const A=String(t||"").trim(),Ae=String(e.body?.runtimeAccessToken||"").trim()||void 0,B=String(e.body?.schedulerBaseUrl||"").trim()||String(e.header("x-bridge-tunnel-source")||"").trim()||je(Ze(e))||void 0;B?l.info(`[startSdkSession] \u56DE\u8C03\u76EE\u6807 server: ${B} (agentId=${A})`):l.warn(`[startSdkSession] \u672A\u89E3\u6790\u5230 schedulerBaseUrl\uFF0C\u5C06\u56DE\u9000\u5230\u9ED8\u8BA4\u5730\u5740 (agentId=${A})`);try{if(cr(),!A){n.status(400).json({error:"agentId is required"});return}const j=dt(A);if(j){n.json(await wn(j));return}const b=await Qt(A);if(b){const O=await Dn(b);if(!O.reusable)console.warn(`[Runtime] Ignoring stale persisted SDK session for agentId=${A}, sessionId=${b.sessionId}, reason=${O.reason}`),await H(b.sessionId);else{const P=Z(b.runtimeStatus,b.runtimeStatus,b.runtimeActionType);n.json({sessionId:b.sessionId,status:P,runtimeStatus:P,runtimeActionType:b.runtimeActionType,runtimeActionLabel:b.runtimeActionLabel,runtimeActionDetail:b.runtimeActionDetail,agentId:b.agentId,workspacePath:b.workspacePath,command:b.command,mode:b.mode||"sdk",pid:b.pid,reused:!0,persistedOnly:!0});return}}if(q.has(A)){n.status(409).json({error:"SDK session is already starting for this agent"});return}q.add(A);const D=yt(s),It=T.get(D);R=kt();const ht=D==="claude-code"?await Un():null,te=ft(D==="claude-code"?ht:null,y),Y=D==="acode"?w?String(w).trim():void 0:(()=>{const O=w?String(w).trim():void 0,P=te.model?String(te.model).trim():void 0;return O||P})();G.log({level:"info",category:"resolve",message:"\u6A21\u578B\u89E3\u6790\u7ED3\u679C",source:"bridge",agentId:A,sessionId:R??void 0,details:{perAgentModel:w??null,globalModel:te.model??null,resolvedModel:Y??null,providerId:D,note:D==="acode"?"adapter handles full priority":"request > global"}});const Te={...te.envOverrides};Y&&(Te.ANTHROPIC_MODEL=Y,Te.CODEX_MODEL=Y);let X,_e=k;if(D==="acode"){const O=W||{},P=await Mt({apiOverrides:ot(O)??void 0,agentId:A,sessionId:R??void 0,runtimeBridgeBaseUrl:B});X=P.instanceConfig.config,_e=P.perInstanceConfigPath,G.log({level:"info",category:"apply",message:"prepareAcodeInstanceConfig \u5B8C\u6210",source:"bridge",agentId:A,sessionId:R??void 0,details:{sanitizedApiOverrides:(()=>{const N=ot(O);return N?ce(N):null})(),resolvedInstanceAiConfig:X?ce(X):null,perInstanceConfigPath:_e,instanceConfigSources:P.instanceConfig.source??null}})}let Me=c||void 0,be,ke,ne;const re=typeof p=="string"&&p.trim()?_t(p):void 0;if(D==="acode")if(be=typeof u=="string"&&u.trim()||void 0,ke=typeof d=="string"&&d.trim()||void 0,typeof m=="string"&&m.trim())ne=m.trim();else{const O=await $t(r,{schedulerBaseUrl:B,runtimeAccessToken:Ae,agentId:A});O&&(ne=O,l.info(`[startSdkSession] Auto-loaded memories for ACode agent ${A}`))}else if(typeof u=="string"&&u.trim()||typeof d=="string"&&d.trim()||typeof m=="string"&&m.trim()||re!==void 0){const P=[u,d,m,re,c].filter(N=>typeof N=="string"&&N.trim().length>0).map(N=>N.trim());Me=P.length>0?P.join(`
39
39
 
40
- `):void 0}const x={command:s||"acode",workingDirectory:r,agentId:A,...Oe?{scopeKey:Oe}:{},...typeof Pe=="boolean"?{browserAllowPrivate:Pe}:{},autoAccept:!!i,initialPrompt:a,systemPrompt:Le,...be!==void 0?{globalPrompt:be}:{},...ke!==void 0?{rolePrompt:ke}:{},...ne!==void 0?{memory:ne}:{},...re!==void 0?{resumeContext:re}:{},...D==="acode"&&Array.isArray(z)&&z.length>0?{resumeTranscript:z}:{},model:Y,mcpConfigPath:_e,...X?{instanceAiConfig:X}:{},...typeof Ie=="string"&&Ie.trim()?{subAgentModel:Ie.trim()}:{},...typeof he=="string"&&he.trim()?{subAgentEffort:he.trim()}:{},extraMcpServers:E||{},envOverrides:dt(String(t),String(r),process.env,Te,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?ce(x.instanceAiConfig):null,adapterMcpConfigPath:x.mcpConfigPath??null}}),await G.flush(),f.set(w,{agentId:A,workspacePath:r,sessionId:w,config:x,providerId:D,seq:0,runtimeAccessToken:Ae,schedulerBaseUrl:B}),n.json({sessionId:w,status:"starting",runtimeStatus:"starting",agentId:A,workspacePath:r,command:x.command,mode:"sdk"}),cr({sessionId:w,agentId:A,config:x,adapter:St,providerId:D,idleInputAutoCommand:L,nonInputAutoCommand:_,runtimeAccessToken:Ae,requestedSchedulerBaseUrl:B})}catch(j){if(w&&(M(w),f.delete(w),K(w)),A&&q.delete(A),!n.headersSent){const b=j instanceof Error?j.message:String(j);n.status(500).json({error:`Failed to start SDK session: ${b}`})}}}async function cr(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||xe,nonInputCommand:a||""});let d;if(ln(o))try{if(await new Promise(p=>setTimeout(p,500)),d=s.getSessionPid?.(n),!d){const g=(await Ht()).find(k=>k.agentId===t||k.cwd===r.workingDirectory||k.command.includes(r.workingDirectory));g&&(d=g.pid,l.info(`[Runtime] Found SDK process PID: ${d} for agentId=${t}`))}}catch(p){console.warn(`[Runtime] Failed to get SDK PID for agentId=${t}:`,p)}const m=Z(s.getSessionStatus(n),f.get(n)?.currentRuntimeStatus,f.get(n)?.currentRuntimeActionType);await Zt({sessionId:n,agentId:t,workspacePath:r.workingDirectory,command:r.command,startedAt:new Date().toISOString(),status:"running",runtimeStatus:m,mode:"sdk",pid:d,providerSessionId:s.getProviderSessionId(n)}),d&&await Ee().startProcess({agentId:t,sessionId:n,pid:d,mode:"sdk",workspacePath:r.workingDirectory,command:r.command}),await ur({agentId:t,sessionId:n,sdkPid:d,status:m,schedulerBaseUrl:u,runtimeAccessToken:c})}catch(d){M(n),f.delete(n),K(n),await H(n);const m=d instanceof Error?d.message:String(d);console.error(`[Runtime] Background SDK session startup failed for agentId=${t}: ${m}`),await dr({agentId:t,sessionId:n,schedulerBaseUrl:u,runtimeAccessToken:c,errorMessage:m})}finally{q.delete(t)}}async function ur(e){const{agentId:n,sessionId:t,sdkPid:r,status:s,schedulerBaseUrl:o,runtimeAccessToken:i}=e;if(!o||!i){l.debug(`[Runtime] notifyServerSessionReady skipped: missing schedulerBaseUrl or runtimeAccessToken for agentId=${n}`);return}const a=`${o.replace(/\/+$/,"")}/api/runtime/callback/status`;try{await Me.post(a,{agentId:n,sessionId:t,status:s,pid:r},{headers:{"X-Runtime-Token":i,"Content-Type":"application/json"},timeout:5e3}),l.debug(`[Runtime] Notified server session ready: agentId=${n}, sessionId=${t}, status=${s}`)}catch(c){const u=c instanceof Error?c.message:String(c);l.warn(`[Runtime] Failed to notify server session ready: agentId=${n}, error=${u}`)}}async function dr(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 Me.post(o,{agentId:n,sessionId:t,status:"stopped"},{headers:{"X-Runtime-Token":s,"Content-Type":"application/json"},timeout:5e3}),l.debug(`[Runtime] Notified server session failed: agentId=${n}, sessionId=${t}`)}catch(i){const a=i instanceof Error?i.message:String(i);l.warn(`[Runtime] Failed to notify server session failed: agentId=${n}, error=${a}`)}}h.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=f.get(t);if(!s){n.status(404).json({error:"SDK session not found"});return}try{const o=s.providerId||"claude-code";await T.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})}}),h.post("/sdk/answer",I,async(e,n)=>{const{sessionId:t,answers:r,cancelled:s,reason:o}=e.body||{},i=s===!0;if(!t||!i&&!r){n.status(400).json({error:i?"sessionId is required":"sessionId and answers are required"});return}const a=f.get(t);if(!a){n.status(404).json({error:"SDK session not found"});return}try{const c=a.providerId||"claude-code",u=T.get(c);if(i){if(!u.cancelQuestionAnswer){n.status(400).json({error:"adapter does not support cancelling a question"});return}l.debug(`[sdk/answer] cancel question: sessionId=${t}, providerId=${c}, hasReason=${!!String(o||"").trim()}`),await u.cancelQuestionAnswer(t,typeof o=="string"?o:void 0)}else u.sendQuestionAnswer&&await u.sendQuestionAnswer(t,r);n.json({ok:!0})}catch(c){const u=c instanceof Error?c.message:String(c);n.status(500).json({error:u})}}),h.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=f.get(t);if(!o){n.status(404).json({error:"SDK session not found"});return}try{const i=o.providerId||"claude-code",a=T.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})}}),h.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=f.get(t);if(!r){n.status(404).json({error:"SDK session not found"});return}try{const s=r.providerId||"claude-code",i=T.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})}}),h.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=f.get(t);if(!s){n.status(404).json({error:"SDK session not found"});return}try{const o=s.providerId||"claude-code";await T.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})}}),h.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=f.get(t);if(!r){n.status(404).json({error:"SDK session not found"});return}try{const s=r.providerId||"claude-code";await T.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})}}),h.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=f.get(t);if(!r){n.json({ok:!0,status:"stopped"});return}try{const s=r.providerId||"claude-code",o=T.get(s);o.abortCurrentTurn(t).catch(()=>{}),await o.terminateSession(t),M(t),f.delete(t),K(t),fe(t),ae(r.agentId),await H(t),await Ee().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(s){const o=s instanceof Error?s.message:String(s);n.status(500).json({error:o})}}),h.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=f.get(t);if(!r){n.status(404).json({error:"SDK session not found"});return}try{const s=r.providerId||"claude-code",o=T.get(s),i=o.getConversation(t),a=sn(i);let c=null;if(s==="acode"){const d=o;typeof d.exportRawTranscript!="function"?l.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&&l.warn(`[HIBERNATE-EXPORT] exportRawTranscript \u8FD4\u56DE\u7A7A \u2014 runtime \u53EF\u80FD\u672A\u5B8C\u6210 start() \u6216\u4E0D\u652F\u6301\u3002providerId=${s}`))}else l.info(`[HIBERNATE-EXPORT] provider=${s} \u4E0D\u652F\u6301\u5B8C\u6574\u91CD\u653E\uFF0C\u6309\u4EC5\u6458\u8981\u4F11\u7720`);const u=o.getTotalUsage?.(t);l.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})}}),h.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=f.get(t);if(!r){n.status(404).json({error:"SDK session not found"});return}try{const s=r.providerId||"claude-code",o=T.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})}}),h.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=f.get(t);if(!r){n.status(404).json({error:"SDK session not found"});return}try{const s=r.providerId||"claude-code",i=T.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})}}),h.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=f.get(t);if(!r){n.status(404).json({error:"SDK session not found"});return}try{const s=r.providerId||"claude-code",i=T.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})}}),h.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 Dn(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 lr(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
41
- ${e}`}h.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=f.get(t);if(!i){n.status(404).json({error:"SDK session not found"});return}try{const a=i.providerId||"claude-code",c=T.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,lr(await Pn(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})}}),h.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=[...f.values()].find(c=>c.agentId===o),a={idleInputCommand:String(r||"").trim()||xe,nonInputCommand:String(s||"")};try{let c=!1;i&&(T.get(i.providerId||"claude-code").setIdleCommands?.(i.sessionId,a),c=!0);const u=await Jt(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})}}),h.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(!f.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)})}),h.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=f.get(t);if(!s){n.status(404).json({error:"SDK session not found"});return}const o=s.providerId||"claude-code",i=T.get(o),a=i.resetContext?.bind(i),c=dn(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=Z(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})}}),h.post("/compact-context",I,async(e,n)=>{const{sessionId:t}=e.body||{};if(!t){n.status(400).json({ok:!1,error:"sessionId is required"});return}const r=f.get(t);if(!r){n.status(404).json({ok:!1,error:"SDK session not found"});return}const s=r.providerId||"claude-code",o=T.get(s),i=o.compactContext?.bind(o);if(!i){n.status(400).json({ok:!1,error:`context compaction is not supported by provider: ${s}`});return}try{const a=i(String(t)),c=Z(o.getSessionStatus(String(t)),r.currentRuntimeStatus,r.currentRuntimeActionType);n.json({ok:!0,requested:!0,compacted:!0,sessionId:t,agentId:r.agentId,mode:"sdk",providerId:s,status:c,runtimeStatus:c,result:a??null})}catch(a){const c=a instanceof Error?a.message:String(a);l.warn(`[Runtime] compact-context failed: sessionId=${t}, error=${c}`),n.status(500).json({ok:!1,compacted:!1,mode:"sdk",error:c})}}),h.post("/stop",I,async(e,n)=>{const{sessionId:t}=e.body||{},r=fn(e.body);if(!t){n.status(400).json({error:"sessionId is required"});return}const s=f.get(t);if(!s){await H(t),n.json({ok:!0,status:"stopped",mode:"none",statusNotified:!1,reason:r.reason});return}const o=s.agentId;try{l.info(`[Runtime] Stopping SDK session ${t}; suppressStatus=${!r.statusNotified}, reason=${r.reason||"unspecified"}`);const i=s.providerId||"claude-code",a=T.get(i);a.abortCurrentTurn(t).catch(()=>{}),await a.terminateSession(t),M(t),f.delete(t),K(t),fe(t),ae(o),await H(t),await Ee().removeProcess(o),r.statusNotified?await $(o,null,"stopped",void 0,void 0,{runtimeAccessToken:s.runtimeAccessToken,schedulerBaseUrl:s.schedulerBaseUrl}):l.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})}}),h.post("/stop-all",I,async(e,n)=>{const t=[],r=[];for(const[s,o]of f.entries())try{const i=o.providerId||"claude-code",a=T.get(i);a.abortCurrentTurn(s).catch(()=>{}),await a.terminateSession(s),M(s),f.delete(s),K(s),fe(s),ae(o.agentId),t.push(s),await $(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 Vt([]),l.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})}),h.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=Je.getLastN(t);n.json({ok:!0,count:r.length,entries:r})}),h.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=Je.getSinceIndex(t);n.json({ok:!0,entries:r.entries,nextIndex:r.nextIndex,oldestIndex:r.oldestIndex,dataLoss:r.oldestIndex>t+1})}),h.get("/events/push-stats",I,(e,n)=>{const t=Dt();n.json({ok:!0,count:t.length,agents:t})});export{Sn as buildAcodeCommandOutputPath,lt as buildClaudeCodeLaunchConfig,dt as buildRuntimeEnv,jn as buildSdkOutputMetadata,Nn as buildToolResultTimelineActionInfo,Hr as cleanupSdkSessionByAgentId,In as countTerminalOutputLines,ct as createTerminalOutputDecoder,le as decodeTerminalOutputChunk,rr as enqueueCompactionSummaryChunk,wn as evaluatePersistedSessionReuse,De as flushCompactionSummaryAccumulator,An as formatCommandInactivityTimeoutNotice,hn as formatCommandOutputSpilloverNotice,Bn as formatSdkOutputEvent,we as formatTerminalPrompt,pn as isIdleStatusChangeRetryable,gn as isUsageOnlyStatusChange,Tn as normalizeTerminalCommandInput,cn as parseResumeTranscript,fn as parseRuntimeStopOptions,kn as parseTerminalDirectoryChangeTarget,ge as raceSendOutputWithRetry,sn as renderSessionSnapshot,dn as resolveRuntimeContextResetSupport,Vn as resolveRuntimeStatusFromProviderEvent,Pn as resolveSdkInputMessage,gt as resolveSdkProviderId,Z as resolveSdkSessionDisplayStatus,mn as resolveStatusChangeRuntimeState,V as resolveStatusChangeUsage,_n as resolveTerminalOutputEncoding,f as sdkSessions,ln as shouldProbeSdkProcessPid,h as terminalRouter,lr as withSenderSignature};
40
+ `):void 0}const U={command:s||"acode",workingDirectory:r,agentId:A,...Pe?{scopeKey:Pe}:{},...typeof Le=="boolean"?{browserAllowPrivate:Le}:{},autoAccept:!!i,initialPrompt:a,systemPrompt:Me,...be!==void 0?{globalPrompt:be}:{},...ke!==void 0?{rolePrompt:ke}:{},...ne!==void 0?{memory:ne}:{},...re!==void 0?{resumeContext:re}:{},...D==="acode"&&Array.isArray(z)&&z.length>0?{resumeTranscript:z}:{},model:Y,mcpConfigPath:_e,...X?{instanceAiConfig:X}:{},...typeof Ie=="string"&&Ie.trim()?{subAgentModel:Ie.trim()}:{},...typeof he=="string"&&he.trim()?{subAgentEffort:he.trim()}:{},extraMcpServers:E||{},envOverrides:lt(String(t),String(r),process.env,Te,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:R,details:{adapterModel:U.model??null,adapterInstanceAiConfig:U.instanceAiConfig?ce(U.instanceAiConfig):null,adapterMcpConfigPath:U.mcpConfigPath??null}}),await G.flush(),f.set(R,{agentId:A,workspacePath:r,sessionId:R,config:U,providerId:D,seq:0,runtimeAccessToken:Ae,schedulerBaseUrl:B}),n.json({sessionId:R,status:"starting",runtimeStatus:"starting",agentId:A,workspacePath:r,command:U.command,mode:"sdk"}),lr({sessionId:R,agentId:A,config:U,adapter:It,providerId:D,idleInputAutoCommand:L,nonInputAutoCommand:_,runtimeAccessToken:Ae,requestedSchedulerBaseUrl:B})}catch(j){if(R&&(M(R),f.delete(R),v(R)),A&&q.delete(A),!n.headersSent){const b=j instanceof Error?j.message:String(j);n.status(500).json({error:`Failed to start SDK session: ${b}`})}}}async function lr(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||Ne,nonInputCommand:a||""});let d;if(pn(o))try{if(await new Promise(p=>setTimeout(p,500)),d=s.getSessionPid?.(n),!d){const g=(await Wt()).find(k=>k.agentId===t||k.cwd===r.workingDirectory||k.command.includes(r.workingDirectory));g&&(d=g.pid,l.info(`[Runtime] Found SDK process PID: ${d} for agentId=${t}`))}}catch(p){console.warn(`[Runtime] Failed to get SDK PID for agentId=${t}:`,p)}const m=Z(s.getSessionStatus(n),f.get(n)?.currentRuntimeStatus,f.get(n)?.currentRuntimeActionType);await nn({sessionId:n,agentId:t,workspacePath:r.workingDirectory,command:r.command,startedAt:new Date().toISOString(),status:"running",runtimeStatus:m,mode:"sdk",pid:d,providerSessionId:s.getProviderSessionId(n)}),d&&await Ee().startProcess({agentId:t,sessionId:n,pid:d,mode:"sdk",workspacePath:r.workingDirectory,command:r.command}),await fr({agentId:t,sessionId:n,sdkPid:d,status:m,schedulerBaseUrl:u,runtimeAccessToken:c})}catch(d){M(n),f.delete(n),v(n),await H(n);const m=d instanceof Error?d.message:String(d);console.error(`[Runtime] Background SDK session startup failed for agentId=${t}: ${m}`),await mr({agentId:t,sessionId:n,schedulerBaseUrl:u,runtimeAccessToken:c,errorMessage:m})}finally{q.delete(t)}}async function fr(e){const{agentId:n,sessionId:t,sdkPid:r,status:s,schedulerBaseUrl:o,runtimeAccessToken:i}=e;if(!o||!i){l.debug(`[Runtime] notifyServerSessionReady skipped: missing schedulerBaseUrl or runtimeAccessToken for agentId=${n}`);return}const a=`${o.replace(/\/+$/,"")}/api/runtime/callback/status`;try{await xe.post(a,{agentId:n,sessionId:t,status:s,pid:r},{headers:{"X-Runtime-Token":i,"Content-Type":"application/json"},timeout:5e3}),l.debug(`[Runtime] Notified server session ready: agentId=${n}, sessionId=${t}, status=${s}`)}catch(c){const u=c instanceof Error?c.message:String(c);l.warn(`[Runtime] Failed to notify server session ready: agentId=${n}, error=${u}`)}}async function mr(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 xe.post(o,{agentId:n,sessionId:t,status:"stopped"},{headers:{"X-Runtime-Token":s,"Content-Type":"application/json"},timeout:5e3}),l.debug(`[Runtime] Notified server session failed: agentId=${n}, sessionId=${t}`)}catch(i){const a=i instanceof Error?i.message:String(i);l.warn(`[Runtime] Failed to notify server session failed: agentId=${n}, error=${a}`)}}h.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=f.get(t);if(!s){n.status(404).json({error:"SDK session not found"});return}try{const o=s.providerId||"claude-code";await T.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})}}),h.post("/sdk/answer",I,async(e,n)=>{const{sessionId:t,answers:r,cancelled:s,reason:o}=e.body||{},i=s===!0;if(!t||!i&&!r){n.status(400).json({error:i?"sessionId is required":"sessionId and answers are required"});return}const a=f.get(t);if(!a){n.status(404).json({error:"SDK session not found"});return}try{const c=a.providerId||"claude-code",u=T.get(c);if(i){if(!u.cancelQuestionAnswer){n.status(400).json({error:"adapter does not support cancelling a question"});return}l.debug(`[sdk/answer] cancel question: sessionId=${t}, providerId=${c}, hasReason=${!!String(o||"").trim()}`),await u.cancelQuestionAnswer(t,typeof o=="string"?o:void 0)}else u.sendQuestionAnswer&&await u.sendQuestionAnswer(t,r);n.json({ok:!0})}catch(c){const u=c instanceof Error?c.message:String(c);n.status(500).json({error:u})}}),h.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=f.get(t);if(!o){n.status(404).json({error:"SDK session not found"});return}try{const i=o.providerId||"claude-code",a=T.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})}}),h.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=f.get(t);if(!r){n.status(404).json({error:"SDK session not found"});return}try{const s=r.providerId||"claude-code",i=T.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})}}),h.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=f.get(t);if(!s){n.status(404).json({error:"SDK session not found"});return}try{const o=s.providerId||"claude-code";await T.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})}}),h.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=f.get(t);if(!r){n.status(404).json({error:"SDK session not found"});return}try{const s=r.providerId||"claude-code";await T.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})}}),h.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=f.get(t);if(!r){n.json({ok:!0,status:"stopped"});return}try{const s=r.providerId||"claude-code",o=T.get(s);o.abortCurrentTurn(t).catch(()=>{}),await o.terminateSession(t),M(t),f.delete(t),v(t),fe(t),ae(r.agentId),await H(t),await Ee().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(s){const o=s instanceof Error?s.message:String(s);n.status(500).json({error:o})}}),h.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=f.get(t);if(!r){n.status(404).json({error:"SDK session not found"});return}try{const s=r.providerId||"claude-code",o=T.get(s),i=o.getConversation(t),a=un(i);let c=null;if(s==="acode"){const d=o;typeof d.exportRawTranscript!="function"?l.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&&l.warn(`[HIBERNATE-EXPORT] exportRawTranscript \u8FD4\u56DE\u7A7A \u2014 runtime \u53EF\u80FD\u672A\u5B8C\u6210 start() \u6216\u4E0D\u652F\u6301\u3002providerId=${s}`))}else l.info(`[HIBERNATE-EXPORT] provider=${s} \u4E0D\u652F\u6301\u5B8C\u6574\u91CD\u653E\uFF0C\u6309\u4EC5\u6458\u8981\u4F11\u7720`);const u=o.getTotalUsage?.(t);l.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})}}),h.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=f.get(t);if(!r){n.status(404).json({error:"SDK session not found"});return}try{const s=r.providerId||"claude-code",o=T.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})}}),h.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=f.get(t);if(!r){n.status(404).json({error:"SDK session not found"});return}try{const s=r.providerId||"claude-code",i=T.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})}}),h.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=f.get(t);if(!r){n.status(404).json({error:"SDK session not found"});return}try{const s=r.providerId||"claude-code",i=T.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})}}),h.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 Ln(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 pr(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
41
+ ${e}`}h.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=f.get(t);if(!i){n.status(404).json({error:"SDK session not found"});return}try{const a=i.providerId||"claude-code",c=T.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,pr(await xn(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})}}),h.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=[...f.values()].find(c=>c.agentId===o),a={idleInputCommand:String(r||"").trim()||Ne,nonInputCommand:String(s||"")};try{let c=!1;i&&(T.get(i.providerId||"claude-code").setIdleCommands?.(i.sessionId,a),c=!0);const u=await en(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})}}),h.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(!f.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)})}),h.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=f.get(t);if(!s){n.status(404).json({error:"SDK session not found"});return}const o=s.providerId||"claude-code",i=T.get(o),a=i.resetContext?.bind(i),c=mn(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=Z(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})}}),h.post("/compact-context",I,async(e,n)=>{const{sessionId:t}=e.body||{};if(!t){n.status(400).json({ok:!1,error:"sessionId is required"});return}const r=f.get(t);if(!r){n.status(404).json({ok:!1,error:"SDK session not found"});return}const s=r.providerId||"claude-code",o=T.get(s),i=o.compactContext?.bind(o);if(!i){n.status(400).json({ok:!1,error:`context compaction is not supported by provider: ${s}`});return}try{const a=i(String(t)),c=Z(o.getSessionStatus(String(t)),r.currentRuntimeStatus,r.currentRuntimeActionType);n.json({ok:!0,requested:!0,compacted:!0,sessionId:t,agentId:r.agentId,mode:"sdk",providerId:s,status:c,runtimeStatus:c,result:a??null})}catch(a){const c=a instanceof Error?a.message:String(a);l.warn(`[Runtime] compact-context failed: sessionId=${t}, error=${c}`),n.status(500).json({ok:!1,compacted:!1,mode:"sdk",error:c})}}),h.post("/stop",I,async(e,n)=>{const{sessionId:t}=e.body||{},r=gn(e.body);if(!t){n.status(400).json({error:"sessionId is required"});return}const s=f.get(t);if(!s){await H(t),n.json({ok:!0,status:"stopped",mode:"none",statusNotified:!1,reason:r.reason});return}const o=s.agentId;try{l.info(`[Runtime] Stopping SDK session ${t}; suppressStatus=${!r.statusNotified}, reason=${r.reason||"unspecified"}`);const i=s.providerId||"claude-code",a=T.get(i);a.abortCurrentTurn(t).catch(()=>{}),await a.terminateSession(t),M(t),f.delete(t),v(t),fe(t),ae(o),await H(t),await Ee().removeProcess(o),r.statusNotified?await $(o,null,"stopped",void 0,void 0,{runtimeAccessToken:s.runtimeAccessToken,schedulerBaseUrl:s.schedulerBaseUrl}):l.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})}}),h.post("/stop-all",I,async(e,n)=>{const t=[],r=[];for(const[s,o]of f.entries())try{const i=o.providerId||"claude-code",a=T.get(i);a.abortCurrentTurn(s).catch(()=>{}),await a.terminateSession(s),M(s),f.delete(s),v(s),fe(s),ae(o.agentId),t.push(s),await $(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 Zt([]),l.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})}),h.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=Qe.getLastN(t);n.json({ok:!0,count:r.length,entries:r})}),h.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=Qe.getSinceIndex(t);n.json({ok:!0,entries:r.entries,nextIndex:r.nextIndex,oldestIndex:r.oldestIndex,dataLoss:r.oldestIndex>t+1})}),h.get("/events/push-stats",I,(e,n)=>{const t=Ot();n.json({ok:!0,count:t.length,agents:t})});export{An as buildAcodeCommandOutputPath,ft as buildClaudeCodeLaunchConfig,lt as buildRuntimeEnv,Kn as buildSdkOutputMetadata,Fn as buildToolResultTimelineActionInfo,Yr as cleanupSdkSessionByAgentId,Tn as countTerminalOutputLines,ut as createTerminalOutputDecoder,le as decodeTerminalOutputChunk,ir as enqueueCompactionSummaryChunk,Dn as evaluatePersistedSessionReuse,Oe as flushCompactionSummaryAccumulator,bn as formatCommandInactivityTimeoutNotice,_n as formatCommandOutputSpilloverNotice,vn as formatSdkOutputEvent,$e as formatTerminalPrompt,Sn as isIdleStatusChangeRetryable,In as isUsageOnlyStatusChange,kn as normalizeTerminalCommandInput,ln as parseResumeTranscript,gn as parseRuntimeStopOptions,Rn as parseTerminalDirectoryChangeTarget,ge as raceSendOutputWithRetry,un as renderSessionSnapshot,mn as resolveRuntimeContextResetSupport,Zn as resolveRuntimeStatusFromProviderEvent,xn as resolveSdkInputMessage,yt as resolveSdkProviderId,Z as resolveSdkSessionDisplayStatus,yn as resolveStatusChangeRuntimeState,V as resolveStatusChangeUsage,Cn as resolveTerminalOutputEncoding,f as sdkSessions,pn as shouldProbeSdkProcessPid,h as terminalRouter,pr as withSenderSignature};
42
42
 
@@ -14,6 +14,8 @@ export declare class AgentPtyManager implements TerminalManager {
14
14
  kill(id: string): void;
15
15
 
16
16
  killByAgent(agentId: string): void;
17
+
18
+ listWaitingForInput(agentId: string): string[];
17
19
  resize(id: string, cols: number, rows: number): void;
18
20
 
19
21
  private touch;
@@ -1,5 +1,6 @@
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};
1
+ import{ptySessions as u,createPtySession as y,closePtySession as a,readPtyOutputBuffer as d}from"../routes/pty.js";const T=30*60*1e3,M=2e3,l=500;function p(c){const t=c.trimEnd();if(!t)return!1;const s=t.split(`
2
+ `).pop()??"";return!!(/[:?]\s*$/.test(s)||/\((?:yes\/no|Y\/N|y\/n)\)/i.test(s)||/\b[Yy]\/?[Nn]\b/.test(s)||/\(press RETURN\)/i.test(s)||/\(press ENTER\)/i.test(s)||/press ENTER[^]*continue/i.test(s))}function w(c){const t=d(c);if(!t)return"";const s=t.split(`
3
+ `);for(let e=s.length-1;e>=0;e-=1){const n=s[e]??"";if(n.trim())return n}return""}class I{constructor(){this.cursors=new Map,this.idleTimers=new Map}create(t){const s=t.shell&&t.shell.trim()?t.shell.trim():"auto",e=typeof t.cols=="number"&&t.cols>0?Math.min(t.cols,l):120,n=typeof t.rows=="number"&&t.rows>0?Math.min(t.rows,l):30,i=t.preCommand&&t.preCommand.trim()?t.preCommand:void 0,r=y({workspacePath:t.cwd,shell:s,cols:e,rows:n,preCommand:i,persistent:!0,ownerUserId:t.agentId}),o=u.get(r.id);return this.cursors.set(r.id,0),this.touch(r.id),{id:r.id,pid:o?.ptyProcess.pid}}write(t,s){const e=u.get(t);!e||e.status==="exited"||(e.ptyProcess.write(s.replace(/\n/g,"\r")),this.touch(t))}read(t,s){const e=u.get(t);if(!e)return{status:"closed",exit_code:null,output:"",needs_input:!1,truncated:!1};this.touch(t);const n=d(e),i=this.cursors.get(t)??0,r=i>=n.length?"":n.slice(i);this.cursors.set(t,n.length);const o=r.split(`
4
+ `),f=Math.min(Math.max(1,s.lines??200),M);let h=o,m=!1;o.length>f&&(h=o.slice(o.length-f),m=!0);const g=e.status==="running"&&p(r);return{status:e.status,exit_code:e.exitCode??null,output:h.join(`
5
+ `),needs_input:g,truncated:m}}kill(t){a(t,"agent-kill"),this.cursors.delete(t),this.clearIdle(t)}killByAgent(t){if(!t)return;const s=[];for(const[e,n]of u.entries())n.ownerUserId===t&&s.push(e);for(const e of s){try{a(e,`agent-stop:${t}`)}catch{}this.cursors.delete(e),this.clearIdle(e)}}listWaitingForInput(t){const s=[];for(const e of u.values())e.ownerUserId===t&&e.status==="running"&&p(w(e))&&s.push(e.id);return s}resize(t,s,e){const n=u.get(t);if(!n)return;const i=typeof s=="number"&&s>0?Math.min(s,l):120,r=typeof e=="number"&&e>0?Math.min(e,l):30;n.ptyProcess.resize(i,r)}touch(t){const s=this.idleTimers.get(t);s&&clearTimeout(s);const e=setTimeout(()=>{a(t,"agent-idle-timeout"),this.cursors.delete(t),this.idleTimers.delete(t)},T);e.unref?.(),this.idleTimers.set(t,e)}clearIdle(t){const s=this.idleTimers.get(t);s&&clearTimeout(s),this.idleTimers.delete(t)}}const _=new I;export{I as AgentPtyManager,_ as agentPtyManager,p as detectNeedsInput};
5
6
 
@@ -1,8 +1,8 @@
1
- import{promises as y}from"node:fs";import f from"node:path";import{resolveSchedulerBaseUrl as h}from"../config.js";import{getRuntimeAccessToken as d}from"./runtime-binding.js";import{createLogger as A}from"../utils/logger.js";const m=A("agent-startup-memory"),p=10;async function S(u,n){const e=[],i=f.join(u,".agentswork","memory");try{const s=(await y.readdir(i)).filter(r=>r.endsWith(".json")),t=await Promise.all(s.map(async r=>{try{const o=await y.readFile(f.join(i,r),"utf-8");return JSON.parse(o)}catch{return m.warn("[loadAgentStartupMemories] Failed to parse memory file: %s",f.join(i,r)),null}}));for(const r of t)if(r?.by_uri)for(const o of Object.values(r.by_uri)){const l=o.memory_type||"memory",g=(o.content||"").trim();g&&l==="instance_memory"&&e.push({title:o.title,content:g,uri:o.uri||""})}}catch{m.debug("[loadAgentStartupMemories] \u65E0\u6CD5\u8BFB\u53D6\u8BB0\u5FC6\u76EE\u5F55: %s",i)}if(e.length===0&&n?.schedulerBaseUrl&&n?.runtimeAccessToken&&n?.agentId){const c=`${n.schedulerBaseUrl.replace(/\/+$/,"")}/mcp/call`,s={"Content-Type":"application/json","X-Runtime-Token":n.runtimeAccessToken,Authorization:`Bearer ${n.runtimeAccessToken}`};try{const t=await fetch(c,{method:"POST",headers:s,body:JSON.stringify({tool:"list_memories",arguments:{agentId:n.agentId,memory_type:"instance_memory"}})});if(!t.ok)throw new Error(`Server returned ${t.status}`);const r=await t.json();if(Array.isArray(r))for(const o of r){const l=(o.content||"").trim();l&&e.push({title:o.title,content:l,uri:o.uri||""})}e.length>0&&m.info(`[loadAgentStartupMemories] Loaded ${e.length} instance memory(s) from server for ${n.agentId}`)}catch(t){m.warn("[loadAgentStartupMemories] \u4ECE server \u52A0\u8F7D instance_memory \u5931\u8D25: %s",t instanceof Error?t.message:String(t))}}e.sort((c,s)=>s.uri.localeCompare(c.uri));const a=[];if(e.length>0){const s=e.slice(0,p).map((t,r)=>`${t.title?`\u3010${t.title}\u3011`:`\u6761\u76EE ${r+1}`}
2
- ${t.content}`);a.push(`\u3010\u5B9E\u4F8B\u5373\u65F6\u8BB0\u5FC6\u3011
1
+ import{promises as g}from"node:fs";import p from"node:path";import{resolveSchedulerBaseUrl as y}from"../config.js";import{getRuntimeAccessToken as f}from"./runtime-binding.js";import{createLogger as A}from"../utils/logger.js";const m=A("agent-startup-memory"),d=10;async function S(u,n){const e=[],i=p.join(u,".agentswork","memory");try{const s=(await g.readdir(i)).filter(r=>r.endsWith(".json")),t=await Promise.all(s.map(async r=>{try{const o=await g.readFile(p.join(i,r),"utf-8");return JSON.parse(o)}catch{return m.warn("[loadAgentStartupMemories] Failed to parse memory file: %s",p.join(i,r)),null}}));for(const r of t)if(r?.by_uri)for(const o of Object.values(r.by_uri)){const l=o.memory_type||"memory",h=(o.content||"").trim();h&&l==="instance_hotspot_memory"&&e.push({title:o.title,content:h,uri:o.uri||""})}}catch{m.debug("[loadAgentStartupMemories] \u65E0\u6CD5\u8BFB\u53D6\u8BB0\u5FC6\u76EE\u5F55: %s",i)}if(e.length===0&&n?.schedulerBaseUrl&&n?.runtimeAccessToken&&n?.agentId){const c=`${n.schedulerBaseUrl.replace(/\/+$/,"")}/mcp/call`,s={"Content-Type":"application/json","X-Runtime-Token":n.runtimeAccessToken,Authorization:`Bearer ${n.runtimeAccessToken}`};try{const t=await fetch(c,{method:"POST",headers:s,body:JSON.stringify({tool:"list_memories",arguments:{agentId:n.agentId,memory_type:"instance_hotspot_memory"}})});if(!t.ok)throw new Error(`Server returned ${t.status}`);const r=await t.json();if(Array.isArray(r))for(const o of r){const l=(o.content||"").trim();l&&e.push({title:o.title,content:l,uri:o.uri||""})}e.length>0&&m.info(`[loadAgentStartupMemories] Loaded ${e.length} instance memory(s) from server for ${n.agentId}`)}catch(t){m.warn("[loadAgentStartupMemories] \u4ECE server \u52A0\u8F7D instance_hotspot_memory \u5931\u8D25: %s",t instanceof Error?t.message:String(t))}}e.sort((c,s)=>s.uri.localeCompare(c.uri));const a=[];if(e.length>0){const s=e.slice(0,d).map((t,r)=>`${t.title?`\u3010${t.title}\u3011`:`\u6761\u76EE ${r+1}`}
2
+ ${t.content}`);a.push(`\u3010\u5B9E\u4F8B\u70ED\u70B9\u8BB0\u5FC6\u3011
3
3
  ${s.join(`
4
4
 
5
- `)}`),e.length>p&&a.push(`... \u53CA\u53E6\u5916 ${e.length-p} \u6761\u5B9E\u4F8B\u5373\u65F6\u8BB0\u5FC6`)}if(a.length!==0)return a.join(`
5
+ `)}`),e.length>d&&a.push(`... \u53CA\u53E6\u5916 ${e.length-d} \u6761\u5B9E\u4F8B\u70ED\u70B9\u8BB0\u5FC6`)}if(a.length!==0)return a.join(`
6
6
 
7
- `)}function M(u,n){return async()=>{try{const{url:e}=h(),i=e?d(e)||d():d();return await S(u,{schedulerBaseUrl:e,runtimeAccessToken:i,agentId:n})??null}catch(e){return m.warn(`buildAgentStartupMemorySnapshot failed (memory refresh skipped): agentId=${n??"?"}, error=${e?.message}`),null}}}export{M as buildAgentStartupMemorySnapshot,S as loadAgentStartupMemories};
7
+ `)}function M(u,n){return async()=>{try{const{url:e}=y(),i=e?f(e)||f():f();return await S(u,{schedulerBaseUrl:e,runtimeAccessToken:i,agentId:n})??null}catch(e){return m.warn(`buildAgentStartupMemorySnapshot failed (memory refresh skipped): agentId=${n??"?"}, error=${e?.message}`),null}}}export{M as buildAgentStartupMemorySnapshot,S as loadAgentStartupMemories};
8
8
 
@@ -0,0 +1,36 @@
1
+
2
+ export declare const BRIDGE_TEMP_ROOT: string;
3
+
4
+ export declare const BRIDGE_TEMP_MAX_BYTES: number;
5
+
6
+ export declare function normalizeTempFileExtension(originalName: string): string;
7
+
8
+ export declare function decodePossiblyLatin1Utf8FileName(rawName: string): string;
9
+ export interface WriteBridgeTempFileParams {
10
+
11
+ originalName: string;
12
+
13
+ bytes: Buffer;
14
+
15
+ mediaType?: string;
16
+ }
17
+ export interface BridgeTempFileResult {
18
+
19
+ path: string;
20
+
21
+ name: string;
22
+
23
+ mediaType: string;
24
+
25
+ size: number;
26
+ }
27
+
28
+ export declare function writeBridgeTempFile(params: WriteBridgeTempFileParams): Promise<BridgeTempFileResult>;
29
+
30
+ export declare function resolveBridgeTempFilePath(rawPath: string): string | null;
31
+
32
+ export declare function readBridgeTempFile(rawPath: string): Promise<Buffer | null>;
33
+
34
+ export declare function deleteBridgeTempFile(rawPath: string): Promise<boolean>;
35
+
36
+ export declare function guessTempFileMediaType(filePath: string): string;
@@ -0,0 +1,2 @@
1
+ import{randomUUID as m}from"node:crypto";import{promises as a}from"node:fs";import f from"node:os";import n from"node:path";import{createLogger as d}from"../utils/logger.js";const s=d("bridge-temp-files"),p=n.join(f.tmpdir(),"aw-temp","ATT"),u=7,F=Number.POSITIVE_INFINITY;function g(r=new Date){const e=r.getFullYear(),t=String(r.getMonth()+1).padStart(2,"0"),i=String(r.getDate()).padStart(2,"0");return n.join(p,`${e}${t}${i}`)}async function x(){const r=Date.now()-u*24*60*60*1e3;try{const e=await a.readdir(p,{withFileTypes:!0});for(const t of e){if(!t.isDirectory())continue;const i=n.join(p,t.name);try{(await a.stat(i)).mtimeMs<r&&(await a.rm(i,{recursive:!0,force:!0}),s.info(`[bridge-temp-files] removed expired temp dir: ${i}`))}catch{}}}catch(e){const t=e;t.code!=="ENOENT"&&s.warn("[bridge-temp-files] cleanup expired dirs failed:",t)}}function w(r){const e=n.basename(c(r).replace(/\\/g,"/")),t=e.lastIndexOf(".");if(t<=0||t===e.length-1)return"";const o=e.slice(t+1).toLowerCase().replace(/[^a-z0-9]/g,"");return!o||o.length>16?"":`.${o}`}function c(r){const e=String(r||"");if(!/[\u00c0-\u00ff]/.test(e))return e;const t=Buffer.from(e,"latin1").toString("utf8");return!t||t.includes("\uFFFD")?e:t}async function b(r){const e=r.bytes;if(!e||e.length===0)throw new Error("file content is empty");const t=c(r.originalName),i=g();await a.mkdir(i,{recursive:!0});const o=n.join(i,`${m()}${w(t)}`);return await a.writeFile(o,e),x(),s.info(`[bridge-temp-files] wrote temp file: name=${t} path=${o} size=${e.length}`),{path:o.replace(/\\/g,"/"),name:t,mediaType:r.mediaType||"application/octet-stream",size:e.length}}function l(r){const e=String(r||"").trim();if(!e)return null;const t=n.resolve(e),i=n.resolve(p);return t!==i&&!t.startsWith(i+n.sep)?null:t}async function N(r){const e=l(r);if(!e)return null;try{return(await a.stat(e)).isFile()?await a.readFile(e):null}catch(t){const i=t;return i.code!=="ENOENT"&&s.warn("[bridge-temp-files] read temp file failed:",i),null}}async function D(r){const e=l(r);if(!e)return!1;try{return await a.rm(e,{force:!0}),!0}catch(t){return s.warn("[bridge-temp-files] delete temp file failed:",t),!1}}function I(r){const e=n.extname(r).toLowerCase();return{".txt":"text/plain",".md":"text/markdown",".json":"application/json",".csv":"text/csv",".xml":"application/xml",".html":"text/html",".pdf":"application/pdf",".png":"image/png",".jpg":"image/jpeg",".jpeg":"image/jpeg",".gif":"image/gif",".webp":"image/webp",".svg":"image/svg+xml",".zip":"application/zip",".gz":"application/gzip",".tar":"application/x-tar",".doc":"application/msword",".docx":"application/vnd.openxmlformats-officedocument.wordprocessingml.document",".xls":"application/vnd.ms-excel",".xlsx":"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",".ppt":"application/vnd.ms-powerpoint",".pptx":"application/vnd.openxmlformats-officedocument.presentationml.presentation"}[e]||"application/octet-stream"}export{F as BRIDGE_TEMP_MAX_BYTES,p as BRIDGE_TEMP_ROOT,c as decodePossiblyLatin1Utf8FileName,D as deleteBridgeTempFile,I as guessTempFileMediaType,w as normalizeTempFileExtension,N as readBridgeTempFile,l as resolveBridgeTempFilePath,b as writeBridgeTempFile};
2
+
@@ -65,3 +65,12 @@ export declare function deleteSnapshot(snapshotKey: string): Promise<{
65
65
  }>;
66
66
 
67
67
  export declare function getSnapshotRootPath(): string;
68
+ export interface SnapshotRetentionSweepResult {
69
+ retentionDays: number | null;
70
+ removedSnapshots: number;
71
+ removedDirs: number;
72
+ failures: number;
73
+ bytesFreed: number;
74
+ }
75
+
76
+ export declare function sweepExpiredSnapshots(retentionDays: number | null): Promise<SnapshotRetentionSweepResult>;
@@ -1,2 +1,2 @@
1
- import{createHash as b}from"node:crypto";import{promises as e}from"node:fs";import s from"node:path";import{getRuntimeHomeDir as M}from"../config.js";import{createLogger as U}from"../utils/logger.js";const p=U("file-snapshot-store");function T(){const t=String(process.env.AWS_RUNTIME_SNAPSHOT_ROOT||"").trim();return t||s.join(M(),".aws-bridge","snapshots")}function A(){const t=Number(process.env.AWS_RUNTIME_SNAPSHOT_TIMEOUT_MS);return Number.isFinite(t)&&t>=5e3?t:12e4}const C=new Set([".git","node_modules",".agentswork-snapshots","__pycache__",".cache",".next","target","dist",".idea",".vscode"]),B=Number(process.env.AWS_RUNTIME_SNAPSHOT_MAX_FILE_SIZE||50*1024*1024),v=Number(process.env.AWS_RUNTIME_SNAPSHOT_MAX_FILES||5e4);function E(t){return b("sha256").update(t).digest("hex").slice(0,16)}function x(t){return E(s.resolve(t))}function I(t,i,h){return s.join(t,i,h)}async function O(t,i,h,o){let n;try{n=await e.readdir(t,{withFileTypes:!0})}catch(r){const a=r;if(a.code==="ENOENT"||a.code==="EACCES")return;throw r}for(const r of n){if(h.length>=o){p.warn(`[FileSnapshot] \u6587\u4EF6\u6570\u5DF2\u8FBE\u4E0A\u9650 ${o}\uFF0C\u505C\u6B62\u904D\u5386`);return}if(C.has(r.name))continue;const a=s.join(t,r.name),d=s.relative(i,a);r.isDirectory()?await O(a,i,h,o):r.isFile()&&h.push(d)}}async function H(t){try{await e.unlink(t)}catch(i){if(i.code!=="ENOENT")throw i}}async function P(t,i){if(t!==i)try{(await e.readdir(t)).length===0&&(await e.rmdir(t),await P(s.dirname(t),i))}catch{}}async function K(t){const i=Date.now(),h=T(),o=s.resolve(String(t.workspacePath).trim()),n=x(o);try{if(!(await e.stat(o)).isDirectory())return{ok:!1,snapshotId:"",snapshotKey:"",fileCount:0,totalBytes:0,workspaceHash:n,error:"workspace path is not a directory"}}catch{return{ok:!1,snapshotId:"",snapshotKey:"",fileCount:0,totalBytes:0,workspaceHash:n,error:"workspace path does not exist"}}const r=t.snapshotId?.trim()||crypto.randomUUID(),a=t.snapshotName?.trim()||`snapshot-${new Date().toISOString()}`,d=t.triggerType?.trim()||"MANUAL",m=`${n}/${r}`,f=I(h,n,r),c=s.join(f,"files");try{await e.mkdir(c,{recursive:!0});const y=[];await O(o,o,y,v);const w={};let F=0,k=0;const g=A(),N=Date.now()+g;for(const $ of y){if(Date.now()>N){p.warn(`[FileSnapshot] \u5FEB\u7167\u8D85\u65F6 ${g}ms\uFF0C\u5DF2\u5907\u4EFD ${k}/${y.length} \u4E2A\u6587\u4EF6`);break}const u=s.join(o,$);try{const l=await e.stat(u);if(!l.isFile())continue;if(l.size>B){p.warn(`[FileSnapshot] \u8DF3\u8FC7\u5927\u6587\u4EF6: ${$} (${(l.size/1024/1024).toFixed(1)}MB)`);continue}const S=await e.readFile(u),_=E(S),D=s.join(c,_);try{await e.access(D)}catch{await e.writeFile(D,S)}w[$]={backupName:_,size:l.size,mtime:l.mtimeMs,mode:l.mode},F+=l.size,k++}catch(l){const S=l;if(S.code==="ENOENT"||S.code==="EACCES"){p.warn(`[FileSnapshot] \u8DF3\u8FC7\u4E0D\u53EF\u8BFB\u6587\u4EF6: ${$}`);continue}throw l}}await e.writeFile(s.join(f,"index.json"),JSON.stringify(w,null,2));const j={snapshotId:r,workspacePath:o,snapshotName:a,triggerType:d,createdAt:new Date().toISOString(),fileCount:k,totalBytes:F,workspaceHash:n};await e.writeFile(s.join(f,"meta.json"),JSON.stringify(j,null,2));const R=Date.now()-i;return p.info(`[FileSnapshot] \u521B\u5EFA\u5FEB\u7167\u5B8C\u6210: ${m}, ${k} files, ${(F/1024/1024).toFixed(1)}MB, ${R}ms`),{ok:!0,snapshotId:r,snapshotKey:m,fileCount:k,totalBytes:F,workspaceHash:n}}catch(y){const w=y;p.error(`[FileSnapshot] \u521B\u5EFA\u5FEB\u7167\u5931\u8D25: ${w.message}`);try{await e.rm(f,{recursive:!0,force:!0})}catch{}return{ok:!1,snapshotId:r,snapshotKey:m,fileCount:0,totalBytes:0,workspaceHash:n,error:w.message}}}async function G(t){const i=Date.now(),h=T(),o=s.resolve(String(t.workspacePath).trim()),n=t.preRestoreBackup!==!1,[r,a]=t.snapshotKey.split("/");if(!r||!a)return{ok:!1,filesRestored:0,filesDeleted:0,filesSkipped:0,error:"invalid snapshotKey format"};const d=I(h,r,a),m=s.join(d,"index.json");try{await e.access(m)}catch{return{ok:!1,filesRestored:0,filesDeleted:0,filesSkipped:0,error:`snapshot not found: ${t.snapshotKey}`}}try{let f;if(n)try{const u=await K({workspacePath:o,snapshotName:`pre-restore-guard-${a}`,triggerType:"AUTO_RESTORE_GUARD"});u.ok?(f=u.snapshotKey,p.info(`[FileSnapshot] \u8FD8\u539F\u524D\u5B89\u5168\u7F51\u5FEB\u7167: ${f}`)):p.warn(`[FileSnapshot] \u8FD8\u539F\u524D\u5B89\u5168\u7F51\u5FEB\u7167\u5931\u8D25: ${u.error}`)}catch(u){p.warn(`[FileSnapshot] \u8FD8\u539F\u524D\u5B89\u5168\u7F51\u5FEB\u7167\u5F02\u5E38: ${u.message}`)}const c=await e.readFile(m,"utf-8"),y=JSON.parse(c);await e.mkdir(o,{recursive:!0});const w=[];await O(o,o,w,v*2);const F=new Set(Object.keys(y));let k=0,g=0,N=0;for(const u of w)if(!F.has(u)){const l=s.join(o,u);await H(l),k++;const S=s.dirname(l);S!==o&&await P(S,o)}const j=A(),R=Date.now()+j;for(const[u,l]of Object.entries(y)){if(Date.now()>R){p.warn(`[FileSnapshot] \u8FD8\u539F\u8D85\u65F6 ${j}ms\uFF0C\u5DF2\u8FD8\u539F ${g} \u4E2A\u6587\u4EF6`);break}const S=s.join(o,u),_=s.join(d,"files",l.backupName);try{try{await e.access(_)}catch{p.warn(`[FileSnapshot] \u5907\u4EFD\u6587\u4EF6\u4E22\u5931\uFF0C\u8DF3\u8FC7: ${u}`),N++;continue}try{const D=await e.readFile(S);if(E(D)===l.backupName){N++;continue}}catch{}await e.mkdir(s.dirname(S),{recursive:!0}),await e.copyFile(_,S);try{await e.chmod(S,l.mode)}catch{}g++}catch(D){p.warn(`[FileSnapshot] \u8FD8\u539F\u6587\u4EF6\u5931\u8D25: ${u} - ${D.message}`),N++}}const $=Date.now()-i;return p.info(`[FileSnapshot] \u8FD8\u539F\u5B8C\u6210: ${t.snapshotKey}, restored=${g}, deleted=${k}, skipped=${N}, ${$}ms`),{ok:!0,filesRestored:g,filesDeleted:k,filesSkipped:N,preRestoreSnapshotKey:f}}catch(f){const c=f;return p.error(`[FileSnapshot] \u8FD8\u539F\u5FEB\u7167\u5931\u8D25: ${c.message}`),{ok:!1,filesRestored:0,filesDeleted:0,filesSkipped:0,error:c.message}}}async function q(t){const i=T(),h=s.resolve(String(t).trim()),o=x(h),n=s.join(i,o);try{await e.access(n)}catch{return[]}const r=await e.readdir(n,{withFileTypes:!0}),a=[];for(const d of r){if(!d.isDirectory())continue;const m=s.join(n,d.name,"meta.json");try{const f=await e.readFile(m,"utf-8"),c=JSON.parse(f);a.push({snapshotId:c.snapshotId,snapshotKey:`${o}/${c.snapshotId}`,snapshotName:c.snapshotName,triggerType:c.triggerType,createdAt:c.createdAt,fileCount:c.fileCount,totalBytes:c.totalBytes})}catch{p.warn(`[FileSnapshot] \u8DF3\u8FC7\u635F\u574F\u5FEB\u7167: ${d.name}`)}}return a.sort((d,m)=>new Date(m.createdAt).getTime()-new Date(d.createdAt).getTime()),a}async function Q(t){const i=T(),[h,o]=t.split("/");if(!h||!o)return{ok:!1,error:"invalid snapshotKey format"};const n=I(i,h,o);try{await e.access(n)}catch{return{ok:!1,error:`snapshot not found: ${t}`}}try{const r=await e.readFile(s.join(n,"index.json"),"utf-8"),a=JSON.parse(r),d=new Set(Object.values(a).map(f=>f.backupName));await e.rm(n,{recursive:!0,force:!0});const m=s.join(i,h);try{const f=await e.readdir(m,{withFileTypes:!0}),c=new Set;for(const w of f)if(w.isDirectory())try{const F=await e.readFile(s.join(m,w.name,"index.json"),"utf-8"),k=JSON.parse(F);for(const g of Object.values(k))c.add(g.backupName)}catch{}const y=s.join(n,"files");try{for(const w of d)c.has(w)||await H(s.join(y,w))}catch{}}catch{}return p.info(`[FileSnapshot] \u5220\u9664\u5FEB\u7167: ${t}`),{ok:!0}}catch(r){const a=r;return p.error(`[FileSnapshot] \u5220\u9664\u5FEB\u7167\u5931\u8D25: ${a.message}`),{ok:!1,error:a.message}}}function V(){return T()}export{K as createSnapshot,Q as deleteSnapshot,V as getSnapshotRootPath,q as listSnapshots,G as restoreSnapshot};
1
+ import{createHash as B}from"node:crypto";import{promises as e}from"node:fs";import o from"node:path";import{getRuntimeHomeDir as U}from"../config.js";import{createLogger as C}from"../utils/logger.js";const p=C("file-snapshot-store");function j(){const t=String(process.env.AWS_RUNTIME_SNAPSHOT_ROOT||"").trim();return t||o.join(U(),".aws-bridge","snapshots")}function I(){const t=Number(process.env.AWS_RUNTIME_SNAPSHOT_TIMEOUT_MS);return Number.isFinite(t)&&t>=5e3?t:12e4}const z=new Set([".git","node_modules",".agentswork-snapshots","__pycache__",".cache",".next","target","dist",".idea",".vscode"]),K=Number(process.env.AWS_RUNTIME_SNAPSHOT_MAX_FILE_SIZE||50*1024*1024),x=Number(process.env.AWS_RUNTIME_SNAPSHOT_MAX_FILES||5e4);function _(t){return B("sha256").update(t).digest("hex").slice(0,16)}function O(t){return _(o.resolve(t))}function E(t,s,c){return o.join(t,s,c)}async function A(t,s,c,r){let n;try{n=await e.readdir(t,{withFileTypes:!0})}catch(a){const h=a;if(h.code==="ENOENT"||h.code==="EACCES")return;throw a}for(const a of n){if(c.length>=r){p.warn(`[FileSnapshot] \u6587\u4EF6\u6570\u5DF2\u8FBE\u4E0A\u9650 ${r}\uFF0C\u505C\u6B62\u904D\u5386`);return}if(z.has(a.name))continue;const h=o.join(t,a.name),f=o.relative(s,h);a.isDirectory()?await A(h,s,c,r):a.isFile()&&c.push(f)}}async function b(t){try{await e.unlink(t)}catch(s){if(s.code!=="ENOENT")throw s}}async function H(t,s){if(t!==s)try{(await e.readdir(t)).length===0&&(await e.rmdir(t),await H(o.dirname(t),s))}catch{}}async function J(t){const s=Date.now(),c=j(),r=o.resolve(String(t.workspacePath).trim()),n=O(r);try{if(!(await e.stat(r)).isDirectory())return{ok:!1,snapshotId:"",snapshotKey:"",fileCount:0,totalBytes:0,workspaceHash:n,error:"workspace path is not a directory"}}catch{return{ok:!1,snapshotId:"",snapshotKey:"",fileCount:0,totalBytes:0,workspaceHash:n,error:"workspace path does not exist"}}const a=t.snapshotId?.trim()||crypto.randomUUID(),h=t.snapshotName?.trim()||`snapshot-${new Date().toISOString()}`,f=t.triggerType?.trim()||"MANUAL",u=`${n}/${a}`,i=E(c,n,a),l=o.join(i,"files");try{await e.mkdir(l,{recursive:!0});const y=[];await A(r,r,y,x);const w={};let g=0,S=0;const k=I(),$=Date.now()+k;for(const D of y){if(Date.now()>$){p.warn(`[FileSnapshot] \u5FEB\u7167\u8D85\u65F6 ${k}ms\uFF0C\u5DF2\u5907\u4EFD ${S}/${y.length} \u4E2A\u6587\u4EF6`);break}const m=o.join(r,D);try{const d=await e.stat(m);if(!d.isFile())continue;if(d.size>K){p.warn(`[FileSnapshot] \u8DF3\u8FC7\u5927\u6587\u4EF6: ${D} (${(d.size/1024/1024).toFixed(1)}MB)`);continue}const F=await e.readFile(m),v=_(F),N=o.join(l,v);try{await e.access(N)}catch{await e.writeFile(N,F)}w[D]={backupName:v,size:d.size,mtime:d.mtimeMs,mode:d.mode},g+=d.size,S++}catch(d){const F=d;if(F.code==="ENOENT"||F.code==="EACCES"){p.warn(`[FileSnapshot] \u8DF3\u8FC7\u4E0D\u53EF\u8BFB\u6587\u4EF6: ${D}`);continue}throw d}}await e.writeFile(o.join(i,"index.json"),JSON.stringify(w,null,2));const T={snapshotId:a,workspacePath:r,snapshotName:h,triggerType:f,createdAt:new Date().toISOString(),fileCount:S,totalBytes:g,workspaceHash:n};await e.writeFile(o.join(i,"meta.json"),JSON.stringify(T,null,2));const R=Date.now()-s;return p.info(`[FileSnapshot] \u521B\u5EFA\u5FEB\u7167\u5B8C\u6210: ${u}, ${S} files, ${(g/1024/1024).toFixed(1)}MB, ${R}ms`),{ok:!0,snapshotId:a,snapshotKey:u,fileCount:S,totalBytes:g,workspaceHash:n}}catch(y){const w=y;p.error(`[FileSnapshot] \u521B\u5EFA\u5FEB\u7167\u5931\u8D25: ${w.message}`);try{await e.rm(i,{recursive:!0,force:!0})}catch{}return{ok:!1,snapshotId:a,snapshotKey:u,fileCount:0,totalBytes:0,workspaceHash:n,error:w.message}}}async function V(t){const s=Date.now(),c=j(),r=o.resolve(String(t.workspacePath).trim()),n=t.preRestoreBackup!==!1,[a,h]=t.snapshotKey.split("/");if(!a||!h)return{ok:!1,filesRestored:0,filesDeleted:0,filesSkipped:0,error:"invalid snapshotKey format"};const f=E(c,a,h),u=o.join(f,"index.json");try{await e.access(u)}catch{return{ok:!1,filesRestored:0,filesDeleted:0,filesSkipped:0,error:`snapshot not found: ${t.snapshotKey}`}}try{let i;if(n)try{const m=await J({workspacePath:r,snapshotName:`pre-restore-guard-${h}`,triggerType:"AUTO_RESTORE_GUARD"});m.ok?(i=m.snapshotKey,p.info(`[FileSnapshot] \u8FD8\u539F\u524D\u5B89\u5168\u7F51\u5FEB\u7167: ${i}`)):p.warn(`[FileSnapshot] \u8FD8\u539F\u524D\u5B89\u5168\u7F51\u5FEB\u7167\u5931\u8D25: ${m.error}`)}catch(m){p.warn(`[FileSnapshot] \u8FD8\u539F\u524D\u5B89\u5168\u7F51\u5FEB\u7167\u5F02\u5E38: ${m.message}`)}const l=await e.readFile(u,"utf-8"),y=JSON.parse(l);await e.mkdir(r,{recursive:!0});const w=[];await A(r,r,w,x*2);const g=new Set(Object.keys(y));let S=0,k=0,$=0;for(const m of w)if(!g.has(m)){const d=o.join(r,m);await b(d),S++;const F=o.dirname(d);F!==r&&await H(F,r)}const T=I(),R=Date.now()+T;for(const[m,d]of Object.entries(y)){if(Date.now()>R){p.warn(`[FileSnapshot] \u8FD8\u539F\u8D85\u65F6 ${T}ms\uFF0C\u5DF2\u8FD8\u539F ${k} \u4E2A\u6587\u4EF6`);break}const F=o.join(r,m),v=o.join(f,"files",d.backupName);try{try{await e.access(v)}catch{p.warn(`[FileSnapshot] \u5907\u4EFD\u6587\u4EF6\u4E22\u5931\uFF0C\u8DF3\u8FC7: ${m}`),$++;continue}try{const N=await e.readFile(F);if(_(N)===d.backupName){$++;continue}}catch{}await e.mkdir(o.dirname(F),{recursive:!0}),await e.copyFile(v,F);try{await e.chmod(F,d.mode)}catch{}k++}catch(N){p.warn(`[FileSnapshot] \u8FD8\u539F\u6587\u4EF6\u5931\u8D25: ${m} - ${N.message}`),$++}}const D=Date.now()-s;return p.info(`[FileSnapshot] \u8FD8\u539F\u5B8C\u6210: ${t.snapshotKey}, restored=${k}, deleted=${S}, skipped=${$}, ${D}ms`),{ok:!0,filesRestored:k,filesDeleted:S,filesSkipped:$,preRestoreSnapshotKey:i}}catch(i){const l=i;return p.error(`[FileSnapshot] \u8FD8\u539F\u5FEB\u7167\u5931\u8D25: ${l.message}`),{ok:!1,filesRestored:0,filesDeleted:0,filesSkipped:0,error:l.message}}}async function Y(t){const s=j(),c=o.resolve(String(t).trim()),r=O(c),n=o.join(s,r);try{await e.access(n)}catch{return[]}const a=await e.readdir(n,{withFileTypes:!0}),h=[];for(const f of a){if(!f.isDirectory())continue;const u=o.join(n,f.name,"meta.json");try{const i=await e.readFile(u,"utf-8"),l=JSON.parse(i);h.push({snapshotId:l.snapshotId,snapshotKey:`${r}/${l.snapshotId}`,snapshotName:l.snapshotName,triggerType:l.triggerType,createdAt:l.createdAt,fileCount:l.fileCount,totalBytes:l.totalBytes})}catch{p.warn(`[FileSnapshot] \u8DF3\u8FC7\u635F\u574F\u5FEB\u7167: ${f.name}`)}}return h.sort((f,u)=>new Date(u.createdAt).getTime()-new Date(f.createdAt).getTime()),h}async function tt(t){const s=j(),[c,r]=t.split("/");if(!c||!r)return{ok:!1,error:"invalid snapshotKey format"};const n=E(s,c,r);try{await e.access(n)}catch{return{ok:!1,error:`snapshot not found: ${t}`}}try{const a=await e.readFile(o.join(n,"index.json"),"utf-8"),h=JSON.parse(a),f=new Set(Object.values(h).map(i=>i.backupName));await e.rm(n,{recursive:!0,force:!0});const u=o.join(s,c);try{const i=await e.readdir(u,{withFileTypes:!0}),l=new Set;for(const w of i)if(w.isDirectory())try{const g=await e.readFile(o.join(u,w.name,"index.json"),"utf-8"),S=JSON.parse(g);for(const k of Object.values(S))l.add(k.backupName)}catch{}const y=o.join(n,"files");try{for(const w of f)l.has(w)||await b(o.join(y,w))}catch{}}catch{}return p.info(`[FileSnapshot] \u5220\u9664\u5FEB\u7167: ${t}`),{ok:!0}}catch(a){const h=a;return p.error(`[FileSnapshot] \u5220\u9664\u5FEB\u7167\u5931\u8D25: ${h.message}`),{ok:!1,error:h.message}}}function et(){return j()}let M=Promise.resolve();async function P(t){let s=0,c;try{c=await e.readdir(t,{withFileTypes:!0})}catch{return 0}for(const r of c){const n=o.join(t,r.name);if(r.isDirectory())s+=await P(n);else if(r.isFile())try{s+=(await e.stat(n)).size}catch{}}return s}async function W(t){const s={retentionDays:t,removedSnapshots:0,removedDirs:0,failures:0,bytesFreed:0};if(t===null||t<=0)return s;const c=j(),r=Date.now()-t*24*60*60*1e3;let n;try{n=(await e.readdir(c)).filter(a=>!a.startsWith("."))}catch{return s}for(const a of n){const h=o.join(c,a);let f;try{f=(await e.readdir(h,{withFileTypes:!0})).filter(i=>i.isDirectory()).map(i=>i.name)}catch{continue}for(const u of f){const i=o.join(h,u);try{if((await e.stat(i)).mtimeMs>=r)continue;let y=!0;try{const w=await e.readFile(o.join(i,"meta.json"),"utf-8"),g=JSON.parse(w);if(g.createdAt){const S=Date.parse(g.createdAt);Number.isFinite(S)&&(y=S<r)}}catch{}if(!y)continue;s.bytesFreed+=await P(i),await e.rm(i,{recursive:!0,force:!0}),s.removedSnapshots++}catch(l){s.failures++,p.warn(`[FileSnapshot] \u6E05\u7406\u8FC7\u671F\u5FEB\u7167\u5931\u8D25: ${i} - ${l.message}`)}}try{(await e.readdir(h)).length===0&&(await e.rmdir(h),s.removedDirs++)}catch{}}return s.removedSnapshots>0&&p.info(`[FileSnapshot] \u5FEB\u7167\u6E05\u7406\u5B8C\u6210\uFF1A\u5220\u9664 ${s.removedSnapshots} \u4E2A\u8FC7\u671F\u5FEB\u7167\uFF0C\u91CA\u653E ${(s.bytesFreed/1024/1024).toFixed(1)} MB\uFF08\u4FDD\u7559 ${t} \u5929\uFF09`),s}function st(t){const s=M.then(()=>W(t));return M=s.then(()=>{},()=>{}),s.catch(c=>(p.warn(`[FileSnapshot] \u5FEB\u7167\u6E05\u7406\u5F02\u5E38: ${c.message}`),{retentionDays:t,removedSnapshots:0,removedDirs:0,failures:1,bytesFreed:0}))}export{J as createSnapshot,tt as deleteSnapshot,et as getSnapshotRootPath,Y as listSnapshots,V as restoreSnapshot,st as sweepExpiredSnapshots};
2
2
 
@@ -0,0 +1,12 @@
1
+
2
+ export interface GitIgnoreRule {
3
+ pattern: string;
4
+ negated: boolean;
5
+ directoryOnly: boolean;
6
+ anchored: boolean;
7
+ hasSlash: boolean;
8
+ }
9
+ export declare function parseGitIgnoreRules(content: string): GitIgnoreRule[];
10
+
11
+ export declare function loadGitIgnoreRules(rootPath: string): Promise<GitIgnoreRule[]>;
12
+ export declare function isIgnoredByGitIgnore(relativePath: string, isDirectory: boolean, rules: GitIgnoreRule[]): boolean;
@@ -0,0 +1,2 @@
1
+ import{promises as p}from"node:fs";import a from"node:path";function g(e){return String(e||"").split(/\r?\n/).map(t=>t.trim()).filter(t=>t&&!t.startsWith("#")).map(t=>{const r=t.startsWith("!"),n=r?t.slice(1).trim():t,s=n.startsWith("/"),o=n.endsWith("/"),c=n.replace(/^\/+/,"").replace(/\/+$/,"").replace(/\\/g,"/");return{pattern:c,negated:r,directoryOnly:o,anchored:s,hasSlash:c.includes("/")}}).filter(t=>t.pattern.length>0)}async function x(e){const t=[];let r=e;for(;;){try{const s=a.join(r,".gitignore"),o=await p.readFile(s,"utf8"),c=g(o);t.unshift(...c)}catch{}const n=a.dirname(r);if(n===r)break;r=n}return t}function R(e,t,r){const n=h(e);if(!n)return!1;let s=!1;for(const o of r)o.directoryOnly&&!t||u(n,o)&&(s=!o.negated);return s}function u(e,t){if(!t.hasSlash&&!t.anchored)return e.split("/").some(n=>f(n,t.pattern));const r=t.pattern;return t.anchored?i(e,r)||e.startsWith(r+"/"):i(e,r)||e.endsWith("/"+r)||e.includes("/"+r+"/")}function i(e,t){return new RegExp("^"+l(t)+"(?:/.*)?$").test(e)}function f(e,t){return new RegExp("^"+l(t)+"$").test(e)}function l(e){return e.replace(/[.+^${}()|[\]\\]/g,"\\$&").replace(/\*\*/g,".*").replace(/\*/g,"[^/]*").replace(/\?/g,"[^/]")}function h(e){return String(e||"").replace(/\\/g,"/").replace(/^\.\//,"").replace(/^\/+/,"").replace(/\/+$/,"")}export{R as isIgnoredByGitIgnore,x as loadGitIgnoreRules,g as parseGitIgnoreRules};
2
+