@explorer02/cfm-survey-sdk 0.2.4 → 0.2.5

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 (31) hide show
  1. package/dist/cli/index.js +34 -33
  2. package/dist/cli/index.mjs +35 -34
  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 +39 -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 +4 -2
  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-config-handoff.md +55 -9
  19. package/templates/docs/00-integration/wizard-preview-build-guide.md +12 -7
  20. package/templates/docs/00-integration/wizard-question-type-styling.md +4 -2
  21. package/templates/docs/00-integration/wizard-troubleshooting.md +80 -0
  22. package/templates/docs/01-components/10-header-footer.md +3 -3
  23. package/templates/docs/MANIFEST.json +30 -13
  24. package/templates/docs/index.md +7 -9
  25. package/templates/docs/templates/deploy-to-aws.sh +74 -0
  26. package/templates/docs/templates/implementation_plan.md +19 -12
  27. package/templates/wizard-dist/assets/{PreviewMock-DgHfrVeb.js → PreviewMock-AoZdAEPZ.js} +1 -1
  28. package/templates/wizard-dist/assets/{TypePanel-CFVC3Ptn.js → TypePanel-39FnbtvG.js} +1 -1
  29. package/templates/wizard-dist/assets/index-CWKdsJOp.js +34 -0
  30. package/templates/wizard-dist/index.html +1 -1
  31. package/templates/wizard-dist/assets/index-DYK3X1e5.js +0 -34
@@ -1,144 +1,123 @@
1
1
  # UI Customization Wizard
2
2
 
3
- > Optional **run** after Phase 6 verify. **Wizard-ready build** is mandatory in Phase 5 — see [`agent-execution-flow.md`](agent-execution-flow.md).
4
- > **Wait + apply protocol:** [`wizard-config-handoff.md`](wizard-config-handoff.md).
3
+ > Optional **run** after Phase 6 verify. **Wizard-ready build** is mandatory in Phase 5 — see [`agent-execution-flow.md`](agent-execution-flow.md).
5
4
 
6
- **Before the client opts in:** agents must already have wired [`wizard-preview-build-guide.md`](wizard-preview-build-guide.md) artifacts so AWS wizard previews update live (`--cfm-*` CSS vars + `data-cfm-*` content hooks).
5
+ ## Default: local wizard (`customize`)
7
6
 
8
- ## When to Use
9
-
10
- After **Phase 6** (verify + `npm run dev`), ask the client:
11
-
12
- > *"Your survey is running locally. Would you like to customize the UI through the web wizard?"*
13
-
14
- - **Yes** → Phase 6b: run `npx cfm-sdk customize-ui` (AWS) or `customize` (local)
15
- - **No** → proceed to Phase 7 deploy
16
-
17
- ## AWS flow (production) — agent waits for client
7
+ When the client says **yes** to customization in agent chat, **always run:**
18
8
 
19
9
  ```bash
20
- export CFM_INSTANCE_ID="..." CFM_DEPLOY_API_BASE="http://43.204.26.213:3000"
21
- npx cfm-sdk customize-ui
10
+ npx cfm-sdk customize
22
11
  ```
23
12
 
24
- **Default = review mode.** The CLI:
13
+ This is the **recommended default** because it:
25
14
 
26
- 1. Resolves seed config from project (`survey-ui-config.json` `survey-theme.css` `Header.tsx` → defaults)
27
- 2. Exports component preview pages (`export-previews`) one HTML per preview key (`header`, `footer`, `MCQ_single`, …)
28
- 3. Uploads preview HTML to S3 via EC2 API (`POST /wizard/session/start` → presigned PUTs → `upload/complete`)
29
- 4. Prints the **deployed wizard link** and opens it for the agent **agent must copy this link to the client**
30
- 5. **Polls until client submits** (`GET /wizard/config/:surveyId` `status: ready`)
31
- 6. Writes review artifacts — **does not auto-apply to codebase**
15
+ - Serves wizard + component previews from **one local server** (`localhost:4200`)
16
+ - Auto-exports all **11** question-type previews from agent components
17
+ - Writes `survey-ui-config.json` **directly** on save no S3, no session polling
18
+ - Cleans up automatically when the CLI exits (no orphan S3 garbage)
19
+ - Updates live previews via the same iframe + preview bridge as production
32
20
 
33
- ### Client wizard link (after S3 upload)
21
+ **Agent script after client says yes:**
34
22
 
35
- Once previews are on S3, the CLI prints:
23
+ > *"I'll open the customization wizard in your browser. Complete all steps and click **Review & Build** when done — I'll apply your changes automatically."*
24
+
25
+ The CLI **blocks** until the client saves. Wait for:
36
26
 
37
27
  ```
38
- Previews uploaded
39
- 🔗 Client wizard link — share with the client:
40
- http://43.204.26.213:3000/wizard-app/index.html?session=<uuid>&secret=<hex>
28
+ UI configuration saved to survey-ui-config.json
41
29
  ```
42
30
 
43
- | Who | Uses |
44
- |-----|------|
45
- | **Client** | Opens the **deployed EC2 wizard link** only — customizes branding, colors, question-type tokens; previews update live from S3-backed component pages |
46
- | **Agent** | Keeps `customize-ui` running (polls API); does **not** ask client to use localhost |
31
+ Then apply per [`apply-ui-config.md`](apply-ui-config.md).
47
32
 
48
- **URL shape:** `{CFM_DEPLOY_API_BASE}/wizard-app/index.html?session={sessionId}&secret={sessionSecret}`
33
+ ### Who can use it
49
34
 
50
- Default production API: `http://43.204.26.213:3000` (see `MANIFEST.json` `apiBaseDefault`).
35
+ | User | Can use `customize`? |
36
+ |------|---------------------|
37
+ | Client on **same machine** as agent (Cursor chat on dev laptop) | **Yes — default** |
38
+ | Client on **another device** | **No** — use EC2 fallback below |
51
39
 
52
- **Agent script (after CLI prints the link):**
40
+ `localhost:4200` is only reachable on the machine running the CLI.
53
41
 
54
- > *"I've uploaded your survey component previews. Open this link to customize the UI: [paste wizard URL]. When you're done, click **Review & Build** on the last step. I'll wait here until your changes are saved."*
42
+ ---
55
43
 
56
- **On success, CLI prints:**
57
- ```
58
- Configuration ready
59
- Final: survey-ui-config.final.json
60
- Diff: survey-ui-config.diff.md
61
- Apply when ready: npx cfm-sdk confirm-ui-config
44
+ ## EC2 fallback (`customize-ui`) — remote clients only
45
+
46
+ Use **only** when the client must customize from another PC/tablet/network:
47
+
48
+ ```bash
49
+ export CFM_INSTANCE_ID="..." CFM_DEPLOY_API_BASE="http://43.204.26.213:3000"
50
+ npx cfm-sdk customize-ui
62
51
  ```
63
52
 
64
- **Agent must:**
65
- - [ ] Keep terminal open until CLI exits 0
66
- - [ ] **Copy the deployed wizard link from CLI output and send it to the client** (after previews upload to S3)
67
- - [ ] Tell client: *"Please complete the wizard and click Review & Build."*
68
- - [ ] Read `survey-ui-config.diff.md` before Phase 6c
69
- - [ ] Apply codebase per [`apply-ui-config.md`](apply-ui-config.md) from **`.final.json`**
70
- - [ ] Run `npx cfm-sdk confirm-ui-config` after codebase apply
53
+ - Uploads previews to EC2 disk (local-server model on remote host)
54
+ - Prints EC2 wizard link agent sends link to client
55
+ - CLI **polls** until client submits writes `.final.json` + `.diff.md`
56
+ - Requires deploy-api on EC2 + `CFM_INSTANCE_ID`
71
57
 
72
- See [`wizard-config-handoff.md`](wizard-config-handoff.md) for full handoff checklist.
58
+ See [`wizard-api.md`](wizard-api.md) and [`wizard-config-handoff.md`](wizard-config-handoff.md).
73
59
 
74
- ### Legacy immediate write
60
+ **Do not** use `customize-ui` when client and agent share the same machine — `customize` is simpler and more reliable.
75
61
 
76
- ```bash
77
- npx cfm-sdk customize-ui --apply
78
- ```
62
+ ---
79
63
 
80
- Writes `survey-ui-config.json` + logo immediately (no diff review). Phase 6c apply still required.
64
+ ## When to ask (INPUT 3)
81
65
 
82
- ### Detached session
66
+ After Phase 6 verify + dev server:
83
67
 
84
- ```bash
85
- npx cfm-sdk customize-ui --no-wait
86
- # Later, when client done:
87
- export CFM_WIZARD_SESSION_ID="..."
88
- npx cfm-sdk fetch-ui-config
89
- ```
68
+ > *"Your survey is running locally. Would you like to customize the UI through the web wizard?"*
90
69
 
91
- ## Local flow (development)
70
+ - **Yes** `npx cfm-sdk customize` (default)
71
+ - **Yes, but I'm on a different device** → `npx cfm-sdk customize-ui`
72
+ - **No** → Phase 7 deploy ask
92
73
 
93
- ```bash
94
- npx cfm-sdk customize
74
+ ---
75
+
76
+ ## How local wizard works
77
+
78
+ ```mermaid
79
+ sequenceDiagram
80
+ participant Agent as Agent CLI
81
+ participant Srv as localhost:4200
82
+ participant Wizard as Wizard SPA
83
+ participant Prev as out/previews/
84
+
85
+ Agent->>Agent: export-previews (all 11 types)
86
+ Agent->>Srv: customize serves wizard + previews
87
+ Wizard->>Srv: GET /api/inventory
88
+ Wizard->>Prev: iframe /previews/MCQ_single/...
89
+ Wizard->>Srv: POST /api/save-config
90
+ Srv->>Agent: survey-ui-config.json written, CLI exits
95
91
  ```
96
92
 
97
- Opens browser at `http://localhost:4200`. **Blocks** until client saves → writes `survey-ui-config.json` directly. Then Phase 6c apply from that file (no `confirm-ui-config`).
93
+ | Route | Purpose |
94
+ |-------|---------|
95
+ | `/api/inventory` | Preview manifest + seed config |
96
+ | `/previews/{key}/index.html` | Component-wise live preview |
97
+ | `/api/save-config` | Client submit → JSON on disk |
98
+ | `/api/upload-logo` | Logo → `public/` |
99
+
100
+ ---
98
101
 
99
102
  ## Seed config
100
103
 
101
104
  | Priority | Source |
102
105
  |----------|--------|
103
106
  | 1 | `./survey-ui-config.json` (draft) |
104
- | 2 | `src/styles/survey-theme.css` (`--cfm-*` vars) |
105
- | 3 | `implementation_plan.md` branding hints |
106
- | 4 | `Header.tsx` — `data-cfm-logo` / `data-cfm-logo-text` |
107
+ | 2 | `src/styles/survey-theme.css` |
108
+ | 3 | `implementation_plan.md` |
109
+ | 4 | `Header.tsx` logo contract |
107
110
  | 5 | SDK defaults |
108
111
 
109
- Debug: `npx cfm-sdk resolve-ui-config --write`
110
-
111
- ## Wizard Steps
112
-
113
- | Step | Controls |
114
- |------|----------|
115
- | Identity | Survey title, company name, tab title, thank-you message |
116
- | Logo | Upload S3 (AWS) or `public/` (local) |
117
- | Header / Footer | Logo box, company, links, copyright, colors |
118
- | Theme & Colors | Presets, palette, question card (cell selected + focus ring) |
119
- | Layout & Chrome | Header/footer toggles, nav, width, font |
120
- | Question Types | Per-type tokens + format preview tabs |
121
- | Testing & Tokens | Placeholders, custom fields, debug |
122
- | Deploy | AWS or Vercel target |
123
- | Review & Build | **Client submits** — triggers CLI poll success |
124
-
125
- ## Output artifacts
126
-
127
- | File | When |
128
- |------|------|
129
- | `survey-ui-config.final.json` | AWS — client's submitted config (apply source) |
130
- | `survey-ui-config.diff.md` | AWS — every changed path (audit before apply) |
131
- | `survey-ui-config.json` | Active config (seed until `confirm-ui-config`; or final for local/`--apply`) |
132
-
133
- Apply tokens per [`apply-ui-config.md`](apply-ui-config.md).
134
-
135
- ## Agent Checklist
136
-
137
- - [ ] Phase 5: components wired per [`wizard-preview-build-guide.md`](wizard-preview-build-guide.md)
138
- - [ ] Client opted in after localhost preview (INPUT 3)
139
- - [ ] Ran `customize-ui` or `customize` and **waited** for CLI exit 0
140
- - [ ] Read `survey-ui-config.diff.md` (AWS review mode)
141
- - [ ] Phase 6c: applied **all** diff paths per [`apply-ui-config.md`](apply-ui-config.md)
142
- - [ ] AWS: ran `confirm-ui-config` after codebase apply
143
- - [ ] Re-ran verify script + build
144
- - [ ] Did not modify SDK integration (`onAction`, dispatch logic)
112
+ ---
113
+
114
+ ## Agent checklist
115
+
116
+ - [ ] Phase 5: wizard-preview artifacts wired
117
+ - [ ] Client opted in (INPUT 3)
118
+ - [ ] Ran **`npx cfm-sdk customize`** (default) and waited for CLI exit 0
119
+ - [ ] Read `survey-ui-config.json` (or `.diff.md` if used EC2 fallback)
120
+ - [ ] Phase 6c: applied per [`apply-ui-config.md`](apply-ui-config.md)
121
+ - [ ] Re-ran verify + build
122
+
123
+ See [`wizard-troubleshooting.md`](wizard-troubleshooting.md) if previews show mock UI.
@@ -1,134 +1,126 @@
1
- # Wizard API (`/wizard/*`)
1
+ # Wizard API — EC2 fallback (`customize-ui` only)
2
2
 
3
- > EC2 middle API routes for AWS-hosted UI customization. Consumed by `npx cfm-sdk customize-ui` and the survey-wizard SPA.
3
+ > **Default wizard is `npx cfm-sdk customize` on localhost** no EC2 API needed.
4
+ > This doc applies **only** when the client customizes from another device.
4
5
 
5
- Base URL: `CFM_DEPLOY_API_BASE` — production default: `http://43.204.26.213:3000`
6
+ Base URL: `CFM_DEPLOY_API_BASE` — default: `http://43.204.26.213:3000`
6
7
 
7
- ## Client wizard link (deployed)
8
+ ## Architecture
8
9
 
9
- After `customize-ui` uploads component previews to S3, the CLI prints a **deployed wizard URL** for the client:
10
-
11
- ```
12
- {CFM_DEPLOY_API_BASE}/wizard-app/index.html?session={sessionId}&secret={sessionSecret}
10
+ ```mermaid
11
+ flowchart LR
12
+ CLI[customize-ui CLI] -->|PUT preview files| Disk[EC2 disk data/wizard-sessions/]
13
+ Client[Client browser] --> SPA[wizard-app SPA]
14
+ SPA -->|GET /api/inventory| API[deploy-api]
15
+ SPA -->|iframe /previews/...| Disk
16
+ SPA -->|POST /api/save-config| API
17
+ API -->|final config + logo| S3[S3 hosting bucket]
18
+ CLI -->|poll GET /wizard/config| API
13
19
  ```
14
20
 
15
- Example:
21
+ | During session | Storage |
22
+ |----------------|---------|
23
+ | Preview HTML | EC2 disk (`WIZARD_DATA_DIR/{sessionId}/previews/`) |
24
+ | Seed config | EC2 disk (`seed-config.json`) |
25
+ | Temp logo | EC2 disk (`assets/`) |
26
+ | **On submit** | Final JSON + permanent logo → S3 |
27
+
28
+ Previews are **not** loaded from S3 during customization — avoids "Storage service unavailable" on preview iframes.
29
+
30
+ ## Client wizard link
16
31
 
17
32
  ```
18
- http://43.204.26.213:3000/wizard-app/index.html?session=abc-123&secret=fe7698d0...
33
+ {CFM_DEPLOY_API_BASE}/wizard-app/index.html?session={sessionId}&secret={sessionSecret}
19
34
  ```
20
35
 
21
- | Piece | Role |
36
+ | Route | Role |
22
37
  |-------|------|
23
- | `/wizard-app/` | Wizard SPA on EC2 (customization forms + preview panel) |
24
- | `session` + `secret` | Tie the client to the S3 preview session |
25
- | S3 `previews/` | Component-wise HTML (`header`, `footer`, `MCQ_single`, …) — loaded via EC2 proxy |
26
-
27
- **Agent:** copy link from CLI → send to client. **Client:** opens link only (no localhost). **Agent:** keeps CLI polling until submit.
28
-
29
- `wizardUrl` in `POST /wizard/session/start` response is this full URL (built by `getWizardPublicUrl` in deploy-api).
30
-
31
- ## Auth
32
-
33
- | Caller | Header |
34
- |--------|--------|
35
- | CLI | `Authorization: Bearer {CFM_INSTANCE_ID}` |
36
- | Wizard SPA | `X-Wizard-Session: {secret}` + `X-Wizard-Session-Id: {sessionId}` |
37
-
38
- ## Endpoints
38
+ | `/wizard-app/` | Wizard SPA |
39
+ | `/api/inventory` | Session metadata + `previewManifest` (local-server API) |
40
+ | `/previews/{sessionId}/{key}/index.html` | Component preview iframes |
41
+ | `/api/save-config` | Client submit (same as local `customize`) |
39
42
 
40
- ### `POST /wizard/session/start`
41
-
42
- Starts session; returns presigned PUT URLs for preview HTML files.
43
-
44
- **Body:** `{ "files": [...], "surveyTypes": ["MCQ", "NPS_SCALE"], "initialConfig": { ... } }`
43
+ ## Local-server routes (`/api/*`, `/previews/*`)
45
44
 
46
- `initialConfig` is optional. When present, the CLI sends the agent's resolved UI config (from draft `survey-ui-config.json`, parsed `survey-theme.css`, `Header.tsx` logo contract, or defaults). The API normalizes, validates, stores on the session, and persists to `sites/{surveyId}/wizard-sessions/{sessionId}/seed-config.json` for restart durability.
45
+ Same contract as `packages/sdk/src/cli/customize.ts`:
47
46
 
48
- **Response:** `{ sessionId, sessionSecret, wizardUrl, uploads[] }`
47
+ ### `GET /api/inventory?session=&secret=`
49
48
 
50
- ### `POST /wizard/previews/upload/complete`
49
+ Returns `{ surveyTypes, instanceId, previewUrl, previewManifest, initialConfig, localServer: true }`.
51
50
 
52
- **Body:** `{ "sessionId": "uuid" }`
51
+ ### `GET /api/preview-url`
53
52
 
54
- Activates session; builds same-origin `previewManifest` (API proxy URLs — session previews are private in S3).
53
+ Health check for preview availability indicator.
55
54
 
56
- ### `GET /wizard/preview/:sessionId/:component/index.html?secret=...`
55
+ ### `POST /api/upload-logo?session=&secret=`
57
56
 
58
- Serves preview HTML from S3 for wizard iframes. Auth via `secret` query param (iframes cannot send session headers).
57
+ Body: `{ filename, base64 }` stores logo on EC2 disk for session.
59
58
 
60
- ### `GET /wizard/session/:sessionId`
59
+ ### `POST /api/save-config?session=&secret=`
61
60
 
62
- Wizard boot returns `surveyTypes`, `previewManifest`, `sessionExpiresAt`, and `initialConfig` when the session was seeded.
61
+ Body: full `survey-ui-config.json`. Persists final config + logo to S3, cleans session disk.
63
62
 
64
- **Response:** `{ surveyTypes, instanceId, previewManifest, sessionExpiresAt, initialConfig? }`
63
+ ## Session management (`/wizard/*`)
65
64
 
66
- The wizard SPA calls `loadConfig(initialConfig)` on boot so the client edits on top of the agent build.
65
+ ### `POST /wizard/session/start`
67
66
 
68
- ### `POST /wizard/logo`
67
+ **Auth:** `Authorization: Bearer {JWT}`
69
68
 
70
- **Body:** `{ "filename": "logo.png", "base64": "data:image/png;base64,..." }`
69
+ **Body:** `{ files, surveyTypes, initialConfig }`
71
70
 
72
- Max 512KB. Stores in session S3 prefix.
71
+ **Response:** `{ sessionId, sessionSecret, wizardUrl, uploads[], localServer: true }`
73
72
 
74
- ### `POST /wizard/complete`
73
+ `uploads[].uploadUrl` `PUT /wizard/session/:sessionId/preview-file?path=previews/...` (EC2 disk, not S3 presign).
75
74
 
76
- **Body:** full `survey-ui-config.json` object.
75
+ ### `PUT /wizard/session/:sessionId/preview-file?path=...`
77
76
 
78
- On success:
77
+ **Auth:** `X-Wizard-Session` + `X-Wizard-Session-Id`
79
78
 
80
- 1. Copies uploaded logo to **permanent** S3 key: `sites/{surveyId}/assets/{fileName}`
81
- 2. Saves final config to `sites/{surveyId}/wizard/config.json` (with `logoKey` + `logoUrl` metadata)
82
- 3. **Deletes** entire wizard session folder `sites/{surveyId}/wizard-sessions/{sessionId}/` (previews, seed-config, temp logo)
83
- 4. Returns public logo URL: `{ logoUrl, logoKey, logoFileName }`
79
+ Raw file body written to session disk.
84
80
 
85
- Public logo URL format: `{CLOUDFRONT_BASE_URL}/sites/{surveyId}/assets/{fileName}` — readable by anyone with the link (via CloudFront, bucket stays private).
81
+ ### `POST /wizard/previews/upload/complete`
86
82
 
87
- ### `GET /wizard/config/:surveyId`
83
+ **Auth:** JWT. Verifies all files on disk; activates session; builds manifest with `/previews/{sessionId}/…` URLs.
88
84
 
89
- CLI poll. Query `?sessionId=` to scope to current session.
85
+ ### `POST /wizard/session/quit`
90
86
 
91
- **Pending:** `{ "status": "pending" }`
92
- **Ready:** `{ "status": "ready", "config": { ... }, "logoUrl": "...", "logoKey": "...", "sessionId": "..." }`
87
+ Deletes session disk folder + in-memory session. CLI poll returns `status: abandoned`.
93
88
 
94
- `config.global.logo.url` is populated with the public CloudFront URL when a logo was uploaded.
89
+ ### `GET /wizard/config/:surveyId?sessionId=`
95
90
 
96
- ### `GET /wizard/logo/:surveyId/:fileName`
91
+ CLI poll after client submit.
97
92
 
98
- Returns `{ "downloadUrl": "presigned-get" }` for CLI to save logo to agent `public/` (fallback when CloudFront is not reachable from agent network).
93
+ - **pending** waiting
94
+ - **abandoned** — client quit
95
+ - **ready** — `{ config, logoUrl, … }`
99
96
 
100
97
  ## Env (deploy-api)
101
98
 
102
99
  ```bash
103
- WIZARD_DEV_URL=http://localhost:5173 # dev only
104
- WIZARD_PATH=/sites/_wizard # prod CloudFront path
105
- WIZARD_SESSION_TTL_MS=7200000 # 2h expired sessions trigger S3 GC
100
+ WIZARD_DATA_DIR=./data/wizard-sessions # preview + seed + temp logo on disk
101
+ WIZARD_SESSION_TTL_MS=7200000
102
+ HOSTING_BUCKET=... # final config + permanent logo only
103
+ CLOUDFRONT_BASE_URL=...
106
104
  ```
107
105
 
108
- ## AWS console (one-time logo public URL)
106
+ ## IAM (EC2 instance role)
109
107
 
110
- Logos are **not** public on S3 directly. They are served through **CloudFront** (same distribution as survey deploys).
108
+ Required for **submit** (not previews):
111
109
 
112
- Verify (usually already done if deploy works):
110
+ - `s3:PutObject`, `s3:GetObject` on hosting bucket
111
+ - `cloudfront:CreateInvalidation` (logo cache bust)
113
112
 
114
- 1. **CloudFront** → your distribution → Origins → hosting bucket is the origin
115
- 2. **Origin access** → OAC/OAI allows CloudFront to read the bucket (bucket policy blocks public access)
116
- 3. **Behavior** → default or `sites/*` path serves objects from the bucket
117
-
118
- No extra bucket policy for public read is required. The public URL is:
119
-
120
- `https://{CLOUDFRONT_DOMAIN}/sites/{surveyId}/assets/{logoFileName}`
121
-
122
- **IAM (EC2 instance role)** must allow: `s3:PutObject`, `s3:GetObject`, `s3:DeleteObject`, `s3:ListBucket` on the hosting bucket, plus `cloudfront:CreateInvalidation` on the distribution.
123
-
124
- ## CLI flow (review mode — default)
113
+ ## CLI flow
125
114
 
126
115
  ```bash
127
116
  export CFM_INSTANCE_ID="..." CFM_DEPLOY_API_BASE="http://43.204.26.213:3000"
128
117
  npx cfm-sdk customize-ui
129
- # export-previews → upload component previews to S3 → print client wizard link →
130
- # POLL until client submits → survey-ui-config.final.json + .diff.md
131
- # Agent applies codebase → npx cfm-sdk confirm-ui-config
132
118
  ```
133
119
 
134
- See [`wizard-config-handoff.md`](wizard-config-handoff.md).
120
+ 1. `export-previews` on agent machine
121
+ 2. Upload preview files to EC2 disk
122
+ 3. Print client wizard link
123
+ 4. Poll until `status: ready`
124
+ 5. Write `.final.json` + `.diff.md`
125
+
126
+ See [`wizard-config-handoff.md`](wizard-config-handoff.md), [`ui-customization-wizard.md`](ui-customization-wizard.md).
@@ -11,14 +11,51 @@ 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
+ ---
57
+
58
+ ## Remote client flow — `customize-ui` (fallback only)
22
59
 
23
60
  ### Step 1 — Agent runs CLI (and waits)
24
61
 
@@ -31,12 +68,12 @@ npx cfm-sdk customize-ui
31
68
  **Default is review mode** (no flags). The CLI will:
32
69
 
33
70
  1. Export component preview pages (`export-previews`)
34
- 2. Upload preview HTML to S3 (one page per component key `header`, `footer`, `MCQ_single`, …)
71
+ 2. Upload preview HTML to **EC2 disk** (local-server model same as agent `customize`)
35
72
  3. Print the **deployed EC2 wizard link** — agent **must share this URL with the client**
36
73
  4. **Poll every ~3s** (`GET /wizard/config/:surveyId`) until the client submits
37
74
  5. Print `✅ Configuration ready` when `status === 'ready'`
38
75
 
39
- ### Deployed wizard link (give to client after S3 upload)
76
+ ### Deployed wizard link (give to client after preview upload)
40
77
 
41
78
  The client does **not** use localhost. After previews are uploaded, the CLI prints:
42
79
 
@@ -45,8 +82,9 @@ The client does **not** use localhost. After previews are uploaded, the CLI prin
45
82
  http://43.204.26.213:3000/wizard-app/index.html?session=<uuid>&secret=<hex>
46
83
  ```
47
84
 
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`)
85
+ - **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`)
86
+ - **Wizard UI:** served from EC2 at `/wizard-app/`; inventory via `GET /api/inventory`
87
+ - **On submit:** final config + permanent logo → S3 only
50
88
 
51
89
  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
90
 
@@ -71,13 +109,16 @@ Set `CFM_DEPLOY_API_BASE=http://43.204.26.213:3000` (or your EC2 host). The link
71
109
 
72
110
  Poll response includes `logoUrl` and `logoKey` — CLI merges `logo.url` into final JSON.
73
111
 
112
+ **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.
113
+
74
114
  **If all diff counts are 0:** client submitted without changes — still verify; skip heavy apply.
75
115
 
76
116
  ### S3 garbage collection
77
117
 
78
118
  | When | Deleted | Kept |
79
119
  |------|---------|------|
80
- | Client **Review & Build** | `wizard-sessions/{sessionId}/` (previews, seed-config, temp logo) | `sites/{surveyId}/assets/{logo}`, `wizard/config.json` |
120
+ | Client **Review & Build** | EC2 session disk folder (`data/wizard-sessions/{sessionId}/`) | `sites/{surveyId}/assets/{logo}`, `wizard/config.json` |
121
+ | Client **Quit** (or tab close) | Same session prefix — `POST /wizard/session/quit` | N/A |
81
122
  | Session **expires** (2h default) | Same session prefix — auto sweep every 5 min | N/A |
82
123
 
83
124
  ### Step 3 — Agent reads diff before touching code
@@ -216,6 +257,8 @@ npx cfm-sdk fetch-ui-config
216
257
  - [ ] `src/styles/survey-theme.css` fully synced to final config
217
258
  - [ ] All `data-cfm-*` content hooks updated
218
259
  - [ ] Logo file exists in `public/` when config has `global.logo.fileName`
260
+ - [ ] `out/{fileName}` exists after build when logo configured (AWS deploy gate)
261
+ - [ ] `Header.tsx` uses `data-cfm-logo src="./{fileName}"` — not `data:` or `/assets/` URL
219
262
  - [ ] `placeholders` / `customFields` / `debug` wired if present in final
220
263
  - [ ] AWS: ran `npx cfm-sdk confirm-ui-config` after codebase apply
221
264
  - [ ] `verify-agent-build.sh` + `npm run build` pass
@@ -228,11 +271,14 @@ npx cfm-sdk fetch-ui-config
228
271
  | Mistake | Fix |
229
272
  |---------|-----|
230
273
  | Killed CLI during poll | Re-run `customize-ui`; client re-submits |
274
+ | Client quit wizard | CLI exits with abandon message; S3 GC done — re-run `customize-ui` for new session |
231
275
  | Applied from `survey-ui-config.json` while still seed | Use `.final.json` or run `confirm-ui-config` after apply |
232
276
  | Only changed primary color, ignored diff | Read **entire** `diff.md` — clients often change 20+ paths |
233
277
  | Skipped `confirm-ui-config` | Active JSON stays seed; next wizard re-open is wrong |
234
278
  | Changed `Question.tsx` dispatch during apply | UI tokens only — see `apply-ui-config.md` scope |
235
279
  | Proceeded to deploy before apply | Complete Phase 6c first |
280
+ | Logo works in wizard but broken on CloudFront | Preview uses memory; deploy needs `public/` → `out/` → S3 — see `aws-deploy.md` § Logos |
281
+ | Used `global.logo.url` as Header src | Use `./{fileName}` only; download assets URL via `confirm-ui-config` |
236
282
 
237
283
  ---
238
284
 
@@ -20,13 +20,13 @@ The wizard does **not** re-render your React app. It loads **static preview page
20
20
  sequenceDiagram
21
21
  participant Agent as Agent_build
22
22
  participant CLI as export_previews
23
- participant S3 as S3_previews
23
+ participant Disk as EC2_or_agent_disk
24
24
  participant Wizard as Wizard_SPA
25
25
  participant Iframe as Preview_iframe
26
26
 
27
27
  Agent->>Agent: Build components with token contract
28
- Agent->>CLI: customize-ui / export-previews
29
- CLI->>S3: Upload HTML + JS + CSS
28
+ Agent->>CLI: customize (default) / customize-ui (remote)
29
+ CLI->>Disk: Upload HTML + JS + CSS (local-server)
30
30
  Wizard->>Iframe: Load chrome / MCQ_single / etc.
31
31
  Wizard->>Iframe: postMessage SNAPSHOT + DELTA
32
32
  Iframe->>Iframe: Apply --cfm-* vars + content patches
@@ -271,6 +271,7 @@ CLI resolution order:
271
271
  - **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
272
  - **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
273
  - **After wizard upload:** `global.logo.fileName` in saved config takes precedence — do not fall back to `Header.tsx` or scan `public/logo_*`.
274
+ - **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
275
 
275
276
  Debug without opening wizard:
276
277
 
@@ -284,20 +285,20 @@ Keep draft JSON and `survey-theme.css` **in sync** (same primary color, title, c
284
285
 
285
286
  ## How `export-previews` uses your code
286
287
 
287
- When the client opts in, `customize-ui` runs `export-previews`:
288
+ When the client opts in, **`npx cfm-sdk customize`** (default) or `customize-ui` (remote) runs `export-previews`:
288
289
 
289
290
  1. Copies `src/components/`, `src/lib/`, `public/`, `survey-theme.css` into a temp Vite harness
290
291
  2. Stubs `next/image` and `next/dynamic` for static build
291
292
  3. Builds one HTML page per preview key (`header`, `chrome`, `MCQ_single`, …) with canonical fixtures
292
293
  4. Injects `preview-bridge.inline.js` into each `index.html`
293
- 5. Uploads each preview page to S3 via EC2 presigned PUTs
294
+ 5. Uploads each preview page to **EC2 disk** via `PUT /wizard/session/:id/preview-file` (local-server model)
294
295
  6. Prints the **deployed wizard link** for the client:
295
296
 
296
297
  ```
297
298
  http://43.204.26.213:3000/wizard-app/index.html?session=<uuid>&secret=<hex>
298
299
  ```
299
300
 
300
- 7. Wizard iframes load previews via EC2 proxy (`GET /wizard/preview/:sessionId/:component/...`)
301
+ 7. Wizard iframes load previews from `/previews/{sessionId}/{component}/…` on the same EC2 host (`GET /api/inventory` + local-server API)
301
302
 
302
303
  **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
304
 
@@ -356,6 +357,10 @@ npx cfm-sdk export-previews
356
357
  | Logo `<Image>` without `data-cfm-logo` | Logo step doesn't update preview | Add `data-cfm-logo` to img |
357
358
  | Only Phase 6c tokenization | Worked after wizard, not during | Tokenize in Phase 5 (this guide) |
358
359
  | Skipped `export-previews` after component edits | Wizard shows old UI | Re-run `customize-ui` |
360
+ | Used `customize-ui` when client is on same machine | Unnecessary complexity | Use **`customize`** (default) |
361
+ | `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 |
362
+ | Missing `data-cfm-progress` / `data-cfm-question-number` | Layout toggles don't work | Wire hooks per § Layer 2 table |
363
+ | Hardcoded brand hex in scales | Only NPS-like paths look correct | Use `--cfm-*` + `selectionStyles.ts` |
359
364
 
360
365
  ---
361
366
 
@@ -365,7 +370,7 @@ npx cfm-sdk export-previews
365
370
  |-------|----------------|
366
371
  | **5 BUILD** | Implement components per this guide + UI specs; draft config + theme |
367
372
  | **6 VERIFY** | `npm run build`, verify script, localhost preview |
368
- | **6b WIZARD** (optional) | Client says yes → `customize-ui`**wait** for submitread `.diff.md` |
373
+ | **6b WIZARD** (optional) | Client says yes → **`npx cfm-sdk customize`** → wait for saveapply config |
369
374
  | **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
375
  | **7 DEPLOY** | Full static build upload (separate from wizard preview files) |
371
376