coding-tool-x 3.5.8 → 3.5.10

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 (91) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/README.md +4 -25
  3. package/bin/ctx.js +1 -6
  4. package/dist/web/assets/{Analytics-BzoNzfbi.js → Analytics-DPb1zErn.js} +2 -2
  5. package/dist/web/assets/Analytics-RNn1BUbG.css +1 -0
  6. package/dist/web/assets/{ConfigTemplates-O4ikBt1o.js → ConfigTemplates-Bki2k4Lo.js} +1 -1
  7. package/dist/web/assets/{Home-BQjsnblU.js → Home-BKYHKSax.js} +1 -1
  8. package/dist/web/assets/Home-BQxQ1LhR.css +1 -0
  9. package/dist/web/assets/{PluginManager-DS_DJnVc.js → PluginManager-jgeQOE24.js} +1 -1
  10. package/dist/web/assets/ProjectList-CF67RzP_.js +1 -0
  11. package/dist/web/assets/ProjectList-DL4JK6ci.css +1 -0
  12. package/dist/web/assets/SessionList-DhHsY5q9.js +1 -0
  13. package/dist/web/assets/SessionList-lz23U6ZJ.css +1 -0
  14. package/dist/web/assets/{SkillManager-DpNE02r0.js → SkillManager-CtEz5gGp.js} +1 -1
  15. package/dist/web/assets/{WorkspaceManager-DMY7_SHh.js → WorkspaceManager-D3B0Y5XE.js} +1 -1
  16. package/dist/web/assets/icons-lKCTySl7.js +1 -0
  17. package/dist/web/assets/index-BS7aplYp.css +1 -0
  18. package/dist/web/assets/index-BnyNm74G.js +2 -0
  19. package/dist/web/assets/{markdown-DyTJGI4N.js → markdown-BNJfEgCA.js} +1 -1
  20. package/dist/web/assets/{naive-ui-Cg4_ZeoT.js → naive-ui-DM897mIP.js} +1 -1
  21. package/dist/web/assets/vendors-DQA4Hw9v.js +7 -0
  22. package/dist/web/assets/vue-vendor-B5RqjEjQ.js +45 -0
  23. package/dist/web/index.html +8 -8
  24. package/package.json +1 -2
  25. package/src/commands/daemon.js +5 -33
  26. package/src/commands/export-config.js +6 -6
  27. package/src/commands/stats.js +4 -41
  28. package/src/commands/ui.js +3 -12
  29. package/src/config/channel-preset-websites.js +114 -0
  30. package/src/config/default.js +9 -5
  31. package/src/config/loader.js +2 -2
  32. package/src/config/model-metadata.json +16 -20
  33. package/src/config/paths.js +33 -166
  34. package/src/index.js +34 -125
  35. package/src/server/api/agents.js +2 -52
  36. package/src/server/api/codex-proxy.js +4 -2
  37. package/src/server/api/codex-sessions.js +88 -9
  38. package/src/server/api/commands.js +2 -38
  39. package/src/server/api/dashboard.js +1 -25
  40. package/src/server/api/gemini-proxy.js +4 -2
  41. package/src/server/api/gemini-sessions.js +86 -9
  42. package/src/server/api/hooks.js +1 -17
  43. package/src/server/api/opencode-proxy.js +7 -2
  44. package/src/server/api/opencode-sessions.js +82 -7
  45. package/src/server/api/plugins.js +34 -128
  46. package/src/server/api/proxy.js +5 -3
  47. package/src/server/api/sessions.js +180 -24
  48. package/src/server/api/workspaces.js +0 -14
  49. package/src/server/index.js +9 -31
  50. package/src/server/services/agents-service.js +62 -269
  51. package/src/server/services/base/base-channel-service.js +3 -1
  52. package/src/server/services/channels.js +5 -0
  53. package/src/server/services/codex-channels.js +2 -0
  54. package/src/server/services/codex-sessions.js +78 -108
  55. package/src/server/services/commands-service.js +81 -281
  56. package/src/server/services/config-export-service.js +7 -7
  57. package/src/server/services/config-registry-service.js +9 -8
  58. package/src/server/services/config-sync-manager.js +41 -61
  59. package/src/server/services/config-sync-service.js +3 -3
  60. package/src/server/services/gemini-channels.js +17 -6
  61. package/src/server/services/gemini-config.js +4 -3
  62. package/src/server/services/gemini-sessions.js +51 -26
  63. package/src/server/services/gemini-settings-manager.js +3 -2
  64. package/src/server/services/mcp-service.js +14 -9
  65. package/src/server/services/native-oauth-adapters.js +3 -3
  66. package/src/server/services/network-access.js +2 -61
  67. package/src/server/services/notification-hooks.js +19 -184
  68. package/src/server/services/opencode-channels.js +9 -0
  69. package/src/server/services/opencode-sessions.js +4 -4
  70. package/src/server/services/opencode-settings-manager.js +3 -3
  71. package/src/server/services/plugins-service.js +62 -996
  72. package/src/server/services/prompts-service.js +9 -5
  73. package/src/server/services/sessions.js +128 -99
  74. package/src/server/services/skill-service.js +18 -155
  75. package/src/server/websocket-server.js +4 -35
  76. package/dist/web/assets/Analytics-vQS5IWvs.css +0 -1
  77. package/dist/web/assets/Home-qzk118Of.css +0 -1
  78. package/dist/web/assets/ProjectList-CqYDtsHx.js +0 -1
  79. package/dist/web/assets/ProjectList-GCC2QOmq.css +0 -1
  80. package/dist/web/assets/SessionList-CfPtcq6Y.css +0 -1
  81. package/dist/web/assets/SessionList-DMlLtMCz.js +0 -1
  82. package/dist/web/assets/icons-CEq2hYB-.js +0 -1
  83. package/dist/web/assets/index-Clf0l3wc.js +0 -2
  84. package/dist/web/assets/index-Dih_bOsv.css +0 -1
  85. package/dist/web/assets/vendors-Bsp-dq2d.js +0 -7
  86. package/dist/web/assets/vue-vendor-BxIT0uQq.js +0 -45
  87. package/docs/Caddyfile.example +0 -19
  88. package/docs/reverse-proxy-https.md +0 -57
  89. package/src/server/services/https-cert.js +0 -171
  90. package/src/server/services/session-launch-command.js +0 -81
  91. 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,81 +0,0 @@
1
- const { isWindowsLikePlatform } = require('../../utils/home-dir');
2
-
3
- function escapeForDoubleQuotes(value) {
4
- return String(value).replace(/"/g, '\\"');
5
- }
6
-
7
- function escapeForPowerShellSingleQuotes(value) {
8
- return String(value).replace(/'/g, "''");
9
- }
10
-
11
- function buildDisplayCommand(executable, args = []) {
12
- return [String(executable || ''), ...args.map(arg => String(arg))].filter(Boolean).join(' ').trim();
13
- }
14
-
15
- function buildWindowsCopyCommand(cwd, executable, args = []) {
16
- const quotedCwd = `'${escapeForPowerShellSingleQuotes(cwd)}'`;
17
- const quotedExecutable = `'${escapeForPowerShellSingleQuotes(executable)}'`;
18
- const quotedArgs = args.map(arg => `'${escapeForPowerShellSingleQuotes(arg)}'`).join(' ');
19
- const invokeCommand = quotedArgs
20
- ? `& ${quotedExecutable} ${quotedArgs}`
21
- : `& ${quotedExecutable}`;
22
-
23
- return `powershell -NoProfile -ExecutionPolicy Bypass -Command "& { Set-Location -LiteralPath ${quotedCwd}; ${invokeCommand} }"`;
24
- }
25
-
26
- function buildPosixCopyCommand(cwd, command) {
27
- const quotedCwd = `"${escapeForDoubleQuotes(cwd)}"`;
28
- return `cd ${quotedCwd} && ${command}`;
29
- }
30
-
31
- function buildCopyCommand({
32
- cwd,
33
- command,
34
- executable,
35
- args = [],
36
- runtimePlatform = process.platform,
37
- runtimeEnv = process.env
38
- }) {
39
- const resolvedCommand = command || buildDisplayCommand(executable, args);
40
- if (!cwd) {
41
- return resolvedCommand;
42
- }
43
-
44
- if (isWindowsLikePlatform(runtimePlatform, runtimeEnv)) {
45
- return buildWindowsCopyCommand(cwd, executable, args);
46
- }
47
-
48
- return buildPosixCopyCommand(cwd, resolvedCommand);
49
- }
50
-
51
- function buildLaunchCommand({
52
- cwd,
53
- executable,
54
- args = [],
55
- runtimePlatform = process.platform,
56
- runtimeEnv = process.env
57
- }) {
58
- const command = buildDisplayCommand(executable, args);
59
- return {
60
- command,
61
- copyCommand: buildCopyCommand({
62
- cwd,
63
- command,
64
- executable,
65
- args,
66
- runtimePlatform,
67
- runtimeEnv
68
- })
69
- };
70
- }
71
-
72
- module.exports = {
73
- buildLaunchCommand,
74
- _test: {
75
- buildDisplayCommand,
76
- buildCopyCommand,
77
- buildWindowsCopyCommand,
78
- buildPosixCopyCommand,
79
- escapeForPowerShellSingleQuotes
80
- }
81
- };
@@ -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
- };