@gordon.gan/specflow 1.5.0-beta → 1.8.0-alpha

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 (135) hide show
  1. package/README.md +4 -4
  2. package/dist/cli/commands/document-run.d.ts +84 -0
  3. package/dist/cli/commands/document-run.js +539 -0
  4. package/dist/cli/index.js +2 -2
  5. package/dist/core/artifact-language.js +11 -1
  6. package/dist/core/document/chapters.d.ts +6 -0
  7. package/dist/core/document/chapters.js +21 -0
  8. package/dist/core/document/coverage.d.ts +25 -0
  9. package/dist/core/document/coverage.js +49 -0
  10. package/dist/core/document/digests.d.ts +41 -0
  11. package/dist/core/document/digests.js +136 -0
  12. package/dist/core/document/engine.d.ts +92 -0
  13. package/dist/core/document/engine.js +487 -0
  14. package/dist/core/document/forbidden-patterns.d.ts +8 -0
  15. package/dist/core/document/forbidden-patterns.js +33 -0
  16. package/dist/core/document/gates.d.ts +27 -0
  17. package/dist/core/document/gates.js +33 -0
  18. package/dist/core/document/index.d.ts +7 -0
  19. package/dist/core/document/index.js +7 -0
  20. package/dist/core/document/input-digest.d.ts +55 -0
  21. package/dist/core/document/input-digest.js +121 -0
  22. package/dist/core/document/input-features.d.ts +24 -0
  23. package/dist/core/document/input-features.js +112 -0
  24. package/dist/core/document/lint.d.ts +22 -0
  25. package/dist/core/document/lint.js +29 -0
  26. package/dist/core/document/llm.d.ts +35 -0
  27. package/dist/core/document/llm.js +27 -0
  28. package/dist/core/document/map.d.ts +46 -0
  29. package/dist/core/document/map.js +212 -0
  30. package/dist/core/document/outline.d.ts +26 -0
  31. package/dist/core/document/outline.js +128 -0
  32. package/dist/core/document/paths.d.ts +23 -0
  33. package/dist/core/document/paths.js +31 -0
  34. package/dist/core/document/profile-validator.d.ts +23 -0
  35. package/dist/core/document/profile-validator.js +127 -0
  36. package/dist/core/document/profiles.d.ts +23 -0
  37. package/dist/core/document/profiles.js +69 -0
  38. package/dist/core/document/render.d.ts +19 -0
  39. package/dist/core/document/render.js +97 -0
  40. package/dist/core/document/review.d.ts +42 -0
  41. package/dist/core/document/review.js +157 -0
  42. package/dist/core/document/scene-detect.d.ts +25 -0
  43. package/dist/core/document/scene-detect.js +121 -0
  44. package/dist/core/document/schemas.d.ts +949 -0
  45. package/dist/core/document/schemas.js +158 -0
  46. package/dist/integrations/shared/capability-evidence.js +4 -6
  47. package/dist/integrations/shared/command-catalog.js +1 -1
  48. package/dist/integrations/shared/parity-manifest.js +4 -6
  49. package/package.json +2 -1
  50. package/prompts/apply/phase-a-plan.md +1 -1
  51. package/prompts/document/map/acceptance.md +8 -0
  52. package/prompts/document/map/api-design.md +17 -0
  53. package/prompts/document/map/architecture.md +7 -0
  54. package/prompts/document/map/closed-loop.md +8 -0
  55. package/prompts/document/map/compat-migration.md +8 -0
  56. package/prompts/document/map/config-runtime.md +8 -0
  57. package/prompts/document/map/core-logic.md +8 -0
  58. package/prompts/document/map/data-model.md +17 -0
  59. package/prompts/document/map/deploy.md +8 -0
  60. package/prompts/document/map/fix.md +7 -0
  61. package/prompts/document/map/goal.md +7 -0
  62. package/prompts/document/map/impact.md +7 -0
  63. package/prompts/document/map/implementability.md +8 -0
  64. package/prompts/document/map/mvp-boundary.md +7 -0
  65. package/prompts/document/map/non-goals.md +7 -0
  66. package/prompts/document/map/regression.md +7 -0
  67. package/prompts/document/map/reproduce.md +7 -0
  68. package/prompts/document/map/requirement.md +7 -0
  69. package/prompts/document/map/root-cause.md +7 -0
  70. package/prompts/document/map/signoff.md +8 -0
  71. package/prompts/document/map/tech-selection.md +17 -0
  72. package/prompts/document/map/test-strategy.md +7 -0
  73. package/prompts/document/map/ui-design.md +18 -0
  74. package/prompts/document/outline/general.md +37 -0
  75. package/prompts/document/review/ai-review.md +56 -0
  76. package/prompts/explore/explore-session.md +1 -1
  77. package/prompts/propose/design-draft.md +1 -1
  78. package/prompts/propose/proposal.md +1 -1
  79. package/prompts/propose/specs.md +1 -1
  80. package/prompts/propose/tasks-draft.md +1 -1
  81. package/prompts/refine/design-output.md +1 -1
  82. package/prompts/refine/update-artifacts.md +2 -0
  83. package/prompts/shared/artifact-language.md +13 -0
  84. package/skills/GUIDANCE_PACKS.md +1 -1
  85. package/skills/specflow-document/SKILL.md +124 -0
  86. package/templates/document/chapters/acceptance.yaml +16 -0
  87. package/templates/document/chapters/api-design.yaml +24 -0
  88. package/templates/document/chapters/architecture.yaml +18 -0
  89. package/templates/document/chapters/closed-loop.yaml +22 -0
  90. package/templates/document/chapters/compat-migration.yaml +17 -0
  91. package/templates/document/chapters/config-runtime.yaml +16 -0
  92. package/templates/document/chapters/core-logic.yaml +16 -0
  93. package/templates/document/chapters/data-model.yaml +25 -0
  94. package/templates/document/chapters/deploy.yaml +18 -0
  95. package/templates/document/chapters/fix.yaml +18 -0
  96. package/templates/document/chapters/goal.yaml +17 -0
  97. package/templates/document/chapters/impact.yaml +16 -0
  98. package/templates/document/chapters/implementability.yaml +22 -0
  99. package/templates/document/chapters/mvp-boundary.yaml +20 -0
  100. package/templates/document/chapters/non-goals.yaml +17 -0
  101. package/templates/document/chapters/regression.yaml +16 -0
  102. package/templates/document/chapters/reproduce.yaml +16 -0
  103. package/templates/document/chapters/requirement.yaml +18 -0
  104. package/templates/document/chapters/root-cause.yaml +18 -0
  105. package/templates/document/chapters/signoff.yaml +15 -0
  106. package/templates/document/chapters/tech-selection.yaml +20 -0
  107. package/templates/document/chapters/test-strategy.yaml +20 -0
  108. package/templates/document/chapters/ui-design.yaml +22 -0
  109. package/templates/document/profiles/0to1.yaml +12 -0
  110. package/templates/document/profiles/approve.yaml +22 -0
  111. package/templates/document/profiles/bugfix.yaml +10 -0
  112. package/templates/document/profiles/feature.yaml +11 -0
  113. package/dist/cli/commands/approval-assemble.d.ts +0 -21
  114. package/dist/cli/commands/approval-assemble.js +0 -95
  115. package/dist/core/approval/assemble.d.ts +0 -10
  116. package/dist/core/approval/assemble.js +0 -391
  117. package/dist/core/approval/index-schema.d.ts +0 -473
  118. package/dist/core/approval/index-schema.js +0 -146
  119. package/dist/core/approval/index.d.ts +0 -4
  120. package/dist/core/approval/index.js +0 -3
  121. package/dist/core/approval/paths.d.ts +0 -8
  122. package/dist/core/approval/paths.js +0 -28
  123. package/dist/core/approval/types.d.ts +0 -120
  124. package/dist/core/approval/types.js +0 -1
  125. package/prompts/approval/api-guidance.md +0 -179
  126. package/prompts/approval/database-guidance.md +0 -105
  127. package/prompts/approval/frontend-guidance.md +0 -249
  128. package/prompts/approval/generate.md +0 -1498
  129. package/prompts/approval/multi-repo-guidance.md +0 -202
  130. package/prompts/approval/project-conventions-guidance.md +0 -171
  131. package/prompts/approval/segmented-generation.md +0 -151
  132. package/skills/specflow-approval/SKILL.md +0 -640
  133. package/templates/approval-index.yaml +0 -72
  134. package/templates/approval-part.md +0 -15
  135. package/templates/approval.md +0 -261
@@ -1,473 +0,0 @@
1
- import { z } from 'zod';
2
- import type { ApprovalIndex } from './types.js';
3
- export declare const approvalIndexSchema: z.ZodObject<{
4
- schema: z.ZodLiteral<"specflow.approval.index/v1">;
5
- change: z.ZodString;
6
- generated_at: z.ZodEffects<z.ZodString, string, unknown>;
7
- mode: z.ZodDefault<z.ZodEnum<["segmented", "monolithic"]>>;
8
- ui_in_scope: z.ZodDefault<z.ZodBoolean>;
9
- db_in_scope: z.ZodDefault<z.ZodBoolean>;
10
- api_in_scope: z.ZodDefault<z.ZodBoolean>;
11
- optional: z.ZodDefault<z.ZodObject<{
12
- s5: z.ZodDefault<z.ZodBoolean>;
13
- s7: z.ZodDefault<z.ZodBoolean>;
14
- s8: z.ZodDefault<z.ZodBoolean>;
15
- }, "strip", z.ZodTypeAny, {
16
- s5: boolean;
17
- s7: boolean;
18
- s8: boolean;
19
- }, {
20
- s5?: boolean | undefined;
21
- s7?: boolean | undefined;
22
- s8?: boolean | undefined;
23
- }>>;
24
- parts_order: z.ZodArray<z.ZodString, "many">;
25
- design_points: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
26
- decisions: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
27
- tables: z.ZodDefault<z.ZodArray<z.ZodObject<{
28
- id: z.ZodString;
29
- name: z.ZodString;
30
- action: z.ZodString;
31
- part: z.ZodString;
32
- repo: z.ZodOptional<z.ZodString>;
33
- }, "strip", z.ZodTypeAny, {
34
- id: string;
35
- name: string;
36
- action: string;
37
- part: string;
38
- repo?: string | undefined;
39
- }, {
40
- id: string;
41
- name: string;
42
- action: string;
43
- part: string;
44
- repo?: string | undefined;
45
- }>, "many">>;
46
- interfaces: z.ZodDefault<z.ZodArray<z.ZodObject<{
47
- id: z.ZodString;
48
- short: z.ZodString;
49
- change: z.ZodString;
50
- part: z.ZodString;
51
- repo: z.ZodOptional<z.ZodString>;
52
- }, "strip", z.ZodTypeAny, {
53
- id: string;
54
- part: string;
55
- short: string;
56
- change: string;
57
- repo?: string | undefined;
58
- }, {
59
- id: string;
60
- part: string;
61
- short: string;
62
- change: string;
63
- repo?: string | undefined;
64
- }>, "many">>;
65
- pages: z.ZodDefault<z.ZodArray<z.ZodObject<{
66
- id: z.ZodString;
67
- route: z.ZodString;
68
- apis: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
69
- part: z.ZodString;
70
- repo: z.ZodOptional<z.ZodString>;
71
- }, "strip", z.ZodTypeAny, {
72
- id: string;
73
- part: string;
74
- route: string;
75
- apis: string[];
76
- repo?: string | undefined;
77
- }, {
78
- id: string;
79
- part: string;
80
- route: string;
81
- repo?: string | undefined;
82
- apis?: string[] | undefined;
83
- }>, "many">>;
84
- capabilities: z.ZodDefault<z.ZodArray<z.ZodObject<{
85
- id: z.ZodString;
86
- part: z.ZodString;
87
- }, "strip", z.ZodTypeAny, {
88
- id: string;
89
- part: string;
90
- }, {
91
- id: string;
92
- part: string;
93
- }>, "many">>;
94
- batching: z.ZodDefault<z.ZodObject<{
95
- tables_per_call: z.ZodDefault<z.ZodNumber>;
96
- interfaces_per_call: z.ZodDefault<z.ZodNumber>;
97
- pages_per_call: z.ZodDefault<z.ZodNumber>;
98
- capabilities_per_call: z.ZodDefault<z.ZodNumber>;
99
- }, "strip", z.ZodTypeAny, {
100
- tables_per_call: number;
101
- interfaces_per_call: number;
102
- pages_per_call: number;
103
- capabilities_per_call: number;
104
- }, {
105
- tables_per_call?: number | undefined;
106
- interfaces_per_call?: number | undefined;
107
- pages_per_call?: number | undefined;
108
- capabilities_per_call?: number | undefined;
109
- }>>;
110
- conventions: z.ZodDefault<z.ZodObject<{
111
- architecture: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
112
- database: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
113
- api: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
114
- frontend: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
115
- }, "strip", z.ZodTypeAny, {
116
- architecture?: string[] | undefined;
117
- api?: string[] | undefined;
118
- database?: string[] | undefined;
119
- frontend?: string[] | undefined;
120
- }, {
121
- architecture?: string[] | undefined;
122
- api?: string[] | undefined;
123
- database?: string[] | undefined;
124
- frontend?: string[] | undefined;
125
- }>>;
126
- meta: z.ZodOptional<z.ZodObject<{
127
- language: z.ZodOptional<z.ZodString>;
128
- tech_stack: z.ZodOptional<z.ZodString>;
129
- project_mode: z.ZodOptional<z.ZodString>;
130
- }, "strip", z.ZodTypeAny, {
131
- language?: string | undefined;
132
- tech_stack?: string | undefined;
133
- project_mode?: string | undefined;
134
- }, {
135
- language?: string | undefined;
136
- tech_stack?: string | undefined;
137
- project_mode?: string | undefined;
138
- }>>;
139
- multi_repo: z.ZodOptional<z.ZodEffects<z.ZodObject<{
140
- enabled: z.ZodBoolean;
141
- document_mode: z.ZodOptional<z.ZodEnum<["unified", "per_repo"]>>;
142
- primary_repo: z.ZodOptional<z.ZodString>;
143
- repos: z.ZodArray<z.ZodObject<{
144
- id: z.ZodString;
145
- label: z.ZodString;
146
- role: z.ZodOptional<z.ZodEnum<["platform", "web", "worker", "hub", "other"]>>;
147
- change: z.ZodString;
148
- root_hint: z.ZodOptional<z.ZodString>;
149
- }, "strip", z.ZodTypeAny, {
150
- id: string;
151
- change: string;
152
- label: string;
153
- role?: "platform" | "web" | "worker" | "hub" | "other" | undefined;
154
- root_hint?: string | undefined;
155
- }, {
156
- id: string;
157
- change: string;
158
- label: string;
159
- role?: "platform" | "web" | "worker" | "hub" | "other" | undefined;
160
- root_hint?: string | undefined;
161
- }>, "many">;
162
- outputs: z.ZodOptional<z.ZodObject<{
163
- unified: z.ZodOptional<z.ZodObject<{
164
- repo: z.ZodString;
165
- change: z.ZodString;
166
- path: z.ZodString;
167
- }, "strip", z.ZodTypeAny, {
168
- path: string;
169
- repo: string;
170
- change: string;
171
- }, {
172
- path: string;
173
- repo: string;
174
- change: string;
175
- }>>;
176
- per_repo: z.ZodOptional<z.ZodArray<z.ZodObject<{
177
- repo: z.ZodString;
178
- change: z.ZodString;
179
- path: z.ZodString;
180
- }, "strip", z.ZodTypeAny, {
181
- path: string;
182
- repo: string;
183
- change: string;
184
- }, {
185
- path: string;
186
- repo: string;
187
- change: string;
188
- }>, "many">>;
189
- }, "strip", z.ZodTypeAny, {
190
- unified?: {
191
- path: string;
192
- repo: string;
193
- change: string;
194
- } | undefined;
195
- per_repo?: {
196
- path: string;
197
- repo: string;
198
- change: string;
199
- }[] | undefined;
200
- }, {
201
- unified?: {
202
- path: string;
203
- repo: string;
204
- change: string;
205
- } | undefined;
206
- per_repo?: {
207
- path: string;
208
- repo: string;
209
- change: string;
210
- }[] | undefined;
211
- }>>;
212
- }, "strip", z.ZodTypeAny, {
213
- enabled: boolean;
214
- repos: {
215
- id: string;
216
- change: string;
217
- label: string;
218
- role?: "platform" | "web" | "worker" | "hub" | "other" | undefined;
219
- root_hint?: string | undefined;
220
- }[];
221
- document_mode?: "unified" | "per_repo" | undefined;
222
- primary_repo?: string | undefined;
223
- outputs?: {
224
- unified?: {
225
- path: string;
226
- repo: string;
227
- change: string;
228
- } | undefined;
229
- per_repo?: {
230
- path: string;
231
- repo: string;
232
- change: string;
233
- }[] | undefined;
234
- } | undefined;
235
- }, {
236
- enabled: boolean;
237
- repos: {
238
- id: string;
239
- change: string;
240
- label: string;
241
- role?: "platform" | "web" | "worker" | "hub" | "other" | undefined;
242
- root_hint?: string | undefined;
243
- }[];
244
- document_mode?: "unified" | "per_repo" | undefined;
245
- primary_repo?: string | undefined;
246
- outputs?: {
247
- unified?: {
248
- path: string;
249
- repo: string;
250
- change: string;
251
- } | undefined;
252
- per_repo?: {
253
- path: string;
254
- repo: string;
255
- change: string;
256
- }[] | undefined;
257
- } | undefined;
258
- }>, {
259
- enabled: boolean;
260
- repos: {
261
- id: string;
262
- change: string;
263
- label: string;
264
- role?: "platform" | "web" | "worker" | "hub" | "other" | undefined;
265
- root_hint?: string | undefined;
266
- }[];
267
- document_mode?: "unified" | "per_repo" | undefined;
268
- primary_repo?: string | undefined;
269
- outputs?: {
270
- unified?: {
271
- path: string;
272
- repo: string;
273
- change: string;
274
- } | undefined;
275
- per_repo?: {
276
- path: string;
277
- repo: string;
278
- change: string;
279
- }[] | undefined;
280
- } | undefined;
281
- }, {
282
- enabled: boolean;
283
- repos: {
284
- id: string;
285
- change: string;
286
- label: string;
287
- role?: "platform" | "web" | "worker" | "hub" | "other" | undefined;
288
- root_hint?: string | undefined;
289
- }[];
290
- document_mode?: "unified" | "per_repo" | undefined;
291
- primary_repo?: string | undefined;
292
- outputs?: {
293
- unified?: {
294
- path: string;
295
- repo: string;
296
- change: string;
297
- } | undefined;
298
- per_repo?: {
299
- path: string;
300
- repo: string;
301
- change: string;
302
- }[] | undefined;
303
- } | undefined;
304
- }>>;
305
- }, "strip", z.ZodTypeAny, {
306
- schema: "specflow.approval.index/v1";
307
- conventions: {
308
- architecture?: string[] | undefined;
309
- api?: string[] | undefined;
310
- database?: string[] | undefined;
311
- frontend?: string[] | undefined;
312
- };
313
- change: string;
314
- generated_at: string;
315
- mode: "segmented" | "monolithic";
316
- ui_in_scope: boolean;
317
- db_in_scope: boolean;
318
- api_in_scope: boolean;
319
- optional: {
320
- s5: boolean;
321
- s7: boolean;
322
- s8: boolean;
323
- };
324
- parts_order: string[];
325
- design_points: string[];
326
- decisions: string[];
327
- tables: {
328
- id: string;
329
- name: string;
330
- action: string;
331
- part: string;
332
- repo?: string | undefined;
333
- }[];
334
- interfaces: {
335
- id: string;
336
- part: string;
337
- short: string;
338
- change: string;
339
- repo?: string | undefined;
340
- }[];
341
- pages: {
342
- id: string;
343
- part: string;
344
- route: string;
345
- apis: string[];
346
- repo?: string | undefined;
347
- }[];
348
- capabilities: {
349
- id: string;
350
- part: string;
351
- }[];
352
- batching: {
353
- tables_per_call: number;
354
- interfaces_per_call: number;
355
- pages_per_call: number;
356
- capabilities_per_call: number;
357
- };
358
- meta?: {
359
- language?: string | undefined;
360
- tech_stack?: string | undefined;
361
- project_mode?: string | undefined;
362
- } | undefined;
363
- multi_repo?: {
364
- enabled: boolean;
365
- repos: {
366
- id: string;
367
- change: string;
368
- label: string;
369
- role?: "platform" | "web" | "worker" | "hub" | "other" | undefined;
370
- root_hint?: string | undefined;
371
- }[];
372
- document_mode?: "unified" | "per_repo" | undefined;
373
- primary_repo?: string | undefined;
374
- outputs?: {
375
- unified?: {
376
- path: string;
377
- repo: string;
378
- change: string;
379
- } | undefined;
380
- per_repo?: {
381
- path: string;
382
- repo: string;
383
- change: string;
384
- }[] | undefined;
385
- } | undefined;
386
- } | undefined;
387
- }, {
388
- schema: "specflow.approval.index/v1";
389
- change: string;
390
- parts_order: string[];
391
- conventions?: {
392
- architecture?: string[] | undefined;
393
- api?: string[] | undefined;
394
- database?: string[] | undefined;
395
- frontend?: string[] | undefined;
396
- } | undefined;
397
- generated_at?: unknown;
398
- mode?: "segmented" | "monolithic" | undefined;
399
- ui_in_scope?: boolean | undefined;
400
- db_in_scope?: boolean | undefined;
401
- api_in_scope?: boolean | undefined;
402
- optional?: {
403
- s5?: boolean | undefined;
404
- s7?: boolean | undefined;
405
- s8?: boolean | undefined;
406
- } | undefined;
407
- design_points?: string[] | undefined;
408
- decisions?: string[] | undefined;
409
- tables?: {
410
- id: string;
411
- name: string;
412
- action: string;
413
- part: string;
414
- repo?: string | undefined;
415
- }[] | undefined;
416
- interfaces?: {
417
- id: string;
418
- part: string;
419
- short: string;
420
- change: string;
421
- repo?: string | undefined;
422
- }[] | undefined;
423
- pages?: {
424
- id: string;
425
- part: string;
426
- route: string;
427
- repo?: string | undefined;
428
- apis?: string[] | undefined;
429
- }[] | undefined;
430
- capabilities?: {
431
- id: string;
432
- part: string;
433
- }[] | undefined;
434
- batching?: {
435
- tables_per_call?: number | undefined;
436
- interfaces_per_call?: number | undefined;
437
- pages_per_call?: number | undefined;
438
- capabilities_per_call?: number | undefined;
439
- } | undefined;
440
- meta?: {
441
- language?: string | undefined;
442
- tech_stack?: string | undefined;
443
- project_mode?: string | undefined;
444
- } | undefined;
445
- multi_repo?: {
446
- enabled: boolean;
447
- repos: {
448
- id: string;
449
- change: string;
450
- label: string;
451
- role?: "platform" | "web" | "worker" | "hub" | "other" | undefined;
452
- root_hint?: string | undefined;
453
- }[];
454
- document_mode?: "unified" | "per_repo" | undefined;
455
- primary_repo?: string | undefined;
456
- outputs?: {
457
- unified?: {
458
- path: string;
459
- repo: string;
460
- change: string;
461
- } | undefined;
462
- per_repo?: {
463
- path: string;
464
- repo: string;
465
- change: string;
466
- }[] | undefined;
467
- } | undefined;
468
- } | undefined;
469
- }>;
470
- export declare function parseApprovalIndex(raw: unknown): ApprovalIndex;
471
- /** Returns true when segmented fast-path (monolithic) is allowed. */
472
- export declare function isLightweightApproval(index: ApprovalIndex): boolean;
473
- export declare function shouldForceSegmented(index: ApprovalIndex): boolean;
@@ -1,146 +0,0 @@
1
- import { z } from 'zod';
2
- const tableRefSchema = z.object({
3
- id: z.string().min(1),
4
- name: z.string().min(1),
5
- action: z.string().min(1),
6
- part: z.string().min(1),
7
- repo: z.string().min(1).optional(),
8
- });
9
- const interfaceRefSchema = z.object({
10
- id: z.string().min(1),
11
- short: z.string().min(1),
12
- change: z.string().min(1),
13
- part: z.string().min(1),
14
- repo: z.string().min(1).optional(),
15
- });
16
- const pageRefSchema = z.object({
17
- id: z.string().min(1),
18
- route: z.string().min(1),
19
- apis: z.array(z.string()).default([]),
20
- part: z.string().min(1),
21
- repo: z.string().min(1).optional(),
22
- });
23
- const capabilityRefSchema = z.object({
24
- id: z.string().min(1),
25
- part: z.string().min(1),
26
- });
27
- const outputRefSchema = z.object({
28
- repo: z.string().min(1),
29
- change: z.string().min(1),
30
- path: z.string().min(1),
31
- });
32
- const multiRepoSchema = z
33
- .object({
34
- enabled: z.boolean(),
35
- document_mode: z.enum(['unified', 'per_repo']).optional(),
36
- primary_repo: z.string().min(1).optional(),
37
- repos: z
38
- .array(z.object({
39
- id: z.string().min(1),
40
- label: z.string().min(1),
41
- role: z.enum(['platform', 'web', 'worker', 'hub', 'other']).optional(),
42
- change: z.string().min(1),
43
- root_hint: z.string().min(1).optional(),
44
- }))
45
- .min(1),
46
- outputs: z
47
- .object({
48
- unified: outputRefSchema.optional(),
49
- per_repo: z.array(outputRefSchema).optional(),
50
- })
51
- .optional(),
52
- })
53
- .superRefine((value, ctx) => {
54
- if (!value.enabled) {
55
- return;
56
- }
57
- if (value.repos.length < 2) {
58
- ctx.addIssue({
59
- code: z.ZodIssueCode.custom,
60
- message: 'multi_repo.repos must have at least 2 entries when enabled',
61
- path: ['repos'],
62
- });
63
- }
64
- if (value.document_mode === 'unified' && !value.primary_repo) {
65
- ctx.addIssue({
66
- code: z.ZodIssueCode.custom,
67
- message: 'multi_repo.primary_repo is required when document_mode is unified',
68
- path: ['primary_repo'],
69
- });
70
- }
71
- if (value.primary_repo && !value.repos.some((r) => r.id === value.primary_repo)) {
72
- ctx.addIssue({
73
- code: z.ZodIssueCode.custom,
74
- message: 'multi_repo.primary_repo must match a repos[].id',
75
- path: ['primary_repo'],
76
- });
77
- }
78
- });
79
- export const approvalIndexSchema = z.object({
80
- schema: z.literal('specflow.approval.index/v1'),
81
- change: z.string().min(1),
82
- generated_at: z.preprocess((val) => (val instanceof Date ? val.toISOString() : val), z.string().min(1)),
83
- mode: z.enum(['segmented', 'monolithic']).default('segmented'),
84
- ui_in_scope: z.boolean().default(false),
85
- db_in_scope: z.boolean().default(false),
86
- api_in_scope: z.boolean().default(false),
87
- optional: z
88
- .object({
89
- s5: z.boolean().default(false),
90
- s7: z.boolean().default(false),
91
- s8: z.boolean().default(false),
92
- })
93
- .default({ s5: false, s7: false, s8: false }),
94
- parts_order: z.array(z.string().min(1)).min(1),
95
- design_points: z.array(z.string()).default([]),
96
- decisions: z.array(z.string()).default([]),
97
- tables: z.array(tableRefSchema).default([]),
98
- interfaces: z.array(interfaceRefSchema).default([]),
99
- pages: z.array(pageRefSchema).default([]),
100
- capabilities: z.array(capabilityRefSchema).default([]),
101
- batching: z
102
- .object({
103
- tables_per_call: z.number().int().positive().default(3),
104
- interfaces_per_call: z.number().int().positive().default(3),
105
- pages_per_call: z.number().int().positive().default(3),
106
- capabilities_per_call: z.number().int().positive().default(1),
107
- })
108
- .default({
109
- tables_per_call: 3,
110
- interfaces_per_call: 3,
111
- pages_per_call: 3,
112
- capabilities_per_call: 1,
113
- }),
114
- conventions: z
115
- .object({
116
- architecture: z.array(z.string()).optional(),
117
- database: z.array(z.string()).optional(),
118
- api: z.array(z.string()).optional(),
119
- frontend: z.array(z.string()).optional(),
120
- })
121
- .default({}),
122
- meta: z
123
- .object({
124
- language: z.string().optional(),
125
- tech_stack: z.string().optional(),
126
- project_mode: z.string().optional(),
127
- })
128
- .optional(),
129
- multi_repo: multiRepoSchema.optional(),
130
- });
131
- export function parseApprovalIndex(raw) {
132
- return approvalIndexSchema.parse(raw);
133
- }
134
- /** Returns true when segmented fast-path (monolithic) is allowed. */
135
- export function isLightweightApproval(index) {
136
- return (index.tables.length <= 2 &&
137
- index.interfaces.length <= 3 &&
138
- index.pages.length <= 2 &&
139
- !index.optional.s5);
140
- }
141
- export function shouldForceSegmented(index) {
142
- if (index.mode === 'monolithic') {
143
- return false;
144
- }
145
- return !isLightweightApproval(index);
146
- }
@@ -1,4 +0,0 @@
1
- export type { ApprovalAssembleResult, ApprovalDiagnostic, ApprovalIndex, ApprovalManifest, ApprovalGenerationMode, ApprovalMultiRepo, ApprovalDocumentMode, } from './types.js';
2
- export { parseApprovalIndex, isLightweightApproval, shouldForceSegmented, approvalIndexSchema, } from './index-schema.js';
3
- export { getChangeDirectory, getApprovalWorkspaceDir, getApprovalIndexPath, getApprovalManifestPath, getApprovalPartsDir, getApprovalPartPath, getApprovalOutputPath, getApprovalAnalysisPath, } from './paths.js';
4
- export { assembleApprovalDocument, readApprovalIndex, readApprovalManifest, } from './assemble.js';
@@ -1,3 +0,0 @@
1
- export { parseApprovalIndex, isLightweightApproval, shouldForceSegmented, approvalIndexSchema, } from './index-schema.js';
2
- export { getChangeDirectory, getApprovalWorkspaceDir, getApprovalIndexPath, getApprovalManifestPath, getApprovalPartsDir, getApprovalPartPath, getApprovalOutputPath, getApprovalAnalysisPath, } from './paths.js';
3
- export { assembleApprovalDocument, readApprovalIndex, readApprovalManifest, } from './assemble.js';
@@ -1,8 +0,0 @@
1
- export declare function getChangeDirectory(projectRoot: string, changeName: string): string;
2
- export declare function getApprovalWorkspaceDir(changeDir: string): string;
3
- export declare function getApprovalIndexPath(changeDir: string): string;
4
- export declare function getApprovalManifestPath(changeDir: string): string;
5
- export declare function getApprovalPartsDir(changeDir: string): string;
6
- export declare function getApprovalPartPath(changeDir: string, partId: string): string;
7
- export declare function getApprovalOutputPath(changeDir: string): string;
8
- export declare function getApprovalAnalysisPath(changeDir: string): string;
@@ -1,28 +0,0 @@
1
- import { join } from 'node:path';
2
- import { validateChangeName } from '../../utils/change-utils.js';
3
- const CHANGES_REL = 'specflow/changes';
4
- export function getChangeDirectory(projectRoot, changeName) {
5
- validateChangeName(changeName);
6
- return join(projectRoot, CHANGES_REL, changeName);
7
- }
8
- export function getApprovalWorkspaceDir(changeDir) {
9
- return join(changeDir, 'approval');
10
- }
11
- export function getApprovalIndexPath(changeDir) {
12
- return join(getApprovalWorkspaceDir(changeDir), 'index.yaml');
13
- }
14
- export function getApprovalManifestPath(changeDir) {
15
- return join(getApprovalWorkspaceDir(changeDir), 'manifest.json');
16
- }
17
- export function getApprovalPartsDir(changeDir) {
18
- return join(getApprovalWorkspaceDir(changeDir), 'parts');
19
- }
20
- export function getApprovalPartPath(changeDir, partId) {
21
- return join(getApprovalPartsDir(changeDir), `${partId}.md`);
22
- }
23
- export function getApprovalOutputPath(changeDir) {
24
- return join(changeDir, 'approval.md');
25
- }
26
- export function getApprovalAnalysisPath(changeDir) {
27
- return join(getApprovalWorkspaceDir(changeDir), 'analysis.json');
28
- }