@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,278 @@
1
+ import { z } from 'zod';
2
+ import type { AiTask } from '../ai/index.js';
3
+ /**
4
+ * Generic jobs (spec 05 §6.19, §13; slice B9). A job is one row of `jobs`; `ai_jobs` rows are mirrored as `ai.*`
5
+ * jobs (decision D21a) so `/ai/jobs/:id` and `/jobs/:id` read the same job.
6
+ */
7
+ export declare const JOB_STATUSES: readonly ["queued", "running", "succeeded", "failed", "cancelled"];
8
+ export type JobStatus = (typeof JOB_STATUSES)[number];
9
+ export declare const TERMINAL_JOB_STATUSES: readonly ["succeeded", "failed", "cancelled"];
10
+ export declare const isTerminalJobStatus: (s: JobStatus) => boolean;
11
+ export declare const JOB_LANES: readonly ["ai", "interactive", "bulk", "system", "provider"];
12
+ export type JobLane = (typeof JOB_LANES)[number];
13
+ /**
14
+ * Closed vocabulary of job kinds, `<family>.<variant>` (R10). Every kind has a `job_kind_config` row; a kind
15
+ * without a registered runner is seeded disabled and `POST /jobs` answers `JOB_KIND_DISABLED`. Extend by adding a
16
+ * member here and a row in `screenwriter_api/src/services/jobs/kinds.ts`. `test.*` kinds exist only to prove the
17
+ * framework and are enabled only under `AI_TEST_MODE=1`.
18
+ */
19
+ export declare const JOB_KINDS: readonly ["ai.review", "ai.polish", "ai.describe", "export.pdf", "export.fdx", "export.fountain", "export.fadein", "export.fadewright", "export.json", "export.docx", "watermark.batch", "import.fdx", "import.fountain", "import.fadein", "import.pdf", "import.ocr", "import.celtx", "import.scrivener", "import.fdxt", "report.render", "doc.applyTemplate", "doc.importOver", "doc.snapshotOpen", "doc.versionRestore", "doc.compare", "doc.normalize", "doc.renormalize", "doc.compact", "snapshot.project", "project.duplicate", "asset.derive", "account.export", "system.emailSend", "system.emailDigest", "system.writingReminder", "system.pushSend", "system.purge", "system.retentionSweep", "template.thumbnail", "image.generate", "image.edit", "image.upscale", "image.turnaround", "video.generate", "video.extend", "video.upscale", "video.lipSync", "voice.tts", "voice.cloneProfile", "voice.change", "music.generate", "sfx.generate", "audio.isolate", "model3d.generate", "model3d.convert", "model3d.rig", "storyboard.generate", "animatic.assemble", "timeline.export", "test.echo", "test.flaky"];
20
+ export type JobKind = (typeof JOB_KINDS)[number];
21
+ export declare const jobKindSchema: z.ZodEnum<{
22
+ "ai.review": "ai.review";
23
+ "ai.polish": "ai.polish";
24
+ "ai.describe": "ai.describe";
25
+ "export.pdf": "export.pdf";
26
+ "export.fdx": "export.fdx";
27
+ "export.fountain": "export.fountain";
28
+ "export.fadein": "export.fadein";
29
+ "export.fadewright": "export.fadewright";
30
+ "export.json": "export.json";
31
+ "export.docx": "export.docx";
32
+ "watermark.batch": "watermark.batch";
33
+ "import.fdx": "import.fdx";
34
+ "import.fountain": "import.fountain";
35
+ "import.fadein": "import.fadein";
36
+ "import.pdf": "import.pdf";
37
+ "import.ocr": "import.ocr";
38
+ "import.celtx": "import.celtx";
39
+ "import.scrivener": "import.scrivener";
40
+ "import.fdxt": "import.fdxt";
41
+ "report.render": "report.render";
42
+ "doc.applyTemplate": "doc.applyTemplate";
43
+ "doc.importOver": "doc.importOver";
44
+ "doc.snapshotOpen": "doc.snapshotOpen";
45
+ "doc.versionRestore": "doc.versionRestore";
46
+ "doc.compare": "doc.compare";
47
+ "doc.normalize": "doc.normalize";
48
+ "doc.renormalize": "doc.renormalize";
49
+ "doc.compact": "doc.compact";
50
+ "snapshot.project": "snapshot.project";
51
+ "project.duplicate": "project.duplicate";
52
+ "asset.derive": "asset.derive";
53
+ "account.export": "account.export";
54
+ "system.emailSend": "system.emailSend";
55
+ "system.emailDigest": "system.emailDigest";
56
+ "system.writingReminder": "system.writingReminder";
57
+ "system.pushSend": "system.pushSend";
58
+ "system.purge": "system.purge";
59
+ "system.retentionSweep": "system.retentionSweep";
60
+ "template.thumbnail": "template.thumbnail";
61
+ "image.generate": "image.generate";
62
+ "image.edit": "image.edit";
63
+ "image.upscale": "image.upscale";
64
+ "image.turnaround": "image.turnaround";
65
+ "video.generate": "video.generate";
66
+ "video.extend": "video.extend";
67
+ "video.upscale": "video.upscale";
68
+ "video.lipSync": "video.lipSync";
69
+ "voice.tts": "voice.tts";
70
+ "voice.cloneProfile": "voice.cloneProfile";
71
+ "voice.change": "voice.change";
72
+ "music.generate": "music.generate";
73
+ "sfx.generate": "sfx.generate";
74
+ "audio.isolate": "audio.isolate";
75
+ "model3d.generate": "model3d.generate";
76
+ "model3d.convert": "model3d.convert";
77
+ "model3d.rig": "model3d.rig";
78
+ "storyboard.generate": "storyboard.generate";
79
+ "animatic.assemble": "animatic.assemble";
80
+ "timeline.export": "timeline.export";
81
+ "test.echo": "test.echo";
82
+ "test.flaky": "test.flaky";
83
+ }>;
84
+ /** The `ai.*` kind an `AiTask` mirrors as (its `subkind` is the task itself). */
85
+ export declare function aiKindForTask(task: AiTask): JobKind;
86
+ export declare const isAiKind: (kind: string) => boolean;
87
+ export interface JobProgress {
88
+ /** 0..1 */
89
+ fraction: number;
90
+ stage: string | null;
91
+ /** An i18n key plus params, never prose (spec 05 §13.6). */
92
+ message: string | null;
93
+ }
94
+ export interface JobUsage {
95
+ promptTokens?: number;
96
+ completionTokens?: number;
97
+ model?: string | null;
98
+ pages?: number;
99
+ }
100
+ /** What `GET /jobs/:id` says about an output: no storage key, no URL (fetch those from `/jobs/:id/outputs`). */
101
+ export interface JobOutputSummary {
102
+ name: string;
103
+ mimeType: string;
104
+ sizeBytes: number;
105
+ recipientId?: string;
106
+ assetId?: string;
107
+ documentId?: string;
108
+ }
109
+ /** `GET /jobs/:jobId` never carries `request` or `result` bodies (spec 05 §10 rule 5), only summaries. */
110
+ export interface Job {
111
+ id: string;
112
+ kind: JobKind;
113
+ subkind: string | null;
114
+ status: JobStatus;
115
+ progress: JobProgress;
116
+ documentId: string | null;
117
+ /** Small scalar digest of the request (long strings dropped, arrays counted). */
118
+ requestSummary: Record<string, unknown>;
119
+ sources: JobSource[];
120
+ estimate?: JobEstimate;
121
+ quotedCredits?: number | null;
122
+ chargedCredits?: number | null;
123
+ refundedCredits?: number | null;
124
+ error?: string | null;
125
+ errorCode?: string | null;
126
+ usage?: JobUsage;
127
+ outputs?: JobOutputSummary[];
128
+ cancelRequested: boolean;
129
+ sourcesChangedDuringRun?: boolean | null;
130
+ attempt: number;
131
+ createdAt: string;
132
+ startedAt: string | null;
133
+ finishedAt: string | null;
134
+ }
135
+ export interface JobEstimate {
136
+ credits: number;
137
+ billable: boolean;
138
+ }
139
+ export declare const jobSourceSchema: z.ZodObject<{
140
+ documentId: z.ZodString;
141
+ snapshotId: z.ZodOptional<z.ZodString>;
142
+ targetKind: z.ZodString;
143
+ targetId: z.ZodString;
144
+ }, z.core.$strip>;
145
+ export type JobSource = z.infer<typeof jobSourceSchema> & {
146
+ sourceHash?: string;
147
+ };
148
+ /** `POST /jobs`. `idempotencyKey` (or the `Idempotency-Key` header) makes a retried create return the original job. */
149
+ export declare const jobCreateSchema: z.ZodObject<{
150
+ kind: z.ZodEnum<{
151
+ "ai.review": "ai.review";
152
+ "ai.polish": "ai.polish";
153
+ "ai.describe": "ai.describe";
154
+ "export.pdf": "export.pdf";
155
+ "export.fdx": "export.fdx";
156
+ "export.fountain": "export.fountain";
157
+ "export.fadein": "export.fadein";
158
+ "export.fadewright": "export.fadewright";
159
+ "export.json": "export.json";
160
+ "export.docx": "export.docx";
161
+ "watermark.batch": "watermark.batch";
162
+ "import.fdx": "import.fdx";
163
+ "import.fountain": "import.fountain";
164
+ "import.fadein": "import.fadein";
165
+ "import.pdf": "import.pdf";
166
+ "import.ocr": "import.ocr";
167
+ "import.celtx": "import.celtx";
168
+ "import.scrivener": "import.scrivener";
169
+ "import.fdxt": "import.fdxt";
170
+ "report.render": "report.render";
171
+ "doc.applyTemplate": "doc.applyTemplate";
172
+ "doc.importOver": "doc.importOver";
173
+ "doc.snapshotOpen": "doc.snapshotOpen";
174
+ "doc.versionRestore": "doc.versionRestore";
175
+ "doc.compare": "doc.compare";
176
+ "doc.normalize": "doc.normalize";
177
+ "doc.renormalize": "doc.renormalize";
178
+ "doc.compact": "doc.compact";
179
+ "snapshot.project": "snapshot.project";
180
+ "project.duplicate": "project.duplicate";
181
+ "asset.derive": "asset.derive";
182
+ "account.export": "account.export";
183
+ "system.emailSend": "system.emailSend";
184
+ "system.emailDigest": "system.emailDigest";
185
+ "system.writingReminder": "system.writingReminder";
186
+ "system.pushSend": "system.pushSend";
187
+ "system.purge": "system.purge";
188
+ "system.retentionSweep": "system.retentionSweep";
189
+ "template.thumbnail": "template.thumbnail";
190
+ "image.generate": "image.generate";
191
+ "image.edit": "image.edit";
192
+ "image.upscale": "image.upscale";
193
+ "image.turnaround": "image.turnaround";
194
+ "video.generate": "video.generate";
195
+ "video.extend": "video.extend";
196
+ "video.upscale": "video.upscale";
197
+ "video.lipSync": "video.lipSync";
198
+ "voice.tts": "voice.tts";
199
+ "voice.cloneProfile": "voice.cloneProfile";
200
+ "voice.change": "voice.change";
201
+ "music.generate": "music.generate";
202
+ "sfx.generate": "sfx.generate";
203
+ "audio.isolate": "audio.isolate";
204
+ "model3d.generate": "model3d.generate";
205
+ "model3d.convert": "model3d.convert";
206
+ "model3d.rig": "model3d.rig";
207
+ "storyboard.generate": "storyboard.generate";
208
+ "animatic.assemble": "animatic.assemble";
209
+ "timeline.export": "timeline.export";
210
+ "test.echo": "test.echo";
211
+ "test.flaky": "test.flaky";
212
+ }>;
213
+ input: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
214
+ sources: z.ZodDefault<z.ZodArray<z.ZodObject<{
215
+ documentId: z.ZodString;
216
+ snapshotId: z.ZodOptional<z.ZodString>;
217
+ targetKind: z.ZodString;
218
+ targetId: z.ZodString;
219
+ }, z.core.$strip>>>;
220
+ idempotencyKey: z.ZodOptional<z.ZodString>;
221
+ maxCredits: z.ZodOptional<z.ZodNumber>;
222
+ dryRun: z.ZodOptional<z.ZodBoolean>;
223
+ }, z.core.$strip>;
224
+ export type JobCreateRequest = z.input<typeof jobCreateSchema>;
225
+ /** `dryRun: true` answers this instead of a job. */
226
+ export interface JobDryRunResponse {
227
+ estimate: JobEstimate;
228
+ }
229
+ /** `?kind=` is exact (`export.pdf`) or a family prefix ending in a dot (`ai.`). */
230
+ export declare const jobListQuerySchema: z.ZodObject<{
231
+ limit: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
232
+ cursor: z.ZodOptional<z.ZodString>;
233
+ documentId: z.ZodOptional<z.ZodString>;
234
+ kind: z.ZodOptional<z.ZodString>;
235
+ status: z.ZodOptional<z.ZodEnum<{
236
+ cancelled: "cancelled";
237
+ queued: "queued";
238
+ running: "running";
239
+ succeeded: "succeeded";
240
+ failed: "failed";
241
+ }>>;
242
+ }, z.core.$strip>;
243
+ export type JobListQuery = z.input<typeof jobListQuerySchema>;
244
+ /** `GET /jobs/:jobId?wait=N` long-polls up to N seconds (max 120) until status or progress stage changes. */
245
+ export declare const JOB_WAIT_MAX_S = 120;
246
+ export declare const jobGetQuerySchema: z.ZodObject<{
247
+ wait: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
248
+ }, z.core.$strip>;
249
+ export type JobGetQuery = z.input<typeof jobGetQuerySchema>;
250
+ export interface JobOutput extends JobOutputSummary {
251
+ /** Signed download URL (or a `data:` URL for a small inline output). */
252
+ url: string;
253
+ expiresAt: string | null;
254
+ }
255
+ export interface JobOutputsResponse {
256
+ outputs: JobOutput[];
257
+ }
258
+ /** `GET /jobs/:jobId/recipients` item (batch watermark, B16). */
259
+ export interface JobRecipient {
260
+ id: string;
261
+ name: string;
262
+ email: string | null;
263
+ company: string | null;
264
+ exportId: string;
265
+ emailedAt: string | null;
266
+ firstDownloadedAt: string | null;
267
+ downloadCount: number;
268
+ }
269
+ /** `POST /webhooks/jobs/:adapterId`: every verified delivery answers this. */
270
+ export interface JobWebhookResponse {
271
+ ok: true;
272
+ }
273
+ /** Header carrying `sha256=<hex HMAC-SHA256(secret, raw body)>` on a provider webhook. */
274
+ export declare const JOB_WEBHOOK_SIGNATURE_HEADER = "X-Webhook-Signature";
275
+ /** The generic `Idempotency-Key` header (spec 05 §6.25). Values are 1-128 characters. */
276
+ export declare const IDEMPOTENCY_HEADER = "Idempotency-Key";
277
+ export declare const IDEMPOTENT_REPLAY_HEADER = "Idempotent-Replayed";
278
+ export declare const idempotencyKeySchema: z.ZodString;
@@ -0,0 +1,138 @@
1
+ import { z } from 'zod';
2
+ import { cursorQuerySchema } from '../api/pagination.js';
3
+ /**
4
+ * Generic jobs (spec 05 §6.19, §13; slice B9). A job is one row of `jobs`; `ai_jobs` rows are mirrored as `ai.*`
5
+ * jobs (decision D21a) so `/ai/jobs/:id` and `/jobs/:id` read the same job.
6
+ */
7
+ export const JOB_STATUSES = [
8
+ 'queued',
9
+ 'running',
10
+ 'succeeded',
11
+ 'failed',
12
+ 'cancelled',
13
+ ];
14
+ export const TERMINAL_JOB_STATUSES = [
15
+ 'succeeded',
16
+ 'failed',
17
+ 'cancelled',
18
+ ];
19
+ export const isTerminalJobStatus = (s) => TERMINAL_JOB_STATUSES.includes(s);
20
+ export const JOB_LANES = [
21
+ 'ai',
22
+ 'interactive',
23
+ 'bulk',
24
+ 'system',
25
+ 'provider',
26
+ ];
27
+ /**
28
+ * Closed vocabulary of job kinds, `<family>.<variant>` (R10). Every kind has a `job_kind_config` row; a kind
29
+ * without a registered runner is seeded disabled and `POST /jobs` answers `JOB_KIND_DISABLED`. Extend by adding a
30
+ * member here and a row in `screenwriter_api/src/services/jobs/kinds.ts`. `test.*` kinds exist only to prove the
31
+ * framework and are enabled only under `AI_TEST_MODE=1`.
32
+ */
33
+ export const JOB_KINDS = [
34
+ 'ai.review',
35
+ 'ai.polish',
36
+ 'ai.describe',
37
+ 'export.pdf',
38
+ 'export.fdx',
39
+ 'export.fountain',
40
+ 'export.fadein',
41
+ 'export.fadewright',
42
+ 'export.json',
43
+ 'export.docx',
44
+ 'watermark.batch',
45
+ 'import.fdx',
46
+ 'import.fountain',
47
+ 'import.fadein',
48
+ 'import.pdf',
49
+ 'import.ocr',
50
+ 'import.celtx',
51
+ 'import.scrivener',
52
+ 'import.fdxt',
53
+ 'report.render',
54
+ 'doc.applyTemplate',
55
+ 'doc.importOver',
56
+ 'doc.snapshotOpen',
57
+ 'doc.versionRestore',
58
+ 'doc.compare',
59
+ 'doc.normalize',
60
+ 'doc.renormalize',
61
+ 'doc.compact',
62
+ 'snapshot.project',
63
+ 'project.duplicate',
64
+ 'asset.derive',
65
+ 'account.export',
66
+ 'system.emailSend',
67
+ 'system.emailDigest',
68
+ 'system.writingReminder',
69
+ 'system.pushSend',
70
+ 'system.purge',
71
+ 'system.retentionSweep',
72
+ 'template.thumbnail',
73
+ // reserved for media adapters (spec 11 §6.2): registered, seeded disabled
74
+ 'image.generate',
75
+ 'image.edit',
76
+ 'image.upscale',
77
+ 'image.turnaround',
78
+ 'video.generate',
79
+ 'video.extend',
80
+ 'video.upscale',
81
+ 'video.lipSync',
82
+ 'voice.tts',
83
+ 'voice.cloneProfile',
84
+ 'voice.change',
85
+ 'music.generate',
86
+ 'sfx.generate',
87
+ 'audio.isolate',
88
+ 'model3d.generate',
89
+ 'model3d.convert',
90
+ 'model3d.rig',
91
+ 'storyboard.generate',
92
+ 'animatic.assemble',
93
+ 'timeline.export',
94
+ // framework tests
95
+ 'test.echo',
96
+ 'test.flaky',
97
+ ];
98
+ export const jobKindSchema = z.enum(JOB_KINDS);
99
+ /** The `ai.*` kind an `AiTask` mirrors as (its `subkind` is the task itself). */
100
+ export function aiKindForTask(task) {
101
+ return task.startsWith('polish') ? 'ai.polish' : 'ai.review';
102
+ }
103
+ export const isAiKind = (kind) => kind.startsWith('ai.');
104
+ export const jobSourceSchema = z.object({
105
+ documentId: z.string().min(1),
106
+ snapshotId: z.string().min(1).optional(),
107
+ targetKind: z.string().min(1).max(40),
108
+ targetId: z.string().min(1).max(100),
109
+ });
110
+ /** `POST /jobs`. `idempotencyKey` (or the `Idempotency-Key` header) makes a retried create return the original job. */
111
+ export const jobCreateSchema = z.object({
112
+ kind: jobKindSchema,
113
+ input: z.record(z.string(), z.unknown()).default({}),
114
+ sources: z.array(jobSourceSchema).max(20).default([]),
115
+ idempotencyKey: z.string().min(1).max(128).optional(),
116
+ maxCredits: z.number().int().min(0).optional(),
117
+ dryRun: z.boolean().optional(),
118
+ });
119
+ /** `?kind=` is exact (`export.pdf`) or a family prefix ending in a dot (`ai.`). */
120
+ export const jobListQuerySchema = cursorQuerySchema.extend({
121
+ documentId: z.string().min(1).optional(),
122
+ kind: z
123
+ .string()
124
+ .regex(/^[A-Za-z0-9]+(\.[A-Za-z0-9]*)?$/)
125
+ .optional(),
126
+ status: z.enum(JOB_STATUSES).optional(),
127
+ });
128
+ /** `GET /jobs/:jobId?wait=N` long-polls up to N seconds (max 120) until status or progress stage changes. */
129
+ export const JOB_WAIT_MAX_S = 120;
130
+ export const jobGetQuerySchema = z.object({
131
+ wait: z.coerce.number().int().min(0).max(JOB_WAIT_MAX_S).optional(),
132
+ });
133
+ /** Header carrying `sha256=<hex HMAC-SHA256(secret, raw body)>` on a provider webhook. */
134
+ export const JOB_WEBHOOK_SIGNATURE_HEADER = 'X-Webhook-Signature';
135
+ /** The generic `Idempotency-Key` header (spec 05 §6.25). Values are 1-128 characters. */
136
+ export const IDEMPOTENCY_HEADER = 'Idempotency-Key';
137
+ export const IDEMPOTENT_REPLAY_HEADER = 'Idempotent-Replayed';
138
+ export const idempotencyKeySchema = z.string().min(1).max(128);
@@ -0,0 +1,53 @@
1
+ import { z } from 'zod';
2
+ /** Personal API keys (`fwk_`), spec 05 4.2 and 6.5. */
3
+ export declare const API_KEY_SCOPES: readonly ["read", "read_write"];
4
+ export type ApiKeyScope = (typeof API_KEY_SCOPES)[number];
5
+ export declare const apiKeyScopeSchema: z.ZodEnum<{
6
+ read: "read";
7
+ read_write: "read_write";
8
+ }>;
9
+ /** At most this many active (unrevoked) keys per user. */
10
+ export declare const API_KEY_MAX_ACTIVE = 25;
11
+ /** `fwk_` + 8-char public prefix + `_` + 32 bytes base64url secret. */
12
+ export declare const API_KEY_FORMAT_RE: RegExp;
13
+ /** `GET /api-keys` item. Never contains the secret. */
14
+ export interface ApiKeySummary {
15
+ id: string;
16
+ name: string;
17
+ /** The 8-char public prefix. */
18
+ prefix: string;
19
+ workspaceId: string;
20
+ scope: ApiKeyScope;
21
+ ai: boolean;
22
+ createdAt: string;
23
+ lastUsedAt: string | null;
24
+ expiresAt: string | null;
25
+ revokedAt: string | null;
26
+ }
27
+ export declare const apiKeyCreateSchema: z.ZodObject<{
28
+ name: z.ZodString;
29
+ workspaceId: z.ZodString;
30
+ scope: z.ZodEnum<{
31
+ read: "read";
32
+ read_write: "read_write";
33
+ }>;
34
+ ai: z.ZodDefault<z.ZodBoolean>;
35
+ expiresInDays: z.ZodOptional<z.ZodNumber>;
36
+ }, z.core.$strip>;
37
+ export type ApiKeyCreateRequest = z.input<typeof apiKeyCreateSchema>;
38
+ /** `POST /api-keys` response: the only time `key` is ever returned. */
39
+ export type ApiKeyCreated = ApiKeySummary & {
40
+ key: string;
41
+ };
42
+ export declare const apiKeyUpdateSchema: z.ZodObject<{
43
+ name: z.ZodOptional<z.ZodString>;
44
+ ai: z.ZodOptional<z.ZodBoolean>;
45
+ }, z.core.$strip>;
46
+ export type ApiKeyUpdateRequest = z.infer<typeof apiKeyUpdateSchema>;
47
+ /** `DELETE /api-keys/:kid` response. */
48
+ export interface ApiKeyRevokeResponse {
49
+ revokedAt: string;
50
+ }
51
+ /** Sent by API clients so command transactions record the right origin (`fadewright-mcp/<version>`). */
52
+ export declare const CLIENT_HEADER = "X-Client";
53
+ export declare const MCP_CLIENT_NAME = "fadewright-mcp";
@@ -0,0 +1,22 @@
1
+ import { z } from 'zod';
2
+ /** Personal API keys (`fwk_`), spec 05 4.2 and 6.5. */
3
+ export const API_KEY_SCOPES = ['read', 'read_write'];
4
+ export const apiKeyScopeSchema = z.enum(API_KEY_SCOPES);
5
+ /** At most this many active (unrevoked) keys per user. */
6
+ export const API_KEY_MAX_ACTIVE = 25;
7
+ /** `fwk_` + 8-char public prefix + `_` + 32 bytes base64url secret. */
8
+ export const API_KEY_FORMAT_RE = /^fwk_([a-z0-9]{8})_([A-Za-z0-9_-]{43})$/;
9
+ export const apiKeyCreateSchema = z.object({
10
+ name: z.string().trim().min(1).max(60),
11
+ workspaceId: z.string().min(1),
12
+ scope: apiKeyScopeSchema,
13
+ ai: z.boolean().default(false),
14
+ expiresInDays: z.number().int().min(1).max(365).optional(),
15
+ });
16
+ export const apiKeyUpdateSchema = z.object({
17
+ name: z.string().trim().min(1).max(60).optional(),
18
+ ai: z.boolean().optional(),
19
+ });
20
+ /** Sent by API clients so command transactions record the right origin (`fadewright-mcp/<version>`). */
21
+ export const CLIENT_HEADER = 'X-Client';
22
+ export const MCP_CLIENT_NAME = 'fadewright-mcp';