@musnows/scriverse 0.6.11 → 0.7.0

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.
@@ -944,6 +944,27 @@ body.work-viewer-mode .character-editor-actions { display: none !important; }
944
944
  font-size: 13px;
945
945
  }
946
946
  .search-form .primary-button { min-height: 38px; white-space: nowrap; }
947
+ .replace-dialog { display: flex; width: min(620px, calc(100vw - 32px)); height: min(680px, calc(100dvh - 32px)); max-height: calc(100dvh - 32px); overflow: hidden; }
948
+ .replace-dialog:not([open]) { display: none; }
949
+ .replace-dialog > form { display: grid; grid-template-rows: auto minmax(0, 1fr) auto; width: 100%; min-height: 0; }
950
+ .replace-dialog-body { display: grid; min-height: 0; gap: 16px; padding: 20px 24px 6px; overflow-y: auto; }
951
+ .replace-field { display: grid; gap: 6px; color: var(--muted); font-size: 11px; }
952
+ .replace-field input, .replace-field textarea { width: 100%; padding: 9px 10px; border: 1px solid var(--line); border-radius: 4px; background: var(--surface); color: var(--ink); font-size: 13px; line-height: 1.6; }
953
+ .replace-field textarea { min-height: 96px; resize: vertical; }
954
+ .replace-scope-fieldset { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; margin: 0; padding: 12px; border: 1px solid var(--line); border-radius: 6px; background: var(--surface-soft); }
955
+ .replace-scope-fieldset legend { padding: 0 6px; color: var(--ink); font-size: 12px; font-weight: 650; }
956
+ .replace-scope-fieldset legend, .replace-scope-fieldset > p { grid-column: 1 / -1; }
957
+ .replace-scope-fieldset > p { margin: -1px 0 1px; color: var(--muted); font-size: 10px; line-height: 1.5; }
958
+ .replace-scope-option { display: grid; grid-template-columns: 18px minmax(0, 1fr); align-items: start; gap: 7px; min-width: 0; padding: 8px; border: 1px solid var(--line); border-radius: 5px; background: var(--surface); cursor: pointer; }
959
+ .replace-scope-option > span { display: grid; gap: 3px; min-width: 0; }
960
+ .replace-scope-option strong { color: var(--ink); font-size: 12px; }
961
+ .replace-scope-option small { color: var(--muted); font-size: 10px; line-height: 1.45; }
962
+ .replace-scope-option:has(input:checked) { border-color: var(--accent); background: color-mix(in srgb, var(--accent) 8%, var(--surface)); box-shadow: inset 0 0 0 1px var(--accent); }
963
+ .replace-scope-option.is-disabled, .replace-scope-option:has(input:disabled) { cursor: not-allowed; opacity: .5; }
964
+ .replace-scope-option input:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
965
+ .replace-permission-note { margin: 0; color: var(--accent-dark); font-size: 10px; line-height: 1.5; }
966
+ .replace-permission-note:empty { display: none; }
967
+ .replace-dialog .primary-button:disabled { cursor: not-allowed; opacity: .42; }
947
968
  .search-results { display: grid; gap: 8px; max-height: min(52vh, 480px); overflow: auto; }
948
969
  .search-results-summary { margin: 0; padding: 2px 2px 5px; color: var(--muted); font-size: 10px; }
949
970
  .search-results-empty, .search-results-status {
@@ -1479,7 +1500,7 @@ select:focus, input:focus, textarea:focus { border-color: #a77768; box-shadow: 0
1479
1500
  .platform-image-tool-panel .config-save-button { flex: 0 0 auto; min-height: 36px; padding: 8px 14px; }
1480
1501
  .task-auto-run-panel {
1481
1502
  display: grid;
1482
- grid-template-columns: minmax(0, 1fr) 148px;
1503
+ grid-template-columns: minmax(0, 1fr) 268px;
1483
1504
  gap: 12px;
1484
1505
  column-gap: 24px;
1485
1506
  margin-bottom: 22px;
@@ -1488,12 +1509,13 @@ select:focus, input:focus, textarea:focus { border-color: #a77768; box-shadow: 0
1488
1509
  border-radius: 5px;
1489
1510
  background: var(--surface-soft);
1490
1511
  }
1491
- .task-auto-run-header { display: grid; grid-column: 1; grid-template-columns: minmax(0, 1fr) auto; align-items: start; gap: 12px; }
1512
+ .task-auto-run-header { display: grid; grid-column: 1 / -1; grid-template-columns: minmax(0, 1fr) auto; align-items: start; gap: 12px; }
1492
1513
  .task-auto-run-copy { display: grid; gap: 4px; }
1493
1514
  .task-auto-run-copy strong { font-size: 13px; }
1494
1515
  .task-auto-run-copy small { color: var(--muted); font-size: 10px; line-height: 1.5; }
1495
1516
  .task-auto-run-actions { display: flex; align-items: start; justify-content: flex-end; min-height: 32px; }
1496
1517
  .task-auto-run-actions:empty { display: none; }
1518
+ .task-auto-run-actions .record-card-edit { position: static; flex: 0 0 32px; width: 32px; height: 32px; }
1497
1519
  .task-auto-run-controls {
1498
1520
  display: flex;
1499
1521
  grid-column: 1;
@@ -1525,12 +1547,12 @@ select:focus, input:focus, textarea:focus { border-color: #a77768; box-shadow: 0
1525
1547
  .task-auto-run-progress {
1526
1548
  display: grid;
1527
1549
  grid-column: 2;
1528
- grid-row: 1 / 4;
1550
+ grid-row: 2 / 5;
1529
1551
  align-self: center;
1530
- justify-self: center;
1531
- width: 132px;
1552
+ justify-self: start;
1553
+ width: 192px;
1532
1554
  }
1533
- .task-auto-run-progress-ring { position: relative; display: grid; width: 132px; height: 132px; place-items: center; }
1555
+ .task-auto-run-progress-ring { position: relative; display: grid; width: 192px; height: 192px; place-items: center; }
1534
1556
  .task-auto-run-progress-ring svg { display: block; width: 100%; height: 100%; overflow: visible; transform: rotate(-90deg); }
1535
1557
  .task-auto-run-progress-ring-track, .task-auto-run-progress-ring-value { fill: none; stroke-width: 8; }
1536
1558
  .task-auto-run-progress-ring-track { stroke: color-mix(in srgb, var(--line) 72%, transparent); }
@@ -1538,9 +1560,9 @@ select:focus, input:focus, textarea:focus { border-color: #a77768; box-shadow: 0
1538
1560
  .task-auto-run-progress-ring.is-running svg { animation: task-auto-run-active 1.8s ease-in-out infinite; }
1539
1561
  .task-auto-run-progress-ring.is-running .task-auto-run-progress-ring-value { stroke: var(--task-running); }
1540
1562
  .task-auto-run-progress-ring.is-paused .task-auto-run-progress-ring-value { stroke: var(--accent); }
1541
- .task-auto-run-progress-ring-label { position: absolute; inset: 22px; display: grid; align-content: center; justify-items: center; gap: 3px; text-align: center; }
1542
- .task-auto-run-progress-ring-label strong { color: var(--ink); font-family: var(--font-latin), monospace; font-size: 22px; font-weight: 600; line-height: 1; }
1543
- .task-auto-run-progress-ring-label span { color: var(--muted); font-size: 9px; line-height: 1.35; }
1563
+ .task-auto-run-progress-ring-label { position: absolute; inset: 32px; display: grid; align-content: center; justify-items: center; gap: 4px; text-align: center; }
1564
+ .task-auto-run-progress-ring-label strong { color: var(--ink); font-family: var(--font-latin), monospace; font-size: 28px; font-weight: 600; line-height: 1; }
1565
+ .task-auto-run-progress-ring-label span { color: var(--muted); font-size: 10px; line-height: 1.35; }
1544
1566
  .task-auto-run-progress-bar-layout { display: none; }
1545
1567
  .task-auto-run-progress-label { display: flex; align-items: center; justify-content: space-between; gap: 12px; color: var(--muted); font-size: 10px; }
1546
1568
  .task-auto-run-progress-label strong { color: var(--ink); font-family: var(--font-latin), monospace; font-size: 10px; font-weight: 600; }
@@ -1626,6 +1648,23 @@ select:focus, input:focus, textarea:focus { border-color: #a77768; box-shadow: 0
1626
1648
  background: color-mix(in srgb, var(--accent) 32%, transparent);
1627
1649
  animation: task-progress-waiting 1.9s ease-in-out infinite;
1628
1650
  }
1651
+ .task-scope-link, .task-reference-link {
1652
+ display: inline;
1653
+ margin: 0;
1654
+ padding: 0;
1655
+ border: 0;
1656
+ border-bottom: 1px dashed color-mix(in srgb, var(--accent) 58%, var(--line));
1657
+ background: transparent;
1658
+ color: var(--accent-dark);
1659
+ font: inherit;
1660
+ text-align: left;
1661
+ cursor: pointer;
1662
+ }
1663
+ .task-scope-link:hover, .task-scope-link:focus-visible, .task-reference-link:hover, .task-reference-link:focus-visible {
1664
+ border-bottom-style: solid;
1665
+ color: var(--accent);
1666
+ outline: none;
1667
+ }
1629
1668
  @keyframes task-auto-run-active { 0%, 100% { filter: drop-shadow(0 0 0 transparent); opacity: .72; } 50% { filter: drop-shadow(0 0 4px color-mix(in srgb, var(--green) 42%, transparent)); opacity: 1; } }
1630
1669
  @keyframes task-status-waiting { 0%, 100% { opacity: .45; transform: scale(.74); } 50% { opacity: 1; transform: scale(1); } }
1631
1670
  @keyframes task-status-running-breathe { 0%, 100% { background: color-mix(in srgb, var(--green) 5%, transparent); box-shadow: 0 0 0 0 transparent; opacity: .72; } 50% { background: color-mix(in srgb, var(--green) 16%, transparent); box-shadow: 0 0 12px color-mix(in srgb, var(--green) 20%, transparent); opacity: 1; } }
@@ -1690,8 +1729,8 @@ select:focus, input:focus, textarea:focus { border-color: #a77768; box-shadow: 0
1690
1729
  .task-result-item summary, .task-result-technical > summary { width: fit-content; cursor: pointer; color: var(--accent-dark); font-size: 10px; }
1691
1730
  .task-result-evidence { display: grid; gap: 7px; margin-top: 8px !important; padding-left: 17px !important; }
1692
1731
  .task-result-evidence li { padding-left: 2px; }
1693
- .task-result-evidence li strong, .task-result-evidence li q, .task-result-evidence li small { display: block; }
1694
- .task-result-evidence li strong { font-size: 10px; }
1732
+ .task-result-evidence li strong, .task-result-evidence li button, .task-result-evidence li q, .task-result-evidence li small { display: block; }
1733
+ .task-result-evidence li strong, .task-result-evidence li button { font-size: 10px; }
1695
1734
  .task-result-evidence li q { margin-top: 2px; color: var(--ink); }
1696
1735
  .task-result-evidence li small, .task-result-muted { color: var(--muted); }
1697
1736
  .task-result-empty, .task-result-warning { padding: 9px; border-radius: 5px; background: var(--surface-soft); color: var(--muted); }
@@ -3325,6 +3364,10 @@ select:focus, input:focus, textarea:focus { border-color: #a77768; box-shadow: 0
3325
3364
  .dialog-header h2 { font-size: 20px; }
3326
3365
  .settings-dialog-header-actions { gap: 6px; }
3327
3366
  .dialog-fields, .appearance-grid, .access-dialog-body, .account-settings-body, .versions-list, .entity-history-list, .chapter-annotations-list { padding-inline: 16px; }
3367
+ .replace-dialog-body { padding-inline: 16px; }
3368
+ .replace-dialog { height: calc(100dvh - 20px); max-height: calc(100dvh - 20px); }
3369
+ .replace-scope-fieldset { grid-template-columns: minmax(0, 1fr); }
3370
+ .replace-scope-fieldset legend, .replace-scope-fieldset > p { grid-column: auto; }
3328
3371
  .task-detail-overview { grid-template-columns: minmax(0, 1fr); padding: 12px; }
3329
3372
  .task-detail-overview > * { grid-column: 1 !important; }
3330
3373
  .task-result-metrics { grid-template-columns: repeat(2, minmax(0, 1fr)); }
@@ -3379,7 +3422,8 @@ select:focus, input:focus, textarea:focus { border-color: #a77768; box-shadow: 0
3379
3422
  }
3380
3423
 
3381
3424
  @media (max-width: 480px) {
3382
- .top-actions .settings-button { display: none; }
3425
+ .app-shell:not(.shelf-mode) .topbar .brand-block > div { display: none; }
3426
+ .top-actions .settings-button { display: grid; flex: 0 0 32px; }
3383
3427
  .topbar-icon-button, .theme-toggle, .account-button { flex: 0 0 32px; width: 32px; min-width: 32px; height: 32px; }
3384
3428
  button.account-button { width: 32px; height: 32px; }
3385
3429
  .top-actions { gap: 3px; }
@@ -1,4 +1,4 @@
1
- import { chmodSync, cpSync, existsSync, mkdirSync, renameSync, writeFileSync } from "node:fs";
1
+ import { chmodSync, cpSync, existsSync, mkdirSync, readdirSync, readFileSync, renameSync, rmSync, statSync, writeFileSync } from "node:fs";
2
2
  import { fileURLToPath } from "node:url";
3
3
  import { basename, join } from "node:path";
4
4
  import { createRuntime } from "./app.js";
@@ -8,6 +8,12 @@ import { isDevelopmentAuthBypassEnabled, resolveRuntimeSecurity } from "./securi
8
8
  import { logger, sanitizeError } from "./logger.js";
9
9
  import { resolveReleaseCheckIntervalMs, resolveReleaseCheckRetries, resolveReleaseCheckTimeoutMs } from "./release-update.js";
10
10
  const publicPath = fileURLToPath(new URL("./public/", import.meta.url));
11
+ export const PRE_MIGRATION_BACKUP_RETENTION_ENV = "SCRIVERSE_PRE_MIGRATION_BACKUP_RETENTION";
12
+ export const DEFAULT_PRE_MIGRATION_BACKUP_RETENTION = 5;
13
+ export const MIN_PRE_MIGRATION_BACKUP_RETENTION = 2;
14
+ export const STARTUP_RETRY_LIMIT_ENV = "SCRIVERSE_STARTUP_RETRY_LIMIT";
15
+ export const DEFAULT_STARTUP_RETRY_LIMIT = 2;
16
+ export const STARTUP_RETRY_STATE_FILENAME = ".startup-retry.json";
11
17
  export function isDevelopmentServer(environment) {
12
18
  return environment.NODE_ENV === "development" || environment.npm_lifecycle_event === "dev";
13
19
  }
@@ -15,12 +21,118 @@ export function isLoopbackHost(host) {
15
21
  const normalized = host.trim().toLocaleLowerCase().replace(/^\[|\]$/gu, "");
16
22
  return normalized === "localhost" || normalized === "::1" || /^127(?:\.\d{1,3}){3}$/u.test(normalized);
17
23
  }
18
- export function createPreMigrationBackup(options) {
24
+ export function resolvePreMigrationBackupRetention(environment) {
25
+ const raw = environment[PRE_MIGRATION_BACKUP_RETENTION_ENV]?.trim() ?? "";
26
+ if (raw === "")
27
+ return DEFAULT_PRE_MIGRATION_BACKUP_RETENTION;
28
+ const configured = Number(raw);
29
+ if (!Number.isFinite(configured))
30
+ return DEFAULT_PRE_MIGRATION_BACKUP_RETENTION;
31
+ return Math.max(MIN_PRE_MIGRATION_BACKUP_RETENTION, Math.floor(configured));
32
+ }
33
+ export function resolveStartupRetryLimit(environment) {
34
+ const raw = environment[STARTUP_RETRY_LIMIT_ENV]?.trim() ?? "";
35
+ if (raw === "")
36
+ return DEFAULT_STARTUP_RETRY_LIMIT;
37
+ const configured = Number(raw);
38
+ if (!Number.isFinite(configured) || configured < 1)
39
+ return DEFAULT_STARTUP_RETRY_LIMIT;
40
+ return Math.floor(configured);
41
+ }
42
+ function startupRetryStatePath(dataDirectory) {
43
+ return join(dataDirectory, STARTUP_RETRY_STATE_FILENAME);
44
+ }
45
+ function readStartupRetryCount(dataDirectory) {
46
+ const statePath = startupRetryStatePath(dataDirectory);
47
+ if (!existsSync(statePath))
48
+ return 0;
49
+ try {
50
+ const parsed = JSON.parse(readFileSync(statePath, "utf8"));
51
+ const attempts = Number(parsed.attempts);
52
+ return Number.isInteger(attempts) && attempts >= 0 ? attempts : 0;
53
+ }
54
+ catch (error) {
55
+ logger.warn("server.startup_retry_state.invalid", { retryStatePath: statePath, error: sanitizeError(error) });
56
+ return 0;
57
+ }
58
+ }
59
+ function writeStartupRetryCount(dataDirectory, attempts) {
60
+ const statePath = startupRetryStatePath(dataDirectory);
61
+ const temporaryPath = `${statePath}.tmp`;
62
+ writeFileSync(temporaryPath, JSON.stringify({ attempts, updatedAt: new Date().toISOString() }, null, 2), { encoding: "utf8", mode: 0o600 });
63
+ chmodSync(temporaryPath, 0o600);
64
+ renameSync(temporaryPath, statePath);
65
+ chmodSync(statePath, 0o600);
66
+ }
67
+ function recordStartupAttempt(dataDirectory, environment) {
68
+ const retryLimit = resolveStartupRetryLimit(environment);
69
+ const previousAttempts = readStartupRetryCount(dataDirectory);
70
+ const retryStatePath = startupRetryStatePath(dataDirectory);
71
+ if (previousAttempts >= retryLimit) {
72
+ logger.error("server.startup_retry_limit_reached", {
73
+ retryStatePath,
74
+ attempts: previousAttempts,
75
+ retryLimit,
76
+ message: "Startup retry limit reached. Fix the previous initialization error, remove the startup retry state file, and restart Scriverse."
77
+ });
78
+ throw new Error(`Startup retry limit reached (${retryLimit}); fix the previous initialization error and remove ${retryStatePath} before restarting`);
79
+ }
80
+ const attempts = previousAttempts + 1;
81
+ writeStartupRetryCount(dataDirectory, attempts);
82
+ logger.warn("server.startup_attempt.recorded", { retryStatePath, attempts, retryLimit });
83
+ }
84
+ function clearStartupRetryState(dataDirectory) {
85
+ const statePath = startupRetryStatePath(dataDirectory);
86
+ if (!existsSync(statePath))
87
+ return;
88
+ try {
89
+ rmSync(statePath, { force: true });
90
+ logger.info("server.startup_retry_state.cleared", { retryStatePath: statePath });
91
+ }
92
+ catch (error) {
93
+ logger.error("server.startup_retry_state.clear_failed", { retryStatePath: statePath, error: sanitizeError(error) });
94
+ }
95
+ }
96
+ function listPreMigrationBackups(backupsDirectory) {
97
+ if (!existsSync(backupsDirectory))
98
+ return [];
99
+ return readdirSync(backupsDirectory, { withFileTypes: true })
100
+ .filter((entry) => entry.isDirectory() && entry.name.startsWith("pre-migration-v") && !entry.name.endsWith(".incomplete"))
101
+ .map((entry) => {
102
+ const directory = join(backupsDirectory, entry.name);
103
+ return { directory, modifiedAt: statSync(directory).mtimeMs };
104
+ })
105
+ .filter(({ directory }) => existsSync(join(directory, "backup.json")))
106
+ .sort((left, right) => left.modifiedAt - right.modifiedAt || left.directory.localeCompare(right.directory));
107
+ }
108
+ function prunePreMigrationBackups(backupsDirectory, maximumCount) {
109
+ const backups = listPreMigrationBackups(backupsDirectory);
110
+ const excessCount = Math.max(0, backups.length - maximumCount);
111
+ for (const backup of backups.slice(0, excessCount)) {
112
+ try {
113
+ rmSync(backup.directory, { recursive: true, force: true });
114
+ logger.info("database.pre_migration_backup.pruned", {
115
+ backupDirectory: backup.directory,
116
+ retentionCount: maximumCount
117
+ });
118
+ }
119
+ catch (error) {
120
+ logger.warn("database.pre_migration_backup.prune_failed", {
121
+ backupDirectory: backup.directory,
122
+ error: sanitizeError(error)
123
+ });
124
+ }
125
+ }
126
+ }
127
+ export function createPreMigrationBackup(options, environment = process.env) {
128
+ const backupsDirectory = join(options.dataDirectory, "backups");
129
+ const retentionCount = resolvePreMigrationBackupRetention(environment);
130
+ prunePreMigrationBackups(backupsDirectory, retentionCount);
19
131
  const schemaVersion = readDatabaseSchemaVersion(options.databasePath);
20
132
  if (schemaVersion === null || schemaVersion >= DATABASE_SCHEMA_VERSION)
21
133
  return null;
134
+ prunePreMigrationBackups(backupsDirectory, retentionCount - 1);
22
135
  const timestamp = new Date().toISOString().replace(/[:.]/gu, "-");
23
- const backupsDirectory = join(options.dataDirectory, "backups");
24
136
  const backupName = `pre-migration-v${schemaVersion}-to-v${DATABASE_SCHEMA_VERSION}-${timestamp}`;
25
137
  const incompleteDirectory = join(backupsDirectory, `${backupName}.incomplete`);
26
138
  const backupDirectory = join(backupsDirectory, backupName);
@@ -64,8 +176,9 @@ export async function startLocalServer(options) {
64
176
  try {
65
177
  mkdirSync(options.dataDirectory, { recursive: true, mode: 0o700 });
66
178
  chmodSync(options.dataDirectory, 0o700);
179
+ recordStartupAttempt(options.dataDirectory, options.env);
67
180
  security = resolveRuntimeSecurity(options.env);
68
- createPreMigrationBackup(options);
181
+ createPreMigrationBackup(options, options.env);
69
182
  const devAuthBypass = isDevelopmentAuthBypassEnabled(options.env);
70
183
  if (devAuthBypass && !isLoopbackHost(options.host)) {
71
184
  throw new Error("APP_DEV_SKIP_AUTH 仅允许绑定本机回环地址");
@@ -108,6 +221,7 @@ export async function startLocalServer(options) {
108
221
  }
109
222
  const port = address.port;
110
223
  const displayHost = options.host.includes(":") ? `[${options.host}]` : options.host;
224
+ clearStartupRetryState(options.dataDirectory);
111
225
  let closed = false;
112
226
  const close = async () => {
113
227
  if (closed)
@@ -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
@@ -1488,6 +1488,81 @@ export class Store {
1488
1488
  });
1489
1489
  return this.getChapter(chapterId);
1490
1490
  }
1491
+ replaceWorkText(workId, input) {
1492
+ const find = input.find;
1493
+ if (!find)
1494
+ throw new AppError(400, "REPLACE_TEXT_REQUIRED", "查找内容不能为空");
1495
+ if (!["prose", "settings", "prose-and-settings"].includes(input.scope)) {
1496
+ throw new AppError(400, "REPLACE_SCOPE_INVALID", "替换范围无效");
1497
+ }
1498
+ const operationId = id("globalReplace");
1499
+ let chapterCount = 0;
1500
+ let settingCount = 0;
1501
+ let totalMatches = 0;
1502
+ const includeProse = input.scope === "prose" || input.scope === "prose-and-settings";
1503
+ const includeSettings = input.scope === "settings" || input.scope === "prose-and-settings";
1504
+ const replaceLiteral = (value) => {
1505
+ let matches = 0;
1506
+ let offset = 0;
1507
+ while (true) {
1508
+ const index = value.indexOf(find, offset);
1509
+ if (index < 0)
1510
+ break;
1511
+ matches += 1;
1512
+ offset = index + find.length;
1513
+ }
1514
+ return {
1515
+ content: value.replaceAll(find, () => input.replacement),
1516
+ matches
1517
+ };
1518
+ };
1519
+ this.getWork(workId);
1520
+ this.db.transaction(() => {
1521
+ if (includeProse) {
1522
+ 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);
1523
+ for (const row of chapters) {
1524
+ const chapterId = requiredString(row, "id");
1525
+ const result = replaceLiteral(requiredString(row, "content"));
1526
+ if (!result.matches || result.content === requiredString(row, "content"))
1527
+ continue;
1528
+ this.saveChapter(chapterId, { content: result.content }, "global-replace", operationId, "全局替换正文");
1529
+ chapterCount += 1;
1530
+ totalMatches += result.matches;
1531
+ }
1532
+ }
1533
+ if (includeSettings) {
1534
+ const settings = this.db.all("SELECT id, content FROM settings WHERE work_id = ? ORDER BY id", workId);
1535
+ for (const row of settings) {
1536
+ const settingId = requiredString(row, "id");
1537
+ const currentContent = requiredString(row, "content");
1538
+ const result = replaceLiteral(currentContent);
1539
+ if (!result.matches || result.content === currentContent)
1540
+ continue;
1541
+ this.updateSetting(settingId, { content: result.content }, "global-replace", operationId, "全局替换设定库");
1542
+ settingCount += 1;
1543
+ totalMatches += result.matches;
1544
+ }
1545
+ }
1546
+ if (totalMatches > 0) {
1547
+ this.db.run("UPDATE works SET updated_at = ? WHERE id = ?", now(), workId);
1548
+ this.audit(workId, "work.global-replace", "work", workId, {
1549
+ operationId,
1550
+ scope: input.scope,
1551
+ chapterCount,
1552
+ settingCount,
1553
+ totalMatches
1554
+ });
1555
+ }
1556
+ });
1557
+ return {
1558
+ operationId,
1559
+ scope: input.scope,
1560
+ chapterCount,
1561
+ settingCount,
1562
+ totalMatches,
1563
+ work: this.getWorkDirectory(workId)
1564
+ };
1565
+ }
1491
1566
  restoreChapter(chapterId, versionNo, expectedVersionNo) {
1492
1567
  const version = this.db.get("SELECT * FROM chapter_versions WHERE chapter_id = ? AND version_no = ?", chapterId, versionNo);
1493
1568
  if (!version)
@@ -3451,10 +3526,32 @@ export class Store {
3451
3526
  const row = this.db.get(`SELECT attachment.*
3452
3527
  FROM attachments attachment
3453
3528
  JOIN attachment_references reference ON reference.attachment_id = attachment.id
3454
- WHERE attachment.id = ? AND attachment.work_id = ? AND reference.work_id = ? AND reference.entity_type = 'setting'
3529
+ WHERE attachment.id = ? AND attachment.work_id = ? AND reference.work_id = ?
3530
+ AND (
3531
+ (reference.entity_type = 'setting' AND EXISTS (
3532
+ SELECT 1 FROM settings current_setting
3533
+ WHERE current_setting.id = reference.entity_id AND current_setting.work_id = reference.work_id
3534
+ ))
3535
+ OR (reference.entity_type = 'character-section' AND EXISTS (
3536
+ SELECT 1
3537
+ FROM character_profile_sections current_section
3538
+ JOIN characters current_character ON current_character.id = current_section.character_id
3539
+ WHERE current_section.id = reference.entity_id
3540
+ AND current_section.work_id = reference.work_id
3541
+ AND current_character.work_id = reference.work_id
3542
+ ))
3543
+ OR (reference.entity_type = 'race' AND EXISTS (
3544
+ SELECT 1 FROM races current_race
3545
+ WHERE current_race.id = reference.entity_id AND current_race.work_id = reference.work_id
3546
+ ))
3547
+ OR (reference.entity_type = 'organization' AND EXISTS (
3548
+ SELECT 1 FROM organizations current_organization
3549
+ WHERE current_organization.id = reference.entity_id AND current_organization.work_id = reference.work_id
3550
+ ))
3551
+ )
3455
3552
  LIMIT 1`, attachmentId, workId, workId);
3456
3553
  if (!row)
3457
- throw new AppError(404, "SETTING_IMAGE_ATTACHMENT_NOT_FOUND", "图片附件不存在或未被设定正文引用");
3554
+ throw new AppError(404, "SETTING_IMAGE_ATTACHMENT_NOT_FOUND", "图片附件不存在或未被生效设定库当前文档引用");
3458
3555
  return this.mapAttachment(row);
3459
3556
  }
3460
3557
  attachmentModules(attachmentId) {
@@ -4967,7 +5064,7 @@ export class Store {
4967
5064
  const volumeTitles = new Map(this.db.all("SELECT id, title FROM volumes WHERE work_id = ?", workId).map((row) => [requiredString(row, "id"), requiredString(row, "title")]));
4968
5065
  const characterNames = this.taskCharacterNames(workId, rows.map((row) => json(requiredString(row, "scope_json"), {})));
4969
5066
  return {
4970
- ...paginated(rows.map((row) => this.mapTaskSummary(row, chapterSummaries, volumeTitles, characterNames)), pagination, total),
5067
+ ...paginated(rows.map((row) => this.mapTaskSummary(workId, row, chapterSummaries, volumeTitles, characterNames)), pagination, total),
4971
5068
  stats: {
4972
5069
  total,
4973
5070
  pendingCount: numberValue(statsRow, "pending_count"),
@@ -5125,12 +5222,30 @@ export class Store {
5125
5222
  : [];
5126
5223
  }
5127
5224
  taskResultEvidence(value) {
5128
- return this.taskResultObjects(value).map((item) => ({
5129
- chapterId: String(item.chapterId ?? ""),
5130
- chapterTitle: String(item.chapterTitle ?? ""),
5131
- quote: String(item.quote ?? ""),
5132
- supports: String(item.supports ?? item.conclusion ?? "")
5133
- })).filter((item) => item.chapterId || item.chapterTitle || item.quote || item.supports).slice(0, 5);
5225
+ return this.taskResultObjects(value).map((item) => {
5226
+ const chapterId = String(item.chapterId ?? "");
5227
+ const chapterTitle = String(item.chapterTitle ?? "");
5228
+ const settingId = String(item.settingId ?? "");
5229
+ const settingTitle = String(item.settingTitle ?? "");
5230
+ const sourceType = item.contextType === "setting" || settingId || settingTitle
5231
+ ? "setting"
5232
+ : chapterId || chapterTitle
5233
+ ? "chapter"
5234
+ : "";
5235
+ const sourceId = sourceType === "chapter" ? chapterId : sourceType === "setting" ? settingId : "";
5236
+ const sourceTitle = sourceType === "chapter" ? chapterTitle : sourceType === "setting" ? settingTitle : "";
5237
+ return {
5238
+ ...(chapterId ? { chapterId } : {}),
5239
+ ...(chapterTitle ? { chapterTitle } : {}),
5240
+ ...(settingId ? { settingId } : {}),
5241
+ ...(settingTitle ? { settingTitle } : {}),
5242
+ ...(sourceType ? { sourceType } : {}),
5243
+ ...(sourceId ? { sourceId } : {}),
5244
+ ...(sourceTitle ? { sourceTitle } : {}),
5245
+ quote: String(item.quote ?? ""),
5246
+ supports: String(item.supports ?? item.conclusion ?? "")
5247
+ };
5248
+ }).filter((item) => item.sourceId || item.sourceTitle || item.quote || item.supports).slice(0, 5);
5134
5249
  }
5135
5250
  taskResultItem(value, fallbackTitle) {
5136
5251
  if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
@@ -5880,12 +5995,7 @@ export class Store {
5880
5995
  confidence: numberValue(row, "confidence"),
5881
5996
  confirmationStatus: requiredString(row, "confirmation_status"),
5882
5997
  evidenceCount: evidence.length,
5883
- evidence: evidence.slice(0, 3).map((item) => ({
5884
- chapterId: String(item.chapterId ?? ""),
5885
- chapterTitle: String(item.chapterTitle ?? ""),
5886
- quote: String(item.quote ?? ""),
5887
- supports: String(item.supports ?? "")
5888
- })),
5998
+ evidence: this.taskResultEvidence(evidence).slice(0, 3),
5889
5999
  evidenceTruncated: evidence.length > 3
5890
6000
  };
5891
6001
  });
@@ -5922,6 +6032,7 @@ export class Store {
5922
6032
  scope,
5923
6033
  scopeSummary: this.taskScopeSummary(workId, scope, characterNames),
5924
6034
  scopeSummaryWithoutCharacterNames: this.taskScopeSummary(workId, scope, new Map(), false),
6035
+ scopeTarget: this.taskScopeTarget(workId, scope),
5925
6036
  scopeDetails: this.taskScopeDetails(workId, scope),
5926
6037
  status: requiredString(row, "status"),
5927
6038
  progress: numberValue(row, "progress"),
@@ -5935,7 +6046,7 @@ export class Store {
5935
6046
  updatedAt: requiredString(row, "updated_at")
5936
6047
  };
5937
6048
  }
5938
- mapTaskSummary(row, chapterSummaries, volumeTitles, characterNames) {
6049
+ mapTaskSummary(workId, row, chapterSummaries, volumeTitles, characterNames) {
5939
6050
  const scope = json(requiredString(row, "scope_json"), {});
5940
6051
  return {
5941
6052
  id: requiredString(row, "id"),
@@ -5943,6 +6054,7 @@ export class Store {
5943
6054
  taskType: requiredString(row, "task_type"),
5944
6055
  scopeSummary: this.taskScopeSummaryFromMaps(scope, chapterSummaries, volumeTitles, characterNames),
5945
6056
  scopeSummaryWithoutCharacterNames: this.taskScopeSummaryFromMaps(scope, chapterSummaries, volumeTitles, new Map(), false),
6057
+ scopeTarget: this.taskScopeTargetFromMaps(workId, scope, chapterSummaries),
5946
6058
  status: requiredString(row, "status"),
5947
6059
  progress: numberValue(row, "progress"),
5948
6060
  attemptCount: numberValue(row, "attempt_count"),
@@ -6050,6 +6162,48 @@ export class Store {
6050
6162
  const names = characterIds.map((characterId) => snapshotNames.get(characterId) ?? characterNames.get(characterId) ?? "已删除角色");
6051
6163
  return ` · 定向 ${characterIds.length} 人:${names.join("、")}${preFilterSuffix}${sourcePreviewSuffix}${overwriteSuffix}`;
6052
6164
  }
6165
+ taskScopeTargetFromMaps(workId, scope, chapterSummaries) {
6166
+ const characterIds = Array.isArray(scope.characterIds)
6167
+ ? scope.characterIds.filter((characterId) => typeof characterId === "string")
6168
+ : [];
6169
+ if (characterIds.length === 1 && typeof scope.chapterId !== "string") {
6170
+ const characterId = characterIds[0];
6171
+ if (!characterId)
6172
+ return null;
6173
+ const character = this.db.get("SELECT name FROM characters WHERE id = ? AND work_id = ?", characterId, workId);
6174
+ return character ? { type: "character", id: characterId, label: requiredString(character, "name") } : null;
6175
+ }
6176
+ if (characterIds.length === 0 && typeof scope.chapterId === "string") {
6177
+ const label = chapterSummaries.get(scope.chapterId);
6178
+ return label ? { type: "chapter", id: scope.chapterId, label } : null;
6179
+ }
6180
+ return null;
6181
+ }
6182
+ taskScopeTarget(workId, scope) {
6183
+ const characterIds = Array.isArray(scope.characterIds)
6184
+ ? scope.characterIds.filter((characterId) => typeof characterId === "string")
6185
+ : [];
6186
+ if (characterIds.length === 1 && typeof scope.chapterId !== "string") {
6187
+ const characterId = characterIds[0];
6188
+ if (!characterId)
6189
+ return null;
6190
+ const character = this.db.get("SELECT name FROM characters WHERE id = ? AND work_id = ?", characterId, workId);
6191
+ return character ? { type: "character", id: characterId, label: requiredString(character, "name") } : null;
6192
+ }
6193
+ if (characterIds.length !== 0 || typeof scope.chapterId !== "string")
6194
+ return null;
6195
+ const chapter = this.db.get(`SELECT chapter.title AS title, volume.title AS volume_title
6196
+ FROM chapters chapter
6197
+ JOIN volumes volume ON volume.id = chapter.volume_id
6198
+ WHERE chapter.id = ? AND chapter.work_id = ? AND chapter.deleted_at IS NULL`, scope.chapterId, workId);
6199
+ if (!chapter)
6200
+ return null;
6201
+ return {
6202
+ type: "chapter",
6203
+ id: scope.chapterId,
6204
+ label: `${requiredString(chapter, "volume_title")} · ${requiredString(chapter, "title")}`
6205
+ };
6206
+ }
6053
6207
  taskCharacterSnapshotNames(scope) {
6054
6208
  const snapshotNames = new Map();
6055
6209
  if (Array.isArray(scope.targetCharacters)) {