@ogygie/generate 0.20.0 → 0.22.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.
@@ -0,0 +1,55 @@
1
+ /**
2
+ * @intent The body of a CUSTOM VIEW as a hole (DECISIONS.md D41, D53 — spec
3
+ * ogygie-hosted-mode B10): the text mechanics `fill` needs to treat
4
+ * `views/<Vue>.tsx` like `logic.ts`. A candidate answered by a model is TWO
5
+ * written parts — the import lines it needs, then the body of the component —
6
+ * because a view composes patterns the generator cannot foresee; they go
7
+ * between the `// @hole-imports` and the `// @hole` markers of the file. The
8
+ * imports are judged against a CLOSED catalogue (react, the i18n macro,
9
+ * `@ogygie/ui` and its entries, the product's patterns folder, the sibling
10
+ * views, the feature's own reads), the body against the bans of a logic hole
11
+ * plus what a view may not do: a data hook, a raw table or form, an inline
12
+ * style, an arbitrary Tailwind value or a hex colour (the tokens), an
13
+ * innerHTML. The rules of D24 then apply unchanged: the first candidate green
14
+ * at the view's example test — and at the static render of the nominal
15
+ * state — wins, and enters the library under the view's signature. Pure
16
+ * functions, proven in memory; the command wires the files and the runner.
17
+ */
18
+ import type { CustomViewPlan, ScreenPlan } from "../emit/screen-plan.js";
19
+ import { type HoleLibraryEntry, type HoleShape } from "../hole-shape.js";
20
+ import { type BodyBan } from "./body.js";
21
+ import type { HoleFillRules } from "./fill.js";
22
+ /** The mark the generator leaves in a view whose body nobody wrote yet. */
23
+ export declare const VIEW_PLACEHOLDER = "data-pattern=\"HoleUnfilled\"";
24
+ /** Whether a view's body is still the generator's placeholder. */
25
+ export declare function isUnfilledViewBody(body: string): boolean;
26
+ export interface ViewCandidateParts {
27
+ /** The import statements, one per entry, as written. */
28
+ imports: string[];
29
+ /** The body lines of the component, two-space indented. */
30
+ body: string;
31
+ }
32
+ /** A candidate text split into its leading import statements (multi-line ones included) and the body that follows. */
33
+ export declare function splitViewCandidate(text: string): ViewCandidateParts;
34
+ /** The canonical text of a view candidate: its import lines, then its body — what the library stores and `writeBody` splits. */
35
+ export declare function viewCandidateTextOf(parts: ViewCandidateParts): string;
36
+ /** A model's answer reduced to a canonical candidate: the fenced block when there is one, the imports first, the body extracted as a logic body is. */
37
+ export declare function extractViewCandidate(answer: string): string;
38
+ /** The sources a model-written view may import from — the closed catalogue of D53 — besides a type-only import, which is harmless anywhere. */
39
+ export declare function isAllowedViewImportSource(source: string): boolean;
40
+ /** The import statements that leave the catalogue — each named by its source. */
41
+ export declare function forbiddenInViewImports(imports: readonly string[]): string[];
42
+ /** What the body of a view may not carry: a logic body's bans, and what a view in particular never does. */
43
+ export declare const VIEW_BODY_BANS: readonly BodyBan[];
44
+ /** The rules a view candidate breaks — its imports against the catalogue, its body against the bans; empty when it may be tested. */
45
+ export declare function forbiddenInViewCandidate(text: string): string[];
46
+ /** The body currently written for a view, read between its markers — empty when the markers are absent. */
47
+ export declare function currentViewBody(file: string, holeId: string): string;
48
+ /** `views/<Vue>.tsx` with its two written parts replaced — the candidate's imports and body, or the placeholder and no import when the candidate is null — everything else byte for byte. */
49
+ export declare function replaceViewSections(file: string, holeId: string, candidate: string | null): string;
50
+ /** The literal signature of a custom view: its props and its function line, as the file carries them. */
51
+ export declare function customViewSignatureText(view: CustomViewPlan): string;
52
+ /** The shape of a custom view: the normalized types it receives, by position, and the kinds of the writes it may trigger. */
53
+ export declare function customViewShapeOf(view: CustomViewPlan): HoleShape;
54
+ /** The rules `fillHole` applies to the body of a custom view (D53): placeholder, catalogue and bans, library by signature then by shape, entry under the view's signature. */
55
+ export declare function customViewRules(view: CustomViewPlan, plan: ScreenPlan, library: readonly HoleLibraryEntry[]): HoleFillRules;
@@ -10,6 +10,7 @@ export declare const HoleShapeSchema: z.ZodObject<{
10
10
  derive: "derive";
11
11
  project: "project";
12
12
  view: "view";
13
+ "custom-view": "custom-view";
13
14
  }>;
14
15
  reads: z.ZodArray<z.ZodString>;
15
16
  columns: z.ZodArray<z.ZodString>;
@@ -47,6 +48,7 @@ export declare const HoleLibraryEntrySchema: z.ZodObject<{
47
48
  derive: "derive";
48
49
  project: "project";
49
50
  view: "view";
51
+ "custom-view": "custom-view";
50
52
  }>;
51
53
  reads: z.ZodArray<z.ZodString>;
52
54
  columns: z.ZodArray<z.ZodString>;
package/dist/index.d.ts CHANGED
@@ -38,8 +38,10 @@ export { applyGeneratedContracts } from "./emit/spec-contracts.js";
38
38
  export { boundScreenBehaviorsOf, type LoadedConsumedForVerify } from "./verify-generation.js";
39
39
  export { FrontTargetSchema, type FrontTarget } from "./manifest-generation.schema.js";
40
40
  export { DERIVED_READ_GUARD, consumableOperationsOf, derivedReadsOf, readIdOfInputSchema } from "./consumed-feature.js";
41
- export { fillHole, fillFeature, DEFAULT_FILL_OPTIONS, type Candidate, type FillDeps, type FillOptions, type HoleFillInput, type HoleFillResult, type FeatureFillSummary } from "./fill/fill.js";
42
- export { replaceHoleBody, extractCandidateBody, forbiddenInBody, isTodoBody, BODY_BANS } from "./fill/body.js";
43
- export { createModelDrawer, DEFAULT_FILL_MODELS, HOLE_SYSTEM_PROMPT, type FillModels, type ModelDrawer } from "./fill/model-draw.js";
44
- export { recordLibraryEntry, scrubbedEnvironment, parseFillFlags } from "./cli/fill-command.js";
41
+ export { fillHole, fillFeature, logicHoleRules, DEFAULT_FILL_OPTIONS, type Candidate, type FillDeps, type FillOptions, type HoleFillInput, type HoleFillResult, type HoleFillRules, type FeatureFillSummary } from "./fill/fill.js";
42
+ export { replaceHoleBody, extractCandidateBody, forbiddenInBody, isTodoBody, BODY_BANS, type BodyBan } from "./fill/body.js";
43
+ export { createModelDrawer, DEFAULT_FILL_MODELS, HOLE_SYSTEM_PROMPT, VIEW_SYSTEM_PROMPT, VIEW_DRAWER_OPTIONS, type FillModels, type ModelDrawer, type ModelDrawerOptions } from "./fill/model-draw.js";
44
+ export { VIEW_PLACEHOLDER, VIEW_BODY_BANS, isUnfilledViewBody, splitViewCandidate, viewCandidateTextOf, extractViewCandidate, isAllowedViewImportSource, forbiddenInViewImports, forbiddenInViewCandidate, currentViewBody, replaceViewSections, customViewSignatureText, customViewShapeOf, customViewRules, type ViewCandidateParts, } from "./fill/view.js";
45
+ export { recordLibraryEntry, scrubbedEnvironment, parseFillFlags, viewExampleTestName, NOMINAL_PREVIEW_TEST_NAME, FILL_NEEDS_OPERATOR_EXIT } from "./cli/fill-command.js";
46
+ export { screenPlanOf, type ScreenPlanLookup } from "./cli/generate-screen-command.js";
45
47
  export { generationGrammarCard } from "./prompt-card.js";
package/dist/index.js CHANGED
@@ -11,6 +11,7 @@ import {
11
11
  DEFAULT_FILL_OPTIONS,
12
12
  DERIVED_READ_GUARD,
13
13
  EMPTY_GUARD_REGISTRY,
14
+ FILL_NEEDS_OPERATOR_EXIT,
14
15
  FORM_RENDERS,
15
16
  FORM_STATES,
16
17
  FormViewSchema,
@@ -44,6 +45,7 @@ import {
44
45
  ModuleExportSchema,
45
46
  ModuleTypeSchema,
46
47
  MotifsSchema,
48
+ NOMINAL_PREVIEW_TEST_NAME,
47
49
  OPENING_KEYWORD,
48
50
  OperationSchema,
49
51
  READ_RENDERS,
@@ -56,6 +58,10 @@ import {
56
58
  ScreenHoleSchema,
57
59
  TableDeclarationSchema,
58
60
  TableRefSchema,
61
+ VIEW_BODY_BANS,
62
+ VIEW_DRAWER_OPTIONS,
63
+ VIEW_PLACEHOLDER,
64
+ VIEW_SYSTEM_PROMPT,
59
65
  ViewSchema,
60
66
  WRITE_OPERATION_KINDS,
61
67
  acceptExamplesOf,
@@ -80,6 +86,10 @@ import {
80
86
  consumerOf,
81
87
  contractViolationCodeOf,
82
88
  createModelDrawer,
89
+ currentViewBody,
90
+ customViewRules,
91
+ customViewShapeOf,
92
+ customViewSignatureText,
83
93
  deepOverlay,
84
94
  deniedCodeOf,
85
95
  derivedReadsOf,
@@ -92,10 +102,13 @@ import {
92
102
  extractCandidateBody,
93
103
  extractGenerationSection,
94
104
  extractSpecContracts,
105
+ extractViewCandidate,
95
106
  fieldNamesOf,
96
107
  fillFeature,
97
108
  fillHole,
98
109
  forbiddenInBody,
110
+ forbiddenInViewCandidate,
111
+ forbiddenInViewImports,
99
112
  generateFeature,
100
113
  generateScreen,
101
114
  hasSameFieldsAs,
@@ -104,16 +117,19 @@ import {
104
117
  intentForManifest,
105
118
  intentOfSpec,
106
119
  invalidSampleOf,
120
+ isAllowedViewImportSource,
107
121
  isAsyncHole,
108
122
  isHttpOperation,
109
123
  isKeyedOperation,
110
124
  isLiteralValue,
111
125
  isTodoBody,
126
+ isUnfilledViewBody,
112
127
  isWriteOperation,
113
128
  labelOf,
114
129
  libraryEntryOf,
115
130
  libraryFileNameOf,
116
131
  loadHolesLibrary,
132
+ logicHoleRules,
117
133
  manifestEntryDrift,
118
134
  manifestEntryOf,
119
135
  migrationFileNameFor,
@@ -143,11 +159,13 @@ import {
143
159
  recordLibraryEntry,
144
160
  refusalsOf,
145
161
  replaceHoleBody,
162
+ replaceViewSections,
146
163
  routeDescriptionOf,
147
164
  sampleOf,
148
165
  screenBodyDefault,
149
166
  screenBodyPath,
150
167
  screenCaseKey,
168
+ screenPlanOf,
151
169
  screenVocabularyOf,
152
170
  scrubbedEnvironment,
153
171
  serializeManifest,
@@ -157,6 +175,7 @@ import {
157
175
  signatureTextOf,
158
176
  specGeneratedStart,
159
177
  splitTopLevelSections,
178
+ splitViewCandidate,
160
179
  tableNameOf,
161
180
  tableRefOf,
162
181
  tablesOf,
@@ -165,8 +184,10 @@ import {
165
184
  validationOf,
166
185
  verifyGeneration,
167
186
  viewBodiesOf,
187
+ viewCandidateTextOf,
188
+ viewExampleTestName,
168
189
  vocabularyOf
169
- } from "./chunk-WVFHAPGC.js";
190
+ } from "./chunk-ASXSTGY5.js";
170
191
 
171
192
  // src/prompt-card.ts
172
193
  var phrase = (caseKey) => caseKey.replace(/^with:/u, "avec ").replace(/^without:/u, "sans ");
@@ -243,6 +264,7 @@ export {
243
264
  DEFAULT_FILL_OPTIONS,
244
265
  DERIVED_READ_GUARD,
245
266
  EMPTY_GUARD_REGISTRY,
267
+ FILL_NEEDS_OPERATOR_EXIT,
246
268
  FORM_RENDERS,
247
269
  FORM_STATES,
248
270
  FormViewSchema,
@@ -275,6 +297,7 @@ export {
275
297
  ModuleExportSchema,
276
298
  ModuleTypeSchema,
277
299
  MotifsSchema,
300
+ NOMINAL_PREVIEW_TEST_NAME,
278
301
  OPENING_KEYWORD,
279
302
  OperationSchema,
280
303
  READ_RENDERS,
@@ -287,6 +310,10 @@ export {
287
310
  ScreenHoleSchema,
288
311
  TableDeclarationSchema,
289
312
  TableRefSchema,
313
+ VIEW_BODY_BANS,
314
+ VIEW_DRAWER_OPTIONS,
315
+ VIEW_PLACEHOLDER,
316
+ VIEW_SYSTEM_PROMPT,
290
317
  ViewSchema,
291
318
  WRITE_OPERATION_KINDS,
292
319
  acceptExamplesOf,
@@ -311,6 +338,10 @@ export {
311
338
  consumerOf,
312
339
  contractViolationCodeOf,
313
340
  createModelDrawer,
341
+ currentViewBody,
342
+ customViewRules,
343
+ customViewShapeOf,
344
+ customViewSignatureText,
314
345
  deepOverlay,
315
346
  deniedCodeOf,
316
347
  derivedReadsOf,
@@ -323,10 +354,13 @@ export {
323
354
  extractCandidateBody,
324
355
  extractGenerationSection,
325
356
  extractSpecContracts,
357
+ extractViewCandidate,
326
358
  fieldNamesOf,
327
359
  fillFeature,
328
360
  fillHole,
329
361
  forbiddenInBody,
362
+ forbiddenInViewCandidate,
363
+ forbiddenInViewImports,
330
364
  generateFeature,
331
365
  generateScreen,
332
366
  generationGrammarCard,
@@ -336,16 +370,19 @@ export {
336
370
  intentForManifest,
337
371
  intentOfSpec,
338
372
  invalidSampleOf,
373
+ isAllowedViewImportSource,
339
374
  isAsyncHole,
340
375
  isHttpOperation,
341
376
  isKeyedOperation,
342
377
  isLiteralValue,
343
378
  isTodoBody,
379
+ isUnfilledViewBody,
344
380
  isWriteOperation,
345
381
  labelOf,
346
382
  libraryEntryOf,
347
383
  libraryFileNameOf,
348
384
  loadHolesLibrary,
385
+ logicHoleRules,
349
386
  manifestEntryDrift,
350
387
  manifestEntryOf,
351
388
  migrationFileNameFor,
@@ -375,11 +412,13 @@ export {
375
412
  recordLibraryEntry,
376
413
  refusalsOf,
377
414
  replaceHoleBody,
415
+ replaceViewSections,
378
416
  routeDescriptionOf,
379
417
  sampleOf,
380
418
  screenBodyDefault,
381
419
  screenBodyPath,
382
420
  screenCaseKey,
421
+ screenPlanOf,
383
422
  screenVocabularyOf,
384
423
  scrubbedEnvironment,
385
424
  serializeManifest,
@@ -389,6 +428,7 @@ export {
389
428
  signatureTextOf,
390
429
  specGeneratedStart,
391
430
  splitTopLevelSections,
431
+ splitViewCandidate,
392
432
  tableNameOf,
393
433
  tableRefOf,
394
434
  tablesOf,
@@ -397,5 +437,7 @@ export {
397
437
  validationOf,
398
438
  verifyGeneration,
399
439
  viewBodiesOf,
440
+ viewCandidateTextOf,
441
+ viewExampleTestName,
400
442
  vocabularyOf
401
443
  };
@@ -10,7 +10,7 @@ porte sous `// @hole <id>`.
10
10
  "hole": "<id du trou>",
11
11
  "signature": "<signature générée>",
12
12
  "signatureHash": "<16 hex — sha256 du texte de la signature>",
13
- "shape": { "kind": "validate | transform", "reads": ["<type normalisé par position>"], "columns": ["…"], "codeRole": "operation-refusal | motif-rejection", "returns": "void | rows:<n>" },
13
+ "shape": { "kind": "validate | transform | derive | project | view | custom-view", "reads": ["<type normalisé par position>"], "columns": ["…"], "codeRole": "operation-refusal | motif-rejection | none", "returns": "void | rows:<n> | <type dérivé> | output | view:<forme> | jsx" },
14
14
  "shapeHash": "<16 hex — sha256 du JSON de la forme>",
15
15
  "errorCode": "<code que le trou rend>",
16
16
  "bodyTemplate": "<corps en gabarit : {{read:n}}, {{column:n}}, {{code}}, {{rowType}} à la place des noms de la feature>",
@@ -31,3 +31,9 @@ Lot 2 : les entrées sont écrites par `pnpm ogygie:holes-library <feature>`,
31
31
  qui enregistre les corps qu'un humain a remplis (chemin `human`, `model: null`).
32
32
  La recherche par forme au remplissage, le tirage-vérification et l'escalade
33
33
  sont le lot 2 bis.
34
+
35
+ Depuis la 0.21.0 (D53), le corps d'une vue `custom` d'un écran entre ici
36
+ aussi : `kind: "custom-view"`, `reads` les types normalisés des champs reçus,
37
+ `columns` les genres des écritures que la vue peut déclencher, `returns: "jsx"`,
38
+ la signature étant les props et la ligne de fonction de `views/<Vue>.tsx` ; le
39
+ `bodyTemplate` porte les lignes d'import puis le corps, sans gabarit.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ogygie/generate",
3
- "version": "0.20.0",
3
+ "version": "0.22.0",
4
4
  "description": "Ogygie generator: reads the `# Génération` block of a spec and its schemas.ts, derives everything deterministic without a model (routes, pipeline, database, factories, tests, screens, previews), fills the typed holes of logic.ts by library, draw and escalation, and draws the first schemas.ts of a new feature — judged by the gates. Sixth package of the lockstep (D55).",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -29,7 +29,7 @@
29
29
  }
30
30
  },
31
31
  "dependencies": {
32
- "@ogygie/core": "0.20.0",
32
+ "@ogygie/core": "0.22.0",
33
33
  "tsx": "^4.20.0",
34
34
  "yaml": "^2.9.0",
35
35
  "zod": "^4.0.0"
@@ -38,7 +38,7 @@
38
38
  "@lingui/babel-plugin-lingui-macro": "^5.9.5",
39
39
  "@lingui/core": "^5.9.5",
40
40
  "@lingui/react": "^5.9.5",
41
- "@ogygie/ui": "0.20.0",
41
+ "@ogygie/ui": "0.22.0",
42
42
  "@starter/api": "0.1.0",
43
43
  "@tanstack/react-query": "^5.102.2",
44
44
  "@tanstack/react-router": "^1.170.32",
@@ -53,7 +53,7 @@
53
53
  "react-dom": "^19.2.8",
54
54
  "typescript": "^5.8.0",
55
55
  "vite": "^7.3.6",
56
- "vitest": "^3.2.0"
56
+ "vitest": "^4.1.12"
57
57
  },
58
58
  "scripts": {
59
59
  "build": "tsx scripts/build.ts",