@schandlergarcia/sf-web-components 1.9.87 → 2.0.0
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/.a4drules/features/command-center-dashboard-rule.md +1 -1
- package/.a4drules/skills/command-center-builder/SKILL.md +33 -36
- package/.a4drules/skills/command-center-builder/getting-started.md +64 -104
- package/.a4drules/skills/command-center-builder/improved-build-process.md +28 -34
- package/.a4drules/skills/command-center-guide/SKILL.md +9 -9
- package/.a4drules/skills/command-center-project/SKILL.md +4 -5
- package/.a4drules/skills/component-library/SKILL.md +8 -10
- package/.a4drules/skills/component-library/card-components.md +3 -3
- package/.a4drules/skills/component-library/chat-data.md +4 -6
- package/.a4drules/troubleshooting/codegen-overwrites-types.md +21 -162
- package/.a4drules/troubleshooting/graphql-introspection-failure.md +13 -264
- package/.a4drules/validation-requirements.md +3 -5
- package/.a4drules/webapp-data.md +1 -1
- package/CHANGELOG.md +30 -0
- package/CLAUDE.md +19 -39
- package/dist/components/library/cards/ActivityCard.js +9 -9
- package/dist/components/library/cards/ActivityCard.js.map +1 -1
- package/dist/styles/base.css +112 -27
- package/dist/styles/global.css +15 -30
- package/package.json +2 -3
- package/scripts/postinstall.mjs +39 -178
- package/scripts/reset-command-center.sh +67 -406
- package/scripts/validate-dashboard.sh +4 -4
- package/src/components/library/cards/ActivityCard.jsx +2 -2
- package/src/styles/base.css +223 -0
- package/src/styles/global.css +223 -0
- package/src/templates/config/vite.config.ts.template +0 -18
- package/.a4drules/features/engine-dashboard-rule.md +0 -63
- package/.a4drules/features/phase2-data-pattern.md +0 -15
- package/assets/images/engine_logo.png +0 -0
- package/data/README.md +0 -202
- package/data/USAGE.md +0 -81
- package/data/agentApiConfig.ts +0 -36
- package/data/copy-to-webapp.sh +0 -61
- package/data/engine-command-center-prd.md +0 -575
- package/data/engine-live-data.js +0 -135
- package/data/engine-sample-data.js +0 -378
- package/data/schema.graphql +0 -292
- package/data/useEngineLiveData.ts +0 -49
- package/data/useEvaAgent.ts +0 -288
- package/scripts/generate-schema-from-sample.mjs +0 -370
package/dist/styles/base.css
CHANGED
|
@@ -1,3 +1,25 @@
|
|
|
1
|
+
@import '@heroui/styles';
|
|
2
|
+
|
|
3
|
+
@layer base {
|
|
4
|
+
html,
|
|
5
|
+
body,
|
|
6
|
+
#root {
|
|
7
|
+
@apply min-h-screen;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
body {
|
|
11
|
+
@apply antialiased bg-white;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
@import 'tw-animate-css';
|
|
16
|
+
@import 'shadcn/tailwind.css';
|
|
17
|
+
|
|
18
|
+
@custom-variant dark (&:is(.dark *));
|
|
19
|
+
|
|
20
|
+
@source "../components/library";
|
|
21
|
+
@source "../components/pages";
|
|
22
|
+
|
|
1
23
|
@theme inline {
|
|
2
24
|
--color-background: var(--background);
|
|
3
25
|
--color-foreground: var(--foreground);
|
|
@@ -36,39 +58,26 @@
|
|
|
36
58
|
--color-sidebar-border: var(--sidebar-border);
|
|
37
59
|
--color-sidebar-ring: var(--sidebar-ring);
|
|
38
60
|
|
|
39
|
-
/*
|
|
40
|
-
--color-
|
|
41
|
-
--color-
|
|
42
|
-
--color-
|
|
43
|
-
--color-
|
|
44
|
-
--color-
|
|
45
|
-
--color-
|
|
46
|
-
--color-
|
|
47
|
-
--color-
|
|
48
|
-
--color-
|
|
49
|
-
--color-
|
|
50
|
-
--color-
|
|
51
|
-
|
|
52
|
-
/* Engine teal brand palette */
|
|
53
|
-
--color-brand-50: #ECFDF9;
|
|
54
|
-
--color-brand-100: #D1FAF0;
|
|
55
|
-
--color-brand-200: #A7F3E1;
|
|
56
|
-
--color-brand-300: #6EE7C8;
|
|
57
|
-
--color-brand-400: #34D3AB;
|
|
58
|
-
--color-brand-500: #5BC8C8;
|
|
59
|
-
--color-brand-600: #0D9488;
|
|
60
|
-
--color-brand-700: #0F766E;
|
|
61
|
-
--color-brand-800: #115E59;
|
|
62
|
-
--color-brand-900: #134E4A;
|
|
63
|
-
--color-brand-950: #042F2E;
|
|
61
|
+
/* Brand palette — customize these to match your brand */
|
|
62
|
+
--color-brand-50: #F0F9FF;
|
|
63
|
+
--color-brand-100: #E0F2FE;
|
|
64
|
+
--color-brand-200: #BAE6FD;
|
|
65
|
+
--color-brand-300: #7DD3FC;
|
|
66
|
+
--color-brand-400: #38BDF8;
|
|
67
|
+
--color-brand-500: #0EA5E9;
|
|
68
|
+
--color-brand-600: #0284C7;
|
|
69
|
+
--color-brand-700: #0369A1;
|
|
70
|
+
--color-brand-800: #075985;
|
|
71
|
+
--color-brand-900: #0C4A6E;
|
|
72
|
+
--color-brand-950: #082F49;
|
|
64
73
|
|
|
65
74
|
--font-sans: 'Inter', ui-sans-serif, system-ui, -apple-system, sans-serif;
|
|
66
75
|
--font-mono: 'JetBrains Mono', ui-monospace, monospace;
|
|
67
76
|
|
|
68
|
-
/* Engine border radius tokens */
|
|
69
77
|
--radius-pill: 9999px;
|
|
70
78
|
--radius-card: 10px;
|
|
71
79
|
}
|
|
80
|
+
|
|
72
81
|
:root {
|
|
73
82
|
--radius: 0.625rem;
|
|
74
83
|
--background: oklch(1 0 0);
|
|
@@ -103,6 +112,7 @@
|
|
|
103
112
|
--sidebar-border: oklch(0.922 0 0);
|
|
104
113
|
--sidebar-ring: oklch(0.708 0 0);
|
|
105
114
|
}
|
|
115
|
+
|
|
106
116
|
.dark {
|
|
107
117
|
--background: oklch(0.145 0 0);
|
|
108
118
|
--foreground: oklch(0.985 0 0);
|
|
@@ -135,4 +145,79 @@
|
|
|
135
145
|
--sidebar-accent-foreground: oklch(0.985 0 0);
|
|
136
146
|
--sidebar-border: oklch(1 0 0 / 10%);
|
|
137
147
|
--sidebar-ring: oklch(0.556 0 0);
|
|
138
|
-
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
@layer base {
|
|
151
|
+
* {
|
|
152
|
+
@apply border-border outline-ring/50;
|
|
153
|
+
}
|
|
154
|
+
body {
|
|
155
|
+
@apply bg-background text-foreground;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/*
|
|
160
|
+
* Restore HeroUI theme variables inside the Command Center scope.
|
|
161
|
+
* shadcn redefines --muted, --accent, --accent-foreground with different
|
|
162
|
+
* semantics (bg colors vs text colors). This scope restores HeroUI's values
|
|
163
|
+
* so HeroUI components render correctly.
|
|
164
|
+
*/
|
|
165
|
+
.heroui-scope {
|
|
166
|
+
--primary: #000000;
|
|
167
|
+
--primary-foreground: oklch(0.9911 0 0);
|
|
168
|
+
--secondary: #0EA5E9;
|
|
169
|
+
--secondary-foreground: oklch(0.9911 0 0);
|
|
170
|
+
--success: #16A34A;
|
|
171
|
+
--success-foreground: oklch(0.9911 0 0);
|
|
172
|
+
--warning: #F59E0B;
|
|
173
|
+
--warning-foreground: oklch(0.2103 0.0059 285.89);
|
|
174
|
+
--danger: #EF4444;
|
|
175
|
+
--danger-foreground: oklch(0.9911 0 0);
|
|
176
|
+
|
|
177
|
+
--muted: oklch(0.5517 0.0138 285.94);
|
|
178
|
+
--accent: oklch(0.6204 0.195 253.83);
|
|
179
|
+
--accent-foreground: oklch(0.9911 0 0);
|
|
180
|
+
--background: oklch(0.9702 0 0);
|
|
181
|
+
--foreground: oklch(0.2103 0.0059 285.89);
|
|
182
|
+
--default: oklch(94% 0.001 286.375);
|
|
183
|
+
--default-foreground: oklch(0.2103 0.0059 285.89);
|
|
184
|
+
--border: oklch(90% 0.004 286.32);
|
|
185
|
+
--separator: oklch(92% 0.004 286.32);
|
|
186
|
+
--segment: oklch(100% 0 0);
|
|
187
|
+
--segment-foreground: oklch(0.2103 0.0059 285.89);
|
|
188
|
+
--surface: oklch(100% 0 0);
|
|
189
|
+
--surface-foreground: oklch(0.2103 0.0059 285.89);
|
|
190
|
+
--overlay: oklch(100% 0 0);
|
|
191
|
+
--overlay-foreground: oklch(0.2103 0.0059 285.89);
|
|
192
|
+
--focus: oklch(0.6204 0.195 253.83);
|
|
193
|
+
--link: oklch(0.2103 0.0059 285.89);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/* ChatBar expanded overlay — horizontal padding so it doesn't hit window edges */
|
|
197
|
+
body > .fixed.inset-x-0.rounded-2xl {
|
|
198
|
+
left: 1.5rem !important;
|
|
199
|
+
right: 1.5rem !important;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
.dark .heroui-scope,
|
|
203
|
+
.heroui-scope.dark {
|
|
204
|
+
--muted: oklch(70.5% 0.015 286.067);
|
|
205
|
+
--background: oklch(12% 0.005 285.823);
|
|
206
|
+
--foreground: oklch(0.9911 0 0);
|
|
207
|
+
--default: oklch(27.4% 0.006 286.033);
|
|
208
|
+
--default-foreground: oklch(0.9911 0 0);
|
|
209
|
+
--border: oklch(28% 0.006 286.033);
|
|
210
|
+
--separator: oklch(25% 0.006 286.033);
|
|
211
|
+
--segment: oklch(0.3964 0.01 285.93);
|
|
212
|
+
--segment-foreground: oklch(0.9911 0 0);
|
|
213
|
+
--surface: oklch(0.2103 0.0059 285.89);
|
|
214
|
+
--surface-foreground: oklch(0.9911 0 0);
|
|
215
|
+
--overlay: oklch(0.2103 0.0059 285.89);
|
|
216
|
+
--overlay-foreground: oklch(0.9911 0 0);
|
|
217
|
+
--warning: oklch(0.8203 0.1388 76.34);
|
|
218
|
+
--warning-foreground: oklch(0.2103 0.0059 285.89);
|
|
219
|
+
--danger: oklch(0.594 0.1967 24.63);
|
|
220
|
+
--danger-foreground: oklch(0.9911 0 0);
|
|
221
|
+
--focus: oklch(0.6204 0.195 253.83);
|
|
222
|
+
--link: oklch(0.9911 0 0);
|
|
223
|
+
}
|
package/dist/styles/global.css
CHANGED
|
@@ -58,36 +58,22 @@
|
|
|
58
58
|
--color-sidebar-border: var(--sidebar-border);
|
|
59
59
|
--color-sidebar-ring: var(--sidebar-ring);
|
|
60
60
|
|
|
61
|
-
/*
|
|
62
|
-
--color-
|
|
63
|
-
--color-
|
|
64
|
-
--color-
|
|
65
|
-
--color-
|
|
66
|
-
--color-
|
|
67
|
-
--color-
|
|
68
|
-
--color-
|
|
69
|
-
--color-
|
|
70
|
-
--color-
|
|
71
|
-
--color-
|
|
72
|
-
--color-
|
|
73
|
-
|
|
74
|
-
/* Engine teal brand palette */
|
|
75
|
-
--color-brand-50: #ECFDF9;
|
|
76
|
-
--color-brand-100: #D1FAF0;
|
|
77
|
-
--color-brand-200: #A7F3E1;
|
|
78
|
-
--color-brand-300: #6EE7C8;
|
|
79
|
-
--color-brand-400: #34D3AB;
|
|
80
|
-
--color-brand-500: #5BC8C8;
|
|
81
|
-
--color-brand-600: #0D9488;
|
|
82
|
-
--color-brand-700: #0F766E;
|
|
83
|
-
--color-brand-800: #115E59;
|
|
84
|
-
--color-brand-900: #134E4A;
|
|
85
|
-
--color-brand-950: #042F2E;
|
|
61
|
+
/* Brand palette — customize these to match your brand */
|
|
62
|
+
--color-brand-50: #F0F9FF;
|
|
63
|
+
--color-brand-100: #E0F2FE;
|
|
64
|
+
--color-brand-200: #BAE6FD;
|
|
65
|
+
--color-brand-300: #7DD3FC;
|
|
66
|
+
--color-brand-400: #38BDF8;
|
|
67
|
+
--color-brand-500: #0EA5E9;
|
|
68
|
+
--color-brand-600: #0284C7;
|
|
69
|
+
--color-brand-700: #0369A1;
|
|
70
|
+
--color-brand-800: #075985;
|
|
71
|
+
--color-brand-900: #0C4A6E;
|
|
72
|
+
--color-brand-950: #082F49;
|
|
86
73
|
|
|
87
74
|
--font-sans: 'Inter', ui-sans-serif, system-ui, -apple-system, sans-serif;
|
|
88
75
|
--font-mono: 'JetBrains Mono', ui-monospace, monospace;
|
|
89
76
|
|
|
90
|
-
/* Engine border radius tokens */
|
|
91
77
|
--radius-pill: 9999px;
|
|
92
78
|
--radius-card: 10px;
|
|
93
79
|
}
|
|
@@ -177,16 +163,15 @@
|
|
|
177
163
|
* so HeroUI components render correctly.
|
|
178
164
|
*/
|
|
179
165
|
.heroui-scope {
|
|
180
|
-
/* Engine HeroUI theme overrides */
|
|
181
166
|
--primary: #000000;
|
|
182
167
|
--primary-foreground: oklch(0.9911 0 0);
|
|
183
|
-
--secondary: #
|
|
184
|
-
--secondary-foreground: oklch(0.
|
|
168
|
+
--secondary: #0EA5E9;
|
|
169
|
+
--secondary-foreground: oklch(0.9911 0 0);
|
|
185
170
|
--success: #16A34A;
|
|
186
171
|
--success-foreground: oklch(0.9911 0 0);
|
|
187
172
|
--warning: #F59E0B;
|
|
188
173
|
--warning-foreground: oklch(0.2103 0.0059 285.89);
|
|
189
|
-
--danger: #
|
|
174
|
+
--danger: #EF4444;
|
|
190
175
|
--danger-foreground: oklch(0.9911 0 0);
|
|
191
176
|
|
|
192
177
|
--muted: oklch(0.5517 0.0138 285.94);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@schandlergarcia/sf-web-components",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "Reusable Salesforce web components library with Tailwind CSS v4 and shadcn/ui",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -27,11 +27,10 @@
|
|
|
27
27
|
"files": [
|
|
28
28
|
"dist",
|
|
29
29
|
"scripts",
|
|
30
|
-
"data",
|
|
31
|
-
"assets",
|
|
32
30
|
"src/templates",
|
|
33
31
|
"src/components",
|
|
34
32
|
"src/lib",
|
|
33
|
+
"src/styles",
|
|
35
34
|
"src/types",
|
|
36
35
|
"README.md",
|
|
37
36
|
"INSTALL.md",
|
package/scripts/postinstall.mjs
CHANGED
|
@@ -227,174 +227,29 @@ if (fs.existsSync(templatesDir)) {
|
|
|
227
227
|
}
|
|
228
228
|
}
|
|
229
229
|
|
|
230
|
-
// Copy
|
|
231
|
-
const dataSourceDir = path.join(packageRoot, 'data');
|
|
232
|
-
const targetDataDir = path.join(cwd, 'src/data');
|
|
233
|
-
|
|
234
|
-
console.log('\n📊 Installing sample data files...\n');
|
|
235
|
-
|
|
236
|
-
let dataFilesInstalled = 0;
|
|
237
|
-
|
|
238
|
-
if (fs.existsSync(dataSourceDir)) {
|
|
239
|
-
// Create target data directory if it doesn't exist
|
|
240
|
-
if (!fs.existsSync(targetDataDir)) {
|
|
241
|
-
fs.mkdirSync(targetDataDir, { recursive: true });
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
// Copy engine-sample-data.js
|
|
245
|
-
const engineDataSource = path.join(dataSourceDir, 'engine-sample-data.js');
|
|
246
|
-
const engineDataTarget = path.join(targetDataDir, 'engine-sample-data.js');
|
|
247
|
-
|
|
248
|
-
if (fs.existsSync(engineDataSource)) {
|
|
249
|
-
try {
|
|
250
|
-
fs.copyFileSync(engineDataSource, engineDataTarget);
|
|
251
|
-
console.log(' ✓ Installed engine-sample-data.js');
|
|
252
|
-
dataFilesInstalled++;
|
|
253
|
-
} catch (error) {
|
|
254
|
-
console.error(` ✗ Failed to install engine-sample-data.js: ${error.message}`);
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
// Copy schema.graphql
|
|
259
|
-
const schemaSource = path.join(dataSourceDir, 'schema.graphql');
|
|
260
|
-
const schemaTarget = path.join(cwd, 'schema.graphql');
|
|
261
|
-
|
|
262
|
-
if (fs.existsSync(schemaSource)) {
|
|
263
|
-
try {
|
|
264
|
-
fs.copyFileSync(schemaSource, schemaTarget);
|
|
265
|
-
console.log(' ✓ Installed schema.graphql (pre-built from sample data)');
|
|
266
|
-
dataFilesInstalled++;
|
|
267
|
-
} catch (error) {
|
|
268
|
-
console.error(` ✗ Failed to install schema.graphql: ${error.message}`);
|
|
269
|
-
}
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
// Copy engine-command-center-prd.md
|
|
273
|
-
const prdSource = path.join(dataSourceDir, 'engine-command-center-prd.md');
|
|
274
|
-
const prdTarget = path.join(cwd, 'engine-command-center-prd.md');
|
|
275
|
-
|
|
276
|
-
if (fs.existsSync(prdSource)) {
|
|
277
|
-
try {
|
|
278
|
-
fs.copyFileSync(prdSource, prdTarget);
|
|
279
|
-
console.log(' ✓ Installed engine-command-center-prd.md');
|
|
280
|
-
dataFilesInstalled++;
|
|
281
|
-
} catch (error) {
|
|
282
|
-
console.error(` ✗ Failed to install engine-command-center-prd.md: ${error.message}`);
|
|
283
|
-
}
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
// Copy engine-live-data.js
|
|
287
|
-
const engineLiveDataSource = path.join(dataSourceDir, 'engine-live-data.js');
|
|
288
|
-
const engineLiveDataTarget = path.join(targetDataDir, 'engine-live-data.js');
|
|
289
|
-
|
|
290
|
-
if (fs.existsSync(engineLiveDataSource)) {
|
|
291
|
-
try {
|
|
292
|
-
fs.copyFileSync(engineLiveDataSource, engineLiveDataTarget);
|
|
293
|
-
console.log(' ✓ Installed engine-live-data.js');
|
|
294
|
-
dataFilesInstalled++;
|
|
295
|
-
} catch (error) {
|
|
296
|
-
console.error(` ✗ Failed to install engine-live-data.js: ${error.message}`);
|
|
297
|
-
}
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
// Copy useEngineLiveData.ts
|
|
301
|
-
const targetHooksDir = path.join(cwd, 'src/hooks');
|
|
302
|
-
const useEngineLiveDataSource = path.join(dataSourceDir, 'useEngineLiveData.ts');
|
|
303
|
-
const useEngineLiveDataTarget = path.join(targetHooksDir, 'useEngineLiveData.ts');
|
|
304
|
-
|
|
305
|
-
if (fs.existsSync(useEngineLiveDataSource)) {
|
|
306
|
-
try {
|
|
307
|
-
if (!fs.existsSync(targetHooksDir)) {
|
|
308
|
-
fs.mkdirSync(targetHooksDir, { recursive: true });
|
|
309
|
-
}
|
|
310
|
-
fs.copyFileSync(useEngineLiveDataSource, useEngineLiveDataTarget);
|
|
311
|
-
console.log(' ✓ Installed useEngineLiveData.ts');
|
|
312
|
-
dataFilesInstalled++;
|
|
313
|
-
} catch (error) {
|
|
314
|
-
console.error(` ✗ Failed to install useEngineLiveData.ts: ${error.message}`);
|
|
315
|
-
}
|
|
316
|
-
}
|
|
317
|
-
|
|
318
|
-
// Copy useEvaAgent.ts (Agentforce Agent API hook)
|
|
319
|
-
const useEvaAgentSource = path.join(dataSourceDir, 'useEvaAgent.ts');
|
|
320
|
-
const useEvaAgentTarget = path.join(targetHooksDir, 'useEvaAgent.ts');
|
|
321
|
-
|
|
322
|
-
if (fs.existsSync(useEvaAgentSource)) {
|
|
323
|
-
try {
|
|
324
|
-
if (!fs.existsSync(targetHooksDir)) {
|
|
325
|
-
fs.mkdirSync(targetHooksDir, { recursive: true });
|
|
326
|
-
}
|
|
327
|
-
fs.copyFileSync(useEvaAgentSource, useEvaAgentTarget);
|
|
328
|
-
console.log(' ✓ Installed useEvaAgent.ts');
|
|
329
|
-
dataFilesInstalled++;
|
|
330
|
-
} catch (error) {
|
|
331
|
-
console.error(` ✗ Failed to install useEvaAgent.ts: ${error.message}`);
|
|
332
|
-
}
|
|
333
|
-
}
|
|
334
|
-
|
|
335
|
-
// Copy agentApiConfig.ts → src/config/agentApi.ts
|
|
336
|
-
const agentApiConfigSource = path.join(dataSourceDir, 'agentApiConfig.ts');
|
|
337
|
-
const targetConfigDir = path.join(cwd, 'src/config');
|
|
338
|
-
const agentApiConfigTarget = path.join(targetConfigDir, 'agentApi.ts');
|
|
339
|
-
|
|
340
|
-
if (fs.existsSync(agentApiConfigSource)) {
|
|
341
|
-
try {
|
|
342
|
-
if (!fs.existsSync(targetConfigDir)) {
|
|
343
|
-
fs.mkdirSync(targetConfigDir, { recursive: true });
|
|
344
|
-
}
|
|
345
|
-
fs.copyFileSync(agentApiConfigSource, agentApiConfigTarget);
|
|
346
|
-
console.log(' ✓ Installed src/config/agentApi.ts');
|
|
347
|
-
dataFilesInstalled++;
|
|
348
|
-
} catch (error) {
|
|
349
|
-
console.error(` ✗ Failed to install agentApiConfig.ts: ${error.message}`);
|
|
350
|
-
}
|
|
351
|
-
}
|
|
352
|
-
|
|
353
|
-
// Copy engine_logo.png
|
|
354
|
-
const assetsSourceDir = path.join(packageRoot, 'assets/images');
|
|
355
|
-
const targetAssetsDir = path.join(cwd, 'src/assets/images');
|
|
356
|
-
const engineLogoSource = path.join(assetsSourceDir, 'engine_logo.png');
|
|
357
|
-
const engineLogoTarget = path.join(targetAssetsDir, 'engine_logo.png');
|
|
358
|
-
|
|
359
|
-
if (fs.existsSync(engineLogoSource)) {
|
|
360
|
-
try {
|
|
361
|
-
if (!fs.existsSync(targetAssetsDir)) {
|
|
362
|
-
fs.mkdirSync(targetAssetsDir, { recursive: true });
|
|
363
|
-
}
|
|
364
|
-
fs.copyFileSync(engineLogoSource, engineLogoTarget);
|
|
365
|
-
console.log(' ✓ Installed engine_logo.png');
|
|
366
|
-
dataFilesInstalled++;
|
|
367
|
-
} catch (error) {
|
|
368
|
-
console.error(` ✗ Failed to install engine_logo.png: ${error.message}`);
|
|
369
|
-
}
|
|
370
|
-
}
|
|
371
|
-
}
|
|
372
|
-
|
|
373
|
-
// Copy GraphQL schema generator script
|
|
230
|
+
// Copy GraphQL introspection script (generic — works with any Salesforce org)
|
|
374
231
|
const scriptsSourceDir = path.join(packageRoot, 'scripts');
|
|
375
232
|
const targetScriptsDir = path.join(cwd, 'scripts');
|
|
376
233
|
|
|
377
|
-
console.log('\n📝 Installing
|
|
234
|
+
console.log('\n📝 Installing utility scripts...\n');
|
|
378
235
|
|
|
379
236
|
let scriptsInstalled = 0;
|
|
380
237
|
|
|
381
238
|
if (fs.existsSync(scriptsSourceDir)) {
|
|
382
|
-
// Create target scripts directory if it doesn't exist
|
|
383
239
|
if (!fs.existsSync(targetScriptsDir)) {
|
|
384
240
|
fs.mkdirSync(targetScriptsDir, { recursive: true });
|
|
385
241
|
}
|
|
386
242
|
|
|
387
|
-
|
|
388
|
-
const
|
|
389
|
-
const generatorTarget = path.join(targetScriptsDir, 'generate-schema-from-sample.mjs');
|
|
243
|
+
const getSchemaSource = path.join(scriptsSourceDir, 'get-graphql-schema.mjs');
|
|
244
|
+
const getSchemaTarget = path.join(targetScriptsDir, 'get-graphql-schema.mjs');
|
|
390
245
|
|
|
391
|
-
if (fs.existsSync(
|
|
246
|
+
if (fs.existsSync(getSchemaSource)) {
|
|
392
247
|
try {
|
|
393
|
-
fs.copyFileSync(
|
|
394
|
-
console.log(' ✓ Installed
|
|
248
|
+
fs.copyFileSync(getSchemaSource, getSchemaTarget);
|
|
249
|
+
console.log(' ✓ Installed get-graphql-schema.mjs');
|
|
395
250
|
scriptsInstalled++;
|
|
396
251
|
} catch (error) {
|
|
397
|
-
console.error(` ✗ Failed to install
|
|
252
|
+
console.error(` ✗ Failed to install get-graphql-schema.mjs: ${error.message}`);
|
|
398
253
|
}
|
|
399
254
|
}
|
|
400
255
|
}
|
|
@@ -480,12 +335,6 @@ if (fs.existsSync(packageJsonPath)) {
|
|
|
480
335
|
scriptsAdded.push('validate:dashboard');
|
|
481
336
|
}
|
|
482
337
|
|
|
483
|
-
// Add the graphql:schema:sample script if it doesn't exist
|
|
484
|
-
if (!packageJson.scripts['graphql:schema:sample']) {
|
|
485
|
-
packageJson.scripts['graphql:schema:sample'] = 'node scripts/generate-schema-from-sample.mjs';
|
|
486
|
-
scriptsAdded.push('graphql:schema:sample');
|
|
487
|
-
}
|
|
488
|
-
|
|
489
338
|
if (scriptsAdded.length > 0) {
|
|
490
339
|
fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2) + '\n', 'utf-8');
|
|
491
340
|
scriptsAdded.forEach(script => {
|
|
@@ -501,35 +350,48 @@ if (fs.existsSync(packageJsonPath)) {
|
|
|
501
350
|
|
|
502
351
|
// Copy .a4drules from package to project root (so AI assistants can discover them)
|
|
503
352
|
const packageA4dRules = path.join(packageRoot, '.a4drules');
|
|
504
|
-
const projectRootA4dRules = path.join(cwd, '../../../../../.a4drules'); // Go up from webapp to project root
|
|
505
353
|
|
|
506
354
|
if (fs.existsSync(packageA4dRules)) {
|
|
507
355
|
console.log('\n📋 Copying AI assistant rules to project root...\n');
|
|
508
356
|
|
|
509
|
-
// Resolve to absolute path
|
|
510
357
|
const projectRootPath = path.resolve(cwd, '../../../../../');
|
|
511
358
|
const targetA4dRules = path.join(projectRootPath, '.a4drules');
|
|
512
359
|
|
|
513
|
-
// Create .a4drules if it doesn't exist
|
|
514
360
|
if (!fs.existsSync(targetA4dRules)) {
|
|
515
361
|
fs.mkdirSync(targetA4dRules, { recursive: true });
|
|
516
362
|
}
|
|
517
363
|
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
364
|
+
let totalA4dCopied = 0;
|
|
365
|
+
|
|
366
|
+
// Force-copy root-level .md files first
|
|
367
|
+
const rootFiles = fs.readdirSync(packageA4dRules).filter(f => f.endsWith('.md'));
|
|
368
|
+
for (const file of rootFiles) {
|
|
369
|
+
try {
|
|
370
|
+
fs.copyFileSync(path.join(packageA4dRules, file), path.join(targetA4dRules, file));
|
|
371
|
+
totalA4dCopied++;
|
|
372
|
+
} catch (error) {
|
|
373
|
+
console.error(` ✗ Failed to copy ${file}: ${error.message}`);
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
if (rootFiles.length > 0) {
|
|
377
|
+
console.log(` ✓ Copied ${rootFiles.length} root rule files`);
|
|
524
378
|
}
|
|
525
379
|
|
|
526
|
-
// Copy features
|
|
527
|
-
const
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
380
|
+
// Copy all subdirectories (skills, features, troubleshooting)
|
|
381
|
+
const subdirs = fs.readdirSync(packageA4dRules).filter(d => {
|
|
382
|
+
const full = path.join(packageA4dRules, d);
|
|
383
|
+
return fs.statSync(full).isDirectory();
|
|
384
|
+
});
|
|
385
|
+
|
|
386
|
+
for (const subdir of subdirs) {
|
|
387
|
+
const src = path.join(packageA4dRules, subdir);
|
|
388
|
+
const dst = path.join(targetA4dRules, subdir);
|
|
389
|
+
const copied = copyDirectoryRecursive(src, dst);
|
|
390
|
+
totalA4dCopied += copied;
|
|
391
|
+
console.log(` ✓ Copied ${copied} files from ${subdir}/`);
|
|
532
392
|
}
|
|
393
|
+
|
|
394
|
+
console.log(` 📋 Total: ${totalA4dCopied} rule files installed`);
|
|
533
395
|
}
|
|
534
396
|
|
|
535
397
|
// Migrate any dashboards from old location (src/components/pages/) to new location (src/pages/)
|
|
@@ -575,13 +437,12 @@ if (fs.existsSync(oldPagesDir)) {
|
|
|
575
437
|
|
|
576
438
|
console.log('\n📊 Summary:');
|
|
577
439
|
console.log(` - Copied ${componentsCopied} UI components`);
|
|
578
|
-
console.log(` - Updated ${filesUpdated}
|
|
440
|
+
console.log(` - Updated ${filesUpdated} import references`);
|
|
579
441
|
console.log(` - Installed ${templatesInstalled} page templates`);
|
|
580
|
-
console.log(` - Installed ${
|
|
581
|
-
console.log(` - Installed ${scriptsInstalled} GraphQL scripts`);
|
|
442
|
+
console.log(` - Installed ${scriptsInstalled} utility scripts`);
|
|
582
443
|
console.log(` - Installed CommandCenter.tsx for dashboard management`);
|
|
583
444
|
console.log(` - Added "npm run reset:command-center" script`);
|
|
584
|
-
console.log(` - Installed AI assistant rules
|
|
445
|
+
console.log(` - Installed AI assistant rules (.a4drules)`);
|
|
585
446
|
if (migratedFiles > 0) {
|
|
586
447
|
console.log(` - Migrated ${migratedFiles} dashboard files to correct location`);
|
|
587
448
|
}
|