cc-viewer 1.9.17 → 1.9.19

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.
package/cli.js CHANGED
@@ -838,6 +838,7 @@ async function runSdkMode(extraClaudeArgs = [], cwd, noOpen = false) {
838
838
  }
839
839
  // 观测面走与 PTY 相同的 wire 通路(SDK 子进程流量经 ANTHROPIC_BASE_URL 到 ccv proxy →
840
840
  // fetch hook → v2 transcript → SSE),sdk-manager 不再另接 v2/streaming 注入。
841
+ const { runWaterfallHook } = await import('./server/lib/plugin-loader.js');
841
842
  sdkManager.initSdkSession(workingDir, basename(workingDir), {
842
843
  broadcastWs: (msg) => serverMod.broadcastWsMessage(msg),
843
844
  permissionMode,
@@ -849,7 +850,7 @@ async function runSdkMode(extraClaudeArgs = [], cwd, noOpen = false) {
849
850
  ? { continue: sdkArgs.continue, resumeId: sdkArgs.resume, forkSession: sdkArgs.forkSession }
850
851
  : null,
851
852
  userArgs: sdkArgs.rest,
852
- runWaterfallHook: (await import('./server/lib/plugin-loader.js')).runWaterfallHook,
853
+ runWaterfallHook,
853
854
  // Round-3 P0: SDK mode has no Stop hook (ensureHooks() skipped above), so
854
855
  // the only place we learn a turn ended is the SDK 'result' message. Forward
855
856
  // it to the same SSE channel the Stop hook bridge uses in PTY mode.
@@ -872,6 +873,24 @@ async function runSdkMode(extraClaudeArgs = [], cwd, noOpen = false) {
872
873
  // persistent dialogue row plus a toast; meta (cwd/sessionId/instanceKey, filled by
873
874
  // the sdk-manager session closure) routes it to the owning workspace's viewers.
874
875
  onQueryError: (message, meta) => serverMod.broadcastWsMessage({ type: 'sdk-error', message, ...(meta || {}) }),
876
+ // Authoritative per-turn loop boundaries (immediate, turn-correlated) — the voice
877
+ // pack / plugin lifecycle complement to the debounced turn_end above.
878
+ onAgentLoopStart: (p) => {
879
+ if (typeof serverMod.broadcastAgentLoopStart !== 'function') {
880
+ console.warn('[sdk] serverMod.broadcastAgentLoopStart is not a function (export missing?); loop-start signal dropped');
881
+ return;
882
+ }
883
+ try { serverMod.broadcastAgentLoopStart(p); }
884
+ catch (err) { console.warn('[sdk] broadcastAgentLoopStart threw:', err?.message); }
885
+ },
886
+ onAgentLoopEnd: (p) => {
887
+ if (typeof serverMod.broadcastAgentLoopEnd !== 'function') {
888
+ console.warn('[sdk] serverMod.broadcastAgentLoopEnd is not a function (export missing?); loop-end signal dropped');
889
+ return;
890
+ }
891
+ try { serverMod.broadcastAgentLoopEnd(p); }
892
+ catch (err) { console.warn('[sdk] broadcastAgentLoopEnd threw:', err?.message); }
893
+ },
875
894
  });
876
895
 
877
896
  // Per-cwd multi-session (2026-10-12): hand the boot launch config (proxy env, model,
@@ -894,6 +913,7 @@ async function runSdkMode(extraClaudeArgs = [], cwd, noOpen = false) {
894
913
  serverMod.setSdkAutoCancelApproval(sdkManager.autoCancelApproval);
895
914
  serverMod.setSdkSendUserMessage(sdkManager.sendUserMessage);
896
915
  serverMod.setSdkInterruptTurn(sdkManager.interruptTurn);
916
+ serverMod.setSdkRetryTurn(sdkManager.retryInterruptedTurn);
897
917
  serverMod.setSdkGetPendingApprovals(sdkManager.getPendingApprovals);
898
918
  serverMod.setSdkGetInitSnapshot(sdkManager.getSdkInitSnapshot);
899
919
  serverMod.setSdkGetSkillsSnapshot(sdkManager.getSkillsSnapshot);
@@ -906,6 +926,36 @@ async function runSdkMode(extraClaudeArgs = [], cwd, noOpen = false) {
906
926
  serverMod.setSdkClearQueued(sdkManager.clearQueued);
907
927
  serverMod.setSdkGetQueueSnapshot(sdkManager.getQueueSnapshot);
908
928
 
929
+ // Durable process-level wiring: registered ONCE here so a workspace stop→relaunch
930
+ // (which calls stopSession and clears the mutable callbacks, then re-inits without
931
+ // them) re-adopts the process wiring instead of silently losing every sdk-* frame.
932
+ sdkManager.setSdkProcessWiring({
933
+ onTurnEnd: ({ sessionId, ts, cwd }) => {
934
+ if (typeof serverMod.broadcastTurnEnd !== 'function') return;
935
+ try { serverMod.broadcastTurnEnd(sessionId, ts, null, cwd); }
936
+ catch (err) { console.warn('[sdk] broadcastTurnEnd threw:', err?.message); }
937
+ },
938
+ onQueryError: (message, meta) => serverMod.broadcastWsMessage({ type: 'sdk-error', message, ...(meta || {}) }),
939
+ onAgentLoopStart: (p) => {
940
+ if (typeof serverMod.broadcastAgentLoopStart !== 'function') {
941
+ console.warn('[sdk] serverMod.broadcastAgentLoopStart is not a function (export missing?); loop-start signal dropped');
942
+ return;
943
+ }
944
+ try { serverMod.broadcastAgentLoopStart(p); }
945
+ catch (err) { console.warn('[sdk] broadcastAgentLoopStart threw:', err?.message); }
946
+ },
947
+ onAgentLoopEnd: (p) => {
948
+ if (typeof serverMod.broadcastAgentLoopEnd !== 'function') {
949
+ console.warn('[sdk] serverMod.broadcastAgentLoopEnd is not a function (export missing?); loop-end signal dropped');
950
+ return;
951
+ }
952
+ try { serverMod.broadcastAgentLoopEnd(p); }
953
+ catch (err) { console.warn('[sdk] broadcastAgentLoopEnd threw:', err?.message); }
954
+ },
955
+ broadcastWs: (msg) => serverMod.broadcastWsMessage(msg),
956
+ runWaterfallHook,
957
+ });
958
+
909
959
  // 自动打开浏览器
910
960
  const protocol = serverMod.getProtocol();
911
961
  const basePath = normalizeBasePath(process.env.CCV_BASE_PATH);