@musnows/scriverse 0.4.2 → 0.4.4

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.
@@ -29,5 +29,5 @@ export function characterVersionSourceLabel(source) {
29
29
  race: "种族变更",
30
30
  organization: "组织变更",
31
31
  migration: "历史基线"
32
- })[String(source)] ?? String(source || "未知来源");
32
+ })[String(source)] ?? "其他来源";
33
33
  }
@@ -0,0 +1,16 @@
1
+ export function settingStatusLabel(value: unknown): string;
2
+ export function characterVisibilityLabel(value: unknown): string;
3
+ export function timelineStatusLabel(value: unknown): string;
4
+ export function levelLabel(value: unknown): string;
5
+ export function foreshadowStatusLabel(value: unknown): string;
6
+ export function outlineStatusLabel(value: unknown): string;
7
+ export function relationshipCategoryLabel(value: unknown): string;
8
+ export function relationshipConfirmationLabel(value: unknown): string;
9
+ export function reviewItemTypeLabel(value: unknown): string;
10
+ export function reviewStatusLabel(value: unknown): string;
11
+ export function taskScopeLabel(value: unknown): string;
12
+ export function providerStatusLabel(value: unknown): string;
13
+ export function providerConnectionLabel(value: unknown): string;
14
+ export function chapterVersionSourceLabel(value: unknown): string;
15
+ export function occurrenceRoleLabel(value: unknown): string;
16
+ export function searchResultTypeLabel(value: unknown): string;
@@ -0,0 +1,81 @@
1
+ function enumLabel(labels, value, fallback) {
2
+ const normalized = String(value ?? "").trim();
3
+ if (Object.hasOwn(labels, normalized)) return labels[normalized];
4
+ if (!normalized || /^[a-z][a-z0-9_-]*$/iu.test(normalized)) return fallback;
5
+ return normalized;
6
+ }
7
+
8
+ export function settingStatusLabel(value) {
9
+ return enumLabel({ draft: "草稿", pending: "待确认", confirmed: "已确认", deprecated: "已弃用" }, value, "未知状态");
10
+ }
11
+
12
+ export function characterVisibilityLabel(value) {
13
+ return enumLabel({ public: "公开", author: "仅作者", collaborators: "协作者可见" }, value, "未知范围");
14
+ }
15
+
16
+ export function timelineStatusLabel(value) {
17
+ return enumLabel({ candidate: "候选", pending: "待确认", confirmed: "已确认", deprecated: "已弃用" }, value, "未知状态");
18
+ }
19
+
20
+ export function levelLabel(value) {
21
+ return enumLabel({ low: "低", medium: "中", high: "高" }, value, "未知等级");
22
+ }
23
+
24
+ export function foreshadowStatusLabel(value) {
25
+ return enumLabel({ planned: "计划中", planted: "已埋设", resolved: "已回收", abandoned: "已放弃" }, value, "未知状态");
26
+ }
27
+
28
+ export function outlineStatusLabel(value) {
29
+ return enumLabel({ draft: "草稿", ready: "可执行", completed: "已完成" }, value, "未知状态");
30
+ }
31
+
32
+ export function relationshipCategoryLabel(value) {
33
+ return enumLabel({ family: "亲属", social: "社交", emotional: "情感", conflict: "冲突", uncertain: "未确定" }, value, "其他关系");
34
+ }
35
+
36
+ export function relationshipConfirmationLabel(value) {
37
+ return enumLabel({ pending: "待确认", confirmed: "已确认", rejected: "已拒绝" }, value, "未知状态");
38
+ }
39
+
40
+ export function reviewItemTypeLabel(value) {
41
+ return enumLabel({
42
+ consistency: "一致性问题",
43
+ "character-duplicate": "角色重复",
44
+ "timeline-conflict": "时间线冲突",
45
+ "setting-conflict": "设定冲突",
46
+ "relationship-conflict": "关系冲突",
47
+ "character-conflict": "角色冲突",
48
+ "plot-hole": "剧情漏洞",
49
+ "low-confidence": "低置信度结论",
50
+ chronology: "时间顺序问题",
51
+ factual: "事实问题"
52
+ }, value, "其他审核问题");
53
+ }
54
+
55
+ export function reviewStatusLabel(value) {
56
+ return enumLabel({ pending: "待处理", ignored: "已忽略", fixing: "处理中", fixed: "已修复", exception: "例外保留" }, value, "未知状态");
57
+ }
58
+
59
+ export function taskScopeLabel(value) {
60
+ return enumLabel({ none: "无上下文", selection: "选中文本", chapter: "当前章节", volume: "当前分卷", book: "全书", entities: "指定资料" }, value, "未指定范围");
61
+ }
62
+
63
+ export function providerStatusLabel(value) {
64
+ return enumLabel({ enabled: "已启用", disabled: "已停用", error: "异常" }, value, "未知状态");
65
+ }
66
+
67
+ export function providerConnectionLabel(value) {
68
+ return enumLabel({ unchecked: "未测试", success: "连接正常", failed: "连接失败" }, value, "未知连接状态");
69
+ }
70
+
71
+ export function chapterVersionSourceLabel(value) {
72
+ return enumLabel({ manual: "人工保存", auto: "自动保存", "ai-suggestion": "AI 建议", restore: "历史恢复", import: "文件导入", create: "初始版本" }, value, "其他来源");
73
+ }
74
+
75
+ export function occurrenceRoleLabel(value) {
76
+ return enumLabel({ setup: "埋设", reminder: "提醒", payoff: "回收" }, value, "其他节点");
77
+ }
78
+
79
+ export function searchResultTypeLabel(value) {
80
+ return enumLabel({ chapter: "章节", setting: "设定", character: "角色", race: "种族", organization: "组织" }, value, "其他资料");
81
+ }
@@ -1,3 +1,5 @@
1
+ import { levelLabel, relationshipCategoryLabel } from "./display-labels.js?v=20260725-enum-labels-zh";
2
+
1
3
  export const VERSIONED_ENTITY_LABELS = Object.freeze({
2
4
  setting: "世界观设定",
3
5
  race: "种族档案",
@@ -18,7 +20,7 @@ export function entityVersionSourceLabel(source) {
18
20
  analysis: "AI 分析",
19
21
  merge: "事件合并",
20
22
  split: "事件拆分"
21
- })[source] ?? source;
23
+ })[source] ?? "其他来源";
22
24
  }
23
25
 
24
26
  export function entityVersionSnapshotSummary(type, snapshot = {}) {
@@ -27,8 +29,8 @@ export function entityVersionSnapshotSummary(type, snapshot = {}) {
27
29
  if (type === "organization") return `${snapshot.name || "未命名组织"} · ${(snapshot.memberIds ?? []).length} 位成员`;
28
30
  if (type === "timeline-track") return `${snapshot.name || "未命名时间轴"} · 排序 ${snapshot.sortOrder ?? 0}`;
29
31
  if (type === "timeline-event") return `${snapshot.timeLabel || "时间待定"} · ${snapshot.name || "未命名事件"}`;
30
- if (type === "relationship") return `${snapshot.category || "未分类"} / ${snapshot.subtype || "未细分"} · ${Math.round(Number(snapshot.confidence ?? 0) * 100)}%`;
32
+ if (type === "relationship") return `${relationshipCategoryLabel(snapshot.category)} / ${snapshot.subtype || "未细分"} · ${Math.round(Number(snapshot.confidence ?? 0) * 100)}%`;
31
33
  if (type === "chapter-outline") return `目标:${snapshot.goal || "未填写"}`;
32
- if (type === "foreshadow") return `${snapshot.importance || "medium"} · ${snapshot.title || "未命名伏笔"}`;
34
+ if (type === "foreshadow") return `${levelLabel(snapshot.importance || "medium")} · ${snapshot.title || "未命名伏笔"}`;
33
35
  return "历史快照";
34
36
  }
@@ -10,7 +10,7 @@
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=20260724-account-menu-identity">
13
+ <link rel="stylesheet" href="/styles.css?v=20260725-ui-mobile-drawer-logo">
14
14
  </head>
15
15
  <body class="auth-pending">
16
16
  <section id="auth-view" class="auth-view hidden" aria-labelledby="auth-title">
@@ -70,9 +70,17 @@
70
70
  <small>小说 AI 创作工作台</small>
71
71
  </div>
72
72
  </button>
73
+ <button id="mobile-module-tab" class="mobile-module-tab" type="button" aria-label="打开作品模块" aria-expanded="false">模块</button>
73
74
  <div id="work-meta" class="work-meta">尚未选择作品</div>
74
75
  <div class="top-actions">
75
76
  <span id="save-state" class="save-state">就绪</span>
77
+ <div id="presence-control" class="presence-control hidden">
78
+ <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
+ <section id="presence-panel" class="presence-panel hidden" aria-label="当前作品在线协作者">
80
+ <header><strong>正在访问这部作品</strong><small>离开后状态会自动过期</small></header>
81
+ <div id="presence-list" class="presence-list" aria-live="polite"></div>
82
+ </section>
83
+ </div>
76
84
  <button id="account-button" class="account-button" type="button" aria-haspopup="menu" aria-expanded="false"><span id="account-avatar" class="user-avatar account-avatar" aria-hidden="true"><span class="user-avatar-fallback">作</span></span><span id="account-name">账户</span></button>
77
85
  <div id="account-menu" class="account-menu hidden" role="menu">
78
86
  <strong id="account-menu-name" class="account-menu-name"><span id="account-menu-display-name">账户</span><span id="account-menu-username" class="account-menu-username">@account</span></strong><small id="account-menu-role">普通用户</small>
@@ -93,6 +101,8 @@
93
101
  </div>
94
102
  </header>
95
103
 
104
+ <button id="mobile-panel-backdrop" class="mobile-panel-backdrop" type="button" aria-label="关闭作品模块侧栏"></button>
105
+
96
106
  <aside class="left-panel">
97
107
  <div id="left-panel-resize" class="panel-resize-handle" role="separator" aria-label="调整作品侧栏宽度" aria-orientation="vertical" tabindex="0"></div>
98
108
  <div class="left-actions">
@@ -321,7 +331,7 @@
321
331
  <dialog id="form-dialog" class="dialog">
322
332
  <form id="dynamic-form" method="dialog">
323
333
  <div class="dialog-header">
324
- <div><span id="dialog-eyebrow" class="eyebrow">新增</span><h2 id="dialog-title">创建记录</h2></div>
334
+ <div><span id="dialog-eyebrow" class="eyebrow">新增</span><h2 id="dialog-title">创建记录</h2><p id="dialog-meta" class="dialog-header-meta hidden"></p></div>
325
335
  <button class="dialog-close" value="cancel" aria-label="关闭" type="submit">×</button>
326
336
  </div>
327
337
  <div id="dialog-fields" class="dialog-fields"></div>
@@ -365,23 +375,25 @@
365
375
  <header class="entity-editor-header setting-editor-header">
366
376
  <button id="setting-editor-back" class="entity-editor-back" type="button">返回设定库</button>
367
377
  <div class="entity-editor-heading">
368
- <span id="setting-editor-eyebrow" class="eyebrow">作者事实</span>
378
+ <span id="setting-editor-eyebrow" class="eyebrow">新建设定</span>
369
379
  <input id="setting-editor-name" class="setting-editor-title-input" name="title" maxlength="200" placeholder="新建设定" aria-label="设定标题">
370
380
  <div class="setting-editor-header-fields">
371
381
  <label>分类<select id="setting-editor-category" name="category">
372
382
  <option value="世界规则">世界规则</option><option value="历史与年代">历史与年代</option><option value="地点与地图">地点与地图</option><option value="组织与阵营">组织与阵营</option><option value="物种与族群">物种与族群</option><option value="科技与物品">科技与物品</option><option value="术语与称谓">术语与称谓</option><option value="创作约束">创作约束</option>
373
383
  </select></label>
374
384
  <label class="setting-editor-lock"><input id="setting-editor-locked" name="locked" type="checkbox"><span><b>锁定为 AI 硬约束</b><small>锁定后,AI 续写与校对不能擅自覆盖这条设定。</small></span></label>
375
- <label id="setting-change-note-field" class="setting-editor-change-note">版本说明<input id="setting-change-note" name="changeNote" maxlength="500" placeholder="可选,例如:补充纪元历法限制"></label>
376
385
  </div>
377
386
  </div>
378
- <button id="setting-editor-submit" class="primary-button" type="submit">保存设定</button>
387
+ <div class="entity-editor-mode-actions">
388
+ <button id="setting-editor-edit" class="ghost-button hidden" type="button">编辑设定</button>
389
+ <button id="setting-editor-confirm" class="ghost-button hidden" type="button">确认候选</button>
390
+ <button id="setting-editor-deprecate" class="ghost-button hidden" type="button">弃用</button>
391
+ <button id="setting-editor-history" class="ghost-button hidden" type="button">版本历史</button>
392
+ <button id="setting-editor-delete" class="danger-button hidden" type="button">删除设定</button>
393
+ <button id="setting-editor-submit" class="primary-button" type="submit">保存设定</button>
394
+ </div>
379
395
  </header>
380
396
  <div class="setting-editor-workspace">
381
- <section id="setting-editor-management" class="entity-editor-management hidden" aria-label="设定档案操作">
382
- <div><strong>档案操作</strong><small>版本历史和高风险操作集中在编辑面板内。</small></div>
383
- <div class="entity-editor-management-actions"><button id="setting-editor-confirm" class="ghost-button hidden" type="button">确认候选</button><button id="setting-editor-deprecate" class="ghost-button hidden" type="button">弃用</button><button id="setting-editor-history" class="ghost-button" type="button">版本历史</button><button id="setting-editor-delete" class="danger-button" type="button">删除设定</button></div>
384
- </section>
385
397
  <main class="setting-editor-content">
386
398
  <div class="setting-markdown-field" data-vditor-editor-field>
387
399
  <div id="setting-editor-markdown" class="vditor-editor-host" data-vditor-editor aria-label="Markdown 编辑器"></div>
@@ -399,6 +411,7 @@
399
411
  <div class="character-editor-title-row"><h1 id="character-editor-title">新建角色</h1><span id="character-editor-version" class="character-version-badge">新档案</span></div>
400
412
  </div>
401
413
  <div class="character-editor-header-actions">
414
+ <button id="character-editor-edit" class="primary-button hidden" type="button">编辑角色</button>
402
415
  <button id="character-history-button" class="ghost-button" type="button" aria-controls="character-history-panel" aria-expanded="false">版本历史</button>
403
416
  <button id="character-merge-button" class="ghost-button hidden" type="button">合并角色</button>
404
417
  <button id="character-delete-button" class="danger-button hidden" type="button">删除角色</button>
@@ -433,6 +446,7 @@
433
446
  </div>
434
447
  <div class="character-editor-header-actions">
435
448
  <span id="knowledge-editor-header-note" class="knowledge-editor-header-note">独立资料页</span>
449
+ <button id="knowledge-editor-edit" class="primary-button hidden" type="button">编辑档案</button>
436
450
  <button id="knowledge-editor-history" class="ghost-button hidden" type="button">版本历史</button>
437
451
  <button id="knowledge-editor-merge" class="ghost-button hidden" type="button">合并档案</button>
438
452
  <button id="knowledge-editor-delete" class="danger-button hidden" type="button">删除档案</button>
@@ -683,6 +697,6 @@
683
697
  <div id="auth-loading" class="auth-loading" role="status" aria-label="正在载入工作台"></div>
684
698
  <script id="vditorIconScript" src="/vendor/vditor/dist/js/icons/ant.js?v=3.11.2"></script>
685
699
  <script src="/vendor/vditor/dist/index.min.js?v=3.11.2"></script>
686
- <script type="module" src="/app.js?v=20260724-account-menu-identity"></script>
700
+ <script type="module" src="/app.js?v=20260725-ui-mobile-drawer-logo"></script>
687
701
  </body>
688
702
  </html>
@@ -47,6 +47,7 @@ export function serializePageRoute(route = {}) {
47
47
  params.set("work", workId);
48
48
  params.set("entity", route.entity);
49
49
  if (route.entityId) params.set("id", String(route.entityId));
50
+ if (route.entityMode === "read") params.set("mode", "read");
50
51
  } else if (view === "welcome" && workId) {
51
52
  params.set("view", "welcome");
52
53
  params.set("work", workId);
@@ -80,7 +81,8 @@ export function parsePageRoute(hash = "") {
80
81
  const entity = value(params, "entity");
81
82
  if (!entityEditorSet.has(entity)) return { view: "shelf" };
82
83
  const entityId = value(params, "id");
83
- return { view, workId, entity, entityId: entityId || null };
84
+ const entityMode = value(params, "mode") === "read" ? "read" : "edit";
85
+ return { view, workId, entity, entityId: entityId || null, entityMode };
84
86
  }
85
87
  if (view === "welcome" && workId) return { view, workId };
86
88
  if (view === "settings" || view === "platform-ai") {