@sequenceholdings/artifact-studio 0.4.0 → 0.5.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.
Files changed (90) hide show
  1. package/README.md +35 -1
  2. package/VERSION-PIN.md +9 -0
  3. package/dist/active-deploy-policy.d.ts +9 -3
  4. package/dist/active-deploy-policy.js +20 -8
  5. package/dist/artifact-env-bindings.d.ts +9 -0
  6. package/dist/artifact-env-bindings.js +32 -0
  7. package/dist/build.js +6 -0
  8. package/dist/cli.js +61 -12
  9. package/dist/deployment-validation.d.ts +2 -0
  10. package/dist/deployment-validation.js +2 -0
  11. package/dist/dev-link.js +28 -2
  12. package/dist/env-binding-scan.d.ts +10 -0
  13. package/dist/env-binding-scan.js +179 -0
  14. package/dist/env-bindings.d.ts +52 -0
  15. package/dist/env-bindings.js +180 -0
  16. package/dist/gateway/control.d.ts +33 -0
  17. package/dist/gateway/control.js +29 -0
  18. package/dist/gateway/hosted-proxy.d.ts +5 -0
  19. package/dist/gateway/hosted-proxy.js +4 -1
  20. package/dist/gateway/lattice-invoke.d.ts +48 -0
  21. package/dist/gateway/lattice-invoke.js +245 -0
  22. package/dist/gateway/lattice-upstream.d.ts +38 -0
  23. package/dist/gateway/lattice-upstream.js +136 -0
  24. package/dist/gateway/server.js +2 -3
  25. package/dist/gateway/session.d.ts +3 -1
  26. package/dist/gateway/session.js +10 -3
  27. package/dist/manifest-next.d.ts +55 -0
  28. package/dist/manifest-next.js +35 -2
  29. package/dist/manifest-static.d.ts +35 -0
  30. package/dist/manifest-static.js +12 -0
  31. package/dist/manifest.d.ts +48 -0
  32. package/dist/next-build.d.ts +2 -1
  33. package/dist/next-build.js +12 -7
  34. package/dist/offline/cache.d.ts +4 -0
  35. package/dist/offline/cache.js +7 -0
  36. package/dist/offline/connector.d.ts +26 -0
  37. package/dist/offline/connector.js +118 -0
  38. package/dist/offline/crypto.d.ts +5 -0
  39. package/dist/offline/crypto.js +24 -0
  40. package/dist/offline/index.d.ts +8 -0
  41. package/dist/offline/index.js +7 -0
  42. package/dist/offline/indexed-db.d.ts +10 -0
  43. package/dist/offline/indexed-db.js +104 -0
  44. package/dist/offline/outbox.d.ts +7 -0
  45. package/dist/offline/outbox.js +46 -0
  46. package/dist/offline/replay.d.ts +25 -0
  47. package/dist/offline/replay.js +192 -0
  48. package/dist/offline/secure-store.d.ts +6 -0
  49. package/dist/offline/secure-store.js +51 -0
  50. package/dist/offline/types.d.ts +162 -0
  51. package/dist/offline/types.js +1 -0
  52. package/dist/orm-json-scalars.d.ts +21 -0
  53. package/dist/orm-json-scalars.js +21 -0
  54. package/dist/runtime-contracts.d.ts +7 -7
  55. package/dist/sdk-orm.d.ts +7 -1
  56. package/dist/sdk-orm.js +12 -5
  57. package/dist/sdk.d.ts +126 -0
  58. package/dist/server/broker-contract.d.ts +191 -5
  59. package/dist/server/broker-contract.js +142 -1
  60. package/dist/server/client.d.ts +60 -12
  61. package/dist/server/client.js +143 -20
  62. package/dist/server/errors.d.ts +26 -0
  63. package/dist/server/errors.js +29 -0
  64. package/dist/server/managed-server-path.d.ts +6 -0
  65. package/dist/server/managed-server-path.js +14 -0
  66. package/dist/server/processes.d.ts +290 -0
  67. package/dist/server/processes.js +56 -0
  68. package/dist/server/request-context.d.ts +6 -0
  69. package/dist/server/request-context.js +10 -1
  70. package/dist/server.d.ts +5 -1
  71. package/dist/server.js +1 -0
  72. package/dist/source-resolver.d.ts +9 -2
  73. package/dist/source-resolver.js +55 -8
  74. package/dist/templates/nextjs/AGENTS.md +10 -0
  75. package/dist/templates/nextjs/CLAUDE.md +1 -0
  76. package/dist/templates/nextjs/README.md +88 -0
  77. package/dist/templates/react-vite/AGENTS.md +8 -88
  78. package/dist/templates/react-vite/CLAUDE.md +0 -6
  79. package/dist/templates/react-vite/package.json +1 -1
  80. package/dist/templates/react-vite/src/App.tsx +37 -14
  81. package/dist/templates/react-vite/src/styles.css +10 -0
  82. package/package.json +7 -3
  83. package/templates/nextjs/AGENTS.md +10 -0
  84. package/templates/nextjs/CLAUDE.md +1 -0
  85. package/templates/nextjs/README.md +88 -0
  86. package/templates/react-vite/AGENTS.md +8 -88
  87. package/templates/react-vite/CLAUDE.md +0 -6
  88. package/templates/react-vite/package.json +1 -1
  89. package/templates/react-vite/src/App.tsx +37 -14
  90. package/templates/react-vite/src/styles.css +10 -0
@@ -1,4 +1,5 @@
1
1
  import { z } from 'zod';
2
+ export { ORM_JSON_SCALARS_HEADER, ORM_LOSSLESS_JSON_SCALARS, type ArtifactOrmJsonScalars } from '../orm-json-scalars.js';
2
3
  export declare const artifactServerMethodSchema: z.ZodEnum<{
3
4
  GET: "GET";
4
5
  POST: "POST";
@@ -8,17 +9,38 @@ export declare const artifactServerMethodSchema: z.ZodEnum<{
8
9
  PATCH: "PATCH";
9
10
  }>;
10
11
  export declare const artifactServerModeSchema: z.ZodDefault<z.ZodEnum<{
11
- user: "user";
12
12
  service: "service";
13
+ user: "user";
13
14
  }>>;
14
15
  /** Reject paths that intermediaries can normalize into a different authorization target. */
15
16
  export declare function isArtifactApiPath(path: string): boolean;
17
+ /** A Lattice run's lifecycle status, as `GET /api/lattice/runs` filters it. */
18
+ export declare const ARTIFACT_PROCESS_RUN_STATUSES: readonly ["pending", "running", "completed", "failed", "cancelled", "timed_out"];
19
+ /** Lattice lists at most this many runs per call. */
20
+ export declare const ARTIFACT_PROCESS_RUNS_LIMIT = 500;
21
+ /** Which of the user's human steps to list: parked and waiting on them, or already done. */
22
+ export declare const ARTIFACT_PROCESS_TASK_VIEWS: readonly ["active", "completed"];
23
+ /** Lattice lists at most this many human steps per call, as its own inbox does. */
24
+ export declare const ARTIFACT_PROCESS_TASKS_LIMIT = 500;
25
+ /** A grant or revocation names at most this many users and groups together. */
26
+ export declare const ARTIFACT_PROCESS_PRINCIPALS_PER_CALL = 100;
27
+ /** A principal search returns at most this many users and groups together, as Lattice's own picker. */
28
+ export declare const ARTIFACT_PROCESS_PRINCIPAL_SEARCH_LIMIT = 50;
29
+ export declare const ARTIFACT_PROCESS_PRINCIPAL_TYPES: readonly ["user", "group"];
30
+ /** A start seeds assignments for at most this many human nodes. */
31
+ export declare const ARTIFACT_PROCESS_START_ASSIGNMENT_NODES = 64;
32
+ export declare const ARTIFACT_FLAGS_PER_REQUEST = 32;
33
+ /** The audit actions an application may record. Sign-in, identity merges and webhooks stay Atlas's. */
34
+ export declare const ARTIFACT_AUDIT_ACTIONS: readonly ["view", "search", "create", "update", "delete", "download", "upload", "export", "import", "share", "submit", "approve", "reject", "execute"];
35
+ /** One bulk action (archive the 100 selected applications) is one event naming each of them. */
36
+ export declare const ARTIFACT_AUDIT_RESOURCES_PER_EVENT = 100;
37
+ export declare const ARTIFACT_AUDIT_METADATA_KEYS = 32;
16
38
  /** Atlas validates these operations against current manifest, bindings and principal grants. */
17
39
  export declare const artifactServerRequestSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
18
40
  operation: z.ZodLiteral<"api">;
19
41
  mode: z.ZodDefault<z.ZodEnum<{
20
- user: "user";
21
42
  service: "service";
43
+ user: "user";
22
44
  }>>;
23
45
  method: z.ZodEnum<{
24
46
  GET: "GET";
@@ -33,17 +55,18 @@ export declare const artifactServerRequestSchema: z.ZodDiscriminatedUnion<[z.Zod
33
55
  }, z.core.$strict>, z.ZodObject<{
34
56
  operation: z.ZodLiteral<"orm">;
35
57
  mode: z.ZodDefault<z.ZodEnum<{
36
- user: "user";
37
58
  service: "service";
59
+ user: "user";
38
60
  }>>;
39
61
  namespace: z.ZodString;
40
62
  op: z.ZodString;
41
63
  variables: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
64
+ jsonScalars: z.ZodOptional<z.ZodLiteral<"lossless-v1">>;
42
65
  }, z.core.$strict>, z.ZodObject<{
43
66
  operation: z.ZodLiteral<"storage">;
44
67
  mode: z.ZodDefault<z.ZodEnum<{
45
- user: "user";
46
68
  service: "service";
69
+ user: "user";
47
70
  }>>;
48
71
  method: z.ZodEnum<{
49
72
  GET: "GET";
@@ -58,11 +81,174 @@ export declare const artifactServerRequestSchema: z.ZodDiscriminatedUnion<[z.Zod
58
81
  }, z.core.$strict>, z.ZodObject<{
59
82
  operation: z.ZodLiteral<"function">;
60
83
  mode: z.ZodDefault<z.ZodEnum<{
61
- user: "user";
62
84
  service: "service";
85
+ user: "user";
63
86
  }>>;
64
87
  id: z.ZodString;
65
88
  params: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
89
+ }, z.core.$strict>, z.ZodObject<{
90
+ operation: z.ZodLiteral<"lattice">;
91
+ mode: z.ZodDefault<z.ZodEnum<{
92
+ service: "service";
93
+ user: "user";
94
+ }>>;
95
+ process: z.ZodString;
96
+ runId: z.ZodOptional<z.ZodString>;
97
+ title: z.ZodOptional<z.ZodString>;
98
+ entity: z.ZodOptional<z.ZodObject<{
99
+ type: z.ZodString;
100
+ id: z.ZodString;
101
+ }, z.core.$strict>>;
102
+ metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
103
+ assignments: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
104
+ users: z.ZodOptional<z.ZodArray<z.ZodString>>;
105
+ groups: z.ZodOptional<z.ZodArray<z.ZodString>>;
106
+ }, z.core.$strict>>>;
107
+ }, z.core.$strict>, z.ZodObject<{
108
+ operation: z.ZodLiteral<"lattice_runs">;
109
+ mode: z.ZodDefault<z.ZodEnum<{
110
+ service: "service";
111
+ user: "user";
112
+ }>>;
113
+ process: z.ZodString;
114
+ status: z.ZodOptional<z.ZodEnum<{
115
+ running: "running";
116
+ failed: "failed";
117
+ cancelled: "cancelled";
118
+ pending: "pending";
119
+ completed: "completed";
120
+ timed_out: "timed_out";
121
+ }>>;
122
+ entity: z.ZodOptional<z.ZodObject<{
123
+ type: z.ZodString;
124
+ id: z.ZodOptional<z.ZodString>;
125
+ }, z.core.$strict>>;
126
+ limit: z.ZodOptional<z.ZodNumber>;
127
+ archived: z.ZodOptional<z.ZodBoolean>;
128
+ }, z.core.$strict>, z.ZodObject<{
129
+ operation: z.ZodLiteral<"lattice_run">;
130
+ mode: z.ZodDefault<z.ZodEnum<{
131
+ service: "service";
132
+ user: "user";
133
+ }>>;
134
+ runId: z.ZodString;
135
+ }, z.core.$strict>, z.ZodObject<{
136
+ operation: z.ZodLiteral<"lattice_process">;
137
+ mode: z.ZodDefault<z.ZodEnum<{
138
+ service: "service";
139
+ user: "user";
140
+ }>>;
141
+ process: z.ZodString;
142
+ version: z.ZodOptional<z.ZodString>;
143
+ }, z.core.$strict>, z.ZodObject<{
144
+ operation: z.ZodLiteral<"lattice_tasks">;
145
+ mode: z.ZodDefault<z.ZodEnum<{
146
+ service: "service";
147
+ user: "user";
148
+ }>>;
149
+ processes: z.ZodOptional<z.ZodArray<z.ZodString>>;
150
+ view: z.ZodOptional<z.ZodEnum<{
151
+ active: "active";
152
+ completed: "completed";
153
+ }>>;
154
+ limit: z.ZodOptional<z.ZodNumber>;
155
+ }, z.core.$strict>, z.ZodObject<{
156
+ operation: z.ZodLiteral<"lattice_advance">;
157
+ mode: z.ZodDefault<z.ZodEnum<{
158
+ service: "service";
159
+ user: "user";
160
+ }>>;
161
+ runId: z.ZodString;
162
+ stepId: z.ZodOptional<z.ZodString>;
163
+ edgeId: z.ZodOptional<z.ZodString>;
164
+ payload: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
165
+ }, z.core.$strict>, z.ZodObject<{
166
+ users: z.ZodOptional<z.ZodArray<z.ZodString>>;
167
+ groups: z.ZodOptional<z.ZodArray<z.ZodString>>;
168
+ operation: z.ZodLiteral<"lattice_assign">;
169
+ mode: z.ZodDefault<z.ZodEnum<{
170
+ service: "service";
171
+ user: "user";
172
+ }>>;
173
+ runId: z.ZodString;
174
+ stepId: z.ZodString;
175
+ }, z.core.$strict>, z.ZodObject<{
176
+ operation: z.ZodLiteral<"lattice_viewers">;
177
+ mode: z.ZodDefault<z.ZodEnum<{
178
+ service: "service";
179
+ user: "user";
180
+ }>>;
181
+ runId: z.ZodString;
182
+ }, z.core.$strict>, z.ZodObject<{
183
+ users: z.ZodOptional<z.ZodArray<z.ZodString>>;
184
+ groups: z.ZodOptional<z.ZodArray<z.ZodString>>;
185
+ operation: z.ZodLiteral<"lattice_viewer_grant">;
186
+ mode: z.ZodDefault<z.ZodEnum<{
187
+ service: "service";
188
+ user: "user";
189
+ }>>;
190
+ runId: z.ZodString;
191
+ }, z.core.$strict>, z.ZodObject<{
192
+ users: z.ZodOptional<z.ZodArray<z.ZodString>>;
193
+ groups: z.ZodOptional<z.ZodArray<z.ZodString>>;
194
+ operation: z.ZodLiteral<"lattice_viewer_revoke">;
195
+ mode: z.ZodDefault<z.ZodEnum<{
196
+ service: "service";
197
+ user: "user";
198
+ }>>;
199
+ runId: z.ZodString;
200
+ }, z.core.$strict>, z.ZodObject<{
201
+ operation: z.ZodLiteral<"lattice_principals">;
202
+ mode: z.ZodDefault<z.ZodEnum<{
203
+ service: "service";
204
+ user: "user";
205
+ }>>;
206
+ q: z.ZodString;
207
+ types: z.ZodOptional<z.ZodArray<z.ZodEnum<{
208
+ user: "user";
209
+ group: "group";
210
+ }>>>;
211
+ limit: z.ZodOptional<z.ZodNumber>;
212
+ }, z.core.$strict>, z.ZodObject<{
213
+ operation: z.ZodLiteral<"flags">;
214
+ mode: z.ZodDefault<z.ZodEnum<{
215
+ service: "service";
216
+ user: "user";
217
+ }>>;
218
+ names: z.ZodArray<z.ZodString>;
219
+ }, z.core.$strict>, z.ZodObject<{
220
+ eventId: z.ZodUUID;
221
+ action: z.ZodEnum<{
222
+ search: "search";
223
+ delete: "delete";
224
+ import: "import";
225
+ share: "share";
226
+ upload: "upload";
227
+ submit: "submit";
228
+ view: "view";
229
+ create: "create";
230
+ update: "update";
231
+ download: "download";
232
+ export: "export";
233
+ approve: "approve";
234
+ reject: "reject";
235
+ execute: "execute";
236
+ }>;
237
+ detail: z.ZodString;
238
+ resources: z.ZodArray<z.ZodObject<{
239
+ type: z.ZodString;
240
+ id: z.ZodString;
241
+ }, z.core.$strict>>;
242
+ metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean, z.ZodNull]>>>;
243
+ operation: z.ZodLiteral<"audit">;
244
+ mode: z.ZodDefault<z.ZodEnum<{
245
+ service: "service";
246
+ user: "user";
247
+ }>>;
66
248
  }, z.core.$strict>], "operation">;
67
249
  export type ArtifactServerRequest = z.infer<typeof artifactServerRequestSchema>;
68
250
  export type ArtifactServerMode = z.infer<typeof artifactServerModeSchema>;
251
+ export type ArtifactAuditAction = (typeof ARTIFACT_AUDIT_ACTIONS)[number];
252
+ export type ArtifactProcessRunStatus = (typeof ARTIFACT_PROCESS_RUN_STATUSES)[number];
253
+ export type ArtifactProcessTaskView = (typeof ARTIFACT_PROCESS_TASK_VIEWS)[number];
254
+ export type ArtifactProcessPrincipalType = (typeof ARTIFACT_PROCESS_PRINCIPAL_TYPES)[number];
@@ -1,4 +1,6 @@
1
1
  import { z } from 'zod';
2
+ import { ORM_LOSSLESS_JSON_SCALARS } from '../orm-json-scalars.js';
3
+ export { ORM_JSON_SCALARS_HEADER, ORM_LOSSLESS_JSON_SCALARS } from '../orm-json-scalars.js';
2
4
  export const artifactServerMethodSchema = z.enum(['GET', 'HEAD', 'POST', 'PUT', 'PATCH', 'DELETE']);
3
5
  export const artifactServerModeSchema = z.enum(['user', 'service']).default('user');
4
6
  /** Reject paths that intermediaries can normalize into a different authorization target. */
@@ -21,13 +23,152 @@ const path = z.string().min(6).max(8192).refine(isArtifactApiPath, 'Expected a c
21
23
  const method = artifactServerMethodSchema;
22
24
  const mode = artifactServerModeSchema;
23
25
  const id = z.string().min(1).max(255).regex(/^[a-zA-Z0-9_-]+$/);
26
+ // Lattice ids become FGA object ids, so they keep to the FGA-safe class.
27
+ const latticeId = z.string().min(2).max(128).regex(/^[A-Za-z0-9._-]+$/);
28
+ // A process version is the registry's own label (the bundle hash prefix today); FGA-safe class.
29
+ const latticeVersion = z.string().min(1).max(128).regex(/^[A-Za-z0-9._-]+$/);
30
+ /** A Lattice run's lifecycle status, as `GET /api/lattice/runs` filters it. */
31
+ export const ARTIFACT_PROCESS_RUN_STATUSES = ['pending', 'running', 'completed', 'failed', 'cancelled', 'timed_out'];
32
+ /** Lattice lists at most this many runs per call. */
33
+ export const ARTIFACT_PROCESS_RUNS_LIMIT = 500;
34
+ /** Which of the user's human steps to list: parked and waiting on them, or already done. */
35
+ export const ARTIFACT_PROCESS_TASK_VIEWS = ['active', 'completed'];
36
+ /** Lattice lists at most this many human steps per call, as its own inbox does. */
37
+ export const ARTIFACT_PROCESS_TASKS_LIMIT = 500;
38
+ /** A grant or revocation names at most this many users and groups together. */
39
+ export const ARTIFACT_PROCESS_PRINCIPALS_PER_CALL = 100;
40
+ /** A principal search returns at most this many users and groups together, as Lattice's own picker. */
41
+ export const ARTIFACT_PROCESS_PRINCIPAL_SEARCH_LIMIT = 50;
42
+ export const ARTIFACT_PROCESS_PRINCIPAL_TYPES = ['user', 'group'];
43
+ // A user's Auth0 `sub` or a chat group id, as FGA subjects are keyed: no whitespace, `:`, `#` or `*`.
44
+ const principalId = z.string().min(1).max(255).regex(/^[^\s:#*]+$/);
45
+ /** The users and groups a grant, revocation or reassignment names: at least one principal, bounded. */
46
+ const principalSet = {
47
+ users: z.array(principalId).max(ARTIFACT_PROCESS_PRINCIPALS_PER_CALL).optional(),
48
+ groups: z.array(principalId).max(ARTIFACT_PROCESS_PRINCIPALS_PER_CALL).optional(),
49
+ };
50
+ function namesPrincipals(value) {
51
+ const count = (value.users?.length ?? 0) + (value.groups?.length ?? 0);
52
+ return count > 0 && count <= ARTIFACT_PROCESS_PRINCIPALS_PER_CALL;
53
+ }
54
+ const PRINCIPAL_SET_MESSAGE = `Between 1 and ${ARTIFACT_PROCESS_PRINCIPALS_PER_CALL} users and groups`;
55
+ /** A start seeds assignments for at most this many human nodes. */
56
+ export const ARTIFACT_PROCESS_START_ASSIGNMENT_NODES = 64;
57
+ // A human node of the started run (`execute`), or one inside a nested subprocess (`application::qa_review`).
58
+ const assignmentNodeKey = z.string().min(1).max(255).regex(/^[A-Za-z0-9._-]+(?:::[A-Za-z0-9._-]+)*$/);
59
+ /**
60
+ * Per-run default assignees for human nodes, as `POST /api/lattice/runs` takes them: each node's
61
+ * principals become its advancers when the run reaches it. Atlas refuses principals it has tombstoned.
62
+ */
63
+ const runAssignments = z.record(assignmentNodeKey, z.object(principalSet).strict().refine(namesPrincipals, PRINCIPAL_SET_MESSAGE))
64
+ .refine((value) => Object.keys(value).length > 0 && Object.keys(value).length <= ARTIFACT_PROCESS_START_ASSIGNMENT_NODES, `Between 1 and ${ARTIFACT_PROCESS_START_ASSIGNMENT_NODES} assigned nodes`);
65
+ const entityRef = z.string().min(1).max(255);
66
+ // Unleash feature names are URL-safe.
67
+ const flagName = z.string().min(1).max(255).regex(/^[A-Za-z0-9._~-]+$/);
68
+ export const ARTIFACT_FLAGS_PER_REQUEST = 32;
69
+ /** The audit actions an application may record. Sign-in, identity merges and webhooks stay Atlas's. */
70
+ export const ARTIFACT_AUDIT_ACTIONS = [
71
+ 'view', 'search', 'create', 'update', 'delete', 'download', 'upload', 'export', 'import', 'share', 'submit', 'approve', 'reject', 'execute',
72
+ ];
73
+ /** One bulk action (archive the 100 selected applications) is one event naming each of them. */
74
+ export const ARTIFACT_AUDIT_RESOURCES_PER_EVENT = 100;
75
+ export const ARTIFACT_AUDIT_METADATA_KEYS = 32;
76
+ // Resource types are identifiers, as Atlas's own (`application`, `applicationDocument`), so an
77
+ // application that takes over a product's routes can keep the types its audit queries filter on.
78
+ const auditResourceType = z.string().regex(/^[A-Za-z][A-Za-z0-9_]{0,63}$/);
79
+ const auditMetadataKey = z.string().regex(/^[A-Za-z][A-Za-z0-9_]{0,63}$/);
80
+ const auditEvent = {
81
+ /** Names the logical event. A retry of the same event reuses it, so the audit sink keeps one copy. */
82
+ eventId: z.uuid(),
83
+ action: z.enum(ARTIFACT_AUDIT_ACTIONS),
84
+ /** What happened, as the product names it (`applications.view`). Recorded as the event's `action_detail`. */
85
+ detail: z.string().regex(/^[a-z][a-z0-9_.-]{0,95}$/),
86
+ // None for an event about no one record (a list or a settings view), as Atlas's own list events.
87
+ resources: z.array(z.object({ type: auditResourceType, id: z.string().min(1).max(255) }).strict())
88
+ .max(ARTIFACT_AUDIT_RESOURCES_PER_EVENT),
89
+ // Scalars only: an audit record names what happened, it doesn't copy payloads.
90
+ metadata: z.record(auditMetadataKey, z.union([z.string().max(256), z.number(), z.boolean(), z.null()]))
91
+ .refine(value => Object.keys(value).length <= ARTIFACT_AUDIT_METADATA_KEYS, `At most ${ARTIFACT_AUDIT_METADATA_KEYS} metadata keys`)
92
+ .optional(),
93
+ };
24
94
  /** Atlas validates these operations against current manifest, bindings and principal grants. */
25
95
  export const artifactServerRequestSchema = z.discriminatedUnion('operation', [
26
96
  z.object({ operation: z.literal('api'), mode, method, path, body: z.unknown().optional() }).strict(),
27
- z.object({ operation: z.literal('orm'), mode, namespace: id, op: z.string().regex(/^sha256:[a-f0-9]{64}$/), variables: z.record(z.string(), z.unknown()).optional() }).strict(),
97
+ // jsonScalars asks the data plane for exact numeric and bigint strings; Atlas forwards it as
98
+ // the data plane's own header and passes the acknowledgment back.
99
+ z.object({
100
+ operation: z.literal('orm'), mode, namespace: id, op: z.string().regex(/^sha256:[a-f0-9]{64}$/),
101
+ variables: z.record(z.string(), z.unknown()).optional(), jsonScalars: z.literal(ORM_LOSSLESS_JSON_SCALARS).optional(),
102
+ }).strict(),
28
103
  z.object({ operation: z.literal('storage'), mode, method, path: path.refine(value => {
29
104
  const pathname = value.split('?')[0];
30
105
  return pathname === '/api/storage' || pathname.startsWith('/api/storage/');
31
106
  }, 'Expected a Storage API path'), body: z.unknown().optional() }).strict(),
32
107
  z.object({ operation: z.literal('function'), mode, id, params: z.record(z.string(), z.unknown()).optional() }).strict(),
108
+ // Starts a run of a declared process, as `POST /api/lattice/runs` does: the application names the
109
+ // run, passes its input and may seed who works each human node. The start node, version and
110
+ // engine stay with the process and its owning routes.
111
+ z.object({
112
+ operation: z.literal('lattice'), mode, process: latticeId, runId: latticeId.optional(),
113
+ title: z.string().max(500).optional(),
114
+ entity: z.object({ type: entityRef, id: entityRef }).strict().optional(),
115
+ metadata: z.record(z.string(), z.unknown()).optional(),
116
+ assignments: runAssignments.optional(),
117
+ }).strict(),
118
+ // Lists runs of a declared process, as `GET /api/lattice/runs` does: newest first, only the runs
119
+ // the user may view. Soft-archived runs are excluded unless `archived` is set.
120
+ z.object({
121
+ operation: z.literal('lattice_runs'), mode, process: latticeId,
122
+ status: z.enum(ARTIFACT_PROCESS_RUN_STATUSES).optional(),
123
+ entity: z.object({ type: entityRef, id: entityRef.optional() }).strict().optional(),
124
+ limit: z.number().int().min(1).max(ARTIFACT_PROCESS_RUNS_LIMIT).optional(),
125
+ archived: z.boolean().optional(),
126
+ }).strict(),
127
+ // Reads one run the user may view, as `GET /api/lattice/runs/[runId]` does: the run, its steps, the
128
+ // collapsed per-node states and the event cursor to resume its stream from.
129
+ z.object({ operation: z.literal('lattice_run'), mode, runId: latticeId }).strict(),
130
+ // Describes a declared process — the applied template its runs are filled in from: nodes, edges and
131
+ // what a person working each human step is shown. The active version, or the one a run pinned.
132
+ z.object({ operation: z.literal('lattice_process'), mode, process: latticeId, version: latticeVersion.optional() }).strict(),
133
+ // Lists the user's own human steps across declared processes (a subset, or every declared one),
134
+ // as `GET /api/lattice/inbox` does for the Tasks app: newest first, from the assignment index.
135
+ z.object({
136
+ operation: z.literal('lattice_tasks'), mode,
137
+ processes: z.array(latticeId).min(1).max(256).optional(),
138
+ view: z.enum(ARTIFACT_PROCESS_TASK_VIEWS).optional(),
139
+ limit: z.number().int().min(1).max(ARTIFACT_PROCESS_TASKS_LIMIT).optional(),
140
+ }).strict(),
141
+ // Completes one of the user's parked human steps on a run of a process declared under
142
+ // `processes.act`, as `POST /api/lattice/runs/[runId]/advance` does. The user's own step
143
+ // `advancer` grant decides; the application cannot complete it as someone else.
144
+ z.object({
145
+ operation: z.literal('lattice_advance'), mode, runId: latticeId,
146
+ stepId: latticeId.optional(), edgeId: z.string().min(1).max(255).optional(),
147
+ payload: z.record(z.string(), z.unknown()).optional(),
148
+ }).strict(),
149
+ // Reassigns a parked human step to users and groups, as `POST .../steps/[stepId]/assign` does.
150
+ // The user's run `owner` relation decides; the node's assignee allowlist still applies.
151
+ z.object({ operation: z.literal('lattice_assign'), mode, runId: latticeId, stepId: latticeId, ...principalSet }).strict()
152
+ .refine(namesPrincipals, PRINCIPAL_SET_MESSAGE),
153
+ // The explicit viewer grants on a run, for its owner.
154
+ z.object({ operation: z.literal('lattice_viewers'), mode, runId: latticeId }).strict(),
155
+ // Shares a run with users and groups (grants `viewer`), or takes a share back. Owner-gated;
156
+ // grants Atlas has tombstoned (disabled users, deleted groups) are refused.
157
+ z.object({ operation: z.literal('lattice_viewer_grant'), mode, runId: latticeId, ...principalSet }).strict()
158
+ .refine(namesPrincipals, PRINCIPAL_SET_MESSAGE),
159
+ z.object({ operation: z.literal('lattice_viewer_revoke'), mode, runId: latticeId, ...principalSet }).strict()
160
+ .refine(namesPrincipals, PRINCIPAL_SET_MESSAGE),
161
+ // Finds users in the user's own tenant and groups they may see, to name in an assignment or a
162
+ // share. The user is the directory's own, so no manifest binding beyond `processes.act` applies.
163
+ z.object({
164
+ operation: z.literal('lattice_principals'), mode, q: z.string().trim().max(200),
165
+ types: z.array(z.enum(ARTIFACT_PROCESS_PRINCIPAL_TYPES)).min(1).max(2).optional(),
166
+ limit: z.number().int().min(1).max(ARTIFACT_PROCESS_PRINCIPAL_SEARCH_LIMIT).optional(),
167
+ }).strict(),
168
+ // Evaluates feature flags as Atlas evaluates its own: for the user, or with no user in service mode.
169
+ // A read: it needs no manifest declaration, as the browser bridge's flags.isEnabled needs none.
170
+ z.object({ operation: z.literal('flags'), mode, names: z.array(flagName).min(1).max(ARTIFACT_FLAGS_PER_REQUEST) }).strict(),
171
+ // Records an audit event for the request's user, under the service `server.capabilities.audit`
172
+ // declares. It changes no data, so read-only and stale contexts may record what they read.
173
+ z.object({ operation: z.literal('audit'), mode, ...auditEvent }).strict(),
33
174
  ]);
@@ -1,15 +1,14 @@
1
1
  import { storageClient } from '@sequenceholdings/storage';
2
2
  import { type OperationExecutor } from '@sequenceholdings/orm/client';
3
3
  import type { SequenceApiFetchResponse } from '../sdk.js';
4
- import { type ArtifactServerMode, type ArtifactServerRequest } from './broker-contract.js';
4
+ import { type ArtifactAuditAction, type ArtifactServerMode, type ArtifactServerRequest } from './broker-contract.js';
5
+ import { type ArtifactServerProcesses } from './processes.js';
6
+ import { type ArtifactOrmJsonScalars } from '../orm-json-scalars.js';
5
7
  import { createArtifactLogger, type ArtifactLogRecord } from './logger.js';
6
8
  import { type ArtifactRequestContext } from './request-context.js';
7
9
  import { type ArtifactRuntimeConfig, type ArtifactRequestHeaders } from './runtime-config.js';
8
- export declare class ArtifactServerError extends Error {
9
- readonly status: number;
10
- readonly code: string;
11
- constructor(status: number, code: string, message: string);
12
- }
10
+ export { ArtifactServerError } from './errors.js';
11
+ export type * from './processes.js';
13
12
  export interface ArtifactServerFetchOptions {
14
13
  method?: 'GET' | 'HEAD' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
15
14
  body?: unknown;
@@ -29,6 +28,49 @@ export interface ArtifactOrmOperations {
29
28
  readonly requires?: unknown;
30
29
  }>>;
31
30
  }
31
+ export interface ArtifactOrmOptions {
32
+ namespace: string;
33
+ manifest: ArtifactOrmOperations;
34
+ /**
35
+ * `lossless-v1` returns numeric and bigint values as strings instead of JSON numbers,
36
+ * so money and large ids survive a read-then-write. The executor refuses any successful
37
+ * result Atlas does not acknowledge in that form. Omit it for the JSON-number default.
38
+ */
39
+ jsonScalars?: ArtifactOrmJsonScalars;
40
+ }
41
+ /**
42
+ * Feature flags, evaluated by Atlas for this request's user (with no user in service mode), the
43
+ * same evaluation Atlas routes make. Any flag may be read, as in the browser's `seq.flags`. A
44
+ * refused or failed request rejects with ArtifactServerError; treat that as off where a flag gates
45
+ * a change.
46
+ */
47
+ export interface ArtifactServerFlags {
48
+ isEnabled(flagName: string): Promise<boolean>;
49
+ /** Up to ARTIFACT_FLAGS_PER_REQUEST flags in one broker call. */
50
+ evaluate(flagNames: readonly string[]): Promise<Record<string, boolean>>;
51
+ }
52
+ /** One audit event, recorded for this request's user under the manifest's `server.capabilities.audit` service. */
53
+ export interface ArtifactAuditEvent {
54
+ action: ArtifactAuditAction;
55
+ /** What happened, as the product names it (`applications.view`). Recorded as the event's `action_detail`. */
56
+ detail: string;
57
+ /** What it happened to, at most ARTIFACT_AUDIT_RESOURCES_PER_EVENT: `{ type: 'application', id }`. Empty for a list. */
58
+ resources: ReadonlyArray<{
59
+ type: string;
60
+ id: string;
61
+ }>;
62
+ /** Scalars that qualify the event (counts, kinds, outcomes). Never payloads, document contents or secrets. */
63
+ metadata?: Readonly<Record<string, string | number | boolean | null>>;
64
+ /** Names the logical event; one is generated when omitted. Pass the same id to retry the same event. */
65
+ eventId?: string;
66
+ }
67
+ /**
68
+ * Audit events, delivered before `record` resolves. A refused or undeliverable event rejects with
69
+ * ArtifactServerError; decide per route whether that should fail the request.
70
+ */
71
+ export interface ArtifactServerAudit {
72
+ record(event: ArtifactAuditEvent): Promise<void>;
73
+ }
32
74
  export interface ArtifactServerClient {
33
75
  context: ArtifactRequestContext;
34
76
  mode: ArtifactServerMode;
@@ -38,10 +80,10 @@ export interface ArtifactServerClient {
38
80
  functions: {
39
81
  invoke<TOutput = unknown>(id: string, params?: Record<string, unknown>): Promise<TOutput>;
40
82
  };
41
- orm(input: {
42
- namespace: string;
43
- manifest: ArtifactOrmOperations;
44
- }): OperationExecutor;
83
+ processes: ArtifactServerProcesses;
84
+ flags: ArtifactServerFlags;
85
+ audit: ArtifactServerAudit;
86
+ orm(input: ArtifactOrmOptions): OperationExecutor;
45
87
  asService(): ArtifactServerClient;
46
88
  }
47
89
  /** One instance per incoming request. Never cache it at module scope. */
@@ -63,7 +105,14 @@ type ClientArguments = {
63
105
  logSink?: (record: ArtifactLogRecord) => void;
64
106
  };
65
107
  type BrokerTransport = ReturnType<typeof createBrokerTransport>;
66
- declare function createBrokerTransport({ context, token, getRuntime, fetcher }: ClientArguments): (input: ArtifactServerRequest, signal?: AbortSignal) => Promise<Response>;
108
+ interface BrokerCallOptions {
109
+ signal?: AbortSignal;
110
+ /** Whether sending the call twice is harmless. Defaults to the operation's own answer (isReadOperation). */
111
+ replaySafe?: boolean;
112
+ }
113
+ declare function createBrokerTransport({ context, token, getRuntime, fetcher, log }: ClientArguments & {
114
+ log: ReturnType<typeof createArtifactLogger>;
115
+ }): (input: ArtifactServerRequest, { signal, replaySafe }?: BrokerCallOptions) => Promise<Response>;
67
116
  declare function createApiClient({ mode, request, json }: {
68
117
  mode: ArtifactServerMode;
69
118
  request: BrokerTransport;
@@ -78,4 +127,3 @@ declare function createApiClient({ mode, request, json }: {
78
127
  patch: <T = unknown>(path: string, body?: unknown) => Promise<T>;
79
128
  delete: <T = unknown>(path: string, body?: unknown) => Promise<T>;
80
129
  };
81
- export {};