@pega/sdk 0.0.5 → 0.0.7
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/README.md +10 -3
- package/dist/index.js +828 -165
- package/package.json +1 -1
- package/templates/react-native-sdk-reference/.claude/settings.json +5 -0
- package/templates/react-native-sdk-reference/.prettierignore +17 -0
- package/templates/react-native-sdk-reference/.vscode/extensions.json +1 -0
- package/templates/react-native-sdk-reference/.vscode/settings.json +7 -0
- package/templates/react-native-sdk-reference/AGENTS.md +3 -0
- package/templates/react-native-sdk-reference/CLAUDE.md +1 -0
- package/templates/react-native-sdk-reference/README.md +56 -0
- package/templates/react-native-sdk-reference/app.json +40 -5
- package/templates/react-native-sdk-reference/assets/expo.icon/Assets/expo-symbol 2.svg +3 -0
- package/templates/react-native-sdk-reference/assets/expo.icon/Assets/grid.png +0 -0
- package/templates/react-native-sdk-reference/assets/expo.icon/icon.json +35 -0
- package/templates/react-native-sdk-reference/assets/icons/bell.png +0 -0
- package/templates/react-native-sdk-reference/assets/icons/clock.png +0 -0
- package/templates/react-native-sdk-reference/assets/icons/cross.png +0 -0
- package/templates/react-native-sdk-reference/assets/icons/donut.png +0 -0
- package/templates/react-native-sdk-reference/assets/icons/gear.png +0 -0
- package/templates/react-native-sdk-reference/assets/icons/globe.png +0 -0
- package/templates/react-native-sdk-reference/assets/icons/internet.png +0 -0
- package/templates/react-native-sdk-reference/assets/icons/music.png +0 -0
- package/templates/react-native-sdk-reference/assets/icons/right-arrow.png +0 -0
- package/templates/react-native-sdk-reference/assets/icons/speed.png +0 -0
- package/templates/react-native-sdk-reference/assets/images/MediaCo.png +0 -0
- package/templates/react-native-sdk-reference/assets/images/adaptive-icon.png +0 -0
- package/templates/react-native-sdk-reference/assets/images/android-icon-background.png +0 -0
- package/templates/react-native-sdk-reference/assets/images/android-icon-foreground.png +0 -0
- package/templates/react-native-sdk-reference/assets/images/android-icon-monochrome.png +0 -0
- package/templates/react-native-sdk-reference/assets/images/expo-badge-white.png +0 -0
- package/templates/react-native-sdk-reference/assets/images/expo-badge.png +0 -0
- package/templates/react-native-sdk-reference/assets/images/expo-logo.png +0 -0
- package/templates/react-native-sdk-reference/assets/images/favicon.png +0 -0
- package/templates/react-native-sdk-reference/assets/images/icon.png +0 -0
- package/templates/react-native-sdk-reference/assets/images/logo-glow.png +0 -0
- package/templates/react-native-sdk-reference/assets/images/partial-react-logo.png +0 -0
- package/templates/react-native-sdk-reference/assets/images/react-logo.png +0 -0
- package/templates/react-native-sdk-reference/assets/images/react-logo@2x.png +0 -0
- package/templates/react-native-sdk-reference/assets/images/react-logo@3x.png +0 -0
- package/templates/react-native-sdk-reference/assets/images/splash-icon.png +0 -0
- package/templates/react-native-sdk-reference/assets/images/tutorial-web.png +0 -0
- package/templates/react-native-sdk-reference/eslint.config.mjs +68 -0
- package/templates/react-native-sdk-reference/package.json +59 -14
- package/templates/react-native-sdk-reference/pega-constellationjs-0.26.3.tgz +0 -0
- package/templates/react-native-sdk-reference/pega-sdk-react-0.1.0.tgz +0 -0
- package/templates/react-native-sdk-reference/pega-sdk-types-0.1.0.tgz +0 -0
- package/templates/react-native-sdk-reference/sdk-config.json +31 -9
- package/templates/react-native-sdk-reference/src/app/_layout.tsx +38 -0
- package/templates/react-native-sdk-reference/src/app/home/_layout.tsx +39 -0
- package/templates/react-native-sdk-reference/src/app/home/contact.tsx +11 -0
- package/templates/react-native-sdk-reference/src/app/home/index.tsx +36 -0
- package/templates/react-native-sdk-reference/src/app/home/shop.tsx +11 -0
- package/templates/react-native-sdk-reference/src/app/home/your-services.tsx +11 -0
- package/templates/react-native-sdk-reference/src/app/index.tsx +72 -0
- package/templates/react-native-sdk-reference/src/app/workarea.tsx +135 -0
- package/templates/react-native-sdk-reference/src/bridge/Context/StoreContext.ts +4 -0
- package/templates/react-native-sdk-reference/src/bridge/RootComponent.tsx +12 -0
- package/templates/react-native-sdk-reference/src/bridge/react_pconnect.jsx +334 -0
- package/templates/react-native-sdk-reference/src/components/common/DisplayField.tsx +29 -0
- package/templates/react-native-sdk-reference/src/components/common/FormFieldWrapper.tsx +5 -0
- package/templates/react-native-sdk-reference/src/components/common/HelperText.tsx +11 -0
- package/templates/react-native-sdk-reference/src/components/common/LabelText.tsx +22 -0
- package/templates/react-native-sdk-reference/src/components/common/inputTheme.ts +17 -0
- package/templates/react-native-sdk-reference/src/components/design-system/AutoComplete.tsx +126 -0
- package/templates/react-native-sdk-reference/src/components/design-system/FieldGroup.tsx +72 -0
- package/templates/react-native-sdk-reference/src/components/design-system/Radio.tsx +61 -0
- package/templates/react-native-sdk-reference/src/components/field/AutoComplete/AutoComplete.tsx +196 -0
- package/templates/react-native-sdk-reference/src/components/field/AutoComplete/index.tsx +1 -0
- package/templates/react-native-sdk-reference/src/components/field/Checkbox/Checkbox.tsx +89 -0
- package/templates/react-native-sdk-reference/src/components/field/Checkbox/index.tsx +1 -0
- package/templates/react-native-sdk-reference/src/components/field/Currency/Currency.tsx +84 -0
- package/templates/react-native-sdk-reference/src/components/field/Currency/index.tsx +1 -0
- package/templates/react-native-sdk-reference/src/components/field/Date/Date.tsx +94 -0
- package/templates/react-native-sdk-reference/src/components/field/Date/index.tsx +1 -0
- package/templates/react-native-sdk-reference/src/components/field/Dropdown/Dropdown.tsx +211 -0
- package/templates/react-native-sdk-reference/src/components/field/Dropdown/index.tsx +1 -0
- package/templates/react-native-sdk-reference/src/components/field/Email/Email.tsx +81 -0
- package/templates/react-native-sdk-reference/src/components/field/Email/index.tsx +1 -0
- package/templates/react-native-sdk-reference/src/components/field/Group/Group.tsx +47 -0
- package/templates/react-native-sdk-reference/src/components/field/Group/index.tsx +1 -0
- package/templates/react-native-sdk-reference/src/components/field/Integer/Integer.tsx +84 -0
- package/templates/react-native-sdk-reference/src/components/field/Integer/index.tsx +1 -0
- package/templates/react-native-sdk-reference/src/components/field/Phone/Phone.tsx +85 -0
- package/templates/react-native-sdk-reference/src/components/field/Phone/index.ts +1 -0
- package/templates/react-native-sdk-reference/src/components/field/RadioButtons/RadioButtons.tsx +118 -0
- package/templates/react-native-sdk-reference/src/components/field/RadioButtons/index.ts +1 -0
- package/templates/react-native-sdk-reference/src/components/field/TextArea/TextArea.tsx +86 -0
- package/templates/react-native-sdk-reference/src/components/field/TextArea/index.tsx +1 -0
- package/templates/react-native-sdk-reference/src/components/field/TextInput/TextInput.tsx +84 -0
- package/templates/react-native-sdk-reference/src/components/field/TextInput/index.tsx +1 -0
- package/templates/react-native-sdk-reference/src/components/field/URL/URL.tsx +86 -0
- package/templates/react-native-sdk-reference/src/components/field/URL/index.tsx +1 -0
- package/templates/react-native-sdk-reference/src/components/helpers/data_page.ts +20 -0
- package/templates/react-native-sdk-reference/src/components/helpers/event-utils.ts +20 -0
- package/templates/react-native-sdk-reference/src/components/helpers/instructions-utils.ts +57 -0
- package/templates/react-native-sdk-reference/src/components/helpers/state-utils.tsx +46 -0
- package/templates/react-native-sdk-reference/src/components/helpers/template-utils.ts +75 -0
- package/templates/react-native-sdk-reference/src/components/helpers/utils.ts +339 -0
- package/templates/react-native-sdk-reference/src/components/infra/ActionButtons/ActionButtons.tsx +63 -0
- package/templates/react-native-sdk-reference/src/components/infra/ActionButtons/index.tsx +1 -0
- package/templates/react-native-sdk-reference/src/components/infra/Assignment/Assignment.tsx +348 -0
- package/templates/react-native-sdk-reference/src/components/infra/Assignment/index.tsx +1 -0
- package/templates/react-native-sdk-reference/src/components/infra/AssignmentCard/AssignmentCard.tsx +56 -0
- package/templates/react-native-sdk-reference/src/components/infra/AssignmentCard/index.tsx +1 -0
- package/templates/react-native-sdk-reference/src/components/infra/Containers/FlowContainer/FlowContainer.tsx +57 -0
- package/templates/react-native-sdk-reference/src/components/infra/Containers/FlowContainer/helpers.ts +137 -0
- package/templates/react-native-sdk-reference/src/components/infra/Containers/FlowContainer/index.tsx +1 -0
- package/templates/react-native-sdk-reference/src/components/infra/Containers/RootContainer/RootContainer.tsx +52 -0
- package/templates/react-native-sdk-reference/src/components/infra/Containers/RootContainer/index.tsx +1 -0
- package/templates/react-native-sdk-reference/src/components/infra/Containers/SimpleView/helper.ts +128 -0
- package/templates/react-native-sdk-reference/src/components/infra/Containers/SimpleView/index.tsx +59 -0
- package/templates/react-native-sdk-reference/src/components/infra/Containers/ViewContainer/ViewContainer.tsx +31 -0
- package/templates/react-native-sdk-reference/src/components/infra/Containers/ViewContainer/helper.ts +39 -0
- package/templates/react-native-sdk-reference/src/components/infra/Containers/ViewContainer/index.ts +1 -0
- package/templates/react-native-sdk-reference/src/components/infra/Containers/helper.ts +9 -0
- package/templates/react-native-sdk-reference/src/components/infra/ErrorBoundary/ErrorBoundary.tsx +53 -0
- package/templates/react-native-sdk-reference/src/components/infra/ErrorBoundary/index.tsx +1 -0
- package/templates/react-native-sdk-reference/src/components/infra/MultiStep/MultiStep.tsx +24 -0
- package/templates/react-native-sdk-reference/src/components/infra/MultiStep/index.ts +1 -0
- package/templates/react-native-sdk-reference/src/components/infra/Reference/Reference.tsx +68 -0
- package/templates/react-native-sdk-reference/src/components/infra/Reference/index.tsx +1 -0
- package/templates/react-native-sdk-reference/src/components/infra/Reference/utils.ts +16 -0
- package/templates/react-native-sdk-reference/src/components/infra/Region/Region.tsx +10 -0
- package/templates/react-native-sdk-reference/src/components/infra/Region/index.tsx +1 -0
- package/templates/react-native-sdk-reference/src/components/infra/View/View.tsx +49 -0
- package/templates/react-native-sdk-reference/src/components/template/DefaultForm/DefaultForm.tsx +38 -0
- package/templates/react-native-sdk-reference/src/components/template/DefaultForm/index.tsx +1 -0
- package/templates/react-native-sdk-reference/src/components/template/DefaultForm/utils/index.ts +28 -0
- package/templates/react-native-sdk-reference/src/components/template/Details/Details.tsx +82 -0
- package/templates/react-native-sdk-reference/src/components/template/Details/index.tsx +1 -0
- package/templates/react-native-sdk-reference/src/components/template/OneColumn/OneColumn.tsx +29 -0
- package/templates/react-native-sdk-reference/src/components/template/OneColumn/index.tsx +1 -0
- package/templates/react-native-sdk-reference/src/context/LoaderContext.tsx +42 -0
- package/templates/react-native-sdk-reference/src/mediaco/AdvBanner.tsx +62 -0
- package/templates/react-native-sdk-reference/src/mediaco/Header.tsx +60 -0
- package/templates/react-native-sdk-reference/src/mediaco/HomeScreen.tsx +78 -0
- package/templates/react-native-sdk-reference/src/mediaco/QuickActions.tsx +68 -0
- package/templates/react-native-sdk-reference/src/mediaco/ResolutionScreen.tsx +48 -0
- package/templates/react-native-sdk-reference/src/mediaco/SafeArea.tsx +11 -0
- package/templates/react-native-sdk-reference/src/mediaco/TabBar.tsx +102 -0
- package/templates/react-native-sdk-reference/src/mediaco/YourServices.tsx +90 -0
- package/templates/react-native-sdk-reference/src/sdk-pega-component-map.ts +64 -0
- package/templates/react-native-sdk-reference/src/types/PConnProps.d.ts +41 -0
- package/templates/react-native-sdk-reference/src/utils/auth.ts +62 -0
- package/templates/react-native-sdk-reference/src/utils/init-pcore.ts +37 -0
- package/templates/react-native-sdk-reference/src/utils/pcore-polyfills.ts +66 -0
- package/templates/react-native-sdk-reference/tsconfig.json +9 -8
- package/templates/react-sdk-reference/.ai-common/agents/embedded-flow-expert.md +171 -0
- package/templates/react-sdk-reference/.ai-common/agents/implementation-expert.md +25 -26
- package/templates/react-sdk-reference/.ai-common/global/ai-agent-instructions-embedded.md +119 -0
- package/templates/react-sdk-reference/.ai-common/global/ai-agent-instructions.md +70 -121
- package/templates/react-sdk-reference/.ai-common/instructions/component-map.md +7 -19
- package/templates/react-sdk-reference/.ai-common/instructions/dse-component.md +10 -40
- package/templates/react-sdk-reference/.ai-common/instructions/embedded-component.md +134 -0
- package/templates/react-sdk-reference/.ai-common/instructions/field-component.md +15 -43
- package/templates/react-sdk-reference/.ai-common/instructions/template-component.md +11 -63
- package/templates/react-sdk-reference/.ai-common/instructions/widget-component.md +12 -57
- package/templates/react-sdk-reference/.ai-common/mcp/claude-code.mcp.json +8 -0
- package/templates/react-sdk-reference/.ai-common/mcp/copilot.mcp.json +8 -0
- package/templates/react-sdk-reference/.ai-common/mcp/cursor.mcp.json +11 -0
- package/templates/react-sdk-reference/.ai-common/prompts/add-component.md +45 -71
- package/templates/react-sdk-reference/.ai-common/prompts/component-manifest.json +98 -0
- package/templates/react-sdk-reference/.ai-common/prompts/embedded-component-manifest.md +155 -0
- package/templates/react-sdk-reference/.ai-common/prompts/generate-all-components.md +67 -237
- package/templates/react-sdk-reference/.ai-common/prompts/generate-dse-components.md +26 -77
- package/templates/react-sdk-reference/.ai-common/prompts/generate-embedded-components.md +315 -0
- package/templates/react-sdk-reference/.ai-common/prompts/generate-field-components.md +31 -80
- package/templates/react-sdk-reference/.ai-common/prompts/generate-template-components.md +43 -99
- package/templates/react-sdk-reference/.ai-common/prompts/generate-widget-components.md +33 -83
- package/templates/react-sdk-reference/.ai-common/skills/design-system-extension-skills/AlertBanner.md +60 -74
- package/templates/react-sdk-reference/.ai-common/skills/design-system-extension-skills/Banner.md +64 -84
- package/templates/react-sdk-reference/.ai-common/skills/design-system-extension-skills/CaseSummaryFields.md +76 -109
- package/templates/react-sdk-reference/.ai-common/skills/design-system-extension-skills/DetailsFields.md +84 -101
- package/templates/react-sdk-reference/.ai-common/skills/design-system-extension-skills/FieldGroup.md +62 -87
- package/templates/react-sdk-reference/.ai-common/skills/design-system-extension-skills/FieldGroupList.md +56 -76
- package/templates/react-sdk-reference/.ai-common/skills/design-system-extension-skills/FieldValueList.md +61 -85
- package/templates/react-sdk-reference/.ai-common/skills/design-system-extension-skills/Operator.md +84 -107
- package/templates/react-sdk-reference/.ai-common/skills/design-system-extension-skills/Pulse.md +36 -44
- package/templates/react-sdk-reference/.ai-common/skills/design-system-extension-skills/RichTextEditor.md +125 -189
- package/templates/react-sdk-reference/.ai-common/skills/design-system-extension-skills/WssQuickCreate.md +34 -50
- package/templates/react-sdk-reference/.ai-common/skills/design-system-extension.md +57 -179
- package/templates/react-sdk-reference/.ai-common/skills/embedded-flow/analyze-customer-repo.md +130 -0
- package/templates/react-sdk-reference/.ai-common/skills/embedded-flow/authenticate.md +311 -0
- package/templates/react-sdk-reference/.ai-common/skills/embedded-flow/run-and-verify-integration.md +156 -0
- package/templates/react-sdk-reference/.ai-common/skills/embedded-flow/wire-integration.md +476 -0
- package/templates/react-sdk-reference/.ai-common/skills/field-components.md +120 -242
- package/templates/react-sdk-reference/.ai-common/skills/field-skills/AutoComplete.md +71 -212
- package/templates/react-sdk-reference/.ai-common/skills/field-skills/CancelAlert.md +47 -209
- package/templates/react-sdk-reference/.ai-common/skills/field-skills/Checkbox.md +90 -259
- package/templates/react-sdk-reference/.ai-common/skills/field-skills/Currency.md +75 -169
- package/templates/react-sdk-reference/.ai-common/skills/field-skills/Date.md +65 -160
- package/templates/react-sdk-reference/.ai-common/skills/field-skills/DateTime.md +59 -157
- package/templates/react-sdk-reference/.ai-common/skills/field-skills/Decimal.md +55 -134
- package/templates/react-sdk-reference/.ai-common/skills/field-skills/Dropdown.md +61 -185
- package/templates/react-sdk-reference/.ai-common/skills/field-skills/Email.md +60 -138
- package/templates/react-sdk-reference/.ai-common/skills/field-skills/Group.md +40 -99
- package/templates/react-sdk-reference/.ai-common/skills/field-skills/Integer.md +44 -111
- package/templates/react-sdk-reference/.ai-common/skills/field-skills/Location.md +57 -165
- package/templates/react-sdk-reference/.ai-common/skills/field-skills/Multiselect.md +41 -122
- package/templates/react-sdk-reference/.ai-common/skills/field-skills/ObjectReference.md +32 -130
- package/templates/react-sdk-reference/.ai-common/skills/field-skills/Percentage.md +48 -112
- package/templates/react-sdk-reference/.ai-common/skills/field-skills/Phone.md +43 -153
- package/templates/react-sdk-reference/.ai-common/skills/field-skills/RadioButtons.md +76 -183
- package/templates/react-sdk-reference/.ai-common/skills/field-skills/RichText.md +59 -176
- package/templates/react-sdk-reference/.ai-common/skills/field-skills/ScalarList.md +30 -123
- package/templates/react-sdk-reference/.ai-common/skills/field-skills/SelectableCard.md +47 -178
- package/templates/react-sdk-reference/.ai-common/skills/field-skills/SemanticLink.md +31 -117
- package/templates/react-sdk-reference/.ai-common/skills/field-skills/TextArea.md +51 -106
- package/templates/react-sdk-reference/.ai-common/skills/field-skills/TextContent.md +22 -75
- package/templates/react-sdk-reference/.ai-common/skills/field-skills/TextInput.md +54 -116
- package/templates/react-sdk-reference/.ai-common/skills/field-skills/Time.md +46 -100
- package/templates/react-sdk-reference/.ai-common/skills/field-skills/URL.md +44 -93
- package/templates/react-sdk-reference/.ai-common/skills/field-skills/UserReference.md +40 -167
- package/templates/react-sdk-reference/.ai-common/skills/infra-components.md +165 -0
- package/templates/react-sdk-reference/.ai-common/skills/infra-skills/ActionButtons.md +122 -0
- package/templates/react-sdk-reference/.ai-common/skills/infra-skills/MultiStep.md +178 -0
- package/templates/react-sdk-reference/.ai-common/skills/infra-skills/Stages.md +140 -0
- package/templates/react-sdk-reference/.ai-common/skills/template-components.md +74 -228
- package/templates/react-sdk-reference/.ai-common/skills/template-skills/AdvancedSearch.md +66 -167
- package/templates/react-sdk-reference/.ai-common/skills/template-skills/AppShell.md +57 -170
- package/templates/react-sdk-reference/.ai-common/skills/template-skills/BannerPage.md +41 -76
- package/templates/react-sdk-reference/.ai-common/skills/template-skills/CaseSummary.md +53 -109
- package/templates/react-sdk-reference/.ai-common/skills/template-skills/CaseView.md +86 -289
- package/templates/react-sdk-reference/.ai-common/skills/template-skills/CaseViewActionsMenu.md +60 -185
- package/templates/react-sdk-reference/.ai-common/skills/template-skills/Confirmation.md +66 -115
- package/templates/react-sdk-reference/.ai-common/skills/template-skills/DataReference.md +33 -68
- package/templates/react-sdk-reference/.ai-common/skills/template-skills/DefaultForm.md +53 -133
- package/templates/react-sdk-reference/.ai-common/skills/template-skills/DefaultPage.md +39 -82
- package/templates/react-sdk-reference/.ai-common/skills/template-skills/Details.md +38 -91
- package/templates/react-sdk-reference/.ai-common/skills/template-skills/DetailsSubTabs.md +47 -101
- package/templates/react-sdk-reference/.ai-common/skills/template-skills/DetailsThreeColumn.md +27 -34
- package/templates/react-sdk-reference/.ai-common/skills/template-skills/DetailsTwoColumn.md +25 -40
- package/templates/react-sdk-reference/.ai-common/skills/template-skills/DynamicTabs.md +34 -104
- package/templates/react-sdk-reference/.ai-common/skills/template-skills/FieldGroupTemplate.md +46 -147
- package/templates/react-sdk-reference/.ai-common/skills/template-skills/HierarchicalForm.md +139 -100
- package/templates/react-sdk-reference/.ai-common/skills/template-skills/InlineDashboard.md +43 -82
- package/templates/react-sdk-reference/.ai-common/skills/template-skills/InlineDashboardPage.md +47 -80
- package/templates/react-sdk-reference/.ai-common/skills/template-skills/ListPage.md +16 -29
- package/templates/react-sdk-reference/.ai-common/skills/template-skills/ListView.md +43 -228
- package/templates/react-sdk-reference/.ai-common/skills/template-skills/MultiReferenceReadOnly.md +20 -65
- package/templates/react-sdk-reference/.ai-common/skills/template-skills/NarrowWide.md +49 -97
- package/templates/react-sdk-reference/.ai-common/skills/template-skills/OneColumn.md +37 -71
- package/templates/react-sdk-reference/.ai-common/skills/template-skills/PromotedFilters.md +58 -148
- package/templates/react-sdk-reference/.ai-common/skills/template-skills/SelfServiceCaseView.md +82 -107
- package/templates/react-sdk-reference/.ai-common/skills/template-skills/SimpleTable.md +21 -60
- package/templates/react-sdk-reference/.ai-common/skills/template-skills/SingleReferenceReadOnly.md +43 -100
- package/templates/react-sdk-reference/.ai-common/skills/template-skills/SubTabs.md +36 -76
- package/templates/react-sdk-reference/.ai-common/skills/template-skills/TwoColumn.md +41 -90
- package/templates/react-sdk-reference/.ai-common/skills/template-skills/WideNarrow.md +36 -43
- package/templates/react-sdk-reference/.ai-common/skills/template-skills/WssNavBar.md +25 -115
- package/templates/react-sdk-reference/.ai-common/skills/widget-components.md +38 -174
- package/templates/react-sdk-reference/.ai-common/skills/widget-skills/AppAnnouncement.md +30 -57
- package/templates/react-sdk-reference/.ai-common/skills/widget-skills/Attachment.md +55 -101
- package/templates/react-sdk-reference/.ai-common/skills/widget-skills/CaseHistory.md +38 -121
- package/templates/react-sdk-reference/.ai-common/skills/widget-skills/FileUtility.md +37 -98
- package/templates/react-sdk-reference/.ai-common/skills/widget-skills/Followers.md +18 -33
- package/templates/react-sdk-reference/.ai-common/skills/widget-skills/QuickCreate.md +26 -91
- package/templates/react-sdk-reference/.ai-common/skills/widget-skills/SummaryItem.md +28 -120
- package/templates/react-sdk-reference/.ai-common/skills/widget-skills/ToDo.md +41 -272
- package/templates/react-sdk-reference/package.json +1 -1
- package/templates/react-sdk-reference/pega-auth-0.2.44.tgz +0 -0
- package/templates/react-sdk-reference/pega-sdk-react-0.1.0.tgz +0 -0
- package/templates/react-sdk-reference/src/components/helpers/formatters/index.ts +13 -3
- package/templates/react-native-sdk-reference/.github/AGENTS.md +0 -23
- package/templates/react-native-sdk-reference/.github/copilot-instructions.md +0 -40
- package/templates/react-native-sdk-reference/.github/skills/pega-sdk-component.md +0 -48
- package/templates/react-native-sdk-reference/App.tsx +0 -49
- package/templates/react-native-sdk-reference/expo-env.d.ts +0 -3
- package/templates/react-sdk-reference/pega-auth-0.2.42.tgz +0 -0
package/dist/index.js
CHANGED
|
@@ -3,12 +3,12 @@
|
|
|
3
3
|
// src/index.ts
|
|
4
4
|
import * as p from "@clack/prompts";
|
|
5
5
|
import pc from "picocolors";
|
|
6
|
-
import
|
|
6
|
+
import path3 from "path";
|
|
7
7
|
import { createRequire } from "module";
|
|
8
8
|
|
|
9
9
|
// src/scaffold.ts
|
|
10
|
-
import
|
|
11
|
-
import
|
|
10
|
+
import fs2 from "fs";
|
|
11
|
+
import path2 from "path";
|
|
12
12
|
import { fileURLToPath } from "url";
|
|
13
13
|
import { spawn } from "child_process";
|
|
14
14
|
|
|
@@ -302,15 +302,134 @@ export function registerSampleComponents(registry: ComponentRegistry<React.Compo
|
|
|
302
302
|
return body;
|
|
303
303
|
}
|
|
304
304
|
|
|
305
|
+
// src/merge.ts
|
|
306
|
+
import fs from "fs";
|
|
307
|
+
import path from "path";
|
|
308
|
+
var PEGA_BEGIN = "<!-- BEGIN PEGA SDK \u2014 generated by @pega/sdk. Do not edit inside this block. -->";
|
|
309
|
+
var PEGA_END = "<!-- END PEGA SDK -->";
|
|
310
|
+
var PEGA_BLOCK_RE = new RegExp(`${escapeRegExp(PEGA_BEGIN)}[\\s\\S]*?${escapeRegExp(PEGA_END)}`);
|
|
311
|
+
function escapeRegExp(value) {
|
|
312
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
313
|
+
}
|
|
314
|
+
function hasPegaBlock(content) {
|
|
315
|
+
return PEGA_BLOCK_RE.test(content);
|
|
316
|
+
}
|
|
317
|
+
function wrapPegaBlock(body) {
|
|
318
|
+
return `${PEGA_BEGIN}
|
|
319
|
+
${body.replace(/\s+$/, "")}
|
|
320
|
+
${PEGA_END}
|
|
321
|
+
`;
|
|
322
|
+
}
|
|
323
|
+
function splitFrontmatter(content) {
|
|
324
|
+
const match = content.match(/^---\r?\n[\s\S]*?\r?\n---\r?\n/);
|
|
325
|
+
if (!match) return { frontmatter: "", body: content };
|
|
326
|
+
return { frontmatter: match[0], body: content.slice(match[0].length) };
|
|
327
|
+
}
|
|
328
|
+
function writeManagedMarkdown(destPath, input) {
|
|
329
|
+
const { frontmatter, body, policy, markers = true } = input;
|
|
330
|
+
fs.mkdirSync(path.dirname(destPath), { recursive: true });
|
|
331
|
+
if (!markers) {
|
|
332
|
+
const existed = fs.existsSync(destPath);
|
|
333
|
+
fs.writeFileSync(destPath, frontmatter + body);
|
|
334
|
+
return existed ? "overwritten" : "created";
|
|
335
|
+
}
|
|
336
|
+
const block = wrapPegaBlock(body);
|
|
337
|
+
if (!fs.existsSync(destPath)) {
|
|
338
|
+
fs.writeFileSync(destPath, frontmatter + block);
|
|
339
|
+
return "created";
|
|
340
|
+
}
|
|
341
|
+
const existing = fs.readFileSync(destPath, "utf-8");
|
|
342
|
+
if (hasPegaBlock(existing)) {
|
|
343
|
+
const outside = existing.replace(PEGA_BLOCK_RE, "");
|
|
344
|
+
const { body: outsideBody } = splitFrontmatter(outside);
|
|
345
|
+
if (outsideBody.trim() === "") {
|
|
346
|
+
fs.writeFileSync(destPath, frontmatter + block);
|
|
347
|
+
return "block-replaced";
|
|
348
|
+
}
|
|
349
|
+
fs.writeFileSync(destPath, existing.replace(PEGA_BLOCK_RE, block.replace(/\n$/, "")));
|
|
350
|
+
return "block-replaced";
|
|
351
|
+
}
|
|
352
|
+
if (policy === "override") {
|
|
353
|
+
fs.writeFileSync(destPath, frontmatter + block);
|
|
354
|
+
return "overwritten";
|
|
355
|
+
}
|
|
356
|
+
const separator = existing.endsWith("\n") ? "\n" : "\n\n";
|
|
357
|
+
fs.writeFileSync(destPath, existing + separator + block);
|
|
358
|
+
return "appended";
|
|
359
|
+
}
|
|
360
|
+
function isPlainObject(value) {
|
|
361
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
362
|
+
}
|
|
363
|
+
function deepMergeJson(existing, incoming, incomingWins = [], basePath = "") {
|
|
364
|
+
if (!isPlainObject(existing) || !isPlainObject(incoming)) {
|
|
365
|
+
return existing === void 0 ? incoming : existing;
|
|
366
|
+
}
|
|
367
|
+
const result = { ...existing };
|
|
368
|
+
for (const [key, incomingValue] of Object.entries(incoming)) {
|
|
369
|
+
const keyPath = basePath ? `${basePath}.${key}` : key;
|
|
370
|
+
if (!(key in result)) {
|
|
371
|
+
result[key] = incomingValue;
|
|
372
|
+
continue;
|
|
373
|
+
}
|
|
374
|
+
const existingValue = result[key];
|
|
375
|
+
if (isPlainObject(existingValue) && isPlainObject(incomingValue)) {
|
|
376
|
+
result[key] = deepMergeJson(existingValue, incomingValue, incomingWins, keyPath);
|
|
377
|
+
continue;
|
|
378
|
+
}
|
|
379
|
+
if (incomingWins.includes(keyPath) || incomingWins.includes(key)) {
|
|
380
|
+
result[key] = incomingValue;
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
return result;
|
|
384
|
+
}
|
|
385
|
+
function writeManagedJson(destPath, incoming, policy, incomingWins = []) {
|
|
386
|
+
fs.mkdirSync(path.dirname(destPath), { recursive: true });
|
|
387
|
+
if (!fs.existsSync(destPath)) {
|
|
388
|
+
fs.writeFileSync(destPath, JSON.stringify(incoming, null, 2) + "\n");
|
|
389
|
+
return "created";
|
|
390
|
+
}
|
|
391
|
+
if (policy === "merge") {
|
|
392
|
+
try {
|
|
393
|
+
const existing = JSON.parse(fs.readFileSync(destPath, "utf-8"));
|
|
394
|
+
const merged = deepMergeJson(existing, incoming, incomingWins);
|
|
395
|
+
fs.writeFileSync(destPath, JSON.stringify(merged, null, 2) + "\n");
|
|
396
|
+
return "appended";
|
|
397
|
+
} catch {
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
fs.writeFileSync(destPath, JSON.stringify(incoming, null, 2) + "\n");
|
|
401
|
+
return "overwritten";
|
|
402
|
+
}
|
|
403
|
+
function isConflict(destPath, incomingJson, incomingWins = []) {
|
|
404
|
+
if (!fs.existsSync(destPath)) return false;
|
|
405
|
+
let existing;
|
|
406
|
+
try {
|
|
407
|
+
existing = fs.readFileSync(destPath, "utf-8");
|
|
408
|
+
} catch {
|
|
409
|
+
return true;
|
|
410
|
+
}
|
|
411
|
+
if (/\.json$/i.test(destPath)) {
|
|
412
|
+
if (incomingJson === void 0) return true;
|
|
413
|
+
try {
|
|
414
|
+
const parsed = JSON.parse(existing);
|
|
415
|
+
const merged = deepMergeJson(parsed, incomingJson, incomingWins);
|
|
416
|
+
return JSON.stringify(merged) !== JSON.stringify(parsed);
|
|
417
|
+
} catch {
|
|
418
|
+
return true;
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
return !hasPegaBlock(existing);
|
|
422
|
+
}
|
|
423
|
+
|
|
305
424
|
// src/scaffold.ts
|
|
306
|
-
var __dirname =
|
|
307
|
-
var MONOREPO_SAMPLES_DIR =
|
|
308
|
-
var PACKAGED_TEMPLATES_DIR =
|
|
425
|
+
var __dirname = path2.dirname(fileURLToPath(import.meta.url));
|
|
426
|
+
var MONOREPO_SAMPLES_DIR = path2.resolve(__dirname, "..", "..", "..", "samples");
|
|
427
|
+
var PACKAGED_TEMPLATES_DIR = path2.resolve(__dirname, "..", "templates");
|
|
309
428
|
function resolveTemplateSourceRoot() {
|
|
310
|
-
if (
|
|
429
|
+
if (fs2.existsSync(MONOREPO_SAMPLES_DIR)) {
|
|
311
430
|
return MONOREPO_SAMPLES_DIR;
|
|
312
431
|
}
|
|
313
|
-
if (
|
|
432
|
+
if (fs2.existsSync(PACKAGED_TEMPLATES_DIR)) {
|
|
314
433
|
return PACKAGED_TEMPLATES_DIR;
|
|
315
434
|
}
|
|
316
435
|
throw new Error(
|
|
@@ -330,64 +449,86 @@ var CATEGORY_DIR_MAP = {
|
|
|
330
449
|
infra: "infra",
|
|
331
450
|
designSystemExtension: "designSystemExtension"
|
|
332
451
|
};
|
|
333
|
-
var SKIP_ENTRIES = /* @__PURE__ */ new Set([
|
|
452
|
+
var SKIP_ENTRIES = /* @__PURE__ */ new Set([
|
|
453
|
+
"node_modules",
|
|
454
|
+
"dist",
|
|
455
|
+
".DS_Store",
|
|
456
|
+
".next",
|
|
457
|
+
".expo",
|
|
458
|
+
".angular",
|
|
459
|
+
"build",
|
|
460
|
+
".pnpm-store"
|
|
461
|
+
]);
|
|
334
462
|
async function scaffold(choices, targetDir, onProgress) {
|
|
335
463
|
const report = (message) => onProgress?.(message);
|
|
336
|
-
|
|
464
|
+
let { framework, aiTool, includeTemplates, componentCategories, projectName } = choices;
|
|
465
|
+
if (framework === "react-native") {
|
|
466
|
+
includeTemplates = true;
|
|
467
|
+
componentCategories = ["fields", "templates", "infra"];
|
|
468
|
+
}
|
|
337
469
|
report("Preparing project directory\u2026");
|
|
338
|
-
if (
|
|
339
|
-
const files =
|
|
470
|
+
if (fs2.existsSync(targetDir)) {
|
|
471
|
+
const files = fs2.readdirSync(targetDir);
|
|
340
472
|
if (files.length > 0) {
|
|
341
473
|
throw new Error(`Directory "${targetDir}" is not empty.`);
|
|
342
474
|
}
|
|
343
475
|
} else {
|
|
344
|
-
|
|
476
|
+
fs2.mkdirSync(targetDir, { recursive: true });
|
|
345
477
|
}
|
|
346
478
|
const templateSourceRoot = resolveTemplateSourceRoot();
|
|
347
479
|
const sampleName = FRAMEWORK_SAMPLE_MAP[framework];
|
|
348
|
-
const sampleDir =
|
|
349
|
-
if (!
|
|
480
|
+
const sampleDir = path2.join(templateSourceRoot, sampleName);
|
|
481
|
+
if (!fs2.existsSync(sampleDir)) {
|
|
350
482
|
throw new Error(`Template "${sampleName}" not found at ${sampleDir}.`);
|
|
351
483
|
}
|
|
352
484
|
report(`Copying ${sampleName} reference app\u2026`);
|
|
353
485
|
copyDir(sampleDir, targetDir);
|
|
354
486
|
report("Configuring component set\u2026");
|
|
355
|
-
const componentsDir =
|
|
356
|
-
if (
|
|
487
|
+
const componentsDir = path2.join(targetDir, "src", "components");
|
|
488
|
+
if (fs2.existsSync(componentsDir)) {
|
|
489
|
+
const allowedCategories = framework === "react-native" ? ["fields", "templates", "infra"] : ["fields", "templates", "widgets", "infra", "designSystemExtension"];
|
|
357
490
|
if (!includeTemplates || componentCategories.length === 0) {
|
|
358
491
|
for (const cat of Object.values(CATEGORY_DIR_MAP)) {
|
|
359
|
-
const catDir =
|
|
360
|
-
if (
|
|
361
|
-
|
|
492
|
+
const catDir = path2.join(componentsDir, cat);
|
|
493
|
+
if (fs2.existsSync(catDir)) {
|
|
494
|
+
fs2.rmSync(catDir, { recursive: true });
|
|
362
495
|
}
|
|
363
496
|
}
|
|
364
|
-
|
|
497
|
+
fs2.writeFileSync(path2.join(componentsDir, "component-map.ts"), generateMinimalComponentMap(framework));
|
|
365
498
|
if (framework === "react") {
|
|
366
|
-
|
|
367
|
-
const muiThemeAugmentation =
|
|
368
|
-
if (
|
|
369
|
-
|
|
499
|
+
fs2.writeFileSync(path2.join(targetDir, "src", "AppProviders.tsx"), generateMinimalReactProviders());
|
|
500
|
+
const muiThemeAugmentation = path2.join(targetDir, "src", "mui-theme-augmentation.d.ts");
|
|
501
|
+
if (fs2.existsSync(muiThemeAugmentation)) {
|
|
502
|
+
fs2.rmSync(muiThemeAugmentation);
|
|
370
503
|
}
|
|
371
504
|
}
|
|
372
505
|
} else {
|
|
373
|
-
const
|
|
374
|
-
for (const cat of allCategories) {
|
|
506
|
+
for (const cat of allowedCategories) {
|
|
375
507
|
if (!componentCategories.includes(cat)) {
|
|
376
|
-
const catDir =
|
|
377
|
-
if (
|
|
378
|
-
|
|
508
|
+
const catDir = path2.join(componentsDir, CATEGORY_DIR_MAP[cat]);
|
|
509
|
+
if (fs2.existsSync(catDir)) {
|
|
510
|
+
fs2.rmSync(catDir, { recursive: true });
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
if (framework === "react-native") {
|
|
515
|
+
const unsupportedCats = ["widgets", "designSystemExtension"];
|
|
516
|
+
for (const cat of unsupportedCats) {
|
|
517
|
+
const catDir = path2.join(componentsDir, CATEGORY_DIR_MAP[cat]);
|
|
518
|
+
if (fs2.existsSync(catDir)) {
|
|
519
|
+
fs2.rmSync(catDir, { recursive: true });
|
|
379
520
|
}
|
|
380
521
|
}
|
|
381
522
|
}
|
|
382
523
|
const componentMapContent = generateComponentMap(componentCategories, framework);
|
|
383
|
-
|
|
524
|
+
fs2.writeFileSync(path2.join(componentsDir, "component-map.ts"), componentMapContent);
|
|
384
525
|
}
|
|
385
526
|
}
|
|
386
527
|
if (!aiTool) {
|
|
387
528
|
for (const dir of [".github", ".cursor", "AGENTS.md", ".claude", ".ai-common"]) {
|
|
388
|
-
const target =
|
|
389
|
-
if (
|
|
390
|
-
|
|
529
|
+
const target = path2.join(targetDir, dir);
|
|
530
|
+
if (fs2.existsSync(target)) {
|
|
531
|
+
fs2.rmSync(target, { recursive: true });
|
|
391
532
|
}
|
|
392
533
|
}
|
|
393
534
|
} else {
|
|
@@ -400,9 +541,9 @@ async function scaffold(choices, targetDir, onProgress) {
|
|
|
400
541
|
const keepPaths = AI_TOOL_PATHS[aiTool];
|
|
401
542
|
for (const dir of allAiPaths) {
|
|
402
543
|
if (!keepPaths.includes(dir)) {
|
|
403
|
-
const target =
|
|
404
|
-
if (
|
|
405
|
-
|
|
544
|
+
const target = path2.join(targetDir, dir);
|
|
545
|
+
if (fs2.existsSync(target)) {
|
|
546
|
+
fs2.rmSync(target, { recursive: true });
|
|
406
547
|
}
|
|
407
548
|
}
|
|
408
549
|
}
|
|
@@ -410,9 +551,12 @@ async function scaffold(choices, targetDir, onProgress) {
|
|
|
410
551
|
}
|
|
411
552
|
report("Finalizing project configuration\u2026");
|
|
412
553
|
selectReactPackageManifest(targetDir, framework, includeTemplates, componentCategories);
|
|
413
|
-
transformPackageJson(
|
|
414
|
-
transformTsConfig(
|
|
415
|
-
transformSdkConfig(
|
|
554
|
+
transformPackageJson(path2.join(targetDir, "package.json"), projectName);
|
|
555
|
+
transformTsConfig(path2.join(targetDir, "tsconfig.json"));
|
|
556
|
+
transformSdkConfig(path2.join(targetDir, "sdk-config.json"));
|
|
557
|
+
if (framework === "react-native") {
|
|
558
|
+
transformExpoConfig(path2.join(targetDir, "app.json"), projectName);
|
|
559
|
+
}
|
|
416
560
|
report("Installing dependencies (this may take a minute)\u2026");
|
|
417
561
|
try {
|
|
418
562
|
await runInstall(targetDir);
|
|
@@ -434,27 +578,27 @@ function runInstall(cwd) {
|
|
|
434
578
|
});
|
|
435
579
|
}
|
|
436
580
|
function transformPackageJson(pkgJsonPath, projectName) {
|
|
437
|
-
if (!
|
|
438
|
-
const pkgJson = JSON.parse(
|
|
581
|
+
if (!fs2.existsSync(pkgJsonPath)) return;
|
|
582
|
+
const pkgJson = JSON.parse(fs2.readFileSync(pkgJsonPath, "utf-8"));
|
|
439
583
|
pkgJson.name = projectName;
|
|
440
584
|
delete pkgJson.private;
|
|
441
|
-
|
|
585
|
+
fs2.writeFileSync(pkgJsonPath, JSON.stringify(pkgJson, null, 2) + "\n");
|
|
442
586
|
}
|
|
443
587
|
function selectReactPackageManifest(targetDir, framework, includeTemplates, componentCategories) {
|
|
444
588
|
if (framework !== "react") return;
|
|
445
|
-
const pkgJsonPath =
|
|
446
|
-
const minimalPkgJsonPath =
|
|
589
|
+
const pkgJsonPath = path2.join(targetDir, "package.json");
|
|
590
|
+
const minimalPkgJsonPath = path2.join(targetDir, "package.minimal.json");
|
|
447
591
|
const hasSampleComponents = includeTemplates && componentCategories.length > 0;
|
|
448
|
-
if (!hasSampleComponents &&
|
|
449
|
-
|
|
592
|
+
if (!hasSampleComponents && fs2.existsSync(minimalPkgJsonPath)) {
|
|
593
|
+
fs2.copyFileSync(minimalPkgJsonPath, pkgJsonPath);
|
|
450
594
|
}
|
|
451
|
-
if (
|
|
452
|
-
|
|
595
|
+
if (fs2.existsSync(minimalPkgJsonPath)) {
|
|
596
|
+
fs2.rmSync(minimalPkgJsonPath);
|
|
453
597
|
}
|
|
454
598
|
}
|
|
455
599
|
function transformTsConfig(tsconfigPath) {
|
|
456
|
-
if (!
|
|
457
|
-
const tsconfig = JSON.parse(
|
|
600
|
+
if (!fs2.existsSync(tsconfigPath)) return;
|
|
601
|
+
const tsconfig = JSON.parse(fs2.readFileSync(tsconfigPath, "utf-8"));
|
|
458
602
|
if (tsconfig.compilerOptions) {
|
|
459
603
|
if (tsconfig.compilerOptions.paths) {
|
|
460
604
|
const cleanedPaths = {};
|
|
@@ -474,11 +618,11 @@ function transformTsConfig(tsconfigPath) {
|
|
|
474
618
|
tsconfig.compilerOptions.typeRoots = ["./node_modules/@types", "./node_modules/@pega"];
|
|
475
619
|
}
|
|
476
620
|
}
|
|
477
|
-
|
|
621
|
+
fs2.writeFileSync(tsconfigPath, JSON.stringify(tsconfig, null, 2) + "\n");
|
|
478
622
|
}
|
|
479
623
|
function transformSdkConfig(sdkConfigPath) {
|
|
480
|
-
if (!
|
|
481
|
-
const sdkConfig = JSON.parse(
|
|
624
|
+
if (!fs2.existsSync(sdkConfigPath)) return;
|
|
625
|
+
const sdkConfig = JSON.parse(fs2.readFileSync(sdkConfigPath, "utf-8"));
|
|
482
626
|
if (sdkConfig.serverConfig) {
|
|
483
627
|
if ("infinityRestServerUrl" in sdkConfig.serverConfig) sdkConfig.serverConfig.infinityRestServerUrl = "";
|
|
484
628
|
if ("appAlias" in sdkConfig.serverConfig) sdkConfig.serverConfig.appAlias = "";
|
|
@@ -489,9 +633,45 @@ function transformSdkConfig(sdkConfigPath) {
|
|
|
489
633
|
if ("mashupUserIdentifier" in sdkConfig.authConfig) sdkConfig.authConfig.mashupUserIdentifier = "";
|
|
490
634
|
if ("portalClientId" in sdkConfig.authConfig) sdkConfig.authConfig.portalClientId = "";
|
|
491
635
|
}
|
|
492
|
-
|
|
636
|
+
fs2.writeFileSync(sdkConfigPath, JSON.stringify(sdkConfig, null, 2) + "\n");
|
|
637
|
+
}
|
|
638
|
+
function transformExpoConfig(appJsonPath, projectName) {
|
|
639
|
+
if (!fs2.existsSync(appJsonPath)) return;
|
|
640
|
+
const appJson = JSON.parse(fs2.readFileSync(appJsonPath, "utf-8"));
|
|
641
|
+
if (appJson.expo) {
|
|
642
|
+
appJson.expo.name = projectName;
|
|
643
|
+
appJson.expo.slug = projectName.toLowerCase().replace(/\s+/g, "-").replace(/[^a-z0-9-]/g, "");
|
|
644
|
+
}
|
|
645
|
+
fs2.writeFileSync(appJsonPath, JSON.stringify(appJson, null, 2) + "\n");
|
|
493
646
|
}
|
|
494
|
-
function generateMinimalComponentMap() {
|
|
647
|
+
function generateMinimalComponentMap(framework) {
|
|
648
|
+
if (framework === "react-native") {
|
|
649
|
+
return `import { sdkComponents } from '@pega/sdk-react';
|
|
650
|
+
import type { ComponentRegistry } from '@pega/sdk-types';
|
|
651
|
+
|
|
652
|
+
/**
|
|
653
|
+
* Returns a map of Pega component names \u2192 React Native components.
|
|
654
|
+
* Add your own components here as you build them.
|
|
655
|
+
*/
|
|
656
|
+
function getSampleComponentMap(): Record<string, React.ComponentType<Record<string, unknown>>> {
|
|
657
|
+
return {
|
|
658
|
+
...sdkComponents,
|
|
659
|
+
};
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
/**
|
|
663
|
+
* Registers all components into the given registry.
|
|
664
|
+
*/
|
|
665
|
+
export function registerComponents(
|
|
666
|
+
registry: ComponentRegistry<React.ComponentType<Record<string, unknown>>>,
|
|
667
|
+
) {
|
|
668
|
+
const map = getSampleComponentMap();
|
|
669
|
+
for (const [name, component] of Object.entries(map)) {
|
|
670
|
+
registry.register(name, component);
|
|
671
|
+
}
|
|
672
|
+
}
|
|
673
|
+
`;
|
|
674
|
+
}
|
|
495
675
|
return `import { sdkComponents } from '@pega/sdk-react';
|
|
496
676
|
import type { ComponentRegistry } from '@pega/sdk-types';
|
|
497
677
|
|
|
@@ -539,6 +719,7 @@ var AI_GEN_CONFIGS = {
|
|
|
539
719
|
tokens: {
|
|
540
720
|
"{{PROMPT_DIR}}": ".github/prompts",
|
|
541
721
|
"{{SKILL_DIR}}": ".github/skills",
|
|
722
|
+
"{{INSTRUCTIONS_DIR}}": ".github/instructions",
|
|
542
723
|
"{{PROMPT_EXT}}": ".prompt.md",
|
|
543
724
|
"{{SKILL_EXT}}": ".md",
|
|
544
725
|
"{{AI_FILE_EXT}}": ".instructions.md"
|
|
@@ -556,6 +737,7 @@ var AI_GEN_CONFIGS = {
|
|
|
556
737
|
tokens: {
|
|
557
738
|
"{{PROMPT_DIR}}": ".claude/prompts",
|
|
558
739
|
"{{SKILL_DIR}}": ".claude/skills",
|
|
740
|
+
"{{INSTRUCTIONS_DIR}}": ".claude/instructions",
|
|
559
741
|
"{{PROMPT_EXT}}": ".md",
|
|
560
742
|
"{{SKILL_EXT}}": ".md",
|
|
561
743
|
"{{AI_FILE_EXT}}": ".md"
|
|
@@ -573,6 +755,7 @@ var AI_GEN_CONFIGS = {
|
|
|
573
755
|
tokens: {
|
|
574
756
|
"{{PROMPT_DIR}}": ".cursor/rules/prompts",
|
|
575
757
|
"{{SKILL_DIR}}": ".cursor/rules/skills",
|
|
758
|
+
"{{INSTRUCTIONS_DIR}}": ".cursor/rules",
|
|
576
759
|
"{{PROMPT_EXT}}": ".mdrules",
|
|
577
760
|
"{{SKILL_EXT}}": ".mdrules",
|
|
578
761
|
"{{AI_FILE_EXT}}": ".mdrules"
|
|
@@ -611,22 +794,21 @@ function cursorSkillDescription(relPath) {
|
|
|
611
794
|
}
|
|
612
795
|
return relPath.replace(/\.md$/, "").split("/").pop();
|
|
613
796
|
}
|
|
614
|
-
function
|
|
615
|
-
|
|
616
|
-
if (!fs.existsSync(aiCommonDir)) return;
|
|
797
|
+
function planAiConfigs(aiCommonDir, targetDir, aiTool, options = {}) {
|
|
798
|
+
if (!fs2.existsSync(aiCommonDir)) return [];
|
|
617
799
|
const cfg = AI_GEN_CONFIGS[aiTool];
|
|
618
800
|
const { tokens } = cfg;
|
|
619
|
-
const
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
801
|
+
const planned = [];
|
|
802
|
+
const skillsSrc = path2.join(aiCommonDir, "skills");
|
|
803
|
+
if (fs2.existsSync(skillsSrc)) {
|
|
804
|
+
const walkSkills = (srcDir, relDir = "") => {
|
|
805
|
+
for (const entry of fs2.readdirSync(srcDir, { withFileTypes: true })) {
|
|
623
806
|
const relPath = relDir ? `${relDir}/${entry.name}` : entry.name;
|
|
624
|
-
const srcPath =
|
|
807
|
+
const srcPath = path2.join(srcDir, entry.name);
|
|
625
808
|
if (entry.isDirectory()) {
|
|
626
|
-
|
|
809
|
+
walkSkills(srcPath, relPath);
|
|
627
810
|
} else if (entry.name.endsWith(".md")) {
|
|
628
|
-
const { body } = parseAiMeta(
|
|
629
|
-
const outContent = applyTokens(body, tokens);
|
|
811
|
+
const { body } = parseAiMeta(fs2.readFileSync(srcPath, "utf-8"));
|
|
630
812
|
let frontmatter = "";
|
|
631
813
|
if (aiTool === "cursor") {
|
|
632
814
|
const desc = cursorSkillDescription(relPath);
|
|
@@ -638,26 +820,31 @@ alwaysApply: false
|
|
|
638
820
|
`;
|
|
639
821
|
}
|
|
640
822
|
const outName = `${entry.name.replace(/\.md$/, "")}.${cfg.skillExt}`;
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
823
|
+
planned.push({
|
|
824
|
+
destPath: path2.join(targetDir, cfg.skillDir, relDir, outName),
|
|
825
|
+
frontmatter,
|
|
826
|
+
body: applyTokens(body, tokens),
|
|
827
|
+
kind: "md"
|
|
828
|
+
});
|
|
644
829
|
}
|
|
645
830
|
}
|
|
646
831
|
};
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
const
|
|
653
|
-
|
|
654
|
-
for (const entry of fs.readdirSync(promptsSrc, { withFileTypes: true })) {
|
|
655
|
-
const srcPath = path.join(promptsSrc, entry.name);
|
|
832
|
+
walkSkills(skillsSrc);
|
|
833
|
+
}
|
|
834
|
+
const promptsSrc = path2.join(aiCommonDir, "prompts");
|
|
835
|
+
if (fs2.existsSync(promptsSrc)) {
|
|
836
|
+
const promptsDest = path2.join(targetDir, cfg.promptDir);
|
|
837
|
+
for (const entry of fs2.readdirSync(promptsSrc, { withFileTypes: true })) {
|
|
838
|
+
const srcPath = path2.join(promptsSrc, entry.name);
|
|
656
839
|
if (entry.name === "component-manifest.json") {
|
|
657
|
-
|
|
840
|
+
planned.push({
|
|
841
|
+
destPath: path2.join(promptsDest, entry.name),
|
|
842
|
+
frontmatter: "",
|
|
843
|
+
body: fs2.readFileSync(srcPath, "utf-8"),
|
|
844
|
+
kind: "json"
|
|
845
|
+
});
|
|
658
846
|
} else if (entry.name.endsWith(".md")) {
|
|
659
|
-
const { meta, body } = parseAiMeta(
|
|
660
|
-
const outContent = applyTokens(body, tokens);
|
|
847
|
+
const { meta, body } = parseAiMeta(fs2.readFileSync(srcPath, "utf-8"));
|
|
661
848
|
const basename = entry.name.replace(/\.md$/, "");
|
|
662
849
|
let frontmatter = "";
|
|
663
850
|
if (aiTool === "copilot") {
|
|
@@ -675,18 +862,21 @@ alwaysApply: false
|
|
|
675
862
|
|
|
676
863
|
`;
|
|
677
864
|
}
|
|
678
|
-
|
|
865
|
+
planned.push({
|
|
866
|
+
destPath: path2.join(promptsDest, `${basename}.${cfg.promptExt}`),
|
|
867
|
+
frontmatter,
|
|
868
|
+
body: applyTokens(body, tokens),
|
|
869
|
+
kind: "md"
|
|
870
|
+
});
|
|
679
871
|
}
|
|
680
872
|
}
|
|
681
873
|
}
|
|
682
|
-
const instructionsSrc =
|
|
683
|
-
if (
|
|
684
|
-
const instructionsDest =
|
|
685
|
-
|
|
686
|
-
for (const entry of fs.readdirSync(instructionsSrc, { withFileTypes: true })) {
|
|
874
|
+
const instructionsSrc = path2.join(aiCommonDir, "instructions");
|
|
875
|
+
if (fs2.existsSync(instructionsSrc)) {
|
|
876
|
+
const instructionsDest = path2.join(targetDir, cfg.instructionsDir);
|
|
877
|
+
for (const entry of fs2.readdirSync(instructionsSrc, { withFileTypes: true })) {
|
|
687
878
|
if (!entry.name.endsWith(".md")) continue;
|
|
688
|
-
const { meta, body } = parseAiMeta(
|
|
689
|
-
const outContent = applyTokens(body, tokens);
|
|
879
|
+
const { meta, body } = parseAiMeta(fs2.readFileSync(path2.join(instructionsSrc, entry.name), "utf-8"));
|
|
690
880
|
const basename = entry.name.replace(/\.md$/, "");
|
|
691
881
|
let frontmatter = "";
|
|
692
882
|
if (aiTool === "cursor") {
|
|
@@ -706,19 +896,21 @@ applyTo: '${meta.globs}'
|
|
|
706
896
|
|
|
707
897
|
`;
|
|
708
898
|
}
|
|
709
|
-
|
|
899
|
+
planned.push({
|
|
900
|
+
destPath: path2.join(instructionsDest, `${basename}.${cfg.instructionsExt}`),
|
|
901
|
+
frontmatter,
|
|
902
|
+
body: applyTokens(body, tokens),
|
|
903
|
+
kind: "md"
|
|
904
|
+
});
|
|
710
905
|
}
|
|
711
906
|
}
|
|
712
|
-
const agentsSrc =
|
|
713
|
-
if (
|
|
714
|
-
const agentsDest =
|
|
715
|
-
|
|
716
|
-
for (const entry of fs.readdirSync(agentsSrc, { withFileTypes: true })) {
|
|
907
|
+
const agentsSrc = path2.join(aiCommonDir, "agents");
|
|
908
|
+
if (fs2.existsSync(agentsSrc)) {
|
|
909
|
+
const agentsDest = path2.join(targetDir, cfg.agentsDir);
|
|
910
|
+
for (const entry of fs2.readdirSync(agentsSrc, { withFileTypes: true })) {
|
|
717
911
|
if (!entry.name.endsWith(".md")) continue;
|
|
718
912
|
const basename = entry.name.replace(/\.md$/, "");
|
|
719
|
-
const
|
|
720
|
-
const { meta, body } = parseAiMeta(fs.readFileSync(srcPath, "utf-8"));
|
|
721
|
-
const outContent = applyTokens(body, tokens);
|
|
913
|
+
const { meta, body } = parseAiMeta(fs2.readFileSync(path2.join(agentsSrc, entry.name), "utf-8"));
|
|
722
914
|
let frontmatter = "";
|
|
723
915
|
if (aiTool === "copilot") {
|
|
724
916
|
const description = applyTokens(meta.description || "", tokens);
|
|
@@ -726,7 +918,6 @@ applyTo: '${meta.globs}'
|
|
|
726
918
|
frontmatter = `---
|
|
727
919
|
description: "${description}"
|
|
728
920
|
name: '${name}'
|
|
729
|
-
tools: [read, edit, search, execute, agent, vscode_askQuestions]
|
|
730
921
|
user-invocable: true
|
|
731
922
|
disable-model-invocation: false
|
|
732
923
|
---
|
|
@@ -739,40 +930,302 @@ description: ${description}
|
|
|
739
930
|
alwaysApply: false
|
|
740
931
|
---
|
|
741
932
|
|
|
933
|
+
`;
|
|
934
|
+
} else if (aiTool === "claude-code") {
|
|
935
|
+
const description = applyTokens(meta.description || `Agent config: ${basename}`, tokens);
|
|
936
|
+
frontmatter = `---
|
|
937
|
+
name: ${basename}
|
|
938
|
+
description: "${description}"
|
|
939
|
+
---
|
|
940
|
+
|
|
742
941
|
`;
|
|
743
942
|
}
|
|
744
|
-
|
|
943
|
+
planned.push({
|
|
944
|
+
destPath: path2.join(agentsDest, `${basename}.${cfg.agentExt}`),
|
|
945
|
+
frontmatter,
|
|
946
|
+
body: applyTokens(body, tokens),
|
|
947
|
+
kind: "md"
|
|
948
|
+
});
|
|
745
949
|
}
|
|
746
950
|
}
|
|
747
|
-
const globalSrc =
|
|
748
|
-
if (
|
|
749
|
-
const
|
|
750
|
-
if (
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
951
|
+
const globalSrc = path2.join(aiCommonDir, "global", options.globalFile ?? "ai-agent-instructions.md");
|
|
952
|
+
if (fs2.existsSync(globalSrc)) {
|
|
953
|
+
const body = applyTokens(fs2.readFileSync(globalSrc, "utf-8"), tokens);
|
|
954
|
+
if (aiTool === "copilot") {
|
|
955
|
+
planned.push({
|
|
956
|
+
destPath: path2.join(targetDir, ".github", "copilot-instructions.md"),
|
|
957
|
+
frontmatter: "",
|
|
958
|
+
body,
|
|
959
|
+
kind: "md"
|
|
960
|
+
});
|
|
961
|
+
} else if (aiTool === "cursor") {
|
|
962
|
+
planned.push({
|
|
963
|
+
destPath: path2.join(targetDir, ".cursor", "rules", "pega-sdk.mdrules"),
|
|
964
|
+
frontmatter: "---\ndescription: Core rules for working with Pega SDK components\nalwaysApply: true\n---\n\n",
|
|
965
|
+
body,
|
|
966
|
+
kind: "md"
|
|
967
|
+
});
|
|
968
|
+
} else if (aiTool === "claude-code") {
|
|
969
|
+
planned.push({
|
|
970
|
+
destPath: path2.join(targetDir, "AGENTS.md"),
|
|
971
|
+
frontmatter: "",
|
|
972
|
+
body,
|
|
973
|
+
kind: "md"
|
|
974
|
+
});
|
|
975
|
+
}
|
|
976
|
+
}
|
|
977
|
+
return planned;
|
|
978
|
+
}
|
|
979
|
+
function applyPlannedFiles(files, policy, options = {}) {
|
|
980
|
+
const { markers = true } = options;
|
|
981
|
+
const counts = {
|
|
982
|
+
created: 0,
|
|
983
|
+
"block-replaced": 0,
|
|
984
|
+
appended: 0,
|
|
985
|
+
overwritten: 0
|
|
986
|
+
};
|
|
987
|
+
for (const file of files) {
|
|
988
|
+
let outcome;
|
|
989
|
+
if (file.kind === "json") {
|
|
990
|
+
let parsed;
|
|
991
|
+
try {
|
|
992
|
+
parsed = markers ? JSON.parse(file.body) : void 0;
|
|
993
|
+
} catch {
|
|
994
|
+
parsed = void 0;
|
|
995
|
+
}
|
|
996
|
+
if (parsed === void 0) {
|
|
997
|
+
fs2.mkdirSync(path2.dirname(file.destPath), { recursive: true });
|
|
998
|
+
const existed = fs2.existsSync(file.destPath);
|
|
999
|
+
fs2.writeFileSync(file.destPath, file.body);
|
|
1000
|
+
counts[existed ? "overwritten" : "created"] += 1;
|
|
1001
|
+
continue;
|
|
1002
|
+
}
|
|
1003
|
+
outcome = writeManagedJson(file.destPath, parsed, policy);
|
|
1004
|
+
} else {
|
|
1005
|
+
outcome = writeManagedMarkdown(file.destPath, {
|
|
1006
|
+
frontmatter: file.frontmatter,
|
|
1007
|
+
body: file.body,
|
|
1008
|
+
policy,
|
|
1009
|
+
markers
|
|
1010
|
+
});
|
|
1011
|
+
}
|
|
1012
|
+
counts[outcome] += 1;
|
|
1013
|
+
}
|
|
1014
|
+
return counts;
|
|
1015
|
+
}
|
|
1016
|
+
function generateAiConfigs(targetDir, aiTool) {
|
|
1017
|
+
const aiCommonDir = path2.join(targetDir, ".ai-common");
|
|
1018
|
+
if (!fs2.existsSync(aiCommonDir)) return;
|
|
1019
|
+
applyPlannedFiles(planAiConfigs(aiCommonDir, targetDir, aiTool), "override", { markers: false });
|
|
1020
|
+
fs2.rmSync(aiCommonDir, { recursive: true });
|
|
1021
|
+
}
|
|
1022
|
+
var EMBEDDED_GLOBAL_FILE = "ai-agent-instructions-embedded.md";
|
|
1023
|
+
function resolveEmbeddedSource() {
|
|
1024
|
+
const templateSourceRoot = resolveTemplateSourceRoot();
|
|
1025
|
+
const sampleDir = path2.join(templateSourceRoot, FRAMEWORK_SAMPLE_MAP.react);
|
|
1026
|
+
const aiCommonSrc = path2.join(sampleDir, ".ai-common");
|
|
1027
|
+
if (!fs2.existsSync(aiCommonSrc)) {
|
|
1028
|
+
throw new Error(`AI common source not found at ${aiCommonSrc}. Ensure the template source is available.`);
|
|
1029
|
+
}
|
|
1030
|
+
return { sampleDir, aiCommonSrc };
|
|
1031
|
+
}
|
|
1032
|
+
var SDK_CONFIG_USER_KEYS = [
|
|
1033
|
+
"serverConfig.infinityRestServerUrl",
|
|
1034
|
+
"serverConfig.appAlias",
|
|
1035
|
+
"authConfig.mashupClientId",
|
|
1036
|
+
"authConfig.mashupUserIdentifier",
|
|
1037
|
+
"authConfig.portalClientId"
|
|
1038
|
+
];
|
|
1039
|
+
var MCP_CONFIG_USER_KEYS = ["url", "clientId"];
|
|
1040
|
+
var MCP_CONFIG_FILES = {
|
|
1041
|
+
copilot: { source: "copilot.mcp.json", dest: path2.join(".vscode", "mcp.json") },
|
|
1042
|
+
cursor: { source: "cursor.mcp.json", dest: path2.join(".cursor", "mcp.json") },
|
|
1043
|
+
"claude-code": { source: "claude-code.mcp.json", dest: ".mcp.json" }
|
|
1044
|
+
};
|
|
1045
|
+
function resolveMcpConfig(aiCommonSrc, choices) {
|
|
1046
|
+
const { source, dest } = MCP_CONFIG_FILES[choices.aiTool];
|
|
1047
|
+
const srcPath = path2.join(aiCommonSrc, "mcp", source);
|
|
1048
|
+
if (!fs2.existsSync(srcPath)) {
|
|
1049
|
+
throw new Error(`MCP config template not found at ${srcPath}. Ensure the template source is available.`);
|
|
1050
|
+
}
|
|
1051
|
+
const tokens = {
|
|
1052
|
+
"{InfinityURL}": choices.serverUrl,
|
|
1053
|
+
"{AppAlias}": choices.appAlias,
|
|
1054
|
+
"{ClientId}": choices.clientId
|
|
1055
|
+
};
|
|
1056
|
+
if (choices.mcpRuleName) tokens["{MCPRuleName}"] = choices.mcpRuleName;
|
|
1057
|
+
if (choices.mcpRuleInsKey) tokens["{MCPRuleInsKey}"] = choices.mcpRuleInsKey;
|
|
1058
|
+
const content = applyTokens(fs2.readFileSync(srcPath, "utf-8"), tokens);
|
|
1059
|
+
return { config: JSON.parse(content), destRelPath: dest };
|
|
1060
|
+
}
|
|
1061
|
+
function ensureGitignoreEntry(targetDir, entry) {
|
|
1062
|
+
const gitignorePath = path2.join(targetDir, ".gitignore");
|
|
1063
|
+
const existing = fs2.existsSync(gitignorePath) ? fs2.readFileSync(gitignorePath, "utf-8") : "";
|
|
1064
|
+
if (existing.split(/\r?\n/).some((line) => line.trim() === entry)) return;
|
|
1065
|
+
const separator = existing.length > 0 && !existing.endsWith("\n") ? "\n" : "";
|
|
1066
|
+
fs2.writeFileSync(gitignorePath, existing + separator + entry + "\n");
|
|
1067
|
+
}
|
|
1068
|
+
function buildSdkConfig(choices) {
|
|
1069
|
+
return {
|
|
1070
|
+
serverConfig: {
|
|
1071
|
+
infinityRestServerUrl: choices.serverUrl,
|
|
1072
|
+
appAlias: choices.appAlias,
|
|
1073
|
+
sdkContentServerUrl: "",
|
|
1074
|
+
appPortal: "",
|
|
1075
|
+
appMashupCaseType: "",
|
|
1076
|
+
excludePortals: [
|
|
1077
|
+
"pxExpress",
|
|
1078
|
+
"Developer",
|
|
1079
|
+
"pxPredictionStudio",
|
|
1080
|
+
"pxAdminStudio",
|
|
1081
|
+
"pyCaseWorker",
|
|
1082
|
+
"pyCaseManager7"
|
|
1083
|
+
]
|
|
1084
|
+
},
|
|
1085
|
+
authConfig: {
|
|
1086
|
+
authService: "pega",
|
|
1087
|
+
mashupClientId: choices.clientId,
|
|
1088
|
+
mashupUserIdentifier: choices.userIdentifier,
|
|
1089
|
+
mashupPassword: "",
|
|
1090
|
+
portalClientId: choices.clientId,
|
|
1091
|
+
portalClientSecret: "",
|
|
1092
|
+
portalGrantType: ""
|
|
1093
|
+
}
|
|
1094
|
+
};
|
|
1095
|
+
}
|
|
1096
|
+
function collectEmbeddedConflicts(targetDir, choices) {
|
|
1097
|
+
const { aiCommonSrc } = resolveEmbeddedSource();
|
|
1098
|
+
const planned = planAiConfigs(aiCommonSrc, targetDir, choices.aiTool, { globalFile: EMBEDDED_GLOBAL_FILE });
|
|
1099
|
+
const conflicts = planned.filter((file) => {
|
|
1100
|
+
if (file.kind !== "json") return isConflict(file.destPath);
|
|
1101
|
+
try {
|
|
1102
|
+
return isConflict(file.destPath, JSON.parse(file.body));
|
|
1103
|
+
} catch {
|
|
1104
|
+
return isConflict(file.destPath);
|
|
1105
|
+
}
|
|
1106
|
+
}).map((file) => file.destPath);
|
|
1107
|
+
const sdkConfigPath = path2.join(resolveStaticDir(targetDir), "sdk-config.json");
|
|
1108
|
+
if (isConflict(sdkConfigPath, buildSdkConfig(choices), SDK_CONFIG_USER_KEYS)) {
|
|
1109
|
+
conflicts.push(sdkConfigPath);
|
|
1110
|
+
}
|
|
1111
|
+
const { config: mcpConfig, destRelPath: mcpDestRelPath } = resolveMcpConfig(aiCommonSrc, choices);
|
|
1112
|
+
const mcpConfigPath = path2.join(targetDir, mcpDestRelPath);
|
|
1113
|
+
if (isConflict(mcpConfigPath, mcpConfig, MCP_CONFIG_USER_KEYS)) {
|
|
1114
|
+
conflicts.push(mcpConfigPath);
|
|
1115
|
+
}
|
|
1116
|
+
return conflicts.map((filePath) => path2.relative(targetDir, filePath));
|
|
1117
|
+
}
|
|
1118
|
+
async function scaffoldEmbedded(choices, targetDir, onProgress) {
|
|
1119
|
+
const report = (message) => onProgress?.(message);
|
|
1120
|
+
const { aiTool } = choices;
|
|
1121
|
+
const policy = choices.conflictPolicy ?? "merge";
|
|
1122
|
+
report("Locating embedded flow skills\u2026");
|
|
1123
|
+
const { sampleDir, aiCommonSrc } = resolveEmbeddedSource();
|
|
1124
|
+
report(`Generating ${aiTool} configuration\u2026`);
|
|
1125
|
+
const planned = planAiConfigs(aiCommonSrc, targetDir, aiTool, { globalFile: EMBEDDED_GLOBAL_FILE });
|
|
1126
|
+
const counts = applyPlannedFiles(planned, policy);
|
|
1127
|
+
report(
|
|
1128
|
+
`Wrote ${planned.length} file(s): ${counts.created} new, ${counts["block-replaced"]} updated, ${counts.appended} merged, ${counts.overwritten} replaced.`
|
|
1129
|
+
);
|
|
1130
|
+
report("Copying SDK packages\u2026");
|
|
1131
|
+
const tgzFiles = fs2.readdirSync(sampleDir).filter((f) => f.endsWith(".tgz"));
|
|
1132
|
+
for (const tgz of tgzFiles) {
|
|
1133
|
+
const src = path2.join(sampleDir, tgz);
|
|
1134
|
+
const dest = path2.join(targetDir, tgz);
|
|
1135
|
+
fs2.copyFileSync(src, dest);
|
|
1136
|
+
}
|
|
1137
|
+
report("Adding SDK dependencies\u2026");
|
|
1138
|
+
const pkgJsonPath = path2.join(targetDir, "package.json");
|
|
1139
|
+
if (fs2.existsSync(pkgJsonPath)) {
|
|
1140
|
+
const pkgJson = JSON.parse(fs2.readFileSync(pkgJsonPath, "utf-8"));
|
|
1141
|
+
if (!pkgJson.dependencies) pkgJson.dependencies = {};
|
|
1142
|
+
const TGZ_PACKAGE_MAP = {
|
|
1143
|
+
"pega-auth": "@pega/auth",
|
|
1144
|
+
"pega-constellationjs": "@pega/constellationjs",
|
|
1145
|
+
"pega-sdk-react": "@pega/sdk-react",
|
|
1146
|
+
"pega-sdk-types": "@pega/sdk-types"
|
|
1147
|
+
};
|
|
1148
|
+
for (const tgz of tgzFiles) {
|
|
1149
|
+
const match = tgz.match(/^(pega-[\w-]+?)-\d/);
|
|
1150
|
+
if (match) {
|
|
1151
|
+
const pkgName = TGZ_PACKAGE_MAP[match[1]];
|
|
1152
|
+
if (pkgName) {
|
|
1153
|
+
pkgJson.dependencies[pkgName] = `file:${tgz}`;
|
|
1154
|
+
}
|
|
761
1155
|
}
|
|
762
1156
|
}
|
|
1157
|
+
fs2.writeFileSync(pkgJsonPath, JSON.stringify(pkgJson, null, 2) + "\n");
|
|
1158
|
+
}
|
|
1159
|
+
report("Creating SDK configuration\u2026");
|
|
1160
|
+
const staticDir = ensureStaticDir(targetDir);
|
|
1161
|
+
const sdkConfigPath = path2.join(staticDir, "sdk-config.json");
|
|
1162
|
+
writeManagedJson(sdkConfigPath, buildSdkConfig(choices), policy, SDK_CONFIG_USER_KEYS);
|
|
1163
|
+
if (staticDir !== targetDir && fs2.existsSync(path2.join(targetDir, "sdk-config.json"))) {
|
|
1164
|
+
report(`\u26A0\uFE0F A sdk-config.json also exists at the project root. The active one is ${sdkConfigPath}.`);
|
|
1165
|
+
}
|
|
1166
|
+
report("Creating MCP server configuration\u2026");
|
|
1167
|
+
const { config: mcpConfig, destRelPath: mcpDestRelPath } = resolveMcpConfig(aiCommonSrc, choices);
|
|
1168
|
+
writeManagedJson(path2.join(targetDir, mcpDestRelPath), mcpConfig, policy, MCP_CONFIG_USER_KEYS);
|
|
1169
|
+
if (aiTool === "cursor") {
|
|
1170
|
+
ensureGitignoreEntry(targetDir, mcpDestRelPath);
|
|
1171
|
+
}
|
|
1172
|
+
report("Installing dependencies (this may take a minute)\u2026");
|
|
1173
|
+
let installSucceeded = true;
|
|
1174
|
+
try {
|
|
1175
|
+
await runInstall(targetDir);
|
|
1176
|
+
} catch {
|
|
1177
|
+
installSucceeded = false;
|
|
1178
|
+
report(
|
|
1179
|
+
"\u26A0\uFE0F Dependency installation failed. Run your package manager manually, then copy OAuth callback assets (see below)."
|
|
1180
|
+
);
|
|
1181
|
+
}
|
|
1182
|
+
if (installSucceeded) {
|
|
1183
|
+
report("Copying OAuth callback assets\u2026");
|
|
1184
|
+
const authOAuthDir = path2.join(targetDir, "node_modules", "@pega", "auth", "lib", "oauth-client");
|
|
1185
|
+
if (fs2.existsSync(authOAuthDir)) {
|
|
1186
|
+
const authHtmlSrc = path2.join(authOAuthDir, "authDone.html");
|
|
1187
|
+
const authJsSrc = path2.join(authOAuthDir, "authDone.js");
|
|
1188
|
+
const lockSvgSrc = path2.join(authOAuthDir, "lock-closed-solid.svg");
|
|
1189
|
+
if (fs2.existsSync(authHtmlSrc)) fs2.copyFileSync(authHtmlSrc, path2.join(staticDir, "auth.html"));
|
|
1190
|
+
if (fs2.existsSync(authJsSrc)) fs2.copyFileSync(authJsSrc, path2.join(staticDir, "authDone.js"));
|
|
1191
|
+
if (fs2.existsSync(lockSvgSrc)) fs2.copyFileSync(lockSvgSrc, path2.join(staticDir, "lock-closed-solid.svg"));
|
|
1192
|
+
} else {
|
|
1193
|
+
report(
|
|
1194
|
+
"\u26A0\uFE0F Auth OAuth assets not found after install. Copy auth.html, authDone.js, and lock-closed-solid.svg manually to the served static directory."
|
|
1195
|
+
);
|
|
1196
|
+
}
|
|
763
1197
|
}
|
|
764
|
-
|
|
1198
|
+
report("Done!");
|
|
1199
|
+
}
|
|
1200
|
+
function detectExistingProject(dir) {
|
|
1201
|
+
return fs2.existsSync(path2.join(dir, "package.json"));
|
|
1202
|
+
}
|
|
1203
|
+
function resolveStaticDir(targetDir) {
|
|
1204
|
+
const pkgJsonPath = path2.join(targetDir, "package.json");
|
|
1205
|
+
if (fs2.existsSync(pkgJsonPath)) {
|
|
1206
|
+
const pkgJson = JSON.parse(fs2.readFileSync(pkgJsonPath, "utf-8"));
|
|
1207
|
+
const allDeps = { ...pkgJson.dependencies, ...pkgJson.devDependencies };
|
|
1208
|
+
if (allDeps["next"] || allDeps["vite"] || allDeps["react-scripts"]) {
|
|
1209
|
+
return path2.join(targetDir, "public");
|
|
1210
|
+
}
|
|
1211
|
+
}
|
|
1212
|
+
return targetDir;
|
|
1213
|
+
}
|
|
1214
|
+
function ensureStaticDir(targetDir) {
|
|
1215
|
+
const staticDir = resolveStaticDir(targetDir);
|
|
1216
|
+
fs2.mkdirSync(staticDir, { recursive: true });
|
|
1217
|
+
return staticDir;
|
|
765
1218
|
}
|
|
766
1219
|
function copyDir(src, dest) {
|
|
767
|
-
|
|
768
|
-
for (const entry of
|
|
1220
|
+
fs2.mkdirSync(dest, { recursive: true });
|
|
1221
|
+
for (const entry of fs2.readdirSync(src, { withFileTypes: true })) {
|
|
769
1222
|
if (SKIP_ENTRIES.has(entry.name)) continue;
|
|
770
|
-
const srcPath =
|
|
771
|
-
const destPath =
|
|
1223
|
+
const srcPath = path2.join(src, entry.name);
|
|
1224
|
+
const destPath = path2.join(dest, entry.name);
|
|
772
1225
|
if (entry.isDirectory()) {
|
|
773
1226
|
copyDir(srcPath, destPath);
|
|
774
1227
|
} else {
|
|
775
|
-
|
|
1228
|
+
fs2.copyFileSync(srcPath, destPath);
|
|
776
1229
|
}
|
|
777
1230
|
}
|
|
778
1231
|
}
|
|
@@ -792,6 +1245,209 @@ async function main() {
|
|
|
792
1245
|
Usage: ${pc.cyan("npx @pega/sdk init")}`);
|
|
793
1246
|
process.exit(1);
|
|
794
1247
|
}
|
|
1248
|
+
const cwd = process.cwd();
|
|
1249
|
+
const projectMode = detectExistingProject(cwd) ? "embedded" : "new";
|
|
1250
|
+
if (projectMode === "embedded") {
|
|
1251
|
+
const continueEmbedded = await p.confirm({
|
|
1252
|
+
message: "An existing project was detected in this folder (package.json found). Would you like to continue and integrate the embedded flow into it?",
|
|
1253
|
+
initialValue: true
|
|
1254
|
+
});
|
|
1255
|
+
if (p.isCancel(continueEmbedded) || !continueEmbedded) {
|
|
1256
|
+
p.cancel("Operation cancelled.");
|
|
1257
|
+
process.exit(0);
|
|
1258
|
+
}
|
|
1259
|
+
} else {
|
|
1260
|
+
p.log.info(pc.dim("No existing project detected in this folder \u2014 continuing with the new-project flow."));
|
|
1261
|
+
}
|
|
1262
|
+
if (projectMode === "embedded") {
|
|
1263
|
+
p.log.info(pc.dim("Let's set up Pega embedded flow in your existing project."));
|
|
1264
|
+
const aiAssisted = await p.confirm({
|
|
1265
|
+
message: "Would you like AI assistance to set up the embedded flow?",
|
|
1266
|
+
initialValue: true
|
|
1267
|
+
});
|
|
1268
|
+
if (p.isCancel(aiAssisted)) {
|
|
1269
|
+
p.cancel("Operation cancelled.");
|
|
1270
|
+
process.exit(0);
|
|
1271
|
+
}
|
|
1272
|
+
if (!aiAssisted) {
|
|
1273
|
+
p.log.info("Non-AI embedded flow is still under development. Stay tuned!");
|
|
1274
|
+
p.outro(pc.dim("No changes were made."));
|
|
1275
|
+
process.exit(0);
|
|
1276
|
+
}
|
|
1277
|
+
const embeddedAiTool = await p.select({
|
|
1278
|
+
message: "Which AI coding assistant do you use?",
|
|
1279
|
+
options: [
|
|
1280
|
+
{ value: "copilot", label: "GitHub Copilot" },
|
|
1281
|
+
{ value: "cursor", label: "Cursor" },
|
|
1282
|
+
{ value: "claude-code", label: "Claude Code" }
|
|
1283
|
+
]
|
|
1284
|
+
});
|
|
1285
|
+
if (p.isCancel(embeddedAiTool)) {
|
|
1286
|
+
p.cancel("Operation cancelled.");
|
|
1287
|
+
process.exit(0);
|
|
1288
|
+
}
|
|
1289
|
+
p.log.info(pc.dim("\nNow let's connect to your Pega server."));
|
|
1290
|
+
const serverUrlResult = await p.text({
|
|
1291
|
+
message: "What is your Pega server URL?",
|
|
1292
|
+
placeholder: "https://your-pega-server.com/prweb",
|
|
1293
|
+
validate(value) {
|
|
1294
|
+
if (!value) return "Server URL is required.";
|
|
1295
|
+
if (!value.startsWith("http")) return "Must be a valid URL starting with http:// or https://";
|
|
1296
|
+
}
|
|
1297
|
+
});
|
|
1298
|
+
if (p.isCancel(serverUrlResult)) {
|
|
1299
|
+
p.cancel("Operation cancelled.");
|
|
1300
|
+
process.exit(0);
|
|
1301
|
+
}
|
|
1302
|
+
const serverUrl = serverUrlResult.replace(/\/+$/, "");
|
|
1303
|
+
const appAlias = await p.text({
|
|
1304
|
+
message: "What is your Pega application alias?",
|
|
1305
|
+
placeholder: "MyApp",
|
|
1306
|
+
validate(value) {
|
|
1307
|
+
if (!value) return "Application alias is required.";
|
|
1308
|
+
}
|
|
1309
|
+
});
|
|
1310
|
+
if (p.isCancel(appAlias)) {
|
|
1311
|
+
p.cancel("Operation cancelled.");
|
|
1312
|
+
process.exit(0);
|
|
1313
|
+
}
|
|
1314
|
+
const clientId = await p.text({
|
|
1315
|
+
message: "What is the OAuth Client ID for your app?",
|
|
1316
|
+
placeholder: "Your OAuth 2.0 client identifier",
|
|
1317
|
+
validate(value) {
|
|
1318
|
+
if (!value) return "Client ID is required for authentication.";
|
|
1319
|
+
}
|
|
1320
|
+
});
|
|
1321
|
+
if (p.isCancel(clientId)) {
|
|
1322
|
+
p.cancel("Operation cancelled.");
|
|
1323
|
+
process.exit(0);
|
|
1324
|
+
}
|
|
1325
|
+
const userIdentifier = await p.text({
|
|
1326
|
+
message: "What is the operator ID for the embedded session?",
|
|
1327
|
+
placeholder: "user@yourapp",
|
|
1328
|
+
validate(value) {
|
|
1329
|
+
if (!value) return "Operator ID is required.";
|
|
1330
|
+
}
|
|
1331
|
+
});
|
|
1332
|
+
if (p.isCancel(userIdentifier)) {
|
|
1333
|
+
p.cancel("Operation cancelled.");
|
|
1334
|
+
process.exit(0);
|
|
1335
|
+
}
|
|
1336
|
+
p.log.info(pc.dim("\nIf you've configured an MCP server for this app, we can wire it up too (optional)."));
|
|
1337
|
+
const mcpRuleNameResult = await p.text({
|
|
1338
|
+
message: "What is your Pega MCP rule name? (press Enter to skip)",
|
|
1339
|
+
placeholder: "SDKMCP"
|
|
1340
|
+
});
|
|
1341
|
+
if (p.isCancel(mcpRuleNameResult)) {
|
|
1342
|
+
p.cancel("Operation cancelled.");
|
|
1343
|
+
process.exit(0);
|
|
1344
|
+
}
|
|
1345
|
+
const mcpRuleInsKeyResult = await p.text({
|
|
1346
|
+
message: "What is your Pega MCP rule instance key? (press Enter to skip)",
|
|
1347
|
+
placeholder: "@baseclass!SDKMCP"
|
|
1348
|
+
});
|
|
1349
|
+
if (p.isCancel(mcpRuleInsKeyResult)) {
|
|
1350
|
+
p.cancel("Operation cancelled.");
|
|
1351
|
+
process.exit(0);
|
|
1352
|
+
}
|
|
1353
|
+
const mcpRuleName = mcpRuleNameResult || void 0;
|
|
1354
|
+
const mcpRuleInsKey = mcpRuleInsKeyResult || void 0;
|
|
1355
|
+
const embeddedTargetDir = cwd;
|
|
1356
|
+
p.note(
|
|
1357
|
+
[
|
|
1358
|
+
`${pc.bold("Mode")}: Embed Pega flow`,
|
|
1359
|
+
`${pc.bold("Directory")}: ${embeddedTargetDir}`,
|
|
1360
|
+
`${pc.bold("AI Tool")}: ${embeddedAiTool}`,
|
|
1361
|
+
`${pc.bold("Server")}: ${serverUrl}`,
|
|
1362
|
+
`${pc.bold("App Alias")}: ${appAlias}`,
|
|
1363
|
+
`${pc.bold("Client ID")}: ${clientId}`,
|
|
1364
|
+
`${pc.bold("Operator")}: ${userIdentifier}`,
|
|
1365
|
+
`${pc.bold("MCP Rule")}: ${mcpRuleName ?? pc.dim("(not configured \u2014 markers left in generated file)")}`,
|
|
1366
|
+
`${pc.bold("MCP Ins Key")}: ${mcpRuleInsKey ?? pc.dim("(not configured \u2014 markers left in generated file)")}`
|
|
1367
|
+
].join("\n"),
|
|
1368
|
+
"Configuration"
|
|
1369
|
+
);
|
|
1370
|
+
const embeddedConfirmed = await p.confirm({
|
|
1371
|
+
message: "Looks good? Let's set it up.",
|
|
1372
|
+
initialValue: true
|
|
1373
|
+
});
|
|
1374
|
+
if (p.isCancel(embeddedConfirmed) || !embeddedConfirmed) {
|
|
1375
|
+
p.cancel("Operation cancelled.");
|
|
1376
|
+
process.exit(0);
|
|
1377
|
+
}
|
|
1378
|
+
const embeddedChoices = {
|
|
1379
|
+
aiTool: embeddedAiTool,
|
|
1380
|
+
serverUrl,
|
|
1381
|
+
appAlias,
|
|
1382
|
+
clientId,
|
|
1383
|
+
userIdentifier,
|
|
1384
|
+
mcpRuleName,
|
|
1385
|
+
mcpRuleInsKey
|
|
1386
|
+
};
|
|
1387
|
+
let conflicts = [];
|
|
1388
|
+
try {
|
|
1389
|
+
conflicts = collectEmbeddedConflicts(embeddedTargetDir, embeddedChoices);
|
|
1390
|
+
} catch (err) {
|
|
1391
|
+
p.log.error(String(err));
|
|
1392
|
+
process.exit(1);
|
|
1393
|
+
}
|
|
1394
|
+
if (conflicts.length > 0) {
|
|
1395
|
+
const MAX_LISTED = 15;
|
|
1396
|
+
const listed = conflicts.slice(0, MAX_LISTED);
|
|
1397
|
+
const remaining = conflicts.length - listed.length;
|
|
1398
|
+
p.note(
|
|
1399
|
+
[...listed, ...remaining > 0 ? [pc.dim(`\u2026and ${remaining} more`)] : []].join("\n"),
|
|
1400
|
+
`Found ${conflicts.length} existing file(s)`
|
|
1401
|
+
);
|
|
1402
|
+
const policyResult = await p.select({
|
|
1403
|
+
message: "These files already exist. How should we handle them?",
|
|
1404
|
+
options: [
|
|
1405
|
+
{
|
|
1406
|
+
value: "merge",
|
|
1407
|
+
label: "Merge",
|
|
1408
|
+
hint: "keep your content and add Pega content in a marked block"
|
|
1409
|
+
},
|
|
1410
|
+
{
|
|
1411
|
+
value: "override",
|
|
1412
|
+
label: "Override",
|
|
1413
|
+
hint: "replace these files with the Pega versions"
|
|
1414
|
+
}
|
|
1415
|
+
],
|
|
1416
|
+
initialValue: "merge"
|
|
1417
|
+
});
|
|
1418
|
+
if (p.isCancel(policyResult)) {
|
|
1419
|
+
p.cancel("Operation cancelled.");
|
|
1420
|
+
process.exit(0);
|
|
1421
|
+
}
|
|
1422
|
+
embeddedChoices.conflictPolicy = policyResult;
|
|
1423
|
+
}
|
|
1424
|
+
const spinner3 = p.spinner();
|
|
1425
|
+
spinner3.start("Setting up embedded flow\u2026");
|
|
1426
|
+
try {
|
|
1427
|
+
await scaffoldEmbedded(embeddedChoices, embeddedTargetDir, (message) => {
|
|
1428
|
+
spinner3.message(message);
|
|
1429
|
+
});
|
|
1430
|
+
spinner3.stop("Embedded flow ready!");
|
|
1431
|
+
} catch (err) {
|
|
1432
|
+
spinner3.stop("Failed to set up embedded flow.");
|
|
1433
|
+
p.log.error(String(err));
|
|
1434
|
+
process.exit(1);
|
|
1435
|
+
}
|
|
1436
|
+
p.note(
|
|
1437
|
+
[
|
|
1438
|
+
"# Open your AI coding assistant and say:",
|
|
1439
|
+
'"Embed case [YOUR-CASE-TYPE] on click of [your button]"',
|
|
1440
|
+
"",
|
|
1441
|
+
"# The assistant will:",
|
|
1442
|
+
"1. Scan your codebase to understand your design system",
|
|
1443
|
+
"2. Generate Pega components matching your app's style",
|
|
1444
|
+
"3. Wire everything together so the case flow just works"
|
|
1445
|
+
].join("\n"),
|
|
1446
|
+
"Next Steps"
|
|
1447
|
+
);
|
|
1448
|
+
p.outro(pc.green("You're all set! Open your AI assistant and start embedding."));
|
|
1449
|
+
process.exit(0);
|
|
1450
|
+
}
|
|
795
1451
|
const nameResult = await p.text({
|
|
796
1452
|
message: "What is the name of your project?",
|
|
797
1453
|
placeholder: "my-pega-app",
|
|
@@ -848,12 +1504,12 @@ Usage: ${pc.cyan("npx @pega/sdk init")}`);
|
|
|
848
1504
|
{
|
|
849
1505
|
value: "react",
|
|
850
1506
|
label: "React",
|
|
851
|
-
hint: "Vite + React
|
|
1507
|
+
hint: "Vite + React 19 + @pega/sdk-react"
|
|
852
1508
|
},
|
|
853
1509
|
{
|
|
854
1510
|
value: "angular",
|
|
855
1511
|
label: "Angular",
|
|
856
|
-
hint: "Angular
|
|
1512
|
+
hint: "Angular 21 + @pega/sdk-angular"
|
|
857
1513
|
},
|
|
858
1514
|
{
|
|
859
1515
|
value: "web-components",
|
|
@@ -871,54 +1527,61 @@ Usage: ${pc.cyan("npx @pega/sdk init")}`);
|
|
|
871
1527
|
p.cancel("Operation cancelled.");
|
|
872
1528
|
process.exit(0);
|
|
873
1529
|
}
|
|
874
|
-
|
|
875
|
-
message: "Include starter component implementations? (scaffolds working component files you can customize)",
|
|
876
|
-
initialValue: true
|
|
877
|
-
});
|
|
878
|
-
if (p.isCancel(includeTemplates)) {
|
|
879
|
-
p.cancel("Operation cancelled.");
|
|
880
|
-
process.exit(0);
|
|
881
|
-
}
|
|
1530
|
+
let includeTemplates;
|
|
882
1531
|
let componentCategories = [];
|
|
883
|
-
if (
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
hint: "TextInput, Dropdown, Checkbox, Date, etc."
|
|
891
|
-
},
|
|
892
|
-
{
|
|
893
|
-
value: "templates",
|
|
894
|
-
label: "Templates",
|
|
895
|
-
hint: "OneColumn, TwoColumn, CaseView, DefaultForm, etc."
|
|
896
|
-
},
|
|
897
|
-
{
|
|
898
|
-
value: "widgets",
|
|
899
|
-
label: "Widgets",
|
|
900
|
-
hint: "Attachment, CaseHistory, ToDo, etc."
|
|
901
|
-
},
|
|
902
|
-
{
|
|
903
|
-
value: "infra",
|
|
904
|
-
label: "Infrastructure",
|
|
905
|
-
hint: "NavBar, ActionButtons, Stages, etc."
|
|
906
|
-
},
|
|
907
|
-
{
|
|
908
|
-
value: "designSystemExtension",
|
|
909
|
-
label: "Design System Extensions",
|
|
910
|
-
hint: "AlertBanner, FieldGroup, Pulse, etc."
|
|
911
|
-
}
|
|
912
|
-
],
|
|
913
|
-
required: true
|
|
1532
|
+
if (framework === "react-native") {
|
|
1533
|
+
includeTemplates = true;
|
|
1534
|
+
componentCategories = ["fields", "templates", "infra"];
|
|
1535
|
+
} else {
|
|
1536
|
+
const includeTemplatesResult = await p.confirm({
|
|
1537
|
+
message: "Include starter component implementations? (scaffolds working component files you can customize)",
|
|
1538
|
+
initialValue: true
|
|
914
1539
|
});
|
|
915
|
-
if (p.isCancel(
|
|
1540
|
+
if (p.isCancel(includeTemplatesResult)) {
|
|
916
1541
|
p.cancel("Operation cancelled.");
|
|
917
1542
|
process.exit(0);
|
|
918
1543
|
}
|
|
919
|
-
|
|
1544
|
+
includeTemplates = includeTemplatesResult;
|
|
1545
|
+
if (includeTemplates) {
|
|
1546
|
+
const categories = await p.multiselect({
|
|
1547
|
+
message: "Which component types do you want scaffolded?",
|
|
1548
|
+
options: [
|
|
1549
|
+
{
|
|
1550
|
+
value: "fields",
|
|
1551
|
+
label: "Fields",
|
|
1552
|
+
hint: "TextInput, Dropdown, Checkbox, Date, etc."
|
|
1553
|
+
},
|
|
1554
|
+
{
|
|
1555
|
+
value: "templates",
|
|
1556
|
+
label: "Templates",
|
|
1557
|
+
hint: "OneColumn, TwoColumn, CaseView, DefaultForm, etc."
|
|
1558
|
+
},
|
|
1559
|
+
{
|
|
1560
|
+
value: "widgets",
|
|
1561
|
+
label: "Widgets",
|
|
1562
|
+
hint: "Attachment, CaseHistory, ToDo, etc."
|
|
1563
|
+
},
|
|
1564
|
+
{
|
|
1565
|
+
value: "infra",
|
|
1566
|
+
label: "Infrastructure",
|
|
1567
|
+
hint: "NavBar, ActionButtons, Stages, etc."
|
|
1568
|
+
},
|
|
1569
|
+
{
|
|
1570
|
+
value: "designSystemExtension",
|
|
1571
|
+
label: "Design System Extensions",
|
|
1572
|
+
hint: "AlertBanner, FieldGroup, Pulse, etc."
|
|
1573
|
+
}
|
|
1574
|
+
],
|
|
1575
|
+
required: true
|
|
1576
|
+
});
|
|
1577
|
+
if (p.isCancel(categories)) {
|
|
1578
|
+
p.cancel("Operation cancelled.");
|
|
1579
|
+
process.exit(0);
|
|
1580
|
+
}
|
|
1581
|
+
componentCategories = categories;
|
|
1582
|
+
}
|
|
920
1583
|
}
|
|
921
|
-
const targetDir =
|
|
1584
|
+
const targetDir = path3.resolve(process.cwd(), projectName);
|
|
922
1585
|
p.note(
|
|
923
1586
|
[
|
|
924
1587
|
`${pc.bold("Project")}: ${projectName}`,
|