aws-runtime-bridge 1.9.137 → 1.9.140

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 (110) hide show
  1. package/dist/adapter/AcodeSdkAdapter.d.ts +4 -1
  2. package/dist/adapter/AcodeSdkAdapter.js +2 -2
  3. package/dist/adapter/ClaudeSdkAdapter.js +3 -3
  4. package/dist/adapter/CodexSdkAdapter.js +3 -3
  5. package/dist/adapter/OpencodeSdkAdapter.js +3 -3
  6. package/dist/browser/browser-pool.js +1 -1
  7. package/dist/browser/built-in-browser-tools.d.ts +1 -2
  8. package/dist/browser/built-in-browser-tools.js +1 -1
  9. package/dist/browser/ws-server.js +1 -1
  10. package/dist/config.d.ts +22 -6
  11. package/dist/config.js +2 -2
  12. package/dist/index.js +1 -1
  13. package/dist/middleware/auth.js +1 -1
  14. package/dist/remote-desktop/computer-control.d.ts +2 -2
  15. package/dist/remote-desktop/index.d.ts +1 -1
  16. package/dist/remote-desktop/index.js +2 -2
  17. package/dist/remote-desktop/screen-capture.js +1 -1
  18. package/dist/remote-desktop/session-manager.d.ts +2 -2
  19. package/dist/remote-desktop/session-manager.js +1 -1
  20. package/dist/remote-desktop/system-backend.js +3 -3
  21. package/dist/remote-desktop/types.d.ts +1 -1
  22. package/dist/remote-desktop/ui-automation.d.ts +2 -2
  23. package/dist/remote-desktop/ui-automation.js +5 -5
  24. package/dist/routes/ai-sources.js +1 -1
  25. package/dist/routes/background-tasks.js +5 -5
  26. package/dist/routes/browser-listeners.js +1 -1
  27. package/dist/routes/capabilities.js +1 -1
  28. package/dist/routes/dashboard.js +1 -1
  29. package/dist/routes/file-change-diff.js +3 -3
  30. package/dist/routes/file-diff-rollback.js +1 -1
  31. package/dist/routes/file-snapshot.js +1 -1
  32. package/dist/routes/git.js +20 -20
  33. package/dist/routes/instance.js +1 -1
  34. package/dist/routes/launch.js +1 -1
  35. package/dist/routes/mcp.js +1 -1
  36. package/dist/routes/plugins.js +1 -1
  37. package/dist/routes/properties.js +1 -1
  38. package/dist/routes/pty.d.ts +1 -1
  39. package/dist/routes/pty.js +1 -1
  40. package/dist/routes/runtime-binding.js +1 -1
  41. package/dist/routes/skills.js +1 -1
  42. package/dist/routes/sub-agents.js +1 -1
  43. package/dist/routes/task-context.js +1 -1
  44. package/dist/routes/terminal.js +27 -27
  45. package/dist/routes/yml.js +1 -1
  46. package/dist/services/access-control.js +1 -1
  47. package/dist/services/acode-bg-manager.js +1 -1
  48. package/dist/services/agent-capability-sync.js +1 -1
  49. package/dist/services/agent-process-manager.d.ts +1 -1
  50. package/dist/services/agent-process-manager.js +1 -1
  51. package/dist/services/ai-config-service.js +2 -2
  52. package/dist/services/ai-source-apply.d.ts +1 -1
  53. package/dist/services/auto-register.js +1 -1
  54. package/dist/services/aws-client-agent-mcp.d.ts +5 -0
  55. package/dist/services/aws-client-agent-mcp.js +2 -2
  56. package/dist/services/bridge-package-publish-hooks.js +1 -1
  57. package/dist/services/browser-session-manager.d.ts +3 -3
  58. package/dist/services/browser-session-manager.js +3 -3
  59. package/dist/services/capability-config.js +2 -2
  60. package/dist/services/cli-commands.js +2 -2
  61. package/dist/services/desktop-mcp-manager.js +1 -1
  62. package/dist/services/event-delta-pusher.d.ts +1 -1
  63. package/dist/services/fileSnapshotStore.js +1 -1
  64. package/dist/services/instance-ai-config-service.js +1 -1
  65. package/dist/services/instance-init-service.js +1 -1
  66. package/dist/services/instance-state.d.ts +1 -1
  67. package/dist/services/instance-state.js +1 -1
  68. package/dist/services/jdk-scanner.js +1 -1
  69. package/dist/services/launch-manager.js +1 -1
  70. package/dist/services/legacy-path-migration.d.ts +0 -2
  71. package/dist/services/legacy-path-migration.js +1 -1
  72. package/dist/services/lifecycle-state.js +2 -2
  73. package/dist/services/mcp-deploy.js +2 -2
  74. package/dist/services/orphan-monitor.js +1 -1
  75. package/dist/services/plugin-manager.d.ts +27 -5
  76. package/dist/services/plugin-manager.js +15 -9
  77. package/dist/services/process-detail.js +2 -2
  78. package/dist/services/process-detector.js +10 -10
  79. package/dist/services/process-registry.js +1 -1
  80. package/dist/services/process-top.js +2 -2
  81. package/dist/services/runtime-binding.js +4 -4
  82. package/dist/services/sdk-tool-file-change-recorder.js +1 -1
  83. package/dist/services/skill-manager.js +2 -2
  84. package/dist/services/startup-config-wizard.js +6 -6
  85. package/dist/services/system-metrics.js +1 -1
  86. package/dist/services/tunnel-client.js +1 -1
  87. package/dist/services/update-notifier.js +2 -2
  88. package/dist/services/windows-service-manager.js +1 -1
  89. package/dist/services/workspace-files.js +1 -1
  90. package/dist/services/workspaceTaskChangeWatcher.js +3 -3
  91. package/dist/utils/file-utils.js +2 -2
  92. package/dist/utils/instance-ai-config-debug-logger.js +1 -1
  93. package/dist/utils/mcp-utils.js +1 -1
  94. package/dist/utils/yaml-utils.js +1 -1
  95. package/package/acode/dist/cli.js +2 -2
  96. package/package/acode/dist/plugin-tools.js +3 -8
  97. package/package/acode/dist/plugin-types.d.ts +10 -0
  98. package/package/acode/dist/runtime.d.ts +4 -0
  99. package/package/acode/dist/runtime.js +18 -18
  100. package/package/acode/dist/types.d.ts +4 -0
  101. package/package/aws-client-agent-mcp/dist/http-client.js +1 -1
  102. package/package/aws-client-agent-mcp/dist/mcp-server.d.ts +0 -1
  103. package/package/aws-client-agent-mcp/dist/mcp-server.js +10 -10
  104. package/package/aws-client-agent-mcp/dist/memory-tools.js +6 -6
  105. package/package/aws-client-agent-mcp/dist/server-memory-store.d.ts +1 -1
  106. package/package/aws-client-agent-mcp/dist/server-memory-store.js +1 -1
  107. package/package/aws-client-agent-mcp/dist/status-reporter.d.ts +2 -0
  108. package/package/aws-client-agent-mcp/dist/status-reporter.js +3 -2
  109. package/package/aws-client-agent-mcp/dist/types.d.ts +1 -0
  110. package/package.json +1 -1
@@ -1,5 +1,5 @@
1
- import { type ClaudeCodeConfig, type CodexConfig, type OpenCodeConfig } from './ai-config-service.js';
2
1
  import type { ToolInstallStatus } from '../types.js';
2
+ import { type ClaudeCodeConfig, type CodexConfig, type OpenCodeConfig } from './ai-config-service.js';
3
3
  export interface AiSourceTemplateInput {
4
4
  baseUrl?: unknown;
5
5
  apiKey?: unknown;
@@ -1,2 +1,2 @@
1
- import{v4 as G}from"uuid";import A from"axios";import I from"node:os";import g from"node:fs";import{logger as i}from"../utils/logger.js";import{getActiveBridgeHttpPort as M,getAutoRegisterConfigFilePath as m,schedulerBaseUrl as d}from"../config.js";import{runExclusiveConfigWrite as z}from"../utils/config-write-queue.js";import{clearRuntimeBinding as J,clearScopedRuntimeAccessToken as Y,getRuntimeAccessToken as h,getRuntimeBindingPublicState as w,getScopedRuntimeAccessToken as q,loadRuntimeBinding as y,normalizeSchedulerBaseUrl as p,saveRuntimeBinding as K,saveScopedRuntimeAccessToken as C}from"./runtime-binding.js";const b={enabled:!1,serverUrl:d,preferSameLanIp:!0,maxRetries:3,retryInterval:2e3};let u={registered:!1,registrations:{}},P=[];function Ae(){return[...P]}const H=3e4;function W(){const e=Number(process.env.AWS_REGISTER_BACKGROUND_RETRY_INTERVAL);return Number.isFinite(e)&&e>0?e:H}const R=new Map;function L(e){const r=e.serverUrl||d,t=p(r)||r;if(R.has(t))return;const n=setTimeout(()=>{R.delete(t),V(e,t)},W());n.unref?.(),R.set(t,n)}async function V(e,r){try{const t=S().find(n=>(p(n.serverUrl||d)||n.serverUrl||d)===r)||e;await $(t,{backgroundRetry:!0})}catch(t){i.warn(`[AutoRegister] \u540E\u53F0\u91CD\u8BD5\u6CE8\u518C\u5F02\u5E38: ${t.message}`),L(e)}}function Ie(){for(const e of R.values())clearTimeout(e);R.clear()}function f(e){return e==null?void 0:String(e).trim()||void 0}function O(e){return p(e)}function T(e){if(typeof e=="boolean")return e;if(typeof e=="string"){const r=e.trim().toLowerCase();if(["true","1","yes","y"].includes(r))return!0;if(["false","0","no","n"].includes(r))return!1}}function x(e){if(e==null||e==="")return;const r=Number(e);return Number.isFinite(r)?r:void 0}function k(e){const r=f(e.serverUrl)||f(e.schedulerBaseUrl),t=f(e.connectionKey)||f(e.password);return{enabled:T(e.enabled),serverUrl:r,tenantId:f(e.tenantId),userKey:f(e.userKey),connectionKey:t,instanceName:f(e.instanceName),instanceId:f(e.instanceId),projectId:f(e.projectId),roleName:f(e.roleName),workspacePath:f(e.workspacePath),registerAddr:f(e.registerAddr),registerIp:f(e.registerIp),virtualIp:f(e.virtualIp),tunnel:T(e.tunnel),preferSameLanIp:T(e.preferSameLanIp),maxRetries:x(e.maxRetries),retryInterval:x(e.retryInterval)}}function j(){const e=m();try{if(!g.existsSync(e))return i.debug(`[AutoRegister] \u914D\u7F6E\u6587\u4EF6\u4E0D\u5B58\u5728: ${e}`),null;const r=g.readFileSync(e,"utf-8"),t=JSON.parse(r);return i.info(`[AutoRegister] \u4ECE\u914D\u7F6E\u6587\u4EF6\u52A0\u8F7D\u914D\u7F6E: ${e}`),k(t)}catch(r){const t=r;return i.warn(`[AutoRegister] \u8BFB\u53D6\u914D\u7F6E\u6587\u4EF6\u5931\u8D25: ${e}, error: ${t.message}`),null}}function X(){const e=m();try{if(!g.existsSync(e))return[];const r=g.readFileSync(e,"utf-8"),t=JSON.parse(r),n=k(t),o=Array.isArray(t.autoRegisterTargets)?t.autoRegisterTargets:[];return o.length===0?n.userKey?[n]:[]:o.filter(s=>!!(s&&typeof s=="object"&&!Array.isArray(s))).map(s=>{const a=k(s);return{...n,...a,connectionKey:a.connectionKey||n.connectionKey}})}catch(r){const t=r;return i.warn(`[AutoRegister] \u8BFB\u53D6\u81EA\u52A8\u6CE8\u518C\u76EE\u6807\u5931\u8D25: ${e}, error: ${t.message}`),[]}}function F(){const e={};return process.env.AWS_AUTO_REGISTER==="true"&&(e.enabled=!0),process.env.AWS_RUNTIME_SCHEDULER_BASE_URL&&(e.serverUrl=process.env.AWS_RUNTIME_SCHEDULER_BASE_URL),process.env.AWS_TENANT_ID&&(e.tenantId=process.env.AWS_TENANT_ID),process.env.AWS_USER_KEY&&(e.userKey=process.env.AWS_USER_KEY),process.env.AWS_BRIDGE_CONNECTION_KEY&&(e.connectionKey=process.env.AWS_BRIDGE_CONNECTION_KEY),process.env.AWS_INSTANCE_NAME&&(e.instanceName=process.env.AWS_INSTANCE_NAME),process.env.AWS_PROJECT_NAME&&(e.projectId=process.env.AWS_PROJECT_NAME),process.env.AWS_ROLE_NAME&&(e.roleName=process.env.AWS_ROLE_NAME),process.env.AWS_WORKSPACE_PATH&&(e.workspacePath=process.env.AWS_WORKSPACE_PATH),process.env.AWS_REGISTER_ADDR&&(e.registerAddr=process.env.AWS_REGISTER_ADDR),process.env.AWS_REGISTER_IP&&(e.registerIp=process.env.AWS_REGISTER_IP),process.env.AWS_VIRTUAL_IP&&(e.virtualIp=process.env.AWS_VIRTUAL_IP),process.env.AWS_PREFER_SAME_LAN_IP&&(e.preferSameLanIp=T(process.env.AWS_PREFER_SAME_LAN_IP)??!0),process.env.AWS_REGISTER_MAX_RETRIES&&(e.maxRetries=parseInt(process.env.AWS_REGISTER_MAX_RETRIES,10)),process.env.AWS_REGISTER_RETRY_INTERVAL&&(e.retryInterval=parseInt(process.env.AWS_REGISTER_RETRY_INTERVAL,10)),e}function U(){const e=j(),r=F(),t={...b,...e||{},...r},n=t.instanceName||I.hostname();let o=!1;return process.env.AWS_AUTO_REGISTER!==void 0?o=process.env.AWS_AUTO_REGISTER==="true":e&&(o=!0),{enabled:o,serverUrl:t.serverUrl||d,tenantId:t.tenantId||"",userKey:t.userKey||"",connectionKey:t.connectionKey,instanceName:n,instanceId:t.instanceId,projectId:t.projectId,roleName:t.roleName,workspacePath:t.workspacePath,registerAddr:t.registerAddr,registerIp:t.registerIp,virtualIp:t.virtualIp,tunnel:typeof t.tunnel=="boolean"?t.tunnel:void 0,preferSameLanIp:t.preferSameLanIp!==!1,maxRetries:t.maxRetries,retryInterval:t.retryInterval}}function S(){const e=X(),r=F(),n=(e.length>0?e:[j()||{}]).map(o=>{const s={...b,...o,...r};let a=!1;return process.env.AWS_AUTO_REGISTER!==void 0?a=process.env.AWS_AUTO_REGISTER==="true":a=e.length>0||!!s.userKey,{enabled:a,serverUrl:s.serverUrl||d,tenantId:s.tenantId||"",userKey:s.userKey||"",connectionKey:s.connectionKey,instanceName:s.instanceName||I.hostname(),instanceId:s.instanceId,projectId:s.projectId,roleName:s.roleName,workspacePath:s.workspacePath,registerAddr:s.registerAddr,registerIp:s.registerIp,virtualIp:s.virtualIp,tunnel:typeof s.tunnel=="boolean"?s.tunnel:void 0,preferSameLanIp:s.preferSameLanIp!==!1,maxRetries:s.maxRetries,retryInterval:s.retryInterval}});return P=n.map(o=>o.connectionKey).filter(o=>!!(o&&o.trim())),n}function Q(){const e=I.networkInterfaces(),r=[];for(const t of Object.keys(e)){const n=e[t];if(n)for(const o of n)o.family==="IPv4"&&!o.internal&&r.push({address:o.address,netmask:o.netmask,name:t})}return r}function N(e){const r=e.split(".").map(Number);return(r[0]<<24)+(r[1]<<16)+(r[2]<<8)+r[3]}function Z(e,r,t){const n=N(e),o=N(r),s=N(t);return(n&s)===(o&s)}function ee(e){try{const r=new URL(e);return r.hostname==="localhost"||r.hostname==="127.0.0.1"?"127.0.0.1":/^(\d{1,3}\.){3}\d{1,3}$/.test(r.hostname)?r.hostname:null}catch{return null}}function re(e){return e==="127.0.0.1"}function te(e){const r=Q();if(r.length===0)return i.warn("[AutoRegister] \u672A\u627E\u5230\u4EFB\u4F55\u975E\u5185\u90E8 IP \u5730\u5740\uFF0C\u4F7F\u7528 127.0.0.1"),"127.0.0.1";const t=ee(e);if(t){if(re(t))return"127.0.0.1";for(const n of r)if(Z(n.address,t,n.netmask))return i.info(`[AutoRegister] \u627E\u5230\u4E0E\u8C03\u5EA6\u4E2D\u5FC3\u540C\u5B50\u7F51\u7684 IP: ${n.address} (\u7F51\u5361: ${n.name}, \u5B50\u7F51\u63A9\u7801: ${n.netmask})`),n.address;i.warn(`[AutoRegister] \u672A\u627E\u5230\u4E0E\u8C03\u5EA6\u4E2D\u5FC3 (${t}) \u540C\u5B50\u7F51\u7684\u672C\u673A IP\uFF0C\u4F7F\u7528 127.0.0.1`)}else i.warn("[AutoRegister] \u65E0\u6CD5\u89E3\u6790\u8C03\u5EA6\u4E2D\u5FC3 IP\uFF0C\u4F7F\u7528 127.0.0.1");return"127.0.0.1"}function ne(e=d){return te(e)}function D(e){const r=e||U();return!r.enabled||!r.userKey?!1:r.tunnel===!0?!0:r.tunnel===!1?!1:!r.registerAddr&&!r.registerIp&&!r.virtualIp}function _(e){const r=M();if(D(e)){const s=e.serverUrl||d;try{const a=new URL(s);if(!e.instanceId)i.warn("[AutoRegister] \u96A7\u9053\u6A21\u5F0F\u4F46\u7F3A\u5C11 instanceId\uFF0C\u964D\u7EA7\u4E3A\u76F4\u8FDE\u6A21\u5F0F");else return`${a.protocol}//${a.host}/tunnel/${e.instanceId}`}catch{i.warn("[AutoRegister] serverUrl \u89E3\u6790\u5931\u8D25\uFF0C\u964D\u7EA7\u4E3A\u76F4\u8FDE\u6A21\u5F0F")}}const t=e.preferSameLanIp===!1?"127.0.0.1":ne(e.serverUrl||d),n=e.registerAddr||e.registerIp||e.virtualIp||t;return n?/^https?:\/\//i.test(n)?n:/:[0-9]+$/.test(n)?`http://${n}`:`http://${n}:${r}`:`http://127.0.0.1:${r}`}function v(){return S()[0]||U()}function Re(e){const r=String(e||"").trim();if(!r)return;const t=[];for(const o of S())o?.serverUrl&&t.push(o.serverUrl);const n=y();n.schedulerBaseUrl&&t.push(n.schedulerBaseUrl);for(const o of t){const s=q(o);if(s&&s===r)return p(o)}}function se(e){return e?Object.entries(u.registrations).find(([,t])=>t===e)?.[0]:void 0}function E(e,r){const t=se(r);if(t)return t;const n=f(e.serverUrl);if(n&&(n!==d||process.env.AWS_RUNTIME_SCHEDULER_BASE_URL))return n;const o=y(),s=f(o.schedulerBaseUrl);return o.status==="paired"&&s?s:n||d}async function oe(e){const r=e.instanceName||I.hostname(),t=e.serverUrl||d,n={tenantId:e.tenantId,userKey:e.userKey,instanceId:e.instanceId,instanceName:r,hostname:I.hostname(),virtualIp:e.registerAddr||e.registerIp||e.virtualIp,runtimeBridgeBaseUrl:_(e),connectionKey:e.connectionKey,workspacePath:e.workspacePath,projectId:e.projectId,roleName:e.roleName};return i.info(`[AutoRegister] \u6B63\u5728\u6CE8\u518C\u5B9E\u4F8B: ${r}`),i.info(`[AutoRegister] \u8C03\u5EA6\u4E2D\u5FC3: ${t}`),i.info(`[AutoRegister] \u7528\u6237 Key: ${e.userKey?"****"+e.userKey.slice(-4):"(\u672A\u8BBE\u7F6E)"}`),i.info(`[AutoRegister] \u79DF\u6237 ID: ${e.tenantId||"(\u81EA\u52A8\u63A8\u5BFC)"}`),(await A.post(`${t}/api/instances/register`,n,{headers:{"Content-Type":"application/json"},timeout:1e4})).data}function ie(e,r){const t=m();return z(t,()=>{if(!g.existsSync(t))return;const n=g.readFileSync(t,"utf-8"),o=JSON.parse(n),s=p(e);if(!s)return;let a=!1;const l=c=>{p(String(c.serverUrl||c.schedulerBaseUrl||""))===s&&r&&c.instanceId!==r&&(c.instanceId=r,a=!0)};if(Array.isArray(o.autoRegisterTargets))for(const c of o.autoRegisterTargets)c&&typeof c=="object"&&!Array.isArray(c)&&l(c);else l(o);a&&(g.writeFileSync(t,JSON.stringify(o,null,2),"utf-8"),i.info(`[AutoRegister] \u5DF2\u56DE\u5199 instanceId \u5230 config.json (serverUrl=${e})`))})}async function ae(e){const r=E(v(),e),t=y(),n=h(r);if(!n)throw new Error("runtimeAccessToken is required to unregister bridge instance");return(await A.post(`${r}/api/instances/unregister`,{instanceId:e},{headers:{"Content-Type":"application/json","X-Runtime-Token":n},timeout:1e4})).data}async function Se(e){const r=e?[{...U(),...e}]:S(),n=(r.length>1?await Promise.all(r.map(s=>$(s))):[await $(r[0]||U())]).every(Boolean),o=r.every(s=>!s.enabled||!s.userKey);if(!e&&(n||o)){const{stopTunnelClientsExcept:s}=await import("./tunnel-client.js");s(r.map(a=>a.serverUrl).filter(a=>!!a))}return n}async function $(e,r){if(!e.enabled)return i.info("[AutoRegister] \u81EA\u52A8\u6CE8\u518C\u672A\u542F\u7528"),i.info(`[AutoRegister] \u8981\u542F\u7528\u81EA\u52A8\u6CE8\u518C\uFF0C\u8BF7\u521B\u5EFA\u914D\u7F6E\u6587\u4EF6 ${m()} \u6216\u8BBE\u7F6E\u73AF\u5883\u53D8\u91CF AWS_AUTO_REGISTER=true`),!1;if(!e.userKey)return i.error("[AutoRegister] \u7F3A\u5C11\u7528\u6237 Key\uFF08\u5728\u914D\u7F6E\u6587\u4EF6\u4E2D\u8BBE\u7F6E userKey \u6216\u8BBE\u7F6E\u73AF\u5883\u53D8\u91CF AWS_USER_KEY\uFF09"),!1;const t=D(e);t&&!e.instanceId&&(e={...e,instanceId:`bridge-${G().replace(/-/g,"").slice(0,12)}`},i.info(`[AutoRegister] \u96A7\u9053\u6A21\u5F0F\uFF1A\u5DF2\u9884\u58F0\u660E instanceId=${e.instanceId}`));const n=r?.backgroundRetry?1:e.maxRetries??3,o=e.retryInterval??2e3;for(let s=1;s<=n;s++){try{u.lastAttempt=new Date;const a=await oe(e);if(a.success){if(u.registered=!0,u.instanceId=a.instanceId,a.instanceId&&(u.registrations[e.serverUrl||d]=a.instanceId),u.error=void 0,i.info("[AutoRegister] \u2713 \u6CE8\u518C\u6210\u529F\uFF01"),i.info(`[AutoRegister] \u5B9E\u4F8B ID: ${a.instanceId}`),i.info(`[AutoRegister] \u6D88\u606F: ${a.message}`),i.info(`[AutoRegister] \u66F4\u65B0: ${a.isUpdate?"\u662F":"\u5426"}`),a.runtimeAccessToken)try{const l=e.serverUrl||d;K({accessToken:a.runtimeAccessToken,instanceId:a.instanceId,userId:a.userId,schedulerBaseUrl:l});const c=p(a.serverUrl);c&&c!==p(l)&&(C({serverBaseUrl:c,accessToken:a.runtimeAccessToken}),i.info(`[AutoRegister] \u68C0\u6D4B\u5230 server \u4E0B\u53D1\u5730\u5740(${c})\u4E0E\u8FDE\u63A5\u5730\u5740(${l})\u4E0D\u540C\uFF0C\u5DF2\u6309\u4E24\u4E2A\u5730\u5740\u5206\u522B\u4FDD\u5B58 scoped token`)),i.info("[AutoRegister] \u5DF2\u4FDD\u5B58\u8C03\u5EA6\u4E2D\u5FC3\u4E0B\u53D1\u7684 runtime access token"),a.instanceId&&ie(e.serverUrl||d,a.instanceId).catch(B=>{i.warn(`[AutoRegister] \u56DE\u5199 instanceId \u5230 config.json \u5931\u8D25: ${B.message}`)})}catch(l){const c=l;return i.error(`[AutoRegister] \u4FDD\u5B58 runtime access token \u5931\u8D25: ${c.message}`),u.error=c.message,!1}else i.warn("[AutoRegister] \u6CE8\u518C\u54CD\u5E94\u672A\u5305\u542B runtime access token\uFF0CMCP \u5C06\u65E0\u6CD5\u8BBF\u95EE\u8C03\u5EA6\u4E2D\u5FC3\uFF0C\u8BF7\u68C0\u67E5 server \u7684 bridge \u5B9E\u4F8B token \u9881\u53D1\u903B\u8F91");if(t&&a.instanceId&&a.runtimeAccessToken){const{startTunnelClient:l}=await import("./tunnel-client.js"),c=e.serverUrl||d;l(c,a.instanceId),i.info(`[AutoRegister] \u96A7\u9053\u5BA2\u6237\u7AEF\u5DF2\u542F\u52A8: server=${c}, instanceId=${a.instanceId}`)}return!0}else i.warn(`[AutoRegister] \u6CE8\u518C\u5931\u8D25: ${a.message}`),u.error=a.message}catch(a){const l=a,c=l.response?.data?JSON.stringify(l.response.data):l.message;i.error(`[AutoRegister] \u6CE8\u518C\u8BF7\u6C42\u5931\u8D25 (\u5C1D\u8BD5 ${s}/${n}): ${c}`),u.error=c}s<n&&(i.info(`[AutoRegister] ${o/1e3} \u79D2\u540E\u91CD\u8BD5...`),await new Promise(a=>setTimeout(a,o)))}return r?.backgroundRetry?i.warn(`[AutoRegister] \u540E\u53F0\u91CD\u8BD5\u6CE8\u518C\u4ECD\u672A\u6210\u529F (server=${e.serverUrl||d}): ${u.error||"\u672A\u77E5"}`):(i.error("[AutoRegister] \u2717 \u6CE8\u518C\u5931\u8D25\uFF0C\u5DF2\u8FBE\u6700\u5927\u91CD\u8BD5\u6B21\u6570"),i.error("[AutoRegister] ========================================"),i.error("[AutoRegister] \u81EA\u52A8\u6CE8\u518C\u5DF2\u542F\u7528\u4F46\u6CE8\u518C\u5931\u8D25\uFF0C\u5B9E\u4F8B\u6682\u65F6\u65E0\u6CD5\u6B63\u5E38\u5DE5\u4F5C"),i.error("[AutoRegister] \u8BF7\u68C0\u67E5\u4EE5\u4E0B\u914D\u7F6E\uFF1A"),i.error(`[AutoRegister] - \u7528\u6237 Key (userKey): ${e.userKey?"****"+e.userKey.slice(-4):"(\u672A\u8BBE\u7F6E)"}`),i.error(`[AutoRegister] - \u79DF\u6237 ID (tenantId): ${e.tenantId||"(\u53EF\u9009\uFF0C\u5C06\u81EA\u52A8\u63A8\u5BFC)"}`),i.error(`[AutoRegister] - \u5B9E\u4F8B\u540D (instanceName): ${e.instanceName||"(\u4F7F\u7528\u4E3B\u673A\u540D)"}`),i.error(`[AutoRegister] - \u8C03\u5EA6\u4E2D\u5FC3\u5730\u5740: ${e.serverUrl||d}`),i.error(`[AutoRegister] - \u6700\u540E\u9519\u8BEF: ${u.error||"\u672A\u77E5"}`),i.error("[AutoRegister] ========================================"),i.error(`[AutoRegister] \u914D\u7F6E\u6765\u6E90\uFF1A${m()} \u6216\u73AF\u5883\u53D8\u91CF`),i.warn(`[AutoRegister] \u5C06\u5728\u540E\u53F0\u6301\u7EED\u91CD\u8BD5\u6CE8\u518C\uFF08\u6BCF ${Math.round(W()/1e3)} \u79D2\uFF09\uFF0C\u76F4\u5230\u4E0E\u8C03\u5EA6\u4E2D\u5FC3\u5EFA\u7ACB\u8FDE\u63A5`)),L(e),!1}async function ve(){const e=v();if(!e.userKey)return{success:!1,error:"userKey is required for runtime token refresh"};const r=w(),t=E(e),n=_(e);try{const o=await A.post(`${t}/api/instances/runtime-tokens/refresh`,{tenantId:e.tenantId,userKey:e.userKey,instanceId:r.instanceId,instanceName:e.instanceName,runtimeBridgeBaseUrl:n},{headers:{"Content-Type":"application/json"},timeout:1e4});if(!o.data.success||!o.data.runtimeAccessToken)return{success:!1,error:o.data.message||"scheduler did not return runtimeAccessToken"};const a=h()!==o.data.runtimeAccessToken;return K({accessToken:o.data.runtimeAccessToken,instanceId:r.instanceId,userId:o.data.userId||e.userKey,schedulerBaseUrl:t}),{success:!0,runtimeAccessToken:o.data.runtimeAccessToken,updated:a}}catch(o){const s=o;return{success:!1,error:s.response?.data?JSON.stringify(s.response.data):s.message}}}async function ye(e){const r=O(e);if(!r)return{success:!1,error:"serverUrl is required for runtime token refresh"};const t=S().find(s=>O(s.serverUrl)===r)||v();if(!t.userKey)return{success:!1,error:"userKey is required for runtime token refresh"};const n=w(),o=_(t);try{const s=await A.post(`${r}/api/instances/runtime-tokens/refresh`,{tenantId:t.tenantId,userKey:t.userKey,instanceId:n.instanceId,instanceName:t.instanceName,runtimeBridgeBaseUrl:o},{headers:{"Content-Type":"application/json"},timeout:1e4});if(!s.data.success||!s.data.runtimeAccessToken)return{success:!1,error:s.data.message||"scheduler did not return runtimeAccessToken"};const l=h(r)!==s.data.runtimeAccessToken;return C({serverBaseUrl:r,accessToken:s.data.runtimeAccessToken}),{success:!0,runtimeAccessToken:s.data.runtimeAccessToken,updated:l}}catch(s){const a=s;return{success:!1,error:a.response?.data?JSON.stringify(a.response.data):a.message}}}async function Te(){if(!u.registered||!u.instanceId)return i.info("[AutoRegister] \u5B9E\u4F8B\u672A\u6CE8\u518C\uFF0C\u65E0\u9700\u6CE8\u9500"),!0;try{const e=await ae(u.instanceId);if(e.success){i.info(`[AutoRegister] \u2713 \u6CE8\u9500\u6210\u529F: ${u.instanceId}`);const r=E(v(),u.instanceId);y().schedulerBaseUrl&&Y(r),J();try{const{stopTunnelClientForServer:n}=await import("./tunnel-client.js");n(r)}catch(n){i.warn(`[AutoRegister] \u6CE8\u9500\u540E\u505C\u6B62\u96A7\u9053\u5931\u8D25: ${n.message}`)}return u.registered=!1,u.instanceId=void 0,!0}else return i.warn(`[AutoRegister] \u6CE8\u9500\u5931\u8D25: ${e.message}`),!1}catch(e){const r=e;return i.error(`[AutoRegister] \u6CE8\u9500\u8BF7\u6C42\u5931\u8D25: ${r.message}`),!1}}function Ue(){return{...u}}function _e(){return u.registered}function Ee(){return u.instanceId}async function he(){const e=v(),r=u.instanceId,t=E(e,r),n={};if(r&&(n.instanceId=r),e.enabled&&(n.runtimeBridgeBaseUrl=_(e)),!n.instanceId&&!n.runtimeBridgeBaseUrl)return i.info("[AutoRegister] Bridge \u91CD\u542F\u6E05\u7406\uFF1A\u6CA1\u6709 instanceId \u6216 runtimeBridgeBaseUrl\uFF0C\u8DF3\u8FC7\u6E05\u7406"),{success:!0,agentCount:0};try{i.info("[AutoRegister] Bridge \u91CD\u542F\u6E05\u7406\uFF1A\u6B63\u5728\u901A\u77E5\u8C03\u5EA6\u4E2D\u5FC3..."),i.info(`[AutoRegister] instanceId: ${n.instanceId||"(\u65E0)"}`),i.info(`[AutoRegister] runtimeBridgeBaseUrl: ${n.runtimeBridgeBaseUrl||"(\u65E0)"}`);const o=await A.post(`${t}/api/instances/bridge-restart-cleanup`,n,{headers:{"Content-Type":"application/json"},timeout:1e4});return o.data.success?(i.info(`[AutoRegister] \u2713 Bridge \u91CD\u542F\u6E05\u7406\u6210\u529F\uFF1A${o.data.message}`),i.info(`[AutoRegister] \u6E05\u7406\u4E86 ${o.data.agentCount||0} \u4E2A Agent`),{success:!0,agentCount:o.data.agentCount||0}):(i.warn(`[AutoRegister] Bridge \u91CD\u542F\u6E05\u7406\u5931\u8D25\uFF1A${o.data.message}`),{success:!1,error:o.data.message})}catch(o){const s=o,a=s.response?.data?JSON.stringify(s.response.data):s.message;return i.warn(`[AutoRegister] Bridge \u91CD\u542F\u6E05\u7406\u8BF7\u6C42\u5931\u8D25\uFF1A${a}`),{success:!1,error:a}}}export{Se as autoRegister,he as bridgeRestartCleanup,Ie as cancelBackgroundRegisterRetries,m as getAutoRegisterConfigFilePath,Ae as getConfiguredConnectionKeys,Ee as getInstanceId,Ue as getRegistrationState,_e as isRegistered,D as isTunnelConfig,U as loadConfig,S as loadConfigs,v as loadPrimaryLifecycleConfig,ve as requestRuntimeAccessTokenRefresh,ye as requestRuntimeAccessTokenRefreshForServer,Re as resolveSchedulerBaseUrlFromToken,Te as unregister};
1
+ import g from"node:fs";import A from"node:os";import I from"axios";import{v4 as G}from"uuid";import{getActiveBridgeHttpPort as M,getAutoRegisterConfigFilePath as m,schedulerBaseUrl as d}from"../config.js";import{runExclusiveConfigWrite as z}from"../utils/config-write-queue.js";import{logger as i}from"../utils/logger.js";import{clearRuntimeBinding as J,clearScopedRuntimeAccessToken as Y,getRuntimeAccessToken as E,getRuntimeBindingPublicState as w,getScopedRuntimeAccessToken as q,loadRuntimeBinding as h,normalizeSchedulerBaseUrl as p,saveRuntimeBinding as K,saveScopedRuntimeAccessToken as C}from"./runtime-binding.js";const P={enabled:!1,serverUrl:d,preferSameLanIp:!0,maxRetries:3,retryInterval:2e3},u={registered:!1,registrations:{}};let b=[];function Ae(){return[...b]}const H=3e4;function W(){const e=Number(process.env.AWS_REGISTER_BACKGROUND_RETRY_INTERVAL);return Number.isFinite(e)&&e>0?e:H}const R=new Map;function L(e){const r=e.serverUrl||d,t=p(r)||r;if(R.has(t))return;const n=setTimeout(()=>{R.delete(t),V(e,t)},W());n.unref?.(),R.set(t,n)}async function V(e,r){try{const t=S().find(n=>(p(n.serverUrl||d)||n.serverUrl||d)===r)||e;await $(t,{backgroundRetry:!0})}catch(t){i.warn(`[AutoRegister] \u540E\u53F0\u91CD\u8BD5\u6CE8\u518C\u5F02\u5E38: ${t.message}`),L(e)}}function Ie(){for(const e of R.values())clearTimeout(e);R.clear()}function f(e){return e==null?void 0:String(e).trim()||void 0}function O(e){return p(e)}function v(e){if(typeof e=="boolean")return e;if(typeof e=="string"){const r=e.trim().toLowerCase();if(["true","1","yes","y"].includes(r))return!0;if(["false","0","no","n"].includes(r))return!1}}function x(e){if(e==null||e==="")return;const r=Number(e);return Number.isFinite(r)?r:void 0}function k(e){const r=f(e.serverUrl)||f(e.schedulerBaseUrl),t=f(e.connectionKey)||f(e.password);return{enabled:v(e.enabled),serverUrl:r,tenantId:f(e.tenantId),userKey:f(e.userKey),connectionKey:t,instanceName:f(e.instanceName),instanceId:f(e.instanceId),projectId:f(e.projectId),roleName:f(e.roleName),workspacePath:f(e.workspacePath),registerAddr:f(e.registerAddr),registerIp:f(e.registerIp),virtualIp:f(e.virtualIp),tunnel:v(e.tunnel),preferSameLanIp:v(e.preferSameLanIp),maxRetries:x(e.maxRetries),retryInterval:x(e.retryInterval)}}function j(){const e=m();try{if(!g.existsSync(e))return i.debug(`[AutoRegister] \u914D\u7F6E\u6587\u4EF6\u4E0D\u5B58\u5728: ${e}`),null;const r=g.readFileSync(e,"utf-8"),t=JSON.parse(r);return i.info(`[AutoRegister] \u4ECE\u914D\u7F6E\u6587\u4EF6\u52A0\u8F7D\u914D\u7F6E: ${e}`),k(t)}catch(r){const t=r;return i.warn(`[AutoRegister] \u8BFB\u53D6\u914D\u7F6E\u6587\u4EF6\u5931\u8D25: ${e}, error: ${t.message}`),null}}function X(){const e=m();try{if(!g.existsSync(e))return[];const r=g.readFileSync(e,"utf-8"),t=JSON.parse(r),n=k(t),o=Array.isArray(t.autoRegisterTargets)?t.autoRegisterTargets:[];return o.length===0?n.userKey?[n]:[]:o.filter(s=>!!(s&&typeof s=="object"&&!Array.isArray(s))).map(s=>{const a=k(s);return{...n,...a,connectionKey:a.connectionKey||n.connectionKey}})}catch(r){const t=r;return i.warn(`[AutoRegister] \u8BFB\u53D6\u81EA\u52A8\u6CE8\u518C\u76EE\u6807\u5931\u8D25: ${e}, error: ${t.message}`),[]}}function F(){const e={};return process.env.AWS_AUTO_REGISTER==="true"&&(e.enabled=!0),process.env.AWS_RUNTIME_SCHEDULER_BASE_URL&&(e.serverUrl=process.env.AWS_RUNTIME_SCHEDULER_BASE_URL),process.env.AWS_TENANT_ID&&(e.tenantId=process.env.AWS_TENANT_ID),process.env.AWS_USER_KEY&&(e.userKey=process.env.AWS_USER_KEY),process.env.AWS_BRIDGE_CONNECTION_KEY&&(e.connectionKey=process.env.AWS_BRIDGE_CONNECTION_KEY),process.env.AWS_INSTANCE_NAME&&(e.instanceName=process.env.AWS_INSTANCE_NAME),process.env.AWS_PROJECT_NAME&&(e.projectId=process.env.AWS_PROJECT_NAME),process.env.AWS_ROLE_NAME&&(e.roleName=process.env.AWS_ROLE_NAME),process.env.AWS_WORKSPACE_PATH&&(e.workspacePath=process.env.AWS_WORKSPACE_PATH),process.env.AWS_REGISTER_ADDR&&(e.registerAddr=process.env.AWS_REGISTER_ADDR),process.env.AWS_REGISTER_IP&&(e.registerIp=process.env.AWS_REGISTER_IP),process.env.AWS_VIRTUAL_IP&&(e.virtualIp=process.env.AWS_VIRTUAL_IP),process.env.AWS_PREFER_SAME_LAN_IP&&(e.preferSameLanIp=v(process.env.AWS_PREFER_SAME_LAN_IP)??!0),process.env.AWS_REGISTER_MAX_RETRIES&&(e.maxRetries=parseInt(process.env.AWS_REGISTER_MAX_RETRIES,10)),process.env.AWS_REGISTER_RETRY_INTERVAL&&(e.retryInterval=parseInt(process.env.AWS_REGISTER_RETRY_INTERVAL,10)),e}function T(){const e=j(),r=F(),t={...P,...e||{},...r},n=t.instanceName||A.hostname();let o=!1;return process.env.AWS_AUTO_REGISTER!==void 0?o=process.env.AWS_AUTO_REGISTER==="true":e&&(o=!0),{enabled:o,serverUrl:t.serverUrl||d,tenantId:t.tenantId||"",userKey:t.userKey||"",connectionKey:t.connectionKey,instanceName:n,instanceId:t.instanceId,projectId:t.projectId,roleName:t.roleName,workspacePath:t.workspacePath,registerAddr:t.registerAddr,registerIp:t.registerIp,virtualIp:t.virtualIp,tunnel:typeof t.tunnel=="boolean"?t.tunnel:void 0,preferSameLanIp:t.preferSameLanIp!==!1,maxRetries:t.maxRetries,retryInterval:t.retryInterval}}function S(){const e=X(),r=F(),n=(e.length>0?e:[j()||{}]).map(o=>{const s={...P,...o,...r};let a=!1;return process.env.AWS_AUTO_REGISTER!==void 0?a=process.env.AWS_AUTO_REGISTER==="true":a=e.length>0||!!s.userKey,{enabled:a,serverUrl:s.serverUrl||d,tenantId:s.tenantId||"",userKey:s.userKey||"",connectionKey:s.connectionKey,instanceName:s.instanceName||A.hostname(),instanceId:s.instanceId,projectId:s.projectId,roleName:s.roleName,workspacePath:s.workspacePath,registerAddr:s.registerAddr,registerIp:s.registerIp,virtualIp:s.virtualIp,tunnel:typeof s.tunnel=="boolean"?s.tunnel:void 0,preferSameLanIp:s.preferSameLanIp!==!1,maxRetries:s.maxRetries,retryInterval:s.retryInterval}});return b=n.map(o=>o.connectionKey).filter(o=>!!(o&&o.trim())),n}function Q(){const e=A.networkInterfaces(),r=[];for(const t of Object.keys(e)){const n=e[t];if(n)for(const o of n)o.family==="IPv4"&&!o.internal&&r.push({address:o.address,netmask:o.netmask,name:t})}return r}function N(e){const r=e.split(".").map(Number);return(r[0]<<24)+(r[1]<<16)+(r[2]<<8)+r[3]}function Z(e,r,t){const n=N(e),o=N(r),s=N(t);return(n&s)===(o&s)}function ee(e){try{const r=new URL(e);return r.hostname==="localhost"||r.hostname==="127.0.0.1"?"127.0.0.1":/^(\d{1,3}\.){3}\d{1,3}$/.test(r.hostname)?r.hostname:null}catch{return null}}function re(e){return e==="127.0.0.1"}function te(e){const r=Q();if(r.length===0)return i.warn("[AutoRegister] \u672A\u627E\u5230\u4EFB\u4F55\u975E\u5185\u90E8 IP \u5730\u5740\uFF0C\u4F7F\u7528 127.0.0.1"),"127.0.0.1";const t=ee(e);if(t){if(re(t))return"127.0.0.1";for(const n of r)if(Z(n.address,t,n.netmask))return i.info(`[AutoRegister] \u627E\u5230\u4E0E\u8C03\u5EA6\u4E2D\u5FC3\u540C\u5B50\u7F51\u7684 IP: ${n.address} (\u7F51\u5361: ${n.name}, \u5B50\u7F51\u63A9\u7801: ${n.netmask})`),n.address;i.warn(`[AutoRegister] \u672A\u627E\u5230\u4E0E\u8C03\u5EA6\u4E2D\u5FC3 (${t}) \u540C\u5B50\u7F51\u7684\u672C\u673A IP\uFF0C\u4F7F\u7528 127.0.0.1`)}else i.warn("[AutoRegister] \u65E0\u6CD5\u89E3\u6790\u8C03\u5EA6\u4E2D\u5FC3 IP\uFF0C\u4F7F\u7528 127.0.0.1");return"127.0.0.1"}function ne(e=d){return te(e)}function D(e){const r=e||T();return!r.enabled||!r.userKey?!1:r.tunnel===!0?!0:r.tunnel===!1?!1:!r.registerAddr&&!r.registerIp&&!r.virtualIp}function U(e){const r=M();if(D(e)){const s=e.serverUrl||d;try{const a=new URL(s);if(!e.instanceId)i.warn("[AutoRegister] \u96A7\u9053\u6A21\u5F0F\u4F46\u7F3A\u5C11 instanceId\uFF0C\u964D\u7EA7\u4E3A\u76F4\u8FDE\u6A21\u5F0F");else return`${a.protocol}//${a.host}/tunnel/${e.instanceId}`}catch{i.warn("[AutoRegister] serverUrl \u89E3\u6790\u5931\u8D25\uFF0C\u964D\u7EA7\u4E3A\u76F4\u8FDE\u6A21\u5F0F")}}const t=e.preferSameLanIp===!1?"127.0.0.1":ne(e.serverUrl||d),n=e.registerAddr||e.registerIp||e.virtualIp||t;return n?/^https?:\/\//i.test(n)?n:/:[0-9]+$/.test(n)?`http://${n}`:`http://${n}:${r}`:`http://127.0.0.1:${r}`}function y(){return S()[0]||T()}function Re(e){const r=String(e||"").trim();if(!r)return;const t=[];for(const o of S())o?.serverUrl&&t.push(o.serverUrl);const n=h();n.schedulerBaseUrl&&t.push(n.schedulerBaseUrl);for(const o of t){const s=q(o);if(s&&s===r)return p(o)}}function se(e){return e?Object.entries(u.registrations).find(([,t])=>t===e)?.[0]:void 0}function _(e,r){const t=se(r);if(t)return t;const n=f(e.serverUrl);if(n&&(n!==d||process.env.AWS_RUNTIME_SCHEDULER_BASE_URL))return n;const o=h(),s=f(o.schedulerBaseUrl);return o.status==="paired"&&s?s:n||d}async function oe(e){const r=e.instanceName||A.hostname(),t=e.serverUrl||d,n={tenantId:e.tenantId,userKey:e.userKey,instanceId:e.instanceId,instanceName:r,hostname:A.hostname(),virtualIp:e.registerAddr||e.registerIp||e.virtualIp,runtimeBridgeBaseUrl:U(e),connectionKey:e.connectionKey,workspacePath:e.workspacePath,projectId:e.projectId,roleName:e.roleName};return i.info(`[AutoRegister] \u6B63\u5728\u6CE8\u518C\u5B9E\u4F8B: ${r}`),i.info(`[AutoRegister] \u8C03\u5EA6\u4E2D\u5FC3: ${t}`),i.info(`[AutoRegister] \u7528\u6237 Key: ${e.userKey?"****"+e.userKey.slice(-4):"(\u672A\u8BBE\u7F6E)"}`),i.info(`[AutoRegister] \u79DF\u6237 ID: ${e.tenantId||"(\u81EA\u52A8\u63A8\u5BFC)"}`),(await I.post(`${t}/api/instances/register`,n,{headers:{"Content-Type":"application/json"},timeout:1e4})).data}function ie(e,r){const t=m();return z(t,()=>{if(!g.existsSync(t))return;const n=g.readFileSync(t,"utf-8"),o=JSON.parse(n),s=p(e);if(!s)return;let a=!1;const l=c=>{p(String(c.serverUrl||c.schedulerBaseUrl||""))===s&&r&&c.instanceId!==r&&(c.instanceId=r,a=!0)};if(Array.isArray(o.autoRegisterTargets))for(const c of o.autoRegisterTargets)c&&typeof c=="object"&&!Array.isArray(c)&&l(c);else l(o);a&&(g.writeFileSync(t,JSON.stringify(o,null,2),"utf-8"),i.info(`[AutoRegister] \u5DF2\u56DE\u5199 instanceId \u5230 config.json (serverUrl=${e})`))})}async function ae(e){const r=_(y(),e),t=E(r);if(!t)throw new Error("runtimeAccessToken is required to unregister bridge instance");return(await I.post(`${r}/api/instances/unregister`,{instanceId:e},{headers:{"Content-Type":"application/json","X-Runtime-Token":t},timeout:1e4})).data}async function Se(e){const r=e?[{...T(),...e}]:S(),n=(r.length>1?await Promise.all(r.map(s=>$(s))):[await $(r[0]||T())]).every(Boolean),o=r.every(s=>!s.enabled||!s.userKey);if(!e&&(n||o)){const{stopTunnelClientsExcept:s}=await import("./tunnel-client.js");s(r.map(a=>a.serverUrl).filter(a=>!!a))}return n}async function $(e,r){if(!e.enabled)return i.info("[AutoRegister] \u81EA\u52A8\u6CE8\u518C\u672A\u542F\u7528"),i.info(`[AutoRegister] \u8981\u542F\u7528\u81EA\u52A8\u6CE8\u518C\uFF0C\u8BF7\u521B\u5EFA\u914D\u7F6E\u6587\u4EF6 ${m()} \u6216\u8BBE\u7F6E\u73AF\u5883\u53D8\u91CF AWS_AUTO_REGISTER=true`),!1;if(!e.userKey)return i.error("[AutoRegister] \u7F3A\u5C11\u7528\u6237 Key\uFF08\u5728\u914D\u7F6E\u6587\u4EF6\u4E2D\u8BBE\u7F6E userKey \u6216\u8BBE\u7F6E\u73AF\u5883\u53D8\u91CF AWS_USER_KEY\uFF09"),!1;const t=D(e);t&&!e.instanceId&&(e={...e,instanceId:`bridge-${G().replace(/-/g,"").slice(0,12)}`},i.info(`[AutoRegister] \u96A7\u9053\u6A21\u5F0F\uFF1A\u5DF2\u9884\u58F0\u660E instanceId=${e.instanceId}`));const n=r?.backgroundRetry?1:e.maxRetries??3,o=e.retryInterval??2e3;for(let s=1;s<=n;s++){try{u.lastAttempt=new Date;const a=await oe(e);if(a.success){if(u.registered=!0,u.instanceId=a.instanceId,a.instanceId&&(u.registrations[e.serverUrl||d]=a.instanceId),u.error=void 0,i.info("[AutoRegister] \u2713 \u6CE8\u518C\u6210\u529F\uFF01"),i.info(`[AutoRegister] \u5B9E\u4F8B ID: ${a.instanceId}`),i.info(`[AutoRegister] \u6D88\u606F: ${a.message}`),i.info(`[AutoRegister] \u66F4\u65B0: ${a.isUpdate?"\u662F":"\u5426"}`),a.runtimeAccessToken)try{const l=e.serverUrl||d;K({accessToken:a.runtimeAccessToken,instanceId:a.instanceId,userId:a.userId,schedulerBaseUrl:l});const c=p(a.serverUrl);c&&c!==p(l)&&(C({serverBaseUrl:c,accessToken:a.runtimeAccessToken}),i.info(`[AutoRegister] \u68C0\u6D4B\u5230 server \u4E0B\u53D1\u5730\u5740(${c})\u4E0E\u8FDE\u63A5\u5730\u5740(${l})\u4E0D\u540C\uFF0C\u5DF2\u6309\u4E24\u4E2A\u5730\u5740\u5206\u522B\u4FDD\u5B58 scoped token`)),i.info("[AutoRegister] \u5DF2\u4FDD\u5B58\u8C03\u5EA6\u4E2D\u5FC3\u4E0B\u53D1\u7684 runtime access token"),a.instanceId&&ie(e.serverUrl||d,a.instanceId).catch(B=>{i.warn(`[AutoRegister] \u56DE\u5199 instanceId \u5230 config.json \u5931\u8D25: ${B.message}`)})}catch(l){const c=l;return i.error(`[AutoRegister] \u4FDD\u5B58 runtime access token \u5931\u8D25: ${c.message}`),u.error=c.message,!1}else i.warn("[AutoRegister] \u6CE8\u518C\u54CD\u5E94\u672A\u5305\u542B runtime access token\uFF0CMCP \u5C06\u65E0\u6CD5\u8BBF\u95EE\u8C03\u5EA6\u4E2D\u5FC3\uFF0C\u8BF7\u68C0\u67E5 server \u7684 bridge \u5B9E\u4F8B token \u9881\u53D1\u903B\u8F91");if(t&&a.instanceId&&a.runtimeAccessToken){const{startTunnelClient:l}=await import("./tunnel-client.js"),c=e.serverUrl||d;l(c,a.instanceId),i.info(`[AutoRegister] \u96A7\u9053\u5BA2\u6237\u7AEF\u5DF2\u542F\u52A8: server=${c}, instanceId=${a.instanceId}`)}return!0}else i.warn(`[AutoRegister] \u6CE8\u518C\u5931\u8D25: ${a.message}`),u.error=a.message}catch(a){const l=a,c=l.response?.data?JSON.stringify(l.response.data):l.message;i.error(`[AutoRegister] \u6CE8\u518C\u8BF7\u6C42\u5931\u8D25 (\u5C1D\u8BD5 ${s}/${n}): ${c}`),u.error=c}s<n&&(i.info(`[AutoRegister] ${o/1e3} \u79D2\u540E\u91CD\u8BD5...`),await new Promise(a=>setTimeout(a,o)))}return r?.backgroundRetry?i.warn(`[AutoRegister] \u540E\u53F0\u91CD\u8BD5\u6CE8\u518C\u4ECD\u672A\u6210\u529F (server=${e.serverUrl||d}): ${u.error||"\u672A\u77E5"}`):(i.error("[AutoRegister] \u2717 \u6CE8\u518C\u5931\u8D25\uFF0C\u5DF2\u8FBE\u6700\u5927\u91CD\u8BD5\u6B21\u6570"),i.error("[AutoRegister] ========================================"),i.error("[AutoRegister] \u81EA\u52A8\u6CE8\u518C\u5DF2\u542F\u7528\u4F46\u6CE8\u518C\u5931\u8D25\uFF0C\u5B9E\u4F8B\u6682\u65F6\u65E0\u6CD5\u6B63\u5E38\u5DE5\u4F5C"),i.error("[AutoRegister] \u8BF7\u68C0\u67E5\u4EE5\u4E0B\u914D\u7F6E\uFF1A"),i.error(`[AutoRegister] - \u7528\u6237 Key (userKey): ${e.userKey?"****"+e.userKey.slice(-4):"(\u672A\u8BBE\u7F6E)"}`),i.error(`[AutoRegister] - \u79DF\u6237 ID (tenantId): ${e.tenantId||"(\u53EF\u9009\uFF0C\u5C06\u81EA\u52A8\u63A8\u5BFC)"}`),i.error(`[AutoRegister] - \u5B9E\u4F8B\u540D (instanceName): ${e.instanceName||"(\u4F7F\u7528\u4E3B\u673A\u540D)"}`),i.error(`[AutoRegister] - \u8C03\u5EA6\u4E2D\u5FC3\u5730\u5740: ${e.serverUrl||d}`),i.error(`[AutoRegister] - \u6700\u540E\u9519\u8BEF: ${u.error||"\u672A\u77E5"}`),i.error("[AutoRegister] ========================================"),i.error(`[AutoRegister] \u914D\u7F6E\u6765\u6E90\uFF1A${m()} \u6216\u73AF\u5883\u53D8\u91CF`),i.warn(`[AutoRegister] \u5C06\u5728\u540E\u53F0\u6301\u7EED\u91CD\u8BD5\u6CE8\u518C\uFF08\u6BCF ${Math.round(W()/1e3)} \u79D2\uFF09\uFF0C\u76F4\u5230\u4E0E\u8C03\u5EA6\u4E2D\u5FC3\u5EFA\u7ACB\u8FDE\u63A5`)),L(e),!1}async function ye(){const e=y();if(!e.userKey)return{success:!1,error:"userKey is required for runtime token refresh"};const r=w(),t=_(e),n=U(e);try{const o=await I.post(`${t}/api/instances/runtime-tokens/refresh`,{tenantId:e.tenantId,userKey:e.userKey,instanceId:r.instanceId,instanceName:e.instanceName,runtimeBridgeBaseUrl:n},{headers:{"Content-Type":"application/json"},timeout:1e4});if(!o.data.success||!o.data.runtimeAccessToken)return{success:!1,error:o.data.message||"scheduler did not return runtimeAccessToken"};const a=E()!==o.data.runtimeAccessToken;return K({accessToken:o.data.runtimeAccessToken,instanceId:r.instanceId,userId:o.data.userId||e.userKey,schedulerBaseUrl:t}),{success:!0,runtimeAccessToken:o.data.runtimeAccessToken,updated:a}}catch(o){const s=o;return{success:!1,error:s.response?.data?JSON.stringify(s.response.data):s.message}}}async function ve(e){const r=O(e);if(!r)return{success:!1,error:"serverUrl is required for runtime token refresh"};const t=S().find(s=>O(s.serverUrl)===r)||y();if(!t.userKey)return{success:!1,error:"userKey is required for runtime token refresh"};const n=w(),o=U(t);try{const s=await I.post(`${r}/api/instances/runtime-tokens/refresh`,{tenantId:t.tenantId,userKey:t.userKey,instanceId:n.instanceId,instanceName:t.instanceName,runtimeBridgeBaseUrl:o},{headers:{"Content-Type":"application/json"},timeout:1e4});if(!s.data.success||!s.data.runtimeAccessToken)return{success:!1,error:s.data.message||"scheduler did not return runtimeAccessToken"};const l=E(r)!==s.data.runtimeAccessToken;return C({serverBaseUrl:r,accessToken:s.data.runtimeAccessToken}),{success:!0,runtimeAccessToken:s.data.runtimeAccessToken,updated:l}}catch(s){const a=s;return{success:!1,error:a.response?.data?JSON.stringify(a.response.data):a.message}}}async function Te(){if(!u.registered||!u.instanceId)return i.info("[AutoRegister] \u5B9E\u4F8B\u672A\u6CE8\u518C\uFF0C\u65E0\u9700\u6CE8\u9500"),!0;try{const e=await ae(u.instanceId);if(e.success){i.info(`[AutoRegister] \u2713 \u6CE8\u9500\u6210\u529F: ${u.instanceId}`);const r=_(y(),u.instanceId);h().schedulerBaseUrl&&Y(r),J();try{const{stopTunnelClientForServer:n}=await import("./tunnel-client.js");n(r)}catch(n){i.warn(`[AutoRegister] \u6CE8\u9500\u540E\u505C\u6B62\u96A7\u9053\u5931\u8D25: ${n.message}`)}return u.registered=!1,u.instanceId=void 0,!0}else return i.warn(`[AutoRegister] \u6CE8\u9500\u5931\u8D25: ${e.message}`),!1}catch(e){const r=e;return i.error(`[AutoRegister] \u6CE8\u9500\u8BF7\u6C42\u5931\u8D25: ${r.message}`),!1}}function Ue(){return{...u}}function _e(){return u.registered}function Ee(){return u.instanceId}async function he(){const e=y(),r=u.instanceId,t=_(e,r),n={};if(r&&(n.instanceId=r),e.enabled&&(n.runtimeBridgeBaseUrl=U(e)),!n.instanceId&&!n.runtimeBridgeBaseUrl)return i.info("[AutoRegister] Bridge \u91CD\u542F\u6E05\u7406\uFF1A\u6CA1\u6709 instanceId \u6216 runtimeBridgeBaseUrl\uFF0C\u8DF3\u8FC7\u6E05\u7406"),{success:!0,agentCount:0};try{i.info("[AutoRegister] Bridge \u91CD\u542F\u6E05\u7406\uFF1A\u6B63\u5728\u901A\u77E5\u8C03\u5EA6\u4E2D\u5FC3..."),i.info(`[AutoRegister] instanceId: ${n.instanceId||"(\u65E0)"}`),i.info(`[AutoRegister] runtimeBridgeBaseUrl: ${n.runtimeBridgeBaseUrl||"(\u65E0)"}`);const o=await I.post(`${t}/api/instances/bridge-restart-cleanup`,n,{headers:{"Content-Type":"application/json"},timeout:1e4});return o.data.success?(i.info(`[AutoRegister] \u2713 Bridge \u91CD\u542F\u6E05\u7406\u6210\u529F\uFF1A${o.data.message}`),i.info(`[AutoRegister] \u6E05\u7406\u4E86 ${o.data.agentCount||0} \u4E2A Agent`),{success:!0,agentCount:o.data.agentCount||0}):(i.warn(`[AutoRegister] Bridge \u91CD\u542F\u6E05\u7406\u5931\u8D25\uFF1A${o.data.message}`),{success:!1,error:o.data.message})}catch(o){const s=o,a=s.response?.data?JSON.stringify(s.response.data):s.message;return i.warn(`[AutoRegister] Bridge \u91CD\u542F\u6E05\u7406\u8BF7\u6C42\u5931\u8D25\uFF1A${a}`),{success:!1,error:a}}}export{Se as autoRegister,he as bridgeRestartCleanup,Ie as cancelBackgroundRegisterRetries,m as getAutoRegisterConfigFilePath,Ae as getConfiguredConnectionKeys,Ee as getInstanceId,Ue as getRegistrationState,_e as isRegistered,D as isTunnelConfig,T as loadConfig,S as loadConfigs,y as loadPrimaryLifecycleConfig,ye as requestRuntimeAccessTokenRefresh,ve as requestRuntimeAccessTokenRefreshForServer,Re as resolveSchedulerBaseUrlFromToken,Te as unregister};
2
2
 
@@ -1,3 +1,4 @@
1
+ import type { McpDeploySpec } from "./mcp-deploy.js";
1
2
 
2
3
  export declare const AWS_MCP_SERVER_NAME: string;
3
4
  export interface AwsMcpServerConfigInput {
@@ -29,3 +30,7 @@ export declare function resolveAwsClientAgentMcpCommand(options?: ResolveAwsClie
29
30
  export declare function getAwsClientAgentMcpPreparedInfo(options?: ResolveAwsClientAgentMcpCommandOptions): AwsMcpPreparedInfo;
30
31
  export declare function buildAwsMcpServerConfig(input: AwsMcpServerConfigInput): AwsMcpServerConfig;
31
32
  export declare function ensureAwsClientAgentMcpReleased(): void;
33
+
34
+ export declare const BUILTIN_AWS_MCP_SERVER_NAME = "agents-work-studio";
35
+
36
+ export declare function buildBuiltinAwsMcpDeploySpec(): McpDeploySpec;
@@ -1,3 +1,3 @@
1
- import{createHash as w}from"node:crypto";import{cpSync as l,existsSync as c,lstatSync as L,mkdirSync as U,readdirSync as b,readFileSync as d,realpathSync as S,rmSync as E,statSync as M,symlinkSync as v,writeFileSync as W}from"node:fs";import t from"node:path";import{fileURLToPath as I}from"node:url";import{getActiveBridgeHttpPort as B,getRuntimeHomeDir as D,isDevMode as O,schedulerBaseUrl as $}from"../config.js";import{logger as i}from"../utils/logger.js";import{loadRuntimeBinding as H}from"./runtime-binding.js";const a=O()?"aws-mcp-dev":"aws-mcp",k=["AWS_PROJECT_NAME","AWS_PROMPT","AWS_ROLE_NAME","AWS_SERVER_URL","AWS_MCP_HTTP_URL","AWS_RUNTIME_BRIDGE_BASE_URL","AWS_HEARTBEAT_INTERVAL","AWS_HEARTBEAT_TIMEOUT","PATH","HOME","USERPROFILE","TMP","TEMP","SystemRoot","COMSPEC","PATHEXT","WINDIR"];function R(){const r=I(import.meta.url);return t.resolve(t.dirname(r),"..","..")}function V(r=R()){return t.join(p(r),"dist","index.js")}function p(r){return t.join(r,"package","aws-client-agent-mcp")}function f(){return t.join(D(),".aws-bridge","mcp")}function de(){return t.join(f(),"dist")}function C(r=f()){return t.join(r,".release.json")}function y(r){try{return JSON.parse(d(r,"utf-8")).version||"unknown"}catch{return"unknown"}}function x(r){return y(t.join(r,"package.json"))}function G(r){return y(t.join(p(r),"package.json"))}function g(r,e){c(r)&&F(r,e)}function F(r,e){if(M(r).isDirectory()){l(r,e,{errorOnExist:!1,force:!0,recursive:!0});return}l(r,e,{errorOnExist:!1,force:!0})}function N(r,e){const n=p(r);g(t.join(n,"package.json"),t.join(e,"package.json")),g(t.join(n,"README.md"),t.join(e,"README.md")),g(t.join(n,"package-lock.json"),t.join(e,"package-lock.json"))}function J(r){if(!c(r))return!0;const e=L(r);return e.isSymbolicLink()||e.isDirectory()}function z(r,e){if(!c(r))return!1;try{return S(r)===S(e)}catch{return!1}}function T(r,e){const n=t.join(r,"node_modules"),o=t.join(e,"node_modules");if(!c(n)){i.warn(`[runtime-bridge] ${a} MCP \u672A\u627E\u5230\u4F9D\u8D56\u76EE\u5F55\uFF0Crelease \u4EA7\u7269\u53EF\u80FD\u65E0\u6CD5\u89E3\u6790\u8FD0\u884C\u65F6\u4F9D\u8D56: ${n}`);return}if(!z(o,n)){if(!J(o)){i.warn(`[runtime-bridge] ${a} MCP \u4F9D\u8D56\u8DEF\u5F84\u5DF2\u5B58\u5728\u4F46\u4E0D\u662F\u76EE\u5F55\u6216\u94FE\u63A5\uFF0C\u5DF2\u4FDD\u7559: ${o}`);return}E(o,{recursive:!0,force:!0}),v(n,o,process.platform==="win32"?"junction":"dir")}}function P(r,e=r){return b(r,{withFileTypes:!0}).flatMap(n=>{const o=t.join(r,n.name);return n.isDirectory()?P(o,e):n.isFile()?[t.relative(e,o).split(t.sep).join("/")]:[]})}function K(r){const e=w("sha256");for(const n of P(r).sort()){const o=t.join(r,...n.split("/")),s=M(o);e.update(n),e.update("\0"),e.update(String(s.size)),e.update("\0"),e.update(d(o)),e.update("\0")}return`sha256:${e.digest("hex")}`}function X(r){try{const e=JSON.parse(d(C(r),"utf-8"));if(typeof e.bridgeVersion=="string"&&typeof e.mcpVersion=="string"&&typeof e.distHash=="string")return{bridgeVersion:e.bridgeVersion,mcpVersion:e.mcpVersion,distHash:e.distHash,releasedAt:typeof e.releasedAt=="string"?e.releasedAt:""}}catch{return null}return null}function Y(r,e,n){return!c(r)||!e||e.bridgeVersion!==n.bridgeVersion||e.mcpVersion!==n.mcpVersion||e.distHash!==n.distHash}function q(r={}){const e=r.packageRoot||R(),n=t.dirname(V(e)),o=t.join(n,"index.js");if(!c(o))return null;if(c(t.join(e,"src")))return i.info(`[runtime-bridge] ${a} MCP \u672C\u5730\u5F00\u53D1\u6A21\u5F0F\uFF0C\u76F4\u63A5\u4F7F\u7528\u9879\u76EE dist: ${o}`),o;const s=r.releasedRoot||f(),u=t.join(s,"dist"),A=t.join(u,"index.js"),_={bridgeVersion:x(e),mcpVersion:G(e),distHash:K(n)},j=X(s);return Y(A,j,_)?(E(u,{recursive:!0,force:!0}),U(s,{recursive:!0}),N(e,s),T(e,s),l(n,u,{errorOnExist:!1,force:!0,recursive:!0}),W(C(s),`${JSON.stringify({..._,releasedAt:r.now?r.now():new Date().toISOString()},null,2)}
2
- `,"utf-8"),i.info(`[runtime-bridge] ${a} MCP \u5DF2\u66F4\u65B0\u5230: ${u}`)):(N(e,s),T(e,s),i.info(`[runtime-bridge] ${a} MCP \u5DF2\u662F\u6700\u65B0: ${u}`)),A}function Q(){return Object.fromEntries(Object.entries(process.env).filter(r=>typeof r[1]=="string"))}function Z(r){return Object.fromEntries(k.flatMap(e=>{const n=r[e];return typeof n=="string"&&n.length>0?[[e,n]]:[]}))}function ee(r){try{const e=JSON.parse(r);if(Array.isArray(e)&&e.every(n=>typeof n=="string"))return e}catch(e){i.warn(`[runtime-bridge] AWS_CLIENT_AGENT_MCP_ARGS \u4E0D\u662F\u5408\u6CD5 JSON\uFF0C\u5DF2\u5FFD\u7565: ${e instanceof Error?e.message:String(e)}`)}return i.warn("[runtime-bridge] AWS_CLIENT_AGENT_MCP_ARGS \u5FC5\u987B\u662F string[] JSON\uFF0C\u5DF2\u5FFD\u7565"),[]}function h(r){const e=r.replace(/^((?:https?|wss?):\/\/(?:\[[^\]]+\]|[^/:?#]+):\d+):\d+(?=\/|$)/i,"$1");try{const n=new URL(e);return n.protocol==="ws:"?n.protocol="http:":n.protocol==="wss:"?n.protocol="https:":n.protocol=n.protocol.toLowerCase(),n.origin}catch{return e.replace(/\/+$/,"")}}function re(r){const e=new URL("/ws/agent",h(r));return e.protocol==="https:"?e.protocol="wss:":e.protocol="ws:",e.toString()}function ne(r){const e=h(r);return new URL("/mcp/call",e).toString()}function te(){const r=String(process.env.AWS_RUNTIME_SCHEDULER_BASE_URL||"").trim();if(r)return r;const e=H(),n=String(e.schedulerBaseUrl||"").trim();return e.status==="paired"&&n?n:$}function pe(r={}){return m(r)}function m(r={}){const e=String(process.env.AWS_CLIENT_AGENT_MCP_COMMAND||"").trim();if(e)return{source:"override",command:e,args:process.env.AWS_CLIENT_AGENT_MCP_ARGS?ee(process.env.AWS_CLIENT_AGENT_MCP_ARGS):[]};const n=r.exists||c,s=(r.release||q)();return s&&n(s)?{source:"bundled",command:process.execPath,args:[s]}:{source:"global",command:"aws-client-agent-mcp",args:[]}}function fe(r){const e=Q(),n=m(),o=te();return{command:n.command,args:n.args,env:{...Z(e),AWS_AGENT_ID:r.agentId,AWS_WORKSPACE_PATH:r.workspacePath,AWS_SERVER_URL:e.AWS_SERVER_URL||re(o),AWS_MCP_HTTP_URL:e.AWS_MCP_HTTP_URL||ne(o),AWS_RUNTIME_BRIDGE_BASE_URL:e.AWS_RUNTIME_BRIDGE_BASE_URL||`http://127.0.0.1:${B()}`,AWS_MCP_CLAIM_LAUNCH_BINDING:e.AWS_MCP_CLAIM_LAUNCH_BINDING||"true"}}}function ge(){const r=m(),e=r.args[0]?`${r.command} ${r.args.join(" ")}`:r.command;if(r.source==="global"){i.warn(`[runtime-bridge] ${a} MCP \u672A\u627E\u5230 bundled \u4EA7\u7269\uFF0C\u542F\u52A8\u65F6\u5C06\u56DE\u9000\u5230 PATH \u547D\u4EE4: ${e}`);return}i.info(`[runtime-bridge] ${a} MCP \u5DF2\u51C6\u5907(${r.source}): ${e}`)}export{a as AWS_MCP_SERVER_NAME,fe as buildAwsMcpServerConfig,ge as ensureAwsClientAgentMcpReleased,m as getAwsClientAgentMcpPreparedInfo,de as getReleasedMcpDistPath,q as releaseBundledAwsClientAgentMcp,pe as resolveAwsClientAgentMcpCommand};
1
+ import{createHash as j}from"node:crypto";import{cpSync as l,existsSync as c,lstatSync as L,mkdirSync as U,readdirSync as b,readFileSync as p,realpathSync as S,rmSync as E,statSync as M,symlinkSync as W,writeFileSync as v}from"node:fs";import t from"node:path";import{fileURLToPath as I}from"node:url";import{getActiveBridgeHttpPort as B,getRuntimeHomeDir as D,isDevMode as H,schedulerBaseUrl as O}from"../config.js";import{logger as i}from"../utils/logger.js";import{loadRuntimeBinding as $}from"./runtime-binding.js";const a=H()?"aws-mcp-dev":"aws-mcp",k=["AWS_PROJECT_NAME","AWS_PROMPT","AWS_ROLE_NAME","AWS_SERVER_URL","AWS_MCP_HTTP_URL","AWS_RUNTIME_BRIDGE_BASE_URL","AWS_HEARTBEAT_INTERVAL","AWS_HEARTBEAT_TIMEOUT","PATH","HOME","USERPROFILE","TMP","TEMP","SystemRoot","COMSPEC","PATHEXT","WINDIR"];function R(){const r=I(import.meta.url);return t.resolve(t.dirname(r),"..","..")}function V(r=R()){return t.join(f(r),"dist","index.js")}function f(r){return t.join(r,"package","aws-client-agent-mcp")}function g(){return t.join(D(),".aws-bridge","mcp")}function le(){return t.join(g(),"dist")}function C(r=g()){return t.join(r,".release.json")}function y(r){try{return JSON.parse(p(r,"utf-8")).version||"unknown"}catch{return"unknown"}}function x(r){return y(t.join(r,"package.json"))}function G(r){return y(t.join(f(r),"package.json"))}function m(r,e){c(r)&&F(r,e)}function F(r,e){if(M(r).isDirectory()){l(r,e,{errorOnExist:!1,force:!0,recursive:!0});return}l(r,e,{errorOnExist:!1,force:!0})}function w(r,e){const n=f(r);m(t.join(n,"package.json"),t.join(e,"package.json")),m(t.join(n,"README.md"),t.join(e,"README.md")),m(t.join(n,"package-lock.json"),t.join(e,"package-lock.json"))}function J(r){if(!c(r))return!0;const e=L(r);return e.isSymbolicLink()||e.isDirectory()}function z(r,e){if(!c(r))return!1;try{return S(r)===S(e)}catch{return!1}}function N(r,e){const n=t.join(r,"node_modules"),o=t.join(e,"node_modules");if(!c(n)){i.warn(`[runtime-bridge] ${a} MCP \u672A\u627E\u5230\u4F9D\u8D56\u76EE\u5F55\uFF0Crelease \u4EA7\u7269\u53EF\u80FD\u65E0\u6CD5\u89E3\u6790\u8FD0\u884C\u65F6\u4F9D\u8D56: ${n}`);return}if(!z(o,n)){if(!J(o)){i.warn(`[runtime-bridge] ${a} MCP \u4F9D\u8D56\u8DEF\u5F84\u5DF2\u5B58\u5728\u4F46\u4E0D\u662F\u76EE\u5F55\u6216\u94FE\u63A5\uFF0C\u5DF2\u4FDD\u7559: ${o}`);return}E(o,{recursive:!0,force:!0}),W(n,o,process.platform==="win32"?"junction":"dir")}}function P(r,e=r){return b(r,{withFileTypes:!0}).flatMap(n=>{const o=t.join(r,n.name);return n.isDirectory()?P(o,e):n.isFile()?[t.relative(e,o).split(t.sep).join("/")]:[]})}function K(r){const e=j("sha256");for(const n of P(r).sort()){const o=t.join(r,...n.split("/")),s=M(o);e.update(n),e.update("\0"),e.update(String(s.size)),e.update("\0"),e.update(p(o)),e.update("\0")}return`sha256:${e.digest("hex")}`}function X(r){try{const e=JSON.parse(p(C(r),"utf-8"));if(typeof e.bridgeVersion=="string"&&typeof e.mcpVersion=="string"&&typeof e.distHash=="string")return{bridgeVersion:e.bridgeVersion,mcpVersion:e.mcpVersion,distHash:e.distHash,releasedAt:typeof e.releasedAt=="string"?e.releasedAt:""}}catch{return null}return null}function Y(r,e,n){return!c(r)||!e||e.bridgeVersion!==n.bridgeVersion||e.mcpVersion!==n.mcpVersion||e.distHash!==n.distHash}function q(r={}){const e=r.packageRoot||R(),n=t.dirname(V(e)),o=t.join(n,"index.js");if(!c(o))return null;if(c(t.join(e,"src")))return i.info(`[runtime-bridge] ${a} MCP \u672C\u5730\u5F00\u53D1\u6A21\u5F0F\uFF0C\u76F4\u63A5\u4F7F\u7528\u9879\u76EE dist: ${o}`),o;const s=r.releasedRoot||g(),u=t.join(s,"dist"),A=t.join(u,"index.js"),_={bridgeVersion:x(e),mcpVersion:G(e),distHash:K(n)},h=X(s);return Y(A,h,_)?(E(u,{recursive:!0,force:!0}),U(s,{recursive:!0}),w(e,s),N(e,s),l(n,u,{errorOnExist:!1,force:!0,recursive:!0}),v(C(s),`${JSON.stringify({..._,releasedAt:r.now?r.now():new Date().toISOString()},null,2)}
2
+ `,"utf-8"),i.info(`[runtime-bridge] ${a} MCP \u5DF2\u66F4\u65B0\u5230: ${u}`)):(w(e,s),N(e,s),i.info(`[runtime-bridge] ${a} MCP \u5DF2\u662F\u6700\u65B0: ${u}`)),A}function Q(){return Object.fromEntries(Object.entries(process.env).filter(r=>typeof r[1]=="string"))}function Z(r){return Object.fromEntries(k.flatMap(e=>{const n=r[e];return typeof n=="string"&&n.length>0?[[e,n]]:[]}))}function ee(r){try{const e=JSON.parse(r);if(Array.isArray(e)&&e.every(n=>typeof n=="string"))return e}catch(e){i.warn(`[runtime-bridge] AWS_CLIENT_AGENT_MCP_ARGS \u4E0D\u662F\u5408\u6CD5 JSON\uFF0C\u5DF2\u5FFD\u7565: ${e instanceof Error?e.message:String(e)}`)}return i.warn("[runtime-bridge] AWS_CLIENT_AGENT_MCP_ARGS \u5FC5\u987B\u662F string[] JSON\uFF0C\u5DF2\u5FFD\u7565"),[]}function T(r){const e=r.replace(/^((?:https?|wss?):\/\/(?:\[[^\]]+\]|[^/:?#]+):\d+):\d+(?=\/|$)/i,"$1");try{const n=new URL(e);return n.protocol==="ws:"?n.protocol="http:":n.protocol==="wss:"?n.protocol="https:":n.protocol=n.protocol.toLowerCase(),n.origin}catch{return e.replace(/\/+$/,"")}}function re(r){const e=new URL("/ws/agent",T(r));return e.protocol==="https:"?e.protocol="wss:":e.protocol="ws:",e.toString()}function ne(r){const e=T(r);return new URL("/mcp/call",e).toString()}function te(){const r=String(process.env.AWS_RUNTIME_SCHEDULER_BASE_URL||"").trim();if(r)return r;const e=$(),n=String(e.schedulerBaseUrl||"").trim();return e.status==="paired"&&n?n:O}function pe(r={}){return d(r)}function d(r={}){const e=String(process.env.AWS_CLIENT_AGENT_MCP_COMMAND||"").trim();if(e)return{source:"override",command:e,args:process.env.AWS_CLIENT_AGENT_MCP_ARGS?ee(process.env.AWS_CLIENT_AGENT_MCP_ARGS):[]};const n=r.exists||c,s=(r.release||q)();return s&&n(s)?{source:"bundled",command:process.execPath,args:[s]}:{source:"global",command:"aws-client-agent-mcp",args:[]}}function fe(r){const e=Q(),n=d(),o=te();return{command:n.command,args:n.args,env:{...Z(e),AWS_AGENT_ID:r.agentId,AWS_WORKSPACE_PATH:r.workspacePath,AWS_SERVER_URL:e.AWS_SERVER_URL||re(o),AWS_MCP_HTTP_URL:e.AWS_MCP_HTTP_URL||ne(o),AWS_RUNTIME_BRIDGE_BASE_URL:e.AWS_RUNTIME_BRIDGE_BASE_URL||`http://127.0.0.1:${B()}`,AWS_MCP_CLAIM_LAUNCH_BINDING:e.AWS_MCP_CLAIM_LAUNCH_BINDING||"true"}}}function ge(){const r=d(),e=r.args[0]?`${r.command} ${r.args.join(" ")}`:r.command;if(r.source==="global"){i.warn(`[runtime-bridge] ${a} MCP \u672A\u627E\u5230 bundled \u4EA7\u7269\uFF0C\u542F\u52A8\u65F6\u5C06\u56DE\u9000\u5230 PATH \u547D\u4EE4: ${e}`);return}i.info(`[runtime-bridge] ${a} MCP \u5DF2\u51C6\u5907(${r.source}): ${e}`)}const me="agents-work-studio";function Ae(){const r=d(),e={type:"stdio"};if(r.command&&(e.command=r.command),r.args.length>0&&(e.args=[...r.args]),!e.command)throw new Error("\u5185\u7F6E\u901A\u8BAF MCP \u547D\u4EE4\u89E3\u6790\u5931\u8D25\uFF1A\u672A\u80FD\u5B9A\u4F4D\u53EF\u6267\u884C\u5165\u53E3\uFF08bundled/\u8986\u76D6\u53D8\u91CF/PATH \u5747\u4E0D\u53EF\u7528\uFF09");return e}export{a as AWS_MCP_SERVER_NAME,me as BUILTIN_AWS_MCP_SERVER_NAME,fe as buildAwsMcpServerConfig,Ae as buildBuiltinAwsMcpDeploySpec,ge as ensureAwsClientAgentMcpReleased,d as getAwsClientAgentMcpPreparedInfo,le as getReleasedMcpDistPath,q as releaseBundledAwsClientAgentMcp,pe as resolveAwsClientAgentMcpCommand};
3
3
 
@@ -1,2 +1,2 @@
1
- import m from"axios";import{createHmac as h}from"node:crypto";import{readFile as k}from"node:fs/promises";import _ from"node:path";import{fileURLToPath as S}from"node:url";import{createLogger as U}from"../utils/logger.js";const g="BRIDGE_PACKAGE_ON_PUBLIC_HOOKS_URL",p="BRIDGE_PACKAGE_ON_PUBLIC_HOOKS_SECRET",b=1e4,u=U("bridge-package-publish-hooks");function n(e){return e==null?void 0:String(e).trim()||void 0}function B(e){try{const o=new URL(e);return`${o.protocol}//${o.host}`}catch{return"configured-url"}}async function E(){const e=new URL("../../package.json",import.meta.url),o=await k(e,"utf-8"),r=JSON.parse(o),t=n(r.name),i=n(r.version);if(!t||!i)throw new Error("package.json must contain non-empty name and version fields");return{name:t,version:i}}function O(e,o=process.env,r=()=>new Date){return{package:e.name,version:e.version,repository:n(o.GITHUB_REPOSITORY),ref:n(o.GITHUB_REF),sha:n(o.GITHUB_SHA),runId:n(o.GITHUB_RUN_ID),runNumber:n(o.GITHUB_RUN_NUMBER),publishedAt:r().toISOString()}}function I(e,o){return`sha256=${h("sha256",o).update(e,"utf-8").digest("hex")}`}async function R(e={}){const o=e.env??process.env,r=e.logger??u,t=n(o[g]),i=n(o[p]);if(!t&&!i)return r.info("Bridge package publish hook is not configured. Skipping notification."),!1;if(!t||!i)return r.warn(`Bridge package publish hook requires both ${g} and ${p}. Skipping notification.`),!1;const a=e.packageInfo??await E(),s=O(a,o,e.now),c=JSON.stringify(s),f=I(c,i),d=String(Math.floor(Date.parse(s.publishedAt)/1e3)),l=e.post??m.post;return r.info(`Notifying bridge package publish hook for ${a.name}@${a.version} (${B(t)}).`),await l(t,c,{headers:{"Content-Type":"application/json","X-Bridge-Signature":f,"X-Bridge-Timestamp":d},timeout:b}),r.info(`Bridge package publish hook notified for ${a.name}@${a.version}.`),!0}const y=process.argv[1]?S(import.meta.url)===_.resolve(process.argv[1]):!1;y&&R().catch(e=>{u.error("Failed to notify bridge package publish hook:",e instanceof Error?e.message:String(e)),process.exitCode=1});export{O as createBridgePackagePublishPayload,I as createBridgePublishSignature,R as notifyBridgePackagePublished,E as readBridgePackageInfo};
1
+ import{createHmac as m}from"node:crypto";import{readFile as h}from"node:fs/promises";import k from"node:path";import{fileURLToPath as _}from"node:url";import S from"axios";import{createLogger as U}from"../utils/logger.js";const g="BRIDGE_PACKAGE_ON_PUBLIC_HOOKS_URL",p="BRIDGE_PACKAGE_ON_PUBLIC_HOOKS_SECRET",b=1e4,u=U("bridge-package-publish-hooks");function n(e){return e==null?void 0:String(e).trim()||void 0}function B(e){try{const o=new URL(e);return`${o.protocol}//${o.host}`}catch{return"configured-url"}}async function E(){const e=new URL("../../package.json",import.meta.url),o=await h(e,"utf-8"),r=JSON.parse(o),t=n(r.name),i=n(r.version);if(!t||!i)throw new Error("package.json must contain non-empty name and version fields");return{name:t,version:i}}function O(e,o=process.env,r=()=>new Date){return{package:e.name,version:e.version,repository:n(o.GITHUB_REPOSITORY),ref:n(o.GITHUB_REF),sha:n(o.GITHUB_SHA),runId:n(o.GITHUB_RUN_ID),runNumber:n(o.GITHUB_RUN_NUMBER),publishedAt:r().toISOString()}}function I(e,o){return`sha256=${m("sha256",o).update(e,"utf-8").digest("hex")}`}async function R(e={}){const o=e.env??process.env,r=e.logger??u,t=n(o[g]),i=n(o[p]);if(!t&&!i)return r.info("Bridge package publish hook is not configured. Skipping notification."),!1;if(!t||!i)return r.warn(`Bridge package publish hook requires both ${g} and ${p}. Skipping notification.`),!1;const a=e.packageInfo??await E(),s=O(a,o,e.now),c=JSON.stringify(s),f=I(c,i),d=String(Math.floor(Date.parse(s.publishedAt)/1e3)),l=e.post??S.post;return r.info(`Notifying bridge package publish hook for ${a.name}@${a.version} (${B(t)}).`),await l(t,c,{headers:{"Content-Type":"application/json","X-Bridge-Signature":f,"X-Bridge-Timestamp":d},timeout:b}),r.info(`Bridge package publish hook notified for ${a.name}@${a.version}.`),!0}const y=process.argv[1]?_(import.meta.url)===k.resolve(process.argv[1]):!1;y&&R().catch(e=>{u.error("Failed to notify bridge package publish hook:",e instanceof Error?e.message:String(e)),process.exitCode=1});export{O as createBridgePackagePublishPayload,I as createBridgePublishSignature,R as notifyBridgePackagePublished,E as readBridgePackageInfo};
2
2
 
@@ -1,10 +1,10 @@
1
1
 
2
2
  import { type BrowserPool } from "../browser/browser-pool.js";
3
- import { type BrowserWsServer } from "../browser/ws-server.js";
4
3
  import { createBuiltInBrowserTools } from "../browser/built-in-browser-tools.js";
5
- import type { BrowserPoolConfig, SsrfConfig, WsServerConfig } from "../browser/types.js";
6
- import type { PageListener, PageListenerInfo, ListenerId, ListenerTriggerEvent } from "../browser/page-listener-types.js";
7
4
  import type { AddListenerParams, UpdateListenerParams } from "../browser/page-listener-manager.js";
5
+ import type { PageListener, PageListenerInfo, ListenerId, ListenerTriggerEvent } from "../browser/page-listener-types.js";
6
+ import type { BrowserPoolConfig, SsrfConfig, WsServerConfig } from "../browser/types.js";
7
+ import { type BrowserWsServer } from "../browser/ws-server.js";
8
8
 
9
9
  interface BrowserSessionManagerState {
10
10
  pool: BrowserPool;
@@ -1,8 +1,8 @@
1
- import{resolve as g}from"node:path";import{getBrowserPool as L,disposeBrowserPool as y}from"../browser/browser-pool.js";import{getBrowserWsServer as S,stopBrowserWsServer as B}from"../browser/ws-server.js";import{createBuiltInBrowserTools as h}from"../browser/built-in-browser-tools.js";import{WS_HOST as d}from"../browser/types.js";let t=null,a=null;const x={headless:!0,stealth:!0,viewportWidth:1280,viewportHeight:720,maxPagesPerSession:5,maxSessionDurationMs:0,idleTimeoutMs:0,profileDir:T()},W={port:v(),host:d,heartbeatMs:30*1e3,idleTimeoutMs:30*60*1e3};function v(){const r=process.env.AWS_BROWSER_WS_PORT;if(r){const e=parseInt(r,10);if(Number.isFinite(e)&&e>0&&e<65536)return e}return 7891}function T(){const r=process.env.AWS_BROWSER_PROFILE_DIR;return r||g(process.cwd(),".browser-profiles")}async function P(r,e){return t||a||(a=(async()=>{const o=L({...x,...r}),s=await S(o,{...W,...e}),{port:n,host:i}=await s.start();o.setListenerTriggerHook((c,f,l,m)=>{try{s.broadcastListenerTriggered(c,f,{listenerId:l.listenerId,selector:m.selector,prompt:l.prompt,url:l.url,text:l.text??"",at:l.triggeredAt,changeType:l.changeType})}catch{}u(c,f).catch(()=>{});try{w.get(c)?.()}catch{}});const p={pool:o,wsServer:s,wsPort:n,wsHost:i};return t=p,a=null,p})(),a)}function O(r,e){return!t||!r?null:t.wsServer.getUrl(r,e)}function U(r){return!t||!r?[]:t.pool.listSessions(r).map(o=>({browserId:o.browserId,title:o.title,wsUrl:t.wsServer.getUrl(r,o.browserId)}))}function b(){return t?.wsPort??null}async function H(r,e,o){return r?(await P(),t?h({pool:t.pool,wsServer:t.wsServer,agentId:r,scopeKey:e,ssrfConfig:o}):[]):[]}async function R(r){if(!(!t||!r))try{await t.pool.closeByAgent(r)}catch{}}async function k(r,e){if(!(!t||!r))try{await t.pool.close(r,e)}catch{}}async function D(){if(t)try{await B(),await y()}finally{t=null,a=null}}function F(){return t!==null}async function C(r,e,o){if(!t||!r)throw new Error("browser manager not started");const s=t.pool.get(r,e);if(!s)throw new Error(`Browser session not launched for ${r}/${e}. Call browser_launch first.`);const n=await s.listenerManager.addListener(o);return await u(r,e),n}async function N(r,e,o,s){if(!t||!r)return;const n=t.pool.get(r,e);if(!n)return;const i=await n.listenerManager.updateListener({...s,listenerId:o});return await u(r,e),i}async function G(r,e,o){if(!t||!r)return!1;const s=t.pool.get(r,e);if(!s)return!1;const n=await s.listenerManager.removeListener(o);return await u(r,e),n}async function j(r,e,o,s){if(!t||!r)return;const n=t.pool.get(r,e);if(!n)return;const i=await n.listenerManager.toggleListener(o,s);return await u(r,e),i}async function Y(r,e){if(!t||!r)return[];const o=t.pool.get(r,e);return o?o.listenerManager.listListeners():[]}async function u(r,e){if(!t)return;const o=t.pool.get(r,e);if(o)try{const s=await o.listenerManager.listListeners();t.wsServer.broadcastListenerUpdate(r,e,s)}catch{}}async function q(r){return!t||!r?[]:t.pool.collectListenerEvents(r)}const w=new Map;function z(r,e){r&&w.set(r,e)}function J(r,e){r&&(e&&w.get(r)!==e||w.delete(r))}function K(r){if(r.length===0)return"";const e={added:"\u65B0\u589E",removed:"\u5220\u9664",changed:"\u6539\u53D8"};return`\u7CFB\u7EDF\u63D0\u9192\uFF1A\u4EE5\u4E0B\u6D4F\u89C8\u5668\u76D1\u542C\u5668\u5DF2\u89E6\u53D1\uFF0C\u8BF7\u7ACB\u5373\u5904\u7406\uFF1A
1
+ import{resolve as m}from"node:path";import{getBrowserPool as L,disposeBrowserPool as S}from"../browser/browser-pool.js";import{createBuiltInBrowserTools as y}from"../browser/built-in-browser-tools.js";import{WS_HOST as B}from"../browser/types.js";import{getBrowserWsServer as h,stopBrowserWsServer as d}from"../browser/ws-server.js";let t=null,c=null;const x={headless:!0,stealth:!0,viewportWidth:1280,viewportHeight:720,maxPagesPerSession:5,maxSessionDurationMs:0,idleTimeoutMs:0,profileDir:T()},v={port:W(),host:B,heartbeatMs:30*1e3,idleTimeoutMs:30*60*1e3};function W(){const r=process.env.AWS_BROWSER_WS_PORT;if(r){const e=parseInt(r,10);if(Number.isFinite(e)&&e>0&&e<65536)return e}return 7891}function T(){const r=process.env.AWS_BROWSER_PROFILE_DIR;return r||m(process.cwd(),".browser-profiles")}async function P(r,e){return t||c||(c=(async()=>{const o=L({...x,...r}),s=await h(o,{...v,...e}),{port:n,host:i}=await s.start();o.setListenerTriggerHook((l,f,a,g)=>{try{s.broadcastListenerTriggered(l,f,{listenerId:a.listenerId,selector:g.selector,prompt:a.prompt,url:a.url,text:a.text??"",at:a.triggeredAt,changeType:a.changeType})}catch{}u(l,f).catch(()=>{});try{w.get(l)?.()}catch{}});const p={pool:o,wsServer:s,wsPort:n,wsHost:i};return t=p,c=null,p})(),c)}function O(r,e){return!t||!r?null:t.wsServer.getUrl(r,e)}function U(r){if(!t||!r)return[];const e=t.pool.listSessions(r),o=t;return e.map(s=>({browserId:s.browserId,title:s.title,wsUrl:o.wsServer.getUrl(r,s.browserId)}))}function b(){return t?.wsPort??null}async function H(r,e,o){return r?(await P(),t?y({pool:t.pool,wsServer:t.wsServer,agentId:r,scopeKey:e,ssrfConfig:o}):[]):[]}async function R(r){if(!(!t||!r))try{await t.pool.closeByAgent(r)}catch{}}async function k(r,e){if(!(!t||!r))try{await t.pool.close(r,e)}catch{}}async function D(){if(t)try{await d(),await S()}finally{t=null,c=null}}function F(){return t!==null}async function C(r,e,o){if(!t||!r)throw new Error("browser manager not started");const s=t.pool.get(r,e);if(!s)throw new Error(`Browser session not launched for ${r}/${e}. Call browser_launch first.`);const n=await s.listenerManager.addListener(o);return await u(r,e),n}async function N(r,e,o,s){if(!t||!r)return;const n=t.pool.get(r,e);if(!n)return;const i=await n.listenerManager.updateListener({...s,listenerId:o});return await u(r,e),i}async function G(r,e,o){if(!t||!r)return!1;const s=t.pool.get(r,e);if(!s)return!1;const n=await s.listenerManager.removeListener(o);return await u(r,e),n}async function j(r,e,o,s){if(!t||!r)return;const n=t.pool.get(r,e);if(!n)return;const i=await n.listenerManager.toggleListener(o,s);return await u(r,e),i}async function Y(r,e){if(!t||!r)return[];const o=t.pool.get(r,e);return o?o.listenerManager.listListeners():[]}async function u(r,e){if(!t)return;const o=t.pool.get(r,e);if(o)try{const s=await o.listenerManager.listListeners();t.wsServer.broadcastListenerUpdate(r,e,s)}catch{}}async function q(r){return!t||!r?[]:t.pool.collectListenerEvents(r)}const w=new Map;function z(r,e){r&&w.set(r,e)}function J(r,e){r&&(e&&w.get(r)!==e||w.delete(r))}function K(r){if(r.length===0)return"";const e={added:"\u65B0\u589E",removed:"\u5220\u9664",changed:"\u6539\u53D8"};return`\u7CFB\u7EDF\u63D0\u9192\uFF1A\u4EE5\u4E0B\u6D4F\u89C8\u5668\u76D1\u542C\u5668\u5DF2\u89E6\u53D1\uFF0C\u8BF7\u7ACB\u5373\u5904\u7406\uFF1A
2
2
 
3
3
  `+r.map((s,n)=>{const i=s.browserId&&s.browserId!=="default"?`\u6D4F\u89C8\u5668[${s.browserId}]`:"\u6D4F\u89C8\u5668",p=s.selector?`\u5143\u7D20\u9009\u62E9\u5668: ${s.selector}
4
- `:"",c=e[s.changeType??"changed"]??"\u6539\u53D8",f=new Date(s.triggeredAt).toISOString();return`\u3010\u76D1\u542C\u5668\u4E8B\u4EF6 ${n+1} | ${i} | URL: ${s.url}\u3011
5
- ${p}\u53D8\u5316\u7C7B\u578B: ${c}
4
+ `:"",l=e[s.changeType??"changed"]??"\u6539\u53D8",f=new Date(s.triggeredAt).toISOString();return`\u3010\u76D1\u542C\u5668\u4E8B\u4EF6 ${n+1} | ${i} | URL: ${s.url}\u3011
5
+ ${p}\u53D8\u5316\u7C7B\u578B: ${l}
6
6
  \u89E6\u53D1\u65F6\u95F4: ${f}
7
7
  \u63D0\u793A\u8BCD: ${s.prompt}`}).join(`
8
8
 
@@ -1,3 +1,3 @@
1
- import{existsSync as m,readFileSync as S,readdirSync as h}from"node:fs";import f from"node:path";import{getAcodeDataHome as x,getAcodePluginDataHome as A,getAcodeSkillDataHome as v}from"../config.js";import{atomicWriteFileSync as J,sanitizeAgentId as b}from"../utils/file-utils.js";const T=["skills","mcp","plugins"];function d(e){switch(e){case"skills":return f.join(v(),"skills");case"mcp":return f.join(x(),"mcp-deployed");case"plugins":return f.join(A(),"plugins");default:throw new Error(`\u672A\u77E5\u80FD\u529B\u7C7B\u578B: ${String(e)}`)}}const l=new Map;function W(e,t){t?l.set(e,t):l.delete(e)}function w(e,t){const r=l.get(e);if(r)try{return r()[t]}catch{return}}function a(e){try{if(!m(e))return{};const t=JSON.parse(S(e,"utf8"));return!t||typeof t!="object"||Array.isArray(t)?{}:t}catch{return{}}}function y(e,t){J(e,`${JSON.stringify(t,null,2)}
2
- `)}function s(e,t){const r=t[e];if(!r||typeof r!="object"||Array.isArray(r))return{};const o={};for(const[n,i]of Object.entries(r))n.trim()&&typeof i=="boolean"&&(o[n.trim()]=i);return o}function j(e,t,r,o){const n={...s(t,e)};o==null?delete n[r]:n[r]=o,e[t]=n}function D(e){return f.join(d(e),"config.json")}function O(e,t){return f.join(d(e),"agents",`${b(t)}.json`)}function p(e){return s(e,a(D(e)))}function F(e,t){return e?s(t,a(O(t,e))):{}}function k(e,t,r,o){const i=F(e,t)[r];if(i!==void 0)return i;const c=p(t)[r];if(c!==void 0)return c;if(o!==void 0)return o;const g=w(t,r);return g!==void 0?g:!1}function N(e,t,r){const o=D(e),n=a(o),i=s(e,n);j(n,e,t,r);const u=s(e,n);return JSON.stringify(i)===JSON.stringify(u)?!1:(y(o,n),!0)}function $(e,t,r,o){if(!e)return!1;const n=O(t,e),i=a(n),u=s(t,i);j(i,t,r,o);const c=s(t,i);return JSON.stringify(u)===JSON.stringify(c)?!1:(y(n,i),!0)}function V(e){const t=f.join(d(e),"agents");try{return m(t)?h(t).filter(r=>r.endsWith(".json")&&!r.startsWith(".")).map(r=>r.slice(0,-5)):[]}catch{return[]}}function Y(e){const t=l.get(e);if(!t)return 0;let r=0;const o=p(e),n=t()??{};for(const i of Object.keys(n))i in o||n[i]===!0&&(N(e,i,!1),r++);return r}function z(e){return Object.keys(p(e)).length>0}function B(e,t,r){const o={};for(const n of r)o[n]=k(e,t,n);return o}export{T as CAPABILITY_TYPES,p as getDefaults,k as getEffective,B as getEffectiveMap,F as getOverrides,z as hasAnyDefault,V as listOverrideAgents,Y as reconcileDefaultsFromDeployed,N as setDefault,W as setDeployedDefaultsProvider,$ as setOverride};
1
+ import{existsSync as m,readFileSync as h,readdirSync as j}from"node:fs";import d from"node:path";import{getBridgeTemplateMcpDir as x,getBridgeTemplatePluginsDir as v,getBridgeTemplateSkillsDir as A}from"../config.js";import{atomicWriteFileSync as J,sanitizeAgentId as b}from"../utils/file-utils.js";const M=["skills","mcp","plugins"];function a(e){switch(e){case"skills":return A();case"mcp":return x();case"plugins":return v();default:throw new Error(`\u672A\u77E5\u80FD\u529B\u7C7B\u578B: ${String(e)}`)}}const c=new Map;function W(e,t){t?c.set(e,t):c.delete(e)}function w(e,t){const r=c.get(e);if(r)try{return r()[t]}catch{return}}function l(e){try{if(!m(e))return{};const t=JSON.parse(h(e,"utf8"));return!t||typeof t!="object"||Array.isArray(t)?{}:t}catch{return{}}}function y(e,t){J(e,`${JSON.stringify(t,null,2)}
2
+ `)}function s(e,t){const r=t[e];if(!r||typeof r!="object"||Array.isArray(r))return{};const i={};for(const[n,o]of Object.entries(r))n.trim()&&typeof o=="boolean"&&(i[n.trim()]=o);return i}function D(e,t,r,i){const n={...s(t,e)};i==null?delete n[r]:n[r]=i,e[t]=n}function O(e){return d.join(a(e),"config.json")}function S(e,t){return d.join(a(e),"agents",`${b(t)}.json`)}function p(e){return s(e,l(O(e)))}function F(e,t){return e?s(t,l(S(t,e))):{}}function N(e,t,r,i){const o=F(e,t)[r];if(o!==void 0)return o;const u=p(t)[r];if(u!==void 0)return u;if(i!==void 0)return i;const g=w(t,r);return g!==void 0?g:!1}function P(e,t,r){const i=O(e),n=l(i),o=s(e,n);D(n,e,t,r);const f=s(e,n);return JSON.stringify(o)===JSON.stringify(f)?!1:(y(i,n),!0)}function $(e,t,r,i){if(!e)return!1;const n=S(t,e),o=l(n),f=s(t,o);D(o,t,r,i);const u=s(t,o);return JSON.stringify(f)===JSON.stringify(u)?!1:(y(n,o),!0)}function V(e){const t=d.join(a(e),"agents");try{return m(t)?j(t).filter(r=>r.endsWith(".json")&&!r.startsWith(".")).map(r=>r.slice(0,-5)):[]}catch{return[]}}function Y(e){const t=c.get(e);if(!t)return 0;let r=0;const i=p(e),n=t()??{};for(const o of Object.keys(n))o in i||n[o]===!0&&(P(e,o,!1),r++);return r}function z(e){return Object.keys(p(e)).length>0}function C(e,t,r){const i={};for(const n of r)i[n]=N(e,t,n);return i}export{M as CAPABILITY_TYPES,p as getDefaults,N as getEffective,C as getEffectiveMap,F as getOverrides,z as hasAnyDefault,V as listOverrideAgents,Y as reconcileDefaultsFromDeployed,P as setDefault,W as setDeployedDefaultsProvider,$ as setOverride};
3
3
 
@@ -1,7 +1,7 @@
1
- import{spawnSync as g}from"node:child_process";import{createInterface as X}from"node:readline/promises";import{existsSync as h,mkdirSync as I,readFileSync as Z,rmSync as ee,unlinkSync as H,writeFileSync as G}from"node:fs";import m from"node:path";import D from"node:os";import{fileURLToPath as j}from"node:url";import{configureStartupConfig as re,printConfigExampleCommand as te}from"./startup-config-wizard.js";import{getRuntimeHomeDir as ne}from"../config.js";import{createWindowsServiceManager as se,isNodeWindowsAvailable as ie}from"./windows-service-manager.js";const w="awsb.service",N=`/etc/systemd/system/${w}`,q="awsb",c=`${q}.exe`;function A(){return m.join(ne(),".aws-bridge","log")}const B=m.join(A(),"awsb.out.log"),L="com.agentsworkstudio.awsb",T=m.join(D.homedir(),"Library","LaunchAgents",`${L}.plist`),U=m.join(A(),"awsb.out.log");function ae(){const e=j(import.meta.url);return m.resolve(m.dirname(e),"..","..")}function ue(e=ae()){const r=m.join(e,"package.json");return JSON.parse(Z(r,"utf-8")).version||"unknown"}function _(e,r){const t=g(e,r,{shell:process.platform==="win32",stdio:"inherit"});return{status:t.status,error:t.error}}function de(){try{const e=g("npm",["root","-g"],{shell:process.platform==="win32",encoding:"utf-8",stdio:["ignore","pipe","ignore"]});if(e.status===0&&e.stdout){const r=e.stdout.trim();if(r)return r}}catch{}return null}function oe(e){try{const r=new SharedArrayBuffer(4);Atomics.wait(new Int32Array(r),0,0,e)}catch{const r=Date.now()+e;for(;Date.now()<r;);}}function M(e){if(process.platform!=="win32")return null;try{const r=g("sc.exe",["query",e],{shell:!0,encoding:"utf-8",stdio:["ignore","pipe","ignore"]});if(r.status!==0||!r.stdout)return null;const t=r.stdout.match(/STATE\s*:\s*\d+\s+(\S+)/);return t?t[1]:null}catch{return null}}function V(e,r,t=15e3,s=500){const i=Date.now()+t;for(;Date.now()<i;){const n=e(r);if(n===null||n==="STOPPED")return!0;oe(s)}return!1}function ce(e){process.stdout.write(`${e}
1
+ import{spawnSync as g}from"node:child_process";import{existsSync as h,mkdirSync as I,readFileSync as X,rmSync as Z,unlinkSync as H,writeFileSync as G}from"node:fs";import D from"node:os";import m from"node:path";import{createInterface as ee}from"node:readline/promises";import{fileURLToPath as j}from"node:url";import{getRuntimeHomeDir as re}from"../config.js";import{configureStartupConfig as te,printConfigExampleCommand as ne}from"./startup-config-wizard.js";import{createWindowsServiceManager as se,isNodeWindowsAvailable as ie}from"./windows-service-manager.js";const w="awsb.service",N=`/etc/systemd/system/${w}`,q="awsb",c=`${q}.exe`;function A(){return m.join(re(),".aws-bridge","log")}const B=m.join(A(),"awsb.out.log"),L="com.agentsworkstudio.awsb",T=m.join(D.homedir(),"Library","LaunchAgents",`${L}.plist`),U=m.join(A(),"awsb.out.log");function ae(){const e=j(import.meta.url);return m.resolve(m.dirname(e),"..","..")}function ue(e=ae()){const r=m.join(e,"package.json");return JSON.parse(X(r,"utf-8")).version||"unknown"}function _(e,r){const t=g(e,r,{shell:process.platform==="win32",stdio:"inherit"});return{status:t.status,error:t.error}}function de(){try{const e=g("npm",["root","-g"],{shell:process.platform==="win32",encoding:"utf-8",stdio:["ignore","pipe","ignore"]});if(e.status===0&&e.stdout){const r=e.stdout.trim();if(r)return r}}catch{}return null}function oe(e){try{const r=new SharedArrayBuffer(4);Atomics.wait(new Int32Array(r),0,0,e)}catch{const r=Date.now()+e;for(;Date.now()<r;);}}function M(e){if(process.platform!=="win32")return null;try{const r=g("sc.exe",["query",e],{shell:!0,encoding:"utf-8",stdio:["ignore","pipe","ignore"]});if(r.status!==0||!r.stdout)return null;const t=r.stdout.match(/STATE\s*:\s*\d+\s+(\S+)/);return t?t[1]:null}catch{return null}}function V(e,r,t=15e3,s=500){const i=Date.now()+t;for(;Date.now()<i;){const n=e(r);if(n===null||n==="STOPPED")return!0;oe(s)}return!1}function ce(e){process.stdout.write(`${e}
2
2
  `)}function le(e){process.stderr.write(`${e}
3
3
  `)}function me(e){return e==="-v"||e==="--version"||e==="version"}function fe(e){return`"${e.replace(/\\/g,"\\\\").replace(/"/g,'\\"')}"`}function K(){return process.argv[1]?m.resolve(process.argv[1]):j(import.meta.url)}function ge(e){return["[Unit]","Description=AgentsWorkStudio Runtime Bridge","After=network-online.target","Wants=network-online.target","","[Service]","Type=simple","Environment=AWS_BRIDGE_SKIP_SETUP=true",`ExecStart=${[process.execPath,e].map(t=>fe(t)).join(" ")}`,"Restart=on-failure","RestartSec=5s","","[Install]","WantedBy=multi-user.target",""].join(`
4
4
  `)}function P(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function he(e,r={}){const t=r.userHomeDir??D.homedir(),s=r.logPath??U,i=s.replace(/\.out\.log$/,".err.log");return['<?xml version="1.0" encoding="UTF-8"?>','<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">','<plist version="1.0">',"<dict>"," <key>Label</key>",` <string>${P(L)}</string>`," <key>ProgramArguments</key>"," <array>",` <string>${P(process.execPath)}</string>`,` <string>${P(e)}</string>`," </array>"," <key>EnvironmentVariables</key>"," <dict>"," <key>AWS_BRIDGE_SKIP_SETUP</key>"," <string>true</string>"," <key>AWS_RUNTIME_HOME_DIR</key>",` <string>${P(t)}</string>`," </dict>"," <key>RunAtLoad</key>"," <true/>"," <key>KeepAlive</key>"," <true/>"," <key>StandardOutPath</key>",` <string>${P(s)}</string>`," <key>StandardErrorPath</key>",` <string>${P(i)}</string>`,"</dict>","</plist>",""].join(`
5
5
  `)}function b(e,r){return e("systemctl",r)}function C(e,r){return r.error?`[runtime-bridge] ${e}\u5931\u8D25: ${r.error.message}`:`[runtime-bridge] ${e}\u5931\u8D25\uFF0Csystemctl \u9000\u51FA\u7801: ${r.status??"unknown"}`}function o(e){return!e.error&&e.status===0}function $(e,r){return e==="linux"?!0:(r("[runtime-bridge] service \u547D\u4EE4\u4EC5\u652F\u6301 Linux systemd \u73AF\u5883\u3002"),!1)}function R(e,r){return e==="darwin"?!0:(r("[runtime-bridge] service \u547D\u4EE4\u4EC5\u652F\u6301 macOS launchd \u73AF\u5883\u3002"),!1)}function Y(e){e("Usage: awsb service <install|uninstall|start|stop|restart>")}function we(e){if(!$(e.platform,e.stderr))return{handled:!0,exitCode:1};const r=ge(e.executablePath);try{I(m.dirname(e.serviceUnitPath),{recursive:!0}),G(e.serviceUnitPath,r,{encoding:"utf-8",mode:420})}catch(n){const a=n instanceof Error?n:new Error(String(n));return e.stderr(`[runtime-bridge] \u5199\u5165 systemd unit \u5931\u8D25: ${a.message}`),{handled:!0,exitCode:1}}const t=b(e.runCommand,["daemon-reload"]);if(!o(t))return e.stderr(C("\u91CD\u8F7D systemd",t)),{handled:!0,exitCode:t.status??1};const s=b(e.runCommand,["enable",w]);if(!o(s))return e.stderr(C("\u542F\u7528 awsb \u5F00\u673A\u81EA\u542F",s)),{handled:!0,exitCode:s.status??1};const i=b(e.runCommand,["is-active","--quiet",w]);if(i.error)return e.stderr(C("\u68C0\u67E5 awsb \u670D\u52A1\u72B6\u6001",i)),{handled:!0,exitCode:1};if(i.status!==0){const n=b(e.runCommand,["start",w]);return o(n)?(e.stdout("[runtime-bridge] awsb systemd \u670D\u52A1\u5DF2\u5B89\u88C5\u3001\u5DF2\u542F\u7528\u5F00\u673A\u81EA\u542F\u5E76\u5DF2\u542F\u52A8\u3002"),{handled:!0,exitCode:0}):(e.stderr(C("\u542F\u52A8 awsb \u670D\u52A1",n)),{handled:!0,exitCode:n.status??1})}return e.stdout("[runtime-bridge] awsb systemd \u670D\u52A1\u5DF2\u5B89\u88C5\u5E76\u5DF2\u542F\u7528\u5F00\u673A\u81EA\u542F\uFF1B\u670D\u52A1\u5DF2\u5728\u8FD0\u884C\u3002"),{handled:!0,exitCode:0}}function be(e){if(!$(e.platform,e.stderr))return{handled:!0,exitCode:1};const r=h(e.serviceUnitPath),t=b(e.runCommand,["is-active","--quiet",w]);if(t.error)return e.stderr(C("\u68C0\u67E5 awsb \u670D\u52A1\u72B6\u6001",t)),{handled:!0,exitCode:1};if(t.status===0){const n=b(e.runCommand,["stop",w]);if(!o(n))return e.stderr(C("\u505C\u6B62 awsb \u670D\u52A1",n)),{handled:!0,exitCode:n.status??1}}const s=b(e.runCommand,["disable",w]);if(s.error||s.status!==0&&r)return e.stderr(C("\u7981\u7528 awsb \u5F00\u673A\u81EA\u542F",s)),{handled:!0,exitCode:s.status??1};if(r)try{H(e.serviceUnitPath)}catch(n){const a=n instanceof Error?n:new Error(String(n));return e.stderr(`[runtime-bridge] \u5220\u9664 systemd unit \u5931\u8D25: ${a.message}`),{handled:!0,exitCode:1}}else e.stdout("[runtime-bridge] awsb systemd unit \u4E0D\u5B58\u5728\uFF0C\u8DF3\u8FC7\u5220\u9664\u3002");const i=b(e.runCommand,["daemon-reload"]);return o(i)?(e.stdout("[runtime-bridge] awsb systemd \u670D\u52A1\u5DF2\u5378\u8F7D\u3002"),{handled:!0,exitCode:0}):(e.stderr(C("\u91CD\u8F7D systemd",i)),{handled:!0,exitCode:i.status??1})}function Ce(e){if(!$(e.platform,e.stderr))return{handled:!0,exitCode:1};if(!h(e.serviceUnitPath))return e.stderr("[runtime-bridge] awsb systemd \u670D\u52A1\u5C1A\u672A\u5B89\u88C5\uFF0C\u8BF7\u5148\u6267\u884C `awsb service install`\u3002"),{handled:!0,exitCode:1};const r=b(e.runCommand,["restart",w]);return o(r)?(e.stdout("[runtime-bridge] awsb systemd \u670D\u52A1\u5DF2\u91CD\u542F\u3002"),{handled:!0,exitCode:0}):(e.stderr(C("\u91CD\u542F awsb \u670D\u52A1",r)),{handled:!0,exitCode:r.status??1})}function xe(e){if(!$(e.platform,e.stderr))return{handled:!0,exitCode:1};if(!h(e.serviceUnitPath))return e.stderr("[runtime-bridge] awsb systemd \u670D\u52A1\u5C1A\u672A\u5B89\u88C5\uFF0C\u8BF7\u5148\u6267\u884C `awsb service install`\u3002"),{handled:!0,exitCode:1};const r=b(e.runCommand,["start",w]);return o(r)?(e.stdout("[runtime-bridge] awsb systemd \u670D\u52A1\u5DF2\u542F\u52A8\u3002"),{handled:!0,exitCode:0}):(e.stderr(C("\u542F\u52A8 awsb \u670D\u52A1",r)),{handled:!0,exitCode:r.status??1})}function Se(e){if(!$(e.platform,e.stderr))return{handled:!0,exitCode:1};if(!h(e.serviceUnitPath))return e.stderr("[runtime-bridge] awsb systemd \u670D\u52A1\u5C1A\u672A\u5B89\u88C5\uFF0C\u8BF7\u5148\u6267\u884C `awsb service install`\u3002"),{handled:!0,exitCode:1};const r=b(e.runCommand,["stop",w]);return o(r)?(e.stdout("[runtime-bridge] awsb systemd \u670D\u52A1\u5DF2\u505C\u6B62\u3002"),{handled:!0,exitCode:0}):(e.stderr(C("\u505C\u6B62 awsb \u670D\u52A1",r)),{handled:!0,exitCode:r.status??1})}function ve(e){return e(`[runtime-bridge] \u672A\u68C0\u6D4B\u5230 node-windows \u6A21\u5757\u3002\u8BF7\u91CD\u65B0\u5B89\u88C5 aws-runtime-bridge\uFF1A
6
- npm install -g aws-runtime-bridge`),{handled:!0,exitCode:1}}async function O(e){const r=e.windowsServiceManager;if(!r&&!ie())return ve(e.stderr);const t=e.windowsServiceLogPath||B,s=m.dirname(e.executablePath),i=D.homedir();try{await(r||se()).install({name:q,description:"awsb runtime bridge",script:e.executablePath,workingDirectory:s,env:[{name:"AWS_BRIDGE_SKIP_SETUP",value:"true"},{name:"AWS_RUNTIME_HOME_DIR",value:i}],logpath:A()})}catch(u){const l=u instanceof Error?u:new Error(String(u));return e.stderr(`[runtime-bridge] \u5B89\u88C5 Windows \u670D\u52A1\u5931\u8D25: ${l.message}`),{handled:!0,exitCode:1}}const n=e.runCommand("sc.exe",["start",c]);if(!o(n))return e.stderr(`[runtime-bridge] \u542F\u52A8 Windows \u670D\u52A1\u5931\u8D25: ${n.error?.message??`\u9000\u51FA\u7801 ${n.status??"unknown"}`}`),{handled:!0,exitCode:n.status??1};const a=["failure",c,"reset=","86400","actions=","restart/5000/restart/10000/restart/30000"],d=e.runCommand("sc.exe",a);return o(d)?e.stdout("[runtime-bridge] \u5DF2\u914D\u7F6E awsb \u670D\u52A1\u5931\u8D25\u81EA\u52A8\u91CD\u542F\uFF085s/10s/30s\uFF09\u3002"):e.stderr(`[runtime-bridge] \u914D\u7F6E\u670D\u52A1\u5931\u8D25\u81EA\u52A8\u91CD\u542F\u672A\u751F\u6548\uFF08\u53EF\u5FFD\u7565\uFF09: ${d.error?.message??`\u9000\u51FA\u7801 ${d.status??"unknown"}`}`),e.stdout(`[runtime-bridge] awsb Windows \u670D\u52A1\u5DF2\u5B89\u88C5\u5E76\u5DF2\u542F\u52A8\uFF08\u65E5\u5FD7: ${t}\uFF09\u3002`),{handled:!0,exitCode:0}}function Pe(e){const r=s=>e.runCommand("sc.exe",s);r(["stop",c]);const t=r(["delete",c]);return o(t)?(e.stdout("[runtime-bridge] awsb Windows \u670D\u52A1\u5DF2\u5378\u8F7D\u3002"),{handled:!0,exitCode:0}):(e.stderr(`[runtime-bridge] \u5378\u8F7D Windows \u670D\u52A1\u5931\u8D25: ${t.error?.message??`\u9000\u51FA\u7801 ${t.status??"unknown"}`}`),{handled:!0,exitCode:t.status??1})}async function ye(e){e.runCommand("sc.exe",["stop",c]);const r=e.queryWindowsServiceState||M;return V(r,c)||e.stdout("[runtime-bridge] \u7B49\u5F85 Windows \u670D\u52A1\u505C\u6B62\u8D85\u65F6\uFF0C\u4ECD\u5C1D\u8BD5\u542F\u52A8\uFF08\u53EF\u80FD\u62A5 1056\uFF09\u3002"),J(e,"\u91CD\u542F")}async function Ee(e){return J(e,"\u542F\u52A8")}const $e=2,Re=1056;async function J(e,r){const t=e.runCommand("sc.exe",["start",c]);if(o(t))return e.stdout(`[runtime-bridge] awsb Windows \u670D\u52A1\u5DF2${r}\u3002`),{handled:!0,exitCode:0};if(t.status===Re)return e.stdout(`[runtime-bridge] awsb Windows \u670D\u52A1\u5DF2\u5728\u8FD0\u884C\u4E2D\uFF08\u65E0\u9700${r}\uFF09\u3002`),{handled:!0,exitCode:0};if(t.status===$e){e.stdout("[runtime-bridge] \u68C0\u6D4B\u5230 Windows \u670D\u52A1\u4E8C\u8FDB\u5236\u6587\u4EF6\u4E22\u5931\uFF08winsw.exe\uFF09\uFF0C\u6B63\u5728\u91CD\u5EFA..."),e.runCommand("sc.exe",["delete",c]);try{const s=await O(e);return s.exitCode!==0&&e.stderr(`[runtime-bridge] ${r} Windows \u670D\u52A1\u5931\u8D25\u4E14\u81EA\u52A8\u91CD\u5EFA\u5931\u8D25\u3002\u8BF7\u624B\u52A8\u6267\u884C \`awsb service uninstall && awsb service install\` \u4FEE\u590D\u3002`),s}catch(s){const i=s instanceof Error?s:new Error(String(s));return e.stderr(`[runtime-bridge] ${r} Windows \u670D\u52A1\u5931\u8D25\u4E14\u81EA\u52A8\u91CD\u5EFA\u5F02\u5E38: ${i.message}\u3002\u8BF7\u624B\u52A8\u6267\u884C \`awsb service uninstall && awsb service install\` \u4FEE\u590D\u3002`),{handled:!0,exitCode:1}}}return e.stderr(`[runtime-bridge] ${r} Windows \u670D\u52A1\u5931\u8D25: ${t.error?.message??`\u9000\u51FA\u7801 ${t.status??"unknown"}`}`),{handled:!0,exitCode:t.status??1}}function ke(e){const r=e.runCommand("sc.exe",["stop",c]);return o(r)?(e.stdout("[runtime-bridge] awsb Windows \u670D\u52A1\u5DF2\u505C\u6B62\u3002"),{handled:!0,exitCode:0}):(e.stderr(`[runtime-bridge] \u505C\u6B62 Windows \u670D\u52A1\u5931\u8D25: ${r.error?.message??`\u9000\u51FA\u7801 ${r.status??"unknown"}`}`),{handled:!0,exitCode:r.status??1})}function pe(){return`gui/${process.getuid?.()??0}`}function k(e){return e.launchdDomainTarget||pe()}function p(e){return`${e}/${L}`}function W(e,r){return r.error?`[runtime-bridge] ${e}\u5931\u8D25: ${r.error.message}`:`[runtime-bridge] ${e}\u5931\u8D25\uFF0Claunchctl \u9000\u51FA\u7801: ${r.status??"unknown"}`}function We(e){if(!R(e.platform,e.stderr))return{handled:!0,exitCode:1};const r=e.launchdPlistPath||T,t=e.launchdLogPath||U,s=he(e.executablePath,{userHomeDir:D.homedir(),logPath:t});try{I(m.dirname(r),{recursive:!0}),I(m.dirname(t),{recursive:!0}),G(r,s,{encoding:"utf-8",mode:420})}catch(a){const d=a instanceof Error?a:new Error(String(a));return e.stderr(`[runtime-bridge] \u5199\u5165 launchd plist \u5931\u8D25: ${d.message}`),{handled:!0,exitCode:1}}const i=k(e);e.runCommand("launchctl",["bootout",p(i)]);const n=e.runCommand("launchctl",["bootstrap",i,r]);return o(n)?(e.stdout(`[runtime-bridge] awsb launchd \u670D\u52A1\u5DF2\u5B89\u88C5\u5E76\u5DF2\u542F\u52A8\uFF08\u65E5\u5FD7: ${t}\uFF09\u3002`),{handled:!0,exitCode:0}):(e.stderr(W("\u5B89\u88C5 awsb \u670D\u52A1",n)),{handled:!0,exitCode:n.status??1})}function De(e){if(!R(e.platform,e.stderr))return{handled:!0,exitCode:1};const r=e.launchdPlistPath||T,t=k(e),s=p(t),i=e.runCommand("launchctl",["bootout",s]);if(i.error)return e.stderr(W("\u5378\u8F7D awsb \u670D\u52A1",i)),{handled:!0,exitCode:1};if(h(r))try{H(r)}catch(n){const a=n instanceof Error?n:new Error(String(n));return e.stderr(`[runtime-bridge] \u5220\u9664 launchd plist \u5931\u8D25: ${a.message}`),{handled:!0,exitCode:1}}else e.stdout("[runtime-bridge] awsb launchd plist \u4E0D\u5B58\u5728\uFF0C\u8DF3\u8FC7\u5220\u9664\u3002");return e.stdout("[runtime-bridge] awsb launchd \u670D\u52A1\u5DF2\u5378\u8F7D\u3002"),{handled:!0,exitCode:0}}function Te(e){if(!R(e.platform,e.stderr))return{handled:!0,exitCode:1};const r=e.launchdPlistPath||T;if(!h(r))return e.stderr("[runtime-bridge] awsb launchd \u670D\u52A1\u5C1A\u672A\u5B89\u88C5\uFF0C\u8BF7\u5148\u6267\u884C `awsb service install`\u3002"),{handled:!0,exitCode:1};const t=k(e),s=p(t),i=e.runCommand("launchctl",["kickstart",s]);if(o(i))return e.stdout("[runtime-bridge] awsb launchd \u670D\u52A1\u5DF2\u542F\u52A8\u3002"),{handled:!0,exitCode:0};const n=e.runCommand("launchctl",["bootstrap",t,r]);return o(n)?(e.stdout("[runtime-bridge] awsb launchd \u670D\u52A1\u5DF2\u542F\u52A8\u3002"),{handled:!0,exitCode:0}):(e.stderr(W("\u542F\u52A8 awsb \u670D\u52A1",n)),{handled:!0,exitCode:n.status??1})}function _e(e){if(!R(e.platform,e.stderr))return{handled:!0,exitCode:1};const r=k(e),t=e.runCommand("launchctl",["bootout",p(r)]);return o(t)?(e.stdout("[runtime-bridge] awsb launchd \u670D\u52A1\u5DF2\u505C\u6B62\u3002"),{handled:!0,exitCode:0}):(e.stderr(W("\u505C\u6B62 awsb \u670D\u52A1",t)),{handled:!0,exitCode:t.status??1})}function Ie(e){if(!R(e.platform,e.stderr))return{handled:!0,exitCode:1};const r=e.launchdPlistPath||T;if(!h(r))return e.stderr("[runtime-bridge] awsb launchd \u670D\u52A1\u5C1A\u672A\u5B89\u88C5\uFF0C\u8BF7\u5148\u6267\u884C `awsb service install`\u3002"),{handled:!0,exitCode:1};const t=k(e);e.runCommand("launchctl",["bootout",p(t)]);const s=e.runCommand("launchctl",["bootstrap",t,r]);return o(s)?(e.stdout("[runtime-bridge] awsb launchd \u670D\u52A1\u5DF2\u91CD\u542F\u3002"),{handled:!0,exitCode:0}):(e.stderr(W("\u91CD\u542F awsb \u670D\u52A1",s)),{handled:!0,exitCode:s.status??1})}async function Ne(e,r,t,s){const i=e[1];if(!i||i==="-h"||i==="--help"||i==="help")return Y(t),{handled:!0,exitCode:i?0:1};const n={stdout:t,stderr:s,runCommand:r.runCommand||_,platform:r.platform||process.platform,serviceUnitPath:r.serviceUnitPath||N,executablePath:r.executablePath||K(),windowsServiceManager:r.windowsServiceManager,launchdPlistPath:r.launchdPlistPath,launchdLogPath:r.launchdLogPath,launchdDomainTarget:r.launchdDomainTarget,queryWindowsServiceState:r.queryWindowsServiceState||M};return n.platform!=="linux"&&n.platform!=="win32"&&n.platform!=="darwin"?(s("[runtime-bridge] service \u547D\u4EE4\u4EC5\u652F\u6301 Linux systemd\u3001Windows \u670D\u52A1\u4E0E macOS launchd \u73AF\u5883\u3002"),{handled:!0,exitCode:1}):i==="install"?n.platform==="win32"?await O(n):n.platform==="darwin"?We(n):we(n):i==="uninstall"?n.platform==="win32"?Pe(n):n.platform==="darwin"?De(n):be(n):i==="restart"?n.platform==="win32"?ye(n):n.platform==="darwin"?Ie(n):Ce(n):i==="start"?n.platform==="win32"?Ee(n):n.platform==="darwin"?Te(n):xe(n):i==="stop"?n.platform==="win32"?ke(n):n.platform==="darwin"?_e(n):Se(n):(s(`[runtime-bridge] \u672A\u77E5 service \u5B50\u547D\u4EE4: ${i}`),Y(t),{handled:!0,exitCode:1})}function Q(e){return e?e.split(/\r?\n/).map(r=>r.trim()).filter(r=>/^\d+$/.test(r)).map(Number):[]}function Ae(e){try{if(e==="win32"){const t=g("powershell",["-NoProfile","-Command",`Get-CimInstance Win32_Process -Filter "Name='node.exe'" | Where-Object { $_.CommandLine -like '*aws-runtime-bridge*' -and $_.ProcessId -ne ${process.pid} } | ForEach-Object { $_.ProcessId }`],{encoding:"utf-8"}),s=Le(e);return Ue([...Q(t.stdout),...s]).filter(i=>i!==process.pid)}const r=g("pgrep",["-f","aws-runtime-bridge"],{encoding:"utf-8"});return Q(r.stdout).filter(t=>t!==process.pid)}catch{return[]}}function Le(e){if(e!=="win32")return[];try{const r=g("sc.exe",["query",c],{encoding:"utf-8",shell:!0,stdio:["ignore","pipe","ignore"]});if(r.status!==0||!r.stdout)return[];const t=r.stdout.match(/STATE\s*:\s*\d+\s+(\S+)/);if(!t)return[];const s=t[1];if(s!=="RUNNING"&&s!=="START_PENDING"&&s!=="STOP_PENDING")return[];const i=g("tasklist",["/FI","IMAGENAME eq awsb.exe","/FO","CSV","/NH"],{encoding:"utf-8",shell:!0,stdio:["ignore","pipe","ignore"]});return i.status!==0||!i.stdout?[]:i.stdout.split(/\r?\n/).map(n=>n.trim()).filter(n=>n.length>0).map(n=>{const a=n.match(/^"awsb\.exe","(\d+)"/i);return a?Number(a[1]):NaN}).filter(n=>Number.isFinite(n)&&n>0)}catch{return[]}}function Ue(e){const r=new Set,t=[];for(const s of e)r.has(s)||(r.add(s),t.push(s));return t}function Me(e,r){if(r==="win32"){if(Oe(e,r)){g("sc.exe",["stop",c],{stdio:"ignore",shell:!0}),V(M,c);return}g("taskkill",["/PID",String(e),"/F","/T"],{stdio:"ignore"});return}g("kill",["-9",String(e)],{stdio:"ignore"})}function Oe(e,r){if(r!=="win32"||!Number.isFinite(e)||e<=0)return!1;try{const t=g("powershell",["-NoProfile","-Command",`(Get-CimInstance Win32_Process -Filter "ProcessId=${e}" -ErrorAction SilentlyContinue).Name`],{encoding:"utf-8",stdio:["ignore","pipe","ignore"]});return t.status!==0||!t.stdout?!1:/^awsb\.exe$/i.test(t.stdout.trim())}catch{return!1}}function Fe(e){if(!process.stdin.isTTY)return Promise.resolve("n");const r=X({input:process.stdin,output:process.stdout});return r.question(e).finally(()=>r.close())}async function He(e,r,t){const s=e.runCommand||_,i=e.platform||process.platform,n=e.findRunningBridgeProcesses||Ae,a=e.prompt||Fe,d=e.killBridgeProcess||Me,u=e.globalModulePath||de;r("[runtime-bridge] \u6B63\u5728\u66F4\u65B0 aws-runtime-bridge \u5230\u6700\u65B0\u7248\u672C...");let l=!1;if(e.skipKill)l=!0,r("[runtime-bridge] \u5DF2\u6307\u5B9A --no-kill\uFF0C\u8DF3\u8FC7\u8FD0\u884C\u8FDB\u7A0B\u68C0\u6D4B\uFF0C\u5C06\u4EE5 --force \u65B9\u5F0F\u5B89\u88C5\u3002");else{const S=n(i).filter(f=>f!==process.pid);if(S.length>0)if(r(`[runtime-bridge] \u68C0\u6D4B\u5230 aws-runtime-bridge \u6B63\u5728\u8FD0\u884C (PID: ${S.join(", ")})\uFF0C\u66F4\u65B0\u65F6\u8FD9\u4E9B\u8FDB\u7A0B\u53EF\u80FD\u5360\u7528\u6587\u4EF6\u5BFC\u81F4\u8986\u76D6\u5931\u8D25\u3002`),e.assumeYes){r("[runtime-bridge] \u975E\u4EA4\u4E92\u6A21\u5F0F(--yes)\uFF0C\u81EA\u52A8\u5173\u95ED\u4E0A\u8FF0\u8FDB\u7A0B\u4EE5\u7EE7\u7EED\u66F4\u65B0...");for(const f of S)try{d(f,i),r(`[runtime-bridge] \u5DF2\u5173\u95ED\u8FDB\u7A0B PID: ${f}`)}catch(v){const E=v instanceof Error?v:new Error(String(v));t(`[runtime-bridge] \u5173\u95ED\u8FDB\u7A0B PID ${f} \u5931\u8D25: ${E.message}`)}}else{const f=(await a("\u662F\u5426\u5173\u95ED\u4E0A\u8FF0\u8FDB\u7A0B\u4EE5\u7EE7\u7EED\u66F4\u65B0? (y/N) ")).trim().toLowerCase();if(f==="y"||f==="yes")for(const v of S)try{d(v,i),r(`[runtime-bridge] \u5DF2\u5173\u95ED\u8FDB\u7A0B PID: ${v}`)}catch(E){const z=E instanceof Error?E:new Error(String(E));t(`[runtime-bridge] \u5173\u95ED\u8FDB\u7A0B PID ${v} \u5931\u8D25: ${z.message}`)}else l=!0,r("[runtime-bridge] \u5DF2\u9009\u62E9\u4E0D\u5173\u95ED\u8FDB\u7A0B\uFF0C\u5C06\u4EE5 --force \u65B9\u5F0F\u5F3A\u5236\u5B89\u88C5\uFF08\u82E5\u6587\u4EF6\u4ECD\u88AB\u5360\u7528\u53EF\u80FD\u4F1A\u6709\u8B66\u544A\uFF09\u3002")}}const x=u();if(x){const S=m.join(x,"aws-runtime-bridge");if(h(S)){r("[runtime-bridge] \u6E05\u7406\u65E7\u7248\u672C\u6B8B\u7559\u76EE\u5F55...");try{ee(S,{recursive:!0,force:!0})}catch(f){const v=f instanceof Error?f:new Error(String(f));t(`[runtime-bridge] \u6E05\u7406\u6B8B\u7559\u76EE\u5F55\u5931\u8D25\uFF08\u5C06\u5C1D\u8BD5\u7EE7\u7EED\u5B89\u88C5\uFF09: ${v.message}`)}}}const F=["install","-g","aws-runtime-bridge@latest","--omit=optional"];l&&F.push("--force");const y=s("npm",F);if(y.error)return t(`[runtime-bridge] \u66F4\u65B0\u5931\u8D25: ${y.error.message}`),{handled:!0,exitCode:1};if(y.status!==0)return t(`[runtime-bridge] \u66F4\u65B0\u5931\u8D25\uFF0Cnpm \u9000\u51FA\u7801: ${y.status??"unknown"}`),{handled:!0,exitCode:y.status??1};if(i==="win32"){const S=await Ge(e,r,t);if(S.exitCode!==0)return S}return r("[runtime-bridge] \u66F4\u65B0\u5B8C\u6210\u3002\u8BF7\u91CD\u65B0\u8FD0\u884C awsb -v \u67E5\u770B\u5F53\u524D\u7248\u672C\u3002"),{handled:!0,exitCode:0}}async function Ge(e,r,t){const s=e.runCommand||_,i=s("sc.exe",["query",c]);if(!o(i))return{handled:!0,exitCode:0};r("[runtime-bridge] \u68C0\u6D4B\u5230 Windows \u670D\u52A1\u5DF2\u6CE8\u518C\uFF0C\u6B63\u5728\u91CD\u5EFA\u670D\u52A1\u6587\u4EF6\uFF08daemon/winsw.exe\uFF09..."),s("sc.exe",["stop",c]);const n=s("sc.exe",["delete",c]);o(n)||t(`[runtime-bridge] \u5220\u9664\u65E7 SCM \u8BB0\u5F55\u5931\u8D25: ${n.error?.message??`\u9000\u51FA\u7801 ${n.status??"unknown"}`}\uFF08\u5C1D\u8BD5\u7EE7\u7EED\u5B89\u88C5\uFF09`);const a={stdout:r,stderr:t,runCommand:s,platform:"win32",serviceUnitPath:e.serviceUnitPath||N,executablePath:e.executablePath||K(),windowsServiceManager:e.windowsServiceManager};try{return(await O(a)).exitCode!==0?(t("[runtime-bridge] \u91CD\u5EFA Windows \u670D\u52A1\u6587\u4EF6\u5931\u8D25\u3002\u5305\u5DF2\u66F4\u65B0\uFF0C\u8BF7\u624B\u52A8\u6267\u884C `awsb service uninstall && awsb service install` \u4FEE\u590D\u670D\u52A1\u3002"),{handled:!0,exitCode:0}):(r("[runtime-bridge] Windows \u670D\u52A1\u6587\u4EF6\u5DF2\u91CD\u5EFA\u3002"),{handled:!0,exitCode:0})}catch(d){const u=d instanceof Error?d:new Error(String(d));return t(`[runtime-bridge] \u91CD\u5EFA Windows \u670D\u52A1\u6587\u4EF6\u5F02\u5E38: ${u.message}\u3002\u5305\u5DF2\u66F4\u65B0\uFF0C\u8BF7\u624B\u52A8\u6267\u884C \`awsb service uninstall && awsb service install\` \u4FEE\u590D\u670D\u52A1\u3002`),{handled:!0,exitCode:0}}}function je(e,r,t){const i=(e.argv||process.argv.slice(2)).slice(1).some(u=>u==="--follow"||u==="-f"),n=e.platform||process.platform,a=e.runCommand||_,d=e.serviceUnitPath||N;if(n==="linux"){if(!h(d))return t("[runtime-bridge] awsb \u670D\u52A1\u5C1A\u672A\u5B89\u88C5\uFF08awsb service install\uFF09\uFF0C\u65E0\u65E5\u5FD7\u53EF\u67E5\u770B\u3002"),{handled:!0,exitCode:1};const u=["-u",w];i?u.push("-f"):u.push("-n","200","--no-pager");const l=a("journalctl",u);return l.error?(t(`[runtime-bridge] \u8BFB\u53D6\u65E5\u5FD7\u5931\u8D25: ${l.error.message}`),{handled:!0,exitCode:1}):{handled:!0,exitCode:l.status??0}}if(n==="win32"){const u=e.windowsServiceLogPath||B;if(!h(u))return t(`[runtime-bridge] \u5C1A\u672A\u751F\u6210\u65E5\u5FD7\u6587\u4EF6: ${u}\u3002\u8BF7\u5148\u6267\u884C \`awsb service install\` \u5E76\u8FD0\u884C\u670D\u52A1\u3002`),{handled:!0,exitCode:1};const l=`Get-Content -Encoding UTF8 -Tail 200 "${u}"`+(i?" -Wait":""),x=a("powershell",["-NoProfile","-Command",l]);return x.error?(t(`[runtime-bridge] \u8BFB\u53D6\u65E5\u5FD7\u5931\u8D25: ${x.error.message}`),{handled:!0,exitCode:1}):{handled:!0,exitCode:x.status??0}}if(n==="darwin"){const u=e.launchdLogPath||U;if(!h(u))return t(`[runtime-bridge] \u5C1A\u672A\u751F\u6210\u65E5\u5FD7\u6587\u4EF6: ${u}\u3002\u8BF7\u5148\u6267\u884C \`awsb service install\` \u5E76\u8FD0\u884C\u670D\u52A1\u3002`),{handled:!0,exitCode:1};const x=a("tail",i?["-f",u]:["-n","200",u]);return x.error?(t(`[runtime-bridge] \u8BFB\u53D6\u65E5\u5FD7\u5931\u8D25: ${x.error.message}`),{handled:!0,exitCode:1}):{handled:!0,exitCode:x.status??0}}return t("[runtime-bridge] awsb log \u4EC5\u652F\u6301 Linux systemd\u3001Windows \u670D\u52A1\u4E0E macOS launchd \u73AF\u5883\u3002"),{handled:!0,exitCode:1}}async function Ze(e={}){const r=e.argv||process.argv.slice(2),t=r[0],s=e.stdout||ce,i=e.stderr||le;if(me(t))return s(`aws-runtime-bridge ${ue(e.packageRoot)}`),{handled:!0,exitCode:0};if(t==="update"){const n=r.includes("--yes")||r.includes("-y"),a=r.includes("--no-kill"),d=n||a?{...e,assumeYes:n,skipKill:a}:e;return await He(d,s,i)}if(t==="config"){const n=r[1];if(n==="example"||n==="minimal"||n==="--minimal"||n==="-m")return{handled:!0,exitCode:await(e.configureExample||te)()==="created"?0:1};const d=await(e.configure||re)();return{handled:!0,exitCode:d==="configured"||d==="created"?0:1}}return t==="service"?await Ne(r,e,s,i):t==="log"?je(e,s,i):{handled:!1,exitCode:0}}export{he as createLaunchdPlistContent,ge as createSystemdUnitContent,Ae as defaultFindRunningBridgeProcesses,Me as defaultKillBridgeProcess,Ze as handleCliCommand,ue as readPackageVersion};
6
+ npm install -g aws-runtime-bridge`),{handled:!0,exitCode:1}}async function O(e){const r=e.windowsServiceManager;if(!r&&!ie())return ve(e.stderr);const t=e.windowsServiceLogPath||B,s=m.dirname(e.executablePath),i=D.homedir();try{await(r||se()).install({name:q,description:"awsb runtime bridge",script:e.executablePath,workingDirectory:s,env:[{name:"AWS_BRIDGE_SKIP_SETUP",value:"true"},{name:"AWS_RUNTIME_HOME_DIR",value:i}],logpath:A()})}catch(u){const l=u instanceof Error?u:new Error(String(u));return e.stderr(`[runtime-bridge] \u5B89\u88C5 Windows \u670D\u52A1\u5931\u8D25: ${l.message}`),{handled:!0,exitCode:1}}const n=e.runCommand("sc.exe",["start",c]);if(!o(n))return e.stderr(`[runtime-bridge] \u542F\u52A8 Windows \u670D\u52A1\u5931\u8D25: ${n.error?.message??`\u9000\u51FA\u7801 ${n.status??"unknown"}`}`),{handled:!0,exitCode:n.status??1};const a=["failure",c,"reset=","86400","actions=","restart/5000/restart/10000/restart/30000"],d=e.runCommand("sc.exe",a);return o(d)?e.stdout("[runtime-bridge] \u5DF2\u914D\u7F6E awsb \u670D\u52A1\u5931\u8D25\u81EA\u52A8\u91CD\u542F\uFF085s/10s/30s\uFF09\u3002"):e.stderr(`[runtime-bridge] \u914D\u7F6E\u670D\u52A1\u5931\u8D25\u81EA\u52A8\u91CD\u542F\u672A\u751F\u6548\uFF08\u53EF\u5FFD\u7565\uFF09: ${d.error?.message??`\u9000\u51FA\u7801 ${d.status??"unknown"}`}`),e.stdout(`[runtime-bridge] awsb Windows \u670D\u52A1\u5DF2\u5B89\u88C5\u5E76\u5DF2\u542F\u52A8\uFF08\u65E5\u5FD7: ${t}\uFF09\u3002`),{handled:!0,exitCode:0}}function Pe(e){const r=s=>e.runCommand("sc.exe",s);r(["stop",c]);const t=r(["delete",c]);return o(t)?(e.stdout("[runtime-bridge] awsb Windows \u670D\u52A1\u5DF2\u5378\u8F7D\u3002"),{handled:!0,exitCode:0}):(e.stderr(`[runtime-bridge] \u5378\u8F7D Windows \u670D\u52A1\u5931\u8D25: ${t.error?.message??`\u9000\u51FA\u7801 ${t.status??"unknown"}`}`),{handled:!0,exitCode:t.status??1})}async function ye(e){e.runCommand("sc.exe",["stop",c]);const r=e.queryWindowsServiceState||M;return V(r,c)||e.stdout("[runtime-bridge] \u7B49\u5F85 Windows \u670D\u52A1\u505C\u6B62\u8D85\u65F6\uFF0C\u4ECD\u5C1D\u8BD5\u542F\u52A8\uFF08\u53EF\u80FD\u62A5 1056\uFF09\u3002"),J(e,"\u91CD\u542F")}async function Ee(e){return J(e,"\u542F\u52A8")}const $e=2,Re=1056;async function J(e,r){const t=e.runCommand("sc.exe",["start",c]);if(o(t))return e.stdout(`[runtime-bridge] awsb Windows \u670D\u52A1\u5DF2${r}\u3002`),{handled:!0,exitCode:0};if(t.status===Re)return e.stdout(`[runtime-bridge] awsb Windows \u670D\u52A1\u5DF2\u5728\u8FD0\u884C\u4E2D\uFF08\u65E0\u9700${r}\uFF09\u3002`),{handled:!0,exitCode:0};if(t.status===$e){e.stdout("[runtime-bridge] \u68C0\u6D4B\u5230 Windows \u670D\u52A1\u4E8C\u8FDB\u5236\u6587\u4EF6\u4E22\u5931\uFF08winsw.exe\uFF09\uFF0C\u6B63\u5728\u91CD\u5EFA..."),e.runCommand("sc.exe",["delete",c]);try{const s=await O(e);return s.exitCode!==0&&e.stderr(`[runtime-bridge] ${r} Windows \u670D\u52A1\u5931\u8D25\u4E14\u81EA\u52A8\u91CD\u5EFA\u5931\u8D25\u3002\u8BF7\u624B\u52A8\u6267\u884C \`awsb service uninstall && awsb service install\` \u4FEE\u590D\u3002`),s}catch(s){const i=s instanceof Error?s:new Error(String(s));return e.stderr(`[runtime-bridge] ${r} Windows \u670D\u52A1\u5931\u8D25\u4E14\u81EA\u52A8\u91CD\u5EFA\u5F02\u5E38: ${i.message}\u3002\u8BF7\u624B\u52A8\u6267\u884C \`awsb service uninstall && awsb service install\` \u4FEE\u590D\u3002`),{handled:!0,exitCode:1}}}return e.stderr(`[runtime-bridge] ${r} Windows \u670D\u52A1\u5931\u8D25: ${t.error?.message??`\u9000\u51FA\u7801 ${t.status??"unknown"}`}`),{handled:!0,exitCode:t.status??1}}function ke(e){const r=e.runCommand("sc.exe",["stop",c]);return o(r)?(e.stdout("[runtime-bridge] awsb Windows \u670D\u52A1\u5DF2\u505C\u6B62\u3002"),{handled:!0,exitCode:0}):(e.stderr(`[runtime-bridge] \u505C\u6B62 Windows \u670D\u52A1\u5931\u8D25: ${r.error?.message??`\u9000\u51FA\u7801 ${r.status??"unknown"}`}`),{handled:!0,exitCode:r.status??1})}function pe(){return`gui/${process.getuid?.()??0}`}function k(e){return e.launchdDomainTarget||pe()}function p(e){return`${e}/${L}`}function W(e,r){return r.error?`[runtime-bridge] ${e}\u5931\u8D25: ${r.error.message}`:`[runtime-bridge] ${e}\u5931\u8D25\uFF0Claunchctl \u9000\u51FA\u7801: ${r.status??"unknown"}`}function We(e){if(!R(e.platform,e.stderr))return{handled:!0,exitCode:1};const r=e.launchdPlistPath||T,t=e.launchdLogPath||U,s=he(e.executablePath,{userHomeDir:D.homedir(),logPath:t});try{I(m.dirname(r),{recursive:!0}),I(m.dirname(t),{recursive:!0}),G(r,s,{encoding:"utf-8",mode:420})}catch(a){const d=a instanceof Error?a:new Error(String(a));return e.stderr(`[runtime-bridge] \u5199\u5165 launchd plist \u5931\u8D25: ${d.message}`),{handled:!0,exitCode:1}}const i=k(e);e.runCommand("launchctl",["bootout",p(i)]);const n=e.runCommand("launchctl",["bootstrap",i,r]);return o(n)?(e.stdout(`[runtime-bridge] awsb launchd \u670D\u52A1\u5DF2\u5B89\u88C5\u5E76\u5DF2\u542F\u52A8\uFF08\u65E5\u5FD7: ${t}\uFF09\u3002`),{handled:!0,exitCode:0}):(e.stderr(W("\u5B89\u88C5 awsb \u670D\u52A1",n)),{handled:!0,exitCode:n.status??1})}function De(e){if(!R(e.platform,e.stderr))return{handled:!0,exitCode:1};const r=e.launchdPlistPath||T,t=k(e),s=p(t),i=e.runCommand("launchctl",["bootout",s]);if(i.error)return e.stderr(W("\u5378\u8F7D awsb \u670D\u52A1",i)),{handled:!0,exitCode:1};if(h(r))try{H(r)}catch(n){const a=n instanceof Error?n:new Error(String(n));return e.stderr(`[runtime-bridge] \u5220\u9664 launchd plist \u5931\u8D25: ${a.message}`),{handled:!0,exitCode:1}}else e.stdout("[runtime-bridge] awsb launchd plist \u4E0D\u5B58\u5728\uFF0C\u8DF3\u8FC7\u5220\u9664\u3002");return e.stdout("[runtime-bridge] awsb launchd \u670D\u52A1\u5DF2\u5378\u8F7D\u3002"),{handled:!0,exitCode:0}}function Te(e){if(!R(e.platform,e.stderr))return{handled:!0,exitCode:1};const r=e.launchdPlistPath||T;if(!h(r))return e.stderr("[runtime-bridge] awsb launchd \u670D\u52A1\u5C1A\u672A\u5B89\u88C5\uFF0C\u8BF7\u5148\u6267\u884C `awsb service install`\u3002"),{handled:!0,exitCode:1};const t=k(e),s=p(t),i=e.runCommand("launchctl",["kickstart",s]);if(o(i))return e.stdout("[runtime-bridge] awsb launchd \u670D\u52A1\u5DF2\u542F\u52A8\u3002"),{handled:!0,exitCode:0};const n=e.runCommand("launchctl",["bootstrap",t,r]);return o(n)?(e.stdout("[runtime-bridge] awsb launchd \u670D\u52A1\u5DF2\u542F\u52A8\u3002"),{handled:!0,exitCode:0}):(e.stderr(W("\u542F\u52A8 awsb \u670D\u52A1",n)),{handled:!0,exitCode:n.status??1})}function _e(e){if(!R(e.platform,e.stderr))return{handled:!0,exitCode:1};const r=k(e),t=e.runCommand("launchctl",["bootout",p(r)]);return o(t)?(e.stdout("[runtime-bridge] awsb launchd \u670D\u52A1\u5DF2\u505C\u6B62\u3002"),{handled:!0,exitCode:0}):(e.stderr(W("\u505C\u6B62 awsb \u670D\u52A1",t)),{handled:!0,exitCode:t.status??1})}function Ie(e){if(!R(e.platform,e.stderr))return{handled:!0,exitCode:1};const r=e.launchdPlistPath||T;if(!h(r))return e.stderr("[runtime-bridge] awsb launchd \u670D\u52A1\u5C1A\u672A\u5B89\u88C5\uFF0C\u8BF7\u5148\u6267\u884C `awsb service install`\u3002"),{handled:!0,exitCode:1};const t=k(e);e.runCommand("launchctl",["bootout",p(t)]);const s=e.runCommand("launchctl",["bootstrap",t,r]);return o(s)?(e.stdout("[runtime-bridge] awsb launchd \u670D\u52A1\u5DF2\u91CD\u542F\u3002"),{handled:!0,exitCode:0}):(e.stderr(W("\u91CD\u542F awsb \u670D\u52A1",s)),{handled:!0,exitCode:s.status??1})}async function Ne(e,r,t,s){const i=e[1];if(!i||i==="-h"||i==="--help"||i==="help")return Y(t),{handled:!0,exitCode:i?0:1};const n={stdout:t,stderr:s,runCommand:r.runCommand||_,platform:r.platform||process.platform,serviceUnitPath:r.serviceUnitPath||N,executablePath:r.executablePath||K(),windowsServiceManager:r.windowsServiceManager,launchdPlistPath:r.launchdPlistPath,launchdLogPath:r.launchdLogPath,launchdDomainTarget:r.launchdDomainTarget,queryWindowsServiceState:r.queryWindowsServiceState||M};return n.platform!=="linux"&&n.platform!=="win32"&&n.platform!=="darwin"?(s("[runtime-bridge] service \u547D\u4EE4\u4EC5\u652F\u6301 Linux systemd\u3001Windows \u670D\u52A1\u4E0E macOS launchd \u73AF\u5883\u3002"),{handled:!0,exitCode:1}):i==="install"?n.platform==="win32"?await O(n):n.platform==="darwin"?We(n):we(n):i==="uninstall"?n.platform==="win32"?Pe(n):n.platform==="darwin"?De(n):be(n):i==="restart"?n.platform==="win32"?ye(n):n.platform==="darwin"?Ie(n):Ce(n):i==="start"?n.platform==="win32"?Ee(n):n.platform==="darwin"?Te(n):xe(n):i==="stop"?n.platform==="win32"?ke(n):n.platform==="darwin"?_e(n):Se(n):(s(`[runtime-bridge] \u672A\u77E5 service \u5B50\u547D\u4EE4: ${i}`),Y(t),{handled:!0,exitCode:1})}function Q(e){return e?e.split(/\r?\n/).map(r=>r.trim()).filter(r=>/^\d+$/.test(r)).map(Number):[]}function Ae(e){try{if(e==="win32"){const t=g("powershell",["-NoProfile","-Command",`Get-CimInstance Win32_Process -Filter "Name='node.exe'" | Where-Object { $_.CommandLine -like '*aws-runtime-bridge*' -and $_.ProcessId -ne ${process.pid} } | ForEach-Object { $_.ProcessId }`],{encoding:"utf-8"}),s=Le(e);return Ue([...Q(t.stdout),...s]).filter(i=>i!==process.pid)}const r=g("pgrep",["-f","aws-runtime-bridge"],{encoding:"utf-8"});return Q(r.stdout).filter(t=>t!==process.pid)}catch{return[]}}function Le(e){if(e!=="win32")return[];try{const r=g("sc.exe",["query",c],{encoding:"utf-8",shell:!0,stdio:["ignore","pipe","ignore"]});if(r.status!==0||!r.stdout)return[];const t=r.stdout.match(/STATE\s*:\s*\d+\s+(\S+)/);if(!t)return[];const s=t[1];if(s!=="RUNNING"&&s!=="START_PENDING"&&s!=="STOP_PENDING")return[];const i=g("tasklist",["/FI","IMAGENAME eq awsb.exe","/FO","CSV","/NH"],{encoding:"utf-8",shell:!0,stdio:["ignore","pipe","ignore"]});return i.status!==0||!i.stdout?[]:i.stdout.split(/\r?\n/).map(n=>n.trim()).filter(n=>n.length>0).map(n=>{const a=n.match(/^"awsb\.exe","(\d+)"/i);return a?Number(a[1]):NaN}).filter(n=>Number.isFinite(n)&&n>0)}catch{return[]}}function Ue(e){const r=new Set,t=[];for(const s of e)r.has(s)||(r.add(s),t.push(s));return t}function Me(e,r){if(r==="win32"){if(Oe(e,r)){g("sc.exe",["stop",c],{stdio:"ignore",shell:!0}),V(M,c);return}g("taskkill",["/PID",String(e),"/F","/T"],{stdio:"ignore"});return}g("kill",["-9",String(e)],{stdio:"ignore"})}function Oe(e,r){if(r!=="win32"||!Number.isFinite(e)||e<=0)return!1;try{const t=g("powershell",["-NoProfile","-Command",`(Get-CimInstance Win32_Process -Filter "ProcessId=${e}" -ErrorAction SilentlyContinue).Name`],{encoding:"utf-8",stdio:["ignore","pipe","ignore"]});return t.status!==0||!t.stdout?!1:/^awsb\.exe$/i.test(t.stdout.trim())}catch{return!1}}function Fe(e){if(!process.stdin.isTTY)return Promise.resolve("n");const r=ee({input:process.stdin,output:process.stdout});return r.question(e).finally(()=>r.close())}async function He(e,r,t){const s=e.runCommand||_,i=e.platform||process.platform,n=e.findRunningBridgeProcesses||Ae,a=e.prompt||Fe,d=e.killBridgeProcess||Me,u=e.globalModulePath||de;r("[runtime-bridge] \u6B63\u5728\u66F4\u65B0 aws-runtime-bridge \u5230\u6700\u65B0\u7248\u672C...");let l=!1;if(e.skipKill)l=!0,r("[runtime-bridge] \u5DF2\u6307\u5B9A --no-kill\uFF0C\u8DF3\u8FC7\u8FD0\u884C\u8FDB\u7A0B\u68C0\u6D4B\uFF0C\u5C06\u4EE5 --force \u65B9\u5F0F\u5B89\u88C5\u3002");else{const S=n(i).filter(f=>f!==process.pid);if(S.length>0)if(r(`[runtime-bridge] \u68C0\u6D4B\u5230 aws-runtime-bridge \u6B63\u5728\u8FD0\u884C (PID: ${S.join(", ")})\uFF0C\u66F4\u65B0\u65F6\u8FD9\u4E9B\u8FDB\u7A0B\u53EF\u80FD\u5360\u7528\u6587\u4EF6\u5BFC\u81F4\u8986\u76D6\u5931\u8D25\u3002`),e.assumeYes){r("[runtime-bridge] \u975E\u4EA4\u4E92\u6A21\u5F0F(--yes)\uFF0C\u81EA\u52A8\u5173\u95ED\u4E0A\u8FF0\u8FDB\u7A0B\u4EE5\u7EE7\u7EED\u66F4\u65B0...");for(const f of S)try{d(f,i),r(`[runtime-bridge] \u5DF2\u5173\u95ED\u8FDB\u7A0B PID: ${f}`)}catch(v){const E=v instanceof Error?v:new Error(String(v));t(`[runtime-bridge] \u5173\u95ED\u8FDB\u7A0B PID ${f} \u5931\u8D25: ${E.message}`)}}else{const f=(await a("\u662F\u5426\u5173\u95ED\u4E0A\u8FF0\u8FDB\u7A0B\u4EE5\u7EE7\u7EED\u66F4\u65B0? (y/N) ")).trim().toLowerCase();if(f==="y"||f==="yes")for(const v of S)try{d(v,i),r(`[runtime-bridge] \u5DF2\u5173\u95ED\u8FDB\u7A0B PID: ${v}`)}catch(E){const z=E instanceof Error?E:new Error(String(E));t(`[runtime-bridge] \u5173\u95ED\u8FDB\u7A0B PID ${v} \u5931\u8D25: ${z.message}`)}else l=!0,r("[runtime-bridge] \u5DF2\u9009\u62E9\u4E0D\u5173\u95ED\u8FDB\u7A0B\uFF0C\u5C06\u4EE5 --force \u65B9\u5F0F\u5F3A\u5236\u5B89\u88C5\uFF08\u82E5\u6587\u4EF6\u4ECD\u88AB\u5360\u7528\u53EF\u80FD\u4F1A\u6709\u8B66\u544A\uFF09\u3002")}}const x=u();if(x){const S=m.join(x,"aws-runtime-bridge");if(h(S)){r("[runtime-bridge] \u6E05\u7406\u65E7\u7248\u672C\u6B8B\u7559\u76EE\u5F55...");try{Z(S,{recursive:!0,force:!0})}catch(f){const v=f instanceof Error?f:new Error(String(f));t(`[runtime-bridge] \u6E05\u7406\u6B8B\u7559\u76EE\u5F55\u5931\u8D25\uFF08\u5C06\u5C1D\u8BD5\u7EE7\u7EED\u5B89\u88C5\uFF09: ${v.message}`)}}}const F=["install","-g","aws-runtime-bridge@latest","--omit=optional"];l&&F.push("--force");const y=s("npm",F);if(y.error)return t(`[runtime-bridge] \u66F4\u65B0\u5931\u8D25: ${y.error.message}`),{handled:!0,exitCode:1};if(y.status!==0)return t(`[runtime-bridge] \u66F4\u65B0\u5931\u8D25\uFF0Cnpm \u9000\u51FA\u7801: ${y.status??"unknown"}`),{handled:!0,exitCode:y.status??1};if(i==="win32"){const S=await Ge(e,r,t);if(S.exitCode!==0)return S}return r("[runtime-bridge] \u66F4\u65B0\u5B8C\u6210\u3002\u8BF7\u91CD\u65B0\u8FD0\u884C awsb -v \u67E5\u770B\u5F53\u524D\u7248\u672C\u3002"),{handled:!0,exitCode:0}}async function Ge(e,r,t){const s=e.runCommand||_,i=s("sc.exe",["query",c]);if(!o(i))return{handled:!0,exitCode:0};r("[runtime-bridge] \u68C0\u6D4B\u5230 Windows \u670D\u52A1\u5DF2\u6CE8\u518C\uFF0C\u6B63\u5728\u91CD\u5EFA\u670D\u52A1\u6587\u4EF6\uFF08daemon/winsw.exe\uFF09..."),s("sc.exe",["stop",c]);const n=s("sc.exe",["delete",c]);o(n)||t(`[runtime-bridge] \u5220\u9664\u65E7 SCM \u8BB0\u5F55\u5931\u8D25: ${n.error?.message??`\u9000\u51FA\u7801 ${n.status??"unknown"}`}\uFF08\u5C1D\u8BD5\u7EE7\u7EED\u5B89\u88C5\uFF09`);const a={stdout:r,stderr:t,runCommand:s,platform:"win32",serviceUnitPath:e.serviceUnitPath||N,executablePath:e.executablePath||K(),windowsServiceManager:e.windowsServiceManager};try{return(await O(a)).exitCode!==0?(t("[runtime-bridge] \u91CD\u5EFA Windows \u670D\u52A1\u6587\u4EF6\u5931\u8D25\u3002\u5305\u5DF2\u66F4\u65B0\uFF0C\u8BF7\u624B\u52A8\u6267\u884C `awsb service uninstall && awsb service install` \u4FEE\u590D\u670D\u52A1\u3002"),{handled:!0,exitCode:0}):(r("[runtime-bridge] Windows \u670D\u52A1\u6587\u4EF6\u5DF2\u91CD\u5EFA\u3002"),{handled:!0,exitCode:0})}catch(d){const u=d instanceof Error?d:new Error(String(d));return t(`[runtime-bridge] \u91CD\u5EFA Windows \u670D\u52A1\u6587\u4EF6\u5F02\u5E38: ${u.message}\u3002\u5305\u5DF2\u66F4\u65B0\uFF0C\u8BF7\u624B\u52A8\u6267\u884C \`awsb service uninstall && awsb service install\` \u4FEE\u590D\u670D\u52A1\u3002`),{handled:!0,exitCode:0}}}function je(e,r,t){const i=(e.argv||process.argv.slice(2)).slice(1).some(u=>u==="--follow"||u==="-f"),n=e.platform||process.platform,a=e.runCommand||_,d=e.serviceUnitPath||N;if(n==="linux"){if(!h(d))return t("[runtime-bridge] awsb \u670D\u52A1\u5C1A\u672A\u5B89\u88C5\uFF08awsb service install\uFF09\uFF0C\u65E0\u65E5\u5FD7\u53EF\u67E5\u770B\u3002"),{handled:!0,exitCode:1};const u=["-u",w];i?u.push("-f"):u.push("-n","200","--no-pager");const l=a("journalctl",u);return l.error?(t(`[runtime-bridge] \u8BFB\u53D6\u65E5\u5FD7\u5931\u8D25: ${l.error.message}`),{handled:!0,exitCode:1}):{handled:!0,exitCode:l.status??0}}if(n==="win32"){const u=e.windowsServiceLogPath||B;if(!h(u))return t(`[runtime-bridge] \u5C1A\u672A\u751F\u6210\u65E5\u5FD7\u6587\u4EF6: ${u}\u3002\u8BF7\u5148\u6267\u884C \`awsb service install\` \u5E76\u8FD0\u884C\u670D\u52A1\u3002`),{handled:!0,exitCode:1};const l=`Get-Content -Encoding UTF8 -Tail 200 "${u}"`+(i?" -Wait":""),x=a("powershell",["-NoProfile","-Command",l]);return x.error?(t(`[runtime-bridge] \u8BFB\u53D6\u65E5\u5FD7\u5931\u8D25: ${x.error.message}`),{handled:!0,exitCode:1}):{handled:!0,exitCode:x.status??0}}if(n==="darwin"){const u=e.launchdLogPath||U;if(!h(u))return t(`[runtime-bridge] \u5C1A\u672A\u751F\u6210\u65E5\u5FD7\u6587\u4EF6: ${u}\u3002\u8BF7\u5148\u6267\u884C \`awsb service install\` \u5E76\u8FD0\u884C\u670D\u52A1\u3002`),{handled:!0,exitCode:1};const x=a("tail",i?["-f",u]:["-n","200",u]);return x.error?(t(`[runtime-bridge] \u8BFB\u53D6\u65E5\u5FD7\u5931\u8D25: ${x.error.message}`),{handled:!0,exitCode:1}):{handled:!0,exitCode:x.status??0}}return t("[runtime-bridge] awsb log \u4EC5\u652F\u6301 Linux systemd\u3001Windows \u670D\u52A1\u4E0E macOS launchd \u73AF\u5883\u3002"),{handled:!0,exitCode:1}}async function Ze(e={}){const r=e.argv||process.argv.slice(2),t=r[0],s=e.stdout||ce,i=e.stderr||le;if(me(t))return s(`aws-runtime-bridge ${ue(e.packageRoot)}`),{handled:!0,exitCode:0};if(t==="update"){const n=r.includes("--yes")||r.includes("-y"),a=r.includes("--no-kill"),d=n||a?{...e,assumeYes:n,skipKill:a}:e;return await He(d,s,i)}if(t==="config"){const n=r[1];if(n==="example"||n==="minimal"||n==="--minimal"||n==="-m")return{handled:!0,exitCode:await(e.configureExample||ne)()==="created"?0:1};const d=await(e.configure||te)();return{handled:!0,exitCode:d==="configured"||d==="created"?0:1}}return t==="service"?await Ne(r,e,s,i):t==="log"?je(e,s,i):{handled:!1,exitCode:0}}export{he as createLaunchdPlistContent,ge as createSystemdUnitContent,Ae as defaultFindRunningBridgeProcesses,Me as defaultKillBridgeProcess,Ze as handleCliCommand,ue as readPackageVersion};
7
7
 
@@ -1,2 +1,2 @@
1
- import{access as b,constants as P}from"node:fs/promises";import{getPanelEnvVars as M}from"./panel-env.js";import{join as m,resolve as O}from"node:path";import{createBuiltInDesktopTools as w}from"../desktop/built-in-desktop-tools.js";import{DesktopMcpConnection as T}from"../desktop/desktop-mcp-client.js";import{logger as C}from"../utils/logger.js";import{DESKTOP_FEATURE_KEY as D,isFeatureEnabled as I}from"./instance-features.js";const d=C.child("desktop-mcp");let n=null,c=null,r=null,l,f="none";const k=process.platform==="win32"?"nuphus-mcp.exe":"nuphus-mcp",N=12e4,U=6e4;function x(){const e=process.env.AWS_DESKTOP_MCP_TIMEOUT_MS;if(e){const t=parseInt(e,10);if(Number.isFinite(t)&&t>0)return t}return N}function A(){const e=process.env.AWS_DESKTOP_MCP_RETRY_BACKOFF_MS;if(e){const t=parseInt(e,10);if(Number.isFinite(t)&&t>=0)return t}return U}async function K(){const e=process.env.AWS_DESKTOP_MCP_BIN;if(e){const o=O(e);return await g(o)?o:null}const t=m(process.cwd(),".desktop-mcp","bin",k);return await g(t)?t:null}async function g(e){try{return await b(e,P.F_OK),!0}catch{return!1}}function $(){const e={},t="AWS_DESKTOP_MCP_ENV_";for(const[o,s]of Object.entries(process.env))o.startsWith(t)&&s!==void 0&&(e[o.slice(t.length)]=s);return e}function h(){const e={...$(),...M()},t=e.NUPHUS_MCP_VISION_API_KEY!==void 0||e.NUPHUS_MCP_VISION_MODEL!==void 0;return!t&&l?.apiKey&&l.supportsImage===!0?(f="agent-fallback",e.NUPHUS_MCP_VISION_API_KEY=l.apiKey,e.NUPHUS_MCP_VISION_MODEL=l.model,l.baseURL&&(e.NUPHUS_MCP_VISION_BASE_URL=l.baseURL),d.info(`vision model fallback: reusing agent model ${l.model} for desktop_vision`)):t?f="panel-env":f="none",e}function S(e){return Object.keys(e).sort().map(t=>`${t}=${e[t]}`).join("\0")}async function y(){if(n){if(n.connection.isConnected())return n;await _(n.connection),n=null}if(c)return c;if(r){if(r.reason==="binary-missing"||Date.now()-r.at<A())return null;r=null}return c=(async()=>{const e=await K();if(!e)return r={reason:"binary-missing",message:`nuphus-mcp binary not found. Set AWS_DESKTOP_MCP_BIN or place it at ${m(process.cwd(),".desktop-mcp","bin",k)}`,at:Date.now()},u(`desktop tools unavailable: ${r.message}`),null;const t=h(),o=new T({command:e,env:t,onUnexpectedClose:()=>{u("nuphus-mcp process exited unexpectedly; will restart on next use"),n?.connection===o&&(n=null)}});try{const s=await o.start(),i=x();r=null;const a={connection:o,tools:s,binaryPath:e,envSig:S(t),forwarder:(p,E)=>F(o,p,E,i)};return n=a,u(`nuphus-mcp started (${e}), ${s.filter(p=>p.name.startsWith("desktop_")).length} desktop tools available`),a}catch(s){return await _(o),r={reason:"start-failed",message:s.message,at:Date.now()},v(`nuphus-mcp start failed: ${r.message}`),null}finally{c=null}})(),c}async function F(e,t,o,s){try{return await e.callTool(t,o,s)}catch(i){if(e.isConnected())throw i;v(`nuphus-mcp connection lost during ${t}: ${i.message}; restarting`),n?.connection===e&&(n=null),await _(e);const a=await y();if(!a)throw new Error(`nuphus-mcp restart failed: ${r?.message??"unknown"}`);return a.connection.callTool(t,o,s)}}async function q(e,t){if(!e)return[];t?.model&&(l=t);const o=h(),s=S(o);n&&n.connection.isConnected()&&n.envSig!==s&&(u("nuphus-mcp env changed; restarting to apply new env"),await L());const i=await y();return i?w({tools:i.tools,forwarder:(a,p)=>I(e,D)?i.forwarder(a,p):(d.warn(`tool ${a} blocked: desktop capability disabled for ${e}`),Promise.resolve("desktop capability is disabled for this agent (toggled off while tools were exposed); stop calling desktop_* tools"))}):[]}function G(){const e=n;return!e||!e.connection.isConnected()?R.map(t=>({kind:"builtin",toolName:t,exposedName:t,description:`${t}\uFF08\u684C\u9762\u81EA\u52A8\u5316\u5DE5\u5177\uFF0Cnuphus-mcp \u672A\u8FD0\u884C\uFF09\u3002\u5206\u914D desktop \u5206\u7C7B\u540E\u6309\u9700\u542F\u52A8\u540E\u7AEF\uFF0C\u5177\u4F53\u5DE5\u5177\u4EE5\u542F\u52A8\u540E\u76EE\u5F55\u4E3A\u51C6\u3002`,inputSchema:{type:"object",properties:{}},category:"desktop",async execute(){return`${t} is not ready: nuphus-mcp backend is not running. Allocate the desktop catalog to lazily start it, then retry.`}})):w({tools:e.tools,forwarder:(t,o)=>e.forwarder(t,o)})}const R=["desktop_screenshot","desktop_window_screenshot","desktop_perceive","desktop_vision","desktop_input","desktop_mouse","desktop_mouse_drag","desktop_screen_size","desktop_clipboard_write","desktop_clipboard_clean","desktop_config","desktop_uia_tree","desktop_uia_click","desktop_window_activate","desktop_window_info","desktop_window_move","desktop_window_resize","desktop_windows_list"];async function L(){const e=n;if(n=null,r=null,c){try{await c}catch{}c=null}e&&(await _(e.connection),u("nuphus-mcp stopped"))}function J(){return{started:n!==null,binaryPath:n?.binaryPath??null,toolCount:n?n.tools.filter(e=>e.name.startsWith("desktop_")).length:0,failure:r,visionSource:f}}async function _(e){try{await e.close()}catch{}}function u(e){d.info(e)}function v(e){d.warn(e)}export{L as disposeDesktopMcpManager,J as getDesktopMcpStatus,q as getDesktopTools,G as getDesktopToolsIfReady,K as resolveDesktopMcpBinary,y as startDesktopMcpManager};
1
+ import{access as b,constants as P}from"node:fs/promises";import{join as m,resolve as M}from"node:path";import{createBuiltInDesktopTools as w}from"../desktop/built-in-desktop-tools.js";import{DesktopMcpConnection as O}from"../desktop/desktop-mcp-client.js";import{logger as T}from"../utils/logger.js";import{DESKTOP_FEATURE_KEY as C,isFeatureEnabled as D}from"./instance-features.js";import{getPanelEnvVars as I}from"./panel-env.js";const d=T.child("desktop-mcp");let n=null,c=null,r=null,l,f="none";const k=process.platform==="win32"?"nuphus-mcp.exe":"nuphus-mcp",N=12e4,U=6e4;function x(){const e=process.env.AWS_DESKTOP_MCP_TIMEOUT_MS;if(e){const t=parseInt(e,10);if(Number.isFinite(t)&&t>0)return t}return N}function A(){const e=process.env.AWS_DESKTOP_MCP_RETRY_BACKOFF_MS;if(e){const t=parseInt(e,10);if(Number.isFinite(t)&&t>=0)return t}return U}async function K(){const e=process.env.AWS_DESKTOP_MCP_BIN;if(e){const o=M(e);return await g(o)?o:null}const t=m(process.cwd(),".desktop-mcp","bin",k);return await g(t)?t:null}async function g(e){try{return await b(e,P.F_OK),!0}catch{return!1}}function $(){const e={},t="AWS_DESKTOP_MCP_ENV_";for(const[o,s]of Object.entries(process.env))o.startsWith(t)&&s!==void 0&&(e[o.slice(t.length)]=s);return e}function h(){const e={...$(),...I()},t=e.NUPHUS_MCP_VISION_API_KEY!==void 0||e.NUPHUS_MCP_VISION_MODEL!==void 0;return!t&&l?.apiKey&&l.supportsImage===!0?(f="agent-fallback",e.NUPHUS_MCP_VISION_API_KEY=l.apiKey,e.NUPHUS_MCP_VISION_MODEL=l.model,l.baseURL&&(e.NUPHUS_MCP_VISION_BASE_URL=l.baseURL),d.info(`vision model fallback: reusing agent model ${l.model} for desktop_vision`)):t?f="panel-env":f="none",e}function S(e){return Object.keys(e).sort().map(t=>`${t}=${e[t]}`).join("\0")}async function y(){if(n){if(n.connection.isConnected())return n;await _(n.connection),n=null}if(c)return c;if(r){if(r.reason==="binary-missing"||Date.now()-r.at<A())return null;r=null}return c=(async()=>{const e=await K();if(!e)return r={reason:"binary-missing",message:`nuphus-mcp binary not found. Set AWS_DESKTOP_MCP_BIN or place it at ${m(process.cwd(),".desktop-mcp","bin",k)}`,at:Date.now()},u(`desktop tools unavailable: ${r.message}`),null;const t=h(),o=new O({command:e,env:t,onUnexpectedClose:()=>{u("nuphus-mcp process exited unexpectedly; will restart on next use"),n?.connection===o&&(n=null)}});try{const s=await o.start(),i=x();r=null;const a={connection:o,tools:s,binaryPath:e,envSig:S(t),forwarder:(p,E)=>F(o,p,E,i)};return n=a,u(`nuphus-mcp started (${e}), ${s.filter(p=>p.name.startsWith("desktop_")).length} desktop tools available`),a}catch(s){return await _(o),r={reason:"start-failed",message:s.message,at:Date.now()},v(`nuphus-mcp start failed: ${r.message}`),null}finally{c=null}})(),c}async function F(e,t,o,s){try{return await e.callTool(t,o,s)}catch(i){if(e.isConnected())throw i;v(`nuphus-mcp connection lost during ${t}: ${i.message}; restarting`),n?.connection===e&&(n=null),await _(e);const a=await y();if(!a)throw new Error(`nuphus-mcp restart failed: ${r?.message??"unknown"}`);return a.connection.callTool(t,o,s)}}async function q(e,t){if(!e)return[];t?.model&&(l=t);const o=h(),s=S(o);n&&n.connection.isConnected()&&n.envSig!==s&&(u("nuphus-mcp env changed; restarting to apply new env"),await L());const i=await y();return i?w({tools:i.tools,forwarder:(a,p)=>D(e,C)?i.forwarder(a,p):(d.warn(`tool ${a} blocked: desktop capability disabled for ${e}`),Promise.resolve("desktop capability is disabled for this agent (toggled off while tools were exposed); stop calling desktop_* tools"))}):[]}function G(){const e=n;return!e||!e.connection.isConnected()?R.map(t=>({kind:"builtin",toolName:t,exposedName:t,description:`${t}\uFF08\u684C\u9762\u81EA\u52A8\u5316\u5DE5\u5177\uFF0Cnuphus-mcp \u672A\u8FD0\u884C\uFF09\u3002\u5206\u914D desktop \u5206\u7C7B\u540E\u6309\u9700\u542F\u52A8\u540E\u7AEF\uFF0C\u5177\u4F53\u5DE5\u5177\u4EE5\u542F\u52A8\u540E\u76EE\u5F55\u4E3A\u51C6\u3002`,inputSchema:{type:"object",properties:{}},category:"desktop",async execute(){return`${t} is not ready: nuphus-mcp backend is not running. Allocate the desktop catalog to lazily start it, then retry.`}})):w({tools:e.tools,forwarder:(t,o)=>e.forwarder(t,o)})}const R=["desktop_screenshot","desktop_window_screenshot","desktop_perceive","desktop_vision","desktop_input","desktop_mouse","desktop_mouse_drag","desktop_screen_size","desktop_clipboard_write","desktop_clipboard_clean","desktop_config","desktop_uia_tree","desktop_uia_click","desktop_window_activate","desktop_window_info","desktop_window_move","desktop_window_resize","desktop_windows_list"];async function L(){const e=n;if(n=null,r=null,c){try{await c}catch{}c=null}e&&(await _(e.connection),u("nuphus-mcp stopped"))}function J(){return{started:n!==null,binaryPath:n?.binaryPath??null,toolCount:n?n.tools.filter(e=>e.name.startsWith("desktop_")).length:0,failure:r,visionSource:f}}async function _(e){try{await e.close()}catch{}}function u(e){d.info(e)}function v(e){d.warn(e)}export{L as disposeDesktopMcpManager,J as getDesktopMcpStatus,q as getDesktopTools,G as getDesktopToolsIfReady,K as resolveDesktopMcpBinary,y as startDesktopMcpManager};
2
2
 
@@ -15,7 +15,7 @@ export interface PushStatEntry {
15
15
  lastError?: string;
16
16
  }
17
17
 
18
- export declare function scheduleEventPush(agentId: string, _entry: RingBufferEntry<BridgeEventPayload>, authOptions?: RuntimeCallbackAuthOptions): Promise<void>;
18
+ export declare function scheduleEventPush(agentId: string, _entry: RingBufferEntry<BridgeEventPayload>, _authOptions?: RuntimeCallbackAuthOptions): Promise<void>;
19
19
 
20
20
  export declare function startHeartbeatScheduler(): void;
21
21
 
@@ -1,2 +1,2 @@
1
- import{createHash as M}from"node:crypto";import{promises as e}from"node:fs";import s from"node:path";import{createLogger as U}from"../utils/logger.js";import{getRuntimeHomeDir as C}from"../config.js";const l=U("file-snapshot-store");function T(){const t=String(process.env.AWS_RUNTIME_SNAPSHOT_ROOT||"").trim();return t||s.join(C(),".aws-bridge","snapshots")}function A(){const t=Number(process.env.AWS_RUNTIME_SNAPSHOT_TIMEOUT_MS);return Number.isFinite(t)&&t>=5e3?t:12e4}const v=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),x=Number(process.env.AWS_RUNTIME_SNAPSHOT_MAX_FILES||5e4);function E(t){return M("sha256").update(t).digest("hex").slice(0,16)}function H(t){return E(s.resolve(t))}function I(t,a,c){return s.join(t,a,c)}function G(t){return t.split(s.sep).some(c=>v.has(c))}async function O(t,a,c,o){let n;try{n=await e.readdir(t,{withFileTypes:!0})}catch(r){const i=r;if(i.code==="ENOENT"||i.code==="EACCES")return;throw r}for(const r of n){if(c.length>=o){l.warn(`[FileSnapshot] \u6587\u4EF6\u6570\u5DF2\u8FBE\u4E0A\u9650 ${o}\uFF0C\u505C\u6B62\u904D\u5386`);return}if(v.has(r.name))continue;const i=s.join(t,r.name),d=s.relative(a,i);r.isDirectory()?await O(i,a,c,o):r.isFile()&&c.push(d)}}async function P(t){try{await e.unlink(t)}catch(a){if(a.code!=="ENOENT")throw a}}async function b(t,a){if(t!==a)try{(await e.readdir(t)).length===0&&(await e.rmdir(t),await b(s.dirname(t),a))}catch{}}async function K(t){const a=Date.now(),c=T(),o=s.resolve(String(t.workspacePath).trim()),n=H(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(),i=t.snapshotName?.trim()||`snapshot-${new Date().toISOString()}`,d=t.triggerType?.trim()||"MANUAL",m=`${n}/${r}`,f=I(c,n,r),h=s.join(f,"files");try{await e.mkdir(h,{recursive:!0});const y=[];await O(o,o,y,x);const w={};let F=0,k=0;const g=A(),N=Date.now()+g;for(const $ of y){if(Date.now()>N){l.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 p=await e.stat(u);if(!p.isFile())continue;if(p.size>B){l.warn(`[FileSnapshot] \u8DF3\u8FC7\u5927\u6587\u4EF6: ${$} (${(p.size/1024/1024).toFixed(1)}MB)`);continue}const S=await e.readFile(u),_=E(S),D=s.join(h,_);try{await e.access(D)}catch{await e.writeFile(D,S)}w[$]={backupName:_,size:p.size,mtime:p.mtimeMs,mode:p.mode},F+=p.size,k++}catch(p){const S=p;if(S.code==="ENOENT"||S.code==="EACCES"){l.warn(`[FileSnapshot] \u8DF3\u8FC7\u4E0D\u53EF\u8BFB\u6587\u4EF6: ${$}`);continue}throw p}}await e.writeFile(s.join(f,"index.json"),JSON.stringify(w,null,2));const j={snapshotId:r,workspacePath:o,snapshotName:i,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()-a;return l.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;l.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 q(t){const a=Date.now(),c=T(),o=s.resolve(String(t.workspacePath).trim()),n=t.preRestoreBackup!==!1,[r,i]=t.snapshotKey.split("/");if(!r||!i)return{ok:!1,filesRestored:0,filesDeleted:0,filesSkipped:0,error:"invalid snapshotKey format"};const d=I(c,r,i),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-${i}`,triggerType:"AUTO_RESTORE_GUARD"});u.ok?(f=u.snapshotKey,l.info(`[FileSnapshot] \u8FD8\u539F\u524D\u5B89\u5168\u7F51\u5FEB\u7167: ${f}`)):l.warn(`[FileSnapshot] \u8FD8\u539F\u524D\u5B89\u5168\u7F51\u5FEB\u7167\u5931\u8D25: ${u.error}`)}catch(u){l.warn(`[FileSnapshot] \u8FD8\u539F\u524D\u5B89\u5168\u7F51\u5FEB\u7167\u5F02\u5E38: ${u.message}`)}const h=await e.readFile(m,"utf-8"),y=JSON.parse(h);await e.mkdir(o,{recursive:!0});const w=[];await O(o,o,w,x*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 p=s.join(o,u);await P(p),k++;const S=s.dirname(p);S!==o&&await b(S,o)}const j=A(),R=Date.now()+j;for(const[u,p]of Object.entries(y)){if(Date.now()>R){l.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",p.backupName);try{try{await e.access(_)}catch{l.warn(`[FileSnapshot] \u5907\u4EFD\u6587\u4EF6\u4E22\u5931\uFF0C\u8DF3\u8FC7: ${u}`),N++;continue}try{const D=await e.readFile(S);if(E(D)===p.backupName){N++;continue}}catch{}await e.mkdir(s.dirname(S),{recursive:!0}),await e.copyFile(_,S);try{await e.chmod(S,p.mode)}catch{}g++}catch(D){l.warn(`[FileSnapshot] \u8FD8\u539F\u6587\u4EF6\u5931\u8D25: ${u} - ${D.message}`),N++}}const $=Date.now()-a;return l.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 h=f;return l.error(`[FileSnapshot] \u8FD8\u539F\u5FEB\u7167\u5931\u8D25: ${h.message}`),{ok:!1,filesRestored:0,filesDeleted:0,filesSkipped:0,error:h.message}}}async function Q(t){const a=T(),c=s.resolve(String(t).trim()),o=H(c),n=s.join(a,o);try{await e.access(n)}catch{return[]}const r=await e.readdir(n,{withFileTypes:!0}),i=[];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"),h=JSON.parse(f);i.push({snapshotId:h.snapshotId,snapshotKey:`${o}/${h.snapshotId}`,snapshotName:h.snapshotName,triggerType:h.triggerType,createdAt:h.createdAt,fileCount:h.fileCount,totalBytes:h.totalBytes})}catch{l.warn(`[FileSnapshot] \u8DF3\u8FC7\u635F\u574F\u5FEB\u7167: ${d.name}`)}}return i.sort((d,m)=>new Date(m.createdAt).getTime()-new Date(d.createdAt).getTime()),i}async function V(t){const a=T(),[c,o]=t.split("/");if(!c||!o)return{ok:!1,error:"invalid snapshotKey format"};const n=I(a,c,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"),i=JSON.parse(r),d=new Set(Object.values(i).map(f=>f.backupName));await e.rm(n,{recursive:!0,force:!0});const m=s.join(a,c);try{const f=await e.readdir(m,{withFileTypes:!0}),h=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))h.add(g.backupName)}catch{}const y=s.join(n,"files");try{for(const w of d)h.has(w)||await P(s.join(y,w))}catch{}}catch{}return l.info(`[FileSnapshot] \u5220\u9664\u5FEB\u7167: ${t}`),{ok:!0}}catch(r){const i=r;return l.error(`[FileSnapshot] \u5220\u9664\u5FEB\u7167\u5931\u8D25: ${i.message}`),{ok:!1,error:i.message}}}function Y(){return T()}export{K as createSnapshot,V as deleteSnapshot,Y as getSnapshotRootPath,Q as listSnapshots,q as restoreSnapshot};
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};
2
2
 
@@ -1,2 +1,2 @@
1
- import l from"node:fs/promises";import v from"node:path";import{getAcodeConfigFile as w,getRuntimeHomeDir as A}from"../config.js";import{getInstanceAiConfigDebugLogger as _}from"../utils/instance-ai-config-debug-logger.js";import{sanitizeAgentId as K}from"../utils/file-utils.js";import{mcpDeployManager as D}from"./mcp-deploy.js";const j=new Set(["apiKey","api_key","apikey","key","secret","token","password"]);function F(e){const o={...e};for(const r of Object.keys(o))if(j.has(r)){const n=o[r];typeof n=="string"&&n.length>0&&(o[r]=n.length>8?`${n.slice(0,4)}...${n.slice(-4)}`:"***")}else typeof o[r]=="object"&&o[r]!==null&&(o[r]=F(o[r]));return o}function h(){return{...process.env.ACODE_MODEL?{model:process.env.ACODE_MODEL}:{},...process.env.ACODE_BASE_URL?{baseURL:process.env.ACODE_BASE_URL}:{},...process.env.ACODE_API_KEY?{apiKey:process.env.ACODE_API_KEY}:{},...process.env.ACODE_EFFORT?{effort:process.env.ACODE_EFFORT}:{}}}async function x(e){try{const o=await l.readFile(e,"utf-8"),s=JSON.parse(o).provider?.default,t=s?.options;return{...s?.model?{model:s.model}:{},...t?.baseURL||t?.baseUrl?{baseURL:t.baseURL||t.baseUrl}:{},...t?.apiKey?{apiKey:t.apiKey}:{}}}catch{return{}}}function b(e,o,r,n){return o!==void 0?"api":r!==void 0?"env":n!==void 0?"file":"default"}function M(e){return v.join(A(),".aws-bridge","instances",K(e),"mcp-extra.json")}async function k(e){try{const o=await l.readFile(v.join(e,"mcp-extra.json"),"utf-8"),r=JSON.parse(o);return r.servers&&typeof r.servers=="object"?r.servers:{}}catch{return{}}}function B(e){return M(e)}async function z(e){const o=w(),r=v.join(A(),".aws-bridge","instances",K(e.agentId)),n=v.join(r,"acode.json"),s=e.apiOverrides??{},t=h(),c=await x(o),g=s.model??t.model??c.model,y=s.baseURL??t.baseURL??c.baseURL,u=s.apiKey??t.apiKey??c.apiKey,m=s.effort??t.effort,d={};g&&(d.model=g),y&&(d.baseURL=y),u&&(d.apiKey=u),m&&(d.effort=m);const O={model:b("model",s.model,t.model,c.model),baseURL:b("baseURL",s.baseURL,t.baseURL,c.baseURL),apiKey:b("apiKey",s.apiKey,t.apiKey,c.apiKey),effort:b("effort",s.effort,t.effort,void 0)},L=_();try{await l.mkdir(r,{recursive:!0});let f={};try{const i=await l.readFile(o,"utf-8");f=JSON.parse(i)}catch{}const a=JSON.parse(JSON.stringify(f)),E=a.provider??{},I=E.default??{},p=I.options??{};g&&(p.model=g),y&&(p.baseURL=y),u&&(p.apiKey=u),m&&(p.effort=m),I.options=p,E.default=I,a.provider=E;try{const i=a.mcpServers??{};let R=D.resolveEnabledMcp(e.agentId,i);const U=await k(r);for(const[C,S]of Object.entries(U))R[C]=S;a.mcpServers=R}catch(i){L.log({level:"error",category:"apply",message:`MCP \u80FD\u529B\u8FC7\u6EE4/\u79C1\u6709\u5408\u5E76\u5931\u8D25\uFF08fail-open\uFF0C\u4FDD\u6301\u539F\u914D\u7F6E\uFF09: ${i instanceof Error?i.message:String(i)}`,source:"bridge",agentId:e.agentId,sessionId:e.sessionId})}await l.writeFile(n,JSON.stringify(a,null,2),"utf-8"),L.log({level:"info",category:"apply",message:"per-instance acode.json \u5DF2\u5199\u5165",source:"bridge",agentId:e.agentId,sessionId:e.sessionId,details:{perInstanceConfigPath:n,source:O}})}catch(f){const a=f instanceof Error?f.message:String(f);L.log({level:"error",category:"apply",message:`per-instance acode.json \u5199\u5165\u5931\u8D25: ${a}`,source:"bridge",agentId:e.agentId})}return{instanceConfig:{config:d,source:O},perInstanceConfigPath:n}}export{B as getAgentMcpExtraFilePath,z as prepareAcodeInstanceConfig,F as redactForLog};
1
+ import p from"node:fs/promises";import U from"node:path";import{getBridgeInstanceConfigFile as S,getBridgeInstanceMcpExtraFile as A,getBridgeTemplateConfigFile as F}from"../config.js";import{getInstanceAiConfigDebugLogger as _}from"../utils/instance-ai-config-debug-logger.js";import{mcpDeployManager as w}from"./mcp-deploy.js";const h=new Set(["apiKey","api_key","apikey","key","secret","token","password"]);function D(e){const t={...e};for(const r of Object.keys(t))if(h.has(r)){const o=t[r];typeof o=="string"&&o.length>0&&(t[r]=o.length>8?`${o.slice(0,4)}...${o.slice(-4)}`:"***")}else typeof t[r]=="object"&&t[r]!==null&&(t[r]=D(t[r]));return t}function M(){return{...process.env.ACODE_MODEL?{model:process.env.ACODE_MODEL}:{},...process.env.ACODE_BASE_URL?{baseURL:process.env.ACODE_BASE_URL}:{},...process.env.ACODE_API_KEY?{apiKey:process.env.ACODE_API_KEY}:{},...process.env.ACODE_EFFORT?{effort:process.env.ACODE_EFFORT}:{}}}async function k(e){try{const t=await p.readFile(e,"utf-8"),a=JSON.parse(t).provider?.default,n=a?.options;return{...a?.model?{model:a.model}:{},...n?.baseURL||n?.baseUrl?{baseURL:n.baseURL||n.baseUrl}:{},...n?.apiKey?{apiKey:n.apiKey}:{}}}catch{return{}}}function m(e,t,r,o){return t!==void 0?"api":r!==void 0?"env":o!==void 0?"file":"default"}function O(e){return A(e)}async function x(e){try{const t=await p.readFile(O(e),"utf-8"),r=JSON.parse(t);return r.servers&&typeof r.servers=="object"?r.servers:{}}catch{return{}}}function T(e){return O(e)}async function $(e){const t=F(),r=S(e.agentId),o=e.apiOverrides??{},a=M(),n=await k(t),l=o.model??a.model??n.model,g=o.baseURL??a.baseURL??n.baseURL,y=o.apiKey??a.apiKey??n.apiKey,u=o.effort??a.effort,f={};l&&(f.model=l),g&&(f.baseURL=g),y&&(f.apiKey=y),u&&(f.effort=u);const L={model:m("model",o.model,a.model,n.model),baseURL:m("baseURL",o.baseURL,a.baseURL,n.baseURL),apiKey:m("apiKey",o.apiKey,a.apiKey,n.apiKey),effort:m("effort",o.effort,a.effort,void 0)},v=_();try{await p.mkdir(U.dirname(r),{recursive:!0});let c={};try{const i=await p.readFile(t,"utf-8");c=JSON.parse(i)}catch{}const s=JSON.parse(JSON.stringify(c)),b=s.provider??{},E=b.default??{},d=E.options??{};l&&(d.model=l),g&&(d.baseURL=g),y&&(d.apiKey=y),u&&(d.effort=u),E.options=d,b.default=E,s.provider=b;try{const i=s.mcpServers??{},I=w.resolveEnabledMcp(e.agentId,i),R=await x(e.agentId);for(const[C,K]of Object.entries(R))I[C]=K;s.mcpServers=I}catch(i){v.log({level:"error",category:"apply",message:`MCP \u80FD\u529B\u8FC7\u6EE4/\u79C1\u6709\u5408\u5E76\u5931\u8D25\uFF08fail-open\uFF0C\u4FDD\u6301\u539F\u914D\u7F6E\uFF09: ${i instanceof Error?i.message:String(i)}`,source:"bridge",agentId:e.agentId,sessionId:e.sessionId})}await p.writeFile(r,JSON.stringify(s,null,2),"utf-8"),v.log({level:"info",category:"apply",message:"per-instance acode.json \u5DF2\u5199\u5165",source:"bridge",agentId:e.agentId,sessionId:e.sessionId,details:{perInstanceConfigPath:r,source:L}})}catch(c){const s=c instanceof Error?c.message:String(c);v.log({level:"error",category:"apply",message:`per-instance acode.json \u5199\u5165\u5931\u8D25: ${s}`,source:"bridge",agentId:e.agentId})}return{instanceConfig:{config:f,source:L},perInstanceConfigPath:r}}export{T as getAgentMcpExtraFilePath,$ as prepareAcodeInstanceConfig,D as redactForLog};
2
2
 
@@ -1,2 +1,2 @@
1
- import{promises as P}from"node:fs";import w from"node:path";import{downloadPluginZip as A,downloadSkillZip as D,ensureDir as y}from"../utils/file-utils.js";import{createLogger as O}from"../utils/logger.js";import{normalizeMcpPayload as j}from"../utils/mcp-utils.js";import{ensureEnabledTools as z,parseBoolean as T}from"../utils/validation.js";import{getAgentInitRoot as I,loadInstanceState as F,saveInstanceState as $}from"./instance-state.js";import{mcpDeployManager as B}from"./mcp-deploy.js";import{reconcileMcpDefaultsFromDeployed as R}from"./mcp-deploy.js";import{reconcileSkillsDefaultsFromDeployed as L}from"./skill-manager.js";import{reconcilePluginsDefaultsFromDeployed as Z}from"./plugin-manager.js";import{pluginManager as q}from"./plugin-manager.js";import{skillManager as x}from"./skill-manager.js";import{detectToolStatuses as U}from"./tool-installer.js";const W=O("instance-init");function G(i,p){const s=new Set(Object.values(p).filter(o=>o.installed).map(o=>o.tool));return i.filter(o=>s.has(o))}async function H(i,p){try{const s=await D(i,p);if(!s)return null;const o=await P.readFile(s.outputPath),c=i.defaultEnabled!==!1,g=String(i.skillName||"").trim()||void 0,e=await x.saveSharedSkill(o,s.fileName,c,i.sha256,g);return!e.ok||!e.skillName?null:{id:e.skillName,name:e.skillName,fileName:s.fileName,filePath:"",bytes:s.bytes,installedAt:new Date().toISOString()}}catch(s){return W.warn("\u6280\u80FD\u5305\u90E8\u7F72\u5230 bridge \u5931\u8D25\uFF08\u6309\u8DF3\u8FC7\u5904\u7406\uFF09: %s. %s",i.skillName||i.fileName||"(\u672A\u547D\u540D)",s instanceof Error?s.message:String(s)),null}}async function re(i,p,s){const o=w.resolve(p),c=I(i),g=[];function e(t,l,n,a){g.push({step:t,status:l,message:n,timestamp:new Date().toISOString(),details:a})}e("prepare","running","\u5F00\u59CB\u521D\u59CB\u5316\u5B9E\u4F8B",{agentId:String(i),workspacePath:o}),await y(c),e("prepare","success","\u521D\u59CB\u5316\u76EE\u5F55\u5DF2\u5C31\u7EEA",{initRoot:c});const d=z(s.ccSwitchEnabledTools);e("detect-tools","running","\u5F00\u59CB\u68C0\u6D4B\u5DE5\u5177\u5B89\u88C5\u72B6\u6001",{tools:d});const u=await U(d);e("detect-tools","success","\u5DE5\u5177\u5B89\u88C5\u72B6\u6001\u68C0\u6D4B\u5B8C\u6210",{installedTools:Object.values(u).filter(t=>t.installed).map(t=>t.tool),missingTools:Object.values(u).filter(t=>!t.installed).map(t=>t.tool)});const C=G(d,u),b=Object.values(u).filter(t=>!t.installed),r={ok:!0,agentId:String(i),workspacePath:o,initRoot:c,enabledTools:d,toolStatus:u,logs:g,skill:{enabled:T(s.skillEnabled,!0),packagePresent:!1},mcp:{enabled:T(s.mcpEnabled,!0),configPath:null}},m=await F(i);if(b.length>0&&e("skip-uninstalled-tools","skipped","\u5DF2\u8DF3\u8FC7\u672A\u5B89\u88C5\u5DE5\u5177",{skippedTools:b.map(t=>({tool:t.tool,error:t.error}))}),e("select-installed-tools","success","\u5DF2\u9009\u62E9\u53EF\u521D\u59CB\u5316\u5DE5\u5177",{enabledTools:d,installedTools:C}),e("load-sdk","running","\u5F00\u59CB\u90E8\u7F72\u6280\u80FD/MCP \u6A21\u677F\u5230\u672C bridge"),e("load-sdk","success","\u6280\u80FD/MCP \u6A21\u677F\u90E8\u7F72\u51C6\u5907\u5B8C\u6210",{tools:d}),r.skill.enabled){e("install-skills","running","\u5F00\u59CB\u90E8\u7F72\u6280\u80FD\u5305",{count:Array.isArray(s.skillPackages)?s.skillPackages.length:s.skillPackage?1:0});const t=await y(w.join(c,"skills")),l=Array.isArray(s.skillPackages)&&s.skillPackages.length>0?s.skillPackages:s.skillPackage?[s.skillPackage]:[],n=[];for(const a of l){const S=await H(a,t);S&&n.push(S)}n.length>0?(r.skill.packagePresent=!0,r.skill.installedCount=n.length,r.skill.installed=n,e("install-skills","success","\u6280\u80FD\u5305\u90E8\u7F72\u5B8C\u6210",{installedCount:n.length,skills:n.map(a=>a.name)})):e("install-skills","skipped","\u6CA1\u6709\u53EF\u90E8\u7F72\u7684\u6280\u80FD\u5305")}else e("install-skills","skipped","\u5DF2\u8DF3\u8FC7\u6280\u80FD\u5305\u90E8\u7F72\uFF08skillEnabled=false\uFF09");const k=Array.isArray(s.pluginPackages)?s.pluginPackages:[];if(k.length>0){e("install-plugins","running","\u5F00\u59CB\u90E8\u7F72\u63D2\u4EF6\u6A21\u677F\u5305",{count:k.length});const t=await y(w.join(c,"plugins-tmp"));let l=0;for(const n of k)if(!(!n||!String(n.downloadUrl||"").trim()))try{const a=await A(n,t);if(!a)continue;const S=await P.readFile(a.outputPath),E=n.defaultEnabled!==!1,h=await q.saveSharedPlugin(S,a.fileName,E,n.sha256);h.ok?(l++,e("install-plugins","success",`\u63D2\u4EF6 ${h.pluginName||a.fileName} \u5DF2\u90E8\u7F72\u5230\u672C bridge`)):e("install-plugins","error",`\u63D2\u4EF6 ${a.fileName} \u90E8\u7F72\u5931\u8D25: ${h.error||"\u672A\u77E5\u9519\u8BEF"}`)}catch(a){e("install-plugins","error",`\u63D2\u4EF6 ${n.fileName||"(\u672A\u547D\u540D)"} \u90E8\u7F72\u5931\u8D25: ${a instanceof Error?a.message:String(a)}`)}r.plugin={enabled:!0,packagePresent:k.length>0,installedCount:l},l>0?e("install-plugins","success","\u63D2\u4EF6\u6A21\u677F\u5305\u90E8\u7F72\u5B8C\u6210",{installedCount:l}):e("install-plugins","skipped","\u6CA1\u6709\u53EF\u90E8\u7F72\u7684\u63D2\u4EF6\u5305"),await P.rm(t,{recursive:!0,force:!0}).catch(()=>{})}const f=[];if(r.mcp.enabled){e("install-mcp","running","\u5F00\u59CB\u90E8\u7F72 MCP \u6A21\u677F",{count:Array.isArray(s.mcpServers)?s.mcpServers.length:0});const t=(Array.isArray(s.mcpServers)?s.mcpServers:[]).map(l=>j(l)).filter(l=>l!==null);for(const l of t){const n={type:l.transport||"stdio",command:l.command||void 0,url:l.url||void 0,args:l.args||void 0,env:l.env||void 0};B.saveMcp(l.name,n,l.enabled!==!1).ok&&f.push({id:l.id||"",name:l.name,transport:l.transport||"stdio",command:l.command||"",url:l.url||"",args:l.args||[],env:l.env||{},enabled:l.enabled!==!1,installedAt:new Date().toISOString()})}r.mcp.installedCount=f.length,e("install-mcp","success","MCP \u6A21\u677F\u90E8\u7F72\u5B8C\u6210",{installedCount:f.length,mcpServers:f.map(l=>l.name)})}else e("install-mcp","skipped","\u5DF2\u8DF3\u8FC7 MCP \u6A21\u677F\uFF08mcpEnabled=false\uFF09");e("persist-state","running","\u5F00\u59CB\u4FDD\u5B58\u5B9E\u4F8B\u72B6\u6001"),m.initialized=!0,m.enabledTools=d,m.toolStatus=u,m.skillEnabled=r.skill.enabled,m.mcpEnabled=r.mcp.enabled,await $(i,m),e("persist-state","success","\u5B9E\u4F8B\u72B6\u6001\u4FDD\u5B58\u5B8C\u6210");const v=L(),M=R(),N=Z();return(v||M||N)&&e("sync-state","success","\u80FD\u529B\u9ED8\u8BA4\u5F00\u5173\u5DF2\u5BF9\u8D26\uFF08\u65B0\u589E\u9879\u9ED8\u8BA4\u5173\u95ED\uFF09",{reconciledSkills:v,reconciledMcp:M,reconciledPlugins:N}),e("sync-state","success","\u6280\u80FD/MCP \u6A21\u677F\u90E8\u7F72\u72B6\u6001\u5DF2\u5C31\u7EEA"),e("complete","success",b.length>0?"\u5B9E\u4F8B\u521D\u59CB\u5316\u5B8C\u6210\uFF0C\u672A\u5B89\u88C5\u5DE5\u5177\u5DF2\u8DF3\u8FC7":"\u5B9E\u4F8B\u521D\u59CB\u5316\u5B8C\u6210"),{...r,installed:{skills:r.skill.installed||[],mcpServers:f}}}export{re as initInstance};
1
+ import{promises as P}from"node:fs";import w from"node:path";import{downloadPluginZip as I,downloadSkillZip as O,ensureDir as y}from"../utils/file-utils.js";import{createLogger as j}from"../utils/logger.js";import{normalizeMcpPayload as z}from"../utils/mcp-utils.js";import{ensureEnabledTools as B,parseBoolean as D}from"../utils/validation.js";import{buildBuiltinAwsMcpDeploySpec as $,BUILTIN_AWS_MCP_SERVER_NAME as v}from"./aws-client-agent-mcp.js";import{setDefault as F}from"./capability-config.js";import{getAgentInitRoot as R,loadInstanceState as _,saveInstanceState as L}from"./instance-state.js";import{mcpDeployManager as N,reconcileMcpDefaultsFromDeployed as U}from"./mcp-deploy.js";import{reconcilePluginsDefaultsFromDeployed as W,pluginManager as Z}from"./plugin-manager.js";import{reconcileSkillsDefaultsFromDeployed as q,skillManager as x}from"./skill-manager.js";import{detectToolStatuses as V}from"./tool-installer.js";const G=j("instance-init");function H(a,g){const s=new Set(Object.values(g).filter(r=>r.installed).map(r=>r.tool));return a.filter(r=>s.has(r))}async function J(a,g){try{const s=await O(a,g);if(!s)return null;const r=await P.readFile(s.outputPath),c=a.defaultEnabled!==!1,k=String(a.skillName||"").trim()||void 0,l=await x.saveSharedSkill(r,s.fileName,c,a.sha256,k);return!l.ok||!l.skillName?null:{id:l.skillName,name:l.skillName,fileName:s.fileName,filePath:"",bytes:s.bytes,installedAt:new Date().toISOString()}}catch(s){return G.warn("\u6280\u80FD\u5305\u90E8\u7F72\u5230 bridge \u5931\u8D25\uFF08\u6309\u8DF3\u8FC7\u5904\u7406\uFF09: %s. %s",a.skillName||a.fileName||"(\u672A\u547D\u540D)",s instanceof Error?s.message:String(s)),null}}async function ce(a,g,s){const r=w.resolve(g),c=R(a),k=[];function l(t,o,e,n){k.push({step:t,status:o,message:e,timestamp:new Date().toISOString(),details:n})}l("prepare","running","\u5F00\u59CB\u521D\u59CB\u5316\u5B9E\u4F8B",{agentId:String(a),workspacePath:r}),await y(c),l("prepare","success","\u521D\u59CB\u5316\u76EE\u5F55\u5DF2\u5C31\u7EEA",{initRoot:c});const u=B(s.ccSwitchEnabledTools);l("detect-tools","running","\u5F00\u59CB\u68C0\u6D4B\u5DE5\u5177\u5B89\u88C5\u72B6\u6001",{tools:u});const d=await V(u);l("detect-tools","success","\u5DE5\u5177\u5B89\u88C5\u72B6\u6001\u68C0\u6D4B\u5B8C\u6210",{installedTools:Object.values(d).filter(t=>t.installed).map(t=>t.tool),missingTools:Object.values(d).filter(t=>!t.installed).map(t=>t.tool)});const C=H(u,d),b=Object.values(d).filter(t=>!t.installed),i={ok:!0,agentId:String(a),workspacePath:r,initRoot:c,enabledTools:u,toolStatus:d,logs:k,skill:{enabled:D(s.skillEnabled,!0),packagePresent:!1},mcp:{enabled:D(s.mcpEnabled,!0),configPath:null}},p=await _(a);if(b.length>0&&l("skip-uninstalled-tools","skipped","\u5DF2\u8DF3\u8FC7\u672A\u5B89\u88C5\u5DE5\u5177",{skippedTools:b.map(t=>({tool:t.tool,error:t.error}))}),l("select-installed-tools","success","\u5DF2\u9009\u62E9\u53EF\u521D\u59CB\u5316\u5DE5\u5177",{enabledTools:u,installedTools:C}),l("load-sdk","running","\u5F00\u59CB\u90E8\u7F72\u6280\u80FD/MCP \u6A21\u677F\u5230\u672C bridge"),l("load-sdk","success","\u6280\u80FD/MCP \u6A21\u677F\u90E8\u7F72\u51C6\u5907\u5B8C\u6210",{tools:u}),i.skill.enabled){l("install-skills","running","\u5F00\u59CB\u90E8\u7F72\u6280\u80FD\u5305",{count:Array.isArray(s.skillPackages)?s.skillPackages.length:s.skillPackage?1:0});const t=await y(w.join(c,"skills")),o=Array.isArray(s.skillPackages)&&s.skillPackages.length>0?s.skillPackages:s.skillPackage?[s.skillPackage]:[],e=[];for(const n of o){const f=await J(n,t);f&&e.push(f)}e.length>0?(i.skill.packagePresent=!0,i.skill.installedCount=e.length,i.skill.installed=e,l("install-skills","success","\u6280\u80FD\u5305\u90E8\u7F72\u5B8C\u6210",{installedCount:e.length,skills:e.map(n=>n.name)})):l("install-skills","skipped","\u6CA1\u6709\u53EF\u90E8\u7F72\u7684\u6280\u80FD\u5305")}else l("install-skills","skipped","\u5DF2\u8DF3\u8FC7\u6280\u80FD\u5305\u90E8\u7F72\uFF08skillEnabled=false\uFF09");const S=Array.isArray(s.pluginPackages)?s.pluginPackages:[];if(S.length>0){l("install-plugins","running","\u5F00\u59CB\u90E8\u7F72\u63D2\u4EF6\u6A21\u677F\u5305",{count:S.length});const t=await y(w.join(c,"plugins-tmp"));let o=0;for(const e of S)if(!(!e||!String(e.downloadUrl||"").trim()))try{const n=await I(e,t);if(!n)continue;const f=await P.readFile(n.outputPath),T=e.defaultEnabled!==!1,h=await Z.saveSharedPlugin(f,n.fileName,T,e.sha256);h.ok?(o++,l("install-plugins","success",`\u63D2\u4EF6 ${h.pluginName||n.fileName} \u5DF2\u90E8\u7F72\u5230\u672C bridge`)):l("install-plugins","error",`\u63D2\u4EF6 ${n.fileName} \u90E8\u7F72\u5931\u8D25: ${h.error||"\u672A\u77E5\u9519\u8BEF"}`)}catch(n){l("install-plugins","error",`\u63D2\u4EF6 ${e.fileName||"(\u672A\u547D\u540D)"} \u90E8\u7F72\u5931\u8D25: ${n instanceof Error?n.message:String(n)}`)}i.plugin={enabled:!0,packagePresent:S.length>0,installedCount:o},o>0?l("install-plugins","success","\u63D2\u4EF6\u6A21\u677F\u5305\u90E8\u7F72\u5B8C\u6210",{installedCount:o}):l("install-plugins","skipped","\u6CA1\u6709\u53EF\u90E8\u7F72\u7684\u63D2\u4EF6\u5305"),await P.rm(t,{recursive:!0,force:!0}).catch(()=>{})}const m=[];if(i.mcp.enabled){l("install-mcp","running","\u5F00\u59CB\u90E8\u7F72 MCP \u6A21\u677F",{count:(Array.isArray(s.mcpServers)?s.mcpServers.length:0)+1});let t;try{const e=$();t=N.saveMcp(v,e,!0),t.ok&&(F("mcp",v,!0),m.push({id:"",name:v,transport:"stdio",command:e.command||"",url:e.url||"",args:e.args||[],env:e.env||{},enabled:!0,installedAt:new Date().toISOString()}))}catch(e){t={ok:!1,error:e instanceof Error?e.message:String(e)}}t.ok||l("install-mcp","error",`\u5185\u7F6E\u901A\u8BAF MCP \u90E8\u7F72\u5931\u8D25: ${t.error||"\u672A\u77E5\u9519\u8BEF"}`);const o=(Array.isArray(s.mcpServers)?s.mcpServers:[]).map(e=>z(e)).filter(e=>e!==null);for(const e of o){const n={type:e.transport||"stdio",command:e.command||void 0,url:e.url||void 0,args:e.args||void 0,env:e.env||void 0};N.saveMcp(e.name,n,e.enabled!==!1).ok&&m.push({id:e.id||"",name:e.name,transport:e.transport||"stdio",command:e.command||"",url:e.url||"",args:e.args||[],env:e.env||{},enabled:e.enabled!==!1,installedAt:new Date().toISOString()})}i.mcp.installedCount=m.length,l("install-mcp","success","MCP \u6A21\u677F\u90E8\u7F72\u5B8C\u6210",{installedCount:m.length,mcpServers:m.map(e=>e.name)})}else l("install-mcp","skipped","\u5DF2\u8DF3\u8FC7 MCP \u6A21\u677F\uFF08mcpEnabled=false\uFF09");l("persist-state","running","\u5F00\u59CB\u4FDD\u5B58\u5B9E\u4F8B\u72B6\u6001"),p.initialized=!0,p.enabledTools=u,p.toolStatus=d,p.skillEnabled=i.skill.enabled,p.mcpEnabled=i.mcp.enabled,await L(a,p),l("persist-state","success","\u5B9E\u4F8B\u72B6\u6001\u4FDD\u5B58\u5B8C\u6210");const M=q(),E=U(),A=W();return(M||E||A)&&l("sync-state","success","\u80FD\u529B\u9ED8\u8BA4\u5F00\u5173\u5DF2\u5BF9\u8D26\uFF08\u65B0\u589E\u9879\u9ED8\u8BA4\u5173\u95ED\uFF09",{reconciledSkills:M,reconciledMcp:E,reconciledPlugins:A}),l("sync-state","success","\u6280\u80FD/MCP \u6A21\u677F\u90E8\u7F72\u72B6\u6001\u5DF2\u5C31\u7EEA"),l("complete","success",b.length>0?"\u5B9E\u4F8B\u521D\u59CB\u5316\u5B8C\u6210\uFF0C\u672A\u5B89\u88C5\u5DE5\u5177\u5DF2\u8DF3\u8FC7":"\u5B9E\u4F8B\u521D\u59CB\u5316\u5B8C\u6210"),{...i,installed:{skills:i.skill.installed||[],mcpServers:m}}}export{ce as initInstance};
2
2
 
@@ -1,5 +1,5 @@
1
1
 
2
- import type { InstanceState } from '../types.js';
2
+ import type { InstanceState } from "../types.js";
3
3
 
4
4
  export declare function getInstanceStateFile(agentId: string): string;
5
5
 
@@ -1,2 +1,2 @@
1
- import{promises as s}from"node:fs";import p from"node:os";import a from"node:path";import{getRuntimeHomeDir as l}from"../config.js";import{atomicWriteJsonFile as c,ensureDir as m,sanitizeAgentId as o}from"../utils/file-utils.js";import{ensureEnabledTools as S,parseBoolean as u}from"../utils/validation.js";function f(e){return a.join(p.tmpdir(),"agentswork-runtime-init",o(String(e)),"state.json")}function g(){return{initialized:!1,skills:[],mcpServers:[],enabledTools:["acode","claude","opencode","codex"],toolStatus:{},skillEnabled:!0,mcpEnabled:!0,updatedAt:null}}function d(e){return a.join(l(),".aws-bridge","instances",o(String(e)),"state.json")}async function I(e){const t=d(e),r=f(e);try{const n=await s.readFile(t,"utf-8");return JSON.parse(n)}catch{try{const n=await s.readFile(r,"utf-8"),i=JSON.parse(n);return await c(t,i),i}catch{return g()}}}async function h(e,t){const r=d(e);await m(a.dirname(r));const n={initialized:!!t?.initialized,skills:Array.isArray(t?.skills)?t.skills:[],mcpServers:Array.isArray(t?.mcpServers)?t.mcpServers:[],enabledTools:S(t?.enabledTools),toolStatus:t?.toolStatus&&typeof t.toolStatus=="object"&&!Array.isArray(t.toolStatus)?t.toolStatus:{},skillEnabled:u(t?.skillEnabled,!0),mcpEnabled:u(t?.mcpEnabled,!0),updatedAt:new Date().toISOString()};return await c(r,n),n}function j(e){return a.join(l(),".aws-bridge","instances",o(String(e)))}export{j as getAgentInitRoot,d as getInstanceStateFile,I as loadInstanceState,h as saveInstanceState};
1
+ import{promises as i}from"node:fs";import d from"node:os";import a from"node:path";import{getBridgeInstanceRuntimeDir as l}from"../config.js";import{atomicWriteJsonFile as s,ensureDir as p,sanitizeAgentId as m}from"../utils/file-utils.js";import{ensureEnabledTools as S,parseBoolean as c}from"../utils/validation.js";function f(e){return a.join(d.tmpdir(),"agentswork-runtime-init",m(String(e)),"state.json")}function g(){return{initialized:!1,skills:[],mcpServers:[],enabledTools:["acode","claude","opencode","codex"],toolStatus:{},skillEnabled:!0,mcpEnabled:!0,updatedAt:null}}function u(e){return a.join(l(String(e)),"state.json")}async function E(e){const t=u(e),n=f(e);try{const r=await i.readFile(t,"utf-8");return JSON.parse(r)}catch{try{const r=await i.readFile(n,"utf-8"),o=JSON.parse(r);return await s(t,o),o}catch{return g()}}}async function h(e,t){const n=u(e);await p(a.dirname(n));const r={initialized:!!t?.initialized,skills:Array.isArray(t?.skills)?t.skills:[],mcpServers:Array.isArray(t?.mcpServers)?t.mcpServers:[],enabledTools:S(t?.enabledTools),toolStatus:t?.toolStatus&&typeof t.toolStatus=="object"&&!Array.isArray(t.toolStatus)?t.toolStatus:{},skillEnabled:c(t?.skillEnabled,!0),mcpEnabled:c(t?.mcpEnabled,!0),updatedAt:new Date().toISOString()};return await s(n,r),r}function x(e){return l(String(e))}export{x as getAgentInitRoot,u as getInstanceStateFile,E as loadInstanceState,h as saveInstanceState};
2
2