@jingyi0605/codingns 0.3.5 → 0.4.0

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 (255) hide show
  1. package/README.md +16 -0
  2. package/bin/codingns.mjs +1369 -10
  3. package/dist/public/assets/{TerminalPage-CgrfstRm.js → TerminalPage-6jHZV9Mh.js} +17 -17
  4. package/dist/public/assets/index-CSVhg7I8.js +123 -0
  5. package/dist/public/assets/index-Ce1VX19m.css +1 -0
  6. package/dist/public/index.html +2 -2
  7. package/dist/server/config/opencode-base-url-resolver.d.ts +7 -0
  8. package/dist/server/config/opencode-base-url-resolver.js +48 -11
  9. package/dist/server/config/opencode-base-url-resolver.js.map +1 -1
  10. package/dist/server/config/opencode-system-probe-helper-client.d.ts +4 -0
  11. package/dist/server/config/opencode-system-probe-helper-client.js +29 -0
  12. package/dist/server/config/opencode-system-probe-helper-client.js.map +1 -1
  13. package/dist/server/config/opencode-system-probe-helper-process.d.ts +12 -0
  14. package/dist/server/config/opencode-system-probe-helper-process.js +34 -7
  15. package/dist/server/config/opencode-system-probe-helper-process.js.map +1 -1
  16. package/dist/server/modules/assistant-capability/assistant-capability-controller.d.ts +317 -0
  17. package/dist/server/modules/assistant-capability/assistant-capability-controller.js +549 -1
  18. package/dist/server/modules/assistant-capability/assistant-capability-controller.js.map +1 -1
  19. package/dist/server/modules/assistant-capability/assistant-capability-service.d.ts +330 -2
  20. package/dist/server/modules/assistant-capability/assistant-capability-service.js +958 -3
  21. package/dist/server/modules/assistant-capability/assistant-capability-service.js.map +1 -1
  22. package/dist/server/modules/butler/assistant-automation-service.d.ts +110 -0
  23. package/dist/server/modules/butler/assistant-automation-service.js +786 -0
  24. package/dist/server/modules/butler/assistant-automation-service.js.map +1 -0
  25. package/dist/server/modules/butler/assistant-automation-trigger.d.ts +94 -0
  26. package/dist/server/modules/butler/assistant-automation-trigger.js +400 -0
  27. package/dist/server/modules/butler/assistant-automation-trigger.js.map +1 -0
  28. package/dist/server/modules/butler/assistant-sandbox-service.d.ts +55 -0
  29. package/dist/server/modules/butler/assistant-sandbox-service.js +266 -0
  30. package/dist/server/modules/butler/assistant-sandbox-service.js.map +1 -0
  31. package/dist/server/modules/butler/butler-action-context-service.d.ts +4 -1
  32. package/dist/server/modules/butler/butler-action-context-service.js +8 -2
  33. package/dist/server/modules/butler/butler-action-context-service.js.map +1 -1
  34. package/dist/server/modules/butler/butler-control-session-service.d.ts +8 -1
  35. package/dist/server/modules/butler/butler-control-session-service.js +154 -40
  36. package/dist/server/modules/butler/butler-control-session-service.js.map +1 -1
  37. package/dist/server/modules/butler/butler-control-timer-scheduler.d.ts +32 -0
  38. package/dist/server/modules/butler/butler-control-timer-scheduler.js +93 -0
  39. package/dist/server/modules/butler/butler-control-timer-scheduler.js.map +1 -0
  40. package/dist/server/modules/butler/butler-control-timer-service.d.ts +42 -0
  41. package/dist/server/modules/butler/butler-control-timer-service.js +132 -0
  42. package/dist/server/modules/butler/butler-control-timer-service.js.map +1 -0
  43. package/dist/server/modules/butler/butler-controller.d.ts +42 -2
  44. package/dist/server/modules/butler/butler-controller.js +79 -12
  45. package/dist/server/modules/butler/butler-controller.js.map +1 -1
  46. package/dist/server/modules/butler/butler-follow-up-service.d.ts +9 -1
  47. package/dist/server/modules/butler/butler-follow-up-service.js +273 -181
  48. package/dist/server/modules/butler/butler-follow-up-service.js.map +1 -1
  49. package/dist/server/modules/butler/butler-inbox-analysis-service.d.ts +4 -1
  50. package/dist/server/modules/butler/butler-inbox-analysis-service.js +18 -4
  51. package/dist/server/modules/butler/butler-inbox-analysis-service.js.map +1 -1
  52. package/dist/server/modules/butler/butler-inbox-instruction-adapter.js +7 -6
  53. package/dist/server/modules/butler/butler-inbox-instruction-adapter.js.map +1 -1
  54. package/dist/server/modules/butler/butler-profile-service.js +2 -5
  55. package/dist/server/modules/butler/butler-profile-service.js.map +1 -1
  56. package/dist/server/modules/butler/butler-project-service.d.ts +3 -1
  57. package/dist/server/modules/butler/butler-project-service.js +7 -1
  58. package/dist/server/modules/butler/butler-project-service.js.map +1 -1
  59. package/dist/server/modules/butler/butler-session-service.d.ts +3 -1
  60. package/dist/server/modules/butler/butler-session-service.js +12 -1
  61. package/dist/server/modules/butler/butler-session-service.js.map +1 -1
  62. package/dist/server/modules/butler/butler-session-summary-service.js +2 -1
  63. package/dist/server/modules/butler/butler-session-summary-service.js.map +1 -1
  64. package/dist/server/modules/butler/butler-workspace-context.d.ts +3 -0
  65. package/dist/server/modules/butler/butler-workspace-context.js +182 -51
  66. package/dist/server/modules/butler/butler-workspace-context.js.map +1 -1
  67. package/dist/server/modules/butler/patrol-execution-service.js +2 -1
  68. package/dist/server/modules/butler/patrol-execution-service.js.map +1 -1
  69. package/dist/server/modules/butler/provider-adapter-registry.d.ts +3 -0
  70. package/dist/server/modules/butler/provider-adapter-registry.js +18 -1
  71. package/dist/server/modules/butler/provider-adapter-registry.js.map +1 -1
  72. package/dist/server/modules/butler/verification-run-service.d.ts +9 -2
  73. package/dist/server/modules/butler/verification-run-service.js +188 -34
  74. package/dist/server/modules/butler/verification-run-service.js.map +1 -1
  75. package/dist/server/modules/debug-target/debug-target-controller.d.ts +13 -0
  76. package/dist/server/modules/debug-target/debug-target-controller.js +77 -2
  77. package/dist/server/modules/debug-target/debug-target-controller.js.map +1 -1
  78. package/dist/server/modules/debug-target/debug-target-service.d.ts +17 -3
  79. package/dist/server/modules/debug-target/debug-target-service.js +696 -98
  80. package/dist/server/modules/debug-target/debug-target-service.js.map +1 -1
  81. package/dist/server/modules/git/git-command-helper-client.d.ts +3 -0
  82. package/dist/server/modules/git/git-command-helper-client.js +71 -29
  83. package/dist/server/modules/git/git-command-helper-client.js.map +1 -1
  84. package/dist/server/modules/git/git-command-helper-process.js +62 -9
  85. package/dist/server/modules/git/git-command-helper-process.js.map +1 -1
  86. package/dist/server/modules/git/git-command-runner.d.ts +1 -0
  87. package/dist/server/modules/git/git-command-runner.js +44 -1
  88. package/dist/server/modules/git/git-command-runner.js.map +1 -1
  89. package/dist/server/modules/git/git-controller.js +8 -7
  90. package/dist/server/modules/git/git-controller.js.map +1 -1
  91. package/dist/server/modules/git/git-read-service.d.ts +7 -7
  92. package/dist/server/modules/git/git-read-service.js +41 -24
  93. package/dist/server/modules/git/git-read-service.js.map +1 -1
  94. package/dist/server/modules/model-switch/cc-switch-adapter.js +6 -2
  95. package/dist/server/modules/model-switch/cc-switch-adapter.js.map +1 -1
  96. package/dist/server/modules/preferences/profile-service.d.ts +3 -1
  97. package/dist/server/modules/preferences/profile-service.js +74 -3
  98. package/dist/server/modules/preferences/profile-service.js.map +1 -1
  99. package/dist/server/modules/provider/codex-model-options.js +2 -3
  100. package/dist/server/modules/provider/codex-model-options.js.map +1 -1
  101. package/dist/server/modules/provider/opencode-model-options.js +2 -3
  102. package/dist/server/modules/provider/opencode-model-options.js.map +1 -1
  103. package/dist/server/modules/provider/provider-discovery-helper-client.d.ts +14 -7
  104. package/dist/server/modules/provider/provider-discovery-helper-client.js +208 -46
  105. package/dist/server/modules/provider/provider-discovery-helper-client.js.map +1 -1
  106. package/dist/server/modules/provider/provider-discovery-helper-process.js +96 -47
  107. package/dist/server/modules/provider/provider-discovery-helper-process.js.map +1 -1
  108. package/dist/server/modules/provider/provider-discovery-runtime.d.ts +4 -0
  109. package/dist/server/modules/provider/provider-discovery-runtime.js +145 -0
  110. package/dist/server/modules/provider/provider-discovery-runtime.js.map +1 -0
  111. package/dist/server/modules/sessions/claude-runtime-helper-client.js +23 -1
  112. package/dist/server/modules/sessions/claude-runtime-helper-client.js.map +1 -1
  113. package/dist/server/modules/sessions/session-history-service.d.ts +12 -3
  114. package/dist/server/modules/sessions/session-history-service.js +465 -67
  115. package/dist/server/modules/sessions/session-history-service.js.map +1 -1
  116. package/dist/server/modules/sessions/session-live-runtime-service.d.ts +8 -0
  117. package/dist/server/modules/sessions/session-live-runtime-service.js +164 -34
  118. package/dist/server/modules/sessions/session-live-runtime-service.js.map +1 -1
  119. package/dist/server/modules/sessions/session-message-origin-utils.d.ts +12 -0
  120. package/dist/server/modules/sessions/session-message-origin-utils.js +45 -0
  121. package/dist/server/modules/sessions/session-message-origin-utils.js.map +1 -0
  122. package/dist/server/modules/sessions/session-permission-request-service.js +167 -0
  123. package/dist/server/modules/sessions/session-permission-request-service.js.map +1 -1
  124. package/dist/server/modules/skills/builtin-skill-service.d.ts +12 -0
  125. package/dist/server/modules/skills/builtin-skill-service.js +49 -0
  126. package/dist/server/modules/skills/builtin-skill-service.js.map +1 -0
  127. package/dist/server/modules/skills/builtin-skills/codingns-assistant/SKILL.md +82 -0
  128. package/dist/server/modules/skills/builtin-skills/codingns-assistant/agents/openai.yaml +4 -0
  129. package/dist/server/modules/skills/builtin-skills/codingns-assistant/references/cli-workflow.md +136 -0
  130. package/dist/server/modules/skills/skill-manager-service.d.ts +7 -0
  131. package/dist/server/modules/skills/skill-manager-service.js +98 -0
  132. package/dist/server/modules/skills/skill-manager-service.js.map +1 -1
  133. package/dist/server/modules/tailscale/tailscale-helper-client.d.ts +1 -0
  134. package/dist/server/modules/tailscale/tailscale-helper-client.js +12 -0
  135. package/dist/server/modules/tailscale/tailscale-helper-client.js.map +1 -1
  136. package/dist/server/modules/tasks/task-helper-client.d.ts +10 -2
  137. package/dist/server/modules/tasks/task-helper-client.js +152 -27
  138. package/dist/server/modules/tasks/task-helper-client.js.map +1 -1
  139. package/dist/server/modules/tasks/task-helper-process-handlers.d.ts +10 -3
  140. package/dist/server/modules/tasks/task-helper-process-handlers.js +7 -5
  141. package/dist/server/modules/tasks/task-helper-process-handlers.js.map +1 -1
  142. package/dist/server/modules/tasks/task-helper-process.js +104 -3
  143. package/dist/server/modules/tasks/task-helper-process.js.map +1 -1
  144. package/dist/server/modules/tasks/task-lane-executors.js +2 -2
  145. package/dist/server/modules/tasks/task-lane-executors.js.map +1 -1
  146. package/dist/server/modules/tasks/task-types.d.ts +4 -0
  147. package/dist/server/modules/tasks/task-types.js +5 -1
  148. package/dist/server/modules/tasks/task-types.js.map +1 -1
  149. package/dist/server/modules/terminal/command-template-service.d.ts +11 -2
  150. package/dist/server/modules/terminal/command-template-service.js +91 -9
  151. package/dist/server/modules/terminal/command-template-service.js.map +1 -1
  152. package/dist/server/modules/terminal/runtime/terminal-log-writer-client.js +1 -1
  153. package/dist/server/modules/terminal/runtime/terminal-log-writer-client.js.map +1 -1
  154. package/dist/server/modules/terminal/runtime/terminal-log-writer-process.js +160 -11
  155. package/dist/server/modules/terminal/runtime/terminal-log-writer-process.js.map +1 -1
  156. package/dist/server/modules/terminal/template-port-runtime.d.ts +1 -1
  157. package/dist/server/modules/terminal/template-port-runtime.js +87 -37
  158. package/dist/server/modules/terminal/template-port-runtime.js.map +1 -1
  159. package/dist/server/modules/terminal/terminal-controller.d.ts +3 -0
  160. package/dist/server/modules/terminal/terminal-controller.js +41 -0
  161. package/dist/server/modules/terminal/terminal-controller.js.map +1 -1
  162. package/dist/server/modules/terminal/terminal-service.d.ts +4 -0
  163. package/dist/server/modules/terminal/terminal-service.js +35 -1
  164. package/dist/server/modules/terminal/terminal-service.js.map +1 -1
  165. package/dist/server/modules/workbench/workbench-service.d.ts +3 -0
  166. package/dist/server/modules/workbench/workbench-service.js +7 -6
  167. package/dist/server/modules/workbench/workbench-service.js.map +1 -1
  168. package/dist/server/modules/workbench/workspace-file-watcher.d.ts +14 -6
  169. package/dist/server/modules/workbench/workspace-file-watcher.js +267 -57
  170. package/dist/server/modules/workbench/workspace-file-watcher.js.map +1 -1
  171. package/dist/server/modules/workbench/workspace-panel-snapshot-service.d.ts +3 -0
  172. package/dist/server/modules/workbench/workspace-panel-snapshot-service.js +149 -41
  173. package/dist/server/modules/workbench/workspace-panel-snapshot-service.js.map +1 -1
  174. package/dist/server/modules/workspace/workspace-code-composition.d.ts +1 -0
  175. package/dist/server/modules/workspace/workspace-code-composition.js +183 -1
  176. package/dist/server/modules/workspace/workspace-code-composition.js.map +1 -1
  177. package/dist/server/modules/workspace/workspace-service.js +54 -17
  178. package/dist/server/modules/workspace/workspace-service.js.map +1 -1
  179. package/dist/server/modules/worktree/worktree-cleanup-service.d.ts +1 -1
  180. package/dist/server/modules/worktree/worktree-cleanup-service.js +22 -17
  181. package/dist/server/modules/worktree/worktree-cleanup-service.js.map +1 -1
  182. package/dist/server/modules/worktree/worktree-controller.js +6 -5
  183. package/dist/server/modules/worktree/worktree-controller.js.map +1 -1
  184. package/dist/server/modules/worktree/worktree-manager.d.ts +10 -2
  185. package/dist/server/modules/worktree/worktree-manager.js +35 -20
  186. package/dist/server/modules/worktree/worktree-manager.js.map +1 -1
  187. package/dist/server/modules/worktree/worktree-merge-service.d.ts +2 -2
  188. package/dist/server/modules/worktree/worktree-merge-service.js +34 -27
  189. package/dist/server/modules/worktree/worktree-merge-service.js.map +1 -1
  190. package/dist/server/modules/worktree/worktree-sync-service.d.ts +1 -1
  191. package/dist/server/modules/worktree/worktree-sync-service.js +5 -3
  192. package/dist/server/modules/worktree/worktree-sync-service.js.map +1 -1
  193. package/dist/server/routes/assistant.js +43 -0
  194. package/dist/server/routes/assistant.js.map +1 -1
  195. package/dist/server/routes/butler.js +5 -0
  196. package/dist/server/routes/butler.js.map +1 -1
  197. package/dist/server/server/create-server.d.ts +8 -0
  198. package/dist/server/server/create-server.js +51 -13
  199. package/dist/server/server/create-server.js.map +1 -1
  200. package/dist/server/shared/http/request-abort.d.ts +2 -0
  201. package/dist/server/shared/http/request-abort.js +38 -0
  202. package/dist/server/shared/http/request-abort.js.map +1 -0
  203. package/dist/server/storage/repositories/assistant-automation-run-repository.d.ts +12 -0
  204. package/dist/server/storage/repositories/assistant-automation-run-repository.js +139 -0
  205. package/dist/server/storage/repositories/assistant-automation-run-repository.js.map +1 -0
  206. package/dist/server/storage/repositories/assistant-automation-task-repository.d.ts +15 -0
  207. package/dist/server/storage/repositories/assistant-automation-task-repository.js +173 -0
  208. package/dist/server/storage/repositories/assistant-automation-task-repository.js.map +1 -0
  209. package/dist/server/storage/repositories/assistant-sandbox-workspace-repository.d.ts +17 -0
  210. package/dist/server/storage/repositories/assistant-sandbox-workspace-repository.js +164 -0
  211. package/dist/server/storage/repositories/assistant-sandbox-workspace-repository.js.map +1 -0
  212. package/dist/server/storage/repositories/butler-control-session-repository.js +27 -3
  213. package/dist/server/storage/repositories/butler-control-session-repository.js.map +1 -1
  214. package/dist/server/storage/repositories/butler-control-timer-repository.d.ts +15 -0
  215. package/dist/server/storage/repositories/butler-control-timer-repository.js +157 -0
  216. package/dist/server/storage/repositories/butler-control-timer-repository.js.map +1 -0
  217. package/dist/server/storage/repositories/user-preference-profile-repository.js +6 -3
  218. package/dist/server/storage/repositories/user-preference-profile-repository.js.map +1 -1
  219. package/dist/server/storage/sqlite/client.js +239 -2
  220. package/dist/server/storage/sqlite/client.js.map +1 -1
  221. package/dist/server/storage/sqlite/schema.sql +107 -1
  222. package/dist/server/types/domain.d.ts +89 -2
  223. package/dist/server/ws/workbench-ws-hub.d.ts +14 -7
  224. package/dist/server/ws/workbench-ws-hub.js +316 -158
  225. package/dist/server/ws/workbench-ws-hub.js.map +1 -1
  226. package/node_modules/@codingns/session-sync-core/dist/providers/claude-code.d.ts +4 -1
  227. package/node_modules/@codingns/session-sync-core/dist/providers/claude-code.js +111 -3
  228. package/node_modules/@codingns/session-sync-core/dist/providers/claude-code.js.map +1 -1
  229. package/node_modules/@codingns/session-sync-core/dist/providers/codex.d.ts +6 -1
  230. package/node_modules/@codingns/session-sync-core/dist/providers/codex.js +306 -31
  231. package/node_modules/@codingns/session-sync-core/dist/providers/codex.js.map +1 -1
  232. package/node_modules/@codingns/session-sync-core/dist/providers/gemini.d.ts +5 -1
  233. package/node_modules/@codingns/session-sync-core/dist/providers/gemini.js +187 -26
  234. package/node_modules/@codingns/session-sync-core/dist/providers/gemini.js.map +1 -1
  235. package/node_modules/@codingns/session-sync-core/dist/providers/kimi.d.ts +4 -1
  236. package/node_modules/@codingns/session-sync-core/dist/providers/kimi.js +98 -1
  237. package/node_modules/@codingns/session-sync-core/dist/providers/kimi.js.map +1 -1
  238. package/node_modules/@codingns/session-sync-core/dist/providers/opencode.d.ts +2 -0
  239. package/node_modules/@codingns/session-sync-core/dist/providers/opencode.js +71 -8
  240. package/node_modules/@codingns/session-sync-core/dist/providers/opencode.js.map +1 -1
  241. package/node_modules/@codingns/session-sync-core/dist/providers/utils.d.ts +1 -0
  242. package/node_modules/@codingns/session-sync-core/dist/providers/utils.js +4 -1
  243. package/node_modules/@codingns/session-sync-core/dist/providers/utils.js.map +1 -1
  244. package/node_modules/@codingns/session-sync-core/dist/runtime/claude-runtime.js +44 -0
  245. package/node_modules/@codingns/session-sync-core/dist/runtime/claude-runtime.js.map +1 -1
  246. package/node_modules/@codingns/session-sync-core/dist/runtime/codex-runtime.js +9 -3
  247. package/node_modules/@codingns/session-sync-core/dist/runtime/codex-runtime.js.map +1 -1
  248. package/node_modules/@codingns/session-sync-core/dist/runtime/types.d.ts +1 -0
  249. package/node_modules/@codingns/session-sync-core/dist/services.js +17 -8
  250. package/node_modules/@codingns/session-sync-core/dist/services.js.map +1 -1
  251. package/node_modules/@codingns/session-sync-core/dist/types.d.ts +4 -0
  252. package/package.json +1 -1
  253. package/scripts/postinstall.mjs +33 -0
  254. package/dist/public/assets/index-Cek6u0b9.css +0 -1
  255. package/dist/public/assets/index-THHY79si.js +0 -122
@@ -2,7 +2,7 @@ import { existsSync, readdirSync } from "node:fs";
2
2
  import path from "node:path";
3
3
  import { performance } from "node:perf_hooks";
4
4
  import { ClaudeRuntimeAdapter, CodexRuntimeAdapter, GeminiRuntimeAdapter, KimiRuntimeAdapter, OpenCodeRuntimeAdapter, ProviderRuntimeService } from "@codingns/session-sync-core";
5
- import { AppError } from "../../shared/errors/app-error.js";
5
+ import { AppError, isAppError } from "../../shared/errors/app-error.js";
6
6
  import { createId } from "../../shared/utils/id.js";
7
7
  import { isPerfDebugEnabled, logPerformance } from "../../shared/utils/perf-log.js";
8
8
  import { logPermissionDebug } from "../../shared/utils/permission-debug-log.js";
@@ -33,6 +33,7 @@ export class SessionLiveRuntimeService {
33
33
  externalRuntimeSnapshots = new Map();
34
34
  runtimeListeners = new Map();
35
35
  terminalStateListeners = new Set();
36
+ deadRuntimeReconciliationSessions = new Set();
36
37
  runtimeMessageSeenSessions = new Set();
37
38
  runtimeHistoryFallbackSentSessions = new Set();
38
39
  queueDispatchSessions = new Set();
@@ -78,6 +79,7 @@ export class SessionLiveRuntimeService {
78
79
  this.ensurePendingSessionBinding(sessionId, workspace.id, input.provider);
79
80
  const persistedAttachments = this.persistMessageAttachments(sessionId, input.clientRequestId, input.runtimeOptions?.attachments ?? []);
80
81
  const providerPrompt = this.sessionMessageAttachmentService.buildProviderPrompt(input.provider, input.content, persistedAttachments.runtimeAttachments);
82
+ const providerInstructionFilePath = resolveRuntimeInstructionFilePath(input.provider, workspace.path, input.runtimeOptions?.providerInstructionFilePath ?? null);
81
83
  this.ensureCapability(capabilities.canStartSession, "provider", "provider 不支持 start-live");
82
84
  this.ensureCapability(capabilities.canSendMessage, "provider", "provider 不支持实时对话");
83
85
  const launchRuntimeStartedAtMs = performance.now();
@@ -96,6 +98,7 @@ export class SessionLiveRuntimeService {
96
98
  reasoningLevel: input.runtimeOptions?.reasoningLevel ?? null,
97
99
  permissionMode: input.runtimeOptions?.permissionMode ?? null,
98
100
  providerPrompt,
101
+ providerInstructionFilePath,
99
102
  attachments: persistedAttachments.runtimeAttachments
100
103
  }
101
104
  }, "start");
@@ -145,7 +148,18 @@ export class SessionLiveRuntimeService {
145
148
  }
146
149
  const acceptedAt = acceptedMessage?.timestamp ?? nowIso();
147
150
  const boundAttachments = this.sessionMessageAttachmentService.bindClientRequestToMessage(sessionId, input.clientRequestId, acceptedMessage?.messageId ?? null);
148
- const session = this.sessionHistoryService.getSession(sessionId, input.userId);
151
+ const session = this.resolveStartedSession({
152
+ sessionId,
153
+ workspaceId: workspace.id,
154
+ userId: input.userId,
155
+ provider: input.provider,
156
+ parentSessionId: input.parentSessionId ?? null,
157
+ sessionKind: input.sessionKind ?? "default",
158
+ annotationSourceMessageId: input.annotationSourceMessageId ?? null,
159
+ annotationSourceText: input.annotationSourceText ?? null,
160
+ initialContent: input.content,
161
+ handle
162
+ });
149
163
  this.markSendDebugResponseReady(debugTrace, {
150
164
  returnedAcceptedMessage: Boolean(acceptedMessage),
151
165
  returnedSyntheticUser: !acceptedMessage,
@@ -228,7 +242,7 @@ export class SessionLiveRuntimeService {
228
242
  });
229
243
  }
230
244
  const runtimeSessionId = this.resolveRuntimeSessionId(sessionId);
231
- const runtimeSnapshot = this.providerRuntimeService.getSnapshot(runtimeSessionId);
245
+ const runtimeSnapshot = this.getLiveRuntimeSnapshot(runtimeSessionId);
232
246
  if (!runtimeSnapshot || !isActiveRuntimeState(runtimeSnapshot.runningState)) {
233
247
  throw new AppError({
234
248
  statusCode: 409,
@@ -428,7 +442,7 @@ export class SessionLiveRuntimeService {
428
442
  }
429
443
  async getSessionRuntime(sessionId, userId) {
430
444
  const runtimeSessionId = this.resolveRuntimeSessionId(sessionId);
431
- const runtimeSnapshot = this.providerRuntimeService.getSnapshot(runtimeSessionId);
445
+ const runtimeSnapshot = this.getLiveRuntimeSnapshot(runtimeSessionId);
432
446
  const externalRuntimeSnapshot = this.externalRuntimeSnapshots.get(runtimeSessionId) ?? null;
433
447
  const runtimeHasActiveRun = runtimeSnapshot ? isActiveRuntimeState(runtimeSnapshot.runningState) : false;
434
448
  const externalHasActiveRun = externalRuntimeSnapshot
@@ -518,7 +532,7 @@ export class SessionLiveRuntimeService {
518
532
  }
519
533
  resolveLiveActivityObservation(sessionId) {
520
534
  const runtimeSessionId = this.resolveRuntimeSessionId(sessionId);
521
- const runtimeSnapshot = this.providerRuntimeService.getSnapshot(runtimeSessionId);
535
+ const runtimeSnapshot = this.getLiveRuntimeSnapshot(runtimeSessionId);
522
536
  if (runtimeSnapshot) {
523
537
  return createRuntimeActivityObservation(runtimeSessionId, runtimeSnapshot);
524
538
  }
@@ -531,7 +545,7 @@ export class SessionLiveRuntimeService {
531
545
  async interruptSession(sessionId, userId) {
532
546
  this.sessionHistoryService.getSession(sessionId, userId);
533
547
  const runtimeSessionId = this.resolveRuntimeSessionId(sessionId);
534
- const runtime = this.providerRuntimeService.getSnapshot(runtimeSessionId);
548
+ const runtime = this.getLiveRuntimeSnapshot(runtimeSessionId);
535
549
  if (!runtime || (runtime.runningState !== "running" && runtime.runningState !== "starting")) {
536
550
  throw new AppError({
537
551
  statusCode: 409,
@@ -573,7 +587,7 @@ export class SessionLiveRuntimeService {
573
587
  }
574
588
  subscribeRuntime(sessionId, onEnvelope) {
575
589
  const runtimeSessionId = this.resolveRuntimeSessionId(sessionId);
576
- const runtimeSnapshot = this.providerRuntimeService.getSnapshot(runtimeSessionId);
590
+ const runtimeSnapshot = this.getLiveRuntimeSnapshot(runtimeSessionId);
577
591
  const externalRuntimeSnapshot = this.externalRuntimeSnapshots.get(runtimeSessionId) ?? null;
578
592
  const initialActivityEnvelope = this.buildSessionActivityEnvelope(sessionId, runtimeSessionId);
579
593
  if (runtimeSnapshot) {
@@ -674,8 +688,74 @@ export class SessionLiveRuntimeService {
674
688
  await listener(envelope);
675
689
  }));
676
690
  }
691
+ getLiveRuntimeSnapshot(sessionId) {
692
+ const snapshot = this.providerRuntimeService.getSnapshot(sessionId);
693
+ if (!snapshot) {
694
+ return null;
695
+ }
696
+ if (!isActiveRuntimeState(snapshot.runningState)) {
697
+ return snapshot;
698
+ }
699
+ if (this.providerRuntimeService.isRunHealthy(sessionId) === false) {
700
+ this.demoteDeadRuntimeSnapshot(snapshot);
701
+ this.scheduleDeadRuntimeReconciliation(snapshot);
702
+ return null;
703
+ }
704
+ return snapshot;
705
+ }
706
+ demoteDeadRuntimeSnapshot(snapshot) {
707
+ const updatedAt = nowIso();
708
+ for (const userId of this.authUserRepository.listIds()) {
709
+ const current = this.sessionStateRepository.findBySessionAndUser(snapshot.sessionId, userId);
710
+ if (!current || !isPendingSessionRunningState(current.runningState) || current.activitySource !== "runtime") {
711
+ continue;
712
+ }
713
+ this.sessionStateRepository.upsert({
714
+ ...current,
715
+ runningState: "interrupted",
716
+ activitySource: "runtime",
717
+ completedAt: updatedAt,
718
+ updatedAt
719
+ });
720
+ }
721
+ this.sessionActivityAuthorityService.observe({
722
+ sessionId: snapshot.sessionId,
723
+ runId: buildRuntimeRunId(snapshot.sessionId, snapshot.startedAt),
724
+ runningState: "interrupted",
725
+ source: "authoritative_runtime",
726
+ confidence: "strong",
727
+ detail: "Host 检测到这轮运行已经异常结束,已自动回收残留运行态",
728
+ interruptSource: "runtime",
729
+ errorCode: null,
730
+ observedAt: updatedAt
731
+ });
732
+ }
733
+ scheduleDeadRuntimeReconciliation(snapshot) {
734
+ if (this.deadRuntimeReconciliationSessions.has(snapshot.sessionId)) {
735
+ return;
736
+ }
737
+ this.deadRuntimeReconciliationSessions.add(snapshot.sessionId);
738
+ void this.reconcileDeadRuntimeSession(snapshot).finally(() => {
739
+ this.deadRuntimeReconciliationSessions.delete(snapshot.sessionId);
740
+ });
741
+ }
742
+ async reconcileDeadRuntimeSession(snapshot) {
743
+ await this.providerRuntimeService.abandonRun(snapshot.sessionId).catch(() => {
744
+ return;
745
+ });
746
+ for (const userId of this.authUserRepository.listIds()) {
747
+ await this.sessionHistoryService.refreshRuntimeFallbackSession(snapshot.sessionId, userId).catch(() => {
748
+ return;
749
+ });
750
+ }
751
+ const envelope = this.buildSessionActivityEnvelope(snapshot.sessionId, snapshot.sessionId);
752
+ if (envelope) {
753
+ await this.emitExternalRuntimeEnvelope(envelope);
754
+ }
755
+ void this.dispatchNextQueuedMessage(snapshot.sessionId);
756
+ }
677
757
  buildSessionActivityEnvelope(sessionId, runtimeSessionId = sessionId) {
678
- const runtimeSnapshot = this.providerRuntimeService.getSnapshot(runtimeSessionId);
758
+ const runtimeSnapshot = this.getLiveRuntimeSnapshot(runtimeSessionId);
679
759
  if (runtimeSnapshot) {
680
760
  const resolution = this.sessionActivityAuthorityService.observe(createRuntimeActivityObservation(runtimeSessionId, runtimeSnapshot));
681
761
  return {
@@ -957,6 +1037,7 @@ export class SessionLiveRuntimeService {
957
1037
  const resolvedAttachments = persistedAttachments
958
1038
  ?? this.persistMessageAttachments(input.sessionId, input.clientRequestId, input.runtimeOptions?.attachments ?? []);
959
1039
  const providerPrompt = this.sessionMessageAttachmentService.buildProviderPrompt(session.provider, input.content, resolvedAttachments.runtimeAttachments);
1040
+ const providerInstructionFilePath = resolveRuntimeInstructionFilePath(session.provider, workspace.path, input.runtimeOptions?.providerInstructionFilePath ?? null);
960
1041
  this.ensureCapability(capabilities.canSendMessage, "sessionId", "provider 不支持实时对话");
961
1042
  const runtimeRequest = {
962
1043
  sessionId: input.sessionId,
@@ -973,11 +1054,12 @@ export class SessionLiveRuntimeService {
973
1054
  reasoningLevel: input.runtimeOptions?.reasoningLevel ?? null,
974
1055
  permissionMode: input.runtimeOptions?.permissionMode ?? null,
975
1056
  providerPrompt,
1057
+ providerInstructionFilePath,
976
1058
  attachments: resolvedAttachments.runtimeAttachments
977
1059
  }
978
1060
  };
979
1061
  const runtimeSessionId = this.resolveRuntimeSessionId(input.sessionId);
980
- const activeRun = this.providerRuntimeService.getSnapshot(runtimeSessionId);
1062
+ const activeRun = this.getLiveRuntimeSnapshot(runtimeSessionId);
981
1063
  const externalRuntimeSnapshot = this.externalRuntimeSnapshots.get(runtimeSessionId);
982
1064
  if (activeRun &&
983
1065
  activeRun.provider === "claude-code" &&
@@ -1020,6 +1102,7 @@ export class SessionLiveRuntimeService {
1020
1102
  matched: Boolean(acceptedMessage)
1021
1103
  });
1022
1104
  const acceptedAt = acceptedMessage?.timestamp ?? nowIso();
1105
+ this.sessionHistoryService.resolveMessageOriginByClientRequestId(input.sessionId, input.clientRequestId, acceptedMessage?.messageId ?? null, acceptedAt);
1023
1106
  const boundAttachments = this.sessionMessageAttachmentService.bindClientRequestToMessage(input.sessionId, input.clientRequestId, acceptedMessage?.messageId ?? null);
1024
1107
  this.refreshSyntheticSessionTitle(session, input.content, input.userId);
1025
1108
  this.markSendDebugResponseReady(debugTrace, {
@@ -1056,7 +1139,7 @@ export class SessionLiveRuntimeService {
1056
1139
  }
1057
1140
  this.queueDispatchSessions.add(sessionId);
1058
1141
  try {
1059
- const runtimeSnapshot = this.providerRuntimeService.getSnapshot(sessionId);
1142
+ const runtimeSnapshot = this.getLiveRuntimeSnapshot(sessionId);
1060
1143
  const externalRuntimeSnapshot = this.externalRuntimeSnapshots.get(sessionId);
1061
1144
  if ((runtimeSnapshot && isActiveRuntimeState(runtimeSnapshot.runningState))
1062
1145
  || (externalRuntimeSnapshot && isActiveRuntimeState(externalRuntimeSnapshot.runningState))) {
@@ -1119,7 +1202,7 @@ export class SessionLiveRuntimeService {
1119
1202
  void this.dispatchNextQueuedMessage(session.sessionId);
1120
1203
  }
1121
1204
  shouldBlockQueueDispatch(session) {
1122
- const runtimeSnapshot = this.providerRuntimeService.getSnapshot(session.sessionId);
1205
+ const runtimeSnapshot = this.getLiveRuntimeSnapshot(session.sessionId);
1123
1206
  if (runtimeSnapshot && isActiveRuntimeState(runtimeSnapshot.runningState)) {
1124
1207
  return true;
1125
1208
  }
@@ -1159,7 +1242,7 @@ export class SessionLiveRuntimeService {
1159
1242
  || !isPendingSessionRunningState(session.runningState)) {
1160
1243
  return session;
1161
1244
  }
1162
- const runtimeSnapshot = this.providerRuntimeService.getSnapshot(sessionId);
1245
+ const runtimeSnapshot = this.getLiveRuntimeSnapshot(sessionId);
1163
1246
  const externalRuntimeSnapshot = this.externalRuntimeSnapshots.get(sessionId);
1164
1247
  if ((runtimeSnapshot && isActiveRuntimeState(runtimeSnapshot.runningState))
1165
1248
  || (externalRuntimeSnapshot && isActiveRuntimeState(externalRuntimeSnapshot.runningState))) {
@@ -1185,42 +1268,71 @@ export class SessionLiveRuntimeService {
1185
1268
  });
1186
1269
  }
1187
1270
  createRuntimeBackedSession(input) {
1271
+ this.upsertRuntimeBackedSessionRecords(input);
1272
+ }
1273
+ resolveStartedSession(input) {
1274
+ try {
1275
+ return this.sessionHistoryService.getSession(input.sessionId, input.userId);
1276
+ }
1277
+ catch (error) {
1278
+ if (!isRepairableStartedSessionLookupError(error)) {
1279
+ throw error;
1280
+ }
1281
+ this.upsertRuntimeBackedSessionRecords({
1282
+ sessionId: input.sessionId,
1283
+ workspaceId: input.workspaceId,
1284
+ userId: input.userId,
1285
+ provider: input.provider,
1286
+ parentSessionId: input.parentSessionId,
1287
+ sessionKind: input.sessionKind,
1288
+ annotationSourceMessageId: input.annotationSourceMessageId,
1289
+ annotationSourceText: input.annotationSourceText,
1290
+ initialContent: input.initialContent,
1291
+ snapshot: input.handle.getSnapshot()
1292
+ });
1293
+ return this.sessionHistoryService.getSession(input.sessionId, input.userId);
1294
+ }
1295
+ }
1296
+ upsertRuntimeBackedSessionRecords(input) {
1188
1297
  const timestamp = nowIso();
1298
+ const currentIndex = this.sessionIndexRepository.findIndexRecordBySessionId(input.sessionId);
1299
+ const currentState = this.sessionStateRepository.findBySessionAndUser(input.sessionId, input.userId);
1300
+ const currentSnapshot = this.sessionStatusSnapshotRepository.findBySessionId(input.sessionId);
1189
1301
  this.sessionHistoryService.persistSessionBinding(input.sessionId, input.workspaceId, this.buildBindingSnapshot(input.sessionId, input.snapshot.provider, input.snapshot.providerSessionId, input.snapshot.rawStoreRef));
1190
1302
  this.sessionIndexRepository.upsert({
1191
1303
  sessionId: input.sessionId,
1192
1304
  workspaceId: input.workspaceId,
1193
1305
  provider: input.provider,
1194
- parentSessionId: input.parentSessionId,
1195
- sessionKind: input.sessionKind,
1196
- annotationSourceMessageId: input.annotationSourceMessageId,
1197
- annotationSourceText: input.annotationSourceText,
1198
- isSubagent: false,
1199
- subagentLabel: null,
1200
- title: buildSessionTitle(input.initialContent),
1201
- messageCount: 0,
1202
- isArchived: false,
1203
- lastMessageAt: input.snapshot.lastEventAt,
1204
- createdAt: timestamp,
1306
+ parentSessionId: currentIndex?.parentSessionId ?? input.parentSessionId,
1307
+ sessionKind: currentIndex?.sessionKind ?? input.sessionKind,
1308
+ annotationSourceMessageId: currentIndex?.annotationSourceMessageId ?? input.annotationSourceMessageId,
1309
+ annotationSourceText: currentIndex?.annotationSourceText ?? input.annotationSourceText,
1310
+ isSubagent: currentIndex?.isSubagent ?? false,
1311
+ subagentLabel: currentIndex?.subagentLabel ?? null,
1312
+ title: currentIndex?.title?.trim() || buildSessionTitle(input.initialContent),
1313
+ messageCount: currentIndex?.messageCount ?? 0,
1314
+ isArchived: currentIndex?.isArchived ?? false,
1315
+ lastMessageAt: currentIndex?.lastMessageAt ?? input.snapshot.lastEventAt,
1316
+ createdAt: currentIndex?.createdAt ?? timestamp,
1205
1317
  updatedAt: timestamp
1206
1318
  });
1207
1319
  this.upsertSnapshot(input.sessionId, {
1208
- syncStatus: "idle",
1209
- syncCursor: null,
1210
- lastSyncAt: input.snapshot.lastEventAt ?? timestamp,
1211
- lastErrorCode: null,
1212
- lastErrorDetail: null,
1213
- resumedAt: null
1320
+ syncStatus: currentSnapshot?.syncStatus ?? "idle",
1321
+ syncCursor: currentSnapshot?.syncCursor ?? null,
1322
+ lastSyncAt: currentSnapshot?.lastSyncAt ?? input.snapshot.lastEventAt ?? timestamp,
1323
+ lastErrorCode: currentSnapshot?.lastErrorCode ?? null,
1324
+ lastErrorDetail: currentSnapshot?.lastErrorDetail ?? null,
1325
+ resumedAt: currentSnapshot?.resumedAt ?? null
1214
1326
  });
1215
1327
  this.sessionStateRepository.upsert({
1216
1328
  sessionId: input.sessionId,
1217
1329
  userId: input.userId,
1218
1330
  runningState: toStoredRunningState(input.snapshot.runningState),
1219
1331
  activitySource: "runtime",
1220
- favorite: false,
1221
- lastEventAt: input.snapshot.lastEventAt,
1222
- completedAt: input.snapshot.completedAt,
1223
- lastSeenAt: null,
1332
+ favorite: currentState?.favorite ?? false,
1333
+ lastEventAt: input.snapshot.lastEventAt ?? currentState?.lastEventAt ?? null,
1334
+ completedAt: input.snapshot.completedAt ?? currentState?.completedAt ?? null,
1335
+ lastSeenAt: currentState?.lastSeenAt ?? null,
1224
1336
  updatedAt: timestamp
1225
1337
  });
1226
1338
  this.sessionActivityAuthorityService.observe(createRuntimeActivityObservation(input.sessionId, input.snapshot));
@@ -1628,7 +1740,7 @@ export class SessionLiveRuntimeService {
1628
1740
  });
1629
1741
  }
1630
1742
  shouldIgnoreClaudeExternalRuntimeUpdate(sessionId) {
1631
- const runtimeSnapshot = this.providerRuntimeService.getSnapshot(sessionId);
1743
+ const runtimeSnapshot = this.getLiveRuntimeSnapshot(sessionId);
1632
1744
  return Boolean(runtimeSnapshot &&
1633
1745
  runtimeSnapshot.provider === "claude-code" &&
1634
1746
  isActiveRuntimeState(runtimeSnapshot.runningState));
@@ -1948,6 +2060,10 @@ function isGeminiPendingRuntimeAliasBinding(value, targetSessionId) {
1948
2060
  function shouldAwaitAcceptedUserMessage(provider) {
1949
2061
  return provider !== "gemini";
1950
2062
  }
2063
+ function isRepairableStartedSessionLookupError(error) {
2064
+ return isAppError(error)
2065
+ && (error.errorCode === "SESSION_INDEX_MISSING" || error.errorCode === "SESSION_NOT_FOUND");
2066
+ }
1951
2067
  function shouldAwaitStartBindingBeforeAcceptedUserLookup(provider) {
1952
2068
  return provider === "kimi";
1953
2069
  }
@@ -2012,6 +2128,20 @@ function createProviderRuntimeAdapters(config, options = {}) {
2012
2128
  disposables
2013
2129
  };
2014
2130
  }
2131
+ function resolveRuntimeInstructionFilePath(provider, workspacePath, explicitFilePath) {
2132
+ const normalizedExplicit = explicitFilePath?.trim();
2133
+ if (normalizedExplicit) {
2134
+ const resolvedExplicit = path.resolve(normalizedExplicit);
2135
+ return existsSync(resolvedExplicit) ? resolvedExplicit : null;
2136
+ }
2137
+ if (provider !== "claude-code") {
2138
+ return null;
2139
+ }
2140
+ const defaultClaudeInstructionPath = path.join(workspacePath, "CLAUDE.md");
2141
+ return existsSync(defaultClaudeInstructionPath)
2142
+ ? path.resolve(defaultClaudeInstructionPath)
2143
+ : null;
2144
+ }
2015
2145
  function buildClaudeHookBridgeConfig(config) {
2016
2146
  const bridgeUrl = `http://127.0.0.1:${config.port}/api/providers/claude-code/hook-bridge/events`;
2017
2147
  const scriptPath = resolveClaudeHookBridgeScriptPath();