coding-tool-x 3.3.8 → 3.4.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/CHANGELOG.md +17 -2
- package/README.md +253 -326
- package/dist/web/assets/{Analytics-DLpoDZ2M.js → Analytics-DEjfL5Jx.js} +4 -4
- package/dist/web/assets/Analytics-RNn1BUbG.css +1 -0
- package/dist/web/assets/{ConfigTemplates-D_hRb55W.js → ConfigTemplates-DkRL_-tf.js} +1 -1
- package/dist/web/assets/Home-BQxQ1LhR.css +1 -0
- package/dist/web/assets/Home-CF-L640I.js +1 -0
- package/dist/web/assets/{PluginManager-JXsyym1s.js → PluginManager-BzNYTdNB.js} +1 -1
- package/dist/web/assets/{ProjectList-DZWSeb-q.js → ProjectList-C0-JgHMM.js} +1 -1
- package/dist/web/assets/{SessionList-Cs624DR3.js → SessionList-CkZUdX5N.js} +1 -1
- package/dist/web/assets/{SkillManager-bEliz7qz.js → SkillManager-Cak0-4d4.js} +1 -1
- package/dist/web/assets/{WorkspaceManager-J3RecFGn.js → WorkspaceManager-CGDJzwEr.js} +1 -1
- package/dist/web/assets/{icons-Cuc23WS7.js → icons-B5Pl4lrD.js} +1 -1
- package/dist/web/assets/index-D_WItvHE.js +2 -0
- package/dist/web/assets/index-Dz7v9OM0.css +1 -0
- package/dist/web/assets/{markdown-C9MYpaSi.js → markdown-DyTJGI4N.js} +1 -1
- package/dist/web/assets/{naive-ui-CxpuzdjU.js → naive-ui-Bdxp09n2.js} +1 -1
- package/dist/web/assets/{vendors-DMjSfzlv.js → vendors-CKPV1OAU.js} +2 -2
- package/dist/web/assets/{vue-vendor-DET08QYg.js → vue-vendor-3bf-fPGP.js} +1 -1
- package/dist/web/index.html +7 -7
- package/docs/home.png +0 -0
- package/package.json +13 -5
- package/src/commands/daemon.js +3 -2
- package/src/commands/security.js +1 -2
- package/src/config/paths.js +638 -93
- package/src/server/api/agents.js +1 -1
- package/src/server/api/claude-hooks.js +13 -8
- package/src/server/api/codex-proxy.js +5 -4
- package/src/server/api/hooks.js +45 -0
- package/src/server/api/plugins.js +0 -1
- package/src/server/api/statistics.js +4 -4
- package/src/server/api/ui-config.js +5 -0
- package/src/server/api/workspaces.js +1 -3
- package/src/server/codex-proxy-server.js +89 -59
- package/src/server/gemini-proxy-server.js +107 -88
- package/src/server/index.js +1 -0
- package/src/server/opencode-proxy-server.js +381 -225
- package/src/server/proxy-server.js +86 -60
- package/src/server/services/alias.js +3 -3
- package/src/server/services/channels.js +3 -2
- package/src/server/services/codex-channels.js +38 -87
- package/src/server/services/codex-env-manager.js +426 -0
- package/src/server/services/codex-settings-manager.js +15 -15
- package/src/server/services/codex-statistics-service.js +3 -27
- package/src/server/services/config-export-service.js +20 -7
- package/src/server/services/config-registry-service.js +3 -2
- package/src/server/services/config-sync-manager.js +1 -1
- package/src/server/services/favorites.js +4 -3
- package/src/server/services/gemini-channels.js +3 -3
- package/src/server/services/gemini-statistics-service.js +3 -25
- package/src/server/services/mcp-service.js +2 -3
- package/src/server/services/model-detector.js +4 -3
- package/src/server/services/native-oauth-adapters.js +2 -1
- package/src/server/services/network-access.js +39 -1
- package/src/server/services/notification-hooks.js +951 -0
- package/src/server/services/opencode-channels.js +6 -6
- package/src/server/services/opencode-sessions.js +2 -2
- package/src/server/services/opencode-statistics-service.js +3 -27
- package/src/server/services/plugins-service.js +110 -31
- package/src/server/services/prompts-service.js +2 -3
- package/src/server/services/proxy-log-helper.js +242 -0
- package/src/server/services/proxy-runtime.js +6 -4
- package/src/server/services/repo-scanner-base.js +12 -4
- package/src/server/services/request-logger.js +7 -7
- package/src/server/services/security-config.js +4 -4
- package/src/server/services/session-cache.js +2 -2
- package/src/server/services/sessions.js +2 -2
- package/src/server/services/skill-service.js +174 -55
- package/src/server/services/statistics-service.js +10 -6
- package/src/server/services/ui-config.js +4 -3
- package/src/server/services/workspace-service.js +101 -156
- package/src/server/websocket-server.js +5 -4
- package/dist/web/assets/Analytics-DuYvId7u.css +0 -1
- package/dist/web/assets/Home-BMoFdAwy.css +0 -1
- package/dist/web/assets/Home-DNwp-0J-.js +0 -1
- package/dist/web/assets/index-BXeSvAwU.js +0 -2
- package/dist/web/assets/index-DWAC3Tdv.css +0 -1
- package/docs/bannel.png +0 -0
- package/docs/model-redirection.md +0 -251
|
@@ -4,34 +4,12 @@ const {
|
|
|
4
4
|
getDailyStatistics: getSharedDailyStatistics,
|
|
5
5
|
getTodayStatistics: getSharedTodayStatistics
|
|
6
6
|
} = require('./statistics-service');
|
|
7
|
+
const { normalizeUsageTokens, toNumber } = require('./proxy-log-helper');
|
|
7
8
|
|
|
8
9
|
const TOOL_TYPE = 'gemini';
|
|
9
10
|
|
|
10
|
-
function toNumber(value) {
|
|
11
|
-
const num = Number(value);
|
|
12
|
-
return Number.isFinite(num) ? num : 0;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
function normalizeToolTokens(tokens = {}) {
|
|
16
|
-
const input = toNumber(tokens.input);
|
|
17
|
-
const output = toNumber(tokens.output);
|
|
18
|
-
const cached = toNumber(tokens.cached);
|
|
19
|
-
const cacheCreation = toNumber(tokens.cacheCreation);
|
|
20
|
-
const cacheRead = toNumber(tokens.cacheRead || cached);
|
|
21
|
-
const total = toNumber(tokens.total) || (input + output);
|
|
22
|
-
|
|
23
|
-
return {
|
|
24
|
-
input,
|
|
25
|
-
output,
|
|
26
|
-
cached,
|
|
27
|
-
cacheCreation,
|
|
28
|
-
cacheRead,
|
|
29
|
-
total
|
|
30
|
-
};
|
|
31
|
-
}
|
|
32
|
-
|
|
33
11
|
function toLegacyEntryShape(entry = {}, includeName = false) {
|
|
34
|
-
const normalized =
|
|
12
|
+
const normalized = normalizeUsageTokens(TOOL_TYPE, entry.tokens || {});
|
|
35
13
|
const result = {
|
|
36
14
|
requests: toNumber(entry.requests),
|
|
37
15
|
tokens: {
|
|
@@ -123,7 +101,7 @@ function buildDailyStatistics(sharedDaily = {}, fallbackDate) {
|
|
|
123
101
|
}
|
|
124
102
|
|
|
125
103
|
function recordRequest(requestData = {}) {
|
|
126
|
-
const normalizedTokens =
|
|
104
|
+
const normalizedTokens = normalizeUsageTokens(TOOL_TYPE, requestData.tokens || {});
|
|
127
105
|
return recordSharedRequest({
|
|
128
106
|
...requestData,
|
|
129
107
|
toolType: TOOL_TYPE,
|
|
@@ -12,14 +12,13 @@ const { spawn } = require('child_process');
|
|
|
12
12
|
const http = require('http');
|
|
13
13
|
const https = require('https');
|
|
14
14
|
const { McpClient, buildMissingCommandMessage, createMissingCommandHint } = require('./mcp-client');
|
|
15
|
-
const { NATIVE_PATHS } = require('../../config/paths');
|
|
15
|
+
const { NATIVE_PATHS, PATHS } = require('../../config/paths');
|
|
16
16
|
const { resolvePreferredHomeDir } = require('../../utils/home-dir');
|
|
17
17
|
|
|
18
18
|
const HOME_DIR = resolvePreferredHomeDir(process.platform, process.env, os.homedir());
|
|
19
19
|
|
|
20
20
|
// MCP 配置文件路径
|
|
21
|
-
const
|
|
22
|
-
const MCP_SERVERS_FILE = path.join(CC_TOOL_DIR, 'mcp-servers.json');
|
|
21
|
+
const MCP_SERVERS_FILE = PATHS.mcpServers;
|
|
23
22
|
|
|
24
23
|
// 各平台配置文件路径
|
|
25
24
|
const CLAUDE_CONFIG_PATH = path.join(HOME_DIR, '.claude.json');
|
|
@@ -11,7 +11,7 @@ const { URL } = require('url');
|
|
|
11
11
|
const crypto = require('crypto');
|
|
12
12
|
const zlib = require('zlib');
|
|
13
13
|
const { loadConfig } = require('../../config/loader');
|
|
14
|
-
const {
|
|
14
|
+
const { PATHS } = require('../../config/paths');
|
|
15
15
|
|
|
16
16
|
// 内置模型优先级(当配置缺失时兜底)
|
|
17
17
|
const MODEL_PRIORITY = {
|
|
@@ -669,11 +669,12 @@ function collectResponseBody(res) {
|
|
|
669
669
|
* Get cache file path
|
|
670
670
|
*/
|
|
671
671
|
function getCacheFilePath() {
|
|
672
|
-
const
|
|
672
|
+
const filePath = PATHS.channelModels;
|
|
673
|
+
const dir = path.dirname(filePath);
|
|
673
674
|
if (!fs.existsSync(dir)) {
|
|
674
675
|
fs.mkdirSync(dir, { recursive: true });
|
|
675
676
|
}
|
|
676
|
-
return
|
|
677
|
+
return filePath;
|
|
677
678
|
}
|
|
678
679
|
|
|
679
680
|
/**
|
|
@@ -9,6 +9,7 @@ const claudeSettingsManager = require('./settings-manager');
|
|
|
9
9
|
const codexSettingsManager = require('./codex-settings-manager');
|
|
10
10
|
const geminiSettingsManager = require('./gemini-settings-manager');
|
|
11
11
|
const opencodeSettingsManager = require('./opencode-settings-manager');
|
|
12
|
+
const { syncCodexUserEnvironment } = require('./codex-env-manager');
|
|
12
13
|
const nativeKeychain = require('./native-keychain');
|
|
13
14
|
const { maskToken, decodeJwtPayload, removeFileIfExists, sha256 } = require('./oauth-utils');
|
|
14
15
|
|
|
@@ -312,7 +313,7 @@ function clearCodexOAuth() {
|
|
|
312
313
|
}
|
|
313
314
|
|
|
314
315
|
function removeCodexChannelEnvVars() {
|
|
315
|
-
|
|
316
|
+
syncCodexUserEnvironment({}, { replace: true });
|
|
316
317
|
}
|
|
317
318
|
|
|
318
319
|
function clearCodexChannelConfig() {
|
|
@@ -30,6 +30,26 @@ function isLoopbackRequest(req) {
|
|
|
30
30
|
return true;
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
+
function isSameOriginRequest(req) {
|
|
34
|
+
if (!req) return false;
|
|
35
|
+
const origin = req.headers && req.headers.origin;
|
|
36
|
+
if (!origin) {
|
|
37
|
+
return true;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const host = req.headers && req.headers.host;
|
|
41
|
+
if (!host) {
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
try {
|
|
46
|
+
const originUrl = new URL(origin);
|
|
47
|
+
return originUrl.host === host;
|
|
48
|
+
} catch (error) {
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
33
53
|
function createRemoteMutationGuard(options = {}) {
|
|
34
54
|
const enabled = options.enabled === true;
|
|
35
55
|
const allowRemoteMutation = options.allowRemoteMutation === true;
|
|
@@ -71,10 +91,28 @@ function createRemoteRouteGuard(options = {}) {
|
|
|
71
91
|
};
|
|
72
92
|
}
|
|
73
93
|
|
|
94
|
+
function createSameOriginGuard(options = {}) {
|
|
95
|
+
const enabled = options.enabled !== false;
|
|
96
|
+
const message = options.message || '禁止跨站访问该接口';
|
|
97
|
+
|
|
98
|
+
return (req, res, next) => {
|
|
99
|
+
if (!enabled || isSameOriginRequest(req)) {
|
|
100
|
+
return next();
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
return res.status(403).json({
|
|
104
|
+
error: message,
|
|
105
|
+
code: 'CROSS_ORIGIN_REQUEST_BLOCKED'
|
|
106
|
+
});
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
|
|
74
110
|
module.exports = {
|
|
75
111
|
normalizeAddress,
|
|
76
112
|
isLoopbackAddress,
|
|
77
113
|
isLoopbackRequest,
|
|
114
|
+
isSameOriginRequest,
|
|
78
115
|
createRemoteMutationGuard,
|
|
79
|
-
createRemoteRouteGuard
|
|
116
|
+
createRemoteRouteGuard,
|
|
117
|
+
createSameOriginGuard
|
|
80
118
|
};
|