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.
- package/cli.js +6 -1
- package/concepts/ar/GlobalSettings.md +232 -0
- package/concepts/da/GlobalSettings.md +232 -0
- package/concepts/de/GlobalSettings.md +232 -0
- package/concepts/en/GlobalSettings.md +232 -0
- package/concepts/es/GlobalSettings.md +232 -0
- package/concepts/fr/GlobalSettings.md +232 -0
- package/concepts/it/GlobalSettings.md +232 -0
- package/concepts/ja/GlobalSettings.md +232 -0
- package/concepts/ko/GlobalSettings.md +232 -0
- package/concepts/no/GlobalSettings.md +232 -0
- package/concepts/pl/GlobalSettings.md +232 -0
- package/concepts/pt-BR/GlobalSettings.md +232 -0
- package/concepts/ru/GlobalSettings.md +232 -0
- package/concepts/th/GlobalSettings.md +232 -0
- package/concepts/tr/GlobalSettings.md +232 -0
- package/concepts/uk/GlobalSettings.md +232 -0
- package/concepts/zh/GlobalSettings.md +232 -0
- package/concepts/zh-TW/GlobalSettings.md +232 -0
- package/dist/assets/App-D9tbz6gh.js +39 -0
- package/dist/assets/{AppHeader-CmLos5-f.css → AppHeader-CoP_9OY5.css} +1 -1
- package/dist/assets/{AppHeader.module-CTBJwgrr.js → AppHeader.module-NjKaHOFk.js} +93 -93
- package/dist/assets/{Mobile-AicWwDuy.js → Mobile-Kzk2YO-c.js} +1 -1
- package/dist/assets/{_basePickBy-BWXOF6Ri.js → _basePickBy-DloMkc-G.js} +1 -1
- package/dist/assets/{_baseUniq-CtBh9QNw.js → _baseUniq-DS0g4orB.js} +1 -1
- package/dist/assets/{arc-BZEM3DMb.js → arc-DjVGcsRC.js} +1 -1
- package/dist/assets/{architectureDiagram-2XIMDMQ5-BcsqHztP.js → architectureDiagram-2XIMDMQ5-C78NysdK.js} +1 -1
- package/dist/assets/{blockDiagram-WCTKOSBZ-xKCLQIlA.js → blockDiagram-WCTKOSBZ-D1eulsBg.js} +1 -1
- package/dist/assets/{c4Diagram-IC4MRINW-BMTzjp_O.js → c4Diagram-IC4MRINW-D_vDMNpu.js} +1 -1
- package/dist/assets/channel-DMPi3tRx.js +1 -0
- package/dist/assets/{chunk-4BX2VUAB-cu74dN32.js → chunk-4BX2VUAB-DvydnNaE.js} +1 -1
- package/dist/assets/{chunk-55IACEB6-Cn5pJZI7.js → chunk-55IACEB6-CAEBnB2g.js} +1 -1
- package/dist/assets/{chunk-FMBD7UC4-ClJXAago.js → chunk-FMBD7UC4-Ic2AFusw.js} +1 -1
- package/dist/assets/{chunk-JSJVCQXG-CvsqFIVj.js → chunk-JSJVCQXG-B6Pf0kWF.js} +1 -1
- package/dist/assets/{chunk-KX2RTZJC-By2tUg3C.js → chunk-KX2RTZJC-aqNHjszh.js} +1 -1
- package/dist/assets/{chunk-NQ4KR5QH-ryihu0iB.js → chunk-NQ4KR5QH-BRcgqkZb.js} +1 -1
- package/dist/assets/{chunk-QZHKN3VN-CkLeF_JG.js → chunk-QZHKN3VN-Dg6rNEne.js} +1 -1
- package/dist/assets/{chunk-WL4C6EOR-DGZ_HPlH.js → chunk-WL4C6EOR-BQztZi27.js} +1 -1
- package/dist/assets/classDiagram-VBA2DB6C-B6fMcVCH.js +1 -0
- package/dist/assets/classDiagram-v2-RAHNMMFH-B6fMcVCH.js +1 -0
- package/dist/assets/clone-NPdkGfRa.js +1 -0
- package/dist/assets/{cose-bilkent-S5V4N54A-Bug5hL7O.js → cose-bilkent-S5V4N54A-CpNbxUgF.js} +1 -1
- package/dist/assets/{dagre-KLK3FWXG-Bp95f3av.js → dagre-KLK3FWXG-DMV6CAiu.js} +1 -1
- package/dist/assets/{diagram-E7M64L7V-BnJcznPG.js → diagram-E7M64L7V-CzQpTBkT.js} +1 -1
- package/dist/assets/{diagram-IFDJBPK2-DTa6uDlT.js → diagram-IFDJBPK2-n98W4lW5.js} +1 -1
- package/dist/assets/{diagram-P4PSJMXO-BNjVizvt.js → diagram-P4PSJMXO-Da-Dxb0d.js} +1 -1
- package/dist/assets/{erDiagram-INFDFZHY-DeYo5Exx.js → erDiagram-INFDFZHY-DV6WDsOa.js} +1 -1
- package/dist/assets/{flowDiagram-PKNHOUZH-D8Rh5RJD.js → flowDiagram-PKNHOUZH-uPCoTO1u.js} +1 -1
- package/dist/assets/{ganttDiagram-A5KZAMGK-DZ0z2OiO.js → ganttDiagram-A5KZAMGK-C18veywB.js} +1 -1
- package/dist/assets/{gitGraphDiagram-K3NZZRJ6-DsoU0UJ3.js → gitGraphDiagram-K3NZZRJ6-CRgTEgJX.js} +1 -1
- package/dist/assets/{graph-FtHGSVXM.js → graph-E73hSxND.js} +1 -1
- package/dist/assets/{index-yvprqgUP.js → index-C7N4gnFf.js} +2 -2
- package/dist/assets/{infoDiagram-LFFYTUFH-BWptl6Gm.js → infoDiagram-LFFYTUFH-X_hBGUL2.js} +1 -1
- package/dist/assets/{ishikawaDiagram-PHBUUO56-DTN7vdFN.js → ishikawaDiagram-PHBUUO56-CUIYqfv2.js} +1 -1
- package/dist/assets/{journeyDiagram-4ABVD52K-C6rSfKFW.js → journeyDiagram-4ABVD52K-Ja_oFdN5.js} +1 -1
- package/dist/assets/{kanban-definition-K7BYSVSG-7zlzYuQI.js → kanban-definition-K7BYSVSG-CoxZi981.js} +1 -1
- package/dist/assets/{layout-DetVF_Xi.js → layout-CxyNCowe.js} +1 -1
- package/dist/assets/{linear-D7AP5ZM2.js → linear-BvMEMoa5.js} +1 -1
- package/dist/assets/{mermaid.core-BF7AL9QP.js → mermaid.core-yxi-tJV1.js} +4 -4
- package/dist/assets/{mindmap-definition-YRQLILUH-BAEZ_Kww.js → mindmap-definition-YRQLILUH-D0an_YiX.js} +1 -1
- package/dist/assets/{pieDiagram-SKSYHLDU-CTRIrNJJ.js → pieDiagram-SKSYHLDU-2_qKTz49.js} +1 -1
- package/dist/assets/{quadrantDiagram-337W2JSQ-DcUVHBRU.js → quadrantDiagram-337W2JSQ-DEdMIEZ6.js} +1 -1
- package/dist/assets/{requirementDiagram-Z7DCOOCP-nMrfF214.js → requirementDiagram-Z7DCOOCP-D34qZwqS.js} +1 -1
- package/dist/assets/{sankeyDiagram-WA2Y5GQK-BKM2oKi0.js → sankeyDiagram-WA2Y5GQK-CuWEPTrY.js} +1 -1
- package/dist/assets/{sequenceDiagram-2WXFIKYE-DcJnjEps.js → sequenceDiagram-2WXFIKYE-C_j_NZww.js} +1 -1
- package/dist/assets/{stateDiagram-RAJIS63D--wjhber7.js → stateDiagram-RAJIS63D-BQMmW3qX.js} +1 -1
- package/dist/assets/stateDiagram-v2-FVOUBMTO-C_b_318T.js +1 -0
- package/dist/assets/{timeline-definition-YZTLITO2-BzEHHLxX.js → timeline-definition-YZTLITO2-CQlUZTgI.js} +1 -1
- package/dist/assets/{treemap-KZPCXAKY-BKg_1Uvh.js → treemap-KZPCXAKY-Df9Nkrlt.js} +1 -1
- package/dist/assets/{vennDiagram-LZ73GAT5-BKfBvDlz.js → vennDiagram-LZ73GAT5-CaXvJV8t.js} +1 -1
- package/dist/assets/{xychartDiagram-JWTSCODW-2O6N9OtR.js → xychartDiagram-JWTSCODW-BWwflUcf.js} +1 -1
- package/dist/index.html +1 -1
- package/findcc.js +17 -1
- package/lib/perm-bridge.js +15 -14
- package/lib/plugin-loader.js +13 -12
- package/lib/sdk-manager.js +2 -2
- package/package.json +1 -1
- package/server.js +25 -14
- package/workspace-registry.js +11 -10
- package/dist/assets/App-BlTt-0pD.js +0 -39
- package/dist/assets/channel-UwYsH-gK.js +0 -1
- package/dist/assets/classDiagram-VBA2DB6C-BJV4gG6V.js +0 -1
- package/dist/assets/classDiagram-v2-RAHNMMFH-BJV4gG6V.js +0 -1
- package/dist/assets/clone-CjbFDS02.js +0 -1
- 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,
|
|
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
|
-
|
|
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(
|
|
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(
|
|
353
|
+
try { if (existsSync(getPrefsFile())) prefs = JSON.parse(readFileSync(getPrefsFile(), 'utf-8')); } catch { }
|
|
348
354
|
Object.assign(prefs, incoming);
|
|
349
|
-
|
|
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:
|
|
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(
|
|
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:
|
|
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:
|
|
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(
|
|
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:
|
|
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(
|
|
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:
|
|
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' });
|
package/workspace-registry.js
CHANGED
|
@@ -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
|
-
|
|
8
|
-
|
|
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(
|
|
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(
|
|
31
|
+
const stats = statSync(getLockFile());
|
|
31
32
|
if (Date.now() - stats.mtimeMs > STALE_THRESHOLD) {
|
|
32
33
|
// 尝试强制移除锁
|
|
33
|
-
try { unlinkSync(
|
|
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(
|
|
52
|
+
try { unlinkSync(getLockFile()); } catch { }
|
|
52
53
|
}
|
|
53
54
|
}
|
|
54
55
|
|
|
55
56
|
export function loadWorkspaces() {
|
|
56
57
|
try {
|
|
57
|
-
if (!existsSync(
|
|
58
|
-
const data = JSON.parse(readFileSync(
|
|
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 = `${
|
|
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,
|
|
77
|
+
renameSync(tmpFile, getWorkspacesFile());
|
|
77
78
|
break;
|
|
78
79
|
} catch (err) {
|
|
79
80
|
if (retries === 1) throw err;
|