opencode-bridge 2.9.0-beta

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 (237) hide show
  1. package/.env.example +131 -0
  2. package/LICENSE +674 -0
  3. package/README.md +1195 -0
  4. package/bin/opencode-bridge.js +31 -0
  5. package/dist/commands/effort.d.ts +9 -0
  6. package/dist/commands/effort.d.ts.map +1 -0
  7. package/dist/commands/effort.js +56 -0
  8. package/dist/commands/effort.js.map +1 -0
  9. package/dist/commands/parser.d.ts +37 -0
  10. package/dist/commands/parser.d.ts.map +1 -0
  11. package/dist/commands/parser.js +355 -0
  12. package/dist/commands/parser.js.map +1 -0
  13. package/dist/config.d.ts +91 -0
  14. package/dist/config.d.ts.map +1 -0
  15. package/dist/config.js +340 -0
  16. package/dist/config.js.map +1 -0
  17. package/dist/feishu/cards-stream.d.ts +65 -0
  18. package/dist/feishu/cards-stream.d.ts.map +1 -0
  19. package/dist/feishu/cards-stream.js +448 -0
  20. package/dist/feishu/cards-stream.js.map +1 -0
  21. package/dist/feishu/cards.d.ts +81 -0
  22. package/dist/feishu/cards.d.ts.map +1 -0
  23. package/dist/feishu/cards.js +560 -0
  24. package/dist/feishu/cards.js.map +1 -0
  25. package/dist/feishu/client.d.ts +132 -0
  26. package/dist/feishu/client.d.ts.map +1 -0
  27. package/dist/feishu/client.js +952 -0
  28. package/dist/feishu/client.js.map +1 -0
  29. package/dist/feishu/streamer.d.ts +30 -0
  30. package/dist/feishu/streamer.d.ts.map +1 -0
  31. package/dist/feishu/streamer.js +95 -0
  32. package/dist/feishu/streamer.js.map +1 -0
  33. package/dist/handlers/card-action.d.ts +12 -0
  34. package/dist/handlers/card-action.d.ts.map +1 -0
  35. package/dist/handlers/card-action.js +154 -0
  36. package/dist/handlers/card-action.js.map +1 -0
  37. package/dist/handlers/command.d.ts +76 -0
  38. package/dist/handlers/command.d.ts.map +1 -0
  39. package/dist/handlers/command.js +1773 -0
  40. package/dist/handlers/command.js.map +1 -0
  41. package/dist/handlers/discord.d.ts +78 -0
  42. package/dist/handlers/discord.d.ts.map +1 -0
  43. package/dist/handlers/discord.js +1832 -0
  44. package/dist/handlers/discord.js.map +1 -0
  45. package/dist/handlers/file-sender.d.ts +22 -0
  46. package/dist/handlers/file-sender.d.ts.map +1 -0
  47. package/dist/handlers/file-sender.js +183 -0
  48. package/dist/handlers/file-sender.js.map +1 -0
  49. package/dist/handlers/group.d.ts +21 -0
  50. package/dist/handlers/group.d.ts.map +1 -0
  51. package/dist/handlers/group.js +414 -0
  52. package/dist/handlers/group.js.map +1 -0
  53. package/dist/handlers/lifecycle.d.ts +17 -0
  54. package/dist/handlers/lifecycle.d.ts.map +1 -0
  55. package/dist/handlers/lifecycle.js +129 -0
  56. package/dist/handlers/lifecycle.js.map +1 -0
  57. package/dist/handlers/p2p.d.ts +44 -0
  58. package/dist/handlers/p2p.d.ts.map +1 -0
  59. package/dist/handlers/p2p.js +625 -0
  60. package/dist/handlers/p2p.js.map +1 -0
  61. package/dist/index.d.ts +33 -0
  62. package/dist/index.d.ts.map +1 -0
  63. package/dist/index.js +1562 -0
  64. package/dist/index.js.map +1 -0
  65. package/dist/opencode/client.d.ts +176 -0
  66. package/dist/opencode/client.d.ts.map +1 -0
  67. package/dist/opencode/client.js +1126 -0
  68. package/dist/opencode/client.js.map +1 -0
  69. package/dist/opencode/delayed-handler.d.ts +33 -0
  70. package/dist/opencode/delayed-handler.d.ts.map +1 -0
  71. package/dist/opencode/delayed-handler.js +74 -0
  72. package/dist/opencode/delayed-handler.js.map +1 -0
  73. package/dist/opencode/output-buffer.d.ts +56 -0
  74. package/dist/opencode/output-buffer.d.ts.map +1 -0
  75. package/dist/opencode/output-buffer.js +202 -0
  76. package/dist/opencode/output-buffer.js.map +1 -0
  77. package/dist/opencode/question-handler.d.ts +61 -0
  78. package/dist/opencode/question-handler.d.ts.map +1 -0
  79. package/dist/opencode/question-handler.js +183 -0
  80. package/dist/opencode/question-handler.js.map +1 -0
  81. package/dist/opencode/question-parser.d.ts +9 -0
  82. package/dist/opencode/question-parser.d.ts.map +1 -0
  83. package/dist/opencode/question-parser.js +69 -0
  84. package/dist/opencode/question-parser.js.map +1 -0
  85. package/dist/opencode/session-queue.d.ts +16 -0
  86. package/dist/opencode/session-queue.d.ts.map +1 -0
  87. package/dist/opencode/session-queue.js +41 -0
  88. package/dist/opencode/session-queue.js.map +1 -0
  89. package/dist/permissions/handler.d.ts +36 -0
  90. package/dist/permissions/handler.d.ts.map +1 -0
  91. package/dist/permissions/handler.js +141 -0
  92. package/dist/permissions/handler.js.map +1 -0
  93. package/dist/platform/adapters/discord-adapter.d.ts +45 -0
  94. package/dist/platform/adapters/discord-adapter.d.ts.map +1 -0
  95. package/dist/platform/adapters/discord-adapter.js +497 -0
  96. package/dist/platform/adapters/discord-adapter.js.map +1 -0
  97. package/dist/platform/adapters/feishu-adapter.d.ts +29 -0
  98. package/dist/platform/adapters/feishu-adapter.d.ts.map +1 -0
  99. package/dist/platform/adapters/feishu-adapter.js +150 -0
  100. package/dist/platform/adapters/feishu-adapter.js.map +1 -0
  101. package/dist/platform/registry.d.ts +41 -0
  102. package/dist/platform/registry.d.ts.map +1 -0
  103. package/dist/platform/registry.js +87 -0
  104. package/dist/platform/registry.js.map +1 -0
  105. package/dist/platform/types.d.ts +92 -0
  106. package/dist/platform/types.d.ts.map +1 -0
  107. package/dist/platform/types.js +4 -0
  108. package/dist/platform/types.js.map +1 -0
  109. package/dist/reliability/audit-log.d.ts +93 -0
  110. package/dist/reliability/audit-log.d.ts.map +1 -0
  111. package/dist/reliability/audit-log.js +248 -0
  112. package/dist/reliability/audit-log.js.map +1 -0
  113. package/dist/reliability/config-guard.d.ts +42 -0
  114. package/dist/reliability/config-guard.d.ts.map +1 -0
  115. package/dist/reliability/config-guard.js +264 -0
  116. package/dist/reliability/config-guard.js.map +1 -0
  117. package/dist/reliability/conversation-heartbeat.d.ts +37 -0
  118. package/dist/reliability/conversation-heartbeat.d.ts.map +1 -0
  119. package/dist/reliability/conversation-heartbeat.js +179 -0
  120. package/dist/reliability/conversation-heartbeat.js.map +1 -0
  121. package/dist/reliability/cron-api-server.d.ts +13 -0
  122. package/dist/reliability/cron-api-server.d.ts.map +1 -0
  123. package/dist/reliability/cron-api-server.js +247 -0
  124. package/dist/reliability/cron-api-server.js.map +1 -0
  125. package/dist/reliability/cron-control.d.ts +34 -0
  126. package/dist/reliability/cron-control.d.ts.map +1 -0
  127. package/dist/reliability/cron-control.js +864 -0
  128. package/dist/reliability/cron-control.js.map +1 -0
  129. package/dist/reliability/cron-semantic.d.ts +9 -0
  130. package/dist/reliability/cron-semantic.d.ts.map +1 -0
  131. package/dist/reliability/cron-semantic.js +208 -0
  132. package/dist/reliability/cron-semantic.js.map +1 -0
  133. package/dist/reliability/environment-doctor.d.ts +56 -0
  134. package/dist/reliability/environment-doctor.d.ts.map +1 -0
  135. package/dist/reliability/environment-doctor.js +213 -0
  136. package/dist/reliability/environment-doctor.js.map +1 -0
  137. package/dist/reliability/job-registry.d.ts +26 -0
  138. package/dist/reliability/job-registry.d.ts.map +1 -0
  139. package/dist/reliability/job-registry.js +77 -0
  140. package/dist/reliability/job-registry.js.map +1 -0
  141. package/dist/reliability/opencode-probe.d.ts +37 -0
  142. package/dist/reliability/opencode-probe.d.ts.map +1 -0
  143. package/dist/reliability/opencode-probe.js +195 -0
  144. package/dist/reliability/opencode-probe.js.map +1 -0
  145. package/dist/reliability/opencode-restart.d.ts +42 -0
  146. package/dist/reliability/opencode-restart.d.ts.map +1 -0
  147. package/dist/reliability/opencode-restart.js +155 -0
  148. package/dist/reliability/opencode-restart.js.map +1 -0
  149. package/dist/reliability/proactive-heartbeat.d.ts +39 -0
  150. package/dist/reliability/proactive-heartbeat.d.ts.map +1 -0
  151. package/dist/reliability/proactive-heartbeat.js +147 -0
  152. package/dist/reliability/proactive-heartbeat.js.map +1 -0
  153. package/dist/reliability/process-check-job.d.ts +73 -0
  154. package/dist/reliability/process-check-job.d.ts.map +1 -0
  155. package/dist/reliability/process-check-job.js +254 -0
  156. package/dist/reliability/process-check-job.js.map +1 -0
  157. package/dist/reliability/process-guard.d.ts +53 -0
  158. package/dist/reliability/process-guard.d.ts.map +1 -0
  159. package/dist/reliability/process-guard.js +344 -0
  160. package/dist/reliability/process-guard.js.map +1 -0
  161. package/dist/reliability/recovery-reporter.d.ts +37 -0
  162. package/dist/reliability/recovery-reporter.d.ts.map +1 -0
  163. package/dist/reliability/recovery-reporter.js +161 -0
  164. package/dist/reliability/recovery-reporter.js.map +1 -0
  165. package/dist/reliability/rescue-executor.d.ts +52 -0
  166. package/dist/reliability/rescue-executor.d.ts.map +1 -0
  167. package/dist/reliability/rescue-executor.js +244 -0
  168. package/dist/reliability/rescue-executor.js.map +1 -0
  169. package/dist/reliability/rescue-policy.d.ts +39 -0
  170. package/dist/reliability/rescue-policy.d.ts.map +1 -0
  171. package/dist/reliability/rescue-policy.js +85 -0
  172. package/dist/reliability/rescue-policy.js.map +1 -0
  173. package/dist/reliability/runtime-cron-dispatcher.d.ts +30 -0
  174. package/dist/reliability/runtime-cron-dispatcher.d.ts.map +1 -0
  175. package/dist/reliability/runtime-cron-dispatcher.js +100 -0
  176. package/dist/reliability/runtime-cron-dispatcher.js.map +1 -0
  177. package/dist/reliability/runtime-cron-orphan.d.ts +18 -0
  178. package/dist/reliability/runtime-cron-orphan.d.ts.map +1 -0
  179. package/dist/reliability/runtime-cron-orphan.js +87 -0
  180. package/dist/reliability/runtime-cron-orphan.js.map +1 -0
  181. package/dist/reliability/runtime-cron-registry.d.ts +4 -0
  182. package/dist/reliability/runtime-cron-registry.d.ts.map +1 -0
  183. package/dist/reliability/runtime-cron-registry.js +8 -0
  184. package/dist/reliability/runtime-cron-registry.js.map +1 -0
  185. package/dist/reliability/runtime-cron.d.ts +75 -0
  186. package/dist/reliability/runtime-cron.d.ts.map +1 -0
  187. package/dist/reliability/runtime-cron.js +309 -0
  188. package/dist/reliability/runtime-cron.js.map +1 -0
  189. package/dist/reliability/scheduler.d.ts +38 -0
  190. package/dist/reliability/scheduler.d.ts.map +1 -0
  191. package/dist/reliability/scheduler.js +174 -0
  192. package/dist/reliability/scheduler.js.map +1 -0
  193. package/dist/reliability/types.d.ts +151 -0
  194. package/dist/reliability/types.d.ts.map +1 -0
  195. package/dist/reliability/types.js +178 -0
  196. package/dist/reliability/types.js.map +1 -0
  197. package/dist/router/action-handlers.d.ts +27 -0
  198. package/dist/router/action-handlers.d.ts.map +1 -0
  199. package/dist/router/action-handlers.js +226 -0
  200. package/dist/router/action-handlers.js.map +1 -0
  201. package/dist/router/opencode-event-hub.d.ts +159 -0
  202. package/dist/router/opencode-event-hub.d.ts.map +1 -0
  203. package/dist/router/opencode-event-hub.js +589 -0
  204. package/dist/router/opencode-event-hub.js.map +1 -0
  205. package/dist/router/root-router.d.ts +94 -0
  206. package/dist/router/root-router.d.ts.map +1 -0
  207. package/dist/router/root-router.js +214 -0
  208. package/dist/router/root-router.js.map +1 -0
  209. package/dist/store/chat-session.d.ts +150 -0
  210. package/dist/store/chat-session.d.ts.map +1 -0
  211. package/dist/store/chat-session.js +640 -0
  212. package/dist/store/chat-session.js.map +1 -0
  213. package/dist/store/session-directory.d.ts +12 -0
  214. package/dist/store/session-directory.d.ts.map +1 -0
  215. package/dist/store/session-directory.js +47 -0
  216. package/dist/store/session-directory.js.map +1 -0
  217. package/dist/store/session-group.d.ts +19 -0
  218. package/dist/store/session-group.d.ts.map +1 -0
  219. package/dist/store/session-group.js +92 -0
  220. package/dist/store/session-group.js.map +1 -0
  221. package/dist/store/user-session.d.ts +19 -0
  222. package/dist/store/user-session.d.ts.map +1 -0
  223. package/dist/store/user-session.js +112 -0
  224. package/dist/store/user-session.js.map +1 -0
  225. package/dist/utils/async-queue.d.ts +12 -0
  226. package/dist/utils/async-queue.d.ts.map +1 -0
  227. package/dist/utils/async-queue.js +51 -0
  228. package/dist/utils/async-queue.js.map +1 -0
  229. package/dist/utils/directory-policy.d.ts +50 -0
  230. package/dist/utils/directory-policy.d.ts.map +1 -0
  231. package/dist/utils/directory-policy.js +379 -0
  232. package/dist/utils/directory-policy.js.map +1 -0
  233. package/dist/utils/session-title.d.ts +2 -0
  234. package/dist/utils/session-title.d.ts.map +1 -0
  235. package/dist/utils/session-title.js +10 -0
  236. package/dist/utils/session-title.js.map +1 -0
  237. package/package.json +73 -0
@@ -0,0 +1,151 @@
1
+ /**
2
+ * 故障分类与救援状态机类型定义
3
+ *
4
+ * 本模块定义桥接服务可靠性相关的故障分类体系和救援状态机。
5
+ * 用于统一故障检测、状态管理和恢复策略。
6
+ */
7
+ /**
8
+ * 故障类型分类
9
+ *
10
+ * 按故障来源和性质分为:
11
+ * - 桥接启动故障 (bridge_boot_failed): 桥接服务自身启动失败
12
+ * - 桥接陈旧故障 (bridge_stale): 桥接会话/状态过期
13
+ * - OpenCode TCP 连接故障 (opencode_tcp_down): TCP 层连接超时/拒绝
14
+ * - OpenCode HTTP 服务故障 (opencode_http_down): HTTP 层响应异常
15
+ * - OpenCode 认证故障 (opencode_auth_invalid): 401/403 认证失败
16
+ * - 事件流陈旧故障 (event_stream_stale): SSE 事件流停滞
17
+ */
18
+ export declare enum FailureType {
19
+ /** 桥接启动失败 - 端口占用/配置错误等 */
20
+ BRIDGE_BOOT_FAILED = "bridge_boot_failed",
21
+ /** 桥接状态陈旧 - 会话映射过期/缓存失效 */
22
+ BRIDGE_STALE = "bridge_stale",
23
+ /** OpenCode TCP 连接故障 - 连接超时/拒绝/重置 */
24
+ OPENCODE_TCP_DOWN = "opencode_tcp_down",
25
+ /** OpenCode HTTP 服务故障 - HTTP 响应超时/5xx 错误 */
26
+ OPENCODE_HTTP_DOWN = "opencode_http_down",
27
+ /** OpenCode 认证失败 - 401/403 认证无效 */
28
+ OPENCODE_AUTH_INVALID = "opencode_auth_invalid",
29
+ /** 事件流陈旧 - SSE 连接停滞/心跳丢失 */
30
+ EVENT_STREAM_STALE = "event_stream_stale"
31
+ }
32
+ /**
33
+ * 救援状态机状态
34
+ *
35
+ * 状态跃迁规则:
36
+ * - healthy -> suspect: 检测到潜在故障
37
+ * - suspect -> healthy: 故障消失/自愈
38
+ * - suspect -> degraded: 故障确认
39
+ * - degraded -> repairing: 启动自动修复
40
+ * - degraded -> manual_required: 需要人工介入
41
+ * - repairing -> recovered: 修复成功
42
+ * - repairing -> degraded: 修复失败回退
43
+ * - repairing -> manual_required: 修复失败需人工
44
+ * - recovered -> healthy: 观察期结束后恢复正常
45
+ * - manual_required -> healthy: 人工处理后恢复
46
+ */
47
+ export declare enum RescueState {
48
+ /** 健康状态 - 所有系统正常 */
49
+ HEALTHY = "healthy",
50
+ /** 可疑状态 - 检测到潜在异常待确认 */
51
+ SUSPECT = "suspect",
52
+ /** 降级状态 - 故障确认但服务仍可用 */
53
+ DEGRADED = "degraded",
54
+ /** 修复中状态 - 正在执行自动恢复流程 */
55
+ REPAIRING = "repairing",
56
+ /** 已恢复状态 - 修复完成待观察确认 */
57
+ RECOVERED = "recovered",
58
+ /** 需人工介入 - 自动修复失败需人工处理 */
59
+ MANUAL_REQUIRED = "manual_required"
60
+ }
61
+ /**
62
+ * 状态跃迁规则定义
63
+ *
64
+ * 禁止的跃迁:
65
+ * - healthy -> repairing: 健康状态不能直接跳修复
66
+ * - healthy -> recovered: 健康状态不能直接跳已恢复
67
+ * - healthy -> manual_required: 健康状态不能直接跳人工
68
+ * - suspect -> repairing: 可疑状态需先确认故障
69
+ * - suspect -> recovered: 可疑状态不能直接跳已恢复
70
+ * - degraded -> healthy: 降级状态需经过修复流程
71
+ * - repairing -> healthy: 修复中需先确认恢复再观察
72
+ * - manual_required -> 任意状态 (除 healthy): 人工介入后必须观察
73
+ */
74
+ export declare const VALID_STATE_TRANSITIONS: Record<RescueState, RescueState[]>;
75
+ /**
76
+ * 故障到初始救援状态的映射
77
+ *
78
+ * 不同故障类型触发不同的初始响应策略
79
+ */
80
+ export declare const FAILURE_TO_INITIAL_STATE: Record<FailureType, RescueState>;
81
+ /**
82
+ * 验证状态跃迁是否合法
83
+ *
84
+ * @param from 当前状态
85
+ * @param to 目标状态
86
+ * @returns 是否允许跃迁
87
+ */
88
+ export declare function isValidStateTransition(from: RescueState, to: RescueState): boolean;
89
+ /**
90
+ * 状态跃迁验证器类
91
+ *
92
+ * 提供带错误信息的跃迁验证
93
+ */
94
+ export declare class StateTransitionValidator {
95
+ private currentState;
96
+ constructor(initialState?: RescueState);
97
+ /**
98
+ * 尝试执行状态跃迁
99
+ *
100
+ * @param nextState 目标状态
101
+ * @returns 是否成功
102
+ * @throws 当跃迁非法时抛出错误
103
+ */
104
+ transitionTo(nextState: RescueState): boolean;
105
+ /**
106
+ * 检查跃迁是否合法(不执行实际跃迁)
107
+ *
108
+ * @param nextState 目标状态
109
+ * @returns 是否允许
110
+ */
111
+ canTransitionTo(nextState: RescueState): boolean;
112
+ /**
113
+ * 获取当前状态
114
+ */
115
+ getState(): RescueState;
116
+ /**
117
+ * 重置状态
118
+ */
119
+ reset(initialState?: RescueState): void;
120
+ }
121
+ /**
122
+ * 故障事件接口
123
+ *
124
+ * 用于在系统内部传递故障信息
125
+ */
126
+ export interface FailureEvent {
127
+ /** 故障类型 */
128
+ type: FailureType;
129
+ /** 故障发生时间戳 */
130
+ timestamp: number;
131
+ /** 故障详细描述 */
132
+ message: string;
133
+ /** 相关错误对象(可选) */
134
+ error?: Error;
135
+ /** 附加上下文信息 */
136
+ context?: Record<string, unknown>;
137
+ }
138
+ /**
139
+ * 救援状态变更事件接口
140
+ */
141
+ export interface StateChangeEvent {
142
+ /** 变更前状态 */
143
+ from: RescueState;
144
+ /** 变更后状态 */
145
+ to: RescueState;
146
+ /** 变更原因 */
147
+ reason: string;
148
+ /** 变更时间戳 */
149
+ timestamp: number;
150
+ }
151
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/reliability/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;;;;;;;;GAUG;AACH,oBAAY,WAAW;IACrB,0BAA0B;IAC1B,kBAAkB,uBAAuB;IAEzC,2BAA2B;IAC3B,YAAY,iBAAiB;IAE7B,qCAAqC;IACrC,iBAAiB,sBAAsB;IAEvC,4CAA4C;IAC5C,kBAAkB,uBAAuB;IAEzC,mCAAmC;IACnC,qBAAqB,0BAA0B;IAE/C,4BAA4B;IAC5B,kBAAkB,uBAAuB;CAC1C;AAED;;;;;;;;;;;;;;GAcG;AACH,oBAAY,WAAW;IACrB,oBAAoB;IACpB,OAAO,YAAY;IAEnB,wBAAwB;IACxB,OAAO,YAAY;IAEnB,wBAAwB;IACxB,QAAQ,aAAa;IAErB,yBAAyB;IACzB,SAAS,cAAc;IAEvB,wBAAwB;IACxB,SAAS,cAAc;IAEvB,0BAA0B;IAC1B,eAAe,oBAAoB;CACpC;AAED;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,uBAAuB,EAAE,MAAM,CAAC,WAAW,EAAE,WAAW,EAAE,CAwBtE,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,wBAAwB,EAAE,MAAM,CAAC,WAAW,EAAE,WAAW,CAOrE,CAAC;AAEF;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,WAAW,EAAE,EAAE,EAAE,WAAW,GAAG,OAAO,CAMlF;AAED;;;;GAIG;AACH,qBAAa,wBAAwB;IACnC,OAAO,CAAC,YAAY,CAAc;gBAEtB,YAAY,GAAE,WAAiC;IAO3D;;;;;;OAMG;IACH,YAAY,CAAC,SAAS,EAAE,WAAW,GAAG,OAAO;IAW7C;;;;;OAKG;IACH,eAAe,CAAC,SAAS,EAAE,WAAW,GAAG,OAAO;IAIhD;;OAEG;IACH,QAAQ,IAAI,WAAW;IAIvB;;OAEG;IACH,KAAK,CAAC,YAAY,GAAE,WAAiC,GAAG,IAAI;CAG7D;AAED;;;;GAIG;AACH,MAAM,WAAW,YAAY;IAC3B,WAAW;IACX,IAAI,EAAE,WAAW,CAAC;IAClB,cAAc;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,iBAAiB;IACjB,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,cAAc;IACd,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,YAAY;IACZ,IAAI,EAAE,WAAW,CAAC;IAClB,YAAY;IACZ,EAAE,EAAE,WAAW,CAAC;IAChB,WAAW;IACX,MAAM,EAAE,MAAM,CAAC;IACf,YAAY;IACZ,SAAS,EAAE,MAAM,CAAC;CACnB"}
@@ -0,0 +1,178 @@
1
+ /**
2
+ * 故障分类与救援状态机类型定义
3
+ *
4
+ * 本模块定义桥接服务可靠性相关的故障分类体系和救援状态机。
5
+ * 用于统一故障检测、状态管理和恢复策略。
6
+ */
7
+ /**
8
+ * 故障类型分类
9
+ *
10
+ * 按故障来源和性质分为:
11
+ * - 桥接启动故障 (bridge_boot_failed): 桥接服务自身启动失败
12
+ * - 桥接陈旧故障 (bridge_stale): 桥接会话/状态过期
13
+ * - OpenCode TCP 连接故障 (opencode_tcp_down): TCP 层连接超时/拒绝
14
+ * - OpenCode HTTP 服务故障 (opencode_http_down): HTTP 层响应异常
15
+ * - OpenCode 认证故障 (opencode_auth_invalid): 401/403 认证失败
16
+ * - 事件流陈旧故障 (event_stream_stale): SSE 事件流停滞
17
+ */
18
+ export var FailureType;
19
+ (function (FailureType) {
20
+ /** 桥接启动失败 - 端口占用/配置错误等 */
21
+ FailureType["BRIDGE_BOOT_FAILED"] = "bridge_boot_failed";
22
+ /** 桥接状态陈旧 - 会话映射过期/缓存失效 */
23
+ FailureType["BRIDGE_STALE"] = "bridge_stale";
24
+ /** OpenCode TCP 连接故障 - 连接超时/拒绝/重置 */
25
+ FailureType["OPENCODE_TCP_DOWN"] = "opencode_tcp_down";
26
+ /** OpenCode HTTP 服务故障 - HTTP 响应超时/5xx 错误 */
27
+ FailureType["OPENCODE_HTTP_DOWN"] = "opencode_http_down";
28
+ /** OpenCode 认证失败 - 401/403 认证无效 */
29
+ FailureType["OPENCODE_AUTH_INVALID"] = "opencode_auth_invalid";
30
+ /** 事件流陈旧 - SSE 连接停滞/心跳丢失 */
31
+ FailureType["EVENT_STREAM_STALE"] = "event_stream_stale";
32
+ })(FailureType || (FailureType = {}));
33
+ /**
34
+ * 救援状态机状态
35
+ *
36
+ * 状态跃迁规则:
37
+ * - healthy -> suspect: 检测到潜在故障
38
+ * - suspect -> healthy: 故障消失/自愈
39
+ * - suspect -> degraded: 故障确认
40
+ * - degraded -> repairing: 启动自动修复
41
+ * - degraded -> manual_required: 需要人工介入
42
+ * - repairing -> recovered: 修复成功
43
+ * - repairing -> degraded: 修复失败回退
44
+ * - repairing -> manual_required: 修复失败需人工
45
+ * - recovered -> healthy: 观察期结束后恢复正常
46
+ * - manual_required -> healthy: 人工处理后恢复
47
+ */
48
+ export var RescueState;
49
+ (function (RescueState) {
50
+ /** 健康状态 - 所有系统正常 */
51
+ RescueState["HEALTHY"] = "healthy";
52
+ /** 可疑状态 - 检测到潜在异常待确认 */
53
+ RescueState["SUSPECT"] = "suspect";
54
+ /** 降级状态 - 故障确认但服务仍可用 */
55
+ RescueState["DEGRADED"] = "degraded";
56
+ /** 修复中状态 - 正在执行自动恢复流程 */
57
+ RescueState["REPAIRING"] = "repairing";
58
+ /** 已恢复状态 - 修复完成待观察确认 */
59
+ RescueState["RECOVERED"] = "recovered";
60
+ /** 需人工介入 - 自动修复失败需人工处理 */
61
+ RescueState["MANUAL_REQUIRED"] = "manual_required";
62
+ })(RescueState || (RescueState = {}));
63
+ /**
64
+ * 状态跃迁规则定义
65
+ *
66
+ * 禁止的跃迁:
67
+ * - healthy -> repairing: 健康状态不能直接跳修复
68
+ * - healthy -> recovered: 健康状态不能直接跳已恢复
69
+ * - healthy -> manual_required: 健康状态不能直接跳人工
70
+ * - suspect -> repairing: 可疑状态需先确认故障
71
+ * - suspect -> recovered: 可疑状态不能直接跳已恢复
72
+ * - degraded -> healthy: 降级状态需经过修复流程
73
+ * - repairing -> healthy: 修复中需先确认恢复再观察
74
+ * - manual_required -> 任意状态 (除 healthy): 人工介入后必须观察
75
+ */
76
+ export const VALID_STATE_TRANSITIONS = {
77
+ [RescueState.HEALTHY]: [
78
+ RescueState.SUSPECT
79
+ ],
80
+ [RescueState.SUSPECT]: [
81
+ RescueState.HEALTHY,
82
+ RescueState.DEGRADED
83
+ ],
84
+ [RescueState.DEGRADED]: [
85
+ RescueState.REPAIRING,
86
+ RescueState.MANUAL_REQUIRED
87
+ ],
88
+ [RescueState.REPAIRING]: [
89
+ RescueState.RECOVERED,
90
+ RescueState.DEGRADED,
91
+ RescueState.MANUAL_REQUIRED
92
+ ],
93
+ [RescueState.RECOVERED]: [
94
+ RescueState.HEALTHY,
95
+ RescueState.SUSPECT
96
+ ],
97
+ [RescueState.MANUAL_REQUIRED]: [
98
+ RescueState.HEALTHY
99
+ ]
100
+ };
101
+ /**
102
+ * 故障到初始救援状态的映射
103
+ *
104
+ * 不同故障类型触发不同的初始响应策略
105
+ */
106
+ export const FAILURE_TO_INITIAL_STATE = {
107
+ [FailureType.BRIDGE_BOOT_FAILED]: RescueState.MANUAL_REQUIRED,
108
+ [FailureType.BRIDGE_STALE]: RescueState.SUSPECT,
109
+ [FailureType.OPENCODE_TCP_DOWN]: RescueState.SUSPECT,
110
+ [FailureType.OPENCODE_HTTP_DOWN]: RescueState.SUSPECT,
111
+ [FailureType.OPENCODE_AUTH_INVALID]: RescueState.DEGRADED,
112
+ [FailureType.EVENT_STREAM_STALE]: RescueState.SUSPECT
113
+ };
114
+ /**
115
+ * 验证状态跃迁是否合法
116
+ *
117
+ * @param from 当前状态
118
+ * @param to 目标状态
119
+ * @returns 是否允许跃迁
120
+ */
121
+ export function isValidStateTransition(from, to) {
122
+ const validTargets = VALID_STATE_TRANSITIONS[from];
123
+ if (!validTargets) {
124
+ return false;
125
+ }
126
+ return validTargets.includes(to);
127
+ }
128
+ /**
129
+ * 状态跃迁验证器类
130
+ *
131
+ * 提供带错误信息的跃迁验证
132
+ */
133
+ export class StateTransitionValidator {
134
+ currentState;
135
+ constructor(initialState = RescueState.HEALTHY) {
136
+ if (!Object.values(RescueState).includes(initialState)) {
137
+ throw new Error(`无效的初始状态:${initialState}`);
138
+ }
139
+ this.currentState = initialState;
140
+ }
141
+ /**
142
+ * 尝试执行状态跃迁
143
+ *
144
+ * @param nextState 目标状态
145
+ * @returns 是否成功
146
+ * @throws 当跃迁非法时抛出错误
147
+ */
148
+ transitionTo(nextState) {
149
+ if (!isValidStateTransition(this.currentState, nextState)) {
150
+ throw new Error(`非法的状态跃迁:${this.currentState} -> ${nextState}。` +
151
+ `允许的跃迁:${VALID_STATE_TRANSITIONS[this.currentState].join(', ') || '无'}`);
152
+ }
153
+ this.currentState = nextState;
154
+ return true;
155
+ }
156
+ /**
157
+ * 检查跃迁是否合法(不执行实际跃迁)
158
+ *
159
+ * @param nextState 目标状态
160
+ * @returns 是否允许
161
+ */
162
+ canTransitionTo(nextState) {
163
+ return isValidStateTransition(this.currentState, nextState);
164
+ }
165
+ /**
166
+ * 获取当前状态
167
+ */
168
+ getState() {
169
+ return this.currentState;
170
+ }
171
+ /**
172
+ * 重置状态
173
+ */
174
+ reset(initialState = RescueState.HEALTHY) {
175
+ this.currentState = initialState;
176
+ }
177
+ }
178
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/reliability/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * 路由器动作处理器
3
+ *
4
+ * 从 index.ts 抽取的权限和问题处理逻辑,
5
+ * 通过依赖注入方式提供给 RootRouter。
6
+ */
7
+ import type { FeishuCardActionEvent } from '../feishu/client.js';
8
+ import type { FeishuMessageEvent } from '../feishu/client.js';
9
+ import type { CardActionResponse } from './root-router.js';
10
+ /**
11
+ * Timeline 回调类型
12
+ */
13
+ export type UpsertTimelineNote = (bufferKey: string, noteKey: string, text: string, variant?: 'retry' | 'compaction' | 'question' | 'error' | 'permission') => void;
14
+ /**
15
+ * 创建权限动作处理器
16
+ */
17
+ export declare function createPermissionActionCallbacks(upsertTimelineNote: UpsertTimelineNote): {
18
+ handlePermissionAction: (actionValue: Record<string, unknown>, action: 'permission_allow' | 'permission_deny') => Promise<CardActionResponse>;
19
+ tryHandlePendingPermissionByText: (event: FeishuMessageEvent) => Promise<boolean>;
20
+ };
21
+ /**
22
+ * 创建问题动作处理器
23
+ */
24
+ export declare function createQuestionActionCallbacks(): {
25
+ handleQuestionSkipAction: (event: FeishuCardActionEvent, actionValue: Record<string, unknown>) => Promise<CardActionResponse>;
26
+ };
27
+ //# sourceMappingURL=action-handlers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"action-handlers.d.ts","sourceRoot":"","sources":["../../src/router/action-handlers.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AACjE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAC9D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAQ3D;;GAEG;AACH,MAAM,MAAM,kBAAkB,GAAG,CAC/B,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE,OAAO,GAAG,YAAY,GAAG,UAAU,GAAG,OAAO,GAAG,YAAY,KACnE,IAAI,CAAC;AAiEV;;GAEG;AACH,wBAAgB,+BAA+B,CAC7C,kBAAkB,EAAE,kBAAkB,GACrC;IACD,sBAAsB,EAAE,CACtB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACpC,MAAM,EAAE,kBAAkB,GAAG,iBAAiB,KAC3C,OAAO,CAAC,kBAAkB,CAAC,CAAC;IACjC,gCAAgC,EAAE,CAChC,KAAK,EAAE,kBAAkB,KACtB,OAAO,CAAC,OAAO,CAAC,CAAC;CACvB,CAuLA;AAED;;GAEG;AACH,wBAAgB,6BAA6B,IAAI;IAC/C,wBAAwB,EAAE,CACxB,KAAK,EAAE,qBAAqB,EAC5B,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KACjC,OAAO,CAAC,kBAAkB,CAAC,CAAC;CAClC,CAyCA"}
@@ -0,0 +1,226 @@
1
+ /**
2
+ * 路由器动作处理器
3
+ *
4
+ * 从 index.ts 抽取的权限和问题处理逻辑,
5
+ * 通过依赖注入方式提供给 RootRouter。
6
+ */
7
+ import { chatSessionStore } from '../store/chat-session.js';
8
+ import { permissionHandler } from '../permissions/handler.js';
9
+ import { opencodeClient } from '../opencode/client.js';
10
+ import { outputBuffer } from '../opencode/output-buffer.js';
11
+ import { feishuClient } from '../feishu/client.js';
12
+ import { groupHandler } from '../handlers/group.js';
13
+ // 辅助函数
14
+ const toTrimmedString = (value) => {
15
+ if (typeof value !== 'string')
16
+ return undefined;
17
+ const trimmed = value.trim();
18
+ return trimmed.length > 0 ? trimmed : undefined;
19
+ };
20
+ const toInteger = (value) => {
21
+ if (typeof value === 'number' && Number.isInteger(value))
22
+ return value;
23
+ if (typeof value === 'string' && value.trim().length > 0) {
24
+ const parsed = Number(value);
25
+ return Number.isInteger(parsed) ? parsed : undefined;
26
+ }
27
+ return undefined;
28
+ };
29
+ const parsePermissionDecision = (raw) => {
30
+ const normalized = raw.normalize('NFKC').trim().toLowerCase();
31
+ if (!normalized)
32
+ return null;
33
+ const compact = normalized
34
+ .replace(/[\s\u3000]+/g, '')
35
+ .replace(/[。!!,.,;;::\-]/g, '');
36
+ const hasAlways = compact.includes('始终') ||
37
+ compact.includes('永久') ||
38
+ compact.includes('always') ||
39
+ compact.includes('记住') ||
40
+ compact.includes('总是');
41
+ const containsAny = (words) => {
42
+ return words.some(word => compact === word || compact.includes(word));
43
+ };
44
+ const isDeny = compact === 'n' ||
45
+ compact === 'no' ||
46
+ compact === '否' ||
47
+ compact === '拒绝' ||
48
+ containsAny(['拒绝', '不同意', '不允许', 'deny']);
49
+ if (isDeny) {
50
+ return { allow: false, remember: false };
51
+ }
52
+ const isAllow = compact === 'y' ||
53
+ compact === 'yes' ||
54
+ compact === 'ok' ||
55
+ compact === 'always' ||
56
+ compact === '允许' ||
57
+ compact === '始终允许' ||
58
+ containsAny(['允许', '同意', '通过', '批准', 'allow']);
59
+ if (isAllow) {
60
+ return { allow: true, remember: hasAlways };
61
+ }
62
+ return null;
63
+ };
64
+ /**
65
+ * 创建权限动作处理器
66
+ */
67
+ export function createPermissionActionCallbacks(upsertTimelineNote) {
68
+ const resolvePermissionDirectoryOptions = (sessionId, chatIdHint) => {
69
+ const conversation = chatSessionStore.getConversationBySessionId(sessionId);
70
+ const boundSession = conversation
71
+ ? chatSessionStore.getSessionByConversation(conversation.platform, conversation.conversationId)
72
+ : undefined;
73
+ const queueHintSession = chatIdHint
74
+ ? chatSessionStore.getSession(chatIdHint)
75
+ : undefined;
76
+ const directory = boundSession?.resolvedDirectory
77
+ || queueHintSession?.resolvedDirectory
78
+ || boundSession?.defaultDirectory
79
+ || queueHintSession?.defaultDirectory;
80
+ const fallbackDirectories = Array.from(new Set([
81
+ boundSession?.resolvedDirectory,
82
+ boundSession?.defaultDirectory,
83
+ queueHintSession?.resolvedDirectory,
84
+ queueHintSession?.defaultDirectory,
85
+ ...chatSessionStore.getKnownDirectories(),
86
+ ].filter((value) => typeof value === 'string' && value.trim().length > 0)));
87
+ return {
88
+ ...(directory ? { directory } : {}),
89
+ ...(fallbackDirectories.length > 0 ? { fallbackDirectories } : {}),
90
+ };
91
+ };
92
+ const handlePermissionAction = async (actionValue, action) => {
93
+ const sessionId = toTrimmedString(actionValue.sessionId);
94
+ const permissionId = toTrimmedString(actionValue.permissionId);
95
+ if (!sessionId || !permissionId) {
96
+ return {
97
+ toast: {
98
+ type: 'error',
99
+ content: '权限参数缺失',
100
+ i18n_content: { zh_cn: '权限参数缺失', en_us: 'Missing permission params' },
101
+ },
102
+ };
103
+ }
104
+ const allow = action === 'permission_allow';
105
+ const rememberRaw = typeof actionValue.remember === 'string'
106
+ ? actionValue.remember.normalize('NFKC').trim().toLowerCase()
107
+ : actionValue.remember;
108
+ const remember = rememberRaw === true ||
109
+ rememberRaw === 1 ||
110
+ rememberRaw === '1' ||
111
+ rememberRaw === 'true' ||
112
+ rememberRaw === 'always' ||
113
+ rememberRaw === '始终允许';
114
+ const permissionDirectoryOptions = resolvePermissionDirectoryOptions(sessionId);
115
+ const responded = await opencodeClient.respondToPermission(sessionId, permissionId, allow, remember, permissionDirectoryOptions);
116
+ if (!responded) {
117
+ console.error(`[权限] 响应失败: session=${sessionId}, permission=${permissionId}`);
118
+ return {
119
+ toast: {
120
+ type: 'error',
121
+ content: '权限响应失败',
122
+ i18n_content: { zh_cn: '权限响应失败', en_us: 'Permission response failed' },
123
+ },
124
+ };
125
+ }
126
+ console.log(`[权限] 卡片响应成功: session=${sessionId}, permission=${permissionId}, allow=${allow}, remember=${remember}`);
127
+ const permissionChatId = chatSessionStore.getChatId(sessionId);
128
+ if (permissionChatId) {
129
+ const bufferKey = `chat:${permissionChatId}`;
130
+ const removed = permissionHandler.resolveForChat(permissionChatId, permissionId);
131
+ if (removed) {
132
+ const resolvedText = allow
133
+ ? remember ? `✅ 已允许并记住权限:${removed.tool}` : `✅ 已允许权限:${removed.tool}`
134
+ : `❌ 已拒绝权限:${removed.tool}`;
135
+ upsertTimelineNote(bufferKey, `permission-result:${sessionId}:${permissionId}:${allow ? 'allow' : 'deny'}:${remember ? 'always' : 'once'}`, resolvedText, 'permission');
136
+ }
137
+ outputBuffer.touch(bufferKey);
138
+ }
139
+ return {
140
+ toast: {
141
+ type: allow ? 'success' : 'error',
142
+ content: allow ? '已允许' : '已拒绝',
143
+ i18n_content: { zh_cn: allow ? '已允许' : '已拒绝', en_us: allow ? 'Allowed' : 'Denied' },
144
+ },
145
+ };
146
+ };
147
+ const tryHandlePendingPermissionByText = async (event) => {
148
+ if (event.chatType !== 'group')
149
+ return false;
150
+ const trimmedContent = event.content.trim();
151
+ if (!trimmedContent || trimmedContent.startsWith('/'))
152
+ return false;
153
+ const pending = permissionHandler.peekForChat(event.chatId);
154
+ if (!pending)
155
+ return false;
156
+ const decision = parsePermissionDecision(trimmedContent);
157
+ if (!decision) {
158
+ await feishuClient.reply(event.messageId, '当前有待确认权限,请回复:允许 / 拒绝 / 始终允许(也支持 y / n / always)');
159
+ return true;
160
+ }
161
+ const permissionDirectoryOptions = resolvePermissionDirectoryOptions(pending.sessionId, event.chatId);
162
+ const responded = await opencodeClient.respondToPermission(pending.sessionId, pending.permissionId, decision.allow, decision.remember, permissionDirectoryOptions);
163
+ if (!responded) {
164
+ console.error(`[权限] 文本响应失败: chat=${event.chatId}`);
165
+ await feishuClient.reply(event.messageId, '权限响应失败,请重试');
166
+ return true;
167
+ }
168
+ console.log(`[权限] 文本响应成功: chat=${event.chatId}, session=${pending.sessionId}, permission=${pending.permissionId}, allow=${decision.allow}, remember=${decision.remember}`);
169
+ const removed = permissionHandler.resolveForChat(event.chatId, pending.permissionId);
170
+ const bufferKey = `chat:${event.chatId}`;
171
+ if (!outputBuffer.get(bufferKey)) {
172
+ outputBuffer.getOrCreate(bufferKey, event.chatId, pending.sessionId, event.messageId);
173
+ }
174
+ const toolName = removed?.tool || pending.tool || '工具';
175
+ const resolvedText = decision.allow
176
+ ? decision.remember ? `✅ 已允许并记住权限:${toolName}` : `✅ 已允许权限:${toolName}`
177
+ : `❌ 已拒绝权限:${toolName}`;
178
+ upsertTimelineNote(bufferKey, `permission-result-text:${pending.sessionId}:${pending.permissionId}:${decision.allow ? 'allow' : 'deny'}:${decision.remember ? 'always' : 'once'}`, resolvedText, 'permission');
179
+ outputBuffer.touch(bufferKey);
180
+ await feishuClient.reply(event.messageId, decision.allow ? (decision.remember ? '已允许并记住该权限' : '已允许该权限') : '已拒绝该权限');
181
+ return true;
182
+ };
183
+ return {
184
+ handlePermissionAction,
185
+ tryHandlePendingPermissionByText,
186
+ };
187
+ }
188
+ /**
189
+ * 创建问题动作处理器
190
+ */
191
+ export function createQuestionActionCallbacks() {
192
+ const handleQuestionSkipAction = async (event, actionValue) => {
193
+ const chatId = toTrimmedString(actionValue.chatId) || event.chatId;
194
+ const requestId = toTrimmedString(actionValue.requestId);
195
+ const questionIndex = toInteger(actionValue.questionIndex);
196
+ if (!chatId) {
197
+ return {
198
+ toast: {
199
+ type: 'error',
200
+ content: '无法定位会话',
201
+ i18n_content: { zh_cn: '无法定位会话', en_us: 'Failed to locate chat' },
202
+ },
203
+ };
204
+ }
205
+ const result = await groupHandler.handleQuestionSkipAction({
206
+ chatId,
207
+ messageId: event.messageId,
208
+ requestId,
209
+ questionIndex,
210
+ });
211
+ if (result === 'applied') {
212
+ return { toast: { type: 'success', content: '已跳过本题', i18n_content: { zh_cn: '已跳过本题', en_us: 'Question skipped' } } };
213
+ }
214
+ if (result === 'stale_card') {
215
+ return { toast: { type: 'error', content: '请操作最新问题状态', i18n_content: { zh_cn: '请操作最新问题状态', en_us: 'Please use latest question state' } } };
216
+ }
217
+ if (result === 'not_found') {
218
+ return { toast: { type: 'error', content: '当前没有待回答问题', i18n_content: { zh_cn: '当前没有待回答问题', en_us: 'No pending question' } } };
219
+ }
220
+ return { toast: { type: 'error', content: '跳过失败,请重试', i18n_content: { zh_cn: '跳过失败,请重试', en_us: 'Skip failed, try again' } } };
221
+ };
222
+ return {
223
+ handleQuestionSkipAction,
224
+ };
225
+ }
226
+ //# sourceMappingURL=action-handlers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"action-handlers.js","sourceRoot":"","sources":["../../src/router/action-handlers.ts"],"names":[],"mappings":"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"}