cc-viewer 1.7.0 → 1.7.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 (123) hide show
  1. package/dist/assets/App-B224r-8M.js +2 -0
  2. package/dist/assets/{MdxEditorPanel-C5Q6uUyH.js → MdxEditorPanel-BUubiE6Y.js} +1 -1
  3. package/dist/assets/{Mobile-MoBp9c8k.js → Mobile-CKmfRRvo.js} +1 -1
  4. package/dist/assets/index-CjsQEQc2.js +2 -0
  5. package/dist/assets/seqResourceLoaders-C-T_EMiO.js +2 -0
  6. package/dist/assets/{seqResourceLoaders-CxuD1CYl.css → seqResourceLoaders-DFrHmgnK.css} +1 -1
  7. package/dist/index.html +1 -1
  8. package/package.json +2 -1
  9. package/server/lib/log-management.js +1 -0
  10. package/server/lib/log-watcher.js +29 -3
  11. package/server/lib/stats-worker.js +21 -2
  12. package/server/lib/v2/adapter.js +123 -18
  13. package/server/lib/v2/journal.js +9 -5
  14. package/server/lib/v2/jsonl-read.js +127 -0
  15. package/server/lib/v2/live-feed.js +222 -20
  16. package/server/lib/v2/meta-rows.js +361 -0
  17. package/server/lib/v2/replay.js +5 -5
  18. package/server/lib/v2/session-select.js +69 -2
  19. package/server/lib/v2/v2-writer.js +15 -0
  20. package/server/lib/wire-compress.js +167 -0
  21. package/server/routes/events.js +96 -26
  22. package/server/routes/im.js +1 -1
  23. package/server/routes/logs.js +15 -12
  24. package/server/routes/v2.js +60 -0
  25. package/server/routes/workspaces.js +7 -6
  26. package/server/server.js +23 -1
  27. package/server/workspace-registry.js +5 -0
  28. package/src/utils/apiUrl.js +26 -0
  29. package/src/utils/askFallback.js +21 -0
  30. package/src/utils/askOptionDesc.js +55 -0
  31. package/src/utils/askPortalMatcher.js +54 -0
  32. package/src/utils/autoApproveOptions.js +27 -0
  33. package/src/utils/avatarAnimationPostPass.js +49 -0
  34. package/src/utils/builtinPresets.js +18 -0
  35. package/src/utils/clearCheckpoint.js +7 -0
  36. package/src/utils/commandValidator.js +45 -0
  37. package/src/utils/contentFilter.js +620 -0
  38. package/src/utils/contextRaw.js +18 -0
  39. package/src/utils/contextSidebarNavigation.js +16 -0
  40. package/src/utils/contextTurns.js +117 -0
  41. package/src/utils/displayScaleHelper.js +47 -0
  42. package/src/utils/effectiveModel.js +13 -0
  43. package/src/utils/entry-slim.js +563 -0
  44. package/src/utils/entryCache.js +144 -0
  45. package/src/utils/errorReport.js +6 -0
  46. package/src/utils/fileExpandedPathsStorage.js +70 -0
  47. package/src/utils/fileIcons.jsx +36 -0
  48. package/src/utils/fileOpen.js +37 -0
  49. package/src/utils/formatters.js +48 -0
  50. package/src/utils/gitApi.js +50 -0
  51. package/src/utils/gitTreeBuilder.js +19 -0
  52. package/src/utils/helpers.js +846 -0
  53. package/src/utils/identityHeal.js +99 -0
  54. package/src/utils/imConnState.js +59 -0
  55. package/src/utils/imOrigin.js +24 -0
  56. package/src/utils/imTr.js +7 -0
  57. package/src/utils/imageCompress.js +83 -0
  58. package/src/utils/imageDownscale.js +28 -0
  59. package/src/utils/imageResize.js +112 -0
  60. package/src/utils/ingestPipeline.js +47 -0
  61. package/src/utils/lazyWithReload.js +53 -0
  62. package/src/utils/markdown.js +30 -0
  63. package/src/utils/markdownIncremental.js +39 -0
  64. package/src/utils/markdownProfiler.js +113 -0
  65. package/src/utils/mdExtensionDetect.js +64 -0
  66. package/src/utils/memoryLinkParser.js +44 -0
  67. package/src/utils/modalMask.js +15 -0
  68. package/src/utils/monotime.js +6 -0
  69. package/src/utils/pinnedMenu.js +55 -0
  70. package/src/utils/presetShortcuts.js +14 -0
  71. package/src/utils/projectAlias.js +135 -0
  72. package/src/utils/promptClassifier.js +112 -0
  73. package/src/utils/promptDetect.js +196 -0
  74. package/src/utils/promptNav.js +60 -0
  75. package/src/utils/ptyChunkBuilder.js +251 -0
  76. package/src/utils/quickMenuHoverIntent.js +35 -0
  77. package/src/utils/rateLimitParser.js +119 -0
  78. package/src/utils/readResultPool.js +106 -0
  79. package/src/utils/refreshCachedItemProp.js +30 -0
  80. package/src/utils/requestType.js +208 -0
  81. package/src/utils/resizeCalc.js +21 -0
  82. package/src/utils/resolveLocalized.js +17 -0
  83. package/src/utils/searchApi.js +47 -0
  84. package/src/utils/searchReplace.js +51 -0
  85. package/src/utils/seqResourceLoaders.js +79 -0
  86. package/src/utils/sessionManager.js +471 -0
  87. package/src/utils/sessionMerge.js +180 -0
  88. package/src/utils/skillModalController.js +111 -0
  89. package/src/utils/skillsParser.js +116 -0
  90. package/src/utils/slashCommandLabels.js +80 -0
  91. package/src/utils/splitDragCalc.js +73 -0
  92. package/src/utils/stickyBottomController.js +643 -0
  93. package/src/utils/svgSanitize.js +48 -0
  94. package/src/utils/systemTags.js +47 -0
  95. package/src/utils/tClaude.js +20 -0
  96. package/src/utils/teamModalBuilder.js +351 -0
  97. package/src/utils/teamSessionParser.js +190 -0
  98. package/src/utils/teammateAvatars.js +194 -0
  99. package/src/utils/teammateDetector.js +121 -0
  100. package/src/utils/termDiag.js +114 -0
  101. package/src/utils/terminalClipboard.js +117 -0
  102. package/src/utils/terminalWriteQueue.js +398 -0
  103. package/src/utils/thinkingMerge.js +49 -0
  104. package/src/utils/toolCatalog.js +29 -0
  105. package/src/utils/toolResultBuilder.js +393 -0
  106. package/src/utils/toolResultClassifier.js +16 -0
  107. package/src/utils/toolResultCore.js +167 -0
  108. package/src/utils/toolsDiff.js +44 -0
  109. package/src/utils/toolsXmlFormatter.js +3 -0
  110. package/src/utils/ultraplanController.js +109 -0
  111. package/src/utils/ultraplanExperts.js +86 -0
  112. package/src/utils/ultraplanTemplates.js +154 -0
  113. package/src/utils/userImageRefs.js +49 -0
  114. package/src/utils/v3Assembler.js +112 -0
  115. package/src/utils/v3Rows.js +48 -0
  116. package/src/utils/voicePackPlayer.js +233 -0
  117. package/src/utils/webSearchGrouping.js +111 -0
  118. package/src/utils/workflowFormat.js +52 -0
  119. package/src/utils/workflowRuns.js +118 -0
  120. package/src/utils/workflowStore.js +94 -0
  121. package/dist/assets/App-DTkacfRW.js +0 -2
  122. package/dist/assets/index-Ac8vnV3v.js +0 -2
  123. package/dist/assets/seqResourceLoaders-Cd_TAXTb.js +0 -2
@@ -0,0 +1,117 @@
1
+ // Context tab message parsing + turn grouping (extracted from ContextTab.jsx so the
2
+ // pairing logic is unit-testable — JSX modules cannot be imported by the test harness).
3
+
4
+ export function parseContentBlocks(content) {
5
+ if (content == null) return [];
6
+
7
+ if (typeof content === 'string') {
8
+ const trimmed = content.trim();
9
+ return trimmed ? [{ type: 'markdown', text: trimmed }] : [];
10
+ }
11
+
12
+ if (Array.isArray(content)) {
13
+ const blocks = [];
14
+ for (const block of content) {
15
+ if (!block) continue;
16
+ if (block.type === 'text') {
17
+ const trimmed = (block.text || '').trim();
18
+ if (trimmed) blocks.push({ type: 'markdown', text: trimmed });
19
+ } else if (block.type === 'tool_use') {
20
+ blocks.push({
21
+ type: 'tool_use',
22
+ name: block.name || 'unknown',
23
+ id: block.id || '',
24
+ input: block.input ?? {},
25
+ });
26
+ } else if (block.type === 'tool_result') {
27
+ const inner = parseResultContent(block.content);
28
+ blocks.push({
29
+ type: 'tool_result',
30
+ tool_use_id: block.tool_use_id || '',
31
+ is_error: block.is_error,
32
+ content: inner,
33
+ });
34
+ } else if (block.type === 'thinking') {
35
+ const text = block.thinking || '';
36
+ if (text.trim()) blocks.push({ type: 'thinking', text });
37
+ } else if (block.type === 'image') {
38
+ blocks.push({ type: 'json', label: 'image', data: block });
39
+ } else {
40
+ blocks.push({ type: 'json', label: block.type || 'block', data: block });
41
+ }
42
+ }
43
+ return blocks;
44
+ }
45
+
46
+ return [{ type: 'json', label: 'content', data: content }];
47
+ }
48
+
49
+ export function parseResultContent(content) {
50
+ if (content == null) return [];
51
+ if (typeof content === 'string') {
52
+ const trimmed = content.trim();
53
+ return trimmed ? [{ type: 'markdown', text: trimmed }] : [];
54
+ }
55
+ if (Array.isArray(content)) {
56
+ return content.flatMap((c) => {
57
+ if (!c) return [];
58
+ if (c.type === 'text') {
59
+ const trimmed = (c.text || '').trim();
60
+ return trimmed ? [{ type: 'markdown', text: trimmed }] : [];
61
+ }
62
+ return [{ type: 'json', label: c.type || 'block', data: c }];
63
+ });
64
+ }
65
+ return [{ type: 'json', label: 'content', data: content }];
66
+ }
67
+
68
+ export function extractPreviewText(content) {
69
+ if (typeof content === 'string') return content.slice(0, 60).replace(/\n/g, ' ');
70
+ if (Array.isArray(content)) {
71
+ for (const block of content) {
72
+ if (block?.type === 'text' && block.text?.trim()) {
73
+ return block.text.trim().slice(0, 60).replace(/\n/g, ' ');
74
+ }
75
+ }
76
+ }
77
+ return '';
78
+ }
79
+
80
+ // 注意:非 user 开头的消息(首条 assistant、连续 assistant 等)不进任何 turn,
81
+ // 「原文」视图与解析视图同口径,同样不展示这些消息。
82
+ // Mid-conversation `role:"system"` messages (mid-conversation-system beta) may sit
83
+ // between the user message and its assistant reply; they are folded into the turn
84
+ // (systemBlocks/rawSystem) so the assistant pairing is not broken. Only messages
85
+ // with role === 'system' are skipped when locating the paired assistant — any
86
+ // other unknown role still ends the turn, matching the old strict-adjacency rule.
87
+ export function groupMessagesIntoTurns(messages) {
88
+ const turns = [];
89
+ let i = 0;
90
+ while (i < messages.length) {
91
+ const userMsg = messages[i];
92
+ if (userMsg?.role !== 'user') { i++; continue; }
93
+ let j = i + 1;
94
+ const systemMsgs = [];
95
+ while (messages[j]?.role === 'system') { systemMsgs.push(messages[j]); j++; }
96
+ const assistantMsg = messages[j]?.role === 'assistant' ? messages[j] : null;
97
+ turns.push({
98
+ id: `turn__${i}`,
99
+ isTurn: true,
100
+ turnIndex: turns.length,
101
+ timestamp: userMsg._timestamp || null,
102
+ assistantTimestamp: assistantMsg?._timestamp || null,
103
+ userBlocks: parseContentBlocks(userMsg?.content),
104
+ systemBlocks: systemMsgs.length
105
+ ? systemMsgs.map((m) => ({ blocks: parseContentBlocks(m.content), timestamp: m._timestamp || null }))
106
+ : null,
107
+ assistantBlocks: assistantMsg ? parseContentBlocks(assistantMsg.content) : null,
108
+ // 原始消息引用:供「原文」视图无损输出(解析 blocks 是单向的,不可逆)
109
+ rawUser: userMsg,
110
+ rawSystem: systemMsgs.length ? systemMsgs : null,
111
+ rawAssistant: assistantMsg,
112
+ preview: extractPreviewText(userMsg?.content),
113
+ });
114
+ i = assistantMsg ? j + 1 : i + 1;
115
+ }
116
+ return turns;
117
+ }
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Display-scale (整体显示大小 / Chrome 式缩放) 的纯计算工具。
3
+ * 无 DOM / React 依赖,便于单测。比例以「整数百分比」表示(100 = 原始大小)。
4
+ */
5
+
6
+ // 预设档位,贴近 Chrome 的缩放档位。
7
+ export const DISPLAY_SCALE_PRESETS = [50, 67, 75, 80, 90, 100, 110, 125, 150, 175, 200];
8
+
9
+ const MIN_SCALE = DISPLAY_SCALE_PRESETS[0];
10
+ const MAX_SCALE = DISPLAY_SCALE_PRESETS[DISPLAY_SCALE_PRESETS.length - 1];
11
+
12
+ /**
13
+ * 把任意输入(可能来自手改 preferences.json / 旧数据)夹到 [50,200] 并吸附到最近的预设档位。
14
+ * 平局时取较大档位。非法输入回退到 100。
15
+ * @param {number|string} pct
16
+ * @returns {number} 一个合法的预设值
17
+ */
18
+ export function snapToPreset(pct) {
19
+ const n = Number(pct);
20
+ if (!Number.isFinite(n)) return 100;
21
+ const clamped = Math.max(MIN_SCALE, Math.min(MAX_SCALE, n));
22
+ let best = DISPLAY_SCALE_PRESETS[0];
23
+ let bestDist = Infinity;
24
+ for (const p of DISPLAY_SCALE_PRESETS) {
25
+ const d = Math.abs(p - clamped);
26
+ // `<=` 让平局时取后出现(更大)的档位
27
+ if (d <= bestDist) {
28
+ bestDist = d;
29
+ best = p;
30
+ }
31
+ }
32
+ return best;
33
+ }
34
+
35
+ /**
36
+ * 在预设档位上前进/后退一格(用于 Cmd/Ctrl +/- 快捷键)。
37
+ * 先把当前值吸附到档位,再按方向移动一格,两端夹紧。
38
+ * @param {number|string} current 当前比例
39
+ * @param {number} dir +1 放大 / -1 缩小
40
+ * @returns {number} 新的预设值
41
+ */
42
+ export function stepPreset(current, dir) {
43
+ const snapped = snapToPreset(current);
44
+ const idx = DISPLAY_SCALE_PRESETS.indexOf(snapped);
45
+ const nextIdx = Math.max(0, Math.min(DISPLAY_SCALE_PRESETS.length - 1, idx + Math.sign(dir)));
46
+ return DISPLAY_SCALE_PRESETS[nextIdx];
47
+ }
@@ -0,0 +1,13 @@
1
+ // Extracted from helpers.js so pure session modules (sessionMerge/sessionManager) and node:test
2
+ // can import it without pulling helpers' Vite-only svg imports; helpers.js re-exports it to keep
3
+ // existing import paths unchanged (same pattern as autoApproveOptions.js).
4
+
5
+ /**
6
+ * Resolve the effective model name for a log request entry, preferring the
7
+ * server-reported model in `response.body.model` (authoritative under proxy
8
+ * hot-switch) over the client-supplied `body.model`. Returns null when both
9
+ * are missing — callers should fall back to a sensible default.
10
+ */
11
+ export function getEffectiveModel(request) {
12
+ return request?.response?.body?.model || request?.body?.model || null;
13
+ }