@jingyi0605/codingns 1.0.0-beta.1 → 1.0.0-beta.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 (105) hide show
  1. package/dist/public/assets/AdaptiveButlerPage-BHUAx_24.js +2 -0
  2. package/dist/public/assets/{App-CHsm-VrM.js → App-D5hc6KuU.js} +6 -6
  3. package/dist/public/assets/{BootstrapPage-Bp0KfySv.js → BootstrapPage-C2sMZMJa.js} +1 -1
  4. package/dist/public/assets/ConversationPage-CDpyEOUA.js +9 -0
  5. package/dist/public/assets/{DesktopDetachPreviewPage-DlDSb_tf.js → DesktopDetachPreviewPage-D9Abm5NU.js} +1 -1
  6. package/dist/public/assets/{DesktopModal-Csj5AdAN.js → DesktopModal-BCVZq_PQ.js} +1 -1
  7. package/dist/public/assets/{DesktopWindowPage-CacXiWjV.js → DesktopWindowPage-Cotl5fte.js} +1 -1
  8. package/dist/public/assets/{FileContextPanel-DzMUQvE5.js → FileContextPanel-DbPOq5w-.js} +1 -1
  9. package/dist/public/assets/{GitSidebar-C8IC18GH.js → GitSidebar-Cuxi2R93.js} +1 -1
  10. package/dist/public/assets/{MobileCreateSessionSheet-BtqR_hKc.js → MobileCreateSessionSheet-DYqarJqO.js} +1 -1
  11. package/dist/public/assets/{MobileSheet-Co-qPMBD.js → MobileSheet-DPYtp5Ze.js} +1 -1
  12. package/dist/public/assets/{PluginAccessOverview-D-KXkcyj.js → PluginAccessOverview-CiVzb_NI.js} +1 -1
  13. package/dist/public/assets/{PluginContainerPage-BKwCIs4r.js → PluginContainerPage-BfZ3E41c.js} +1 -1
  14. package/dist/public/assets/{PluginDetailPage-Djv_swcO.js → PluginDetailPage-DQQAg_ba.js} +1 -1
  15. package/dist/public/assets/{PluginsListPage-DAECNoN6.js → PluginsListPage-bF1NmA_r.js} +1 -1
  16. package/dist/public/assets/{PureConversationPage-DP1X7Hix.js → PureConversationPage-CWji-ARJ.js} +1 -1
  17. package/dist/public/assets/{RelayConnectEntryPage-xL_IPH8a.js → RelayConnectEntryPage-D4-3Fher.js} +1 -1
  18. package/dist/public/assets/{ServerSettingsModal-CyhMgk10.js → ServerSettingsModal-BUY1Y3g6.js} +1 -1
  19. package/dist/public/assets/{SessionIndexPage-CVEz50tc.js → SessionIndexPage-zVB9jnzP.js} +1 -1
  20. package/dist/public/assets/SettingsPage-DeqR2p7d.js +2 -0
  21. package/dist/public/assets/{TerminalManagerPanel-wVnoRA8u.js → TerminalManagerPanel-BjnC70ga.js} +1 -1
  22. package/dist/public/assets/{ToolFilesPage-BospXumK.js → ToolFilesPage-BZseQqvZ.js} +1 -1
  23. package/dist/public/assets/{ToolGitPage-B2zOeCAD.js → ToolGitPage-SrOO8Ftz.js} +1 -1
  24. package/dist/public/assets/{ToolProcessesPage-BDShao4b.js → ToolProcessesPage-Dbzlqjdy.js} +1 -1
  25. package/dist/public/assets/{ToolsHomePage-s4zH7D9M.js → ToolsHomePage-BBilUc0P.js} +1 -1
  26. package/dist/public/assets/{WorkbenchLandingPage-D51QCU_u.js → WorkbenchLandingPage-FdsBC8WN.js} +1 -1
  27. package/dist/public/assets/WorkbenchLayout-yGxGKcG1.js +1081 -0
  28. package/dist/public/assets/{WorkbenchModal-YsyEdJ_m.js → WorkbenchModal-Cm-ciXO9.js} +1 -1
  29. package/dist/public/assets/WorkbenchShellRoute-CijuAd9-.js +1 -0
  30. package/dist/public/assets/WorkbenchShellRoute-DpycFsbp.css +1 -0
  31. package/dist/public/assets/{WorkspaceDebugDetailPage-CMjNLqFq.js → WorkspaceDebugDetailPage-CZtpOiY0.js} +1 -1
  32. package/dist/public/assets/{WorkspaceDetailPage-CKxTbPKh.js → WorkspaceDetailPage-CbbgUz1H.js} +1 -1
  33. package/dist/public/assets/{WorkspaceHomePage-CEy4ShCu.js → WorkspaceHomePage-DMNJKAYe.js} +1 -1
  34. package/dist/public/assets/{client-runtime-manager-BFXU9DmS.js → client-runtime-manager-tsFkLtO_.js} +1 -1
  35. package/dist/public/assets/{host-alias-Zb2xyVrf.js → host-alias-df5bYDlE.js} +1 -1
  36. package/dist/public/assets/index-CILPuSCp.js +50 -0
  37. package/dist/public/assets/index-CSlwKnM4.css +1 -0
  38. package/dist/public/assets/{login-direct-candidate-resolver-DL8DS-Si.js → login-direct-candidate-resolver-pkfXrMJy.js} +1 -1
  39. package/dist/public/assets/peer-host-config-sync-nS_66OLg.js +1 -0
  40. package/dist/public/assets/{plugin-permission-copy-DrLk22m5.js → plugin-permission-copy-LDy-lW7h.js} +1 -1
  41. package/dist/public/assets/{plugins-api-COF4oh24.js → plugins-api-BGF9OybZ.js} +1 -1
  42. package/dist/public/assets/{preferences-service-CEWNV1w9.js → preferences-service-BC25oxA_.js} +1 -1
  43. package/dist/public/assets/{relay-entry-Cmc8vTlE.js → relay-entry-ErQKnI7B.js} +1 -1
  44. package/dist/public/assets/{useRegisteredDebugTemplates-FdmHG2S4.js → useRegisteredDebugTemplates-BTr3ATCZ.js} +1 -1
  45. package/dist/public/assets/{workbench-navigation-ED0157V-.js → workbench-navigation-hwM28xIb.js} +1 -1
  46. package/dist/public/index.html +2 -2
  47. package/dist/server/modules/client/client-controller.d.ts +1 -0
  48. package/dist/server/modules/client/client-controller.js +4 -0
  49. package/dist/server/modules/client/client-controller.js.map +1 -1
  50. package/dist/server/modules/client/client-service.d.ts +3 -0
  51. package/dist/server/modules/client/client-service.js +3 -0
  52. package/dist/server/modules/client/client-service.js.map +1 -1
  53. package/dist/server/modules/client/npm-global-package-service.js +32 -7
  54. package/dist/server/modules/client/npm-global-package-service.js.map +1 -1
  55. package/dist/server/modules/peer-host/host-ws-proxy-service.js +73 -12
  56. package/dist/server/modules/peer-host/host-ws-proxy-service.js.map +1 -1
  57. package/dist/server/modules/provider/provider-discovery-helper-client.d.ts +2 -0
  58. package/dist/server/modules/provider/provider-discovery-helper-client.js.map +1 -1
  59. package/dist/server/modules/provider/provider-discovery-helper-process.js +6 -3
  60. package/dist/server/modules/provider/provider-discovery-helper-process.js.map +1 -1
  61. package/dist/server/modules/provider/provider-discovery-runtime.js +4 -1
  62. package/dist/server/modules/provider/provider-discovery-runtime.js.map +1 -1
  63. package/dist/server/modules/sessions/session-history-service.d.ts +8 -0
  64. package/dist/server/modules/sessions/session-history-service.js +123 -5
  65. package/dist/server/modules/sessions/session-history-service.js.map +1 -1
  66. package/dist/server/modules/sessions/session-live-runtime-service.d.ts +13 -0
  67. package/dist/server/modules/sessions/session-live-runtime-service.js +354 -5
  68. package/dist/server/modules/sessions/session-live-runtime-service.js.map +1 -1
  69. package/dist/server/modules/sessions/session-permission-request-service.d.ts +16 -1
  70. package/dist/server/modules/sessions/session-permission-request-service.js +375 -9
  71. package/dist/server/modules/sessions/session-permission-request-service.js.map +1 -1
  72. package/dist/server/modules/sessions/workspace-session-runtime-context-service.js +10 -0
  73. package/dist/server/modules/sessions/workspace-session-runtime-context-service.js.map +1 -1
  74. package/dist/server/modules/tasks/task-helper-process-handlers.d.ts +1 -0
  75. package/dist/server/modules/tasks/task-helper-process-handlers.js +4 -1
  76. package/dist/server/modules/tasks/task-helper-process-handlers.js.map +1 -1
  77. package/dist/server/modules/workbench/workbench-service.js +7 -4
  78. package/dist/server/modules/workbench/workbench-service.js.map +1 -1
  79. package/dist/server/routes/client.js +1 -0
  80. package/dist/server/routes/client.js.map +1 -1
  81. package/dist/server/shared/utils/peer-host-proxy-log.d.ts +3 -0
  82. package/dist/server/shared/utils/peer-host-proxy-log.js +48 -0
  83. package/dist/server/shared/utils/peer-host-proxy-log.js.map +1 -0
  84. package/node_modules/@codingns/session-sync-core/dist/providers/claude-code.d.ts +2 -0
  85. package/node_modules/@codingns/session-sync-core/dist/providers/claude-code.js +93 -12
  86. package/node_modules/@codingns/session-sync-core/dist/providers/claude-code.js.map +1 -1
  87. package/node_modules/@codingns/session-sync-core/dist/providers/codex.d.ts +3 -0
  88. package/node_modules/@codingns/session-sync-core/dist/providers/codex.js +116 -2
  89. package/node_modules/@codingns/session-sync-core/dist/providers/codex.js.map +1 -1
  90. package/node_modules/@codingns/session-sync-core/dist/runtime/claude-runtime.d.ts +1 -0
  91. package/node_modules/@codingns/session-sync-core/dist/runtime/claude-runtime.js +19 -8
  92. package/node_modules/@codingns/session-sync-core/dist/runtime/claude-runtime.js.map +1 -1
  93. package/node_modules/@codingns/session-sync-core/dist/runtime/provider-runtime-service.d.ts +1 -0
  94. package/node_modules/@codingns/session-sync-core/dist/runtime/provider-runtime-service.js +30 -2
  95. package/node_modules/@codingns/session-sync-core/dist/runtime/provider-runtime-service.js.map +1 -1
  96. package/package.json +1 -1
  97. package/dist/public/assets/AdaptiveButlerPage-BYETYaIe.js +0 -2
  98. package/dist/public/assets/ConversationPage-BCrNml1k.js +0 -9
  99. package/dist/public/assets/SettingsPage-CQNCrgaj.js +0 -2
  100. package/dist/public/assets/WorkbenchLayout-Bo2BbMY6.js +0 -1081
  101. package/dist/public/assets/WorkbenchShellRoute-D3l4aWJS.js +0 -1
  102. package/dist/public/assets/WorkbenchShellRoute-D5fnyF8z.css +0 -1
  103. package/dist/public/assets/index-BilHJjYU.js +0 -50
  104. package/dist/public/assets/index-OR7OITpQ.css +0 -1
  105. package/dist/public/assets/peer-host-config-sync-d2ZcPC5P.js +0 -1
@@ -170,6 +170,13 @@ interface ClaudeHookEventPayload {
170
170
  session_id?: string;
171
171
  transcript_path?: string;
172
172
  cwd?: string;
173
+ path?: string;
174
+ file_path?: string;
175
+ worktree_path?: string;
176
+ config_path?: string;
177
+ rule_file?: string;
178
+ matcher?: string;
179
+ permission_mode?: string;
173
180
  reason?: string;
174
181
  stop_hook_active?: boolean;
175
182
  tool_name?: string;
@@ -177,6 +184,11 @@ interface ClaudeHookEventPayload {
177
184
  permission_suggestions?: unknown;
178
185
  title?: string;
179
186
  message?: string;
187
+ prompt?: string;
188
+ command_name?: string;
189
+ action?: string;
190
+ trigger?: string;
191
+ mcp_server_name?: string;
180
192
  notification_type?: string;
181
193
  }
182
194
  export declare class SessionLiveRuntimeService {
@@ -268,6 +280,7 @@ export declare class SessionLiveRuntimeService {
268
280
  private assertProviderBindingStableDuringActiveRun;
269
281
  private hasSessionProviderBindingChanged;
270
282
  private resolveCodexRuntimeRequestRawStoreRef;
283
+ private buildClaudeForkBootstrapDescriptor;
271
284
  private buildBindingSnapshot;
272
285
  private persistRuntimeEvent;
273
286
  private runRuntimeSqliteRead;
@@ -1,4 +1,4 @@
1
- import { existsSync, mkdirSync, writeFileSync } from "node:fs";
1
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } 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, LegnaRuntimeAdapter, OpenCodeRuntimeAdapter, ProviderRuntimeService } from "@codingns/session-sync-core";
@@ -449,6 +449,13 @@ export class SessionLiveRuntimeService {
449
449
  });
450
450
  return this.sessionPermissionRequestService.handleClaudePermissionRequest(resolvedPayload, provider);
451
451
  }
452
+ if (hookEventName === "Elicitation") {
453
+ logPermissionDebug("claude_hook_event.route", {
454
+ hookEventName,
455
+ route: "handleClaudeElicitation"
456
+ });
457
+ return this.sessionPermissionRequestService.handleClaudeElicitation(resolvedPayload, provider);
458
+ }
452
459
  const providerSessionId = normalizeRequiredText(resolvedPayload.session_id, "session_id");
453
460
  const workspacePath = normalizeRequiredText(resolvedPayload.cwd, "cwd");
454
461
  const workspace = this.workspaceService.findWorkspaceByPath(workspacePath);
@@ -1193,9 +1200,12 @@ export class SessionLiveRuntimeService {
1193
1200
  const runtimeRawStoreRef = runtimeMode === "start"
1194
1201
  ? syntheticForkRawStoreRef
1195
1202
  : await this.resolveCodexRuntimeRequestRawStoreRef(session, providerBinding);
1196
- const nextUserSequence = runtimeMode === "start"
1197
- ? 1
1198
- : await this.resolveNextUserSequence(input.sessionId, session.messageCount);
1203
+ const sequenceBase = resolveRuntimeSequenceBase(session, runtimeMode);
1204
+ const nextUserSequence = sequenceBase !== null
1205
+ ? sequenceBase
1206
+ : (runtimeMode === "start"
1207
+ ? 1
1208
+ : await this.resolveNextUserSequence(input.sessionId, session.messageCount));
1199
1209
  const resolvedAttachments = persistedAttachments
1200
1210
  ?? this.persistMessageAttachments(input.sessionId, input.clientRequestId, input.runtimeOptions?.attachments ?? []);
1201
1211
  const providerPrompt = this.sessionMessageAttachmentService.buildProviderPrompt(session.provider, input.content, resolvedAttachments.runtimeAttachments);
@@ -1219,7 +1229,17 @@ export class SessionLiveRuntimeService {
1219
1229
  providerLaunchRuntimeHomeDir: providerLaunchContext.runtimeHomeDir,
1220
1230
  providerBindingRuntimeHomeDir: providerBinding.runtimeHomeDir
1221
1231
  });
1222
- const providerInstructionFilePath = resolveRuntimeInstructionFilePath(session.provider, workspace.path, input.runtimeOptions?.providerInstructionFilePath
1232
+ const claudeForkBootstrap = await this.buildClaudeForkBootstrapDescriptor({
1233
+ session,
1234
+ runtimeMode,
1235
+ baseInstructionFilePath: input.runtimeOptions?.providerInstructionFilePath
1236
+ ?? workspaceRuntimeContext.instructionFilePath
1237
+ ?? providerLaunchContext.providerInstructionFilePath
1238
+ ?? null,
1239
+ runtimeHomeDir: effectiveRuntimeHomeDir
1240
+ });
1241
+ const providerInstructionFilePath = resolveRuntimeInstructionFilePath(session.provider, workspace.path, claudeForkBootstrap?.instructionFilePath
1242
+ ?? input.runtimeOptions?.providerInstructionFilePath
1223
1243
  ?? workspaceRuntimeContext.instructionFilePath
1224
1244
  ?? providerLaunchContext.providerInstructionFilePath
1225
1245
  ?? null);
@@ -1707,6 +1727,37 @@ export class SessionLiveRuntimeService {
1707
1727
  writeFileSync(syntheticFilePath, `${serialized}\n`, "utf8");
1708
1728
  return syntheticFilePath;
1709
1729
  }
1730
+ async buildClaudeForkBootstrapDescriptor(input) {
1731
+ if (input.runtimeMode !== "start" || !shouldBootstrapClaudeForkSession(input.session)) {
1732
+ return null;
1733
+ }
1734
+ const messages = await Promise.resolve(this.sessionHistoryService.readAllTextHistoryMessages(input.session.sessionId)).catch(() => []);
1735
+ const textMessages = Array.isArray(messages)
1736
+ ? messages.filter((message) => (message.role === "user" || message.role === "assistant")
1737
+ && message.kind === "text"
1738
+ && message.content.trim().length > 0)
1739
+ : [];
1740
+ if (textMessages.length === 0) {
1741
+ return null;
1742
+ }
1743
+ const overlay = buildClaudeForkBootstrapInstructionOverlay({
1744
+ sessionTitle: input.session.title,
1745
+ messages: textMessages
1746
+ });
1747
+ if (!overlay) {
1748
+ return null;
1749
+ }
1750
+ const baseInstructionContent = readInstructionFileSafe(input.baseInstructionFilePath);
1751
+ const targetRoot = input.runtimeHomeDir?.trim()
1752
+ || path.resolve(path.dirname(this.config.databasePath), "runtime", "claude-fork-bootstrap");
1753
+ const targetDir = path.join(targetRoot, ".codingns-fork-bootstrap");
1754
+ const instructionFilePath = path.join(targetDir, `${input.session.sessionId}.md`);
1755
+ mkdirSync(targetDir, { recursive: true });
1756
+ writeFileSync(instructionFilePath, composeForkBootstrapInstructionFile(baseInstructionContent, overlay), "utf8");
1757
+ return {
1758
+ instructionFilePath
1759
+ };
1760
+ }
1710
1761
  buildBindingSnapshot(sessionId, provider, providerSessionId, rawStoreRef) {
1711
1762
  const pendingValue = `pending://${provider}/${sessionId}`;
1712
1763
  return {
@@ -2445,8 +2496,30 @@ function normalizeClaudeHookEventName(value) {
2445
2496
  }
2446
2497
  function isSupportedClaudeHookEvent(value) {
2447
2498
  return (value === "PreToolUse" ||
2499
+ value === "PostToolUse" ||
2500
+ value === "PostToolUseFailure" ||
2448
2501
  value === "PermissionRequest" ||
2502
+ value === "PermissionDenied" ||
2503
+ value === "Elicitation" ||
2504
+ value === "ElicitationResult" ||
2505
+ value === "MessageDisplay" ||
2449
2506
  value === "Notification" ||
2507
+ value === "PostToolBatch" ||
2508
+ value === "TaskCreated" ||
2509
+ value === "TaskCompleted" ||
2510
+ value === "TeammateIdle" ||
2511
+ value === "SubagentStart" ||
2512
+ value === "SubagentStop" ||
2513
+ value === "PreCompact" ||
2514
+ value === "PostCompact" ||
2515
+ value === "InstructionsLoaded" ||
2516
+ value === "ConfigChange" ||
2517
+ value === "CwdChanged" ||
2518
+ value === "FileChanged" ||
2519
+ value === "WorktreeCreate" ||
2520
+ value === "WorktreeRemove" ||
2521
+ value === "Setup" ||
2522
+ value === "UserPromptExpansion" ||
2450
2523
  value === "UserPromptSubmit" ||
2451
2524
  value === "SessionStart" ||
2452
2525
  value === "Stop" ||
@@ -2484,6 +2557,160 @@ function mapClaudeHookToRuntimeUpdate(hookEventName, payload, timestamp) {
2484
2557
  timestamp
2485
2558
  };
2486
2559
  }
2560
+ if (hookEventName === "Setup") {
2561
+ return {
2562
+ runningState: "running",
2563
+ detail: buildClaudeHookRunningDetail("Claude 正在执行初始化", payload),
2564
+ timestamp
2565
+ };
2566
+ }
2567
+ if (hookEventName === "UserPromptExpansion") {
2568
+ return {
2569
+ runningState: "running",
2570
+ detail: buildClaudeHookRunningDetail("Claude 正在展开用户指令", payload),
2571
+ timestamp
2572
+ };
2573
+ }
2574
+ if (hookEventName === "PostToolUse") {
2575
+ return {
2576
+ runningState: "running",
2577
+ detail: buildClaudeHookRunningDetail("Claude 已完成一次工具调用", payload),
2578
+ timestamp
2579
+ };
2580
+ }
2581
+ if (hookEventName === "PostToolUseFailure") {
2582
+ return {
2583
+ runningState: "running",
2584
+ detail: buildClaudeHookRunningDetail("Claude 的一次工具调用失败", payload),
2585
+ timestamp
2586
+ };
2587
+ }
2588
+ if (hookEventName === "PermissionDenied") {
2589
+ return {
2590
+ runningState: "running",
2591
+ detail: buildClaudeHookRunningDetail("Claude 的工具权限请求被拒绝", payload),
2592
+ timestamp
2593
+ };
2594
+ }
2595
+ if (hookEventName === "Notification") {
2596
+ return {
2597
+ runningState: "running",
2598
+ detail: buildClaudeHookRunningDetail("Claude 发来一条通知", payload),
2599
+ timestamp
2600
+ };
2601
+ }
2602
+ if (hookEventName === "MessageDisplay") {
2603
+ return {
2604
+ runningState: "running",
2605
+ detail: buildClaudeHookRunningDetail("Claude 正在展示回复内容", payload),
2606
+ timestamp
2607
+ };
2608
+ }
2609
+ if (hookEventName === "ElicitationResult") {
2610
+ return {
2611
+ runningState: "running",
2612
+ detail: buildClaudeHookRunningDetail("Claude 已收到补充信息结果", payload),
2613
+ timestamp
2614
+ };
2615
+ }
2616
+ if (hookEventName === "PostToolBatch") {
2617
+ return {
2618
+ runningState: "running",
2619
+ detail: buildClaudeHookRunningDetail("Claude 已完成一批工具调用", payload),
2620
+ timestamp
2621
+ };
2622
+ }
2623
+ if (hookEventName === "TaskCreated") {
2624
+ return {
2625
+ runningState: "running",
2626
+ detail: buildClaudeHookRunningDetail("Claude 新建了一个任务", payload),
2627
+ timestamp
2628
+ };
2629
+ }
2630
+ if (hookEventName === "TaskCompleted") {
2631
+ return {
2632
+ runningState: "running",
2633
+ detail: buildClaudeHookRunningDetail("Claude 完成了一个任务", payload),
2634
+ timestamp
2635
+ };
2636
+ }
2637
+ if (hookEventName === "SubagentStart") {
2638
+ return {
2639
+ runningState: "running",
2640
+ detail: buildClaudeHookRunningDetail("Claude 子任务已启动", payload),
2641
+ timestamp
2642
+ };
2643
+ }
2644
+ if (hookEventName === "SubagentStop") {
2645
+ return {
2646
+ runningState: "running",
2647
+ detail: buildClaudeHookRunningDetail("Claude 子任务已结束", payload),
2648
+ timestamp
2649
+ };
2650
+ }
2651
+ if (hookEventName === "TeammateIdle") {
2652
+ return {
2653
+ runningState: "running",
2654
+ detail: buildClaudeHookRunningDetail("Claude 队友任务即将空闲", payload),
2655
+ timestamp
2656
+ };
2657
+ }
2658
+ if (hookEventName === "PreCompact") {
2659
+ return {
2660
+ runningState: "running",
2661
+ detail: buildClaudeHookRunningDetail("Claude 正在压缩上下文", payload),
2662
+ timestamp
2663
+ };
2664
+ }
2665
+ if (hookEventName === "PostCompact") {
2666
+ return {
2667
+ runningState: "running",
2668
+ detail: buildClaudeHookRunningDetail("Claude 已完成上下文压缩", payload),
2669
+ timestamp
2670
+ };
2671
+ }
2672
+ if (hookEventName === "InstructionsLoaded") {
2673
+ return {
2674
+ runningState: "running",
2675
+ detail: buildClaudeHookRunningDetail("Claude 已加载指令文件", payload),
2676
+ timestamp
2677
+ };
2678
+ }
2679
+ if (hookEventName === "ConfigChange") {
2680
+ return {
2681
+ runningState: "running",
2682
+ detail: buildClaudeHookRunningDetail("Claude 检测到配置变化", payload),
2683
+ timestamp
2684
+ };
2685
+ }
2686
+ if (hookEventName === "CwdChanged") {
2687
+ return {
2688
+ runningState: "running",
2689
+ detail: buildClaudeHookRunningDetail("Claude 已切换工作目录", payload),
2690
+ timestamp
2691
+ };
2692
+ }
2693
+ if (hookEventName === "FileChanged") {
2694
+ return {
2695
+ runningState: "running",
2696
+ detail: buildClaudeHookRunningDetail("Claude 检测到文件变化", payload),
2697
+ timestamp
2698
+ };
2699
+ }
2700
+ if (hookEventName === "WorktreeCreate") {
2701
+ return {
2702
+ runningState: "running",
2703
+ detail: buildClaudeHookRunningDetail("Claude 正在创建工作树", payload),
2704
+ timestamp
2705
+ };
2706
+ }
2707
+ if (hookEventName === "WorktreeRemove") {
2708
+ return {
2709
+ runningState: "running",
2710
+ detail: buildClaudeHookRunningDetail("Claude 正在移除工作树", payload),
2711
+ timestamp
2712
+ };
2713
+ }
2487
2714
  if (hookEventName === "StopFailure") {
2488
2715
  return {
2489
2716
  runningState: "failed",
@@ -2514,6 +2741,32 @@ function mapClaudeHookToRuntimeUpdate(hookEventName, payload, timestamp) {
2514
2741
  }
2515
2742
  return null;
2516
2743
  }
2744
+ function buildClaudeHookRunningDetail(base, payload) {
2745
+ const candidates = [
2746
+ normalizeOptionalText(payload.title),
2747
+ normalizeOptionalText(payload.message),
2748
+ normalizeOptionalText(payload.reason),
2749
+ normalizeOptionalText(payload.prompt),
2750
+ normalizeOptionalText(payload.path),
2751
+ normalizeOptionalText(payload.file_path),
2752
+ normalizeOptionalText(payload.worktree_path),
2753
+ normalizeOptionalText(payload.config_path),
2754
+ normalizeOptionalText(payload.rule_file),
2755
+ normalizeOptionalText(payload.cwd),
2756
+ normalizeOptionalText(payload.command_name),
2757
+ normalizeOptionalText(payload.notification_type),
2758
+ normalizeOptionalText(payload.mcp_server_name),
2759
+ normalizeOptionalText(payload.matcher),
2760
+ normalizeOptionalText(payload.trigger),
2761
+ normalizeOptionalText(payload.action)
2762
+ ].filter((value) => Boolean(value));
2763
+ const suffix = payload.tool_name?.trim()
2764
+ ? `(${payload.tool_name.trim()})`
2765
+ : candidates[0]
2766
+ ? `:${candidates[0]}`
2767
+ : "";
2768
+ return `${base}${suffix}`;
2769
+ }
2517
2770
  function resolveRuntimeSessionTitle(provider, existingTitle, content, parentTitle, forkMethod, forkSourceType) {
2518
2771
  const normalizedExistingTitle = existingTitle.trim();
2519
2772
  const normalizedParentTitle = parentTitle?.trim() ?? "";
@@ -2525,6 +2778,76 @@ function resolveRuntimeSessionTitle(provider, existingTitle, content, parentTitl
2525
2778
  }
2526
2779
  return buildSessionTitleFromContent(content, "继续对话");
2527
2780
  }
2781
+ function shouldBootstrapClaudeForkSession(session) {
2782
+ if (session.provider !== "claude-code") {
2783
+ return false;
2784
+ }
2785
+ if (session.forkMethod !== "native_message_fork"
2786
+ && session.forkMethod !== "native_session_fork") {
2787
+ return false;
2788
+ }
2789
+ const inheritedCount = typeof session.inheritedPrefixMessageCount === "number"
2790
+ ? Math.max(0, session.inheritedPrefixMessageCount)
2791
+ : null;
2792
+ if (inheritedCount === null) {
2793
+ return false;
2794
+ }
2795
+ return session.messageCount <= inheritedCount;
2796
+ }
2797
+ function resolveRuntimeSequenceBase(session, runtimeMode) {
2798
+ if (runtimeMode !== "start"
2799
+ || session.provider !== "claude-code"
2800
+ || (session.forkMethod !== "native_message_fork"
2801
+ && session.forkMethod !== "native_session_fork")
2802
+ || typeof session.inheritedPrefixMessageCount !== "number") {
2803
+ return null;
2804
+ }
2805
+ return Math.max(0, session.inheritedPrefixMessageCount);
2806
+ }
2807
+ function buildClaudeForkBootstrapInstructionOverlay(input) {
2808
+ const title = input.sessionTitle.trim() || "未命名会话";
2809
+ const lines = [
2810
+ `这是一个从既有 Claude Code 会话 fork 出来的子会话,标题:${title}。`,
2811
+ "下面这些历史内容已经发生过,只是给你恢复上下文。",
2812
+ "不要把它们当成新的用户问题逐条重答,也不要重复总结。",
2813
+ "真正需要处理的新用户输入,会在你看到这段说明之后单独发给你。",
2814
+ ""
2815
+ ];
2816
+ let appended = 0;
2817
+ for (const message of input.messages) {
2818
+ if (message.kind !== "text") {
2819
+ continue;
2820
+ }
2821
+ const normalizedContent = message.content.trim();
2822
+ if (!normalizedContent) {
2823
+ continue;
2824
+ }
2825
+ lines.push(message.role === "user" ? "[历史用户]" : "[历史助手]");
2826
+ lines.push(normalizedContent);
2827
+ lines.push("");
2828
+ appended += 1;
2829
+ }
2830
+ if (appended === 0) {
2831
+ return null;
2832
+ }
2833
+ return lines.join("\n").trim();
2834
+ }
2835
+ function readInstructionFileSafe(filePath) {
2836
+ const normalizedPath = filePath?.trim() || null;
2837
+ if (!normalizedPath || !existsSync(normalizedPath)) {
2838
+ return null;
2839
+ }
2840
+ try {
2841
+ return readFileSync(normalizedPath, "utf8");
2842
+ }
2843
+ catch {
2844
+ return null;
2845
+ }
2846
+ }
2847
+ function composeForkBootstrapInstructionFile(baseInstructionContent, overlay) {
2848
+ const sections = [baseInstructionContent?.trim() ?? "", overlay.trim()].filter((value) => value.length > 0);
2849
+ return `${sections.join("\n\n")}\n`;
2850
+ }
2528
2851
  function isSyntheticRuntimeSessionTitle(provider, title) {
2529
2852
  if (provider !== "codex") {
2530
2853
  return false;
@@ -2534,6 +2857,10 @@ function isSyntheticRuntimeSessionTitle(provider, title) {
2534
2857
  }
2535
2858
  function shouldStartNativeSessionOnFirstMessage(session) {
2536
2859
  if (session.provider !== "codex" && session.provider !== "opencode") {
2860
+ if (session.provider === "claude-code"
2861
+ && shouldBootstrapClaudeForkSession(session)) {
2862
+ return "start";
2863
+ }
2537
2864
  return "continue";
2538
2865
  }
2539
2866
  if (session.provider === "codex" && session.providerSessionId.startsWith("rollout-")) {
@@ -2798,8 +3125,30 @@ function buildClaudeHookBridgeConfig(config, provider) {
2798
3125
  command,
2799
3126
  supportedEvents: [
2800
3127
  "PreToolUse",
3128
+ "PostToolUse",
3129
+ "PostToolUseFailure",
3130
+ "PostToolBatch",
2801
3131
  "PermissionRequest",
3132
+ "PermissionDenied",
3133
+ "Elicitation",
3134
+ "ElicitationResult",
3135
+ "MessageDisplay",
2802
3136
  "Notification",
3137
+ "TaskCreated",
3138
+ "TaskCompleted",
3139
+ "TeammateIdle",
3140
+ "SubagentStart",
3141
+ "SubagentStop",
3142
+ "PreCompact",
3143
+ "PostCompact",
3144
+ "InstructionsLoaded",
3145
+ "ConfigChange",
3146
+ "CwdChanged",
3147
+ "FileChanged",
3148
+ "WorktreeCreate",
3149
+ "WorktreeRemove",
3150
+ "Setup",
3151
+ "UserPromptExpansion",
2803
3152
  "UserPromptSubmit",
2804
3153
  "SessionStart",
2805
3154
  "Stop",