cc-viewer 1.6.97 → 1.6.99

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 (85) hide show
  1. package/cli.js +6 -1
  2. package/concepts/ar/GlobalSettings.md +232 -0
  3. package/concepts/da/GlobalSettings.md +232 -0
  4. package/concepts/de/GlobalSettings.md +232 -0
  5. package/concepts/en/GlobalSettings.md +232 -0
  6. package/concepts/es/GlobalSettings.md +232 -0
  7. package/concepts/fr/GlobalSettings.md +232 -0
  8. package/concepts/it/GlobalSettings.md +232 -0
  9. package/concepts/ja/GlobalSettings.md +232 -0
  10. package/concepts/ko/GlobalSettings.md +232 -0
  11. package/concepts/no/GlobalSettings.md +232 -0
  12. package/concepts/pl/GlobalSettings.md +232 -0
  13. package/concepts/pt-BR/GlobalSettings.md +232 -0
  14. package/concepts/ru/GlobalSettings.md +232 -0
  15. package/concepts/th/GlobalSettings.md +232 -0
  16. package/concepts/tr/GlobalSettings.md +232 -0
  17. package/concepts/uk/GlobalSettings.md +232 -0
  18. package/concepts/zh/GlobalSettings.md +232 -0
  19. package/concepts/zh-TW/GlobalSettings.md +232 -0
  20. package/dist/assets/App-D9tbz6gh.js +39 -0
  21. package/dist/assets/{AppHeader-CmLos5-f.css → AppHeader-CoP_9OY5.css} +1 -1
  22. package/dist/assets/{AppHeader.module-CTBJwgrr.js → AppHeader.module-NjKaHOFk.js} +93 -93
  23. package/dist/assets/{Mobile-AicWwDuy.js → Mobile-Kzk2YO-c.js} +1 -1
  24. package/dist/assets/{_basePickBy-BWXOF6Ri.js → _basePickBy-DloMkc-G.js} +1 -1
  25. package/dist/assets/{_baseUniq-CtBh9QNw.js → _baseUniq-DS0g4orB.js} +1 -1
  26. package/dist/assets/{arc-BZEM3DMb.js → arc-DjVGcsRC.js} +1 -1
  27. package/dist/assets/{architectureDiagram-2XIMDMQ5-BcsqHztP.js → architectureDiagram-2XIMDMQ5-C78NysdK.js} +1 -1
  28. package/dist/assets/{blockDiagram-WCTKOSBZ-xKCLQIlA.js → blockDiagram-WCTKOSBZ-D1eulsBg.js} +1 -1
  29. package/dist/assets/{c4Diagram-IC4MRINW-BMTzjp_O.js → c4Diagram-IC4MRINW-D_vDMNpu.js} +1 -1
  30. package/dist/assets/channel-DMPi3tRx.js +1 -0
  31. package/dist/assets/{chunk-4BX2VUAB-cu74dN32.js → chunk-4BX2VUAB-DvydnNaE.js} +1 -1
  32. package/dist/assets/{chunk-55IACEB6-Cn5pJZI7.js → chunk-55IACEB6-CAEBnB2g.js} +1 -1
  33. package/dist/assets/{chunk-FMBD7UC4-ClJXAago.js → chunk-FMBD7UC4-Ic2AFusw.js} +1 -1
  34. package/dist/assets/{chunk-JSJVCQXG-CvsqFIVj.js → chunk-JSJVCQXG-B6Pf0kWF.js} +1 -1
  35. package/dist/assets/{chunk-KX2RTZJC-By2tUg3C.js → chunk-KX2RTZJC-aqNHjszh.js} +1 -1
  36. package/dist/assets/{chunk-NQ4KR5QH-ryihu0iB.js → chunk-NQ4KR5QH-BRcgqkZb.js} +1 -1
  37. package/dist/assets/{chunk-QZHKN3VN-CkLeF_JG.js → chunk-QZHKN3VN-Dg6rNEne.js} +1 -1
  38. package/dist/assets/{chunk-WL4C6EOR-DGZ_HPlH.js → chunk-WL4C6EOR-BQztZi27.js} +1 -1
  39. package/dist/assets/classDiagram-VBA2DB6C-B6fMcVCH.js +1 -0
  40. package/dist/assets/classDiagram-v2-RAHNMMFH-B6fMcVCH.js +1 -0
  41. package/dist/assets/clone-NPdkGfRa.js +1 -0
  42. package/dist/assets/{cose-bilkent-S5V4N54A-Bug5hL7O.js → cose-bilkent-S5V4N54A-CpNbxUgF.js} +1 -1
  43. package/dist/assets/{dagre-KLK3FWXG-Bp95f3av.js → dagre-KLK3FWXG-DMV6CAiu.js} +1 -1
  44. package/dist/assets/{diagram-E7M64L7V-BnJcznPG.js → diagram-E7M64L7V-CzQpTBkT.js} +1 -1
  45. package/dist/assets/{diagram-IFDJBPK2-DTa6uDlT.js → diagram-IFDJBPK2-n98W4lW5.js} +1 -1
  46. package/dist/assets/{diagram-P4PSJMXO-BNjVizvt.js → diagram-P4PSJMXO-Da-Dxb0d.js} +1 -1
  47. package/dist/assets/{erDiagram-INFDFZHY-DeYo5Exx.js → erDiagram-INFDFZHY-DV6WDsOa.js} +1 -1
  48. package/dist/assets/{flowDiagram-PKNHOUZH-D8Rh5RJD.js → flowDiagram-PKNHOUZH-uPCoTO1u.js} +1 -1
  49. package/dist/assets/{ganttDiagram-A5KZAMGK-DZ0z2OiO.js → ganttDiagram-A5KZAMGK-C18veywB.js} +1 -1
  50. package/dist/assets/{gitGraphDiagram-K3NZZRJ6-DsoU0UJ3.js → gitGraphDiagram-K3NZZRJ6-CRgTEgJX.js} +1 -1
  51. package/dist/assets/{graph-FtHGSVXM.js → graph-E73hSxND.js} +1 -1
  52. package/dist/assets/{index-yvprqgUP.js → index-C7N4gnFf.js} +2 -2
  53. package/dist/assets/{infoDiagram-LFFYTUFH-BWptl6Gm.js → infoDiagram-LFFYTUFH-X_hBGUL2.js} +1 -1
  54. package/dist/assets/{ishikawaDiagram-PHBUUO56-DTN7vdFN.js → ishikawaDiagram-PHBUUO56-CUIYqfv2.js} +1 -1
  55. package/dist/assets/{journeyDiagram-4ABVD52K-C6rSfKFW.js → journeyDiagram-4ABVD52K-Ja_oFdN5.js} +1 -1
  56. package/dist/assets/{kanban-definition-K7BYSVSG-7zlzYuQI.js → kanban-definition-K7BYSVSG-CoxZi981.js} +1 -1
  57. package/dist/assets/{layout-DetVF_Xi.js → layout-CxyNCowe.js} +1 -1
  58. package/dist/assets/{linear-D7AP5ZM2.js → linear-BvMEMoa5.js} +1 -1
  59. package/dist/assets/{mermaid.core-BF7AL9QP.js → mermaid.core-yxi-tJV1.js} +4 -4
  60. package/dist/assets/{mindmap-definition-YRQLILUH-BAEZ_Kww.js → mindmap-definition-YRQLILUH-D0an_YiX.js} +1 -1
  61. package/dist/assets/{pieDiagram-SKSYHLDU-CTRIrNJJ.js → pieDiagram-SKSYHLDU-2_qKTz49.js} +1 -1
  62. package/dist/assets/{quadrantDiagram-337W2JSQ-DcUVHBRU.js → quadrantDiagram-337W2JSQ-DEdMIEZ6.js} +1 -1
  63. package/dist/assets/{requirementDiagram-Z7DCOOCP-nMrfF214.js → requirementDiagram-Z7DCOOCP-D34qZwqS.js} +1 -1
  64. package/dist/assets/{sankeyDiagram-WA2Y5GQK-BKM2oKi0.js → sankeyDiagram-WA2Y5GQK-CuWEPTrY.js} +1 -1
  65. package/dist/assets/{sequenceDiagram-2WXFIKYE-DcJnjEps.js → sequenceDiagram-2WXFIKYE-C_j_NZww.js} +1 -1
  66. package/dist/assets/{stateDiagram-RAJIS63D--wjhber7.js → stateDiagram-RAJIS63D-BQMmW3qX.js} +1 -1
  67. package/dist/assets/stateDiagram-v2-FVOUBMTO-C_b_318T.js +1 -0
  68. package/dist/assets/{timeline-definition-YZTLITO2-BzEHHLxX.js → timeline-definition-YZTLITO2-CQlUZTgI.js} +1 -1
  69. package/dist/assets/{treemap-KZPCXAKY-BKg_1Uvh.js → treemap-KZPCXAKY-Df9Nkrlt.js} +1 -1
  70. package/dist/assets/{vennDiagram-LZ73GAT5-BKfBvDlz.js → vennDiagram-LZ73GAT5-CaXvJV8t.js} +1 -1
  71. package/dist/assets/{xychartDiagram-JWTSCODW-2O6N9OtR.js → xychartDiagram-JWTSCODW-BWwflUcf.js} +1 -1
  72. package/dist/index.html +1 -1
  73. package/findcc.js +17 -1
  74. package/lib/perm-bridge.js +15 -14
  75. package/lib/plugin-loader.js +13 -12
  76. package/lib/sdk-manager.js +2 -2
  77. package/package.json +1 -1
  78. package/server.js +25 -14
  79. package/workspace-registry.js +11 -10
  80. package/dist/assets/App-BlTt-0pD.js +0 -39
  81. package/dist/assets/channel-UwYsH-gK.js +0 -1
  82. package/dist/assets/classDiagram-VBA2DB6C-BJV4gG6V.js +0 -1
  83. package/dist/assets/classDiagram-v2-RAHNMMFH-BJV4gG6V.js +0 -1
  84. package/dist/assets/clone-CjbFDS02.js +0 -1
  85. package/dist/assets/stateDiagram-v2-FVOUBMTO-BjJCClaV.js +0 -1
package/server.js CHANGED
@@ -35,10 +35,10 @@ function execWithStdin(cmd, args, input, options) {
35
35
  });
36
36
  }
37
37
  import { LOG_FILE, _initPromise, _resumeState, resolveResumeChoice, _projectName, _logDir, _cachedApiKey, _cachedAuthHeader, _cachedHaikuModel, initForWorkspace, resetWorkspace, streamingState, resetStreamingState, _loadProxyProfile, PROFILE_PATH, _defaultConfig } from './interceptor.js';
38
- import { LOG_DIR } from './findcc.js';
38
+ import { LOG_DIR, setLogDir } from './findcc.js';
39
39
  import { t, detectLanguage } from './i18n.js';
40
40
  import { checkAndUpdate } from './lib/updater.js';
41
- import { loadPlugins, runWaterfallHook, runParallelHook, getPluginsInfo, PLUGINS_DIR } from './lib/plugin-loader.js';
41
+ import { loadPlugins, runWaterfallHook, runParallelHook, getPluginsInfo, getPluginsDir } from './lib/plugin-loader.js';
42
42
  import { uploadPlugins, installPluginFromUrl } from './lib/plugin-manager.js';
43
43
  import { getUserProfile } from './lib/user-profile.js';
44
44
  import { getGitDiffs } from './lib/git-diff.js';
@@ -49,7 +49,8 @@ import { listLocalLogs, deleteLogFiles, mergeLogFiles } from './lib/log-manageme
49
49
  import { countLogEntries, streamRawEntriesAsync, readPagedEntries } from './lib/log-stream.js';
50
50
 
51
51
 
52
- const PREFS_FILE = join(LOG_DIR, 'preferences.json');
52
+ // 动态获取 getPrefsFile()(LOG_DIR 可能在运行时被 setLogDir 修改)
53
+ function getPrefsFile() { return join(LOG_DIR, 'preferences.json'); }
53
54
 
54
55
  // 启动时一次性读取 ~/.claude/settings.json(不 watch)
55
56
  let claudeSettings = {};
@@ -331,7 +332,8 @@ async function handleRequest(req, res) {
331
332
 
332
333
  if (url === '/api/preferences' && method === 'GET') {
333
334
  let prefs = {};
334
- try { if (existsSync(PREFS_FILE)) prefs = JSON.parse(readFileSync(PREFS_FILE, 'utf-8')); } catch { }
335
+ try { if (existsSync(getPrefsFile())) prefs = JSON.parse(readFileSync(getPrefsFile(), 'utf-8')); } catch { }
336
+ prefs.logDir = LOG_DIR; // 始终返回当前运行时的日志目录
335
337
  res.writeHead(200, { 'Content-Type': 'application/json' });
336
338
  res.end(JSON.stringify(prefs));
337
339
  return;
@@ -343,10 +345,19 @@ async function handleRequest(req, res) {
343
345
  req.on('end', () => {
344
346
  try {
345
347
  const incoming = JSON.parse(body);
348
+ // 如果修改了日志目录,先切换再保存到新位置(新目录下生成 preferences.json)
349
+ if (incoming.logDir && typeof incoming.logDir === 'string') {
350
+ setLogDir(incoming.logDir);
351
+ }
346
352
  let prefs = {};
347
- try { if (existsSync(PREFS_FILE)) prefs = JSON.parse(readFileSync(PREFS_FILE, 'utf-8')); } catch { }
353
+ try { if (existsSync(getPrefsFile())) prefs = JSON.parse(readFileSync(getPrefsFile(), 'utf-8')); } catch { }
348
354
  Object.assign(prefs, incoming);
349
- writeFileSync(PREFS_FILE, JSON.stringify(prefs, null, 2));
355
+ // 确保目录存在
356
+ const prefsFile = getPrefsFile();
357
+ const prefsDir = dirname(prefsFile);
358
+ if (!existsSync(prefsDir)) mkdirSync(prefsDir, { recursive: true });
359
+ writeFileSync(prefsFile, JSON.stringify(prefs, null, 2));
360
+ prefs.logDir = LOG_DIR;
350
361
  res.writeHead(200, { 'Content-Type': 'application/json' });
351
362
  res.end(JSON.stringify(prefs));
352
363
  } catch {
@@ -1972,7 +1983,7 @@ async function handleRequest(req, res) {
1972
1983
  if (url === '/api/plugins' && method === 'GET') {
1973
1984
  const plugins = getPluginsInfo();
1974
1985
  res.writeHead(200, { 'Content-Type': 'application/json' });
1975
- res.end(JSON.stringify({ plugins, pluginsDir: PLUGINS_DIR }));
1986
+ res.end(JSON.stringify({ plugins, pluginsDir: getPluginsDir() }));
1976
1987
  return;
1977
1988
  }
1978
1989
 
@@ -1983,7 +1994,7 @@ async function handleRequest(req, res) {
1983
1994
  res.end(JSON.stringify({ error: 'Invalid file name' }));
1984
1995
  return;
1985
1996
  }
1986
- const filePath = join(PLUGINS_DIR, file);
1997
+ const filePath = join(getPluginsDir(), file);
1987
1998
  try {
1988
1999
  if (!existsSync(filePath)) {
1989
2000
  res.writeHead(404, { 'Content-Type': 'application/json' });
@@ -1994,7 +2005,7 @@ async function handleRequest(req, res) {
1994
2005
  await loadPlugins();
1995
2006
  const plugins = getPluginsInfo();
1996
2007
  res.writeHead(200, { 'Content-Type': 'application/json' });
1997
- res.end(JSON.stringify({ ok: true, plugins, pluginsDir: PLUGINS_DIR }));
2008
+ res.end(JSON.stringify({ ok: true, plugins, pluginsDir: getPluginsDir() }));
1998
2009
  } catch (err) {
1999
2010
  res.writeHead(500, { 'Content-Type': 'application/json' });
2000
2011
  res.end(JSON.stringify({ error: err.message }));
@@ -2007,7 +2018,7 @@ async function handleRequest(req, res) {
2007
2018
  await loadPlugins();
2008
2019
  const plugins = getPluginsInfo();
2009
2020
  res.writeHead(200, { 'Content-Type': 'application/json' });
2010
- res.end(JSON.stringify({ ok: true, plugins, pluginsDir: PLUGINS_DIR }));
2021
+ res.end(JSON.stringify({ ok: true, plugins, pluginsDir: getPluginsDir() }));
2011
2022
  } catch (err) {
2012
2023
  res.writeHead(500, { 'Content-Type': 'application/json' });
2013
2024
  res.end(JSON.stringify({ error: err.message }));
@@ -2021,11 +2032,11 @@ async function handleRequest(req, res) {
2021
2032
  req.on('end', async () => {
2022
2033
  try {
2023
2034
  const { files: fileList } = JSON.parse(body);
2024
- uploadPlugins(PLUGINS_DIR, fileList);
2035
+ uploadPlugins(getPluginsDir(), fileList);
2025
2036
  await loadPlugins();
2026
2037
  const plugins = getPluginsInfo();
2027
2038
  res.writeHead(200, { 'Content-Type': 'application/json' });
2028
- res.end(JSON.stringify({ ok: true, plugins, pluginsDir: PLUGINS_DIR }));
2039
+ res.end(JSON.stringify({ ok: true, plugins, pluginsDir: getPluginsDir() }));
2029
2040
  } catch (err) {
2030
2041
  const status = err.statusCode || 500;
2031
2042
  res.writeHead(status, { 'Content-Type': 'application/json' });
@@ -2042,11 +2053,11 @@ async function handleRequest(req, res) {
2042
2053
  try {
2043
2054
  const { url: fileUrl } = JSON.parse(body);
2044
2055
  const extractScript = join(__dirname, 'lib', 'extract-plugin-name.mjs');
2045
- await installPluginFromUrl(PLUGINS_DIR, fileUrl, extractScript);
2056
+ await installPluginFromUrl(getPluginsDir(), fileUrl, extractScript);
2046
2057
  await loadPlugins();
2047
2058
  const plugins = getPluginsInfo();
2048
2059
  res.writeHead(200, { 'Content-Type': 'application/json' });
2049
- res.end(JSON.stringify({ ok: true, plugins, pluginsDir: PLUGINS_DIR }));
2060
+ res.end(JSON.stringify({ ok: true, plugins, pluginsDir: getPluginsDir() }));
2050
2061
  } catch (err) {
2051
2062
  const status = err.statusCode || 500;
2052
2063
  res.writeHead(status, { 'Content-Type': 'application/json' });
@@ -4,8 +4,9 @@ import { join, basename, resolve } from 'node:path';
4
4
  import { randomBytes } from 'node:crypto';
5
5
  import { LOG_DIR } from './findcc.js';
6
6
 
7
- const WORKSPACES_FILE = join(LOG_DIR, 'workspaces.json');
8
- const LOCK_FILE = join(LOG_DIR, 'workspaces.lock');
7
+ // 动态获取(LOG_DIR 可能在运行时被 setLogDir 修改)
8
+ function getWorkspacesFile() { return join(LOG_DIR, 'workspaces.json'); }
9
+ function getLockFile() { return join(LOG_DIR, 'workspaces.lock'); }
9
10
 
10
11
  function sleep(ms) {
11
12
  Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms);
@@ -19,7 +20,7 @@ function withLock(fn) {
19
20
 
20
21
  while (true) {
21
22
  try {
22
- const fd = openSync(LOCK_FILE, 'wx');
23
+ const fd = openSync(getLockFile(), 'wx');
23
24
  closeSync(fd);
24
25
  break;
25
26
  } catch (err) {
@@ -27,10 +28,10 @@ function withLock(fn) {
27
28
  if (Date.now() < deadline) {
28
29
  // 检查是否为陈旧锁
29
30
  try {
30
- const stats = statSync(LOCK_FILE);
31
+ const stats = statSync(getLockFile());
31
32
  if (Date.now() - stats.mtimeMs > STALE_THRESHOLD) {
32
33
  // 尝试强制移除锁
33
- try { unlinkSync(LOCK_FILE); } catch { }
34
+ try { unlinkSync(getLockFile()); } catch { }
34
35
  // 立即重试获取
35
36
  continue;
36
37
  }
@@ -48,14 +49,14 @@ function withLock(fn) {
48
49
  try {
49
50
  return fn();
50
51
  } finally {
51
- try { unlinkSync(LOCK_FILE); } catch { }
52
+ try { unlinkSync(getLockFile()); } catch { }
52
53
  }
53
54
  }
54
55
 
55
56
  export function loadWorkspaces() {
56
57
  try {
57
- if (!existsSync(WORKSPACES_FILE)) return [];
58
- const data = JSON.parse(readFileSync(WORKSPACES_FILE, 'utf-8'));
58
+ if (!existsSync(getWorkspacesFile())) return [];
59
+ const data = JSON.parse(readFileSync(getWorkspacesFile(), 'utf-8'));
59
60
  return Array.isArray(data.workspaces) ? data.workspaces : [];
60
61
  } catch {
61
62
  return [];
@@ -63,7 +64,7 @@ export function loadWorkspaces() {
63
64
  }
64
65
 
65
66
  export function saveWorkspaces(list) {
66
- const tmpFile = `${WORKSPACES_FILE}.tmp-${process.pid}-${randomBytes(4).toString('hex')}`;
67
+ const tmpFile = `${getWorkspacesFile()}.tmp-${process.pid}-${randomBytes(4).toString('hex')}`;
67
68
  try {
68
69
  mkdirSync(LOG_DIR, { recursive: true });
69
70
  writeFileSync(tmpFile, JSON.stringify({ workspaces: list }, null, 2));
@@ -73,7 +74,7 @@ export function saveWorkspaces(list) {
73
74
  let retries = 3;
74
75
  while (retries > 0) {
75
76
  try {
76
- renameSync(tmpFile, WORKSPACES_FILE);
77
+ renameSync(tmpFile, getWorkspacesFile());
77
78
  break;
78
79
  } catch (err) {
79
80
  if (retries === 1) throw err;