@kumwe/studio-core 0.1.0-alpha.10

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 (104) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +86 -0
  3. package/THIRD_PARTY_NOTICES.md +9 -0
  4. package/dist/binding-projection.d.ts +47 -0
  5. package/dist/binding-projection.d.ts.map +1 -0
  6. package/dist/binding-projection.js +253 -0
  7. package/dist/binding-projection.js.map +1 -0
  8. package/dist/canonical.d.ts +20 -0
  9. package/dist/canonical.d.ts.map +1 -0
  10. package/dist/canonical.js +100 -0
  11. package/dist/canonical.js.map +1 -0
  12. package/dist/clone.d.ts +2 -0
  13. package/dist/clone.d.ts.map +1 -0
  14. package/dist/clone.js +4 -0
  15. package/dist/clone.js.map +1 -0
  16. package/dist/commands.d.ts +18 -0
  17. package/dist/commands.d.ts.map +1 -0
  18. package/dist/commands.js +799 -0
  19. package/dist/commands.js.map +1 -0
  20. package/dist/contributions.d.ts +93 -0
  21. package/dist/contributions.d.ts.map +1 -0
  22. package/dist/contributions.js +435 -0
  23. package/dist/contributions.js.map +1 -0
  24. package/dist/entry-commands.d.ts +3 -0
  25. package/dist/entry-commands.d.ts.map +1 -0
  26. package/dist/entry-commands.js +36 -0
  27. package/dist/entry-commands.js.map +1 -0
  28. package/dist/extension-sdk.d.ts +51 -0
  29. package/dist/extension-sdk.d.ts.map +1 -0
  30. package/dist/extension-sdk.js +260 -0
  31. package/dist/extension-sdk.js.map +1 -0
  32. package/dist/history.d.ts +22 -0
  33. package/dist/history.d.ts.map +1 -0
  34. package/dist/history.js +81 -0
  35. package/dist/history.js.map +1 -0
  36. package/dist/host-session.d.ts +74 -0
  37. package/dist/host-session.d.ts.map +1 -0
  38. package/dist/host-session.js +713 -0
  39. package/dist/host-session.js.map +1 -0
  40. package/dist/index.d.ts +23 -0
  41. package/dist/index.d.ts.map +1 -0
  42. package/dist/index.js +23 -0
  43. package/dist/index.js.map +1 -0
  44. package/dist/layout.d.ts +66 -0
  45. package/dist/layout.d.ts.map +1 -0
  46. package/dist/layout.js +240 -0
  47. package/dist/layout.js.map +1 -0
  48. package/dist/migrations.d.ts +47 -0
  49. package/dist/migrations.d.ts.map +1 -0
  50. package/dist/migrations.js +83 -0
  51. package/dist/migrations.js.map +1 -0
  52. package/dist/model-commands.d.ts +3 -0
  53. package/dist/model-commands.d.ts.map +1 -0
  54. package/dist/model-commands.js +21 -0
  55. package/dist/model-commands.js.map +1 -0
  56. package/dist/modes.d.ts +47 -0
  57. package/dist/modes.d.ts.map +1 -0
  58. package/dist/modes.js +280 -0
  59. package/dist/modes.js.map +1 -0
  60. package/dist/negotiation.d.ts +23 -0
  61. package/dist/negotiation.d.ts.map +1 -0
  62. package/dist/negotiation.js +65 -0
  63. package/dist/negotiation.js.map +1 -0
  64. package/dist/production-values.d.ts +12 -0
  65. package/dist/production-values.d.ts.map +1 -0
  66. package/dist/production-values.js +224 -0
  67. package/dist/production-values.js.map +1 -0
  68. package/dist/production.d.ts +86 -0
  69. package/dist/production.d.ts.map +1 -0
  70. package/dist/production.js +811 -0
  71. package/dist/production.js.map +1 -0
  72. package/dist/profile-validator.d.ts +47 -0
  73. package/dist/profile-validator.d.ts.map +1 -0
  74. package/dist/profile-validator.js +887 -0
  75. package/dist/profile-validator.js.map +1 -0
  76. package/dist/recipes.d.ts +15 -0
  77. package/dist/recipes.d.ts.map +1 -0
  78. package/dist/recipes.js +34 -0
  79. package/dist/recipes.js.map +1 -0
  80. package/dist/registry.d.ts +17 -0
  81. package/dist/registry.d.ts.map +1 -0
  82. package/dist/registry.js +56 -0
  83. package/dist/registry.js.map +1 -0
  84. package/dist/schema-profile.d.ts +27 -0
  85. package/dist/schema-profile.d.ts.map +1 -0
  86. package/dist/schema-profile.js +1015 -0
  87. package/dist/schema-profile.js.map +1 -0
  88. package/dist/semver.d.ts +20 -0
  89. package/dist/semver.d.ts.map +1 -0
  90. package/dist/semver.js +128 -0
  91. package/dist/semver.js.map +1 -0
  92. package/dist/session.d.ts +73 -0
  93. package/dist/session.d.ts.map +1 -0
  94. package/dist/session.js +191 -0
  95. package/dist/session.js.map +1 -0
  96. package/dist/url-policy.d.ts +45 -0
  97. package/dist/url-policy.d.ts.map +1 -0
  98. package/dist/url-policy.js +248 -0
  99. package/dist/url-policy.js.map +1 -0
  100. package/dist/validation.d.ts +13 -0
  101. package/dist/validation.d.ts.map +1 -0
  102. package/dist/validation.js +444 -0
  103. package/dist/validation.js.map +1 -0
  104. package/package.json +41 -0
@@ -0,0 +1,21 @@
1
+ import { cloneContractValue } from './clone.js';
2
+ import { StudioCommandError } from './commands.js';
3
+ export function applyModelCommand(model, command) {
4
+ if (command.artifactId !== model.id) {
5
+ throw new StudioCommandError('node-not-found', `Command targets ${command.artifactId}, not content model ${model.id}.`);
6
+ }
7
+ if (model.status !== 'draft') {
8
+ throw new StudioCommandError('artifact-not-draft', `Content model ${model.id} is ${model.status}; fields are added through a new draft.`);
9
+ }
10
+ if (model.fields.some((field) => field.id === command.payload.field.id)) {
11
+ throw new StudioCommandError('duplicate-field', `Field ${command.payload.field.id} already exists on ${model.id}.`);
12
+ }
13
+ const position = command.payload.position ?? model.fields.length;
14
+ if (!Number.isInteger(position) || position < 0 || position > model.fields.length) {
15
+ throw new StudioCommandError('invalid-index', `Field position ${position} is outside the model's field list.`);
16
+ }
17
+ const next = cloneContractValue(model);
18
+ next.fields.splice(position, 0, cloneContractValue(command.payload.field));
19
+ return next;
20
+ }
21
+ //# sourceMappingURL=model-commands.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model-commands.js","sourceRoot":"","sources":["../src/model-commands.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAEnD,MAAM,UAAU,iBAAiB,CAC/B,KAA2B,EAC3B,OAA6B;IAE7B,IAAI,OAAO,CAAC,UAAU,KAAK,KAAK,CAAC,EAAE,EAAE,CAAC;QACpC,MAAM,IAAI,kBAAkB,CAC1B,gBAAgB,EAChB,mBAAmB,OAAO,CAAC,UAAU,uBAAuB,KAAK,CAAC,EAAE,GAAG,CACxE,CAAC;IACJ,CAAC;IACD,IAAI,KAAK,CAAC,MAAM,KAAK,OAAO,EAAE,CAAC;QAC7B,MAAM,IAAI,kBAAkB,CAC1B,oBAAoB,EACpB,iBAAiB,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC,MAAM,yCAAyC,CACtF,CAAC;IACJ,CAAC;IACD,IAAI,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,KAAK,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC;QACxE,MAAM,IAAI,kBAAkB,CAC1B,iBAAiB,EACjB,SAAS,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,sBAAsB,KAAK,CAAC,EAAE,GAAG,CACnE,CAAC;IACJ,CAAC;IACD,MAAM,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC,QAAQ,IAAI,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC;IACjE,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,QAAQ,GAAG,CAAC,IAAI,QAAQ,GAAG,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;QAClF,MAAM,IAAI,kBAAkB,CAC1B,eAAe,EACf,kBAAkB,QAAQ,qCAAqC,CAChE,CAAC;IACJ,CAAC;IAED,MAAM,IAAI,GAAG,kBAAkB,CAAC,KAAK,CAAC,CAAC;IACvC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,EAAE,kBAAkB,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;IAC3E,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -0,0 +1,47 @@
1
+ import type { BlueprintCommand, BlueprintDocument, StudioCommand, StudioConfiguration, StudioSessionMode } from '@kumwe/studio-protocol';
2
+ /**
3
+ * Every session mode, in stable sorted order. The permitted-command table is
4
+ * total over exactly this set.
5
+ */
6
+ export declare const STUDIO_SESSION_MODES: readonly StudioSessionMode[];
7
+ /** Every canonical command type addressable by the mode table. */
8
+ export type StudioCommandType = StudioCommand['type'];
9
+ /**
10
+ * The deterministic mode-to-permitted-command table: one immutable set per
11
+ * session mode, shared across calls, so UIs derive disabled affordances from
12
+ * the same source the session enforces. The table is type-level only; the
13
+ * hybrid entries additionally require every affected collection to stay
14
+ * inside a structural authoring region, which the session enforces per
15
+ * command target.
16
+ */
17
+ export declare function permittedCommandTypes(mode: StudioSessionMode): ReadonlySet<StudioCommandType>;
18
+ /**
19
+ * Flattens a configuration's editing mode, composite, and session state into
20
+ * the single session mode fixed at session creation: a read-only session
21
+ * state always flattens to `read-only`, the hybrid composite flattens to
22
+ * `hybrid`, and every other session keeps its authoring mode. The hybrid
23
+ * composite is invalid with Model mode, mirroring the configuration schema.
24
+ */
25
+ export declare function resolveSessionMode(configuration: Pick<StudioConfiguration, 'composite' | 'mode' | 'sessionState'>): StudioSessionMode;
26
+ /**
27
+ * Fails closed with the stable `mode-forbidden` code when the command type is
28
+ * outside the active mode's permitted set.
29
+ */
30
+ export declare function assertModePermitsCommandType(mode: StudioSessionMode, type: StudioCommandType): void;
31
+ /**
32
+ * Enforces the bounded-composition rule for one hybrid structure command:
33
+ * every collection the command inserts into, removes from, moves across, or
34
+ * reorders must be a named slot of a node whose authoring policy mode is
35
+ * `structural`; inserted block types must satisfy the structural node's
36
+ * `allowedBlocks` when declared; subtrees containing a `locked` node are
37
+ * never inserted, removed, moved, or duplicated; and document roots are
38
+ * never in bounds. Batch operations are evaluated sequentially against a
39
+ * trial state so later operations may compose nodes earlier operations
40
+ * introduced. A violation fails closed with `mode-forbidden`; a reference
41
+ * the gate cannot resolve is left for the reducer's canonical failure code.
42
+ *
43
+ * The passed document is consumed as trial scratch state and may be mutated;
44
+ * callers pass a clone.
45
+ */
46
+ export declare function assertHybridCommandInBounds(document: BlueprintDocument, command: BlueprintCommand): void;
47
+ //# sourceMappingURL=modes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"modes.d.ts","sourceRoot":"","sources":["../src/modes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,gBAAgB,EAChB,iBAAiB,EAKjB,aAAa,EACb,mBAAmB,EACnB,iBAAiB,EAClB,MAAM,wBAAwB,CAAC;AAGhC;;;GAGG;AACH,eAAO,MAAM,oBAAoB,EAAE,SAAS,iBAAiB,EAM3D,CAAC;AAEH,kEAAkE;AAClE,MAAM,MAAM,iBAAiB,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC;AAoDtD;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,iBAAiB,GAAG,WAAW,CAAC,iBAAiB,CAAC,CAE7F;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAChC,aAAa,EAAE,IAAI,CAAC,mBAAmB,EAAE,WAAW,GAAG,MAAM,GAAG,cAAc,CAAC,GAC9E,iBAAiB,CAWnB;AAED;;;GAGG;AACH,wBAAgB,4BAA4B,CAC1C,IAAI,EAAE,iBAAiB,EACvB,IAAI,EAAE,iBAAiB,GACtB,IAAI,CAON;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,2BAA2B,CACzC,QAAQ,EAAE,iBAAiB,EAC3B,OAAO,EAAE,gBAAgB,GACxB,IAAI,CAyCN"}
package/dist/modes.js ADDED
@@ -0,0 +1,280 @@
1
+ import { applyOperation, StudioCommandError } from './commands.js';
2
+ /**
3
+ * Every session mode, in stable sorted order. The permitted-command table is
4
+ * total over exactly this set.
5
+ */
6
+ export const STUDIO_SESSION_MODES = Object.freeze([
7
+ 'blueprint',
8
+ 'content',
9
+ 'hybrid',
10
+ 'model',
11
+ 'read-only',
12
+ ]);
13
+ const BLUEPRINT_STRUCTURE_COMMAND_TYPES = [
14
+ 'studio.command/apply-pattern',
15
+ 'studio.command/batch',
16
+ 'studio.command/duplicate-node',
17
+ 'studio.command/insert-node',
18
+ 'studio.command/move-node',
19
+ 'studio.command/remove-binding',
20
+ 'studio.command/remove-node',
21
+ 'studio.command/reorder-children',
22
+ 'studio.command/reset-inherited-property',
23
+ 'studio.command/restore-node',
24
+ 'studio.command/set-binding',
25
+ 'studio.command/set-property',
26
+ 'studio.command/set-size-role',
27
+ 'studio.command/unset-property',
28
+ 'studio.command/unset-size-role',
29
+ ];
30
+ /**
31
+ * The structure commands hybrid composition may dispatch when every affected
32
+ * collection stays inside a structural authoring region. Property, binding,
33
+ * size-role, inheritance-reset, and pattern commands remain Blueprint-mode
34
+ * vocabulary.
35
+ */
36
+ const HYBRID_STRUCTURE_OPERATION_TYPES = [
37
+ 'studio.command/duplicate-node',
38
+ 'studio.command/insert-node',
39
+ 'studio.command/move-node',
40
+ 'studio.command/remove-node',
41
+ 'studio.command/reorder-children',
42
+ 'studio.command/restore-node',
43
+ ];
44
+ const PERMITTED_COMMAND_TYPES = Object.freeze({
45
+ blueprint: immutableCommandTypeSet(BLUEPRINT_STRUCTURE_COMMAND_TYPES),
46
+ content: immutableCommandTypeSet(['studio.command/set-field-value']),
47
+ hybrid: immutableCommandTypeSet([
48
+ 'studio.command/batch',
49
+ ...HYBRID_STRUCTURE_OPERATION_TYPES,
50
+ 'studio.command/set-field-value',
51
+ ]),
52
+ model: immutableCommandTypeSet(['studio.command/add-model-field']),
53
+ 'read-only': immutableCommandTypeSet([]),
54
+ });
55
+ const HYBRID_BATCHABLE_OPERATION_TYPES = immutableCommandTypeSet(HYBRID_STRUCTURE_OPERATION_TYPES);
56
+ /**
57
+ * The deterministic mode-to-permitted-command table: one immutable set per
58
+ * session mode, shared across calls, so UIs derive disabled affordances from
59
+ * the same source the session enforces. The table is type-level only; the
60
+ * hybrid entries additionally require every affected collection to stay
61
+ * inside a structural authoring region, which the session enforces per
62
+ * command target.
63
+ */
64
+ export function permittedCommandTypes(mode) {
65
+ return PERMITTED_COMMAND_TYPES[mode];
66
+ }
67
+ /**
68
+ * Flattens a configuration's editing mode, composite, and session state into
69
+ * the single session mode fixed at session creation: a read-only session
70
+ * state always flattens to `read-only`, the hybrid composite flattens to
71
+ * `hybrid`, and every other session keeps its authoring mode. The hybrid
72
+ * composite is invalid with Model mode, mirroring the configuration schema.
73
+ */
74
+ export function resolveSessionMode(configuration) {
75
+ if (configuration.sessionState === 'read-only') {
76
+ return 'read-only';
77
+ }
78
+ if (configuration.composite === 'hybrid') {
79
+ if (configuration.mode === 'model') {
80
+ throw new RangeError('The hybrid composite is invalid with the model editing mode.');
81
+ }
82
+ return 'hybrid';
83
+ }
84
+ return configuration.mode;
85
+ }
86
+ /**
87
+ * Fails closed with the stable `mode-forbidden` code when the command type is
88
+ * outside the active mode's permitted set.
89
+ */
90
+ export function assertModePermitsCommandType(mode, type) {
91
+ if (!PERMITTED_COMMAND_TYPES[mode].has(type)) {
92
+ throw new StudioCommandError('mode-forbidden', `Command type ${type} is not permitted in ${mode} mode.`);
93
+ }
94
+ }
95
+ /**
96
+ * Enforces the bounded-composition rule for one hybrid structure command:
97
+ * every collection the command inserts into, removes from, moves across, or
98
+ * reorders must be a named slot of a node whose authoring policy mode is
99
+ * `structural`; inserted block types must satisfy the structural node's
100
+ * `allowedBlocks` when declared; subtrees containing a `locked` node are
101
+ * never inserted, removed, moved, or duplicated; and document roots are
102
+ * never in bounds. Batch operations are evaluated sequentially against a
103
+ * trial state so later operations may compose nodes earlier operations
104
+ * introduced. A violation fails closed with `mode-forbidden`; a reference
105
+ * the gate cannot resolve is left for the reducer's canonical failure code.
106
+ *
107
+ * The passed document is consumed as trial scratch state and may be mutated;
108
+ * callers pass a clone.
109
+ */
110
+ export function assertHybridCommandInBounds(document, command) {
111
+ switch (command.type) {
112
+ case 'studio.command/batch': {
113
+ for (const operation of command.payload.operations) {
114
+ const type = operation.type;
115
+ if (type === 'studio.command/batch' ||
116
+ type === 'studio.command/apply-pattern' ||
117
+ type === 'studio.command/reset-inherited-property') {
118
+ // Never legal inside a batch; the reducer's canonical
119
+ // invalid-batch rejection resurfaces when the command executes.
120
+ return;
121
+ }
122
+ if (!HYBRID_BATCHABLE_OPERATION_TYPES.has(operation.type)) {
123
+ throw new StudioCommandError('mode-forbidden', `Batch operation type ${operation.type} is not permitted in hybrid mode.`);
124
+ }
125
+ assertHybridOperationInBounds(document, operation);
126
+ try {
127
+ applyOperation(document, operation);
128
+ }
129
+ catch {
130
+ // The trial cannot advance past this operation; the reducer's
131
+ // canonical failure code resurfaces when the command executes.
132
+ return;
133
+ }
134
+ }
135
+ return;
136
+ }
137
+ case 'studio.command/apply-pattern':
138
+ case 'studio.command/reset-inherited-property':
139
+ // Unreachable behind the type gate; kept for fail-closed defence.
140
+ throw new StudioCommandError('mode-forbidden', `Command type ${command.type} is not permitted in hybrid mode.`);
141
+ default:
142
+ assertHybridOperationInBounds(document, command);
143
+ }
144
+ }
145
+ function assertHybridOperationInBounds(document, operation) {
146
+ switch (operation.type) {
147
+ case 'studio.command/insert-node':
148
+ case 'studio.command/restore-node': {
149
+ assertSubtreeUnlocked(operation.payload.node);
150
+ assertComposableDestination(document, operation.payload.destination, operation.payload.node);
151
+ return;
152
+ }
153
+ case 'studio.command/remove-node': {
154
+ const location = locateNode(document.roots, operation.payload.nodeId);
155
+ if (location === undefined) {
156
+ return;
157
+ }
158
+ assertSubtreeUnlocked(location.node);
159
+ assertComposableParent(location.parent, location.slot);
160
+ return;
161
+ }
162
+ case 'studio.command/move-node': {
163
+ const location = locateNode(document.roots, operation.payload.nodeId);
164
+ if (location === undefined) {
165
+ return;
166
+ }
167
+ assertSubtreeUnlocked(location.node);
168
+ assertComposableParent(location.parent, location.slot);
169
+ assertComposableDestination(document, operation.payload.destination, location.node);
170
+ return;
171
+ }
172
+ case 'studio.command/duplicate-node': {
173
+ const location = locateNode(document.roots, operation.payload.nodeId);
174
+ if (location === undefined) {
175
+ return;
176
+ }
177
+ assertSubtreeUnlocked(location.node);
178
+ if (operation.payload.destination === undefined) {
179
+ assertComposableParent(location.parent, location.slot);
180
+ if (location.parent !== undefined) {
181
+ assertAllowedBlock(location.parent, location.slot, location.node);
182
+ }
183
+ }
184
+ else {
185
+ assertComposableDestination(document, operation.payload.destination, location.node);
186
+ }
187
+ return;
188
+ }
189
+ case 'studio.command/reorder-children': {
190
+ if (operation.payload.parentNodeId === undefined) {
191
+ throw rootsOutOfBounds();
192
+ }
193
+ assertComposableParent(locateNode(document.roots, operation.payload.parentNodeId)?.node, operation.payload.slot);
194
+ return;
195
+ }
196
+ default:
197
+ // Unreachable behind the type gate; kept for fail-closed defence.
198
+ throw new StudioCommandError('mode-forbidden', `Batch operation type ${operation.type} is not permitted in hybrid mode.`);
199
+ }
200
+ }
201
+ function locateNode(nodes, nodeId, parent, slot) {
202
+ for (const node of nodes) {
203
+ if (node.id === nodeId) {
204
+ if (parent === undefined) {
205
+ return { node };
206
+ }
207
+ return slot === undefined ? { node, parent } : { node, parent, slot };
208
+ }
209
+ for (const [slotName, children] of Object.entries(node.slots)) {
210
+ const nested = locateNode(children, nodeId, node, slotName);
211
+ if (nested !== undefined) {
212
+ return nested;
213
+ }
214
+ }
215
+ }
216
+ return undefined;
217
+ }
218
+ function assertComposableDestination(document, destination, node) {
219
+ if (destination.parentNodeId === undefined) {
220
+ throw rootsOutOfBounds();
221
+ }
222
+ const parent = locateNode(document.roots, destination.parentNodeId)?.node;
223
+ if (parent === undefined) {
224
+ // The reducer's canonical parent-not-found rejection resurfaces.
225
+ return;
226
+ }
227
+ assertComposableParent(parent, destination.slot);
228
+ assertAllowedBlock(parent, destination.slot, node);
229
+ }
230
+ /**
231
+ * A collection is composable when its parent node declares structural
232
+ * authoring, or when the parent's per-slot composition marker names the slot
233
+ * (ADR 0013). The marker only grants composability; it never revokes what
234
+ * the node-level policy permits.
235
+ */
236
+ function assertComposableParent(parent, slot) {
237
+ if (parent === undefined) {
238
+ throw rootsOutOfBounds();
239
+ }
240
+ if (parent.authoring.mode === 'structural') {
241
+ return;
242
+ }
243
+ if (slot !== undefined && parent.authoring.slots?.[slot]?.composable === true) {
244
+ return;
245
+ }
246
+ throw new StudioCommandError('mode-forbidden', `Hybrid composition is bounded to structural slots; node ${parent.id} declares neither structural authoring nor a composable marker for the affected slot.`);
247
+ }
248
+ function assertAllowedBlock(parent, slot, node) {
249
+ const slotPolicy = slot === undefined ? undefined : parent.authoring.slots?.[slot];
250
+ const allowedBlocks = slotPolicy?.allowedBlocks ?? parent.authoring.allowedBlocks;
251
+ if (allowedBlocks !== undefined && !allowedBlocks.includes(node.type)) {
252
+ throw new StudioCommandError('mode-forbidden', `Block type ${node.type} is not an allowed block inside the composable region of node ${parent.id}.`);
253
+ }
254
+ }
255
+ function assertSubtreeUnlocked(node) {
256
+ const stack = [node];
257
+ while (stack.length > 0) {
258
+ const current = stack.pop();
259
+ if (current === undefined) {
260
+ break;
261
+ }
262
+ if (current.authoring.mode === 'locked') {
263
+ throw new StudioCommandError('mode-forbidden', `Node ${current.id} is locked and never changes through hybrid composition.`);
264
+ }
265
+ for (const children of Object.values(current.slots)) {
266
+ stack.push(...children);
267
+ }
268
+ }
269
+ }
270
+ function rootsOutOfBounds() {
271
+ return new StudioCommandError('mode-forbidden', 'Hybrid composition is bounded to structural slots; the document roots are out of bounds.');
272
+ }
273
+ function immutableCommandTypeSet(types) {
274
+ const set = new Set(types);
275
+ const forbidMutation = () => {
276
+ throw new TypeError('The permitted command-type table is immutable.');
277
+ };
278
+ return Object.freeze(Object.assign(set, { add: forbidMutation, clear: forbidMutation, delete: forbidMutation }));
279
+ }
280
+ //# sourceMappingURL=modes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"modes.js","sourceRoot":"","sources":["../src/modes.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ import type { HostCapabilities, QualifiedName, StudioDiagnostic } from '@kumwe/studio-protocol';
2
+ export interface CapabilityNegotiationOptions {
3
+ optionalPorts?: readonly QualifiedName[];
4
+ requiredPorts?: readonly QualifiedName[];
5
+ supportedProtocolVersions?: readonly string[];
6
+ }
7
+ export interface CapabilityNegotiationResult {
8
+ availablePorts: QualifiedName[];
9
+ diagnostics: StudioDiagnostic[];
10
+ missingOptionalPorts: QualifiedName[];
11
+ missingRequiredPorts: QualifiedName[];
12
+ protocolVersion?: string;
13
+ sessionState: 'editable' | 'read-only';
14
+ }
15
+ /**
16
+ * Resolve one session posture from a host capability document. Capability
17
+ * negotiation fails closed: without a common wire protocol version or a
18
+ * required port there is no editable session, only a diagnosable read-only
19
+ * one. Optional ports degrade with informational diagnostics instead of
20
+ * being silently assumed.
21
+ */
22
+ export declare function negotiateCapabilities(capabilities: HostCapabilities, options?: Readonly<CapabilityNegotiationOptions>): CapabilityNegotiationResult;
23
+ //# sourceMappingURL=negotiation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"negotiation.d.ts","sourceRoot":"","sources":["../src/negotiation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAGhG,MAAM,WAAW,4BAA4B;IAC3C,aAAa,CAAC,EAAE,SAAS,aAAa,EAAE,CAAC;IACzC,aAAa,CAAC,EAAE,SAAS,aAAa,EAAE,CAAC;IACzC,yBAAyB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC/C;AAED,MAAM,WAAW,2BAA2B;IAC1C,cAAc,EAAE,aAAa,EAAE,CAAC;IAChC,WAAW,EAAE,gBAAgB,EAAE,CAAC;IAChC,oBAAoB,EAAE,aAAa,EAAE,CAAC;IACtC,oBAAoB,EAAE,aAAa,EAAE,CAAC;IACtC,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,YAAY,EAAE,UAAU,GAAG,WAAW,CAAC;CACxC;AAID;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CACnC,YAAY,EAAE,gBAAgB,EAC9B,OAAO,GAAE,QAAQ,CAAC,4BAA4B,CAAM,GACnD,2BAA2B,CA6D7B"}
@@ -0,0 +1,65 @@
1
+ import { STUDIO_WIRE_PROTOCOL_VERSION } from '@kumwe/studio-protocol';
2
+ const DEFAULT_REQUIRED_PORTS = ['studio.port/artifact'];
3
+ /**
4
+ * Resolve one session posture from a host capability document. Capability
5
+ * negotiation fails closed: without a common wire protocol version or a
6
+ * required port there is no editable session, only a diagnosable read-only
7
+ * one. Optional ports degrade with informational diagnostics instead of
8
+ * being silently assumed.
9
+ */
10
+ export function negotiateCapabilities(capabilities, options = {}) {
11
+ const supportedVersions = options.supportedProtocolVersions ?? [STUDIO_WIRE_PROTOCOL_VERSION];
12
+ const requiredPorts = options.requiredPorts ?? DEFAULT_REQUIRED_PORTS;
13
+ const optionalPorts = options.optionalPorts ?? [];
14
+ const diagnostics = [];
15
+ const availablePorts = capabilities.ports.map((port) => port.id);
16
+ const available = new Set(availablePorts);
17
+ const protocolVersion = supportedVersions.find((version) => capabilities.protocolVersions.includes(version));
18
+ if (protocolVersion === undefined) {
19
+ diagnostics.push({
20
+ code: 'studio.host/no-common-protocol-version',
21
+ message: {
22
+ defaultMessage: 'Studio and the host share no wire protocol version.',
23
+ key: 'studio.host/no-common-protocol-version',
24
+ },
25
+ severity: 'blocking',
26
+ });
27
+ }
28
+ const missingRequiredPorts = requiredPorts.filter((port) => !available.has(port));
29
+ for (const port of missingRequiredPorts) {
30
+ diagnostics.push({
31
+ code: 'studio.host/missing-required-port',
32
+ message: {
33
+ defaultMessage: `The host does not provide the required ${port} port.`,
34
+ key: 'studio.host/missing-required-port',
35
+ },
36
+ parameters: { port },
37
+ severity: 'blocking',
38
+ });
39
+ }
40
+ const missingOptionalPorts = optionalPorts.filter((port) => !available.has(port));
41
+ for (const port of missingOptionalPorts) {
42
+ diagnostics.push({
43
+ code: 'studio.host/missing-optional-port',
44
+ message: {
45
+ defaultMessage: `The optional ${port} port is unavailable; its features are disabled.`,
46
+ key: 'studio.host/missing-optional-port',
47
+ },
48
+ parameters: { port },
49
+ severity: 'information',
50
+ });
51
+ }
52
+ const editable = protocolVersion !== undefined && missingRequiredPorts.length === 0;
53
+ const result = {
54
+ availablePorts,
55
+ diagnostics,
56
+ missingOptionalPorts,
57
+ missingRequiredPorts,
58
+ sessionState: editable ? 'editable' : 'read-only',
59
+ };
60
+ if (protocolVersion !== undefined) {
61
+ result.protocolVersion = protocolVersion;
62
+ }
63
+ return result;
64
+ }
65
+ //# sourceMappingURL=negotiation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"negotiation.js","sourceRoot":"","sources":["../src/negotiation.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,4BAA4B,EAAE,MAAM,wBAAwB,CAAC;AAiBtE,MAAM,sBAAsB,GAA6B,CAAC,sBAAsB,CAAC,CAAC;AAElF;;;;;;GAMG;AACH,MAAM,UAAU,qBAAqB,CACnC,YAA8B,EAC9B,UAAkD,EAAE;IAEpD,MAAM,iBAAiB,GAAG,OAAO,CAAC,yBAAyB,IAAI,CAAC,4BAA4B,CAAC,CAAC;IAC9F,MAAM,aAAa,GAAG,OAAO,CAAC,aAAa,IAAI,sBAAsB,CAAC;IACtE,MAAM,aAAa,GAAG,OAAO,CAAC,aAAa,IAAI,EAAE,CAAC;IAElD,MAAM,WAAW,GAAuB,EAAE,CAAC;IAC3C,MAAM,cAAc,GAAG,YAAY,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACjE,MAAM,SAAS,GAAG,IAAI,GAAG,CAAgB,cAAc,CAAC,CAAC;IAEzD,MAAM,eAAe,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CACzD,YAAY,CAAC,gBAAgB,CAAC,QAAQ,CAAC,OAAO,CAAC,CAChD,CAAC;IACF,IAAI,eAAe,KAAK,SAAS,EAAE,CAAC;QAClC,WAAW,CAAC,IAAI,CAAC;YACf,IAAI,EAAE,wCAAwC;YAC9C,OAAO,EAAE;gBACP,cAAc,EAAE,qDAAqD;gBACrE,GAAG,EAAE,wCAAwC;aAC9C;YACD,QAAQ,EAAE,UAAU;SACrB,CAAC,CAAC;IACL,CAAC;IAED,MAAM,oBAAoB,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;IAClF,KAAK,MAAM,IAAI,IAAI,oBAAoB,EAAE,CAAC;QACxC,WAAW,CAAC,IAAI,CAAC;YACf,IAAI,EAAE,mCAAmC;YACzC,OAAO,EAAE;gBACP,cAAc,EAAE,0CAA0C,IAAI,QAAQ;gBACtE,GAAG,EAAE,mCAAmC;aACzC;YACD,UAAU,EAAE,EAAE,IAAI,EAAE;YACpB,QAAQ,EAAE,UAAU;SACrB,CAAC,CAAC;IACL,CAAC;IAED,MAAM,oBAAoB,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;IAClF,KAAK,MAAM,IAAI,IAAI,oBAAoB,EAAE,CAAC;QACxC,WAAW,CAAC,IAAI,CAAC;YACf,IAAI,EAAE,mCAAmC;YACzC,OAAO,EAAE;gBACP,cAAc,EAAE,gBAAgB,IAAI,kDAAkD;gBACtF,GAAG,EAAE,mCAAmC;aACzC;YACD,UAAU,EAAE,EAAE,IAAI,EAAE;YACpB,QAAQ,EAAE,aAAa;SACxB,CAAC,CAAC;IACL,CAAC;IAED,MAAM,QAAQ,GAAG,eAAe,KAAK,SAAS,IAAI,oBAAoB,CAAC,MAAM,KAAK,CAAC,CAAC;IACpF,MAAM,MAAM,GAAgC;QAC1C,cAAc;QACd,WAAW;QACX,oBAAoB;QACpB,oBAAoB;QACpB,YAAY,EAAE,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,WAAW;KAClD,CAAC;IACF,IAAI,eAAe,KAAK,SAAS,EAAE,CAAC;QAClC,MAAM,CAAC,eAAe,GAAG,eAAe,CAAC;IAC3C,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,12 @@
1
+ import type { StudioChartSpec, StudioDrawingDocument, StudioMoneyValue, StudioPresentationIntent, StudioTableDocument } from '@kumwe/studio-protocol';
2
+ /** Parse and detach one canonical chart spec, refusing library-specific configuration. */
3
+ export declare function parseStudioChartSpec(value: unknown): StudioChartSpec;
4
+ /** Parse bounded vector strokes and reject SVG, data URLs, and canvas commands. */
5
+ export declare function parseStudioDrawingDocument(value: unknown): StudioDrawingDocument;
6
+ /** Parse exact decimal money without converting through a binary float. */
7
+ export declare function parseStudioMoneyValue(value: unknown): StudioMoneyValue;
8
+ /** Parse closed presentation intent without accepting selectors, declarations, or measurements. */
9
+ export declare function parseStudioPresentationIntent(value: unknown): StudioPresentationIntent;
10
+ /** Parse a bounded, text-only table and require one cell per declared column. */
11
+ export declare function parseStudioTableDocument(value: unknown): StudioTableDocument;
12
+ //# sourceMappingURL=production-values.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"production-values.d.ts","sourceRoot":"","sources":["../src/production-values.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,eAAe,EACf,qBAAqB,EAGrB,gBAAgB,EAChB,wBAAwB,EACxB,mBAAmB,EACpB,MAAM,wBAAwB,CAAC;AAOhC,0FAA0F;AAC1F,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,GAAG,eAAe,CA4CpE;AAED,mFAAmF;AACnF,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,OAAO,GAAG,qBAAqB,CA2ChF;AAED,2EAA2E;AAC3E,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,OAAO,GAAG,gBAAgB,CAStE;AAED,mGAAmG;AACnG,wBAAgB,6BAA6B,CAAC,KAAK,EAAE,OAAO,GAAG,wBAAwB,CA4FtF;AAED,iFAAiF;AACjF,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,OAAO,GAAG,mBAAmB,CAsB5E"}