aws-runtime-bridge 1.4.0 → 1.6.1

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 (72) hide show
  1. package/README.md +1 -1
  2. package/dist/adapter/AdapterRegistry.d.ts +1 -1
  3. package/dist/adapter/AdapterRegistry.d.ts.map +1 -1
  4. package/dist/adapter/AdapterRegistry.js +0 -2
  5. package/dist/adapter/ClaudeSdkAdapter.d.ts +4 -0
  6. package/dist/adapter/ClaudeSdkAdapter.d.ts.map +1 -1
  7. package/dist/adapter/ClaudeSdkAdapter.js +11 -2
  8. package/dist/adapter/CodexSdkAdapter.js +1 -1
  9. package/dist/adapter/OpencodeSdkAdapter.d.ts +13 -1
  10. package/dist/adapter/OpencodeSdkAdapter.d.ts.map +1 -1
  11. package/dist/adapter/OpencodeSdkAdapter.js +58 -6
  12. package/dist/adapter/OpencodeSdkAdapter.test.js +57 -1
  13. package/dist/adapter/types.d.ts +10 -0
  14. package/dist/adapter/types.d.ts.map +1 -1
  15. package/dist/index.js +14 -43
  16. package/dist/middleware/auth.d.ts +5 -0
  17. package/dist/middleware/auth.d.ts.map +1 -1
  18. package/dist/middleware/auth.js +9 -1
  19. package/dist/routes/file-browser.d.ts +10 -0
  20. package/dist/routes/file-browser.d.ts.map +1 -1
  21. package/dist/routes/file-browser.js +226 -4
  22. package/dist/routes/file-browser.test.js +31 -0
  23. package/dist/routes/instance.d.ts +10 -0
  24. package/dist/routes/instance.d.ts.map +1 -1
  25. package/dist/routes/instance.js +93 -2
  26. package/dist/routes/instance.test.js +50 -0
  27. package/dist/routes/pty.d.ts +106 -0
  28. package/dist/routes/pty.d.ts.map +1 -0
  29. package/dist/routes/pty.js +526 -0
  30. package/dist/routes/pty.test.d.ts +2 -0
  31. package/dist/routes/pty.test.d.ts.map +1 -0
  32. package/dist/routes/pty.test.js +73 -0
  33. package/dist/routes/sessions.d.ts +1 -1
  34. package/dist/routes/sessions.d.ts.map +1 -1
  35. package/dist/routes/sessions.js +32 -213
  36. package/dist/routes/terminal.d.ts +32 -3
  37. package/dist/routes/terminal.d.ts.map +1 -1
  38. package/dist/routes/terminal.js +411 -243
  39. package/dist/routes/terminal.test.js +105 -29
  40. package/dist/services/agent-process-manager.d.ts +2 -2
  41. package/dist/services/agent-process-manager.d.ts.map +1 -1
  42. package/dist/services/agent-process-manager.js +3 -3
  43. package/dist/services/process-detector.d.ts +2 -4
  44. package/dist/services/process-detector.d.ts.map +1 -1
  45. package/dist/services/process-detector.js +9 -16
  46. package/dist/services/process-registry.d.ts +2 -2
  47. package/dist/services/process-registry.d.ts.map +1 -1
  48. package/dist/services/process-registry.js +1 -1
  49. package/dist/services/session-output.d.ts +27 -5
  50. package/dist/services/session-output.d.ts.map +1 -1
  51. package/dist/services/session-output.js +48 -3
  52. package/dist/services/session-output.test.js +43 -29
  53. package/dist/services/terminal-persistence.d.ts +9 -0
  54. package/dist/services/terminal-persistence.d.ts.map +1 -1
  55. package/dist/services/terminal-persistence.js +20 -0
  56. package/dist/services/tool-installer.d.ts +10 -0
  57. package/dist/services/tool-installer.d.ts.map +1 -1
  58. package/dist/services/tool-installer.js +126 -5
  59. package/dist/services/tool-installer.test.js +32 -1
  60. package/dist/services/workspace-files.d.ts +86 -0
  61. package/dist/services/workspace-files.d.ts.map +1 -1
  62. package/dist/services/workspace-files.js +571 -21
  63. package/dist/services/workspace-files.test.js +471 -11
  64. package/dist/services/workspace-watch.d.ts +21 -0
  65. package/dist/services/workspace-watch.d.ts.map +1 -0
  66. package/dist/services/workspace-watch.js +123 -0
  67. package/dist/services/workspace-watch.test.d.ts +2 -0
  68. package/dist/services/workspace-watch.test.d.ts.map +1 -0
  69. package/dist/services/workspace-watch.test.js +38 -0
  70. package/dist/types.d.ts +8 -4
  71. package/dist/types.d.ts.map +1 -1
  72. package/package.json +9 -1
package/README.md CHANGED
@@ -58,7 +58,7 @@ If an existing runtime binding still stores an old scheduler URL such as `http:/
58
58
  `aws-runtime-bridge` 命令仍作为兼容别名保留。安装 `aws-runtime-bridge` 后,包内会随附
59
59
  `aws-client-agent-mcp` 的编译产物;bridge 启动时只负责准备该 MCP 产物,不再在 Agent 启动时默认动态注入 `aws-mcp`。
60
60
 
61
- 请在面板中为目标运行时安装/配置 MCP;这样 Claude Code、Codex、OpenCode、PTY 等不同启动模式都走一致的持久化 MCP 配置链路。
61
+ 请在面板中为目标运行时安装/配置 MCP;这样 Claude Code、Codex、OpenCode SDK 启动模式都走一致的持久化 MCP 配置链路。
62
62
 
63
63
  如需使用自定义 MCP 可执行文件,可设置:
64
64
 
@@ -2,7 +2,7 @@
2
2
  * Adapter 注册表 —— 管理 Provider ID → Adapter 实例的映射
3
3
  */
4
4
  import type { BaseProviderAdapter } from './types.js';
5
- export type AdapterType = 'claude-sdk' | 'codex-sdk' | 'opencode-sdk' | 'pty';
5
+ export type AdapterType = 'claude-sdk' | 'codex-sdk' | 'opencode-sdk';
6
6
  /**
7
7
  * Adapter 注册表
8
8
  * 管理所有 Provider Adapter 实例的生命周期
@@ -1 +1 @@
1
- {"version":3,"file":"AdapterRegistry.d.ts","sourceRoot":"","sources":["../../src/adapter/AdapterRegistry.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAEtD,MAAM,MAAM,WAAW,GAAG,YAAY,GAAG,WAAW,GAAG,cAAc,GAAG,KAAK,CAAC;AAE9E;;;GAGG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAA+C;IAE/D;;;;OAIG;IACH,QAAQ,CAAC,OAAO,EAAE,mBAAmB,GAAG,IAAI;IAO5C;;;;OAIG;IACH,GAAG,CAAC,UAAU,EAAE,MAAM,GAAG,mBAAmB;IAU5C;;;;OAIG;IACH,SAAS,CAAC,WAAW,EAAE,WAAW,GAAG,mBAAmB;IASxD;;;OAGG;IACH,GAAG,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO;IAIhC;;OAEG;IACH,gBAAgB,IAAI,MAAM,EAAE;IAI5B;;OAEG;IACH,MAAM,IAAI,mBAAmB,EAAE;IAI/B;;OAEG;IACH,OAAO,IAAI,IAAI;IAWf;;OAEG;IACH,OAAO,CAAC,SAAS;CAclB;AAGD,eAAO,MAAM,eAAe,iBAAwB,CAAC"}
1
+ {"version":3,"file":"AdapterRegistry.d.ts","sourceRoot":"","sources":["../../src/adapter/AdapterRegistry.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAEtD,MAAM,MAAM,WAAW,GAAG,YAAY,GAAG,WAAW,GAAG,cAAc,CAAC;AAEtE;;;GAGG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAA+C;IAE/D;;;;OAIG;IACH,QAAQ,CAAC,OAAO,EAAE,mBAAmB,GAAG,IAAI;IAO5C;;;;OAIG;IACH,GAAG,CAAC,UAAU,EAAE,MAAM,GAAG,mBAAmB;IAU5C;;;;OAIG;IACH,SAAS,CAAC,WAAW,EAAE,WAAW,GAAG,mBAAmB;IASxD;;;OAGG;IACH,GAAG,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO;IAIhC;;OAEG;IACH,gBAAgB,IAAI,MAAM,EAAE;IAI5B;;OAEG;IACH,MAAM,IAAI,mBAAmB,EAAE;IAI/B;;OAEG;IACH,OAAO,IAAI,IAAI;IAWf;;OAEG;IACH,OAAO,CAAC,SAAS;CAYlB;AAGD,eAAO,MAAM,eAAe,iBAAwB,CAAC"}
@@ -89,8 +89,6 @@ export class AdapterRegistry {
89
89
  return providerId === 'codex';
90
90
  case 'opencode-sdk':
91
91
  return providerId === 'opencode';
92
- case 'pty':
93
- return providerId === 'pty';
94
92
  default:
95
93
  return false;
96
94
  }
@@ -73,6 +73,10 @@ export declare class ClaudeSdkAdapter extends EventEmitter implements BaseProvid
73
73
  private isTaskPollingIdleCommand;
74
74
  private isMessagePollingIdleCommand;
75
75
  private buildMessagePollingIdlePrompt;
76
+ /**
77
+ * 发送手动快捷键 token 序列,和空闲自动命令共用解析逻辑。
78
+ */
79
+ sendShortcutInput(sessionId: string, command: string): Promise<void>;
76
80
  /**
77
81
  * 执行空闲命令(支持 [enter], [wait:n] 等 token)
78
82
  */
@@ -1 +1 @@
1
- {"version":3,"file":"ClaudeSdkAdapter.d.ts","sourceRoot":"","sources":["../../src/adapter/ClaudeSdkAdapter.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ClaudeSdkAdapter.d.ts","sourceRoot":"","sources":["../../src/adapter/ClaudeSdkAdapter.ts"],"names":[],"mappings":"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"}
@@ -463,6 +463,12 @@ export class ClaudeSdkAdapter extends EventEmitter {
463
463
  buildMessagePollingIdlePrompt() {
464
464
  return '请调用 poll_message 工具阻塞等待新消息;收到消息后再处理消息内容。';
465
465
  }
466
+ /**
467
+ * 发送手动快捷键 token 序列,和空闲自动命令共用解析逻辑。
468
+ */
469
+ async sendShortcutInput(sessionId, command) {
470
+ await this.executeIdleCommand(sessionId, command);
471
+ }
466
472
  /**
467
473
  * 执行空闲命令(支持 [enter], [wait:n] 等 token)
468
474
  */
@@ -921,12 +927,13 @@ export class ClaudeSdkAdapter extends EventEmitter {
921
927
  case 'tool_use_start':
922
928
  // AI 正在调用工具
923
929
  {
924
- const actionInfo = getToolActionInfo(msg.tool_name, msg.tool_input);
930
+ const actionInfo = { ...getToolActionInfo(msg.tool_name, msg.tool_input), actionId: msg.tool_use_id };
925
931
  session.status = 'tool_using';
926
932
  this.emit('status-change', sessionId, 'tool_using', {
927
933
  actionType: actionInfo.actionType,
928
934
  actionLabel: actionInfo.actionLabel,
929
935
  actionDetail: actionInfo.actionDetail,
936
+ actionId: actionInfo.actionId,
930
937
  });
931
938
  this.stopIdleDetection(sessionId);
932
939
  this.handleToolUse(sessionId, session, msg, timestamp);
@@ -1141,13 +1148,14 @@ export class ClaudeSdkAdapter extends EventEmitter {
1141
1148
  }
1142
1149
  }
1143
1150
  // 获取工具动作分类信息(使用完整参数)
1144
- const actionInfo = getToolActionInfo(recentInfo.name, toolInput);
1151
+ const actionInfo = { ...getToolActionInfo(recentInfo.name, toolInput), actionId: toolId };
1145
1152
  // 更新状态
1146
1153
  session.status = 'tool_using';
1147
1154
  this.emit('status-change', sessionId, 'tool_using', {
1148
1155
  actionType: actionInfo.actionType,
1149
1156
  actionLabel: actionInfo.actionLabel,
1150
1157
  actionDetail: actionInfo.actionDetail,
1158
+ actionId: actionInfo.actionId,
1151
1159
  });
1152
1160
  this.stopIdleDetection(sessionId);
1153
1161
  // 发送工具调用开始事件(此时有完整参数)
@@ -1162,6 +1170,7 @@ export class ClaudeSdkAdapter extends EventEmitter {
1162
1170
  actionType: actionInfo.actionType,
1163
1171
  actionLabel: actionInfo.actionLabel,
1164
1172
  actionDetail: actionInfo.actionDetail,
1173
+ actionId: actionInfo.actionId,
1165
1174
  },
1166
1175
  });
1167
1176
  // 记录到消息历史
@@ -663,7 +663,7 @@ export class CodexSdkAdapter extends EventEmitter {
663
663
  handleToolLikeItem(sessionId, session, item) {
664
664
  if (!session.emittedToolStarts.has(item.id)) {
665
665
  session.emittedToolStarts.add(item.id);
666
- const actionInfo = getToolActionInfo(item.toolName, item.toolInput, item.metadata);
666
+ const actionInfo = { ...getToolActionInfo(item.toolName, item.toolInput, item.metadata), actionId: item.id };
667
667
  this.emitEvent({
668
668
  type: 'tool_use_start',
669
669
  sessionId,
@@ -11,7 +11,7 @@
11
11
  * 参考:spectrai-community/src/main/adapter/OpenCodeSdkAdapter.ts
12
12
  */
13
13
  import { EventEmitter } from 'node:events';
14
- import type { BaseProviderAdapter, AdapterSessionConfig, ConversationMessage, SessionStatus } from './types.js';
14
+ import type { AdapterSessionConfig, BaseProviderAdapter, ConversationMessage, SessionStatus } from './types.js';
15
15
  export declare class OpencodeSdkAdapter extends EventEmitter implements BaseProviderAdapter {
16
16
  readonly providerId = "opencode";
17
17
  readonly displayName = "OpenCode";
@@ -39,6 +39,18 @@ export declare class OpencodeSdkAdapter extends EventEmitter implements BaseProv
39
39
  */
40
40
  private loadSdk;
41
41
  private waitForServer;
42
+ /**
43
+ * 记录 OpenCode serve 启动阶段输出,用于进程提前退出时返回可诊断错误。
44
+ */
45
+ private recordStartupOutput;
46
+ /**
47
+ * 将 OpenCode serve 提前退出信息转成前端可直接展示的错误文本。
48
+ */
49
+ private formatStartupExitMessage;
50
+ /**
51
+ * 异步投递启动提示,避免首轮 OpenCode 处理耗时导致 /runtime/start 被前端误判为启动失败。
52
+ */
53
+ private dispatchInitialPrompt;
42
54
  private startSseLoop;
43
55
  private runSseLoop;
44
56
  private handleOpenCodeEvent;
@@ -1 +1 @@
1
- {"version":3,"file":"OpencodeSdkAdapter.d.ts","sourceRoot":"","sources":["../../src/adapter/OpencodeSdkAdapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AASH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAM3C,OAAO,KAAK,EACV,mBAAmB,EACnB,oBAAoB,EAGpB,mBAAmB,EACnB,aAAa,EACd,MAAM,YAAY,CAAC;AAsGpB,qBAAa,kBAAmB,SAAQ,YAAa,YAAW,mBAAmB;IACjF,QAAQ,CAAC,UAAU,cAAc;IACjC,QAAQ,CAAC,WAAW,cAAc;IAElC,OAAO,CAAC,QAAQ,CAA2C;IAC3D,OAAO,CAAC,SAAS,CAAC,CAAoB;IAEhC,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,oBAAoB,GAAG,OAAO,CAAC,IAAI,CAAC;IAgI5E,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAwC9D,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAqBnE,kBAAkB,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAI7F,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE;QAAE,gBAAgB,EAAE,MAAM,CAAC;QAAC,eAAe,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IAOnG,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAclD,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA4BxD,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,mBAAmB,EAAE;IAIzD,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO;IAItC,oBAAoB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAI3D,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS;IAI9D,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAOpD,OAAO,IAAI,IAAI;IAaf;;;OAGG;YACW,OAAO;YA6BP,aAAa;IAmB3B,OAAO,CAAC,YAAY;YAYN,UAAU;IAuBxB,OAAO,CAAC,mBAAmB;IA6H3B,OAAO,CAAC,gBAAgB;IA6GxB,OAAO,CAAC,SAAS;IAIjB,OAAO,CAAC,kBAAkB;IAW1B,OAAO,CAAC,iBAAiB;IAQzB,OAAO,CAAC,cAAc;IAStB,OAAO,CAAC,YAAY;IAQpB,OAAO,CAAC,2BAA2B;CAOpC"}
1
+ {"version":3,"file":"OpencodeSdkAdapter.d.ts","sourceRoot":"","sources":["../../src/adapter/OpencodeSdkAdapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAc3C,OAAO,KAAK,EACV,oBAAoB,EAEpB,mBAAmB,EACnB,mBAAmB,EAEnB,aAAa,EACd,MAAM,YAAY,CAAC;AA4GpB,qBAAa,kBAAmB,SAAQ,YAAa,YAAW,mBAAmB;IACjF,QAAQ,CAAC,UAAU,cAAc;IACjC,QAAQ,CAAC,WAAW,cAAc;IAElC,OAAO,CAAC,QAAQ,CAA2C;IAC3D,OAAO,CAAC,SAAS,CAAC,CAAoB;IAEhC,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,oBAAoB,GAAG,OAAO,CAAC,IAAI,CAAC;IA+I5E,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAwC9D,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAqBnE,kBAAkB,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAI7F,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE;QAAE,gBAAgB,EAAE,MAAM,CAAC;QAAC,eAAe,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IAUnG,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAclD,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA4BxD,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,mBAAmB,EAAE;IAIzD,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO;IAItC,oBAAoB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAI3D,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS;IAI9D,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAOpD,OAAO,IAAI,IAAI;IAaf;;;OAGG;YACW,OAAO;YA6BP,aAAa;IAmB3B;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAO3B;;OAEG;IACH,OAAO,CAAC,wBAAwB;IAahC;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAY7B,OAAO,CAAC,YAAY;YAYN,UAAU;IAuBxB,OAAO,CAAC,mBAAmB;IA6H3B,OAAO,CAAC,gBAAgB;IA6GxB,OAAO,CAAC,SAAS;IAIjB,OAAO,CAAC,kBAAkB;IAW1B,OAAO,CAAC,iBAAiB;IAQzB,OAAO,CAAC,cAAc;IAStB,OAAO,CAAC,YAAY;IAQpB,OAAO,CAAC,2BAA2B;CAOpC"}
@@ -132,11 +132,16 @@ export class OpencodeSdkAdapter extends EventEmitter {
132
132
  shell: useShell,
133
133
  });
134
134
  session.serverProcess = proc;
135
+ session.startupOutput = [];
135
136
  proc.stdout?.on('data', (d) => {
136
- console.debug(`[OpencodeSdkAdapter] serve stdout: ${d.toString().slice(0, 200)}`);
137
+ const text = d.toString();
138
+ this.recordStartupOutput(session, text);
139
+ console.debug(`[OpencodeSdkAdapter] serve stdout: ${text.slice(0, 200)}`);
137
140
  });
138
141
  proc.stderr?.on('data', (d) => {
139
- console.debug(`[OpencodeSdkAdapter] serve stderr: ${d.toString().slice(0, 200)}`);
142
+ const text = d.toString();
143
+ this.recordStartupOutput(session, text);
144
+ console.debug(`[OpencodeSdkAdapter] serve stderr: ${text.slice(0, 200)}`);
140
145
  });
141
146
  proc.on('error', (err) => {
142
147
  console.error(`[OpencodeSdkAdapter] Server process error:`, err);
@@ -155,6 +160,9 @@ export class OpencodeSdkAdapter extends EventEmitter {
155
160
  console.log(`[OpencodeSdkAdapter] Server exited with code ${code}`);
156
161
  session.sseActive = false;
157
162
  });
163
+ const exitDuringStartup = new Promise((resolve) => {
164
+ proc.once('exit', (code, signal) => resolve({ code, signal }));
165
+ });
158
166
  // 步骤 3:创建 SDK 客户端
159
167
  const sdk = await this.loadSdk();
160
168
  const client = sdk.createOpencodeClient({
@@ -162,7 +170,12 @@ export class OpencodeSdkAdapter extends EventEmitter {
162
170
  });
163
171
  session.client = client;
164
172
  // 步骤 4:等待服务器就绪
165
- await this.waitForServer(client, config.workingDirectory, 10_000, port);
173
+ await Promise.race([
174
+ this.waitForServer(client, config.workingDirectory, 10_000, port),
175
+ exitDuringStartup.then((exitInfo) => {
176
+ throw new Error(this.formatStartupExitMessage(exitInfo, session.startupOutput));
177
+ }),
178
+ ]);
166
179
  console.log(`[OpencodeSdkAdapter] ★★★ OpenCode server ready ★★★ port=${port}`);
167
180
  // 步骤 5:创建 OpenCode 会话
168
181
  const createResult = await client.session.create({
@@ -182,7 +195,7 @@ export class OpencodeSdkAdapter extends EventEmitter {
182
195
  this.emit('status-change', sessionId, 'waiting_input');
183
196
  // 步骤 7:发送初始 Prompt
184
197
  if (config.initialPrompt) {
185
- await this.sendMessage(sessionId, config.initialPrompt);
198
+ this.dispatchInitialPrompt(sessionId, config.initialPrompt);
186
199
  }
187
200
  }
188
201
  catch (err) {
@@ -264,6 +277,9 @@ export class OpencodeSdkAdapter extends EventEmitter {
264
277
  const session = this.sessions.get(sessionId);
265
278
  if (session) {
266
279
  session.idleCommands = commands;
280
+ if (session.adapterSession.status === 'waiting_input' && (commands.idleInputCommand || commands.nonInputCommand)) {
281
+ this.startIdleDetection(sessionId);
282
+ }
267
283
  }
268
284
  }
269
285
  async abortCurrentTurn(sessionId) {
@@ -382,6 +398,42 @@ export class OpencodeSdkAdapter extends EventEmitter {
382
398
  }
383
399
  throw new Error(`OpenCode server (port ${port}) did not start within ${timeoutMs}ms`);
384
400
  }
401
+ /**
402
+ * 记录 OpenCode serve 启动阶段输出,用于进程提前退出时返回可诊断错误。
403
+ */
404
+ recordStartupOutput(session, text) {
405
+ const normalized = text.trim();
406
+ if (!normalized)
407
+ return;
408
+ session.startupOutput = [...(session.startupOutput ?? []), normalized].slice(-8);
409
+ }
410
+ /**
411
+ * 将 OpenCode serve 提前退出信息转成前端可直接展示的错误文本。
412
+ */
413
+ formatStartupExitMessage(exitInfo, startupOutput) {
414
+ const exitReason = exitInfo.signal
415
+ ? `signal ${exitInfo.signal}`
416
+ : `code ${exitInfo.code ?? 'unknown'}`;
417
+ const output = (startupOutput ?? []).join('\n').trim();
418
+ if (!output) {
419
+ return `OpenCode server exited during startup (${exitReason}). Please check whether opencode serve can run in this workspace.`;
420
+ }
421
+ return `OpenCode server exited during startup (${exitReason}): ${output}`;
422
+ }
423
+ /**
424
+ * 异步投递启动提示,避免首轮 OpenCode 处理耗时导致 /runtime/start 被前端误判为启动失败。
425
+ */
426
+ dispatchInitialPrompt(sessionId, initialPrompt) {
427
+ void this.sendMessage(sessionId, initialPrompt).catch((err) => {
428
+ const msg = err instanceof Error ? err.message : String(err);
429
+ this.emitEvent({
430
+ type: 'error',
431
+ sessionId,
432
+ timestamp: new Date().toISOString(),
433
+ data: { text: `OpenCode initial prompt failed: ${msg}` },
434
+ });
435
+ });
436
+ }
385
437
  startSseLoop(sessionId, session) {
386
438
  session.sseActive = true;
387
439
  const ac = new AbortController();
@@ -578,7 +630,7 @@ export class OpencodeSdkAdapter extends EventEmitter {
578
630
  if (session.emittedToolStarts.has(toolUseId))
579
631
  return;
580
632
  session.emittedToolStarts.add(toolUseId);
581
- const actionInfo = getToolActionInfo(toolName, toolInput, metadata);
633
+ const actionInfo = { ...getToolActionInfo(toolName, toolInput, metadata), actionId: toolUseId };
582
634
  this.emitEvent({
583
635
  type: 'tool_use_start',
584
636
  sessionId,
@@ -598,7 +650,7 @@ export class OpencodeSdkAdapter extends EventEmitter {
598
650
  };
599
651
  if (state.status === 'running') {
600
652
  emitToolStart();
601
- const actionInfo = getToolActionInfo(toolName, toolInput, metadata);
653
+ const actionInfo = { ...getToolActionInfo(toolName, toolInput, metadata), actionId: toolUseId };
602
654
  this.emit('status-change', sessionId, 'tool_using', actionInfo);
603
655
  }
604
656
  else if (state.status === 'completed') {
@@ -1,5 +1,9 @@
1
- import { describe, expect, it } from 'vitest';
1
+ import { afterEach, describe, expect, it, vi } from 'vitest';
2
2
  import { OpencodeSdkAdapter } from './OpencodeSdkAdapter.js';
3
+ afterEach(() => {
4
+ vi.useRealTimers();
5
+ vi.restoreAllMocks();
6
+ });
3
7
  describe('OpencodeSdkAdapter', () => {
4
8
  it('should expose opencode provider identity', () => {
5
9
  const adapter = new OpencodeSdkAdapter();
@@ -16,4 +20,56 @@ describe('OpencodeSdkAdapter', () => {
16
20
  const prompt = Reflect.get(adapter, 'toIdlePrompt').call(adapter, 'system: 醒来了吗?使用get_profile获取自己的信息,继续未完成的任务或使用poll_message阻塞获取消息');
17
21
  expect(prompt).toBe('请调用 poll_message 工具阻塞等待新消息;收到消息后再处理消息内容。');
18
22
  });
23
+ it('starts idle detection when commands are set after OpenCode is already waiting for input', async () => {
24
+ vi.useFakeTimers();
25
+ const adapter = new OpencodeSdkAdapter();
26
+ const sentMessages = [];
27
+ Reflect.set(adapter, 'sessions', new Map([
28
+ [
29
+ 'session-1',
30
+ {
31
+ adapterSession: {
32
+ sessionId: 'session-1',
33
+ status: 'waiting_input',
34
+ messages: [],
35
+ createdAt: new Date().toISOString(),
36
+ totalUsage: { inputTokens: 0, outputTokens: 0 },
37
+ },
38
+ config: {
39
+ command: 'opencode',
40
+ workingDirectory: process.cwd(),
41
+ autoAccept: true,
42
+ },
43
+ sseActive: false,
44
+ pendingPermissions: new Map(),
45
+ emittedToolStarts: new Set(),
46
+ workingDirectory: process.cwd(),
47
+ userMessageIds: new Set(),
48
+ currentAssistantText: '',
49
+ seenTextPartIds: new Set(),
50
+ },
51
+ ],
52
+ ]));
53
+ vi.spyOn(adapter, 'sendMessage').mockImplementation(async (_sessionId, message) => {
54
+ sentMessages.push(message);
55
+ });
56
+ adapter.setIdleCommands('session-1', {
57
+ idleInputCommand: 'system: 使用poll_message阻塞获取消息',
58
+ nonInputCommand: '',
59
+ });
60
+ await vi.advanceTimersByTimeAsync(500);
61
+ expect(sentMessages).toEqual(['请调用 poll_message 工具阻塞等待新消息;收到消息后再处理消息内容。']);
62
+ });
63
+ it('includes serve startup output when the OpenCode process exits early', () => {
64
+ const adapter = new OpencodeSdkAdapter();
65
+ const message = Reflect.get(adapter, 'formatStartupExitMessage').call(adapter, { code: 1, signal: null }, ['missing auth configuration']);
66
+ expect(message).toContain('OpenCode server exited during startup (code 1)');
67
+ expect(message).toContain('missing auth configuration');
68
+ });
69
+ it('dispatches the initial prompt asynchronously so launch can return after session creation', () => {
70
+ const adapter = new OpencodeSdkAdapter();
71
+ const sendMessage = vi.spyOn(adapter, 'sendMessage').mockResolvedValue(undefined);
72
+ Reflect.get(adapter, 'dispatchInitialPrompt').call(adapter, 'session-1', 'hello');
73
+ expect(sendMessage).toHaveBeenCalledWith('session-1', 'hello');
74
+ });
19
75
  });
@@ -81,6 +81,10 @@ export interface ProviderEvent {
81
81
  actionLabel?: string;
82
82
  /** 工具动作详情(tool_use_start) */
83
83
  actionDetail?: string;
84
+ /** 工具调用关联 ID(tool_use_start / tool_use_end) */
85
+ actionId?: string;
86
+ /** 工具返回数据(tool_use_end) */
87
+ actionResult?: string;
84
88
  };
85
89
  }
86
90
  export interface AdapterSessionConfig {
@@ -230,6 +234,12 @@ export declare abstract class BaseProviderAdapter extends EventEmitter {
230
234
  idleInputCommand: string;
231
235
  nonInputCommand: string;
232
236
  }): void;
237
+ /**
238
+ * 发送快捷键 token 序列(如 [enter]、[ctrl+c]),复用 SDK 输入流但不创建普通用户消息。
239
+ * @param sessionId 会话 ID
240
+ * @param command 快捷 token 文本
241
+ */
242
+ abstract sendShortcutInput?(sessionId: string, command: string): Promise<void>;
233
243
  /**
234
244
  * 中止当前正在执行的轮次(软中断)
235
245
  * 会话保持活跃,用户可继续发送新消息。
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/adapter/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/adapter/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAItC,MAAM,MAAM,aAAa,GACrB,UAAU,GACV,UAAU,GACV,YAAY,GACZ,eAAe,GACf,WAAW,GACX,YAAY,GACZ,OAAO,CAAC;AAIZ,MAAM,MAAM,iBAAiB,GACzB,YAAY,GACZ,UAAU,GACV,gBAAgB,GAChB,cAAc,GACd,oBAAoB,GACpB,mBAAmB,GACnB,gBAAgB,GAChB,eAAe,GACf,kBAAkB,GAClB,OAAO,CAAC;AAIZ;;;GAGG;AACH,MAAM,MAAM,cAAc,GACtB,OAAO,GACP,KAAK,GACL,MAAM,GACN,WAAW,GACX,YAAY,GACZ,WAAW,GACX,MAAM,GACN,QAAQ,GACR,KAAK,GACL,KAAK,GACL,UAAU,GACV,OAAO,CAAC;AAEZ;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,aAAa;IACb,UAAU,EAAE,cAAc,CAAC;IAC3B,iBAAiB;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,qBAAqB;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,iCAAiC;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY;IACZ,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AA6BD;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,MAAM,GAAG,SAAS,EAC5B,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACnC,QAAQ,CAAC,EAAE,YAAY,GACtB,cAAc,CAmPhB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,iBAAiB,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE;QACJ,0CAA0C;QAC1C,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,0CAA0C;QAC1C,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,kEAAkE;QAClE,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACpC,2BAA2B;QAC3B,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,6BAA6B;QAC7B,OAAO,CAAC,EAAE,OAAO,CAAC;QAClB,8BAA8B;QAC9B,KAAK,CAAC,EAAE;YAAE,WAAW,EAAE,MAAM,CAAC;YAAC,YAAY,EAAE,MAAM,CAAA;SAAE,CAAC;QACtD,4BAA4B;QAC5B,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,iCAAiC;QACjC,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAC1B,4BAA4B;QAC5B,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,4BAA4B;QAC5B,SAAS,CAAC,EAAE,KAAK,CAAC;YAChB,QAAQ,EAAE,MAAM,CAAC;YACjB,MAAM,CAAC,EAAE,MAAM,CAAC;YAChB,OAAO,CAAC,EAAE,KAAK,CAAC;gBAAE,KAAK,EAAE,MAAM,CAAC;gBAAC,WAAW,CAAC,EAAE,MAAM,CAAA;aAAE,CAAC,CAAC;YACzD,QAAQ,CAAC,EAAE,OAAO,CAAC;SACpB,CAAC,CAAC;QACH,6BAA6B;QAC7B,UAAU,CAAC,EAAE,cAAc,CAAC;QAC5B,+BAA+B;QAC/B,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,6BAA6B;QAC7B,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,+CAA+C;QAC/C,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,2BAA2B;QAC3B,YAAY,CAAC,EAAE,MAAM,CAAC;KACvB,CAAC;CACH;AAID,MAAM,WAAW,oBAAoB;IACnC,qBAAqB;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW;IACX,gBAAgB,EAAE,MAAM,CAAC;IACzB,2BAA2B;IAC3B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,0BAA0B;IAC1B,uBAAuB,CAAC,EAAE,SAAS,GAAG,QAAQ,CAAC;IAC/C,mBAAmB;IACnB,UAAU,EAAE,OAAO,CAAC;IACpB,aAAa;IACb,YAAY,CAAC,EAAE,MAAM,GAAG;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IACzE,aAAa;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,mBAAmB;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,oBAAoB;IACpB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,eAAe;IACf,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,oBAAoB;IACpB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,aAAa;IACb,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,iBAAiB;IACjB,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC1C,iBAAiB;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,0BAA0B;IAC1B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,6BAA6B;IAC7B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,eAAe;IACf,qBAAqB,CAAC,EAAE,MAAM,EAAE,CAAC;CAClC;AAID,MAAM,WAAW,cAAc;IAC7B,cAAc;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,6BAA6B;IAC7B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,WAAW;IACX,MAAM,EAAE,aAAa,CAAC;IACtB,aAAa;IACb,QAAQ,EAAE,mBAAmB,EAAE,CAAC;IAChC,WAAW;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,kBAAkB;IAClB,UAAU,EAAE;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAA;KAAE,CAAC;IAE1D,6BAA6B;IAC7B,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAID,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,UAAU,GAAG,aAAa,CAAC;IACxD,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,mCAAmC;IACnC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,uBAAuB;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACpC,wBAAwB;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,wBAAwB;IACxB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,cAAc;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAID,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAID,MAAM,WAAW,sBAAsB;IACrC,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,KAAK,CAAC;QACf,QAAQ,EAAE,MAAM,CAAC;QACjB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,OAAO,CAAC,EAAE,KAAK,CAAC;YAAE,KAAK,EAAE,MAAM,CAAC;YAAC,WAAW,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;QACzD,QAAQ,CAAC,EAAE,OAAO,CAAC;KACpB,CAAC,CAAC;CACJ;AAID;;;;;;;;;;;;;GAaG;AACH,8BAAsB,mBAAoB,SAAQ,YAAY;IAC5D,iDAAiD;IACjD,QAAQ,CAAC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAErC,wCAAwC;IACxC,QAAQ,CAAC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAEtC;;;;OAIG;IACH,QAAQ,CAAC,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,oBAAoB,GAAG,OAAO,CAAC,IAAI,CAAC;IAErF;;;;OAIG;IACH,QAAQ,CAAC,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAEvE;;;;OAIG;IACH,QAAQ,CAAC,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAE5E;;;;OAIG;IACH,QAAQ,CAAC,kBAAkB,CAAC,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAE/F;;;;;OAKG;IACH,QAAQ,CAAC,eAAe,CAAC,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE;QAAE,gBAAgB,EAAE,MAAM,CAAC;QAAC,eAAe,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IAEnH;;;;OAIG;IACH,QAAQ,CAAC,iBAAiB,CAAC,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAE9E;;;;OAIG;IACH,QAAQ,CAAC,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAE3D;;;OAGG;IACH,QAAQ,CAAC,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAE3D;;;;;OAKG;IACH,QAAQ,CAAC,aAAa,CAAC,CACrB,SAAS,EAAE,MAAM,EACjB,iBAAiB,EAAE,MAAM,EACzB,MAAM,EAAE,oBAAoB,GAC3B,OAAO,CAAC,IAAI,CAAC;IAEhB;;;OAGG;IACH,QAAQ,CAAC,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,mBAAmB,EAAE;IAElE;;;OAGG;IACH,QAAQ,CAAC,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO;IAE/C;;OAEG;IACH,QAAQ,CAAC,oBAAoB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAEpE;;OAEG;IACH,QAAQ,CAAC,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS;IAEvE;;OAEG;IACH,QAAQ,CAAC,aAAa,CAAC,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAE9D;;OAEG;IACH,QAAQ,CAAC,OAAO,IAAI,IAAI;CACzB"}
package/dist/index.js CHANGED
@@ -21,8 +21,8 @@ import { gitRouter } from "./routes/git.js";
21
21
  import { fileBrowserRouter } from "./routes/file-browser.js";
22
22
  import { aiSourcesRouter } from "./routes/ai-sources.js";
23
23
  import { processesRouter } from "./routes/processes.js";
24
+ import { attachPtyWebSocketServer, closeAllPtySessions, ptyRouter, ptySessions, } from "./routes/pty.js";
24
25
  import { runtimeBindingRouter, logRuntimeBindingStartupState, } from "./routes/runtime-binding.js";
25
- import { sessions, flushSessionOutput } from "./services/session-output.js";
26
26
  import { loadPersistedSessions, savePersistedSessions, } from "./services/terminal-persistence.js";
27
27
  import { detectOrphanProcesses } from "./services/process-detector.js";
28
28
  import { startOrphanMonitor, stopOrphanMonitor, } from "./services/orphan-monitor.js";
@@ -124,7 +124,7 @@ async function rebuildProcessRegistry() {
124
124
  pid: s.pid,
125
125
  workspacePath: s.workspacePath,
126
126
  command: s.command,
127
- mode: s.mode || "pty",
127
+ mode: "sdk",
128
128
  })));
129
129
  logger.info(`[runtime-bridge] 进程注册表重建完成: ${persistedSessions.length} 条记录`);
130
130
  }
@@ -175,12 +175,11 @@ async function detectOrphansOnStartup() {
175
175
  pid: s.pid,
176
176
  workspacePath: s.workspacePath,
177
177
  command: s.command,
178
- mode: s.mode || "pty",
178
+ mode: "sdk",
179
179
  })));
180
180
  return;
181
181
  }
182
182
  logger.info(`[runtime-bridge] ★ Bridge 重启,检测 ${persistedSessions.length} 个持久化会话的孤儿进程...`);
183
- // ★★★ 修复:不再区分 SDK 和 PTY 模式,全部清理
184
183
  // bridge 重启 = 整个运行环境重启,所有 agent 都应该被终止
185
184
  const orphans = detectOrphanProcesses(persistedSessions.map((s) => ({
186
185
  agentId: s.agentId,
@@ -264,6 +263,7 @@ app.use("/runtime", sessionsRouter);
264
263
  app.use("/runtime", processesRouter);
265
264
  app.use("/runtime", gitRouter);
266
265
  app.use("/runtime", aiSourcesRouter);
266
+ app.use("/pty", ptyRouter);
267
267
  app.use("/api/file-browser", fileBrowserRouter);
268
268
  /**
269
269
  * 启动 HTTP 服务并对端口占用给出可诊断错误,避免未捕获异常直接崩溃。
@@ -272,6 +272,7 @@ function startServer() {
272
272
  const server = app.listen(port, () => {
273
273
  logger.info(`[runtime-bridge] listening on ${port}`);
274
274
  });
275
+ attachPtyWebSocketServer(server);
275
276
  server.on("error", (error) => {
276
277
  if (error.code === "EADDRINUSE") {
277
278
  logger.error(`[runtime-bridge] port ${port} is already in use. ` +
@@ -288,11 +289,10 @@ function startServer() {
288
289
  * 优雅关闭处理
289
290
  *
290
291
  * 在收到终止信号时:
291
- * 1. 停止所有 PTY 会话(杀死终端进程)
292
- * 2. 停止所有 SDK 会话(终止 Agent 进程)
293
- * 3. 验证所有进程已终止
294
- * 4. 清空持久化状态(避免恢复残留会话)
295
- * 5. 关闭 HTTP 服务器
292
+ * 1. 停止所有 SDK 会话(终止 Agent 进程)
293
+ * 2. 验证所有进程已终止
294
+ * 3. 清空持久化状态(避免恢复残留会话)
295
+ * 4. 关闭 HTTP 服务器
296
296
  *
297
297
  * ★★★ 修复:添加 preserveSessions 参数
298
298
  * - preserveSessions=true: aws-mcp-server 触发的关闭,保留会话状态
@@ -318,39 +318,7 @@ async function gracefulShutdown(signal, server, preserveSessions = false) {
318
318
  logger.info(`[runtime-bridge] 收到 ${signal} 信号,开始优雅关闭... (preserveSessions=${preserveSessions})`);
319
319
  const startTime = Date.now();
320
320
  try {
321
- // 1. 停止所有 PTY 会话
322
- const ptyCount = sessions.size;
323
- logger.info(`[runtime-bridge] 正在停止 ${ptyCount} 个 PTY 会话...`);
324
- for (const [sessionId, session] of sessions.entries()) {
325
- try {
326
- // 清理定时器
327
- if (session.flushTimer) {
328
- clearTimeout(session.flushTimer);
329
- session.flushTimer = null;
330
- }
331
- // 刷新剩余输出
332
- try {
333
- await flushSessionOutput(sessionId);
334
- }
335
- catch {
336
- // 忽略刷新错误
337
- }
338
- // 杀死 PTY 进程
339
- try {
340
- session.ptyProcess.kill();
341
- logger.info(`[runtime-bridge] PTY 会话 ${sessionId} 已终止 (PID: ${session.ptyProcess.pid})`);
342
- }
343
- catch {
344
- // 忽略终止错误
345
- }
346
- sessions.delete(sessionId);
347
- }
348
- catch (e) {
349
- const err = e;
350
- logger.error(`[runtime-bridge] PTY 会话 ${sessionId} 终止失败:`, err.message);
351
- }
352
- }
353
- // 2. 停止所有 SDK 会话
321
+ // 1. 停止所有 SDK 会话
354
322
  const sdkCount = sdkSessions.size;
355
323
  logger.info(`[runtime-bridge] 正在停止 ${sdkCount} 个 SDK 会话...`);
356
324
  for (const [sessionId, entry] of sdkSessions.entries()) {
@@ -379,6 +347,9 @@ async function gracefulShutdown(signal, server, preserveSessions = false) {
379
347
  sdkSessions.delete(sessionId);
380
348
  }
381
349
  }
350
+ const ptyCount = ptySessions.size;
351
+ logger.info(`[runtime-bridge] 正在停止 ${ptyCount} 个 PTY 会话...`);
352
+ closeAllPtySessions("shutdown");
382
353
  // 3. 停止孤儿进程监控
383
354
  logger.info("[runtime-bridge] 正在停止孤儿进程监控...");
384
355
  stopOrphanMonitor();
@@ -440,7 +411,7 @@ async function gracefulShutdown(signal, server, preserveSessions = false) {
440
411
  }
441
412
  // 8. 关闭 HTTP 服务器
442
413
  const elapsed = Date.now() - startTime;
443
- logger.info(`[runtime-bridge] 优雅关闭完成 (耗时 ${elapsed}ms),停止 ${ptyCount} PTY + ${sdkCount} SDK 会话`);
414
+ logger.info(`[runtime-bridge] 优雅关闭完成 (耗时 ${elapsed}ms),停止 ${sdkCount} SDK 会话`);
444
415
  server.close(() => {
445
416
  logger.info("[runtime-bridge] HTTP 服务器已关闭");
446
417
  process.exit(0);
@@ -4,6 +4,11 @@
4
4
  * 验证请求头中的 X-Runtime-Token 是否为已配对的 connectionKey 或 runtime binding token。
5
5
  */
6
6
  import type { Request, Response, NextFunction } from "express";
7
+ /**
8
+ * 校验 runtime token。
9
+ * 主流程:复用 REST 中间件的 runtime binding token 与 connectionKey 校验逻辑,供 WebSocket upgrade 使用。
10
+ */
11
+ export declare function isRuntimeTokenValid(token: unknown): boolean;
7
12
  /**
8
13
  * Token 验证中间件
9
14
  * 检查请求头中的 X-Runtime-Token 或 Authorization: Bearer 是否有效。
@@ -1 +1 @@
1
- {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/middleware/auth.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AA8B/D;;;;;GAKG;AACH,wBAAgB,aAAa,CAC3B,GAAG,EAAE,OAAO,EACZ,GAAG,EAAE,QAAQ,EACb,IAAI,EAAE,YAAY,GACjB,IAAI,CAmBN"}
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/middleware/auth.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AA8B/D;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAG3D;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAC3B,GAAG,EAAE,OAAO,EACZ,GAAG,EAAE,QAAQ,EACb,IAAI,EAAE,YAAY,GACjB,IAAI,CAmBN"}
@@ -23,6 +23,14 @@ function validateConfiguredToken(token) {
23
23
  }
24
24
  return false;
25
25
  }
26
+ /**
27
+ * 校验 runtime token。
28
+ * 主流程:复用 REST 中间件的 runtime binding token 与 connectionKey 校验逻辑,供 WebSocket upgrade 使用。
29
+ */
30
+ export function isRuntimeTokenValid(token) {
31
+ const normalized = String(token || "").trim();
32
+ return validateRuntimeBindingToken(normalized) || validateConfiguredToken(normalized);
33
+ }
26
34
  /**
27
35
  * Token 验证中间件
28
36
  * 检查请求头中的 X-Runtime-Token 或 Authorization: Bearer 是否有效。
@@ -31,7 +39,7 @@ function validateConfiguredToken(token) {
31
39
  */
32
40
  export function validateToken(req, res, next) {
33
41
  const token = extractRuntimeToken(req);
34
- if (validateRuntimeBindingToken(token) || validateConfiguredToken(token)) {
42
+ if (isRuntimeTokenValid(token)) {
35
43
  next();
36
44
  return;
37
45
  }
@@ -3,5 +3,15 @@
3
3
  *
4
4
  * 提供文件系统浏览功能
5
5
  */
6
+ import multer from 'multer';
6
7
  export declare const fileBrowserRouter: import("express-serve-static-core").Router;
8
+ export declare const WORKSPACE_UPLOAD_FILE_LIMIT = 2000;
9
+ export declare function createWorkspaceUploadLimitResponse(error: multer.MulterError): {
10
+ status: number;
11
+ body: {
12
+ error: string;
13
+ code: string;
14
+ };
15
+ };
16
+ export declare function parseWorkspaceUploadRelativePaths(body: Record<string, unknown>): string[];
7
17
  //# sourceMappingURL=file-browser.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"file-browser.d.ts","sourceRoot":"","sources":["../../src/routes/file-browser.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAmBH,eAAO,MAAM,iBAAiB,4CAAW,CAAC"}
1
+ {"version":3,"file":"file-browser.d.ts","sourceRoot":"","sources":["../../src/routes/file-browser.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAOH,OAAO,MAAM,MAAM,QAAQ,CAAC;AAuB5B,eAAO,MAAM,iBAAiB,4CAAW,CAAC;AAE1C,eAAO,MAAM,2BAA2B,OAAO,CAAC;AAqChD,wBAAgB,kCAAkC,CAAC,KAAK,EAAE,MAAM,CAAC,WAAW,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,CAUvI;AAED,wBAAgB,iCAAiC,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,EAAE,CAgBzF"}