coding-tool-x 3.5.9 → 3.5.11
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 +11 -0
- package/README.md +4 -25
- package/bin/ctx.js +1 -6
- package/dist/web/assets/{Analytics-C5W3axXs.js → Analytics-Bw-0r4Ys.js} +2 -2
- package/dist/web/assets/Analytics-RNn1BUbG.css +1 -0
- package/dist/web/assets/{ConfigTemplates-DzyVFDx9.js → ConfigTemplates-C6QRIeDj.js} +1 -1
- package/dist/web/assets/Home-BQxQ1LhR.css +1 -0
- package/dist/web/assets/{Home-C9TQNB6f.js → Home-B_Z9ythw.js} +1 -1
- package/dist/web/assets/{PluginManager-9B_brLWT.js → PluginManager-Ce-mws6Q.js} +1 -1
- package/dist/web/assets/ProjectList-9Z7FFCIT.js +1 -0
- package/dist/web/assets/ProjectList-DL4JK6ci.css +1 -0
- package/dist/web/assets/SessionList-CyETQcs8.js +1 -0
- package/dist/web/assets/SessionList-D12muXvx.css +1 -0
- package/dist/web/assets/{SkillManager-vST8DRRg.js → SkillManager-DSUcP1se.js} +1 -1
- package/dist/web/assets/{WorkspaceManager-ov1KgRXR.js → WorkspaceManager-Cvbc11bJ.js} +1 -1
- package/dist/web/assets/icons-lKCTySl7.js +1 -0
- package/dist/web/assets/index-BS7aplYp.css +1 -0
- package/dist/web/assets/index-CTeg1xG-.js +2 -0
- package/dist/web/assets/{markdown-DyTJGI4N.js → markdown-BNJfEgCA.js} +1 -1
- package/dist/web/assets/{naive-ui-Cg4_ZeoT.js → naive-ui-DM897mIP.js} +1 -1
- package/dist/web/assets/vendors-DQA4Hw9v.js +7 -0
- package/dist/web/assets/vue-vendor-B5RqjEjQ.js +45 -0
- package/dist/web/index.html +8 -8
- package/package.json +1 -2
- package/src/commands/daemon.js +5 -33
- package/src/commands/export-config.js +6 -6
- package/src/commands/stats.js +4 -41
- package/src/commands/ui.js +3 -12
- package/src/config/channel-preset-websites.js +114 -0
- package/src/config/default.js +9 -5
- package/src/config/loader.js +2 -2
- package/src/config/model-metadata.json +16 -20
- package/src/config/paths.js +33 -166
- package/src/index.js +34 -125
- package/src/server/api/agents.js +2 -52
- package/src/server/api/codex-channels.js +4 -0
- package/src/server/api/codex-proxy.js +45 -2
- package/src/server/api/codex-sessions.js +89 -12
- package/src/server/api/commands.js +2 -38
- package/src/server/api/dashboard.js +1 -25
- package/src/server/api/gemini-proxy.js +4 -2
- package/src/server/api/gemini-sessions.js +86 -9
- package/src/server/api/hooks.js +1 -17
- package/src/server/api/opencode-proxy.js +7 -2
- package/src/server/api/opencode-sessions.js +83 -10
- package/src/server/api/plugins.js +34 -128
- package/src/server/api/proxy.js +5 -3
- package/src/server/api/sessions.js +181 -27
- package/src/server/api/workspaces.js +0 -14
- package/src/server/index.js +9 -31
- package/src/server/services/agents-service.js +62 -269
- package/src/server/services/base/base-channel-service.js +3 -1
- package/src/server/services/channels.js +5 -0
- package/src/server/services/codex-channels.js +2 -0
- package/src/server/services/codex-sessions.js +88 -108
- package/src/server/services/commands-service.js +81 -281
- package/src/server/services/config-export-service.js +7 -7
- package/src/server/services/config-registry-service.js +9 -8
- package/src/server/services/config-sync-manager.js +41 -61
- package/src/server/services/config-sync-service.js +3 -3
- package/src/server/services/gemini-channels.js +17 -6
- package/src/server/services/gemini-config.js +4 -3
- package/src/server/services/gemini-sessions.js +59 -26
- package/src/server/services/gemini-settings-manager.js +3 -2
- package/src/server/services/mcp-service.js +14 -9
- package/src/server/services/native-oauth-adapters.js +3 -3
- package/src/server/services/network-access.js +2 -61
- package/src/server/services/notification-hooks.js +19 -184
- package/src/server/services/opencode-channels.js +9 -0
- package/src/server/services/opencode-sessions.js +6 -16
- package/src/server/services/opencode-settings-manager.js +3 -3
- package/src/server/services/plugins-service.js +62 -996
- package/src/server/services/prompts-service.js +9 -5
- package/src/server/services/sessions.js +171 -183
- package/src/server/services/skill-service.js +18 -155
- package/src/server/websocket-server.js +4 -35
- package/dist/web/assets/Analytics-vQS5IWvs.css +0 -1
- package/dist/web/assets/Home-qzk118Of.css +0 -1
- package/dist/web/assets/ProjectList-Bjt6mrsV.js +0 -1
- package/dist/web/assets/ProjectList-GCC2QOmq.css +0 -1
- package/dist/web/assets/SessionList-BsHPgmUR.css +0 -1
- package/dist/web/assets/SessionList-DcBH13uA.js +0 -1
- package/dist/web/assets/icons-CEq2hYB-.js +0 -1
- package/dist/web/assets/index-Dih_bOsv.css +0 -1
- package/dist/web/assets/index-Duc7QP4e.js +0 -2
- package/dist/web/assets/vendors-Bsp-dq2d.js +0 -7
- package/dist/web/assets/vue-vendor-BxIT0uQq.js +0 -45
- package/docs/Caddyfile.example +0 -19
- package/docs/reverse-proxy-https.md +0 -57
- package/src/server/services/https-cert.js +0 -171
- package/src/server/services/session-launch-command.js +0 -58
- package/src/server/services/web-ui-runtime.js +0 -54
|
@@ -1,171 +0,0 @@
|
|
|
1
|
-
const fs = require('fs');
|
|
2
|
-
const net = require('net');
|
|
3
|
-
const os = require('os');
|
|
4
|
-
const path = require('path');
|
|
5
|
-
const selfsigned = require('selfsigned');
|
|
6
|
-
const { PATHS } = require('../../config/paths');
|
|
7
|
-
|
|
8
|
-
function dedupeSorted(values = []) {
|
|
9
|
-
return [...new Set(values.filter(Boolean).map((value) => String(value).trim()).filter(Boolean))].sort();
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
function isIpAddress(value) {
|
|
13
|
-
return net.isIP(String(value || '').trim()) !== 0;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
function isValidDnsLabel(value) {
|
|
17
|
-
return /^[A-Za-z0-9.-]+$/.test(String(value || '').trim());
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
function collectLocalCertificateHosts() {
|
|
21
|
-
const hosts = ['localhost', '127.0.0.1', '::1'];
|
|
22
|
-
const hostname = os.hostname();
|
|
23
|
-
if (isValidDnsLabel(hostname)) {
|
|
24
|
-
hosts.push(hostname);
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
const interfaces = os.networkInterfaces();
|
|
28
|
-
Object.values(interfaces).forEach((entries) => {
|
|
29
|
-
(entries || []).forEach((entry) => {
|
|
30
|
-
const address = String(entry?.address || '').trim();
|
|
31
|
-
if (!address) {
|
|
32
|
-
return;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
if (entry?.family === 'IPv4' || entry?.family === 4) {
|
|
36
|
-
hosts.push(address);
|
|
37
|
-
return;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
if ((entry?.family === 'IPv6' || entry?.family === 6) && address !== '::1' && !address.startsWith('fe80::')) {
|
|
41
|
-
hosts.push(address);
|
|
42
|
-
}
|
|
43
|
-
});
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
return dedupeSorted(hosts);
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
function buildSubjectAltNames(hosts = collectLocalCertificateHosts()) {
|
|
50
|
-
return dedupeSorted(hosts).map((value) => (
|
|
51
|
-
isIpAddress(value)
|
|
52
|
-
? { type: 7, ip: value }
|
|
53
|
-
: { type: 2, value }
|
|
54
|
-
));
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
function ensureParentDir(filePath) {
|
|
58
|
-
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
function readMeta(metaPath) {
|
|
62
|
-
if (!fs.existsSync(metaPath)) {
|
|
63
|
-
return null;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
try {
|
|
67
|
-
return JSON.parse(fs.readFileSync(metaPath, 'utf8'));
|
|
68
|
-
} catch {
|
|
69
|
-
return null;
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
function needsRegeneration(hosts, meta) {
|
|
74
|
-
if (!meta || !Array.isArray(meta.hosts)) {
|
|
75
|
-
return true;
|
|
76
|
-
}
|
|
77
|
-
const currentHosts = dedupeSorted(hosts);
|
|
78
|
-
const storedHosts = dedupeSorted(meta.hosts);
|
|
79
|
-
return currentHosts.length !== storedHosts.length || currentHosts.some((value, index) => value !== storedHosts[index]);
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
function generateSelfSignedCertificate(hosts) {
|
|
83
|
-
const primaryHost = hosts.find((value) => value === '127.0.0.1')
|
|
84
|
-
|| hosts.find((value) => !isIpAddress(value))
|
|
85
|
-
|| hosts[0]
|
|
86
|
-
|| '127.0.0.1';
|
|
87
|
-
|
|
88
|
-
const attrs = [{ name: 'commonName', value: primaryHost }];
|
|
89
|
-
return selfsigned.generate(attrs, {
|
|
90
|
-
algorithm: 'sha256',
|
|
91
|
-
days: 3650,
|
|
92
|
-
keySize: 2048,
|
|
93
|
-
extensions: [
|
|
94
|
-
{ name: 'basicConstraints', cA: false },
|
|
95
|
-
{
|
|
96
|
-
name: 'keyUsage',
|
|
97
|
-
digitalSignature: true,
|
|
98
|
-
keyEncipherment: true
|
|
99
|
-
},
|
|
100
|
-
{
|
|
101
|
-
name: 'extKeyUsage',
|
|
102
|
-
serverAuth: true
|
|
103
|
-
},
|
|
104
|
-
{
|
|
105
|
-
name: 'subjectAltName',
|
|
106
|
-
altNames: buildSubjectAltNames(hosts)
|
|
107
|
-
}
|
|
108
|
-
]
|
|
109
|
-
});
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
function ensureLocalHttpsCertificate(options = {}) {
|
|
113
|
-
const keyPath = options.keyPath || PATHS.https.key;
|
|
114
|
-
const certPath = options.certPath || PATHS.https.cert;
|
|
115
|
-
const metaPath = options.metaPath || PATHS.https.meta;
|
|
116
|
-
const hosts = dedupeSorted(options.hosts || collectLocalCertificateHosts());
|
|
117
|
-
const existingMeta = readMeta(metaPath);
|
|
118
|
-
const hasFiles = fs.existsSync(keyPath) && fs.existsSync(certPath);
|
|
119
|
-
|
|
120
|
-
if (hasFiles && !needsRegeneration(hosts, existingMeta)) {
|
|
121
|
-
return {
|
|
122
|
-
keyPath,
|
|
123
|
-
certPath,
|
|
124
|
-
metaPath,
|
|
125
|
-
hosts,
|
|
126
|
-
generated: false
|
|
127
|
-
};
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
ensureParentDir(keyPath);
|
|
131
|
-
ensureParentDir(certPath);
|
|
132
|
-
ensureParentDir(metaPath);
|
|
133
|
-
|
|
134
|
-
const certificate = generateSelfSignedCertificate(hosts);
|
|
135
|
-
fs.writeFileSync(keyPath, certificate.private, 'utf8');
|
|
136
|
-
fs.writeFileSync(certPath, certificate.cert, 'utf8');
|
|
137
|
-
fs.writeFileSync(metaPath, JSON.stringify({
|
|
138
|
-
hosts,
|
|
139
|
-
generatedAt: new Date().toISOString()
|
|
140
|
-
}, null, 2), 'utf8');
|
|
141
|
-
|
|
142
|
-
return {
|
|
143
|
-
keyPath,
|
|
144
|
-
certPath,
|
|
145
|
-
metaPath,
|
|
146
|
-
hosts,
|
|
147
|
-
generated: true
|
|
148
|
-
};
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
function getLocalHttpsCredentials(options = {}) {
|
|
152
|
-
const certificate = ensureLocalHttpsCertificate(options);
|
|
153
|
-
return {
|
|
154
|
-
...certificate,
|
|
155
|
-
key: fs.readFileSync(certificate.keyPath),
|
|
156
|
-
cert: fs.readFileSync(certificate.certPath)
|
|
157
|
-
};
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
module.exports = {
|
|
161
|
-
ensureLocalHttpsCertificate,
|
|
162
|
-
getLocalHttpsCredentials,
|
|
163
|
-
_test: {
|
|
164
|
-
dedupeSorted,
|
|
165
|
-
isIpAddress,
|
|
166
|
-
isValidDnsLabel,
|
|
167
|
-
collectLocalCertificateHosts,
|
|
168
|
-
buildSubjectAltNames,
|
|
169
|
-
needsRegeneration
|
|
170
|
-
}
|
|
171
|
-
};
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
function escapeForDoubleQuotes(value) {
|
|
2
|
-
return String(value).replace(/"/g, '\\"');
|
|
3
|
-
}
|
|
4
|
-
|
|
5
|
-
function buildDisplayCommand(executable, args = []) {
|
|
6
|
-
return [String(executable || ''), ...args.map(arg => String(arg))].filter(Boolean).join(' ').trim();
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
function buildPosixCopyCommand(cwd, command) {
|
|
10
|
-
const quotedCwd = `"${escapeForDoubleQuotes(cwd)}"`;
|
|
11
|
-
return `cd ${quotedCwd} && ${command}`;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
function buildCopyCommand({
|
|
15
|
-
cwd,
|
|
16
|
-
command,
|
|
17
|
-
executable,
|
|
18
|
-
args = [],
|
|
19
|
-
runtimePlatform = process.platform,
|
|
20
|
-
runtimeEnv = process.env
|
|
21
|
-
}) {
|
|
22
|
-
const resolvedCommand = command || buildDisplayCommand(executable, args);
|
|
23
|
-
if (!cwd) {
|
|
24
|
-
return resolvedCommand;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
return buildPosixCopyCommand(cwd, resolvedCommand);
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
function buildLaunchCommand({
|
|
31
|
-
cwd,
|
|
32
|
-
executable,
|
|
33
|
-
args = [],
|
|
34
|
-
runtimePlatform = process.platform,
|
|
35
|
-
runtimeEnv = process.env
|
|
36
|
-
}) {
|
|
37
|
-
const command = buildDisplayCommand(executable, args);
|
|
38
|
-
return {
|
|
39
|
-
command,
|
|
40
|
-
copyCommand: buildCopyCommand({
|
|
41
|
-
cwd,
|
|
42
|
-
command,
|
|
43
|
-
executable,
|
|
44
|
-
args,
|
|
45
|
-
runtimePlatform,
|
|
46
|
-
runtimeEnv
|
|
47
|
-
})
|
|
48
|
-
};
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
module.exports = {
|
|
52
|
-
buildLaunchCommand,
|
|
53
|
-
_test: {
|
|
54
|
-
buildDisplayCommand,
|
|
55
|
-
buildCopyCommand,
|
|
56
|
-
buildPosixCopyCommand
|
|
57
|
-
}
|
|
58
|
-
};
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
function normalizeWebUiProtocol(value) {
|
|
2
|
-
return String(value || '').trim().toLowerCase() === 'https' ? 'https' : 'http';
|
|
3
|
-
}
|
|
4
|
-
|
|
5
|
-
function hasHttpsFlag(argv = process.argv) {
|
|
6
|
-
return Array.isArray(argv) && argv.includes('--https');
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
function getWebUiProtocol(options = {}) {
|
|
10
|
-
if (typeof options.https === 'boolean') {
|
|
11
|
-
return options.https ? 'https' : 'http';
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
if (typeof options.protocol === 'string' && options.protocol.trim()) {
|
|
15
|
-
return normalizeWebUiProtocol(options.protocol);
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
const env = options.env || process.env;
|
|
19
|
-
if (env && typeof env.CC_TOOL_WEB_UI_PROTOCOL === 'string' && env.CC_TOOL_WEB_UI_PROTOCOL.trim()) {
|
|
20
|
-
return normalizeWebUiProtocol(env.CC_TOOL_WEB_UI_PROTOCOL);
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
return hasHttpsFlag(options.argv || process.argv) ? 'https' : 'http';
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
function isHttpsEnabled(options = {}) {
|
|
27
|
-
return getWebUiProtocol(options) === 'https';
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
function getDefaultLoopbackHost(protocol = 'http') {
|
|
31
|
-
return normalizeWebUiProtocol(protocol) === 'https' ? '127.0.0.1' : 'localhost';
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
function getWebUiBaseUrl(port, options = {}) {
|
|
35
|
-
const protocol = getWebUiProtocol(options);
|
|
36
|
-
const hostname = String(options.hostname || '').trim() || getDefaultLoopbackHost(protocol);
|
|
37
|
-
return `${protocol}://${hostname}:${port}`;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
function getWebSocketBaseUrl(port, options = {}) {
|
|
41
|
-
const protocol = getWebUiProtocol(options) === 'https' ? 'wss' : 'ws';
|
|
42
|
-
const hostname = String(options.hostname || '').trim() || getDefaultLoopbackHost(protocol === 'wss' ? 'https' : 'http');
|
|
43
|
-
return `${protocol}://${hostname}:${port}`;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
module.exports = {
|
|
47
|
-
normalizeWebUiProtocol,
|
|
48
|
-
hasHttpsFlag,
|
|
49
|
-
getWebUiProtocol,
|
|
50
|
-
isHttpsEnabled,
|
|
51
|
-
getDefaultLoopbackHost,
|
|
52
|
-
getWebUiBaseUrl,
|
|
53
|
-
getWebSocketBaseUrl
|
|
54
|
-
};
|