@jingyi0605/codingns 0.1.0 → 0.1.2

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 (241) hide show
  1. package/README.md +14 -0
  2. package/dist/public/assets/TerminalPage-Dr7knYq2.js +55 -0
  3. package/dist/public/assets/index-BpUi6zoT.js +108 -0
  4. package/dist/public/assets/index-NMtdQNda.css +1 -0
  5. package/dist/public/index.html +2 -2
  6. package/dist/server/config/env.js +72 -7
  7. package/dist/server/config/env.js.map +1 -1
  8. package/dist/server/config/opencode-base-url-resolver.d.ts +13 -8
  9. package/dist/server/config/opencode-base-url-resolver.js +117 -147
  10. package/dist/server/config/opencode-base-url-resolver.js.map +1 -1
  11. package/dist/server/config/opencode-system-probe-helper-client.d.ts +18 -0
  12. package/dist/server/config/opencode-system-probe-helper-client.js +127 -0
  13. package/dist/server/config/opencode-system-probe-helper-client.js.map +1 -0
  14. package/dist/server/config/opencode-system-probe-helper-process.d.ts +1 -0
  15. package/dist/server/config/opencode-system-probe-helper-process.js +208 -0
  16. package/dist/server/config/opencode-system-probe-helper-process.js.map +1 -0
  17. package/dist/server/modules/git/git-command-helper-client.d.ts +25 -0
  18. package/dist/server/modules/git/git-command-helper-client.js +143 -0
  19. package/dist/server/modules/git/git-command-helper-client.js.map +1 -0
  20. package/dist/server/modules/git/git-command-helper-process.d.ts +1 -0
  21. package/dist/server/modules/git/git-command-helper-process.js +237 -0
  22. package/dist/server/modules/git/git-command-helper-process.js.map +1 -0
  23. package/dist/server/modules/git/git-command-runner.d.ts +8 -0
  24. package/dist/server/modules/git/git-command-runner.js +77 -6
  25. package/dist/server/modules/git/git-command-runner.js.map +1 -1
  26. package/dist/server/modules/git/git-controller.d.ts +4 -0
  27. package/dist/server/modules/git/git-controller.js +4 -1
  28. package/dist/server/modules/git/git-controller.js.map +1 -1
  29. package/dist/server/modules/git/git-read-service.d.ts +2 -1
  30. package/dist/server/modules/git/git-read-service.js +30 -0
  31. package/dist/server/modules/git/git-read-service.js.map +1 -1
  32. package/dist/server/modules/git/git-write-service.d.ts +1 -1
  33. package/dist/server/modules/git/git-write-service.js +8 -7
  34. package/dist/server/modules/git/git-write-service.js.map +1 -1
  35. package/dist/server/modules/git/types.d.ts +5 -0
  36. package/dist/server/modules/preferences/common.d.ts +2 -0
  37. package/dist/server/modules/preferences/common.js +13 -0
  38. package/dist/server/modules/preferences/common.js.map +1 -0
  39. package/dist/server/modules/preferences/profile-controller.d.ts +11 -0
  40. package/dist/server/modules/preferences/profile-controller.js +14 -0
  41. package/dist/server/modules/preferences/profile-controller.js.map +1 -0
  42. package/dist/server/modules/preferences/profile-service.d.ts +17 -0
  43. package/dist/server/modules/preferences/profile-service.js +213 -0
  44. package/dist/server/modules/preferences/profile-service.js.map +1 -0
  45. package/dist/server/modules/preferences/quick-phrase-controller.js +2 -12
  46. package/dist/server/modules/preferences/quick-phrase-controller.js.map +1 -1
  47. package/dist/server/modules/provider/codex-model-options.js +26 -165
  48. package/dist/server/modules/provider/codex-model-options.js.map +1 -1
  49. package/dist/server/modules/provider/opencode-model-options.js +6 -71
  50. package/dist/server/modules/provider/opencode-model-options.js.map +1 -1
  51. package/dist/server/modules/provider/provider-controller.d.ts +2 -0
  52. package/dist/server/modules/provider/provider-controller.js +21 -1
  53. package/dist/server/modules/provider/provider-controller.js.map +1 -1
  54. package/dist/server/modules/provider/provider-discovery-helper-client.d.ts +25 -0
  55. package/dist/server/modules/provider/provider-discovery-helper-client.js +114 -0
  56. package/dist/server/modules/provider/provider-discovery-helper-client.js.map +1 -0
  57. package/dist/server/modules/provider/provider-discovery-helper-process.d.ts +1 -0
  58. package/dist/server/modules/provider/provider-discovery-helper-process.js +296 -0
  59. package/dist/server/modules/provider/provider-discovery-helper-process.js.map +1 -0
  60. package/dist/server/modules/sessions/claude-runtime-helper-client.d.ts +28 -0
  61. package/dist/server/modules/sessions/claude-runtime-helper-client.js +221 -0
  62. package/dist/server/modules/sessions/claude-runtime-helper-client.js.map +1 -0
  63. package/dist/server/modules/sessions/claude-runtime-helper-process.d.ts +1 -0
  64. package/dist/server/modules/sessions/claude-runtime-helper-process.js +146 -0
  65. package/dist/server/modules/sessions/claude-runtime-helper-process.js.map +1 -0
  66. package/dist/server/modules/sessions/codex-app-server-helper-client.d.ts +16 -0
  67. package/dist/server/modules/sessions/codex-app-server-helper-client.js +237 -0
  68. package/dist/server/modules/sessions/codex-app-server-helper-client.js.map +1 -0
  69. package/dist/server/modules/sessions/codex-app-server-helper-process.d.ts +1 -0
  70. package/dist/server/modules/sessions/codex-app-server-helper-process.js +484 -0
  71. package/dist/server/modules/sessions/codex-app-server-helper-process.js.map +1 -0
  72. package/dist/server/modules/sessions/session-activity-authority-service.d.ts +52 -0
  73. package/dist/server/modules/sessions/session-activity-authority-service.js +377 -0
  74. package/dist/server/modules/sessions/session-activity-authority-service.js.map +1 -0
  75. package/dist/server/modules/sessions/session-activity-inspector.js +80 -40
  76. package/dist/server/modules/sessions/session-activity-inspector.js.map +1 -1
  77. package/dist/server/modules/sessions/session-controller.d.ts +15 -1
  78. package/dist/server/modules/sessions/session-controller.js +14 -1
  79. package/dist/server/modules/sessions/session-controller.js.map +1 -1
  80. package/dist/server/modules/sessions/session-history-service.d.ts +8 -3
  81. package/dist/server/modules/sessions/session-history-service.js +303 -64
  82. package/dist/server/modules/sessions/session-history-service.js.map +1 -1
  83. package/dist/server/modules/sessions/session-live-runtime-service.d.ts +40 -4
  84. package/dist/server/modules/sessions/session-live-runtime-service.js +334 -44
  85. package/dist/server/modules/sessions/session-live-runtime-service.js.map +1 -1
  86. package/dist/server/modules/sessions/session-permission-request-service.d.ts +175 -0
  87. package/dist/server/modules/sessions/session-permission-request-service.js +1615 -0
  88. package/dist/server/modules/sessions/session-permission-request-service.js.map +1 -0
  89. package/dist/server/modules/sessions/session-provider-error-mapper.js +14 -0
  90. package/dist/server/modules/sessions/session-provider-error-mapper.js.map +1 -1
  91. package/dist/server/modules/terminal/command-template-service.d.ts +2 -2
  92. package/dist/server/modules/terminal/command-template-service.js +3 -3
  93. package/dist/server/modules/terminal/command-template-service.js.map +1 -1
  94. package/dist/server/modules/terminal/runtime/adapters/conpty-control-helper-client.d.ts +24 -0
  95. package/dist/server/modules/terminal/runtime/adapters/conpty-control-helper-client.js +104 -0
  96. package/dist/server/modules/terminal/runtime/adapters/conpty-control-helper-client.js.map +1 -0
  97. package/dist/server/modules/terminal/runtime/adapters/conpty-control-helper-process.d.ts +1 -0
  98. package/dist/server/modules/terminal/runtime/adapters/conpty-control-helper-process.js +96 -0
  99. package/dist/server/modules/terminal/runtime/adapters/conpty-control-helper-process.js.map +1 -0
  100. package/dist/server/modules/terminal/runtime/adapters/conpty-runtime-adapter.d.ts +37 -0
  101. package/dist/server/modules/terminal/runtime/adapters/conpty-runtime-adapter.js +123 -0
  102. package/dist/server/modules/terminal/runtime/adapters/conpty-runtime-adapter.js.map +1 -0
  103. package/dist/server/modules/terminal/runtime/adapters/embedded-pty-runtime-adapter.d.ts +12 -5
  104. package/dist/server/modules/terminal/runtime/adapters/embedded-pty-runtime-adapter.js +44 -4
  105. package/dist/server/modules/terminal/runtime/adapters/embedded-pty-runtime-adapter.js.map +1 -1
  106. package/dist/server/modules/terminal/runtime/adapters/tmux-helper-client.d.ts +14 -0
  107. package/dist/server/modules/terminal/runtime/adapters/tmux-helper-client.js +105 -0
  108. package/dist/server/modules/terminal/runtime/adapters/tmux-helper-client.js.map +1 -0
  109. package/dist/server/modules/terminal/runtime/adapters/tmux-helper-process.d.ts +1 -0
  110. package/dist/server/modules/terminal/runtime/adapters/tmux-helper-process.js +67 -0
  111. package/dist/server/modules/terminal/runtime/adapters/tmux-helper-process.js.map +1 -0
  112. package/dist/server/modules/terminal/runtime/adapters/tmux-runtime-adapter.d.ts +8 -12
  113. package/dist/server/modules/terminal/runtime/adapters/tmux-runtime-adapter.js +112 -21
  114. package/dist/server/modules/terminal/runtime/adapters/tmux-runtime-adapter.js.map +1 -1
  115. package/dist/server/modules/terminal/runtime/conpty-runtime-shared.d.ts +25 -0
  116. package/dist/server/modules/terminal/runtime/conpty-runtime-shared.js +124 -0
  117. package/dist/server/modules/terminal/runtime/conpty-runtime-shared.js.map +1 -0
  118. package/dist/server/modules/terminal/runtime/conpty-session-agent-process.d.ts +1 -0
  119. package/dist/server/modules/terminal/runtime/conpty-session-agent-process.js +205 -0
  120. package/dist/server/modules/terminal/runtime/conpty-session-agent-process.js.map +1 -0
  121. package/dist/server/modules/terminal/runtime/conpty-session-attach-client.d.ts +1 -0
  122. package/dist/server/modules/terminal/runtime/conpty-session-attach-client.js +108 -0
  123. package/dist/server/modules/terminal/runtime/conpty-session-attach-client.js.map +1 -0
  124. package/dist/server/modules/terminal/runtime/conpty-session-control-client.d.ts +1 -0
  125. package/dist/server/modules/terminal/runtime/conpty-session-control-client.js +90 -0
  126. package/dist/server/modules/terminal/runtime/conpty-session-control-client.js.map +1 -0
  127. package/dist/server/modules/terminal/runtime/pty-broker-agent-process.d.ts +1 -0
  128. package/dist/server/modules/terminal/runtime/pty-broker-agent-process.js +179 -0
  129. package/dist/server/modules/terminal/runtime/pty-broker-agent-process.js.map +1 -0
  130. package/dist/server/modules/terminal/runtime/pty-broker-client.d.ts +29 -0
  131. package/dist/server/modules/terminal/runtime/pty-broker-client.js +169 -0
  132. package/dist/server/modules/terminal/runtime/pty-broker-client.js.map +1 -0
  133. package/dist/server/modules/terminal/runtime/pty-broker-shared.d.ts +22 -0
  134. package/dist/server/modules/terminal/runtime/pty-broker-shared.js +123 -0
  135. package/dist/server/modules/terminal/runtime/pty-broker-shared.js.map +1 -0
  136. package/dist/server/modules/terminal/runtime/pty-host-attachment-manager.d.ts +1 -0
  137. package/dist/server/modules/terminal/runtime/pty-host-attachment-manager.js +11 -1
  138. package/dist/server/modules/terminal/runtime/pty-host-attachment-manager.js.map +1 -1
  139. package/dist/server/modules/terminal/runtime/terminal-log-file-store.d.ts +1 -0
  140. package/dist/server/modules/terminal/runtime/terminal-log-file-store.js +7 -1
  141. package/dist/server/modules/terminal/runtime/terminal-log-file-store.js.map +1 -1
  142. package/dist/server/modules/terminal/runtime/terminal-log-spooler.js +3 -2
  143. package/dist/server/modules/terminal/runtime/terminal-log-spooler.js.map +1 -1
  144. package/dist/server/modules/terminal/runtime/terminal-runtime-adapter.d.ts +5 -3
  145. package/dist/server/modules/terminal/runtime/terminal-runtime-manager.d.ts +11 -5
  146. package/dist/server/modules/terminal/runtime/terminal-runtime-manager.js +110 -13
  147. package/dist/server/modules/terminal/runtime/terminal-runtime-manager.js.map +1 -1
  148. package/dist/server/modules/terminal/terminal-controller.js +7 -7
  149. package/dist/server/modules/terminal/terminal-controller.js.map +1 -1
  150. package/dist/server/modules/terminal/terminal-service.d.ts +30 -14
  151. package/dist/server/modules/terminal/terminal-service.js +260 -51
  152. package/dist/server/modules/terminal/terminal-service.js.map +1 -1
  153. package/dist/server/modules/terminal/terminal-shell.d.ts +4 -0
  154. package/dist/server/modules/terminal/terminal-shell.js +165 -18
  155. package/dist/server/modules/terminal/terminal-shell.js.map +1 -1
  156. package/dist/server/modules/workbench/workspace-file-watcher.d.ts +30 -0
  157. package/dist/server/modules/workbench/workspace-file-watcher.js +137 -0
  158. package/dist/server/modules/workbench/workspace-file-watcher.js.map +1 -0
  159. package/dist/server/modules/workbench/workspace-panel-snapshot-service.js +43 -7
  160. package/dist/server/modules/workbench/workspace-panel-snapshot-service.js.map +1 -1
  161. package/dist/server/routes/git.js +1 -0
  162. package/dist/server/routes/git.js.map +1 -1
  163. package/dist/server/routes/preferences.d.ts +2 -1
  164. package/dist/server/routes/preferences.js +3 -1
  165. package/dist/server/routes/preferences.js.map +1 -1
  166. package/dist/server/routes/sessions.js +2 -0
  167. package/dist/server/routes/sessions.js.map +1 -1
  168. package/dist/server/server/create-server.d.ts +4 -0
  169. package/dist/server/server/create-server.js +22 -5
  170. package/dist/server/server/create-server.js.map +1 -1
  171. package/dist/server/shared/utils/command-launch.d.ts +6 -0
  172. package/dist/server/shared/utils/command-launch.js +39 -0
  173. package/dist/server/shared/utils/command-launch.js.map +1 -0
  174. package/dist/server/shared/utils/perf-log.d.ts +1 -0
  175. package/dist/server/shared/utils/perf-log.js +8 -2
  176. package/dist/server/shared/utils/perf-log.js.map +1 -1
  177. package/dist/server/shared/utils/permission-debug-log.d.ts +2 -0
  178. package/dist/server/shared/utils/permission-debug-log.js +40 -0
  179. package/dist/server/shared/utils/permission-debug-log.js.map +1 -0
  180. package/dist/server/shared/utils/terminal-debug-log.d.ts +4 -0
  181. package/dist/server/shared/utils/terminal-debug-log.js +71 -0
  182. package/dist/server/shared/utils/terminal-debug-log.js.map +1 -0
  183. package/dist/server/storage/repositories/user-preference-profile-repository.d.ts +8 -0
  184. package/dist/server/storage/repositories/user-preference-profile-repository.js +46 -0
  185. package/dist/server/storage/repositories/user-preference-profile-repository.js.map +1 -0
  186. package/dist/server/storage/sqlite/schema.sql +13 -0
  187. package/dist/server/types/domain.d.ts +28 -1
  188. package/dist/server/ws/terminal-ws-hub.d.ts +2 -0
  189. package/dist/server/ws/terminal-ws-hub.js +42 -5
  190. package/dist/server/ws/terminal-ws-hub.js.map +1 -1
  191. package/dist/server/ws/workbench-ws-hub.d.ts +9 -1
  192. package/dist/server/ws/workbench-ws-hub.js +132 -21
  193. package/dist/server/ws/workbench-ws-hub.js.map +1 -1
  194. package/dist/server/ws/ws-server.d.ts +22 -1
  195. package/dist/server/ws/ws-server.js +134 -46
  196. package/dist/server/ws/ws-server.js.map +1 -1
  197. package/node_modules/@codingns/session-sync-core/dist/claude-message-utils.d.ts +4 -1
  198. package/node_modules/@codingns/session-sync-core/dist/claude-message-utils.js +107 -6
  199. package/node_modules/@codingns/session-sync-core/dist/claude-message-utils.js.map +1 -1
  200. package/node_modules/@codingns/session-sync-core/dist/patch-builder.d.ts +30 -0
  201. package/node_modules/@codingns/session-sync-core/dist/patch-builder.js +103 -0
  202. package/node_modules/@codingns/session-sync-core/dist/patch-builder.js.map +1 -0
  203. package/node_modules/@codingns/session-sync-core/dist/providers/claude-code.d.ts +1 -1
  204. package/node_modules/@codingns/session-sync-core/dist/providers/claude-code.js +38 -6
  205. package/node_modules/@codingns/session-sync-core/dist/providers/claude-code.js.map +1 -1
  206. package/node_modules/@codingns/session-sync-core/dist/providers/codex.d.ts +1 -1
  207. package/node_modules/@codingns/session-sync-core/dist/providers/codex.js +1 -1
  208. package/node_modules/@codingns/session-sync-core/dist/providers/codex.js.map +1 -1
  209. package/node_modules/@codingns/session-sync-core/dist/providers/opencode-permissions.d.ts +1 -0
  210. package/node_modules/@codingns/session-sync-core/dist/providers/opencode-permissions.js +8 -0
  211. package/node_modules/@codingns/session-sync-core/dist/providers/opencode-permissions.js.map +1 -0
  212. package/node_modules/@codingns/session-sync-core/dist/providers/opencode-shared.js +87 -7
  213. package/node_modules/@codingns/session-sync-core/dist/providers/opencode-shared.js.map +1 -1
  214. package/node_modules/@codingns/session-sync-core/dist/providers/opencode.d.ts +1 -1
  215. package/node_modules/@codingns/session-sync-core/dist/providers/opencode.js +8 -4
  216. package/node_modules/@codingns/session-sync-core/dist/providers/opencode.js.map +1 -1
  217. package/node_modules/@codingns/session-sync-core/dist/runtime/active-run-registry.d.ts +1 -0
  218. package/node_modules/@codingns/session-sync-core/dist/runtime/active-run-registry.js +5 -0
  219. package/node_modules/@codingns/session-sync-core/dist/runtime/active-run-registry.js.map +1 -1
  220. package/node_modules/@codingns/session-sync-core/dist/runtime/claude-runtime.d.ts +5 -0
  221. package/node_modules/@codingns/session-sync-core/dist/runtime/claude-runtime.js +114 -6
  222. package/node_modules/@codingns/session-sync-core/dist/runtime/claude-runtime.js.map +1 -1
  223. package/node_modules/@codingns/session-sync-core/dist/runtime/codex-runtime.d.ts +23 -0
  224. package/node_modules/@codingns/session-sync-core/dist/runtime/codex-runtime.js +721 -18
  225. package/node_modules/@codingns/session-sync-core/dist/runtime/codex-runtime.js.map +1 -1
  226. package/node_modules/@codingns/session-sync-core/dist/runtime/opencode-runtime.d.ts +3 -0
  227. package/node_modules/@codingns/session-sync-core/dist/runtime/opencode-runtime.js +106 -23
  228. package/node_modules/@codingns/session-sync-core/dist/runtime/opencode-runtime.js.map +1 -1
  229. package/node_modules/@codingns/session-sync-core/dist/runtime/provider-runtime-service.d.ts +1 -0
  230. package/node_modules/@codingns/session-sync-core/dist/runtime/provider-runtime-service.js +3 -0
  231. package/node_modules/@codingns/session-sync-core/dist/runtime/provider-runtime-service.js.map +1 -1
  232. package/node_modules/@codingns/session-sync-core/dist/runtime/types.d.ts +1 -0
  233. package/node_modules/@codingns/session-sync-core/dist/services.d.ts +1 -1
  234. package/node_modules/@codingns/session-sync-core/dist/services.js +2 -2
  235. package/node_modules/@codingns/session-sync-core/dist/services.js.map +1 -1
  236. package/node_modules/@codingns/session-sync-core/dist/types.d.ts +1 -1
  237. package/package.json +6 -2
  238. package/scripts/postinstall.mjs +218 -0
  239. package/dist/public/assets/TerminalPage-Dj_VDew3.js +0 -54
  240. package/dist/public/assets/index-C1GZV2wq.js +0 -106
  241. package/dist/public/assets/index-DU7f8NaZ.css +0 -1
@@ -3,8 +3,13 @@ import path from "node:path";
3
3
  import { ClaudeRuntimeAdapter, CodexRuntimeAdapter, OpenCodeRuntimeAdapter, ProviderRuntimeService } from "@codingns/session-sync-core";
4
4
  import { AppError } from "../../shared/errors/app-error.js";
5
5
  import { createId } from "../../shared/utils/id.js";
6
+ import { logPermissionDebug } from "../../shared/utils/permission-debug-log.js";
6
7
  import { nowIso } from "../../shared/utils/time.js";
8
+ import { SessionActivityAuthorityService } from "./session-activity-authority-service.js";
9
+ import { SessionPermissionRequestService } from "./session-permission-request-service.js";
7
10
  import { mapSessionProviderError } from "./session-provider-error-mapper.js";
11
+ import { ClaudeRuntimeHelperAdapter } from "./claude-runtime-helper-client.js";
12
+ import { CodexAppServerHelperClient } from "./codex-app-server-helper-client.js";
8
13
  export class SessionLiveRuntimeService {
9
14
  sessionHistoryService;
10
15
  sessionMessageAttachmentService;
@@ -18,13 +23,16 @@ export class SessionLiveRuntimeService {
18
23
  sessionStatusSnapshotRepository;
19
24
  config;
20
25
  providerRuntimeService;
26
+ sessionActivityAuthorityService;
27
+ sessionPermissionRequestService;
28
+ runtimeAdapterDisposables;
21
29
  externalRuntimeSnapshots = new Map();
22
30
  runtimeListeners = new Map();
23
31
  runtimeMessageSeenSessions = new Set();
24
32
  runtimeHistoryFallbackSentSessions = new Set();
25
33
  queueDispatchSessions = new Set();
26
34
  queueRetryTimers = new Map();
27
- constructor(sessionHistoryService, sessionMessageAttachmentService, workspaceService, sessionChangedFileService, sessionBindingRepository, authUserRepository, sessionSendQueueRepository, sessionIndexRepository, sessionStateRepository, sessionStatusSnapshotRepository, config) {
35
+ constructor(sessionHistoryService, sessionMessageAttachmentService, workspaceService, sessionChangedFileService, sessionBindingRepository, authUserRepository, sessionSendQueueRepository, sessionIndexRepository, sessionStateRepository, sessionStatusSnapshotRepository, config, sessionActivityAuthorityService = new SessionActivityAuthorityService()) {
28
36
  this.sessionHistoryService = sessionHistoryService;
29
37
  this.sessionMessageAttachmentService = sessionMessageAttachmentService;
30
38
  this.workspaceService = workspaceService;
@@ -36,7 +44,17 @@ export class SessionLiveRuntimeService {
36
44
  this.sessionStateRepository = sessionStateRepository;
37
45
  this.sessionStatusSnapshotRepository = sessionStatusSnapshotRepository;
38
46
  this.config = config;
39
- this.providerRuntimeService = new ProviderRuntimeService(createProviderRuntimeAdapters(config));
47
+ this.sessionActivityAuthorityService = sessionActivityAuthorityService;
48
+ this.sessionPermissionRequestService = new SessionPermissionRequestService(sessionHistoryService, sessionBindingRepository, authUserRepository, workspaceService, config, async (envelope) => {
49
+ await this.emitExternalRuntimeEnvelope(envelope);
50
+ }, async (input) => {
51
+ return this.resolveActiveClaudePermissionSession(input);
52
+ });
53
+ const runtimeAdapters = createProviderRuntimeAdapters(config, {
54
+ handleCodexServerRequest: async (input) => this.sessionPermissionRequestService.handleCodexServerRequest(input.sessionId, input.providerSessionId, input.request)
55
+ });
56
+ this.runtimeAdapterDisposables = runtimeAdapters.disposables;
57
+ this.providerRuntimeService = new ProviderRuntimeService(runtimeAdapters.adapters);
40
58
  }
41
59
  async startLiveSession(input) {
42
60
  const requestStartedAt = nowIso();
@@ -54,6 +72,7 @@ export class SessionLiveRuntimeService {
54
72
  provider: input.provider,
55
73
  providerSessionId: null,
56
74
  rawStoreRef: null,
75
+ sequenceBase: 1,
57
76
  options: {
58
77
  content: input.content,
59
78
  clientRequestId: input.clientRequestId,
@@ -243,20 +262,16 @@ export class SessionLiveRuntimeService {
243
262
  };
244
263
  }
245
264
  getClaudeHookBridgeConfig() {
246
- const bridgeUrl = `http://127.0.0.1:${this.config.port}/api/providers/claude-code/hook-bridge/events`;
247
- const scriptPath = path.resolve(process.cwd(), "scripts", "claude-hook-bridge.cjs");
248
- const command = `node "${scriptPath}" --url "${bridgeUrl}" --token "${this.config.claudeHookBridgeToken}"`;
249
- return {
250
- provider: "claude-code",
251
- bridgeUrl,
252
- token: this.config.claudeHookBridgeToken,
253
- scriptPath,
254
- command,
255
- supportedEvents: ["UserPromptSubmit", "SessionStart", "Stop", "StopFailure", "SessionEnd"]
256
- };
265
+ return buildClaudeHookBridgeConfig(this.config);
257
266
  }
258
267
  async ingestClaudeHookEvent(payload) {
259
268
  const hookEventName = normalizeClaudeHookEventName(payload.hook_event_name);
269
+ logPermissionDebug("claude_hook_event.ingest.begin", {
270
+ hookEventName,
271
+ sessionId: payload.session_id ?? null,
272
+ cwd: payload.cwd ?? null,
273
+ transcriptPath: payload.transcript_path ?? null
274
+ });
260
275
  if (!hookEventName) {
261
276
  throw new AppError({
262
277
  statusCode: 400,
@@ -266,20 +281,44 @@ export class SessionLiveRuntimeService {
266
281
  });
267
282
  }
268
283
  if (!isSupportedClaudeHookEvent(hookEventName)) {
284
+ logPermissionDebug("claude_hook_event.ingest.unsupported", {
285
+ hookEventName
286
+ });
269
287
  return {
270
288
  accepted: true,
271
289
  ignored: true,
272
- sessionId: null
290
+ sessionId: null,
291
+ bridgeResponse: null
273
292
  };
274
293
  }
294
+ if (hookEventName === "PreToolUse") {
295
+ logPermissionDebug("claude_hook_event.route", {
296
+ hookEventName,
297
+ route: "handleClaudePreToolUse"
298
+ });
299
+ return this.sessionPermissionRequestService.handleClaudePreToolUse(payload);
300
+ }
301
+ if (hookEventName === "PermissionRequest") {
302
+ logPermissionDebug("claude_hook_event.route", {
303
+ hookEventName,
304
+ route: "handleClaudePermissionRequest"
305
+ });
306
+ return this.sessionPermissionRequestService.handleClaudePermissionRequest(payload);
307
+ }
275
308
  const providerSessionId = normalizeRequiredText(payload.session_id, "session_id");
276
309
  const workspacePath = normalizeRequiredText(payload.cwd, "cwd");
277
310
  const workspace = this.workspaceService.findWorkspaceByPath(workspacePath);
278
311
  if (!workspace) {
312
+ logPermissionDebug("claude_hook_event.workspace_not_found", {
313
+ hookEventName,
314
+ sessionId: payload.session_id ?? null,
315
+ cwd: payload.cwd ?? null
316
+ });
279
317
  return {
280
318
  accepted: true,
281
319
  ignored: true,
282
- sessionId: null
320
+ sessionId: null,
321
+ bridgeResponse: null
283
322
  };
284
323
  }
285
324
  const binding = await this.resolveClaudeExternalBinding({
@@ -290,11 +329,18 @@ export class SessionLiveRuntimeService {
290
329
  });
291
330
  const timestamp = nowIso();
292
331
  const runtimeUpdate = mapClaudeHookToRuntimeUpdate(hookEventName, payload, timestamp);
332
+ logPermissionDebug("claude_hook_event.runtime_update", {
333
+ hookEventName,
334
+ sessionId: binding.sessionId,
335
+ providerSessionId,
336
+ hasRuntimeUpdate: runtimeUpdate !== null
337
+ });
293
338
  if (!runtimeUpdate) {
294
339
  return {
295
340
  accepted: true,
296
341
  ignored: true,
297
- sessionId: binding.sessionId
342
+ sessionId: binding.sessionId,
343
+ bridgeResponse: null
298
344
  };
299
345
  }
300
346
  if (this.shouldIgnoreClaudeExternalRuntimeUpdate(binding.sessionId)) {
@@ -302,7 +348,8 @@ export class SessionLiveRuntimeService {
302
348
  return {
303
349
  accepted: true,
304
350
  ignored: true,
305
- sessionId: binding.sessionId
351
+ sessionId: binding.sessionId,
352
+ bridgeResponse: null
306
353
  };
307
354
  }
308
355
  await this.applyExternalRuntimeUpdate({
@@ -315,7 +362,8 @@ export class SessionLiveRuntimeService {
315
362
  return {
316
363
  accepted: true,
317
364
  ignored: false,
318
- sessionId: binding.sessionId
365
+ sessionId: binding.sessionId,
366
+ bridgeResponse: null
319
367
  };
320
368
  }
321
369
  async getSessionRuntime(sessionId, userId) {
@@ -327,24 +375,33 @@ export class SessionLiveRuntimeService {
327
375
  this.maybeDispatchQueuedMessages(session);
328
376
  const capabilities = await this.sessionHistoryService.getSessionCapabilities(sessionId);
329
377
  const contextUsage = await this.sessionHistoryService.getSessionContextUsage(sessionId).catch(() => null);
378
+ const resolution = runtimeSnapshot
379
+ ? this.sessionActivityAuthorityService.observe(createRuntimeActivityObservation(sessionId, runtimeSnapshot))
380
+ : externalRuntimeSnapshot
381
+ ? this.sessionActivityAuthorityService.observe(createExternalRuntimeActivityObservation(sessionId, externalRuntimeSnapshot))
382
+ : this.sessionActivityAuthorityService.resolvePersistedSession(session);
330
383
  if (runtimeSnapshot) {
331
384
  return {
332
385
  sessionId,
333
386
  provider: session.provider,
334
387
  providerSessionId: runtimeSnapshot.providerSessionId ?? session.providerSessionId,
335
- runningState: runtimeSnapshot.runningState,
388
+ runningState: resolution.runningState,
336
389
  hasActiveRun: true,
337
390
  canAttach: true,
338
391
  canInterrupt: runtimeSnapshot.supportsInterrupt,
339
392
  inRunInputMode: capabilities.inRunInputMode,
340
- detail: runtimeSnapshot.detail,
341
- errorCode: runtimeSnapshot.runningState === "failed"
342
- ? runtimeSnapshot.errorCode ?? session.lastErrorCode
393
+ activityResolutionSource: resolution.activityResolutionSource,
394
+ activityConfidence: resolution.activityConfidence,
395
+ runId: resolution.runId,
396
+ detail: resolution.detail,
397
+ errorCode: resolution.runningState === "failed"
398
+ ? resolution.errorCode ?? session.lastErrorCode
343
399
  : null,
344
- errorDetail: runtimeSnapshot.runningState === "failed"
345
- ? runtimeSnapshot.detail ?? session.lastErrorDetail
400
+ errorDetail: resolution.runningState === "failed"
401
+ ? resolution.detail ?? session.lastErrorDetail
346
402
  : null,
347
- updatedAt: runtimeSnapshot.lastEventAt ?? runtimeSnapshot.startedAt,
403
+ updatedAt: resolution.updatedAt,
404
+ watchdogTriggeredAt: resolution.watchdogTriggeredAt,
348
405
  contextUsage
349
406
  };
350
407
  }
@@ -353,33 +410,41 @@ export class SessionLiveRuntimeService {
353
410
  sessionId,
354
411
  provider: "claude-code",
355
412
  providerSessionId: externalRuntimeSnapshot.providerSessionId,
356
- runningState: externalRuntimeSnapshot.runningState,
413
+ runningState: resolution.runningState,
357
414
  hasActiveRun: true,
358
415
  canAttach: false,
359
416
  canInterrupt: false,
360
417
  inRunInputMode: capabilities.inRunInputMode,
361
- detail: externalRuntimeSnapshot.detail,
362
- errorCode: session.runningState === "failed" ? session.lastErrorCode : null,
363
- errorDetail: session.runningState === "failed" ? session.lastErrorDetail : null,
364
- updatedAt: externalRuntimeSnapshot.updatedAt,
418
+ activityResolutionSource: resolution.activityResolutionSource,
419
+ activityConfidence: resolution.activityConfidence,
420
+ runId: resolution.runId,
421
+ detail: resolution.detail,
422
+ errorCode: resolution.runningState === "failed" ? resolution.errorCode ?? session.lastErrorCode : null,
423
+ errorDetail: resolution.runningState === "failed" ? resolution.detail ?? session.lastErrorDetail : null,
424
+ updatedAt: resolution.updatedAt,
425
+ watchdogTriggeredAt: resolution.watchdogTriggeredAt,
365
426
  contextUsage
366
427
  };
367
428
  }
368
- const persistedErrorCode = session.runningState === "failed" ? session.lastErrorCode : null;
369
- const persistedErrorDetail = session.runningState === "failed" ? session.lastErrorDetail : null;
429
+ const persistedErrorCode = resolution.runningState === "failed" ? resolution.errorCode ?? session.lastErrorCode : null;
430
+ const persistedErrorDetail = resolution.runningState === "failed" ? resolution.detail ?? session.lastErrorDetail : null;
370
431
  return {
371
432
  sessionId,
372
433
  provider: session.provider,
373
434
  providerSessionId: session.providerSessionId,
374
- runningState: session.runningState ?? "idle",
435
+ runningState: resolution.runningState,
375
436
  hasActiveRun: false,
376
437
  canAttach: false,
377
438
  canInterrupt: false,
378
439
  inRunInputMode: capabilities.inRunInputMode,
440
+ activityResolutionSource: resolution.activityResolutionSource,
441
+ activityConfidence: resolution.activityConfidence,
442
+ runId: resolution.runId,
379
443
  detail: persistedErrorDetail,
380
444
  errorCode: persistedErrorCode,
381
445
  errorDetail: persistedErrorDetail,
382
- updatedAt: session.lastEventAt ?? session.updatedAt,
446
+ updatedAt: resolution.updatedAt,
447
+ watchdogTriggeredAt: resolution.watchdogTriggeredAt,
383
448
  contextUsage
384
449
  };
385
450
  }
@@ -411,9 +476,16 @@ export class SessionLiveRuntimeService {
411
476
  detail: interrupted.detail ?? "interrupt requested"
412
477
  };
413
478
  }
479
+ async listPermissionRequests(sessionId, userId) {
480
+ return this.sessionPermissionRequestService.listSessionPermissionRequests(sessionId, userId);
481
+ }
482
+ async replyPermissionRequest(sessionId, userId, requestId, input) {
483
+ return this.sessionPermissionRequestService.replyToSessionPermissionRequest(sessionId, userId, requestId, input);
484
+ }
414
485
  subscribeRuntime(sessionId, onEnvelope) {
415
486
  const runtimeSnapshot = this.providerRuntimeService.getSnapshot(sessionId);
416
487
  const externalRuntimeSnapshot = this.externalRuntimeSnapshots.get(sessionId) ?? null;
488
+ const initialActivityEnvelope = this.buildSessionActivityEnvelope(sessionId);
417
489
  if (runtimeSnapshot) {
418
490
  void onEnvelope({
419
491
  type: "session.runtime_status",
@@ -432,6 +504,9 @@ export class SessionLiveRuntimeService {
432
504
  timestamp: externalRuntimeSnapshot.updatedAt
433
505
  });
434
506
  }
507
+ if (initialActivityEnvelope) {
508
+ void onEnvelope(initialActivityEnvelope);
509
+ }
435
510
  const runtimeSubscription = this.providerRuntimeService.subscribe(sessionId, async (event) => {
436
511
  const envelope = this.mapRuntimeEventToEnvelope(sessionId, event);
437
512
  if (!envelope) {
@@ -440,10 +515,18 @@ export class SessionLiveRuntimeService {
440
515
  await onEnvelope(envelope);
441
516
  });
442
517
  const externalSubscription = this.subscribeExternalRuntime(sessionId, onEnvelope);
518
+ const activitySubscription = this.sessionActivityAuthorityService.subscribe(sessionId, async () => {
519
+ const envelope = this.buildSessionActivityEnvelope(sessionId);
520
+ if (!envelope) {
521
+ return;
522
+ }
523
+ await onEnvelope(envelope);
524
+ });
443
525
  return {
444
526
  close: () => {
445
527
  runtimeSubscription.close();
446
528
  externalSubscription.close();
529
+ activitySubscription.close();
447
530
  }
448
531
  };
449
532
  }
@@ -454,7 +537,12 @@ export class SessionLiveRuntimeService {
454
537
  this.queueRetryTimers.clear();
455
538
  this.runtimeMessageSeenSessions.clear();
456
539
  this.runtimeHistoryFallbackSentSessions.clear();
540
+ this.sessionActivityAuthorityService.dispose();
541
+ await this.sessionPermissionRequestService.dispose();
457
542
  await this.providerRuntimeService.dispose();
543
+ for (const disposable of this.runtimeAdapterDisposables) {
544
+ disposable.dispose();
545
+ }
458
546
  this.externalRuntimeSnapshots.clear();
459
547
  this.runtimeListeners.clear();
460
548
  }
@@ -489,6 +577,49 @@ export class SessionLiveRuntimeService {
489
577
  await listener(envelope);
490
578
  }));
491
579
  }
580
+ buildSessionActivityEnvelope(sessionId) {
581
+ const runtimeSnapshot = this.providerRuntimeService.getSnapshot(sessionId);
582
+ if (runtimeSnapshot) {
583
+ const resolution = this.sessionActivityAuthorityService.observe(createRuntimeActivityObservation(sessionId, runtimeSnapshot));
584
+ return this.mapResolutionToActivityEnvelope(resolution, {
585
+ hasActiveRun: true,
586
+ canInterrupt: runtimeSnapshot.supportsInterrupt
587
+ });
588
+ }
589
+ const externalRuntimeSnapshot = this.externalRuntimeSnapshots.get(sessionId) ?? null;
590
+ if (externalRuntimeSnapshot) {
591
+ const resolution = this.sessionActivityAuthorityService.observe(createExternalRuntimeActivityObservation(sessionId, externalRuntimeSnapshot));
592
+ return this.mapResolutionToActivityEnvelope(resolution, {
593
+ hasActiveRun: true,
594
+ canInterrupt: false
595
+ });
596
+ }
597
+ const resolution = this.sessionActivityAuthorityService.getResolution(sessionId);
598
+ if (!resolution) {
599
+ return null;
600
+ }
601
+ return this.mapResolutionToActivityEnvelope(resolution, {
602
+ hasActiveRun: resolution.runningState === "stale" || resolution.runningState === "unknown",
603
+ canInterrupt: false
604
+ });
605
+ }
606
+ mapResolutionToActivityEnvelope(resolution, options) {
607
+ return {
608
+ type: "session.activity",
609
+ sessionId: resolution.sessionId,
610
+ runningState: resolution.runningState,
611
+ activityResolutionSource: resolution.activityResolutionSource,
612
+ activityConfidence: resolution.activityConfidence,
613
+ runId: resolution.runId,
614
+ detail: resolution.detail,
615
+ errorCode: resolution.errorCode,
616
+ errorDetail: resolution.detail,
617
+ hasActiveRun: options.hasActiveRun,
618
+ canInterrupt: options.canInterrupt,
619
+ updatedAt: resolution.updatedAt,
620
+ watchdogTriggeredAt: resolution.watchdogTriggeredAt
621
+ };
622
+ }
492
623
  async resolveClaudeExternalBinding(input) {
493
624
  const rawStoreRef = input.transcriptPath ??
494
625
  findClaudeSessionFile(this.config.claudeCodeHomeDir, input.providerSessionId) ??
@@ -591,6 +722,16 @@ export class SessionLiveRuntimeService {
591
722
  lastErrorDetail: input.runningState === "failed" ? (input.detail ?? "Claude hook failed") : null,
592
723
  resumedAt: this.sessionStatusSnapshotRepository.findBySessionId(input.sessionId)?.resumedAt ?? null
593
724
  });
725
+ this.sessionActivityAuthorityService.observe({
726
+ sessionId: input.sessionId,
727
+ runId: null,
728
+ runningState: input.runningState,
729
+ source: "authoritative_provider_event",
730
+ confidence: input.runningState === "failed" ? "strong" : "authoritative",
731
+ detail: input.detail,
732
+ errorCode: input.runningState === "failed" ? "CLAUDE_HOOK_STOP_FAILURE" : null,
733
+ observedAt: input.timestamp
734
+ });
594
735
  if (input.runningState === "running") {
595
736
  this.externalRuntimeSnapshots.set(input.sessionId, {
596
737
  sessionId: input.sessionId,
@@ -647,6 +788,7 @@ export class SessionLiveRuntimeService {
647
788
  lastSeenAt: currentState?.lastSeenAt ?? null,
648
789
  updatedAt: nowIso()
649
790
  });
791
+ this.sessionActivityAuthorityService.observe(createRuntimeActivityObservation(request.sessionId, snapshot));
650
792
  }
651
793
  async sendLiveMessageDirect(input, persistedAttachments) {
652
794
  const requestStartedAt = nowIso();
@@ -665,6 +807,9 @@ export class SessionLiveRuntimeService {
665
807
  provider: session.provider,
666
808
  providerSessionId: runtimeMode === "start" ? null : session.providerSessionId,
667
809
  rawStoreRef: runtimeMode === "start" ? null : session.rawStoreRef,
810
+ sequenceBase: runtimeMode === "start"
811
+ ? 1
812
+ : Math.max(session.messageCount + 1, 1),
668
813
  options: {
669
814
  content: input.content,
670
815
  clientRequestId: input.clientRequestId,
@@ -899,6 +1044,7 @@ export class SessionLiveRuntimeService {
899
1044
  lastSeenAt: null,
900
1045
  updatedAt: timestamp
901
1046
  });
1047
+ this.sessionActivityAuthorityService.observe(createRuntimeActivityObservation(input.sessionId, input.snapshot));
902
1048
  }
903
1049
  async persistRuntimeEvent(sessionId, workspaceId, userId, event) {
904
1050
  this.sessionHistoryService.persistSessionBinding(sessionId, workspaceId, {
@@ -989,6 +1135,7 @@ export class SessionLiveRuntimeService {
989
1135
  lastSeenAt: currentState?.lastSeenAt ?? null,
990
1136
  updatedAt: nowIso()
991
1137
  });
1138
+ this.sessionActivityAuthorityService.observe(createRuntimeEventObservation(sessionId, event, this.providerRuntimeService.getSnapshot(sessionId)?.startedAt ?? null));
992
1139
  this.upsertSnapshot(sessionId, {
993
1140
  syncStatus: event.type === "error" ? "error" : "idle",
994
1141
  syncCursor: this.sessionStatusSnapshotRepository.findBySessionId(sessionId)?.syncCursor ?? null,
@@ -1106,6 +1253,32 @@ export class SessionLiveRuntimeService {
1106
1253
  clearExternalRuntimeSnapshot(sessionId) {
1107
1254
  this.externalRuntimeSnapshots.delete(sessionId);
1108
1255
  }
1256
+ async resolveActiveClaudePermissionSession(input) {
1257
+ const activeSnapshots = this.providerRuntimeService
1258
+ .listSnapshots()
1259
+ .filter((snapshot) => snapshot.provider === "claude-code" &&
1260
+ snapshot.workspaceId === input.workspaceId &&
1261
+ isActiveRuntimeState(snapshot.runningState));
1262
+ if (activeSnapshots.length !== 1) {
1263
+ return null;
1264
+ }
1265
+ const activeSnapshot = activeSnapshots[0];
1266
+ if (!activeSnapshot) {
1267
+ return null;
1268
+ }
1269
+ const rawStoreRef = input.transcriptPath ??
1270
+ activeSnapshot.rawStoreRef ??
1271
+ buildClaudeRawStoreRef(this.config.claudeCodeHomeDir, input.workspacePath, input.providerSessionId);
1272
+ this.sessionHistoryService.persistSessionBinding(activeSnapshot.sessionId, input.workspaceId, {
1273
+ provider: "claude-code",
1274
+ providerSessionId: input.providerSessionId,
1275
+ rawStoreRef
1276
+ });
1277
+ return {
1278
+ sessionId: activeSnapshot.sessionId,
1279
+ rawStoreRef
1280
+ };
1281
+ }
1109
1282
  }
1110
1283
  function createSyntheticUserMessage(provider, providerSessionId, content, timestamp, sequence, attachments = []) {
1111
1284
  const syntheticId = createId();
@@ -1123,6 +1296,51 @@ function createSyntheticUserMessage(provider, providerSessionId, content, timest
1123
1296
  rawRef: `synthetic://${provider}/${providerSessionId}/${syntheticId}`
1124
1297
  };
1125
1298
  }
1299
+ function createRuntimeActivityObservation(sessionId, snapshot) {
1300
+ return {
1301
+ sessionId,
1302
+ runId: buildRuntimeRunId(sessionId, snapshot.startedAt),
1303
+ runningState: snapshot.runningState,
1304
+ source: "authoritative_runtime",
1305
+ confidence: snapshot.runningState === "failed" || snapshot.runningState === "completed" || snapshot.runningState === "interrupted"
1306
+ ? "strong"
1307
+ : "authoritative",
1308
+ detail: snapshot.detail,
1309
+ errorCode: snapshot.runningState === "failed" ? snapshot.errorCode ?? null : null,
1310
+ observedAt: snapshot.lastEventAt ?? snapshot.startedAt
1311
+ };
1312
+ }
1313
+ function createExternalRuntimeActivityObservation(sessionId, snapshot) {
1314
+ return {
1315
+ sessionId,
1316
+ runId: null,
1317
+ runningState: snapshot.runningState,
1318
+ source: "authoritative_provider_event",
1319
+ confidence: snapshot.runningState === "failed" ? "strong" : "authoritative",
1320
+ detail: snapshot.detail,
1321
+ errorCode: snapshot.runningState === "failed" ? "CLAUDE_HOOK_STOP_FAILURE" : null,
1322
+ observedAt: snapshot.updatedAt
1323
+ };
1324
+ }
1325
+ function createRuntimeEventObservation(sessionId, event, startedAt) {
1326
+ return {
1327
+ sessionId,
1328
+ runId: buildRuntimeRunId(sessionId, startedAt ?? event.timestamp),
1329
+ runningState: event.type === "message" ? "running" : event.status ?? "running",
1330
+ source: "authoritative_runtime",
1331
+ confidence: event.type === "error" || event.status === "completed" || event.status === "interrupted"
1332
+ ? "strong"
1333
+ : "authoritative",
1334
+ detail: event.type === "message"
1335
+ ? "Host 正在接收这一轮运行的实时事件"
1336
+ : event.detail,
1337
+ errorCode: event.type === "error" ? event.errorCode : null,
1338
+ observedAt: event.type === "message" ? event.message.timestamp : event.timestamp
1339
+ };
1340
+ }
1341
+ function buildRuntimeRunId(sessionId, startedAt) {
1342
+ return `runtime:${sessionId}:${startedAt}`;
1343
+ }
1126
1344
  function withTimeout(promise, timeoutMs) {
1127
1345
  return new Promise((resolve, reject) => {
1128
1346
  const timer = setTimeout(() => {
@@ -1147,7 +1365,10 @@ function normalizeClaudeHookEventName(value) {
1147
1365
  return normalized && normalized.length > 0 ? normalized : null;
1148
1366
  }
1149
1367
  function isSupportedClaudeHookEvent(value) {
1150
- return (value === "UserPromptSubmit" ||
1368
+ return (value === "PreToolUse" ||
1369
+ value === "PermissionRequest" ||
1370
+ value === "Notification" ||
1371
+ value === "UserPromptSubmit" ||
1151
1372
  value === "SessionStart" ||
1152
1373
  value === "Stop" ||
1153
1374
  value === "StopFailure" ||
@@ -1266,17 +1487,86 @@ function mapQueueItemRecordToView(record) {
1266
1487
  function isTerminalSessionRunningState(state) {
1267
1488
  return state === "completed" || state === "interrupted" || state === "failed";
1268
1489
  }
1269
- function createProviderRuntimeAdapters(config) {
1270
- return [
1271
- new ClaudeRuntimeAdapter({
1272
- homeDir: config.claudeCodeHomeDir
1273
- }),
1274
- new CodexRuntimeAdapter(),
1275
- new OpenCodeRuntimeAdapter({
1276
- baseUrl: config.opencodeBaseUrl,
1277
- baseUrlResolver: config.opencodeBaseUrlResolver?.resolve.bind(config.opencodeBaseUrlResolver)
1490
+ function createProviderRuntimeAdapters(config, options = {}) {
1491
+ const claudeHookBridgeConfig = buildClaudeHookBridgeConfig(config);
1492
+ const claudeAdapter = process.env.VITEST
1493
+ ? new ClaudeRuntimeAdapter({
1494
+ homeDir: config.claudeCodeHomeDir,
1495
+ hookBridge: {
1496
+ url: claudeHookBridgeConfig.bridgeUrl,
1497
+ token: config.claudeHookBridgeToken,
1498
+ scriptPath: claudeHookBridgeConfig.scriptPath
1499
+ }
1278
1500
  })
1501
+ : new ClaudeRuntimeHelperAdapter({
1502
+ homeDir: config.claudeCodeHomeDir,
1503
+ hookBridge: {
1504
+ url: claudeHookBridgeConfig.bridgeUrl,
1505
+ token: config.claudeHookBridgeToken,
1506
+ scriptPath: claudeHookBridgeConfig.scriptPath
1507
+ }
1508
+ });
1509
+ const disposables = [];
1510
+ if ("dispose" in claudeAdapter && typeof claudeAdapter.dispose === "function") {
1511
+ disposables.push(claudeAdapter);
1512
+ }
1513
+ const codexTransportHelper = process.env.VITEST
1514
+ ? null
1515
+ : new CodexAppServerHelperClient(config.codexCliPath);
1516
+ if (codexTransportHelper) {
1517
+ disposables.push(codexTransportHelper);
1518
+ }
1519
+ return {
1520
+ adapters: [
1521
+ claudeAdapter,
1522
+ new CodexRuntimeAdapter({
1523
+ homeDir: config.codexHomeDir,
1524
+ commandPath: config.codexCliPath,
1525
+ transportFactory: codexTransportHelper?.createTransport.bind(codexTransportHelper),
1526
+ handleServerRequest: options.handleCodexServerRequest
1527
+ }),
1528
+ new OpenCodeRuntimeAdapter({
1529
+ baseUrl: config.opencodeBaseUrl,
1530
+ baseUrlResolver: config.opencodeBaseUrlResolver?.resolve.bind(config.opencodeBaseUrlResolver)
1531
+ })
1532
+ ],
1533
+ disposables
1534
+ };
1535
+ }
1536
+ function buildClaudeHookBridgeConfig(config) {
1537
+ const bridgeUrl = `http://127.0.0.1:${config.port}/api/providers/claude-code/hook-bridge/events`;
1538
+ const scriptPath = resolveClaudeHookBridgeScriptPath();
1539
+ const command = `node "${scriptPath}" --url "${bridgeUrl}" --token "${config.claudeHookBridgeToken}"`;
1540
+ return {
1541
+ provider: "claude-code",
1542
+ bridgeUrl,
1543
+ token: config.claudeHookBridgeToken,
1544
+ scriptPath,
1545
+ command,
1546
+ supportedEvents: [
1547
+ "PreToolUse",
1548
+ "PermissionRequest",
1549
+ "Notification",
1550
+ "UserPromptSubmit",
1551
+ "SessionStart",
1552
+ "Stop",
1553
+ "StopFailure",
1554
+ "SessionEnd"
1555
+ ]
1556
+ };
1557
+ }
1558
+ function resolveClaudeHookBridgeScriptPath() {
1559
+ const candidates = [
1560
+ path.resolve(process.cwd(), "scripts", "claude-hook-bridge.cjs"),
1561
+ path.resolve(process.cwd(), "..", "scripts", "claude-hook-bridge.cjs"),
1562
+ path.resolve(process.cwd(), "..", "..", "scripts", "claude-hook-bridge.cjs")
1279
1563
  ];
1564
+ for (const candidate of candidates) {
1565
+ if (existsSync(candidate)) {
1566
+ return candidate;
1567
+ }
1568
+ }
1569
+ return candidates[0];
1280
1570
  }
1281
1571
  function buildClaudeRawStoreRef(homeDir, workspacePath, sessionId) {
1282
1572
  return path.join(homeDir, "projects", workspaceSlug(workspacePath), `${sessionId}.jsonl`);