@explorer02/cfm-survey-sdk 0.2.4 → 0.2.6

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 (43) hide show
  1. package/dist/cli/index.js +45 -44
  2. package/dist/cli/index.mjs +43 -42
  3. package/package.json +1 -6
  4. package/postinstall.js +2 -1
  5. package/templates/AGENT.md +3 -3
  6. package/templates/docs/00-integration/agent-execution-flow.md +46 -27
  7. package/templates/docs/00-integration/agent-operating-contract.md +13 -5
  8. package/templates/docs/00-integration/apply-ui-config.md +35 -10
  9. package/templates/docs/00-integration/aws-deploy.md +117 -3
  10. package/templates/docs/00-integration/component-checklist.md +8 -4
  11. package/templates/docs/00-integration/constraints.md +3 -2
  12. package/templates/docs/00-integration/custom-field-logic-and-navigation.md +1 -1
  13. package/templates/docs/00-integration/mockup-ui-extraction.md +113 -0
  14. package/templates/docs/00-integration/placeholders-and-custom-fields-wiring.md +192 -0
  15. package/templates/docs/00-integration/placeholders-and-tokens.md +2 -1
  16. package/templates/docs/00-integration/ui-customization-wizard.md +83 -104
  17. package/templates/docs/00-integration/wizard-api.md +74 -82
  18. package/templates/docs/00-integration/wizard-chrome-contract.md +210 -0
  19. package/templates/docs/00-integration/wizard-config-handoff.md +57 -9
  20. package/templates/docs/00-integration/wizard-preview-build-guide.md +30 -11
  21. package/templates/docs/00-integration/wizard-question-type-styling.md +4 -2
  22. package/templates/docs/00-integration/wizard-troubleshooting.md +80 -0
  23. package/templates/docs/01-components/10-header-footer.md +3 -3
  24. package/templates/docs/01-components/19-survey-sticky-chrome.md +16 -55
  25. package/templates/docs/MANIFEST.json +34 -13
  26. package/templates/docs/index.md +9 -11
  27. package/templates/docs/templates/Footer.tsx +72 -0
  28. package/templates/docs/templates/Header.tsx +84 -0
  29. package/templates/docs/templates/LanguageSelector.tsx +40 -0
  30. package/templates/docs/templates/PreviewBridgeInit.tsx +13 -0
  31. package/templates/docs/templates/ProgressBar.tsx +33 -0
  32. package/templates/docs/templates/Question.tsx +50 -7
  33. package/templates/docs/templates/SurveyStickyChrome.tsx +19 -5
  34. package/templates/docs/templates/deploy-to-aws.sh +74 -0
  35. package/templates/docs/templates/implementation_plan.md +19 -12
  36. package/templates/docs/templates/verify-agent-build.sh +25 -1
  37. package/templates/preview-harness/preview-bridge.inline.js +1 -1
  38. package/templates/previewBridge.ts +131 -38
  39. package/templates/wizard-dist/assets/{PreviewMock-DgHfrVeb.js → PreviewMock-7peNZK-z.js} +1 -1
  40. package/templates/wizard-dist/assets/{TypePanel-CFVC3Ptn.js → TypePanel-BxHnE3cm.js} +1 -1
  41. package/templates/wizard-dist/assets/index-DtZhNwPS.js +34 -0
  42. package/templates/wizard-dist/index.html +1 -1
  43. package/templates/wizard-dist/assets/index-DYK3X1e5.js +0 -34
@@ -0,0 +1,210 @@
1
+ # Wizard Chrome Contract — Required DOM + CSS Hooks
2
+
3
+ > **Mandatory Phase 5.** If any hook is missing, wizard live preview fails for that control — even though the survey may look fine in localhost dev without the wizard open.
4
+ > **Copy-first templates:** [`templates/Header.tsx`](../templates/Header.tsx), [`Footer.tsx`](../templates/Footer.tsx), [`ProgressBar.tsx`](../templates/ProgressBar.tsx), [`SurveyStickyChrome.tsx`](../templates/SurveyStickyChrome.tsx), [`LanguageSelector.tsx`](../templates/LanguageSelector.tsx), [`PreviewBridgeInit.tsx`](../templates/PreviewBridgeInit.tsx), [`previewBridge.ts`](../../previewBridge.ts).
5
+
6
+ Pipeline: [`wizard-preview-build-guide.md`](wizard-preview-build-guide.md) · [`apply-ui-config.md`](apply-ui-config.md)
7
+
8
+ ---
9
+
10
+ ## Symptom → missing hook (quick fix)
11
+
12
+ | Wizard control / symptom | Required fix |
13
+ |--------------------------|--------------|
14
+ | Logo not updating in Branding / Header preview | `data-cfm-logo` img + `data-cfm-logo-text` fallback in `Header.tsx` |
15
+ | Company name not updating | `data-cfm-company` span in `Header.tsx` |
16
+ | Show header works but progress bar toggle does nothing | Progress bar needs `data-cfm-progress` + class `cfm-progress`; header needs class `cfm-header` only — **not** on sticky wrapper |
17
+ | Show footer toggle does nothing | `footer` + class `cfm-footer` |
18
+ | Question numbers / required asterisk toggles | `data-cfm-question-number` + `data-cfm-required` on every question title |
19
+ | Question card padding/shadow/colors not live-updating | Question wrapper uses `var(--cfm-card-*)` — not hardcoded `bg-white shadow-sm` |
20
+ | MCQ / NPS / dropzone style pickers | Root reads `html[data-cfm-mcq-style]`, `[data-cfm-nps-button-style]`, `[data-cfm-dropzone-style]` from bridge |
21
+ | Scale selection colors not updating | Import `selectionStyles.ts`; use `var(--cfm-matrix-selected)` / `var(--cfm-input-focus-ring)` |
22
+ | Nothing updates except static harness | Agent build missing token contract — re-copy templates above |
23
+
24
+ ---
25
+
26
+ ## Copy order (agents — do this in Phase 5)
27
+
28
+ ```bash
29
+ # From SDK templates folder (monorepo or node_modules)
30
+ cp templates/docs/templates/Header.tsx src/components/Header.tsx
31
+ cp templates/docs/templates/Footer.tsx src/components/Footer.tsx
32
+ cp templates/docs/templates/ProgressBar.tsx src/components/ProgressBar.tsx
33
+ cp templates/docs/templates/SurveyStickyChrome.tsx src/components/SurveyStickyChrome.tsx
34
+ cp templates/docs/templates/LanguageSelector.tsx src/components/LanguageSelector.tsx
35
+ cp templates/docs/templates/PreviewBridgeInit.tsx src/components/PreviewBridgeInit.tsx
36
+ cp templates/previewBridge.ts src/lib/previewBridge.ts
37
+ cp templates/survey-theme.css src/styles/survey-theme.css
38
+ cp templates/docs/templates/selectionStyles.ts src/lib/surveyUi/selectionStyles.ts
39
+ cp templates/docs/templates/labelStyles.ts src/lib/surveyUi/labelStyles.ts
40
+ ```
41
+
42
+ Wire `PreviewBridgeInit` in `layout.tsx` (local dev). Wizard iframes use injected `preview-bridge.inline.js` at export time.
43
+
44
+ Run verification:
45
+
46
+ ```bash
47
+ bash templates/verify-agent-build.sh
48
+ ```
49
+
50
+ ---
51
+
52
+ ## Layer 1 — CSS variables (`--cfm-*`)
53
+
54
+ Wizard sends SNAPSHOT (full) + DELTA (partial) CSS vars to `:root`.
55
+
56
+ **Rule:** Every color, radius, spacing, or chrome dimension editable in the wizard must be consumed via `var(--cfm-…)` — not hardcoded `#e20074` / `bg-[#e20074]`.
57
+
58
+ Minimum files:
59
+
60
+ | File | Role |
61
+ |------|------|
62
+ | `src/styles/survey-theme.css` | All default `--cfm-*` vars |
63
+ | `globals.css` | `@import './styles/survey-theme.css'` |
64
+ | Scale components | `selectionStyles.ts` + `labelStyles.ts` |
65
+
66
+ ---
67
+
68
+ ## Layer 2 — Content patches (`data-cfm-*` + layout flags)
69
+
70
+ Wizard sends `contentPatch` on SNAPSHOT (not DELTA). Preview bridge applies patches to matching DOM nodes.
71
+
72
+ ### Branding & header
73
+
74
+ | Patch field | DOM target | Template location |
75
+ |-------------|------------|-------------------|
76
+ | `logoUrl` | `[data-cfm-logo]` → sets `src`, shows img; hides `[data-cfm-logo-text]` | `Header.tsx` |
77
+ | `companyName` | `[data-cfm-company]` text; fills logo-text when img hidden | `Header.tsx` |
78
+ | `layoutFlags.showCompanyName` | `[data-cfm-company]` display | bridge |
79
+
80
+ ### Layout toggles (independent — critical)
81
+
82
+ | `layoutFlags` key | Bridge selector | Component requirement |
83
+ |-------------------|-----------------|----------------------|
84
+ | `showHeader` | `.cfm-header`, `header.cfm-header` | Class on `<header>` only |
85
+ | `showProgressBar` | `.cfm-progress`, `[data-cfm-progress]` | **Separate** from header — `ProgressBar.tsx` |
86
+ | `showFooter` | `.cfm-footer`, `footer.cfm-footer` | Class on `<footer>` |
87
+ | `showLanguageSwitcher` | `[data-cfm-language]` | `LanguageSelector.tsx` |
88
+ | `showNextButton` | `[data-cfm-btn-next]` | `SurveyPage.tsx` nav |
89
+ | `showBackButton` | `[data-cfm-btn-back]` | `SurveyPage.tsx` nav |
90
+ | `showQuestionNumbers` | `[data-cfm-question-number]` | `Question.tsx` title |
91
+ | `showRequiredAsterisk` | `[data-cfm-required]` | `Question.tsx` title |
92
+ | `showFooterLogo` | `[data-cfm-footer-logo]` | `Footer.tsx` |
93
+
94
+ **Anti-pattern:** Putting `sticky top-0` on the same element as `cfm-header` — bridge used to hide progress when toggling header. Templates use `cfm-sticky-chrome` wrapper without using it for `showHeader`.
95
+
96
+ ### Survey chrome content
97
+
98
+ | Patch field | DOM target |
99
+ |-------------|------------|
100
+ | `surveyTitle` | `[data-cfm-survey-title]` |
101
+ | `thankYouMessage` | `[data-cfm-thank-you]` |
102
+ | `buttonLabels.next` / `.back` | `[data-cfm-btn-next]` / `[data-cfm-btn-back]` |
103
+ | `copyrightText` | `[data-cfm-copyright]` |
104
+ | `footerLinks[]` | `[data-cfm-footer-links]` innerHTML |
105
+
106
+ ### Question-type DOM attributes (on `<html>`)
107
+
108
+ Set via `contentPatch.domAttributes`:
109
+
110
+ | Attribute | Wizard source | Component reads |
111
+ |-----------|---------------|-----------------|
112
+ | `data-cfm-mcq-style` | `questionTypes.MCQ.optionStyle` | MCQ card classes / CSS |
113
+ | `data-cfm-nps-button-style` | `questionTypes.NPS_SCALE.buttonStyle` | `RatingScale.tsx` |
114
+ | `data-cfm-dropzone-style` | `questionTypes.FILE_UPLOAD.dropzoneStyle` | `FileUploadScale.tsx` |
115
+
116
+ Vite preview harness also applies `previewState` via `PreviewConfigContext` for placeholders, NPS hints, rank variant, etc.
117
+
118
+ ---
119
+
120
+ ## Question card (Theme step)
121
+
122
+ Question outer wrapper **must** use theme vars:
123
+
124
+ ```tsx
125
+ <section
126
+ id={question.id}
127
+ className="cfm-question-card space-y-4"
128
+ style={{
129
+ background: 'var(--cfm-card-bg, #fff)',
130
+ borderColor: 'var(--cfm-card-border-color, #e5e7eb)',
131
+ padding: 'var(--cfm-card-padding, 24px)',
132
+ boxShadow: 'var(--cfm-card-shadow, 0 1px 3px rgba(0,0,0,0.1))',
133
+ borderRadius: 'var(--cfm-border-radius, 12px)',
134
+ borderWidth: 1,
135
+ borderStyle: 'solid',
136
+ }}
137
+ >
138
+ ```
139
+
140
+ Question title hooks:
141
+
142
+ ```tsx
143
+ <h2>
144
+ {question.questionNumber != null && (
145
+ <span data-cfm-question-number className="mr-1 font-semibold">
146
+ {question.questionNumber}.
147
+ </span>
148
+ )}
149
+ <span dangerouslySetInnerHTML={{ __html: displayQuestionText }} />
150
+ {question.required && (
151
+ <span data-cfm-required className="ml-1 text-red-500">*</span>
152
+ )}
153
+ </h2>
154
+ ```
155
+
156
+ TEXTFIELD placeholder live preview: `data-cfm-textfield` on input/textarea.
157
+
158
+ ---
159
+
160
+ ## SurveyPage wiring (content phase)
161
+
162
+ ```tsx
163
+ <div className="flex min-h-screen flex-col" style={{ background: 'var(--cfm-background)' }}>
164
+ <SurveyStickyChrome progressPercentage={state.progressPercentage} />
165
+ <main style={{ maxWidth: 'var(--cfm-max-width)' }}>...</main>
166
+ <Footer />
167
+ </div>
168
+ ```
169
+
170
+ Intro / end / paused: standalone `<Header />` (not sticky chrome). Footer still uses `cfm-footer`.
171
+
172
+ ---
173
+
174
+ ## Local wizard quit — preview garbage collection
175
+
176
+ When the client **quits** local wizard (`npx cfm-sdk customize`) without saving:
177
+
178
+ 1. Wizard SPA calls `POST /api/wizard-quit` on the customize server
179
+ 2. CLI deletes `out/previews/` on agent disk
180
+ 3. CLI exits; no orphan preview folders
181
+
182
+ When client **saves**: config written; previews remain until CLI exits (then server stops).
183
+
184
+ When CLI is **Ctrl+C**'d: customize server runs the same preview cleanup on shutdown.
185
+
186
+ EC2 `customize-ui`: quit calls `POST /wizard/session/quit` — disk session folder deleted (see [`wizard-config-handoff.md`](wizard-config-handoff.md)).
187
+
188
+ ---
189
+
190
+ ## Verification checklist (blocking before Phase 6b)
191
+
192
+ - [ ] Copied all templates from § Copy order
193
+ - [ ] `grep -r data-cfm-logo src/components/Header.tsx` — match
194
+ - [ ] `grep -r data-cfm-progress src/components/ProgressBar.tsx` — match
195
+ - [ ] `grep -r cfm-footer src/components/Footer.tsx` — match
196
+ - [ ] `grep -r data-cfm-question-number src/components/Question.tsx` — match
197
+ - [ ] `grep -rE 'var\\(--cfm-' src/components/` — no wizard colors as hardcoded hex only
198
+ - [ ] `bash templates/verify-agent-build.sh` exit 0
199
+ - [ ] `npx cfm-sdk export-previews` exit 0
200
+
201
+ ---
202
+
203
+ ## Related
204
+
205
+ | Doc | Role |
206
+ |-----|------|
207
+ | [`wizard-preview-build-guide.md`](wizard-preview-build-guide.md) | Full build guide |
208
+ | [`wizard-question-type-styling.md`](wizard-question-type-styling.md) | Per-type CSS vars |
209
+ | [`10-header-footer.md`](../01-components/10-header-footer.md) | Branding patterns |
210
+ | [`12-survey-chrome.md`](../03-ui-specs/12-survey-chrome.md) | Chrome layout spec |
@@ -11,14 +11,53 @@ This doc tells the agent **exactly** how to wait for the client to finish the wi
11
11
 
12
12
  **Do not apply wizard changes until the client has submitted the wizard.**
13
13
 
14
- - **AWS (`customize-ui`):** CLI blocks and polls until status `ready` — wait for CLI success message.
15
- - **Local (`customize`):** CLI blocks until client saves in browser — wait for `✅ UI configuration saved`.
14
+ - **Default (`customize`):** CLI blocks until client saves — wait for `✅ UI configuration saved`.
15
+ - **Remote client (`customize-ui`):** CLI blocks and polls until status `ready`.
16
16
 
17
- **Do not** guess final colors from memory, skip the diff, or proceed to deploy while `survey-ui-config.json` still holds the **seed** (AWS review mode).
17
+ **Do not** guess final colors from memory or proceed to deploy before the wizard CLI exits 0.
18
18
 
19
19
  ---
20
20
 
21
- ## AWS flow (default review mode)
21
+ ## Default flow — `npx cfm-sdk customize`
22
+
23
+ ### Step 1 — Agent runs CLI (and waits)
24
+
25
+ ```bash
26
+ npx cfm-sdk customize
27
+ ```
28
+
29
+ The CLI will:
30
+
31
+ 1. Export all 11 component preview pages (`export-previews` if needed)
32
+ 2. Start wizard at `http://localhost:4200`
33
+ 3. Open browser on the **agent machine**
34
+ 4. **Block** until client clicks **Review & Build**
35
+ 5. Write `survey-ui-config.json` and exit 0
36
+
37
+ **Agent must:**
38
+
39
+ - [ ] Client is on the **same machine** (can see `localhost:4200`)
40
+ - [ ] Keep terminal open until `✅ UI configuration saved`
41
+ - [ ] Apply per Phase 6c from `survey-ui-config.json`
42
+
43
+ **Artifact:** `survey-ui-config.json` — apply source for local flow.
44
+
45
+ **Logo on local wizard (critical for AWS deploy):**
46
+
47
+ When the client uploads a logo in the local wizard:
48
+
49
+ 1. CLI writes the file to `public/logo_{timestamp}_{name}.jpg` via `POST /api/upload-logo`.
50
+ 2. Saved config has `global.logo.fileName` — preview `data:` URL is **not** persisted (stripped on save).
51
+ 3. Agent **must** set `Header.tsx` `data-cfm-logo` to `src="./{fileName}"` during Phase 6c.
52
+ 4. `yarn build` copies `public/` → `out/`; Phase 7 uploads `out/` to `sites/{surveyId}/{deployId}/`.
53
+
54
+ The logo is **not** fetched from wizard memory on CloudFront — only from the deploy bundle. See [`aws-deploy.md`](aws-deploy.md) § Logos & local assets.
55
+
56
+ **Local quit (preview GC):** If the client exits without saving, wizard calls `POST /api/wizard-quit` → CLI deletes `out/previews/` on agent disk. Ctrl+C on customize CLI runs the same cleanup.
57
+
58
+ ---
59
+
60
+ ## Remote client flow — `customize-ui` (fallback only)
22
61
 
23
62
  ### Step 1 — Agent runs CLI (and waits)
24
63
 
@@ -31,12 +70,12 @@ npx cfm-sdk customize-ui
31
70
  **Default is review mode** (no flags). The CLI will:
32
71
 
33
72
  1. Export component preview pages (`export-previews`)
34
- 2. Upload preview HTML to S3 (one page per component key `header`, `footer`, `MCQ_single`, …)
73
+ 2. Upload preview HTML to **EC2 disk** (local-server model same as agent `customize`)
35
74
  3. Print the **deployed EC2 wizard link** — agent **must share this URL with the client**
36
75
  4. **Poll every ~3s** (`GET /wizard/config/:surveyId`) until the client submits
37
76
  5. Print `✅ Configuration ready` when `status === 'ready'`
38
77
 
39
- ### Deployed wizard link (give to client after S3 upload)
78
+ ### Deployed wizard link (give to client after preview upload)
40
79
 
41
80
  The client does **not** use localhost. After previews are uploaded, the CLI prints:
42
81
 
@@ -45,8 +84,9 @@ The client does **not** use localhost. After previews are uploaded, the CLI prin
45
84
  http://43.204.26.213:3000/wizard-app/index.html?session=<uuid>&secret=<hex>
46
85
  ```
47
86
 
48
- - **Previews:** stored in S3 under `sites/{surveyId}/wizard-sessions/{sessionId}/previews/`; wizard iframes load them via EC2 proxy (`GET /wizard/preview/:sessionId/:component/...`)
49
- - **Wizard UI:** served from EC2 at `/wizard-app/` (not CloudFront `sites/_wizard` — agents and clients use the EC2 link from `customize-ui`)
87
+ - **Previews:** stored on **EC2 disk** (`WIZARD_DATA_DIR/{sessionId}/previews/`); wizard iframes load via `GET /previews/{sessionId}/{component}/index.html` (local-server API — same model as `customize`)
88
+ - **Wizard UI:** served from EC2 at `/wizard-app/`; inventory via `GET /api/inventory`
89
+ - **On submit:** final config + permanent logo → S3 only
50
90
 
51
91
  Set `CFM_DEPLOY_API_BASE=http://43.204.26.213:3000` (or your EC2 host). The link is built from that base + session credentials returned by `POST /wizard/session/start`.
52
92
 
@@ -71,13 +111,16 @@ Set `CFM_DEPLOY_API_BASE=http://43.204.26.213:3000` (or your EC2 host). The link
71
111
 
72
112
  Poll response includes `logoUrl` and `logoKey` — CLI merges `logo.url` into final JSON.
73
113
 
114
+ **EC2 logo vs deploy bundle:** `logoUrl` points to `sites/{surveyId}/assets/{fileName}` on CloudFront. That path is for **wizard handoff** (download into `public/` via `confirm-ui-config`). The **live survey** loads the logo from `sites/{surveyId}/{deployId}/{fileName}` only after you rebuild and run Phase 7 deploy. Apply `data-cfm-logo src="./{fileName}"` then deploy — see [`aws-deploy.md`](aws-deploy.md) § Logos & local assets.
115
+
74
116
  **If all diff counts are 0:** client submitted without changes — still verify; skip heavy apply.
75
117
 
76
118
  ### S3 garbage collection
77
119
 
78
120
  | When | Deleted | Kept |
79
121
  |------|---------|------|
80
- | Client **Review & Build** | `wizard-sessions/{sessionId}/` (previews, seed-config, temp logo) | `sites/{surveyId}/assets/{logo}`, `wizard/config.json` |
122
+ | Client **Review & Build** | EC2 session disk folder (`data/wizard-sessions/{sessionId}/`) | `sites/{surveyId}/assets/{logo}`, `wizard/config.json` |
123
+ | Client **Quit** (or tab close) | Same session prefix — `POST /wizard/session/quit` | N/A |
81
124
  | Session **expires** (2h default) | Same session prefix — auto sweep every 5 min | N/A |
82
125
 
83
126
  ### Step 3 — Agent reads diff before touching code
@@ -216,6 +259,8 @@ npx cfm-sdk fetch-ui-config
216
259
  - [ ] `src/styles/survey-theme.css` fully synced to final config
217
260
  - [ ] All `data-cfm-*` content hooks updated
218
261
  - [ ] Logo file exists in `public/` when config has `global.logo.fileName`
262
+ - [ ] `out/{fileName}` exists after build when logo configured (AWS deploy gate)
263
+ - [ ] `Header.tsx` uses `data-cfm-logo src="./{fileName}"` — not `data:` or `/assets/` URL
219
264
  - [ ] `placeholders` / `customFields` / `debug` wired if present in final
220
265
  - [ ] AWS: ran `npx cfm-sdk confirm-ui-config` after codebase apply
221
266
  - [ ] `verify-agent-build.sh` + `npm run build` pass
@@ -228,11 +273,14 @@ npx cfm-sdk fetch-ui-config
228
273
  | Mistake | Fix |
229
274
  |---------|-----|
230
275
  | Killed CLI during poll | Re-run `customize-ui`; client re-submits |
276
+ | Client quit wizard | CLI exits with abandon message; S3 GC done — re-run `customize-ui` for new session |
231
277
  | Applied from `survey-ui-config.json` while still seed | Use `.final.json` or run `confirm-ui-config` after apply |
232
278
  | Only changed primary color, ignored diff | Read **entire** `diff.md` — clients often change 20+ paths |
233
279
  | Skipped `confirm-ui-config` | Active JSON stays seed; next wizard re-open is wrong |
234
280
  | Changed `Question.tsx` dispatch during apply | UI tokens only — see `apply-ui-config.md` scope |
235
281
  | Proceeded to deploy before apply | Complete Phase 6c first |
282
+ | Logo works in wizard but broken on CloudFront | Preview uses memory; deploy needs `public/` → `out/` → S3 — see `aws-deploy.md` § Logos |
283
+ | Used `global.logo.url` as Header src | Use `./{fileName}` only; download assets URL via `confirm-ui-config` |
236
284
 
237
285
  ---
238
286
 
@@ -1,10 +1,13 @@
1
1
  # Wizard Live Preview — Client Build Guide
2
2
 
3
3
  > **Read during Phase 5 (BUILD) — mandatory.** Wizard **run** (Phase 6b) is optional; this contract is required for every agent build.
4
+ > **Authoritative hook list + copy commands:** [`wizard-chrome-contract.md`](wizard-chrome-contract.md) — fixes logo, layout toggles, question card, and per-type preview issues.
4
5
  > Pipeline: [`agent-execution-flow.md`](agent-execution-flow.md).
5
6
 
6
7
  Related docs:
7
8
 
9
+ - [`wizard-chrome-contract.md`](wizard-chrome-contract.md) — **copy-first templates** + symptom → fix table
10
+
8
11
  - [`ui-customization-wizard.md`](ui-customization-wizard.md) — wizard flow and CLI
9
12
  - [`apply-ui-config.md`](apply-ui-config.md) — applying final `survey-ui-config.json` after wizard
10
13
  - [`wizard-api.md`](wizard-api.md) — EC2 `/wizard/*` API
@@ -20,13 +23,13 @@ The wizard does **not** re-render your React app. It loads **static preview page
20
23
  sequenceDiagram
21
24
  participant Agent as Agent_build
22
25
  participant CLI as export_previews
23
- participant S3 as S3_previews
26
+ participant Disk as EC2_or_agent_disk
24
27
  participant Wizard as Wizard_SPA
25
28
  participant Iframe as Preview_iframe
26
29
 
27
30
  Agent->>Agent: Build components with token contract
28
- Agent->>CLI: customize-ui / export-previews
29
- CLI->>S3: Upload HTML + JS + CSS
31
+ Agent->>CLI: customize (default) / customize-ui (remote)
32
+ CLI->>Disk: Upload HTML + JS + CSS (local-server)
30
33
  Wizard->>Iframe: Load chrome / MCQ_single / etc.
31
34
  Wizard->>Iframe: postMessage SNAPSHOT + DELTA
32
35
  Iframe->>Iframe: Apply --cfm-* vars + content patches
@@ -51,14 +54,25 @@ If components use **hardcoded** colors (`bg-[#e20074]`) with no `var(--cfm-*)` h
51
54
 
52
55
  ## Required project artifacts (Phase 5)
53
56
 
54
- Create these **before** the client opens the wizard:
57
+ **Copy wizard-ready templates first** (do not hand-write chrome from `apps/client`):
58
+
59
+ | Template (SDK) | Copy to |
60
+ |----------------|---------|
61
+ | `templates/docs/templates/Header.tsx` | `src/components/Header.tsx` |
62
+ | `templates/docs/templates/Footer.tsx` | `src/components/Footer.tsx` |
63
+ | `templates/docs/templates/ProgressBar.tsx` | `src/components/ProgressBar.tsx` |
64
+ | `templates/docs/templates/SurveyStickyChrome.tsx` | `src/components/SurveyStickyChrome.tsx` |
65
+ | `templates/docs/templates/LanguageSelector.tsx` | `src/components/LanguageSelector.tsx` |
66
+ | `templates/docs/templates/PreviewBridgeInit.tsx` | `src/components/PreviewBridgeInit.tsx` |
67
+ | `templates/previewBridge.ts` | `src/lib/previewBridge.ts` |
68
+ | `templates/survey-theme.css` | `src/styles/survey-theme.css` |
69
+ | `templates/docs/templates/Question.tsx` | `src/components/Question.tsx` (dispatcher base) |
70
+
71
+ Full symptom → fix table: [`wizard-chrome-contract.md`](wizard-chrome-contract.md).
55
72
 
56
73
  | File | Purpose |
57
74
  |------|---------|
58
- | `src/styles/survey-theme.css` | All `--cfm-*` CSS custom properties (defaults from mockup) |
59
75
  | `survey-ui-config.json` (draft) | Seeds wizard form fields from agent branding |
60
- | `src/lib/previewBridge.ts` | Live bridge in **local dev** (`npx cfm-sdk customize`) — copy from `templates/previewBridge.ts` |
61
- | `src/components/PreviewBridgeInit.tsx` | Mount bridge once in `layout.tsx` (local dev only) |
62
76
 
63
77
  Import theme in `globals.css`:
64
78
 
@@ -271,6 +285,7 @@ CLI resolution order:
271
285
  - **Image logo:** put file in `public/`, reference exact path on `<img data-cfm-logo src="/your-logo.svg" />`. CLI base64-encodes that file for the wizard preview.
272
286
  - **Text logo:** use `<span data-cfm-logo-text>` in the logo slot (CSS shapes optional). Omit `data-cfm-logo` img. Wizard shows company text until client uploads an image.
273
287
  - **After wizard upload:** `global.logo.fileName` in saved config takes precedence — do not fall back to `Header.tsx` or scan `public/logo_*`.
288
+ - **AWS deploy:** logo file must be in `out/{fileName}` with `data-cfm-logo src="./{fileName}"` — wizard preview memory is not uploaded. See [`aws-deploy.md`](aws-deploy.md) § Logos & local assets.
274
289
 
275
290
  Debug without opening wizard:
276
291
 
@@ -284,20 +299,20 @@ Keep draft JSON and `survey-theme.css` **in sync** (same primary color, title, c
284
299
 
285
300
  ## How `export-previews` uses your code
286
301
 
287
- When the client opts in, `customize-ui` runs `export-previews`:
302
+ When the client opts in, **`npx cfm-sdk customize`** (default) or `customize-ui` (remote) runs `export-previews`:
288
303
 
289
304
  1. Copies `src/components/`, `src/lib/`, `public/`, `survey-theme.css` into a temp Vite harness
290
305
  2. Stubs `next/image` and `next/dynamic` for static build
291
306
  3. Builds one HTML page per preview key (`header`, `chrome`, `MCQ_single`, …) with canonical fixtures
292
307
  4. Injects `preview-bridge.inline.js` into each `index.html`
293
- 5. Uploads each preview page to S3 via EC2 presigned PUTs
308
+ 5. Uploads each preview page to **EC2 disk** via `PUT /wizard/session/:id/preview-file` (local-server model)
294
309
  6. Prints the **deployed wizard link** for the client:
295
310
 
296
311
  ```
297
312
  http://43.204.26.213:3000/wizard-app/index.html?session=<uuid>&secret=<hex>
298
313
  ```
299
314
 
300
- 7. Wizard iframes load previews via EC2 proxy (`GET /wizard/preview/:sessionId/:component/...`)
315
+ 7. Wizard iframes load previews from `/previews/{sessionId}/{component}/…` on the same EC2 host (`GET /api/inventory` + local-server API)
301
316
 
302
317
  **Agent handoff:** after step 5–6, copy the printed link and send it to the client. The client customizes on EC2 only — not localhost.
303
318
 
@@ -356,6 +371,10 @@ npx cfm-sdk export-previews
356
371
  | Logo `<Image>` without `data-cfm-logo` | Logo step doesn't update preview | Add `data-cfm-logo` to img |
357
372
  | Only Phase 6c tokenization | Worked after wizard, not during | Tokenize in Phase 5 (this guide) |
358
373
  | Skipped `export-previews` after component edits | Wizard shows old UI | Re-run `customize-ui` |
374
+ | Used `customize-ui` when client is on same machine | Unnecessary complexity | Use **`customize`** (default) |
375
+ | `surveyTypes` only lists fetched survey types | Wizard shows one question type (e.g. NPS only) | `customize-ui` exports all 11 types; mockup image ≠ wizard inventory |
376
+ | Missing `data-cfm-progress` / `data-cfm-question-number` | Layout toggles don't work | Wire hooks per § Layer 2 table |
377
+ | Hardcoded brand hex in scales | Only NPS-like paths look correct | Use `--cfm-*` + `selectionStyles.ts` |
359
378
 
360
379
  ---
361
380
 
@@ -365,7 +384,7 @@ npx cfm-sdk export-previews
365
384
  |-------|----------------|
366
385
  | **5 BUILD** | Implement components per this guide + UI specs; draft config + theme |
367
386
  | **6 VERIFY** | `npm run build`, verify script, localhost preview |
368
- | **6b WIZARD** (optional) | Client says yes → `customize-ui`**wait** for submitread `.diff.md` |
387
+ | **6b WIZARD** (optional) | Client says yes → **`npx cfm-sdk customize`** → wait for saveapply config |
369
388
  | **6c APPLY** | Apply **all** paths from `survey-ui-config.final.json` per [`wizard-config-handoff.md`](wizard-config-handoff.md) + [`apply-ui-config.md`](apply-ui-config.md) → `confirm-ui-config` |
370
389
  | **7 DEPLOY** | Full static build upload (separate from wizard preview files) |
371
390
 
@@ -172,7 +172,9 @@ For production builds after wizard: syncing `survey-theme.css` is sufficient —
172
172
 
173
173
  ## Agent checklist (per survey type)
174
174
 
175
- For each type in survey inventory:
175
+ **Wizard customization** exposes all **11** question types regardless of fetched survey inventory. Wire styling for every scale template you copy — not only types in the client's mockup image.
176
+
177
+ For each type in **wizard export** (all 11):
176
178
 
177
179
  - [ ] Scale component uses `var(--cfm-*)` for every wizard-exposed token (no hardcoded brand hex)
178
180
  - [ ] Radio/scale selections use `selectionStyles.ts` pattern (focus ring + cell selected)
@@ -191,5 +193,5 @@ For each type in survey inventory:
191
193
  | [`templates/selectionStyles.ts`](../templates/selectionStyles.ts) | Copy to client `src/lib/surveyUi/` |
192
194
  | [`templates/labelStyles.ts`](../templates/labelStyles.ts) | Copy to client `src/lib/surveyUi/` |
193
195
  | [`templates/survey-theme.css`](../../survey-theme.css) | Full `--cfm-*` defaults |
194
- | [`wizard-preview-build-guide.md`](wizard-preview-build-guide.md) | Chrome + bridge contract |
196
+ | [`wizard-troubleshooting.md`](wizard-troubleshooting.md) | Mock preview, local vs EC2, toggle/logo fixes |
195
197
  | [`apply-ui-config.md`](apply-ui-config.md) | Post-wizard apply workflow |
@@ -0,0 +1,80 @@
1
+ # Wizard Troubleshooting — Agent Guide
2
+
3
+ > Companion: [`ui-customization-wizard.md`](ui-customization-wizard.md), [`wizard-preview-build-guide.md`](wizard-preview-build-guide.md).
4
+
5
+ ## Default command
6
+
7
+ **When client says yes → run `npx cfm-sdk customize`** (not `customize-ui` unless client is on another device).
8
+
9
+ | | `customize` **(default)** | `customize-ui` **(fallback)** |
10
+ |--|---------------------------|--------------------------------|
11
+ | **When** | Client on same machine as agent | Client on different device |
12
+ | **URL** | `localhost:4200` | EC2 link with `session` + `secret` |
13
+ | **Previews** | `out/previews/` on agent disk | EC2 disk |
14
+ | **Save** | `survey-ui-config.json` immediately | Poll → `.final.json` + `.diff.md` |
15
+ | **GC** | CLI stops → no orphans | Session cleanup on EC2 |
16
+
17
+ ---
18
+
19
+ ## Mock preview instead of live components
20
+
21
+ ### Symptom
22
+
23
+ Footer: **"Mock preview — run customize or customize-ui…"**
24
+
25
+ ### Fix
26
+
27
+ 1. Run `npx cfm-sdk customize` — auto-runs `export-previews` if needed
28
+ 2. Ensure `src/components/Question.tsx` exists (Phase 5 build complete)
29
+ 3. Re-run if you changed components after last export
30
+
31
+ ---
32
+
33
+ ## Client on another device opened localhost
34
+
35
+ ### Symptom
36
+
37
+ Client cannot open `http://localhost:4200`
38
+
39
+ ### Fix
40
+
41
+ Use EC2 fallback:
42
+
43
+ ```bash
44
+ export CFM_INSTANCE_ID="<JWT>"
45
+ export CFM_DEPLOY_API_BASE="http://43.204.26.213:3000"
46
+ npx cfm-sdk customize-ui
47
+ ```
48
+
49
+ Send **only the EC2 link** from CLI output.
50
+
51
+ ---
52
+
53
+ ## Storage service unavailable (EC2 only)
54
+
55
+ Only applies to **`customize-ui`** on submit — S3 denied when saving final config/logo. Previews on EC2 disk do not need S3.
56
+
57
+ Fix: EC2 IAM + `HOSTING_BUCKET` on deploy-api.
58
+
59
+ For same-machine clients, use **`customize`** — no S3 during wizard at all.
60
+
61
+ ---
62
+
63
+ ## Logo / toggles / layout not updating
64
+
65
+ Wire `data-cfm-*` hooks and `--cfm-*` CSS vars per [`wizard-preview-build-guide.md`](wizard-preview-build-guide.md).
66
+
67
+ ---
68
+
69
+ ## Only one question type showing
70
+
71
+ `customize` exports **all 11** types. Mockup may show NPS only — wizard still customizes all types.
72
+
73
+ ---
74
+
75
+ ## Checklist
76
+
77
+ - [ ] Used **`customize`** as default when client said yes
78
+ - [ ] Waited for `✅ UI configuration saved`
79
+ - [ ] Phase 5 preview bridge + `data-cfm-*` wired
80
+ - [ ] EC2 only if client on remote device
@@ -25,12 +25,12 @@ Agents must implement **one** of these wizard-compatible patterns in `Header.tsx
25
25
 
26
26
  | Mode | When | Required markup |
27
27
  |------|------|-----------------|
28
- | **Image** | Brand asset in `public/` | `<img data-cfm-logo src="/exact-file.svg" />` plus hidden `<span data-cfm-logo-text>` fallback |
28
+ | **Image** | Brand asset in `public/` | `<img data-cfm-logo src="./exact-file.svg" />` for AWS deploy (`assetPrefix: './'`). Use `/exact-file.svg` only for local dev. Include hidden `<span data-cfm-logo-text>` fallback. |
29
29
  | **Text** | CSS-only logo from prompt (no image file) | `<span data-cfm-logo-text>Company</span>` in logo slot — no `data-cfm-logo` img |
30
30
 
31
- - **NO EXTERNAL URLS** for logos (`https://…`).
31
+ - **NO EXTERNAL URLS** for logos (`https://…`, wizard `/assets/` URLs, or `data:image/…`).
32
32
  - **CSS-only logos** use `data-cfm-logo-text` (and optional CSS shapes) — wizard shows text until client uploads an image.
33
- - After wizard upload, saved `global.logo.fileName` is used on subsequent sessions — see `wizard-preview-build-guide.md`.
33
+ - After wizard upload, set `src="./{global.logo.fileName}"` from saved config — see [`aws-deploy.md`](../00-integration/aws-deploy.md) § Logos & local assets.
34
34
 
35
35
  ## Theme Engineering
36
36
  - Map the primary brand color to the accent and border colors across the entire survey.
@@ -1,30 +1,28 @@
1
1
  # Survey Sticky Chrome
2
2
 
3
- > **UI spec (authoritative):** `03-ui-specs/12-survey-chrome.md`
4
- > **Reference implementation:** `apps/client/src/components/SurveyStickyChrome.tsx`
3
+ > **UI spec (authoritative):** `03-ui-specs/12-survey-chrome.md`
4
+ > **Wizard contract:** [`wizard-chrome-contract.md`](../00-integration/wizard-chrome-contract.md) — header and progress are **separate** toggle targets
5
5
  > **Template:** [`templates/SurveyStickyChrome.tsx`](../templates/SurveyStickyChrome.tsx)
6
- > **Component**: `SurveyStickyChrome`
7
6
 
8
7
  ## Purpose
9
8
 
10
- Wrap **Header + ProgressBar** in a single `sticky top-0` container so the progress bar stays visible when the respondent scrolls to answer questions lower on the page (especially the last question on a multi-question page).
9
+ Wrap **Header + ProgressBar** in a sticky container. The wizard toggles them **independently**:
11
10
 
12
- ## Props
11
+ | Toggle | Target |
12
+ |--------|--------|
13
+ | `showHeader` | `.cfm-header` on `<header>` only |
14
+ | `showProgressBar` | `[data-cfm-progress]` / `.cfm-progress` only |
13
15
 
14
- ```typescript
15
- type SurveyStickyChromeProps = {
16
- progressPercentage: number; // from state.progressPercentage
17
- };
18
- ```
16
+ Do **not** put class `cfm-header` on the sticky wrapper.
19
17
 
20
- ## Implementation
18
+ ## Implementation (wizard-ready)
21
19
 
22
20
  ```tsx
23
21
  export default function SurveyStickyChrome({ progressPercentage }: SurveyStickyChromeProps) {
24
22
  return (
25
- <div className="sticky top-0 z-30 bg-white shadow-[0_2px_8px_rgba(0,0,0,0.06)]">
23
+ <div className="cfm-sticky-chrome sticky top-0 z-30" style={{ background: 'var(--cfm-header-bg)' }}>
26
24
  <Header embedded />
27
- <div className="mx-auto w-full max-w-4xl px-4 pb-5 pt-4 sm:px-6 lg:px-8">
25
+ <div className="mx-auto w-full px-4" style={{ maxWidth: 'var(--cfm-max-width)' }}>
28
26
  <ProgressBar progressPercentage={progressPercentage} />
29
27
  </div>
30
28
  </div>
@@ -32,48 +30,11 @@ export default function SurveyStickyChrome({ progressPercentage }: SurveyStickyC
32
30
  }
33
31
  ```
34
32
 
35
- ## Spacing (logo progress bar)
36
-
37
- Keep a visible gap between the logo block and the progress track — do **not** flush them together.
38
-
39
- | Token | Tailwind | Purpose |
40
- |-------|----------|---------|
41
- | Top inset | `pt-4` | 16px gap below logo / header row |
42
- | Bottom inset | `pb-5` | 20px gap above scrollable question content |
43
- | Horizontal | `px-4 sm:px-6 lg:px-8` | Align track with `main` content column (`max-w-4xl`) |
44
-
45
- ## Header `embedded` prop
46
-
47
- When `Header` is inside sticky chrome, pass `embedded` to avoid a double shadow:
48
-
49
- ```tsx
50
- <header className={`relative h-[120px] w-full bg-white ${embedded ? '' : 'z-10 shadow-[0_2px_8px_rgba(0,0,0,0.06)]'}`}>
51
- ```
52
-
53
- Use the standalone `Header` (no `embedded`) on intro, end, loading, and terminal pages.
54
-
55
- ## SurveyPage wiring (content phase only)
56
-
57
- ```tsx
58
- <div className="flex min-h-screen flex-col bg-white">
59
- <SurveyStickyChrome progressPercentage={state.progressPercentage} />
60
-
61
- <main className="mx-auto w-full max-w-4xl flex-1 px-4 py-10 sm:px-6 lg:px-8">
62
- <LanguageSelector ... />
63
- {/* questions + nav */}
64
- </main>
65
-
66
- <Footer />
67
- </div>
68
- ```
69
-
70
- Do **not** render a separate `ProgressBar` inside `<main>` — it belongs in sticky chrome only.
33
+ Copy full file from [`templates/SurveyStickyChrome.tsx`](../templates/SurveyStickyChrome.tsx).
71
34
 
72
35
  ## Agent checklist
73
36
 
74
- - [ ] `SurveyStickyChrome` (or equivalent sticky wrapper) on `phase.kind === 'content'`
75
- - [ ] `ProgressBar` bound to `state.progressPercentage`
76
- - [ ] `sticky top-0 z-30 bg-white` on wrapper; single shadow on wrapper, not Header
77
- - [ ] `pt-4` gap between logo and progress track; `pb-5` below track
78
- - [ ] Progress track aligned to same `max-w-4xl` as question content
79
- - [ ] Standalone `Header` on intro / end / loading / terminal branches
37
+ - [ ] `Header.tsx` has class `cfm-header` + `data-cfm-logo` + `data-cfm-company`
38
+ - [ ] `ProgressBar.tsx` has `data-cfm-progress` + class `cfm-progress`
39
+ - [ ] Sticky wrapper uses `cfm-sticky-chrome` not `cfm-header`
40
+ - [ ] `pt`/`pb` spacing via `--cfm-sticky-pt` / `--cfm-sticky-pb`