@musnows/scriverse 0.6.1 → 0.6.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.
- package/README.en.md +3 -2
- package/README.md +3 -2
- package/dist/ai-tool-results.js +71 -0
- package/dist/ai-tool-results.js.map +1 -1
- package/dist/ai.js +267 -54
- package/dist/ai.js.map +1 -1
- package/dist/app.js +256 -57
- package/dist/app.js.map +1 -1
- package/dist/attachment-storage.js +9 -1
- package/dist/attachment-storage.js.map +1 -1
- package/dist/cli-contract.js +4 -0
- package/dist/cli-contract.js.map +1 -1
- package/dist/cli-core.js +23 -7
- package/dist/cli-core.js.map +1 -1
- package/dist/credential-vault.js +7 -5
- package/dist/credential-vault.js.map +1 -1
- package/dist/database.js +243 -2
- package/dist/database.js.map +1 -1
- package/dist/docx-export.js +89 -0
- package/dist/docx-export.js.map +1 -0
- package/dist/domain.js +9 -0
- package/dist/domain.js.map +1 -1
- package/dist/image-captcha.js +8 -5
- package/dist/image-captcha.js.map +1 -1
- package/dist/public/ai-context-meter.js +4 -0
- package/dist/public/ai-message-time.js +3 -9
- package/dist/public/ai-tool-call.js +4 -0
- package/dist/public/app.js +765 -111
- package/dist/public/index.html +49 -17
- package/dist/public/markdown.js +1 -2
- package/dist/public/page-route.js +2 -2
- package/dist/public/styles.css +87 -29
- package/dist/public/system-status.d.ts +12 -0
- package/dist/public/system-status.js +16 -0
- package/dist/public/theme-init.js +2 -2
- package/dist/security.js +143 -16
- package/dist/security.js.map +1 -1
- package/dist/server-runtime.js +56 -1
- package/dist/server-runtime.js.map +1 -1
- package/dist/store.js +289 -39
- package/dist/store.js.map +1 -1
- package/dist/user-auth.js +56 -88
- package/dist/user-auth.js.map +1 -1
- package/dist/version.js +1 -1
- package/dist/writing-progress-time.js +15 -0
- package/dist/writing-progress-time.js.map +1 -1
- package/package.json +2 -1
package/dist/public/index.html
CHANGED
|
@@ -6,11 +6,11 @@
|
|
|
6
6
|
<meta name="description" content="面向长篇小说创作的 AI 协作工作台">
|
|
7
7
|
<meta name="theme-color" content="#8b3d2c">
|
|
8
8
|
<title>叙界 · 小说 AI 创作工作台</title>
|
|
9
|
-
<script src="/theme-init.js?v=
|
|
9
|
+
<script src="/theme-init.js?v=20260801-work-audit-page-v1"></script>
|
|
10
10
|
<link rel="icon" href="/icon.svg?v=20260712" type="image/svg+xml">
|
|
11
11
|
<link rel="manifest" href="/site.webmanifest">
|
|
12
12
|
<link rel="stylesheet" href="/vendor/vditor/dist/index.css?v=3.11.2">
|
|
13
|
-
<link rel="stylesheet" href="/styles.css?v=
|
|
13
|
+
<link rel="stylesheet" href="/styles.css?v=20260801-merge-pr-291-v1">
|
|
14
14
|
</head>
|
|
15
15
|
<body class="auth-pending">
|
|
16
16
|
<section id="auth-view" class="auth-view hidden" aria-labelledby="auth-title">
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
<form id="login-form" class="auth-form">
|
|
27
27
|
<label>用户名<input name="username" autocomplete="username" maxlength="100" required></label>
|
|
28
28
|
<label>密码<input id="login-password" name="password" type="password" autocomplete="current-password" maxlength="200" required aria-describedby="login-lock-hint"></label>
|
|
29
|
-
<p id="login-lock-hint" class="auth-security-hint"
|
|
29
|
+
<p id="login-lock-hint" class="auth-security-hint">登录和注册采用验证码与来源限速防护,不会因他人输错密码而锁定账户。</p>
|
|
30
30
|
<div class="auth-captcha">
|
|
31
31
|
<label>验证码<input name="captchaAnswer" autocomplete="off" inputmode="text" maxlength="8" spellcheck="false" required aria-describedby="login-captcha-hint"></label>
|
|
32
32
|
<button id="login-captcha-refresh" class="auth-captcha-image" type="button" aria-label="刷新验证码" title="刷新验证码">
|
|
@@ -40,6 +40,7 @@
|
|
|
40
40
|
</form>
|
|
41
41
|
<form id="register-form" class="auth-form hidden">
|
|
42
42
|
<label>用户名<input name="username" autocomplete="username" minlength="3" maxlength="40" pattern="[A-Za-z0-9_.\-\u4e00-\u9fff]+" required></label>
|
|
43
|
+
<label id="register-setup-token-field" class="hidden">初始化令牌<input name="setupToken" type="password" autocomplete="off" minlength="32" maxlength="500" aria-describedby="register-setup-token-hint"><small id="register-setup-token-hint">请输入服务端 APP_SETUP_TOKEN 的值。</small></label>
|
|
43
44
|
<label>密码<span class="password-field"><input id="register-password" name="password" type="password" autocomplete="new-password" minlength="10" maxlength="200" required><button class="password-toggle" type="button" data-password-toggle="register-password" aria-label="显示密码" aria-pressed="false" title="显示密码"><svg viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path d="M2.5 12s3.3-5.5 9.5-5.5S21.5 12 21.5 12 18.2 17.5 12 17.5 2.5 12 2.5 12Z"/><circle cx="12" cy="12" r="2.8"/></svg></button></span></label>
|
|
44
45
|
<label>确认密码<span class="password-field"><input id="register-password-confirmation" name="passwordConfirmation" type="password" autocomplete="new-password" minlength="10" maxlength="200" required><button class="password-toggle" type="button" data-password-toggle="register-password-confirmation" aria-label="显示确认密码" aria-pressed="false" title="显示确认密码"><svg viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path d="M2.5 12s3.3-5.5 9.5-5.5S21.5 12 21.5 12 18.2 17.5 12 17.5 2.5 12 2.5 12Z"/><circle cx="12" cy="12" r="2.8"/></svg></button></span></label>
|
|
45
46
|
<div class="auth-captcha">
|
|
@@ -57,7 +58,7 @@
|
|
|
57
58
|
<p id="auth-error" class="auth-error" role="alert"></p>
|
|
58
59
|
</div>
|
|
59
60
|
<footer class="product-footer auth-product-footer" data-product-footer aria-label="叙界项目信息">
|
|
60
|
-
<span class="product-footer-meta"><span>© <time data-product-footer-year></time
|
|
61
|
+
<span class="product-footer-meta"><span>© <time data-product-footer-year></time></span><span aria-hidden="true">·</span><span>叙界 <span data-product-footer-version>v—</span></span><span aria-hidden="true">·</span><a href="https://github.com/musnows/Scriverse" target="_blank" rel="noopener noreferrer" aria-label="在 GitHub 查看叙界仓库">GitHub</a></span>
|
|
61
62
|
<span class="product-footer-development hidden" data-product-footer-development>开发模式</span>
|
|
62
63
|
</footer>
|
|
63
64
|
</section>
|
|
@@ -73,7 +74,7 @@
|
|
|
73
74
|
<button id="mobile-module-tab" class="mobile-module-tab" type="button" aria-label="打开作品模块" aria-expanded="false">模块</button>
|
|
74
75
|
<div id="work-meta" class="work-meta">尚未选择作品</div>
|
|
75
76
|
<div class="top-actions">
|
|
76
|
-
<span id="save-state" class="save-state"
|
|
77
|
+
<span id="save-state" class="save-state" role="status" aria-live="polite" aria-label="系统状态:检测中">检测中</span>
|
|
77
78
|
<div id="presence-control" class="presence-control hidden">
|
|
78
79
|
<button id="presence-button" class="presence-button" type="button" aria-expanded="false" aria-controls="presence-panel"><span class="presence-status-dot" aria-hidden="true"></span><span id="presence-count">1 人</span></button>
|
|
79
80
|
<section id="presence-panel" class="presence-panel hidden" aria-label="当前作品在线协作者">
|
|
@@ -158,7 +159,7 @@
|
|
|
158
159
|
</div>
|
|
159
160
|
<div id="book-shelf" class="book-shelf" data-testid="book-shelf"></div>
|
|
160
161
|
<footer class="product-footer" data-product-footer aria-label="叙界项目信息">
|
|
161
|
-
<span class="product-footer-meta"><span>© <time data-product-footer-year></time
|
|
162
|
+
<span class="product-footer-meta"><span>© <time data-product-footer-year></time></span><span aria-hidden="true">·</span><span>叙界 <span data-product-footer-version>v—</span></span><span aria-hidden="true">·</span><a href="https://github.com/musnows/Scriverse" target="_blank" rel="noopener noreferrer" aria-label="在 GitHub 查看叙界仓库">GitHub</a></span>
|
|
162
163
|
<span class="product-footer-development hidden" data-product-footer-development>开发模式</span>
|
|
163
164
|
</footer>
|
|
164
165
|
</section>
|
|
@@ -185,6 +186,19 @@
|
|
|
185
186
|
<div id="platform-usage-content" class="module-content usage-page-content"></div>
|
|
186
187
|
</section>
|
|
187
188
|
|
|
189
|
+
<section id="work-audit-view" class="shelf-view work-audit-view hidden" aria-labelledby="work-audit-title">
|
|
190
|
+
<div class="shelf-header work-audit-header">
|
|
191
|
+
<div><span id="work-audit-eyebrow" class="eyebrow">作品安全</span><h1 id="work-audit-title">操作记录</h1><p>按时间倒序查看作品写入与管理操作,以及完整的操作者、对象和变更详情。</p></div>
|
|
192
|
+
<div class="settings-detail-actions">
|
|
193
|
+
<button id="work-audit-return" class="ghost-button settings-parent-button" type="button">返回设置</button>
|
|
194
|
+
<button id="work-audit-refresh" class="ghost-button" type="button">刷新记录</button>
|
|
195
|
+
</div>
|
|
196
|
+
</div>
|
|
197
|
+
<div class="work-audit-toolbar" aria-live="polite"><p id="work-audit-summary">正在读取操作记录……</p></div>
|
|
198
|
+
<div id="work-audit-list" class="work-audit-list" aria-live="polite"></div>
|
|
199
|
+
<div class="work-audit-footer"><button id="work-audit-load-more" class="primary-button hidden" type="button">加载更多记录</button></div>
|
|
200
|
+
</section>
|
|
201
|
+
|
|
188
202
|
<section id="settings-hub-view" class="shelf-view hidden" aria-labelledby="settings-hub-title">
|
|
189
203
|
<div class="shelf-header settings-hub-header">
|
|
190
204
|
<div><span class="eyebrow">工作台配置</span><h1 id="settings-hub-title">设置</h1><p>集中管理 AI、显示偏好、内容检索与作品导出。</p></div>
|
|
@@ -199,11 +213,11 @@
|
|
|
199
213
|
<button id="writing-progress-button" class="settings-hub-card" type="button"><span class="settings-card-mark">字</span><strong>写作目标</strong><small>每日目标、总字数目标与近 30 天趋势</small></button>
|
|
200
214
|
<button id="work-audit-button" class="settings-hub-card" type="button"><span class="settings-card-mark">录</span><strong>操作记录</strong><small>查看作品修改、操作者、对象与时间</small></button>
|
|
201
215
|
<button id="appearance-button" class="settings-hub-card" type="button" data-settings-action="appearance"><span class="settings-card-mark">Aa</span><strong>显示设置</strong><small>中文字体、等宽英文字体、字号与行距</small></button>
|
|
202
|
-
<button id="export-button" class="settings-hub-card" type="button" data-settings-action="export"><span class="settings-card-mark"
|
|
216
|
+
<button id="export-button" class="settings-hub-card" type="button" data-settings-action="export" aria-haspopup="menu" aria-controls="manuscript-export-menu" aria-expanded="false"><span class="settings-card-mark">出</span><strong>导出正文</strong><small>选择导出 Markdown ZIP 或 DOCX;不包含角色和设定资料</small></button>
|
|
203
217
|
</div>
|
|
204
218
|
<p id="settings-work-note" class="settings-work-note"></p>
|
|
205
219
|
<footer class="product-footer settings-product-footer" data-product-footer aria-label="叙界项目信息">
|
|
206
|
-
<span class="product-footer-meta"><span>© <time data-product-footer-year></time
|
|
220
|
+
<span class="product-footer-meta"><span>© <time data-product-footer-year></time></span><span aria-hidden="true">·</span><span>叙界 <span data-product-footer-version>v—</span></span><span aria-hidden="true">·</span><a href="https://github.com/musnows/Scriverse" target="_blank" rel="noopener noreferrer" aria-label="在 GitHub 查看叙界仓库">GitHub</a></span>
|
|
207
221
|
<span class="product-footer-development hidden" data-product-footer-development>开发模式</span>
|
|
208
222
|
</footer>
|
|
209
223
|
</section>
|
|
@@ -264,7 +278,7 @@
|
|
|
264
278
|
<div id="ai-panel-resize" class="panel-resize-handle" role="separator" aria-label="调整创作助手宽度" aria-orientation="vertical" tabindex="0"></div>
|
|
265
279
|
<div class="ai-heading">
|
|
266
280
|
<button id="ai-panel-toggle" class="panel-collapse-button" type="button" aria-label="收起创作助手" aria-expanded="true">›</button>
|
|
267
|
-
<div class="ai-heading-title"><span class="status-dot"></span><strong>创作助手</strong></div>
|
|
281
|
+
<div class="ai-heading-title"><span id="ai-status-dot" class="status-dot" role="status" aria-label="创作助手状态:正常" title="创作助手状态:正常"></span><strong>创作助手</strong></div>
|
|
268
282
|
<div class="ai-heading-actions">
|
|
269
283
|
<span id="ai-conversation-title" title="当前对话">新对话</span>
|
|
270
284
|
<button id="ai-history-toggle" type="button" aria-label="历史记录" aria-controls="ai-history-dialog" aria-expanded="false" aria-haspopup="dialog" title="历史记录"><svg class="ai-heading-action-icon" viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path d="M3 12a9 9 0 1 0 3-6.7L3 8"></path><path d="M3 3v5h5M12 7v5l3.5 2"></path></svg></button>
|
|
@@ -345,6 +359,17 @@
|
|
|
345
359
|
<small>关闭时可横向滚动</small>
|
|
346
360
|
</button>
|
|
347
361
|
</div>
|
|
362
|
+
<div id="manuscript-export-menu" class="manuscript-export-menu hidden" role="menu" aria-label="导出正文格式">
|
|
363
|
+
<strong>选择导出格式</strong>
|
|
364
|
+
<button type="button" role="menuitem" data-export-format="markdown">
|
|
365
|
+
<span>导出 Markdown</span>
|
|
366
|
+
<small>打包为 ZIP,内含 Markdown 正文</small>
|
|
367
|
+
</button>
|
|
368
|
+
<button type="button" role="menuitem" data-export-format="docx">
|
|
369
|
+
<span>导出 DOCX</span>
|
|
370
|
+
<small>Word 正文;有封面时嵌入为首页</small>
|
|
371
|
+
</button>
|
|
372
|
+
</div>
|
|
348
373
|
<input id="new-import-file" class="hidden" type="file" accept=".txt,.docx">
|
|
349
374
|
<input id="cover-file" class="hidden" type="file" accept="image/png,image/jpeg,image/webp">
|
|
350
375
|
<input id="avatar-file" class="hidden" type="file" accept="image/png,image/jpeg,image/webp">
|
|
@@ -383,6 +408,18 @@
|
|
|
383
408
|
</section>
|
|
384
409
|
</dialog>
|
|
385
410
|
|
|
411
|
+
<dialog id="system-restart-dialog" class="dialog system-restart-dialog" aria-labelledby="system-restart-dialog-title" aria-describedby="system-restart-dialog-description">
|
|
412
|
+
<div class="dialog-header">
|
|
413
|
+
<div><span class="eyebrow">系统状态</span><h2 id="system-restart-dialog-title" tabindex="-1">系统已重启或升级</h2></div>
|
|
414
|
+
</div>
|
|
415
|
+
<div class="dialog-fields">
|
|
416
|
+
<p id="system-restart-dialog-description" class="system-restart-message">本次登录已经失效,请重新登录。</p>
|
|
417
|
+
</div>
|
|
418
|
+
<div class="dialog-actions">
|
|
419
|
+
<button id="system-restart-confirm" class="primary-button" type="button">我知道了</button>
|
|
420
|
+
</div>
|
|
421
|
+
</dialog>
|
|
422
|
+
|
|
386
423
|
<dialog id="form-dialog" class="dialog">
|
|
387
424
|
<form id="dynamic-form" method="dialog">
|
|
388
425
|
<div class="dialog-header">
|
|
@@ -709,12 +746,6 @@
|
|
|
709
746
|
</form>
|
|
710
747
|
</dialog>
|
|
711
748
|
|
|
712
|
-
<dialog id="work-audit-dialog" class="dialog wide-dialog work-audit-dialog" aria-labelledby="work-audit-title">
|
|
713
|
-
<div class="dialog-header"><div><span class="eyebrow">作品安全</span><h2 id="work-audit-title">操作记录</h2><p class="dialog-header-meta">按时间倒序展示当前作品的写入与管理操作。</p></div><div class="settings-dialog-header-actions"><button id="work-audit-settings-return" class="ghost-button settings-parent-button" type="button">返回设置</button><button id="work-audit-close" class="dialog-close" aria-label="关闭操作记录" type="button">×</button></div></div>
|
|
714
|
-
<div id="work-audit-list" class="work-audit-list"></div>
|
|
715
|
-
<div class="dialog-actions"><button id="work-audit-refresh" class="ghost-button" type="button">刷新</button><button id="work-audit-load-more" class="primary-button hidden" type="button">加载更多</button></div>
|
|
716
|
-
</dialog>
|
|
717
|
-
|
|
718
749
|
<dialog id="platform-ui-settings-dialog" class="dialog" aria-labelledby="platform-ui-settings-title">
|
|
719
750
|
<div class="dialog-header"><div><span class="eyebrow">系统管理员</span><h2 id="platform-ui-settings-title">界面与分页</h2></div><div class="settings-dialog-header-actions"><button id="platform-ui-settings-return" class="ghost-button settings-parent-button" type="button">返回设置</button><button id="platform-ui-settings-close" class="dialog-close" aria-label="关闭" type="button">×</button></div></div>
|
|
720
751
|
<form id="platform-ui-settings-form">
|
|
@@ -842,7 +873,8 @@
|
|
|
842
873
|
<dl class="ai-tool-call-info">
|
|
843
874
|
<div><dt>函数名称</dt><dd><code id="ai-tool-call-name"></code></dd></div>
|
|
844
875
|
<div><dt>调用时间</dt><dd><time id="ai-tool-call-time"></time></dd></div>
|
|
845
|
-
<div
|
|
876
|
+
<div><dt>函数信息</dt><dd id="ai-tool-call-description"></dd></div>
|
|
877
|
+
<div><dt>返回字符数</dt><dd id="ai-tool-call-result-length"></dd></div>
|
|
846
878
|
</dl>
|
|
847
879
|
<section><h3>参数</h3><pre id="ai-tool-call-arguments"></pre></section>
|
|
848
880
|
<section><h3>返回值</h3><pre id="ai-tool-call-result"></pre></section>
|
|
@@ -895,6 +927,6 @@
|
|
|
895
927
|
<div id="auth-loading" class="auth-loading" role="status" aria-label="正在载入工作台"></div>
|
|
896
928
|
<script id="vditorIconScript" src="/vendor/vditor/dist/js/icons/ant.js?v=3.11.2"></script>
|
|
897
929
|
<script src="/vendor/vditor/dist/index.min.js?v=3.11.2"></script>
|
|
898
|
-
<script type="module" src="/app.js?v=
|
|
930
|
+
<script type="module" src="/app.js?v=20260801-merge-pr-291-v1"></script>
|
|
899
931
|
</body>
|
|
900
932
|
</html>
|
package/dist/public/markdown.js
CHANGED
|
@@ -17,7 +17,6 @@ function safeImageTarget(value) {
|
|
|
17
17
|
const target = String(value ?? "").trim();
|
|
18
18
|
const attachment = target.match(/^attachment:\/\/([A-Za-z0-9_-]{1,300})$/u);
|
|
19
19
|
if (attachment) return `/api/attachments/${encodeURIComponent(attachment[1])}/content`;
|
|
20
|
-
if (/^https:\/\//iu.test(target)) return target;
|
|
21
20
|
if (target.startsWith("/") && !target.startsWith("//")) return target;
|
|
22
21
|
return null;
|
|
23
22
|
}
|
|
@@ -67,7 +66,7 @@ function renderInlineMarkdown(value) {
|
|
|
67
66
|
source = replaceInlineCodeSpans(source, preserve);
|
|
68
67
|
source = source.replace(/!\[([^\]\n]*)\]\(([^)\s]+)\)/gu, (_match, label, src) => {
|
|
69
68
|
const target = safeImageTarget(src);
|
|
70
|
-
if (!target) return `[
|
|
69
|
+
if (!target) return `[外部图片已阻止:${label || "未命名图片"}]`;
|
|
71
70
|
const caption = String(label ?? "").trim();
|
|
72
71
|
return preserve(`<span class="markdown-image"><img src="${escapeHtml(target)}" alt="${escapeHtml(caption)}" loading="lazy" decoding="async">${caption ? `<small>${escapeHtml(caption)}</small>` : ""}</span>`);
|
|
73
72
|
});
|
|
@@ -53,7 +53,7 @@ export function serializePageRoute(route = {}) {
|
|
|
53
53
|
} else if (view === "welcome" && workId) {
|
|
54
54
|
params.set("view", "welcome");
|
|
55
55
|
params.set("work", workId);
|
|
56
|
-
} else if (view === "settings" || view === "platform-ai" || view === "platform-usage") {
|
|
56
|
+
} else if (view === "settings" || view === "platform-ai" || view === "platform-usage" || (view === "work-audit" && workId)) {
|
|
57
57
|
params.set("view", view);
|
|
58
58
|
if (workId) params.set("work", workId);
|
|
59
59
|
appendReturnContext(params, route);
|
|
@@ -87,7 +87,7 @@ export function parsePageRoute(hash = "") {
|
|
|
87
87
|
return { view, workId, entity, entityId: entityId || null, entityMode };
|
|
88
88
|
}
|
|
89
89
|
if (view === "welcome" && workId) return { view, workId };
|
|
90
|
-
if (view === "settings" || view === "platform-ai" || view === "platform-usage") {
|
|
90
|
+
if (view === "settings" || view === "platform-ai" || view === "platform-usage" || (view === "work-audit" && workId)) {
|
|
91
91
|
const route = { view, workId: workId || null };
|
|
92
92
|
const returnView = value(params, "from");
|
|
93
93
|
if (returnViewSet.has(returnView)) route.returnView = returnView;
|
package/dist/public/styles.css
CHANGED
|
@@ -81,6 +81,7 @@
|
|
|
81
81
|
[data-pending-view="settings"] .auth-pending #settings-hub-view.hidden,
|
|
82
82
|
[data-pending-view="platform-ai"] .auth-pending #platform-ai-view.hidden,
|
|
83
83
|
[data-pending-view="platform-usage"] .auth-pending #platform-usage-view.hidden,
|
|
84
|
+
[data-pending-view="work-audit"] .auth-pending #work-audit-view.hidden,
|
|
84
85
|
[data-pending-view="module"] .auth-pending #module-view.hidden { display: block !important; }
|
|
85
86
|
[data-pending-view="welcome"] .auth-pending #welcome-view.hidden,
|
|
86
87
|
[data-pending-view="editor"] .auth-pending #editor-view.hidden { display: grid !important; }
|
|
@@ -581,14 +582,41 @@ body.is-panel-resizing { cursor: col-resize; user-select: none; }
|
|
|
581
582
|
.writing-goal-fields label { display: grid; gap: 7px; color: var(--muted); font-size: 10px; font-weight: 650; }
|
|
582
583
|
.writing-goal-fields input { width: 100%; min-height: 38px; padding: 8px 10px; background: var(--surface); font-size: 12px; font-weight: 500; }
|
|
583
584
|
@media (max-width: 680px) { .writing-progress-stats { grid-template-columns: repeat(2, minmax(0, 1fr)); } .writing-goal-fields { grid-template-columns: 1fr; } }
|
|
584
|
-
.work-audit-
|
|
585
|
-
.work-audit-
|
|
586
|
-
.work-audit-
|
|
587
|
-
.work-audit-
|
|
588
|
-
.work-audit-
|
|
589
|
-
.work-audit-
|
|
590
|
-
.work-audit-
|
|
591
|
-
|
|
585
|
+
.work-audit-view { padding-bottom: 48px; }
|
|
586
|
+
.work-audit-header { margin-bottom: 22px; }
|
|
587
|
+
.work-audit-header h1 { font-size: clamp(30px, 4vw, 48px); }
|
|
588
|
+
.work-audit-toolbar, .work-audit-list, .work-audit-footer { width: 100%; max-width: 1400px; margin-inline: auto; }
|
|
589
|
+
.work-audit-toolbar { display: flex; align-items: center; min-height: 42px; padding: 0 18px; border: 1px solid var(--line); border-bottom: 0; border-radius: 7px 7px 0 0; background: var(--surface-soft); }
|
|
590
|
+
.work-audit-toolbar p { margin: 0; color: var(--muted); font-size: 12px; line-height: 1.5; }
|
|
591
|
+
.work-audit-list { display: grid; border: 1px solid var(--line); border-radius: 0 0 7px 7px; background: var(--panel); }
|
|
592
|
+
.work-audit-row { display: grid; grid-template-columns: minmax(160px, 190px) minmax(0, 1fr); gap: 24px; padding: 22px 20px; border-bottom: 1px solid var(--line); }
|
|
593
|
+
.work-audit-row:last-child { border-bottom: 0; }
|
|
594
|
+
.work-audit-time { min-width: 0; }
|
|
595
|
+
.work-audit-time time { display: grid; gap: 4px; color: var(--muted); font-family: var(--font-mono), monospace; font-variant-numeric: tabular-nums; }
|
|
596
|
+
.work-audit-time span { font-size: 13px; line-height: 1.35; }
|
|
597
|
+
.work-audit-time strong { color: var(--ink); font-size: 18px; font-weight: 600; line-height: 1.25; }
|
|
598
|
+
.work-audit-event { display: grid; min-width: 0; gap: 14px; }
|
|
599
|
+
.work-audit-event-heading { display: flex; align-items: baseline; flex-wrap: wrap; gap: 7px 12px; }
|
|
600
|
+
.work-audit-event-heading strong { color: var(--ink); font-size: 17px; font-weight: 650; line-height: 1.35; }
|
|
601
|
+
.work-audit-event-heading code { color: var(--muted); font: 11px/1.5 var(--font-mono), monospace; overflow-wrap: anywhere; }
|
|
602
|
+
.work-audit-meta, .work-audit-details { margin: 0; }
|
|
603
|
+
.work-audit-meta { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; }
|
|
604
|
+
.work-audit-meta > div, .work-audit-details > div { min-width: 0; }
|
|
605
|
+
.work-audit-meta > div { display: grid; gap: 4px; padding: 10px 12px; border: 1px solid var(--line); border-radius: 5px; background: var(--surface-soft); }
|
|
606
|
+
.work-audit-meta dt, .work-audit-details dt { color: var(--muted); font-size: 10px; font-weight: 650; line-height: 1.4; }
|
|
607
|
+
.work-audit-meta dd, .work-audit-details dd { margin: 0; overflow-wrap: anywhere; color: var(--ink); font-size: 12px; line-height: 1.55; }
|
|
608
|
+
.work-audit-meta code, .work-audit-details code { font-family: var(--font-mono), monospace; font-size: 11px; }
|
|
609
|
+
.work-audit-details { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px 18px; padding: 14px 16px; border-left: 3px solid color-mix(in srgb, var(--accent) 55%, var(--line)); background: color-mix(in srgb, var(--accent) 4%, var(--surface-soft)); }
|
|
610
|
+
.work-audit-details > div { display: grid; grid-template-columns: minmax(88px, .35fr) minmax(0, 1fr); gap: 10px; }
|
|
611
|
+
.work-audit-footer { display: flex; justify-content: center; padding-top: 18px; }
|
|
612
|
+
.work-audit-footer button { min-width: 160px; }
|
|
613
|
+
.work-audit-list > .entity-history-empty { font-size: 13px; }
|
|
614
|
+
@media (max-width: 720px) {
|
|
615
|
+
.work-audit-row { grid-template-columns: 1fr; gap: 14px; padding: 18px 14px; }
|
|
616
|
+
.work-audit-time time { display: flex; align-items: baseline; gap: 8px; }
|
|
617
|
+
.work-audit-time strong { font-size: 16px; }
|
|
618
|
+
.work-audit-meta, .work-audit-details { grid-template-columns: 1fr; }
|
|
619
|
+
}
|
|
592
620
|
.settings-work-note { max-width: 1000px; margin: 18px auto 0; color: var(--muted); font-size: 11px; }
|
|
593
621
|
.usage-page-content { width: 100%; max-width: 1400px; margin: 0 auto; padding-top: 0; }
|
|
594
622
|
.usage-overview { min-width: 0; container-name: usage-overview; container-type: inline-size; }
|
|
@@ -613,6 +641,7 @@ body.is-panel-resizing { cursor: col-resize; user-select: none; }
|
|
|
613
641
|
.usage-calendar-section > header, .usage-work-section > header { display: flex; align-items: end; justify-content: space-between; gap: 18px; margin-bottom: 14px; }
|
|
614
642
|
.usage-calendar-section h3, .usage-work-section h3 { margin: 0 0 4px; font-size: 15px; font-weight: 650; }
|
|
615
643
|
.usage-calendar-section header p, .usage-work-section header p { margin: 0; color: var(--muted); font-size: 10px; }
|
|
644
|
+
.usage-calendar-widget { position: relative; }
|
|
616
645
|
.usage-calendar-scroll { max-width: 100%; padding: 10px 12px 12px; overflow-x: auto; border: 1px solid var(--line); border-radius: 6px; background: var(--surface); }
|
|
617
646
|
.usage-calendar-scroll:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
|
|
618
647
|
.usage-calendar-frame { width: max-content; min-width: 100%; }
|
|
@@ -640,13 +669,16 @@ body.is-panel-resizing { cursor: col-resize; user-select: none; }
|
|
|
640
669
|
gap: 3px;
|
|
641
670
|
min-width: calc(var(--usage-week-count) * 14px);
|
|
642
671
|
}
|
|
643
|
-
.usage-calendar-cell { display: block; width: 11px; height: 11px; border: 1px solid color-mix(in srgb, var(--line) 82%, transparent); border-radius: 2px; background: var(--paper-deep); }
|
|
672
|
+
.usage-calendar-cell { display: block; width: 11px; height: 11px; padding: 0; border: 1px solid color-mix(in srgb, var(--line) 82%, transparent); border-radius: 2px; background: var(--paper-deep); cursor: pointer; }
|
|
644
673
|
.usage-calendar-cell[data-level="1"], .usage-calendar-legend i[data-level="1"] { border-color: color-mix(in srgb, var(--accent) 25%, var(--line)); background: color-mix(in srgb, var(--accent) 18%, var(--surface)); }
|
|
645
674
|
.usage-calendar-cell[data-level="2"], .usage-calendar-legend i[data-level="2"] { border-color: color-mix(in srgb, var(--accent) 46%, var(--line)); background: color-mix(in srgb, var(--accent) 42%, var(--surface)); }
|
|
646
675
|
.usage-calendar-cell[data-level="3"], .usage-calendar-legend i[data-level="3"] { border-color: color-mix(in srgb, var(--accent) 72%, var(--line)); background: color-mix(in srgb, var(--accent) 70%, var(--surface)); }
|
|
647
676
|
.usage-calendar-cell[data-level="4"], .usage-calendar-legend i[data-level="4"] { border-color: var(--accent-dark); background: var(--accent-dark); }
|
|
648
|
-
.usage-calendar-cell.is-future { border-color: transparent; background: transparent; }
|
|
649
|
-
.usage-calendar-cell
|
|
677
|
+
.usage-calendar-cell.is-future { border-color: transparent; background: transparent; cursor: default; }
|
|
678
|
+
.usage-calendar-cell:hover, .usage-calendar-cell:focus-visible { position: relative; z-index: 1; border-color: var(--ink); outline: 2px solid color-mix(in srgb, var(--ink) 48%, transparent); outline-offset: 1px; }
|
|
679
|
+
.usage-calendar-tooltip { position: absolute; z-index: 4; width: max-content; max-width: min(280px, calc(100% - 16px)); padding: 7px 9px; border: 1px solid color-mix(in srgb, var(--ink) 24%, transparent); border-radius: 5px; background: color-mix(in srgb, var(--ink) 94%, transparent); box-shadow: 0 8px 22px rgba(0,0,0,.22); color: var(--panel); font: 10px/1.45 var(--font-latin), var(--font-cjk), monospace; overflow-wrap: anywhere; text-align: center; pointer-events: none; transform: translate(-50%, -100%); }
|
|
680
|
+
.usage-calendar-tooltip[data-placement="bottom"] { transform: translateX(-50%); }
|
|
681
|
+
.usage-calendar-tooltip[hidden] { display: none; }
|
|
650
682
|
.usage-calendar-legend { display: flex; align-items: center; justify-content: flex-end; gap: 4px; margin-top: 8px; color: var(--muted); font-size: 9px; }
|
|
651
683
|
.usage-calendar-legend i { width: 11px; height: 11px; border: 1px solid color-mix(in srgb, var(--line) 82%, transparent); border-radius: 2px; background: var(--paper-deep); }
|
|
652
684
|
.usage-work-table-scroll { max-width: 100%; overflow-x: auto; border: 1px solid var(--line); border-radius: 6px; }
|
|
@@ -1275,10 +1307,12 @@ select:focus, input:focus, textarea:focus { border-color: #a77768; box-shadow: 0
|
|
|
1275
1307
|
.character-filter-toolbar-actions { display: flex; align-items: center; justify-content: flex-end; gap: 12px; min-height: 38px; }
|
|
1276
1308
|
.character-filter-result-count { color: var(--muted); font-size: 11px; white-space: nowrap; }
|
|
1277
1309
|
.character-filter-toolbar-actions button:disabled { cursor: default; opacity: .45; }
|
|
1278
|
-
.draft-filter-toolbar {
|
|
1279
|
-
.draft-filter-
|
|
1280
|
-
.draft-filter-
|
|
1281
|
-
.draft-filter-
|
|
1310
|
+
.draft-filter-toolbar { grid-template-columns: minmax(180px, .72fr) minmax(240px, 1fr) auto; }
|
|
1311
|
+
.draft-type-filter-field { display: grid; min-width: 0; }
|
|
1312
|
+
.draft-type-filter-field > span { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
|
|
1313
|
+
.draft-type-filter-field select { width: 100%; min-width: 0; min-height: 38px; padding: 8px 10px; background: var(--surface); color: var(--ink); font-size: 11px; }
|
|
1314
|
+
.draft-binding-field { min-width: 0; }
|
|
1315
|
+
.draft-binding-field > label { display: grid; gap: 7px; }
|
|
1282
1316
|
.character-card:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
|
|
1283
1317
|
.character-duplicate-review { grid-column: 1 / -1; }
|
|
1284
1318
|
.character-duplicate-pair { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; margin: 14px 0; }
|
|
@@ -1292,7 +1326,7 @@ select:focus, input:focus, textarea:focus { border-color: #a77768; box-shadow: 0
|
|
|
1292
1326
|
.character-duplicate-actions { flex-wrap: wrap; }
|
|
1293
1327
|
.card-actions { display: flex; gap: 6px; margin-top: 15px; }
|
|
1294
1328
|
.card-actions button { border: 1px solid var(--line); background: transparent; border-radius: 3px; font-size: 10px; padding: 5px 8px; }
|
|
1295
|
-
.card-actions .record-card-edit { padding: 0; }
|
|
1329
|
+
.card-actions .record-card-edit { position: static; padding: 0; }
|
|
1296
1330
|
.danger-button { border: 1px solid color-mix(in srgb, var(--accent) 52%, var(--line)); border-radius: 4px; background: transparent; color: var(--accent-dark); padding: 8px 13px; font-size: 12px; }
|
|
1297
1331
|
.danger-button:hover, .danger-button:focus-visible { border-color: var(--accent); background: color-mix(in srgb, var(--accent) 9%, transparent); outline: none; }
|
|
1298
1332
|
.card-actions .danger-button { border-color: color-mix(in srgb, var(--accent) 52%, var(--line)); color: var(--accent-dark); }
|
|
@@ -1676,6 +1710,15 @@ select:focus, input:focus, textarea:focus { border-color: #a77768; box-shadow: 0
|
|
|
1676
1710
|
.config-section-header { display: flex; align-items: flex-end; justify-content: space-between; margin-bottom: 14px; }
|
|
1677
1711
|
.config-section-header h2 { margin: 0 0 6px; font-size: 18px; font-weight: 600; }
|
|
1678
1712
|
.config-section-header p { margin: 0; color: var(--muted); font-size: 11px; }
|
|
1713
|
+
.config-section-header .config-doc-link {
|
|
1714
|
+
display: inline;
|
|
1715
|
+
margin-left: 4px;
|
|
1716
|
+
color: var(--accent-dark);
|
|
1717
|
+
text-decoration: underline;
|
|
1718
|
+
text-underline-offset: 2px;
|
|
1719
|
+
}
|
|
1720
|
+
.config-section-header .config-doc-link:hover,
|
|
1721
|
+
.config-section-header .config-doc-link:focus-visible { color: var(--accent); }
|
|
1679
1722
|
.ai-agent-tools { display: grid; gap: 8px; }
|
|
1680
1723
|
.ai-agent-tools label { display: grid; grid-template-columns: 18px minmax(0, 1fr); gap: 8px; align-items: start; color: var(--muted); font-size: 11px; line-height: 1.45; }
|
|
1681
1724
|
.ai-agent-tools input { width: 16px; margin-top: 2px; }
|
|
@@ -1997,6 +2040,7 @@ select:focus, input:focus, textarea:focus { border-color: #a77768; box-shadow: 0
|
|
|
1997
2040
|
.ai-heading-actions #ai-new-conversation { padding: 0; font: 17px/1 var(--font-latin), monospace; }
|
|
1998
2041
|
.ai-heading-actions button:hover, .ai-heading-actions button[aria-expanded="true"] { background: var(--paper-deep); color: var(--ink); }
|
|
1999
2042
|
.status-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--green); box-shadow: 0 0 0 3px rgba(94,118,92,.14); }
|
|
2043
|
+
.status-dot.is-error { background: var(--accent); box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 18%, transparent); }
|
|
2000
2044
|
.ai-history-dialog-body { min-height: min(360px, 55vh); max-height: 65vh; overflow-y: auto; padding: 18px 24px 24px; }
|
|
2001
2045
|
.ai-history-list { display: grid; gap: 8px; }
|
|
2002
2046
|
.ai-history-item { display: grid; gap: 5px; width: 100%; min-width: 0; padding: 14px 16px; border: 1px solid var(--line); border-radius: 5px; background: var(--surface-soft); text-align: left; }
|
|
@@ -2009,10 +2053,19 @@ select:focus, input:focus, textarea:focus { border-color: #a77768; box-shadow: 0
|
|
|
2009
2053
|
.field-label select { padding: 8px; font-size: 12px; }
|
|
2010
2054
|
.book-summary-context-percent-field { width: min(100%, 280px); }
|
|
2011
2055
|
.context-compact-threshold-field { width: min(100%, 280px); }
|
|
2012
|
-
.
|
|
2056
|
+
.agent-tool-call-limit-field { width: min(100%, 280px); }
|
|
2057
|
+
.daily-token-quota-field { width: min(100%, 144px); }
|
|
2058
|
+
.agent-tool-call-global-multiplier-field { width: auto; min-width: 0; }
|
|
2059
|
+
.book-summary-context-percent-field input, .context-compact-threshold-field input, .agent-tool-call-limit-field input, .daily-token-quota-field input { width: 64px; min-height: 32px; padding: 5px 8px; font-size: 13px; font-family: var(--font-latin), monospace; }
|
|
2060
|
+
.daily-token-quota-field input { width: 144px; }
|
|
2013
2061
|
.config-inline-save { display: flex; align-items: flex-end; gap: 10px; margin: 14px 0 4px; flex-wrap: wrap; }
|
|
2014
2062
|
.config-inline-save .book-summary-context-percent-field,
|
|
2015
|
-
.config-inline-save .context-compact-threshold-field
|
|
2063
|
+
.config-inline-save .context-compact-threshold-field,
|
|
2064
|
+
.config-inline-save .agent-tool-call-limit-field,
|
|
2065
|
+
.config-inline-save .daily-token-quota-field { display: grid; gap: 6px; width: 64px; margin: 0; color: var(--muted); font-size: 10px; }
|
|
2066
|
+
.config-inline-save .daily-token-quota-field { width: 144px; }
|
|
2067
|
+
.config-inline-save .agent-tool-call-global-multiplier-field { display: grid; gap: 6px; width: auto; margin: 0; color: var(--muted); font-size: 10px; }
|
|
2068
|
+
.agent-tool-call-global-multiplier-toggle button { min-width: 32px; padding: 0 10px; font-family: var(--font-latin), monospace; font-size: 12px; font-variant-numeric: tabular-nums; }
|
|
2016
2069
|
.relationship-index-summary { display: grid; gap: 14px; padding: 15px; border: 1px solid var(--line); border-radius: 6px; background: var(--surface-soft); }
|
|
2017
2070
|
.relationship-index-state-row { display: flex; align-items: center; gap: 12px 18px; flex-wrap: wrap; color: var(--muted); font-size: 10px; }
|
|
2018
2071
|
.relationship-index-state-row strong { color: var(--ink); font-family: var(--font-latin), monospace; font-weight: 600; }
|
|
@@ -2050,7 +2103,9 @@ select:focus, input:focus, textarea:focus { border-color: #a77768; box-shadow: 0
|
|
|
2050
2103
|
.quick-actions button { min-width: 0; min-height: 30px; border: 1px solid var(--line); background: transparent; border-radius: 3px; padding: 5px 3px; color: var(--muted); font-size: 10px; white-space: nowrap; }
|
|
2051
2104
|
.quick-actions button:hover { color: var(--ink); background: var(--paper-deep); }
|
|
2052
2105
|
.ai-feed { flex: 1; min-height: 0; overflow-y: auto; margin: 10px -5px 12px; padding: 0 5px; }
|
|
2053
|
-
.ai-context-compaction-divider { display: grid; grid-template-columns: minmax(16px, 1fr) auto minmax(16px, 1fr); gap: 9px; align-items: center;
|
|
2106
|
+
.ai-context-compaction-divider { display: grid; grid-template-columns: minmax(16px, 1fr) auto minmax(16px, 1fr); gap: 9px; align-items: center; min-width: 0; color: var(--muted); font-size: 9px; line-height: 1; text-align: center; }
|
|
2107
|
+
.ai-feed > .ai-context-compaction-divider { margin: 4px 0 16px; }
|
|
2108
|
+
.ai-process-list > .ai-context-compaction-divider { padding: 2px 0; }
|
|
2054
2109
|
.ai-context-compaction-divider::before, .ai-context-compaction-divider::after { height: 1px; background: color-mix(in srgb, var(--muted) 36%, transparent); content: ""; }
|
|
2055
2110
|
.ai-context-compaction-divider span { letter-spacing: .08em; white-space: nowrap; }
|
|
2056
2111
|
.assistant-message, .user-message { position: relative; margin-bottom: 12px; padding: 12px 13px; border-radius: 5px; font-size: 12px; line-height: 1.55; }
|
|
@@ -2114,9 +2169,6 @@ select:focus, input:focus, textarea:focus { border-color: #a77768; box-shadow: 0
|
|
|
2114
2169
|
.ai-process-step-body { max-height: 220px; overflow: auto; padding: 8px 9px; border-left: 2px solid color-mix(in srgb, var(--accent) 46%, var(--line)); background: var(--paper-deep); color: var(--muted); font-size: 10px; }
|
|
2115
2170
|
.ai-process-intermediate-step .ai-process-step-body { border-left-color: var(--muted); }
|
|
2116
2171
|
.ai-process-tool-step { padding-top: 1px; }
|
|
2117
|
-
.ai-process-context-compaction { display: grid; grid-template-columns: minmax(12px, 1fr) auto minmax(12px, 1fr); gap: 8px; align-items: center; min-width: 0; padding: 2px 0; color: var(--muted); font-size: 8px; line-height: 1; text-align: center; }
|
|
2118
|
-
.ai-process-context-compaction::before, .ai-process-context-compaction::after { height: 1px; background: color-mix(in srgb, var(--muted) 38%, transparent); content: ""; }
|
|
2119
|
-
.ai-process-context-compaction span { letter-spacing: .08em; white-space: nowrap; }
|
|
2120
2172
|
@keyframes ai-process-pulse { 0%, 100% { opacity: .45; transform: scale(.8); } 50% { opacity: 1; transform: scale(1); } }
|
|
2121
2173
|
@media (prefers-reduced-motion: reduce) { .is-streaming .ai-process-details[open] > summary::before { animation: none; } }
|
|
2122
2174
|
.ai-tool-call-list { display: grid; gap: 5px; margin-top: 10px; }
|
|
@@ -2131,12 +2183,11 @@ select:focus, input:focus, textarea:focus { border-color: #a77768; box-shadow: 0
|
|
|
2131
2183
|
.ai-tool-call-info dt { margin-bottom: 4px; color: var(--muted); font-size: 9px; }
|
|
2132
2184
|
.ai-tool-call-info dd { min-width: 0; margin: 0; color: var(--ink); font-size: 11px; line-height: 1.5; overflow-wrap: anywhere; }
|
|
2133
2185
|
.ai-tool-call-info code, .ai-tool-call-info time { font-family: var(--font-latin), monospace; }
|
|
2134
|
-
.ai-tool-call-description { grid-column: 1 / -1; }
|
|
2135
2186
|
.ai-tool-call-detail section { min-width: 0; }
|
|
2136
2187
|
.ai-tool-call-detail h3 { margin: 0 0 7px; color: var(--muted); font-size: 10px; font-weight: 600; }
|
|
2137
2188
|
.ai-tool-call-detail pre { min-height: 120px; max-height: 32vh; overflow: auto; margin: 0; padding: 12px; border: 1px solid var(--line); border-radius: 5px; background: var(--paper-deep); color: var(--ink); font: 10px/1.55 var(--font-latin), monospace; white-space: pre-wrap; word-break: break-word; }
|
|
2138
2189
|
.ai-tool-call-detail section:last-child pre { min-height: 180px; }
|
|
2139
|
-
@media (max-width: 680px) { .ai-tool-call-info { grid-template-columns: minmax(0, 1fr); }.ai-tool-call-
|
|
2190
|
+
@media (max-width: 680px) { .ai-tool-call-info { grid-template-columns: minmax(0, 1fr); }.ai-tool-call-detail pre { min-height: 100px; max-height: 26vh; }.ai-tool-call-detail section:last-child pre { min-height: 140px; } }
|
|
2140
2191
|
.guard-card { margin-top: 10px; padding: 9px 10px; border: 1px solid var(--line); border-left: 3px solid var(--green); border-radius: 4px; background: var(--surface-soft); }
|
|
2141
2192
|
.guard-card.warning { border-left-color: #c07b31; }.guard-card.failed { border-left-color: var(--accent); }
|
|
2142
2193
|
.guard-card strong { display: block; margin-bottom: 5px; font-size: 10px; }.guard-card p { margin: 4px 0; color: var(--muted); font-size: 9px; line-height: 1.45; }.guard-card p b { color: var(--ink); }
|
|
@@ -2308,6 +2359,13 @@ select:focus, input:focus, textarea:focus { border-color: #a77768; box-shadow: 0
|
|
|
2308
2359
|
.markdown-table-menu button:hover, .markdown-table-menu button:focus-visible { background: var(--paper-deep); color: var(--accent-dark); }
|
|
2309
2360
|
.markdown-table-menu button span { font-size: 11px; font-weight: 600; }
|
|
2310
2361
|
.markdown-table-menu button small { color: var(--muted); font-size: 9px; }
|
|
2362
|
+
.manuscript-export-menu { position: fixed; z-index: 90; display: grid; min-width: 240px; gap: 3px; padding: 8px; border: 1px solid var(--line); border-radius: 6px; background: var(--panel); box-shadow: 0 14px 38px rgba(49,42,32,.22); }
|
|
2363
|
+
.manuscript-export-menu.hidden { display: none; }
|
|
2364
|
+
.manuscript-export-menu > strong { padding: 5px 8px 7px; color: var(--muted); font-size: 9px; }
|
|
2365
|
+
.manuscript-export-menu button { display: grid; width: 100%; gap: 2px; padding: 8px 9px; border: 0; border-radius: 4px; background: transparent; color: var(--ink); text-align: left; }
|
|
2366
|
+
.manuscript-export-menu button:hover, .manuscript-export-menu button:focus-visible { background: var(--paper-deep); color: var(--accent-dark); outline: 0; }
|
|
2367
|
+
.manuscript-export-menu button span { font-size: 11px; font-weight: 600; }
|
|
2368
|
+
.manuscript-export-menu button small { color: var(--muted); font-size: 9px; line-height: 1.45; }
|
|
2311
2369
|
.chapter-annotations-dialog { width: min(820px, 94vw); }
|
|
2312
2370
|
.chapter-annotations-list { display: grid; gap: 10px; max-height: 62vh; overflow: auto; padding: 18px 24px; }
|
|
2313
2371
|
.chapter-comment-module-list { display: grid; gap: 10px; }
|
|
@@ -2364,6 +2422,8 @@ select:focus, input:focus, textarea:focus { border-color: #a77768; box-shadow: 0
|
|
|
2364
2422
|
.dialog-fields label { display: grid; gap: 6px; color: var(--muted); font-size: 11px; }
|
|
2365
2423
|
.dialog-fields input, .dialog-fields textarea, .dialog-fields select { width: 100%; padding: 9px 10px; font-size: 13px; }
|
|
2366
2424
|
.dialog-fields textarea { resize: vertical; min-height: 90px; line-height: 1.6; }
|
|
2425
|
+
.system-restart-dialog { width: min(500px, 92vw); }
|
|
2426
|
+
.system-restart-message { margin: 0; color: var(--ink); font-size: 13px; line-height: 1.7; }
|
|
2367
2427
|
.background-task-dialog { width: min(860px, 94vw); }
|
|
2368
2428
|
.background-task-content { display: grid; gap: 16px; max-height: 64vh; overflow-y: auto; padding: 20px 24px; }
|
|
2369
2429
|
.background-task-section { display: grid; gap: 12px; min-width: 0; padding: 15px; border: 1px solid var(--line); border-radius: 6px; background: var(--surface-soft); }
|
|
@@ -2558,9 +2618,7 @@ select:focus, input:focus, textarea:focus { border-color: #a77768; box-shadow: 0
|
|
|
2558
2618
|
.import-mode-dialog .dialog-actions { flex-wrap: wrap; }
|
|
2559
2619
|
.character-filter-toolbar { grid-template-columns: minmax(0, 1fr); }
|
|
2560
2620
|
.character-filter-toolbar-actions { justify-content: flex-start; }
|
|
2561
|
-
.draft-filter-toolbar {
|
|
2562
|
-
.draft-filter-toolbar select { width: 100%; min-width: 0; }
|
|
2563
|
-
.draft-filter-toolbar span { margin-left: 0; }
|
|
2621
|
+
.draft-filter-toolbar { grid-template-columns: minmax(0, 1fr); }
|
|
2564
2622
|
}
|
|
2565
2623
|
.entity-editor-open { overflow: hidden; }
|
|
2566
2624
|
.preview-record-card { cursor: pointer; }
|
|
@@ -3067,8 +3125,8 @@ select:focus, input:focus, textarea:focus { border-color: #a77768; box-shadow: 0
|
|
|
3067
3125
|
.welcome-grid { grid-template-columns: 1fr; margin-top: 34px; }
|
|
3068
3126
|
|
|
3069
3127
|
.editor-toolbar { padding: 18px var(--mobile-gutter) 14px; }
|
|
3070
|
-
.editor-actions { position: fixed; z-index: 34; right: 0; bottom:
|
|
3071
|
-
.app-shell.left-panel-collapsed .editor-actions { transform: translateX(
|
|
3128
|
+
.editor-actions { position: fixed; z-index: 34; right: 0; bottom: calc(76px + env(safe-area-inset-bottom)); left: auto; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); width: min(300px, 84vw); max-width: none; gap: 6px; padding: 10px; border: 1px solid var(--line); border-right: 0; border-radius: 6px 0 0 6px; background: var(--panel); box-shadow: -12px 0 36px rgba(36, 30, 24, .2); transform: translateX(0); transition: transform .2s ease; }
|
|
3129
|
+
.app-shell.left-panel-collapsed .editor-actions { transform: translateX(0); pointer-events: auto; }
|
|
3072
3130
|
.editor-actions .chapter-stats { grid-column: 1 / -1; }
|
|
3073
3131
|
.editor-actions > button { min-width: 0; min-height: 36px; padding-inline: 8px; font-size: 11px; }
|
|
3074
3132
|
.chapter-title { font-size: 23px; }
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export type SystemHealthStatus = "checking" | "ready" | "degraded" | "offline";
|
|
2
|
+
|
|
3
|
+
export type SystemStatusPresentation = {
|
|
4
|
+
label: string;
|
|
5
|
+
tone: "ok" | "pending" | "error";
|
|
6
|
+
title: string;
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export function systemStatusPresentation(snapshot?: {
|
|
10
|
+
status?: SystemHealthStatus | string;
|
|
11
|
+
version?: string;
|
|
12
|
+
}): SystemStatusPresentation;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
const supportedSystemStatuses = new Set(["checking", "ready", "degraded", "offline"]);
|
|
2
|
+
|
|
3
|
+
export function systemStatusPresentation(snapshot = {}) {
|
|
4
|
+
const status = supportedSystemStatuses.has(snapshot.status) ? snapshot.status : "checking";
|
|
5
|
+
const version = String(snapshot.version ?? "").trim();
|
|
6
|
+
if (status === "ready") {
|
|
7
|
+
return {
|
|
8
|
+
label: "就绪",
|
|
9
|
+
tone: "ok",
|
|
10
|
+
title: version ? `服务连接正常 · v${version}` : "服务连接正常"
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
if (status === "degraded") return { label: "服务异常", tone: "error", title: "服务可访问,但请求出现异常" };
|
|
14
|
+
if (status === "offline") return { label: "连接中断", tone: "error", title: "无法连接到本地服务,系统将自动重试" };
|
|
15
|
+
return { label: "检测中", tone: "pending", title: "正在检查本地服务状态" };
|
|
16
|
+
}
|
|
@@ -14,9 +14,9 @@
|
|
|
14
14
|
// 会话恢复期间按目标路由预显示对应视图的骨架屏
|
|
15
15
|
const pendingView = ["editor", "module", "welcome"].includes(routeView) && routeParams.get("work")
|
|
16
16
|
? routeView
|
|
17
|
-
: ["settings", "platform-ai", "platform-usage"].includes(routeView) ? routeView : "shelf";
|
|
17
|
+
: ["settings", "platform-ai", "platform-usage", "work-audit"].includes(routeView) ? routeView : "shelf";
|
|
18
18
|
document.documentElement.dataset.pendingView = pendingView;
|
|
19
|
-
if (["shelf", "settings", "platform-ai", "platform-usage"].includes(pendingView)) {
|
|
19
|
+
if (["shelf", "settings", "platform-ai", "platform-usage", "work-audit"].includes(pendingView)) {
|
|
20
20
|
document.documentElement.classList.add("pending-shelf-mode");
|
|
21
21
|
}
|
|
22
22
|
}
|