cc-viewer 1.7.5 → 1.7.6
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 +19 -4
- package/dist/assets/{App-CcLQlV-O.js → App-3VM471BO.js} +2 -2
- package/dist/assets/{MdxEditorPanel-CAqHHy1X.js → MdxEditorPanel-BQ5MgI4D.js} +1 -1
- package/dist/assets/{Mobile-BxRd4DkS.js → Mobile-wwcXmnrU.js} +1 -1
- package/dist/assets/{UnifiedProxyRetryPage-DjL3NQXO.js → UnifiedProxyRetryPage-BpcKIn9N.js} +1 -1
- package/dist/assets/{index-DJ0AQwus.js → index-BjNLFJ0z.js} +2 -2
- package/dist/assets/{seqResourceLoaders-D1y8V4z5.js → seqResourceLoaders-CDRtUSxI.js} +2 -2
- package/dist/index.html +1 -1
- package/findcc.js +58 -0
- package/package.json +1 -1
- package/server/lib/interceptor-core.js +26 -15
- package/server/pty-manager.js +8 -0
package/dist/index.html
CHANGED
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
// 整体显示大小已弃用 CSS zoom:Electron 改用 webFrame.setZoomFactor(首屏抢占见
|
|
22
22
|
// electron/tab-content-preload.js),纯浏览器交由用户用浏览器自带快捷键缩放,故此处不再设 zoom。
|
|
23
23
|
</script>
|
|
24
|
-
<script type="module" crossorigin src="./assets/index-
|
|
24
|
+
<script type="module" crossorigin src="./assets/index-BjNLFJ0z.js"></script>
|
|
25
25
|
<link rel="modulepreload" crossorigin href="./assets/vendor-antd-DeqwrDxf.js">
|
|
26
26
|
<link rel="modulepreload" crossorigin href="./assets/vendor-codemirror-_NbrtdQc.js">
|
|
27
27
|
<link rel="modulepreload" crossorigin href="./assets/vendor-mdxeditor-DG0Nyxw5.js">
|
package/findcc.js
CHANGED
|
@@ -351,6 +351,64 @@ export function pickSpawnableLookupResult(rawOut, platform = process.platform) {
|
|
|
351
351
|
return lines[0] || null;
|
|
352
352
|
}
|
|
353
353
|
|
|
354
|
+
/**
|
|
355
|
+
* Resolve the `claude` executable explicitly selected by the caller's PATH.
|
|
356
|
+
*
|
|
357
|
+
* Wrappers such as CodeFuse's `cfuse --ccv` prepend their managed Claude Code
|
|
358
|
+
* directory to PATH before launching ccv. This lookup must happen before any
|
|
359
|
+
* global npm fallback, otherwise an unrelated global @anthropic-ai install wins
|
|
360
|
+
* and the wrapper-provided (and potentially enterprise-approved) binary is lost.
|
|
361
|
+
*
|
|
362
|
+
* Returns both the path and whether Node is required for a legacy cli.js entry.
|
|
363
|
+
*/
|
|
364
|
+
export function resolveClaudeFromPath() {
|
|
365
|
+
const lookupCmds = process.platform === 'win32'
|
|
366
|
+
? [`where ${BINARY_NAME}`]
|
|
367
|
+
: [`which ${BINARY_NAME}`, `command -v ${BINARY_NAME}`];
|
|
368
|
+
|
|
369
|
+
for (const cmd of lookupCmds) {
|
|
370
|
+
try {
|
|
371
|
+
const rawOut = execSync(cmd, { encoding: 'utf-8', shell: true, env: process.env, windowsHide: true });
|
|
372
|
+
const result = pickSpawnableLookupResult(rawOut);
|
|
373
|
+
if (!result || !existsSync(result)) continue;
|
|
374
|
+
|
|
375
|
+
let real = result;
|
|
376
|
+
try { real = realpathSync(result); } catch { }
|
|
377
|
+
if (real.endsWith('.js')) return { path: real, isNpmVersion: true };
|
|
378
|
+
return { path: result, isNpmVersion: false };
|
|
379
|
+
} catch {
|
|
380
|
+
// Try the next lookup command.
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
return null;
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
// Starpoint currently approves the CodeFuse-managed Claude Code 2.1.199 build.
|
|
388
|
+
// Keep standalone `ccv` on the same binary as `cfuse --ccv`; callers can move
|
|
389
|
+
// the pin deliberately after a new enterprise build has been approved.
|
|
390
|
+
export const DEFAULT_CODEFUSE_CLAUDE_VERSION = '2.1.199';
|
|
391
|
+
|
|
392
|
+
export function resolveCodeFuseClaudePath(
|
|
393
|
+
codeFuseClaudeRoot = null,
|
|
394
|
+
version = process.env.CCV_CODEFUSE_CLAUDE_VERSION?.trim() || DEFAULT_CODEFUSE_CLAUDE_VERSION,
|
|
395
|
+
) {
|
|
396
|
+
// Never let a test process escape its disposable fixtures into the real home.
|
|
397
|
+
// Tests exercise this resolver by passing an explicit temporary root.
|
|
398
|
+
if (!codeFuseClaudeRoot) {
|
|
399
|
+
if (isRealClaudeLookupBlocked()) return null;
|
|
400
|
+
codeFuseClaudeRoot = join(homedir(), '.codefuse', 'fuse', 'engine', 'bin', 'claude');
|
|
401
|
+
}
|
|
402
|
+
if (!version || !/^\d+\.\d+\.\d+$/.test(version)) return null;
|
|
403
|
+
const versionDir = join(codeFuseClaudeRoot, version);
|
|
404
|
+
const names = process.platform === 'win32' ? ['claude.exe'] : ['claude', 'claude.exe'];
|
|
405
|
+
for (const name of names) {
|
|
406
|
+
const candidate = join(versionDir, name);
|
|
407
|
+
if (existsSync(candidate)) return candidate;
|
|
408
|
+
}
|
|
409
|
+
return null;
|
|
410
|
+
}
|
|
411
|
+
|
|
354
412
|
export function resolveNativePath() {
|
|
355
413
|
// L7: steps 1 & 4 (platform/packaged binaries under `npm root -g`) ignore PATH isolation —
|
|
356
414
|
// neutralized under test context via a null globalRoot (both helpers null-guard).
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cc-viewer",
|
|
3
|
-
"version": "1.7.
|
|
3
|
+
"version": "1.7.6",
|
|
4
4
|
"description": "Claude Code logging, visualization, and management toolkit — launch a web viewer alongside Claude Code with full request/response tracing, proxy, and mobile support",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "server.js",
|
|
@@ -400,34 +400,45 @@ export function replaceTopLevelModel(jsonStr, oldModel, newModel) {
|
|
|
400
400
|
// 家族用**大小写不敏感子串**匹配(/opus/i 等),只认这几个已知家族单词——
|
|
401
401
|
// 因此 claude-opus-4-8、未来的 claude-opus-5 等任何版本都命中同一家族,版本升级无需重配。
|
|
402
402
|
// 字段直接沿用 Claude Code 的环境变量名以保持一致:
|
|
403
|
-
// ANTHROPIC_MODEL ——
|
|
403
|
+
// ANTHROPIC_MODEL —— 主模型(catch-all 兜底;body.model 含 "fable"/"mythos"
|
|
404
|
+
// 及所有未识别家族均回落到它)
|
|
404
405
|
// ANTHROPIC_DEFAULT_OPUS_MODEL —— body.model 含 "opus"
|
|
405
406
|
// ANTHROPIC_DEFAULT_SONNET_MODEL —— 含 "sonnet"
|
|
406
407
|
// ANTHROPIC_DEFAULT_HAIKU_MODEL —— 含 "haiku"
|
|
407
|
-
//
|
|
408
|
-
// 未识别家族(既不是 opus/sonnet/haiku 也不是 fable/mythos
|
|
408
|
+
// 家族字段优先:opus/sonnet/haiku 各自命中专属字段;字段留空则回落到 ANTHROPIC_MODEL。
|
|
409
|
+
// 未识别家族(既不是 opus/sonnet/haiku 也不是 fable/mythos)→ ANTHROPIC_MODEL 兜底。
|
|
409
410
|
// 兼容旧数据:profile 未设任何新字段但有 activeModel(老结构)时,回退为旧的整体替换语义。
|
|
410
|
-
// 返回目标模型字符串;无需改写(无目标 / 目标同旧值 /
|
|
411
|
+
// 返回目标模型字符串;无需改写(无目标 / 目标同旧值 / 入参非法)时返回 null。
|
|
412
|
+
// [1m] 后缀(Claude Code 1M context 标记)默认忽略:所有 profile 模型字段值在比较前先剥除。
|
|
411
413
|
export function resolveProfileModel(oldModel, profile) {
|
|
412
414
|
if (typeof oldModel !== 'string' || !oldModel || !profile || typeof profile !== 'object') return null;
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
const
|
|
415
|
+
|
|
416
|
+
// Strip [1m] suffix (case-insensitive) from model names; Claude Code appends it
|
|
417
|
+
// for 1M-context variants and it should not affect model matching/replacement.
|
|
418
|
+
const strip1m = (s) => (typeof s === 'string' ? s.replace(/\[1m\]/gi, '').trim() : '');
|
|
419
|
+
|
|
420
|
+
const opus = strip1m(profile.ANTHROPIC_DEFAULT_OPUS_MODEL);
|
|
421
|
+
const sonnet = strip1m(profile.ANTHROPIC_DEFAULT_SONNET_MODEL);
|
|
422
|
+
const haiku = strip1m(profile.ANTHROPIC_DEFAULT_HAIKU_MODEL);
|
|
423
|
+
const primary = strip1m(profile.ANTHROPIC_MODEL);
|
|
417
424
|
const hasNew = !!(primary || opus || sonnet || haiku);
|
|
418
425
|
|
|
419
426
|
let target = '';
|
|
420
427
|
if (hasNew) {
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
428
|
+
// Family-specific fields take precedence; fall back to ANTHROPIC_MODEL when
|
|
429
|
+
// the family field is empty/unset. ANTHROPIC_MODEL itself acts as the
|
|
430
|
+
// catch-all default for any unrecognized family (including third-party models
|
|
431
|
+
// like gpt-4o, deepseek-v4, K3/kimi, etc.).
|
|
432
|
+
if (/opus/i.test(oldModel)) target = opus || primary;
|
|
433
|
+
else if (/sonnet/i.test(oldModel)) target = sonnet || primary;
|
|
434
|
+
else if (/haiku/i.test(oldModel)) target = haiku || primary;
|
|
435
|
+
else if (/fable/i.test(oldModel) || /mythos/i.test(oldModel)) target = primary;
|
|
436
|
+
else target = primary; // unrecognized family → ANTHROPIC_MODEL catch-all
|
|
426
437
|
} else if (typeof profile.activeModel === 'string') {
|
|
427
|
-
target = profile.activeModel
|
|
438
|
+
target = strip1m(profile.activeModel); // 旧数据整体替换语义
|
|
428
439
|
}
|
|
429
440
|
|
|
430
|
-
if (!target || target === oldModel) return null;
|
|
441
|
+
if (!target || target === strip1m(oldModel)) return null;
|
|
431
442
|
return target;
|
|
432
443
|
}
|
|
433
444
|
|
package/server/pty-manager.js
CHANGED
|
@@ -231,6 +231,14 @@ async function _spawnClaudeImpl(proxyPort, cwd, extraArgs = [], claudePath = nul
|
|
|
231
231
|
}
|
|
232
232
|
|
|
233
233
|
const env = { ...process.env };
|
|
234
|
+
// CodeFuse owns and versions the Claude binary used by `cfuse --ccv`. Keep
|
|
235
|
+
// that managed 2.1.x binary from invoking Claude Code's independent updater;
|
|
236
|
+
// upgrades must come from CodeFuse so the enterprise-approved version cannot
|
|
237
|
+
// be silently replaced during a CCV session.
|
|
238
|
+
const normalizedClaudePath = String(claudePath || '').replace(/\\/g, '/');
|
|
239
|
+
if (normalizedClaudePath.includes('/.codefuse/fuse/engine/bin/claude/')) {
|
|
240
|
+
env.DISABLE_AUTOUPDATER = '1';
|
|
241
|
+
}
|
|
234
242
|
env.ANTHROPIC_BASE_URL = `http://127.0.0.1:${proxyPort}`;
|
|
235
243
|
env.CCV_PROXY_MODE = '1'; // 告诉 interceptor.js 不要再启动 server
|
|
236
244
|
env.CCV_LOG_DIR = LOG_DIR; // 让 fork 出的 Claude Code 进程找到同一份 profile.json 等资源
|