@musnows/scriverse 0.8.0 → 0.8.2
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/ai-conversation-export.js +3 -1
- package/dist/ai-conversation-export.js.map +1 -1
- package/dist/ai.js +72 -6
- package/dist/ai.js.map +1 -1
- package/dist/app.js +48 -14
- package/dist/app.js.map +1 -1
- package/dist/database.js +26 -2
- package/dist/database.js.map +1 -1
- package/dist/public/app.js +326 -72
- package/dist/public/index.html +12 -7
- package/dist/public/relationship-graph.js +11 -3
- package/dist/public/stream-typewriter.d.ts +1 -0
- package/dist/public/stream-typewriter.js +12 -0
- package/dist/public/styles.css +33 -17
- package/dist/public/work-permissions.d.ts +1 -1
- package/dist/public/work-permissions.js +13 -1
- package/dist/store.js +90 -16
- package/dist/store.js.map +1 -1
- package/dist/user-auth.js +34 -7
- package/dist/user-auth.js.map +1 -1
- package/dist/version.js +1 -1
- package/dist/work-permissions.js +13 -2
- package/dist/work-permissions.js.map +1 -1
- package/package.json +1 -1
package/dist/app.js
CHANGED
|
@@ -40,10 +40,14 @@ import { S3BackupManager } from "./s3-backup.js";
|
|
|
40
40
|
import { APP_VERSION } from "./version.js";
|
|
41
41
|
import { ReleaseUpdateChecker } from "./release-update.js";
|
|
42
42
|
import { DEFAULT_IMAGE_UPLOAD_LIMITS, formatUploadLimit } from "./upload-limits.js";
|
|
43
|
-
import { canReadWorkModule, canWriteWorkModule, fullWorkModulePermissions, proseReplacementPermissionModules } from "./work-permissions.js";
|
|
43
|
+
import { canReadWorkModule, canWriteWorkModule, chapterAnnotationPermissionModule, fullWorkModulePermissions, proseReplacementPermissionModules } from "./work-permissions.js";
|
|
44
44
|
import { CollaborationPresence, editorPageKey, entityEditorPageKey, modulePageKey, presencePageKinds } from "./collaboration-presence.js";
|
|
45
45
|
import { PresenceStore } from "./presence-store.js";
|
|
46
46
|
import { analysisTaskReadModules, clearSessionCookie, createCliApiScopeMiddleware, createUserSessionMiddleware, createWorkAuthorizationMiddleware, relationshipAnalysisReadModules, setSessionCookie, UserAuthService } from "./user-auth.js";
|
|
47
|
+
const chapterAnnotationKinds = ["note", "todo"];
|
|
48
|
+
function readableChapterAnnotationKinds(permissions) {
|
|
49
|
+
return chapterAnnotationKinds.filter((kind) => canReadWorkModule(permissions, chapterAnnotationPermissionModule(kind)));
|
|
50
|
+
}
|
|
47
51
|
const nonEmpty = z.string().trim().min(1);
|
|
48
52
|
const identifier = z.string().trim().min(1).max(200);
|
|
49
53
|
const idempotencyKeySchema = z.string().trim().min(16).max(128)
|
|
@@ -110,6 +114,8 @@ const memberRoleValueSchema = z.enum(["editor", "settings-editor", "viewer"]);
|
|
|
110
114
|
const moduleAccessSchema = z.enum(["none", "read", "write"]);
|
|
111
115
|
const modulePermissionsSchema = z.object({
|
|
112
116
|
prose: moduleAccessSchema,
|
|
117
|
+
comments: moduleAccessSchema.optional(),
|
|
118
|
+
todos: moduleAccessSchema.optional(),
|
|
113
119
|
drafts: moduleAccessSchema.optional(),
|
|
114
120
|
settings: moduleAccessSchema,
|
|
115
121
|
characters: moduleAccessSchema,
|
|
@@ -124,6 +130,8 @@ const modulePermissionsSchema = z.object({
|
|
|
124
130
|
"ai-settings": moduleAccessSchema
|
|
125
131
|
}).strict().transform((permissions) => ({
|
|
126
132
|
...permissions,
|
|
133
|
+
comments: permissions.comments ?? permissions.prose,
|
|
134
|
+
todos: permissions.todos ?? permissions.prose,
|
|
127
135
|
drafts: permissions.drafts ?? (permissions.prose === "write" && permissions.settings === "write"
|
|
128
136
|
? "write"
|
|
129
137
|
: permissions.prose === "none" || permissions.settings === "none" ? "none" : "read")
|
|
@@ -932,12 +940,18 @@ function redactAiConversationMessage(item, permissions) {
|
|
|
932
940
|
if (!message)
|
|
933
941
|
return item;
|
|
934
942
|
if (permissions.prose !== "none") {
|
|
935
|
-
if (permissions.characters !== "none")
|
|
936
|
-
return item;
|
|
937
943
|
const metadata = recordValue(message.metadata);
|
|
938
|
-
if (!metadata
|
|
944
|
+
if (!metadata)
|
|
945
|
+
return item;
|
|
946
|
+
const readableMetadata = { ...metadata };
|
|
947
|
+
if (permissions.characters === "none")
|
|
948
|
+
delete readableMetadata.mentionCharacterIds;
|
|
949
|
+
if (permissions.races === "none")
|
|
950
|
+
delete readableMetadata.mentionRaceIds;
|
|
951
|
+
if (permissions.organizations === "none")
|
|
952
|
+
delete readableMetadata.mentionOrganizationIds;
|
|
953
|
+
if (Object.keys(readableMetadata).length === Object.keys(metadata).length)
|
|
939
954
|
return item;
|
|
940
|
-
const { mentionCharacterIds: _mentionCharacterIds, ...readableMetadata } = metadata;
|
|
941
955
|
return { ...message, metadata: readableMetadata };
|
|
942
956
|
}
|
|
943
957
|
return {
|
|
@@ -950,7 +964,9 @@ function redactAiConversationMessage(item, permissions) {
|
|
|
950
964
|
}
|
|
951
965
|
/** 无正文读取权限时隐藏对话预览与消息正文,避免历史对话泄露章节原文。 */
|
|
952
966
|
function redactAiConversation(record, permissions) {
|
|
953
|
-
const readableRecord = permissions.characters === "none"
|
|
967
|
+
const readableRecord = permissions.characters === "none"
|
|
968
|
+
? { ...record, roleplayCharacter: null, roleplayUserCharacter: null }
|
|
969
|
+
: record;
|
|
954
970
|
const scopedRecord = redactAiCallContext(readableRecord, permissions);
|
|
955
971
|
const result = {
|
|
956
972
|
...scopedRecord
|
|
@@ -1609,12 +1625,23 @@ export function createRuntime(options) {
|
|
|
1609
1625
|
const pagination = parsePagination(request.query);
|
|
1610
1626
|
data(response, pagination ? store.listChapterInsightsPage(request.params.chapterId, pagination) : store.listChapterInsights(request.params.chapterId));
|
|
1611
1627
|
});
|
|
1612
|
-
app.get("/api/chapters/:chapterId/
|
|
1628
|
+
app.get("/api/chapters/:chapterId/annotation-counts", (request, response) => {
|
|
1629
|
+
const permissions = requestPermissions(request);
|
|
1630
|
+
data(response, store.listChapterAnnotationCounts(request.params.chapterId, readableChapterAnnotationKinds(permissions)));
|
|
1631
|
+
});
|
|
1632
|
+
app.get("/api/chapters/:chapterId/annotations", (request, response) => {
|
|
1633
|
+
const line = request.query.line === undefined
|
|
1634
|
+
? undefined
|
|
1635
|
+
: parse(z.coerce.number().int().positive().max(100_000), request.query.line);
|
|
1636
|
+
const permissions = requestPermissions(request);
|
|
1637
|
+
data(response, store.listChapterAnnotations(request.params.chapterId, readableChapterAnnotationKinds(permissions), line));
|
|
1638
|
+
});
|
|
1613
1639
|
app.get("/api/works/:workId/chapter-annotations", (request, response) => {
|
|
1614
1640
|
const pagination = parsePagination(request.query);
|
|
1641
|
+
const permissions = requestPermissions(request, request.params.workId);
|
|
1615
1642
|
data(response, pagination
|
|
1616
|
-
? store.listWorkChapterAnnotationsPage(request.params.workId, pagination)
|
|
1617
|
-
: store.listWorkChapterAnnotations(request.params.workId));
|
|
1643
|
+
? store.listWorkChapterAnnotationsPage(request.params.workId, pagination, readableChapterAnnotationKinds(permissions))
|
|
1644
|
+
: store.listWorkChapterAnnotations(request.params.workId, readableChapterAnnotationKinds(permissions)));
|
|
1618
1645
|
});
|
|
1619
1646
|
app.post("/api/chapters/:chapterId/annotations", (request, response) => {
|
|
1620
1647
|
const input = parse(z.object({
|
|
@@ -2436,7 +2463,7 @@ export function createRuntime(options) {
|
|
|
2436
2463
|
}).strict(), request.body);
|
|
2437
2464
|
const sourceConversation = store.getAiConversationSummary(request.params.conversationId);
|
|
2438
2465
|
const permissions = requestPermissions(request, String(sourceConversation.workId));
|
|
2439
|
-
if (sourceConversation.roleplayCharacter && !canReadWorkModule(permissions, "characters")) {
|
|
2466
|
+
if ((sourceConversation.roleplayCharacter || sourceConversation.roleplayUserCharacter) && !canReadWorkModule(permissions, "characters")) {
|
|
2440
2467
|
throw new AppError(403, "WORK_MODULE_READ_DENIED", "你没有读取“角色”模块的权限");
|
|
2441
2468
|
}
|
|
2442
2469
|
const forked = store.forkAiConversation(request.params.conversationId, input.messageId, input.title, input.requestId);
|
|
@@ -2455,8 +2482,11 @@ export function createRuntime(options) {
|
|
|
2455
2482
|
data(response, redactAiConversation(updated, permissions));
|
|
2456
2483
|
});
|
|
2457
2484
|
app.patch("/api/ai-conversations/:conversationId/roleplay", (request, response) => {
|
|
2458
|
-
const input = parse(z.object({
|
|
2459
|
-
|
|
2485
|
+
const input = parse(z.object({
|
|
2486
|
+
characterId: identifier.nullable(),
|
|
2487
|
+
userCharacterId: identifier.nullable().optional()
|
|
2488
|
+
}).strict(), request.body);
|
|
2489
|
+
const updated = store.setAiConversationRoleplayCharacter(request.params.conversationId, input.characterId, input.userCharacterId);
|
|
2460
2490
|
const permissions = requestPermissions(request, String(updated.workId));
|
|
2461
2491
|
data(response, redactAiConversation(updated, permissions));
|
|
2462
2492
|
});
|
|
@@ -2709,6 +2739,8 @@ export function createRuntime(options) {
|
|
|
2709
2739
|
...(resolvedScope.characterIds ?? []),
|
|
2710
2740
|
...(resolvedScope.mentionCharacterIds ?? [])
|
|
2711
2741
|
])];
|
|
2742
|
+
const mentionRaceIds = [...new Set(resolvedScope.raceIds ?? [])];
|
|
2743
|
+
const mentionOrganizationIds = [...new Set(resolvedScope.organizationIds ?? [])];
|
|
2712
2744
|
const begun = store.beginAiConversationStreamRequest({
|
|
2713
2745
|
workId: request.params.workId,
|
|
2714
2746
|
conversationId,
|
|
@@ -2719,9 +2751,11 @@ export function createRuntime(options) {
|
|
|
2719
2751
|
content: input.instruction,
|
|
2720
2752
|
citations,
|
|
2721
2753
|
...(input.currentMessageId ? { existingMessageId: input.currentMessageId } : {}),
|
|
2722
|
-
...((modelId || mentionCharacterIds.length) ? { metadata: {
|
|
2754
|
+
...((modelId || mentionCharacterIds.length || mentionRaceIds.length || mentionOrganizationIds.length) ? { metadata: {
|
|
2723
2755
|
...(modelId ? { modelId } : {}),
|
|
2724
|
-
...(mentionCharacterIds.length ? { mentionCharacterIds } : {})
|
|
2756
|
+
...(mentionCharacterIds.length ? { mentionCharacterIds } : {}),
|
|
2757
|
+
...(mentionRaceIds.length ? { mentionRaceIds } : {}),
|
|
2758
|
+
...(mentionOrganizationIds.length ? { mentionOrganizationIds } : {})
|
|
2725
2759
|
} } : {})
|
|
2726
2760
|
}
|
|
2727
2761
|
});
|