@musnows/scriverse 0.9.3 → 0.9.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.
- package/dist/public/ai-context-meter.js +8 -3
- package/dist/public/app.js +15 -34
- package/dist/public/index.html +2 -2
- package/dist/public/styles.css +7 -5
- package/dist/store.js +5 -6
- package/dist/store.js.map +1 -1
- package/dist/utils.js +0 -8
- package/dist/utils.js.map +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
|
@@ -58,16 +58,21 @@ export function normalizeAiContextTokenDistribution(usage) {
|
|
|
58
58
|
const systemPromptTokens = tokenCount(distribution.systemPromptTokens);
|
|
59
59
|
const functionTokens = tokenCount(distribution.functionTokens);
|
|
60
60
|
const skillsTokens = tokenCount(distribution.skillsTokens);
|
|
61
|
-
const
|
|
61
|
+
const inputTokens = Object.keys(distribution).length > 0
|
|
62
62
|
? tokenCount(distribution.contextTokens)
|
|
63
63
|
: tokenCount(usage?.inputTokens);
|
|
64
|
-
const
|
|
64
|
+
const outputTokens = Math.min(
|
|
65
|
+
tokenCount(distribution.outputTokens ?? usage?.outputReserveTokens),
|
|
66
|
+
Math.max(0, contextWindow - systemPromptTokens - functionTokens - skillsTokens - inputTokens)
|
|
67
|
+
);
|
|
68
|
+
const occupiedTokens = systemPromptTokens + functionTokens + skillsTokens + inputTokens + outputTokens;
|
|
65
69
|
const leftTokens = Math.max(0, contextWindow - occupiedTokens);
|
|
66
70
|
const items = [
|
|
67
71
|
{ key: "system-prompt", label: "system prompt", tokens: systemPromptTokens },
|
|
68
72
|
{ key: "function", label: "function", tokens: functionTokens },
|
|
69
73
|
{ key: "skills", label: "skills", tokens: skillsTokens },
|
|
70
|
-
{ key: "
|
|
74
|
+
{ key: "input", label: "input", tokens: inputTokens },
|
|
75
|
+
{ key: "output", label: "output", tokens: outputTokens },
|
|
71
76
|
{ key: "left", label: "left", tokens: leftTokens }
|
|
72
77
|
];
|
|
73
78
|
return {
|
package/dist/public/app.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { buildRelationshipGraph, createGalaxyRenderer, normalizeGalaxyFrameRate, normalizeGalaxyMotionMode, renderRelationshipMindMap } from "/relationship-graph.js?v=20260817-relationship-canvas-scale-v1&feature=galaxy-motion-mode-v3&feature=galaxy-edge-label-threshold-v1";
|
|
2
|
-
import {
|
|
2
|
+
import { formatDateTime, normalizeParagraphSpacing } from "/text-formatting.js?v=20260713-saved-at-seconds";
|
|
3
3
|
import { renderMarkdown } from "/markdown.js?v=20260731-no-external-images-v1";
|
|
4
4
|
import { findAiMention, listAiMentionOptions, mergeAiReferenceScope, userMessageMentionNames } from "/ai-mentions.js?v=20260811-user-message-mentions-v1";
|
|
5
5
|
import {
|
|
@@ -32,7 +32,7 @@ import { createStreamTypewriter, createStreamTypewriterSpeedController } from "/
|
|
|
32
32
|
import { assertAiStreamCompleted, readAiEventStream } from "/ai-stream-protocol.js?v=20260812-ai-stream-complete-v1";
|
|
33
33
|
import { buildUsageCalendar, formatCacheHitRate, formatEstimatedCost, formatTokenCount } from "/ai-usage.js?v=20260821-ai-usage-pricing-v1";
|
|
34
34
|
import { formatAiMessageTime } from "/ai-message-time.js?v=20260801-month-day-time";
|
|
35
|
-
import { formatAiContextUsagePercent, formatAiContextUsageTooltip, mergeAiContextUsage, normalizeAiContextTokenDistribution, resolveAiContextUsage } from "/ai-context-meter.js?v=
|
|
35
|
+
import { formatAiContextUsagePercent, formatAiContextUsageTooltip, mergeAiContextUsage, normalizeAiContextTokenDistribution, resolveAiContextUsage } from "/ai-context-meter.js?v=20260827-context-input-output-v1";
|
|
36
36
|
import { isPhoneClient } from "/phone-client.js?v=20260819-phone-client-v1";
|
|
37
37
|
import { formatAiToolCallResult } from "/ai-tool-call.js?v=20260801-ai-tool-result-chars-v1";
|
|
38
38
|
import { copyAiRawMarkdown } from "/ai-message-actions.js?v=20260713-copy-raw-markdown";
|
|
@@ -1937,19 +1937,6 @@ function scheduleChapterLineNumbers(delay = 0) {
|
|
|
1937
1937
|
}, wait);
|
|
1938
1938
|
}
|
|
1939
1939
|
|
|
1940
|
-
function collapseChapterInputBlankLines(input) {
|
|
1941
|
-
const value = input.value;
|
|
1942
|
-
const normalized = collapseExcessBlankLines(value);
|
|
1943
|
-
if (normalized === value) return false;
|
|
1944
|
-
const selectionStart = input.selectionStart ?? value.length;
|
|
1945
|
-
const selectionEnd = input.selectionEnd ?? selectionStart;
|
|
1946
|
-
const nextStart = collapseExcessBlankLines(value.slice(0, selectionStart)).length;
|
|
1947
|
-
const nextEnd = collapseExcessBlankLines(value.slice(0, selectionEnd)).length;
|
|
1948
|
-
input.value = normalized;
|
|
1949
|
-
input.setSelectionRange(nextStart, nextEnd);
|
|
1950
|
-
return true;
|
|
1951
|
-
}
|
|
1952
|
-
|
|
1953
1940
|
function lineIndexAtPointer(clientY) {
|
|
1954
1941
|
const rows = [...$("#chapter-line-numbers-inner").querySelectorAll(".chapter-line-number")];
|
|
1955
1942
|
if (!rows.length) return 0;
|
|
@@ -5635,7 +5622,7 @@ function chapterDraftSnapshot() {
|
|
|
5635
5622
|
return {
|
|
5636
5623
|
chapterId: state.chapter.id,
|
|
5637
5624
|
title: $("#chapter-title").value.trim(),
|
|
5638
|
-
content:
|
|
5625
|
+
content: $("#chapter-content").value
|
|
5639
5626
|
};
|
|
5640
5627
|
}
|
|
5641
5628
|
|
|
@@ -5692,11 +5679,6 @@ async function persistChapter({ automatic = false } = {}) {
|
|
|
5692
5679
|
if (!automatic) toast("章节标题不能为空", "error");
|
|
5693
5680
|
return null;
|
|
5694
5681
|
}
|
|
5695
|
-
const input = $("#chapter-content");
|
|
5696
|
-
if (input.value !== draft.content) {
|
|
5697
|
-
input.value = draft.content;
|
|
5698
|
-
scheduleChapterLineNumbers();
|
|
5699
|
-
}
|
|
5700
5682
|
if (sameChapterSnapshot(draft, lastSavedChapterSnapshot)) {
|
|
5701
5683
|
setSaveState(automatic ? "已自动保存" : collaborationAutoSaveDisabled ? "已保存 · 自动保存已关闭" : "已保存");
|
|
5702
5684
|
if (!automatic) await loadChapterForeshadowReminders();
|
|
@@ -8078,9 +8060,7 @@ async function selectChapter(chapterId, { editMode = false } = {}) {
|
|
|
8078
8060
|
$("#chapter-path").textContent = chapterPath;
|
|
8079
8061
|
$("#chapter-path").title = chapterPath;
|
|
8080
8062
|
$("#chapter-title").value = state.chapter.title;
|
|
8081
|
-
|
|
8082
|
-
const spacingChanged = normalizedContent !== state.chapter.content;
|
|
8083
|
-
$("#chapter-content").value = normalizedContent;
|
|
8063
|
+
$("#chapter-content").value = state.chapter.content;
|
|
8084
8064
|
chapterAnnotationCounts = new Map();
|
|
8085
8065
|
clearChapterLineSelection();
|
|
8086
8066
|
scheduleChapterLineNumbers();
|
|
@@ -8091,7 +8071,6 @@ async function selectChapter(chapterId, { editMode = false } = {}) {
|
|
|
8091
8071
|
updateChapterStats();
|
|
8092
8072
|
if (!canEditProse()) setSaveState("正文只读");
|
|
8093
8073
|
else if (chapterEditorReadOnly) setSaveState("阅读模式");
|
|
8094
|
-
else if (spacingChanged) scheduleChapterAutoSave(120);
|
|
8095
8074
|
else setSaveState("已保存");
|
|
8096
8075
|
renderTree();
|
|
8097
8076
|
replacePageRoute({ view: "editor", workId: state.work.id, chapterId: state.chapter.id });
|
|
@@ -12903,9 +12882,11 @@ function renderAiContextDistribution(usage) {
|
|
|
12903
12882
|
label.className = "ai-context-distribution-label";
|
|
12904
12883
|
const title = document.createElement("span");
|
|
12905
12884
|
title.textContent = item.label;
|
|
12906
|
-
if (item.key === "skills" || item.key === "
|
|
12885
|
+
if (item.key === "skills" || item.key === "input" || item.key === "output") {
|
|
12907
12886
|
const description = document.createElement("small");
|
|
12908
|
-
description.textContent = item.key === "skills"
|
|
12887
|
+
description.textContent = item.key === "skills"
|
|
12888
|
+
? "待加入"
|
|
12889
|
+
: item.key === "input" ? "用户和 agent 的交互" : "模型输出预留";
|
|
12909
12890
|
title.append(" ", description);
|
|
12910
12891
|
}
|
|
12911
12892
|
const value = document.createElement("strong");
|
|
@@ -12922,6 +12903,7 @@ function renderAiContextDistribution(usage) {
|
|
|
12922
12903
|
return row;
|
|
12923
12904
|
}));
|
|
12924
12905
|
popover.dataset.hasUsage = String(Boolean(usage));
|
|
12906
|
+
return distribution;
|
|
12925
12907
|
}
|
|
12926
12908
|
|
|
12927
12909
|
function setAiContextMeter(usage, allowShrink = true) {
|
|
@@ -12931,7 +12913,7 @@ function setAiContextMeter(usage, allowShrink = true) {
|
|
|
12931
12913
|
latestAiContextUsage = displayUsage;
|
|
12932
12914
|
const meter = $("#ai-context-meter");
|
|
12933
12915
|
const value = meter.querySelector("b");
|
|
12934
|
-
renderAiContextDistribution(displayUsage);
|
|
12916
|
+
const distribution = renderAiContextDistribution(displayUsage);
|
|
12935
12917
|
if (!displayUsage) {
|
|
12936
12918
|
meter.classList.add("is-empty");
|
|
12937
12919
|
meter.classList.remove("is-warning", "is-danger");
|
|
@@ -12942,14 +12924,14 @@ function setAiContextMeter(usage, allowShrink = true) {
|
|
|
12942
12924
|
meter.setAttribute("aria-label", tooltip);
|
|
12943
12925
|
return;
|
|
12944
12926
|
}
|
|
12945
|
-
const percent =
|
|
12927
|
+
const percent = distribution.contextWindow > 0
|
|
12928
|
+
? Math.min(100, distribution.occupiedTokens / distribution.contextWindow * 100)
|
|
12929
|
+
: 0;
|
|
12946
12930
|
meter.classList.remove("is-empty");
|
|
12947
12931
|
meter.classList.toggle("is-warning", percent >= 70 && percent < 90);
|
|
12948
12932
|
meter.classList.toggle("is-danger", percent >= 90);
|
|
12949
12933
|
meter.style.setProperty("--context-usage", String(percent));
|
|
12950
|
-
value.textContent =
|
|
12951
|
-
? formatAiContextUsagePercent(displayUsage.inputTokens, displayUsage.contextWindow)
|
|
12952
|
-
: `${percent}%`;
|
|
12934
|
+
value.textContent = formatAiContextUsagePercent(distribution.occupiedTokens, distribution.contextWindow);
|
|
12953
12935
|
const tooltip = formatAiContextUsageTooltip(displayUsage);
|
|
12954
12936
|
meter.dataset.tooltip = tooltip;
|
|
12955
12937
|
meter.setAttribute("aria-label", `当前上下文用量:${tooltip}`);
|
|
@@ -18570,8 +18552,7 @@ $("#appearance-form").addEventListener("submit", (event) => {
|
|
|
18570
18552
|
toast(persisted ? "显示设置已保存" : "显示设置已应用,但当前浏览器无法保存偏好", persisted ? "info" : "error");
|
|
18571
18553
|
});
|
|
18572
18554
|
$("#chapter-title").addEventListener("input", () => scheduleChapterAutoSave());
|
|
18573
|
-
$("#chapter-content").addEventListener("input", (
|
|
18574
|
-
if (!event.isComposing) collapseChapterInputBlankLines(event.currentTarget);
|
|
18555
|
+
$("#chapter-content").addEventListener("input", () => {
|
|
18575
18556
|
updateChapterStats();
|
|
18576
18557
|
scheduleChapterAutoSave();
|
|
18577
18558
|
clearChapterLineSelection();
|
package/dist/public/index.html
CHANGED
|
@@ -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=20260816-task-scope-volume-collapse-v2&feature=ai-tool-call-copy-feedback-v2&feature=ai-send-control-v3&feature=character-gender-v1&feature=character-filter-state-v1&feature=relationship-canvas-scale-v1&feature=relationship-table-scroll-v1&feature=galaxy-compact-controls-v2&feature=galaxy-motion-mode-v2&feature=chapter-search-replace-v3&feature=task-auto-run-ring-center-v3&feature=character-relationship-delete-v1&feature=ai-assistant-workspace-v2&feature=mobile-module-tab-position-v1&feature=volume-detail-icon-v1&feature=editor-actions-flow-v1&feature=reader-controls-subpanel-v1&feature=reader-focus-ring-v1&feature=ai-message-actions-v1&feature=assistant-responsive-navigation-v2&feature=ai-composer-square-controls-v2&feature=annotation-line-counts-v1&feature=line-number-gutter-fill-v1&feature=ai-relationship-roleplay-v1&feature=ai-model-picker-v1&feature=markdown-word-count-five-digit-v2&feature=ai-stream-character-count-stable-v1&feature=annotation-marker-offset-v1&feature=mobile-ai-entry-hidden-v1&feature=phone-client-entry-v1&feature=ai-stream-idle-timeout-v1&feature=ai-user-message-width-v2&feature=ai-chat-image-attachments-v9&feature=ai-message-image-preview-v1&feature=ai-thinking-scroll-v2&feature=toast-click-dismiss-v3&feature=character-avatar-v6&feature=admin-ai-conversations-v1&feature=ai-usage-pricing-v1&feature=ai-usage-pricing-badge-v2&feature=ai-token-quota-positive-v5&feature=ai-token-usage-details-v1&feature=ai-token-usage-details-centered-v1&feature=ai-stream-connection-seconds-v1&feature=ai-token-usage-estimated-price-v1&feature=record-favorites-v1&feature=entity-detail-favorites-v1&feature=entity-pin-v1&feature=character-persona-summary-v1&feature=ai-roleplay-scene-turn-v1&feature=admin-account-identity-v2&feature=task-detail-failure-orange-v1&feature=character-card-header-alignment-v6&feature=character-card-title-fit-v2&feature=book-import-progress-v1">
|
|
13
|
+
<link rel="stylesheet" href="/styles.css?v=20260816-task-scope-volume-collapse-v2&feature=ai-tool-call-copy-feedback-v2&feature=ai-send-control-v3&feature=character-gender-v1&feature=character-filter-state-v1&feature=relationship-canvas-scale-v1&feature=relationship-table-scroll-v1&feature=galaxy-compact-controls-v2&feature=galaxy-motion-mode-v2&feature=chapter-search-replace-v3&feature=task-auto-run-ring-center-v3&feature=character-relationship-delete-v1&feature=ai-assistant-workspace-v2&feature=mobile-module-tab-position-v1&feature=volume-detail-icon-v1&feature=editor-actions-flow-v1&feature=reader-controls-subpanel-v1&feature=reader-focus-ring-v1&feature=ai-message-actions-v1&feature=assistant-responsive-navigation-v2&feature=ai-composer-square-controls-v2&feature=annotation-line-counts-v1&feature=line-number-gutter-fill-v1&feature=ai-relationship-roleplay-v1&feature=ai-model-picker-v1&feature=markdown-word-count-five-digit-v2&feature=ai-stream-character-count-stable-v1&feature=annotation-marker-offset-v1&feature=mobile-ai-entry-hidden-v1&feature=phone-client-entry-v1&feature=ai-stream-idle-timeout-v1&feature=ai-user-message-width-v2&feature=ai-chat-image-attachments-v9&feature=ai-message-image-preview-v1&feature=ai-thinking-scroll-v2&feature=toast-click-dismiss-v3&feature=character-avatar-v6&feature=admin-ai-conversations-v1&feature=ai-usage-pricing-v1&feature=ai-usage-pricing-badge-v2&feature=ai-token-quota-positive-v5&feature=ai-token-usage-details-v1&feature=ai-token-usage-details-centered-v1&feature=ai-stream-connection-seconds-v1&feature=ai-token-usage-estimated-price-v1&feature=record-favorites-v1&feature=entity-detail-favorites-v1&feature=entity-pin-v1&feature=character-persona-summary-v1&feature=ai-roleplay-scene-turn-v1&feature=admin-account-identity-v2&feature=task-detail-failure-orange-v1&feature=character-card-header-alignment-v6&feature=character-card-title-fit-v2&feature=book-import-progress-v1&feature=editor-toolbar-compact-v2">
|
|
14
14
|
</head>
|
|
15
15
|
<body class="auth-pending">
|
|
16
16
|
<section id="auth-view" class="auth-view hidden" aria-labelledby="auth-title">
|
|
@@ -1262,6 +1262,6 @@
|
|
|
1262
1262
|
<div id="auth-loading" class="auth-loading" role="status" aria-label="正在载入工作台"></div>
|
|
1263
1263
|
<script id="vditorIconScript" src="/vendor/vditor/dist/js/icons/ant.js?v=3.11.2"></script>
|
|
1264
1264
|
<script src="/vendor/vditor/dist/index.min.js?v=3.11.2"></script>
|
|
1265
|
-
<script type="module" src="/app.js?v=20260816-extended-thinking-effort-v1&feature=ai-tool-call-copy-feedback-v2&feature=ai-send-control-v2&feature=analysis-task-queue-refresh-v1&feature=character-gender-v1&feature=character-filter-state-v1&feature=relationship-canvas-scale-v1&feature=relationship-table-scroll-v1&feature=ai-session-id-copy-v2&feature=galaxy-motion-mode-v3&feature=galaxy-edge-label-threshold-v1&feature=calculate-time-tool-v2&feature=analysis-task-expired-toast-v1&feature=global-replace-volume-v1&feature=chapter-search-replace-v1&feature=chapter-save-toast-v1&feature=character-relationship-delete-v1&feature=character-relationship-group-v1&feature=analysis-task-stability-delay-v1&feature=ai-assistant-workspace-v2&feature=volume-detail-icon-v1&feature=volume-story-order-v1&feature=reader-manual-chapter-navigation-v1&feature=ai-message-reference-badges-v1&feature=ai-roleplay-message-reference-v1&feature=ai-message-actions-v1&feature=assistant-responsive-navigation-v3&feature=annotation-permissions-v1&feature=annotation-line-counts-v1&feature=ai-relationship-roleplay-v1&feature=ai-roleplay-user-character-visibility-v1&feature=ai-roleplay-story-recall-v1&feature=ai-model-picker-v1&feature=ai-fork-model-unlock-v1&feature=context-percent-format-v1&feature=annotation-precise-locate-v1&feature=markdown-word-count-stable-v1&feature=ai-stream-character-count-stable-v2&feature=ai-process-empty-intermediate-v1&feature=ai-feed-scroll-follow-v1&feature=ai-message-retry-v1&feature=ai-stream-idle-timeout-v2&feature=ai-config-delete-v1&feature=ai-provider-protocol-options-v1&feature=ai-provider-thinking-type-v1&feature=ai-chat-image-attachments-v8&feature=ai-message-image-preview-v1&feature=ai-thinking-scroll-v2&feature=ai-image-conversation-model-lock-v1&feature=toast-click-dismiss-v2&feature=system-restart-dialog-delay-v1&feature=character-avatar-v6&feature=character-death-position-v1&feature=admin-ai-conversations-v1&feature=ai-usage-pricing-v1&feature=ai-usage-pricing-badge-v2&feature=ai-usage-pricing-label-v1&feature=ai-usage-token-breakdown-v1&feature=ai-usage-pricing-cache-v2&feature=ai-usage-pricing-manual-refresh-v1&feature=ai-monthly-token-quota-v1&feature=ai-provider-token-quota-v1&feature=ai-token-quota-positive-v6&feature=ai-model-thinking-label-v1&feature=ai-model-picker-focus-v1&feature=ai-provider-model-import-v1&feature=ai-assistant-brain-icon-v1&feature=ai-token-usage-details-v1&feature=ai-token-usage-details-centered-v1&feature=ai-token-usage-raw-input-v1&feature=ai-stream-connection-seconds-v1&feature=phone-client-entry-v1&feature=ai-usage-pricing-cache-v1&feature=ai-model-thinking-label-v3&feature=ai-roleplay-speaker-label-v1&feature=toast-modal-host-v1&feature=api-key-copy-existing-v1&feature=character-favorite-v1&feature=record-favorites-v1&feature=ai-token-usage-estimated-price-v1&feature=entity-detail-favorites-v1&feature=entity-pin-v1&feature=entity-pin-icon-v1&feature=roleplay-favorite-label-v1&feature=ai-roleplay-knowledge-tools-v1&feature=character-persona-summary-v1&feature=ai-roleplay-scene-turn-v2&feature=admin-account-identity-v2&feature=ai-provider-analysis-timeout-v1&feature=task-detail-failure-orange-v1&feature=book-import-progress-v1&feature=presence-multiple-users-v1"></script>
|
|
1265
|
+
<script type="module" src="/app.js?v=20260816-extended-thinking-effort-v1&feature=ai-tool-call-copy-feedback-v2&feature=ai-send-control-v2&feature=analysis-task-queue-refresh-v1&feature=character-gender-v1&feature=character-filter-state-v1&feature=relationship-canvas-scale-v1&feature=relationship-table-scroll-v1&feature=ai-session-id-copy-v2&feature=galaxy-motion-mode-v3&feature=galaxy-edge-label-threshold-v1&feature=calculate-time-tool-v2&feature=analysis-task-expired-toast-v1&feature=global-replace-volume-v1&feature=chapter-search-replace-v1&feature=chapter-save-toast-v1&feature=character-relationship-delete-v1&feature=character-relationship-group-v1&feature=analysis-task-stability-delay-v1&feature=ai-assistant-workspace-v2&feature=volume-detail-icon-v1&feature=volume-story-order-v1&feature=reader-manual-chapter-navigation-v1&feature=ai-message-reference-badges-v1&feature=ai-roleplay-message-reference-v1&feature=ai-message-actions-v1&feature=assistant-responsive-navigation-v3&feature=annotation-permissions-v1&feature=annotation-line-counts-v1&feature=ai-relationship-roleplay-v1&feature=ai-roleplay-user-character-visibility-v1&feature=ai-roleplay-story-recall-v1&feature=ai-model-picker-v1&feature=ai-fork-model-unlock-v1&feature=context-percent-format-v1&feature=annotation-precise-locate-v1&feature=markdown-word-count-stable-v1&feature=ai-stream-character-count-stable-v2&feature=ai-process-empty-intermediate-v1&feature=ai-feed-scroll-follow-v1&feature=ai-message-retry-v1&feature=ai-stream-idle-timeout-v2&feature=ai-config-delete-v1&feature=ai-provider-protocol-options-v1&feature=ai-provider-thinking-type-v1&feature=ai-chat-image-attachments-v8&feature=ai-message-image-preview-v1&feature=ai-thinking-scroll-v2&feature=ai-image-conversation-model-lock-v1&feature=toast-click-dismiss-v2&feature=system-restart-dialog-delay-v1&feature=character-avatar-v6&feature=character-death-position-v1&feature=admin-ai-conversations-v1&feature=ai-usage-pricing-v1&feature=ai-usage-pricing-badge-v2&feature=ai-usage-pricing-label-v1&feature=ai-usage-token-breakdown-v1&feature=ai-usage-pricing-cache-v2&feature=ai-usage-pricing-manual-refresh-v1&feature=ai-monthly-token-quota-v1&feature=ai-provider-token-quota-v1&feature=ai-token-quota-positive-v6&feature=ai-model-thinking-label-v1&feature=ai-model-picker-focus-v1&feature=ai-provider-model-import-v1&feature=ai-assistant-brain-icon-v1&feature=ai-token-usage-details-v1&feature=ai-token-usage-details-centered-v1&feature=ai-token-usage-raw-input-v1&feature=ai-stream-connection-seconds-v1&feature=phone-client-entry-v1&feature=ai-usage-pricing-cache-v1&feature=ai-model-thinking-label-v3&feature=ai-roleplay-speaker-label-v1&feature=toast-modal-host-v1&feature=api-key-copy-existing-v1&feature=character-favorite-v1&feature=record-favorites-v1&feature=ai-token-usage-estimated-price-v1&feature=entity-detail-favorites-v1&feature=entity-pin-v1&feature=entity-pin-icon-v1&feature=roleplay-favorite-label-v1&feature=ai-roleplay-knowledge-tools-v1&feature=character-persona-summary-v1&feature=ai-roleplay-scene-turn-v2&feature=admin-account-identity-v2&feature=ai-provider-analysis-timeout-v1&feature=task-detail-failure-orange-v1&feature=book-import-progress-v1&feature=presence-multiple-users-v1&feature=ai-context-input-output-v1&feature=editor-blank-lines-preserved-v1"></script>
|
|
1266
1266
|
</body>
|
|
1267
1267
|
</html>
|
package/dist/public/styles.css
CHANGED
|
@@ -1437,9 +1437,10 @@ select:focus, input:focus, textarea:focus { border-color: #a77768; box-shadow: 0
|
|
|
1437
1437
|
.editor-view { container-name: editor-workspace; container-type: inline-size; display: grid; grid-template-rows: auto auto minmax(0, 1fr); height: 100%; }
|
|
1438
1438
|
.editor-toolbar { position: relative; display: grid; grid-row: 1; grid-template-areas: "path path" "title actions"; grid-template-columns: minmax(0, 1fr) auto; align-items: flex-end; column-gap: 20px; row-gap: 6px; padding: 25px 7% 18px; border-bottom: 1px solid var(--line); }
|
|
1439
1439
|
#chapter-path { grid-area: path; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
1440
|
-
.chapter-title { grid-area: title; display: block; width: 100%; min-width: 0; border: 0; border-radius: 0; background: transparent; font-size:
|
|
1440
|
+
.chapter-title { grid-area: title; display: block; width: 100%; min-width: 0; border: 0; border-radius: 0; background: transparent; font-size: 25px; padding: 0; }
|
|
1441
1441
|
.chapter-title:focus { box-shadow: none; border-bottom: 1px solid var(--accent); }
|
|
1442
|
-
.editor-actions { grid-area: actions; display: flex; align-items: center; gap:
|
|
1442
|
+
.editor-actions { grid-area: actions; display: flex; align-items: center; gap: 8px; }
|
|
1443
|
+
.editor-view .editor-actions > button { min-height: 32px; padding: 6px 10px; font-size: 11px; }
|
|
1443
1444
|
.chapter-stats { color: var(--muted); font-size: 11px; }
|
|
1444
1445
|
.chapter-search-panel { position: absolute; z-index: 8; top: calc(100% + 8px); right: 7%; display: grid; width: min(520px, calc(100% - 14%)); gap: 12px; padding: 14px; border: 1px solid var(--line-strong); outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 7px; background: var(--panel); box-shadow: 0 16px 36px rgba(36, 30, 24, .22); }
|
|
1445
1446
|
.chapter-search-panel-header { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; }
|
|
@@ -2961,7 +2962,8 @@ select:focus, input:focus, textarea:focus { border-color: #a77768; box-shadow: 0
|
|
|
2961
2962
|
.ai-context-distribution-row[data-key="system-prompt"] { --distribution-color: var(--accent); }
|
|
2962
2963
|
.ai-context-distribution-row[data-key="function"] { --distribution-color: #9a7651; }
|
|
2963
2964
|
.ai-context-distribution-row[data-key="skills"] { --distribution-color: var(--muted); }
|
|
2964
|
-
.ai-context-distribution-row[data-key="
|
|
2965
|
+
.ai-context-distribution-row[data-key="input"] { --distribution-color: var(--green); }
|
|
2966
|
+
.ai-context-distribution-row[data-key="output"] { --distribution-color: #718a9f; }
|
|
2965
2967
|
.ai-context-distribution-row[data-key="left"] { --distribution-color: color-mix(in srgb, var(--muted) 55%, transparent); }
|
|
2966
2968
|
.ai-send-button { display: grid; flex: 0 0 32px; place-items: center; width: 32px; min-width: 32px; min-height: 32px; height: 32px; padding: 0; border: 0; border-radius: 4px; background: var(--accent); color: #fff; box-shadow: 0 4px 12px rgba(139,61,44,.2); }
|
|
2967
2969
|
.ai-send-button:hover, .ai-send-button:focus-visible { background: var(--accent-dark); outline: 0; }
|
|
@@ -4089,8 +4091,8 @@ select:focus, input:focus, textarea:focus { border-color: #a77768; box-shadow: 0
|
|
|
4089
4091
|
.editor-actions { position: static; z-index: auto; right: auto; bottom: auto; left: auto; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); width: 100%; max-width: none; gap: 6px; padding: 0; border: 0; border-radius: 0; background: transparent; box-shadow: none; transform: none; transition: none; }
|
|
4090
4092
|
.app-shell.left-panel-collapsed .editor-actions { transform: none; pointer-events: auto; }
|
|
4091
4093
|
.editor-actions .chapter-stats { grid-column: 1 / -1; }
|
|
4092
|
-
.editor-actions > button { min-width: 0; min-height:
|
|
4093
|
-
.chapter-title { font-size:
|
|
4094
|
+
.editor-view .editor-actions > button { min-width: 0; min-height: 34px; padding-inline: 6px; font-size: 11px; }
|
|
4095
|
+
.chapter-title { font-size: 21px; }
|
|
4094
4096
|
.chapter-content { padding: 22px 16px 64px 12px; font-size: max(16px, var(--editor-font-size)); }
|
|
4095
4097
|
.chapter-line-numbers { width: 32px; font-size: 11px; }
|
|
4096
4098
|
.chapter-editor-frame { grid-template-columns: 32px minmax(0, 1fr); }
|
package/dist/store.js
CHANGED
|
@@ -9,7 +9,7 @@ import { accountReference, logger } from "./logger.js";
|
|
|
9
9
|
import { paginated, paginationSql } from "./pagination.js";
|
|
10
10
|
import { currentRequestActor } from "./request-context.js";
|
|
11
11
|
import { canWriteWorkModule, classifyWorkModulePermissions, emptyWorkModulePermissions, fullWorkModulePermissions, storedWorkModulePermissions } from "./work-permissions.js";
|
|
12
|
-
import { countWords, documentShortSearchTerms, escapeSqlLikePattern, id, json, normalizeDocumentSearchText,
|
|
12
|
+
import { countWords, documentShortSearchTerms, escapeSqlLikePattern, id, json, normalizeDocumentSearchText, now, splitDocumentParagraphs } from "./utils.js";
|
|
13
13
|
import { buildWritingCalendar, writingDateKey } from "./writing-progress-time.js";
|
|
14
14
|
import { resolveMaxAgentToolCallLimit } from "./ai-tool-results.js";
|
|
15
15
|
import { DEFAULT_AI_STREAM_IDLE_TIMEOUT_SECONDS, normalizeAiStreamIdleTimeoutSeconds } from "./ai-stream-timeout.js";
|
|
@@ -2103,7 +2103,7 @@ export class Store {
|
|
|
2103
2103
|
const current = this.getChapter(chapterId);
|
|
2104
2104
|
this.assertExpectedRevision("chapter", chapterId, expectedVersionNo, "章节", Number(current.versionNo));
|
|
2105
2105
|
const nextTitle = input.title ?? String(current.title);
|
|
2106
|
-
const nextContent = input.content === undefined ? String(current.content) :
|
|
2106
|
+
const nextContent = input.content === undefined ? String(current.content) : input.content;
|
|
2107
2107
|
const nextExcluded = input.excludedFromAnalysis ?? Boolean(current.excludedFromAnalysis);
|
|
2108
2108
|
const nextChapterType = input.chapterType ?? String(current.chapterType);
|
|
2109
2109
|
const hasTextChange = nextTitle !== current.title || nextContent !== current.content;
|
|
@@ -2787,16 +2787,15 @@ export class Store {
|
|
|
2787
2787
|
insertChapter(workId, volumeId, title, content, sortOrder, source, sourceRef, chapterType = "正文") {
|
|
2788
2788
|
const chapterId = id("chapter");
|
|
2789
2789
|
const timestamp = now();
|
|
2790
|
-
const normalizedContent = normalizeParagraphSpacing(content);
|
|
2791
2790
|
this.db.run(`INSERT INTO chapters (id, work_id, volume_id, title, content, chapter_type, sort_order, word_count, version_no, analysis_status, created_at, updated_at)
|
|
2792
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, 1, 'pending', ?, ?)`, chapterId, workId, volumeId, title,
|
|
2793
|
-
this.syncChapterParagraphSearch(workId, chapterId,
|
|
2791
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, 1, 'pending', ?, ?)`, chapterId, workId, volumeId, title, content, chapterType, sortOrder, countWords(content), timestamp, timestamp);
|
|
2792
|
+
this.syncChapterParagraphSearch(workId, chapterId, content);
|
|
2794
2793
|
this.insertChapterVersionRow({
|
|
2795
2794
|
workId,
|
|
2796
2795
|
chapterId,
|
|
2797
2796
|
versionNo: 1,
|
|
2798
2797
|
title,
|
|
2799
|
-
content
|
|
2798
|
+
content,
|
|
2800
2799
|
volumeId,
|
|
2801
2800
|
sortOrder,
|
|
2802
2801
|
chapterType,
|