@ogygie/generate 0.0.0-stage → 0.20.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.
- package/LICENSE +21 -0
- package/README.md +39 -2
- package/dist/behavior-binding.d.ts +47 -0
- package/dist/behavior-grammar.d.ts +53 -0
- package/dist/check-spec.d.ts +53 -0
- package/dist/chunk-WVFHAPGC.js +10992 -0
- package/dist/cli/check-command.d.ts +3 -0
- package/dist/cli/fill-command.d.ts +39 -0
- package/dist/cli/generate-command.d.ts +8 -0
- package/dist/cli/generate-screen-command.d.ts +6 -0
- package/dist/cli/output.d.ts +9 -0
- package/dist/cli/preview-command.d.ts +19 -0
- package/dist/cli/project.d.ts +97 -0
- package/dist/cli/run.d.ts +13 -0
- package/dist/cli/run.js +1127 -0
- package/dist/cli/schemas-command.d.ts +31 -0
- package/dist/cli/verify-command.d.ts +3 -0
- package/dist/consumed-feature.d.ts +32 -0
- package/dist/emit/db.d.ts +27 -0
- package/dist/emit/factories.d.ts +14 -0
- package/dist/emit/hole-doc.d.ts +18 -0
- package/dist/emit/hole-tests.d.ts +28 -0
- package/dist/emit/manifest-entry.d.ts +44 -0
- package/dist/emit/mssql/migration.d.ts +2 -0
- package/dist/emit/mssql/repository.d.ts +17 -0
- package/dist/emit/mssql/sql-types.d.ts +23 -0
- package/dist/emit/mssql/statements.d.ts +55 -0
- package/dist/emit/mssql/stub.d.ts +17 -0
- package/dist/emit/names.d.ts +34 -0
- package/dist/emit/plan.d.ts +428 -0
- package/dist/emit/repository.d.ts +16 -0
- package/dist/emit/routes.d.ts +22 -0
- package/dist/emit/runtime.d.ts +47 -0
- package/dist/emit/screen/container.d.ts +17 -0
- package/dist/emit/screen/fixtures.d.ts +14 -0
- package/dist/emit/screen/hole-doc.d.ts +2 -0
- package/dist/emit/screen/previews.d.ts +24 -0
- package/dist/emit/screen/queries.d.ts +10 -0
- package/dist/emit/screen/shared.d.ts +35 -0
- package/dist/emit/screen/spec-contracts.d.ts +10 -0
- package/dist/emit/screen/tests-static.d.ts +21 -0
- package/dist/emit/screen/tests.d.ts +19 -0
- package/dist/emit/screen/views.d.ts +10 -0
- package/dist/emit/screen/writes.d.ts +9 -0
- package/dist/emit/screen-plan.d.ts +187 -0
- package/dist/emit/service.d.ts +18 -0
- package/dist/emit/spec-contracts.d.ts +27 -0
- package/dist/emit/tests.d.ts +3 -0
- package/dist/fill/body.d.ts +26 -0
- package/dist/fill/fill.d.ts +97 -0
- package/dist/fill/model-draw.d.ts +25 -0
- package/dist/generate-feature.d.ts +23 -0
- package/dist/generate-screen.d.ts +19 -0
- package/dist/generation-block.schema.d.ts +1279 -0
- package/dist/hole-shape.d.ts +100 -0
- package/dist/index.d.ts +45 -0
- package/dist/index.js +401 -0
- package/dist/manifest-generation.schema.d.ts +239 -0
- package/dist/motif-catalog.d.ts +175 -0
- package/dist/package-root.d.ts +5 -0
- package/dist/prompt-card.d.ts +3 -0
- package/dist/schema-checks.d.ts +32 -0
- package/dist/schemas/draft.d.ts +111 -0
- package/dist/screen-block.schema.d.ts +146 -0
- package/dist/screen-checks.d.ts +34 -0
- package/dist/screen-grammar.d.ts +36 -0
- package/dist/screen-vocabulary.d.ts +47 -0
- package/dist/spec-sections.d.ts +51 -0
- package/dist/verify-generation.d.ts +93 -0
- package/dist/vocabulary.d.ts +39 -0
- package/dist/zod-introspection.d.ts +119 -0
- package/holes-library/27560e1760bb184c.json +28 -0
- package/holes-library/2c26136fc6bff99a.json +30 -0
- package/holes-library/43a27770407bb38a.json +27 -0
- package/holes-library/46e67880a81012bc.json +27 -0
- package/holes-library/48dc5c44dc2cf3b7.json +32 -0
- package/holes-library/63d0825a61f6f5d3.json +27 -0
- package/holes-library/6784ed6c8e353dac.json +27 -0
- package/holes-library/8b4e4c8f04a5fc6a.json +31 -0
- package/holes-library/README.md +33 -0
- package/holes-library/d3597f50c265ba0c.json +27 -0
- package/holes-library/e48695e16221ff1a.json +32 -0
- package/package.json +59 -3
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @intent Emits `<Ecran>.gen.test.tsx` (D20 for screens, D43): the test file of
|
|
3
|
+
* a screen follows the front target of the manifest — `emitScreenTests` picks
|
|
4
|
+
* the flavour, the spec block being the same on both. This file holds the
|
|
5
|
+
* JSDOM one: one test per behavior line of the spec, named by the line,
|
|
6
|
+
* rendering the CONTAINER under the front's test bench with a recording
|
|
7
|
+
* `fetch` stub — the consumed reads served from the fixtures, the state of the
|
|
8
|
+
* line arranged on the route it speaks of (pending, a server failure, an
|
|
9
|
+
* access refusal, the empty collection, the rows) — and asserting what the
|
|
10
|
+
* line says the screen renders: the skeleton, the error banner, the access
|
|
11
|
+
* explanation, the empty state, the rows and their order, a write sent with
|
|
12
|
+
* the valid input, the error sentences, nothing written, the save banner of a
|
|
13
|
+
* refused write. A custom view gets the test of its example: red until its
|
|
14
|
+
* body is written. A line carried by a hole is a todo. The `static-render`
|
|
15
|
+
* flavour — states in HTML, no gesture — is tests-static.ts.
|
|
16
|
+
*/
|
|
17
|
+
import type { ScreenPlan } from "../screen-plan.js";
|
|
18
|
+
/** The test file of a screen on the front target the manifest declares (D43): the block is the same, only the tests change. */
|
|
19
|
+
export declare function emitScreenTests(plan: ScreenPlan): string;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { CustomViewPlan, FormViewPlan, ListViewPlan, ScreenPlan } from "../screen-plan.js";
|
|
2
|
+
export declare function emitListView(plan: ScreenPlan, view: ListViewPlan): string;
|
|
3
|
+
export declare function emitFormView(plan: ScreenPlan, view: FormViewPlan): string;
|
|
4
|
+
/** The props of a custom view: the received fields of the output, and one MutationLike per action. */
|
|
5
|
+
export declare function customViewPropsLines(view: CustomViewPlan): string[];
|
|
6
|
+
/** The signature line of a custom view — what the markers protect and compare. */
|
|
7
|
+
export declare function customViewSignature(view: CustomViewPlan): string;
|
|
8
|
+
/** The imports a custom view's body needs — written between `// @hole-imports` markers, kept verbatim at regeneration: a body composes patterns and hooks the generator cannot foresee (astorg-ai-pdlc, lot 4 M3). */
|
|
9
|
+
export declare function customImportsLines(view: CustomViewPlan, existing: string | null): string[];
|
|
10
|
+
export declare function emitCustomView(plan: ScreenPlan, view: CustomViewPlan, existing: string | null): string;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @intent Emits `writes.gen.ts` of a screen (D42): one TanStack mutation hook
|
|
3
|
+
* per consumed WRITE, calling the route through `fetchContract` with a JSON
|
|
4
|
+
* body, and making stale — on success — the cache roots the manifest client
|
|
5
|
+
* derives for it: the route's own root and every root the map declares in
|
|
6
|
+
* `invalidates`. A keyed write takes its path parameters with its input.
|
|
7
|
+
*/
|
|
8
|
+
import type { ScreenPlan } from "../screen-plan.js";
|
|
9
|
+
export declare function emitScreenWrites(plan: ScreenPlan): string;
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
import { type ConsumedRoute } from "../consumed-feature.js";
|
|
2
|
+
import type { GuardDenial, GuardRegistry, FrontTarget } from "../manifest-generation.schema.js";
|
|
3
|
+
import { type GenerationBlock, type HttpOperation } from "../generation-block.schema.js";
|
|
4
|
+
import type { HttpOperationKind } from "../motif-catalog.js";
|
|
5
|
+
import { type CustomView, type FormView, type ListView, type ScreenBlock, type ScreenHole } from "../screen-block.schema.js";
|
|
6
|
+
import type { ParsedScreenBehavior } from "../screen-grammar.js";
|
|
7
|
+
import { type FieldModel, type SchemaModels } from "../zod-introspection.js";
|
|
8
|
+
export type { ConsumedRoute };
|
|
9
|
+
export interface ConsumedFeatureInput {
|
|
10
|
+
featureId: string;
|
|
11
|
+
/** Null for a feature without a block: the screen reads its GET routes (D41 precision, lot 4 M3). */
|
|
12
|
+
block: GenerationBlock | null;
|
|
13
|
+
schemas: SchemaModels;
|
|
14
|
+
/** The feature's routes as the map declares them — where `invalidates` lives. */
|
|
15
|
+
routes: readonly ConsumedRoute[];
|
|
16
|
+
}
|
|
17
|
+
export interface BoundScreenBehaviorInput {
|
|
18
|
+
behavior: ParsedScreenBehavior;
|
|
19
|
+
status: "derivable" | "hole";
|
|
20
|
+
}
|
|
21
|
+
export interface ScreenPlanInput {
|
|
22
|
+
featureId: string;
|
|
23
|
+
/** Folder of the screen feature, relative to the repo root. */
|
|
24
|
+
folder: string;
|
|
25
|
+
/** Path of the front app, relative to the repo root. */
|
|
26
|
+
appPath: string;
|
|
27
|
+
specPath: string;
|
|
28
|
+
block: ScreenBlock;
|
|
29
|
+
consumed: readonly ConsumedFeatureInput[];
|
|
30
|
+
front: FrontTarget;
|
|
31
|
+
guards: GuardRegistry;
|
|
32
|
+
contractViolationCode: string;
|
|
33
|
+
generatorVersion: string;
|
|
34
|
+
behaviors: readonly BoundScreenBehaviorInput[];
|
|
35
|
+
}
|
|
36
|
+
/** One consumed operation, with what the screen emits for it: a hook, a key, its invalidations, its fixtures. */
|
|
37
|
+
export interface ScreenOperationPlan {
|
|
38
|
+
featureId: string;
|
|
39
|
+
id: string;
|
|
40
|
+
pascalId: string;
|
|
41
|
+
kind: HttpOperationKind;
|
|
42
|
+
method: HttpOperation["method"];
|
|
43
|
+
path: string;
|
|
44
|
+
pathParameters: string[];
|
|
45
|
+
/** The cache root (first path segment) and the operation name the manifest client derives (D13). */
|
|
46
|
+
root: string;
|
|
47
|
+
clientOperation: string;
|
|
48
|
+
/** `useRatesListAll`. */
|
|
49
|
+
hookName: string;
|
|
50
|
+
/** The TypeScript literal of the cache key: `["rates", "list"]`, parameters and `input` as identifiers. */
|
|
51
|
+
keyLiteral: string;
|
|
52
|
+
/** Cache roots a successful write makes stale, as the manifest client derives them. */
|
|
53
|
+
invalidationRoots: string[];
|
|
54
|
+
inputSchema: string;
|
|
55
|
+
inputType: string;
|
|
56
|
+
inputModel: FieldModel;
|
|
57
|
+
outputSchema: string;
|
|
58
|
+
outputType: string;
|
|
59
|
+
outputModel: FieldModel;
|
|
60
|
+
/** A GET whose input carries fields beyond its path parameters sends them as a query string. */
|
|
61
|
+
hasQueryInput: boolean;
|
|
62
|
+
/** For a read (and a write that responds with one): the collection field of the output and its element. */
|
|
63
|
+
collection: {
|
|
64
|
+
field: string;
|
|
65
|
+
elementModel: FieldModel;
|
|
66
|
+
} | null;
|
|
67
|
+
/** The import specifier of the feature's schemas from the front (D43 `front.contracts`). */
|
|
68
|
+
contractsImport: string;
|
|
69
|
+
/** Refusals the guard of the operation declares — the 401 one is the access-denied fixture. */
|
|
70
|
+
guardDenials: readonly GuardDenial[];
|
|
71
|
+
/** The code and status of the first refusal the operation itself carries (motif, hole), for the refused-write fixture. */
|
|
72
|
+
refusal: {
|
|
73
|
+
code: string;
|
|
74
|
+
status: number;
|
|
75
|
+
} | null;
|
|
76
|
+
/** The valid input a form test sends: the schema's sample under the accept examples of the operation's holes (D23). */
|
|
77
|
+
validInput: Record<string, unknown>;
|
|
78
|
+
/** The served output fixtures: two distinct rows, and an empty collection, for a read. */
|
|
79
|
+
outputFixture: unknown;
|
|
80
|
+
emptyOutputFixture: unknown | null;
|
|
81
|
+
}
|
|
82
|
+
export interface ViewFieldPlan {
|
|
83
|
+
name: string;
|
|
84
|
+
model: FieldModel;
|
|
85
|
+
/** « Effective date » — the English source text of the header or label `<Trans>`. */
|
|
86
|
+
label: string;
|
|
87
|
+
align: "start" | "end";
|
|
88
|
+
}
|
|
89
|
+
export interface ListViewPlan {
|
|
90
|
+
kind: "list";
|
|
91
|
+
id: string;
|
|
92
|
+
componentName: string;
|
|
93
|
+
operation: ScreenOperationPlan;
|
|
94
|
+
/** The element type expression, e.g. `ListAllRatesOutput["publications"][number]`. */
|
|
95
|
+
rowType: string;
|
|
96
|
+
fields: ViewFieldPlan[];
|
|
97
|
+
rowKey: string;
|
|
98
|
+
sort: {
|
|
99
|
+
field: string;
|
|
100
|
+
direction: "asc" | "desc";
|
|
101
|
+
} | null;
|
|
102
|
+
}
|
|
103
|
+
export interface FormViewPlan {
|
|
104
|
+
kind: "form";
|
|
105
|
+
id: string;
|
|
106
|
+
componentName: string;
|
|
107
|
+
operation: ScreenOperationPlan;
|
|
108
|
+
/** `createMutation` — the body prop and the view prop carrying the write. */
|
|
109
|
+
mutationProp: string;
|
|
110
|
+
fields: ViewFieldPlan[];
|
|
111
|
+
multiline: string[];
|
|
112
|
+
/** « Create », « Import », « Save »… the submit label's source text. */
|
|
113
|
+
submitLabel: string;
|
|
114
|
+
}
|
|
115
|
+
export interface CustomViewPlan {
|
|
116
|
+
kind: "custom";
|
|
117
|
+
id: string;
|
|
118
|
+
componentName: string;
|
|
119
|
+
operation: ScreenOperationPlan;
|
|
120
|
+
hole: ScreenHole;
|
|
121
|
+
/** The output fields the view receives, with their models. */
|
|
122
|
+
receives: ViewFieldPlan[];
|
|
123
|
+
/** The writes the view may trigger. */
|
|
124
|
+
actions: Array<{
|
|
125
|
+
operation: ScreenOperationPlan;
|
|
126
|
+
mutationProp: string;
|
|
127
|
+
}>;
|
|
128
|
+
/** The output overlaid by the hole's example — what its test renders. */
|
|
129
|
+
exampleInput: unknown;
|
|
130
|
+
}
|
|
131
|
+
export type ViewPlan = ListViewPlan | FormViewPlan | CustomViewPlan;
|
|
132
|
+
export interface ScreenBehaviorPlan {
|
|
133
|
+
raw: string;
|
|
134
|
+
behavior: ParsedScreenBehavior;
|
|
135
|
+
/** The view the line speaks of; null for « écran », the primary read. */
|
|
136
|
+
view: ViewPlan | null;
|
|
137
|
+
hole: string | null;
|
|
138
|
+
}
|
|
139
|
+
export interface ScreenPlan {
|
|
140
|
+
featureId: string;
|
|
141
|
+
pascalName: string;
|
|
142
|
+
camelName: string;
|
|
143
|
+
folder: string;
|
|
144
|
+
appPath: string;
|
|
145
|
+
specPath: string;
|
|
146
|
+
generatorVersion: string;
|
|
147
|
+
front: FrontTarget;
|
|
148
|
+
route: string | null;
|
|
149
|
+
/** `SaisieDesTauxScreen`, its body `SaisieDesTauxScreenBody`, the body props `SaisieDesTauxScreenBodyProps`, the route factory `saisieDesTauxRoute`. */
|
|
150
|
+
screenName: string;
|
|
151
|
+
bodyName: string;
|
|
152
|
+
propsName: string;
|
|
153
|
+
routeFactoryName: string;
|
|
154
|
+
/** The read the container's ScreenState waits for. */
|
|
155
|
+
primary: ListViewPlan | CustomViewPlan;
|
|
156
|
+
operations: ScreenOperationPlan[];
|
|
157
|
+
reads: ScreenOperationPlan[];
|
|
158
|
+
writes: ScreenOperationPlan[];
|
|
159
|
+
views: ViewPlan[];
|
|
160
|
+
behaviors: ScreenBehaviorPlan[];
|
|
161
|
+
/** Import path of the front test bench from the feature folder, and its export. */
|
|
162
|
+
testBench: {
|
|
163
|
+
exportName: string;
|
|
164
|
+
importPath: string;
|
|
165
|
+
};
|
|
166
|
+
/** Vite `?inline` import of the product's stylesheet from the feature folder — null when the front target names none. */
|
|
167
|
+
stylesheetImport: string | null;
|
|
168
|
+
/** The access-denied and internal-failure bodies the state tests serve. */
|
|
169
|
+
failures: {
|
|
170
|
+
denied: {
|
|
171
|
+
code: string;
|
|
172
|
+
status: number;
|
|
173
|
+
message: string;
|
|
174
|
+
};
|
|
175
|
+
internal: {
|
|
176
|
+
code: string;
|
|
177
|
+
status: number;
|
|
178
|
+
message: string;
|
|
179
|
+
};
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
/** `effectiveDate` → « Effective date » ; `csv` → « CSV » ; `ratePerUnit` → « Rate per unit ». */
|
|
183
|
+
export declare function labelOf(fieldName: string): string;
|
|
184
|
+
/** A distinct sample of a model at `variant`: uuids and dates differ by variant so two rows never share a key. */
|
|
185
|
+
export declare function distinctSampleOf(model: FieldModel, variant: number): unknown;
|
|
186
|
+
export declare function buildScreenPlan(input: ScreenPlanInput): ScreenPlan;
|
|
187
|
+
export type { CustomView, FormView, ListView };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @intent Emits `service.gen.ts`: the pipeline of every operation (D22, as
|
|
3
|
+
* precised on 2026-10-17, extended by D28). A read maps the repository's rows
|
|
4
|
+
* to the output schema — its element covering the resource, the slot arrays
|
|
5
|
+
* (one entry per slot key, null when unset), the reference counts, the values
|
|
6
|
+
* of the view holes — then hands the output to its project holes (D32); a
|
|
7
|
+
* create runs its validate holes in declared order, the first refusal winning
|
|
8
|
+
* as the operation's 400, its derive holes, then the motif's insert; an update,
|
|
9
|
+
* a setOrClear and a delete load the row by key (404 otherwise) and write
|
|
10
|
+
* through the repository; a write that `respondsWith` a read serves that read
|
|
11
|
+
* after writing (D30); every write of a signed resource carries who and when
|
|
12
|
+
* (D31). An import checks the envelope's byte size, runs the transform hole,
|
|
13
|
+
* then validates every line before the all-or-nothing write. Pure functions:
|
|
14
|
+
* the context carrying the db and the clock are injected; a hole receives the
|
|
15
|
+
* effects it declared and nothing else.
|
|
16
|
+
*/
|
|
17
|
+
import type { FeaturePlan } from "./plan.js";
|
|
18
|
+
export declare function emitService(plan: FeaturePlan): string;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { FeaturePlan, OperationPlan } from "./plan.js";
|
|
2
|
+
export declare const CONTRACTS_SECTION_TITLE = "Contrats de donn\u00E9es";
|
|
3
|
+
export declare const SPEC_GENERATED_END = "<!-- @generated:end -->";
|
|
4
|
+
export declare function specGeneratedStart(version: string): string;
|
|
5
|
+
export interface SpecGeneratedBlock {
|
|
6
|
+
version: string;
|
|
7
|
+
/** The lines between the markers, without the markers. */
|
|
8
|
+
content: string;
|
|
9
|
+
/** Offsets of the whole block in the markdown, markers included. */
|
|
10
|
+
start: number;
|
|
11
|
+
end: number;
|
|
12
|
+
}
|
|
13
|
+
/** The generated block of a spec, wherever its markers stand — null without both markers in order. */
|
|
14
|
+
export declare function extractSpecContracts(markdown: string): SpecGeneratedBlock | null;
|
|
15
|
+
/** Every structured refusal a route may answer, code → status, in a stable order. */
|
|
16
|
+
export declare function refusalsOf(operation: OperationPlan, plan: FeaturePlan): Array<[string, number]>;
|
|
17
|
+
/** The lines between the markers — the content `verify` compares. */
|
|
18
|
+
export declare function emitSpecContracts(plan: FeaturePlan): string;
|
|
19
|
+
export interface ApplySpecContractsResult {
|
|
20
|
+
markdown: string;
|
|
21
|
+
/** `inserted` at the end of the section, `replaced` between existing markers, or nothing to do. */
|
|
22
|
+
outcome: "inserted" | "replaced" | "unchanged" | "section-missing";
|
|
23
|
+
}
|
|
24
|
+
/** The spec with its generated block in place — the markers found are replaced, otherwise the block closes the section. */
|
|
25
|
+
export declare function applySpecContracts(markdown: string, plan: FeaturePlan): ApplySpecContractsResult;
|
|
26
|
+
/** Writes a generated block — a feature's or a screen's (D41) — between the markers of `# Contrats de données`: replaced when the markers exist, appended to the section otherwise. */
|
|
27
|
+
export declare function applyGeneratedContracts(markdown: string, content: string, version: string): ApplySpecContractsResult;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @intent The text mechanics of filling a hole (D23, D24): put a body between
|
|
3
|
+
* the markers of `logic.ts` without touching anything else; read a body out of
|
|
4
|
+
* what a model answered (fences, a repeated signature, a stray closing brace
|
|
5
|
+
* stripped); refuse a body that carries what the repo bans before any test
|
|
6
|
+
* runs — the bans of AGENTS.md, plus what a pure hole may not reach (the
|
|
7
|
+
* clock it did not declare, a network, a process, a module). Pure functions,
|
|
8
|
+
* proven in memory.
|
|
9
|
+
*/
|
|
10
|
+
/** `logic.ts` with the body of one hole replaced — the signature, the markers and every other line kept byte for byte. */
|
|
11
|
+
export declare function replaceHoleBody(logic: string, holeId: string, body: string): string;
|
|
12
|
+
/** Whether a section's body is still the generator's `todo`. */
|
|
13
|
+
export declare function isTodoBody(body: string, holeId: string): boolean;
|
|
14
|
+
/**
|
|
15
|
+
* The body in a model's answer: the first fenced block when there is one, a
|
|
16
|
+
* repeated signature dropped up to its opening brace, a closing brace that
|
|
17
|
+
* would close the function dropped, two-space indentation restored.
|
|
18
|
+
*/
|
|
19
|
+
export declare function extractCandidateBody(answer: string): string;
|
|
20
|
+
export interface BodyBan {
|
|
21
|
+
pattern: RegExp;
|
|
22
|
+
rule: string;
|
|
23
|
+
}
|
|
24
|
+
export declare const BODY_BANS: readonly BodyBan[];
|
|
25
|
+
/** The rules a body breaks — empty when it may be tested. */
|
|
26
|
+
export declare function forbiddenInBody(body: string): string[];
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @intent The filling of a hole (DECISIONS.md D24): library, then
|
|
3
|
+
* draw-and-verify, then escalation, then the human — the FIRST GREEN WINS. A
|
|
4
|
+
* candidate body is written between the hole's markers, run against the
|
|
5
|
+
* hole's pure test in a process that holds no secret, checked against the
|
|
6
|
+
* repo's bans; a red one is thrown away and the body goes back to `todo`. A
|
|
7
|
+
* retained body enters the library with its provenance. Nothing here reads a
|
|
8
|
+
* disk or calls a model: every effect is injected, so the whole decision is
|
|
9
|
+
* proven in memory and the real effects (vitest in a subprocess, the Messages
|
|
10
|
+
* client of the core) stay in the command.
|
|
11
|
+
*
|
|
12
|
+
* The threshold of D24 is counted, not enforced: a feature whose holes reach
|
|
13
|
+
* escalation more than one in ten is said to have holes too big for a model —
|
|
14
|
+
* the spec splits them, nobody raises a model.
|
|
15
|
+
*/
|
|
16
|
+
import type { FeaturePlan, HolePlan } from "../emit/plan.js";
|
|
17
|
+
import { type HoleLibraryEntry, type HoleProvenance } from "../hole-shape.js";
|
|
18
|
+
export type FillPath = HoleProvenance["path"];
|
|
19
|
+
export interface Candidate {
|
|
20
|
+
body: string;
|
|
21
|
+
/** Where it came from — the library entry, or the model that drew it. */
|
|
22
|
+
origin: string;
|
|
23
|
+
model: string | null;
|
|
24
|
+
usage: {
|
|
25
|
+
inputTokens: number;
|
|
26
|
+
outputTokens: number;
|
|
27
|
+
} | null;
|
|
28
|
+
}
|
|
29
|
+
export interface FillOptions {
|
|
30
|
+
/** Candidates per draw round (D24: 5). */
|
|
31
|
+
candidates: number;
|
|
32
|
+
/** Draw rounds before escalation (D24: 2). */
|
|
33
|
+
rounds: number;
|
|
34
|
+
/** Library and shape neighbours only: no model is ever called. */
|
|
35
|
+
libraryOnly: boolean;
|
|
36
|
+
}
|
|
37
|
+
export declare const DEFAULT_FILL_OPTIONS: FillOptions;
|
|
38
|
+
export interface FillDeps {
|
|
39
|
+
/** Writes a body between the hole's markers (or `todo` back). */
|
|
40
|
+
writeBody(holeId: string, body: string | null): Promise<void>;
|
|
41
|
+
/** Runs the hole's pure test with the body currently written; green or not, and what the runner said. */
|
|
42
|
+
runHoleTest(holeId: string): Promise<{
|
|
43
|
+
green: boolean;
|
|
44
|
+
lines: string[];
|
|
45
|
+
}>;
|
|
46
|
+
/** `n` candidates from the draw model on the hole's context, in parallel. */
|
|
47
|
+
draw(context: string, n: number, round: number): Promise<Candidate[]>;
|
|
48
|
+
/** One candidate from the escalation model. */
|
|
49
|
+
escalate(context: string): Promise<Candidate>;
|
|
50
|
+
recordLibrary(entry: HoleLibraryEntry): Promise<void>;
|
|
51
|
+
/** ISO date of today — the provenance carries it. */
|
|
52
|
+
today(): string;
|
|
53
|
+
repo: string;
|
|
54
|
+
log(line: string): void;
|
|
55
|
+
}
|
|
56
|
+
export interface HoleFillInput {
|
|
57
|
+
hole: HolePlan;
|
|
58
|
+
plan: FeaturePlan;
|
|
59
|
+
/** `holes/<id>.gen.md`, the one context a model gets. */
|
|
60
|
+
context: string;
|
|
61
|
+
/** What logic.ts holds for this hole now. */
|
|
62
|
+
currentBody: string;
|
|
63
|
+
library: readonly HoleLibraryEntry[];
|
|
64
|
+
}
|
|
65
|
+
export interface HoleFillResult {
|
|
66
|
+
holeId: string;
|
|
67
|
+
outcome: FillPath | "already-filled";
|
|
68
|
+
/** Candidates tried, library included. */
|
|
69
|
+
tried: number;
|
|
70
|
+
/** Candidates the bans rejected before any test. */
|
|
71
|
+
banned: number;
|
|
72
|
+
model: string | null;
|
|
73
|
+
usage: {
|
|
74
|
+
inputTokens: number;
|
|
75
|
+
outputTokens: number;
|
|
76
|
+
model: string;
|
|
77
|
+
}[];
|
|
78
|
+
/** The runner's last lines when nothing was green — what a human reads first. */
|
|
79
|
+
lastRun: string[];
|
|
80
|
+
}
|
|
81
|
+
/** Fills ONE hole along D24's order; the body ends written (green) or back to `todo`. */
|
|
82
|
+
export declare function fillHole(input: HoleFillInput, deps: FillDeps, options?: FillOptions): Promise<HoleFillResult>;
|
|
83
|
+
export interface FeatureFillSummary {
|
|
84
|
+
featureId: string;
|
|
85
|
+
results: HoleFillResult[];
|
|
86
|
+
filled: number;
|
|
87
|
+
unfilled: number;
|
|
88
|
+
/** D24: more than one hole in ten reached escalation — the holes are too big, the spec splits them. */
|
|
89
|
+
holesTooBig: boolean;
|
|
90
|
+
usage: {
|
|
91
|
+
inputTokens: number;
|
|
92
|
+
outputTokens: number;
|
|
93
|
+
model: string;
|
|
94
|
+
}[];
|
|
95
|
+
}
|
|
96
|
+
/** Fills every `todo` hole of a feature, one after the other (one logic.ts, one test file). */
|
|
97
|
+
export declare function fillFeature(inputs: readonly HoleFillInput[], deps: FillDeps, options?: FillOptions): Promise<FeatureFillSummary>;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @intent The model half of the filling (D24): the `draw` and `escalate`
|
|
3
|
+
* models asked for a body on the SOLE `holes/<id>.gen.md` — the one context
|
|
4
|
+
* D23 allows — through the core's shared Messages client. The models are the
|
|
5
|
+
* package's single configuration (`models: { spec, escalate, draw }`), with
|
|
6
|
+
* D24's defaults, overridable by the command's flags; `draw` may name a local
|
|
7
|
+
* Ollama model behind an OpenAI-compatible base, which is the operator's
|
|
8
|
+
* call, not this module's.
|
|
9
|
+
*/
|
|
10
|
+
import type { ModelClient } from "@ogygie/core/model";
|
|
11
|
+
import type { Candidate } from "./fill.js";
|
|
12
|
+
export interface FillModels {
|
|
13
|
+
spec: string;
|
|
14
|
+
escalate: string;
|
|
15
|
+
draw: string;
|
|
16
|
+
}
|
|
17
|
+
/** D24's defaults. */
|
|
18
|
+
export declare const DEFAULT_FILL_MODELS: FillModels;
|
|
19
|
+
/** The stable instructions — cached by the model side; the hole's context is the user turn. */
|
|
20
|
+
export declare const HOLE_SYSTEM_PROMPT: string;
|
|
21
|
+
export interface ModelDrawer {
|
|
22
|
+
draw(context: string, n: number, round: number): Promise<Candidate[]>;
|
|
23
|
+
escalate(context: string): Promise<Candidate>;
|
|
24
|
+
}
|
|
25
|
+
export declare function createModelDrawer(client: ModelClient, models?: FillModels): ModelDrawer;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { HoleLibraryEntry } from "./hole-shape.js";
|
|
2
|
+
import type { FeaturePlan } from "./emit/plan.js";
|
|
3
|
+
export interface GeneratedFile {
|
|
4
|
+
/** Repo-relative path. */
|
|
5
|
+
path: string;
|
|
6
|
+
content: string;
|
|
7
|
+
}
|
|
8
|
+
export interface GenerateOptions {
|
|
9
|
+
/** The repo's current logic.ts, whose bodies survive when their signature is unchanged. */
|
|
10
|
+
existingLogic: string | null;
|
|
11
|
+
/** The repo's current migration of the feature, whose view bodies (D32) survive between their markers. */
|
|
12
|
+
existingMigration?: string | null;
|
|
13
|
+
/** The holes library: neighbours of the same shape in every holes/<id>.gen.md. */
|
|
14
|
+
library: readonly HoleLibraryEntry[];
|
|
15
|
+
}
|
|
16
|
+
/** File names, relative to the feature folder, every generated feature carries (besides its migration and logic.ts). */
|
|
17
|
+
export declare const GENERATED_FEATURE_FILES: readonly ["db.schema.gen.ts", "holes.runtime.gen.ts", "repository.gen.ts", "service.gen.ts", "routes.gen.ts", "index.ts", "factories.gen.ts", "routes.gen.test.ts", "behaviors.gen.test.ts", "holes.gen.test.ts"];
|
|
18
|
+
export declare function generateFeature(plan: FeaturePlan, options?: GenerateOptions): GeneratedFile[];
|
|
19
|
+
/**
|
|
20
|
+
* The migration file of a table: the one already there (`<n>_<table>.gen.sql`),
|
|
21
|
+
* or the next number after the existing migrations — stable across regenerations.
|
|
22
|
+
*/
|
|
23
|
+
export declare function migrationFileNameFor(existingFileNames: readonly string[], table: string): string;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @intent The deterministic half of a SCREEN generation (DECISIONS.md D40,
|
|
3
|
+
* D41, D43): from a screen plan, the list of files to write — path and
|
|
4
|
+
* content — in a fixed order, byte-identical for identical inputs. A custom
|
|
5
|
+
* view is regenerated AROUND its body (kept while its signature is unchanged);
|
|
6
|
+
* the BODY of the screen is not here: `screenBodyDefault` is written once by
|
|
7
|
+
* the generate command when the file is absent, and never compared (D40).
|
|
8
|
+
*/
|
|
9
|
+
import type { GeneratedFile } from "./generate-feature.js";
|
|
10
|
+
import type { ScreenPlan } from "./emit/screen-plan.js";
|
|
11
|
+
export interface GenerateScreenOptions {
|
|
12
|
+
/** The repo's current `views/<Vue>.tsx` of each custom view, by view id — whose body survives when its signature is unchanged. */
|
|
13
|
+
existingCustomViews: ReadonlyMap<string, string | null>;
|
|
14
|
+
}
|
|
15
|
+
/** The path of the written body of a screen, relative to the repo root. */
|
|
16
|
+
export declare function screenBodyPath(plan: ScreenPlan): string;
|
|
17
|
+
/** The written body, as the generator proposes it the first time (D40). */
|
|
18
|
+
export declare function screenBodyDefault(plan: ScreenPlan): string;
|
|
19
|
+
export declare function generateScreen(plan: ScreenPlan, options?: GenerateScreenOptions): GeneratedFile[];
|