@musnows/scriverse 0.5.10 → 0.5.11

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/app.js CHANGED
@@ -65,6 +65,7 @@ const memberRoleValueSchema = z.enum(["editor", "settings-editor", "viewer"]);
65
65
  const moduleAccessSchema = z.enum(["none", "read", "write"]);
66
66
  const modulePermissionsSchema = z.object({
67
67
  prose: moduleAccessSchema,
68
+ drafts: moduleAccessSchema.optional(),
68
69
  settings: moduleAccessSchema,
69
70
  characters: moduleAccessSchema,
70
71
  races: moduleAccessSchema,
@@ -76,7 +77,12 @@ const modulePermissionsSchema = z.object({
76
77
  "ai-chat": moduleAccessSchema,
77
78
  "ai-analysis": moduleAccessSchema,
78
79
  "ai-settings": moduleAccessSchema
79
- }).strict();
80
+ }).strict().transform((permissions) => ({
81
+ ...permissions,
82
+ drafts: permissions.drafts ?? (permissions.prose === "write" && permissions.settings === "write"
83
+ ? "write"
84
+ : permissions.prose === "none" || permissions.settings === "none" ? "none" : "read")
85
+ }));
80
86
  const memberSchema = z.union([
81
87
  z.object({ userId: identifier, permissions: modulePermissionsSchema }).strict(),
82
88
  z.object({ userId: identifier, role: memberRoleValueSchema }).strict()
@@ -97,7 +103,7 @@ const presenceHeartbeatSchema = z.object({
97
103
  page: z.discriminatedUnion("kind", [
98
104
  z.object({ kind: z.literal(presencePageKinds[0]) }).strict(),
99
105
  z.object({ kind: z.literal(presencePageKinds[1]), resourceId: identifier }).strict(),
100
- z.object({ kind: z.literal(presencePageKinds[2]), module: z.enum(["settings", "characters", "races", "organizations", "timeline", "relationships", "outlines", "reviews", "tasks", "ai-settings"]) }).strict(),
106
+ z.object({ kind: z.literal(presencePageKinds[2]), module: z.enum(["drafts", "settings", "characters", "races", "organizations", "timeline", "relationships", "outlines", "reviews", "tasks", "ai-settings"]) }).strict(),
101
107
  z.object({ kind: z.literal(presencePageKinds[3]), module: z.enum(["setting", "character", "race", "organization", "relationship"]), resourceId: identifier.optional() }).strict(),
102
108
  z.object({ kind: z.literal(presencePageKinds[4]) }).strict()
103
109
  ])
@@ -136,6 +142,11 @@ const settingSchema = z.object({
136
142
  scope: jsonObject.optional(),
137
143
  authorNote: z.string().max(20_000).optional()
138
144
  });
145
+ const draftSchema = z.object({
146
+ draftType: z.enum(["prose", "setting"]),
147
+ title: nonEmpty.max(200),
148
+ content: z.string().max(200_000)
149
+ }).strict();
139
150
  const characterSchema = z.object({
140
151
  name: nonEmpty.max(200),
141
152
  code: z.string().trim().max(200).optional(),
@@ -304,6 +315,7 @@ const aiUsageQuerySchema = z.object({
304
315
  timezoneOffset: z.coerce.number().int().min(-840).max(840).default(0)
305
316
  }).strict();
306
317
  const platformPageSizesSchema = z.object({
318
+ drafts: z.number().int().min(10).max(100).optional(),
307
319
  settings: z.number().int().min(10).max(100).optional(),
308
320
  characters: z.number().int().min(10).max(100).optional(),
309
321
  races: z.number().int().min(10).max(100).optional(),
@@ -361,7 +373,7 @@ const workAiSettingsSchema = z.object({
361
373
  autoRunFailureThreshold: z.number().int().min(1).max(10).optional(),
362
374
  bookSummaryContextPercent: z.number().int().min(1).max(90).optional(),
363
375
  contextCompactThreshold: z.number().int().min(50).max(90).optional(),
364
- agentTools: z.array(z.enum(["story_index", "read_chapters", "grep", "search_story_entities", "read_character_sections"])).max(5).optional()
376
+ agentTools: z.array(z.enum(["story_index", "read_chapters", "grep", "search_story_entities", "read_character_sections", "search_drafts"])).max(6).optional()
365
377
  }).strict();
366
378
  const contextSchema = z.object({
367
379
  type: z.enum(["none", "selection", "chapter", "volume", "book", "entities"]),
@@ -1124,6 +1136,33 @@ export function createRuntime(options) {
1124
1136
  store.deleteForeshadowOccurrence(request.params.occurrenceId, input.expectedVersionNo);
1125
1137
  noContent(response);
1126
1138
  });
1139
+ app.get("/api/works/:workId/drafts", (request, response) => {
1140
+ const query = parse(z.object({
1141
+ draftType: z.enum(["prose", "setting"]).optional(),
1142
+ includeContent: z.enum(["true", "false"]).default("false")
1143
+ }), request.query);
1144
+ const pagination = parsePagination(request.query);
1145
+ const includeContent = query.includeContent === "true";
1146
+ data(response, pagination
1147
+ ? store.listDraftsPage(request.params.workId, pagination, query.draftType, includeContent)
1148
+ : store.listDrafts(request.params.workId, query.draftType, includeContent));
1149
+ });
1150
+ app.post("/api/works/:workId/drafts", (request, response) => {
1151
+ data(response, store.createDraft(request.params.workId, parse(draftSchema, request.body)), 201);
1152
+ });
1153
+ app.get("/api/drafts/:draftId", (request, response) => data(response, store.getDraft(request.params.draftId)));
1154
+ app.patch("/api/drafts/:draftId", (request, response) => {
1155
+ const { changeNote, expectedVersionNo, ...input } = parse(draftSchema.partial().extend({
1156
+ changeNote: changeNoteSchema,
1157
+ expectedVersionNo: expectedVersionNoSchema
1158
+ }).strict(), request.body);
1159
+ data(response, store.updateDraft(request.params.draftId, input, "manual", null, changeNote, expectedVersionNo));
1160
+ });
1161
+ app.delete("/api/drafts/:draftId", (request, response) => {
1162
+ const input = parse(z.object({ expectedVersionNo: expectedVersionNoSchema }).strict(), request.body ?? {});
1163
+ store.deleteDraft(request.params.draftId, input.expectedVersionNo);
1164
+ noContent(response);
1165
+ });
1127
1166
  app.get("/api/works/:workId/settings", (request, response) => {
1128
1167
  const pagination = parsePagination(request.query);
1129
1168
  const includeContent = request.query.includeContent === "true";