nx-kv 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +48 -0
- package/LICENSE +21 -0
- package/README.md +133 -0
- package/assets/nx-kv/SKILL.md +99 -0
- package/assets/nx-kv/references/agent-workflow.md +178 -0
- package/assets/nx-kv/references/todo-commands.md +193 -0
- package/bin/cli.mjs +10 -0
- package/package.json +57 -0
- package/src/core/config.js +94 -0
- package/src/core/errors.js +81 -0
- package/src/core/frontmatter.js +65 -0
- package/src/core/fstree.js +74 -0
- package/src/core/kvapi.js +201 -0
- package/src/core/open.js +26 -0
- package/src/core/paths.js +46 -0
- package/src/core/prompt.js +60 -0
- package/src/index.js +9 -0
- package/src/modules/auth/index.js +98 -0
- package/src/modules/auth/view.jsx +78 -0
- package/src/modules/bundled/index.js +51 -0
- package/src/modules/bundled/service.js +80 -0
- package/src/modules/group/index.js +199 -0
- package/src/modules/group/view.jsx +159 -0
- package/src/modules/system/index.js +153 -0
- package/src/modules/todo/index.js +280 -0
- package/src/modules/todo/service.js +524 -0
- package/src/modules/todo/view.jsx +280 -0
- package/src/runtime/api.js +108 -0
- package/src/runtime/cli.js +299 -0
- package/src/runtime/registry.js +56 -0
- package/src/runtime/server.js +74 -0
- package/src/runtime/spec.js +147 -0
- package/src/web/frontend/App.jsx +74 -0
- package/src/web/frontend/api/client.js +39 -0
- package/src/web/frontend/components/CliHints.jsx +25 -0
- package/src/web/frontend/components/ui.jsx +197 -0
- package/src/web/frontend/index.html +13 -0
- package/src/web/frontend/main.jsx +17 -0
- package/src/web/frontend/registry.js +12 -0
- package/src/web/frontend/store.jsx +74 -0
- package/src/web/frontend/style.css +368 -0
- package/src/web/public/assets/CliHints-3H3KOoDZ.js +1 -0
- package/src/web/public/assets/index-BnWex75m.css +1 -0
- package/src/web/public/assets/index-jhTtYCb9.js +10 -0
- package/src/web/public/assets/view-CrL-DSJu.js +1 -0
- package/src/web/public/assets/view-Du7Wv_-h.js +1 -0
- package/src/web/public/assets/view-S0N5g6v1.js +2 -0
- package/src/web/public/index.html +13 -0
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
// 全局面板状态:bootstrap 数据 + 会话级选择。
|
|
2
|
+
// 关键约定:凡是「刷新后不该丢」的用户选择(当前视图、中心/项目路径、多选勾选)
|
|
3
|
+
// 一律走 persist 读写 localStorage——UI 状态持久化是模板的硬标准,不是可选项。
|
|
4
|
+
import { createContext, useCallback, useContext, useEffect, useMemo, useState } from 'react';
|
|
5
|
+
import { api } from './api/client.js';
|
|
6
|
+
|
|
7
|
+
const LS_KEY = 'nx-kv-ui';
|
|
8
|
+
|
|
9
|
+
// 只持久化「选择」,不持久化「数据」——数据永远从 /api 拉,避免陈旧缓存。
|
|
10
|
+
const DEFAULT_UI = {
|
|
11
|
+
view: 'todo', // 当前 tab
|
|
12
|
+
topic: '', // 清单页的主题筛选(空 = 全部)
|
|
13
|
+
};
|
|
14
|
+
// 刻意**不**在这里存当前工作空间:它的真相源是本机配置(~/.nx-kv/config.json),
|
|
15
|
+
// 存两份就会出现「面板显示 A 组、实际写进 B 组」这类不一致。
|
|
16
|
+
|
|
17
|
+
function loadUi() {
|
|
18
|
+
try {
|
|
19
|
+
const raw = localStorage.getItem(LS_KEY);
|
|
20
|
+
if (!raw) return { ...DEFAULT_UI };
|
|
21
|
+
return { ...DEFAULT_UI, ...JSON.parse(raw) };
|
|
22
|
+
} catch {
|
|
23
|
+
return { ...DEFAULT_UI };
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const StoreCtx = createContext(null);
|
|
28
|
+
|
|
29
|
+
export function StoreProvider({ children }) {
|
|
30
|
+
const [boot, setBoot] = useState(null); // /api/bootstrap 结果
|
|
31
|
+
const [bundled, setBundled] = useState(null);
|
|
32
|
+
const [ui, setUi] = useState(loadUi);
|
|
33
|
+
|
|
34
|
+
// UI 选择变化即落盘(同步、廉价、无版本迁移问题——字段级合并已兜底)
|
|
35
|
+
useEffect(() => {
|
|
36
|
+
try { localStorage.setItem(LS_KEY, JSON.stringify(ui)); } catch { /* 隐私模式等场景静默降级 */ }
|
|
37
|
+
}, [ui]);
|
|
38
|
+
|
|
39
|
+
const refreshBoot = useCallback(async () => {
|
|
40
|
+
const b = await api('/api/bootstrap');
|
|
41
|
+
setBoot(b);
|
|
42
|
+
return b;
|
|
43
|
+
}, []);
|
|
44
|
+
|
|
45
|
+
const refreshBundled = useCallback(async () => {
|
|
46
|
+
setBundled(await api('/api/bundled').catch(() => null));
|
|
47
|
+
}, []);
|
|
48
|
+
|
|
49
|
+
useEffect(() => { refreshBoot(); refreshBundled(); }, [refreshBoot, refreshBundled]);
|
|
50
|
+
|
|
51
|
+
// 支持对象 patch 与函数式 patch(函数式用于「基于最新 state 修剪」场景,避免闭包旧值覆盖)
|
|
52
|
+
const patchUi = useCallback((patch) => {
|
|
53
|
+
setUi((u) => (typeof patch === 'function' ? { ...u, ...patch(u) } : { ...u, ...patch }));
|
|
54
|
+
}, []);
|
|
55
|
+
const toggleSel = useCallback((key, name) => {
|
|
56
|
+
setUi((u) => {
|
|
57
|
+
const set = new Set(u[key]);
|
|
58
|
+
if (set.has(name)) set.delete(name); else set.add(name);
|
|
59
|
+
return { ...u, [key]: [...set] };
|
|
60
|
+
});
|
|
61
|
+
}, []);
|
|
62
|
+
|
|
63
|
+
const value = useMemo(
|
|
64
|
+
() => ({ boot, bundled, ui, patchUi, toggleSel, refreshBoot, refreshBundled }),
|
|
65
|
+
[boot, bundled, ui, patchUi, toggleSel, refreshBoot, refreshBundled]
|
|
66
|
+
);
|
|
67
|
+
return <StoreCtx.Provider value={value}>{children}</StoreCtx.Provider>;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export function useStore() {
|
|
71
|
+
const ctx = useContext(StoreCtx);
|
|
72
|
+
if (!ctx) throw new Error('useStore 必须在 StoreProvider 内使用');
|
|
73
|
+
return ctx;
|
|
74
|
+
}
|
|
@@ -0,0 +1,368 @@
|
|
|
1
|
+
/* nx-kv 面板样式:黑白单色、无 emoji。
|
|
2
|
+
视觉取向:圆角 + 浅底 + 少线条——用背景层次和留白做区分,不用硬边框和网格线。 */
|
|
3
|
+
:root {
|
|
4
|
+
--ink: #14161a;
|
|
5
|
+
--paper: #fff;
|
|
6
|
+
--soft: #f5f6f7;
|
|
7
|
+
--soft-2: #ebedf0;
|
|
8
|
+
--mid: #8b9096;
|
|
9
|
+
--radius: 12px;
|
|
10
|
+
--radius-sm: 8px;
|
|
11
|
+
--shadow: 0 1px 2px rgba(20, 22, 26, 0.06), 0 6px 16px rgba(20, 22, 26, 0.04);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
* { box-sizing: border-box; }
|
|
15
|
+
|
|
16
|
+
body {
|
|
17
|
+
margin: 0;
|
|
18
|
+
font-family: system-ui, "Segoe UI", "Microsoft YaHei", sans-serif;
|
|
19
|
+
font-size: 13.5px;
|
|
20
|
+
line-height: 1.55;
|
|
21
|
+
color: var(--ink);
|
|
22
|
+
background: #fbfbfc;
|
|
23
|
+
-webkit-font-smoothing: antialiased;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/* ---------- 顶栏 ---------- */
|
|
27
|
+
header {
|
|
28
|
+
display: flex;
|
|
29
|
+
align-items: center;
|
|
30
|
+
gap: 20px;
|
|
31
|
+
padding: 12px 20px;
|
|
32
|
+
background: var(--paper);
|
|
33
|
+
box-shadow: 0 1px 0 var(--soft-2);
|
|
34
|
+
position: sticky;
|
|
35
|
+
top: 0;
|
|
36
|
+
z-index: 5;
|
|
37
|
+
}
|
|
38
|
+
.brand { font-weight: 800; letter-spacing: 0.4px; }
|
|
39
|
+
.brand .sub { margin-left: 8px; font-weight: 400; color: var(--mid); font-size: 12px; }
|
|
40
|
+
|
|
41
|
+
/* 分段控件:整块浅底 + 圆角滑块,取代带边框的直角 tab */
|
|
42
|
+
nav { display: inline-flex; gap: 2px; padding: 3px; background: var(--soft); border-radius: 999px; }
|
|
43
|
+
.tab {
|
|
44
|
+
font: inherit;
|
|
45
|
+
border: 0;
|
|
46
|
+
background: transparent;
|
|
47
|
+
color: var(--mid);
|
|
48
|
+
padding: 5px 16px;
|
|
49
|
+
border-radius: 999px;
|
|
50
|
+
cursor: pointer;
|
|
51
|
+
transition: background 0.15s, color 0.15s;
|
|
52
|
+
}
|
|
53
|
+
.tab:hover { color: var(--ink); }
|
|
54
|
+
.tab.active { background: var(--paper); color: var(--ink); font-weight: 600; box-shadow: var(--shadow); }
|
|
55
|
+
|
|
56
|
+
.meta { margin-left: auto; color: var(--mid); font-family: ui-monospace, Consolas, monospace; font-size: 11.5px; }
|
|
57
|
+
|
|
58
|
+
main { padding: 18px 20px 28px; max-width: 1240px; margin: 0 auto; }
|
|
59
|
+
.panel { display: none; }
|
|
60
|
+
.panel.active { display: block; }
|
|
61
|
+
|
|
62
|
+
/* ---------- 工具栏 ---------- */
|
|
63
|
+
.toolbar { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin-bottom: 10px; }
|
|
64
|
+
.toolbar label { color: var(--mid); font-size: 12px; }
|
|
65
|
+
.sep { width: 1px; height: 20px; background: var(--soft-2); margin: 0 4px; }
|
|
66
|
+
.grow { max-width: 340px; }
|
|
67
|
+
|
|
68
|
+
input, select {
|
|
69
|
+
font: inherit;
|
|
70
|
+
color: var(--ink);
|
|
71
|
+
background: var(--paper);
|
|
72
|
+
border: 1px solid var(--soft-2);
|
|
73
|
+
border-radius: var(--radius-sm);
|
|
74
|
+
padding: 6px 10px;
|
|
75
|
+
transition: border-color 0.15s, box-shadow 0.15s;
|
|
76
|
+
}
|
|
77
|
+
input::placeholder { color: #b3b8bd; }
|
|
78
|
+
input:focus, select:focus {
|
|
79
|
+
outline: none;
|
|
80
|
+
border-color: var(--ink);
|
|
81
|
+
box-shadow: 0 0 0 3px rgba(20, 22, 26, 0.07);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/* ---------- 按钮:圆角、浅底、无硬边框 ---------- */
|
|
85
|
+
.btn {
|
|
86
|
+
font: inherit;
|
|
87
|
+
cursor: pointer;
|
|
88
|
+
padding: 6px 12px;
|
|
89
|
+
border: 0;
|
|
90
|
+
border-radius: var(--radius-sm);
|
|
91
|
+
background: var(--ink);
|
|
92
|
+
color: var(--paper);
|
|
93
|
+
transition: opacity 0.15s, background 0.15s, color 0.15s;
|
|
94
|
+
}
|
|
95
|
+
.btn:hover { opacity: 0.86; }
|
|
96
|
+
.btn.ghost { background: var(--soft); color: var(--ink); }
|
|
97
|
+
.btn.ghost:hover { background: var(--soft-2); opacity: 1; }
|
|
98
|
+
.btn.small { padding: 3px 9px; font-size: 12px; border-radius: 7px; }
|
|
99
|
+
.btn:disabled { opacity: 0.4; cursor: default; }
|
|
100
|
+
.btn.danger { background: #b3261e; color: #fff; }
|
|
101
|
+
|
|
102
|
+
/* ---------- toast / 对话框(取代浏览器原生弹窗) ---------- */
|
|
103
|
+
.toast-stack {
|
|
104
|
+
position: fixed;
|
|
105
|
+
left: 50%;
|
|
106
|
+
bottom: 28px;
|
|
107
|
+
transform: translateX(-50%);
|
|
108
|
+
display: flex;
|
|
109
|
+
flex-direction: column;
|
|
110
|
+
align-items: center;
|
|
111
|
+
gap: 8px;
|
|
112
|
+
z-index: 60;
|
|
113
|
+
pointer-events: none;
|
|
114
|
+
}
|
|
115
|
+
.toast {
|
|
116
|
+
background: var(--ink);
|
|
117
|
+
color: var(--paper);
|
|
118
|
+
font-size: 12.5px;
|
|
119
|
+
padding: 9px 16px;
|
|
120
|
+
border-radius: 10px;
|
|
121
|
+
box-shadow: 0 8px 24px rgba(20, 22, 26, 0.25);
|
|
122
|
+
max-width: 72vw;
|
|
123
|
+
white-space: pre-wrap;
|
|
124
|
+
word-break: break-all;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
.dlg {
|
|
128
|
+
position: fixed;
|
|
129
|
+
inset: 0;
|
|
130
|
+
background: rgba(251, 251, 252, 0.86);
|
|
131
|
+
backdrop-filter: blur(2px);
|
|
132
|
+
display: flex;
|
|
133
|
+
align-items: flex-start;
|
|
134
|
+
justify-content: center;
|
|
135
|
+
padding: 96px 16px;
|
|
136
|
+
z-index: 50;
|
|
137
|
+
}
|
|
138
|
+
.dlg-box {
|
|
139
|
+
background: var(--paper);
|
|
140
|
+
border-radius: var(--radius);
|
|
141
|
+
box-shadow: 0 12px 40px rgba(20, 22, 26, 0.16);
|
|
142
|
+
width: min(460px, 94vw);
|
|
143
|
+
padding: 16px 18px;
|
|
144
|
+
}
|
|
145
|
+
.dlg-title { font-weight: 700; margin-bottom: 6px; }
|
|
146
|
+
.dlg-msg { color: var(--ink); white-space: pre-wrap; word-break: break-all; margin-bottom: 6px; }
|
|
147
|
+
.dlg-input {
|
|
148
|
+
width: 100%;
|
|
149
|
+
margin: 8px 0 4px;
|
|
150
|
+
font-family: ui-monospace, Consolas, monospace;
|
|
151
|
+
font-size: 12.5px;
|
|
152
|
+
}
|
|
153
|
+
.dlg-acts { display: flex; justify-content: flex-end; gap: 8px; margin-top: 12px; }
|
|
154
|
+
|
|
155
|
+
/* ---------- 卡片与列表 ---------- */
|
|
156
|
+
.card {
|
|
157
|
+
background: var(--paper);
|
|
158
|
+
border-radius: var(--radius);
|
|
159
|
+
padding: 10px 12px;
|
|
160
|
+
box-shadow: var(--shadow);
|
|
161
|
+
margin-bottom: 12px;
|
|
162
|
+
}
|
|
163
|
+
.card.hidden { display: none; }
|
|
164
|
+
.colhead { display: flex; align-items: baseline; gap: 8px; margin: 2px 2px 8px; }
|
|
165
|
+
h3 { font-size: 13px; margin: 0; font-weight: 700; }
|
|
166
|
+
.cols { display: flex; gap: 14px; align-items: flex-start; }
|
|
167
|
+
.col { flex: 1; min-width: 0; }
|
|
168
|
+
.list { padding: 4px; }
|
|
169
|
+
|
|
170
|
+
/* 行:靠 hover 底色区分,不用分隔线;内容多时允许换行 */
|
|
171
|
+
.row {
|
|
172
|
+
display: flex;
|
|
173
|
+
flex-wrap: wrap;
|
|
174
|
+
align-items: center;
|
|
175
|
+
gap: 8px 10px;
|
|
176
|
+
padding: 8px 10px;
|
|
177
|
+
border-radius: 10px;
|
|
178
|
+
transition: background 0.12s;
|
|
179
|
+
}
|
|
180
|
+
.row:hover { background: var(--soft); }
|
|
181
|
+
.row + .row { margin-top: 2px; }
|
|
182
|
+
|
|
183
|
+
/* 清单页行内元素:id / 主题 / 正文 / 时间 / 备注 */
|
|
184
|
+
.row .tid {
|
|
185
|
+
color: var(--mid);
|
|
186
|
+
font-family: ui-monospace, Consolas, monospace;
|
|
187
|
+
font-size: 11.5px;
|
|
188
|
+
min-width: 30px;
|
|
189
|
+
text-align: right;
|
|
190
|
+
flex-shrink: 0;
|
|
191
|
+
}
|
|
192
|
+
.row .topic {
|
|
193
|
+
font-size: 12px;
|
|
194
|
+
font-weight: 600;
|
|
195
|
+
background: var(--soft-2);
|
|
196
|
+
border-radius: 5px;
|
|
197
|
+
padding: 1px 6px;
|
|
198
|
+
white-space: nowrap;
|
|
199
|
+
flex-shrink: 0;
|
|
200
|
+
}
|
|
201
|
+
.row .text {
|
|
202
|
+
flex: 1;
|
|
203
|
+
min-width: 0; /* 关键:没有它,长文本会把整个 flex 行撑破 */
|
|
204
|
+
overflow: hidden;
|
|
205
|
+
text-overflow: ellipsis;
|
|
206
|
+
white-space: nowrap;
|
|
207
|
+
}
|
|
208
|
+
.row .time { color: var(--mid); font-size: 11.5px; white-space: nowrap; flex-shrink: 0; }
|
|
209
|
+
.row .note {
|
|
210
|
+
flex-basis: 100%; /* 强制换行到自己的行 */
|
|
211
|
+
color: var(--mid);
|
|
212
|
+
font-size: 11.5px;
|
|
213
|
+
padding-left: 40px;
|
|
214
|
+
word-break: break-word;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
/* 登录页:行内表单 */
|
|
218
|
+
.row-inline { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
|
|
219
|
+
.row .name { font-weight: 600; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
220
|
+
.row .desc { color: var(--mid); font-size: 12px; flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
221
|
+
.row .acts { margin-left: auto; display: flex; align-items: center; gap: 6px; flex-shrink: 0; }
|
|
222
|
+
|
|
223
|
+
/* 平台小按钮(平行、可勾选) */
|
|
224
|
+
.plats { display: flex; gap: 4px; flex-wrap: wrap; }
|
|
225
|
+
.pill {
|
|
226
|
+
font: inherit;
|
|
227
|
+
font-size: 11px;
|
|
228
|
+
line-height: 1;
|
|
229
|
+
cursor: pointer;
|
|
230
|
+
padding: 5px 8px;
|
|
231
|
+
border: 0;
|
|
232
|
+
border-radius: 999px;
|
|
233
|
+
background: var(--soft);
|
|
234
|
+
color: var(--mid);
|
|
235
|
+
transition: background 0.12s, color 0.12s;
|
|
236
|
+
}
|
|
237
|
+
.pill:hover { background: var(--soft-2); color: var(--ink); }
|
|
238
|
+
.pill.on { background: var(--ink); color: var(--paper); font-weight: 600; }
|
|
239
|
+
/* 形态区分:实体 = 实心(默认 on 样式);软链接 = 虚线描边 */
|
|
240
|
+
.pill.on.lnk {
|
|
241
|
+
background: var(--paper);
|
|
242
|
+
color: var(--ink);
|
|
243
|
+
border: 1.5px dashed var(--ink);
|
|
244
|
+
padding: 4px 6.5px;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
/* 徽标 */
|
|
248
|
+
.tag {
|
|
249
|
+
font-size: 11px;
|
|
250
|
+
padding: 2px 8px;
|
|
251
|
+
border-radius: 999px;
|
|
252
|
+
background: var(--soft);
|
|
253
|
+
color: var(--mid);
|
|
254
|
+
white-space: nowrap;
|
|
255
|
+
}
|
|
256
|
+
.tag.strong { background: var(--ink); color: var(--paper); }
|
|
257
|
+
|
|
258
|
+
/* ---------- 表格:去掉网格线,只用极浅的行分隔 ---------- */
|
|
259
|
+
table { width: 100%; border-collapse: collapse; }
|
|
260
|
+
th, td { text-align: left; padding: 9px 10px; vertical-align: top; }
|
|
261
|
+
th { color: var(--mid); font-weight: 600; font-size: 11.5px; }
|
|
262
|
+
tbody tr:hover { background: var(--soft); }
|
|
263
|
+
tbody tr + tr td { box-shadow: inset 0 1px 0 var(--soft); }
|
|
264
|
+
.mono, td.path { font-family: ui-monospace, Consolas, monospace; font-size: 12px; word-break: break-all; }
|
|
265
|
+
td.ops { white-space: nowrap; }
|
|
266
|
+
td.ops .btn { margin: 0 3px 3px 0; }
|
|
267
|
+
.muted { color: var(--mid); }
|
|
268
|
+
.bad { font-weight: 700; }
|
|
269
|
+
|
|
270
|
+
/* ---------- 点击即复制的路径/标识 ---------- */
|
|
271
|
+
.copyable {
|
|
272
|
+
cursor: copy;
|
|
273
|
+
border-bottom: 1px dashed transparent;
|
|
274
|
+
transition: border-color 0.12s, color 0.12s;
|
|
275
|
+
}
|
|
276
|
+
.copyable:hover { border-bottom-color: var(--mid); }
|
|
277
|
+
.copyable:active { color: var(--ink); }
|
|
278
|
+
/* 适配器总表里多个可复制项并排 */
|
|
279
|
+
dd .adapter-dir { display: inline-block; margin-right: 14px; }
|
|
280
|
+
|
|
281
|
+
/* ---------- 设置页 ---------- */
|
|
282
|
+
.settings { display: grid; grid-template-columns: 120px 1fr; gap: 10px 16px; align-items: center; }
|
|
283
|
+
.settings dt { color: var(--mid); font-size: 12px; }
|
|
284
|
+
.settings dd { margin: 0; }
|
|
285
|
+
.row-inline { display: flex; gap: 8px; margin-top: 8px; }
|
|
286
|
+
.row-inline input { flex: 1; }
|
|
287
|
+
|
|
288
|
+
/* ---------- 提示条 ---------- */
|
|
289
|
+
.cli-hint {
|
|
290
|
+
color: var(--mid);
|
|
291
|
+
font-size: 11.5px;
|
|
292
|
+
padding: 6px 4px 2px;
|
|
293
|
+
display: flex;
|
|
294
|
+
flex-wrap: wrap;
|
|
295
|
+
gap: 4px 8px;
|
|
296
|
+
align-items: baseline;
|
|
297
|
+
}
|
|
298
|
+
.cli-hint-label { flex-basis: 100%; }
|
|
299
|
+
/* CLI 命令串:一条命令一个可点击复制的 chip,密集但可读 */
|
|
300
|
+
.cli-cmd {
|
|
301
|
+
background: var(--soft);
|
|
302
|
+
border-radius: 5px;
|
|
303
|
+
padding: 1px 6px;
|
|
304
|
+
white-space: nowrap;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
/* ---------- 弹窗 ---------- */
|
|
308
|
+
.modal {
|
|
309
|
+
position: fixed;
|
|
310
|
+
inset: 0;
|
|
311
|
+
background: rgba(251, 251, 252, 0.86);
|
|
312
|
+
backdrop-filter: blur(2px);
|
|
313
|
+
display: flex;
|
|
314
|
+
align-items: flex-start;
|
|
315
|
+
justify-content: center;
|
|
316
|
+
padding: 48px 16px;
|
|
317
|
+
z-index: 20;
|
|
318
|
+
}
|
|
319
|
+
.modal.hidden { display: none; }
|
|
320
|
+
.modal-box {
|
|
321
|
+
background: var(--paper);
|
|
322
|
+
border-radius: var(--radius);
|
|
323
|
+
box-shadow: 0 12px 40px rgba(20, 22, 26, 0.16);
|
|
324
|
+
width: min(880px, 96vw);
|
|
325
|
+
max-height: 84vh;
|
|
326
|
+
display: flex;
|
|
327
|
+
flex-direction: column;
|
|
328
|
+
overflow: hidden;
|
|
329
|
+
}
|
|
330
|
+
.modal-title {
|
|
331
|
+
padding: 12px 14px;
|
|
332
|
+
display: flex;
|
|
333
|
+
justify-content: space-between;
|
|
334
|
+
align-items: center;
|
|
335
|
+
font-weight: 700;
|
|
336
|
+
box-shadow: 0 1px 0 var(--soft);
|
|
337
|
+
}
|
|
338
|
+
.modal-body { padding: 14px; overflow: auto; }
|
|
339
|
+
|
|
340
|
+
pre {
|
|
341
|
+
margin: 0;
|
|
342
|
+
font-family: ui-monospace, Consolas, monospace;
|
|
343
|
+
font-size: 12px;
|
|
344
|
+
line-height: 1.6;
|
|
345
|
+
white-space: pre-wrap;
|
|
346
|
+
word-break: break-all;
|
|
347
|
+
}
|
|
348
|
+
.d-add { background: var(--soft-2); font-weight: 600; }
|
|
349
|
+
.d-del { color: var(--mid); text-decoration: line-through; }
|
|
350
|
+
|
|
351
|
+
.conflict-file { background: var(--soft); border-radius: 10px; margin-bottom: 10px; overflow: hidden; }
|
|
352
|
+
.conflict-file .cf-head {
|
|
353
|
+
padding: 8px 12px;
|
|
354
|
+
display: flex;
|
|
355
|
+
justify-content: space-between;
|
|
356
|
+
align-items: center;
|
|
357
|
+
font-family: ui-monospace, Consolas, monospace;
|
|
358
|
+
font-size: 12px;
|
|
359
|
+
}
|
|
360
|
+
.conflict-file pre { padding: 10px 12px; background: var(--paper); }
|
|
361
|
+
|
|
362
|
+
footer { color: var(--mid); padding: 14px 20px 24px; font-size: 11.5px; text-align: center; }
|
|
363
|
+
footer code {
|
|
364
|
+
font-family: ui-monospace, Consolas, monospace;
|
|
365
|
+
background: var(--soft);
|
|
366
|
+
border-radius: 6px;
|
|
367
|
+
padding: 1px 6px;
|
|
368
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{o as e,s as t,t as n}from"./index-jhTtYCb9.js";var r=t();function i({module:t}){let{boot:i}=e(),a=(i?.commands||[]).filter(e=>e.module===t);return a.length?(0,r.jsxs)(`div`,{className:`cli-hint`,children:[(0,r.jsx)(`span`,{className:`cli-hint-label`,children:`CLI 等价(同构命令,加 --json 得机器可读输出):`}),a.map(e=>(0,r.jsx)(n,{className:`cli-cmd`,text:e.command,title:`点击复制:${e.usage}`,children:e.command},e.id))]}):null}export{i as t};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
:root{--ink:#14161a;--paper:#fff;--soft:#f5f6f7;--soft-2:#ebedf0;--mid:#8b9096;--radius:12px;--radius-sm:8px;--shadow:0 1px 2px #14161a0f, 0 6px 16px #14161a0a}*{box-sizing:border-box}body{color:var(--ink);-webkit-font-smoothing:antialiased;background:#fbfbfc;margin:0;font-family:system-ui,Segoe UI,Microsoft YaHei,sans-serif;font-size:13.5px;line-height:1.55}header{background:var(--paper);box-shadow:0 1px 0 var(--soft-2);z-index:5;align-items:center;gap:20px;padding:12px 20px;display:flex;position:sticky;top:0}.brand{letter-spacing:.4px;font-weight:800}.brand .sub{color:var(--mid);margin-left:8px;font-size:12px;font-weight:400}nav{background:var(--soft);border-radius:999px;gap:2px;padding:3px;display:inline-flex}.tab{font:inherit;color:var(--mid);cursor:pointer;background:0 0;border:0;border-radius:999px;padding:5px 16px;transition:background .15s,color .15s}.tab:hover{color:var(--ink)}.tab.active{background:var(--paper);color:var(--ink);box-shadow:var(--shadow);font-weight:600}.meta{color:var(--mid);margin-left:auto;font-family:ui-monospace,Consolas,monospace;font-size:11.5px}main{max-width:1240px;margin:0 auto;padding:18px 20px 28px}.panel{display:none}.panel.active{display:block}.toolbar{flex-wrap:wrap;align-items:center;gap:8px;margin-bottom:10px;display:flex}.toolbar label{color:var(--mid);font-size:12px}.sep{background:var(--soft-2);width:1px;height:20px;margin:0 4px}.grow{max-width:340px}input,select{font:inherit;color:var(--ink);background:var(--paper);border:1px solid var(--soft-2);border-radius:var(--radius-sm);padding:6px 10px;transition:border-color .15s,box-shadow .15s}input::placeholder{color:#b3b8bd}input:focus,select:focus{border-color:var(--ink);outline:none;box-shadow:0 0 0 3px #14161a12}.btn{font:inherit;cursor:pointer;border-radius:var(--radius-sm);background:var(--ink);color:var(--paper);border:0;padding:6px 12px;transition:opacity .15s,background .15s,color .15s}.btn:hover{opacity:.86}.btn.ghost{background:var(--soft);color:var(--ink)}.btn.ghost:hover{background:var(--soft-2);opacity:1}.btn.small{border-radius:7px;padding:3px 9px;font-size:12px}.btn:disabled{opacity:.4;cursor:default}.btn.danger{color:#fff;background:#b3261e}.toast-stack{z-index:60;pointer-events:none;flex-direction:column;align-items:center;gap:8px;display:flex;position:fixed;bottom:28px;left:50%;transform:translate(-50%)}.toast{background:var(--ink);color:var(--paper);white-space:pre-wrap;word-break:break-all;border-radius:10px;max-width:72vw;padding:9px 16px;font-size:12.5px;box-shadow:0 8px 24px #14161a40}.dlg{-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px);z-index:50;background:#fbfbfcdb;justify-content:center;align-items:flex-start;padding:96px 16px;display:flex;position:fixed;inset:0}.dlg-box{background:var(--paper);border-radius:var(--radius);width:min(460px,94vw);padding:16px 18px;box-shadow:0 12px 40px #14161a29}.dlg-title{margin-bottom:6px;font-weight:700}.dlg-msg{color:var(--ink);white-space:pre-wrap;word-break:break-all;margin-bottom:6px}.dlg-input{width:100%;margin:8px 0 4px;font-family:ui-monospace,Consolas,monospace;font-size:12.5px}.dlg-acts{justify-content:flex-end;gap:8px;margin-top:12px;display:flex}.card{background:var(--paper);border-radius:var(--radius);box-shadow:var(--shadow);margin-bottom:12px;padding:10px 12px}.card.hidden{display:none}.colhead{align-items:baseline;gap:8px;margin:2px 2px 8px;display:flex}h3{margin:0;font-size:13px;font-weight:700}.cols{align-items:flex-start;gap:14px;display:flex}.col{flex:1;min-width:0}.list{padding:4px}.row{border-radius:10px;flex-wrap:wrap;align-items:center;gap:8px 10px;padding:8px 10px;transition:background .12s;display:flex}.row:hover{background:var(--soft)}.row+.row{margin-top:2px}.row .tid{color:var(--mid);text-align:right;flex-shrink:0;min-width:30px;font-family:ui-monospace,Consolas,monospace;font-size:11.5px}.row .topic{background:var(--soft-2);white-space:nowrap;border-radius:5px;flex-shrink:0;padding:1px 6px;font-size:12px;font-weight:600}.row .text{text-overflow:ellipsis;white-space:nowrap;flex:1;min-width:0;overflow:hidden}.row .time{color:var(--mid);white-space:nowrap;flex-shrink:0;font-size:11.5px}.row .note{color:var(--mid);word-break:break-word;flex-basis:100%;padding-left:40px;font-size:11.5px}.row-inline{flex-wrap:wrap;align-items:center;gap:8px;display:flex}.row .name{text-overflow:ellipsis;white-space:nowrap;min-width:0;font-weight:600;overflow:hidden}.row .desc{color:var(--mid);text-overflow:ellipsis;white-space:nowrap;flex:1;min-width:0;font-size:12px;overflow:hidden}.row .acts{flex-shrink:0;align-items:center;gap:6px;margin-left:auto;display:flex}.plats{flex-wrap:wrap;gap:4px;display:flex}.pill{font:inherit;cursor:pointer;background:var(--soft);color:var(--mid);border:0;border-radius:999px;padding:5px 8px;font-size:11px;line-height:1;transition:background .12s,color .12s}.pill:hover{background:var(--soft-2);color:var(--ink)}.pill.on{background:var(--ink);color:var(--paper);font-weight:600}.pill.on.lnk{background:var(--paper);color:var(--ink);border:1.5px dashed var(--ink);padding:4px 6.5px}.tag{background:var(--soft);color:var(--mid);white-space:nowrap;border-radius:999px;padding:2px 8px;font-size:11px}.tag.strong{background:var(--ink);color:var(--paper)}table{border-collapse:collapse;width:100%}th,td{text-align:left;vertical-align:top;padding:9px 10px}th{color:var(--mid);font-size:11.5px;font-weight:600}tbody tr:hover{background:var(--soft)}tbody tr+tr td{box-shadow:inset 0 1px 0 var(--soft)}.mono,td.path{word-break:break-all;font-family:ui-monospace,Consolas,monospace;font-size:12px}td.ops{white-space:nowrap}td.ops .btn{margin:0 3px 3px 0}.muted{color:var(--mid)}.bad{font-weight:700}.copyable{cursor:copy;border-bottom:1px dashed #0000;transition:border-color .12s,color .12s}.copyable:hover{border-bottom-color:var(--mid)}.copyable:active{color:var(--ink)}dd .adapter-dir{margin-right:14px;display:inline-block}.settings{grid-template-columns:120px 1fr;align-items:center;gap:10px 16px;display:grid}.settings dt{color:var(--mid);font-size:12px}.settings dd{margin:0}.row-inline{gap:8px;margin-top:8px;display:flex}.row-inline input{flex:1}.cli-hint{color:var(--mid);flex-wrap:wrap;align-items:baseline;gap:4px 8px;padding:6px 4px 2px;font-size:11.5px;display:flex}.cli-hint-label{flex-basis:100%}.cli-cmd{background:var(--soft);white-space:nowrap;border-radius:5px;padding:1px 6px}.modal{-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px);z-index:20;background:#fbfbfcdb;justify-content:center;align-items:flex-start;padding:48px 16px;display:flex;position:fixed;inset:0}.modal.hidden{display:none}.modal-box{background:var(--paper);border-radius:var(--radius);flex-direction:column;width:min(880px,96vw);max-height:84vh;display:flex;overflow:hidden;box-shadow:0 12px 40px #14161a29}.modal-title{box-shadow:0 1px 0 var(--soft);justify-content:space-between;align-items:center;padding:12px 14px;font-weight:700;display:flex}.modal-body{padding:14px;overflow:auto}pre{white-space:pre-wrap;word-break:break-all;margin:0;font-family:ui-monospace,Consolas,monospace;font-size:12px;line-height:1.6}.d-add{background:var(--soft-2);font-weight:600}.d-del{color:var(--mid);text-decoration:line-through}.conflict-file{background:var(--soft);border-radius:10px;margin-bottom:10px;overflow:hidden}.conflict-file .cf-head{justify-content:space-between;align-items:center;padding:8px 12px;font-family:ui-monospace,Consolas,monospace;font-size:12px;display:flex}.conflict-file pre{background:var(--paper);padding:10px 12px}footer{color:var(--mid);text-align:center;padding:14px 20px 24px;font-size:11.5px}footer code{background:var(--soft);border-radius:6px;padding:1px 6px;font-family:ui-monospace,Consolas,monospace}
|