qfai 1.9.0 → 1.9.1
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/assets/init/.qfai/assistant/agents/requirements-analyst.md +6 -0
- package/assets/init/.qfai/assistant/manifest/agent-catalog.yml +13 -46
- package/assets/init/.qfai/assistant/skills/qfai-prototyping/SKILL.md +60 -55
- package/assets/init/.qfai/assistant/skills/qfai-prototyping/references/generator-prompt.md +96 -6
- package/assets/init/.qfai/assistant/skills/qfai-sdd/templates/contracts/ui-contract.sample.yaml +4 -0
- package/dist/cli/index.cjs +2596 -779
- package/dist/cli/index.cjs.map +1 -1
- package/dist/cli/index.mjs +2473 -644
- package/dist/cli/index.mjs.map +1 -1
- package/dist/index.cjs +283 -75
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +9 -3
- package/dist/index.d.ts +9 -3
- package/dist/index.mjs +283 -75
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -1
|
@@ -33,6 +33,12 @@ tools: [Read, Write, Edit, Glob, Grep, Bash]
|
|
|
33
33
|
- Option set with recommendation and rejected rationale
|
|
34
34
|
- Open questions with owner, decision point, and safe deferral notes
|
|
35
35
|
- Mapping from requirements to impacted artifacts
|
|
36
|
+
- For UI-bearing surfaces: every entry in the UI contract `screens[]` must
|
|
37
|
+
carry at least one `primary_task` (≥ 1 primary_task per screen). The
|
|
38
|
+
shipped `ui-contract.sample.yaml` template exposes a `primary_tasks: []`
|
|
39
|
+
placeholder slot; populate it before handing the contract to the
|
|
40
|
+
prototyping phase. Empty `primary_tasks` arrays cause the
|
|
41
|
+
QFAI-AUD-001 aligned validate lane to block `/qfai-prototyping`.
|
|
36
42
|
|
|
37
43
|
## Stop conditions
|
|
38
44
|
|
|
@@ -366,95 +366,62 @@ agents:
|
|
|
366
366
|
- requirements-analyst
|
|
367
367
|
- oq-harvester
|
|
368
368
|
- option-explorer
|
|
369
|
-
developer_instructions:
|
|
369
|
+
developer_instructions: |-
|
|
370
370
|
## Mission
|
|
371
371
|
|
|
372
|
-
|
|
373
|
-
- Convert discussions into testable requirements, explicit open questions,
|
|
374
|
-
and option sets with acceptance signals.
|
|
375
|
-
|
|
372
|
+
- Convert discussions into testable requirements, explicit open questions, and option sets with acceptance signals.
|
|
376
373
|
|
|
377
374
|
## Domain Responsibilities
|
|
378
375
|
|
|
379
|
-
|
|
380
|
-
- Translate stakeholder intent into requirement statements and acceptance
|
|
381
|
-
signals.
|
|
382
|
-
|
|
376
|
+
- Translate stakeholder intent into requirement statements and acceptance signals.
|
|
383
377
|
- Harvest undefined decisions and maintain the OQ backlog.
|
|
384
|
-
|
|
385
378
|
- Produce multiple solution options with a recommendation.
|
|
386
|
-
|
|
387
379
|
- Map requirements to impacted downstream artifacts.
|
|
388
380
|
|
|
389
|
-
|
|
390
381
|
## Inputs you must read
|
|
391
382
|
|
|
392
|
-
|
|
393
383
|
- .qfai/assistant/constitution/\*\*
|
|
394
|
-
|
|
395
384
|
- .qfai/assistant/{manifest,catalog}/\*\*
|
|
396
|
-
|
|
397
385
|
- .qfai/specs/spec-\*/09_delta.md
|
|
398
|
-
|
|
399
386
|
- .qfai/discussion/discussion-\*/04_Sources.md
|
|
400
|
-
|
|
401
387
|
- .qfai/discussion/discussion-\*/06_REQ.md
|
|
402
|
-
|
|
403
388
|
- .qfai/discussion/discussion-\*/11_OQ-Register.md
|
|
404
|
-
|
|
405
389
|
- Discussion records under `.qfai/discussion/`
|
|
406
390
|
|
|
407
|
-
|
|
408
391
|
## Deliverables
|
|
409
392
|
|
|
410
|
-
|
|
411
393
|
- Requirements list with acceptance signals
|
|
412
|
-
|
|
413
394
|
- Option set with recommendation and rejected rationale
|
|
414
|
-
|
|
415
395
|
- Open questions with owner, decision point, and safe deferral notes
|
|
416
|
-
|
|
417
396
|
- Mapping from requirements to impacted artifacts
|
|
418
|
-
|
|
397
|
+
- For UI-bearing surfaces: every entry in the UI contract `screens[]` must
|
|
398
|
+
carry at least one `primary_task` (≥ 1 primary_task per screen). The
|
|
399
|
+
shipped `ui-contract.sample.yaml` template exposes a `primary_tasks: []`
|
|
400
|
+
placeholder slot; populate it before handing the contract to the
|
|
401
|
+
prototyping phase. Empty `primary_tasks` arrays cause the
|
|
402
|
+
QFAI-AUD-001 aligned validate lane to block `/qfai-prototyping`.
|
|
419
403
|
|
|
420
404
|
## Stop conditions
|
|
421
405
|
|
|
422
|
-
|
|
423
|
-
-
|
|
424
|
-
missing.
|
|
425
|
-
|
|
426
|
-
- The requested output belongs to another specialist's ownership without
|
|
427
|
-
an explicit handoff.
|
|
428
|
-
|
|
406
|
+
- Governing specs, routing rules, or required source artifacts are missing.
|
|
407
|
+
- The requested output belongs to another specialist's ownership without an explicit handoff.
|
|
429
408
|
- The task would bypass required validation or reviewer gates.
|
|
430
409
|
|
|
431
|
-
|
|
432
410
|
## Sign-off
|
|
433
411
|
|
|
434
|
-
|
|
435
412
|
- [ ] Deliverables are complete
|
|
436
|
-
|
|
437
413
|
- [ ] Ownership boundaries were respected
|
|
438
|
-
|
|
439
414
|
- [ ] Required gates and follow-up evidence are recorded
|
|
440
415
|
|
|
441
|
-
|
|
442
416
|
## When to use
|
|
443
417
|
|
|
444
|
-
|
|
445
418
|
- Use when `agent-routing.yml` assigns this domain to the current phase.
|
|
446
|
-
|
|
447
419
|
- Use when the task needs this specialist's owned artifacts or decisions.
|
|
448
420
|
|
|
449
|
-
|
|
450
421
|
## When not to use
|
|
451
422
|
|
|
452
|
-
|
|
453
|
-
- Do not use when
|
|
454
|
-
instead.
|
|
455
|
-
|
|
456
|
-
- Do not use when another specialist owns the main artifact or decision
|
|
457
|
-
surface.
|
|
423
|
+
- Do not use when the task is primarily review-only and needs a reviewer instead.
|
|
424
|
+
- Do not use when another specialist owns the main artifact or decision surface.
|
|
458
425
|
- id: solution-architect
|
|
459
426
|
kind: worker
|
|
460
427
|
domain: architecture
|
|
@@ -15,14 +15,11 @@ mode: execution-focused
|
|
|
15
15
|
|
|
16
16
|
This skill is static-first and file-based by default: it runs every
|
|
17
17
|
UI-bearing spec resolved at cycle 0 through up to 10 iterations against
|
|
18
|
-
a frozen brand SSOT (`DESIGN.md`) and a frozen spec set,
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
UI prototyping surfaces are: web, mobile, desktop, mixed. cli is not a
|
|
24
|
-
prototyping execution target and is rejected. ui_bearing: false specs
|
|
25
|
-
are not prototyping execution targets and are excluded.
|
|
18
|
+
a frozen brand SSOT (`DESIGN.md`) and a frozen spec set, one lineage per
|
|
19
|
+
`spec × screen` pair, no parallel candidates, no mode, fixed 10-cycle
|
|
20
|
+
budget. Supported surfaces: web, mobile, desktop, mixed. cli surface is
|
|
21
|
+
rejected and `ui_bearing: false` specs are excluded from prototyping
|
|
22
|
+
execution.
|
|
26
23
|
|
|
27
24
|
## Goal
|
|
28
25
|
|
|
@@ -58,23 +55,13 @@ current `DESIGN.md` hash does not match the lock.
|
|
|
58
55
|
|
|
59
56
|
### Step 2-A — Verify Contract Preconditions
|
|
60
57
|
|
|
61
|
-
- The skill resolves **every UI-bearing spec in
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
frontmatter signal + the matching `.qfai/contracts/ui/<spec-id>*.yaml`
|
|
69
|
-
contract fallback) and folds in the legacy `# … prototyping …`
|
|
70
|
-
title-marker fallback and the operator-pinned spec id from the
|
|
71
|
-
`qfai.config.yaml` `prototyping` section (run
|
|
72
|
-
`qfai doctor --profile prototyping` to surface the resolved value).
|
|
73
|
-
Operators authoring CHG-002-shaped projects can rely on the strict
|
|
74
|
-
frontmatter alone; the broader composition covers legacy /
|
|
75
|
-
config-pinned consumers.
|
|
76
|
-
The operator is never prompted to pick a single spec; zero
|
|
77
|
-
UI-bearing specs at cycle 0 is a deterministic no-op exit `0`.
|
|
58
|
+
- The skill resolves **every UI-bearing spec in one invocation** via
|
|
59
|
+
`resolveAllUiBearingSpecs()` (`core/prototyping/specResolution.ts`):
|
|
60
|
+
strict `surface_type: ui-bearing` frontmatter + matching
|
|
61
|
+
`.qfai/contracts/ui/<spec-id>*.yaml`, with legacy title-marker and
|
|
62
|
+
`qfai.config.yaml` `prototyping` pinning folded in. Run
|
|
63
|
+
`qfai doctor --profile prototyping` to surface the resolved value.
|
|
64
|
+
Zero UI-bearing specs at cycle 0 is a deterministic no-op exit `0`.
|
|
78
65
|
Confirm each resolved spec has a supported `surface`.
|
|
79
66
|
- Confirm root `DESIGN.md` and `.qfai/contracts/design/DESIGN.md.lock.yaml`
|
|
80
67
|
both exist; confirm `.qfai/contracts/ui/*.yaml` exists.
|
|
@@ -85,8 +72,29 @@ current `DESIGN.md` hash does not match the lock.
|
|
|
85
72
|
### Step 2-B — Verify Environment Preconditions
|
|
86
73
|
|
|
87
74
|
- Confirm a capture route exists for each declared screen.
|
|
88
|
-
-
|
|
89
|
-
`node_modules/.bin/playwright
|
|
75
|
+
- Canonical launcher: `npx --no-install playwright` or
|
|
76
|
+
`node_modules/.bin/playwright` when PATH reachability is uncertain.
|
|
77
|
+
- Legacy fallback (deprecation window only, emits
|
|
78
|
+
`D-DEPRECATED-PROBE` and will be removed in a future minor release):
|
|
79
|
+
`npx --no-install playwright-cli` or `node_modules/.bin/playwright-cli`.
|
|
80
|
+
|
|
81
|
+
### Step 2-B.1 — Opt-in iterate flags
|
|
82
|
+
|
|
83
|
+
Three flags extend `qfai prototyping iterate`; all default OFF so the
|
|
84
|
+
prior invocation pattern is byte-equivalent when no flag is passed:
|
|
85
|
+
|
|
86
|
+
- `--capture` — enable PNG / HTML capture per screen each cycle via
|
|
87
|
+
the default Playwright runner (dynamic `import("playwright")`;
|
|
88
|
+
Playwright is `optionalDependencies`). Use for durable pixel / DOM
|
|
89
|
+
evidence; skip for fast prose-only cycles.
|
|
90
|
+
- `--auto-serve` — start an in-process `node:http` server rooted at
|
|
91
|
+
the prototype tree for the cycle. SIGINT teardown <= 2 s;
|
|
92
|
+
EADDRINUSE on a foreign owner exits 2 (no foreign-process kill).
|
|
93
|
+
Use when no external dev server is running.
|
|
94
|
+
- `--check-convergence` — read-only peek of `prototyping.json`.
|
|
95
|
+
Exits `0` when converged (`stopReason === "axes-exceptional"` with
|
|
96
|
+
`acceptedIterationIndex` set), exits `2` otherwise. No writes,
|
|
97
|
+
no Playwright launches. Use at cycle 9 before recovery.
|
|
90
98
|
|
|
91
99
|
### Step 2-C — Run the Loop
|
|
92
100
|
|
|
@@ -113,41 +121,38 @@ covers `frozenSurfaceUnion` / `frozenLicenseCatalog` drift on cycle ≥ 1).
|
|
|
113
121
|
`prototyping.json` violates the cycle-0 frozen license catalog. The
|
|
114
122
|
verifier rejects five distinct error codes:
|
|
115
123
|
|
|
116
|
-
- `license-not-allowlisted` — `source`
|
|
117
|
-
|
|
118
|
-
- `license-tier-unknown` — `license` is not in
|
|
119
|
-
`frozenLicenseCatalog.licenseTiers[source]`
|
|
124
|
+
- `license-not-allowlisted` — `source` not in `allowedSources`
|
|
125
|
+
- `license-tier-unknown` — `license` not in `licenseTiers[source]`
|
|
120
126
|
- `license-non-https-url` — `url` is not HTTPS
|
|
121
|
-
- `license-host-mismatch` —
|
|
122
|
-
|
|
123
|
-
- `license-missing-attribution` — `attribution` is undefined / empty /
|
|
124
|
-
whitespace-only
|
|
127
|
+
- `license-host-mismatch` — URL host not in `sourceHosts[source]`
|
|
128
|
+
- `license-missing-attribution` — `attribution` empty / whitespace
|
|
125
129
|
|
|
126
130
|
Recovery path (no in-loop retry — the verifier is fail-closed):
|
|
127
131
|
|
|
128
|
-
1. Inspect `prototyping.json#frozenLicenseCatalog`
|
|
132
|
+
1. Inspect `prototyping.json#frozenLicenseCatalog` for the frozen
|
|
129
133
|
`allowedSources` / `licenseTiers` / `sourceHosts`.
|
|
130
134
|
2. Edit the offending `imageSources[]` entry to use an allowlisted
|
|
131
|
-
source / known
|
|
132
|
-
attribution. **Do not** edit `frozenLicenseCatalog` mid-loop
|
|
133
|
-
|
|
134
|
-
3.
|
|
135
|
-
|
|
136
|
-
from cycle 0 (`qfai prototyping iterate --cycle 0 --target-url <url>`)
|
|
137
|
-
with the updated stock-photo configuration.
|
|
135
|
+
source / known tier / HTTPS URL / matching host / non-empty
|
|
136
|
+
attribution. **Do not** edit `frozenLicenseCatalog` mid-loop
|
|
137
|
+
(separate exit-2 lock-drift class).
|
|
138
|
+
3. To change the allowlist, refreeze the catalog by restarting from
|
|
139
|
+
cycle 0 with the updated stock-photo configuration.
|
|
138
140
|
|
|
139
141
|
### Cycle 9 budget exhaustion
|
|
140
142
|
|
|
141
|
-
If convergence is not reached at iter-09,
|
|
142
|
-
|
|
143
|
-
`
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
143
|
+
If convergence is not reached at iter-09, certify rejects the run; H
|
|
144
|
+
handoff artifacts and `validate` / `/qfai-verify` can still execute for
|
|
145
|
+
inspection, but `qfai prototyping certify --check` will exit non-zero
|
|
146
|
+
and prevent DONE.
|
|
147
|
+
|
|
148
|
+
Use `qfai prototyping iterate --cycle 9 --check-convergence` for a
|
|
149
|
+
read-only peek of `prototyping.json` before refreezing: exit `0`
|
|
150
|
+
confirms convergence (no recovery needed), exit `2` confirms the run
|
|
151
|
+
did not converge. Recovery: review `DESIGN.md`, the pivot strategy
|
|
152
|
+
in `references/reviewer-prompt.md`, and the latest `review.json`
|
|
153
|
+
findings, then re-run `qfai prototyping iterate --cycle 0
|
|
154
|
+
--target-url <url>` to refreeze. Do not seal a certificate against
|
|
155
|
+
an unconverged iter-09.
|
|
151
156
|
|
|
152
157
|
## Evaluator Inputs (Mandatory)
|
|
153
158
|
|
|
@@ -163,8 +168,8 @@ completion certificate against an unconverged iter-09.
|
|
|
163
168
|
latest iter is always accepted.
|
|
164
169
|
- `DESIGN.md` is frozen for the run; to change it, edit + rerun
|
|
165
170
|
`/qfai-sdd` to refreeze + start cycle 0.
|
|
166
|
-
- Token-only colors / fonts / radii / shadows — non-DESIGN.md hex /
|
|
167
|
-
rgba / hsl / font / radius / shadow values
|
|
171
|
+
- Token-only colors / fonts / radii / shadows — non-DESIGN.md hex /
|
|
172
|
+
rgb / rgba / hsl / font / radius / shadow values land in
|
|
168
173
|
`designMdViolations[]` and block exit 64.
|
|
169
174
|
- DONE only when `qfai prototyping certify --check` returns 0.
|
|
170
175
|
- No `mode / round / polish / branch / concept-fit` artifacts.
|
|
@@ -50,12 +50,102 @@ tokens (e.g. `bg-primary`, `text-text`, `rounded-md`, `shadow-lg`,
|
|
|
50
50
|
|
|
51
51
|
## Hard constraints (enforced by the compliance gate)
|
|
52
52
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
53
|
+
The compliance gate scans rendered HTML — `<style>` blocks, inline
|
|
54
|
+
`style="..."` attributes, AND Tailwind `class="..."` attributes — for
|
|
55
|
+
four categories of forbidden literals. Findings are **advisory-failing**:
|
|
56
|
+
the gate blocks convergence by default, but a Reviewer can override
|
|
57
|
+
when a finding is a known false positive.
|
|
58
|
+
|
|
59
|
+
### 1. color literal ban
|
|
60
|
+
|
|
61
|
+
No raw color literals outside `DESIGN.md.visual.colors`. The scanner
|
|
62
|
+
catches every authoring path:
|
|
63
|
+
|
|
64
|
+
- `#hex` (3 / 4 / 6 / 8 nibbles): e.g. `color: #ff0000`,
|
|
65
|
+
`bg-[#ff0000]`.
|
|
66
|
+
- `rgb(...)` / `rgba(...)`: e.g. `background: rgb(255 0 0)`,
|
|
67
|
+
`bg-[rgb(255_0_0)]`.
|
|
68
|
+
- `hsl(...)` / `hsla(...)`: e.g. `color: hsl(0 100% 50%)`.
|
|
69
|
+
- CSS named-color keywords (`red`, `white`, `blue`, …) when placed
|
|
70
|
+
on a color-bearing property (`color`, `background`, `border`,
|
|
71
|
+
`outline`, `fill`, `stroke`, `caret-color`, `text-decoration`,
|
|
72
|
+
`column-rule`, and their `-color` longhands / shorthand variants).
|
|
73
|
+
- Tailwind palette utilities (`bg-blue-500`, `text-slate-900`,
|
|
74
|
+
`border-red-400`, etc.) — the CDN cannot read `DESIGN.md`, so
|
|
75
|
+
every palette class is by definition drift.
|
|
76
|
+
|
|
77
|
+
### 2. font-family literal ban
|
|
78
|
+
|
|
79
|
+
No `font-family:` whose first family token is outside
|
|
80
|
+
`DESIGN.md.visual.typography.family_sans` / `family_display` /
|
|
81
|
+
`family_mono`. Authored forms caught:
|
|
82
|
+
|
|
83
|
+
- Inline `font-family: Inter, sans-serif` (quoted or unquoted).
|
|
84
|
+
- Tailwind arbitrary `font-[Inter]`. Numeric / named font-weight
|
|
85
|
+
arbitraries (`font-[600]`, `font-[medium]`) are weight tokens —
|
|
86
|
+
not font-family drift — and pass through.
|
|
87
|
+
|
|
88
|
+
### 3. border-radius literal ban
|
|
89
|
+
|
|
90
|
+
No `border-radius:` value outside `DESIGN.md.visual.radius`. Authored
|
|
91
|
+
forms caught:
|
|
92
|
+
|
|
93
|
+
- Inline `border-radius: 12px` / `border-radius: 0.5rem`.
|
|
94
|
+
- Tailwind arbitrary `rounded-[13px]`, `rounded-[0.5rem]`.
|
|
95
|
+
- Tailwind scale aliases (`rounded`, `rounded-sm`, `rounded-md`,
|
|
96
|
+
`rounded-lg`, `rounded-xl`, `rounded-2xl`, `rounded-3xl`,
|
|
97
|
+
`rounded-full`, `rounded-none`) — all resolve to Tailwind defaults,
|
|
98
|
+
not `DESIGN.md` tokens.
|
|
99
|
+
|
|
100
|
+
### 4. box-shadow literal ban (including rgba color slot)
|
|
101
|
+
|
|
102
|
+
No `box-shadow:` declaration outside `DESIGN.md.visual.shadow`. The
|
|
103
|
+
shadow value's embedded `rgba(...)` color slot is also covered.
|
|
104
|
+
Authored forms caught:
|
|
105
|
+
|
|
106
|
+
- Inline `box-shadow: 0 1px 2px rgba(15,23,42,0.05)`.
|
|
107
|
+
- Tailwind arbitrary `shadow-[0_4px_6px_rgba(0,0,0,0.1)]`.
|
|
108
|
+
- Tailwind scale aliases (`shadow`, `shadow-sm`, `shadow-md`,
|
|
109
|
+
`shadow-lg`, `shadow-xl`, `shadow-2xl`, `shadow-inner`,
|
|
110
|
+
`shadow-none`, `drop-shadow-*`).
|
|
111
|
+
|
|
112
|
+
### Safelisted CSS-wide keywords
|
|
113
|
+
|
|
114
|
+
The following values are **not** treated as drift by any of the four
|
|
115
|
+
scanners above — they are CSS inheritance / system keywords with no
|
|
116
|
+
visual identity:
|
|
117
|
+
|
|
118
|
+
- `inherit`
|
|
119
|
+
- `initial`
|
|
120
|
+
- `unset`
|
|
121
|
+
- `revert`
|
|
122
|
+
- `currentColor` (case-insensitive)
|
|
123
|
+
- `transparent`
|
|
124
|
+
- `none`
|
|
125
|
+
- `0` (dimensionless)
|
|
126
|
+
|
|
127
|
+
Authoring `font-family: inherit`, `border-radius: 0`, or
|
|
128
|
+
`box-shadow: none` passes the gate even when not present in
|
|
129
|
+
`DESIGN.md`.
|
|
130
|
+
|
|
131
|
+
### Allowed expression forms
|
|
132
|
+
|
|
133
|
+
The generator MUST express every styled surface as one of:
|
|
134
|
+
|
|
135
|
+
- A Tailwind utility class whose token resolves through the
|
|
136
|
+
`tailwind.config.theme.extend.*` injection above (e.g. `bg-primary`,
|
|
137
|
+
`text-text`, `rounded-md`, `shadow-lg`, `font-display`). These
|
|
138
|
+
utilities reference `DESIGN.md` tokens by name and never carry a
|
|
139
|
+
literal in the rendered DOM.
|
|
140
|
+
- A CSS custom-property reference via `var(--token-name)` where the
|
|
141
|
+
`--token-name` is declared in a `:root { ... }` block inside the
|
|
142
|
+
iter's `<style>` head. The scanner resolves the `var()` against
|
|
143
|
+
the `:root` map and re-validates the resolved value against
|
|
144
|
+
`DESIGN.md`.
|
|
145
|
+
- A `theme(...)` reference to the injected Tailwind theme.
|
|
146
|
+
|
|
147
|
+
### Other envelope constraints
|
|
148
|
+
|
|
59
149
|
- No component library beyond Tailwind + Lucide. No external CSS, no
|
|
60
150
|
design-system imports.
|
|
61
151
|
- One self-contained HTML file; embedded CSS / JS minimal.
|
package/assets/init/.qfai/assistant/skills/qfai-sdd/templates/contracts/ui-contract.sample.yaml
CHANGED
|
@@ -12,6 +12,10 @@ screens:
|
|
|
12
12
|
- id: order_create
|
|
13
13
|
title: Create Order
|
|
14
14
|
route: /orders/new
|
|
15
|
+
# primary_tasks: at least one entry required per screen (QFAI-AUD-001).
|
|
16
|
+
# Replace the example below with the actual primary user action(s).
|
|
17
|
+
primary_tasks:
|
|
18
|
+
- submit a new order
|
|
15
19
|
elements:
|
|
16
20
|
- id: customer_id_input
|
|
17
21
|
label: Customer ID
|