zen-gitsync 2.12.2 → 2.12.3

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 (47) hide show
  1. package/LICENSE +190 -21
  2. package/index.js +25 -11
  3. package/package.json +2 -2
  4. package/scripts/convert-colors-to-vars.cjs +286 -272
  5. package/scripts/convert-fontsize-to-vars.cjs +221 -207
  6. package/scripts/convert-spacing-to-vars.cjs +256 -242
  7. package/scripts/convert-to-standard-vars.cjs +282 -268
  8. package/scripts/release.js +599 -585
  9. package/src/config.js +350 -336
  10. package/src/gitCommit.js +455 -440
  11. package/src/ui/public/assets/EditorView-CbqSI9nw.css +1 -0
  12. package/src/ui/public/assets/{EditorView-bnJmBq-i.js → EditorView-GS5cmh99.js} +2 -2
  13. package/src/ui/public/assets/SourceMapView-DyMK80hS.css +1 -0
  14. package/src/ui/public/assets/{SourceMapView-Rz5SD0A0.js → SourceMapView-_YRtzmZZ.js} +3 -3
  15. package/src/ui/public/assets/{index-bOs5P8fz.css → index-ML5Y-5lO.css} +1 -1
  16. package/src/ui/public/assets/{index-Bo3tntQh.js → index-yky0Sd13.js} +11 -11
  17. package/src/ui/public/index.html +2 -2
  18. package/src/ui/server/index.js +410 -396
  19. package/src/ui/server/middleware/requestLogger.js +51 -37
  20. package/src/ui/server/routes/branchStatus.js +101 -87
  21. package/src/ui/server/routes/code.js +110 -96
  22. package/src/ui/server/routes/codeAnalysis.js +995 -981
  23. package/src/ui/server/routes/config.js +1172 -1158
  24. package/src/ui/server/routes/exec.js +272 -258
  25. package/src/ui/server/routes/fileOpen.js +279 -265
  26. package/src/ui/server/routes/fs.js +701 -687
  27. package/src/ui/server/routes/git/diff.js +352 -338
  28. package/src/ui/server/routes/git/diffUtils.js +128 -114
  29. package/src/ui/server/routes/git/stash.js +552 -538
  30. package/src/ui/server/routes/git/tags.js +172 -158
  31. package/src/ui/server/routes/git.js +190 -176
  32. package/src/ui/server/routes/gitOps.js +1179 -1165
  33. package/src/ui/server/routes/instances.js +14 -0
  34. package/src/ui/server/routes/npm.js +1023 -1009
  35. package/src/ui/server/routes/process.js +82 -68
  36. package/src/ui/server/routes/status.js +67 -53
  37. package/src/ui/server/routes/terminal.js +319 -305
  38. package/src/ui/server/socket/registerUiSocketHandlers.js +226 -212
  39. package/src/ui/server/utils/createSavePortToFile.js +46 -32
  40. package/src/ui/server/utils/instanceRegistry.js +14 -0
  41. package/src/ui/server/utils/pathGuard.js +14 -0
  42. package/src/ui/server/utils/pathGuard.test.js +14 -0
  43. package/src/ui/server/utils/randomStartPort.js +14 -0
  44. package/src/ui/server/utils/startServerOnAvailablePort.js +101 -87
  45. package/src/utils/index.js +14 -0
  46. package/src/ui/public/assets/EditorView-CHBjgiZc.css +0 -1
  47. package/src/ui/public/assets/SourceMapView-DhQX0K7t.css +0 -1
@@ -1,87 +1,101 @@
1
- export async function startServerOnAvailablePort({
2
- httpServer,
3
- startPort,
4
- chalk,
5
- open,
6
- noOpen,
7
- isGitRepo,
8
- savePortToFile,
9
- maxTries = 100,
10
- callbackExecutedRef
11
- }) {
12
- let currentPort = startPort;
13
- const maxPort = startPort + maxTries;
14
- const getCallbackExecuted = () => {
15
- if (callbackExecutedRef && typeof callbackExecutedRef === 'object' && 'value' in callbackExecutedRef) {
16
- return Boolean(callbackExecutedRef.value);
17
- }
18
- return false;
19
- };
20
-
21
- const setCallbackExecuted = (value) => {
22
- if (callbackExecutedRef && typeof callbackExecutedRef === 'object' && 'value' in callbackExecutedRef) {
23
- callbackExecutedRef.value = Boolean(value);
24
- }
25
- };
26
-
27
- while (currentPort < maxPort) {
28
- try {
29
- if (currentPort > startPort) {
30
- await new Promise(resolve => setTimeout(resolve, 800));
31
- console.log(`尝试端口 ${currentPort}...`);
32
- }
33
-
34
- await new Promise((resolve, reject) => {
35
- const errorHandler = (err) => {
36
- httpServer.removeListener('error', errorHandler);
37
- reject(err);
38
- };
39
-
40
- httpServer.once('error', errorHandler);
41
-
42
- httpServer.listen(currentPort, () => {
43
- if (getCallbackExecuted()) return;
44
- setCallbackExecuted(true);
45
-
46
- httpServer.removeListener('error', errorHandler);
47
-
48
- console.log(chalk.green('======================================'));
49
- console.log(chalk.green(` Zen GitSync 服务器已启动`));
50
- console.log(chalk.green(` 访问地址: http://localhost:${currentPort}`));
51
- console.log(chalk.green(` 启动时间: ${new Date().toLocaleString()}`));
52
-
53
- if (isGitRepo) {
54
- console.log(chalk.green(` 当前目录是Git仓库`));
55
- } else {
56
- console.log(chalk.yellow(` 当前目录不是Git仓库,文件监控未启动`));
57
- }
58
-
59
- console.log(chalk.green('======================================'));
60
-
61
- savePortToFile(currentPort);
62
-
63
- if (!noOpen) {
64
- setTimeout(() => {
65
- open(`http://localhost:${currentPort}`);
66
- }, 0);
67
- }
68
-
69
- resolve();
70
- });
71
- });
72
-
73
- return currentPort;
74
- } catch (err) {
75
- if (err.code === 'EADDRINUSE') {
76
- console.log(`端口 ${currentPort} 被占用,尝试下一个端口...`);
77
- currentPort++;
78
- } else {
79
- console.error('启动服务器失败:', err);
80
- process.exit(1);
81
- }
82
- }
83
- }
84
-
85
- console.error(`无法找到可用端口 (尝试范围: ${startPort}-${maxPort - 1})`);
86
- process.exit(1);
87
- }
1
+ // Copyright 2026 xz333221
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+ //
15
+ export async function startServerOnAvailablePort({
16
+ httpServer,
17
+ startPort,
18
+ chalk,
19
+ open,
20
+ noOpen,
21
+ isGitRepo,
22
+ savePortToFile,
23
+ maxTries = 100,
24
+ callbackExecutedRef
25
+ }) {
26
+ let currentPort = startPort;
27
+ const maxPort = startPort + maxTries;
28
+ const getCallbackExecuted = () => {
29
+ if (callbackExecutedRef && typeof callbackExecutedRef === 'object' && 'value' in callbackExecutedRef) {
30
+ return Boolean(callbackExecutedRef.value);
31
+ }
32
+ return false;
33
+ };
34
+
35
+ const setCallbackExecuted = (value) => {
36
+ if (callbackExecutedRef && typeof callbackExecutedRef === 'object' && 'value' in callbackExecutedRef) {
37
+ callbackExecutedRef.value = Boolean(value);
38
+ }
39
+ };
40
+
41
+ while (currentPort < maxPort) {
42
+ try {
43
+ if (currentPort > startPort) {
44
+ await new Promise(resolve => setTimeout(resolve, 800));
45
+ console.log(`尝试端口 ${currentPort}...`);
46
+ }
47
+
48
+ await new Promise((resolve, reject) => {
49
+ const errorHandler = (err) => {
50
+ httpServer.removeListener('error', errorHandler);
51
+ reject(err);
52
+ };
53
+
54
+ httpServer.once('error', errorHandler);
55
+
56
+ httpServer.listen(currentPort, () => {
57
+ if (getCallbackExecuted()) return;
58
+ setCallbackExecuted(true);
59
+
60
+ httpServer.removeListener('error', errorHandler);
61
+
62
+ console.log(chalk.green('======================================'));
63
+ console.log(chalk.green(` Zen GitSync 服务器已启动`));
64
+ console.log(chalk.green(` 访问地址: http://localhost:${currentPort}`));
65
+ console.log(chalk.green(` 启动时间: ${new Date().toLocaleString()}`));
66
+
67
+ if (isGitRepo) {
68
+ console.log(chalk.green(` 当前目录是Git仓库`));
69
+ } else {
70
+ console.log(chalk.yellow(` 当前目录不是Git仓库,文件监控未启动`));
71
+ }
72
+
73
+ console.log(chalk.green('======================================'));
74
+
75
+ savePortToFile(currentPort);
76
+
77
+ if (!noOpen) {
78
+ setTimeout(() => {
79
+ open(`http://localhost:${currentPort}`);
80
+ }, 0);
81
+ }
82
+
83
+ resolve();
84
+ });
85
+ });
86
+
87
+ return currentPort;
88
+ } catch (err) {
89
+ if (err.code === 'EADDRINUSE') {
90
+ console.log(`端口 ${currentPort} 被占用,尝试下一个端口...`);
91
+ currentPort++;
92
+ } else {
93
+ console.error('启动服务器失败:', err);
94
+ process.exit(1);
95
+ }
96
+ }
97
+ }
98
+
99
+ console.error(`无法找到可用端口 (尝试范围: ${startPort}-${maxPort - 1})`);
100
+ process.exit(1);
101
+ }
@@ -1,3 +1,17 @@
1
+ // Copyright 2026 xz333221
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+ //
1
15
  // const chalk = require('chalk');
2
16
  // const boxen = require('boxen');
3
17
  // const message = chalk.blue('git diff') + '\n' +
@@ -1 +0,0 @@
1
- .editor-view[data-v-e532cc8f]{background:var(--bg-container);border:1px solid var(--border-color);width:100%;height:100%;box-shadow:var(--shadow-sm);border-radius:0;display:flex;overflow:hidden}.editor-sidebar[data-v-e532cc8f]{border-right:1px solid var(--border-color);background:var(--bg-panel);flex-direction:column;flex-shrink:0;display:flex;overflow:hidden}.sidebar-header[data-v-e532cc8f]{border-bottom:1px solid var(--border-color);flex-shrink:0;justify-content:space-between;align-items:center;padding:8px 10px 6px;display:flex}.sidebar-title[data-v-e532cc8f]{letter-spacing:.08em;text-transform:uppercase;color:var(--text-secondary);-webkit-user-select:none;user-select:none;font-size:11px;font-weight:700}.sidebar-action-btn[data-v-e532cc8f]{cursor:pointer;color:var(--text-tertiary);border-radius:var(--radius-base);background:0 0;border:none;align-items:center;padding:3px;display:flex}.sidebar-action-btn[data-v-e532cc8f]:hover{color:var(--text-primary);background:var(--bg-hover)}.sidebar-tree[data-v-e532cc8f]{flex:1;padding:4px 0;overflow:hidden auto}.tree-node[data-v-e532cc8f]{cursor:pointer;-webkit-user-select:none;user-select:none;height:24px;color:var(--text-primary);white-space:nowrap;border-radius:4px;align-items:center;gap:4px;padding-right:8px;font-size:13px;transition:background .1s;display:flex;overflow:hidden}.tree-node[data-v-e532cc8f]:hover{background:var(--bg-hover)}.tree-node--active[data-v-e532cc8f]{color:var(--color-primary);background:#3b82f61f}.tree-node--selected[data-v-e532cc8f]{outline-offset:-1px;background:#63b3ed26;outline:1px solid #63b3ed59}.tree-arrow[data-v-e532cc8f]{color:var(--text-tertiary);flex-shrink:0;align-items:center;width:12px;transition:transform .15s;display:flex}.tree-arrow.expanded[data-v-e532cc8f]{transform:rotate(90deg)}.tree-arrow-spacer[data-v-e532cc8f]{flex-shrink:0;width:12px}.tree-icon[data-v-e532cc8f]{flex-shrink:0;align-items:center;font-size:14px;line-height:1;display:flex}.tree-icon.mit-icon[data-v-e532cc8f]{fill:currentColor;vertical-align:middle;width:14px;height:14px;display:inline-block}.tree-icon--dir[data-v-e532cc8f]{color:#e8b84b}.tree-name[data-v-e532cc8f]{text-overflow:ellipsis;flex:1;min-width:0;font-size:13px;overflow:hidden}.tree-loading[data-v-e532cc8f]{border:1.5px solid var(--color-primary);border-top-color:#0000;border-radius:50%;flex-shrink:0;width:10px;height:10px;animation:.8s linear infinite spin-e532cc8f;display:inline-block}.tree-empty[data-v-e532cc8f]{color:var(--text-tertiary);text-align:center;padding:24px 12px;font-size:12px}.sidebar-loading[data-v-e532cc8f]{flex:1;justify-content:center;align-items:center;display:flex}.spin-icon[data-v-e532cc8f]{border:2px solid var(--color-primary);border-top-color:#0000;border-radius:50%;width:20px;height:20px;animation:.8s linear infinite spin-e532cc8f;display:inline-block}@keyframes spin-e532cc8f{to{transform:rotate(360deg)}}.editor-resizer[data-v-e532cc8f]{cursor:col-resize;z-index:2;background:0 0;flex-shrink:0;width:6px;transition:background .15s;position:relative}.editor-resizer[data-v-e532cc8f]:after{content:"";background:var(--color-gray-300);border-radius:2px;width:2px;height:32px;transition:background .15s,height .15s;position:absolute;top:50%;left:50%;transform:translate(-50%,-50%)}.editor-resizer[data-v-e532cc8f]:hover{background:#3b82f60f}.editor-resizer[data-v-e532cc8f]:hover:after{background:var(--color-primary);height:48px;box-shadow:0 0 8px #3b82f666}.editor-main[data-v-e532cc8f]{flex-direction:column;flex:1;display:flex;overflow:hidden}.editor-tabs[data-v-e532cc8f]{border-bottom:1px solid var(--border-color);background:var(--bg-panel);scrollbar-width:none;flex-shrink:0;display:flex;overflow:auto hidden}.editor-tabs[data-v-e532cc8f]::-webkit-scrollbar{display:none}.editor-tab[data-v-e532cc8f]{border-right:1px solid var(--border-color);cursor:pointer;height:34px;color:var(--text-secondary);-webkit-user-select:none;user-select:none;flex-shrink:0;align-items:center;gap:6px;min-width:80px;max-width:200px;padding:0 12px;font-size:12.5px;transition:background .1s,color .1s;display:flex}.editor-tab[data-v-e532cc8f]:hover{background:var(--bg-hover);color:var(--text-primary)}.editor-tab.active[data-v-e532cc8f]{background:var(--bg-container);color:var(--text-primary);border-bottom:2px solid var(--color-primary)}.tab-name[data-v-e532cc8f]{text-overflow:ellipsis;white-space:nowrap;flex:1;overflow:hidden}.tab-dirty-dot[data-v-e532cc8f]{background:var(--color-warning);border-radius:50%;flex-shrink:0;width:6px;height:6px}.tab-close[data-v-e532cc8f]{cursor:pointer;color:var(--text-tertiary);opacity:0;background:0 0;border:none;border-radius:3px;flex-shrink:0;align-items:center;padding:2px;transition:opacity .1s,background .1s;display:flex}.editor-tab:hover .tab-close[data-v-e532cc8f],.editor-tab.active .tab-close[data-v-e532cc8f]{opacity:1}.tab-close[data-v-e532cc8f]:hover{background:var(--bg-hover);color:var(--color-danger)}.editor-empty[data-v-e532cc8f]{color:var(--text-tertiary);-webkit-user-select:none;user-select:none;flex-direction:column;flex:1;justify-content:center;align-items:center;gap:10px;font-size:13px;display:flex}.editor-empty p[data-v-e532cc8f]{margin:0}.editor-empty-hint[data-v-e532cc8f]{opacity:.6;font-size:11px}.monaco-container[data-v-e532cc8f]{flex:1;min-width:0;overflow:hidden}.monaco-container.hidden[data-v-e532cc8f]{display:none}.image-tab-placeholder[data-v-e532cc8f]{justify-content:center;align-items:center;gap:var(--spacing-sm);color:var(--text-secondary);background:var(--bg-container);text-align:center;padding:var(--spacing-lg);flex-direction:column;flex:1;display:flex}.image-tab-placeholder-title[data-v-e532cc8f]{font-size:var(--font-size-md);font-weight:var(--font-weight-medium);color:var(--text-primary);word-break:break-all;margin:0}.image-tab-placeholder-hint[data-v-e532cc8f]{font-size:var(--font-size-sm);color:var(--text-tertiary);margin:0}.editor-body[data-v-e532cc8f]{flex:1;min-height:0;display:flex;overflow:hidden}.preview-resizer[data-v-e532cc8f]{cursor:col-resize;z-index:2;background:0 0;flex-shrink:0;order:99;width:6px;margin-left:auto;transition:background .15s;position:relative}.preview-resizer[data-v-e532cc8f]:after{content:"";background:var(--color-gray-300);border-radius:2px;width:2px;height:32px;transition:background .15s,height .15s;position:absolute;top:50%;left:50%;transform:translate(-50%,-50%)}.preview-resizer[data-v-e532cc8f]:hover{background:#3b82f60f}.preview-resizer[data-v-e532cc8f]:hover:after{background:var(--color-primary);height:48px;box-shadow:0 0 8px #3b82f666}.preview-panel[data-v-e532cc8f]{border-left:1px solid var(--border-color);background:var(--bg-panel);flex-direction:column;flex:1 1 0;min-width:200px;display:flex;overflow:hidden}.preview-header[data-v-e532cc8f]{border-bottom:1px solid var(--border-color);background:var(--bg-panel);flex-shrink:0;align-items:center;gap:6px;height:34px;padding:0 10px;display:flex}.preview-title[data-v-e532cc8f]{letter-spacing:.08em;text-transform:uppercase;color:var(--text-secondary);-webkit-user-select:none;user-select:none;font-size:11px;font-weight:700}.preview-ext-badge[data-v-e532cc8f]{color:var(--color-primary);letter-spacing:.04em;background:#3b82f626;border-radius:3px;padding:1px 5px;font-size:10px;font-weight:600}.preview-header-spacer[data-v-e532cc8f]{flex:1}.preview-close-btn[data-v-e532cc8f]{cursor:pointer;color:var(--text-tertiary);border-radius:var(--radius-base);background:0 0;border:none;align-items:center;padding:3px;transition:color .1s,background .1s;display:flex}.preview-close-btn[data-v-e532cc8f]:hover{color:var(--color-danger);background:var(--bg-hover)}.preview-body[data-v-e532cc8f]{flex-direction:column;flex:1;display:flex;overflow:hidden}.preview-iframe[data-v-e532cc8f]{background:0 0;border:none;flex:1;width:100%;height:100%}.preview-image-wrap[data-v-e532cc8f]{background:var(--bg-container);flex:1;justify-content:center;align-items:center;padding:16px;display:flex;overflow:auto}.preview-image-wrap img[data-v-e532cc8f]{object-fit:contain;border-radius:4px;max-width:100%;max-height:100%;box-shadow:0 2px 12px #0003}.editor-tabs-spacer[data-v-e532cc8f]{flex:1}.preview-toggle-btn[data-v-e532cc8f]{cursor:pointer;height:34px;color:var(--text-secondary);white-space:nowrap;border:none;border-left:1px solid var(--border-color);background:0 0;flex-shrink:0;align-items:center;gap:5px;padding:0 10px;font-size:12px;transition:background .1s,color .1s;display:flex}.preview-toggle-btn[data-v-e532cc8f]:hover{background:var(--bg-hover);color:var(--text-primary)}.preview-toggle-btn.active[data-v-e532cc8f]{color:var(--color-primary);background:#3b82f614}.sidebar-actions[data-v-e532cc8f]{align-items:center;gap:2px;display:flex}.tree-inline-input-row[data-v-e532cc8f]{cursor:default;background:var(--bg-hover)}.tree-inline-input[data-v-e532cc8f]{background:var(--bg-container);border:1px solid var(--color-primary);min-width:0;height:20px;color:var(--text-primary);border-radius:3px;outline:none;flex:1;padding:0 5px;font-family:inherit;font-size:12.5px}.ctx-menu[data-v-e532cc8f]{z-index:9999;background:var(--bg-panel);border:1px solid var(--border-color);-webkit-user-select:none;user-select:none;border-radius:6px;min-width:160px;padding:4px;position:fixed;box-shadow:0 8px 24px #00000040}.ctx-menu-item[data-v-e532cc8f]{cursor:pointer;width:100%;color:var(--text-primary);text-align:left;background:0 0;border:none;border-radius:4px;align-items:center;gap:8px;padding:6px 10px;font-size:12.5px;transition:background .1s;display:flex}.ctx-menu-item[data-v-e532cc8f]:hover{background:var(--bg-hover)}.ctx-menu-item--danger[data-v-e532cc8f]{color:var(--color-danger)}.ctx-menu-item--danger[data-v-e532cc8f]:hover{background:#ef44441a}.ctx-menu-sep[data-v-e532cc8f]{background:var(--border-color);height:1px;margin:4px 2px}
@@ -1 +0,0 @@
1
- .source-map-view[data-v-c404092c]{background:var(--bg-page,#0f172a);width:100%;height:100%;color:var(--text-primary,#e2e8f0);flex-direction:column;font-size:13px;display:flex;overflow:hidden}.sm-toolbar[data-v-c404092c]{background:var(--bg-container,#1e293b);border-bottom:1px solid var(--border-color,#334155);flex-shrink:0;align-items:center;gap:12px;padding:8px 16px;display:flex}.sm-toolbar-left[data-v-c404092c]{flex-shrink:0;align-items:center;gap:8px;display:flex}.sm-toolbar-center[data-v-c404092c]{flex:1;align-items:center;gap:8px;display:flex}.sm-toolbar-right[data-v-c404092c]{flex-shrink:0;align-items:center;gap:4px;display:flex}.sm-icon-map[data-v-c404092c]{color:#f59e0b}.sm-title[data-v-c404092c]{color:var(--text-primary,#e2e8f0);font-size:13px;font-weight:600}.sm-path-input[data-v-c404092c]{background:var(--bg-page,#0f172a);border:1px solid var(--border-color,#334155);height:30px;color:var(--text-primary,#e2e8f0);border-radius:6px;outline:none;flex:1;padding:0 10px;font-family:Consolas,Monaco,monospace;font-size:12px;transition:border-color .15s}.sm-path-input[data-v-c404092c]:focus{border-color:#f59e0b}.sm-path-input[data-v-c404092c]:disabled{opacity:.6;cursor:not-allowed}.sm-btn[data-v-c404092c]{cursor:pointer;white-space:nowrap;border:none;border-radius:6px;align-items:center;gap:6px;height:30px;padding:0 14px;font-size:12px;font-weight:500;transition:all .15s;display:inline-flex}.sm-btn-primary[data-v-c404092c]{color:#fff;background:linear-gradient(135deg,#f59e0b,#d97706)}.sm-btn-primary[data-v-c404092c]:hover:not(:disabled){background:linear-gradient(135deg,#fbbf24,#f59e0b)}.sm-btn-primary[data-v-c404092c]:disabled{opacity:.6;cursor:not-allowed}.sm-panel-btn[data-v-c404092c]{cursor:pointer;width:28px;height:28px;color:var(--text-tertiary,#64748b);background:0 0;border:1px solid #0000;border-radius:5px;justify-content:center;align-items:center;transition:all .15s;display:flex}.sm-panel-btn[data-v-c404092c]:hover,.sm-panel-btn.active[data-v-c404092c]{background:var(--bg-hover,#1e293b);border-color:var(--border-color,#334155);color:var(--text-primary,#e2e8f0)}.sm-panel-btn.active[data-v-c404092c]{color:#f59e0b;border-color:#f59e0b40}.sm-body[data-v-c404092c]{flex:1;min-height:0;display:flex;overflow:hidden}.sm-resizer[data-v-c404092c]{z-index:2;background:0 0;flex-shrink:0;transition:background .15s;position:relative}.sm-resizer-v[data-v-c404092c]{cursor:col-resize;width:6px}.sm-resizer-h[data-v-c404092c]{cursor:row-resize;height:6px}.sm-resizer[data-v-c404092c]:after{content:"";background:var(--border-color,#334155);border-radius:2px;transition:background .15s;position:absolute;top:50%;left:50%;transform:translate(-50%,-50%)}.sm-resizer-v[data-v-c404092c]:after{width:2px;height:32px}.sm-resizer-h[data-v-c404092c]:after{width:32px;height:2px}.sm-resizer[data-v-c404092c]:hover{background:#3b82f60f}.sm-resizer[data-v-c404092c]:hover:after{background:var(--color-primary,#3b82f6);box-shadow:0 0 8px #3b82f666}.sm-resizer-v[data-v-c404092c]:hover:after{height:48px}.sm-resizer-h[data-v-c404092c]:hover:after{width:48px}.sm-panel[data-v-c404092c]{flex-direction:column;min-width:0;display:flex;overflow:hidden}.sm-panel-files[data-v-c404092c]{background:var(--bg-container,#1e293b);border-right:1px solid var(--border-color,#334155);flex-shrink:0;min-width:0;overflow:hidden}.sm-panel-graph[data-v-c404092c]{background:var(--bg-page,#0f172a);flex:1;min-width:300px}.sm-panel-source[data-v-c404092c]{background:var(--bg-container,#1e293b);border-left:1px solid var(--border-color,#334155);flex-shrink:0}.sm-panel-header[data-v-c404092c]{color:var(--text-secondary,#94a3b8);text-transform:uppercase;letter-spacing:.05em;border-bottom:1px solid var(--border-color,#334155);background:var(--bg-container,#1e293b);flex-shrink:0;align-items:center;gap:6px;padding:6px 10px;font-size:11px;font-weight:600;display:flex}.sm-panel-body[data-v-c404092c]{flex:1;min-height:0;overflow:auto}.sm-project-info[data-v-c404092c]{background:var(--bg-container,#1e293b);border-bottom:1px solid var(--border-color,#334155);flex-shrink:0;align-items:center;gap:6px;padding:6px 12px;display:flex;overflow:hidden}.sm-lang-badge[data-v-c404092c]{color:#f59e0b;background:#f59e0b22;border:1px solid #f59e0b44;border-radius:4px;flex-shrink:0;align-items:center;padding:1px 7px;font-size:10px;font-weight:600;display:inline-flex}.sm-tech-tag[data-v-c404092c]{color:#93c5fd;background:#3b82f611;border:1px solid #3b82f630;border-radius:4px;flex-shrink:0;align-items:center;padding:1px 6px;font-size:10px;display:inline-flex}.sm-subsystem-tag[data-v-c404092c]{opacity:.85;background:0 0;border:1px solid;border-radius:4px;flex-shrink:0;align-items:center;gap:3px;padding:1px 7px;font-size:10px;font-weight:600;display:inline-flex}.sm-summary-text[data-v-c404092c]{color:var(--text-tertiary,#64748b);white-space:nowrap;text-overflow:ellipsis;flex:1;font-size:11px;overflow:hidden}.sm-graph-container[data-v-c404092c]{flex:1;min-height:0;position:relative;overflow:hidden}.sm-vue-flow[data-v-c404092c]{width:100%;height:100%}.sm-graph-empty[data-v-c404092c],.sm-graph-loading[data-v-c404092c]{color:var(--text-tertiary,#64748b);pointer-events:none;flex-direction:column;justify-content:center;align-items:center;gap:12px;font-size:13px;display:flex;position:absolute;inset:0}.sm-log-panel[data-v-c404092c]{border-top:1px solid var(--border-color,#334155);background:var(--bg-container,#1e293b);flex-direction:column;flex-shrink:0;min-height:60px;display:flex}.sm-log-header[data-v-c404092c]{color:var(--text-tertiary,#64748b);text-transform:uppercase;letter-spacing:.05em;border-bottom:1px solid var(--border-color,#334155);flex-shrink:0;align-items:center;gap:6px;padding:4px 10px;font-size:10px;font-weight:600;display:flex}.sm-log-indicator[data-v-c404092c]{background:#f59e0b;border-radius:50%;width:6px;height:6px;margin-left:auto;animation:1s infinite pulse-c404092c}@keyframes pulse-c404092c{0%,to{opacity:1}50%{opacity:.3}}.sm-log-body[data-v-c404092c]{flex:1;padding:4px 0;font-family:Consolas,Monaco,monospace;font-size:11px;overflow-y:auto}.sm-log-entry[data-v-c404092c]{padding:2px 10px;line-height:1.5}.sm-log-entry--info[data-v-c404092c]{color:#94a3b8}.sm-log-entry--success[data-v-c404092c]{color:#4ade80}.sm-log-entry--error[data-v-c404092c]{color:#f87171}.sm-log-entry--thinking[data-v-c404092c]{color:#f59e0b}.sm-file-tree[data-v-c404092c]{flex:1;padding:4px 0;overflow:hidden auto}.sm-tree-node[data-v-c404092c]{cursor:pointer;-webkit-user-select:none;user-select:none;height:24px;color:var(--text-primary,#e2e8f0);white-space:nowrap;box-sizing:border-box;border-radius:4px;align-items:center;gap:4px;padding-right:8px;font-size:13px;transition:background .1s;display:flex;overflow:hidden}.sm-tree-node[data-v-c404092c]:hover{background:var(--bg-hover)}.sm-tree-node--active[data-v-c404092c]{color:var(--color-primary,#3b82f6);background:#3b82f61f}.sm-tree-arrow[data-v-c404092c]{color:var(--text-tertiary,#64748b);flex-shrink:0;align-items:center;width:12px;transition:transform .15s;display:flex}.sm-tree-arrow.expanded[data-v-c404092c]{transform:rotate(90deg)}.sm-tree-arrow-spacer[data-v-c404092c]{flex-shrink:0;width:12px;display:inline-block}.sm-tree-icon[data-v-c404092c]{flex-shrink:0;align-items:center;font-size:14px;line-height:1;display:flex}.sm-tree-icon.mit-icon[data-v-c404092c]{fill:currentColor;vertical-align:middle;width:14px;height:14px;display:inline-block}.sm-tree-name[data-v-c404092c]{text-overflow:ellipsis;flex:1;min-width:0;font-size:13px;overflow:hidden}.sm-tree-empty[data-v-c404092c]{color:var(--text-tertiary,#64748b);text-align:center;padding:24px 12px;font-size:12px}.sm-node-detail[data-v-c404092c]{background:#f59e0b0c;border-bottom:1px solid #f59e0b22;flex-shrink:0;padding:8px 12px}.sm-node-name[data-v-c404092c]{color:#f59e0b;font-family:Consolas,monospace;font-size:13px;font-weight:600}.sm-node-file[data-v-c404092c]{color:var(--text-tertiary,#64748b);margin-top:2px;font-family:Consolas,monospace;font-size:10px}.sm-node-desc[data-v-c404092c]{color:var(--text-secondary,#94a3b8);margin-top:4px;font-size:11px;line-height:1.4}.sm-source-body[data-v-c404092c]{background:#0d1117;position:relative;overflow:hidden}.sm-monaco-container[data-v-c404092c]{width:100%;height:100%}.sm-source-overlay[data-v-c404092c]{z-index:10;color:var(--text-tertiary,#64748b);pointer-events:none;background:#0d111799;justify-content:center;align-items:center;font-size:12px;display:flex;position:absolute;inset:0}.sm-source-placeholder[data-v-c404092c]{pointer-events:none;background:#0d1117}.sm-empty[data-v-c404092c]{height:100%;min-height:60px;color:var(--text-tertiary,#64748b);text-align:center;justify-content:center;align-items:center;padding:12px;font-size:12px;display:flex}.sm-badge[data-v-c404092c]{background:var(--bg-page,#0f172a);border:1px solid var(--border-color,#334155);color:var(--text-secondary,#94a3b8);border-radius:4px;align-items:center;margin-left:4px;padding:1px 6px;font-size:10px;font-weight:600;display:inline-flex}.sm-badge-amber[data-v-c404092c]{color:#f59e0b;background:#f59e0b15;border-color:#f59e0b40}.sm-spinner[data-v-c404092c]{border:2px solid #ffffff40;border-top-color:#fff;border-radius:50%;width:12px;height:12px;animation:.8s linear infinite spin-c404092c;display:inline-block}.sm-spinner-lg[data-v-c404092c]{border-width:3px;border-color:#f59e0b #f59e0b20 #f59e0b20;width:32px;height:32px}@keyframes spin-c404092c{to{transform:rotate(360deg)}}[data-v-c404092c] .vue-flow__background{background:#0f172a}[data-v-c404092c] .vue-flow__controls{box-shadow:none;background:#1e293b;border:1px solid #334155;border-radius:8px}[data-v-c404092c] .vue-flow__controls-button{color:#94a3b8;background:0 0;border:none}[data-v-c404092c] .vue-flow__controls-button:hover{color:#e2e8f0;background:#0f172a}[data-v-c404092c] .vue-flow__minimap{background:#1e293b;border:1px solid #334155;border-radius:6px}[data-v-c404092c] .vue-flow__node{transition:box-shadow .15s}[data-v-c404092c] .vue-flow__node:hover{box-shadow:0 0 0 2px #f59e0b80}[data-v-c404092c] .vue-flow__node.selected{box-shadow:0 0 0 2px #f59e0b}.sm-layout-btn-wrap[data-v-c404092c]{z-index:10;position:absolute;top:10px;right:10px}.sm-layout-btn[data-v-c404092c]{background:var(--bg-container,#1e293b);border:1px solid var(--border-color,#334155);height:28px;color:var(--text-secondary,#94a3b8);cursor:pointer;white-space:nowrap;border-radius:6px;align-items:center;gap:5px;padding:0 10px;font-size:11px;font-weight:500;transition:all .15s;display:flex}.sm-layout-btn[data-v-c404092c]:hover:not(:disabled){color:#f59e0b;background:#f59e0b08;border-color:#f59e0b50}.sm-layout-btn[data-v-c404092c]:disabled{opacity:.45;cursor:not-allowed}.sm-fn-inner[data-v-c404092c]{text-align:center;flex-direction:column;gap:3px;width:100%;min-width:0;display:flex;overflow:hidden}.sm-fn-label[data-v-c404092c]{color:#e2e8f0;white-space:nowrap;text-overflow:ellipsis;max-width:100%;font-size:12px;font-weight:600;overflow:hidden}.sm-fn-desc[data-v-c404092c]{color:#94a3b8;white-space:nowrap;text-overflow:ellipsis;max-width:180px;font-size:10px;overflow:hidden}.sm-panel-header--tabs[data-v-c404092c]{gap:0;height:32px;min-height:32px;padding:0}.sm-tab-btn[data-v-c404092c]{cursor:pointer;height:100%;color:var(--text-tertiary,#64748b);text-transform:uppercase;letter-spacing:.05em;white-space:nowrap;background:0 0;border:none;border-bottom:2px solid #0000;flex:1;align-items:center;gap:4px;padding:0 8px;font-size:10px;font-weight:600;transition:all .15s;display:flex}.sm-tab-btn[data-v-c404092c]:hover{color:var(--text-secondary,#94a3b8);background:var(--bg-hover)}.sm-tab-btn.active[data-v-c404092c]{color:#f59e0b;border-bottom-color:#f59e0b}.sm-outline-body[data-v-c404092c]{flex:1;padding:4px 0;overflow:hidden auto}.sm-outline-group[data-v-c404092c]{margin-bottom:2px}.sm-outline-group-header[data-v-c404092c]{text-transform:uppercase;letter-spacing:.06em;background:var(--bg-container,#1e293b);z-index:1;align-items:center;gap:5px;padding:5px 10px 3px;font-size:10px;font-weight:700;display:flex;position:sticky;top:0}.sm-outline-node[data-v-c404092c]{cursor:pointer;align-items:center;gap:6px;height:26px;padding:0 8px 0 16px;transition:background .1s;display:flex;overflow:hidden}.sm-outline-node[data-v-c404092c]:hover{background:var(--bg-hover)}.sm-outline-node--active[data-v-c404092c]{background:#3b82f61f}.sm-outline-dot[data-v-c404092c]{border-radius:50%;flex-shrink:0;width:6px;height:6px}.sm-outline-label[data-v-c404092c]{color:var(--text-primary,#e2e8f0);white-space:nowrap;text-overflow:ellipsis;flex-shrink:0;max-width:80px;font-family:Consolas,monospace;font-size:12px;font-weight:500;overflow:hidden}.sm-outline-desc[data-v-c404092c]{color:var(--text-tertiary,#64748b);white-space:nowrap;text-overflow:ellipsis;flex:1;font-size:10px;overflow:hidden}