@explorer02/cfm-survey-sdk 0.2.7 → 0.2.9
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/dist/cli/index.js +38 -41
- package/dist/cli/index.mjs +36 -39
- package/package.json +1 -1
- package/templates/docs/00-integration/agent-execution-flow.md +7 -9
- package/templates/docs/00-integration/agent-operating-contract.md +2 -1
- package/templates/docs/00-integration/component-checklist.md +1 -0
- package/templates/docs/00-integration/ui-customization-wizard.md +29 -7
- package/templates/docs/00-integration/wizard-chrome-contract.md +11 -1
- package/templates/docs/00-integration/wizard-config-handoff.md +11 -9
- package/templates/docs/00-integration/wizard-post-customize-build.md +8 -2
- package/templates/docs/00-integration/wizard-preview-build-guide.md +0 -2
- package/templates/docs/00-integration/wizard-question-type-styling.md +7 -6
- package/templates/docs/00-integration/wizard-troubleshooting.md +20 -4
- package/templates/docs/03-ui-specs/README.md +1 -1
- package/templates/docs/MANIFEST.json +0 -3
- package/templates/docs/index.md +4 -6
- package/templates/docs/templates/CsatMatrixScale.tsx +56 -53
- package/templates/docs/templates/CustomSliderTrack.tsx +17 -8
- package/templates/docs/templates/FileUploadScale.tsx +11 -3
- package/templates/docs/templates/Header.tsx +32 -48
- package/templates/docs/templates/HeatmapScale.tsx +7 -4
- package/templates/docs/templates/LikertMatrixScale.tsx +58 -43
- package/templates/docs/templates/MatrixDropdown.tsx +12 -11
- package/templates/docs/templates/Question.tsx +4 -23
- package/templates/docs/templates/RankOrderScale.tsx +46 -6
- package/templates/docs/templates/RatingScale.tsx +38 -0
- package/templates/docs/templates/SliderMatrixScale.tsx +4 -3
- package/templates/docs/templates/verify-agent-build.sh +17 -0
- package/templates/preview-harness/preview-bridge.inline.js +10 -0
- package/templates/preview-harness/previewPages.ts +5 -7
- package/templates/preview-harness/vite-app/src/QuestionPreview.tsx +11 -6
- package/templates/preview-harness/vite-app/src/fixtures/questions.ts +2 -10
- package/templates/preview-harness/vite-app/src/preview-live-overrides.css +11 -6
- package/templates/previewBridge.ts +13 -0
- package/templates/survey-theme.css +17 -17
- package/templates/wizard-dist/assets/{PreviewMock-tTMvwuEy.js → PreviewMock-CysRws9G.js} +1 -1
- package/templates/wizard-dist/assets/TypePanel-DWX1LL3q.js +1 -0
- package/templates/wizard-dist/assets/index-DIuc7AU2.js +34 -0
- package/templates/wizard-dist/assets/index-pCM8n0FT.css +1 -0
- package/templates/wizard-dist/index.html +2 -2
- package/templates/docs/00-integration/wizard-customization-catalog.md +0 -391
- package/templates/wizard-dist/assets/TypePanel-B9Ls7BSq.js +0 -1
- package/templates/wizard-dist/assets/index-CjkIlOUI.css +0 -1
- package/templates/wizard-dist/assets/index-CoCrnnxt.js +0 -34
package/dist/cli/index.mjs
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
var jo=Object.defineProperty;var we=(e=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(e,{get:(o,t)=>(typeof require<"u"?require:o)[t]}):e)(function(e){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+e+'" is not supported')});var B=(e,o)=>()=>(e&&(o=e(e=0)),o);var Ie=(e,o)=>{for(var t in o)jo(e,t,{get:o[t],enumerable:!0})};var c,U=B(()=>{"use strict";c={reset:"\x1B[0m",bold:"\x1B[1m",green:"\x1B[32m",red:"\x1B[31m",cyan:"\x1B[36m",yellow:"\x1B[33m",dim:"\x1B[2m"}});var Q,be=B(()=>{"use strict";Q=["MCQ","TEXTFIELD","NPS_SCALE","CFM_MATRIX","CSAT_MATRIX","RATING_MATRIX","SLIDER_MATRIX","FILE_UPLOAD","TEXT_AND_MEDIA","HEATMAP","RANK_ORDER"]});function Mo(e){let o={};for(let t of e)qe[t]&&(o[t]={...qe[t]});return o}function Uo(e=[],o){return{version:"1.0",instanceId:o,surveyTypes:e,global:{surveyTitle:"Customer Feedback Survey",companyName:"Sprinklr",browserTabTitle:"Customer Feedback Survey",thankYouMessage:"Thank you for your valuable feedback!",logo:{fileName:null,url:null},header:{height:120,logoBoxWidth:120,logoBoxHeight:120,logoPadding:10,logoPlacement:"left",showCompanyName:!0,companyNamePlacement:"left",companyNameFontSize:18,companyNameFontWeight:600,companyNameColor:"#1A1F36",backgroundColor:"#FFFFFF",shadowEnabled:!0,borderBottomColor:"#E5E7EB",contentPaddingX:40},footer:{backgroundColor:"#262626",textColor:"#9CA3AF",linkColor:"#9CA3AF",linkHoverColor:"#FFFFFF",showLogo:!0,logoWidth:120,logoHeight:32,logoPlacement:"left",copyrightText:"\xA9 Company Name",layout:"row",paddingY:24,paddingX:40,links:[]},theme:{pageBackground:"#FFFFFF",cardBackground:"#FFFFFF",cardBorderColor:"#E5E7EB",cardPadding:24,cardShadowEnabled:!0,selectedBackground:"#E8F5FD",zebraRowColor:"rgba(249,250,251,0.8)",rowBandColor:"#F3F4F6",validationBorder:"#333333",validationBackground:"#D9D9D9",tooltipBackground:"#1F2937",progressTrackHeight:12,progressTrackColor:"#E5E7EB",progressFillColor:"#1A1F36",stickyChromePaddingTop:16,stickyChromePaddingBottom:20,languageSelectorBackground:"#FFFFFF",languageSelectorTextColor:"#2563EB",languageSelectorBorderColor:"#2563EB"},layout:{showHeader:!0,showFooter:!0,showProgressBar:!0,showLanguageSwitcher:!1,showNextButton:!0,showBackButton:!0,showQuestionNumbers:!0,showRequiredAsterisk:!0,width:"standard",borderStyle:"rounded",fontStyle:"modern"},buttons:{next:"Next",back:"Back",submit:"Submit"},colorScheme:{..._},colorSource:"auto",typography:{fontFamily:"Inter, sans-serif",headingWeight:700},motion:{enabled:!1,durationMs:200}},questionTypes:Mo(e),placeholders:{firstName:"Alex",lastName:"Customer",email:"alex@example.com"},customFields:{},debug:{enabled:!1,sampleAnswers:{}},deploy:{target:"aws",autoDeploy:!1}}}function H(e,o){return{...e,...o??{}}}function Qe(e){let o=(e.surveyTypes??[]).filter(r=>Q.includes(r)),t=Uo(o,e.instanceId),n=e.global??{},i=t.global,s={...t.questionTypes};if(e.questionTypes)for(let[r,a]of Object.entries(e.questionTypes))s[r]={...s[r]??{},...a};return{...t,...e,configuredAt:void 0,surveyTypes:o.length?o:t.surveyTypes,global:{...i,...n,header:H(i.header,n.header),footer:H(i.footer,n.footer),theme:H(i.theme,n.theme),layout:H(i.layout,n.layout),buttons:H(i.buttons,n.buttons),logo:H(i.logo,n.logo),colorScheme:H(i.colorScheme,n.colorScheme),typography:H(i.typography,n.typography),motion:H(i.motion,n.motion)},questionTypes:s,placeholders:{...t.placeholders,...e.placeholders??{}},customFields:{...t.customFields,...e.customFields??{}},debug:{enabled:e.debug?.enabled??t.debug?.enabled??!1,sampleAnswers:e.debug?.sampleAnswers??t.debug?.sampleAnswers},deploy:{...t.deploy,...e.deploy??{}}}}var _,qe,Ge=B(()=>{"use strict";be();_={primary:"#1A1F36",secondary:"#E8F5FD",accent:"#00B5AD",background:"#FFFFFF",text:"#1A1F36",buttonText:"#FFFFFF"},qe={MCQ:{cardStyle:"outlined",selectedAccent:_.accent,optionGap:8,borderRadius:8,cardPadding:12,selectedBackground:_.secondary,hoverBorderColor:_.accent},TEXTFIELD:{inputRadius:8,focusRing:_.accent,borderColor:"#E5E7EB",inputPadding:12,inputHeight:44,placeholderColor:"#9CA3AF"},NPS_SCALE:{buttonStyle:"standard",selectedFill:_.secondary,labelColor:_.text,trackBarColor:"#F2F2F2",trackHighlightColor:"#FBE8F3",cellSize:40,cellGap:4},CFM_MATRIX:{rowLabelWidth:180,cellSelectedColor:_.accent,headerStyle:"bold",bipolarColumnWidthPercent:25,carouselDotColor:"#2563EB",cellPadding:8},CSAT_MATRIX:{rowLabelWidth:180,cellSelectedColor:_.accent,headerStyle:"bold",bipolarColumnWidthPercent:25,carouselDotColor:_.primary,cellPadding:8,accentColor:_.accent,emojiSize:24,unselectedOpacity:.5,selectedRingColor:_.accent,cellSize:40,tooltipBg:"#1F2937"},RATING_MATRIX:{starColor:"#F59E0B",badgeColor:_.primary,rowLabelWidth:180,unselectedStarOpacity:.5},SLIDER_MATRIX:{trackColor:_.accent,thumbColor:_.primary,tickColor:"#9CA3AF",rowLabelWidth:180,rowBandColor:"#F3F4F6",tickBadgeSize:28},FILE_UPLOAD:{dropzoneStyle:"dashed",accentColor:_.accent,dropzonePadding:24},TEXT_AND_MEDIA:{mediaMaxWidth:100,mediaRadius:8,captionColor:"#6B7280",captionSize:14},HEATMAP:{pinColor:_.accent,pinSize:12,pinBorderColor:"#FFFFFF",overlayOpacity:.3},RANK_ORDER:{itemBg:"#F9FAFB",dragHandleColor:"#9CA3AF",rankBadgeColor:_.primary,itemPadding:12,itemGap:8}}});import*as Ce from"fs";import*as ue from"path";function oo(e){let o={},t=/--cfm-[\w-]+\s*:\s*([^;]+);/g,n;for(;(n=t.exec(e))!==null;){let i=n[0].split(":")[0].trim(),s=n[1].trim();o[i]=s}return o}function b(e){if(!e)return;let o=parseFloat(e.replace(/px$/,""));return Number.isFinite(o)?o:void 0}function eo(e){if(!e)return;let o=parseFloat(e.replace(/%$/,""));return Number.isFinite(o)?o:void 0}function ge(e){if(!e)return;let o=parseFloat(e);return Number.isFinite(o)?o:void 0}function to(e){let o={global:{},questionTypes:{}},t=o.global,n={},i={},s={},r={},a={},l={},y={},m=o.questionTypes;if(e["--cfm-primary"]&&(n.primary=e["--cfm-primary"]),e["--cfm-secondary"]&&(n.secondary=e["--cfm-secondary"]),e["--cfm-accent"]&&(n.accent=e["--cfm-accent"]),e["--cfm-background"]&&(n.background=e["--cfm-background"]),e["--cfm-text"]&&(n.text=e["--cfm-text"]),e["--cfm-button-text"]&&(n.buttonText=e["--cfm-button-text"]),e["--cfm-max-width"]&&Ke[e["--cfm-max-width"]]&&(a.width=Ke[e["--cfm-max-width"]]),e["--cfm-border-radius"]&&Ye[e["--cfm-border-radius"]]&&(a.borderStyle=Ye[e["--cfm-border-radius"]]),e["--cfm-font-family"]&&(l.fontFamily=e["--cfm-font-family"],Ze[e["--cfm-font-family"]]&&(a.fontStyle=Ze[e["--cfm-font-family"]])),e["--cfm-heading-weight"]&&(l.headingWeight=ge(e["--cfm-heading-weight"])),e["--cfm-motion-duration"]){let A=b(e["--cfm-motion-duration"]);A!==void 0&&(y.durationMs=A,y.enabled=A>0)}e["--cfm-header-height"]&&(i.height=b(e["--cfm-header-height"])),e["--cfm-header-logo-width"]&&(i.logoBoxWidth=b(e["--cfm-header-logo-width"])),e["--cfm-header-logo-height"]&&(i.logoBoxHeight=b(e["--cfm-header-logo-height"])),e["--cfm-header-logo-padding"]&&(i.logoPadding=b(e["--cfm-header-logo-padding"])),e["--cfm-header-bg"]&&(i.backgroundColor=e["--cfm-header-bg"]),e["--cfm-header-company-color"]&&(i.companyNameColor=e["--cfm-header-company-color"]),e["--cfm-header-company-size"]&&(i.companyNameFontSize=b(e["--cfm-header-company-size"])),e["--cfm-header-company-weight"]&&(i.companyNameFontWeight=ge(e["--cfm-header-company-weight"])),e["--cfm-header-border"]&&(i.borderBottomColor=e["--cfm-header-border"]),e["--cfm-header-padding-x"]&&(i.contentPaddingX=b(e["--cfm-header-padding-x"])),e["--cfm-footer-bg"]&&(s.backgroundColor=e["--cfm-footer-bg"]),e["--cfm-footer-text"]&&(s.textColor=e["--cfm-footer-text"]),e["--cfm-footer-link"]&&(s.linkColor=e["--cfm-footer-link"]),e["--cfm-footer-link-hover"]&&(s.linkHoverColor=e["--cfm-footer-link-hover"]),e["--cfm-footer-logo-width"]&&(s.logoWidth=b(e["--cfm-footer-logo-width"])),e["--cfm-footer-logo-height"]&&(s.logoHeight=b(e["--cfm-footer-logo-height"])),e["--cfm-footer-padding-y"]&&(s.paddingY=b(e["--cfm-footer-padding-y"])),e["--cfm-footer-padding-x"]&&(s.paddingX=b(e["--cfm-footer-padding-x"])),e["--cfm-background"]&&(r.pageBackground=e["--cfm-background"]),e["--cfm-card-bg"]&&(r.cardBackground=e["--cfm-card-bg"]),e["--cfm-card-border-color"]&&(r.cardBorderColor=e["--cfm-card-border-color"]),e["--cfm-card-padding"]&&(r.cardPadding=b(e["--cfm-card-padding"])),e["--cfm-card-shadow"]&&(r.cardShadowEnabled=e["--cfm-card-shadow"]!=="none"),e["--cfm-selected-bg"]&&(r.selectedBackground=e["--cfm-selected-bg"]),e["--cfm-zebra-row"]&&(r.zebraRowColor=e["--cfm-zebra-row"]),e["--cfm-row-band"]&&(r.rowBandColor=e["--cfm-row-band"]),e["--cfm-validation-border"]&&(r.validationBorder=e["--cfm-validation-border"]),e["--cfm-validation-bg"]&&(r.validationBackground=e["--cfm-validation-bg"]),e["--cfm-tooltip-bg"]&&(r.tooltipBackground=e["--cfm-tooltip-bg"]),e["--cfm-progress-height"]&&(r.progressTrackHeight=b(e["--cfm-progress-height"])),e["--cfm-progress-track"]&&(r.progressTrackColor=e["--cfm-progress-track"]),e["--cfm-progress-fill"]&&(r.progressFillColor=e["--cfm-progress-fill"]),e["--cfm-sticky-pt"]&&(r.stickyChromePaddingTop=b(e["--cfm-sticky-pt"])),e["--cfm-sticky-pb"]&&(r.stickyChromePaddingBottom=b(e["--cfm-sticky-pb"]));let C={};e["--cfm-mcq-selected-accent"]&&(C.selectedAccent=e["--cfm-mcq-selected-accent"]),e["--cfm-mcq-border-radius"]&&(C.borderRadius=b(e["--cfm-mcq-border-radius"])),e["--cfm-mcq-option-gap"]&&(C.optionGap=b(e["--cfm-mcq-option-gap"])),e["--cfm-mcq-card-padding"]&&(C.cardPadding=b(e["--cfm-mcq-card-padding"])),e["--cfm-mcq-selected-bg"]&&(C.selectedBackground=e["--cfm-mcq-selected-bg"]),e["--cfm-mcq-hover-border"]&&(C.hoverBorderColor=e["--cfm-mcq-hover-border"]),Object.keys(C).length&&(m.MCQ=C);let S={};e["--cfm-input-radius"]&&(S.inputRadius=b(e["--cfm-input-radius"])),e["--cfm-input-focus-ring"]&&(S.focusRing=e["--cfm-input-focus-ring"]),e["--cfm-input-border"]&&(S.borderColor=e["--cfm-input-border"]),e["--cfm-input-padding"]&&(S.inputPadding=b(e["--cfm-input-padding"])),e["--cfm-input-height"]&&(S.inputHeight=b(e["--cfm-input-height"])),e["--cfm-input-placeholder"]&&(S.placeholderColor=e["--cfm-input-placeholder"]),Object.keys(S).length&&(m.TEXTFIELD=S);let E={};e["--cfm-nps-selected-fill"]&&(E.selectedFill=e["--cfm-nps-selected-fill"]),e["--cfm-nps-label-color"]&&(E.labelColor=e["--cfm-nps-label-color"]),e["--cfm-nps-track-bar"]&&(E.trackBarColor=e["--cfm-nps-track-bar"]),e["--cfm-nps-track-highlight"]&&(E.trackHighlightColor=e["--cfm-nps-track-highlight"]),e["--cfm-nps-cell-size"]&&(E.cellSize=b(e["--cfm-nps-cell-size"])),e["--cfm-nps-cell-gap"]&&(E.cellGap=b(e["--cfm-nps-cell-gap"])),Object.keys(E).length&&(m.NPS_SCALE=E);let v=b(e["--cfm-matrix-row-width"]),x={};v!==void 0&&(x.rowLabelWidth=v),e["--cfm-matrix-selected"]&&(x.cellSelectedColor=e["--cfm-matrix-selected"]),e["--cfm-matrix-bipolar-width"]&&(x.bipolarColumnWidthPercent=eo(e["--cfm-matrix-bipolar-width"])),e["--cfm-matrix-carousel-dot"]&&(x.carouselDotColor=e["--cfm-matrix-carousel-dot"]),e["--cfm-matrix-cell-padding"]&&(x.cellPadding=b(e["--cfm-matrix-cell-padding"])),Object.keys(x).length&&(m.CFM_MATRIX=x);let d={...x};e["--cfm-csat-accent"]&&(d.accentColor=e["--cfm-csat-accent"]),e["--cfm-csat-emoji-size"]&&(d.emojiSize=b(e["--cfm-csat-emoji-size"])),e["--cfm-csat-unselected-opacity"]&&(d.unselectedOpacity=ge(e["--cfm-csat-unselected-opacity"])),e["--cfm-csat-ring-color"]&&(d.selectedRingColor=e["--cfm-csat-ring-color"]),e["--cfm-csat-cell-size"]&&(d.cellSize=b(e["--cfm-csat-cell-size"])),e["--cfm-csat-tooltip-bg"]&&(d.tooltipBg=e["--cfm-csat-tooltip-bg"]),(Object.keys(d).length>Object.keys(x).length||e["--cfm-csat-accent"])&&(m.CSAT_MATRIX=d);let f={};e["--cfm-star-color"]&&(f.starColor=e["--cfm-star-color"]),e["--cfm-badge-color"]&&(f.badgeColor=e["--cfm-badge-color"]),v!==void 0&&(f.rowLabelWidth=v),e["--cfm-star-unselected-opacity"]&&(f.unselectedStarOpacity=ge(e["--cfm-star-unselected-opacity"])),Object.keys(f).length&&(m.RATING_MATRIX=f);let T={};e["--cfm-slider-track"]&&(T.trackColor=e["--cfm-slider-track"]),e["--cfm-slider-thumb"]&&(T.thumbColor=e["--cfm-slider-thumb"]),e["--cfm-slider-tick"]&&(T.tickColor=e["--cfm-slider-tick"]),v!==void 0&&(T.rowLabelWidth=v),e["--cfm-slider-row-band"]&&(T.rowBandColor=e["--cfm-slider-row-band"]),e["--cfm-slider-tick-size"]&&(T.tickBadgeSize=b(e["--cfm-slider-tick-size"])),Object.keys(T).length&&(m.SLIDER_MATRIX=T);let $={};e["--cfm-upload-accent"]&&($.accentColor=e["--cfm-upload-accent"]),e["--cfm-upload-padding"]&&($.dropzonePadding=b(e["--cfm-upload-padding"])),Object.keys($).length&&(m.FILE_UPLOAD=$);let h={};e["--cfm-media-max-width"]&&(h.mediaMaxWidth=eo(e["--cfm-media-max-width"])),e["--cfm-media-radius"]&&(h.mediaRadius=b(e["--cfm-media-radius"])),e["--cfm-media-caption-color"]&&(h.captionColor=e["--cfm-media-caption-color"]),e["--cfm-media-caption-size"]&&(h.captionSize=b(e["--cfm-media-caption-size"])),Object.keys(h).length&&(m.TEXT_AND_MEDIA=h);let P={};e["--cfm-heatmap-pin"]&&(P.pinColor=e["--cfm-heatmap-pin"]),e["--cfm-heatmap-pin-size"]&&(P.pinSize=b(e["--cfm-heatmap-pin-size"])),e["--cfm-heatmap-pin-border"]&&(P.pinBorderColor=e["--cfm-heatmap-pin-border"]),e["--cfm-heatmap-overlay-opacity"]&&(P.overlayOpacity=ge(e["--cfm-heatmap-overlay-opacity"])),Object.keys(P).length&&(m.HEATMAP=P);let w={};return e["--cfm-rank-item-bg"]&&(w.itemBg=e["--cfm-rank-item-bg"]),e["--cfm-rank-badge"]&&(w.rankBadgeColor=e["--cfm-rank-badge"]),e["--cfm-rank-handle"]&&(w.dragHandleColor=e["--cfm-rank-handle"]),e["--cfm-rank-item-padding"]&&(w.itemPadding=b(e["--cfm-rank-item-padding"])),e["--cfm-rank-item-gap"]&&(w.itemGap=b(e["--cfm-rank-item-gap"])),Object.keys(w).length&&(m.RANK_ORDER=w),Object.keys(n).length&&(t.colorScheme=n),Object.keys(i).length&&(t.header=i),Object.keys(s).length&&(t.footer=s),Object.keys(r).length&&(t.theme=r),Object.keys(a).length&&(t.layout=a),Object.keys(l).length&&(t.typography=l),Object.keys(y).length&&(t.motion=y),o}function ne(e){let o=[ue.join(e,"src","styles","survey-theme.css"),ue.join(e,"src","app","survey-theme.css"),ue.join(e,"src","styles","globals.css"),ue.join(e,"src","app","globals.css")];for(let t of o)if(Ce.existsSync(t)&&Ce.readFileSync(t,"utf8").includes("--cfm-"))return t;return null}var Ke,Ye,Ze,$e=B(()=>{"use strict";Ke={"36rem":"narrow","48rem":"standard","64rem":"wide"},Ye={"0px":"sharp","12px":"rounded","9999px":"pill"},Ze={"system-ui, sans-serif":"system","Inter, sans-serif":"modern","Georgia, serif":"serif"}});import*as xe from"fs";import*as no from"path";function Bo(e){for(let o of zo){let t=no.join(e,o);if(xe.existsSync(t))return t}return null}function Wo(e){let o=e.trim();if(!o||o.startsWith("http")||o.startsWith("data:"))return null;let t=o.split("?")[0];return t.startsWith("/")?t.slice(1):t}function io(e){let o=Bo(e);if(!o)return null;let t=xe.readFileSync(o,"utf8"),n=t.match(/data-cfm-logo[\s\S]*?src=["']([^"']+)["']/i)??t.match(/src=["']([^"']+)["'][\s\S]*?data-cfm-logo/i);if(n){let r=Wo(n[1]);if(r)return{mode:"image",publicPath:r,fileName:r}}let i=t.match(/data-cfm-logo-text[^>]*>([^<]+)</i);if(i)return{mode:"text",label:i[1].trim()};let s=t.match(/data-cfm-company[^>]*>([^<]+)</i);return s&&!n?{mode:"text",label:s[1].trim()}:null}var zo,ro=B(()=>{"use strict";zo=["src/components/Header.tsx","components/Header.tsx","app/components/Header.tsx"]});var fo={};Ie(fo,{logSeedSource:()=>Fe,resolveInitialConfig:()=>re,writeResolvedUiConfig:()=>Ne});import*as W from"fs";import*as V from"path";function je(e){return e.filter(o=>Q.includes(o))}function so(e){try{let o=JSON.parse(W.readFileSync(e,"utf8"));return o.version!=="1.0"?null:(delete o.configuredAt,o)}catch{return null}}function Vo(e){let o={global:{}};if(!W.existsSync(e))return o;let t=W.readFileSync(e,"utf8"),n=new Set;for(let s of Q)t.includes(s)&&n.add(s);n.size&&(o.surveyTypes=[...n]);let i=t.match(/\*\*Branding source:\*\*\s*(.+)/i);if(i){let s=i[1].trim(),r=s.match(/company[:\s]+([^,;]+)/i),a=s.match(/title[:\s]+([^,;]+)/i);if(r&&(o.global.companyName=r[1].trim()),a){let l=a[1].trim();o.global.surveyTitle=l,o.global.browserTabTitle=l}}return o}function lo(e,o){let t=V.join(e,o);if(!W.existsSync(t))return null;let n=W.readFileSync(t);if(n.length>Jo)return{fileName:o,dataUrl:""};let i=V.extname(o).toLowerCase(),s=Ho[i]??"application/octet-stream";return{fileName:o,dataUrl:`data:${s};base64,${n.toString("base64")}`}}function co(e,o){if(!o)return null;if(o.url&&typeof o.url=="string")return{fileName:o.fileName??null,url:o.url};if(o.fileName){let t=lo(e,o.fileName);if(t)return{fileName:t.fileName,url:t.dataUrl||null}}return o.fileName===null&&o.url===null?{fileName:null,url:null}:null}function ao(e,o){let t=e.global??{},n=o.global??{},i=e.questionTypes??{},s=o.questionTypes??{},r={...i};for(let[a,l]of Object.entries(s))r[a]={...r[a]??{},...l};return{...e,...o,surveyTypes:o.surveyTypes??e.surveyTypes,global:{...t,...n,header:{...t.header,...n.header},footer:{...t.footer,...n.footer},theme:{...t.theme,...n.theme},layout:{...t.layout,...n.layout},buttons:{...t.buttons,...n.buttons},logo:{...t.logo,...n.logo},colorScheme:{...t.colorScheme,...n.colorScheme},typography:{...t.typography,...n.typography},motion:{...t.motion,...n.motion}},questionTypes:r,placeholders:{...e.placeholders,...o.placeholders},customFields:{...e.customFields,...o.customFields},deploy:{...e.deploy,...o.deploy}}}function re(e){let o=e.projectRoot??process.env.INIT_CWD??process.cwd(),t=V.join(o,"survey-ui-config.json"),n=V.join(o,"implementation_plan.md"),i=V.join(o,"public"),s=je(e.surveyTypes),r={},a="defaults",l=ne(o);if(l){let w=W.readFileSync(l,"utf8"),A=oo(w);Object.keys(A).length>0&&(r=to(A),a="survey-theme.css")}let y=Vo(n);r=ao(r,y);let m=so(t);m&&(r=ao(r,m),a="survey-ui-config.json");let C=V.join(o,"survey-ui-config.final.json"),S=so(C),E=!!m?.configuredAt,v=!!S?.configuredAt;if(S&&v&&!E){let w=co(i,S.global?.logo);w&&(r.global={...r.global??{},logo:{fileName:w.fileName,url:w.url}})}let x=co(i,r.global?.logo),d=io(o),f=!!m?.configuredAt,T=x?.fileName!=null&&/^logo_\d+_/i.test(x.fileName),$=d?.mode==="image"?d.fileName:null,h=!f&&T&&$!=null&&x?.fileName!==$;if(x&&!h)r.global={...r.global??{},logo:{fileName:x.fileName,url:x.url}};else if(d?.mode==="image"){let w=lo(i,d.fileName);r.global={...r.global??{},logo:{fileName:d.fileName,url:w?.dataUrl||null}}}else d?.mode==="text"&&(r.global={...r.global??{},logo:{fileName:null,url:null},companyName:r.global?.companyName??d.label});return r.surveyTypes=je(r.surveyTypes??s),r.surveyTypes?.length||(r.surveyTypes=s),e.instanceId&&(r.instanceId=e.instanceId),{config:Qe(r),source:a}}function Fe(e){console.log(e==="survey-ui-config.json"?`${ie.dim} Seeding wizard from survey-ui-config.json${ie.reset}`:e==="survey-theme.css"?`${ie.dim} Seeding wizard from survey-theme.css + defaults${ie.reset}`:`${ie.dim} Seeding wizard from SDK defaults${ie.reset}`)}function Ne(e={}){let o=e.projectRoot??process.env.INIT_CWD??process.cwd(),t=e.surveyTypes??je(Q),{config:n}=re({projectRoot:o,surveyTypes:t,instanceId:e.instanceId}),i=V.join(o,"survey-ui-config.json");return W.writeFileSync(i,JSON.stringify(n,null,2),"utf8"),i}var ie,Jo,Ho,pe=B(()=>{"use strict";U();Ge();$e();be();ro();ie=c,Jo=512e3,Ho={".png":"image/png",".jpg":"image/jpeg",".jpeg":"image/jpeg",".gif":"image/gif",".webp":"image/webp",".svg":"image/svg+xml"}});import*as ae from"fs";import*as le from"path";function yo(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function wo(e,o){return JSON.stringify(e)===JSON.stringify(o)}function ce(e){return typeof e=="string"&&e.startsWith("data:")&&e.length>80?`${e.slice(0,48)}\u2026 (${e.length} chars)`:e}function So(e,o,t,n){if(wo(e,o)){n.unchangedCount+=1;return}if(e===void 0&&o!==void 0){n.added.push({path:t,before:void 0,after:ce(o)});return}if(e!==void 0&&o===void 0){n.removed.push({path:t,before:ce(e),after:void 0});return}if(Array.isArray(e)&&Array.isArray(o)){wo(e,o)?n.unchangedCount+=1:n.changed.push({path:t,before:ce(e),after:ce(o)});return}if(yo(e)&&yo(o)){let i=new Set([...Object.keys(e),...Object.keys(o)]);for(let s of i){if(ct.has(s)&&t==="")continue;let r=t?`${t}.${s}`:s;So(e[s],o[s],r,n)}return}n.changed.push({path:t,before:ce(e),after:ce(o)})}function Me(e,o){let t={changed:[],added:[],removed:[],unchangedCount:0};return So(e,o,"",t),t}function ke(e){let o=["# UI Config Diff (seed \u2192 final)","",`**Changed:** ${e.changed.length} \xB7 **Added:** ${e.added.length} \xB7 **Removed:** ${e.removed.length}`,"","> Review only \u2014 run `npx cfm-sdk confirm-ui-config` to apply final config to the project.",""],t=(n,i)=>{if(i.length){o.push(`## ${n}`,"");for(let s of i)o.push(`### \`${s.path}\``),o.push(`- **Before:** \`${JSON.stringify(s.before)}\``),o.push(`- **After:** \`${JSON.stringify(s.after)}\``),o.push("")}};return t("Changed",e.changed),t("Added",e.added),t("Removed",e.removed),!e.changed.length&&!e.added.length&&!e.removed.length&&o.push("_No differences \u2014 final config matches seed._",""),o.join(`
|
|
3
|
-
`)}function
|
|
4
|
-
${
|
|
5
|
-
`),console.log(
|
|
6
|
-
${
|
|
7
|
-
`);let o=await
|
|
2
|
+
var No=Object.defineProperty;var we=(e=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(e,{get:(o,t)=>(typeof require<"u"?require:o)[t]}):e)(function(e){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+e+'" is not supported')});var z=(e,o)=>()=>(e&&(o=e(e=0)),o);var Ie=(e,o)=>{for(var t in o)No(e,t,{get:o[t],enumerable:!0})};var c,M=z(()=>{"use strict";c={reset:"\x1B[0m",bold:"\x1B[1m",green:"\x1B[32m",red:"\x1B[31m",cyan:"\x1B[36m",yellow:"\x1B[33m",dim:"\x1B[2m"}});var Q,be=z(()=>{"use strict";Q=["MCQ","TEXTFIELD","NPS_SCALE","CFM_MATRIX","CSAT_MATRIX","RATING_MATRIX","SLIDER_MATRIX","FILE_UPLOAD","TEXT_AND_MEDIA","HEATMAP","RANK_ORDER"]});function Uo(e){let o={};for(let t of e)Qe[t]&&(o[t]={...Qe[t]});return o}function zo(e=[],o){return{version:"1.0",instanceId:o,surveyTypes:e,global:{surveyTitle:"Customer Feedback Survey",companyName:"Sprinklr",browserTabTitle:"Customer Feedback Survey",thankYouMessage:"Thank you for your valuable feedback!",logo:{fileName:null,url:null},header:{height:120,logoBoxWidth:120,logoBoxHeight:120,logoPadding:10,logoPlacement:"left",showCompanyName:!0,companyNamePlacement:"left",companyNameFontSize:18,companyNameFontWeight:600,companyNameColor:"#1A1F36",backgroundColor:"#FFFFFF",shadowEnabled:!0,borderBottomColor:"#E5E7EB",contentPaddingX:40},footer:{backgroundColor:"#262626",textColor:"#9CA3AF",linkColor:"#9CA3AF",linkHoverColor:"#FFFFFF",showLogo:!0,logoWidth:120,logoHeight:32,logoPlacement:"left",copyrightText:"\xA9 Company Name",layout:"row",paddingY:24,paddingX:40,links:[]},theme:{pageBackground:"#FFFFFF",cardBackground:"#FFFFFF",cardBorderColor:"#E5E7EB",cardPadding:24,cardShadowEnabled:!0,selectedBackground:"#E8F5FD",zebraRowColor:"rgba(249,250,251,0.8)",rowBandColor:"#F3F4F6",validationBorder:"#333333",validationBackground:"#D9D9D9",tooltipBackground:"#1F2937",progressTrackHeight:12,progressTrackColor:"#E5E7EB",progressFillColor:"#1A1F36",stickyChromePaddingTop:16,stickyChromePaddingBottom:20,languageSelectorBackground:"#FFFFFF",languageSelectorTextColor:"#2563EB",languageSelectorBorderColor:"#2563EB"},layout:{showHeader:!0,showFooter:!0,showProgressBar:!0,showLanguageSwitcher:!1,showNextButton:!0,showBackButton:!0,showQuestionNumbers:!0,showRequiredAsterisk:!0,width:"standard",borderStyle:"rounded",fontStyle:"modern"},buttons:{next:"Next",back:"Back",submit:"Submit"},colorScheme:{...A},colorSource:"auto",typography:{fontFamily:"Inter, sans-serif",headingWeight:700},motion:{enabled:!1,durationMs:200}},questionTypes:Uo(e),placeholders:{firstName:"Alex",lastName:"Customer",email:"alex@example.com"},customFields:{},debug:{enabled:!1,sampleAnswers:{}},deploy:{target:"aws",autoDeploy:!1}}}function H(e,o){return{...e,...o??{}}}function Ge(e){let o=(e.surveyTypes??[]).filter(r=>Q.includes(r)),t=zo(o,e.instanceId),n=e.global??{},i=t.global,s={...t.questionTypes};if(e.questionTypes)for(let[r,a]of Object.entries(e.questionTypes))s[r]={...s[r]??{},...a};return{...t,...e,configuredAt:void 0,surveyTypes:o.length?o:t.surveyTypes,global:{...i,...n,header:H(i.header,n.header),footer:H(i.footer,n.footer),theme:H(i.theme,n.theme),layout:H(i.layout,n.layout),buttons:H(i.buttons,n.buttons),logo:H(i.logo,n.logo),colorScheme:H(i.colorScheme,n.colorScheme),typography:H(i.typography,n.typography),motion:H(i.motion,n.motion)},questionTypes:s,placeholders:{...t.placeholders,...e.placeholders??{}},customFields:{...t.customFields,...e.customFields??{}},debug:{enabled:e.debug?.enabled??t.debug?.enabled??!1,sampleAnswers:e.debug?.sampleAnswers??t.debug?.sampleAnswers},deploy:{...t.deploy,...e.deploy??{}}}}var A,Qe,Ke=z(()=>{"use strict";be();A={primary:"#1A1F36",secondary:"#E8F5FD",accent:"#00B5AD",background:"#FFFFFF",text:"#1A1F36",buttonText:"#FFFFFF"},Qe={MCQ:{cardStyle:"outlined",selectedAccent:A.accent,optionGap:8,borderRadius:8,cardPadding:12,selectedBackground:A.secondary,hoverBorderColor:A.accent},TEXTFIELD:{inputRadius:8,focusRing:A.accent,borderColor:"#E5E7EB",inputPadding:12,inputHeight:44,placeholderColor:"#9CA3AF"},NPS_SCALE:{buttonStyle:"standard",selectedFill:A.secondary,labelColor:A.text,trackBarColor:"#F2F2F2",trackHighlightColor:"#FBE8F3",cellSize:40,cellGap:4},CFM_MATRIX:{rowLabelWidth:180,cellSelectedColor:A.accent,headerStyle:"bold",bipolarColumnWidthPercent:25,carouselDotColor:"#2563EB",cellPadding:8},CSAT_MATRIX:{rowLabelWidth:180,cellSelectedColor:A.accent,headerStyle:"bold",bipolarColumnWidthPercent:25,carouselDotColor:A.primary,cellPadding:8,accentColor:A.accent,emojiSize:24,unselectedOpacity:.5,selectedRingColor:A.accent,cellSize:40,tooltipBg:"#1F2937"},RATING_MATRIX:{starColor:"#F59E0B",badgeColor:A.primary,rowLabelWidth:180,unselectedStarOpacity:.5},SLIDER_MATRIX:{trackColor:A.accent,thumbColor:A.primary,tickColor:"#9CA3AF",rowLabelWidth:180,rowBandColor:"#F3F4F6",tickBadgeSize:28},FILE_UPLOAD:{dropzoneStyle:"dashed",accentColor:A.accent,dropzonePadding:24},TEXT_AND_MEDIA:{mediaMaxWidth:100,mediaRadius:8,captionColor:"#6B7280",captionSize:14},HEATMAP:{pinColor:A.accent,pinSize:12,pinBorderColor:"#FFFFFF",overlayOpacity:.3},RANK_ORDER:{itemBg:"#F9FAFB",dragHandleColor:"#9CA3AF",rankBadgeColor:A.primary,itemPadding:12,itemGap:8}}});import*as Ce from"fs";import*as pe from"path";function to(e){let o={},t=/--cfm-[\w-]+\s*:\s*([^;]+);/g,n;for(;(n=t.exec(e))!==null;){let i=n[0].split(":")[0].trim(),s=n[1].trim();o[i]=s}return o}function b(e){if(!e)return;let o=parseFloat(e.replace(/px$/,""));return Number.isFinite(o)?o:void 0}function oo(e){if(!e)return;let o=parseFloat(e.replace(/%$/,""));return Number.isFinite(o)?o:void 0}function ue(e){if(!e)return;let o=parseFloat(e);return Number.isFinite(o)?o:void 0}function no(e){let o={global:{},questionTypes:{}},t=o.global,n={},i={},s={},r={},a={},l={},y={},m=o.questionTypes;if(e["--cfm-primary"]&&(n.primary=e["--cfm-primary"]),e["--cfm-secondary"]&&(n.secondary=e["--cfm-secondary"]),e["--cfm-accent"]&&(n.accent=e["--cfm-accent"]),e["--cfm-background"]&&(n.background=e["--cfm-background"]),e["--cfm-text"]&&(n.text=e["--cfm-text"]),e["--cfm-button-text"]&&(n.buttonText=e["--cfm-button-text"]),e["--cfm-max-width"]&&Ye[e["--cfm-max-width"]]&&(a.width=Ye[e["--cfm-max-width"]]),e["--cfm-border-radius"]&&Ze[e["--cfm-border-radius"]]&&(a.borderStyle=Ze[e["--cfm-border-radius"]]),e["--cfm-font-family"]&&(l.fontFamily=e["--cfm-font-family"],eo[e["--cfm-font-family"]]&&(a.fontStyle=eo[e["--cfm-font-family"]])),e["--cfm-heading-weight"]&&(l.headingWeight=ue(e["--cfm-heading-weight"])),e["--cfm-motion-duration"]){let j=b(e["--cfm-motion-duration"]);j!==void 0&&(y.durationMs=j,y.enabled=j>0)}e["--cfm-header-height"]&&(i.height=b(e["--cfm-header-height"])),e["--cfm-header-logo-width"]&&(i.logoBoxWidth=b(e["--cfm-header-logo-width"])),e["--cfm-header-logo-height"]&&(i.logoBoxHeight=b(e["--cfm-header-logo-height"])),e["--cfm-header-logo-padding"]&&(i.logoPadding=b(e["--cfm-header-logo-padding"])),e["--cfm-header-bg"]&&(i.backgroundColor=e["--cfm-header-bg"]),e["--cfm-header-company-color"]&&(i.companyNameColor=e["--cfm-header-company-color"]),e["--cfm-header-company-size"]&&(i.companyNameFontSize=b(e["--cfm-header-company-size"])),e["--cfm-header-company-weight"]&&(i.companyNameFontWeight=ue(e["--cfm-header-company-weight"])),e["--cfm-header-border"]&&(i.borderBottomColor=e["--cfm-header-border"]),e["--cfm-header-padding-x"]&&(i.contentPaddingX=b(e["--cfm-header-padding-x"])),e["--cfm-footer-bg"]&&(s.backgroundColor=e["--cfm-footer-bg"]),e["--cfm-footer-text"]&&(s.textColor=e["--cfm-footer-text"]),e["--cfm-footer-link"]&&(s.linkColor=e["--cfm-footer-link"]),e["--cfm-footer-link-hover"]&&(s.linkHoverColor=e["--cfm-footer-link-hover"]),e["--cfm-footer-logo-width"]&&(s.logoWidth=b(e["--cfm-footer-logo-width"])),e["--cfm-footer-logo-height"]&&(s.logoHeight=b(e["--cfm-footer-logo-height"])),e["--cfm-footer-padding-y"]&&(s.paddingY=b(e["--cfm-footer-padding-y"])),e["--cfm-footer-padding-x"]&&(s.paddingX=b(e["--cfm-footer-padding-x"])),e["--cfm-background"]&&(r.pageBackground=e["--cfm-background"]),e["--cfm-card-bg"]&&(r.cardBackground=e["--cfm-card-bg"]),e["--cfm-card-border-color"]&&(r.cardBorderColor=e["--cfm-card-border-color"]),e["--cfm-card-padding"]&&(r.cardPadding=b(e["--cfm-card-padding"])),e["--cfm-card-shadow"]&&(r.cardShadowEnabled=e["--cfm-card-shadow"]!=="none"),e["--cfm-selected-bg"]&&(r.selectedBackground=e["--cfm-selected-bg"]),e["--cfm-zebra-row"]&&(r.zebraRowColor=e["--cfm-zebra-row"]),e["--cfm-row-band"]&&(r.rowBandColor=e["--cfm-row-band"]),e["--cfm-validation-border"]&&(r.validationBorder=e["--cfm-validation-border"]),e["--cfm-validation-bg"]&&(r.validationBackground=e["--cfm-validation-bg"]),e["--cfm-tooltip-bg"]&&(r.tooltipBackground=e["--cfm-tooltip-bg"]),e["--cfm-progress-height"]&&(r.progressTrackHeight=b(e["--cfm-progress-height"])),e["--cfm-progress-track"]&&(r.progressTrackColor=e["--cfm-progress-track"]),e["--cfm-progress-fill"]&&(r.progressFillColor=e["--cfm-progress-fill"]),e["--cfm-sticky-pt"]&&(r.stickyChromePaddingTop=b(e["--cfm-sticky-pt"])),e["--cfm-sticky-pb"]&&(r.stickyChromePaddingBottom=b(e["--cfm-sticky-pb"]));let C={};e["--cfm-mcq-selected-accent"]&&(C.selectedAccent=e["--cfm-mcq-selected-accent"]),e["--cfm-mcq-border-radius"]&&(C.borderRadius=b(e["--cfm-mcq-border-radius"])),e["--cfm-mcq-option-gap"]&&(C.optionGap=b(e["--cfm-mcq-option-gap"])),e["--cfm-mcq-card-padding"]&&(C.cardPadding=b(e["--cfm-mcq-card-padding"])),e["--cfm-mcq-selected-bg"]&&(C.selectedBackground=e["--cfm-mcq-selected-bg"]),e["--cfm-mcq-hover-border"]&&(C.hoverBorderColor=e["--cfm-mcq-hover-border"]),Object.keys(C).length&&(m.MCQ=C);let S={};e["--cfm-input-radius"]&&(S.inputRadius=b(e["--cfm-input-radius"])),e["--cfm-input-focus-ring"]&&(S.focusRing=e["--cfm-input-focus-ring"]),e["--cfm-input-border"]&&(S.borderColor=e["--cfm-input-border"]),e["--cfm-input-padding"]&&(S.inputPadding=b(e["--cfm-input-padding"])),e["--cfm-input-height"]&&(S.inputHeight=b(e["--cfm-input-height"])),e["--cfm-input-placeholder"]&&(S.placeholderColor=e["--cfm-input-placeholder"]),Object.keys(S).length&&(m.TEXTFIELD=S);let R={};e["--cfm-nps-selected-fill"]&&(R.selectedFill=e["--cfm-nps-selected-fill"]),e["--cfm-nps-label-color"]&&(R.labelColor=e["--cfm-nps-label-color"]),e["--cfm-nps-track-bar"]&&(R.trackBarColor=e["--cfm-nps-track-bar"]),e["--cfm-nps-track-highlight"]&&(R.trackHighlightColor=e["--cfm-nps-track-highlight"]),e["--cfm-nps-cell-size"]&&(R.cellSize=b(e["--cfm-nps-cell-size"])),e["--cfm-nps-cell-gap"]&&(R.cellGap=b(e["--cfm-nps-cell-gap"])),Object.keys(R).length&&(m.NPS_SCALE=R);let E=b(e["--cfm-matrix-row-width"]),x={};E!==void 0&&(x.rowLabelWidth=E),e["--cfm-matrix-selected"]&&(x.cellSelectedColor=e["--cfm-matrix-selected"]),e["--cfm-matrix-bipolar-width"]&&(x.bipolarColumnWidthPercent=oo(e["--cfm-matrix-bipolar-width"])),e["--cfm-matrix-carousel-dot"]&&(x.carouselDotColor=e["--cfm-matrix-carousel-dot"]),e["--cfm-matrix-cell-padding"]&&(x.cellPadding=b(e["--cfm-matrix-cell-padding"])),Object.keys(x).length&&(m.CFM_MATRIX=x);let d={...x};e["--cfm-csat-accent"]&&(d.accentColor=e["--cfm-csat-accent"]),e["--cfm-csat-emoji-size"]&&(d.emojiSize=b(e["--cfm-csat-emoji-size"])),e["--cfm-csat-unselected-opacity"]&&(d.unselectedOpacity=ue(e["--cfm-csat-unselected-opacity"])),e["--cfm-csat-ring-color"]&&(d.selectedRingColor=e["--cfm-csat-ring-color"]),e["--cfm-csat-cell-size"]&&(d.cellSize=b(e["--cfm-csat-cell-size"])),e["--cfm-csat-tooltip-bg"]&&(d.tooltipBg=e["--cfm-csat-tooltip-bg"]),(Object.keys(d).length>Object.keys(x).length||e["--cfm-csat-accent"])&&(m.CSAT_MATRIX=d);let f={};e["--cfm-star-color"]&&(f.starColor=e["--cfm-star-color"]),e["--cfm-badge-color"]&&(f.badgeColor=e["--cfm-badge-color"]),E!==void 0&&(f.rowLabelWidth=E),e["--cfm-star-unselected-opacity"]&&(f.unselectedStarOpacity=ue(e["--cfm-star-unselected-opacity"])),Object.keys(f).length&&(m.RATING_MATRIX=f);let T={};e["--cfm-slider-track"]&&(T.trackColor=e["--cfm-slider-track"]),e["--cfm-slider-thumb"]&&(T.thumbColor=e["--cfm-slider-thumb"]),e["--cfm-slider-tick"]&&(T.tickColor=e["--cfm-slider-tick"]),E!==void 0&&(T.rowLabelWidth=E),e["--cfm-slider-row-band"]&&(T.rowBandColor=e["--cfm-slider-row-band"]),e["--cfm-slider-tick-size"]&&(T.tickBadgeSize=b(e["--cfm-slider-tick-size"])),Object.keys(T).length&&(m.SLIDER_MATRIX=T);let $={};e["--cfm-upload-accent"]&&($.accentColor=e["--cfm-upload-accent"]),e["--cfm-upload-padding"]&&($.dropzonePadding=b(e["--cfm-upload-padding"])),Object.keys($).length&&(m.FILE_UPLOAD=$);let h={};e["--cfm-media-max-width"]&&(h.mediaMaxWidth=oo(e["--cfm-media-max-width"])),e["--cfm-media-radius"]&&(h.mediaRadius=b(e["--cfm-media-radius"])),e["--cfm-media-caption-color"]&&(h.captionColor=e["--cfm-media-caption-color"]),e["--cfm-media-caption-size"]&&(h.captionSize=b(e["--cfm-media-caption-size"])),Object.keys(h).length&&(m.TEXT_AND_MEDIA=h);let v={};e["--cfm-heatmap-pin"]&&(v.pinColor=e["--cfm-heatmap-pin"]),e["--cfm-heatmap-pin-size"]&&(v.pinSize=b(e["--cfm-heatmap-pin-size"])),e["--cfm-heatmap-pin-border"]&&(v.pinBorderColor=e["--cfm-heatmap-pin-border"]),e["--cfm-heatmap-overlay-opacity"]&&(v.overlayOpacity=ue(e["--cfm-heatmap-overlay-opacity"])),Object.keys(v).length&&(m.HEATMAP=v);let w={};return e["--cfm-rank-item-bg"]&&(w.itemBg=e["--cfm-rank-item-bg"]),e["--cfm-rank-badge"]&&(w.rankBadgeColor=e["--cfm-rank-badge"]),e["--cfm-rank-handle"]&&(w.dragHandleColor=e["--cfm-rank-handle"]),e["--cfm-rank-item-padding"]&&(w.itemPadding=b(e["--cfm-rank-item-padding"])),e["--cfm-rank-item-gap"]&&(w.itemGap=b(e["--cfm-rank-item-gap"])),Object.keys(w).length&&(m.RANK_ORDER=w),Object.keys(n).length&&(t.colorScheme=n),Object.keys(i).length&&(t.header=i),Object.keys(s).length&&(t.footer=s),Object.keys(r).length&&(t.theme=r),Object.keys(a).length&&(t.layout=a),Object.keys(l).length&&(t.typography=l),Object.keys(y).length&&(t.motion=y),o}function ie(e){let o=[pe.join(e,"src","styles","survey-theme.css"),pe.join(e,"src","app","survey-theme.css"),pe.join(e,"src","styles","globals.css"),pe.join(e,"src","app","globals.css")];for(let t of o)if(Ce.existsSync(t)&&Ce.readFileSync(t,"utf8").includes("--cfm-"))return t;return null}var Ye,Ze,eo,$e=z(()=>{"use strict";Ye={"36rem":"narrow","48rem":"standard","64rem":"wide"},Ze={"0px":"sharp","12px":"rounded","9999px":"pill"},eo={"system-ui, sans-serif":"system","Inter, sans-serif":"modern","Georgia, serif":"serif"}});import*as xe from"fs";import*as io from"path";function Wo(e){for(let o of Bo){let t=io.join(e,o);if(xe.existsSync(t))return t}return null}function Jo(e){let o=e.trim();if(!o||o.startsWith("http")||o.startsWith("data:"))return null;let t=o.split("?")[0];return t.startsWith("/")?t.slice(1):t}function ro(e){let o=Wo(e);if(!o)return null;let t=xe.readFileSync(o,"utf8"),n=t.match(/data-cfm-logo[\s\S]*?src=["']([^"']+)["']/i)??t.match(/src=["']([^"']+)["'][\s\S]*?data-cfm-logo/i);if(n){let r=Jo(n[1]);if(r)return{mode:"image",publicPath:r,fileName:r}}let i=t.match(/data-cfm-logo-text[^>]*>([^<]+)</i);if(i)return{mode:"text",label:i[1].trim()};let s=t.match(/data-cfm-company[^>]*>([^<]+)</i);return s&&!n?{mode:"text",label:s[1].trim()}:null}var Bo,so=z(()=>{"use strict";Bo=["src/components/Header.tsx","components/Header.tsx","app/components/Header.tsx"]});var uo={};Ie(uo,{logSeedSource:()=>Ne,resolveInitialConfig:()=>se,writeResolvedUiConfig:()=>je});import*as B from"fs";import*as V from"path";function Fe(e){return e.filter(o=>Q.includes(o))}function co(e){try{let o=JSON.parse(B.readFileSync(e,"utf8"));return o.version!=="1.0"?null:(delete o.configuredAt,o)}catch{return null}}function Xo(e){let o={global:{}};if(!B.existsSync(e))return o;let t=B.readFileSync(e,"utf8"),n=new Set;for(let s of Q)t.includes(s)&&n.add(s);n.size&&(o.surveyTypes=[...n]);let i=t.match(/\*\*Branding source:\*\*\s*(.+)/i);if(i){let s=i[1].trim(),r=s.match(/company[:\s]+([^,;]+)/i),a=s.match(/title[:\s]+([^,;]+)/i);if(r&&(o.global.companyName=r[1].trim()),a){let l=a[1].trim();o.global.surveyTitle=l,o.global.browserTabTitle=l}}return o}function fo(e,o){let t=V.join(e,o);if(!B.existsSync(t))return null;let n=B.readFileSync(t);if(n.length>Ho)return{fileName:o,dataUrl:""};let i=V.extname(o).toLowerCase(),s=Vo[i]??"application/octet-stream";return{fileName:o,dataUrl:`data:${s};base64,${n.toString("base64")}`}}function ao(e,o){if(!o)return null;if(o.url&&typeof o.url=="string")return{fileName:o.fileName??null,url:o.url};if(o.fileName){let t=fo(e,o.fileName);if(t)return{fileName:t.fileName,url:t.dataUrl||null}}return o.fileName===null&&o.url===null?{fileName:null,url:null}:null}function lo(e,o){let t=e.global??{},n=o.global??{},i=e.questionTypes??{},s=o.questionTypes??{},r={...i};for(let[a,l]of Object.entries(s))r[a]={...r[a]??{},...l};return{...e,...o,surveyTypes:o.surveyTypes??e.surveyTypes,global:{...t,...n,header:{...t.header,...n.header},footer:{...t.footer,...n.footer},theme:{...t.theme,...n.theme},layout:{...t.layout,...n.layout},buttons:{...t.buttons,...n.buttons},logo:{...t.logo,...n.logo},colorScheme:{...t.colorScheme,...n.colorScheme},typography:{...t.typography,...n.typography},motion:{...t.motion,...n.motion}},questionTypes:r,placeholders:{...e.placeholders,...o.placeholders},customFields:{...e.customFields,...o.customFields},deploy:{...e.deploy,...o.deploy}}}function se(e){let o=e.projectRoot??process.env.INIT_CWD??process.cwd(),t=V.join(o,"survey-ui-config.json"),n=V.join(o,"implementation_plan.md"),i=V.join(o,"public"),s=Fe(e.surveyTypes),r={},a="defaults",l=ie(o);if(l){let w=B.readFileSync(l,"utf8"),j=to(w);Object.keys(j).length>0&&(r=no(j),a="survey-theme.css")}let y=Xo(n);r=lo(r,y);let m=co(t);m&&(r=lo(r,m),a="survey-ui-config.json");let C=V.join(o,"survey-ui-config.final.json"),S=co(C),R=!!m?.configuredAt,E=!!S?.configuredAt;if(S&&E&&!R){let w=ao(i,S.global?.logo);w&&(r.global={...r.global??{},logo:{fileName:w.fileName,url:w.url}})}let x=ao(i,r.global?.logo),d=ro(o),f=!!m?.configuredAt,T=x?.fileName!=null&&/^logo_\d+_/i.test(x.fileName),$=d?.mode==="image"?d.fileName:null,h=!f&&T&&$!=null&&x?.fileName!==$;if(x&&!h)r.global={...r.global??{},logo:{fileName:x.fileName,url:x.url}};else if(d?.mode==="image"){let w=fo(i,d.fileName);r.global={...r.global??{},logo:{fileName:d.fileName,url:w?.dataUrl||null}}}else d?.mode==="text"&&(r.global={...r.global??{},logo:{fileName:null,url:null},companyName:r.global?.companyName??d.label});return r.surveyTypes=Fe(r.surveyTypes??s),r.surveyTypes?.length||(r.surveyTypes=s),e.instanceId&&(r.instanceId=e.instanceId),{config:Ge(r),source:a}}function Ne(e){console.log(e==="survey-ui-config.json"?`${re.dim} Seeding wizard from survey-ui-config.json${re.reset}`:e==="survey-theme.css"?`${re.dim} Seeding wizard from survey-theme.css + defaults${re.reset}`:`${re.dim} Seeding wizard from SDK defaults${re.reset}`)}function je(e={}){let o=e.projectRoot??process.env.INIT_CWD??process.cwd(),t=e.surveyTypes??Fe(Q),{config:n}=se({projectRoot:o,surveyTypes:t,instanceId:e.instanceId}),i=V.join(o,"survey-ui-config.json");return B.writeFileSync(i,JSON.stringify(n,null,2),"utf8"),i}var re,Ho,Vo,ge=z(()=>{"use strict";M();Ke();$e();be();so();re=c,Ho=512e3,Vo={".png":"image/png",".jpg":"image/jpeg",".jpeg":"image/jpeg",".gif":"image/gif",".webp":"image/webp",".svg":"image/svg+xml"}});import*as le from"fs";import*as fe from"path";function So(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function bo(e,o){return JSON.stringify(e)===JSON.stringify(o)}function ae(e){return typeof e=="string"&&e.startsWith("data:")&&e.length>80?`${e.slice(0,48)}\u2026 (${e.length} chars)`:e}function Co(e,o,t,n){if(bo(e,o)){n.unchangedCount+=1;return}if(e===void 0&&o!==void 0){n.added.push({path:t,before:void 0,after:ae(o)});return}if(e!==void 0&&o===void 0){n.removed.push({path:t,before:ae(e),after:void 0});return}if(Array.isArray(e)&&Array.isArray(o)){bo(e,o)?n.unchangedCount+=1:n.changed.push({path:t,before:ae(e),after:ae(o)});return}if(So(e)&&So(o)){let i=new Set([...Object.keys(e),...Object.keys(o)]);for(let s of i){if(ct.has(s)&&t==="")continue;let r=t?`${t}.${s}`:s;Co(e[s],o[s],r,n)}return}n.changed.push({path:t,before:ae(e),after:ae(o)})}function Me(e,o){let t={changed:[],added:[],removed:[],unchangedCount:0};return Co(e,o,"",t),t}function Pe(e){let o=["# UI Config Diff (seed \u2192 final)","",`**Changed:** ${e.changed.length} \xB7 **Added:** ${e.added.length} \xB7 **Removed:** ${e.removed.length}`,"","> Review only \u2014 run `npx cfm-sdk confirm-ui-config` to apply final config to the project.",""],t=(n,i)=>{if(i.length){o.push(`## ${n}`,"");for(let s of i)o.push(`### \`${s.path}\``),o.push(`- **Before:** \`${JSON.stringify(s.before)}\``),o.push(`- **After:** \`${JSON.stringify(s.after)}\``),o.push("")}};return t("Changed",e.changed),t("Added",e.added),t("Removed",e.removed),!e.changed.length&&!e.added.length&&!e.removed.length&&o.push("_No differences \u2014 final config matches seed._",""),o.join(`
|
|
3
|
+
`)}function Y(e){return{seedPath:fe.join(e,"survey-ui-config.seed.json"),finalPath:fe.join(e,"survey-ui-config.final.json"),diffJsonPath:fe.join(e,"survey-ui-config.diff.json"),diffMdPath:fe.join(e,"survey-ui-config.diff.md"),activeConfigPath:fe.join(e,"survey-ui-config.json")}}function ke(e,o,t){let n=Y(e),i=Me(o,t);return le.writeFileSync(n.seedPath,JSON.stringify(o,null,2),"utf8"),le.writeFileSync(n.finalPath,JSON.stringify(t,null,2),"utf8"),le.writeFileSync(n.diffJsonPath,JSON.stringify(i,null,2),"utf8"),le.writeFileSync(n.diffMdPath,Pe(i),"utf8"),le.writeFileSync(n.activeConfigPath,JSON.stringify(o,null,2),"utf8"),i}var ct,ve=z(()=>{"use strict";ct=new Set(["configuredAt","instanceId"])});import*as Z from"fs";import*as xo from"http";import*as To from"https";import*as Ue from"path";function Ee(e){if(!e.config)return null;let o=JSON.parse(JSON.stringify(e.config)),n=o.global?.logo;return e.logoUrl&&n&&(n.url=e.logoUrl),o}function $o(e){return new Promise((o,t)=>{let n=new URL(e);(n.protocol==="https:"?To:xo).get(n,s=>{if((s.statusCode??500)>=400){t(new Error(`Logo download failed HTTP ${s.statusCode}`));return}let r=[];s.on("data",a=>r.push(a)),s.on("end",()=>o(Buffer.concat(r)))}).on("error",t)})}async function at(e,o={}){return new Promise((t,n)=>{let i=new URL(e),r=(i.protocol==="https:"?To:xo).request(i,{method:"GET",headers:o.headers??{}},a=>{let l="";a.on("data",y=>l+=y),a.on("end",()=>{if((a.statusCode??500)>=400){n(new Error(`HTTP ${a.statusCode}: ${l}`));return}try{t(JSON.parse(l))}catch{n(new Error(`Invalid JSON: ${l.slice(0,200)}`))}})});r.on("error",n),r.end()})}async function ee(e){let{projectRoot:o,fileName:t,logoUrl:n,jwt:i,apiBase:s,surveyId:r}=e,a=Ue.join(o,"public");Z.existsSync(a)||Z.mkdirSync(a,{recursive:!0});let l=Ue.join(a,t);if(n){let y=await $o(n);return Z.writeFileSync(l,y),l}if(i&&s&&r){let y=await at(`${s.replace(/\/$/,"")}/wizard/logo/${encodeURIComponent(r)}/${encodeURIComponent(t)}`,{headers:{Authorization:`Bearer ${i}`}}),m=await $o(y.downloadUrl);return Z.writeFileSync(l,m),l}throw new Error("Logo download requires logoUrl from wizard poll or CFM_INSTANCE_ID + CFM_DEPLOY_API_BASE")}var Re=z(()=>{"use strict"});var Eo={};Ie(Eo,{runConfirmUiConfig:()=>mt});import*as J from"fs";function gt(e){try{let o=e.split(".")[1];return JSON.parse(Buffer.from(o,"base64url").toString("utf8")).surveyId??null}catch{return null}}async function mt(e={}){let o=process.env.INIT_CWD??process.cwd(),t=Y(o);if(!J.existsSync(t.finalPath))throw new Error(`Missing ${t.finalPath}. Run customize-ui with --review and complete the wizard first.`);let n=JSON.parse(J.readFileSync(J.existsSync(t.seedPath)?t.seedPath:t.activeConfigPath,"utf8")),i=JSON.parse(J.readFileSync(t.finalPath,"utf8")),s=Me(n,i);if(console.log(`
|
|
4
|
+
${U.bold}${U.cyan}\u{1F4CB} UI config review${U.reset}
|
|
5
|
+
`),console.log(Pe(s)),e.diffOnly){J.writeFileSync(t.diffJsonPath,JSON.stringify(s,null,2),"utf8"),J.writeFileSync(t.diffMdPath,Pe(s),"utf8"),console.log(`${U.dim} Updated ${t.diffMdPath}${U.reset}`);return}J.writeFileSync(t.activeConfigPath,JSON.stringify(i,null,2),"utf8"),console.log(`${U.green}\u2705 Applied final config \u2192 ${t.activeConfigPath}${U.reset}`);let r=i.global?.logo;if(!r?.fileName)return;let a=process.env.CFM_INSTANCE_ID,l=(process.env.CFM_DEPLOY_API_BASE??"").replace(/\/$/,""),y=a?gt(a):null;try{await ee({projectRoot:o,fileName:r.fileName,logoUrl:r.url,jwt:a??void 0,apiBase:l||void 0,surveyId:y??void 0}),console.log(`${U.green} Logo saved to public/${r.fileName}${U.reset}`),r.url&&console.log(`${U.dim} Public logo URL: ${r.url}${U.reset}`)}catch(m){console.log(`${U.yellow} Logo not downloaded \u2014 ${m instanceof Error?m.message:String(m)}${U.reset}`)}}var U,Ro=z(()=>{"use strict";M();ve();Re();U=c});var Io={};Ie(Io,{runFetchUiConfig:()=>bt});import*as ye from"fs";import*as ht from"http";import*as yt from"https";async function wt(e,o={}){return new Promise((t,n)=>{let i=new URL(e),r=(i.protocol==="https:"?yt:ht).request(i,{method:"GET",headers:o.headers??{}},a=>{let l="";a.on("data",y=>l+=y),a.on("end",()=>{if((a.statusCode??500)>=400){n(new Error(`HTTP ${a.statusCode}: ${l}`));return}try{t(JSON.parse(l))}catch{n(new Error(`Invalid JSON: ${l.slice(0,200)}`))}})});r.on("error",n),r.end()})}function St(e){try{let o=e.split(".")[1];return JSON.parse(Buffer.from(o,"base64url").toString("utf8")).surveyId??null}catch{return null}}async function bt(e={}){let o=process.env.CFM_INSTANCE_ID,t=(process.env.CFM_DEPLOY_API_BASE??"").replace(/\/$/,""),n=e.sessionId??process.env.CFM_WIZARD_SESSION_ID;if(!o)throw new Error("CFM_INSTANCE_ID (JWT) is required");if(!t)throw new Error("CFM_DEPLOY_API_BASE is required");if(!n)throw new Error("CFM_WIZARD_SESSION_ID or --session= is required");let i=St(o);if(!i)throw new Error("Could not parse surveyId from CFM_INSTANCE_ID JWT");let s=process.env.INIT_CWD??process.cwd(),r=Y(s),a=ye.existsSync(r.seedPath)?r.seedPath:r.activeConfigPath;if(!ye.existsSync(a))throw new Error(`Missing seed config at ${a}. Run customize-ui --review first.`);let l=await wt(`${t}/wizard/config/${encodeURIComponent(i)}?sessionId=${encodeURIComponent(n)}`,{headers:{Authorization:`Bearer ${o}`}});if(l.status!=="ready"||!l.config)throw new Error(`Wizard not complete yet (status: ${l.status})`);let y=Ee(l)??l.config,m=JSON.parse(ye.readFileSync(a,"utf8")),C=ke(s,m,y),S=y.global?.logo;if(S?.fileName)try{await ee({projectRoot:s,fileName:S.fileName,logoUrl:l.logoUrl,jwt:o,apiBase:t,surveyId:i}),console.log(`${O.green} Logo saved to public/${S.fileName}${O.reset}`)}catch(R){console.warn(`${O.yellow} Logo download failed: ${R}${O.reset}`)}console.log(`
|
|
6
|
+
${O.green}\u2705 Fetched final config (review mode)${O.reset}`),console.log(`${O.green} Final: ${r.finalPath}${O.reset}`),console.log(`${O.green} Diff: ${r.diffMdPath}${O.reset}`),console.log(`${O.yellow} ${C.changed.length} changed, ${C.added.length} added, ${C.removed.length} removed${O.reset}`),console.log(`${O.dim} Apply when ready: npx cfm-sdk confirm-ui-config${O.reset}`)}var O,Fo=z(()=>{"use strict";M();ve();Re();O=c});M();M();import{execSync as We,spawn as jo}from"child_process";function te(e){try{let o=process.platform==="win32"?`where ${e}`:`command -v ${e}`;return We(o,{stdio:"ignore"}),!0}catch{return!1}}var Ao={stdio:"inherit",shell:process.platform==="win32"?"cmd.exe":"/bin/sh"};function de(e,o){try{let t=`${e} ${o.join(" ")}`;return We(t,Ao),!0}catch{return!1}}function Se(e,o){return new Promise(t=>{jo(e,o,{stdio:"inherit",shell:!0}).on("close",i=>{t(i)})})}import _o from"readline/promises";import{stdin as Do,stdout as Oo}from"process";async function ne(e){let o=_o.createInterface({input:Do,output:Oo});try{return(await o.question(e)).trim()}finally{o.close()}}async function Je(){let e=parseInt(process.version.slice(1).split(".")[0],10);if(console.log(`${c.dim}Step 1/4: Checking Node.js version (current: ${process.version})...${c.reset}`),e<18){console.log(`\u26A0\uFE0F ${c.yellow}Outdated Node.js version detected. v18.0.0 or higher is required.${c.reset}`),console.log(`${c.dim}Note: If you already have a higher version installed via nvm, please run 'nvm use <version>' first.${c.reset}
|
|
7
|
+
`);let o=await ne("Would you like to install/upgrade Node.js v18+ automatically? (y/N): ");o.toLowerCase()==="y"||o.toLowerCase()==="yes"||(console.log(`
|
|
8
8
|
\u274C ${c.red}Aborted. Please manually upgrade Node.js to v18+ and try again.${c.reset}
|
|
9
|
-
`),process.exit(1));let n=process.platform==="win32",i=process.platform==="darwin";n?
|
|
9
|
+
`),process.exit(1));let n=process.platform==="win32",i=process.platform==="darwin";n?te("winget")?(console.log(`
|
|
10
10
|
\u{1F4E6} ${c.green}winget package manager found! Installing Node.js v18+ in background...${c.reset}`),de("winget",["upgrade","OpenJS.NodeJS","--silent","--accept-package-agreements","--accept-source-agreements"])?(console.log(`
|
|
11
11
|
\u2714 ${c.green}Node.js installation triggered successfully. Please restart your terminal/command-prompt for changes to take effect.${c.reset}
|
|
12
12
|
`),process.exit(0)):(console.log(`
|
|
13
13
|
\u274C ${c.red}winget update failed. Please update Node.js manually at https://nodejs.org/${c.reset}
|
|
14
14
|
`),process.exit(1))):(console.log(`
|
|
15
15
|
\u274C ${c.red}winget package manager is not installed on this system.${c.reset}`),console.log(`${c.bold}\u{1F449} To proceed, please either:${c.reset}`),console.log(" 1. Install winget (App Installer) from the Microsoft Store."),console.log(` 2. Or manually download and install Node.js (v18+) from: https://nodejs.org/
|
|
16
|
-
`),process.exit(1)):i?
|
|
16
|
+
`),process.exit(1)):i?te("brew")?(console.log(`
|
|
17
17
|
\u{1F4E6} ${c.green}Homebrew package manager found! Installing Node.js v18+ in background...${c.reset}`),de("brew",["install","node"])?console.log(`
|
|
18
18
|
\u2714 ${c.green}Node.js installed successfully via Homebrew.${c.reset}
|
|
19
19
|
`):(console.log(`
|
|
@@ -22,18 +22,18 @@ ${L.green}\u2705 Fetched final config (review mode)${L.reset}`),console.log(`${L
|
|
|
22
22
|
\u274C ${c.red}Homebrew package manager (brew) is not installed on this system.${c.reset}`),console.log(`${c.bold}\u{1F449} To proceed, please either:${c.reset}`),console.log(" 1. Install Homebrew by running the following command in your terminal:"),console.log(` ${c.cyan}/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"${c.reset}`),console.log(` 2. Or manually download and install Node.js (v18+) from: https://nodejs.org/
|
|
23
23
|
`),process.exit(1)):(console.log(`
|
|
24
24
|
\u274C ${c.red}Please install or update Node.js to v18+ using your system's package manager.${c.reset}
|
|
25
|
-
`),process.exit(1))}else console.log(`\u2714 ${c.green}Node.js version (v${e}) is sufficient.${c.reset}`)}
|
|
26
|
-
${c.dim}Step 2/4: Checking Vercel CLI...${c.reset}`);let e="vercel",o=!1;if(
|
|
27
|
-
\u{1F4E5} ${c.cyan}Installing Vercel CLI globally... (npm install -g vercel)${c.reset}`),de("npm",["install","-g","vercel"])&&
|
|
28
|
-
\u26A0\uFE0F ${c.yellow}Global installation failed or permissions restricted.${c.reset}`),console.log(`\u2139 ${c.dim}Falling back: Running Vercel dynamically via npx.${c.reset}`),e="npx --yes vercel",o=!0)):(console.log(`\u2139 ${c.dim}Skipping global installation. Running Vercel dynamically via npx.${c.reset}`),e="npx --yes vercel",o=!0)}return{vercelCmd:e,useNpx:o}}
|
|
29
|
-
${c.dim}Step 3/4: Checking Vercel Login...${c.reset}`);let o=!!process.env.VERCEL_TOKEN,t=!1;if(o)console.log(`\u2714 ${c.green}VERCEL_TOKEN environment variable detected. Skipping login check.${c.reset}`),t=!0;else try{
|
|
30
|
-
\u2714 ${c.green}Logged in successfully!${c.reset}`)}return o}
|
|
25
|
+
`),process.exit(1))}else console.log(`\u2714 ${c.green}Node.js version (v${e}) is sufficient.${c.reset}`)}M();async function He(){console.log(`
|
|
26
|
+
${c.dim}Step 2/4: Checking Vercel CLI...${c.reset}`);let e="vercel",o=!1;if(te("vercel"))console.log(`\u2714 ${c.green}Vercel CLI is installed!${c.reset}`);else{console.log(`\u2753 ${c.yellow}Vercel CLI was not found on your system.${c.reset}`);let t=await ne("\u{1F449} Would you like to install Vercel CLI globally? (Y/n): ");t.toLowerCase()==="y"||t===""?(console.log(`
|
|
27
|
+
\u{1F4E5} ${c.cyan}Installing Vercel CLI globally... (npm install -g vercel)${c.reset}`),de("npm",["install","-g","vercel"])&&te("vercel")?console.log(`\u2714 ${c.green}Vercel CLI installed successfully!${c.reset}`):(console.log(`
|
|
28
|
+
\u26A0\uFE0F ${c.yellow}Global installation failed or permissions restricted.${c.reset}`),console.log(`\u2139 ${c.dim}Falling back: Running Vercel dynamically via npx.${c.reset}`),e="npx --yes vercel",o=!0)):(console.log(`\u2139 ${c.dim}Skipping global installation. Running Vercel dynamically via npx.${c.reset}`),e="npx --yes vercel",o=!0)}return{vercelCmd:e,useNpx:o}}M();import{execSync as Lo}from"child_process";var Mo={stdio:"ignore",shell:process.platform==="win32"?"cmd.exe":"/bin/sh"};async function Ve(e){console.log(`
|
|
29
|
+
${c.dim}Step 3/4: Checking Vercel Login...${c.reset}`);let o=!!process.env.VERCEL_TOKEN,t=!1;if(o)console.log(`\u2714 ${c.green}VERCEL_TOKEN environment variable detected. Skipping login check.${c.reset}`),t=!0;else try{Lo(e?"npx --yes vercel whoami":"vercel whoami",Mo),t=!0,console.log(`\u2714 ${c.green}Logged in!${c.reset}`)}catch{t=!1}if(!t){console.log(`\u{1F511} ${c.yellow}Not logged in to Vercel.${c.reset}`),await ne("\u{1F449} Press [Enter] to login to Vercel... ");let n=["login"],i=e?"npx":"vercel",s=e?["--yes","vercel",...n]:n;if(await Se(i,s)!==0)throw new Error("Vercel login failed or was aborted.");console.log(`
|
|
30
|
+
\u2714 ${c.green}Logged in successfully!${c.reset}`)}return o}M();async function Xe(e,o){console.log(`
|
|
31
31
|
${c.dim}Step 4/4: Deploying project to production...${c.reset}`);let t=["--prod","--yes"];o&&t.push("--token",process.env.VERCEL_TOKEN);let n=e?"npx":"vercel",i=e?["--yes","vercel",...t]:t;if(console.log(`${c.cyan}\u26A1 Running deployment in: ${process.cwd()}${c.reset}
|
|
32
32
|
`),await Se(n,i)!==0)throw new Error("Vercel deployment failed.");console.log(`
|
|
33
33
|
${c.bold}${c.green}\u{1F389} Deployment completed successfully!${c.reset}
|
|
34
|
-
`)}async function
|
|
34
|
+
`)}async function qe(){console.log(`
|
|
35
35
|
${c.bold}${c.cyan}\u{1F680} Starting CFM Vercel Deployment...${c.reset}
|
|
36
|
-
`),await
|
|
36
|
+
`),await Je();let{vercelCmd:e,useNpx:o}=await He(),t=await Ve(o);await Xe(o,t)}M();import*as he from"http";import*as k from"fs";import*as N from"path";function D(e){return e instanceof Error?e.message:String(e)}ge();M();import*as F from"fs";import*as I from"path";$e();$e();import*as u from"fs";import*as p from"path";import{execSync as qo}from"child_process";function K(e,o){if(u.existsSync(e)){u.mkdirSync(o,{recursive:!0});for(let t of u.readdirSync(e,{withFileTypes:!0})){let n=p.join(e,t.name),i=p.join(o,t.name);t.isDirectory()?K(n,i):u.copyFileSync(n,i)}}}function Ae(e){let o=[],t=e;for(let n=0;n<6;n++){let i=p.join(t,"node_modules");u.existsSync(i)&&o.push(i);let s=p.dirname(t);if(s===t)break;t=s}return o}function Qo(e,o){let t=Ae(e);for(let n of t)for(let i of["@explorer02/cfm-survey-sdk","@repo/sdk"])for(let s of["mjs","js"]){let r=p.join(n,i,"dist",`index.${s}`);if(u.existsSync(r))return r}for(let n of["mjs","js"]){let i=p.join(o,"dist",`index.${n}`);if(u.existsSync(i))return i}throw new Error("Could not resolve @explorer02/cfm-survey-sdk for preview build")}function Go(e,o){let t=[...Ae(o).map(n=>p.join(n,"vite","bin","vite.js")),p.join(e,"node_modules","vite","bin","vite.js")];for(let n of t)if(u.existsSync(n))return n;throw new Error("Vite is required for agent preview builds. Install vite in the project or SDK package.")}function Ko(e){let o=p.join(e,"src","components");if(!u.existsSync(p.join(o,"Question.tsx")))throw new Error(`Missing src/components/Question.tsx in ${e}. Build the survey UI before export-previews.`);let t=p.join(e,"src","lib"),n=p.join(e,"public");return{componentsDir:o,libDir:u.existsSync(t)?t:void 0,publicDir:u.existsSync(n)?n:void 0}}function Yo(e){let o=`import React from 'react';
|
|
37
37
|
import { mountPreview } from '../mount';
|
|
38
38
|
`;switch(e){case"header":return`${o}import Header from '@/components/Header';
|
|
39
39
|
import ProgressBar from '@/components/ProgressBar';
|
|
@@ -76,7 +76,7 @@ mountPreview(<EndPage page={FIXTURE_END} />);`;default:return`${o}import { Quest
|
|
|
76
76
|
import { PREVIEW_FIXTURES } from '../fixtures/questions';
|
|
77
77
|
const question = PREVIEW_FIXTURES[${JSON.stringify(e)}];
|
|
78
78
|
if (!question) throw new Error('Missing fixture for ${e}');
|
|
79
|
-
mountPreview(<QuestionPreview question={question} />);`}}function
|
|
79
|
+
mountPreview(<QuestionPreview question={question} />);`}}function Zo(e,o,t,n){let i=Qo(o,t),s=n.map(a=>` '${a}': path.resolve(workDir, '${a}', 'index.html'),`).join(`
|
|
80
80
|
`),r=`import path from 'path';
|
|
81
81
|
import { fileURLToPath } from 'url';
|
|
82
82
|
import { defineConfig } from 'vite';
|
|
@@ -111,37 +111,34 @@ ${s}
|
|
|
111
111
|
},
|
|
112
112
|
},
|
|
113
113
|
});
|
|
114
|
-
`;u.writeFileSync(p.join(e,"vite.config.mjs"),r)}function
|
|
114
|
+
`;u.writeFileSync(p.join(e,"vite.config.mjs"),r)}function et(e,o){let t=u.readFileSync(e,"utf8");if(t.includes("preview-bridge.inline"))return;let n=`<script>${o}</script>`;t=t.includes("</body>")?t.replace("</body>",`${n}
|
|
115
115
|
</body>`):`${t}
|
|
116
|
-
${n}`,u.writeFileSync(e,t)}function
|
|
116
|
+
${n}`,u.writeFileSync(e,t)}function ot(e){return e.replace(/_/g," ")}async function po(e){let{projectRoot:o,outputDir:t,keys:n}=e,i=p.join(__dirname,"..",".."),s=p.join(i,"templates","preview-harness","vite-app");if(!u.existsSync(s))throw new Error(`Missing Vite preview harness template at ${s}`);let r=Ko(o),a=p.join(t,".preview-vite-work");u.existsSync(a)&&u.rmSync(a,{recursive:!0,force:!0}),K(s,a),u.mkdirSync(p.join(a,"agent","src"),{recursive:!0}),K(r.componentsDir,p.join(a,"agent","src","components")),r.libDir&&K(r.libDir,p.join(a,"agent","src","lib")),r.publicDir&&K(r.publicDir,p.join(a,"agent","public"));let l=ie(o),y=p.join(a,"src","survey-theme.css");u.writeFileSync(y,l?u.readFileSync(l,"utf8"):u.readFileSync(p.join(i,"templates","survey-theme.css"),"utf8")),u.mkdirSync(p.join(a,"src","entries"),{recursive:!0});for(let f of n)u.mkdirSync(p.join(a,f),{recursive:!0}),u.writeFileSync(p.join(a,f,"index.html"),`<!DOCTYPE html>
|
|
117
117
|
<html lang="en">
|
|
118
118
|
<head>
|
|
119
119
|
<meta charset="UTF-8" />
|
|
120
120
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
121
|
-
<title>${
|
|
121
|
+
<title>${ot(f)} \u2014 CFM Preview</title>
|
|
122
122
|
</head>
|
|
123
123
|
<body>
|
|
124
124
|
<div id="root"></div>
|
|
125
125
|
<script type="module" src="../src/entries/${f}.tsx"></script>
|
|
126
126
|
</body>
|
|
127
|
-
</html>`),u.writeFileSync(p.join(a,"src","entries",`${f}.tsx`),
|
|
128
|
-
${
|
|
129
|
-
${j.bold}${j.cyan}\u{1F3A8} Survey UI Customization Wizard${j.reset}`),console.log(`${j.dim} Running at ${j.reset}${j.green}${d}${j.reset}`),console.log(`${j.dim} Live previews: ${j.reset}${Object.keys(a).length} components`),console.log(`${j.dim} Preview target: ${j.reset}${r}`),console.log(`${j.dim} Default wizard \u2014 saves directly to survey-ui-config.json when client clicks Review & Build${j.reset}
|
|
130
|
-
`),it(d)}),v.on("error",E);let x=()=>{Le(e),v.close(()=>process.exit(130))};process.once("SIGINT",x),process.once("SIGTERM",x)})}U();import*as fe from"fs";import*as xo from"path";import*as To from"http";import*as ko from"https";be();pe();Ee();Re();var g=c;function lt(e){let{exec:o}=we("child_process"),t=process.platform==="darwin"?`open "${e}"`:process.platform==="win32"?`start "" "${e}"`:`xdg-open "${e}"`;o(t)}function ft(e){return new Promise(o=>setTimeout(o,e))}async function ze(e,o={}){return new Promise((t,n)=>{let i=new URL(e),r=(i.protocol==="https:"?ko:To).request(i,{method:o.method??"GET",headers:o.headers??{}},a=>{let l="";a.on("data",y=>l+=y),a.on("end",()=>{if((a.statusCode??500)>=400){n(new Error(`HTTP ${a.statusCode}: ${l}`));return}try{t(JSON.parse(l))}catch{n(new Error(`Invalid JSON: ${l.slice(0,200)}`))}})});r.on("error",n),o.body&&r.write(o.body),r.end()})}async function dt(e,o,t,n){return new Promise((i,s)=>{let r=new URL(e),a=r.protocol==="https:"?ko:To,l={"Content-Type":t,"Content-Length":o.length};n&&(l["X-Wizard-Session"]=n.sessionSecret,l["X-Wizard-Session-Id"]=n.sessionId);let y=a.request(r,{method:"PUT",headers:l},m=>{if((m.statusCode??500)>=400){let C="";m.on("data",S=>C+=S),m.on("end",()=>s(new Error(`PUT failed ${m.statusCode}: ${C}`)));return}m.resume(),i()});y.on("error",s),y.write(o),y.end()})}function gt(e){try{let o=e.split(".")[1];return JSON.parse(Buffer.from(o,"base64url").toString("utf8")).surveyId??null}catch{return null}}async function Po(e={}){let o=e.wait!==!1,t=e.pollIntervalMs??Number(process.env.CFM_WIZARD_POLL_MS??3e3),n=e.timeoutMs??Number(process.env.CFM_WIZARD_TIMEOUT_MS??72e5),i=process.env.CFM_INSTANCE_ID,s=(process.env.CFM_DEPLOY_API_BASE??"http://localhost:3000").replace(/\/$/,"");if(!i)throw new Error("CFM_INSTANCE_ID (JWT) is required");let r=gt(i);if(!r)throw new Error("Could not parse surveyId from CFM_INSTANCE_ID JWT");let a=Te(),l=K(a),y=l.activeConfigPath,m=e.apply?!1:e.review!==!1;console.log(`
|
|
127
|
+
</html>`),u.writeFileSync(p.join(a,"src","entries",`${f}.tsx`),Yo(f));u.writeFileSync(p.join(a,"tsconfig.json"),JSON.stringify({compilerOptions:{target:"ES2020",lib:["ES2020","DOM","DOM.Iterable"],module:"ESNext",moduleResolution:"bundler",jsx:"react-jsx",strict:!0,skipLibCheck:!0,paths:{"@/*":["./agent/src/*"]}},include:["src","agent/src","stubs"]},null,2)),Zo(a,o,i,n);let m=Go(i,o),C=Ae(o).join(p.delimiter);qo(`node "${m}" build --config "${p.join(a,"vite.config.mjs")}"`,{cwd:a,stdio:"inherit",env:{...process.env,NODE_PATH:C}});let S=p.join(t,"previews");u.mkdirSync(S,{recursive:!0});let R=p.join(a,"dist"),E=u.readFileSync(p.join(i,"templates","preview-harness","preview-bridge.inline.js"),"utf8");for(let f of n){let T=p.join(R,f),$=p.join(S,f);if(!u.existsSync(p.join(T,"index.html")))throw new Error(`Vite build did not produce ${f}/index.html`);u.existsSync($)&&u.rmSync($,{recursive:!0,force:!0}),K(T,$),et(p.join($,"index.html"),E)}let x=p.join(R,"assets");u.existsSync(x)&&K(x,p.join(S,"assets"));let d=p.join(a,"agent","public");if(u.existsSync(d))for(let f of u.readdirSync(d)){let T=p.join(d,f);u.statSync(T).isFile()&&u.copyFileSync(T,p.join(S,f))}u.rmSync(a,{recursive:!0,force:!0})}import*as _e from"fs";import*as De from"path";function Te(e){if(e)return e;let o=process.cwd();if(_e.existsSync(De.join(o,"src","components","Question.tsx")))return o;let t=process.env.INIT_CWD;return t&&_e.existsSync(De.join(t,"src","components","Question.tsx"))?t:o}var _=c;function tt(){return I.join(__dirname,"..","..","templates")}function nt(e){let o=F.readFileSync(e,"utf8"),t=new Set,n=["MCQ","TEXTFIELD","NPS_SCALE","CFM_MATRIX","CSAT_MATRIX","RATING_MATRIX","SLIDER_MATRIX","FILE_UPLOAD","TEXT_AND_MEDIA","HEATMAP","RANK_ORDER"];for(let i of n)o.includes(i)&&t.add(i);return t.size?[...t]:n}function it(e,o){let t=["header","footer","chrome","survey_page","intro","end"],n={MCQ:["MCQ_single","MCQ_multiple"],TEXTFIELD:["TEXTFIELD_short","TEXTFIELD_long"],NPS_SCALE:["NPS_SCALE"],CFM_MATRIX:["CFM_likert","CFM_bipolar"],CSAT_MATRIX:["CSAT_emoji","CSAT_star","CSAT_numbered","CSAT_graphics","CSAT_carousel","CSAT_dropdown"],RATING_MATRIX:["RATING_star","RATING_numbered","RATING_radio","RATING_emoji","RATING_graphics","RATING_slider"],SLIDER_MATRIX:["SLIDER_matrix"],FILE_UPLOAD:["FILE_UPLOAD"],HEATMAP:["HEATMAP"],RANK_ORDER:["RANK_drag","RANK_dropdown"]},i=new Set(t);for(let s of o)for(let r of n[s]??[])i.add(r);return e.filter(s=>i.has(s))}function Oe(e,o,t){if(F.existsSync(e))for(let n of F.readdirSync(e)){let i=I.join(e,n),s=I.posix.join(o,n);if(F.statSync(i).isDirectory())Oe(i,s,t);else{let r=I.extname(n).toLowerCase(),a=r===".html"?"text/html":r===".css"?"text/css":r===".js"?"application/javascript":r===".json"?"application/json":r===".svg"?"image/svg+xml":r===".jpg"||r===".jpeg"?"image/jpeg":r===".png"?"image/png":"application/octet-stream";t.push({path:s,contentType:a,sizeBytes:F.statSync(i).size})}}}async function ce(e={}){let o=Te(e.projectRoot),t=e.outputDir??I.join(o,"out"),n=tt(),i=I.join(n,"preview-harness");e.useTemplatesOnly&&console.log(`${_.dim} Using SDK template preview harness only (--use-templates-only)${_.reset}`);let s=I.join(i,"previewPages.js"),{PREVIEW_PAGE_DEFS:r,buildPreviewHtml:a,PREVIEW_KEYS:l}=we(s),y=(()=>{let d=ie(o);return d?(console.log(`${_.dim} Using project theme: ${I.relative(o,d)}${_.reset}`),F.readFileSync(d,"utf8")):F.readFileSync(I.join(n,"survey-theme.css"),"utf8")})(),m=F.readFileSync(I.join(i,"preview-bridge.inline.js"),"utf8"),C=e.surveyTypes;if(!C){let d=I.join(o,"implementation_plan.md");C=F.existsSync(d)?nt(d):["MCQ","TEXTFIELD","NPS_SCALE","CFM_MATRIX","CSAT_MATRIX","RATING_MATRIX","SLIDER_MATRIX","FILE_UPLOAD","TEXT_AND_MEDIA","HEATMAP","RANK_ORDER"]}let S=it(l,C),R=I.join(t,"previews");if(F.existsSync(R)&&(F.rmSync(R,{recursive:!0,force:!0}),console.log(`${_.dim} Cleared previous preview output${_.reset}`)),F.mkdirSync(R,{recursive:!0}),!e.useTemplatesOnly)try{console.log(`${_.dim} Building previews from agent components (Vite)\u2026${_.reset}`),await po({projectRoot:o,outputDir:t,keys:S});let d={};for(let T of S)d[T]=`previews/${T}/index.html`;F.writeFileSync(I.join(t,"previews","manifest.json"),JSON.stringify(d,null,2));let f=[];return Oe(I.join(t,"previews"),"previews",f),console.log(`${_.green}\u2705 Exported ${S.length} agent component previews \u2192 ${t}${_.reset}`),{outputDir:t,manifestPath:I.join(t,"previews","manifest.json"),files:f,surveyTypes:C}}catch(d){console.warn(`${_.yellow}\u26A0 Agent Vite preview build failed; falling back to template harness.${_.reset}`),console.warn(`${_.dim} ${D(d)}${_.reset}`)}for(let d of r){if(!S.includes(d.key))continue;let f=I.join(t,"previews",d.key);F.mkdirSync(f,{recursive:!0}),F.writeFileSync(I.join(f,"index.html"),a(d,y,m))}let E={};for(let d of S)E[d]=`previews/${d}/index.html`;F.writeFileSync(I.join(t,"previews","manifest.json"),JSON.stringify(E,null,2));let x=[];return Oe(I.join(t,"previews"),"previews",x),console.log(`${_.green}\u2705 Exported ${S.length} preview pages \u2192 ${t}${_.reset}`),{outputDir:t,manifestPath:I.join(t,"previews","manifest.json"),files:x,surveyTypes:C}}var G=c,me=["MCQ","TEXTFIELD","NPS_SCALE","CFM_MATRIX","CSAT_MATRIX","RATING_MATRIX","SLIDER_MATRIX","FILE_UPLOAD","TEXT_AND_MEDIA","HEATMAP","RANK_ORDER"];function yo(e){return new Promise(o=>{let t=he.createServer();t.listen(e,()=>{t.close(()=>o(e))}),t.on("error",()=>o(yo(e+1)))})}function go(e){return new Promise((o,t)=>{let n="";e.on("data",i=>n+=i),e.on("end",()=>o(n)),e.on("error",t)})}function rt(e){let{exec:o}=we("child_process"),t=process.platform==="darwin"?`open "${e}"`:process.platform==="win32"?`start "" "${e}"`:`xdg-open "${e}"`;o(t)}function mo(e){let o=N.extname(e).toLowerCase();return{".html":"text/html",".js":"application/javascript",".css":"text/css",".json":"application/json",".svg":"image/svg+xml",".png":"image/png",".jpg":"image/jpeg",".woff2":"font/woff2",".ico":"image/x-icon"}[o]??"application/octet-stream"}function st(e){let o=new Set,t,n=e.match(/\*\*instanceId:\*\*\s*(.+)/i);if(n){let s=n[1].replace(/[()[\]]/g,"").trim();s&&!s.startsWith("(")&&s!=="JWT"&&(t=s)}for(let s of me)e.includes(s)&&o.add(s);let i=e.matchAll(/\|\s*`([A-Z_]+)`\s*\|/g);for(let s of i)me.includes(s[1])&&o.add(s[1]);return{surveyTypes:o.size>0?[...o]:[...me],instanceId:t}}async function ho(e){return new Promise(o=>{try{let t=he.get(e,n=>{o((n.statusCode??500)<500),n.resume()});t.on("error",()=>o(!1)),t.setTimeout(2e3,()=>{t.destroy(),o(!1)})}catch{o(!1)}})}function Le(e){let o=N.join(e,"out","previews");k.existsSync(o)&&(k.rmSync(o,{recursive:!0,force:!0}),console.log(`${G.dim} Removed local preview files: out/previews/${G.reset}`))}async function wo(){let e=process.env.INIT_CWD||process.cwd(),o=N.join(e,"public"),t=N.join(e,"survey-ui-config.json"),n=N.join(e,"implementation_plan.md"),i=N.join(__dirname,"..","..","templates"),s=N.join(i,"wizard-dist"),r=process.env.CFM_PREVIEW_URL??"http://localhost:3000",a={},l=N.join(e,"out","previews"),y=N.join(l,"manifest.json");k.existsSync(y)||(console.log(`${G.dim} Exporting component previews for local wizard\u2026${G.reset}`),await ce({projectRoot:e,surveyTypes:[...me]})),k.existsSync(y)&&(a=JSON.parse(k.readFileSync(y,"utf8")));let m=await yo(4200),C=`http://localhost:${m}`;return new Promise((S,R)=>{let E=he.createServer(async(d,f)=>{try{let T=d.url??"/";if(d.method==="GET"&&T==="/api/inventory"){let $;if(k.existsSync(n)){let w=k.readFileSync(n,"utf8");$=st(w).instanceId}if(k.existsSync(t))try{let w=JSON.parse(k.readFileSync(t,"utf8"));w.instanceId&&($=w.instanceId)}catch{}let h=[...me],{config:v}=se({projectRoot:e,surveyTypes:h,instanceId:$});f.writeHead(200,{"Content-Type":"application/json"}),f.end(JSON.stringify({surveyTypes:h,instanceId:$,previewUrl:r,initialConfig:v,previewManifest:Object.fromEntries(Object.keys(a).map(w=>[w,`${C}/previews/${w}/index.html`]))}));return}if(d.method==="GET"&&T==="/api/preview-url"){let $=await ho(r);f.writeHead(200,{"Content-Type":"application/json"}),f.end(JSON.stringify({url:r,connected:$}));return}if(d.method==="POST"&&T.split("?")[0]==="/api/wizard-quit"){Le(e),f.writeHead(200,{"Content-Type":"application/json"}),f.end(JSON.stringify({ok:!0,deleted:"out/previews"})),setTimeout(()=>{E.close(()=>S({saved:!1}))},300);return}if(d.method==="POST"&&T==="/api/upload-logo"){let $=await go(d),h=JSON.parse($);k.existsSync(o)||k.mkdirSync(o,{recursive:!0});let v=h.base64.replace(/^data:image\/\w+;base64,/,""),w=Buffer.from(v,"base64"),j=N.extname(h.filename),L=N.basename(h.filename,j).toLowerCase().replace(/[^a-z0-9_-]/g,""),oe=`logo_${Date.now()}_${L}${j||".png"}`;k.writeFileSync(N.join(o,oe),w),f.writeHead(200,{"Content-Type":"application/json"}),f.end(JSON.stringify({fileName:oe}));return}if(d.method==="POST"&&T==="/api/save-config"){let $=await go(d),h=JSON.parse($);h.configuredAt=new Date().toISOString();let v=h.global?.logo;v?.url?.startsWith("data:")&&(v.url=null),k.writeFileSync(t,JSON.stringify(h,null,2),"utf8"),console.log(`
|
|
128
|
+
${G.green}\u2705 UI configuration saved to ${t}${G.reset}`),Le(e),console.log(`${G.dim} Local preview garbage collection complete (out/previews removed)${G.reset}`),f.writeHead(200,{"Content-Type":"application/json"}),f.end(JSON.stringify({ok:!0})),setTimeout(()=>{E.close(()=>S({saved:!0}))},500);return}if(d.method==="GET"){let $=T.split("?")[0];if($==="/"&&($="/index.html"),$.startsWith("/previews/")&&k.existsSync(l)){let w=$.replace(/^\/previews\//,""),j=N.join(l,w),L=N.normalize(j);if(L.startsWith(l)&&k.existsSync(L)&&k.statSync(L).isFile()){let oe=k.readFileSync(L);f.writeHead(200,{"Content-Type":mo(L)}),f.end(oe);return}}let h=k.existsSync(s),v=h?N.join(s,$):N.join(i,"wizard.html");if(h&&k.existsSync(v)&&k.statSync(v).isFile()){let w=k.readFileSync(v);f.writeHead(200,{"Content-Type":mo(v)}),f.end(w);return}if(!h&&$==="/index.html"){let w=k.readFileSync(N.join(i,"wizard.html"),"utf8");f.writeHead(200,{"Content-Type":"text/html"}),f.end(w);return}}f.writeHead(404,{"Content-Type":"text/plain"}),f.end("Not found")}catch(T){f.writeHead(500,{"Content-Type":"text/plain"}),f.end(`Server error: ${D(T)}`)}});E.listen(m,async()=>{let d=C;if(!await ho(`${d}/`)){E.close(()=>R(new Error(`Wizard server failed health check on ${d}`)));return}console.log(`WIZARD_LINK=${d}`),process.env.CFM_WIZARD_OPEN_BROWSER==="1"&&rt(d)}),E.on("error",R);let x=()=>{Le(e),E.close(()=>process.exit(130))};process.once("SIGINT",x),process.once("SIGTERM",x)})}M();import*as W from"fs";import*as Be from"path";import*as Po from"http";import*as ko from"https";be();ge();ve();Re();var g=c;function lt(e){let{exec:o}=we("child_process"),t=process.platform==="darwin"?`open "${e}"`:process.platform==="win32"?`start "" "${e}"`:`xdg-open "${e}"`;o(t)}function ft(e){return new Promise(o=>setTimeout(o,e))}async function ze(e,o={}){return new Promise((t,n)=>{let i=new URL(e),r=(i.protocol==="https:"?ko:Po).request(i,{method:o.method??"GET",headers:o.headers??{}},a=>{let l="";a.on("data",y=>l+=y),a.on("end",()=>{if((a.statusCode??500)>=400){n(new Error(`HTTP ${a.statusCode}: ${l}`));return}try{t(JSON.parse(l))}catch{n(new Error(`Invalid JSON: ${l.slice(0,200)}`))}})});r.on("error",n),o.body&&r.write(o.body),r.end()})}async function dt(e,o,t,n){return new Promise((i,s)=>{let r=new URL(e),a=r.protocol==="https:"?ko:Po,l={"Content-Type":t,"Content-Length":o.length};n&&(l["X-Wizard-Session"]=n.sessionSecret,l["X-Wizard-Session-Id"]=n.sessionId);let y=a.request(r,{method:"PUT",headers:l},m=>{if((m.statusCode??500)>=400){let C="";m.on("data",S=>C+=S),m.on("end",()=>s(new Error(`PUT failed ${m.statusCode}: ${C}`)));return}m.resume(),i()});y.on("error",s),y.write(o),y.end()})}function ut(e){let o=Be.join(e,"out","previews");W.existsSync(o)&&(W.rmSync(o,{recursive:!0,force:!0}),console.log(`${g.dim} Removed local preview files: out/previews/${g.reset}`))}function pt(e){try{let o=e.split(".")[1];return JSON.parse(Buffer.from(o,"base64url").toString("utf8")).surveyId??null}catch{return null}}async function vo(e={}){let o=e.wait!==!1,t=e.pollIntervalMs??Number(process.env.CFM_WIZARD_POLL_MS??3e3),n=e.timeoutMs??Number(process.env.CFM_WIZARD_TIMEOUT_MS??72e5),i=process.env.CFM_INSTANCE_ID,s=(process.env.CFM_DEPLOY_API_BASE??"http://localhost:3000").replace(/\/$/,"");if(!i)throw new Error("CFM_INSTANCE_ID (JWT) is required");let r=pt(i);if(!r)throw new Error("Could not parse surveyId from CFM_INSTANCE_ID JWT");let a=Te(),l=Y(a),y=l.activeConfigPath,m=e.apply?!1:e.review!==!1;console.log(`
|
|
131
129
|
${g.bold}${g.cyan}\u{1F3A8} CFM UI Customization (AWS)${g.reset}
|
|
132
130
|
`),m&&(console.log(`${g.dim} Review mode: seed kept in survey-ui-config.json; final + diff written on complete.${g.reset}`),console.log(`${g.dim} Apply later with: npx cfm-sdk confirm-ui-config${g.reset}
|
|
133
|
-
`));let C=[...Q],{outputDir:S,files:
|
|
134
|
-
${g.
|
|
135
|
-
`)
|
|
136
|
-
${
|
|
137
|
-
${
|
|
138
|
-
`)
|
|
139
|
-
${
|
|
140
|
-
${
|
|
141
|
-
${
|
|
142
|
-
${
|
|
143
|
-
${
|
|
144
|
-
${
|
|
145
|
-
${
|
|
146
|
-
|
|
147
|
-
Usage:`),console.log(" npx cfm-sdk customize \u2013 Local UI customization wizard"),console.log(" npx cfm-sdk customize-ui \u2013 AWS wizard (review mode: seed + diff, no auto-apply)"),console.log(" npx cfm-sdk customize-ui --apply \u2013 AWS wizard (legacy: write final config immediately)"),console.log(" npx cfm-sdk confirm-ui-config \u2013 Apply survey-ui-config.final.json after review"),console.log(" npx cfm-sdk fetch-ui-config \u2013 Pull final + diff after client completes (--no-wait)"),console.log(" npx cfm-sdk export-previews \u2013 Build component preview pages only"),console.log(" npx cfm-sdk resolve-ui-config --write \u2013 Write draft survey-ui-config.json from project"),console.log(" npx cfm-sdk deploy \u2013 Deploy to Vercel"),process.exit(0)}bt();
|
|
131
|
+
`));let C=[...Q],{outputDir:S,files:R}=await ce({projectRoot:a,useTemplatesOnly:e.useTemplatesOnly,surveyTypes:C}),E=R.map(h=>({path:h.path,contentType:h.contentType,sizeBytes:h.sizeBytes})),{config:x,source:d}=se({projectRoot:a,surveyTypes:C,instanceId:r});x.surveyTypes=C,Ne(d),m&&(W.writeFileSync(l.seedPath,JSON.stringify(x,null,2),"utf8"),W.writeFileSync(y,JSON.stringify(x,null,2),"utf8"),console.log(`${g.dim} Seed snapshot \u2192 survey-ui-config.json (+ .seed.json)${g.reset}`));let f=await ze(`${s}/wizard/session/start`,{method:"POST",headers:{Authorization:`Bearer ${i}`,"Content-Type":"application/json"},body:JSON.stringify({files:E,surveyTypes:C,initialConfig:x})});console.log(`${g.dim} Uploading ${E.length} preview files\u2026${g.reset}`);for(let h of f.uploads){let v=Be.join(S,h.path),w=W.readFileSync(v),j=E.find(L=>L.path===h.path)?.contentType??"application/octet-stream";await dt(h.uploadUrl,w,j,{sessionId:f.sessionId,sessionSecret:f.sessionSecret})}if(await ze(`${s}/wizard/previews/upload/complete`,{method:"POST",headers:{Authorization:`Bearer ${i}`,"Content-Type":"application/json"},body:JSON.stringify({sessionId:f.sessionId})}),console.log(`${g.green}\u2705 Previews uploaded${g.reset}`),console.log(`${g.dim} ${E.length} component preview page(s) \u2192 EC2 local server (disk)${g.reset}`),console.log(`WIZARD_LINK=${f.wizardUrl}`),process.env.CFM_WIZARD_OPEN_BROWSER==="1"&<(f.wizardUrl),!o)return m&&console.log(`${g.dim} When wizard completes, poll manually or re-run without --no-wait to capture final + diff.${g.reset}`),{saved:!1};let T=Date.now()+n,$=0;for(;Date.now()<T;){$+=1,process.stdout.write(`\r${g.dim}Waiting for client to finish wizard\u2026 (poll ${$})${g.reset}`);let h=await ze(`${s}/wizard/config/${encodeURIComponent(r)}?sessionId=${f.sessionId}`,{headers:{Authorization:`Bearer ${i}`}});if(h.status==="abandoned")return ut(a),{saved:!1};if(h.status==="ready"&&h.config){let v=Ee(h)??h.config;if(console.log(`
|
|
132
|
+
${g.green}\u2705 Configuration ready${g.reset}`),h.logoUrl&&console.log(`${g.dim} Logo URL: ${h.logoUrl}${g.reset}`),m){let j=ke(a,x,v);console.log(`${g.green} Seed (unchanged active): ${y}${g.reset}`),console.log(`${g.green} Final: ${l.finalPath}${g.reset}`),console.log(`${g.green} Diff: ${l.diffMdPath}${g.reset}`),console.log(`${g.yellow} ${j.changed.length} changed, ${j.added.length} added, ${j.removed.length} removed${g.reset}`);let L=v.global?.logo;if(L?.fileName)try{await ee({projectRoot:a,fileName:L.fileName,logoUrl:h.logoUrl,jwt:i,apiBase:s,surveyId:r}),console.log(`${g.green} Logo saved to public/${L.fileName}${g.reset}`)}catch(oe){console.warn(`${g.yellow} Logo download deferred: ${D(oe)}${g.reset}`)}return console.log(`${g.dim} Apply when ready: npx cfm-sdk confirm-ui-config${g.reset}`),{saved:!0}}W.writeFileSync(y,JSON.stringify(v,null,2),"utf8"),console.log(`${g.green} Written ${y}${g.reset}`);let w=v.global?.logo;return w?.fileName&&(await ee({projectRoot:a,fileName:w.fileName,logoUrl:h.logoUrl,jwt:i,apiBase:s,surveyId:r}),console.log(`${g.green} Logo saved to public/${w.fileName}${g.reset}`)),{saved:!0}}await ft(t)}throw new Error("Timed out waiting for wizard completion")}ge();M();var P=c,q=process.argv.slice(2),X=q[0];async function Ct(){if(X==="customize"||X==="init"){X==="init"&&console.log(`${P.yellow}\u26A0 cfm-sdk init is deprecated. Use \`cfm-sdk customize\` instead.${P.reset}
|
|
133
|
+
`);try{(await wo()).saved||(console.log(`
|
|
134
|
+
${P.yellow}\u26A0 Client quit without saving. Preview garbage collection complete (out/previews removed).${P.reset}`),console.log(`${P.dim} Do not re-run the wizard. Skip Phase 6c. Ask client for deploy confirmation (Phase 7 / INPUT 4).${P.reset}`),process.exit(0))}catch(e){console.error(`
|
|
135
|
+
${P.red}\u274C Error: ${D(e)}${P.reset}`),process.exit(1)}}else if(X==="customize-ui"){let e=q.includes("--use-templates-only"),o=q.includes("--no-wait"),t=q.includes("--apply"),n=q.includes("--no-review")?!1:!t;try{(await vo({useTemplatesOnly:e,wait:!o,review:n,apply:t})).saved||(console.log(`
|
|
136
|
+
${P.yellow}\u26A0 Client quit without saving. Session and preview garbage collection complete.${P.reset}`),console.log(`${P.dim} Do not re-run the wizard. Skip Phase 6c. Ask client for deploy confirmation (Phase 7 / INPUT 4).${P.reset}`),process.exit(0))}catch(i){console.error(`
|
|
137
|
+
${P.red}\u274C Error: ${D(i)}${P.reset}`),process.exit(1)}}else if(X==="confirm-ui-config"){let e=q.includes("--diff-only");try{let{runConfirmUiConfig:o}=await Promise.resolve().then(()=>(Ro(),Eo));await o({diffOnly:e})}catch(o){console.error(`
|
|
138
|
+
${P.red}\u274C Error: ${D(o)}${P.reset}`),process.exit(1)}}else if(X==="fetch-ui-config"){let o=q.find(t=>t.startsWith("--session="))?.split("=")[1];try{let{runFetchUiConfig:t}=await Promise.resolve().then(()=>(Fo(),Io));await t({sessionId:o})}catch(t){console.error(`
|
|
139
|
+
${P.red}\u274C Error: ${D(t)}${P.reset}`),process.exit(1)}}else if(X==="export-previews"){let e=q.includes("--use-templates-only");try{await ce({useTemplatesOnly:e})}catch(o){console.error(`
|
|
140
|
+
${P.red}\u274C Error: ${D(o)}${P.reset}`),process.exit(1)}}else if(X==="resolve-ui-config"){let e=q.includes("--write");try{if(e){let o=je();console.log(`${P.green}\u2705 Wrote ${o}${P.reset}`)}else{let{resolveInitialConfig:o}=await Promise.resolve().then(()=>(ge(),uo)),{config:t,source:n}=o({surveyTypes:[]});console.log(JSON.stringify({source:n,config:t},null,2))}}catch(o){console.error(`
|
|
141
|
+
${P.red}\u274C Error: ${D(o)}${P.reset}`),process.exit(1)}}else if(X==="deploy")try{await qe()}catch(e){console.error(`
|
|
142
|
+
${P.red}\u274C Error: ${D(e)}${P.reset}`),process.exit(1)}else console.log(`
|
|
143
|
+
${P.bold}${P.cyan}CFM SDK CLI Tool${P.reset}`),console.log(`
|
|
144
|
+
Usage:`),console.log(" npx cfm-sdk customize \u2013 Local UI customization wizard"),console.log(" npx cfm-sdk customize-ui \u2013 AWS wizard (review mode: seed + diff, no auto-apply)"),console.log(" npx cfm-sdk customize-ui --apply \u2013 AWS wizard (legacy: write final config immediately)"),console.log(" npx cfm-sdk confirm-ui-config \u2013 Apply survey-ui-config.final.json after review"),console.log(" npx cfm-sdk fetch-ui-config \u2013 Pull final + diff after client completes (--no-wait)"),console.log(" npx cfm-sdk export-previews \u2013 Build component preview pages only"),console.log(" npx cfm-sdk resolve-ui-config --write \u2013 Write draft survey-ui-config.json from project"),console.log(" npx cfm-sdk deploy \u2013 Deploy to Vercel"),process.exit(0)}Ct();
|
package/package.json
CHANGED
|
@@ -115,7 +115,6 @@ Machine-readable routing: [`MANIFEST.json`](../MANIFEST.json) `phases[]`.
|
|
|
115
115
|
|
|
116
116
|
**Read:**
|
|
117
117
|
- `00-integration/wizard-chrome-contract.md` **(required — copy-first templates)**
|
|
118
|
-
- `00-integration/wizard-customization-catalog.md` **(required — all wizard controls × formats)**
|
|
119
118
|
- `00-integration/constraints.md`
|
|
120
119
|
- `00-integration/component-checklist.md`
|
|
121
120
|
- `00-integration/wizard-preview-build-guide.md` **(required)**
|
|
@@ -189,7 +188,7 @@ Machine-readable routing: [`MANIFEST.json`](../MANIFEST.json) `phases[]`.
|
|
|
189
188
|
|
|
190
189
|
### Phase 6b — Wizard session (optional, INPUT 3 = Yes)
|
|
191
190
|
|
|
192
|
-
**Default:** `npx cfm-sdk customize` —
|
|
191
|
+
**Default:** `npx cfm-sdk customize` — probes free port from 4200; CLI prints **`WIZARD_LINK`**. Share only that URL.
|
|
193
192
|
|
|
194
193
|
**EC2 fallback:** `customize-ui` — only when client customizes from **another device**.
|
|
195
194
|
|
|
@@ -204,12 +203,12 @@ npx cfm-sdk customize
|
|
|
204
203
|
|
|
205
204
|
**Sequence:**
|
|
206
205
|
1. CLI auto-exports all 11 component previews to `out/previews/`
|
|
207
|
-
2.
|
|
206
|
+
2. Starts wizard; prints `WIZARD_LINK=http://localhost:{port}` — agent shares **only** this URL
|
|
208
207
|
3. Client customizes (same machine as agent); live iframes from local previews
|
|
209
|
-
4. Client clicks **Review & Build** → `survey-ui-config.json` written
|
|
210
|
-
5. CLI exits 0 →
|
|
208
|
+
4. **Save path:** Client clicks **Review & Build** → `survey-ui-config.json` written → CLI exits 0 → Phase 6c
|
|
209
|
+
5. **Quit path:** Client quits → GC `out/previews/` → CLI exits 0 → skip Phase 6c → ask Phase 7 deploy
|
|
211
210
|
|
|
212
|
-
**Tell the client:** *"
|
|
211
|
+
**Tell the client:** *"Open the wizard link I shared and click **Review & Build** when done."*
|
|
213
212
|
|
|
214
213
|
**Remote client only:**
|
|
215
214
|
```bash
|
|
@@ -217,7 +216,7 @@ export CFM_INSTANCE_ID="<JWT>"
|
|
|
217
216
|
export CFM_DEPLOY_API_BASE="http://43.204.26.213:3000"
|
|
218
217
|
npx cfm-sdk customize-ui
|
|
219
218
|
```
|
|
220
|
-
Share
|
|
219
|
+
Share `WIZARD_LINK` from CLI; keep CLI open until exit 0. See `wizard-config-handoff.md`.
|
|
221
220
|
|
|
222
221
|
**If client said No:** skip to Phase 7 ask.
|
|
223
222
|
|
|
@@ -296,8 +295,7 @@ Full mapping: [`wizard-question-type-styling.md`](wizard-question-type-styling.m
|
|
|
296
295
|
| Hook / answers | `client-integration-guide.md`, `useSurveySDK.md` |
|
|
297
296
|
| Copy files list | `component-checklist.md`, `client-lib-folder.md` |
|
|
298
297
|
| Matrix labels | `canonical-survey-fixtures.md` |
|
|
299
|
-
| Wizard chrome | `wizard-preview-build-guide.md
|
|
300
|
-
| Wizard controls (all formats) | `wizard-customization-catalog.md` |
|
|
298
|
+
| Wizard chrome | `wizard-preview-build-guide.md` |
|
|
301
299
|
| Wizard per-type | `wizard-question-type-styling.md` |
|
|
302
300
|
| Wait + capture + apply order | `wizard-config-handoff.md` |
|
|
303
301
|
| Apply every config path | `apply-ui-config.md` |
|
|
@@ -130,7 +130,8 @@ Use this table when deciding what to read. **Do not substitute similar-sounding
|
|
|
130
130
|
| Placeholder unstable inline object | Stable ref + `useMemo` on hook options |
|
|
131
131
|
| Slider matrix without tick header | `canonical-survey-fixtures.md` + ui-spec |
|
|
132
132
|
| RATING_MATRIX as new component | Reuse `CsatMatrixScale.tsx` |
|
|
133
|
-
| Killed CLI during wizard poll | Keep running until
|
|
133
|
+
| Killed CLI during wizard poll | Keep running until exit 0; see `wizard-config-handoff.md` |
|
|
134
|
+
| Client quit wizard without save | GC complete — **do not** re-run wizard; skip 6c; ask deploy (INPUT 4) |
|
|
134
135
|
| Applied before client submitted | Wait for CLI exit 0; use `.final.json` not seed |
|
|
135
136
|
| Skipped diff paths | Read entire `survey-ui-config.diff.md`; apply every path |
|
|
136
137
|
|
|
@@ -114,6 +114,7 @@ Read: [`wizard-chrome-contract.md`](wizard-chrome-contract.md), [`agent-executio
|
|
|
114
114
|
|
|
115
115
|
- [ ] `src/styles/survey-theme.css` with full `--cfm-*` set (copy from `templates/survey-theme.css`)
|
|
116
116
|
- [ ] `selectionStyles.ts` + `labelStyles.ts` in `src/lib/surveyUi/`
|
|
117
|
+
- [ ] Every scale component (`LikertMatrixScale`, `CsatMatrixScale`, `SliderMatrixScale`, `RatingScale`, `FileUploadScale`, `HeatmapScale`, `RankOrderScale`) imports helpers and uses `var(--cfm-*)` — copy from [`docs/templates/`](../templates/)
|
|
117
118
|
- [ ] Draft `./survey-ui-config.json` synced with mockup branding
|
|
118
119
|
- [ ] `previewBridge.ts` + `PreviewBridgeInit` in root layout
|
|
119
120
|
- [ ] Header/Footer/ProgressBar/SurveyPage use `var(--cfm-*)` — no hardcoded brand hex for wizard-controlled tokens
|
|
@@ -12,7 +12,8 @@ npx cfm-sdk customize
|
|
|
12
12
|
|
|
13
13
|
This is the **recommended default** because it:
|
|
14
14
|
|
|
15
|
-
-
|
|
15
|
+
- Probes the first free port from **4200** upward and starts the wizard there
|
|
16
|
+
- Prints a machine-parseable line: **`WIZARD_LINK=http://localhost:{port}`** — agent shares **only** this URL with the client (never hardcode `:4200`)
|
|
16
17
|
- Auto-exports all **11** question-type previews from agent components
|
|
17
18
|
- Writes `survey-ui-config.json` **directly** on save — no S3, no session polling
|
|
18
19
|
- Cleans up local `out/previews/` when client quits without saving (`POST /api/wizard-quit`) or when CLI exits (Ctrl+C)
|
|
@@ -20,9 +21,15 @@ This is the **recommended default** because it:
|
|
|
20
21
|
|
|
21
22
|
**Agent script after client says yes:**
|
|
22
23
|
|
|
23
|
-
> *"I'll
|
|
24
|
+
> *"I'll start the customization wizard. Use the link I share — complete all steps and click **Review & Build** when done."*
|
|
24
25
|
|
|
25
|
-
|
|
26
|
+
**Strict link handoff:**
|
|
27
|
+
|
|
28
|
+
1. Run `npx cfm-sdk customize` and wait for `WIZARD_LINK=http://localhost:…` in CLI output
|
|
29
|
+
2. Share **only** that URL with the client — do not guess port 4200
|
|
30
|
+
3. Keep the terminal open until CLI exits
|
|
31
|
+
|
|
32
|
+
**On successful save:**
|
|
26
33
|
|
|
27
34
|
```
|
|
28
35
|
✅ UI configuration saved to survey-ui-config.json
|
|
@@ -30,6 +37,8 @@ The CLI **blocks** until the client saves. Wait for:
|
|
|
30
37
|
|
|
31
38
|
Then apply per [`apply-ui-config.md`](apply-ui-config.md).
|
|
32
39
|
|
|
40
|
+
**If client quits without saving:** CLI exits 0 after GC (`out/previews/` removed). **Do not** re-run the wizard. Skip Phase 6c. Ask deploy confirmation (Phase 7 / INPUT 4) with the existing Phase 6 build.
|
|
41
|
+
|
|
33
42
|
### Who can use it
|
|
34
43
|
|
|
35
44
|
| User | Can use `customize`? |
|
|
@@ -37,7 +46,7 @@ Then apply per [`apply-ui-config.md`](apply-ui-config.md).
|
|
|
37
46
|
| Client on **same machine** as agent (Cursor chat on dev laptop) | **Yes — default** |
|
|
38
47
|
| Client on **another device** | **No** — use EC2 fallback below |
|
|
39
48
|
|
|
40
|
-
|
|
49
|
+
The wizard URL is **`WIZARD_LINK` from CLI output** — only reachable on the machine running the CLI (port may be 4201+ if 4200 is busy).
|
|
41
50
|
|
|
42
51
|
---
|
|
43
52
|
|
|
@@ -51,7 +60,7 @@ npx cfm-sdk customize-ui
|
|
|
51
60
|
```
|
|
52
61
|
|
|
53
62
|
- Uploads previews to EC2 disk (local-server model on remote host)
|
|
54
|
-
- Prints
|
|
63
|
+
- Prints **`WIZARD_LINK=…`** after previews upload — agent sends **only** that URL to client
|
|
55
64
|
- CLI **polls** until client submits → writes `.final.json` + `.diff.md`
|
|
56
65
|
- Requires deploy-api on EC2 + `CFM_INSTANCE_ID`
|
|
57
66
|
|
|
@@ -78,7 +87,7 @@ After Phase 6 verify + dev server:
|
|
|
78
87
|
```mermaid
|
|
79
88
|
sequenceDiagram
|
|
80
89
|
participant Agent as Agent CLI
|
|
81
|
-
participant Srv as localhost
|
|
90
|
+
participant Srv as localhost port from WIZARD_LINK
|
|
82
91
|
participant Wizard as Wizard SPA
|
|
83
92
|
participant Prev as out/previews/
|
|
84
93
|
|
|
@@ -111,11 +120,24 @@ sequenceDiagram
|
|
|
111
120
|
|
|
112
121
|
---
|
|
113
122
|
|
|
123
|
+
## Port probe + link-only handoff (mandatory)
|
|
124
|
+
|
|
125
|
+
| Step | Agent action |
|
|
126
|
+
|------|----------------|
|
|
127
|
+
| 1 | Run `npx cfm-sdk customize` (or `customize-ui` for remote) |
|
|
128
|
+
| 2 | Read `WIZARD_LINK=…` from CLI stdout — **never** assume `localhost:4200` |
|
|
129
|
+
| 3 | Share **only** that URL with the client |
|
|
130
|
+
| 4 | Wait until CLI exits (save → exit 0, quit → exit 0 with GC message) |
|
|
131
|
+
|
|
132
|
+
Optional: set `CFM_WIZARD_OPEN_BROWSER=1` to auto-open the wizard in the agent's browser.
|
|
133
|
+
|
|
134
|
+
---
|
|
135
|
+
|
|
114
136
|
## Agent checklist
|
|
115
137
|
|
|
116
138
|
- [ ] Phase 5: wizard-preview artifacts wired
|
|
117
139
|
- [ ] Client opted in (INPUT 3)
|
|
118
|
-
- [ ]
|
|
140
|
+
- [ ] Parsed `WIZARD_LINK` from CLI and shared only that URL with client
|
|
119
141
|
- [ ] Read `survey-ui-config.json` (or `.diff.md` if used EC2 fallback)
|
|
120
142
|
- [ ] Phase 6c: applied per [`apply-ui-config.md`](apply-ui-config.md)
|
|
121
143
|
- [ ] Re-ran verify + build
|