@musnows/scriverse 0.7.13 → 0.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/README.en.md +4 -0
  2. package/README.md +5 -0
  3. package/dist/ai-chat-tab-limit.js +14 -0
  4. package/dist/ai-chat-tab-limit.js.map +1 -0
  5. package/dist/ai-protocol.js +10 -2
  6. package/dist/ai-protocol.js.map +1 -1
  7. package/dist/ai-retry.js +52 -0
  8. package/dist/ai-retry.js.map +1 -0
  9. package/dist/ai.js +547 -119
  10. package/dist/ai.js.map +1 -1
  11. package/dist/app.js +80 -22
  12. package/dist/app.js.map +1 -1
  13. package/dist/cli-contract.js +2 -1
  14. package/dist/cli-contract.js.map +1 -1
  15. package/dist/database.js +127 -2
  16. package/dist/database.js.map +1 -1
  17. package/dist/domain.js +1 -0
  18. package/dist/domain.js.map +1 -1
  19. package/dist/public/ai-chat-tabs.js +75 -0
  20. package/dist/public/ai-request-manager.js +32 -15
  21. package/dist/public/app.js +1305 -298
  22. package/dist/public/background-task-center.d.ts +9 -0
  23. package/dist/public/background-task-center.js +18 -0
  24. package/dist/public/chapter-search.d.ts +6 -0
  25. package/dist/public/chapter-search.js +23 -0
  26. package/dist/public/character-filters.d.ts +3 -1
  27. package/dist/public/character-filters.js +17 -2
  28. package/dist/public/character-version.js +1 -0
  29. package/dist/public/display-labels.d.ts +1 -0
  30. package/dist/public/display-labels.js +5 -1
  31. package/dist/public/index.html +67 -26
  32. package/dist/public/model-config.d.ts +3 -1
  33. package/dist/public/model-config.js +13 -0
  34. package/dist/public/relationship-filters.d.ts +5 -0
  35. package/dist/public/relationship-filters.js +31 -0
  36. package/dist/public/relationship-graph.js +289 -58
  37. package/dist/public/stream-typewriter.d.ts +1 -0
  38. package/dist/public/stream-typewriter.js +12 -0
  39. package/dist/public/styles.css +185 -41
  40. package/dist/public/work-permissions.d.ts +1 -1
  41. package/dist/public/work-permissions.js +13 -1
  42. package/dist/server-runtime.js +6 -0
  43. package/dist/server-runtime.js.map +1 -1
  44. package/dist/store.js +127 -44
  45. package/dist/store.js.map +1 -1
  46. package/dist/user-auth.js +34 -7
  47. package/dist/user-auth.js.map +1 -1
  48. package/dist/version.js +6 -1
  49. package/dist/version.js.map +1 -1
  50. package/dist/work-permissions.js +13 -2
  51. package/dist/work-permissions.js.map +1 -1
  52. package/package.json +1 -1
@@ -2,6 +2,8 @@ import { chmodSync, cpSync, existsSync, mkdirSync, readdirSync, readFileSync, re
2
2
  import { fileURLToPath } from "node:url";
3
3
  import { basename, join } from "node:path";
4
4
  import { createRuntime } from "./app.js";
5
+ import { resolveAiChatTabLimit } from "./ai-chat-tab-limit.js";
6
+ import { resolveAiRetryPolicy } from "./ai-retry.js";
5
7
  import { resolveAiStreamIdleTimeoutMs } from "./ai-stream-timeout.js";
6
8
  import { DATABASE_SCHEMA_VERSION, readDatabaseSchemaVersion } from "./database.js";
7
9
  import { loadMasterSecret } from "./credential-vault.js";
@@ -9,6 +11,7 @@ import { isDevelopmentAuthBypassEnabled, resolveRuntimeSecurity } from "./securi
9
11
  import { logger, sanitizeError } from "./logger.js";
10
12
  import { resolveReleaseCheckIntervalMs, resolveReleaseCheckRetries, resolveReleaseCheckTimeoutMs } from "./release-update.js";
11
13
  import { resolveImageUploadLimits } from "./upload-limits.js";
14
+ import { resolveBetaVersionLabel } from "./version.js";
12
15
  const publicPath = fileURLToPath(new URL("./public/", import.meta.url));
13
16
  export const PRE_MIGRATION_BACKUP_RETENTION_ENV = "SCRIVERSE_PRE_MIGRATION_BACKUP_RETENTION";
14
17
  export const DEFAULT_PRE_MIGRATION_BACKUP_RETENTION = 5;
@@ -195,9 +198,12 @@ export async function startLocalServer(options) {
195
198
  disableUserAuth: devAuthBypass,
196
199
  devAuthBypass,
197
200
  developmentServer: isDevelopmentServer(options.env),
201
+ betaVersionLabel: resolveBetaVersionLabel(options.env),
198
202
  releaseCheckIntervalMs: resolveReleaseCheckIntervalMs(options.env.APP_UPDATE_CHECK_INTERVAL_MINUTES),
199
203
  releaseCheckTimeoutMs: resolveReleaseCheckTimeoutMs(options.env.APP_UPDATE_CHECK_TIMEOUT_SECONDS),
200
204
  releaseCheckRetries: resolveReleaseCheckRetries(options.env.APP_UPDATE_CHECK_RETRIES),
205
+ aiChatTabLimit: resolveAiChatTabLimit(options.env),
206
+ aiRetryPolicy: resolveAiRetryPolicy(options.env),
201
207
  aiStreamIdleTimeoutMs: resolveAiStreamIdleTimeoutMs(options.env),
202
208
  uploadLimits: resolveImageUploadLimits(options.env)
203
209
  });
@@ -1 +1 @@
1
- {"version":3,"file":"server-runtime.js","sourceRoot":"","sources":["../src/server-runtime.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"server-runtime.js","sourceRoot":"","sources":["../src/server-runtime.ts"],"names":[],"mappings":"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"}
package/dist/store.js CHANGED
@@ -1,4 +1,4 @@
1
- import { DRAFT_SETTING_MODULES } from "./domain.js";
1
+ import { CHARACTER_GENDERS, DRAFT_SETTING_MODULES } from "./domain.js";
2
2
  import { createHash } from "node:crypto";
3
3
  import { ENTITY_VERSION_BASELINE_MIGRATION_VERSION, PLATFORM_AI_WORK_ID } from "./database.js";
4
4
  import { exportWorkDocx } from "./docx-export.js";
@@ -26,9 +26,19 @@ export const WORK_AGENT_TOOL_IDS = [
26
26
  "search_story_entities",
27
27
  "read_character_sections",
28
28
  "search_drafts",
29
- "image"
29
+ "image",
30
+ "calculate_time"
30
31
  ];
31
32
  const DEFAULT_WORK_AGENT_TOOLS = [...WORK_AGENT_TOOL_IDS];
33
+ const LEGACY_DEFAULT_WORK_AGENT_TOOLS = [
34
+ "story_index",
35
+ "read_chapters",
36
+ "grep",
37
+ "search_story_entities",
38
+ "read_character_sections",
39
+ "search_drafts",
40
+ "image"
41
+ ];
32
42
  export function normalizeWorkAgentTools(value) {
33
43
  const source = Array.isArray(value)
34
44
  ? value
@@ -43,6 +53,8 @@ export function normalizeWorkAgentTools(value) {
43
53
  if (WORK_AGENT_TOOL_IDS.includes(toolId))
44
54
  enabled.add(toolId);
45
55
  }
56
+ if (LEGACY_DEFAULT_WORK_AGENT_TOOLS.every((toolId) => enabled.has(toolId)))
57
+ enabled.add("calculate_time");
46
58
  return WORK_AGENT_TOOL_IDS.filter((toolId) => enabled.has(toolId));
47
59
  }
48
60
  const galaxyFrameRates = [24, 30, 60, 90, 120, 144, 165, 240];
@@ -204,6 +216,11 @@ export function defaultAiConversationTitle(prompt) {
204
216
  function isRecord(value) {
205
217
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
206
218
  }
219
+ function characterGender(value) {
220
+ return typeof value === "string" && CHARACTER_GENDERS.includes(value)
221
+ ? value
222
+ : "unknown";
223
+ }
207
224
  function invalidFileSnapshot() {
208
225
  throw new AppError(409, "FILE_VERSION_INVALID", "正文历史快照已损坏,未执行恢复");
209
226
  }
@@ -869,10 +886,14 @@ export class Store {
869
886
  return this.getPlatformUiSettings();
870
887
  }
871
888
  analysisTaskQueuedHandler = null;
889
+ chapterAnalysisInvalidatedHandler = null;
872
890
  relationshipIndexQueuedHandler = null;
873
891
  setAnalysisTaskQueuedHandler(handler) {
874
892
  this.analysisTaskQueuedHandler = handler;
875
893
  }
894
+ setChapterAnalysisInvalidatedHandler(handler) {
895
+ this.chapterAnalysisInvalidatedHandler = handler;
896
+ }
876
897
  setRelationshipIndexQueuedHandler(handler) {
877
898
  this.relationshipIndexQueuedHandler = handler;
878
899
  }
@@ -884,6 +905,14 @@ export class Store {
884
905
  // 自动运行调度失败不影响主写入路径
885
906
  }
886
907
  }
908
+ notifyChapterAnalysisInvalidated(workId, chapterId, versionNo) {
909
+ try {
910
+ this.chapterAnalysisInvalidatedHandler?.(workId, chapterId, versionNo);
911
+ }
912
+ catch {
913
+ // 稳定等待调度失败不影响主写入路径
914
+ }
915
+ }
887
916
  getWorkAiSettings(workId) {
888
917
  this.getWork(workId);
889
918
  const row = this.db.get("SELECT * FROM work_ai_settings WHERE work_id = ?", workId);
@@ -899,6 +928,7 @@ export class Store {
899
928
  autoRunBatchLimit: Math.min(200, Math.max(1, Number(row?.auto_run_batch_limit ?? 20) || 20)),
900
929
  autoRunDailyTaskLimit: Math.min(10_000, Math.max(0, Number(row?.auto_run_daily_task_limit ?? 0) || 0)),
901
930
  autoRunFailureThreshold: Math.min(10, Math.max(1, Number(row?.auto_run_failure_threshold ?? 3) || 3)),
931
+ autoRunStabilityDelayMinutes: Math.min(120, Math.max(1, Number(row?.auto_run_stability_delay_minutes ?? 2) || 2)),
902
932
  autoRunPaused: Number(row?.auto_run_paused ?? 0) === 1,
903
933
  autoRunPauseReason: String(row?.auto_run_pause_reason ?? ""),
904
934
  autoRunResumeAt: row?.auto_run_resume_at === null || row?.auto_run_resume_at === undefined ? null : String(row.auto_run_resume_at),
@@ -933,6 +963,7 @@ export class Store {
933
963
  const nextBatchLimit = input.autoRunBatchLimit ?? Number(current.autoRunBatchLimit);
934
964
  const nextDailyTaskLimit = input.autoRunDailyTaskLimit ?? Number(current.autoRunDailyTaskLimit);
935
965
  const nextFailureThreshold = input.autoRunFailureThreshold ?? Number(current.autoRunFailureThreshold);
966
+ const nextStabilityDelayMinutes = input.autoRunStabilityDelayMinutes ?? Number(current.autoRunStabilityDelayMinutes);
936
967
  const nextBookSummaryContextPercent = input.bookSummaryContextPercent ?? Number(current.bookSummaryContextPercent);
937
968
  const nextContextCompactThreshold = input.contextCompactThreshold ?? Number(current.contextCompactThreshold);
938
969
  const nextAgentToolCallLimit = input.agentToolCallLimit ?? Number(current.agentToolCallLimit);
@@ -947,11 +978,11 @@ export class Store {
947
978
  : input.titleGenerationModelId?.trim() || null;
948
979
  this.db.run(`INSERT INTO work_ai_settings (
949
980
  work_id, system_prompt, daily_token_quota, auto_run_enabled, auto_run_concurrency, auto_run_batch_limit,
950
- auto_run_daily_task_limit, auto_run_failure_threshold, auto_run_paused, auto_run_pause_reason,
981
+ auto_run_daily_task_limit, auto_run_failure_threshold, auto_run_stability_delay_minutes, auto_run_paused, auto_run_pause_reason,
951
982
  auto_run_resume_at, auto_run_consecutive_failures, book_summary_context_percent,
952
983
  context_compact_threshold, agent_tool_call_limit, agent_tool_call_global_multiplier,
953
984
  agent_tools_json, title_generation_model_id, image_tool_model_id, always_include_setting_info, updated_at
954
- ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
985
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
955
986
  ON CONFLICT(work_id) DO UPDATE SET
956
987
  system_prompt = excluded.system_prompt,
957
988
  daily_token_quota = excluded.daily_token_quota,
@@ -960,6 +991,7 @@ export class Store {
960
991
  auto_run_batch_limit = excluded.auto_run_batch_limit,
961
992
  auto_run_daily_task_limit = excluded.auto_run_daily_task_limit,
962
993
  auto_run_failure_threshold = excluded.auto_run_failure_threshold,
994
+ auto_run_stability_delay_minutes = excluded.auto_run_stability_delay_minutes,
963
995
  auto_run_paused = excluded.auto_run_paused,
964
996
  auto_run_pause_reason = excluded.auto_run_pause_reason,
965
997
  auto_run_resume_at = excluded.auto_run_resume_at,
@@ -972,7 +1004,7 @@ export class Store {
972
1004
  title_generation_model_id = excluded.title_generation_model_id,
973
1005
  image_tool_model_id = excluded.image_tool_model_id,
974
1006
  always_include_setting_info = excluded.always_include_setting_info,
975
- updated_at = excluded.updated_at`, workId, nextPrompt, nextDailyTokenQuota, nextEnabled ? 1 : 0, Math.min(8, Math.max(1, nextConcurrency)), Math.min(200, Math.max(1, nextBatchLimit)), Math.min(10_000, Math.max(0, nextDailyTaskLimit)), Math.min(10, Math.max(1, nextFailureThreshold)), current.autoRunPaused ? 1 : 0, String(current.autoRunPauseReason ?? ""), current.autoRunResumeAt === null ? null : String(current.autoRunResumeAt), Math.max(0, Number(current.autoRunConsecutiveFailures) || 0), Math.min(90, Math.max(1, nextBookSummaryContextPercent)), Math.min(90, Math.max(50, nextContextCompactThreshold)), Math.min(maximumAgentToolCallLimit, Math.max(5, nextAgentToolCallLimit)), Math.min(6, Math.max(1, nextAgentToolCallGlobalMultiplier)), JSON.stringify(nextAgentTools), nextTitleGenerationModelId, nextImageToolModelId, nextAlwaysIncludeSettingInfo ? 1 : 0, timestamp);
1007
+ updated_at = excluded.updated_at`, workId, nextPrompt, nextDailyTokenQuota, nextEnabled ? 1 : 0, Math.min(8, Math.max(1, nextConcurrency)), Math.min(200, Math.max(1, nextBatchLimit)), Math.min(10_000, Math.max(0, nextDailyTaskLimit)), Math.min(10, Math.max(1, nextFailureThreshold)), Math.min(120, Math.max(1, nextStabilityDelayMinutes)), current.autoRunPaused ? 1 : 0, String(current.autoRunPauseReason ?? ""), current.autoRunResumeAt === null ? null : String(current.autoRunResumeAt), Math.max(0, Number(current.autoRunConsecutiveFailures) || 0), Math.min(90, Math.max(1, nextBookSummaryContextPercent)), Math.min(90, Math.max(50, nextContextCompactThreshold)), Math.min(maximumAgentToolCallLimit, Math.max(5, nextAgentToolCallLimit)), Math.min(6, Math.max(1, nextAgentToolCallGlobalMultiplier)), JSON.stringify(nextAgentTools), nextTitleGenerationModelId, nextImageToolModelId, nextAlwaysIncludeSettingInfo ? 1 : 0, timestamp);
976
1008
  this.audit(workId, "work.ai-settings.updated", "work-ai-settings", workId, {
977
1009
  systemPromptChanged: input.systemPrompt !== undefined,
978
1010
  dailyTokenQuota: nextDailyTokenQuota,
@@ -981,6 +1013,7 @@ export class Store {
981
1013
  autoRunBatchLimit: Math.min(200, Math.max(1, nextBatchLimit)),
982
1014
  autoRunDailyTaskLimit: Math.min(10_000, Math.max(0, nextDailyTaskLimit)),
983
1015
  autoRunFailureThreshold: Math.min(10, Math.max(1, nextFailureThreshold)),
1016
+ autoRunStabilityDelayMinutes: Math.min(120, Math.max(1, nextStabilityDelayMinutes)),
984
1017
  bookSummaryContextPercent: Math.min(90, Math.max(1, nextBookSummaryContextPercent)),
985
1018
  contextCompactThreshold: Math.min(90, Math.max(50, nextContextCompactThreshold)),
986
1019
  agentToolCallLimit: Math.min(maximumAgentToolCallLimit, Math.max(5, nextAgentToolCallLimit)),
@@ -1851,6 +1884,16 @@ export class Store {
1851
1884
  throw new AppError(400, "REPLACE_SCOPE_INVALID", "替换范围无效");
1852
1885
  }
1853
1886
  const work = this.getWork(workId);
1887
+ const volumeId = input.volumeId ?? null;
1888
+ if (volumeId) {
1889
+ const volume = this.getVolume(volumeId);
1890
+ if (String(volume.workId) !== workId) {
1891
+ throw new AppError(400, "REPLACE_VOLUME_INVALID", "分卷不属于当前作品");
1892
+ }
1893
+ if (input.scope === "settings") {
1894
+ throw new AppError(400, "REPLACE_VOLUME_SCOPE_INVALID", "分卷范围只能用于正文替换");
1895
+ }
1896
+ }
1854
1897
  const permissions = work.modulePermissions;
1855
1898
  const requestedProse = input.scope === "prose" || input.scope === "prose-and-settings";
1856
1899
  const requestedSettings = input.scope === "settings" || input.scope === "prose-and-settings";
@@ -1887,7 +1930,9 @@ export class Store {
1887
1930
  };
1888
1931
  this.db.transaction(() => {
1889
1932
  if (includeProse) {
1890
- const chapters = this.db.all("SELECT id, content FROM chapters WHERE work_id = ? AND deleted_at IS NULL ORDER BY sort_order, created_at", workId);
1933
+ const chapters = volumeId
1934
+ ? this.db.all("SELECT id, content FROM chapters WHERE work_id = ? AND volume_id = ? AND deleted_at IS NULL ORDER BY sort_order, created_at", workId, volumeId)
1935
+ : this.db.all("SELECT id, content FROM chapters WHERE work_id = ? AND deleted_at IS NULL ORDER BY sort_order, created_at", workId);
1891
1936
  for (const row of chapters) {
1892
1937
  const chapterId = requiredString(row, "id");
1893
1938
  const result = replaceLiteral(requiredString(row, "content"));
@@ -1916,6 +1961,7 @@ export class Store {
1916
1961
  this.audit(workId, "work.global-replace", "work", workId, {
1917
1962
  operationId,
1918
1963
  scope: input.scope,
1964
+ volumeId,
1919
1965
  chapterCount,
1920
1966
  settingCount,
1921
1967
  totalMatches,
@@ -1927,6 +1973,7 @@ export class Store {
1927
1973
  return {
1928
1974
  operationId,
1929
1975
  scope: input.scope,
1976
+ volumeId,
1930
1977
  chapterCount,
1931
1978
  settingCount,
1932
1979
  totalMatches,
@@ -2114,6 +2161,7 @@ export class Store {
2114
2161
  note: requiredString(row, "note"),
2115
2162
  status: requiredString(row, "status"),
2116
2163
  versionNo: numberValue(row, "version_no"),
2164
+ createdByUserId: optionalString(row, "created_by_user_id"),
2117
2165
  actor: optionalString(row, "actor_display_name") ?? optionalString(row, "actor_username") ?? "历史数据",
2118
2166
  createdAt: requiredString(row, "created_at"),
2119
2167
  updatedAt: requiredString(row, "updated_at")
@@ -2142,47 +2190,86 @@ export class Store {
2142
2190
  throw notFound("章节批注");
2143
2191
  return { ...this.mapChapterAnnotation(row), deletedAt: optionalString(row, "deleted_at") };
2144
2192
  }
2145
- listChapterAnnotations(chapterId) {
2193
+ listChapterAnnotations(chapterId, kinds, line) {
2146
2194
  this.getChapter(chapterId);
2195
+ const kindFilter = kinds === undefined
2196
+ ? { sql: "", params: [] }
2197
+ : kinds.length > 0
2198
+ ? { sql: ` AND annotation.kind IN (${kinds.map(() => "?").join(",")})`, params: [...kinds] }
2199
+ : { sql: " AND 1 = 0", params: [] };
2200
+ const lineFilter = line === undefined
2201
+ ? { sql: "", params: [] }
2202
+ : { sql: " AND annotation.start_line <= ? AND annotation.end_line >= ?", params: [line, line] };
2147
2203
  return this.db.all(`SELECT annotation.*, user.display_name AS actor_display_name, user.username AS actor_username
2148
2204
  FROM chapter_annotations annotation LEFT JOIN users user ON user.id = annotation.updated_by_user_id
2149
- WHERE annotation.chapter_id = ? AND annotation.deleted_at IS NULL
2150
- ORDER BY CASE annotation.status WHEN 'open' THEN 0 ELSE 1 END, annotation.start_line, annotation.created_at`, chapterId).map((row) => this.mapChapterAnnotation(row));
2205
+ WHERE annotation.chapter_id = ? AND annotation.deleted_at IS NULL${kindFilter.sql}${lineFilter.sql}
2206
+ ORDER BY CASE annotation.status WHEN 'open' THEN 0 ELSE 1 END, annotation.start_line, annotation.created_at`, chapterId, ...kindFilter.params, ...lineFilter.params).map((row) => this.mapChapterAnnotation(row));
2151
2207
  }
2152
- listWorkChapterAnnotations(workId) {
2208
+ listChapterAnnotationCounts(chapterId, kinds) {
2209
+ this.getChapter(chapterId);
2210
+ const kindFilter = kinds === undefined
2211
+ ? { sql: "", params: [] }
2212
+ : kinds.length > 0
2213
+ ? { sql: ` AND annotation.kind IN (${kinds.map(() => "?").join(",")})`, params: [...kinds] }
2214
+ : { sql: " AND 1 = 0", params: [] };
2215
+ return this.db.all(`WITH RECURSIVE annotation_lines(line, end_line) AS (
2216
+ SELECT annotation.start_line, annotation.end_line
2217
+ FROM chapter_annotations annotation
2218
+ WHERE annotation.chapter_id = ? AND annotation.deleted_at IS NULL${kindFilter.sql}
2219
+ UNION ALL
2220
+ SELECT line + 1, end_line
2221
+ FROM annotation_lines
2222
+ WHERE line < end_line
2223
+ )
2224
+ SELECT line, COUNT(*) AS count
2225
+ FROM annotation_lines
2226
+ GROUP BY line
2227
+ ORDER BY line`, chapterId, ...kindFilter.params).map((row) => ({ line: Number(row.line), count: Number(row.count) }));
2228
+ }
2229
+ listWorkChapterAnnotations(workId, kinds) {
2153
2230
  this.getWork(workId);
2231
+ const kindFilter = kinds === undefined
2232
+ ? { sql: "", params: [] }
2233
+ : kinds.length > 0
2234
+ ? { sql: ` AND annotation.kind IN (${kinds.map(() => "?").join(",")})`, params: [...kinds] }
2235
+ : { sql: " AND 1 = 0", params: [] };
2154
2236
  return this.db.all(`SELECT annotation.*, user.display_name AS actor_display_name, user.username AS actor_username,
2155
2237
  chapter.title AS chapter_title, volume.title AS volume_title
2156
2238
  FROM chapter_annotations annotation
2157
2239
  JOIN chapters chapter ON chapter.id = annotation.chapter_id
2158
2240
  JOIN volumes volume ON volume.id = chapter.volume_id
2159
2241
  LEFT JOIN users user ON user.id = annotation.updated_by_user_id
2160
- WHERE annotation.work_id = ? AND annotation.deleted_at IS NULL AND chapter.deleted_at IS NULL
2242
+ WHERE annotation.work_id = ? AND annotation.deleted_at IS NULL AND chapter.deleted_at IS NULL${kindFilter.sql}
2161
2243
  ORDER BY CASE annotation.status WHEN 'open' THEN 0 ELSE 1 END,
2162
2244
  volume.sort_order, volume.created_at, chapter.sort_order, chapter.created_at,
2163
- annotation.start_line, annotation.created_at`, workId).map((row) => ({
2245
+ annotation.start_line, annotation.created_at`, workId, ...kindFilter.params).map((row) => ({
2164
2246
  ...this.mapChapterAnnotation(row),
2165
2247
  volumeTitle: requiredString(row, "volume_title"),
2166
2248
  chapterTitle: requiredString(row, "chapter_title")
2167
2249
  }));
2168
2250
  }
2169
- listWorkChapterAnnotationsPage(workId, pagination) {
2251
+ listWorkChapterAnnotationsPage(workId, pagination, kinds) {
2170
2252
  this.getWork(workId);
2171
2253
  const page = paginationSql(pagination);
2254
+ const kindFilter = kinds === undefined
2255
+ ? { sql: "", params: [] }
2256
+ : kinds.length > 0
2257
+ ? { sql: ` AND annotation.kind IN (${kinds.map(() => "?").join(",")})`, params: [...kinds] }
2258
+ : { sql: " AND 1 = 0", params: [] };
2172
2259
  const rows = this.db.all(`SELECT annotation.*, user.display_name AS actor_display_name, user.username AS actor_username,
2173
2260
  chapter.title AS chapter_title, volume.title AS volume_title
2174
2261
  FROM chapter_annotations annotation
2175
2262
  JOIN chapters chapter ON chapter.id = annotation.chapter_id
2176
2263
  JOIN volumes volume ON volume.id = chapter.volume_id
2177
2264
  LEFT JOIN users user ON user.id = annotation.updated_by_user_id
2178
- WHERE annotation.work_id = ? AND annotation.deleted_at IS NULL AND chapter.deleted_at IS NULL
2265
+ WHERE annotation.work_id = ? AND annotation.deleted_at IS NULL AND chapter.deleted_at IS NULL${kindFilter.sql}
2179
2266
  ORDER BY CASE annotation.status WHEN 'open' THEN 0 ELSE 1 END,
2180
2267
  volume.sort_order, volume.created_at, chapter.sort_order, chapter.created_at,
2181
- annotation.start_line, annotation.created_at${page.sql}`, workId, ...page.params);
2268
+ annotation.start_line, annotation.created_at${page.sql}`, workId, ...kindFilter.params, ...page.params);
2182
2269
  const total = numberValue(this.db.get(`SELECT COUNT(*) AS count
2183
2270
  FROM chapter_annotations annotation
2184
2271
  JOIN chapters chapter ON chapter.id = annotation.chapter_id
2185
- WHERE annotation.work_id = ? AND annotation.deleted_at IS NULL AND chapter.deleted_at IS NULL`, workId) ?? {}, "count");
2272
+ WHERE annotation.work_id = ? AND annotation.deleted_at IS NULL AND chapter.deleted_at IS NULL${kindFilter.sql}`, workId, ...kindFilter.params) ?? {}, "count");
2186
2273
  return paginated(rows.map((row) => ({
2187
2274
  ...this.mapChapterAnnotation(row),
2188
2275
  volumeTitle: requiredString(row, "volume_title"),
@@ -2485,8 +2572,6 @@ export class Store {
2485
2572
  invalidateChapter(workId, chapterId, versionNo) {
2486
2573
  this.db.run(`UPDATE analysis_tasks SET status = 'expired', updated_at = ?
2487
2574
  WHERE work_id = ? AND status IN ('pending', 'running', 'completed', 'partial', 'review')
2488
- AND NOT (status = 'pending' AND task_type = 'chapter-analysis'
2489
- AND json_extract(scope_json, '$.chapterId') = ?)
2490
2575
  AND (json_extract(scope_json, '$.chapterId') = ?
2491
2576
  OR EXISTS (SELECT 1 FROM json_each(scope_json, '$.chapterIds') WHERE json_each.value = ?)
2492
2577
  OR json_extract(scope_json, '$.type') = 'book'
@@ -2495,18 +2580,8 @@ export class Store {
2495
2580
  OR EXISTS (
2496
2581
  SELECT 1 FROM json_each(scope_json, '$.volumeIds')
2497
2582
  WHERE json_each.value = (SELECT volume_id FROM chapters WHERE id = ?)
2498
- ))))`, now(), workId, chapterId, chapterId, chapterId, chapterId, chapterId);
2499
- const existing = this.db.get(`SELECT id FROM analysis_tasks WHERE work_id = ? AND task_type = 'chapter-analysis' AND status = 'pending'
2500
- AND json_extract(scope_json, '$.chapterId') = ?`, workId, chapterId);
2501
- if (!existing) {
2502
- const timestamp = now();
2503
- this.db.run(`INSERT INTO analysis_tasks (id, work_id, task_type, scope_json, status, source_versions_json, created_at, updated_at, created_by_user_id)
2504
- VALUES (?, ?, 'chapter-analysis', ?, 'pending', ?, ?, ?, ?)`, id("task"), workId, JSON.stringify({ type: "chapter", chapterId }), JSON.stringify({ [chapterId]: versionNo }), timestamp, timestamp, currentRequestActor()?.userId ?? null);
2505
- }
2506
- else {
2507
- this.db.run("UPDATE analysis_tasks SET source_versions_json = ?, updated_at = ? WHERE id = ?", JSON.stringify({ [chapterId]: versionNo }), now(), requiredString(existing, "id"));
2508
- }
2509
- this.notifyAnalysisTaskQueued(workId);
2583
+ ))))`, now(), workId, chapterId, chapterId, chapterId, chapterId);
2584
+ this.notifyChapterAnalysisInvalidated(workId, chapterId, versionNo);
2510
2585
  }
2511
2586
  mapWorks(rows) {
2512
2587
  if (rows.length === 0)
@@ -4021,6 +4096,7 @@ export class Store {
4021
4096
  delete profile.sections;
4022
4097
  return {
4023
4098
  name: String(character.name),
4099
+ gender: characterGender(character.gender),
4024
4100
  isDead: Boolean(character.isDead),
4025
4101
  code: String(character.code),
4026
4102
  aliases: [...character.aliases],
@@ -4074,9 +4150,9 @@ export class Store {
4074
4150
  const organizationIds = [...new Set(input.organizationIds ?? [])];
4075
4151
  this.assertOrganizationsInWork(workId, organizationIds);
4076
4152
  this.db.transaction(() => {
4077
- this.db.run(`INSERT INTO characters (id, work_id, name, code, aliases_json, species, race_id, attributes_json, profile_json, current_state_json,
4153
+ this.db.run(`INSERT INTO characters (id, work_id, name, code, gender, aliases_json, species, race_id, attributes_json, profile_json, current_state_json,
4078
4154
  is_dead, locked_fields_json, first_chapter_id, created_at, updated_at)
4079
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, characterId, workId, names.name, input.code?.trim() ?? "", JSON.stringify(names.aliases), species, raceId, JSON.stringify(input.attributes ?? {}), JSON.stringify(input.profile ?? {}), JSON.stringify(input.currentState ?? {}), input.isDead ? 1 : 0, JSON.stringify(input.lockedFields ?? []), input.firstChapterId ?? null, timestamp, timestamp);
4155
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, characterId, workId, names.name, input.code?.trim() ?? "", input.gender ?? "unknown", JSON.stringify(names.aliases), species, raceId, JSON.stringify(input.attributes ?? {}), JSON.stringify(input.profile ?? {}), JSON.stringify(input.currentState ?? {}), input.isDead ? 1 : 0, JSON.stringify(input.lockedFields ?? []), input.firstChapterId ?? null, timestamp, timestamp);
4080
4156
  this.insertCharacterNames(workId, characterId, names.entries);
4081
4157
  this.replaceCharacterOrganizations(characterId, organizationIds);
4082
4158
  this.insertCharacterVersion(characterId, 1, source, sourceRef, changeNote, timestamp);
@@ -4311,7 +4387,8 @@ export class Store {
4311
4387
  searchCharacterProfileSections(workId, query, limit = 20) {
4312
4388
  this.getWork(workId);
4313
4389
  const normalized = normalizeDocumentSearchText(query);
4314
- const columns = `SELECT section.*, character.name AS character_name, character.is_dead AS character_is_dead
4390
+ const columns = `SELECT section.*, character.name AS character_name, character.gender AS character_gender,
4391
+ character.is_dead AS character_is_dead
4315
4392
  FROM character_profile_section_search search
4316
4393
  JOIN character_profile_sections section ON section.id = search.section_id
4317
4394
  JOIN characters character ON character.id = search.character_id`;
@@ -4326,6 +4403,7 @@ export class Store {
4326
4403
  return rows.map((row) => ({
4327
4404
  ...this.mapCharacterProfileSection(row),
4328
4405
  characterName: requiredString(row, "character_name"),
4406
+ gender: requiredString(row, "character_gender"),
4329
4407
  isDead: booleanValue(row, "character_is_dead")
4330
4408
  }));
4331
4409
  }
@@ -4553,8 +4631,8 @@ export class Store {
4553
4631
  this.db.transaction(() => {
4554
4632
  const lockedCurrent = this.getCharacter(characterId);
4555
4633
  this.assertExpectedRevision("character", characterId, expectedVersionNo, "人物", Number(lockedCurrent.versionNo));
4556
- this.db.run(`UPDATE characters SET name = ?, code = ?, aliases_json = ?, species = ?, race_id = ?, attributes_json = ?, profile_json = ?, current_state_json = ?,
4557
- is_dead = ?, locked_fields_json = ?, first_chapter_id = ?, updated_at = ? WHERE id = ?`, names.name, input.code === undefined ? String(current.code) : input.code.trim(), JSON.stringify(names.aliases), species, raceId, JSON.stringify(attributes), JSON.stringify(input.profile ?? current.profile), JSON.stringify(input.currentState ?? current.currentState), input.isDead === undefined ? (current.isDead ? 1 : 0) : (input.isDead ? 1 : 0), JSON.stringify(input.lockedFields ?? current.lockedFields), input.firstChapterId === undefined ? current.firstChapterId : input.firstChapterId, now(), characterId);
4634
+ this.db.run(`UPDATE characters SET name = ?, code = ?, gender = ?, aliases_json = ?, species = ?, race_id = ?, attributes_json = ?, profile_json = ?, current_state_json = ?,
4635
+ is_dead = ?, locked_fields_json = ?, first_chapter_id = ?, updated_at = ? WHERE id = ?`, names.name, input.code === undefined ? String(current.code) : input.code.trim(), input.gender ?? characterGender(current.gender), JSON.stringify(names.aliases), species, raceId, JSON.stringify(attributes), JSON.stringify(input.profile ?? current.profile), JSON.stringify(input.currentState ?? current.currentState), input.isDead === undefined ? (current.isDead ? 1 : 0) : (input.isDead ? 1 : 0), JSON.stringify(input.lockedFields ?? current.lockedFields), input.firstChapterId === undefined ? current.firstChapterId : input.firstChapterId, now(), characterId);
4558
4636
  this.db.run("DELETE FROM character_names WHERE character_id = ?", characterId);
4559
4637
  this.insertCharacterNames(workId, characterId, names.entries);
4560
4638
  if (organizationIds)
@@ -4623,7 +4701,7 @@ export class Store {
4623
4701
  this.assertExpectedRevision("character", characterId, expectedVersionNo, "人物", this.currentCharacterVersionNo(characterId));
4624
4702
  return this.recreateCharacterFromVersion(characterId, version, snapshot, versionNo);
4625
4703
  }
4626
- return this.updateCharacter(characterId, { ...snapshot, isDead: snapshot.isDead ?? false, code: snapshot.code ?? "" }, "restore", requiredString(version, "id"), `恢复至 v${versionNo}`, expectedVersionNo);
4704
+ return this.updateCharacter(characterId, { ...snapshot, gender: snapshot.gender ?? "unknown", isDead: snapshot.isDead ?? false, code: snapshot.code ?? "" }, "restore", requiredString(version, "id"), `恢复至 v${versionNo}`, expectedVersionNo);
4627
4705
  }
4628
4706
  recreateCharacterFromVersion(characterId, version, snapshot, versionNo) {
4629
4707
  const workId = requiredString(version, "work_id");
@@ -4640,9 +4718,9 @@ export class Store {
4640
4718
  const timestamp = now();
4641
4719
  const nextVersionNo = numberValue(this.db.get("SELECT COALESCE(MAX(version_no), 0) AS version_no FROM character_versions WHERE character_id = ?", characterId) ?? {}, "version_no") + 1;
4642
4720
  this.db.transaction(() => {
4643
- this.db.run(`INSERT INTO characters (id, work_id, name, code, aliases_json, species, race_id, attributes_json, profile_json, current_state_json,
4721
+ this.db.run(`INSERT INTO characters (id, work_id, name, code, gender, aliases_json, species, race_id, attributes_json, profile_json, current_state_json,
4644
4722
  is_dead, locked_fields_json, first_chapter_id, version_no, created_at, updated_at)
4645
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, characterId, workId, names.name, snapshot.code ?? "", JSON.stringify(names.aliases), species, raceId, JSON.stringify(snapshot.attributes ?? {}), JSON.stringify(snapshot.profile ?? {}), JSON.stringify(snapshot.currentState ?? {}), snapshot.isDead ? 1 : 0, JSON.stringify(snapshot.lockedFields ?? []), snapshot.firstChapterId ?? null, nextVersionNo, timestamp, timestamp);
4723
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, characterId, workId, names.name, snapshot.code ?? "", snapshot.gender ?? "unknown", JSON.stringify(names.aliases), species, raceId, JSON.stringify(snapshot.attributes ?? {}), JSON.stringify(snapshot.profile ?? {}), JSON.stringify(snapshot.currentState ?? {}), snapshot.isDead ? 1 : 0, JSON.stringify(snapshot.lockedFields ?? []), snapshot.firstChapterId ?? null, nextVersionNo, timestamp, timestamp);
4646
4724
  this.insertCharacterNames(workId, characterId, names.entries);
4647
4725
  this.replaceCharacterOrganizations(characterId, organizationIds);
4648
4726
  this.insertCharacterVersion(characterId, nextVersionNo, "restore", requiredString(version, "id"), `恢复至 v${versionNo}`, timestamp, workId);
@@ -4719,6 +4797,7 @@ export class Store {
4719
4797
  workId: requiredString(row, "work_id"),
4720
4798
  name: requiredString(row, "name"),
4721
4799
  code: requiredString(row, "code"),
4800
+ gender: characterGender(row.gender),
4722
4801
  aliases: indexedAliases.length > 0 ? indexedAliases : json(requiredString(row, "aliases_json"), []),
4723
4802
  raceId: race ? String(race.id) : null,
4724
4803
  race: race ? {
@@ -7375,15 +7454,16 @@ export class Store {
7375
7454
  }
7376
7455
  taskScopeSummaryFromMaps(scope, chapterSummaries, volumeTitles, characterNames, includeCharacterNames = true) {
7377
7456
  const targetedSuffix = this.taskTargetedSuffix(scope, characterNames, includeCharacterNames);
7457
+ const chapterSettingsLabel = scope.includeAllSettings === true ? " + 设定集" : "";
7378
7458
  if (Array.isArray(scope.chapterIds) && scope.chapterIds.length > 0) {
7379
7459
  const labels = scope.chapterIds
7380
7460
  .filter((chapterId) => typeof chapterId === "string")
7381
7461
  .map((chapterId) => chapterSummaries.get(chapterId) ?? "章节已删除");
7382
7462
  const preview = labels.slice(0, 3).join("、");
7383
- return `指定章节(${labels.length}):${preview}${labels.length > 3 ? "……" : ""}${targetedSuffix}`;
7463
+ return `指定章节${chapterSettingsLabel}(${labels.length}):${preview}${labels.length > 3 ? "……" : ""}${targetedSuffix}`;
7384
7464
  }
7385
7465
  if (typeof scope.chapterId === "string")
7386
- return `${chapterSummaries.get(scope.chapterId) ?? "章节已删除"}${targetedSuffix}`;
7466
+ return `${chapterSummaries.get(scope.chapterId) ?? "章节已删除"}${chapterSettingsLabel}${targetedSuffix}`;
7387
7467
  if (Array.isArray(scope.volumeIds) && scope.volumeIds.length > 0) {
7388
7468
  const labels = scope.volumeIds
7389
7469
  .filter((volumeId) => typeof volumeId === "string")
@@ -7409,6 +7489,7 @@ export class Store {
7409
7489
  }
7410
7490
  taskScopeSummary(workId, scope, characterNames, includeCharacterNames = true) {
7411
7491
  const targetedSuffix = this.taskTargetedSuffix(scope, characterNames, includeCharacterNames);
7492
+ const chapterSettingsLabel = scope.includeAllSettings === true ? " + 设定集" : "";
7412
7493
  if (Array.isArray(scope.chapterIds) && scope.chapterIds.length > 0) {
7413
7494
  const labels = scope.chapterIds.map((chapterId) => {
7414
7495
  const chapter = this.db.get(`SELECT chapter.title AS title, volume.title AS volume_title
@@ -7418,7 +7499,7 @@ export class Store {
7418
7499
  return chapter ? `${requiredString(chapter, "volume_title")} · ${requiredString(chapter, "title")}` : "章节已删除";
7419
7500
  });
7420
7501
  const preview = labels.slice(0, 3).join("、");
7421
- return `指定章节(${labels.length}):${preview}${labels.length > 3 ? "……" : ""}${targetedSuffix}`;
7502
+ return `指定章节${chapterSettingsLabel}(${labels.length}):${preview}${labels.length > 3 ? "……" : ""}${targetedSuffix}`;
7422
7503
  }
7423
7504
  if (typeof scope.chapterId === "string") {
7424
7505
  const chapter = this.db.get(`SELECT chapter.title AS title, volume.title AS volume_title
@@ -7426,10 +7507,10 @@ export class Store {
7426
7507
  JOIN volumes volume ON volume.id = chapter.volume_id
7427
7508
  WHERE chapter.id = ? AND chapter.work_id = ? AND chapter.deleted_at IS NULL`, scope.chapterId, workId);
7428
7509
  if (!chapter)
7429
- return `章节已删除${targetedSuffix}`;
7510
+ return `章节已删除${chapterSettingsLabel}${targetedSuffix}`;
7430
7511
  const title = requiredString(chapter, "title");
7431
7512
  const volumeTitle = requiredString(chapter, "volume_title");
7432
- return `${volumeTitle} · ${title}${targetedSuffix}`;
7513
+ return `${volumeTitle} · ${title}${chapterSettingsLabel}${targetedSuffix}`;
7433
7514
  }
7434
7515
  if (Array.isArray(scope.volumeIds) && scope.volumeIds.length > 0) {
7435
7516
  const labels = scope.volumeIds.map((volumeId) => {
@@ -7668,7 +7749,7 @@ export class Store {
7668
7749
  ), character_race_paths AS (
7669
7750
  SELECT character_id, path FROM character_race_lineage WHERE parent_race_id IS NULL
7670
7751
  )
7671
- SELECT character.id, character.name, character.aliases_json, character.species, character.is_dead,
7752
+ SELECT character.id, character.name, character.aliases_json, character.species, character.gender, character.is_dead,
7672
7753
  COALESCE(path.path, character.species) AS race_path
7673
7754
  FROM characters character LEFT JOIN character_race_paths path ON path.character_id = character.id
7674
7755
  WHERE character.work_id = ? AND character.merged_into_character_id IS NULL AND (
@@ -7691,6 +7772,7 @@ export class Store {
7691
7772
  title: requiredString(row, "name"),
7692
7773
  snippet: [requiredString(row, "race_path"), ...json(requiredString(row, "aliases_json"), [])].filter(Boolean).join("、"),
7693
7774
  racePath: requiredString(row, "race_path"),
7775
+ gender: requiredString(row, "gender"),
7694
7776
  isDead: booleanValue(row, "is_dead")
7695
7777
  })),
7696
7778
  ...characterSections.map((section) => ({
@@ -7700,6 +7782,7 @@ export class Store {
7700
7782
  title: `${String(section.characterName)} / ${String(section.title)}`,
7701
7783
  snippet: snippet(String(section.contentMarkdown)),
7702
7784
  sectionType: String(section.sectionType),
7785
+ gender: String(section.gender),
7703
7786
  isDead: Boolean(section.isDead)
7704
7787
  })),
7705
7788
  ...settings.map((row) => ({ type: "setting", id: requiredString(row, "id"), title: requiredString(row, "title"), snippet: snippet(requiredString(row, "content")), category: requiredString(row, "category") })),