@pega/sdk 0.0.14 → 0.0.15
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 +46 -6
- package/dist/index.js +50 -24
- package/package.json +42 -3
- package/templates/angular-sdk-reference/angular.json +1 -2
- package/templates/angular-sdk-reference/extra-webpack.config.cjs +23 -0
- package/templates/angular-sdk-reference/index.html +12 -0
- package/templates/angular-sdk-reference/package.json +0 -1
- package/templates/angular-sdk-reference/src/app/app.component.ts +15 -232
- package/templates/angular-sdk-reference/src/app/pconnect-renderer.component.ts +153 -0
- package/templates/angular-sdk-reference/src/components/fields/auto-complete/auto-complete.component.ts +58 -21
- package/templates/angular-sdk-reference/src/components/fields/checkbox/checkbox.component.ts +8 -3
- package/templates/angular-sdk-reference/src/components/fields/currency/currency.component.ts +22 -7
- package/templates/angular-sdk-reference/src/components/fields/date-input/date-input.component.ts +19 -6
- package/templates/angular-sdk-reference/src/components/fields/dropdown/dropdown.component.ts +24 -7
- package/templates/angular-sdk-reference/src/components/fields/email/email.component.ts +19 -6
- package/templates/angular-sdk-reference/src/components/fields/integer/integer.component.ts +19 -6
- package/templates/angular-sdk-reference/src/components/fields/phone/phone.component.ts +19 -6
- package/templates/angular-sdk-reference/src/components/fields/radio-buttons/radio-buttons.component.ts +16 -5
- package/templates/angular-sdk-reference/src/components/fields/text-area/text-area.component.ts +19 -6
- package/templates/angular-sdk-reference/src/components/fields/text-input/text-input.component.ts +19 -6
- package/templates/angular-sdk-reference/src/components/fields/url-input/url-input.component.ts +26 -7
- package/templates/angular-sdk-reference/src/components/helpers/sdk-helpers.ts +93 -0
- package/templates/angular-sdk-reference/src/components/infra/case-summary/case-summary.component.ts +8 -9
- package/templates/angular-sdk-reference/src/components/infra/case-view/case-view.component.ts +24 -12
- package/templates/angular-sdk-reference/src/components/infra/root-container/root-container.component.ts +21 -15
- package/templates/angular-sdk-reference/src/components/infra/stages/stages.component.ts +21 -10
- package/templates/angular-sdk-reference/src/components/infra/view/view.component.ts +14 -9
- package/templates/angular-sdk-reference/src/components/templates/default-form/default-form.component.ts +12 -8
- package/templates/angular-sdk-reference/tsconfig.app.json +13 -0
- package/templates/angular-sdk-reference/tsconfig.json +2 -5
- package/templates/react-sdk-reference/.ai-common/agents/embedded-flow-expert.md +65 -31
- package/templates/react-sdk-reference/.ai-common/agents/implementation-expert.md +74 -38
- package/templates/react-sdk-reference/.ai-common/global/ai-agent-instructions-embedded.md +33 -1
- package/templates/react-sdk-reference/.ai-common/global/ai-agent-instructions.md +57 -22
- package/templates/react-sdk-reference/.ai-common/instructions/embedded-component.md +25 -10
- package/templates/react-sdk-reference/.ai-common/prompts/add-component.md +40 -19
- package/templates/react-sdk-reference/.ai-common/prompts/component-manifest.json +55 -1
- package/templates/react-sdk-reference/.ai-common/prompts/embedded-component-manifest.md +26 -4
- package/templates/react-sdk-reference/.ai-common/prompts/generate-all-components.md +82 -33
- package/templates/react-sdk-reference/.ai-common/prompts/generate-dse-components.md +46 -26
- package/templates/react-sdk-reference/.ai-common/prompts/generate-embedded-components.md +28 -15
- package/templates/react-sdk-reference/.ai-common/prompts/generate-field-components.md +24 -6
- package/templates/react-sdk-reference/.ai-common/prompts/generate-infra-components.md +24 -6
- package/templates/react-sdk-reference/.ai-common/prompts/generate-template-components.md +24 -6
- package/templates/react-sdk-reference/.ai-common/prompts/generate-widget-components.md +24 -6
- package/templates/react-sdk-reference/.ai-common/prompts/identify-components.md +2 -0
- package/templates/react-sdk-reference/.ai-common/prompts/replace-design-system.md +44 -17
- package/templates/react-sdk-reference/.ai-common/skills/connect-pega-server.md +14 -1
- package/templates/react-sdk-reference/.ai-common/skills/design-system-extension-skills/AssignmentHeader.md +79 -0
- package/templates/react-sdk-reference/.ai-common/skills/design-system-extension-skills/Toast.md +96 -0
- package/templates/react-sdk-reference/.ai-common/skills/design-system-extension.md +56 -35
- package/templates/react-sdk-reference/.ai-common/skills/embedded-flow/analyze-customer-repo.md +29 -3
- package/templates/react-sdk-reference/.ai-common/skills/embedded-flow/run-and-verify-integration.md +97 -37
- package/templates/react-sdk-reference/.ai-common/skills/embedded-flow/wire-integration.md +91 -60
- package/templates/react-sdk-reference/.ai-common/skills/field-components.md +13 -1
- package/templates/react-sdk-reference/.ai-common/skills/infra-components.md +13 -1
- package/templates/react-sdk-reference/.ai-common/skills/portal-flow/run-and-verify-portal.md +290 -0
- package/templates/react-sdk-reference/.ai-common/skills/template-components.md +13 -1
- package/templates/react-sdk-reference/.ai-common/skills/widget-components.md +13 -1
- package/templates/react-sdk-reference/assets/icons/trash.svg +3 -0
- package/templates/react-sdk-reference/index.html +0 -1
- package/templates/react-sdk-reference/package.json +2 -2
- package/templates/react-sdk-reference/package.minimal.json +2 -2
- package/templates/react-sdk-reference/sdk-config.json +3 -3
- package/templates/react-sdk-reference/src/FallbackComponent.tsx +1 -1
- package/templates/react-sdk-reference/src/MashupApp.tsx +33 -78
- package/templates/react-sdk-reference/src/PortalApp.tsx +23 -100
- package/templates/react-sdk-reference/src/components/component-map.ts +15 -1
- package/templates/react-sdk-reference/src/components/designSystemExtension/AssignmentHeader/AssignmentHeader.tsx +15 -0
- package/templates/react-sdk-reference/src/components/designSystemExtension/AssignmentHeader/index.tsx +1 -0
- package/templates/react-sdk-reference/src/components/designSystemExtension/FieldGroup/FieldGroup.tsx +1 -1
- package/templates/react-sdk-reference/src/components/designSystemExtension/FieldGroupList/FieldGroupList.tsx +1 -1
- package/templates/react-sdk-reference/src/components/designSystemExtension/FieldValueList/FieldValueList.tsx +16 -4
- package/templates/react-sdk-reference/src/components/designSystemExtension/ModalDialog/ModalDialog.tsx +26 -0
- package/templates/react-sdk-reference/src/components/designSystemExtension/ModalDialog/index.tsx +1 -0
- package/templates/react-sdk-reference/src/components/designSystemExtension/Toast/Toast.tsx +35 -0
- package/templates/react-sdk-reference/src/components/designSystemExtension/Toast/index.tsx +1 -0
- package/templates/react-sdk-reference/src/components/field/AutoComplete/AutoComplete.tsx +362 -24
- package/templates/react-sdk-reference/src/components/field/CancelAlert/CancelAlert.tsx +1 -1
- package/templates/react-sdk-reference/src/components/field/Checkbox/Checkbox.tsx +3 -1
- package/templates/react-sdk-reference/src/components/field/Currency/Currency.tsx +6 -3
- package/templates/react-sdk-reference/src/components/field/Date/Date.tsx +2 -1
- package/templates/react-sdk-reference/src/components/field/DateTime/DateTime.tsx +2 -1
- package/templates/react-sdk-reference/src/components/field/Decimal/Decimal.tsx +4 -3
- package/templates/react-sdk-reference/src/components/field/Dropdown/Dropdown.tsx +2 -0
- package/templates/react-sdk-reference/src/components/field/Email/Email.tsx +2 -1
- package/templates/react-sdk-reference/src/components/field/EmbeddedDataMulti/EmbeddedDataMulti.tsx +121 -0
- package/templates/react-sdk-reference/src/components/field/EmbeddedDataMulti/config-ext.json +7 -0
- package/templates/react-sdk-reference/src/components/field/EmbeddedDataMulti/index.tsx +1 -0
- package/templates/react-sdk-reference/src/components/field/Integer/Integer.tsx +2 -1
- package/templates/react-sdk-reference/src/components/field/Location/Location.tsx +1 -1
- package/templates/react-sdk-reference/src/components/field/Multiselect/Multiselect.tsx +40 -20
- package/templates/react-sdk-reference/src/components/field/ObjectReference/ObjectReference.tsx +554 -49
- package/templates/react-sdk-reference/src/components/field/ObjectReference/utils.ts +111 -20
- package/templates/react-sdk-reference/src/components/field/Percentage/Percentage.tsx +4 -3
- package/templates/react-sdk-reference/src/components/field/Phone/Phone.tsx +2 -1
- package/templates/react-sdk-reference/src/components/field/SelectableCard/SelectableCard.tsx +2 -1
- package/templates/react-sdk-reference/src/components/field/TextArea/TextArea.tsx +2 -1
- package/templates/react-sdk-reference/src/components/field/TextInput/TextInput.tsx +2 -1
- package/templates/react-sdk-reference/src/components/field/Time/Time.tsx +2 -1
- package/templates/react-sdk-reference/src/components/field/URL/URL.tsx +2 -1
- package/templates/react-sdk-reference/src/components/field/UserReference/UserReference.tsx +1 -1
- package/templates/react-sdk-reference/src/components/helpers/field-utils.ts +44 -0
- package/templates/react-sdk-reference/src/components/helpers/simpleTableHelpers.ts +19 -7
- package/templates/react-sdk-reference/src/components/infra/ModalViewContainer/DataViewActionButtons/DataViewActionButtons.tsx +97 -0
- package/templates/react-sdk-reference/src/components/infra/ModalViewContainer/DataViewActionButtons/index.tsx +1 -0
- package/templates/react-sdk-reference/src/components/infra/ModalViewContainer/ListViewActionButtons/ListViewActionButtons.tsx +53 -0
- package/templates/react-sdk-reference/src/components/infra/ModalViewContainer/ListViewActionButtons/index.tsx +1 -0
- package/templates/react-sdk-reference/src/components/template/AdvancedSearch/SearchGroups/SearchGroups.tsx +2 -2
- package/templates/react-sdk-reference/src/components/template/CaseSummary/CaseSummary.tsx +3 -1
- package/templates/react-sdk-reference/src/components/template/DataReference/SearchForm.tsx +4 -4
- package/templates/react-sdk-reference/src/components/template/HierarchicalForm/HierarchicalForm.tsx +2 -2
- package/templates/react-sdk-reference/src/components/template/InlineDashboard/InlineDashboard.tsx +1 -1
- package/templates/react-sdk-reference/src/components/template/ListView/ListView.tsx +7 -3
- package/templates/react-sdk-reference/src/components/template/SimpleTable/SimpleTableManual/SimpleTableManual.tsx +173 -99
- package/templates/react-sdk-reference/src/components/template/SimpleTable/SimpleTableSelect/SimpleTableSelect.tsx +63 -56
- package/templates/react-sdk-reference/src/components/widget/ToDo/ToDo.tsx +1 -1
- package/templates/react-sdk-reference/vite.config.ts +26 -4
- package/templates/angular-sdk-reference/pega-constellationjs-0.26.3-local.tgz +0 -0
- package/templates/angular-sdk-reference/src/helpers/event-utils.ts +0 -18
- package/templates/angular-sdk-reference/src/helpers/utils.ts +0 -38
- package/templates/angular-sdk-reference/src/helpers/versionHelpers.ts +0 -14
- package/templates/react-sdk-reference/.ai-common/instructions/dse-component.md +0 -47
- package/templates/react-sdk-reference/.ai-common/instructions/field-component.md +0 -50
- package/templates/react-sdk-reference/.ai-common/instructions/infra-component.md +0 -76
- package/templates/react-sdk-reference/.ai-common/instructions/template-component.md +0 -43
- package/templates/react-sdk-reference/.ai-common/instructions/widget-component.md +0 -45
- package/templates/react-sdk-reference/.ai-common/skills/embedded-flow/authenticate.md +0 -311
- package/templates/react-sdk-reference/pega-constellationjs-0.26.3-local.tgz +0 -0
- package/templates/react-sdk-reference/pega-sdk-react-0.1.0.tgz +0 -0
package/README.md
CHANGED
|
@@ -8,12 +8,21 @@ building right away.
|
|
|
8
8
|
## For AI Coding Agents
|
|
9
9
|
|
|
10
10
|
Recognize these as requests to run this CLI, whether the folder is empty or already
|
|
11
|
-
has a project in it
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
-
|
|
15
|
-
|
|
16
|
-
|
|
11
|
+
has a project in it. Users rarely use these words — judge by what they want, not
|
|
12
|
+
by how they say it:
|
|
13
|
+
|
|
14
|
+
- **They want a Pega form or workflow inside the app they already have** → run in
|
|
15
|
+
that **existing project's folder**. For example: "Scaffold `@pega/sdk` / add Pega
|
|
16
|
+
embedded flow into this repo", "add the service request form to my app when
|
|
17
|
+
someone clicks Apply", "show a Pega form inside my page", "let customers raise a
|
|
18
|
+
case from our website".
|
|
19
|
+
- **They want a new Pega app or portal** → run in an **empty folder**. For example:
|
|
20
|
+
"Scaffold a new Pega app / project using `@pega/sdk`", "start a new Pega app with
|
|
21
|
+
Chakra UI", "build me a Pega portal".
|
|
22
|
+
|
|
23
|
+
The examples are illustrations, not a complete list. Ask the user only when the
|
|
24
|
+
request is genuinely unclear — for example, they say "my app" but the folder is
|
|
25
|
+
empty.
|
|
17
26
|
|
|
18
27
|
In both cases, run `npx --yes @pega/sdk init` non-interactively — see
|
|
19
28
|
[Non-Interactive / Scripted Usage](#non-interactive--scripted-usage) below for the
|
|
@@ -36,6 +45,12 @@ about or guess:
|
|
|
36
45
|
| `--mode` (auto-detected from whether `package.json` exists in the cwd) | none — these are all optional and not needed to scaffold |
|
|
37
46
|
| `--ai-tool` (set it to yourself: GitHub Copilot → `copilot`, Cursor → `cursor`, Claude Code → `claude-code`) | |
|
|
38
47
|
| `--framework`, `--name`, `--templates`, `--categories` (infer from the request, or ask only if genuinely ambiguous) | |
|
|
48
|
+
| `--conflict-policy` (embedded mode only — see below) | |
|
|
49
|
+
|
|
50
|
+
`--conflict-policy` applies only in embedded mode and is ignored in new-project
|
|
51
|
+
mode. Leave it at `merge` (the default): it keeps the host's existing files, adds
|
|
52
|
+
Pega content inside marked blocks, and fills in missing JSON keys. Pass `override`
|
|
53
|
+
only when the user explicitly asks to replace their existing files.
|
|
39
54
|
|
|
40
55
|
Server connection details (Pega server URL, app alias, OAuth client ID, MCP rule
|
|
41
56
|
name/instance key) are never asked at scaffold time, in either mode — the scaffold
|
|
@@ -44,6 +59,31 @@ placeholder markers. An AI coding assistant gathers these from the user in chat
|
|
|
44
59
|
and fills both files in automatically the first time a workflow needs them (see
|
|
45
60
|
[Configure Your Pega Server](#configure-your-pega-server)).
|
|
46
61
|
|
|
62
|
+
### After the command finishes
|
|
63
|
+
|
|
64
|
+
When `--ai-tool` is set, the CLI prints the project folder, the agent to continue
|
|
65
|
+
with, and its files. Files written during your current turn are not in your context
|
|
66
|
+
yet, so do not carry on from memory:
|
|
67
|
+
|
|
68
|
+
| Mode | Agent | Continue when |
|
|
69
|
+
| ----------- | ------------------------- | -------------------------------------------------------------------------------------------------------------- |
|
|
70
|
+
| Embedded | **Embedded Flow Expert** | Always |
|
|
71
|
+
| New project | **Implementation Expert** | Only when the user asked for more than a new project (e.g. "…with Chakra UI"); otherwise give plain next steps |
|
|
72
|
+
|
|
73
|
+
| AI tool | Project instructions | Agent file | What to do |
|
|
74
|
+
| ----------- | --------------------------------- | -------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
75
|
+
| Copilot | `.github/copilot-instructions.md` | `.github/agents/<agent>.agent.md` | Stop. Tell the user to choose the agent in the agent menu and say "continue" |
|
|
76
|
+
| Cursor | `.cursor/rules/pega-sdk.mdrules` | `.cursor/rules/agents/<agent>.mdrules` | Stop. Tell the user to `@`-mention the agent (e.g. `@embedded-flow-expert`) in chat |
|
|
77
|
+
| Claude Code | `AGENTS.md` | `.claude/agents/<agent>.md` | Read both files, then continue the user's original request in this chat. Suggest a new session for later requests, so the project instructions load from the start |
|
|
78
|
+
|
|
79
|
+
- **Say it in plain words**, for example: "Setup is done. To continue, choose
|
|
80
|
+
**Embedded Flow Expert** in the agent menu and say 'continue'." For Copilot and
|
|
81
|
+
Cursor, repeat the user's original request so they can paste it.
|
|
82
|
+
- **New project:** the AI tools find these files only at the top of the open
|
|
83
|
+
folder, so the user must open the printed project folder first, in every tool.
|
|
84
|
+
- **No agent printed** (a framework without AI files, or `--ai-tool none`): give
|
|
85
|
+
plain next steps only.
|
|
86
|
+
|
|
47
87
|
## Requirements
|
|
48
88
|
|
|
49
89
|
- **Node.js** 20 or later
|
package/dist/index.js
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
import * as p from "@clack/prompts";
|
|
5
5
|
import pc from "picocolors";
|
|
6
6
|
import path4 from "path";
|
|
7
|
+
import fs4 from "fs";
|
|
7
8
|
import { createRequire } from "module";
|
|
8
9
|
|
|
9
10
|
// src/scaffold.ts
|
|
@@ -206,6 +207,10 @@ var DSE_COMPONENTS = [
|
|
|
206
207
|
importName: "AlertBanner",
|
|
207
208
|
importPath: "./designSystemExtension/AlertBanner"
|
|
208
209
|
},
|
|
210
|
+
{
|
|
211
|
+
importName: "AssignmentHeader",
|
|
212
|
+
importPath: "./designSystemExtension/AssignmentHeader"
|
|
213
|
+
},
|
|
209
214
|
{ importName: "Banner", importPath: "./designSystemExtension/Banner" },
|
|
210
215
|
{
|
|
211
216
|
importName: "CaseSummaryFields",
|
|
@@ -233,6 +238,7 @@ var DSE_COMPONENTS = [
|
|
|
233
238
|
importName: "RichTextEditor",
|
|
234
239
|
importPath: "./designSystemExtension/RichTextEditor"
|
|
235
240
|
},
|
|
241
|
+
{ importName: "Toast", importPath: "./designSystemExtension/Toast" },
|
|
236
242
|
{
|
|
237
243
|
importName: "WssQuickCreate",
|
|
238
244
|
importPath: "./designSystemExtension/WssQuickCreate"
|
|
@@ -762,6 +768,15 @@ var AI_GEN_CONFIGS = {
|
|
|
762
768
|
}
|
|
763
769
|
}
|
|
764
770
|
};
|
|
771
|
+
var GLOBAL_INSTRUCTIONS_PATHS = {
|
|
772
|
+
copilot: ".github/copilot-instructions.md",
|
|
773
|
+
cursor: ".cursor/rules/pega-sdk.mdrules",
|
|
774
|
+
"claude-code": "AGENTS.md"
|
|
775
|
+
};
|
|
776
|
+
function aiAgentFiles(aiTool, agent) {
|
|
777
|
+
const cfg = AI_GEN_CONFIGS[aiTool];
|
|
778
|
+
return { agentFile: `${cfg.agentsDir}/${agent}.${cfg.agentExt}`, globalFile: GLOBAL_INSTRUCTIONS_PATHS[aiTool] };
|
|
779
|
+
}
|
|
765
780
|
function parseAiMeta(content) {
|
|
766
781
|
const match = content.match(/^---\n([\s\S]*?)\n---\n\n?/);
|
|
767
782
|
if (!match) return { meta: {}, body: content };
|
|
@@ -954,21 +969,21 @@ description: "${description}"
|
|
|
954
969
|
const body = applyTokens(fs2.readFileSync(globalSrc, "utf-8"), tokens);
|
|
955
970
|
if (aiTool === "copilot") {
|
|
956
971
|
planned.push({
|
|
957
|
-
destPath: path2.join(targetDir,
|
|
972
|
+
destPath: path2.join(targetDir, GLOBAL_INSTRUCTIONS_PATHS.copilot),
|
|
958
973
|
frontmatter: "",
|
|
959
974
|
body,
|
|
960
975
|
kind: "md"
|
|
961
976
|
});
|
|
962
977
|
} else if (aiTool === "cursor") {
|
|
963
978
|
planned.push({
|
|
964
|
-
destPath: path2.join(targetDir,
|
|
979
|
+
destPath: path2.join(targetDir, GLOBAL_INSTRUCTIONS_PATHS.cursor),
|
|
965
980
|
frontmatter: "---\ndescription: Core rules for working with Pega SDK components\nalwaysApply: true\n---\n\n",
|
|
966
981
|
body,
|
|
967
982
|
kind: "md"
|
|
968
983
|
});
|
|
969
984
|
} else if (aiTool === "claude-code") {
|
|
970
985
|
planned.push({
|
|
971
|
-
destPath: path2.join(targetDir, "
|
|
986
|
+
destPath: path2.join(targetDir, GLOBAL_INSTRUCTIONS_PATHS["claude-code"]),
|
|
972
987
|
frontmatter: "",
|
|
973
988
|
body,
|
|
974
989
|
kind: "md"
|
|
@@ -1122,32 +1137,23 @@ async function scaffoldEmbedded(choices, targetDir, onProgress) {
|
|
|
1122
1137
|
`Wrote ${planned.length} file(s): ${counts.created} new, ${counts["block-replaced"]} updated, ${counts.appended} merged, ${counts.overwritten} replaced.`
|
|
1123
1138
|
);
|
|
1124
1139
|
report("Copying SDK packages\u2026");
|
|
1125
|
-
const
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
const
|
|
1129
|
-
|
|
1140
|
+
const samplePkgJson = JSON.parse(fs2.readFileSync(path2.join(sampleDir, "package.json"), "utf-8"));
|
|
1141
|
+
const pegaDependencies = {};
|
|
1142
|
+
for (const pkgName of ["@pega/auth", "@pega/constellationjs", "@pega/sdk-react", "@pega/sdk-types"]) {
|
|
1143
|
+
const spec = samplePkgJson.dependencies?.[pkgName];
|
|
1144
|
+
if (!spec) continue;
|
|
1145
|
+
pegaDependencies[pkgName] = spec;
|
|
1146
|
+
if (spec.startsWith("file:")) {
|
|
1147
|
+
const tgz = spec.slice("file:".length);
|
|
1148
|
+
fs2.copyFileSync(path2.join(sampleDir, tgz), path2.join(targetDir, tgz));
|
|
1149
|
+
}
|
|
1130
1150
|
}
|
|
1131
1151
|
report("Adding SDK dependencies\u2026");
|
|
1132
1152
|
const pkgJsonPath = path2.join(targetDir, "package.json");
|
|
1133
1153
|
if (fs2.existsSync(pkgJsonPath)) {
|
|
1134
1154
|
const pkgJson = JSON.parse(fs2.readFileSync(pkgJsonPath, "utf-8"));
|
|
1135
1155
|
if (!pkgJson.dependencies) pkgJson.dependencies = {};
|
|
1136
|
-
|
|
1137
|
-
"pega-auth": "@pega/auth",
|
|
1138
|
-
"pega-constellationjs": "@pega/constellationjs",
|
|
1139
|
-
"pega-sdk-react": "@pega/sdk-react",
|
|
1140
|
-
"pega-sdk-types": "@pega/sdk-types"
|
|
1141
|
-
};
|
|
1142
|
-
for (const tgz of tgzFiles) {
|
|
1143
|
-
const match = tgz.match(/^(pega-[\w-]+?)-\d/);
|
|
1144
|
-
if (match) {
|
|
1145
|
-
const pkgName = TGZ_PACKAGE_MAP[match[1]];
|
|
1146
|
-
if (pkgName) {
|
|
1147
|
-
pkgJson.dependencies[pkgName] = `file:${tgz}`;
|
|
1148
|
-
}
|
|
1149
|
-
}
|
|
1150
|
-
}
|
|
1156
|
+
Object.assign(pkgJson.dependencies, pegaDependencies);
|
|
1151
1157
|
fs2.writeFileSync(pkgJsonPath, JSON.stringify(pkgJson, null, 2) + "\n");
|
|
1152
1158
|
}
|
|
1153
1159
|
report("Creating SDK configuration\u2026");
|
|
@@ -1254,7 +1260,17 @@ do not need to pass --mode.
|
|
|
1254
1260
|
about. GitHub Copilot -> copilot, Cursor -> cursor, Claude Code -> claude-code.
|
|
1255
1261
|
Always pass it: it decides which agent config files get written, and a repo can
|
|
1256
1262
|
contain another assistant's config left behind by someone else.
|
|
1257
|
-
|
|
1263
|
+
|
|
1264
|
+
Users often ask in plain words ("add the service request form to my app when
|
|
1265
|
+
someone clicks Apply", "start a new Pega app") \u2014 judge by intent, not wording.
|
|
1266
|
+
|
|
1267
|
+
When it finishes, the CLI prints the agent to continue with and its files.
|
|
1268
|
+
Copilot / Cursor: stop. Tell the user, in plain words, to switch to that agent
|
|
1269
|
+
(Copilot: pick it in the agent menu; Cursor: @-mention it in chat), then
|
|
1270
|
+
repeat their original request so they can paste it.
|
|
1271
|
+
Claude Code: read the printed instructions and agent files, then continue the
|
|
1272
|
+
user's original request in this chat.
|
|
1273
|
+
New project: the user must open the printed project folder first.`.trim();
|
|
1258
1274
|
var HELP_TEXT = `
|
|
1259
1275
|
Usage: npx --yes @pega/sdk init [flags]
|
|
1260
1276
|
|
|
@@ -1423,6 +1439,14 @@ function resolveNonInteractiveEmbeddedChoices(args, cwd) {
|
|
|
1423
1439
|
// src/index.ts
|
|
1424
1440
|
var require2 = createRequire(import.meta.url);
|
|
1425
1441
|
var { version: sdkVersion } = require2("../package.json");
|
|
1442
|
+
function printAgentFiles(projectDir, aiTool, agent, agentName) {
|
|
1443
|
+
if (!aiTool) return;
|
|
1444
|
+
const { agentFile, globalFile } = aiAgentFiles(aiTool, agent);
|
|
1445
|
+
if (!fs4.existsSync(path4.join(projectDir, agentFile)) || !fs4.existsSync(path4.join(projectDir, globalFile))) return;
|
|
1446
|
+
console.log(`Project folder: ${projectDir}`);
|
|
1447
|
+
console.log(`Agent: ${agentName} \u2014 ${agentFile}`);
|
|
1448
|
+
console.log(`Project instructions: ${globalFile}`);
|
|
1449
|
+
}
|
|
1426
1450
|
async function runNonInteractive(cwd, flags) {
|
|
1427
1451
|
try {
|
|
1428
1452
|
const mode = flags.mode ?? (detectExistingProject(cwd) ? "embedded" : "new");
|
|
@@ -1438,11 +1462,13 @@ async function runNonInteractive(cwd, flags) {
|
|
|
1438
1462
|
}
|
|
1439
1463
|
await scaffoldEmbedded(choices, cwd, (message) => console.log(pc.dim(message)));
|
|
1440
1464
|
console.log(pc.green("Embedded flow ready!"));
|
|
1465
|
+
printAgentFiles(cwd, choices.aiTool, "embedded-flow-expert", "Embedded Flow Expert");
|
|
1441
1466
|
} else {
|
|
1442
1467
|
const choices = resolveNonInteractiveUserChoices(flags);
|
|
1443
1468
|
const targetDir = path4.resolve(cwd, choices.projectName);
|
|
1444
1469
|
await scaffold(choices, targetDir, (message) => console.log(pc.dim(message)));
|
|
1445
1470
|
console.log(pc.green("Project scaffolded successfully!"));
|
|
1471
|
+
printAgentFiles(targetDir, choices.aiTool, "implementation-expert", "Implementation Expert");
|
|
1446
1472
|
}
|
|
1447
1473
|
} catch (err) {
|
|
1448
1474
|
console.error(pc.red(err instanceof CliValidationError || err instanceof Error ? err.message : String(err)));
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pega/sdk",
|
|
3
|
-
"version": "0.0.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.0.15",
|
|
4
|
+
"description": "CLI to scaffold Pega SDK apps (React, Angular, Web Components) or embed Pega cases and forms into an existing app, with design-matched components and AI agent setup for Copilot, Cursor, and Claude Code",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
7
|
"sdk": "./dist/index.js"
|
|
@@ -39,7 +39,46 @@
|
|
|
39
39
|
"sdk",
|
|
40
40
|
"scaffold",
|
|
41
41
|
"cli",
|
|
42
|
-
"create-app"
|
|
42
|
+
"create-app",
|
|
43
|
+
"embed",
|
|
44
|
+
"embedded",
|
|
45
|
+
"mashup",
|
|
46
|
+
"constellation",
|
|
47
|
+
"pega-infinity",
|
|
48
|
+
"case",
|
|
49
|
+
"form",
|
|
50
|
+
"forms",
|
|
51
|
+
"workflow",
|
|
52
|
+
"ui",
|
|
53
|
+
"components",
|
|
54
|
+
"design-system",
|
|
55
|
+
"pega-sdk",
|
|
56
|
+
"pega-constellation",
|
|
57
|
+
"constellation-sdk",
|
|
58
|
+
"pega-mashup",
|
|
59
|
+
"pega-react-sdk",
|
|
60
|
+
"pega-angular-sdk",
|
|
61
|
+
"web-embed",
|
|
62
|
+
"embed-form",
|
|
63
|
+
"embed-case",
|
|
64
|
+
"case-management",
|
|
65
|
+
"workflow-automation",
|
|
66
|
+
"low-code",
|
|
67
|
+
"react",
|
|
68
|
+
"angular",
|
|
69
|
+
"web-components",
|
|
70
|
+
"react-native",
|
|
71
|
+
"typescript",
|
|
72
|
+
"vite",
|
|
73
|
+
"starter",
|
|
74
|
+
"boilerplate",
|
|
75
|
+
"template",
|
|
76
|
+
"ai-agent",
|
|
77
|
+
"copilot",
|
|
78
|
+
"cursor",
|
|
79
|
+
"claude-code",
|
|
80
|
+
"mcp",
|
|
81
|
+
"oauth"
|
|
43
82
|
],
|
|
44
83
|
"license": "Apache-2.0"
|
|
45
84
|
}
|
|
@@ -19,13 +19,12 @@
|
|
|
19
19
|
"tsConfig": "tsconfig.json",
|
|
20
20
|
"assets": ["src/assets", "src/sdk-config.json"],
|
|
21
21
|
"styles": ["src/styles.css"],
|
|
22
|
-
"scripts": [
|
|
22
|
+
"scripts": []
|
|
23
23
|
}
|
|
24
24
|
},
|
|
25
25
|
"serve": {
|
|
26
26
|
"builder": "@angular-devkit/build-angular:dev-server",
|
|
27
27
|
"options": {
|
|
28
|
-
"buildTarget": "angular-sdk-reference:build",
|
|
29
28
|
"port": 3501
|
|
30
29
|
}
|
|
31
30
|
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const CopyWebpackPlugin = require('copy-webpack-plugin');
|
|
4
|
+
|
|
5
|
+
// comment this code out, if you have an "ENOENT: no such file or directory" build error and re-build
|
|
6
|
+
// to see the real Angular errors, then uncomment onces fixed
|
|
7
|
+
module.exports = (config) => {
|
|
8
|
+
config.plugins.push(
|
|
9
|
+
new CopyWebpackPlugin({
|
|
10
|
+
patterns: [
|
|
11
|
+
{
|
|
12
|
+
from: '../../node_modules/@pega/auth/lib/oauth-client/authDone.html',
|
|
13
|
+
to: './auth.html',
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
from: '../../node_modules/@pega/auth/lib/oauth-client/authDone.js',
|
|
17
|
+
to: './',
|
|
18
|
+
},
|
|
19
|
+
],
|
|
20
|
+
}),
|
|
21
|
+
);
|
|
22
|
+
return config;
|
|
23
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8" />
|
|
5
|
+
<title>Pega SDK Angular Reference</title>
|
|
6
|
+
<base href="/" />
|
|
7
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
8
|
+
</head>
|
|
9
|
+
<body>
|
|
10
|
+
<app-root></app-root>
|
|
11
|
+
</body>
|
|
12
|
+
</html>
|
|
@@ -17,7 +17,6 @@
|
|
|
17
17
|
"@angular/platform-browser": "^21.2.0",
|
|
18
18
|
"@angular/platform-browser-dynamic": "^21.2.0",
|
|
19
19
|
"@angular/router": "^21.2.0",
|
|
20
|
-
"@pega/constellationjs": "file:pega-constellationjs-0.26.3-local.tgz",
|
|
21
20
|
"@pega/sdk-angular": "^0.1.0",
|
|
22
21
|
"rxjs": "~7.8.2",
|
|
23
22
|
"tslib": "^2.8.1",
|
|
@@ -1,72 +1,25 @@
|
|
|
1
|
-
|
|
2
|
-
* Angular Mashup sample — demonstrates @pega/sdk-core + @pega/sdk-angular
|
|
3
|
-
* in embedded/mashup mode using PegaRuntimeService.
|
|
4
|
-
*
|
|
5
|
-
* Flow:
|
|
6
|
-
* 1. PegaRuntimeService.initialize() handles auth + bootstrap
|
|
7
|
-
* 2. Subscribe to state$ for reactive isReady/isLoading/error
|
|
8
|
-
* 3. Show "Create Case" button
|
|
9
|
-
* 4. On click → PCore.getMashupApi().createCase()
|
|
10
|
-
* 5. PConnectRendererComponent renders the case form tree
|
|
11
|
-
*/
|
|
12
|
-
|
|
13
|
-
import { ChangeDetectorRef, Component, NgZone, OnInit, OnDestroy } from '@angular/core';
|
|
1
|
+
import { Component, OnInit } from '@angular/core';
|
|
14
2
|
import { CommonModule } from '@angular/common';
|
|
15
|
-
import { Subscription } from 'rxjs';
|
|
16
|
-
import { PegaRuntimeService, PConnectBridgeComponent, type RuntimeState } from '@pega/sdk-angular';
|
|
17
|
-
import { registerSampleAngularComponents } from '../components/component-map';
|
|
18
|
-
import { getSdkConfig } from '@pega/auth/lib/sdk-auth-manager';
|
|
19
|
-
import { compareSdkPCoreVersions } from '../helpers/versionHelpers';
|
|
20
3
|
|
|
21
4
|
@Component({
|
|
22
5
|
selector: 'app-root',
|
|
23
6
|
standalone: true,
|
|
24
|
-
imports: [CommonModule
|
|
7
|
+
imports: [CommonModule],
|
|
25
8
|
template: `
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
<span class="loading-text">
|
|
29
|
-
{{ errorMessage ? errorMessage : 'Authenticating and loading Pega...' }}
|
|
30
|
-
</span>
|
|
9
|
+
<div *ngIf="!isReady" class="loading-container">
|
|
10
|
+
<span class="loading-text">Authenticating and loading Pega...</span>
|
|
31
11
|
</div>
|
|
32
|
-
|
|
33
|
-
<!-- Main UI -->
|
|
34
|
-
<div *ngIf="isPegaReady" id="pega-root">
|
|
35
|
-
<!-- Header -->
|
|
12
|
+
<div *ngIf="isReady" id="pega-root">
|
|
36
13
|
<div class="header">
|
|
37
|
-
<span class="header-title">Pega SDK — Angular
|
|
38
|
-
<button type="button" class="btn-logout" (click)="logout()">Logout</button>
|
|
14
|
+
<span class="header-title">Pega SDK — Angular Reference</span>
|
|
39
15
|
</div>
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
<!-- Create Case button -->
|
|
43
|
-
<div *ngIf="!showForm" class="create-case-section">
|
|
44
|
-
<h2>Ready to go</h2>
|
|
45
|
-
<p class="subtitle">Click below to create a new case and see the Pega form components in action.</p>
|
|
46
|
-
<button type="button" class="btn-create" (click)="handleCreateCase()">Create Case</button>
|
|
47
|
-
</div>
|
|
48
|
-
|
|
49
|
-
<!-- Pega form area -->
|
|
50
|
-
<div class="form-container">
|
|
51
|
-
<div *ngIf="loading" class="loading-form">Loading case form...</div>
|
|
52
|
-
<pconnect-bridge *ngIf="!loading && rootPConnect" [getPConnect]="rootPConnectGetter!"></pconnect-bridge>
|
|
53
|
-
</div>
|
|
16
|
+
<div class="content">
|
|
17
|
+
<p>Pega SDK Angular app is ready. Implement your components here.</p>
|
|
54
18
|
</div>
|
|
55
19
|
</div>
|
|
56
20
|
`,
|
|
57
21
|
styles: [
|
|
58
22
|
`
|
|
59
|
-
.loading-container {
|
|
60
|
-
display: flex;
|
|
61
|
-
justify-content: center;
|
|
62
|
-
align-items: center;
|
|
63
|
-
height: 100vh;
|
|
64
|
-
font-family: system-ui, sans-serif;
|
|
65
|
-
}
|
|
66
|
-
.loading-text {
|
|
67
|
-
color: #64748b;
|
|
68
|
-
font-size: 1rem;
|
|
69
|
-
}
|
|
70
23
|
.header {
|
|
71
24
|
padding: 1rem 1.5rem;
|
|
72
25
|
background: #1e293b;
|
|
@@ -78,194 +31,24 @@ import { compareSdkPCoreVersions } from '../helpers/versionHelpers';
|
|
|
78
31
|
.header-title {
|
|
79
32
|
font-weight: 600;
|
|
80
33
|
}
|
|
81
|
-
.
|
|
82
|
-
background: transparent;
|
|
83
|
-
border: 1px solid #64748b;
|
|
84
|
-
color: #94a3b8;
|
|
85
|
-
padding: 0.375rem 0.75rem;
|
|
86
|
-
border-radius: 0.375rem;
|
|
87
|
-
cursor: pointer;
|
|
88
|
-
font-size: 0.8125rem;
|
|
89
|
-
}
|
|
90
|
-
.main-content {
|
|
34
|
+
.content {
|
|
91
35
|
max-width: 720px;
|
|
92
36
|
margin: 2rem auto;
|
|
93
37
|
padding: 0 1.5rem;
|
|
94
|
-
font-family: system-ui, sans-serif;
|
|
95
|
-
}
|
|
96
|
-
.create-case-section {
|
|
97
|
-
text-align: center;
|
|
98
|
-
margin-bottom: 2rem;
|
|
99
|
-
}
|
|
100
|
-
.create-case-section h2 {
|
|
101
|
-
font-size: 1.5rem;
|
|
102
|
-
font-weight: 600;
|
|
103
|
-
margin-bottom: 0.75rem;
|
|
104
|
-
}
|
|
105
|
-
.subtitle {
|
|
106
|
-
color: #64748b;
|
|
107
|
-
margin-bottom: 1.5rem;
|
|
108
|
-
}
|
|
109
|
-
.btn-create {
|
|
110
|
-
background: #2563eb;
|
|
111
|
-
color: #fff;
|
|
112
|
-
border: none;
|
|
113
|
-
padding: 0.625rem 1.5rem;
|
|
114
|
-
border-radius: 0.375rem;
|
|
115
|
-
font-size: 0.9375rem;
|
|
116
|
-
font-weight: 500;
|
|
117
|
-
cursor: pointer;
|
|
118
|
-
}
|
|
119
|
-
.form-container {
|
|
120
|
-
background: #fff;
|
|
121
|
-
border: 1px solid #e2e8f0;
|
|
122
|
-
border-radius: 0.75rem;
|
|
123
|
-
padding: 1.5rem;
|
|
124
|
-
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.04);
|
|
125
|
-
}
|
|
126
|
-
.loading-form {
|
|
127
|
-
text-align: center;
|
|
128
|
-
padding: 2rem;
|
|
129
|
-
color: #64748b;
|
|
130
38
|
}
|
|
131
39
|
`,
|
|
132
40
|
],
|
|
133
41
|
})
|
|
134
|
-
export class AppComponent implements OnInit
|
|
135
|
-
|
|
136
|
-
rootPConnect: typeof PConnect | null = null;
|
|
137
|
-
rootPConnectGetter: (() => typeof PConnect) | null = null;
|
|
138
|
-
showForm = false;
|
|
139
|
-
loading = false;
|
|
140
|
-
errorMessage: string | undefined;
|
|
141
|
-
|
|
142
|
-
private runtime = new PegaRuntimeService();
|
|
143
|
-
private stateSub: Subscription | undefined;
|
|
144
|
-
private cancelSubId = 'angularMashup-cancel';
|
|
145
|
-
private doneSubId = 'angularMashup-assignmentDone';
|
|
146
|
-
|
|
147
|
-
constructor(
|
|
148
|
-
private ngZone: NgZone,
|
|
149
|
-
private cdr: ChangeDetectorRef,
|
|
150
|
-
) {}
|
|
42
|
+
export class AppComponent implements OnInit {
|
|
43
|
+
isReady = false;
|
|
151
44
|
|
|
152
|
-
|
|
153
|
-
this.stateSub = this.runtime.state$.subscribe((state: RuntimeState) => {
|
|
154
|
-
console.log('Runtime state update:', state);
|
|
155
|
-
this.ngZone.run(() => {
|
|
156
|
-
this.isPegaReady = state.isReady;
|
|
157
|
-
this.errorMessage = state.error;
|
|
158
|
-
|
|
159
|
-
if (state.isReady && state.bootstrapResult) {
|
|
160
|
-
const rootProps = state.bootstrapResult.rootProps as Record<string, unknown> | undefined;
|
|
161
|
-
const getPConnect = rootProps?.['getPConnect'] as (() => typeof PConnect) | undefined;
|
|
162
|
-
this.rootPConnect = getPConnect?.() ?? null;
|
|
163
|
-
this.rootPConnectGetter = getPConnect ?? null;
|
|
164
|
-
this.subscribeToPubSub();
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
this.cdr.detectChanges();
|
|
168
|
-
});
|
|
169
|
-
});
|
|
170
|
-
|
|
171
|
-
this.bootstrap();
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
ngOnDestroy(): void {
|
|
175
|
-
this.stateSub?.unsubscribe();
|
|
176
|
-
|
|
177
|
-
if (this.isPegaReady) {
|
|
178
|
-
PCore.getPubSubUtils().unsubscribe(PCore.getConstants().PUB_SUB_EVENTS.EVENT_CANCEL, this.cancelSubId);
|
|
179
|
-
PCore.getPubSubUtils().unsubscribe(
|
|
180
|
-
PCore.getConstants().PUB_SUB_EVENTS.CASE_EVENTS.END_OF_ASSIGNMENT_PROCESSING,
|
|
181
|
-
this.doneSubId,
|
|
182
|
-
);
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
async bootstrap(): Promise<void> {
|
|
187
|
-
const sdkConfig = await getSdkConfig();
|
|
188
|
-
const config = sdkConfig as Record<string, Record<string, unknown>>;
|
|
189
|
-
|
|
190
|
-
await this.runtime.initialize(
|
|
191
|
-
{
|
|
192
|
-
serverConfig: {
|
|
193
|
-
infinityRestServerUrl: config['serverConfig']['infinityRestServerUrl'] as string,
|
|
194
|
-
appAlias: config['serverConfig']['appAlias'] as string,
|
|
195
|
-
},
|
|
196
|
-
authConfig: {
|
|
197
|
-
clientId: (config['authConfig']['mashupClientId'] ?? '') as string,
|
|
198
|
-
authorizeUri: (config['authConfig']['authorizeUri'] ?? '') as string,
|
|
199
|
-
tokenUri: (config['authConfig']['tokenUri'] ?? '') as string,
|
|
200
|
-
revokeUri: (config['authConfig']['revokeUri'] ?? '') as string,
|
|
201
|
-
redirectUri: (config['authConfig']['redirectUri'] ?? '') as string,
|
|
202
|
-
},
|
|
203
|
-
},
|
|
204
|
-
'pega-root',
|
|
205
|
-
{
|
|
206
|
-
onPCoreReady: () => {
|
|
207
|
-
console.log('PCore is ready, running onPCoreReady callback');
|
|
208
|
-
// Register component creator so PCore uses our bridge
|
|
209
|
-
PCore.registerComponentCreator((c11nEnv: unknown) => c11nEnv);
|
|
210
|
-
registerSampleAngularComponents();
|
|
211
|
-
compareSdkPCoreVersions();
|
|
212
|
-
|
|
213
|
-
// Initialize container session gates (required by ViewContainer/FlowContainer)
|
|
214
|
-
sessionStorage.setItem('hasViewContainer', 'false');
|
|
215
|
-
sessionStorage.setItem('okToInitFlowContainer', 'true');
|
|
216
|
-
},
|
|
217
|
-
},
|
|
218
|
-
);
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
private subscribeToPubSub(): void {
|
|
222
|
-
PCore.getPubSubUtils().subscribe(
|
|
223
|
-
PCore.getConstants().PUB_SUB_EVENTS.EVENT_CANCEL,
|
|
224
|
-
() => {
|
|
225
|
-
this.ngZone.run(() => {
|
|
226
|
-
this.showForm = false;
|
|
227
|
-
});
|
|
228
|
-
},
|
|
229
|
-
this.cancelSubId,
|
|
230
|
-
);
|
|
231
|
-
|
|
232
|
-
PCore.getPubSubUtils().subscribe(
|
|
233
|
-
PCore.getConstants().PUB_SUB_EVENTS.CASE_EVENTS.END_OF_ASSIGNMENT_PROCESSING,
|
|
234
|
-
() => {
|
|
235
|
-
this.ngZone.run(() => {
|
|
236
|
-
this.showForm = false;
|
|
237
|
-
});
|
|
238
|
-
},
|
|
239
|
-
this.doneSubId,
|
|
240
|
-
);
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
async handleCreateCase(): Promise<void> {
|
|
244
|
-
this.loading = true;
|
|
245
|
-
this.showForm = true;
|
|
45
|
+
constructor() {}
|
|
246
46
|
|
|
47
|
+
async ngOnInit() {
|
|
247
48
|
try {
|
|
248
|
-
|
|
249
|
-
const mashupCaseType = (sdkConfig as Record<string, Record<string, unknown>>).serverConfig[
|
|
250
|
-
'appMashupCaseType'
|
|
251
|
-
] as string;
|
|
252
|
-
|
|
253
|
-
await PCore.getMashupApi().createCase(mashupCaseType, PCore.getConstants().APP.APP, {
|
|
254
|
-
pageName: 'pyEmbedAssignment',
|
|
255
|
-
startingFields: {},
|
|
256
|
-
});
|
|
49
|
+
this.isReady = true;
|
|
257
50
|
} catch (err) {
|
|
258
|
-
console.error('
|
|
259
|
-
this.showForm = false;
|
|
260
|
-
} finally {
|
|
261
|
-
this.ngZone.run(() => {
|
|
262
|
-
this.loading = false;
|
|
263
|
-
this.cdr.detectChanges();
|
|
264
|
-
});
|
|
51
|
+
console.error('Failed to initialize Pega SDK:', err);
|
|
265
52
|
}
|
|
266
53
|
}
|
|
267
|
-
|
|
268
|
-
logout(): void {
|
|
269
|
-
this.runtime.authClient.logout();
|
|
270
|
-
}
|
|
271
54
|
}
|