@schandlergarcia/sf-web-components 1.9.88 → 2.1.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 +33 -0
- package/CLAUDE.md +42 -39
- package/brands/engine/brand.css +40 -0
- package/brands/engine/global.css +234 -0
- 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 +7 -4
- package/scripts/apply-brand.mjs +178 -0
- package/scripts/postinstall.mjs +24 -201
- package/scripts/reset-command-center.sh +53 -411
- 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/data/README.md +0 -202
- package/data/USAGE.md +0 -81
- package/data/copy-to-webapp.sh +0 -61
- package/scripts/generate-schema-from-sample.mjs +0 -370
- /package/{data → brands/engine}/agentApiConfig.ts +0 -0
- /package/{data → brands/engine}/engine-command-center-prd.md +0 -0
- /package/{data → brands/engine}/engine-live-data.js +0 -0
- /package/{data → brands/engine}/engine-sample-data.js +0 -0
- /package/{assets/images → brands/engine}/engine_logo.png +0 -0
- /package/{data → brands/engine}/schema.graphql +0 -0
- /package/{data → brands/engine}/useEngineLiveData.ts +0 -0
- /package/{data → brands/engine}/useEvaAgent.ts +0 -0
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* apply-brand.mjs — Apply a brand theme to the project.
|
|
5
|
+
*
|
|
6
|
+
* Usage:
|
|
7
|
+
* node scripts/apply-brand.mjs engine # Apply Engine brand
|
|
8
|
+
* node scripts/apply-brand.mjs --list # List available brands
|
|
9
|
+
* node scripts/apply-brand.mjs --reset # Remove brand, restore neutral theme
|
|
10
|
+
*
|
|
11
|
+
* When run from a consuming project (via npm run brand:engine), the script
|
|
12
|
+
* detects the package location automatically.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import fs from 'fs';
|
|
16
|
+
import path from 'path';
|
|
17
|
+
import { fileURLToPath } from 'url';
|
|
18
|
+
|
|
19
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
20
|
+
const __dirname = path.dirname(__filename);
|
|
21
|
+
|
|
22
|
+
const arg = process.argv[2];
|
|
23
|
+
|
|
24
|
+
if (!arg) {
|
|
25
|
+
console.error('Usage: node scripts/apply-brand.mjs <brand-name|--list|--reset>');
|
|
26
|
+
process.exit(1);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const cwd = process.cwd();
|
|
30
|
+
const PACKAGE_NAME = '@schandlergarcia/sf-web-components';
|
|
31
|
+
|
|
32
|
+
function findPackageRoot() {
|
|
33
|
+
const fromNodeModules = path.join(cwd, 'node_modules', PACKAGE_NAME);
|
|
34
|
+
if (fs.existsSync(fromNodeModules)) return fromNodeModules;
|
|
35
|
+
|
|
36
|
+
const fromScript = path.resolve(__dirname, '..');
|
|
37
|
+
if (fs.existsSync(path.join(fromScript, 'brands'))) return fromScript;
|
|
38
|
+
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const packageRoot = findPackageRoot();
|
|
43
|
+
if (!packageRoot) {
|
|
44
|
+
console.error('Could not find package root. Run from the project directory.');
|
|
45
|
+
process.exit(1);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const brandsDir = path.join(packageRoot, 'brands');
|
|
49
|
+
|
|
50
|
+
if (arg === '--list') {
|
|
51
|
+
if (!fs.existsSync(brandsDir)) {
|
|
52
|
+
console.log('No brands available.');
|
|
53
|
+
process.exit(0);
|
|
54
|
+
}
|
|
55
|
+
const brands = fs.readdirSync(brandsDir).filter(d =>
|
|
56
|
+
fs.statSync(path.join(brandsDir, d)).isDirectory()
|
|
57
|
+
);
|
|
58
|
+
console.log(`Available brands: ${brands.join(', ') || '(none)'}`);
|
|
59
|
+
process.exit(0);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
if (arg === '--reset') {
|
|
63
|
+
const neutralCSS = path.join(packageRoot, 'src/styles/global.css');
|
|
64
|
+
const targetCSS = path.join(cwd, 'src/styles/global.css');
|
|
65
|
+
if (fs.existsSync(neutralCSS)) {
|
|
66
|
+
fs.copyFileSync(neutralCSS, targetCSS);
|
|
67
|
+
console.log(' ✓ Restored neutral theme (global.css)');
|
|
68
|
+
}
|
|
69
|
+
const brandMarker = path.join(cwd, '.brand');
|
|
70
|
+
if (fs.existsSync(brandMarker)) fs.unlinkSync(brandMarker);
|
|
71
|
+
console.log('\n✅ Brand reset to neutral.\n');
|
|
72
|
+
process.exit(0);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const brandName = arg;
|
|
76
|
+
const brandDir = path.join(brandsDir, brandName);
|
|
77
|
+
|
|
78
|
+
if (!fs.existsSync(brandDir)) {
|
|
79
|
+
console.error(`Brand "${brandName}" not found in ${brandsDir}`);
|
|
80
|
+
const available = fs.existsSync(brandsDir)
|
|
81
|
+
? fs.readdirSync(brandsDir).filter(d => fs.statSync(path.join(brandsDir, d)).isDirectory())
|
|
82
|
+
: [];
|
|
83
|
+
if (available.length) console.error(`Available: ${available.join(', ')}`);
|
|
84
|
+
process.exit(1);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
console.log(`\n🎨 Applying "${brandName}" brand...\n`);
|
|
88
|
+
|
|
89
|
+
let installed = 0;
|
|
90
|
+
|
|
91
|
+
// 1. global.css → src/styles/global.css (always overwrite)
|
|
92
|
+
const brandCSS = path.join(brandDir, 'global.css');
|
|
93
|
+
const targetCSS = path.join(cwd, 'src/styles/global.css');
|
|
94
|
+
if (fs.existsSync(brandCSS)) {
|
|
95
|
+
fs.mkdirSync(path.dirname(targetCSS), { recursive: true });
|
|
96
|
+
fs.copyFileSync(brandCSS, targetCSS);
|
|
97
|
+
console.log(' ✓ Brand theme applied (global.css)');
|
|
98
|
+
installed++;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// 2. Sample data files → src/data/
|
|
102
|
+
const dataFiles = [
|
|
103
|
+
{ src: 'engine-sample-data.js', dst: 'src/data/engine-sample-data.js' },
|
|
104
|
+
{ src: 'engine-live-data.js', dst: 'src/data/engine-live-data.js' },
|
|
105
|
+
];
|
|
106
|
+
for (const { src, dst } of dataFiles) {
|
|
107
|
+
const srcPath = path.join(brandDir, src);
|
|
108
|
+
const dstPath = path.join(cwd, dst);
|
|
109
|
+
if (fs.existsSync(srcPath)) {
|
|
110
|
+
fs.mkdirSync(path.dirname(dstPath), { recursive: true });
|
|
111
|
+
fs.copyFileSync(srcPath, dstPath);
|
|
112
|
+
console.log(` ✓ Installed ${dst}`);
|
|
113
|
+
installed++;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// 3. Hooks → src/hooks/
|
|
118
|
+
const hooks = [
|
|
119
|
+
{ src: 'useEngineLiveData.ts', dst: 'src/hooks/useEngineLiveData.ts' },
|
|
120
|
+
{ src: 'useEvaAgent.ts', dst: 'src/hooks/useEvaAgent.ts' },
|
|
121
|
+
];
|
|
122
|
+
for (const { src, dst } of hooks) {
|
|
123
|
+
const srcPath = path.join(brandDir, src);
|
|
124
|
+
const dstPath = path.join(cwd, dst);
|
|
125
|
+
if (fs.existsSync(srcPath)) {
|
|
126
|
+
fs.mkdirSync(path.dirname(dstPath), { recursive: true });
|
|
127
|
+
fs.copyFileSync(srcPath, dstPath);
|
|
128
|
+
console.log(` ✓ Installed ${dst}`);
|
|
129
|
+
installed++;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// 4. Config files → src/config/
|
|
134
|
+
const configs = [
|
|
135
|
+
{ src: 'agentApiConfig.ts', dst: 'src/config/agentApi.ts' },
|
|
136
|
+
];
|
|
137
|
+
for (const { src, dst } of configs) {
|
|
138
|
+
const srcPath = path.join(brandDir, src);
|
|
139
|
+
const dstPath = path.join(cwd, dst);
|
|
140
|
+
if (fs.existsSync(srcPath)) {
|
|
141
|
+
fs.mkdirSync(path.dirname(dstPath), { recursive: true });
|
|
142
|
+
fs.copyFileSync(srcPath, dstPath);
|
|
143
|
+
console.log(` ✓ Installed ${dst}`);
|
|
144
|
+
installed++;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// 5. PRD → project root
|
|
149
|
+
const prd = path.join(brandDir, 'engine-command-center-prd.md');
|
|
150
|
+
if (fs.existsSync(prd)) {
|
|
151
|
+
fs.copyFileSync(prd, path.join(cwd, 'engine-command-center-prd.md'));
|
|
152
|
+
console.log(' ✓ Installed engine-command-center-prd.md');
|
|
153
|
+
installed++;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// 6. Schema → project root
|
|
157
|
+
const schema = path.join(brandDir, 'schema.graphql');
|
|
158
|
+
if (fs.existsSync(schema)) {
|
|
159
|
+
fs.copyFileSync(schema, path.join(cwd, 'schema.graphql'));
|
|
160
|
+
console.log(' ✓ Installed schema.graphql');
|
|
161
|
+
installed++;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// 7. Logo → src/assets/images/
|
|
165
|
+
const logo = path.join(brandDir, 'engine_logo.png');
|
|
166
|
+
if (fs.existsSync(logo)) {
|
|
167
|
+
const logoTarget = path.join(cwd, 'src/assets/images/engine_logo.png');
|
|
168
|
+
fs.mkdirSync(path.dirname(logoTarget), { recursive: true });
|
|
169
|
+
fs.copyFileSync(logo, logoTarget);
|
|
170
|
+
console.log(' ✓ Installed engine_logo.png');
|
|
171
|
+
installed++;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// 8. Write .brand marker so reset script knows which brand is active
|
|
175
|
+
fs.writeFileSync(path.join(cwd, '.brand'), brandName + '\n', 'utf-8');
|
|
176
|
+
|
|
177
|
+
console.log(`\n✅ "${brandName}" brand applied (${installed} files installed).`);
|
|
178
|
+
console.log(' Run "npm run brand:reset" to revert to neutral theme.\n');
|
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
|
}
|
|
@@ -429,46 +284,7 @@ if (fs.existsSync(viteConfigTemplatePath) && !fs.existsSync(viteConfigPath)) {
|
|
|
429
284
|
console.error(` ✗ Failed to install vite.config.ts: ${error.message}`);
|
|
430
285
|
}
|
|
431
286
|
} else if (fs.existsSync(viteConfigPath)) {
|
|
432
|
-
|
|
433
|
-
try {
|
|
434
|
-
const existing = fs.readFileSync(viteConfigPath, 'utf-8');
|
|
435
|
-
if (!existing.includes('/sf-oauth') || !existing.includes("api.salesforce.com")) {
|
|
436
|
-
const proxyBlock = `
|
|
437
|
-
// Proxy Agentforce Agent API calls through the dev server to avoid CORS.
|
|
438
|
-
// /sf-oauth/* → Salesforce org (for OAuth client-credentials token)
|
|
439
|
-
// /sf-agent/* → Agent API base (for session + message calls)
|
|
440
|
-
server: {
|
|
441
|
-
proxy: {
|
|
442
|
-
'/sf-oauth': {
|
|
443
|
-
target: 'https://tdx26-keynote-org-1com.my.salesforce.com',
|
|
444
|
-
changeOrigin: true,
|
|
445
|
-
rewrite: (p: string) => p.replace(/^\\/sf-oauth/, ''),
|
|
446
|
-
},
|
|
447
|
-
'/sf-agent': {
|
|
448
|
-
target: 'https://api.salesforce.com',
|
|
449
|
-
changeOrigin: true,
|
|
450
|
-
rewrite: (p: string) => p.replace(/^\\/sf-agent/, ''),
|
|
451
|
-
},
|
|
452
|
-
},
|
|
453
|
-
},
|
|
454
|
-
`;
|
|
455
|
-
// Insert before the build: { section if it exists
|
|
456
|
-
if (existing.includes('build: {') && !existing.includes('server: {')) {
|
|
457
|
-
const updated = existing.replace(
|
|
458
|
-
/(\s*)(\/\/.*Build|build:\s*\{)/,
|
|
459
|
-
proxyBlock + '\n$1$2'
|
|
460
|
-
);
|
|
461
|
-
if (updated !== existing) {
|
|
462
|
-
fs.writeFileSync(viteConfigPath, updated, 'utf-8');
|
|
463
|
-
console.log(' ✓ Added Agent API proxy rules to existing vite.config.ts');
|
|
464
|
-
}
|
|
465
|
-
}
|
|
466
|
-
} else {
|
|
467
|
-
console.log(' ℹ vite.config.ts already has proxy rules');
|
|
468
|
-
}
|
|
469
|
-
} catch {
|
|
470
|
-
// Non-critical — proxy can be added manually
|
|
471
|
-
}
|
|
287
|
+
console.log(' ℹ vite.config.ts already exists (not overwriting)');
|
|
472
288
|
}
|
|
473
289
|
|
|
474
290
|
// Copy dataStrategy.ts template
|
|
@@ -519,10 +335,18 @@ if (fs.existsSync(packageJsonPath)) {
|
|
|
519
335
|
scriptsAdded.push('validate:dashboard');
|
|
520
336
|
}
|
|
521
337
|
|
|
522
|
-
// Add
|
|
523
|
-
if (!packageJson.scripts['
|
|
524
|
-
packageJson.scripts['
|
|
525
|
-
scriptsAdded.push('
|
|
338
|
+
// Add brand scripts
|
|
339
|
+
if (!packageJson.scripts['brand:engine']) {
|
|
340
|
+
packageJson.scripts['brand:engine'] = 'node node_modules/@schandlergarcia/sf-web-components/scripts/apply-brand.mjs engine';
|
|
341
|
+
scriptsAdded.push('brand:engine');
|
|
342
|
+
}
|
|
343
|
+
if (!packageJson.scripts['brand:reset']) {
|
|
344
|
+
packageJson.scripts['brand:reset'] = 'node node_modules/@schandlergarcia/sf-web-components/scripts/apply-brand.mjs --reset';
|
|
345
|
+
scriptsAdded.push('brand:reset');
|
|
346
|
+
}
|
|
347
|
+
if (!packageJson.scripts['brand:list']) {
|
|
348
|
+
packageJson.scripts['brand:list'] = 'node node_modules/@schandlergarcia/sf-web-components/scripts/apply-brand.mjs --list';
|
|
349
|
+
scriptsAdded.push('brand:list');
|
|
526
350
|
}
|
|
527
351
|
|
|
528
352
|
if (scriptsAdded.length > 0) {
|
|
@@ -627,13 +451,12 @@ if (fs.existsSync(oldPagesDir)) {
|
|
|
627
451
|
|
|
628
452
|
console.log('\n📊 Summary:');
|
|
629
453
|
console.log(` - Copied ${componentsCopied} UI components`);
|
|
630
|
-
console.log(` - Updated ${filesUpdated}
|
|
454
|
+
console.log(` - Updated ${filesUpdated} import references`);
|
|
631
455
|
console.log(` - Installed ${templatesInstalled} page templates`);
|
|
632
|
-
console.log(` - Installed ${
|
|
633
|
-
console.log(` - Installed ${scriptsInstalled} GraphQL scripts`);
|
|
456
|
+
console.log(` - Installed ${scriptsInstalled} utility scripts`);
|
|
634
457
|
console.log(` - Installed CommandCenter.tsx for dashboard management`);
|
|
635
458
|
console.log(` - Added "npm run reset:command-center" script`);
|
|
636
|
-
console.log(` - Installed AI assistant rules
|
|
459
|
+
console.log(` - Installed AI assistant rules (.a4drules)`);
|
|
637
460
|
if (migratedFiles > 0) {
|
|
638
461
|
console.log(` - Migrated ${migratedFiles} dashboard files to correct location`);
|
|
639
462
|
}
|