@jingyi0605/codingns 0.1.1 → 0.1.3

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 (251) hide show
  1. package/README.md +14 -0
  2. package/dist/public/assets/{TerminalPage-CVG1cGAJ.js → TerminalPage-Nq5sPc5c.js} +19 -19
  3. package/dist/public/assets/index-9hnprhO7.css +1 -0
  4. package/dist/public/assets/index-BTpmuKhG.js +108 -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 +17 -0
  67. package/dist/server/modules/sessions/codex-app-server-helper-client.js +260 -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 +167 -44
  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 +42 -4
  84. package/dist/server/modules/sessions/session-live-runtime-service.js +343 -51
  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 +6 -2
  92. package/dist/server/modules/terminal/command-template-service.js +91 -5
  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/template-reverse-proxy-service.d.ts +10 -0
  149. package/dist/server/modules/terminal/template-reverse-proxy-service.js +320 -0
  150. package/dist/server/modules/terminal/template-reverse-proxy-service.js.map +1 -0
  151. package/dist/server/modules/terminal/terminal-controller.d.ts +1 -0
  152. package/dist/server/modules/terminal/terminal-controller.js +23 -7
  153. package/dist/server/modules/terminal/terminal-controller.js.map +1 -1
  154. package/dist/server/modules/terminal/terminal-service.d.ts +30 -14
  155. package/dist/server/modules/terminal/terminal-service.js +260 -51
  156. package/dist/server/modules/terminal/terminal-service.js.map +1 -1
  157. package/dist/server/modules/terminal/terminal-shell.d.ts +4 -0
  158. package/dist/server/modules/terminal/terminal-shell.js +165 -18
  159. package/dist/server/modules/terminal/terminal-shell.js.map +1 -1
  160. package/dist/server/modules/workbench/workspace-file-watcher.d.ts +30 -0
  161. package/dist/server/modules/workbench/workspace-file-watcher.js +137 -0
  162. package/dist/server/modules/workbench/workspace-file-watcher.js.map +1 -0
  163. package/dist/server/modules/workbench/workspace-panel-snapshot-service.js +48 -7
  164. package/dist/server/modules/workbench/workspace-panel-snapshot-service.js.map +1 -1
  165. package/dist/server/routes/git.js +1 -0
  166. package/dist/server/routes/git.js.map +1 -1
  167. package/dist/server/routes/preferences.d.ts +2 -1
  168. package/dist/server/routes/preferences.js +3 -1
  169. package/dist/server/routes/preferences.js.map +1 -1
  170. package/dist/server/routes/proxy.d.ts +3 -0
  171. package/dist/server/routes/proxy.js +24 -0
  172. package/dist/server/routes/proxy.js.map +1 -0
  173. package/dist/server/routes/sessions.js +2 -0
  174. package/dist/server/routes/sessions.js.map +1 -1
  175. package/dist/server/server/create-server.d.ts +4 -0
  176. package/dist/server/server/create-server.js +29 -5
  177. package/dist/server/server/create-server.js.map +1 -1
  178. package/dist/server/shared/utils/command-launch.d.ts +6 -0
  179. package/dist/server/shared/utils/command-launch.js +39 -0
  180. package/dist/server/shared/utils/command-launch.js.map +1 -0
  181. package/dist/server/shared/utils/perf-log.d.ts +1 -0
  182. package/dist/server/shared/utils/perf-log.js +8 -2
  183. package/dist/server/shared/utils/perf-log.js.map +1 -1
  184. package/dist/server/shared/utils/permission-debug-log.d.ts +2 -0
  185. package/dist/server/shared/utils/permission-debug-log.js +40 -0
  186. package/dist/server/shared/utils/permission-debug-log.js.map +1 -0
  187. package/dist/server/shared/utils/terminal-debug-log.d.ts +4 -0
  188. package/dist/server/shared/utils/terminal-debug-log.js +71 -0
  189. package/dist/server/shared/utils/terminal-debug-log.js.map +1 -0
  190. package/dist/server/storage/repositories/terminal-command-template-repository.d.ts +1 -0
  191. package/dist/server/storage/repositories/terminal-command-template-repository.js +34 -3
  192. package/dist/server/storage/repositories/terminal-command-template-repository.js.map +1 -1
  193. package/dist/server/storage/repositories/user-preference-profile-repository.d.ts +8 -0
  194. package/dist/server/storage/repositories/user-preference-profile-repository.js +46 -0
  195. package/dist/server/storage/repositories/user-preference-profile-repository.js.map +1 -0
  196. package/dist/server/storage/sqlite/client.js +27 -0
  197. package/dist/server/storage/sqlite/client.js.map +1 -1
  198. package/dist/server/storage/sqlite/schema.sql +15 -0
  199. package/dist/server/types/domain.d.ts +30 -1
  200. package/dist/server/ws/terminal-ws-hub.d.ts +2 -0
  201. package/dist/server/ws/terminal-ws-hub.js +42 -5
  202. package/dist/server/ws/terminal-ws-hub.js.map +1 -1
  203. package/dist/server/ws/workbench-ws-hub.d.ts +9 -1
  204. package/dist/server/ws/workbench-ws-hub.js +132 -21
  205. package/dist/server/ws/workbench-ws-hub.js.map +1 -1
  206. package/dist/server/ws/ws-server.d.ts +22 -1
  207. package/dist/server/ws/ws-server.js +82 -44
  208. package/dist/server/ws/ws-server.js.map +1 -1
  209. package/node_modules/@codingns/session-sync-core/dist/claude-message-utils.js +42 -0
  210. package/node_modules/@codingns/session-sync-core/dist/claude-message-utils.js.map +1 -1
  211. package/node_modules/@codingns/session-sync-core/dist/patch-builder.d.ts +30 -0
  212. package/node_modules/@codingns/session-sync-core/dist/patch-builder.js +103 -0
  213. package/node_modules/@codingns/session-sync-core/dist/patch-builder.js.map +1 -0
  214. package/node_modules/@codingns/session-sync-core/dist/providers/claude-code.d.ts +1 -1
  215. package/node_modules/@codingns/session-sync-core/dist/providers/claude-code.js +167 -7
  216. package/node_modules/@codingns/session-sync-core/dist/providers/claude-code.js.map +1 -1
  217. package/node_modules/@codingns/session-sync-core/dist/providers/codex.d.ts +1 -1
  218. package/node_modules/@codingns/session-sync-core/dist/providers/codex.js +1 -1
  219. package/node_modules/@codingns/session-sync-core/dist/providers/codex.js.map +1 -1
  220. package/node_modules/@codingns/session-sync-core/dist/providers/opencode-permissions.d.ts +1 -0
  221. package/node_modules/@codingns/session-sync-core/dist/providers/opencode-permissions.js +8 -0
  222. package/node_modules/@codingns/session-sync-core/dist/providers/opencode-permissions.js.map +1 -0
  223. package/node_modules/@codingns/session-sync-core/dist/providers/opencode-shared.js +31 -0
  224. package/node_modules/@codingns/session-sync-core/dist/providers/opencode-shared.js.map +1 -1
  225. package/node_modules/@codingns/session-sync-core/dist/providers/opencode.d.ts +1 -1
  226. package/node_modules/@codingns/session-sync-core/dist/providers/opencode.js +8 -4
  227. package/node_modules/@codingns/session-sync-core/dist/providers/opencode.js.map +1 -1
  228. package/node_modules/@codingns/session-sync-core/dist/runtime/active-run-registry.d.ts +1 -0
  229. package/node_modules/@codingns/session-sync-core/dist/runtime/active-run-registry.js +15 -0
  230. package/node_modules/@codingns/session-sync-core/dist/runtime/active-run-registry.js.map +1 -1
  231. package/node_modules/@codingns/session-sync-core/dist/runtime/claude-runtime.d.ts +5 -0
  232. package/node_modules/@codingns/session-sync-core/dist/runtime/claude-runtime.js +85 -1
  233. package/node_modules/@codingns/session-sync-core/dist/runtime/claude-runtime.js.map +1 -1
  234. package/node_modules/@codingns/session-sync-core/dist/runtime/codex-runtime.d.ts +25 -0
  235. package/node_modules/@codingns/session-sync-core/dist/runtime/codex-runtime.js +718 -17
  236. package/node_modules/@codingns/session-sync-core/dist/runtime/codex-runtime.js.map +1 -1
  237. package/node_modules/@codingns/session-sync-core/dist/runtime/opencode-runtime.d.ts +3 -0
  238. package/node_modules/@codingns/session-sync-core/dist/runtime/opencode-runtime.js +106 -23
  239. package/node_modules/@codingns/session-sync-core/dist/runtime/opencode-runtime.js.map +1 -1
  240. package/node_modules/@codingns/session-sync-core/dist/runtime/provider-runtime-service.d.ts +3 -0
  241. package/node_modules/@codingns/session-sync-core/dist/runtime/provider-runtime-service.js +19 -0
  242. package/node_modules/@codingns/session-sync-core/dist/runtime/provider-runtime-service.js.map +1 -1
  243. package/node_modules/@codingns/session-sync-core/dist/runtime/types.d.ts +3 -0
  244. package/node_modules/@codingns/session-sync-core/dist/services.d.ts +1 -1
  245. package/node_modules/@codingns/session-sync-core/dist/services.js +2 -2
  246. package/node_modules/@codingns/session-sync-core/dist/services.js.map +1 -1
  247. package/node_modules/@codingns/session-sync-core/dist/types.d.ts +1 -1
  248. package/package.json +3 -2
  249. package/scripts/postinstall.mjs +15 -8
  250. package/dist/public/assets/index-BUPByQPG.css +0 -1
  251. 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,13 +44,24 @@ 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();
43
61
  const capabilities = this.sessionHistoryService.getProviderCapabilitiesSnapshot(input.provider);
44
62
  const workspace = this.workspaceService.getWorkspaceOrThrow(input.workspaceId);
45
63
  const sessionId = createId();
64
+ this.ensurePendingSessionBinding(sessionId, workspace.id, input.provider);
46
65
  const persistedAttachments = this.persistMessageAttachments(sessionId, input.clientRequestId, input.runtimeOptions?.attachments ?? []);
47
66
  const providerPrompt = this.sessionMessageAttachmentService.buildProviderPrompt(input.provider, input.content, persistedAttachments.runtimeAttachments);
48
67
  this.ensureCapability(capabilities.canStartSession, "provider", "provider 不支持 start-live");
@@ -244,20 +263,16 @@ export class SessionLiveRuntimeService {
244
263
  };
245
264
  }
246
265
  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
- };
266
+ return buildClaudeHookBridgeConfig(this.config);
258
267
  }
259
268
  async ingestClaudeHookEvent(payload) {
260
269
  const hookEventName = normalizeClaudeHookEventName(payload.hook_event_name);
270
+ logPermissionDebug("claude_hook_event.ingest.begin", {
271
+ hookEventName,
272
+ sessionId: payload.session_id ?? null,
273
+ cwd: payload.cwd ?? null,
274
+ transcriptPath: payload.transcript_path ?? null
275
+ });
261
276
  if (!hookEventName) {
262
277
  throw new AppError({
263
278
  statusCode: 400,
@@ -267,20 +282,44 @@ export class SessionLiveRuntimeService {
267
282
  });
268
283
  }
269
284
  if (!isSupportedClaudeHookEvent(hookEventName)) {
285
+ logPermissionDebug("claude_hook_event.ingest.unsupported", {
286
+ hookEventName
287
+ });
270
288
  return {
271
289
  accepted: true,
272
290
  ignored: true,
273
- sessionId: null
291
+ sessionId: null,
292
+ bridgeResponse: null
274
293
  };
275
294
  }
295
+ if (hookEventName === "PreToolUse") {
296
+ logPermissionDebug("claude_hook_event.route", {
297
+ hookEventName,
298
+ route: "handleClaudePreToolUse"
299
+ });
300
+ return this.sessionPermissionRequestService.handleClaudePreToolUse(payload);
301
+ }
302
+ if (hookEventName === "PermissionRequest") {
303
+ logPermissionDebug("claude_hook_event.route", {
304
+ hookEventName,
305
+ route: "handleClaudePermissionRequest"
306
+ });
307
+ return this.sessionPermissionRequestService.handleClaudePermissionRequest(payload);
308
+ }
276
309
  const providerSessionId = normalizeRequiredText(payload.session_id, "session_id");
277
310
  const workspacePath = normalizeRequiredText(payload.cwd, "cwd");
278
311
  const workspace = this.workspaceService.findWorkspaceByPath(workspacePath);
279
312
  if (!workspace) {
313
+ logPermissionDebug("claude_hook_event.workspace_not_found", {
314
+ hookEventName,
315
+ sessionId: payload.session_id ?? null,
316
+ cwd: payload.cwd ?? null
317
+ });
280
318
  return {
281
319
  accepted: true,
282
320
  ignored: true,
283
- sessionId: null
321
+ sessionId: null,
322
+ bridgeResponse: null
284
323
  };
285
324
  }
286
325
  const binding = await this.resolveClaudeExternalBinding({
@@ -291,11 +330,18 @@ export class SessionLiveRuntimeService {
291
330
  });
292
331
  const timestamp = nowIso();
293
332
  const runtimeUpdate = mapClaudeHookToRuntimeUpdate(hookEventName, payload, timestamp);
333
+ logPermissionDebug("claude_hook_event.runtime_update", {
334
+ hookEventName,
335
+ sessionId: binding.sessionId,
336
+ providerSessionId,
337
+ hasRuntimeUpdate: runtimeUpdate !== null
338
+ });
294
339
  if (!runtimeUpdate) {
295
340
  return {
296
341
  accepted: true,
297
342
  ignored: true,
298
- sessionId: binding.sessionId
343
+ sessionId: binding.sessionId,
344
+ bridgeResponse: null
299
345
  };
300
346
  }
301
347
  if (this.shouldIgnoreClaudeExternalRuntimeUpdate(binding.sessionId)) {
@@ -303,7 +349,8 @@ export class SessionLiveRuntimeService {
303
349
  return {
304
350
  accepted: true,
305
351
  ignored: true,
306
- sessionId: binding.sessionId
352
+ sessionId: binding.sessionId,
353
+ bridgeResponse: null
307
354
  };
308
355
  }
309
356
  await this.applyExternalRuntimeUpdate({
@@ -316,7 +363,8 @@ export class SessionLiveRuntimeService {
316
363
  return {
317
364
  accepted: true,
318
365
  ignored: false,
319
- sessionId: binding.sessionId
366
+ sessionId: binding.sessionId,
367
+ bridgeResponse: null
320
368
  };
321
369
  }
322
370
  async getSessionRuntime(sessionId, userId) {
@@ -328,24 +376,33 @@ export class SessionLiveRuntimeService {
328
376
  this.maybeDispatchQueuedMessages(session);
329
377
  const capabilities = await this.sessionHistoryService.getSessionCapabilities(sessionId);
330
378
  const contextUsage = await this.sessionHistoryService.getSessionContextUsage(sessionId).catch(() => null);
379
+ const resolution = runtimeSnapshot
380
+ ? this.sessionActivityAuthorityService.observe(createRuntimeActivityObservation(sessionId, runtimeSnapshot))
381
+ : externalRuntimeSnapshot
382
+ ? this.sessionActivityAuthorityService.observe(createExternalRuntimeActivityObservation(sessionId, externalRuntimeSnapshot))
383
+ : this.sessionActivityAuthorityService.resolvePersistedSession(session);
331
384
  if (runtimeSnapshot) {
332
385
  return {
333
386
  sessionId,
334
387
  provider: session.provider,
335
388
  providerSessionId: runtimeSnapshot.providerSessionId ?? session.providerSessionId,
336
- runningState: runtimeSnapshot.runningState,
389
+ runningState: resolution.runningState,
337
390
  hasActiveRun: true,
338
391
  canAttach: true,
339
392
  canInterrupt: runtimeSnapshot.supportsInterrupt,
340
393
  inRunInputMode: capabilities.inRunInputMode,
341
- detail: runtimeSnapshot.detail,
342
- errorCode: runtimeSnapshot.runningState === "failed"
343
- ? runtimeSnapshot.errorCode ?? session.lastErrorCode
394
+ activityResolutionSource: resolution.activityResolutionSource,
395
+ activityConfidence: resolution.activityConfidence,
396
+ runId: resolution.runId,
397
+ detail: resolution.detail,
398
+ errorCode: resolution.runningState === "failed"
399
+ ? resolution.errorCode ?? session.lastErrorCode
344
400
  : null,
345
- errorDetail: runtimeSnapshot.runningState === "failed"
346
- ? runtimeSnapshot.detail ?? session.lastErrorDetail
401
+ errorDetail: resolution.runningState === "failed"
402
+ ? resolution.detail ?? session.lastErrorDetail
347
403
  : null,
348
- updatedAt: runtimeSnapshot.lastEventAt ?? runtimeSnapshot.startedAt,
404
+ updatedAt: resolution.updatedAt,
405
+ watchdogTriggeredAt: resolution.watchdogTriggeredAt,
349
406
  contextUsage
350
407
  };
351
408
  }
@@ -354,33 +411,41 @@ export class SessionLiveRuntimeService {
354
411
  sessionId,
355
412
  provider: "claude-code",
356
413
  providerSessionId: externalRuntimeSnapshot.providerSessionId,
357
- runningState: externalRuntimeSnapshot.runningState,
414
+ runningState: resolution.runningState,
358
415
  hasActiveRun: true,
359
416
  canAttach: false,
360
417
  canInterrupt: false,
361
418
  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,
419
+ activityResolutionSource: resolution.activityResolutionSource,
420
+ activityConfidence: resolution.activityConfidence,
421
+ runId: resolution.runId,
422
+ detail: resolution.detail,
423
+ errorCode: resolution.runningState === "failed" ? resolution.errorCode ?? session.lastErrorCode : null,
424
+ errorDetail: resolution.runningState === "failed" ? resolution.detail ?? session.lastErrorDetail : null,
425
+ updatedAt: resolution.updatedAt,
426
+ watchdogTriggeredAt: resolution.watchdogTriggeredAt,
366
427
  contextUsage
367
428
  };
368
429
  }
369
- const persistedErrorCode = session.runningState === "failed" ? session.lastErrorCode : null;
370
- const persistedErrorDetail = session.runningState === "failed" ? session.lastErrorDetail : null;
430
+ const persistedErrorCode = resolution.runningState === "failed" ? resolution.errorCode ?? session.lastErrorCode : null;
431
+ const persistedErrorDetail = resolution.runningState === "failed" ? resolution.detail ?? session.lastErrorDetail : null;
371
432
  return {
372
433
  sessionId,
373
434
  provider: session.provider,
374
435
  providerSessionId: session.providerSessionId,
375
- runningState: session.runningState ?? "idle",
436
+ runningState: resolution.runningState,
376
437
  hasActiveRun: false,
377
438
  canAttach: false,
378
439
  canInterrupt: false,
379
440
  inRunInputMode: capabilities.inRunInputMode,
441
+ activityResolutionSource: resolution.activityResolutionSource,
442
+ activityConfidence: resolution.activityConfidence,
443
+ runId: resolution.runId,
380
444
  detail: persistedErrorDetail,
381
445
  errorCode: persistedErrorCode,
382
446
  errorDetail: persistedErrorDetail,
383
- updatedAt: session.lastEventAt ?? session.updatedAt,
447
+ updatedAt: resolution.updatedAt,
448
+ watchdogTriggeredAt: resolution.watchdogTriggeredAt,
384
449
  contextUsage
385
450
  };
386
451
  }
@@ -412,9 +477,16 @@ export class SessionLiveRuntimeService {
412
477
  detail: interrupted.detail ?? "interrupt requested"
413
478
  };
414
479
  }
480
+ async listPermissionRequests(sessionId, userId) {
481
+ return this.sessionPermissionRequestService.listSessionPermissionRequests(sessionId, userId);
482
+ }
483
+ async replyPermissionRequest(sessionId, userId, requestId, input) {
484
+ return this.sessionPermissionRequestService.replyToSessionPermissionRequest(sessionId, userId, requestId, input);
485
+ }
415
486
  subscribeRuntime(sessionId, onEnvelope) {
416
487
  const runtimeSnapshot = this.providerRuntimeService.getSnapshot(sessionId);
417
488
  const externalRuntimeSnapshot = this.externalRuntimeSnapshots.get(sessionId) ?? null;
489
+ const initialActivityEnvelope = this.buildSessionActivityEnvelope(sessionId);
418
490
  if (runtimeSnapshot) {
419
491
  void onEnvelope({
420
492
  type: "session.runtime_status",
@@ -433,6 +505,9 @@ export class SessionLiveRuntimeService {
433
505
  timestamp: externalRuntimeSnapshot.updatedAt
434
506
  });
435
507
  }
508
+ if (initialActivityEnvelope) {
509
+ void onEnvelope(initialActivityEnvelope);
510
+ }
436
511
  const runtimeSubscription = this.providerRuntimeService.subscribe(sessionId, async (event) => {
437
512
  const envelope = this.mapRuntimeEventToEnvelope(sessionId, event);
438
513
  if (!envelope) {
@@ -441,10 +516,18 @@ export class SessionLiveRuntimeService {
441
516
  await onEnvelope(envelope);
442
517
  });
443
518
  const externalSubscription = this.subscribeExternalRuntime(sessionId, onEnvelope);
519
+ const activitySubscription = this.sessionActivityAuthorityService.subscribe(sessionId, async () => {
520
+ const envelope = this.buildSessionActivityEnvelope(sessionId);
521
+ if (!envelope) {
522
+ return;
523
+ }
524
+ await onEnvelope(envelope);
525
+ });
444
526
  return {
445
527
  close: () => {
446
528
  runtimeSubscription.close();
447
529
  externalSubscription.close();
530
+ activitySubscription.close();
448
531
  }
449
532
  };
450
533
  }
@@ -455,7 +538,12 @@ export class SessionLiveRuntimeService {
455
538
  this.queueRetryTimers.clear();
456
539
  this.runtimeMessageSeenSessions.clear();
457
540
  this.runtimeHistoryFallbackSentSessions.clear();
541
+ this.sessionActivityAuthorityService.dispose();
542
+ await this.sessionPermissionRequestService.dispose();
458
543
  await this.providerRuntimeService.dispose();
544
+ for (const disposable of this.runtimeAdapterDisposables) {
545
+ disposable.dispose();
546
+ }
459
547
  this.externalRuntimeSnapshots.clear();
460
548
  this.runtimeListeners.clear();
461
549
  }
@@ -490,6 +578,49 @@ export class SessionLiveRuntimeService {
490
578
  await listener(envelope);
491
579
  }));
492
580
  }
581
+ buildSessionActivityEnvelope(sessionId) {
582
+ const runtimeSnapshot = this.providerRuntimeService.getSnapshot(sessionId);
583
+ if (runtimeSnapshot) {
584
+ const resolution = this.sessionActivityAuthorityService.observe(createRuntimeActivityObservation(sessionId, runtimeSnapshot));
585
+ return this.mapResolutionToActivityEnvelope(resolution, {
586
+ hasActiveRun: true,
587
+ canInterrupt: runtimeSnapshot.supportsInterrupt
588
+ });
589
+ }
590
+ const externalRuntimeSnapshot = this.externalRuntimeSnapshots.get(sessionId) ?? null;
591
+ if (externalRuntimeSnapshot) {
592
+ const resolution = this.sessionActivityAuthorityService.observe(createExternalRuntimeActivityObservation(sessionId, externalRuntimeSnapshot));
593
+ return this.mapResolutionToActivityEnvelope(resolution, {
594
+ hasActiveRun: true,
595
+ canInterrupt: false
596
+ });
597
+ }
598
+ const resolution = this.sessionActivityAuthorityService.getResolution(sessionId);
599
+ if (!resolution) {
600
+ return null;
601
+ }
602
+ return this.mapResolutionToActivityEnvelope(resolution, {
603
+ hasActiveRun: resolution.runningState === "stale" || resolution.runningState === "unknown",
604
+ canInterrupt: false
605
+ });
606
+ }
607
+ mapResolutionToActivityEnvelope(resolution, options) {
608
+ return {
609
+ type: "session.activity",
610
+ sessionId: resolution.sessionId,
611
+ runningState: resolution.runningState,
612
+ activityResolutionSource: resolution.activityResolutionSource,
613
+ activityConfidence: resolution.activityConfidence,
614
+ runId: resolution.runId,
615
+ detail: resolution.detail,
616
+ errorCode: resolution.errorCode,
617
+ errorDetail: resolution.detail,
618
+ hasActiveRun: options.hasActiveRun,
619
+ canInterrupt: options.canInterrupt,
620
+ updatedAt: resolution.updatedAt,
621
+ watchdogTriggeredAt: resolution.watchdogTriggeredAt
622
+ };
623
+ }
493
624
  async resolveClaudeExternalBinding(input) {
494
625
  const rawStoreRef = input.transcriptPath ??
495
626
  findClaudeSessionFile(this.config.claudeCodeHomeDir, input.providerSessionId) ??
@@ -592,6 +723,16 @@ export class SessionLiveRuntimeService {
592
723
  lastErrorDetail: input.runningState === "failed" ? (input.detail ?? "Claude hook failed") : null,
593
724
  resumedAt: this.sessionStatusSnapshotRepository.findBySessionId(input.sessionId)?.resumedAt ?? null
594
725
  });
726
+ this.sessionActivityAuthorityService.observe({
727
+ sessionId: input.sessionId,
728
+ runId: null,
729
+ runningState: input.runningState,
730
+ source: "authoritative_provider_event",
731
+ confidence: input.runningState === "failed" ? "strong" : "authoritative",
732
+ detail: input.detail,
733
+ errorCode: input.runningState === "failed" ? "CLAUDE_HOOK_STOP_FAILURE" : null,
734
+ observedAt: input.timestamp
735
+ });
595
736
  if (input.runningState === "running") {
596
737
  this.externalRuntimeSnapshots.set(input.sessionId, {
597
738
  sessionId: input.sessionId,
@@ -648,6 +789,7 @@ export class SessionLiveRuntimeService {
648
789
  lastSeenAt: currentState?.lastSeenAt ?? null,
649
790
  updatedAt: nowIso()
650
791
  });
792
+ this.sessionActivityAuthorityService.observe(createRuntimeActivityObservation(request.sessionId, snapshot));
651
793
  }
652
794
  async sendLiveMessageDirect(input, persistedAttachments) {
653
795
  const requestStartedAt = nowIso();
@@ -863,13 +1005,7 @@ export class SessionLiveRuntimeService {
863
1005
  }
864
1006
  createRuntimeBackedSession(input) {
865
1007
  const timestamp = nowIso();
866
- const providerSessionId = input.snapshot.providerSessionId ?? `pending://${input.provider}/${input.sessionId}`;
867
- const rawStoreRef = input.snapshot.rawStoreRef ?? `pending://${input.provider}/${input.sessionId}`;
868
- this.sessionHistoryService.persistSessionBinding(input.sessionId, input.workspaceId, {
869
- provider: input.snapshot.provider,
870
- providerSessionId,
871
- rawStoreRef
872
- });
1008
+ this.sessionHistoryService.persistSessionBinding(input.sessionId, input.workspaceId, this.buildBindingSnapshot(input.sessionId, input.snapshot.provider, input.snapshot.providerSessionId, input.snapshot.rawStoreRef));
873
1009
  this.sessionIndexRepository.upsert({
874
1010
  sessionId: input.sessionId,
875
1011
  workspaceId: input.workspaceId,
@@ -903,6 +1039,18 @@ export class SessionLiveRuntimeService {
903
1039
  lastSeenAt: null,
904
1040
  updatedAt: timestamp
905
1041
  });
1042
+ this.sessionActivityAuthorityService.observe(createRuntimeActivityObservation(input.sessionId, input.snapshot));
1043
+ }
1044
+ ensurePendingSessionBinding(sessionId, workspaceId, provider) {
1045
+ this.sessionHistoryService.persistSessionBinding(sessionId, workspaceId, this.buildBindingSnapshot(sessionId, provider, null, null));
1046
+ }
1047
+ buildBindingSnapshot(sessionId, provider, providerSessionId, rawStoreRef) {
1048
+ const pendingValue = `pending://${provider}/${sessionId}`;
1049
+ return {
1050
+ provider,
1051
+ providerSessionId: providerSessionId ?? pendingValue,
1052
+ rawStoreRef: rawStoreRef ?? pendingValue
1053
+ };
906
1054
  }
907
1055
  async persistRuntimeEvent(sessionId, workspaceId, userId, event) {
908
1056
  this.sessionHistoryService.persistSessionBinding(sessionId, workspaceId, {
@@ -993,6 +1141,7 @@ export class SessionLiveRuntimeService {
993
1141
  lastSeenAt: currentState?.lastSeenAt ?? null,
994
1142
  updatedAt: nowIso()
995
1143
  });
1144
+ this.sessionActivityAuthorityService.observe(createRuntimeEventObservation(sessionId, event, this.providerRuntimeService.getSnapshot(sessionId)?.startedAt ?? null));
996
1145
  this.upsertSnapshot(sessionId, {
997
1146
  syncStatus: event.type === "error" ? "error" : "idle",
998
1147
  syncCursor: this.sessionStatusSnapshotRepository.findBySessionId(sessionId)?.syncCursor ?? null,
@@ -1110,6 +1259,32 @@ export class SessionLiveRuntimeService {
1110
1259
  clearExternalRuntimeSnapshot(sessionId) {
1111
1260
  this.externalRuntimeSnapshots.delete(sessionId);
1112
1261
  }
1262
+ async resolveActiveClaudePermissionSession(input) {
1263
+ const activeSnapshots = this.providerRuntimeService
1264
+ .listSnapshots()
1265
+ .filter((snapshot) => snapshot.provider === "claude-code" &&
1266
+ snapshot.workspaceId === input.workspaceId &&
1267
+ isActiveRuntimeState(snapshot.runningState));
1268
+ if (activeSnapshots.length !== 1) {
1269
+ return null;
1270
+ }
1271
+ const activeSnapshot = activeSnapshots[0];
1272
+ if (!activeSnapshot) {
1273
+ return null;
1274
+ }
1275
+ const rawStoreRef = input.transcriptPath ??
1276
+ activeSnapshot.rawStoreRef ??
1277
+ buildClaudeRawStoreRef(this.config.claudeCodeHomeDir, input.workspacePath, input.providerSessionId);
1278
+ this.sessionHistoryService.persistSessionBinding(activeSnapshot.sessionId, input.workspaceId, {
1279
+ provider: "claude-code",
1280
+ providerSessionId: input.providerSessionId,
1281
+ rawStoreRef
1282
+ });
1283
+ return {
1284
+ sessionId: activeSnapshot.sessionId,
1285
+ rawStoreRef
1286
+ };
1287
+ }
1113
1288
  }
1114
1289
  function createSyntheticUserMessage(provider, providerSessionId, content, timestamp, sequence, attachments = []) {
1115
1290
  const syntheticId = createId();
@@ -1127,6 +1302,51 @@ function createSyntheticUserMessage(provider, providerSessionId, content, timest
1127
1302
  rawRef: `synthetic://${provider}/${providerSessionId}/${syntheticId}`
1128
1303
  };
1129
1304
  }
1305
+ function createRuntimeActivityObservation(sessionId, snapshot) {
1306
+ return {
1307
+ sessionId,
1308
+ runId: buildRuntimeRunId(sessionId, snapshot.startedAt),
1309
+ runningState: snapshot.runningState,
1310
+ source: "authoritative_runtime",
1311
+ confidence: snapshot.runningState === "failed" || snapshot.runningState === "completed" || snapshot.runningState === "interrupted"
1312
+ ? "strong"
1313
+ : "authoritative",
1314
+ detail: snapshot.detail,
1315
+ errorCode: snapshot.runningState === "failed" ? snapshot.errorCode ?? null : null,
1316
+ observedAt: snapshot.lastEventAt ?? snapshot.startedAt
1317
+ };
1318
+ }
1319
+ function createExternalRuntimeActivityObservation(sessionId, snapshot) {
1320
+ return {
1321
+ sessionId,
1322
+ runId: null,
1323
+ runningState: snapshot.runningState,
1324
+ source: "authoritative_provider_event",
1325
+ confidence: snapshot.runningState === "failed" ? "strong" : "authoritative",
1326
+ detail: snapshot.detail,
1327
+ errorCode: snapshot.runningState === "failed" ? "CLAUDE_HOOK_STOP_FAILURE" : null,
1328
+ observedAt: snapshot.updatedAt
1329
+ };
1330
+ }
1331
+ function createRuntimeEventObservation(sessionId, event, startedAt) {
1332
+ return {
1333
+ sessionId,
1334
+ runId: buildRuntimeRunId(sessionId, startedAt ?? event.timestamp),
1335
+ runningState: event.type === "message" ? "running" : event.status ?? "running",
1336
+ source: "authoritative_runtime",
1337
+ confidence: event.type === "error" || event.status === "completed" || event.status === "interrupted"
1338
+ ? "strong"
1339
+ : "authoritative",
1340
+ detail: event.type === "message"
1341
+ ? "Host 正在接收这一轮运行的实时事件"
1342
+ : event.detail,
1343
+ errorCode: event.type === "error" ? event.errorCode : null,
1344
+ observedAt: event.type === "message" ? event.message.timestamp : event.timestamp
1345
+ };
1346
+ }
1347
+ function buildRuntimeRunId(sessionId, startedAt) {
1348
+ return `runtime:${sessionId}:${startedAt}`;
1349
+ }
1130
1350
  function withTimeout(promise, timeoutMs) {
1131
1351
  return new Promise((resolve, reject) => {
1132
1352
  const timer = setTimeout(() => {
@@ -1151,7 +1371,10 @@ function normalizeClaudeHookEventName(value) {
1151
1371
  return normalized && normalized.length > 0 ? normalized : null;
1152
1372
  }
1153
1373
  function isSupportedClaudeHookEvent(value) {
1154
- return (value === "UserPromptSubmit" ||
1374
+ return (value === "PreToolUse" ||
1375
+ value === "PermissionRequest" ||
1376
+ value === "Notification" ||
1377
+ value === "UserPromptSubmit" ||
1155
1378
  value === "SessionStart" ||
1156
1379
  value === "Stop" ||
1157
1380
  value === "StopFailure" ||
@@ -1270,17 +1493,86 @@ function mapQueueItemRecordToView(record) {
1270
1493
  function isTerminalSessionRunningState(state) {
1271
1494
  return state === "completed" || state === "interrupted" || state === "failed";
1272
1495
  }
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)
1496
+ function createProviderRuntimeAdapters(config, options = {}) {
1497
+ const claudeHookBridgeConfig = buildClaudeHookBridgeConfig(config);
1498
+ const claudeAdapter = process.env.VITEST
1499
+ ? new ClaudeRuntimeAdapter({
1500
+ homeDir: config.claudeCodeHomeDir,
1501
+ hookBridge: {
1502
+ url: claudeHookBridgeConfig.bridgeUrl,
1503
+ token: config.claudeHookBridgeToken,
1504
+ scriptPath: claudeHookBridgeConfig.scriptPath
1505
+ }
1282
1506
  })
1507
+ : new ClaudeRuntimeHelperAdapter({
1508
+ homeDir: config.claudeCodeHomeDir,
1509
+ hookBridge: {
1510
+ url: claudeHookBridgeConfig.bridgeUrl,
1511
+ token: config.claudeHookBridgeToken,
1512
+ scriptPath: claudeHookBridgeConfig.scriptPath
1513
+ }
1514
+ });
1515
+ const disposables = [];
1516
+ if ("dispose" in claudeAdapter && typeof claudeAdapter.dispose === "function") {
1517
+ disposables.push(claudeAdapter);
1518
+ }
1519
+ const codexTransportHelper = process.env.VITEST
1520
+ ? null
1521
+ : new CodexAppServerHelperClient(config.codexCliPath);
1522
+ if (codexTransportHelper) {
1523
+ disposables.push(codexTransportHelper);
1524
+ }
1525
+ return {
1526
+ adapters: [
1527
+ claudeAdapter,
1528
+ new CodexRuntimeAdapter({
1529
+ homeDir: config.codexHomeDir,
1530
+ commandPath: config.codexCliPath,
1531
+ transportFactory: codexTransportHelper?.createTransport.bind(codexTransportHelper),
1532
+ handleServerRequest: options.handleCodexServerRequest
1533
+ }),
1534
+ new OpenCodeRuntimeAdapter({
1535
+ baseUrl: config.opencodeBaseUrl,
1536
+ baseUrlResolver: config.opencodeBaseUrlResolver?.resolve.bind(config.opencodeBaseUrlResolver)
1537
+ })
1538
+ ],
1539
+ disposables
1540
+ };
1541
+ }
1542
+ function buildClaudeHookBridgeConfig(config) {
1543
+ const bridgeUrl = `http://127.0.0.1:${config.port}/api/providers/claude-code/hook-bridge/events`;
1544
+ const scriptPath = resolveClaudeHookBridgeScriptPath();
1545
+ const command = `node "${scriptPath}" --url "${bridgeUrl}" --token "${config.claudeHookBridgeToken}"`;
1546
+ return {
1547
+ provider: "claude-code",
1548
+ bridgeUrl,
1549
+ token: config.claudeHookBridgeToken,
1550
+ scriptPath,
1551
+ command,
1552
+ supportedEvents: [
1553
+ "PreToolUse",
1554
+ "PermissionRequest",
1555
+ "Notification",
1556
+ "UserPromptSubmit",
1557
+ "SessionStart",
1558
+ "Stop",
1559
+ "StopFailure",
1560
+ "SessionEnd"
1561
+ ]
1562
+ };
1563
+ }
1564
+ function resolveClaudeHookBridgeScriptPath() {
1565
+ const candidates = [
1566
+ path.resolve(process.cwd(), "scripts", "claude-hook-bridge.cjs"),
1567
+ path.resolve(process.cwd(), "..", "scripts", "claude-hook-bridge.cjs"),
1568
+ path.resolve(process.cwd(), "..", "..", "scripts", "claude-hook-bridge.cjs")
1283
1569
  ];
1570
+ for (const candidate of candidates) {
1571
+ if (existsSync(candidate)) {
1572
+ return candidate;
1573
+ }
1574
+ }
1575
+ return candidates[0];
1284
1576
  }
1285
1577
  function buildClaudeRawStoreRef(homeDir, workspacePath, sessionId) {
1286
1578
  return path.join(homeDir, "projects", workspaceSlug(workspacePath), `${sessionId}.jsonl`);