@jingyi0605/codingns 0.1.1 → 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 (238) hide show
  1. package/README.md +14 -0
  2. package/dist/public/assets/{TerminalPage-CVG1cGAJ.js → TerminalPage-Dr7knYq2.js} +19 -19
  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 +24 -3
  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 +4 -2
  81. package/dist/server/modules/sessions/session-history-service.js +151 -29
  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 +330 -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 +79 -43
  196. package/dist/server/ws/ws-server.js.map +1 -1
  197. package/node_modules/@codingns/session-sync-core/dist/claude-message-utils.js +42 -0
  198. package/node_modules/@codingns/session-sync-core/dist/claude-message-utils.js.map +1 -1
  199. package/node_modules/@codingns/session-sync-core/dist/patch-builder.d.ts +30 -0
  200. package/node_modules/@codingns/session-sync-core/dist/patch-builder.js +103 -0
  201. package/node_modules/@codingns/session-sync-core/dist/patch-builder.js.map +1 -0
  202. package/node_modules/@codingns/session-sync-core/dist/providers/claude-code.d.ts +1 -1
  203. package/node_modules/@codingns/session-sync-core/dist/providers/claude-code.js +2 -1
  204. package/node_modules/@codingns/session-sync-core/dist/providers/claude-code.js.map +1 -1
  205. package/node_modules/@codingns/session-sync-core/dist/providers/codex.d.ts +1 -1
  206. package/node_modules/@codingns/session-sync-core/dist/providers/codex.js +1 -1
  207. package/node_modules/@codingns/session-sync-core/dist/providers/codex.js.map +1 -1
  208. package/node_modules/@codingns/session-sync-core/dist/providers/opencode-permissions.d.ts +1 -0
  209. package/node_modules/@codingns/session-sync-core/dist/providers/opencode-permissions.js +8 -0
  210. package/node_modules/@codingns/session-sync-core/dist/providers/opencode-permissions.js.map +1 -0
  211. package/node_modules/@codingns/session-sync-core/dist/providers/opencode-shared.js +31 -0
  212. package/node_modules/@codingns/session-sync-core/dist/providers/opencode-shared.js.map +1 -1
  213. package/node_modules/@codingns/session-sync-core/dist/providers/opencode.d.ts +1 -1
  214. package/node_modules/@codingns/session-sync-core/dist/providers/opencode.js +8 -4
  215. package/node_modules/@codingns/session-sync-core/dist/providers/opencode.js.map +1 -1
  216. package/node_modules/@codingns/session-sync-core/dist/runtime/active-run-registry.d.ts +1 -0
  217. package/node_modules/@codingns/session-sync-core/dist/runtime/active-run-registry.js +5 -0
  218. package/node_modules/@codingns/session-sync-core/dist/runtime/active-run-registry.js.map +1 -1
  219. package/node_modules/@codingns/session-sync-core/dist/runtime/claude-runtime.d.ts +5 -0
  220. package/node_modules/@codingns/session-sync-core/dist/runtime/claude-runtime.js +82 -1
  221. package/node_modules/@codingns/session-sync-core/dist/runtime/claude-runtime.js.map +1 -1
  222. package/node_modules/@codingns/session-sync-core/dist/runtime/codex-runtime.d.ts +23 -0
  223. package/node_modules/@codingns/session-sync-core/dist/runtime/codex-runtime.js +688 -17
  224. package/node_modules/@codingns/session-sync-core/dist/runtime/codex-runtime.js.map +1 -1
  225. package/node_modules/@codingns/session-sync-core/dist/runtime/opencode-runtime.d.ts +3 -0
  226. package/node_modules/@codingns/session-sync-core/dist/runtime/opencode-runtime.js +106 -23
  227. package/node_modules/@codingns/session-sync-core/dist/runtime/opencode-runtime.js.map +1 -1
  228. package/node_modules/@codingns/session-sync-core/dist/runtime/provider-runtime-service.d.ts +1 -0
  229. package/node_modules/@codingns/session-sync-core/dist/runtime/provider-runtime-service.js +3 -0
  230. package/node_modules/@codingns/session-sync-core/dist/runtime/provider-runtime-service.js.map +1 -1
  231. package/node_modules/@codingns/session-sync-core/dist/services.d.ts +1 -1
  232. package/node_modules/@codingns/session-sync-core/dist/services.js +2 -2
  233. package/node_modules/@codingns/session-sync-core/dist/services.js.map +1 -1
  234. package/node_modules/@codingns/session-sync-core/dist/types.d.ts +1 -1
  235. package/package.json +3 -2
  236. package/scripts/postinstall.mjs +15 -8
  237. package/dist/public/assets/index-BUPByQPG.css +0 -1
  238. package/dist/public/assets/index-D1CwTkI2.js +0 -106
@@ -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();
@@ -244,20 +262,16 @@ export class SessionLiveRuntimeService {
244
262
  };
245
263
  }
246
264
  getClaudeHookBridgeConfig() {
247
- const bridgeUrl = `http://127.0.0.1:${this.config.port}/api/providers/claude-code/hook-bridge/events`;
248
- const scriptPath = path.resolve(process.cwd(), "scripts", "claude-hook-bridge.cjs");
249
- const command = `node "${scriptPath}" --url "${bridgeUrl}" --token "${this.config.claudeHookBridgeToken}"`;
250
- return {
251
- provider: "claude-code",
252
- bridgeUrl,
253
- token: this.config.claudeHookBridgeToken,
254
- scriptPath,
255
- command,
256
- supportedEvents: ["UserPromptSubmit", "SessionStart", "Stop", "StopFailure", "SessionEnd"]
257
- };
265
+ return buildClaudeHookBridgeConfig(this.config);
258
266
  }
259
267
  async ingestClaudeHookEvent(payload) {
260
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
+ });
261
275
  if (!hookEventName) {
262
276
  throw new AppError({
263
277
  statusCode: 400,
@@ -267,20 +281,44 @@ export class SessionLiveRuntimeService {
267
281
  });
268
282
  }
269
283
  if (!isSupportedClaudeHookEvent(hookEventName)) {
284
+ logPermissionDebug("claude_hook_event.ingest.unsupported", {
285
+ hookEventName
286
+ });
270
287
  return {
271
288
  accepted: true,
272
289
  ignored: true,
273
- sessionId: null
290
+ sessionId: null,
291
+ bridgeResponse: null
274
292
  };
275
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
+ }
276
308
  const providerSessionId = normalizeRequiredText(payload.session_id, "session_id");
277
309
  const workspacePath = normalizeRequiredText(payload.cwd, "cwd");
278
310
  const workspace = this.workspaceService.findWorkspaceByPath(workspacePath);
279
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
+ });
280
317
  return {
281
318
  accepted: true,
282
319
  ignored: true,
283
- sessionId: null
320
+ sessionId: null,
321
+ bridgeResponse: null
284
322
  };
285
323
  }
286
324
  const binding = await this.resolveClaudeExternalBinding({
@@ -291,11 +329,18 @@ export class SessionLiveRuntimeService {
291
329
  });
292
330
  const timestamp = nowIso();
293
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
+ });
294
338
  if (!runtimeUpdate) {
295
339
  return {
296
340
  accepted: true,
297
341
  ignored: true,
298
- sessionId: binding.sessionId
342
+ sessionId: binding.sessionId,
343
+ bridgeResponse: null
299
344
  };
300
345
  }
301
346
  if (this.shouldIgnoreClaudeExternalRuntimeUpdate(binding.sessionId)) {
@@ -303,7 +348,8 @@ export class SessionLiveRuntimeService {
303
348
  return {
304
349
  accepted: true,
305
350
  ignored: true,
306
- sessionId: binding.sessionId
351
+ sessionId: binding.sessionId,
352
+ bridgeResponse: null
307
353
  };
308
354
  }
309
355
  await this.applyExternalRuntimeUpdate({
@@ -316,7 +362,8 @@ export class SessionLiveRuntimeService {
316
362
  return {
317
363
  accepted: true,
318
364
  ignored: false,
319
- sessionId: binding.sessionId
365
+ sessionId: binding.sessionId,
366
+ bridgeResponse: null
320
367
  };
321
368
  }
322
369
  async getSessionRuntime(sessionId, userId) {
@@ -328,24 +375,33 @@ export class SessionLiveRuntimeService {
328
375
  this.maybeDispatchQueuedMessages(session);
329
376
  const capabilities = await this.sessionHistoryService.getSessionCapabilities(sessionId);
330
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);
331
383
  if (runtimeSnapshot) {
332
384
  return {
333
385
  sessionId,
334
386
  provider: session.provider,
335
387
  providerSessionId: runtimeSnapshot.providerSessionId ?? session.providerSessionId,
336
- runningState: runtimeSnapshot.runningState,
388
+ runningState: resolution.runningState,
337
389
  hasActiveRun: true,
338
390
  canAttach: true,
339
391
  canInterrupt: runtimeSnapshot.supportsInterrupt,
340
392
  inRunInputMode: capabilities.inRunInputMode,
341
- detail: runtimeSnapshot.detail,
342
- errorCode: runtimeSnapshot.runningState === "failed"
343
- ? 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
344
399
  : null,
345
- errorDetail: runtimeSnapshot.runningState === "failed"
346
- ? runtimeSnapshot.detail ?? session.lastErrorDetail
400
+ errorDetail: resolution.runningState === "failed"
401
+ ? resolution.detail ?? session.lastErrorDetail
347
402
  : null,
348
- updatedAt: runtimeSnapshot.lastEventAt ?? runtimeSnapshot.startedAt,
403
+ updatedAt: resolution.updatedAt,
404
+ watchdogTriggeredAt: resolution.watchdogTriggeredAt,
349
405
  contextUsage
350
406
  };
351
407
  }
@@ -354,33 +410,41 @@ export class SessionLiveRuntimeService {
354
410
  sessionId,
355
411
  provider: "claude-code",
356
412
  providerSessionId: externalRuntimeSnapshot.providerSessionId,
357
- runningState: externalRuntimeSnapshot.runningState,
413
+ runningState: resolution.runningState,
358
414
  hasActiveRun: true,
359
415
  canAttach: false,
360
416
  canInterrupt: false,
361
417
  inRunInputMode: capabilities.inRunInputMode,
362
- detail: externalRuntimeSnapshot.detail,
363
- errorCode: session.runningState === "failed" ? session.lastErrorCode : null,
364
- errorDetail: session.runningState === "failed" ? session.lastErrorDetail : null,
365
- 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,
366
426
  contextUsage
367
427
  };
368
428
  }
369
- const persistedErrorCode = session.runningState === "failed" ? session.lastErrorCode : null;
370
- 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;
371
431
  return {
372
432
  sessionId,
373
433
  provider: session.provider,
374
434
  providerSessionId: session.providerSessionId,
375
- runningState: session.runningState ?? "idle",
435
+ runningState: resolution.runningState,
376
436
  hasActiveRun: false,
377
437
  canAttach: false,
378
438
  canInterrupt: false,
379
439
  inRunInputMode: capabilities.inRunInputMode,
440
+ activityResolutionSource: resolution.activityResolutionSource,
441
+ activityConfidence: resolution.activityConfidence,
442
+ runId: resolution.runId,
380
443
  detail: persistedErrorDetail,
381
444
  errorCode: persistedErrorCode,
382
445
  errorDetail: persistedErrorDetail,
383
- updatedAt: session.lastEventAt ?? session.updatedAt,
446
+ updatedAt: resolution.updatedAt,
447
+ watchdogTriggeredAt: resolution.watchdogTriggeredAt,
384
448
  contextUsage
385
449
  };
386
450
  }
@@ -412,9 +476,16 @@ export class SessionLiveRuntimeService {
412
476
  detail: interrupted.detail ?? "interrupt requested"
413
477
  };
414
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
+ }
415
485
  subscribeRuntime(sessionId, onEnvelope) {
416
486
  const runtimeSnapshot = this.providerRuntimeService.getSnapshot(sessionId);
417
487
  const externalRuntimeSnapshot = this.externalRuntimeSnapshots.get(sessionId) ?? null;
488
+ const initialActivityEnvelope = this.buildSessionActivityEnvelope(sessionId);
418
489
  if (runtimeSnapshot) {
419
490
  void onEnvelope({
420
491
  type: "session.runtime_status",
@@ -433,6 +504,9 @@ export class SessionLiveRuntimeService {
433
504
  timestamp: externalRuntimeSnapshot.updatedAt
434
505
  });
435
506
  }
507
+ if (initialActivityEnvelope) {
508
+ void onEnvelope(initialActivityEnvelope);
509
+ }
436
510
  const runtimeSubscription = this.providerRuntimeService.subscribe(sessionId, async (event) => {
437
511
  const envelope = this.mapRuntimeEventToEnvelope(sessionId, event);
438
512
  if (!envelope) {
@@ -441,10 +515,18 @@ export class SessionLiveRuntimeService {
441
515
  await onEnvelope(envelope);
442
516
  });
443
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
+ });
444
525
  return {
445
526
  close: () => {
446
527
  runtimeSubscription.close();
447
528
  externalSubscription.close();
529
+ activitySubscription.close();
448
530
  }
449
531
  };
450
532
  }
@@ -455,7 +537,12 @@ export class SessionLiveRuntimeService {
455
537
  this.queueRetryTimers.clear();
456
538
  this.runtimeMessageSeenSessions.clear();
457
539
  this.runtimeHistoryFallbackSentSessions.clear();
540
+ this.sessionActivityAuthorityService.dispose();
541
+ await this.sessionPermissionRequestService.dispose();
458
542
  await this.providerRuntimeService.dispose();
543
+ for (const disposable of this.runtimeAdapterDisposables) {
544
+ disposable.dispose();
545
+ }
459
546
  this.externalRuntimeSnapshots.clear();
460
547
  this.runtimeListeners.clear();
461
548
  }
@@ -490,6 +577,49 @@ export class SessionLiveRuntimeService {
490
577
  await listener(envelope);
491
578
  }));
492
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
+ }
493
623
  async resolveClaudeExternalBinding(input) {
494
624
  const rawStoreRef = input.transcriptPath ??
495
625
  findClaudeSessionFile(this.config.claudeCodeHomeDir, input.providerSessionId) ??
@@ -592,6 +722,16 @@ export class SessionLiveRuntimeService {
592
722
  lastErrorDetail: input.runningState === "failed" ? (input.detail ?? "Claude hook failed") : null,
593
723
  resumedAt: this.sessionStatusSnapshotRepository.findBySessionId(input.sessionId)?.resumedAt ?? null
594
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
+ });
595
735
  if (input.runningState === "running") {
596
736
  this.externalRuntimeSnapshots.set(input.sessionId, {
597
737
  sessionId: input.sessionId,
@@ -648,6 +788,7 @@ export class SessionLiveRuntimeService {
648
788
  lastSeenAt: currentState?.lastSeenAt ?? null,
649
789
  updatedAt: nowIso()
650
790
  });
791
+ this.sessionActivityAuthorityService.observe(createRuntimeActivityObservation(request.sessionId, snapshot));
651
792
  }
652
793
  async sendLiveMessageDirect(input, persistedAttachments) {
653
794
  const requestStartedAt = nowIso();
@@ -903,6 +1044,7 @@ export class SessionLiveRuntimeService {
903
1044
  lastSeenAt: null,
904
1045
  updatedAt: timestamp
905
1046
  });
1047
+ this.sessionActivityAuthorityService.observe(createRuntimeActivityObservation(input.sessionId, input.snapshot));
906
1048
  }
907
1049
  async persistRuntimeEvent(sessionId, workspaceId, userId, event) {
908
1050
  this.sessionHistoryService.persistSessionBinding(sessionId, workspaceId, {
@@ -993,6 +1135,7 @@ export class SessionLiveRuntimeService {
993
1135
  lastSeenAt: currentState?.lastSeenAt ?? null,
994
1136
  updatedAt: nowIso()
995
1137
  });
1138
+ this.sessionActivityAuthorityService.observe(createRuntimeEventObservation(sessionId, event, this.providerRuntimeService.getSnapshot(sessionId)?.startedAt ?? null));
996
1139
  this.upsertSnapshot(sessionId, {
997
1140
  syncStatus: event.type === "error" ? "error" : "idle",
998
1141
  syncCursor: this.sessionStatusSnapshotRepository.findBySessionId(sessionId)?.syncCursor ?? null,
@@ -1110,6 +1253,32 @@ export class SessionLiveRuntimeService {
1110
1253
  clearExternalRuntimeSnapshot(sessionId) {
1111
1254
  this.externalRuntimeSnapshots.delete(sessionId);
1112
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
+ }
1113
1282
  }
1114
1283
  function createSyntheticUserMessage(provider, providerSessionId, content, timestamp, sequence, attachments = []) {
1115
1284
  const syntheticId = createId();
@@ -1127,6 +1296,51 @@ function createSyntheticUserMessage(provider, providerSessionId, content, timest
1127
1296
  rawRef: `synthetic://${provider}/${providerSessionId}/${syntheticId}`
1128
1297
  };
1129
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
+ }
1130
1344
  function withTimeout(promise, timeoutMs) {
1131
1345
  return new Promise((resolve, reject) => {
1132
1346
  const timer = setTimeout(() => {
@@ -1151,7 +1365,10 @@ function normalizeClaudeHookEventName(value) {
1151
1365
  return normalized && normalized.length > 0 ? normalized : null;
1152
1366
  }
1153
1367
  function isSupportedClaudeHookEvent(value) {
1154
- return (value === "UserPromptSubmit" ||
1368
+ return (value === "PreToolUse" ||
1369
+ value === "PermissionRequest" ||
1370
+ value === "Notification" ||
1371
+ value === "UserPromptSubmit" ||
1155
1372
  value === "SessionStart" ||
1156
1373
  value === "Stop" ||
1157
1374
  value === "StopFailure" ||
@@ -1270,17 +1487,86 @@ function mapQueueItemRecordToView(record) {
1270
1487
  function isTerminalSessionRunningState(state) {
1271
1488
  return state === "completed" || state === "interrupted" || state === "failed";
1272
1489
  }
1273
- function createProviderRuntimeAdapters(config) {
1274
- return [
1275
- new ClaudeRuntimeAdapter({
1276
- homeDir: config.claudeCodeHomeDir
1277
- }),
1278
- new CodexRuntimeAdapter(),
1279
- new OpenCodeRuntimeAdapter({
1280
- baseUrl: config.opencodeBaseUrl,
1281
- 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
+ }
1282
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")
1283
1563
  ];
1564
+ for (const candidate of candidates) {
1565
+ if (existsSync(candidate)) {
1566
+ return candidate;
1567
+ }
1568
+ }
1569
+ return candidates[0];
1284
1570
  }
1285
1571
  function buildClaudeRawStoreRef(homeDir, workspacePath, sessionId) {
1286
1572
  return path.join(homeDir, "projects", workspaceSlug(workspacePath), `${sessionId}.jsonl`);