cc-viewer 1.7.23 → 1.8.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.
- package/README.md +19 -0
- package/cli.js +92 -11
- package/concepts/ar/GlobalSettings.md +2 -2
- package/concepts/da/GlobalSettings.md +2 -2
- package/concepts/de/GlobalSettings.md +2 -2
- package/concepts/en/GlobalSettings.md +2 -2
- package/concepts/es/GlobalSettings.md +2 -2
- package/concepts/fr/GlobalSettings.md +2 -2
- package/concepts/it/GlobalSettings.md +2 -2
- package/concepts/ja/GlobalSettings.md +2 -2
- package/concepts/ko/GlobalSettings.md +2 -2
- package/concepts/no/GlobalSettings.md +2 -2
- package/concepts/pl/GlobalSettings.md +2 -2
- package/concepts/pt-BR/GlobalSettings.md +2 -2
- package/concepts/ru/GlobalSettings.md +2 -2
- package/concepts/th/GlobalSettings.md +2 -2
- package/concepts/tr/GlobalSettings.md +2 -2
- package/concepts/uk/GlobalSettings.md +2 -2
- package/concepts/zh/GlobalSettings.md +2 -2
- package/concepts/zh-TW/GlobalSettings.md +2 -2
- package/dist/assets/{App-CusqoEAB.js → App-CCu0y2Cq.js} +2 -2
- package/dist/assets/{MdxEditorPanel-e5DlfcqJ.js → MdxEditorPanel-BBhgTmDk.js} +1 -1
- package/dist/assets/{Mobile-B8xwCLgr.js → Mobile-vN4lyiaz.js} +1 -1
- package/dist/assets/{ProxyStatsModal-_w677xPM.js → ProxyStatsModal-BOflqr0R.js} +1 -1
- package/dist/assets/index-C3BRHDVF.js +2 -0
- package/dist/assets/seqResourceLoaders-DI0G5nu1.css +41 -0
- package/dist/assets/seqResourceLoaders-DpYqp6SP.js +2 -0
- package/dist/index.html +1 -1
- package/findcc.js +17 -8
- package/node_modules/@ccv/core/package.json +13 -0
- package/{server/lib → node_modules/@ccv/core/src}/approval-modal-prefs.js +1 -1
- package/node_modules/@ccv/core/src/clearCheckpoint.js +7 -0
- package/{src/utils → node_modules/@ccv/core/src}/contentFilter.js +207 -141
- package/{server/lib → node_modules/@ccv/core/src}/context-rules.js +2 -2
- package/{server/lib → node_modules/@ccv/core/src}/delta-reconstructor.js +60 -4
- package/{server/lib → node_modules/@ccv/core/src}/error-report.js +5 -4
- package/{server/lib → node_modules/@ccv/core/src}/session-boundary.js +3 -3
- package/{src/utils → node_modules/@ccv/core/src}/teammateDetector.js +9 -0
- package/{server/lib → node_modules/@ccv/core/src}/tools-xml-formatter.js +3 -3
- package/{server/lib → node_modules/@ccv/core/src}/v2-transcript-normalizer.js +1 -1
- package/{server/lib → node_modules/@ccv/core/src}/voice-pack-events.js +2 -2
- package/package.json +11 -97
- package/server/_paths.js +28 -7
- package/server/i18n.js +60 -0
- package/server/interceptor.js +36 -11
- package/server/lib/adapters/dingtalk-adapter.js +2 -2
- package/server/lib/adapters/discord-adapter.js +2 -2
- package/server/lib/adapters/feishu-adapter.js +2 -2
- package/server/lib/adapters/wecom-adapter.js +2 -2
- package/server/lib/approval-policy.js +29 -0
- package/server/lib/{ask-store.js → ask/ask-store.js} +3 -3
- package/server/lib/{perm-bridge.js → ask/perm-bridge.js} +5 -5
- package/server/lib/chat-queue.js +341 -0
- package/server/lib/cli-inject.js +1 -1
- package/server/lib/context-watcher.js +3 -3
- package/server/lib/create_system_prompt.js +0 -9
- package/server/lib/enrich-plan-input.js +1 -1
- package/server/lib/ensure-hooks.js +2 -2
- package/server/lib/file-access-policy.js +6 -1
- package/server/lib/file-api.js +17 -1
- package/server/lib/{dingtalk-bridge.js → im/dingtalk-bridge.js} +1 -1
- package/server/lib/{im-append-system.js → im/im-append-system.js} +5 -13
- package/server/lib/{im-bridge-core.js → im/im-bridge-core.js} +12 -6
- package/server/lib/{im-config.js → im/im-config.js} +1 -1
- package/server/lib/im/im-deny.js +4 -0
- package/server/lib/{im-lang.js → im/im-lang.js} +1 -1
- package/server/lib/{im-lock.js → im/im-lock.js} +2 -2
- package/server/lib/{im-process-manager.js → im/im-process-manager.js} +1 -1
- package/server/lib/{im-senders.js → im/im-senders.js} +1 -1
- package/server/lib/{im-skills.js → im/im-skills.js} +2 -2
- package/server/lib/interceptor-core.js +8 -5
- package/server/lib/kv-cache-analyzer.js +6 -5
- package/server/lib/launch-config.js +321 -0
- package/server/lib/log-file-utils.js +21 -0
- package/server/lib/log-management.js +6 -17
- package/server/lib/log-stream.js +1 -1
- package/server/lib/log-watcher.js +1 -1
- package/server/lib/model-system-prompts.js +1 -1
- package/server/lib/prefs-store.js +2 -2
- package/server/lib/project-prefs.js +6 -6
- package/server/lib/project-state.js +15 -0
- package/server/lib/{proxy-retry.js → proxy/proxy-retry.js} +2 -2
- package/server/lib/{proxy-stats.js → proxy/proxy-stats.js} +3 -3
- package/server/lib/sdk-adapter.js +6 -74
- package/server/lib/sdk-manager.js +383 -278
- package/server/lib/skills-api.js +1 -1
- package/server/lib/spawn-model-resolver.js +21 -6
- package/server/lib/stats-worker.js +2 -2
- package/server/lib/system-prompt-files.js +11 -10
- package/server/lib/system-prompt-render.js +23 -7
- package/server/lib/system-prompt-snapshots.js +452 -0
- package/server/lib/updater.js +63 -3
- package/server/lib/user-prompt-extract.js +5 -5
- package/server/lib/v2/adapter.js +3 -3
- package/server/lib/v2/conversation-store.js +1 -1
- package/server/lib/v2/convert.js +3 -3
- package/server/lib/v2/jsonl-read.js +1 -1
- package/server/lib/v2/live-feed.js +3 -3
- package/server/lib/v2/meta-rows.js +3 -3
- package/server/lib/v2/replay.js +1 -1
- package/server/lib/v2/session-list.js +1 -1
- package/server/lib/v2/session-owner.js +1 -1
- package/server/lib/v2/v2-writer.js +26 -1
- package/server/lib/v2/verify.js +1 -1
- package/server/lib/voice-pack-manager.js +4 -5
- package/server/lib/wire-compress.js +1 -1
- package/server/proxy.js +5 -5
- package/server/pty-manager.js +282 -184
- package/server/routes/ask-perm.js +1 -1
- package/server/routes/dingtalk.js +3 -3
- package/server/routes/events.js +2 -2
- package/server/routes/im.js +5 -5
- package/server/routes/preferences.js +3 -3
- package/server/routes/workspaces.js +1 -1
- package/server/server.js +207 -58
- package/server/system-prompt-templates/systemPromptModel.md +0 -8
- package/server/system-prompt-templates/systemPromptVariables.ar.md +0 -7
- package/server/system-prompt-templates/systemPromptVariables.da.md +0 -7
- package/server/system-prompt-templates/systemPromptVariables.de.md +0 -7
- package/server/system-prompt-templates/systemPromptVariables.es.md +0 -7
- package/server/system-prompt-templates/systemPromptVariables.fr.md +0 -7
- package/server/system-prompt-templates/systemPromptVariables.it.md +0 -7
- package/server/system-prompt-templates/systemPromptVariables.ja.md +0 -7
- package/server/system-prompt-templates/systemPromptVariables.ko.md +0 -7
- package/server/system-prompt-templates/systemPromptVariables.md +0 -7
- package/server/system-prompt-templates/systemPromptVariables.no.md +0 -7
- package/server/system-prompt-templates/systemPromptVariables.pl.md +0 -7
- package/server/system-prompt-templates/systemPromptVariables.pt-BR.md +0 -7
- package/server/system-prompt-templates/systemPromptVariables.ru.md +0 -7
- package/server/system-prompt-templates/systemPromptVariables.th.md +0 -7
- package/server/system-prompt-templates/systemPromptVariables.tr.md +0 -7
- package/server/system-prompt-templates/systemPromptVariables.uk.md +0 -7
- package/server/system-prompt-templates/systemPromptVariables.zh-TW.md +0 -7
- package/server/system-prompt-templates/systemPromptVariables.zh.md +0 -7
- package/dist/assets/index-D6FmFsIz.js +0 -2
- package/dist/assets/seqResourceLoaders-3K77Znll.js +0 -2
- package/dist/assets/seqResourceLoaders-BgD_Rwvc.css +0 -41
- package/src/utils/apiUrl.js +0 -26
- package/src/utils/askFallback.js +0 -21
- package/src/utils/askOptionDesc.js +0 -55
- package/src/utils/askPortalMatcher.js +0 -54
- package/src/utils/autoApproveOptions.js +0 -27
- package/src/utils/avatarAnimationPostPass.js +0 -49
- package/src/utils/builtinPresets.js +0 -18
- package/src/utils/clearCheckpoint.js +0 -7
- package/src/utils/commandValidator.js +0 -45
- package/src/utils/contextRaw.js +0 -18
- package/src/utils/contextSidebarNavigation.js +0 -16
- package/src/utils/contextTurns.js +0 -117
- package/src/utils/displayScaleHelper.js +0 -47
- package/src/utils/effectiveModel.js +0 -17
- package/src/utils/entry-slim.js +0 -563
- package/src/utils/entryCache.js +0 -144
- package/src/utils/errorReport.js +0 -6
- package/src/utils/fileExpandedPathsStorage.js +0 -70
- package/src/utils/fileIcons.jsx +0 -36
- package/src/utils/fileOpen.js +0 -37
- package/src/utils/formatters.js +0 -48
- package/src/utils/gitApi.js +0 -50
- package/src/utils/gitTreeBuilder.js +0 -19
- package/src/utils/helpers.js +0 -854
- package/src/utils/identityHeal.js +0 -108
- package/src/utils/imConnState.js +0 -59
- package/src/utils/imOrigin.js +0 -24
- package/src/utils/imTr.js +0 -7
- package/src/utils/imageCompress.js +0 -83
- package/src/utils/imageDownscale.js +0 -28
- package/src/utils/imageResize.js +0 -112
- package/src/utils/ingestPipeline.js +0 -47
- package/src/utils/isProxyMode.js +0 -11
- package/src/utils/lazyWithReload.js +0 -53
- package/src/utils/markdown.js +0 -30
- package/src/utils/markdownIncremental.js +0 -39
- package/src/utils/markdownProfiler.js +0 -113
- package/src/utils/mdExtensionDetect.js +0 -64
- package/src/utils/memoryLinkParser.js +0 -44
- package/src/utils/modalMask.js +0 -15
- package/src/utils/modelSuggestions.js +0 -48
- package/src/utils/monotime.js +0 -6
- package/src/utils/pinnedMenu.js +0 -55
- package/src/utils/presetShortcuts.js +0 -14
- package/src/utils/projectAlias.js +0 -135
- package/src/utils/promptClassifier.js +0 -112
- package/src/utils/promptDetect.js +0 -196
- package/src/utils/promptNav.js +0 -60
- package/src/utils/ptyChunkBuilder.js +0 -251
- package/src/utils/quickMenuHoverIntent.js +0 -35
- package/src/utils/rateLimitParser.js +0 -119
- package/src/utils/readResultPool.js +0 -106
- package/src/utils/refreshCachedItemProp.js +0 -30
- package/src/utils/resizeCalc.js +0 -21
- package/src/utils/resolveLocalized.js +0 -17
- package/src/utils/searchApi.js +0 -47
- package/src/utils/searchReplace.js +0 -51
- package/src/utils/seqResourceLoaders.js +0 -79
- package/src/utils/sessionManager.js +0 -482
- package/src/utils/sessionMerge.js +0 -239
- package/src/utils/skillModalController.js +0 -111
- package/src/utils/skillsParser.js +0 -116
- package/src/utils/slashCommandLabels.js +0 -80
- package/src/utils/splitDragCalc.js +0 -73
- package/src/utils/stickyBottomController.js +0 -643
- package/src/utils/svgSanitize.js +0 -48
- package/src/utils/systemTags.js +0 -47
- package/src/utils/tClaude.js +0 -20
- package/src/utils/teamModalBuilder.js +0 -351
- package/src/utils/teamSessionParser.js +0 -190
- package/src/utils/teammateAvatars.js +0 -194
- package/src/utils/termDiag.js +0 -114
- package/src/utils/terminalClipboard.js +0 -117
- package/src/utils/terminalWriteQueue.js +0 -398
- package/src/utils/thinkingMerge.js +0 -49
- package/src/utils/toolCatalog.js +0 -30
- package/src/utils/toolResultBuilder.js +0 -411
- package/src/utils/toolResultClassifier.js +0 -16
- package/src/utils/toolResultCore.js +0 -194
- package/src/utils/toolsDiff.js +0 -44
- package/src/utils/toolsXmlFormatter.js +0 -3
- package/src/utils/ultraplanController.js +0 -109
- package/src/utils/ultraplanExperts.js +0 -86
- package/src/utils/ultraplanTemplates.js +0 -154
- package/src/utils/userImageRefs.js +0 -49
- package/src/utils/v3Assembler.js +0 -125
- package/src/utils/v3Rows.js +0 -49
- package/src/utils/voicePackPlayer.js +0 -233
- package/src/utils/webSearchGrouping.js +0 -111
- package/src/utils/workflowFormat.js +0 -52
- package/src/utils/workflowRuns.js +0 -118
- package/src/utils/workflowStore.js +0 -94
- /package/{src/utils → node_modules/@ccv/core/src}/requestType.js +0 -0
- /package/server/lib/{ask-bridge.js → ask/ask-bridge.js} +0 -0
- /package/server/lib/{ask-constants.js → ask/ask-constants.js} +0 -0
- /package/server/lib/{ask-reaper.js → ask/ask-reaper.js} +0 -0
- /package/server/lib/{dingtalk-config.js → im/dingtalk-config.js} +0 -0
- /package/server/lib/{im-log-watcher.js → im/im-log-watcher.js} +0 -0
- /package/server/lib/{proxy-env.js → proxy/proxy-env.js} +0 -0
- /package/server/lib/{proxy-errors.js → proxy/proxy-errors.js} +0 -0
package/server/lib/updater.js
CHANGED
|
@@ -42,6 +42,51 @@ export function detectHomebrewInstall(dirOverride, realpathImpl = realpathSync)
|
|
|
42
42
|
return normalized.slice(0, idx); // 返回 brew prefix
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
+
// Detect whether cc-viewer was installed via a pnpm global install (`pnpm add -g`).
|
|
46
|
+
// pnpm's global layout: <root>/global/<id>/node_modules/.pnpm/cc-viewer@<version>/node_modules/cc-viewer/
|
|
47
|
+
// - macOS default root: ~/Library/pnpm (PNPM_HOME)
|
|
48
|
+
// - Linux default root: ~/.local/share/pnpm
|
|
49
|
+
// - Windows default root: %LOCALAPPDATA%\pnpm
|
|
50
|
+
// - custom PNPM_HOME / global-dir: any path, but the `.pnpm` virtual-store segment stays fixed.
|
|
51
|
+
// Detection key: the `/.pnpm/cc-viewer@` virtual-store segment. npm never creates a `.pnpm`
|
|
52
|
+
// directory and the `pkg@<version>`-style segment only occurs inside pnpm-managed trees, so this
|
|
53
|
+
// is reliable regardless of where PNPM_HOME lives — a plain `/pnpm/` segment check would misfire
|
|
54
|
+
// on `npm i -g --prefix ~/Library/pnpm` installs. The marker covers `pnpm add -g` installs,
|
|
55
|
+
// `pnpm dlx` caches, and pnpm projects running cc-viewer from their own node_modules — all of
|
|
56
|
+
// them must NOT be upgraded via `npm install -g` (dual-channel pollution). The module's own
|
|
57
|
+
// realpath always flows through the virtual store (bin-shim symlinks resolve there too), so no
|
|
58
|
+
// PNPM_HOME env read is needed.
|
|
59
|
+
// dirOverride is for unit-test injection; realpathImpl likewise.
|
|
60
|
+
// Fail-safe: realpath throwing / path mismatch -> null (upstream falls back to the default npm
|
|
61
|
+
// path, never an unintended upgrade).
|
|
62
|
+
export function detectPnpmGlobalInstall(dirOverride, realpathImpl = realpathSync) {
|
|
63
|
+
const dir = dirOverride || __dirname;
|
|
64
|
+
let real;
|
|
65
|
+
try {
|
|
66
|
+
real = realpathImpl(dir);
|
|
67
|
+
} catch {
|
|
68
|
+
real = dir;
|
|
69
|
+
}
|
|
70
|
+
// Normalize Windows backslashes (forward slashes keep indexOf portable)
|
|
71
|
+
const normalized = real.replace(/\\/g, '/');
|
|
72
|
+
const marker = '/.pnpm/cc-viewer@';
|
|
73
|
+
const idx = normalized.indexOf(marker);
|
|
74
|
+
if (idx === -1) return null;
|
|
75
|
+
// The segment after `cc-viewer@` must be version-shaped (same regex as the brew detector):
|
|
76
|
+
// rejects dev-clone / backup paths that merely contain the literal marker text, and tag-style
|
|
77
|
+
// segments like `cc-viewer@nightly` (pnpm tag installs — same caveat as the brew HEAD comment).
|
|
78
|
+
const after = normalized.slice(idx + marker.length);
|
|
79
|
+
if (!/^\d[\w.\-+]*\//.test(after)) return null;
|
|
80
|
+
// Return the pnpm root (PNPM_HOME / custom global-dir): the path up to the first `/global/`
|
|
81
|
+
// segment; without one (e.g. a dlx cache) strip the trailing `/node_modules` and return that.
|
|
82
|
+
const globalIdx = normalized.indexOf('/global/');
|
|
83
|
+
if (globalIdx !== -1) return normalized.slice(0, globalIdx);
|
|
84
|
+
const preMarker = normalized.slice(0, idx);
|
|
85
|
+
return preMarker.endsWith('/node_modules')
|
|
86
|
+
? preMarker.slice(0, -'/node_modules'.length)
|
|
87
|
+
: preMarker;
|
|
88
|
+
}
|
|
89
|
+
|
|
45
90
|
const CHECK_INTERVAL = 4 * 60 * 60 * 1000; // 4 hours
|
|
46
91
|
const CACHE_DIR = join(getClaudeConfigDir(), 'cc-viewer');
|
|
47
92
|
const CACHE_FILE = join(CACHE_DIR, 'update-check.json');
|
|
@@ -138,10 +183,12 @@ export function isAnyCcvBusy({ currentPid, busy, portRange, lsofImpl } = {}) {
|
|
|
138
183
|
// undefined 或不传 = 走真探测。改用 !== undefined 比 hasOwnProperty 更稳,
|
|
139
184
|
// 避免 caller 用 `{ ...opts, brewPrefix: maybe }` 时 maybe 为 undefined
|
|
140
185
|
// 却被当显式传值,从而绕过自动检测,让 brew 用户被错误地走 npm 路径升级。
|
|
186
|
+
// pnpmRoot -- 测试注入。语义与 brewPrefix 完全相同:非 undefined = 显式覆盖(含 null/''),
|
|
187
|
+
// undefined = 走真探测 detectPnpmGlobalInstall()。
|
|
141
188
|
//
|
|
142
189
|
// 返回 status:
|
|
143
190
|
// disabled | skipped | skipped_test_context | latest | major_available | deferred_busy
|
|
144
|
-
// | brew_managed | upgrading_in_background | error
|
|
191
|
+
// | brew_managed | pnpm_managed | upgrading_in_background | error
|
|
145
192
|
export async function checkAndUpdate(options = {}) {
|
|
146
193
|
const fetchImpl = options.fetchImpl || fetch;
|
|
147
194
|
const spawnImpl = options.spawnImpl || realSpawn;
|
|
@@ -153,6 +200,11 @@ export async function checkAndUpdate(options = {}) {
|
|
|
153
200
|
const brewPrefix = options.brewPrefix !== undefined
|
|
154
201
|
? options.brewPrefix
|
|
155
202
|
: detectHomebrewInstall();
|
|
203
|
+
// pnpm 全局安装(pnpm add -g)→ 同样不能 npm install -g:会在 npm 全局前缀残留第二份
|
|
204
|
+
// cc-viewer(双渠道污染),改建议 pnpm add -g cc-viewer@<version>
|
|
205
|
+
const pnpmRoot = options.pnpmRoot !== undefined
|
|
206
|
+
? options.pnpmRoot
|
|
207
|
+
: detectPnpmGlobalInstall();
|
|
156
208
|
const currentVersion = getCurrentVersion();
|
|
157
209
|
|
|
158
210
|
// 跟随 Claude Code 全局配置
|
|
@@ -188,8 +240,8 @@ export async function checkAndUpdate(options = {}) {
|
|
|
188
240
|
const remoteVersion = data['dist-tags']?.latest;
|
|
189
241
|
|
|
190
242
|
// saveCheckTime 在所有分支前统一记录:4h 节流既避免 npm fetch 频繁,
|
|
191
|
-
// 也覆盖 brew_managed banner 的提示频率(stderr 一行 + SSE 一次足够,4h 后再提)。
|
|
192
|
-
// 故意不为 brew_managed 单独提速:banner 刷屏比慢提示更扰人,stderr 仍是侧通道。
|
|
243
|
+
// 也覆盖 brew_managed / pnpm_managed banner 的提示频率(stderr 一行 + SSE 一次足够,4h 后再提)。
|
|
244
|
+
// 故意不为 brew_managed / pnpm_managed 单独提速:banner 刷屏比慢提示更扰人,stderr 仍是侧通道。
|
|
193
245
|
saveCheckTime();
|
|
194
246
|
|
|
195
247
|
if (!remoteVersion) {
|
|
@@ -212,6 +264,14 @@ export async function checkAndUpdate(options = {}) {
|
|
|
212
264
|
return { status: 'brew_managed', currentVersion, remoteVersion, brewPrefix };
|
|
213
265
|
}
|
|
214
266
|
|
|
267
|
+
// pnpm 全局安装:不能 npm install -g(会在 npm 全局前缀造出第二份,双渠道污染)
|
|
268
|
+
// → 提示 pnpm add -g cc-viewer@<version>。同样必须放在 major_available 之前,
|
|
269
|
+
// 否则 pnpm 用户跨大版本时会被引导跑 npm i -g,触发我们正想杜绝的双渠道污染。
|
|
270
|
+
if (pnpmRoot) {
|
|
271
|
+
console.error(`[CC Viewer] ${t('update.pnpmManaged', { version: remoteVersion })}`);
|
|
272
|
+
return { status: 'pnpm_managed', currentVersion, remoteVersion, pnpmRoot };
|
|
273
|
+
}
|
|
274
|
+
|
|
215
275
|
// 跨大版本:仅提示
|
|
216
276
|
if (remote.major !== current.major) {
|
|
217
277
|
console.error(`[CC Viewer] ${t('update.majorAvailable', { version: remoteVersion })}`);
|
|
@@ -6,17 +6,17 @@
|
|
|
6
6
|
//
|
|
7
7
|
// NOTE: this is a deliberate server-side SUBSET of the frontend classifier.
|
|
8
8
|
// The full classification (synthetic prompts, secondary recycling, …) lives in
|
|
9
|
-
//
|
|
9
|
+
// @ccv/core/contentFilter:isSystemText — frontend (dist) and server are two
|
|
10
10
|
// separate bundles that cannot share a module, so only the rules that would
|
|
11
11
|
// LEAK into previews are mirrored here: system tags + cross-session teammate
|
|
12
12
|
// notifications.
|
|
13
13
|
import { openSync, readSync, closeSync } from 'node:fs';
|
|
14
14
|
|
|
15
15
|
// Cross-session / teammate protocol notification `type` whitelist (must match
|
|
16
|
-
//
|
|
16
|
+
// @ccv/core/contentFilter INTER_SESSION_NOTIFICATION_TYPES; add new types in
|
|
17
17
|
// BOTH places). One array derives the Set (brace scan) + the RegExp
|
|
18
18
|
// (isSystemText) so this file cannot drift internally.
|
|
19
|
-
// test/stats-worker-notification-filter.test.js guards frontend↔server sync.
|
|
19
|
+
// packages/app/test/stats-worker-notification-filter.test.js guards frontend↔server sync.
|
|
20
20
|
export const INTER_SESSION_TYPES = [
|
|
21
21
|
'idle_notification', 'shutdown_request', 'shutdown_response', 'shutdown_approved',
|
|
22
22
|
'teammate_terminated', 'plan_approval_request', 'plan_approval_response',
|
|
@@ -25,7 +25,7 @@ const INTER_SESSION_TYPES_SET = new Set(INTER_SESSION_TYPES);
|
|
|
25
25
|
const INTER_SESSION_TYPES_RE = new RegExp(`"type"\\s*:\\s*"(?:${INTER_SESSION_TYPES.join('|')})"`);
|
|
26
26
|
|
|
27
27
|
// CLI-synthesized prompts (HTTP role=user but not typed by a human): Recap /
|
|
28
|
-
// Title / Compact / Topic / Summary. Must match
|
|
28
|
+
// Title / Compact / Topic / Summary. Must match @ccv/core/contentFilter
|
|
29
29
|
// SYNTHETIC_PROMPTS (KEEP IN SYNC — same rule set, `^`-anchored on trimmed
|
|
30
30
|
// text so quoted user text is never swallowed). Without this filter they leak
|
|
31
31
|
// into the "all user prompts" preview (observed on real data: "The user
|
|
@@ -112,7 +112,7 @@ export function stripSystemTags(text) {
|
|
|
112
112
|
|
|
113
113
|
/**
|
|
114
114
|
* Extract the list of user prompt texts from a wire `messages` array.
|
|
115
|
-
* (Kept in sync with
|
|
115
|
+
* (Kept in sync with @ccv/core/contentFilter:classifyUserContent.)
|
|
116
116
|
*/
|
|
117
117
|
export function extractUserTexts(messages) {
|
|
118
118
|
const texts = [];
|
package/server/lib/v2/adapter.js
CHANGED
|
@@ -29,12 +29,12 @@
|
|
|
29
29
|
|
|
30
30
|
import { existsSync, readdirSync, readFileSync, statSync } from 'node:fs';
|
|
31
31
|
import { join, dirname, basename } from 'node:path';
|
|
32
|
-
import { reportSwallowed } from '
|
|
32
|
+
import { reportSwallowed } from '@ccv/core/error-report';
|
|
33
33
|
import { isMainAgentRequest } from '../interceptor-core.js';
|
|
34
34
|
import { readSession } from './replay.js';
|
|
35
35
|
import { iterateJsonlLines } from './jsonl-read.js';
|
|
36
36
|
import { isDiscardableSession } from './session-select.js';
|
|
37
|
-
import { LIVE_SESSION_MTIME_MS } from '../log-
|
|
37
|
+
import { LIVE_SESSION_MTIME_MS } from '../log-file-utils.js';
|
|
38
38
|
import { blobPath, isSupportedWireFormat } from './layout.js';
|
|
39
39
|
import { SingleFlight } from './singleflight.js';
|
|
40
40
|
import { listV2Sessions } from './session-list.js';
|
|
@@ -834,7 +834,7 @@ export async function scanV2Descriptors(sessionDir) {
|
|
|
834
834
|
// the old substring filter (`"mainAgent":true` && !`"teammate"`) also
|
|
835
835
|
// admitted sub/misc entries whose backfilled body LOOKED main-agent; the
|
|
836
836
|
// isMain ring drops those — intentional, more-correct behavior (pinned in
|
|
837
|
-
// test/v2-window-two-pass.test.js). Teammate-session main entries are
|
|
837
|
+
// packages/app/test/v2-window-two-pass.test.js). Teammate-session main entries are
|
|
838
838
|
// excluded by both (they carry the teammate tag / isMain=false).
|
|
839
839
|
if (d.isMain) {
|
|
840
840
|
ring.push(d);
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
// append order is completion order, semantic order is seq.
|
|
18
18
|
|
|
19
19
|
import { readdirSync } from 'node:fs';
|
|
20
|
-
import { isPostClearCheckpoint, isCompactContinuation, normalizeMsgForEquality } from '
|
|
20
|
+
import { isPostClearCheckpoint, isCompactContinuation, normalizeMsgForEquality } from '@ccv/core/session-boundary';
|
|
21
21
|
import { fingerprintMsg } from '../interceptor-core.js';
|
|
22
22
|
import { ensureConvDirSync, convEpochPath, convDir } from './layout.js';
|
|
23
23
|
|
package/server/lib/v2/convert.js
CHANGED
|
@@ -26,9 +26,9 @@
|
|
|
26
26
|
import { readdirSync, existsSync, statSync, statfsSync, renameSync, rmSync, readFileSync, mkdirSync } from 'node:fs';
|
|
27
27
|
import { join, basename } from 'node:path';
|
|
28
28
|
import { iterateRawEntriesAsync } from '../log-stream.js';
|
|
29
|
-
import { createIncrementalReconstructor } from '
|
|
30
|
-
import { isLogFileName, parseLogTs } from '../log-
|
|
31
|
-
import { reportSwallowed } from '
|
|
29
|
+
import { createIncrementalReconstructor } from '@ccv/core/delta-reconstructor';
|
|
30
|
+
import { isLogFileName, parseLogTs } from '../log-file-utils.js';
|
|
31
|
+
import { reportSwallowed } from '@ccv/core/error-report';
|
|
32
32
|
import { V2Writer } from './v2-writer.js';
|
|
33
33
|
import { verifyV1File } from './verify.js';
|
|
34
34
|
import { parseUserId } from './identity.js';
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
// mirroring readJsonlTolerant's torn-tail tolerance (spec §14).
|
|
15
15
|
|
|
16
16
|
import { existsSync, openSync, readSync, closeSync, statSync } from 'node:fs';
|
|
17
|
-
import { reportSwallowed } from '
|
|
17
|
+
import { reportSwallowed } from '@ccv/core/error-report';
|
|
18
18
|
|
|
19
19
|
const DEFAULT_CHUNK_BYTES = 8 * 1024 * 1024;
|
|
20
20
|
// Node's max string length is 0x1fffffe8 (~512MiB) — a line this long can
|
|
@@ -24,15 +24,15 @@
|
|
|
24
24
|
|
|
25
25
|
import { watch, existsSync, readdirSync, readFileSync, statSync, openSync, readSync, closeSync } from 'node:fs';
|
|
26
26
|
import { join } from 'node:path';
|
|
27
|
-
import { reportSwallowed } from '
|
|
28
|
-
import { createIncrementalReconstructor } from '
|
|
27
|
+
import { reportSwallowed } from '@ccv/core/error-report';
|
|
28
|
+
import { createIncrementalReconstructor } from '@ccv/core/delta-reconstructor';
|
|
29
29
|
import { processWatchedEntry, sendEventToClients, sendEventRawToClients } from '../log-watcher.js';
|
|
30
30
|
import { SessionSynthesizer } from './adapter.js';
|
|
31
31
|
import { isDiscardableSession } from './session-select.js';
|
|
32
32
|
import { isForeignLiveOwned } from './session-owner.js';
|
|
33
33
|
import { isConvertRunning } from './convert-manager.js';
|
|
34
34
|
import { computeCacheLoss } from './meta-rows.js';
|
|
35
|
-
import { classifyRequest, withAgentNameSubType } from '
|
|
35
|
+
import { classifyRequest, withAgentNameSubType } from '@ccv/core/requestType';
|
|
36
36
|
|
|
37
37
|
const FSWATCH_DEBOUNCE_MS = 80;
|
|
38
38
|
const SAFETY_POLL_MS = 5000;
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* dropped — the wire carries rows only (~1.3KB each vs full entries).
|
|
8
8
|
*
|
|
9
9
|
* Two DELIBERATE classification divergences from the legacy full-entry list
|
|
10
|
-
* (both more correct; pinned in test/v2-meta-rows.test.js, declared in
|
|
10
|
+
* (both more correct; pinned in packages/app/test/v2-meta-rows.test.js, declared in
|
|
11
11
|
* history.md):
|
|
12
12
|
* - membership is the journal fold — a SUPERSET of the synthesizer's output
|
|
13
13
|
* (conv-gapped crash-orphans get a row; their detail fetch answers 404 and
|
|
@@ -21,8 +21,8 @@ import { readJsonlTolerant } from './replay.js';
|
|
|
21
21
|
import { iterateJsonlLines } from './jsonl-read.js';
|
|
22
22
|
import { iterateV2Items, findTeammateSessionDirs } from './adapter.js';
|
|
23
23
|
import { SingleFlight } from './singleflight.js';
|
|
24
|
-
import { reportSwallowed } from '
|
|
25
|
-
import { classifyRequest, withAgentNameSubType } from '
|
|
24
|
+
import { reportSwallowed } from '@ccv/core/error-report';
|
|
25
|
+
import { classifyRequest, withAgentNameSubType } from '@ccv/core/requestType';
|
|
26
26
|
|
|
27
27
|
// KEEP IN SYNC: server/lib/v2/adapter.js itemKey — (sessionId, seq) identity.
|
|
28
28
|
const itemKey = (sessionId, seq) => `${sessionId}\x00${seq}`;
|
package/server/lib/v2/replay.js
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
import { existsSync, readFileSync, readdirSync } from 'node:fs';
|
|
13
13
|
import { join } from 'node:path';
|
|
14
14
|
import { createHash } from 'node:crypto';
|
|
15
|
-
import { messageFingerprint, normalizeMsgForEquality } from '
|
|
15
|
+
import { messageFingerprint, normalizeMsgForEquality } from '@ccv/core/session-boundary';
|
|
16
16
|
import { isSupportedWireFormat } from './layout.js';
|
|
17
17
|
import { iterateJsonlLines } from './jsonl-read.js';
|
|
18
18
|
|
|
@@ -26,7 +26,7 @@ import { listSessionIds, readJsonlTolerant } from './replay.js';
|
|
|
26
26
|
import { readPromptsHead, collectPromptsFromEvents } from '../user-prompt-extract.js';
|
|
27
27
|
import { isDiscardableSession } from './session-select.js';
|
|
28
28
|
import { isSupportedWireFormat, dirSizeSync } from './layout.js';
|
|
29
|
-
import { reportSwallowed } from '
|
|
29
|
+
import { reportSwallowed } from '@ccv/core/error-report';
|
|
30
30
|
|
|
31
31
|
const MAX_PROJECTS = 32;
|
|
32
32
|
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
import { readFileSync, writeFileSync, unlinkSync, existsSync } from 'node:fs';
|
|
27
27
|
import { join } from 'node:path';
|
|
28
28
|
import { isPidAlive } from '../pid-alive.js';
|
|
29
|
-
import { reportSwallowed } from '
|
|
29
|
+
import { reportSwallowed } from '@ccv/core/error-report';
|
|
30
30
|
|
|
31
31
|
export const OWNER_LOCK_NAME = 'owner.lock';
|
|
32
32
|
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
import { statfsSync, existsSync, readdirSync, readFileSync } from 'node:fs';
|
|
20
20
|
import { join, basename } from 'node:path';
|
|
21
21
|
import { AsyncWriteQueue } from '../async-write-queue.js';
|
|
22
|
-
import { reportSwallowed } from '
|
|
22
|
+
import { reportSwallowed } from '@ccv/core/error-report';
|
|
23
23
|
import { ensureSessionDirSync, compactLocalTs14, sanitizePathComponent } from './layout.js';
|
|
24
24
|
import { resolveSessionDirName, latestMainSession } from './session-select.js';
|
|
25
25
|
import { acquireSessionClaim, releaseSessionClaim, isForeignLiveOwned } from './session-owner.js';
|
|
@@ -29,6 +29,7 @@ import { ConversationStore } from './conversation-store.js';
|
|
|
29
29
|
import { parseUserId, classifyKind, ConvResolver } from './identity.js';
|
|
30
30
|
import { parseAgentId, findHeader } from './agent-id.js';
|
|
31
31
|
import { extractUserTexts, flattenPromptText, isSuggestionMode, readPromptsHead } from '../user-prompt-extract.js';
|
|
32
|
+
import { consumePendingForWireByKey, writeSnapshotByKey, systemTextOfBody } from '../system-prompt-snapshots.js';
|
|
32
33
|
|
|
33
34
|
// Below this many free bytes on the log volume, v2 skips writing and reports
|
|
34
35
|
// once — logging must not be the thing that fills the disk (plan risk #9).
|
|
@@ -428,6 +429,30 @@ export class V2Writer {
|
|
|
428
429
|
// (live ≈ now; convert = the historical first-entry ts).
|
|
429
430
|
const s = this._session(sid, parsed && entry.body.metadata.user_id, parsed && parsed.encoding, project, entry.timestamp, adoptTarget);
|
|
430
431
|
|
|
432
|
+
// System-prompt snapshot, Bind A (wire): the FIRST main request of a session
|
|
433
|
+
// carries the launch's rendered injection in body.system — match it against the
|
|
434
|
+
// project's pending queue and key the snapshot to the wire sid (== transcript
|
|
435
|
+
// uuid for fresh sessions), so a later `-c`/`-r` can pin byte-identical content
|
|
436
|
+
// instead of re-rendering variables and busting the prompt-prefix cache.
|
|
437
|
+
// count_tokens/heartbeat probes wear main-agent shapes but aren't the user's
|
|
438
|
+
// turn (same gate as the resume-switch above); adopted (-c) sessions skip —
|
|
439
|
+
// their pendings are resumeExpected, reserved for the SessionStart-hook bind.
|
|
440
|
+
// First-main-only via the per-session flag: probes may create the session state
|
|
441
|
+
// before the real turn arrives. The live-sessions-dir gate keeps the offline
|
|
442
|
+
// converter (staging dirs) from consuming LIVE pendings. Fully caught: a lost
|
|
443
|
+
// bind degrades to the no-record resume path, never to a dropped log entry.
|
|
444
|
+
if (!adoptTarget && entry.mainAgent && !entry.isCountTokens && !entry.isHeartbeat
|
|
445
|
+
&& this._sessionsDirName === 'sessions'
|
|
446
|
+
&& s && !s.sysPromptBindDone) {
|
|
447
|
+
s.sysPromptBindDone = true;
|
|
448
|
+
try {
|
|
449
|
+
const pend = consumePendingForWireByKey(project, systemTextOfBody(entry.body), this._logDir);
|
|
450
|
+
if (pend) {
|
|
451
|
+
writeSnapshotByKey(project, sid, { entries: pend.entries, model: pend.model, boundVia: 'wire' }, { logDir: this._logDir });
|
|
452
|
+
}
|
|
453
|
+
} catch (err) { reportSwallowed('v2-write.sys-prompt-bind', err); }
|
|
454
|
+
}
|
|
455
|
+
|
|
431
456
|
// Flush requests that arrived before the first sid (they belong here).
|
|
432
457
|
// Their handles are parked in _lateHandles so a completion that arrives
|
|
433
458
|
// after the flush still gets its done line (folded by rid).
|
package/server/lib/v2/verify.js
CHANGED
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
import { statSync } from 'node:fs';
|
|
29
29
|
import { dirname } from 'node:path';
|
|
30
30
|
import { iterateRawEntriesAsync } from '../log-stream.js';
|
|
31
|
-
import { createIncrementalReconstructor } from '
|
|
31
|
+
import { createIncrementalReconstructor } from '@ccv/core/delta-reconstructor';
|
|
32
32
|
import { listSessionIds, readSession, indexSession, messagesDigest, blobRefOf } from './replay.js';
|
|
33
33
|
|
|
34
34
|
const MAX_REPORTED_DIFFS = 50;
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
import { existsSync, mkdirSync, writeFileSync, unlinkSync, readdirSync, statSync, readFileSync, lstatSync } from 'node:fs';
|
|
12
12
|
import { join, extname } from 'node:path';
|
|
13
13
|
import { randomUUID } from 'node:crypto';
|
|
14
|
-
import { EVENT_KEYS, DEFAULT_BINDINGS, BUNDLED_PACK_IDS } from '
|
|
14
|
+
import { EVENT_KEYS, DEFAULT_BINDINGS, BUNDLED_PACK_IDS } from '@ccv/core/voice-pack-events';
|
|
15
15
|
import { DIST_DIR, PUBLIC_DIR } from '../_paths.js';
|
|
16
16
|
|
|
17
17
|
// Bundled pack lookup order, per packId:
|
|
@@ -35,7 +35,7 @@ for (const packId of BUNDLED_PACK_IDS) {
|
|
|
35
35
|
}
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
-
export { EVENT_KEYS } from '
|
|
38
|
+
export { EVENT_KEYS } from '@ccv/core/voice-pack-events';
|
|
39
39
|
export const ID_PATTERN = /^[a-f0-9-]{8,64}$/;
|
|
40
40
|
export const ALLOWED_EXTS = new Set(['.mp3', '.wav', '.ogg', '.m4a']);
|
|
41
41
|
export const MAX_AUDIO_BYTES = 2 * 1024 * 1024; // 2MB per file
|
|
@@ -334,6 +334,5 @@ export function reconcileVoicePackPrefs(logDir, vp) {
|
|
|
334
334
|
// Re-export shared defaults so consumers can pull everything from one module.
|
|
335
335
|
export { DEFAULT_BINDINGS, BUNDLED_PACK_IDS };
|
|
336
336
|
|
|
337
|
-
// mergeApprovalModalPrefs / mergeVoicePackInto moved to
|
|
338
|
-
//(
|
|
339
|
-
// './approval-modal-prefs.js' directly.
|
|
337
|
+
// mergeApprovalModalPrefs / mergeVoicePackInto moved to @ccv/core/approval-modal-prefs
|
|
338
|
+
// (merge logic isn't voice-pack-specific). Import from '@ccv/core/approval-modal-prefs' directly.
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
* knee on large sessions; q5 collapses to ~2.5x there).
|
|
20
20
|
*/
|
|
21
21
|
import zlib from 'node:zlib';
|
|
22
|
-
import { reportSwallowed } from '
|
|
22
|
+
import { reportSwallowed } from '@ccv/core/error-report';
|
|
23
23
|
import { awaitDrainOrClose } from './sse-backpressure.js';
|
|
24
24
|
|
|
25
25
|
const C = zlib.constants;
|
package/server/proxy.js
CHANGED
|
@@ -5,13 +5,13 @@ import { join, basename } from 'node:path';
|
|
|
5
5
|
import { homedir } from 'node:os';
|
|
6
6
|
import * as interceptor from './interceptor.js';
|
|
7
7
|
import { setupInterceptor } from './interceptor.js';
|
|
8
|
-
import { extractApiErrorMessage, formatProxyRequestError } from './lib/proxy-errors.js';
|
|
9
|
-
import { getProxyDispatcher } from './lib/proxy-env.js';
|
|
8
|
+
import { extractApiErrorMessage, formatProxyRequestError } from './lib/proxy/proxy-errors.js';
|
|
9
|
+
import { getProxyDispatcher } from './lib/proxy/proxy-env.js';
|
|
10
10
|
import { getClaudeConfigDir } from '../findcc.js';
|
|
11
11
|
import { isAnthropicApiPath, classifyProxyRole } from './lib/interceptor-core.js';
|
|
12
|
-
import { executeRequest, extractModel } from './lib/proxy-retry.js';
|
|
13
|
-
import { buildRecord, appendRecord, dailyFilePath, todayStr, emitProxyStatsUpdate } from './lib/proxy-stats.js';
|
|
14
|
-
import { reportSwallowed } from '
|
|
12
|
+
import { executeRequest, extractModel } from './lib/proxy/proxy-retry.js';
|
|
13
|
+
import { buildRecord, appendRecord, dailyFilePath, todayStr, emitProxyStatsUpdate } from './lib/proxy/proxy-stats.js';
|
|
14
|
+
import { reportSwallowed } from '@ccv/core/error-report';
|
|
15
15
|
import { LOG_DIR } from '../findcc.js';
|
|
16
16
|
|
|
17
17
|
// Setup interceptor to patch fetch
|