@sudobility/screenwriter_types 0.1.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 (65) hide show
  1. package/CLAUDE.md +50 -0
  2. package/README.md +34 -0
  3. package/dist/account/index.d.ts +440 -0
  4. package/dist/account/index.js +274 -0
  5. package/dist/admin/index.d.ts +95 -0
  6. package/dist/admin/index.js +20 -0
  7. package/dist/ai/index.d.ts +564 -0
  8. package/dist/ai/index.js +179 -0
  9. package/dist/api/envelope.d.ts +33 -0
  10. package/dist/api/envelope.js +140 -0
  11. package/dist/api/pagination.d.ts +7 -0
  12. package/dist/api/pagination.js +9 -0
  13. package/dist/api/routes.d.ts +273 -0
  14. package/dist/api/routes.js +306 -0
  15. package/dist/assets/index.d.ts +722 -0
  16. package/dist/assets/index.js +452 -0
  17. package/dist/collab/index.d.ts +214 -0
  18. package/dist/collab/index.js +211 -0
  19. package/dist/commands/index.d.ts +92 -0
  20. package/dist/commands/index.js +20 -0
  21. package/dist/credits/index.d.ts +26 -0
  22. package/dist/credits/index.js +7 -0
  23. package/dist/formats/index.d.ts +87 -0
  24. package/dist/formats/index.js +26 -0
  25. package/dist/ids/index.d.ts +2 -0
  26. package/dist/ids/index.js +2 -0
  27. package/dist/index.d.ts +33 -0
  28. package/dist/index.js +33 -0
  29. package/dist/io/index.d.ts +395 -0
  30. package/dist/io/index.js +161 -0
  31. package/dist/jobs/index.d.ts +278 -0
  32. package/dist/jobs/index.js +138 -0
  33. package/dist/keys/index.d.ts +53 -0
  34. package/dist/keys/index.js +22 -0
  35. package/dist/lifecycle/index.d.ts +263 -0
  36. package/dist/lifecycle/index.js +148 -0
  37. package/dist/me/index.d.ts +35 -0
  38. package/dist/me/index.js +18 -0
  39. package/dist/packets/index.d.ts +887 -0
  40. package/dist/packets/index.js +312 -0
  41. package/dist/projects/index.d.ts +201 -0
  42. package/dist/projects/index.js +75 -0
  43. package/dist/public/index.d.ts +95 -0
  44. package/dist/public/index.js +25 -0
  45. package/dist/reads/index.d.ts +387 -0
  46. package/dist/reads/index.js +118 -0
  47. package/dist/reports/index.d.ts +168 -0
  48. package/dist/reports/index.js +466 -0
  49. package/dist/sharing/index.d.ts +256 -0
  50. package/dist/sharing/index.js +91 -0
  51. package/dist/sync/codec.d.ts +7 -0
  52. package/dist/sync/codec.js +91 -0
  53. package/dist/sync/index.d.ts +382 -0
  54. package/dist/sync/index.js +262 -0
  55. package/dist/sync/permissions.d.ts +22 -0
  56. package/dist/sync/permissions.js +11 -0
  57. package/dist/templates/index.d.ts +1699 -0
  58. package/dist/templates/index.js +70 -0
  59. package/dist/tenancy/index.d.ts +116 -0
  60. package/dist/tenancy/index.js +102 -0
  61. package/dist/test/index.d.ts +8 -0
  62. package/dist/test/index.js +88 -0
  63. package/dist/versions/index.d.ts +335 -0
  64. package/dist/versions/index.js +107 -0
  65. package/package.json +62 -0
@@ -0,0 +1,179 @@
1
+ import { z } from 'zod';
2
+ /**
3
+ * AI features (spec 06): script review and polish through ShapeShyft.
4
+ *
5
+ * Only the tasks implemented so far are in `AI_TASKS`; adding one means a registry row in
6
+ * `screenwriter_api/src/services/ai/tasks.ts`, a prompt builder, an output schema here and a fixture.
7
+ * Output schemas are written for structured output: every field is required (nullable, never optional)
8
+ * and objects are closed, so `z.toJSONSchema` gives the exact schema to store on the ShapeShyft endpoint.
9
+ */
10
+ export const AI_TASKS = ['coverage', 'polish.dialogue'];
11
+ export const aiTaskSchema = z.enum(AI_TASKS);
12
+ /** ShapeShyft endpoint names (spec 06 2.1). `summarize-chunk` is stage 1 of a long coverage run. */
13
+ export const AI_ENDPOINTS = [
14
+ 'coverage-review',
15
+ 'polish',
16
+ 'summarize-chunk',
17
+ ];
18
+ export const AI_JOB_STATUSES = [
19
+ 'queued',
20
+ 'running',
21
+ 'succeeded',
22
+ 'failed',
23
+ 'cancelled',
24
+ ];
25
+ /** Counted limits, declared once: schemas, validators and prompt text all read these. */
26
+ export const AI_LIMITS = {
27
+ noteTitleMax: 80,
28
+ noteBodyMax: 1200,
29
+ noteAnchorsMax: 8,
30
+ strengthsMax: 8,
31
+ weaknessesMax: 12,
32
+ sceneNotesMax: 20,
33
+ loglineMax: 300,
34
+ summaryMax: 4000,
35
+ genreMax: 3,
36
+ verdictRationaleMax: 800,
37
+ polishSuggestionsMax: 200,
38
+ polishTextMax: 4000,
39
+ rationaleMax: 400,
40
+ chunkSummaryMax: 1200,
41
+ sceneSummaryMax: 280,
42
+ polishMaxScenes: 8,
43
+ instructionsMax: 500,
44
+ };
45
+ export const REVIEW_CATEGORIES = [
46
+ 'premise',
47
+ 'structure',
48
+ 'character',
49
+ 'dialogue',
50
+ 'pacing',
51
+ 'tone',
52
+ 'theme',
53
+ 'worldbuilding',
54
+ 'format',
55
+ 'marketability',
56
+ 'clarity',
57
+ 'continuity',
58
+ ];
59
+ export const SEVERITIES = ['praise', 'minor', 'moderate', 'major'];
60
+ export const COVERAGE_VERDICTS = ['recommend', 'consider', 'pass'];
61
+ // ---- Model output (untrusted until validated; what the ShapeShyft endpoint returns) ----
62
+ /** Where a note points. `elementId: null` means the whole scene. The server adds the content hash. */
63
+ export const anchorRefSchema = z.object({
64
+ sceneId: z.string(),
65
+ elementId: z.string().nullable(),
66
+ });
67
+ export const noteSchema = z.object({
68
+ category: z.enum(REVIEW_CATEGORIES),
69
+ severity: z.enum(SEVERITIES),
70
+ title: z.string().min(1).max(AI_LIMITS.noteTitleMax),
71
+ body: z.string().min(1).max(AI_LIMITS.noteBodyMax),
72
+ anchors: z.array(anchorRefSchema).max(AI_LIMITS.noteAnchorsMax),
73
+ });
74
+ /** `coverage-review` output. */
75
+ export const coverageResponseSchema = z.object({
76
+ logline: z.string().max(AI_LIMITS.loglineMax),
77
+ summary: z.string().max(AI_LIMITS.summaryMax),
78
+ genre: z.array(z.string()).max(AI_LIMITS.genreMax),
79
+ strengths: z.array(noteSchema).max(AI_LIMITS.strengthsMax),
80
+ weaknesses: z.array(noteSchema).max(AI_LIMITS.weaknessesMax),
81
+ /** Notes about specific scenes: each must anchor at least one scene. */
82
+ sceneNotes: z.array(noteSchema).max(AI_LIMITS.sceneNotesMax),
83
+ verdict: z.enum(COVERAGE_VERDICTS),
84
+ verdictRationale: z.string().max(AI_LIMITS.verdictRationaleMax),
85
+ });
86
+ /** `polish` output: one proposed replacement per element. */
87
+ export const polishResponseSchema = z.object({
88
+ suggestions: z
89
+ .array(z.object({
90
+ elementId: z.string(),
91
+ after: z.string().max(AI_LIMITS.polishTextMax),
92
+ rationale: z.string().max(AI_LIMITS.rationaleMax),
93
+ }))
94
+ .max(AI_LIMITS.polishSuggestionsMax),
95
+ });
96
+ /** `summarize-chunk` output (stage 1 of a long-script coverage run). */
97
+ export const chunkSummaryResponseSchema = z.object({
98
+ scenes: z.array(z.object({
99
+ sceneId: z.string(),
100
+ summary: z.string().max(AI_LIMITS.sceneSummaryMax),
101
+ intensity: z.number().int().min(1).max(5),
102
+ })),
103
+ chunkSummary: z.string().max(AI_LIMITS.chunkSummaryMax),
104
+ });
105
+ /** The five input fields every endpoint takes (spec 06 2.1). */
106
+ export const aiEndpointInputSchema = z.object({
107
+ context: z.string(),
108
+ brief: z.string(),
109
+ max_output_tokens: z.number().int().positive(),
110
+ locale: z.string(),
111
+ script_language: z.string(),
112
+ });
113
+ /** Endpoint -> output schema. `bun run ai:schemas` in screenwriter_api prints these as JSON Schema. */
114
+ export const AI_ENDPOINT_OUTPUT_SCHEMAS = {
115
+ 'coverage-review': coverageResponseSchema,
116
+ polish: polishResponseSchema,
117
+ 'summarize-chunk': chunkSummaryResponseSchema,
118
+ };
119
+ // ---- Jobs ----
120
+ export const aiScopeSchema = z.object({
121
+ sceneIds: z.array(z.string().min(1)).max(200).optional(),
122
+ elementIds: z.array(z.string().min(1)).max(2000).optional(),
123
+ });
124
+ export const aiJobOptionsSchema = z.object({
125
+ /** Writer's own request, fenced separately from the script. Fixture failure markers only work in test mode. */
126
+ instructions: z.string().max(AI_LIMITS.instructionsMax).optional(),
127
+ intensity: z.enum(['light', 'medium', 'bold']).optional(),
128
+ locale: z.string().min(2).max(20).optional(),
129
+ });
130
+ /** `POST /documents/:did/ai/jobs` body. `polish.dialogue` needs a scope; `coverage` defaults to the whole script. */
131
+ export const aiJobCreateSchema = z.object({
132
+ task: aiTaskSchema,
133
+ scope: aiScopeSchema.optional(),
134
+ options: aiJobOptionsSchema.optional(),
135
+ });
136
+ // ---- Suggestion sets (spec 06 7) ----
137
+ export const SUGGESTION_STATUSES = [
138
+ 'pending',
139
+ 'accepted',
140
+ 'rejected',
141
+ 'stale',
142
+ ];
143
+ export const SUGGESTION_SET_STATUSES = [
144
+ 'pending',
145
+ 'partiallyAccepted',
146
+ 'accepted',
147
+ 'rejected',
148
+ 'stale',
149
+ 'expired',
150
+ ];
151
+ export const suggestionAcceptSchema = z.object({
152
+ suggestionIds: z.array(z.string().min(1)).min(1).max(200),
153
+ });
154
+ /** `reject` with no ids rejects every pending suggestion in the set. */
155
+ export const suggestionRejectSchema = z.object({
156
+ suggestionIds: z.array(z.string().min(1)).min(1).max(200).optional(),
157
+ });
158
+ // ---- Consent (spec 06 §9.3: gate 3) ----
159
+ /** Bumping this requires every user to re-accept before their next AI job. */
160
+ export const AI_CONSENT_VERSION = 1;
161
+ /** `POST /me/ai-consents`: `version` must equal `AI_CONSENT_VERSION`, else `VALIDATION`. */
162
+ export const aiConsentAcceptSchema = z.object({ version: z.number().int() });
163
+ export const aiEstimateRequestSchema = z.object({
164
+ task: aiTaskSchema,
165
+ scope: z
166
+ .object({
167
+ sceneIds: z.array(z.string()).optional(),
168
+ elementIds: z.array(z.string()).optional(),
169
+ })
170
+ .optional(),
171
+ options: z.record(z.string(), z.unknown()).optional(),
172
+ });
173
+ // ---- Suggestion decide (spec 06 §7.4): a combined, server-side accept/reject for API/MCP callers ----
174
+ export const suggestionDecideSchema = z.object({
175
+ accept: z.union([z.array(z.string().min(1)), z.literal('allPending')]),
176
+ reject: z.union([z.array(z.string().min(1)), z.literal('allPending')]),
177
+ expectedHashes: z.record(z.string(), z.string()).optional(),
178
+ dryRun: z.boolean().optional(),
179
+ });
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Response envelope, error vocabulary (spec 05 §12) and pagination shape.
3
+ * Platform-free: no clock is read here, so the envelope carries no timestamp.
4
+ */
5
+ /** Every REST error code and its fixed HTTP status (spec 05 §12). */
6
+ declare const ERROR_TABLE: readonly [readonly ["UNAUTHORIZED", 401], readonly ["REAUTH_REQUIRED", 401], readonly ["API_KEY_FORBIDDEN", 403], readonly ["FORBIDDEN", 403], readonly ["ROLE_ESCALATION", 403], readonly ["NOT_FOUND", 404], readonly ["PROJECT_NOT_FOUND", 404], readonly ["DOCUMENT_NOT_FOUND", 404], readonly ["SNAPSHOT_NOT_FOUND", 404], readonly ["TEMPLATE_NOT_FOUND", 404], readonly ["ITEM_NOT_FOUND", 404], readonly ["ANCHOR_NOT_FOUND", 404], readonly ["TARGET_NOT_FOUND", 404], readonly ["VALIDATION", 400], readonly ["COMMAND_INVALID", 422], readonly ["TEMPLATE_INVALID", 422], readonly ["CONFIRMATION_MISMATCH", 400], readonly ["EPOCH_MISMATCH", 409], readonly ["DOCUMENT_LOCKED", 423], readonly ["DOCUMENT_BUSY", 409], readonly ["JOB_ALREADY_RUNNING", 409], readonly ["JOB_FINISHED", 409], readonly ["JOB_NOT_FINISHED", 409], readonly ["LAST_OWNER", 409], readonly ["ALREADY_MEMBER", 409], readonly ["NOT_A_MEMBER", 409], readonly ["PERSONAL_WORKSPACE_IMMUTABLE", 409], readonly ["OWNS_TEAM_WORKSPACE", 409], readonly ["NOT_IN_TRASH", 409], readonly ["PARENT_IN_TRASH", 409], readonly ["FOLDER_DEPTH", 409], readonly ["FOLDER_CYCLE", 409], readonly ["MOVE_FORBIDDEN", 403], readonly ["BUILTIN_IMMUTABLE", 409], readonly ["LOCATOR_AMBIGUOUS", 409], readonly ["INVITATION_INVALID", 410], readonly ["INVITATION_EXPIRED", 410], readonly ["INVITATION_CLOSED", 410], readonly ["EMAIL_MISMATCH", 403], readonly ["SHARE_LINK_INVALID", 404], readonly ["SHARE_LINK_PASSWORD_REQUIRED", 401], readonly ["WATERMARK_REQUIRED", 403], readonly ["EDIT_WINDOW_CLOSED", 409], readonly ["ASSET_TOO_LARGE", 413], readonly ["IMPORT_TOO_LARGE", 413], readonly ["UNSUPPORTED_FORMAT", 400], readonly ["IMPORT_FAILED", 400], readonly ["IMPORT_INVALID", 422], readonly ["ASSET_TYPE_REJECTED", 415], readonly ["ASSET_CHECKSUM_MISMATCH", 422], readonly ["ASSET_NOT_READY", 409], readonly ["ASSET_IN_USE", 409], readonly ["UPLOAD_INCOMPLETE", 409], readonly ["UPLOAD_EXPIRED", 410], readonly ["STORAGE_QUOTA_EXCEEDED", 507], readonly ["STORAGE_UNAVAILABLE", 503], readonly ["IMPORT_FORMAT_UNSUPPORTED", 415], readonly ["EXPORT_FORMAT_UNSUPPORTED", 415], readonly ["COMPARE_TOO_LARGE", 413], readonly ["LIMIT_EXCEEDED", 409], readonly ["RATE_LIMITED", 429], readonly ["QUOTA_EXCEEDED", 429], readonly ["INSUFFICIENT_CREDITS", 402], readonly ["AI_UNAVAILABLE", 503], readonly ["AI_INPUT_TOO_LARGE", 413], readonly ["AI_GENERATION_FAILED", 502], readonly ["AI_OUTPUT_INVALID", 502], readonly ["CONFIG_MISSING", 503], readonly ["CLIENT_TOO_OLD", 426], readonly ["CONTENT_CHANGED", 409], readonly ["STYLE_NOT_IN_TEMPLATE", 422], readonly ["NOT_CONTIGUOUS", 422], readonly ["LOCKED_CONTENT", 409], readonly ["NAME_COLLISION", 409], readonly ["KIND_MISMATCH", 422], readonly ["OVERLAPPING_SHOTS", 422], readonly ["OVERLAPPING_NODE", 422], readonly ["SCENES_LOCKED", 409], readonly ["NOT_LOCKED", 409], readonly ["RANGE_OUT_OF_BOUNDS", 422], readonly ["INVALID_TARGET", 422], readonly ["INVALID_DUAL_DIALOGUE", 422], readonly ["FOUNTAIN_PARSE_ERROR", 422], readonly ["UNMAPPED_STYLES", 422], readonly ["RANGE_TOO_LARGE", 413], readonly ["PAYLOAD_TOO_LARGE", 413], readonly ["INVALID_REGEX", 400], readonly ["REPORT_OPTIONS_INVALID", 400], readonly ["REPORT_KIND_UNAVAILABLE", 501], readonly ["ENTITY_IN_USE", 409], readonly ["VARIANT_IN_USE", 409], readonly ["SNAPSHOT_NOT_IN_DOCUMENT", 404], readonly ["ITEM_NOT_IN_SNAPSHOT", 404], readonly ["INVALID_LOCATOR", 400], readonly ["LOCATOR_NOT_FOUND", 404], readonly ["ROLE_NOT_ALLOWED_FOR_TARGET", 422], readonly ["ID_CONFLICT", 409], readonly ["IDEMPOTENCY_KEY_REUSED", 409], readonly ["IDEMPOTENCY_IN_PROGRESS", 409], readonly ["DEVICE_REVOKED", 403], readonly ["MACRO_TRIGGER_TAKEN", 409], readonly ["STALE_WRITE", 409], readonly ["HANDOFF_INVALID", 410], readonly ["WATERMARK_NOT_FOUND", 404], readonly ["OCR_UNAVAILABLE", 503], readonly ["GRAMMAR_UNAVAILABLE", 503], readonly ["AI_CONSENT_REQUIRED", 403], readonly ["AI_DISABLED_FOR_WORKSPACE", 403], readonly ["AI_EXCLUDED_DOCUMENT", 403], readonly ["AI_KEY_NOT_PERMITTED", 403], readonly ["QUOTE_EXCEEDS_MAX", 402], readonly ["AI_CONTENT_REFUSED", 422], readonly ["SCOPE_TOO_LARGE", 413], readonly ["SUGGESTION_UNAVAILABLE", 409], readonly ["JOB_KIND_DISABLED", 501], readonly ["JOB_KIND_NOT_GENERIC", 400], readonly ["JOB_FAILED", 409], readonly ["JOB_TIMEOUT", 504], readonly ["LIKENESS_CONSENT_REQUIRED", 422], readonly ["CONTENT_REJECTED", 422], readonly ["INTERNAL", 500]];
7
+ type ErrorTable = typeof ERROR_TABLE;
8
+ export type ApiErrorCode = ErrorTable[number][0];
9
+ export declare const API_ERROR_CODES: { readonly [C in ApiErrorCode]: C; };
10
+ /** HTTP status per error code. */
11
+ export declare const ERROR_STATUS: Record<ApiErrorCode, number>;
12
+ export interface ApiSuccess<T> {
13
+ success: true;
14
+ data: T;
15
+ }
16
+ export interface ApiFailure {
17
+ success: false;
18
+ /** Human-readable message. */
19
+ error: string;
20
+ code: ApiErrorCode;
21
+ /** Code-specific details (e.g. `issues`, `index`, `ids`). */
22
+ details?: Record<string, unknown>;
23
+ }
24
+ export type ApiResponse<T> = ApiSuccess<T> | ApiFailure;
25
+ export declare function successResponse<T>(data: T): ApiSuccess<T>;
26
+ /** The only constructor for failure envelopes. */
27
+ export declare function errorResponse(message: string, code: ApiErrorCode, details?: Record<string, unknown>): ApiFailure;
28
+ /** Cursor page: `nextCursor` is null on the last page. */
29
+ export interface Paginated<T> {
30
+ items: T[];
31
+ nextCursor: string | null;
32
+ }
33
+ export {};
@@ -0,0 +1,140 @@
1
+ /**
2
+ * Response envelope, error vocabulary (spec 05 §12) and pagination shape.
3
+ * Platform-free: no clock is read here, so the envelope carries no timestamp.
4
+ */
5
+ /** Every REST error code and its fixed HTTP status (spec 05 §12). */
6
+ const ERROR_TABLE = [
7
+ ['UNAUTHORIZED', 401],
8
+ ['REAUTH_REQUIRED', 401],
9
+ ['API_KEY_FORBIDDEN', 403],
10
+ ['FORBIDDEN', 403],
11
+ ['ROLE_ESCALATION', 403],
12
+ ['NOT_FOUND', 404],
13
+ ['PROJECT_NOT_FOUND', 404],
14
+ ['DOCUMENT_NOT_FOUND', 404],
15
+ ['SNAPSHOT_NOT_FOUND', 404],
16
+ ['TEMPLATE_NOT_FOUND', 404],
17
+ ['ITEM_NOT_FOUND', 404],
18
+ ['ANCHOR_NOT_FOUND', 404],
19
+ ['TARGET_NOT_FOUND', 404],
20
+ ['VALIDATION', 400],
21
+ ['COMMAND_INVALID', 422],
22
+ ['TEMPLATE_INVALID', 422],
23
+ ['CONFIRMATION_MISMATCH', 400],
24
+ ['EPOCH_MISMATCH', 409],
25
+ ['DOCUMENT_LOCKED', 423],
26
+ ['DOCUMENT_BUSY', 409],
27
+ ['JOB_ALREADY_RUNNING', 409],
28
+ ['JOB_FINISHED', 409],
29
+ ['JOB_NOT_FINISHED', 409],
30
+ ['LAST_OWNER', 409],
31
+ ['ALREADY_MEMBER', 409],
32
+ ['NOT_A_MEMBER', 409],
33
+ ['PERSONAL_WORKSPACE_IMMUTABLE', 409],
34
+ ['OWNS_TEAM_WORKSPACE', 409],
35
+ ['NOT_IN_TRASH', 409],
36
+ ['PARENT_IN_TRASH', 409],
37
+ ['FOLDER_DEPTH', 409],
38
+ ['FOLDER_CYCLE', 409],
39
+ ['MOVE_FORBIDDEN', 403],
40
+ ['BUILTIN_IMMUTABLE', 409],
41
+ ['LOCATOR_AMBIGUOUS', 409],
42
+ ['INVITATION_INVALID', 410],
43
+ ['INVITATION_EXPIRED', 410],
44
+ ['INVITATION_CLOSED', 410],
45
+ ['EMAIL_MISMATCH', 403],
46
+ ['SHARE_LINK_INVALID', 404],
47
+ ['SHARE_LINK_PASSWORD_REQUIRED', 401],
48
+ ['WATERMARK_REQUIRED', 403],
49
+ ['EDIT_WINDOW_CLOSED', 409],
50
+ ['ASSET_TOO_LARGE', 413],
51
+ ['IMPORT_TOO_LARGE', 413],
52
+ ['UNSUPPORTED_FORMAT', 400],
53
+ ['IMPORT_FAILED', 400],
54
+ ['IMPORT_INVALID', 422],
55
+ ['ASSET_TYPE_REJECTED', 415],
56
+ ['ASSET_CHECKSUM_MISMATCH', 422],
57
+ ['ASSET_NOT_READY', 409],
58
+ ['ASSET_IN_USE', 409],
59
+ ['UPLOAD_INCOMPLETE', 409],
60
+ ['UPLOAD_EXPIRED', 410],
61
+ ['STORAGE_QUOTA_EXCEEDED', 507],
62
+ ['STORAGE_UNAVAILABLE', 503],
63
+ ['IMPORT_FORMAT_UNSUPPORTED', 415],
64
+ ['EXPORT_FORMAT_UNSUPPORTED', 415],
65
+ ['COMPARE_TOO_LARGE', 413],
66
+ ['LIMIT_EXCEEDED', 409],
67
+ ['RATE_LIMITED', 429],
68
+ ['QUOTA_EXCEEDED', 429],
69
+ ['INSUFFICIENT_CREDITS', 402],
70
+ ['AI_UNAVAILABLE', 503],
71
+ ['AI_INPUT_TOO_LARGE', 413],
72
+ ['AI_GENERATION_FAILED', 502],
73
+ ['AI_OUTPUT_INVALID', 502],
74
+ ['CONFIG_MISSING', 503],
75
+ ['CLIENT_TOO_OLD', 426],
76
+ ['CONTENT_CHANGED', 409],
77
+ ['STYLE_NOT_IN_TEMPLATE', 422],
78
+ ['NOT_CONTIGUOUS', 422],
79
+ ['LOCKED_CONTENT', 409],
80
+ ['NAME_COLLISION', 409],
81
+ ['KIND_MISMATCH', 422],
82
+ ['OVERLAPPING_SHOTS', 422],
83
+ ['OVERLAPPING_NODE', 422],
84
+ ['SCENES_LOCKED', 409],
85
+ ['NOT_LOCKED', 409],
86
+ ['RANGE_OUT_OF_BOUNDS', 422],
87
+ ['INVALID_TARGET', 422],
88
+ ['INVALID_DUAL_DIALOGUE', 422],
89
+ ['FOUNTAIN_PARSE_ERROR', 422],
90
+ ['UNMAPPED_STYLES', 422],
91
+ ['RANGE_TOO_LARGE', 413],
92
+ ['PAYLOAD_TOO_LARGE', 413],
93
+ ['INVALID_REGEX', 400],
94
+ ['REPORT_OPTIONS_INVALID', 400],
95
+ ['REPORT_KIND_UNAVAILABLE', 501],
96
+ ['ENTITY_IN_USE', 409],
97
+ ['VARIANT_IN_USE', 409],
98
+ ['SNAPSHOT_NOT_IN_DOCUMENT', 404],
99
+ ['ITEM_NOT_IN_SNAPSHOT', 404],
100
+ ['INVALID_LOCATOR', 400],
101
+ ['LOCATOR_NOT_FOUND', 404],
102
+ ['ROLE_NOT_ALLOWED_FOR_TARGET', 422],
103
+ ['ID_CONFLICT', 409],
104
+ ['IDEMPOTENCY_KEY_REUSED', 409],
105
+ ['IDEMPOTENCY_IN_PROGRESS', 409],
106
+ ['DEVICE_REVOKED', 403],
107
+ ['MACRO_TRIGGER_TAKEN', 409],
108
+ ['STALE_WRITE', 409],
109
+ ['HANDOFF_INVALID', 410],
110
+ ['WATERMARK_NOT_FOUND', 404],
111
+ ['OCR_UNAVAILABLE', 503],
112
+ ['GRAMMAR_UNAVAILABLE', 503],
113
+ ['AI_CONSENT_REQUIRED', 403],
114
+ ['AI_DISABLED_FOR_WORKSPACE', 403],
115
+ ['AI_EXCLUDED_DOCUMENT', 403],
116
+ ['AI_KEY_NOT_PERMITTED', 403],
117
+ ['QUOTE_EXCEEDS_MAX', 402],
118
+ ['AI_CONTENT_REFUSED', 422],
119
+ ['SCOPE_TOO_LARGE', 413],
120
+ ['SUGGESTION_UNAVAILABLE', 409],
121
+ ['JOB_KIND_DISABLED', 501],
122
+ ['JOB_KIND_NOT_GENERIC', 400],
123
+ ['JOB_FAILED', 409],
124
+ ['JOB_TIMEOUT', 504],
125
+ ['LIKENESS_CONSENT_REQUIRED', 422],
126
+ ['CONTENT_REJECTED', 422],
127
+ ['INTERNAL', 500],
128
+ ];
129
+ export const API_ERROR_CODES = Object.fromEntries(ERROR_TABLE.map(([code]) => [code, code]));
130
+ /** HTTP status per error code. */
131
+ export const ERROR_STATUS = Object.fromEntries(ERROR_TABLE);
132
+ export function successResponse(data) {
133
+ return { success: true, data };
134
+ }
135
+ /** The only constructor for failure envelopes. */
136
+ export function errorResponse(message, code, details) {
137
+ return details === undefined
138
+ ? { success: false, error: message, code }
139
+ : { success: false, error: message, code, details };
140
+ }
@@ -0,0 +1,7 @@
1
+ import { z } from 'zod';
2
+ /** `limit` 1-200 (default 50); `cursor` is an opaque base64url string. */
3
+ export declare const cursorQuerySchema: z.ZodObject<{
4
+ limit: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
5
+ cursor: z.ZodOptional<z.ZodString>;
6
+ }, z.core.$strip>;
7
+ export type CursorQuery = z.infer<typeof cursorQuerySchema>;
@@ -0,0 +1,9 @@
1
+ import { z } from 'zod';
2
+ /** `limit` 1-200 (default 50); `cursor` is an opaque base64url string. */
3
+ export const cursorQuerySchema = z.object({
4
+ limit: z.coerce.number().int().min(1).max(200).default(50),
5
+ cursor: z
6
+ .string()
7
+ .regex(/^[A-Za-z0-9_-]+$/)
8
+ .optional(),
9
+ });
@@ -0,0 +1,273 @@
1
+ /**
2
+ * Route table for slices B1-B5 (spec 05 §6). Paths are relative to API_BASE_PATH.
3
+ * `auth` uses the spec legend: U user, K key (r/rw scope), L link, P public.
4
+ * `permission` is the spec 05 §5.2 permission checked on the resolved object.
5
+ */
6
+ export declare const API_BASE_PATH = "/api/v1";
7
+ export type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
8
+ export interface RouteSpec {
9
+ method: HttpMethod;
10
+ path: string;
11
+ auth: string;
12
+ permission: string | null;
13
+ }
14
+ export declare const API_ROUTES: {
15
+ readonly health: RouteSpec;
16
+ readonly meGet: RouteSpec;
17
+ readonly mePatch: RouteSpec;
18
+ readonly workspacesList: RouteSpec;
19
+ readonly workspaceGet: RouteSpec;
20
+ readonly projectsList: RouteSpec;
21
+ readonly projectCreate: RouteSpec;
22
+ readonly projectGet: RouteSpec;
23
+ readonly projectUpdate: RouteSpec;
24
+ readonly projectTrash: RouteSpec;
25
+ readonly projectRestore: RouteSpec;
26
+ readonly documentsList: RouteSpec;
27
+ readonly documentCreate: RouteSpec;
28
+ readonly documentGet: RouteSpec;
29
+ readonly documentUpdate: RouteSpec;
30
+ readonly documentTrash: RouteSpec;
31
+ readonly documentRestore: RouteSpec;
32
+ readonly documentState: RouteSpec;
33
+ readonly documentContent: RouteSpec;
34
+ readonly templatesList: RouteSpec;
35
+ readonly templateGet: RouteSpec;
36
+ readonly sync: RouteSpec;
37
+ readonly versionsList: RouteSpec;
38
+ readonly versionState: RouteSpec;
39
+ readonly versionRestore: RouteSpec;
40
+ readonly versionSnapshot: RouteSpec;
41
+ readonly snapshotsList: RouteSpec;
42
+ readonly snapshotCreate: RouteSpec;
43
+ readonly snapshotGet: RouteSpec;
44
+ readonly snapshotState: RouteSpec;
45
+ readonly snapshotContent: RouteSpec;
46
+ readonly snapshotOpen: RouteSpec;
47
+ readonly snapshotFork: RouteSpec;
48
+ readonly elementHistory: RouteSpec;
49
+ readonly documentPresence: RouteSpec;
50
+ readonly versionRestoreAsCopy: RouteSpec;
51
+ readonly snapshotPrefs: RouteSpec;
52
+ readonly snapshotNotesList: RouteSpec;
53
+ readonly snapshotNoteCreate: RouteSpec;
54
+ readonly snapshotCommentsList: RouteSpec;
55
+ readonly snapshotCommentCreate: RouteSpec;
56
+ readonly snapshotCommentCopyToLive: RouteSpec;
57
+ readonly snapshotCommentResolve: RouteSpec;
58
+ readonly documentCompare: RouteSpec;
59
+ readonly documentImport: RouteSpec;
60
+ readonly documentExport: RouteSpec;
61
+ readonly formatsList: RouteSpec;
62
+ readonly commands: RouteSpec;
63
+ readonly outline: RouteSpec;
64
+ readonly scene: RouteSpec;
65
+ readonly scenesBatch: RouteSpec;
66
+ readonly elementsBatch: RouteSpec;
67
+ readonly apiKeysList: RouteSpec;
68
+ readonly apiKeyCreate: RouteSpec;
69
+ readonly apiKeyUpdate: RouteSpec;
70
+ readonly apiKeyRevoke: RouteSpec;
71
+ readonly aiStatus: RouteSpec;
72
+ readonly aiJobCreate: RouteSpec;
73
+ readonly aiJobsList: RouteSpec;
74
+ readonly aiJobGet: RouteSpec;
75
+ readonly aiJobCancel: RouteSpec;
76
+ readonly aiSuggestionSetsList: RouteSpec;
77
+ readonly aiSuggestionSetGet: RouteSpec;
78
+ readonly aiSuggestionSetAccept: RouteSpec;
79
+ readonly aiSuggestionSetReject: RouteSpec;
80
+ readonly workspaceCreate: RouteSpec;
81
+ readonly workspaceUpdate: RouteSpec;
82
+ readonly workspaceDelete: RouteSpec;
83
+ readonly workspaceTransfer: RouteSpec;
84
+ readonly workspaceLeave: RouteSpec;
85
+ readonly workspaceUsage: RouteSpec;
86
+ readonly workspaceAudit: RouteSpec;
87
+ readonly membersList: RouteSpec;
88
+ readonly memberUpdate: RouteSpec;
89
+ readonly memberRemove: RouteSpec;
90
+ readonly invitationCreateWorkspace: RouteSpec;
91
+ readonly invitationCreateProject: RouteSpec;
92
+ readonly invitationCreateDocument: RouteSpec;
93
+ readonly workspaceInvitationsList: RouteSpec;
94
+ readonly myInvitations: RouteSpec;
95
+ readonly invitationRenew: RouteSpec;
96
+ readonly invitationCancel: RouteSpec;
97
+ readonly invitationAccept: RouteSpec;
98
+ readonly invitationDecline: RouteSpec;
99
+ readonly sharedWithMe: RouteSpec;
100
+ readonly documentLock: RouteSpec;
101
+ readonly documentUnlock: RouteSpec;
102
+ readonly documentUnlockSession: RouteSpec;
103
+ readonly shareLinkCreateDocument: RouteSpec;
104
+ readonly shareLinkCreateProject: RouteSpec;
105
+ readonly shareLinkCreateSnapshot: RouteSpec;
106
+ readonly shareLinksListDocument: RouteSpec;
107
+ readonly shareLinksListProject: RouteSpec;
108
+ readonly shareLinkUpdate: RouteSpec;
109
+ readonly shareLinkRevoke: RouteSpec;
110
+ readonly grantsListDocument: RouteSpec;
111
+ readonly grantsListProject: RouteSpec;
112
+ readonly grantUpdate: RouteSpec;
113
+ readonly grantRemove: RouteSpec;
114
+ readonly publicShareResolve: RouteSpec;
115
+ readonly shareUnlock: RouteSpec;
116
+ readonly shareState: RouteSpec;
117
+ readonly jobsList: RouteSpec;
118
+ readonly jobGet: RouteSpec;
119
+ readonly jobCreate: RouteSpec;
120
+ readonly jobCancel: RouteSpec;
121
+ readonly jobOutputs: RouteSpec;
122
+ readonly jobRecipients: RouteSpec;
123
+ readonly jobWebhook: RouteSpec;
124
+ readonly entitiesList: RouteSpec;
125
+ readonly entityGet: RouteSpec;
126
+ readonly entityUsage: RouteSpec;
127
+ readonly entityDialogue: RouteSpec;
128
+ readonly tagCategoriesList: RouteSpec;
129
+ readonly tagsList: RouteSpec;
130
+ readonly notesList: RouteSpec;
131
+ readonly beatsList: RouteSpec;
132
+ readonly binList: RouteSpec;
133
+ readonly revisionsGet: RouteSpec;
134
+ readonly changesList: RouteSpec;
135
+ readonly alternatesGet: RouteSpec;
136
+ readonly titlePageGet: RouteSpec;
137
+ readonly statsGet: RouteSpec;
138
+ readonly fountainGet: RouteSpec;
139
+ readonly sceneShotsList: RouteSpec;
140
+ readonly resolveBatch: RouteSpec;
141
+ readonly resolveOne: RouteSpec;
142
+ readonly documentSearch: RouteSpec;
143
+ readonly workspaceSearch: RouteSpec;
144
+ readonly search: RouteSpec;
145
+ readonly reportKinds: RouteSpec;
146
+ readonly reportGet: RouteSpec;
147
+ readonly reportCreate: RouteSpec;
148
+ readonly packetScene: RouteSpec;
149
+ readonly packetCharacter: RouteSpec;
150
+ readonly packetLocation: RouteSpec;
151
+ readonly packetShot: RouteSpec;
152
+ readonly meDictionaryGet: RouteSpec;
153
+ readonly meDictionaryUpdate: RouteSpec;
154
+ readonly mePreferencesGet: RouteSpec;
155
+ readonly mePreferencesSet: RouteSpec;
156
+ readonly meMacrosList: RouteSpec;
157
+ readonly meMacroCreate: RouteSpec;
158
+ readonly meMacroUpdate: RouteSpec;
159
+ readonly meMacroDelete: RouteSpec;
160
+ readonly meWritingStats: RouteSpec;
161
+ readonly meWritingSessionCreate: RouteSpec;
162
+ readonly meWritingGoalsGet: RouteSpec;
163
+ readonly meWritingGoalsSet: RouteSpec;
164
+ readonly meExport: RouteSpec;
165
+ readonly meDelete: RouteSpec;
166
+ readonly meRestore: RouteSpec;
167
+ readonly documentMyStateGet: RouteSpec;
168
+ readonly documentMyStateSet: RouteSpec;
169
+ readonly documentStar: RouteSpec;
170
+ readonly documentUnstar: RouteSpec;
171
+ readonly workspaceDocuments: RouteSpec;
172
+ readonly workspaceTrash: RouteSpec;
173
+ readonly workspaceTrashEmpty: RouteSpec;
174
+ readonly projectPurge: RouteSpec;
175
+ readonly projectDuplicate: RouteSpec;
176
+ readonly projectFolderCreate: RouteSpec;
177
+ readonly projectFolderUpdate: RouteSpec;
178
+ readonly projectFolderDelete: RouteSpec;
179
+ readonly documentMove: RouteSpec;
180
+ readonly documentPurge: RouteSpec;
181
+ readonly documentDuplicate: RouteSpec;
182
+ readonly documentApplyTemplate: RouteSpec;
183
+ readonly templateCreate: RouteSpec;
184
+ readonly templateVersionCreate: RouteSpec;
185
+ readonly templateUpdate: RouteSpec;
186
+ readonly templateDelete: RouteSpec;
187
+ readonly templateImport: RouteSpec;
188
+ readonly templateExport: RouteSpec;
189
+ readonly projectBinList: RouteSpec;
190
+ readonly projectBinCreate: RouteSpec;
191
+ readonly projectBinDelete: RouteSpec;
192
+ readonly workspaceDefaultsGet: RouteSpec;
193
+ readonly workspaceDefaultsSet: RouteSpec;
194
+ readonly workspaceContactsList: RouteSpec;
195
+ readonly workspaceContactsCreate: RouteSpec;
196
+ readonly workspaceContactUpdate: RouteSpec;
197
+ readonly workspaceContactDelete: RouteSpec;
198
+ readonly uploadState: RouteSpec;
199
+ readonly importCreate: RouteSpec;
200
+ readonly importStart: RouteSpec;
201
+ readonly documentImportOver: RouteSpec;
202
+ readonly documentExportCreate: RouteSpec;
203
+ readonly documentExportCombined: RouteSpec;
204
+ readonly watermarkLookup: RouteSpec;
205
+ readonly assetUploadCreate: RouteSpec;
206
+ readonly assetUploadGet: RouteSpec;
207
+ readonly assetUploadParts: RouteSpec;
208
+ readonly assetUploadComplete: RouteSpec;
209
+ readonly assetUploadAbort: RouteSpec;
210
+ readonly assetsList: RouteSpec;
211
+ readonly assetGet: RouteSpec;
212
+ readonly assetUrl: RouteSpec;
213
+ readonly assetUpdate: RouteSpec;
214
+ readonly assetDelete: RouteSpec;
215
+ readonly assetRestore: RouteSpec;
216
+ readonly assetLinkCreate: RouteSpec;
217
+ readonly documentAssetLinks: RouteSpec;
218
+ readonly assetLinkUpdate: RouteSpec;
219
+ readonly assetLinkDelete: RouteSpec;
220
+ readonly documentStaleness: RouteSpec;
221
+ readonly assetLinkStaleness: RouteSpec;
222
+ readonly meNotificationPrefsGet: RouteSpec;
223
+ readonly meNotificationPrefsSet: RouteSpec;
224
+ readonly documentMentionsWithoutAccess: RouteSpec;
225
+ readonly documentChatList: RouteSpec;
226
+ readonly documentChatCreate: RouteSpec;
227
+ readonly chatMessageUpdate: RouteSpec;
228
+ readonly chatMessageDelete: RouteSpec;
229
+ readonly documentActivity: RouteSpec;
230
+ readonly workspaceActivity: RouteSpec;
231
+ readonly notificationsList: RouteSpec;
232
+ readonly notificationsRead: RouteSpec;
233
+ readonly notificationDelete: RouteSpec;
234
+ readonly notificationsStream: RouteSpec;
235
+ readonly devicesList: RouteSpec;
236
+ readonly deviceCreate: RouteSpec;
237
+ readonly deviceUpdate: RouteSpec;
238
+ readonly deviceRevoke: RouteSpec;
239
+ readonly devicePushTokenSet: RouteSpec;
240
+ readonly devicePushTokenDelete: RouteSpec;
241
+ readonly meAiConsentGet: RouteSpec;
242
+ readonly meAiConsentAccept: RouteSpec;
243
+ readonly meAiActivity: RouteSpec;
244
+ readonly workspaceAiActivity: RouteSpec;
245
+ readonly aiEstimate: RouteSpec;
246
+ readonly aiReportsList: RouteSpec;
247
+ readonly aiReportGet: RouteSpec;
248
+ readonly aiReportNoteConvert: RouteSpec;
249
+ readonly aiSuggestionSetDecide: RouteSpec;
250
+ readonly consumablesBalance: RouteSpec;
251
+ readonly consumablesPurchases: RouteSpec;
252
+ readonly consumablesUsages: RouteSpec;
253
+ readonly consumablesProducts: RouteSpec;
254
+ readonly consumablesWebhook: RouteSpec;
255
+ readonly purchaseHandoffCreate: RouteSpec;
256
+ readonly publicTemplatesList: RouteSpec;
257
+ readonly publicTemplateGet: RouteSpec;
258
+ readonly publicConfig: RouteSpec;
259
+ readonly publicNamesDb: RouteSpec;
260
+ readonly publicHealthDeep: RouteSpec;
261
+ readonly publicWatermarkedGet: RouteSpec;
262
+ readonly purchaseHandoffRedeem: RouteSpec;
263
+ readonly telemetryCreate: RouteSpec;
264
+ readonly adminUsersLookup: RouteSpec;
265
+ readonly adminUserRestore: RouteSpec;
266
+ readonly adminUserPurge: RouteSpec;
267
+ readonly adminJobsList: RouteSpec;
268
+ readonly adminJobRetry: RouteSpec;
269
+ readonly adminJobRefund: RouteSpec;
270
+ readonly adminJobKindUpdate: RouteSpec;
271
+ readonly adminDocumentMeta: RouteSpec;
272
+ };
273
+ export type ApiRouteName = keyof typeof API_ROUTES;