teleton 0.5.1 → 0.6.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.
@@ -0,0 +1 @@
1
+ *{box-sizing:border-box;margin:0;padding:0}:root{color-scheme:dark;--bg: #000000;--surface: rgba(255, 255, 255, .05);--surface-hover: rgba(255, 255, 255, .08);--surface-active: rgba(255, 255, 255, .12);--glass: rgba(255, 255, 255, .06);--glass-border: rgba(255, 255, 255, .1);--glass-border-strong: rgba(255, 255, 255, .15);--text: rgba(255, 255, 255, .92);--text-secondary: rgba(255, 255, 255, .55);--text-tertiary: rgba(255, 255, 255, .35);--text-on-accent: #ffffff;--accent: #0A84FF;--accent-dim: rgba(10, 132, 255, .15);--green: #30D158;--green-dim: rgba(48, 209, 88, .15);--orange: #FF9F0A;--orange-dim: rgba(255, 159, 10, .15);--red: #FF453A;--red-dim: rgba(255, 69, 58, .15);--purple: #BF5AF2;--purple-dim: rgba(191, 90, 242, .15);--cyan: #64D2FF;--cyan-dim: rgba(100, 210, 255, .15);--separator: rgba(255, 255, 255, .08);--sidebar-bg: rgba(255, 255, 255, .03);--scrollbar: rgba(255, 255, 255, .1);--scrollbar-hover: rgba(255, 255, 255, .2);--shadow-sm: 0 1px 3px rgba(0, 0, 0, .3);--thumb-bg: #ffffff;--radius-sm: 10px;--radius-md: 14px;--radius-lg: 20px;--radius-xl: 26px;--blur: 40px;--blur-heavy: 80px}html,body{height:100%}body{font-family:Inter,-apple-system,BlinkMacSystemFont,sans-serif;background:var(--bg);color:var(--text);line-height:1.5;font-size:14px;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}#root{min-height:100vh}.container{display:flex;min-height:100vh}.sidebar{width:220px;padding:20px 12px;background:var(--sidebar-bg);border-right:1px solid var(--separator);display:flex;flex-direction:column;gap:4px;position:sticky;top:0;height:100vh;overflow-y:auto}.sidebar-brand{padding:4px 12px 20px;font-size:15px;font-weight:600;letter-spacing:-.2px;color:var(--text)}.sidebar nav{display:flex;flex-direction:column;gap:2px}.sidebar a{display:flex;align-items:center;gap:10px;padding:8px 12px;border-radius:var(--radius-sm);color:var(--text-secondary);text-decoration:none;font-size:13px;font-weight:500;transition:all .2s ease}.sidebar a:hover{color:var(--text);background:var(--surface);text-decoration:none}.sidebar a.active{color:var(--text);background:var(--surface-hover);text-decoration:none}.main{flex:1;padding:32px;max-width:1080px;min-width:0}.header{margin-bottom:28px}.header h1{font-size:22px;font-weight:600;letter-spacing:-.4px;margin-bottom:4px}.header p{color:var(--text-secondary);font-size:13px}.card{background:var(--glass);backdrop-filter:blur(var(--blur)) saturate(180%);-webkit-backdrop-filter:blur(var(--blur)) saturate(180%);border:1px solid var(--glass-border);border-radius:var(--radius-lg);padding:20px;margin-bottom:16px}.card h2{font-size:15px;font-weight:600;letter-spacing:-.2px}.stats{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:12px;margin-bottom:20px}.stat-card{background:var(--glass);backdrop-filter:blur(var(--blur)) saturate(180%);-webkit-backdrop-filter:blur(var(--blur)) saturate(180%);border:1px solid var(--glass-border);border-radius:var(--radius-md);padding:16px}.stat-card h3{font-size:12px;font-weight:500;color:var(--text-secondary);margin-bottom:6px;text-transform:uppercase;letter-spacing:.5px}.stat-card .value{font-size:24px;font-weight:600;letter-spacing:-.5px}button{font-family:Inter,-apple-system,BlinkMacSystemFont,sans-serif;background:var(--accent);color:var(--text-on-accent);border:none;padding:8px 16px;border-radius:var(--radius-sm);cursor:pointer;font-size:13px;font-weight:500;transition:opacity .15s ease}button:hover{opacity:.85}button:disabled{opacity:.4;cursor:not-allowed}input,textarea,select{font-family:Inter,-apple-system,BlinkMacSystemFont,sans-serif;background:var(--surface);border:1px solid var(--glass-border);color:var(--text);padding:10px 14px;border-radius:var(--radius-sm);font-size:13px;outline:none;transition:border-color .2s ease}select{-moz-appearance:none;appearance:none;-webkit-appearance:none;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='rgba(255,255,255,0.55)' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right 12px center;padding-right:36px;cursor:pointer}.custom-select{position:relative;z-index:1}.custom-select:has(.custom-select-menu){z-index:200}.custom-select-trigger{width:100%;display:flex;align-items:center;justify-content:space-between;background:var(--surface);border:1px solid var(--glass-border);color:var(--text);padding:10px 14px;border-radius:var(--radius-sm);font-size:13px;font-family:Inter,-apple-system,BlinkMacSystemFont,sans-serif;cursor:pointer;transition:border-color .2s ease}.custom-select-trigger:hover{border-color:var(--glass-border-strong);opacity:1}.custom-select-trigger:focus{border-color:var(--accent)}.custom-select-trigger svg{color:var(--text-secondary);flex-shrink:0}.custom-select-menu{position:absolute;top:calc(100% + 4px);left:0;right:0;background:var(--bg);border:1px solid var(--glass-border-strong);border-radius:var(--radius-sm);padding:4px;z-index:50;box-shadow:0 8px 24px #00000080;max-height:200px;overflow-y:auto}.custom-select-option{padding:8px 12px;border-radius:6px;font-size:13px;color:var(--text-secondary);cursor:pointer;transition:all .1s ease}.custom-select-option:hover,.custom-select-option.focused{background:var(--surface-hover);color:var(--text)}.custom-select-option.active,.custom-select-option.active.focused{background:var(--accent-dim);color:var(--accent)}input:focus,textarea:focus,select:focus{border-color:var(--accent)}input::placeholder,textarea::placeholder{color:var(--text-tertiary)}textarea{width:100%;min-height:400px;font-family:SF Mono,Fira Code,Cascadia Code,monospace;font-size:13px;line-height:1.6;resize:vertical;border-radius:var(--radius-md)}a{color:var(--accent);text-decoration:none}a:hover{text-decoration:none;opacity:.8}.badge{display:inline-flex;align-items:center;padding:2px 7px;border-radius:4px;font-size:11px;font-weight:500;letter-spacing:.2px;background:var(--surface);color:var(--text-secondary);border:1px solid var(--separator)}.badge.count{color:var(--text)}.badge.warn{color:var(--orange);border-color:color-mix(in srgb,var(--orange) 30%,transparent)}.badge.error{color:var(--red);border-color:color-mix(in srgb,var(--red) 30%,transparent)}.badge.always{color:var(--green);border-color:color-mix(in srgb,var(--green) 30%,transparent)}.tabs{display:flex;gap:2px;padding:3px;background:var(--surface);border:1px solid var(--glass-border);border-radius:var(--radius-sm);margin-bottom:16px}.tab{position:relative;padding:7px 16px;background:none;border:none;color:var(--text-secondary);cursor:pointer;border-radius:8px;font-size:13px;font-weight:500;transition:all .2s ease;flex:1;text-align:center}.tab:hover{color:var(--text);opacity:1}.tab.active{color:var(--text);background:var(--surface-active);box-shadow:0 1px 3px #0003}.tab .tab-count{display:inline-flex;align-items:center;justify-content:center;min-width:18px;height:18px;padding:0 5px;margin-left:6px;border-radius:9px;font-size:11px;font-weight:600;background:var(--glass);color:var(--text-tertiary)}.tab.active .tab-count{background:var(--accent-dim);color:var(--accent)}button.btn-ghost{background:var(--surface);color:var(--text-secondary);border:1px solid var(--glass-border)}button.btn-ghost:hover{background:var(--surface-hover);color:var(--text);opacity:1}button.btn-danger{background:var(--red-dim);color:var(--red);border:1px solid rgba(255,69,58,.15)}button.btn-danger:hover{background:#ff453a33;opacity:1}button.btn-sm{padding:5px 10px;font-size:12px;border-radius:8px}.tag-pill{display:inline-flex;align-items:center;padding:3px 9px;border-radius:12px;font-size:11px;font-weight:500;background:var(--surface);color:var(--text-secondary);border:1px solid var(--glass-border);cursor:pointer;transition:all .15s ease}.tag-pill:hover{background:var(--surface-hover);color:var(--text);border-color:var(--glass-border-strong)}.tag-pill.active{background:var(--accent-dim);color:var(--accent);border-color:#0a84ff4d}.form-group{margin-bottom:16px}.form-group label{display:block;margin-bottom:6px;font-size:13px;font-weight:500;color:var(--text-secondary)}.alert{padding:10px 14px;border-radius:var(--radius-sm);margin-bottom:16px;font-size:13px}.alert.success{background:var(--green-dim);color:var(--green);border:1px solid rgba(48,209,88,.2)}.alert.error{background:var(--red-dim);color:var(--red);border:1px solid rgba(255,69,58,.2)}.file-row{transition:background-color .15s ease}.file-row:hover{background-color:var(--sidebar-bg)}.icon-button{background:none;border:none;cursor:pointer;padding:4px 6px;font-size:15px;opacity:.5;filter:grayscale(1);transition:opacity .15s,filter .15s}.icon-button:hover{opacity:1;filter:none}.log-entry{font-family:SF Mono,Fira Code,Cascadia Code,monospace;font-size:12px;padding:5px 0;border-bottom:1px solid var(--separator);line-height:1.5}.log-entry:last-child{border-bottom:none}.accordion-header{position:relative;z-index:2;padding:14px 16px;cursor:pointer;display:flex;align-items:center;gap:12px;transition:background-color .15s ease}.accordion-header:hover{background-color:var(--sidebar-bg)}.accordion-chevron{font-size:10px;color:var(--text-secondary);width:12px;flex-shrink:0}.tool-row{position:relative;padding:10px 14px;background:var(--surface);border-radius:var(--radius-sm);display:flex;justify-content:space-between;align-items:center;transition:background .15s ease}.tool-row:hover{background:var(--surface-hover)}.tool-name{font-size:13px;font-weight:500;margin-bottom:2px}.tool-desc{font-size:12px;color:var(--text-secondary)}.plugin-meta{font-size:12px;color:var(--text-secondary);margin-bottom:8px}.result-item{padding:14px;background:var(--surface);border-radius:var(--radius-sm);margin-bottom:8px}.result-meta{font-size:12px;color:var(--text-secondary);margin-bottom:6px}.result-text{font-size:13px;line-height:1.6}.status-dot{display:inline-block;width:8px;height:8px;border-radius:50%;margin-right:6px}.status-dot.connected{background:var(--green)}.status-dot.disconnected{background:var(--red)}.login-container{display:flex;align-items:center;justify-content:center;min-height:100vh;padding:2rem}.login-card{background:var(--glass);backdrop-filter:blur(var(--blur)) saturate(180%);-webkit-backdrop-filter:blur(var(--blur)) saturate(180%);border:1px solid var(--glass-border);border-radius:var(--radius-xl);padding:32px;max-width:380px;width:100%}.login-card h1{font-size:20px;font-weight:600;margin-bottom:8px;letter-spacing:-.3px}.login-card p{color:var(--text-secondary);font-size:13px;margin-bottom:24px;line-height:1.5}.section-title{font-size:13px;font-weight:600;color:var(--text-secondary);text-transform:uppercase;letter-spacing:.5px;margin-bottom:12px}.empty{color:var(--text-tertiary);font-size:13px;padding:20px 0;text-align:center}::-webkit-scrollbar{width:6px;height:6px}::-webkit-scrollbar-track{background:transparent}::-webkit-scrollbar-thumb{background:var(--scrollbar);border-radius:3px}::-webkit-scrollbar-thumb:hover{background:var(--scrollbar-hover)}.scope-seg{display:inline-flex;padding:2px;background:var(--glass);border-radius:8px;gap:2px}.scope-seg button{padding:4px 10px;font-size:11px;font-weight:500;background:none;color:var(--text-tertiary);border:none;border-radius:6px;cursor:pointer;transition:all .2s ease}.scope-seg button:hover:not(:disabled):not(.active){color:var(--text-secondary);opacity:1}.scope-seg button.active{background:var(--surface-active);color:var(--text)}.scope-seg.disabled{opacity:.4;pointer-events:none}.toggle{position:relative;width:42px;height:26px;flex-shrink:0;cursor:pointer}.toggle input{opacity:0;width:0;height:0;position:absolute}.toggle-track{position:absolute;top:0;right:0;bottom:0;left:0;background:var(--scrollbar);border-radius:13px;transition:background .25s ease}.toggle input:checked+.toggle-track{background:var(--green)}.toggle-thumb{position:absolute;top:3px;left:3px;width:20px;height:20px;background:var(--thumb-bg);border-radius:50%;transition:transform .25s cubic-bezier(.4,0,.2,1);box-shadow:var(--shadow-sm)}.toggle input:checked~.toggle-thumb{transform:translate(16px)}.toggle input:disabled+.toggle-track{opacity:.4}.toggle input:disabled~.toggle-thumb{opacity:.4}.modal-overlay{position:fixed;top:0;right:0;bottom:0;left:0;background:#0009;display:flex;align-items:center;justify-content:center;z-index:100}.modal{background:var(--bg);border:1px solid var(--glass-border-strong);border-radius:var(--radius-lg);padding:24px;max-width:480px;width:90%;max-height:80vh;overflow-y:auto;box-shadow:0 16px 48px #00000080}.loading{color:var(--text-tertiary);font-size:13px;padding:40px 0;text-align:center}
@@ -7,8 +7,8 @@
7
7
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
8
8
  <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&display=swap" rel="stylesheet" />
9
9
  <title>Teleton</title>
10
- <script type="module" crossorigin src="/assets/index-DDX8oQ2z.js"></script>
11
- <link rel="stylesheet" crossorigin href="/assets/index-CDMbujHf.css">
10
+ <script type="module" crossorigin src="/assets/index-BNhrx9S1.js"></script>
11
+ <link rel="stylesheet" crossorigin href="/assets/index-CqrrRLOh.css">
12
12
  </head>
13
13
  <body>
14
14
  <div id="root"></div>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "teleton",
3
- "version": "0.5.1",
3
+ "version": "0.6.0",
4
4
  "workspaces": [
5
5
  "packages/*"
6
6
  ],
@@ -47,8 +47,8 @@
47
47
  "dev:web": "cd web && npm run dev",
48
48
  "setup": "node dist/cli/index.js setup",
49
49
  "doctor": "node dist/cli/index.js doctor",
50
- "lint": "eslint src --ext .ts",
51
- "lint:fix": "eslint src --ext .ts --fix",
50
+ "lint": "eslint src",
51
+ "lint:fix": "eslint src --fix",
52
52
  "format": "prettier --write \"src/**/*.ts\"",
53
53
  "format:check": "prettier --check \"src/**/*.ts\"",
54
54
  "test": "vitest run",
@@ -59,39 +59,39 @@
59
59
  "prepare": "husky"
60
60
  },
61
61
  "dependencies": {
62
- "@clack/prompts": "^0.7.0",
62
+ "@clack/prompts": "^1.0.1",
63
63
  "@dedust/sdk": "^0.8.7",
64
- "@evaafi/sdk": "^0.9.5",
65
64
  "@hono/node-server": "^1.19.9",
66
65
  "@huggingface/transformers": "^3.8.1",
67
- "@mariozechner/pi-ai": "^0.50.9",
66
+ "@mariozechner/pi-ai": "^0.52.12",
67
+ "@modelcontextprotocol/sdk": "^1.26.0",
68
68
  "@orbs-network/ton-access": "^2.3.3",
69
69
  "@sinclair/typebox": "^0.34.48",
70
- "@storm-trade/sdk": "^1.0.0-rc.4",
71
- "@ton/core": "^0.63.0",
70
+ "@tavily/core": "^0.7.1",
71
+ "@ton/core": "^0.63.1",
72
72
  "@ton/crypto": "^3.3.0",
73
- "@ton/ton": "^16.1.0",
74
- "better-sqlite3": "^11.7.0",
73
+ "@ton/ton": "^16.2.2",
74
+ "better-sqlite3": "^12.6.2",
75
75
  "chokidar": "^5.0.0",
76
- "commander": "^12.0.0",
76
+ "commander": "^14.0.3",
77
77
  "crypto-js": "^4.2.0",
78
- "grammy": "^1.39.3",
78
+ "grammy": "^1.40.0",
79
79
  "hono": "^4.11.9",
80
80
  "js-tiktoken": "^1.0.21",
81
81
  "sqlite-vec": "^0.1.7-alpha.2",
82
82
  "telegram": "^2.26.22",
83
83
  "yaml": "^2.7.0",
84
- "zod": "^3.24.0"
84
+ "zod": "^4.3.6"
85
85
  },
86
86
  "devDependencies": {
87
87
  "@ston-fi/api": "^0.30.0",
88
88
  "@ston-fi/sdk": "^2.7.0",
89
89
  "@types/better-sqlite3": "^7.6.11",
90
90
  "@types/node": "^22.0.0",
91
- "@typescript-eslint/eslint-plugin": "^8.54.0",
92
- "@typescript-eslint/parser": "^8.54.0",
91
+ "@typescript-eslint/eslint-plugin": "^8.56.0",
92
+ "@typescript-eslint/parser": "^8.56.0",
93
93
  "@vitest/coverage-v8": "^4.0.18",
94
- "eslint": "^9.39.2",
94
+ "eslint": "^10.0.0",
95
95
  "husky": "^9.1.7",
96
96
  "lint-staged": "^16.2.7",
97
97
  "prettier": "^3.8.1",
@@ -1,124 +0,0 @@
1
- import {
2
- ALLOWED_EXTENSIONS,
3
- WORKSPACE_ROOT
4
- } from "./chunk-EYWNOHMJ.js";
5
-
6
- // src/workspace/validator.ts
7
- import { existsSync, lstatSync, readdirSync } from "fs";
8
- import { resolve, normalize, relative, extname, basename } from "path";
9
- import { homedir } from "os";
10
- var WorkspaceSecurityError = class extends Error {
11
- constructor(message, attemptedPath) {
12
- super(message);
13
- this.attemptedPath = attemptedPath;
14
- this.name = "WorkspaceSecurityError";
15
- }
16
- };
17
- function decodeRecursive(str) {
18
- let decoded = str;
19
- let prev = "";
20
- let iterations = 0;
21
- const maxIterations = 10;
22
- while (decoded !== prev && iterations < maxIterations) {
23
- prev = decoded;
24
- try {
25
- decoded = decodeURIComponent(decoded);
26
- } catch {
27
- break;
28
- }
29
- iterations++;
30
- }
31
- return decoded;
32
- }
33
- function validatePath(inputPath, allowCreate = false) {
34
- if (!inputPath || inputPath.trim() === "") {
35
- throw new WorkspaceSecurityError("Path cannot be empty.", inputPath);
36
- }
37
- const trimmedPath = inputPath.trim().replace(/\\/g, "/");
38
- const decodedPath = decodeRecursive(trimmedPath);
39
- let absolutePath;
40
- if (decodedPath.startsWith("/")) {
41
- absolutePath = resolve(normalize(decodedPath));
42
- } else if (decodedPath.startsWith("~/")) {
43
- const expanded = decodedPath.replace(/^~(?=$|[\\/])/, homedir());
44
- absolutePath = resolve(expanded);
45
- } else {
46
- absolutePath = resolve(WORKSPACE_ROOT, normalize(decodedPath));
47
- }
48
- const relativePath = relative(WORKSPACE_ROOT, absolutePath);
49
- if (relativePath.startsWith("..") || relativePath.startsWith("/")) {
50
- throw new WorkspaceSecurityError(
51
- `Access denied: Path '${inputPath}' is outside the workspace. Only files in ~/.teleton/workspace/ are accessible.`,
52
- inputPath
53
- );
54
- }
55
- const exists = existsSync(absolutePath);
56
- if (!exists && !allowCreate) {
57
- throw new WorkspaceSecurityError(
58
- `File not found: '${inputPath}' does not exist in workspace.`,
59
- inputPath
60
- );
61
- }
62
- if (exists) {
63
- const stats = lstatSync(absolutePath);
64
- if (stats.isSymbolicLink()) {
65
- throw new WorkspaceSecurityError(
66
- `Access denied: Symbolic links are not allowed for security reasons.`,
67
- inputPath
68
- );
69
- }
70
- }
71
- return {
72
- absolutePath,
73
- relativePath,
74
- exists,
75
- isDirectory: exists ? lstatSync(absolutePath).isDirectory() : false,
76
- extension: extname(absolutePath).toLowerCase(),
77
- filename: basename(absolutePath)
78
- };
79
- }
80
- function validateReadPath(inputPath) {
81
- const validated = validatePath(inputPath, false);
82
- if (validated.isDirectory) {
83
- throw new WorkspaceSecurityError(`Cannot read directory as file: '${inputPath}'`, inputPath);
84
- }
85
- return validated;
86
- }
87
- var IMMUTABLE_FILES = ["SOUL.md", "STRATEGY.md", "SECURITY.md"];
88
- function validateWritePath(inputPath, fileType) {
89
- const validated = validatePath(inputPath, true);
90
- if (IMMUTABLE_FILES.includes(validated.filename)) {
91
- throw new WorkspaceSecurityError(
92
- `Cannot write to ${validated.filename}. This file is configured by the owner. Use memory_write instead.`,
93
- inputPath
94
- );
95
- }
96
- if (fileType && ALLOWED_EXTENSIONS[fileType]) {
97
- const allowedExts = ALLOWED_EXTENSIONS[fileType];
98
- if (!allowedExts.includes(validated.extension)) {
99
- throw new WorkspaceSecurityError(
100
- `Invalid file type: '${validated.extension}' is not allowed for ${fileType}. Allowed: ${allowedExts.join(", ")}`,
101
- inputPath
102
- );
103
- }
104
- }
105
- return validated;
106
- }
107
- function validateDirectory(inputPath) {
108
- const validated = validatePath(inputPath, true);
109
- if (validated.exists && !validated.isDirectory) {
110
- throw new WorkspaceSecurityError(
111
- `Path exists but is not a directory: '${inputPath}'`,
112
- inputPath
113
- );
114
- }
115
- return validated;
116
- }
117
-
118
- export {
119
- WorkspaceSecurityError,
120
- validatePath,
121
- validateReadPath,
122
- validateWritePath,
123
- validateDirectory
124
- };
@@ -1 +0,0 @@
1
- *{box-sizing:border-box;margin:0;padding:0}:root{--bg: #000000;--surface: rgba(255, 255, 255, .05);--surface-hover: rgba(255, 255, 255, .08);--glass: rgba(255, 255, 255, .06);--glass-border: rgba(255, 255, 255, .1);--glass-border-strong: rgba(255, 255, 255, .15);--text: rgba(255, 255, 255, .92);--text-secondary: rgba(255, 255, 255, .55);--text-tertiary: rgba(255, 255, 255, .35);--accent: #0A84FF;--accent-dim: rgba(10, 132, 255, .15);--green: #30D158;--green-dim: rgba(48, 209, 88, .15);--orange: #FF9F0A;--orange-dim: rgba(255, 159, 10, .15);--red: #FF453A;--red-dim: rgba(255, 69, 58, .15);--purple: #BF5AF2;--purple-dim: rgba(191, 90, 242, .15);--cyan: #64D2FF;--cyan-dim: rgba(100, 210, 255, .15);--separator: rgba(255, 255, 255, .08);--radius-sm: 10px;--radius-md: 14px;--radius-lg: 20px;--radius-xl: 26px;--blur: 40px;--blur-heavy: 80px}html,body{height:100%}body{font-family:Inter,-apple-system,BlinkMacSystemFont,sans-serif;background:var(--bg);color:var(--text);line-height:1.5;font-size:14px;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}#root{min-height:100vh}.container{display:flex;min-height:100vh}.sidebar{width:220px;padding:20px 12px;background:#ffffff08;border-right:1px solid var(--separator);display:flex;flex-direction:column;gap:4px;position:sticky;top:0;height:100vh;overflow-y:auto}.sidebar-brand{padding:4px 12px 20px;font-size:15px;font-weight:600;letter-spacing:-.2px;color:var(--text)}.sidebar nav{display:flex;flex-direction:column;gap:2px}.sidebar a{display:flex;align-items:center;gap:10px;padding:8px 12px;border-radius:var(--radius-sm);color:var(--text-secondary);text-decoration:none;font-size:13px;font-weight:500;transition:all .2s ease}.sidebar a:hover{color:var(--text);background:var(--surface);text-decoration:none}.sidebar a.active{color:var(--text);background:var(--surface-hover);text-decoration:none}.main{flex:1;padding:32px;max-width:1080px;min-width:0}.header{margin-bottom:28px}.header h1{font-size:22px;font-weight:600;letter-spacing:-.4px;margin-bottom:4px}.header p{color:var(--text-secondary);font-size:13px}.card{background:var(--glass);backdrop-filter:blur(var(--blur)) saturate(180%);-webkit-backdrop-filter:blur(var(--blur)) saturate(180%);border:1px solid var(--glass-border);border-radius:var(--radius-lg);padding:20px;margin-bottom:16px}.card h2{font-size:15px;font-weight:600;letter-spacing:-.2px}.stats{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:12px;margin-bottom:20px}.stat-card{background:var(--glass);backdrop-filter:blur(var(--blur)) saturate(180%);-webkit-backdrop-filter:blur(var(--blur)) saturate(180%);border:1px solid var(--glass-border);border-radius:var(--radius-md);padding:16px}.stat-card h3{font-size:12px;font-weight:500;color:var(--text-secondary);margin-bottom:6px;text-transform:uppercase;letter-spacing:.5px}.stat-card .value{font-size:24px;font-weight:600;letter-spacing:-.5px}button{font-family:Inter,-apple-system,BlinkMacSystemFont,sans-serif;background:var(--accent);color:#fff;border:none;padding:8px 16px;border-radius:var(--radius-sm);cursor:pointer;font-size:13px;font-weight:500;transition:opacity .15s ease}button:hover{opacity:.85}button:disabled{opacity:.4;cursor:not-allowed}input,textarea{font-family:Inter,-apple-system,BlinkMacSystemFont,sans-serif;background:var(--surface);border:1px solid var(--glass-border);color:var(--text);padding:10px 14px;border-radius:var(--radius-sm);font-size:13px;outline:none;transition:border-color .2s ease}input:focus,textarea:focus{border-color:var(--accent)}input::placeholder,textarea::placeholder{color:var(--text-tertiary)}textarea{width:100%;min-height:400px;font-family:SF Mono,Fira Code,Cascadia Code,monospace;font-size:13px;line-height:1.6;resize:vertical;border-radius:var(--radius-md)}a{color:var(--accent);text-decoration:none}a:hover{text-decoration:none;opacity:.8}.badge{display:inline-flex;align-items:center;padding:3px 8px;border-radius:6px;font-size:11px;font-weight:500;letter-spacing:.2px}.badge.dm{background:var(--accent-dim);color:var(--accent)}.badge.group{background:var(--purple-dim);color:var(--purple)}.badge.always{background:var(--green-dim);color:var(--green)}.badge.info{background:var(--cyan-dim);color:var(--cyan)}.badge.warn{background:var(--orange-dim);color:var(--orange)}.badge.error{background:var(--red-dim);color:var(--red)}.tabs{display:flex;gap:4px;padding:4px;background:var(--surface);border-radius:var(--radius-sm);margin-bottom:16px}.tab{padding:6px 14px;background:none;border:none;color:var(--text-secondary);cursor:pointer;border-radius:8px;font-size:13px;font-weight:500;transition:all .2s ease}.tab:hover{color:var(--text);opacity:1}.tab.active{color:var(--text);background:var(--surface-hover)}.form-group{margin-bottom:16px}.form-group label{display:block;margin-bottom:6px;font-size:13px;font-weight:500;color:var(--text-secondary)}.alert{padding:10px 14px;border-radius:var(--radius-sm);margin-bottom:16px;font-size:13px}.alert.success{background:var(--green-dim);color:var(--green);border:1px solid rgba(48,209,88,.2)}.alert.error{background:var(--red-dim);color:var(--red);border:1px solid rgba(255,69,58,.2)}.file-row{transition:background-color .15s ease}.file-row:hover{background-color:#ffffff08}.icon-button{background:none;border:none;cursor:pointer;padding:4px 6px;font-size:15px;opacity:.5;filter:grayscale(1);transition:opacity .15s,filter .15s}.icon-button:hover{opacity:1;filter:none}.log-entry{font-family:SF Mono,Fira Code,Cascadia Code,monospace;font-size:12px;padding:5px 0;border-bottom:1px solid var(--separator);line-height:1.5}.log-entry:last-child{border-bottom:none}.tool-row{padding:10px 14px;background:var(--surface);border-radius:var(--radius-sm);display:flex;justify-content:space-between;align-items:center;transition:background .15s ease}.tool-row:hover{background:var(--surface-hover)}.tool-name{font-size:13px;font-weight:500;margin-bottom:2px}.tool-desc{font-size:12px;color:var(--text-secondary)}.plugin-meta{font-size:12px;color:var(--text-secondary);margin-bottom:8px}.result-item{padding:14px;background:var(--surface);border-radius:var(--radius-sm);margin-bottom:8px}.result-meta{font-size:12px;color:var(--text-secondary);margin-bottom:6px}.result-text{font-size:13px;line-height:1.6}.status-dot{display:inline-block;width:8px;height:8px;border-radius:50%;margin-right:6px}.status-dot.connected{background:var(--green)}.status-dot.disconnected{background:var(--red)}.login-container{display:flex;align-items:center;justify-content:center;min-height:100vh;padding:2rem}.login-card{background:var(--glass);backdrop-filter:blur(var(--blur)) saturate(180%);-webkit-backdrop-filter:blur(var(--blur)) saturate(180%);border:1px solid var(--glass-border);border-radius:var(--radius-xl);padding:32px;max-width:380px;width:100%}.login-card h1{font-size:20px;font-weight:600;margin-bottom:8px;letter-spacing:-.3px}.login-card p{color:var(--text-secondary);font-size:13px;margin-bottom:24px;line-height:1.5}.section-title{font-size:13px;font-weight:600;color:var(--text-secondary);text-transform:uppercase;letter-spacing:.5px;margin-bottom:12px}.empty{color:var(--text-tertiary);font-size:13px;padding:20px 0;text-align:center}::-webkit-scrollbar{width:6px;height:6px}::-webkit-scrollbar-track{background:transparent}::-webkit-scrollbar-thumb{background:#ffffff1a;border-radius:3px}::-webkit-scrollbar-thumb:hover{background:#fff3}.scope-seg{display:inline-flex;padding:2px;background:#ffffff0f;border-radius:8px;gap:2px}.scope-seg button{padding:4px 10px;font-size:11px;font-weight:500;background:none;color:var(--text-tertiary);border:none;border-radius:6px;cursor:pointer;transition:all .2s ease}.scope-seg button:hover:not(:disabled):not(.active){color:var(--text-secondary);opacity:1}.scope-seg button.active{background:#ffffff1f;color:var(--text)}.scope-seg.disabled{opacity:.4;pointer-events:none}.toggle{position:relative;width:42px;height:26px;flex-shrink:0;cursor:pointer}.toggle input{opacity:0;width:0;height:0;position:absolute}.toggle-track{position:absolute;top:0;right:0;bottom:0;left:0;background:#ffffff1a;border-radius:13px;transition:background .25s ease}.toggle input:checked+.toggle-track{background:var(--green)}.toggle-thumb{position:absolute;top:3px;left:3px;width:20px;height:20px;background:#fff;border-radius:50%;transition:transform .25s cubic-bezier(.4,0,.2,1);box-shadow:0 1px 3px #0000004d}.toggle input:checked~.toggle-thumb{transform:translate(16px)}.toggle input:disabled+.toggle-track{opacity:.4}.toggle input:disabled~.toggle-thumb{opacity:.4}.loading{color:var(--text-tertiary);font-size:13px;padding:40px 0;text-align:center}