@happyvertical/smrt-core 0.55.9 → 0.55.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. package/AGENTS.md +2 -0
  2. package/agents/build-knowledge.md +40 -0
  3. package/agents/cookbook-engine.md +102 -0
  4. package/agents/cookbook.md +63 -0
  5. package/dist/consumer-plugin/artifact-publication.js +3 -3
  6. package/dist/consumer-plugin/artifact-publication.js.map +1 -1
  7. package/dist/consumer-plugin/hosted-sti-collections.d.ts +10 -0
  8. package/dist/consumer-plugin/hosted-sti-collections.d.ts.map +1 -0
  9. package/dist/consumer-plugin/hosted-sti-collections.js +92 -0
  10. package/dist/consumer-plugin/hosted-sti-collections.js.map +1 -0
  11. package/dist/consumer-plugin/index.d.ts +1 -1
  12. package/dist/consumer-plugin/index.d.ts.map +1 -1
  13. package/dist/consumer-plugin/index.js +76 -51
  14. package/dist/consumer-plugin/index.js.map +1 -1
  15. package/dist/cookbook/engine/commands.d.ts +37 -0
  16. package/dist/cookbook/engine/commands.d.ts.map +1 -0
  17. package/dist/cookbook/engine/commands.js +275 -0
  18. package/dist/cookbook/engine/commands.js.map +1 -0
  19. package/dist/cookbook/engine/defaults.d.ts +10 -0
  20. package/dist/cookbook/engine/defaults.d.ts.map +1 -0
  21. package/dist/cookbook/engine/defaults.js +49 -0
  22. package/dist/cookbook/engine/defaults.js.map +1 -0
  23. package/dist/cookbook/engine/document.d.ts +66 -0
  24. package/dist/cookbook/engine/document.d.ts.map +1 -0
  25. package/dist/cookbook/engine/document.js +357 -0
  26. package/dist/cookbook/engine/document.js.map +1 -0
  27. package/dist/cookbook/engine/engine.d.ts +49 -0
  28. package/dist/cookbook/engine/engine.d.ts.map +1 -0
  29. package/dist/cookbook/engine/engine.js +399 -0
  30. package/dist/cookbook/engine/engine.js.map +1 -0
  31. package/dist/cookbook/engine/index.d.ts +14 -0
  32. package/dist/cookbook/engine/index.d.ts.map +1 -0
  33. package/dist/cookbook/engine/index.js +8 -0
  34. package/dist/cookbook/engine/nav.d.ts +45 -0
  35. package/dist/cookbook/engine/nav.d.ts.map +1 -0
  36. package/dist/cookbook/engine/nav.js +191 -0
  37. package/dist/cookbook/engine/nav.js.map +1 -0
  38. package/dist/cookbook/engine/schemas.d.ts +29 -0
  39. package/dist/cookbook/engine/schemas.d.ts.map +1 -0
  40. package/dist/cookbook/engine/schemas.js +363 -0
  41. package/dist/cookbook/engine/schemas.js.map +1 -0
  42. package/dist/cookbook/engine/types.d.ts +331 -0
  43. package/dist/cookbook/engine/types.d.ts.map +1 -0
  44. package/dist/cookbook/engine/types.js +10 -0
  45. package/dist/cookbook/engine/types.js.map +1 -0
  46. package/dist/cookbook/engine.d.ts +2 -0
  47. package/dist/cookbook/engine.d.ts.map +1 -0
  48. package/dist/cookbook/engine.js +9 -0
  49. package/dist/cookbook/index.d.ts +6 -0
  50. package/dist/cookbook/index.d.ts.map +1 -0
  51. package/dist/cookbook/v1.schema.json +131 -0
  52. package/dist/cookbook/validate.d.ts +37 -0
  53. package/dist/cookbook/validate.d.ts.map +1 -0
  54. package/dist/cookbook/validate.js +172 -0
  55. package/dist/cookbook/validate.js.map +1 -0
  56. package/dist/cookbook.d.ts +7 -0
  57. package/dist/cookbook.d.ts.map +1 -0
  58. package/dist/cookbook.js +2 -0
  59. package/dist/manifest/browser-capability.generated.d.ts.map +1 -1
  60. package/dist/manifest/browser-capability.generated.js +48 -2
  61. package/dist/manifest/browser-capability.generated.js.map +1 -1
  62. package/dist/manifest/static-manifest.js +1 -1
  63. package/dist/manifest/static-manifest.js.map +1 -1
  64. package/dist/manifest/store.js +1 -1
  65. package/dist/manifest/store.js.map +1 -1
  66. package/dist/manifest.json +1 -1
  67. package/dist/prebuild/index.js +13 -13
  68. package/dist/prebuild/index.js.map +1 -1
  69. package/dist/smrt-knowledge.json +23 -7
  70. package/dist/vite-plugin/web-collections.d.ts +5 -0
  71. package/dist/vite-plugin/web-collections.d.ts.map +1 -1
  72. package/dist/vite-plugin/web-collections.js +1 -1
  73. package/dist/vite-plugin/web-collections.js.map +1 -1
  74. package/dist/vite-preset/cookbook-exposure.d.ts +11 -0
  75. package/dist/vite-preset/cookbook-exposure.d.ts.map +1 -0
  76. package/dist/vite-preset/cookbook-exposure.js +95 -0
  77. package/dist/vite-preset/cookbook-exposure.js.map +1 -0
  78. package/dist/vite-preset/index.d.ts +9 -0
  79. package/dist/vite-preset/index.d.ts.map +1 -1
  80. package/dist/vite-preset/index.js +17 -7
  81. package/dist/vite-preset/index.js.map +1 -1
  82. package/package.json +18 -6
@@ -0,0 +1,331 @@
1
+ /**
2
+ * Cookbook command engine, contract v1 (#3753).
3
+ *
4
+ * Plain data in, plain data out: no SvelteKit, browser storage, planner
5
+ * singleton or inference dependency, and no Node imports, so the same engine
6
+ * runs in a browser planner, a CLI, an MCP server or a website. Adapters own
7
+ * navigation/focus, persistence and transport; the engine owns the document.
8
+ */
9
+ import type { Cookbook, RecipeDefinition } from '@happyvertical/smrt-types';
10
+ /**
11
+ * The command set version. A change an older client could not send or read
12
+ * bumps it; adding a command or an optional field does not.
13
+ */
14
+ export declare const COOKBOOK_COMMANDS_VERSION = 1;
15
+ /** The part of a manifest recipe the engine reads (a `RecipeDefinition` fits). */
16
+ export type EngineRecipe = Pick<RecipeDefinition, 'id' | 'label' | 'models' | 'nav' | 'requires'> & Partial<Pick<RecipeDefinition, 'requiresAny' | 'group' | 'section' | 'options'>>;
17
+ /** One field of a catalog model, for `set_policy` and settings defaults. */
18
+ export interface EngineField {
19
+ name: string;
20
+ /** System fields (id, timestamps) cannot be given a policy. */
21
+ system?: boolean;
22
+ /** The field's own starting value, so a setting equal to it writes no row. */
23
+ default?: unknown;
24
+ }
25
+ /** One catalog model. Same shape as smrt-svelte's `CookbookModelInfo`, plus fields. */
26
+ export interface EngineModel {
27
+ /** Qualified name, `@scope/pkg:Class`. */
28
+ id: string;
29
+ name: string;
30
+ /** Package id used in item ids: `commerce` for `@happyvertical/smrt-commerce`. */
31
+ packageId: string;
32
+ description?: string;
33
+ /** Has an API, MCP or CLI surface; only exposed models can be added as features. */
34
+ exposed?: boolean;
35
+ /** When given, `set_policy` rejects a field not listed. */
36
+ fields?: readonly EngineField[];
37
+ }
38
+ /** A ready-made cookbook the catalog offers (a library entry). */
39
+ export interface EngineLibraryCookbook {
40
+ id: string;
41
+ name: string;
42
+ document: Cookbook;
43
+ }
44
+ /** Which model fields each app setting is the default of. */
45
+ export type SettingTargets = Record<'currency' | 'taxRate' | 'paymentTerms', readonly {
46
+ model: string;
47
+ field: string;
48
+ }[]>;
49
+ /**
50
+ * Everything the engine resolves ids against, as data: recipes and models from
51
+ * published manifests, optionally a library of cookbooks. Nothing here is
52
+ * bundled with the engine.
53
+ */
54
+ export interface EngineCatalog {
55
+ recipes: readonly EngineRecipe[];
56
+ models: readonly EngineModel[];
57
+ cookbooks?: readonly EngineLibraryCookbook[];
58
+ /** Theme preset names; default {@link DEFAULT_THEME_PRESETS}. */
59
+ themePresets?: readonly string[];
60
+ /** ISO 4217 codes; default any three capital letters. */
61
+ currencies?: readonly string[];
62
+ /** Default {@link COMMERCE_SETTING_TARGETS}. */
63
+ settingTargets?: SettingTargets;
64
+ }
65
+ /** Input of each command, keyed by the command's (tool) name. */
66
+ export interface CommandInputs {
67
+ /** Switch recipes on, with everything they `require`. */
68
+ add_recipes: {
69
+ ids: string[];
70
+ };
71
+ /** Switch recipes off; ones another recipe needs are kept (and reported). */
72
+ remove_recipes: {
73
+ ids: string[];
74
+ };
75
+ /** Add models no recipe covers, by qualified name. */
76
+ add_features: {
77
+ ids: string[];
78
+ };
79
+ remove_features: {
80
+ ids: string[];
81
+ };
82
+ /** Add the recipes and features of a library cookbook to what is there. */
83
+ add_cookbook: {
84
+ id: string;
85
+ };
86
+ /** Remove what a library cookbook added (recipes others need are kept). */
87
+ remove_cookbook: {
88
+ id: string;
89
+ };
90
+ /** Select a library cookbook, replacing the app (needs `replace` if non-empty). */
91
+ apply_cookbook: {
92
+ id: string;
93
+ replace?: boolean;
94
+ };
95
+ /** Import a cookbook document, replacing the app (needs `replace` if non-empty). */
96
+ import_cookbook: {
97
+ document: unknown;
98
+ replace?: boolean;
99
+ };
100
+ /** App settings; tax rate in percent, 0 to 100. */
101
+ set_settings: {
102
+ currency?: string;
103
+ taxRate?: number;
104
+ paymentTerms?: string;
105
+ };
106
+ /** Set (or clear with null) one field's policy row. App scope. */
107
+ set_policy: {
108
+ model: string;
109
+ field: string;
110
+ defaultValue?: unknown;
111
+ visibility?: 'basic' | 'advanced' | 'hidden' | null;
112
+ label?: string | null;
113
+ help?: string | null;
114
+ };
115
+ set_theme: {
116
+ preset?: string;
117
+ primary?: string;
118
+ colorScheme?: 'light' | 'dark' | 'system';
119
+ };
120
+ reset_theme: Record<string, never>;
121
+ /** Name (and describe) the app; null clears. */
122
+ set_name: {
123
+ name?: string | null;
124
+ description?: string | null;
125
+ };
126
+ rename_section: {
127
+ id: string;
128
+ label: string;
129
+ };
130
+ /** `null` restores the entry's own name. */
131
+ rename_item: {
132
+ id: string;
133
+ label: string | null;
134
+ };
135
+ hide: {
136
+ id: string;
137
+ };
138
+ show: {
139
+ id: string;
140
+ };
141
+ /** Check the current document and report typed diagnostics. Changes nothing. */
142
+ validate: Record<string, never>;
143
+ /** The cookbook as `<name>.cookbook.json` text. Changes nothing. */
144
+ export_cookbook: {
145
+ name?: string;
146
+ };
147
+ /** Undo an earlier change by the `undoId` its receipt carried. */
148
+ undo: {
149
+ undoId: string;
150
+ force?: boolean;
151
+ };
152
+ }
153
+ export type CommandName = keyof CommandInputs;
154
+ /** A command as a client sends it. */
155
+ export type CookbookCommand = {
156
+ [N in CommandName]: {
157
+ name: N;
158
+ input: CommandInputs[N];
159
+ /** Retry key: a repeated id returns the first receipt and applies nothing. */
160
+ id?: string;
161
+ /** Refuse with `conflict` unless the plan is still at this revision. */
162
+ expectedRevision?: number;
163
+ };
164
+ }[CommandName];
165
+ /** Stable strings a client can switch on. */
166
+ export type CommandErrorCode = 'unknown_command' | 'invalid_input' | 'not_found'
167
+ /** A destructive command needs `replace: true` (or `force: true`). */
168
+ | 'confirmation_required'
169
+ /** The plan moved on since the caller looked (`expectedRevision`, undo). */
170
+ | 'conflict'
171
+ /** A command id was reused with a different command. */
172
+ | 'id_reuse'
173
+ /** An atomic batch failed; `details.index` names the command, nothing applied. */
174
+ | 'batch_failed' | 'failed';
175
+ export interface CommandError {
176
+ code: CommandErrorCode;
177
+ message: string;
178
+ /** Where the problem is, as a path into the input (`input.ids[1]`). */
179
+ path?: string;
180
+ details?: Record<string, unknown>;
181
+ }
182
+ /** What a recipe/feature command did, after `requires` ran. */
183
+ export interface RecipeChanges {
184
+ added: string[];
185
+ removed: string[];
186
+ /** Asked to remove, but another recipe still needs them. */
187
+ kept: string[];
188
+ }
189
+ export interface PlanSnapshot {
190
+ version: typeof COOKBOOK_COMMANDS_VERSION;
191
+ /** Counts applied changes; equal histories give equal revisions. */
192
+ revision: number;
193
+ app: {
194
+ name: string;
195
+ description: string | null;
196
+ cookbook: string | null;
197
+ };
198
+ recipes: {
199
+ id: string;
200
+ label: string;
201
+ }[];
202
+ features: string[];
203
+ /** Recipe and feature ids this catalog lacks; kept on export. */
204
+ unavailable: string[];
205
+ settings: {
206
+ currency: string;
207
+ taxRate: number;
208
+ paymentTerms: string;
209
+ };
210
+ theme: {
211
+ text: string;
212
+ preset: string | null;
213
+ primary: string | null;
214
+ colorScheme: string;
215
+ };
216
+ sections: {
217
+ id: string;
218
+ label: string;
219
+ hidden: boolean;
220
+ items: {
221
+ id: string;
222
+ label: string;
223
+ hidden: boolean;
224
+ }[];
225
+ }[];
226
+ policies: number;
227
+ /** Undo ids still available, newest last. */
228
+ undo: string[];
229
+ }
230
+ export interface CommandReceipt {
231
+ name: CommandName;
232
+ /** The command id, when one was sent. */
233
+ id?: string;
234
+ summary: string;
235
+ changed: boolean;
236
+ revisionBefore: number;
237
+ revisionAfter: number;
238
+ undoId?: string;
239
+ changes?: RecipeChanges;
240
+ /** Non-fatal notes (an import's legacy `$schema` migration). */
241
+ warnings?: string[];
242
+ }
243
+ export type CommandResult = {
244
+ ok: true;
245
+ id?: string;
246
+ /** True when this is the stored result of an earlier run of the same id. */
247
+ replayed?: boolean;
248
+ snapshot: PlanSnapshot;
249
+ receipt: CommandReceipt;
250
+ data?: unknown;
251
+ } | {
252
+ ok: false;
253
+ id?: string;
254
+ replayed?: boolean;
255
+ error: CommandError;
256
+ };
257
+ export interface RunOptions {
258
+ expectedRevision?: number;
259
+ }
260
+ /** Several commands applied all-or-nothing. */
261
+ export interface CommandBatch {
262
+ id?: string;
263
+ commands: readonly unknown[];
264
+ expectedRevision?: number;
265
+ }
266
+ export type BatchResult = {
267
+ ok: true;
268
+ id?: string;
269
+ replayed?: boolean;
270
+ snapshot: PlanSnapshot;
271
+ receipt: {
272
+ id?: string;
273
+ count: number;
274
+ changed: boolean;
275
+ revisionBefore: number;
276
+ revisionAfter: number;
277
+ undoId?: string;
278
+ };
279
+ /** One result per command, in order. */
280
+ results: Extract<CommandResult, {
281
+ ok: true;
282
+ }>[];
283
+ } | {
284
+ ok: false;
285
+ id?: string;
286
+ replayed?: boolean;
287
+ error: CommandError;
288
+ /** The state is exactly as before the batch. */
289
+ snapshot: PlanSnapshot;
290
+ };
291
+ /** One diagnostic from `validate`. */
292
+ export interface Diagnostic {
293
+ severity: 'error' | 'warning';
294
+ code: string;
295
+ path: string;
296
+ message: string;
297
+ }
298
+ export interface ValidateData {
299
+ ok: boolean;
300
+ diagnostics: Diagnostic[];
301
+ }
302
+ export interface ExportData {
303
+ fileName: string;
304
+ text: string;
305
+ cookbook: Cookbook;
306
+ }
307
+ /** A journal row: enough to answer a retry of `id` after a restart. */
308
+ export interface JournalEntry {
309
+ id: string;
310
+ fingerprint: string;
311
+ result: CommandResult | BatchResult;
312
+ }
313
+ /** The engine's whole state as plain JSON, to persist and resume from. */
314
+ export interface EngineState {
315
+ version: typeof COOKBOOK_COMMANDS_VERSION;
316
+ revision: number;
317
+ /** The library cookbook the plan was last set up from, if any. */
318
+ applied: string | null;
319
+ cookbook: Cookbook;
320
+ journal: JournalEntry[];
321
+ }
322
+ export interface JsonSchema {
323
+ [key: string]: unknown;
324
+ }
325
+ /** One command as an LLM or MCP tool definition. */
326
+ export interface CommandTool {
327
+ name: CommandName;
328
+ description: string;
329
+ inputSchema: JsonSchema;
330
+ }
331
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/cookbook/engine/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ //#region src/cookbook/engine/types.ts
2
+ /**
3
+ * The command set version. A change an older client could not send or read
4
+ * bumps it; adding a command or an optional field does not.
5
+ */
6
+ var COOKBOOK_COMMANDS_VERSION = 1;
7
+ //#endregion
8
+ export { COOKBOOK_COMMANDS_VERSION };
9
+
10
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","names":[],"sources":["../../../src/cookbook/engine/types.ts"],"sourcesContent":["/**\n * Cookbook command engine, contract v1 (#3753).\n *\n * Plain data in, plain data out: no SvelteKit, browser storage, planner\n * singleton or inference dependency, and no Node imports, so the same engine\n * runs in a browser planner, a CLI, an MCP server or a website. Adapters own\n * navigation/focus, persistence and transport; the engine owns the document.\n */\nimport type { Cookbook, RecipeDefinition } from '@happyvertical/smrt-types';\n\n/**\n * The command set version. A change an older client could not send or read\n * bumps it; adding a command or an optional field does not.\n */\nexport const COOKBOOK_COMMANDS_VERSION = 1;\n\n/** The part of a manifest recipe the engine reads (a `RecipeDefinition` fits). */\nexport type EngineRecipe = Pick<\n RecipeDefinition,\n 'id' | 'label' | 'models' | 'nav' | 'requires'\n> &\n Partial<\n Pick<RecipeDefinition, 'requiresAny' | 'group' | 'section' | 'options'>\n >;\n\n/** One field of a catalog model, for `set_policy` and settings defaults. */\nexport interface EngineField {\n name: string;\n /** System fields (id, timestamps) cannot be given a policy. */\n system?: boolean;\n /** The field's own starting value, so a setting equal to it writes no row. */\n default?: unknown;\n}\n\n/** One catalog model. Same shape as smrt-svelte's `CookbookModelInfo`, plus fields. */\nexport interface EngineModel {\n /** Qualified name, `@scope/pkg:Class`. */\n id: string;\n name: string;\n /** Package id used in item ids: `commerce` for `@happyvertical/smrt-commerce`. */\n packageId: string;\n description?: string;\n /** Has an API, MCP or CLI surface; only exposed models can be added as features. */\n exposed?: boolean;\n /** When given, `set_policy` rejects a field not listed. */\n fields?: readonly EngineField[];\n}\n\n/** A ready-made cookbook the catalog offers (a library entry). */\nexport interface EngineLibraryCookbook {\n id: string;\n name: string;\n document: Cookbook;\n}\n\n/** Which model fields each app setting is the default of. */\nexport type SettingTargets = Record<\n 'currency' | 'taxRate' | 'paymentTerms',\n readonly { model: string; field: string }[]\n>;\n\n/**\n * Everything the engine resolves ids against, as data: recipes and models from\n * published manifests, optionally a library of cookbooks. Nothing here is\n * bundled with the engine.\n */\nexport interface EngineCatalog {\n recipes: readonly EngineRecipe[];\n models: readonly EngineModel[];\n cookbooks?: readonly EngineLibraryCookbook[];\n /** Theme preset names; default {@link DEFAULT_THEME_PRESETS}. */\n themePresets?: readonly string[];\n /** ISO 4217 codes; default any three capital letters. */\n currencies?: readonly string[];\n /** Default {@link COMMERCE_SETTING_TARGETS}. */\n settingTargets?: SettingTargets;\n}\n\n/** Input of each command, keyed by the command's (tool) name. */\nexport interface CommandInputs {\n /** Switch recipes on, with everything they `require`. */\n add_recipes: { ids: string[] };\n /** Switch recipes off; ones another recipe needs are kept (and reported). */\n remove_recipes: { ids: string[] };\n /** Add models no recipe covers, by qualified name. */\n add_features: { ids: string[] };\n remove_features: { ids: string[] };\n /** Add the recipes and features of a library cookbook to what is there. */\n add_cookbook: { id: string };\n /** Remove what a library cookbook added (recipes others need are kept). */\n remove_cookbook: { id: string };\n /** Select a library cookbook, replacing the app (needs `replace` if non-empty). */\n apply_cookbook: { id: string; replace?: boolean };\n /** Import a cookbook document, replacing the app (needs `replace` if non-empty). */\n import_cookbook: { document: unknown; replace?: boolean };\n /** App settings; tax rate in percent, 0 to 100. */\n set_settings: { currency?: string; taxRate?: number; paymentTerms?: string };\n /** Set (or clear with null) one field's policy row. App scope. */\n set_policy: {\n model: string;\n field: string;\n defaultValue?: unknown;\n visibility?: 'basic' | 'advanced' | 'hidden' | null;\n label?: string | null;\n help?: string | null;\n };\n set_theme: {\n preset?: string;\n primary?: string;\n colorScheme?: 'light' | 'dark' | 'system';\n };\n reset_theme: Record<string, never>;\n /** Name (and describe) the app; null clears. */\n set_name: { name?: string | null; description?: string | null };\n rename_section: { id: string; label: string };\n /** `null` restores the entry's own name. */\n rename_item: { id: string; label: string | null };\n hide: { id: string };\n show: { id: string };\n /** Check the current document and report typed diagnostics. Changes nothing. */\n validate: Record<string, never>;\n /** The cookbook as `<name>.cookbook.json` text. Changes nothing. */\n export_cookbook: { name?: string };\n /** Undo an earlier change by the `undoId` its receipt carried. */\n undo: { undoId: string; force?: boolean };\n}\n\nexport type CommandName = keyof CommandInputs;\n\n/** A command as a client sends it. */\nexport type CookbookCommand = {\n [N in CommandName]: {\n name: N;\n input: CommandInputs[N];\n /** Retry key: a repeated id returns the first receipt and applies nothing. */\n id?: string;\n /** Refuse with `conflict` unless the plan is still at this revision. */\n expectedRevision?: number;\n };\n}[CommandName];\n\n/** Stable strings a client can switch on. */\nexport type CommandErrorCode =\n | 'unknown_command'\n | 'invalid_input'\n | 'not_found'\n /** A destructive command needs `replace: true` (or `force: true`). */\n | 'confirmation_required'\n /** The plan moved on since the caller looked (`expectedRevision`, undo). */\n | 'conflict'\n /** A command id was reused with a different command. */\n | 'id_reuse'\n /** An atomic batch failed; `details.index` names the command, nothing applied. */\n | 'batch_failed'\n | 'failed';\n\nexport interface CommandError {\n code: CommandErrorCode;\n message: string;\n /** Where the problem is, as a path into the input (`input.ids[1]`). */\n path?: string;\n details?: Record<string, unknown>;\n}\n\n/** What a recipe/feature command did, after `requires` ran. */\nexport interface RecipeChanges {\n added: string[];\n removed: string[];\n /** Asked to remove, but another recipe still needs them. */\n kept: string[];\n}\n\nexport interface PlanSnapshot {\n version: typeof COOKBOOK_COMMANDS_VERSION;\n /** Counts applied changes; equal histories give equal revisions. */\n revision: number;\n app: { name: string; description: string | null; cookbook: string | null };\n recipes: { id: string; label: string }[];\n features: string[];\n /** Recipe and feature ids this catalog lacks; kept on export. */\n unavailable: string[];\n settings: { currency: string; taxRate: number; paymentTerms: string };\n theme: {\n text: string;\n preset: string | null;\n primary: string | null;\n colorScheme: string;\n };\n sections: {\n id: string;\n label: string;\n hidden: boolean;\n items: { id: string; label: string; hidden: boolean }[];\n }[];\n policies: number;\n /** Undo ids still available, newest last. */\n undo: string[];\n}\n\nexport interface CommandReceipt {\n name: CommandName;\n /** The command id, when one was sent. */\n id?: string;\n summary: string;\n changed: boolean;\n revisionBefore: number;\n revisionAfter: number;\n undoId?: string;\n changes?: RecipeChanges;\n /** Non-fatal notes (an import's legacy `$schema` migration). */\n warnings?: string[];\n}\n\nexport type CommandResult =\n | {\n ok: true;\n id?: string;\n /** True when this is the stored result of an earlier run of the same id. */\n replayed?: boolean;\n snapshot: PlanSnapshot;\n receipt: CommandReceipt;\n data?: unknown;\n }\n | { ok: false; id?: string; replayed?: boolean; error: CommandError };\n\nexport interface RunOptions {\n expectedRevision?: number;\n}\n\n/** Several commands applied all-or-nothing. */\nexport interface CommandBatch {\n id?: string;\n commands: readonly unknown[];\n expectedRevision?: number;\n}\n\nexport type BatchResult =\n | {\n ok: true;\n id?: string;\n replayed?: boolean;\n snapshot: PlanSnapshot;\n receipt: {\n id?: string;\n count: number;\n changed: boolean;\n revisionBefore: number;\n revisionAfter: number;\n undoId?: string;\n };\n /** One result per command, in order. */\n results: Extract<CommandResult, { ok: true }>[];\n }\n | {\n ok: false;\n id?: string;\n replayed?: boolean;\n error: CommandError;\n /** The state is exactly as before the batch. */\n snapshot: PlanSnapshot;\n };\n\n/** One diagnostic from `validate`. */\nexport interface Diagnostic {\n severity: 'error' | 'warning';\n code: string;\n path: string;\n message: string;\n}\n\nexport interface ValidateData {\n ok: boolean;\n diagnostics: Diagnostic[];\n}\n\nexport interface ExportData {\n fileName: string;\n text: string;\n cookbook: Cookbook;\n}\n\n/** A journal row: enough to answer a retry of `id` after a restart. */\nexport interface JournalEntry {\n id: string;\n fingerprint: string;\n result: CommandResult | BatchResult;\n}\n\n/** The engine's whole state as plain JSON, to persist and resume from. */\nexport interface EngineState {\n version: typeof COOKBOOK_COMMANDS_VERSION;\n revision: number;\n /** The library cookbook the plan was last set up from, if any. */\n applied: string | null;\n cookbook: Cookbook;\n journal: JournalEntry[];\n}\n\nexport interface JsonSchema {\n [key: string]: unknown;\n}\n\n/** One command as an LLM or MCP tool definition. */\nexport interface CommandTool {\n name: CommandName;\n description: string;\n inputSchema: JsonSchema;\n}\n"],"mappings":";;;;;AAcA,IAAa,4BAA4B"}
@@ -0,0 +1,2 @@
1
+ export * from './engine/index.js';
2
+ //# sourceMappingURL=engine.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../src/cookbook/engine.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC"}
@@ -0,0 +1,9 @@
1
+ import { COMMERCE_SETTING_TARGETS, DEFAULT_APP_NAME, DEFAULT_COLOR_SCHEME, DEFAULT_PRESET, DEFAULT_THEME_PRESETS, MAX_TERMS_LENGTH } from "./engine/defaults.js";
2
+ import { buildNav, navItemId } from "./engine/nav.js";
3
+ import { canonical, diagnose, isEmptyCookbook } from "./engine/document.js";
4
+ import { adopt, execute, exportFileName, fail, libraryName, serializeCookbook } from "./engine/commands.js";
5
+ import { buildBatchTool, buildCommandTools, checkSchema, commandSchemas } from "./engine/schemas.js";
6
+ import { COOKBOOK_COMMANDS_VERSION } from "./engine/types.js";
7
+ import { createCookbookEngine } from "./engine/engine.js";
8
+ import "./engine/index.js";
9
+ export { COMMERCE_SETTING_TARGETS, COOKBOOK_COMMANDS_VERSION, DEFAULT_APP_NAME, DEFAULT_COLOR_SCHEME, DEFAULT_PRESET, DEFAULT_THEME_PRESETS, MAX_TERMS_LENGTH, adopt, buildBatchTool, buildCommandTools, buildNav, canonical, checkSchema, commandSchemas, createCookbookEngine, diagnose, execute, exportFileName, fail, isEmptyCookbook, libraryName, navItemId, serializeCookbook };
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Cookbook v1: parse, validate and migrate (browser-safe; no Node imports).
3
+ * Types live in `@happyvertical/smrt-types`; see `agents/cookbook.md`.
4
+ */
5
+ export * from './validate.js';
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cookbook/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,cAAc,eAAe,CAAC"}
@@ -0,0 +1,131 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://s-m-r-t.dev/schemas/cookbook/v1.json",
4
+ "title": "SMRT cookbook v1",
5
+ "description": "What an app is made of: recipes, features, field policies, exposure, shell layout, theme and overview pages. New optional fields are added within v1; readers ignore unknown keys.",
6
+ "type": "object",
7
+ "required": ["version", "recipes", "policies"],
8
+ "properties": {
9
+ "$schema": {
10
+ "enum": [
11
+ "https://s-m-r-t.dev/schemas/cookbook/v1.json",
12
+ "https://s-m-r-t.dev/schemas/blueprint/v1.json"
13
+ ]
14
+ },
15
+ "version": { "const": 1 },
16
+ "name": { "type": "string" },
17
+ "description": { "type": "string" },
18
+ "recipes": { "type": "array", "items": { "type": "string" } },
19
+ "features": { "type": "array", "items": { "type": "string" } },
20
+ "policies": { "type": "array", "items": { "$ref": "#/$defs/policyRow" } },
21
+ "exposure": {
22
+ "type": "object",
23
+ "additionalProperties": {
24
+ "type": "array",
25
+ "items": { "enum": ["api", "mcp", "cli"] }
26
+ }
27
+ },
28
+ "layout": { "$ref": "#/$defs/layout" },
29
+ "theme": { "$ref": "#/$defs/theme" },
30
+ "overviews": {
31
+ "type": "object",
32
+ "additionalProperties": { "$ref": "#/$defs/overviewOverride" }
33
+ }
34
+ },
35
+ "additionalProperties": true,
36
+ "$defs": {
37
+ "stringList": { "type": "array", "items": { "type": "string" } },
38
+ "policyRow": {
39
+ "type": "object",
40
+ "required": ["objectRef", "fieldName", "scopeType"],
41
+ "properties": {
42
+ "objectRef": { "type": "string", "minLength": 1 },
43
+ "fieldName": { "type": "string", "minLength": 1 },
44
+ "scopeType": { "const": "app" },
45
+ "defaultValue": { "type": ["string", "null"] },
46
+ "visibility": { "enum": ["basic", "advanced", "hidden", null] },
47
+ "help": { "type": ["string", "null"] },
48
+ "label": { "type": ["string", "null"] },
49
+ "displayOrder": { "type": ["number", "null"] },
50
+ "locked": { "type": ["boolean", "null"] }
51
+ },
52
+ "additionalProperties": true
53
+ },
54
+ "layout": {
55
+ "type": "object",
56
+ "required": ["version"],
57
+ "properties": {
58
+ "version": { "const": 1 },
59
+ "sectionOrder": { "$ref": "#/$defs/stringList" },
60
+ "hidden": { "$ref": "#/$defs/stringList" },
61
+ "itemOrder": {
62
+ "type": "object",
63
+ "additionalProperties": { "$ref": "#/$defs/stringList" }
64
+ },
65
+ "moved": {
66
+ "type": "object",
67
+ "additionalProperties": { "type": "string" }
68
+ },
69
+ "placements": {
70
+ "type": "object",
71
+ "additionalProperties": { "type": "string" }
72
+ },
73
+ "sections": {
74
+ "type": "object",
75
+ "additionalProperties": { "type": "object" }
76
+ },
77
+ "items": {
78
+ "type": "object",
79
+ "additionalProperties": { "type": "object" }
80
+ },
81
+ "panels": {
82
+ "type": "object",
83
+ "additionalProperties": { "type": "object" }
84
+ },
85
+ "customSections": {
86
+ "type": "array",
87
+ "items": {
88
+ "type": "object",
89
+ "required": ["id", "label"],
90
+ "properties": {
91
+ "id": { "type": "string" },
92
+ "label": { "type": "string" }
93
+ }
94
+ }
95
+ }
96
+ },
97
+ "additionalProperties": true
98
+ },
99
+ "theme": {
100
+ "type": "object",
101
+ "properties": {
102
+ "preset": { "type": "string" },
103
+ "colorScheme": { "enum": ["light", "dark", "system"] },
104
+ "custom": {
105
+ "type": "object",
106
+ "required": ["primary"],
107
+ "properties": {
108
+ "primary": { "type": "string", "pattern": "^#[0-9a-fA-F]{6}$" },
109
+ "fontFamily": { "type": "string" }
110
+ }
111
+ }
112
+ },
113
+ "additionalProperties": true
114
+ },
115
+ "overviewOverride": {
116
+ "type": "object",
117
+ "required": ["version"],
118
+ "properties": {
119
+ "version": { "const": 1 },
120
+ "order": { "$ref": "#/$defs/stringList" },
121
+ "removed": { "$ref": "#/$defs/stringList" },
122
+ "added": { "type": "array", "items": { "type": "object" } },
123
+ "changed": {
124
+ "type": "object",
125
+ "additionalProperties": { "type": "object" }
126
+ }
127
+ },
128
+ "additionalProperties": true
129
+ }
130
+ }
131
+ }
@@ -0,0 +1,37 @@
1
+ import type { Cookbook } from '@happyvertical/smrt-types';
2
+ export type { Cookbook } from '@happyvertical/smrt-types';
3
+ /** What a v1 document carries in `$schema`. */
4
+ export declare const COOKBOOK_SCHEMA_URL = "https://s-m-r-t.dev/schemas/cookbook/v1.json";
5
+ /** Accepted on read (the document used to be called a blueprint); never written. */
6
+ export declare const COOKBOOK_LEGACY_SCHEMA_URL = "https://s-m-r-t.dev/schemas/blueprint/v1.json";
7
+ export declare const COOKBOOK_VERSION = 1;
8
+ export interface CookbookValidateOptions {
9
+ /**
10
+ * The recipe ids that exist (from published manifests). When given, an id
11
+ * outside it is an error. When absent no existence check runs: that is the
12
+ * seam `smrt cookbook validate` fills.
13
+ */
14
+ recipes?: Iterable<string>;
15
+ }
16
+ export type CookbookValidation = {
17
+ ok: true;
18
+ cookbook: Cookbook;
19
+ warnings: string[];
20
+ } | {
21
+ ok: false;
22
+ errors: string[];
23
+ };
24
+ /**
25
+ * Structural validation of an unknown value (parsed JSON). Returns the
26
+ * normalised document (legacy `$schema` rewritten, `features` defaulted,
27
+ * recipes sorted and unique) or every problem found, each a readable line
28
+ * naming the path. Unknown top-level keys are kept (additive fields in v1).
29
+ *
30
+ * Deep checks that need other packages (overview widgets against a page
31
+ * definition, nav ids against recipes, theme presets) are the consumer's job;
32
+ * recipe existence runs only when `options.recipes` is given.
33
+ */
34
+ export declare function validateCookbook(input: unknown, options?: CookbookValidateOptions): CookbookValidation;
35
+ /** Parse JSON text, then {@link validateCookbook} it. */
36
+ export declare function parseCookbookText(text: string, options?: CookbookValidateOptions): CookbookValidation;
37
+ //# sourceMappingURL=validate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../src/cookbook/validate.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,QAAQ,EAMT,MAAM,2BAA2B,CAAC;AAEnC,YAAY,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AAE1D,+CAA+C;AAC/C,eAAO,MAAM,mBAAmB,iDACgB,CAAC;AACjD,oFAAoF;AACpF,eAAO,MAAM,0BAA0B,kDACU,CAAC;AAClD,eAAO,MAAM,gBAAgB,IAAI,CAAC;AAElC,MAAM,WAAW,uBAAuB;IACtC;;;;OAIG;IACH,OAAO,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;CAC5B;AAED,MAAM,MAAM,kBAAkB,GAC1B;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,EAAE,QAAQ,CAAC;IAAC,QAAQ,EAAE,MAAM,EAAE,CAAA;CAAE,GACpD;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC;AA6IpC;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,OAAO,EACd,OAAO,GAAE,uBAA4B,GACpC,kBAAkB,CAwHpB;AAED,yDAAyD;AACzD,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,uBAA4B,GACpC,kBAAkB,CAQpB"}