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.
- package/dist/assets/App-B224r-8M.js +2 -0
- package/dist/assets/{MdxEditorPanel-C5Q6uUyH.js → MdxEditorPanel-BUubiE6Y.js} +1 -1
- package/dist/assets/{Mobile-MoBp9c8k.js → Mobile-CKmfRRvo.js} +1 -1
- package/dist/assets/index-CjsQEQc2.js +2 -0
- package/dist/assets/seqResourceLoaders-C-T_EMiO.js +2 -0
- package/dist/assets/{seqResourceLoaders-CxuD1CYl.css → seqResourceLoaders-DFrHmgnK.css} +1 -1
- package/dist/index.html +1 -1
- package/package.json +2 -1
- package/server/lib/log-management.js +1 -0
- package/server/lib/log-watcher.js +29 -3
- package/server/lib/stats-worker.js +21 -2
- package/server/lib/v2/adapter.js +123 -18
- package/server/lib/v2/journal.js +9 -5
- package/server/lib/v2/jsonl-read.js +127 -0
- package/server/lib/v2/live-feed.js +222 -20
- package/server/lib/v2/meta-rows.js +361 -0
- package/server/lib/v2/replay.js +5 -5
- package/server/lib/v2/session-select.js +69 -2
- package/server/lib/v2/v2-writer.js +15 -0
- package/server/lib/wire-compress.js +167 -0
- package/server/routes/events.js +96 -26
- package/server/routes/im.js +1 -1
- package/server/routes/logs.js +15 -12
- package/server/routes/v2.js +60 -0
- package/server/routes/workspaces.js +7 -6
- package/server/server.js +23 -1
- package/server/workspace-registry.js +5 -0
- package/src/utils/apiUrl.js +26 -0
- package/src/utils/askFallback.js +21 -0
- package/src/utils/askOptionDesc.js +55 -0
- package/src/utils/askPortalMatcher.js +54 -0
- package/src/utils/autoApproveOptions.js +27 -0
- package/src/utils/avatarAnimationPostPass.js +49 -0
- package/src/utils/builtinPresets.js +18 -0
- package/src/utils/clearCheckpoint.js +7 -0
- package/src/utils/commandValidator.js +45 -0
- package/src/utils/contentFilter.js +620 -0
- package/src/utils/contextRaw.js +18 -0
- package/src/utils/contextSidebarNavigation.js +16 -0
- package/src/utils/contextTurns.js +117 -0
- package/src/utils/displayScaleHelper.js +47 -0
- package/src/utils/effectiveModel.js +13 -0
- package/src/utils/entry-slim.js +563 -0
- package/src/utils/entryCache.js +144 -0
- package/src/utils/errorReport.js +6 -0
- package/src/utils/fileExpandedPathsStorage.js +70 -0
- package/src/utils/fileIcons.jsx +36 -0
- package/src/utils/fileOpen.js +37 -0
- package/src/utils/formatters.js +48 -0
- package/src/utils/gitApi.js +50 -0
- package/src/utils/gitTreeBuilder.js +19 -0
- package/src/utils/helpers.js +846 -0
- package/src/utils/identityHeal.js +99 -0
- package/src/utils/imConnState.js +59 -0
- package/src/utils/imOrigin.js +24 -0
- package/src/utils/imTr.js +7 -0
- package/src/utils/imageCompress.js +83 -0
- package/src/utils/imageDownscale.js +28 -0
- package/src/utils/imageResize.js +112 -0
- package/src/utils/ingestPipeline.js +47 -0
- package/src/utils/lazyWithReload.js +53 -0
- package/src/utils/markdown.js +30 -0
- package/src/utils/markdownIncremental.js +39 -0
- package/src/utils/markdownProfiler.js +113 -0
- package/src/utils/mdExtensionDetect.js +64 -0
- package/src/utils/memoryLinkParser.js +44 -0
- package/src/utils/modalMask.js +15 -0
- package/src/utils/monotime.js +6 -0
- package/src/utils/pinnedMenu.js +55 -0
- package/src/utils/presetShortcuts.js +14 -0
- package/src/utils/projectAlias.js +135 -0
- package/src/utils/promptClassifier.js +112 -0
- package/src/utils/promptDetect.js +196 -0
- package/src/utils/promptNav.js +60 -0
- package/src/utils/ptyChunkBuilder.js +251 -0
- package/src/utils/quickMenuHoverIntent.js +35 -0
- package/src/utils/rateLimitParser.js +119 -0
- package/src/utils/readResultPool.js +106 -0
- package/src/utils/refreshCachedItemProp.js +30 -0
- package/src/utils/requestType.js +208 -0
- package/src/utils/resizeCalc.js +21 -0
- package/src/utils/resolveLocalized.js +17 -0
- package/src/utils/searchApi.js +47 -0
- package/src/utils/searchReplace.js +51 -0
- package/src/utils/seqResourceLoaders.js +79 -0
- package/src/utils/sessionManager.js +471 -0
- package/src/utils/sessionMerge.js +180 -0
- package/src/utils/skillModalController.js +111 -0
- package/src/utils/skillsParser.js +116 -0
- package/src/utils/slashCommandLabels.js +80 -0
- package/src/utils/splitDragCalc.js +73 -0
- package/src/utils/stickyBottomController.js +643 -0
- package/src/utils/svgSanitize.js +48 -0
- package/src/utils/systemTags.js +47 -0
- package/src/utils/tClaude.js +20 -0
- package/src/utils/teamModalBuilder.js +351 -0
- package/src/utils/teamSessionParser.js +190 -0
- package/src/utils/teammateAvatars.js +194 -0
- package/src/utils/teammateDetector.js +121 -0
- package/src/utils/termDiag.js +114 -0
- package/src/utils/terminalClipboard.js +117 -0
- package/src/utils/terminalWriteQueue.js +398 -0
- package/src/utils/thinkingMerge.js +49 -0
- package/src/utils/toolCatalog.js +29 -0
- package/src/utils/toolResultBuilder.js +393 -0
- package/src/utils/toolResultClassifier.js +16 -0
- package/src/utils/toolResultCore.js +167 -0
- package/src/utils/toolsDiff.js +44 -0
- package/src/utils/toolsXmlFormatter.js +3 -0
- package/src/utils/ultraplanController.js +109 -0
- package/src/utils/ultraplanExperts.js +86 -0
- package/src/utils/ultraplanTemplates.js +154 -0
- package/src/utils/userImageRefs.js +49 -0
- package/src/utils/v3Assembler.js +112 -0
- package/src/utils/v3Rows.js +48 -0
- package/src/utils/voicePackPlayer.js +233 -0
- package/src/utils/webSearchGrouping.js +111 -0
- package/src/utils/workflowFormat.js +52 -0
- package/src/utils/workflowRuns.js +118 -0
- package/src/utils/workflowStore.js +94 -0
- package/dist/assets/App-DTkacfRW.js +0 -2
- package/dist/assets/index-Ac8vnV3v.js +0 -2
- package/dist/assets/seqResourceLoaders-Cd_TAXTb.js +0 -2
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Portal 决策:判断 inline AskQuestionForm(在 ChatMessage 里渲染的某条 tool_use)
|
|
3
|
+
* 是否应该 createPortal 到 ApprovalModal 的 askSlot。
|
|
4
|
+
*
|
|
5
|
+
* activeAskId 三种合法形态(与 server 端协议绑定,改一边必须改另一边):
|
|
6
|
+
*
|
|
7
|
+
* 1. `toolu_xxx` — SDK 模式 / 新版 Claude Code 透传的真实 tool_use_id
|
|
8
|
+
* → 走 strict 匹配:activeAskId === toolId
|
|
9
|
+
*
|
|
10
|
+
* 2. `__ask__` — LEGACY 老 server(pre-Map 协议)的单槽占位
|
|
11
|
+
* → 走 owner 通配:仅 owner-idx 锁定的那条 ChatMessage(lastPendingAskId === toolId)命中
|
|
12
|
+
*
|
|
13
|
+
* 3. `ask_${ts}_${rnd}` — 老 Claude Code PreToolUse hook payload 不带 tool_use_id 时
|
|
14
|
+
* server.js 自生成的 fallback id(修复 modal 标题在但内容空白的根因)
|
|
15
|
+
* → 走 owner 通配:与 __ask__ 同语义
|
|
16
|
+
*
|
|
17
|
+
* 协议锚点:
|
|
18
|
+
* - server 端 fallback id 生成:server.js(搜索 `ask_${Date.now()}` 定位)
|
|
19
|
+
* - server 端 LEGACY 占位推送:server.js 推送 ask-hook-pending 事件时 id 为 '__ask__'
|
|
20
|
+
* - 前端 setState pendingAsk:src/components/chat/ChatView.jsx
|
|
21
|
+
*
|
|
22
|
+
* 改 server 端 fallback id 格式时,必须同步更新此文件的 isFallbackId 检测。
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
const FALLBACK_ID_PREFIX = 'ask_';
|
|
26
|
+
const LEGACY_PLACEHOLDER_ID = '__ask__';
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* True when the given pending-ask id is a placeholder that can never equal a real
|
|
30
|
+
* tool_use id: the LEGACY single-slot '__ask__' or a server-generated 'ask_<ts>_<rnd>'
|
|
31
|
+
* fallback id. Consumers (e.g. resolveAskQuestions) use this to apply the same
|
|
32
|
+
* owner-wildcard semantics as shouldPortalAskForm on the legacy paths.
|
|
33
|
+
*/
|
|
34
|
+
export function isPlaceholderAskId(id) {
|
|
35
|
+
return id === LEGACY_PLACEHOLDER_ID
|
|
36
|
+
|| (typeof id === 'string' && id.startsWith(FALLBACK_ID_PREFIX));
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* @param {*} activeAskId ApprovalPortalContext.Consumer 提供的 activeAskId(modal 当前 active ask 的 id)
|
|
41
|
+
* @param {*} toolId 当前 ChatMessage 里 tool_use 块的 id(toolu_xxx)
|
|
42
|
+
* @param {*} lastPendingAskId ChatMessage 收到的 owner-idx 派生信号;非 owner 永远为 null
|
|
43
|
+
* @returns {boolean} true 表示当前 ChatMessage 应该 portal 到 askSlot
|
|
44
|
+
*/
|
|
45
|
+
export function shouldPortalAskForm(activeAskId, toolId, lastPendingAskId) {
|
|
46
|
+
if (activeAskId == null) return false;
|
|
47
|
+
// strict:SDK / 新 Claude Code 真实 tool_use_id
|
|
48
|
+
if (String(activeAskId) === String(toolId)) return true;
|
|
49
|
+
// owner 通配:__ask__(LEGACY 老 server)∪ ask_*(server fallback)
|
|
50
|
+
// 必须同时满足 owner-idx 锁定(lastPendingAskId === toolId),否则会让历史所有真实 toolId
|
|
51
|
+
// 都被通配命中,重现旧的双份 portal bug
|
|
52
|
+
if (isPlaceholderAskId(activeAskId) && lastPendingAskId === toolId) return true;
|
|
53
|
+
return false;
|
|
54
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
// 自动审批档位唯一事实源 —— 全部消费点共用同一组档位,防止各处字面量发散:
|
|
2
|
+
// 1. TerminalPanel 终端工具栏四芒星快捷菜单(权限/Plan 两行级联档位)
|
|
3
|
+
// 2. ChatInputBar 对话输入框四芒星快捷菜单(隐藏终端时,同款两行)
|
|
4
|
+
// 3. AppHeader 设置抽屉的权限/Plan 两个 Select
|
|
5
|
+
// 4. Mobile 设置面板的权限/Plan 两个 Select
|
|
6
|
+
// 三态语义(持久化于 preferences.autoApproveSeconds / approvalModal.planAutoApproveSeconds):
|
|
7
|
+
// 0 = 关闭(手动审批)
|
|
8
|
+
// > 0 = 倒计时该秒数后自动批准
|
|
9
|
+
// -1 = 免审批(AUTO_APPROVE_INSTANT):请求到达即放行,从源头绕过审批面板
|
|
10
|
+
// 本模块不依赖 helpers.js(它带 .svg?raw 等 Vite 专属 import),保持 node --test 可直接引用。
|
|
11
|
+
export const AUTO_APPROVE_INSTANT = -1;
|
|
12
|
+
|
|
13
|
+
export const PERM_AUTO_APPROVE_OPTIONS = [0, 3, 5, 10, AUTO_APPROVE_INSTANT];
|
|
14
|
+
export const PLAN_AUTO_APPROVE_OPTIONS = [0, 10, 30, 60, AUTO_APPROVE_INSTANT];
|
|
15
|
+
|
|
16
|
+
// 单个档位值 -> 显示文案;t 由调用方注入,避免本模块依赖前端 i18n。
|
|
17
|
+
// 档位之外的历史值(如 Plan 旧 3/5)同样落在 `${v}s` 分支正常显示。
|
|
18
|
+
export function autoApproveValueLabel(v, t) {
|
|
19
|
+
if (v === AUTO_APPROVE_INSTANT) return t('ui.permission.autoApprove.instant');
|
|
20
|
+
if (!v) return t('ui.permission.autoApprove.off');
|
|
21
|
+
return `${v}s`;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// 档位数组 -> antd Select options
|
|
25
|
+
export function autoApproveSelectOptions(values, t) {
|
|
26
|
+
return values.map(v => ({ value: v, label: autoApproveValueLabel(v, t) }));
|
|
27
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { shouldAnimateTeammateAvatar, pickAvatarAnimationTargets } from './teammateAvatars';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Avatar animation loading strategy — post-pass applied at the end of
|
|
6
|
+
* ChatView.buildAllItems, once every item (and the out-of-band Last Response
|
|
7
|
+
* timestamp) is known. Teammate rows animate their one-shot draw-in only when
|
|
8
|
+
* within the 60s window of the newest item's timestamp; the single newest
|
|
9
|
+
* teammate row always animates ("welcome flourish" on historic logs). Losers
|
|
10
|
+
* get cloneElement({ animateAvatar: false }) — winners keep their original
|
|
11
|
+
* element reference so cached elements skip reconciliation entirely.
|
|
12
|
+
*
|
|
13
|
+
* The flags are frozen per build: the window is measured against the newest
|
|
14
|
+
* item's timestamp, NOT wall clock (do not "fix" with Date.now()); they
|
|
15
|
+
* refresh whenever new data rebuilds the list.
|
|
16
|
+
*
|
|
17
|
+
* @param {Array} items - freshly built ChatMessage element array; mutated in place
|
|
18
|
+
* @param {string|null} lastResponseTs - session.entryTimestamp of the Last
|
|
19
|
+
* Response block, which lives OUTSIDE items but must count toward "newest"
|
|
20
|
+
* @returns {Array} the same array, with stale teammate rows cloned to static
|
|
21
|
+
*/
|
|
22
|
+
export function applyAvatarAnimationTargets(items, lastResponseTs = null) {
|
|
23
|
+
const scanEntries = items.map((item) => ({
|
|
24
|
+
ts: item?.props?.timestamp,
|
|
25
|
+
isTeammateAvatar: isTeammateAvatarItem(item?.props),
|
|
26
|
+
}));
|
|
27
|
+
if (lastResponseTs) scanEntries.push({ ts: lastResponseTs, isTeammateAvatar: false });
|
|
28
|
+
const { latestMs, newestTeammateIdx } = pickAvatarAnimationTargets(scanEntries);
|
|
29
|
+
if (newestTeammateIdx === -1) return items;
|
|
30
|
+
for (let i = 0; i < items.length; i++) {
|
|
31
|
+
if (!scanEntries[i].isTeammateAvatar) continue;
|
|
32
|
+
const animate = i === newestTeammateIdx ||
|
|
33
|
+
shouldAnimateTeammateAvatar(items[i].props.timestamp, latestMs);
|
|
34
|
+
if (!animate) items[i] = React.cloneElement(items[i], { animateAvatar: false });
|
|
35
|
+
}
|
|
36
|
+
return items;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// Mirrors ChatMessage.render()'s THREE teammate-avatar branches:
|
|
40
|
+
// renderSubAgentChatMessage (role 'sub-agent-chat'), renderSubAgentMessage
|
|
41
|
+
// (role 'sub-agent' — currently never constructed, covered defensively), and
|
|
42
|
+
// renderTeammateMessage (role 'teammate-message'). If ChatMessage gains a new
|
|
43
|
+
// teammate-avatar branch, add it here — rows missed by this predicate default
|
|
44
|
+
// to animated forever.
|
|
45
|
+
export function isTeammateAvatarItem(props) {
|
|
46
|
+
if (!props) return false;
|
|
47
|
+
return ((props.role === 'sub-agent-chat' || props.role === 'sub-agent') && props.isTeammate)
|
|
48
|
+
|| props.role === 'teammate-message';
|
|
49
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 内置预置快捷方式。
|
|
3
|
+
*
|
|
4
|
+
* builtinId 跨版本不变,用于追踪用户的删除/编辑。
|
|
5
|
+
* teamName / description 是 i18n key,渲染时通过 t() 解析。
|
|
6
|
+
*/
|
|
7
|
+
export const BUILTIN_PRESETS = [
|
|
8
|
+
{
|
|
9
|
+
builtinId: 'codereview-5',
|
|
10
|
+
teamName: 'ui.preset.codeReview5.name',
|
|
11
|
+
description: 'ui.preset.codeReview5.desc',
|
|
12
|
+
},
|
|
13
|
+
// 历史遗留 builtinId 已连同 i18n key 一并删除(用户反馈不常用):
|
|
14
|
+
// - 'scout-regiment' / ui.preset.scoutRegiment.*
|
|
15
|
+
// - 'codereview-2' / ui.preset.codeReview2.*
|
|
16
|
+
// 若老用户的 preset 列表里已保存这些条目,i18n key 缺失时 t() 会回显原始 key,
|
|
17
|
+
// 视觉上难看但不崩;用户可在管理弹窗里手动删除。
|
|
18
|
+
];
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
// Re-export shell — the implementations moved VERBATIM to the shared client-safe
|
|
2
|
+
// module server/lib/session-boundary.js in wire-v2 step S1 so the server-side
|
|
3
|
+
// conversation router (S2+) and the client use ONE source of truth for session
|
|
4
|
+
// boundaries (docs/refactor/WIRE_FORMAT_V2_PLAN.md). Existing client imports of
|
|
5
|
+
// './clearCheckpoint.js' keep working through this shell; new code should import
|
|
6
|
+
// from server/lib/session-boundary.js directly.
|
|
7
|
+
export { isPostClearCheckpoint, isCompactContinuation, isSessionBoundary } from '../../server/lib/session-boundary.js';
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* File and command validation utilities.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
const IMAGE_EXTS = new Set(['png', 'jpg', 'jpeg', 'gif', 'svg', 'bmp', 'ico', 'icns', 'webp', 'avif']);
|
|
6
|
+
|
|
7
|
+
export function isImageFile(path) {
|
|
8
|
+
const ext = (path || '').split('.').pop().toLowerCase();
|
|
9
|
+
return IMAGE_EXTS.has(ext);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Regex matching Bash commands that may mutate filesystem or git state.
|
|
14
|
+
* 命中任一即触发文件浏览器与 git 面板自动刷新(ToolFileChangeController 的 Bash 路径依赖)。
|
|
15
|
+
*
|
|
16
|
+
* 覆盖类别:
|
|
17
|
+
* - delete:rm(含 rm -rf)、rmdir(删空目录)、unlink(POSIX 单文件删除)、find ... -delete
|
|
18
|
+
* - create/move:mkdir、mv、cp、touch、ln
|
|
19
|
+
* - metadata:chmod、chown
|
|
20
|
+
* - package/archive:npm/yarn/pnpm install/uninstall、pip install、tar、unzip、curl -o、wget
|
|
21
|
+
* - redirect write:> 与 >>(排除 2>、>= 等由 [^>]>(?!>)/>> 处理)
|
|
22
|
+
* - git mutating:checkout/reset/stash/merge/rebase/cherry-pick/restore/clean/rm
|
|
23
|
+
*
|
|
24
|
+
* 设计取舍(trade-off):
|
|
25
|
+
* \b 单词边界不能区分"作为命令"还是"作为参数/字面量",因此 `echo unlink` 之类
|
|
26
|
+
* 会被命中。文件浏览器额外刷新成本极低(一次 GET),宁可多刷不漏刷。
|
|
27
|
+
*
|
|
28
|
+
* find -delete 子表达式 `\bfind\b[^|;&\n]*-delete\b` 限定单条命令内,
|
|
29
|
+
* 避免 `grep find . | echo "-delete"` 之类的跨管道/分号误匹配。
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* isMutatingCommand('rm -rf node_modules') // true
|
|
33
|
+
* isMutatingCommand('find . -name "*.log" -delete') // true
|
|
34
|
+
* isMutatingCommand('git status') // false
|
|
35
|
+
* isMutatingCommand('echo hello') // false
|
|
36
|
+
*/
|
|
37
|
+
const MUTATING_CMD_RE = /\b(rm|rmdir|unlink|mkdir|mv|cp|touch|chmod|chown|ln|git\s+(checkout|reset|stash|merge|rebase|cherry-pick|restore|clean|rm)|npm\s+(install|uninstall|ci)|yarn\s+(add|remove)|pnpm\s+(add|remove|install)|pip\s+install|tar|unzip|curl\s+-[^\s]*o|wget)\b|\bfind\b[^|;&\n]*-delete\b|[^>]>(?!>)|>>/;
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* @param {string} cmd Bash 命令字符串
|
|
41
|
+
* @returns {boolean} true 表示命令可能修改文件树或 git 状态
|
|
42
|
+
*/
|
|
43
|
+
export function isMutatingCommand(cmd) {
|
|
44
|
+
return MUTATING_CMD_RE.test(cmd);
|
|
45
|
+
}
|