@yuhere/js-jsonrpc2 0.0.0-stage → 2.1.2

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 (174) hide show
  1. package/README.md +277 -2
  2. package/SKILL.md +237 -0
  3. package/dist/cli/cli.d.ts +3 -0
  4. package/dist/cli/cli.d.ts.map +1 -0
  5. package/dist/cli/cli.js +132 -0
  6. package/dist/cli/cli.js.map +1 -0
  7. package/dist/cli/demo-methods.d.ts +10 -0
  8. package/dist/cli/demo-methods.d.ts.map +1 -0
  9. package/dist/cli/demo-methods.js +477 -0
  10. package/dist/cli/demo-methods.js.map +1 -0
  11. package/dist/cli/express.d.ts +2 -0
  12. package/dist/cli/express.d.ts.map +1 -0
  13. package/dist/cli/express.js +42 -0
  14. package/dist/cli/express.js.map +1 -0
  15. package/dist/cli/stdio.d.ts +2 -0
  16. package/dist/cli/stdio.d.ts.map +1 -0
  17. package/dist/cli/stdio.js +5 -0
  18. package/dist/cli/stdio.js.map +1 -0
  19. package/dist/core/Repository.d.ts +24 -0
  20. package/dist/core/Repository.d.ts.map +1 -0
  21. package/dist/core/Repository.js +153 -0
  22. package/dist/core/Repository.js.map +1 -0
  23. package/dist/core/convert.d.ts +4 -0
  24. package/dist/core/convert.d.ts.map +1 -0
  25. package/dist/core/convert.js +29 -0
  26. package/dist/core/convert.js.map +1 -0
  27. package/dist/core/descriptor.d.ts +27 -0
  28. package/dist/core/descriptor.d.ts.map +1 -0
  29. package/dist/core/descriptor.js +83 -0
  30. package/dist/core/descriptor.js.map +1 -0
  31. package/dist/core/index.d.ts +4 -0
  32. package/dist/core/index.d.ts.map +1 -0
  33. package/dist/core/index.js +3 -0
  34. package/dist/core/index.js.map +1 -0
  35. package/dist/core/permission.d.ts +4 -0
  36. package/dist/core/permission.d.ts.map +1 -0
  37. package/dist/core/permission.js +18 -0
  38. package/dist/core/permission.js.map +1 -0
  39. package/dist/core/spec-check.d.ts +3 -0
  40. package/dist/core/spec-check.d.ts.map +1 -0
  41. package/dist/core/spec-check.js +11 -0
  42. package/dist/core/spec-check.js.map +1 -0
  43. package/dist/core/system-methods.d.ts +3 -0
  44. package/dist/core/system-methods.d.ts.map +1 -0
  45. package/dist/core/system-methods.js +76 -0
  46. package/dist/core/system-methods.js.map +1 -0
  47. package/dist/errors/RpcError.d.ts +9 -0
  48. package/dist/errors/RpcError.d.ts.map +1 -0
  49. package/dist/errors/RpcError.js +23 -0
  50. package/dist/errors/RpcError.js.map +1 -0
  51. package/dist/errors/codes.d.ts +7 -0
  52. package/dist/errors/codes.d.ts.map +1 -0
  53. package/dist/errors/codes.js +7 -0
  54. package/dist/errors/codes.js.map +1 -0
  55. package/dist/errors/index.d.ts +3 -0
  56. package/dist/errors/index.d.ts.map +1 -0
  57. package/dist/errors/index.js +3 -0
  58. package/dist/errors/index.js.map +1 -0
  59. package/dist/index.d.ts +18 -0
  60. package/dist/index.d.ts.map +1 -0
  61. package/dist/index.js +17 -0
  62. package/dist/index.js.map +1 -0
  63. package/dist/schema/index.d.ts +4 -0
  64. package/dist/schema/index.d.ts.map +1 -0
  65. package/dist/schema/index.js +4 -0
  66. package/dist/schema/index.js.map +1 -0
  67. package/dist/schema/json/index.d.ts +19 -0
  68. package/dist/schema/json/index.d.ts.map +1 -0
  69. package/dist/schema/json/index.js +6 -0
  70. package/dist/schema/json/index.js.map +1 -0
  71. package/dist/schema/json/marker.d.ts +23 -0
  72. package/dist/schema/json/marker.d.ts.map +1 -0
  73. package/dist/schema/json/marker.js +27 -0
  74. package/dist/schema/json/marker.js.map +1 -0
  75. package/dist/schema/json/primitives.d.ts +202 -0
  76. package/dist/schema/json/primitives.d.ts.map +1 -0
  77. package/dist/schema/json/primitives.js +598 -0
  78. package/dist/schema/json/primitives.js.map +1 -0
  79. package/dist/schema/primitives.d.ts +25 -0
  80. package/dist/schema/primitives.d.ts.map +1 -0
  81. package/dist/schema/primitives.js +153 -0
  82. package/dist/schema/primitives.js.map +1 -0
  83. package/dist/schema/rpc.d.ts +21 -0
  84. package/dist/schema/rpc.d.ts.map +1 -0
  85. package/dist/schema/rpc.js +17 -0
  86. package/dist/schema/rpc.js.map +1 -0
  87. package/dist/schema/z/protocol.d.ts +9 -0
  88. package/dist/schema/z/protocol.d.ts.map +1 -0
  89. package/dist/schema/z/protocol.js +9 -0
  90. package/dist/schema/z/protocol.js.map +1 -0
  91. package/dist/schema/z/register.d.ts +9 -0
  92. package/dist/schema/z/register.d.ts.map +1 -0
  93. package/dist/schema/z/register.js +21 -0
  94. package/dist/schema/z/register.js.map +1 -0
  95. package/dist/stream/index.d.ts +3 -0
  96. package/dist/stream/index.d.ts.map +1 -0
  97. package/dist/stream/index.js +2 -0
  98. package/dist/stream/index.js.map +1 -0
  99. package/dist/stream/stringify-stream.d.ts +15 -0
  100. package/dist/stream/stringify-stream.d.ts.map +1 -0
  101. package/dist/stream/stringify-stream.js +322 -0
  102. package/dist/stream/stringify-stream.js.map +1 -0
  103. package/dist/stream/stringify.d.ts +19 -0
  104. package/dist/stream/stringify.d.ts.map +1 -0
  105. package/dist/stream/stringify.js +217 -0
  106. package/dist/stream/stringify.js.map +1 -0
  107. package/dist/transport/express/body.d.ts +9 -0
  108. package/dist/transport/express/body.d.ts.map +1 -0
  109. package/dist/transport/express/body.js +28 -0
  110. package/dist/transport/express/body.js.map +1 -0
  111. package/dist/transport/express/index.d.ts +3 -0
  112. package/dist/transport/express/index.d.ts.map +1 -0
  113. package/dist/transport/express/index.js +2 -0
  114. package/dist/transport/express/index.js.map +1 -0
  115. package/dist/transport/express/middleware.d.ts +12 -0
  116. package/dist/transport/express/middleware.d.ts.map +1 -0
  117. package/dist/transport/express/middleware.js +73 -0
  118. package/dist/transport/express/middleware.js.map +1 -0
  119. package/dist/transport/express/respond.d.ts +4 -0
  120. package/dist/transport/express/respond.d.ts.map +1 -0
  121. package/dist/transport/express/respond.js +125 -0
  122. package/dist/transport/express/respond.js.map +1 -0
  123. package/dist/transport/stdio/index.d.ts +2 -0
  124. package/dist/transport/stdio/index.d.ts.map +1 -0
  125. package/dist/transport/stdio/index.js +2 -0
  126. package/dist/transport/stdio/index.js.map +1 -0
  127. package/dist/transport/stdio/middleware.d.ts +34 -0
  128. package/dist/transport/stdio/middleware.d.ts.map +1 -0
  129. package/dist/transport/stdio/middleware.js +274 -0
  130. package/dist/transport/stdio/middleware.js.map +1 -0
  131. package/dist/transport/ws/index.d.ts +3 -0
  132. package/dist/transport/ws/index.d.ts.map +1 -0
  133. package/dist/transport/ws/index.js +3 -0
  134. package/dist/transport/ws/index.js.map +1 -0
  135. package/dist/transport/ws/middleware.d.ts +25 -0
  136. package/dist/transport/ws/middleware.d.ts.map +1 -0
  137. package/dist/transport/ws/middleware.js +209 -0
  138. package/dist/transport/ws/middleware.js.map +1 -0
  139. package/dist/transport/ws/standalone.d.ts +22 -0
  140. package/dist/transport/ws/standalone.d.ts.map +1 -0
  141. package/dist/transport/ws/standalone.js +39 -0
  142. package/dist/transport/ws/standalone.js.map +1 -0
  143. package/dist/types.d.ts +75 -0
  144. package/dist/types.d.ts.map +1 -0
  145. package/dist/types.js +2 -0
  146. package/dist/types.js.map +1 -0
  147. package/htdoc/assets/index-CQr-lnlD.js +9286 -0
  148. package/htdoc/assets/index-CQr-lnlD.js.map +1 -0
  149. package/htdoc/assets/index-hcP2-9jw.css +729 -0
  150. package/htdoc/index.html +13 -0
  151. package/package.json +89 -3
  152. package/webui/index.html +12 -0
  153. package/webui/src/App.tsx +56 -0
  154. package/webui/src/api/httpTransport.ts +148 -0
  155. package/webui/src/api/paramForm.ts +79 -0
  156. package/webui/src/api/rpc.ts +57 -0
  157. package/webui/src/api/schema.ts +12 -0
  158. package/webui/src/api/types.ts +16 -0
  159. package/webui/src/api/wsTransport.ts +305 -0
  160. package/webui/src/components/MethodDetail.tsx +43 -0
  161. package/webui/src/components/MethodTree.tsx +118 -0
  162. package/webui/src/components/SchemaForm.tsx +696 -0
  163. package/webui/src/components/SchemaView.tsx +151 -0
  164. package/webui/src/components/TestPanel.tsx +279 -0
  165. package/webui/src/components/Toolbar.tsx +70 -0
  166. package/webui/src/hooks/useMethodDetail.ts +61 -0
  167. package/webui/src/hooks/useMethods.ts +27 -0
  168. package/webui/src/main.tsx +13 -0
  169. package/webui/src/styles/geek.css +729 -0
  170. package/webui/src/theme/ThemeProvider.tsx +79 -0
  171. package/webui/src/vite-env.d.ts +1 -0
  172. package/webui/tsconfig.json +34 -0
  173. package/webui/tsconfig.node.json +13 -0
  174. package/webui/vite.config.ts +15 -0
@@ -0,0 +1,729 @@
1
+ /* ================================================================
2
+ * 颜色令牌
3
+ * 默认 = 暗色;light 覆盖;system 由 ThemeProvider 写 data-theme 决定
4
+ * ================================================================ */
5
+ :root {
6
+ --bg: #0b0f14;
7
+ --bg-elev: #11161d;
8
+ --bg-deep: #010409;
9
+ --fg: #c9d1d9;
10
+ --fg-dim: #8b949e;
11
+ --border: #21262d;
12
+ --border-strong: #30363d;
13
+ --accent: #39d353;
14
+ --accent-dim: #2a9f3e;
15
+ --danger: #f85149;
16
+ --hover-bg: #161b22;
17
+ --active-bg: #1f6feb33;
18
+ --accent-fg: #79c0ff;
19
+
20
+ /* Schema / 语法高亮 */
21
+ --syn-string: #a5d6ff;
22
+ --syn-number: #f2cc60;
23
+ --syn-boolean: #ff7b72;
24
+ --syn-literal: #d2a8ff;
25
+ --syn-container: #7ee787;
26
+ --syn-object: #79c0ff;
27
+ --syn-union: #ffa657;
28
+ --syn-muted: #8b949e;
29
+
30
+ --mono: "JetBrains Mono", "Fira Code", Menlo, Consolas, "Courier New", monospace;
31
+ }
32
+
33
+ :root[data-theme='light'] {
34
+ --bg: #ffffff;
35
+ --bg-elev: #f6f8fa;
36
+ --bg-deep: #f6f8fa;
37
+ --fg: #1f2328;
38
+ --fg-dim: #59636e;
39
+ --border: #d0d7de;
40
+ --border-strong: #afb8c1;
41
+ --accent: #1a7f37;
42
+ --accent-dim: #116329;
43
+ --danger: #cf222e;
44
+ --hover-bg: #eaeef2;
45
+ --active-bg: #ddf4ff;
46
+ --accent-fg: #0969da;
47
+
48
+ --syn-string: #0a3069;
49
+ --syn-number: #0550ae;
50
+ --syn-boolean: #cf222e;
51
+ --syn-literal: #8250df;
52
+ --syn-container: #116329;
53
+ --syn-object: #0969da;
54
+ --syn-union: #bc4c00;
55
+ --syn-muted: #57606a;
56
+ }
57
+
58
+ /* ================================================================
59
+ * 基础
60
+ * ================================================================ */
61
+ * {
62
+ box-sizing: border-box;
63
+ }
64
+
65
+ html,
66
+ body,
67
+ #root {
68
+ height: 100%;
69
+ }
70
+
71
+ body {
72
+ margin: 0;
73
+ background: var(--bg);
74
+ color: var(--fg);
75
+ font: 13px/1.55 var(--mono);
76
+ -webkit-font-smoothing: antialiased;
77
+ }
78
+
79
+ button {
80
+ font: inherit;
81
+ background: var(--bg-elev);
82
+ color: var(--fg);
83
+ border: 1px solid var(--border-strong);
84
+ padding: 4px 12px;
85
+ border-radius: 4px;
86
+ cursor: pointer;
87
+ transition: border-color .15s, color .15s, background .15s;
88
+ }
89
+
90
+ button:hover:not(:disabled) {
91
+ border-color: var(--accent);
92
+ color: var(--accent);
93
+ }
94
+
95
+ button:disabled {
96
+ opacity: .5;
97
+ cursor: not-allowed;
98
+ }
99
+
100
+ input[type="checkbox"] {
101
+ accent-color: var(--accent);
102
+ }
103
+
104
+ /* ================================================================
105
+ * 布局
106
+ * ================================================================ */
107
+ .app {
108
+ display: flex;
109
+ flex-direction: column;
110
+ height: 100%;
111
+ }
112
+
113
+ .toolbar {
114
+ display: flex;
115
+ align-items: center;
116
+ gap: 16px;
117
+ padding: 10px 16px;
118
+ border-bottom: 1px solid var(--border);
119
+ background: var(--bg-elev);
120
+ flex-wrap: wrap;
121
+ }
122
+
123
+ .toolbar h1 {
124
+ font-size: 15px;
125
+ margin: 0;
126
+ color: var(--accent);
127
+ letter-spacing: .5px;
128
+ }
129
+
130
+ /* 分段按钮 */
131
+ .segmented {
132
+ display: inline-flex;
133
+ border: 1px solid var(--border-strong);
134
+ border-radius: 4px;
135
+ overflow: hidden;
136
+ }
137
+
138
+ .segmented button {
139
+ border: none;
140
+ border-radius: 0;
141
+ background: transparent;
142
+ padding: 4px 12px;
143
+ color: var(--fg-dim);
144
+ }
145
+
146
+ .segmented button+button {
147
+ border-left: 1px solid var(--border-strong);
148
+ }
149
+
150
+ .segmented button:hover:not(.active) {
151
+ color: var(--fg);
152
+ background: var(--hover-bg);
153
+ }
154
+
155
+ .segmented button.active {
156
+ background: var(--active-bg);
157
+ color: var(--accent);
158
+ }
159
+
160
+ main {
161
+ flex: 1;
162
+ display: grid;
163
+ grid-template-columns: 320px 1fr;
164
+ min-height: 0;
165
+ }
166
+
167
+ .sidebar {
168
+ border-right: 1px solid var(--border);
169
+ overflow: auto;
170
+ padding: 12px;
171
+ background: var(--bg-elev);
172
+ }
173
+
174
+ .sidebar h2 {
175
+ font-size: 12px;
176
+ color: var(--fg-dim);
177
+ text-transform: uppercase;
178
+ letter-spacing: 1px;
179
+ margin: 0 0 8px;
180
+ }
181
+
182
+ .content {
183
+ overflow: auto;
184
+ padding: 16px 20px;
185
+ display: flex;
186
+ flex-direction: column;
187
+ gap: 24px;
188
+ }
189
+
190
+ /* ================================================================
191
+ * 方法树
192
+ * ================================================================ */
193
+ .tree,
194
+ .tree ul {
195
+ list-style: none;
196
+ margin: 0;
197
+ padding: 0;
198
+ }
199
+
200
+ .dir-row {
201
+ display: flex;
202
+ align-items: center;
203
+ gap: 4px;
204
+ padding: 2px 4px;
205
+ cursor: pointer;
206
+ border-radius: 3px;
207
+ }
208
+
209
+ .dir-row:hover {
210
+ background: var(--hover-bg);
211
+ }
212
+
213
+ .expander {
214
+ color: var(--fg-dim);
215
+ width: 12px;
216
+ display: inline-block;
217
+ }
218
+
219
+ .dir {
220
+ color: var(--syn-object);
221
+ }
222
+
223
+ .leaf {
224
+ padding: 2px 4px;
225
+ cursor: pointer;
226
+ border-radius: 3px;
227
+ color: var(--accent);
228
+ white-space: nowrap;
229
+ overflow: hidden;
230
+ text-overflow: ellipsis;
231
+ }
232
+
233
+ .leaf:hover {
234
+ background: var(--hover-bg);
235
+ }
236
+
237
+ .leaf.active {
238
+ background: var(--active-bg);
239
+ color: var(--accent-fg);
240
+ }
241
+
242
+ /* ================================================================
243
+ * 详情 / 测试面板
244
+ * ================================================================ */
245
+ .detail h2 {
246
+ margin: 0 0 12px;
247
+ color: var(--accent);
248
+ font-size: 16px;
249
+ word-break: break-all;
250
+ }
251
+
252
+ .detail h3,
253
+ .test h3 {
254
+ margin: 16px 0 6px;
255
+ font-size: 12px;
256
+ color: var(--fg-dim);
257
+ text-transform: uppercase;
258
+ letter-spacing: 1px;
259
+ }
260
+
261
+ pre,
262
+ textarea {
263
+ background: var(--bg-deep);
264
+ border: 1px solid var(--border);
265
+ color: var(--fg);
266
+ padding: 10px;
267
+ border-radius: 4px;
268
+ font: inherit;
269
+ width: 100%;
270
+ overflow: auto;
271
+ margin: 0;
272
+ }
273
+
274
+ pre {
275
+ white-space: pre-wrap;
276
+ word-break: break-word;
277
+ max-height: 320px;
278
+ }
279
+
280
+ textarea {
281
+ resize: vertical;
282
+ min-height: 100px;
283
+ outline: none;
284
+ }
285
+
286
+ textarea:focus {
287
+ border-color: var(--accent);
288
+ }
289
+
290
+ .test .actions {
291
+ display: flex;
292
+ gap: 8px;
293
+ margin: 10px 0 4px;
294
+ }
295
+
296
+ .hint {
297
+ color: var(--fg-dim);
298
+ font-style: italic;
299
+ }
300
+
301
+ .error {
302
+ color: var(--danger);
303
+ }
304
+
305
+ .output {
306
+ color: var(--syn-string);
307
+ }
308
+
309
+ .empty {
310
+ color: var(--fg-dim);
311
+ padding: 12px 0;
312
+ }
313
+
314
+ ::-webkit-scrollbar {
315
+ width: 10px;
316
+ height: 10px;
317
+ }
318
+
319
+ ::-webkit-scrollbar-track {
320
+ background: var(--bg);
321
+ }
322
+
323
+ ::-webkit-scrollbar-thumb {
324
+ background: var(--border);
325
+ border-radius: 5px;
326
+ border: 2px solid var(--bg);
327
+ }
328
+
329
+ ::-webkit-scrollbar-thumb:hover {
330
+ background: var(--border-strong);
331
+ }
332
+
333
+ /* ================================================================
334
+ * Schema 视图(只读,MethodDetail 返回值用)
335
+ * ================================================================ */
336
+ .signature-schemas {
337
+ display: flex;
338
+ flex-direction: column;
339
+ gap: 10px;
340
+ }
341
+
342
+ .param-block {
343
+ background: var(--bg-deep);
344
+ border: 1px solid var(--border);
345
+ border-radius: 4px;
346
+ padding: 8px 10px;
347
+ }
348
+
349
+ .param-index {
350
+ font-size: 12px;
351
+ color: var(--fg-dim);
352
+ margin-bottom: 4px;
353
+ }
354
+
355
+ .schema-node {
356
+ line-height: 1.6;
357
+ }
358
+
359
+ .schema-head {
360
+ display: flex;
361
+ align-items: baseline;
362
+ gap: 4px;
363
+ cursor: default;
364
+ flex-wrap: wrap;
365
+ }
366
+
367
+ .schema-head:has(.schema-expander:not(:empty)) {
368
+ cursor: pointer;
369
+ }
370
+
371
+ .schema-expander {
372
+ color: var(--fg-dim);
373
+ width: 12px;
374
+ display: inline-block;
375
+ flex: none;
376
+ }
377
+
378
+ .schema-label {
379
+ color: var(--syn-union);
380
+ }
381
+
382
+ .schema-label::after {
383
+ content: '';
384
+ }
385
+
386
+ .schema-kind {
387
+ font-weight: bold;
388
+ }
389
+
390
+ .schema-nullable {
391
+ color: var(--fg-dim);
392
+ }
393
+
394
+ .schema-constraints {
395
+ color: var(--syn-muted);
396
+ font-size: 90%;
397
+ }
398
+
399
+ .schema-description {
400
+ color: var(--fg-dim);
401
+ font-style: italic;
402
+ font-size: 90%;
403
+ }
404
+
405
+ .schema-children {
406
+ margin-top: 2px;
407
+ }
408
+
409
+ /* ================================================================
410
+ * SchemaForm(参数类型 + 值输入合并)
411
+ * ================================================================ */
412
+ .schema-form {
413
+ display: flex;
414
+ flex-direction: column;
415
+ gap: 10px;
416
+ margin-bottom: 12px;
417
+ }
418
+
419
+ .sf-node {
420
+ margin: 2px 0;
421
+ }
422
+
423
+ .sf-head {
424
+ display: flex;
425
+ align-items: baseline;
426
+ gap: 6px;
427
+ flex-wrap: wrap;
428
+ font-size: 12px;
429
+ line-height: 1.6;
430
+ }
431
+
432
+ .sf-head-clickable {
433
+ cursor: pointer;
434
+ border-radius: 3px;
435
+ }
436
+
437
+ .sf-head-clickable:hover {
438
+ background: var(--hover-bg);
439
+ }
440
+
441
+ .sf-expander {
442
+ color: var(--fg-dim);
443
+ width: 12px;
444
+ display: inline-block;
445
+ flex: none;
446
+ }
447
+
448
+ .sf-label {
449
+ color: var(--syn-union);
450
+ font-weight: bold;
451
+ }
452
+
453
+ .sf-kind {
454
+ font-weight: bold;
455
+ }
456
+
457
+ .sf-nullable {
458
+ color: var(--fg-dim);
459
+ }
460
+
461
+ .sf-desc {
462
+ color: var(--fg-dim);
463
+ font-style: italic;
464
+ font-size: 90%;
465
+ }
466
+
467
+ .sf-constraints {
468
+ color: var(--syn-muted);
469
+ font-size: 90%;
470
+ }
471
+
472
+ .sf-children {
473
+ margin-top: 2px;
474
+ }
475
+
476
+ .sf-null-indicator {
477
+ color: var(--syn-muted);
478
+ font-style: italic;
479
+ font-size: 12px;
480
+ }
481
+
482
+ .sf-row {
483
+ display: flex;
484
+ align-items: flex-start;
485
+ gap: 10px;
486
+ }
487
+
488
+ .sf-row>.sf-head-inline {
489
+ flex: 0 0 auto;
490
+ display: flex;
491
+ align-items: baseline;
492
+ gap: 6px;
493
+ flex-wrap: nowrap;
494
+ white-space: nowrap;
495
+ min-width: 0;
496
+ padding-top: 3px;
497
+ }
498
+
499
+ .sf-row>.sf-input-cell {
500
+ flex: 1 1 auto;
501
+ min-width: 0;
502
+ display: flex;
503
+ flex-direction: column;
504
+ gap: 2px;
505
+ }
506
+
507
+ .sf-row .sf-input,
508
+ .sf-row .sf-textarea {
509
+ width: 100%;
510
+ min-width: 0;
511
+ }
512
+
513
+ .sf-array-item,
514
+ .sf-record-item {
515
+ display: flex;
516
+ align-items: flex-start;
517
+ gap: 8px;
518
+ border-left: 2px solid var(--border);
519
+ padding-left: 6px;
520
+ margin: 2px 0;
521
+ }
522
+
523
+ .sf-array-item>.sf-node,
524
+ .sf-record-item>.sf-node {
525
+ flex: 1;
526
+ min-width: 0;
527
+ }
528
+
529
+ .sf-record-add {
530
+ display: flex;
531
+ gap: 6px;
532
+ margin-top: 6px;
533
+ padding-left: 6px;
534
+ }
535
+
536
+ .sf-union-picker {
537
+ margin: 0;
538
+ }
539
+
540
+ .sf-input {
541
+ background: var(--bg);
542
+ border: 1px solid var(--border-strong);
543
+ color: var(--fg);
544
+ font: inherit;
545
+ padding: 3px 8px;
546
+ border-radius: 3px;
547
+ outline: none;
548
+ min-width: 120px;
549
+ }
550
+
551
+ .sf-input:focus {
552
+ border-color: var(--accent);
553
+ }
554
+
555
+ .sf-scalar {
556
+ display: flex;
557
+ align-items: center;
558
+ gap: 6px;
559
+ }
560
+
561
+ .sf-textarea {
562
+ width: 100%;
563
+ min-height: 60px;
564
+ font-size: 12px;
565
+ background: var(--bg-deep);
566
+ border: 1px solid var(--border);
567
+ color: var(--fg);
568
+ padding: 6px;
569
+ border-radius: 3px;
570
+ resize: vertical;
571
+ outline: none;
572
+ font-family: var(--mono);
573
+ }
574
+
575
+ .sf-textarea:focus {
576
+ border-color: var(--accent);
577
+ }
578
+
579
+ @media (max-width: 720px) {
580
+ .sf-row {
581
+ flex-direction: column;
582
+ gap: 4px;
583
+ }
584
+
585
+ .sf-row>.sf-head-inline {
586
+ white-space: normal;
587
+ padding-top: 0;
588
+ }
589
+ }
590
+
591
+ .error.small {
592
+ font-size: 11px;
593
+ }
594
+
595
+ /* ---- 工具栏主题下拉(右上角) ---- */
596
+ .toolbar .theme-select {
597
+ margin-left: auto;
598
+ display: inline-flex;
599
+ align-items: center;
600
+ gap: 6px;
601
+ font-size: 12px;
602
+ color: var(--fg-dim);
603
+ white-space: nowrap;
604
+ }
605
+
606
+ .theme-select-label {
607
+ color: var(--fg-dim);
608
+ }
609
+
610
+ .theme-select select {
611
+ font: inherit;
612
+ font-size: 12px;
613
+ background: var(--bg);
614
+ color: var(--fg);
615
+ border: 1px solid var(--border-strong);
616
+ border-radius: 4px;
617
+ padding: 3px 24px 3px 8px;
618
+ outline: none;
619
+ cursor: pointer;
620
+ /* 自定义下拉箭头,跨主题可见 */
621
+ appearance: none;
622
+ -webkit-appearance: none;
623
+ background-image: linear-gradient(45deg, transparent 50%, var(--fg-dim) 50%),
624
+ linear-gradient(135deg, var(--fg-dim) 50%, transparent 50%);
625
+ background-position: calc(100% - 12px) 50%, calc(100% - 8px) 50%;
626
+ background-size: 4px 4px, 4px 4px;
627
+ background-repeat: no-repeat;
628
+ transition: border-color .15s, color .15s;
629
+ }
630
+
631
+ .theme-select select:hover {
632
+ border-color: var(--accent);
633
+ color: var(--fg);
634
+ }
635
+
636
+ .theme-select select:focus {
637
+ border-color: var(--accent);
638
+ }
639
+
640
+
641
+ .actions .error.small {
642
+ align-self: center;
643
+ margin-left: 4px;
644
+ }
645
+
646
+
647
+
648
+ /* ---- 分裂按钮(主体复制 + ▾ 选格式) ---- */
649
+ .split-button {
650
+ position: relative;
651
+ display: inline-flex;
652
+ }
653
+
654
+ .split-button-main,
655
+ .split-button-caret {
656
+ border-radius: 0;
657
+ border: 1px solid var(--border-strong);
658
+ background: var(--bg-elev);
659
+ color: var(--fg);
660
+ font: inherit;
661
+ padding: 4px 10px;
662
+ cursor: pointer;
663
+ transition: border-color .15s, color .15s, background .15s;
664
+ }
665
+
666
+ .split-button-main {
667
+ border-top-left-radius: 4px;
668
+ border-bottom-left-radius: 4px;
669
+ border-right: none;
670
+ }
671
+
672
+ .split-button-caret {
673
+ border-top-right-radius: 4px;
674
+ border-bottom-right-radius: 4px;
675
+ padding: 4px 8px;
676
+ line-height: 1;
677
+ }
678
+
679
+ .split-button:hover>.split-button-main:not(:disabled),
680
+ .split-button:hover>.split-button-caret:not(:disabled) {
681
+ border-color: var(--accent);
682
+ color: var(--accent);
683
+ }
684
+
685
+ .split-button-main:disabled,
686
+ .split-button-caret:disabled {
687
+ opacity: .5;
688
+ cursor: not-allowed;
689
+ }
690
+
691
+ .split-button-menu {
692
+ position: absolute;
693
+ top: 100%;
694
+ left: 0;
695
+ margin: 4px 0 0;
696
+ padding: 4px 0;
697
+ list-style: none;
698
+ background: var(--bg-elev);
699
+ border: 1px solid var(--border-strong);
700
+ border-radius: 4px;
701
+ min-width: 140px;
702
+ z-index: 20;
703
+ box-shadow: 0 4px 12px rgba(0, 0, 0, .3);
704
+ }
705
+
706
+ .split-button-menu li {
707
+ padding: 5px 12px;
708
+ cursor: pointer;
709
+ font-size: 12px;
710
+ color: var(--fg);
711
+ display: flex;
712
+ justify-content: space-between;
713
+ gap: 12px;
714
+ }
715
+
716
+ .split-button-menu li:hover {
717
+ background: var(--hover-bg);
718
+ color: var(--accent);
719
+ }
720
+
721
+ .split-button-menu li .check {
722
+ color: var(--accent);
723
+ }
724
+
725
+ @media (max-width: 720px) {
726
+ .split-button {
727
+ display: inline-flex;
728
+ }
729
+ }