scc-universal 1.2.1 → 1.3.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.
Files changed (47) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/.cursor/agents/sf-agentforce-agent.md +88 -40
  3. package/.cursor/skills/prompt-optimizer/SKILL.md +21 -21
  4. package/.cursor/skills/sf-2gp-security-review/SKILL.md +167 -0
  5. package/.cursor/skills/sf-agentforce-development/SKILL.md +385 -348
  6. package/.cursor/skills/sf-cli-reference/SKILL.md +221 -0
  7. package/.cursor/skills/sf-harness-audit/SKILL.md +2 -2
  8. package/.cursor/skills/sf-quickstart/SKILL.md +1 -1
  9. package/.cursor-plugin/plugin.json +1 -1
  10. package/README.md +8 -38
  11. package/agents/sf-agentforce-agent.md +88 -40
  12. package/docs/ARCHITECTURE.md +4 -3
  13. package/docs/authoring-guide.md +1 -1
  14. package/docs/hook-development.md +1 -1
  15. package/examples/agentforce-action/README.md +4 -4
  16. package/examples/devops-pipeline/README.md +4 -4
  17. package/examples/integration-pattern/README.md +4 -4
  18. package/examples/platform-events/README.md +4 -4
  19. package/examples/security-audit/README.md +3 -3
  20. package/examples/visualforce-migration/README.md +4 -4
  21. package/manifests/install-modules.json +9 -3
  22. package/package.json +2 -2
  23. package/scripts/lib/install-executor.js +23 -12
  24. package/skills/_reference/AGENTFORCE_PATTERNS.md +433 -51
  25. package/skills/_reference/APPEXCHANGE_REVIEW.md +427 -0
  26. package/skills/_reference/SF_CLI_COMMANDS.md +812 -0
  27. package/skills/prompt-optimizer/SKILL.md +21 -21
  28. package/skills/sf-2gp-security-review/SKILL.md +168 -0
  29. package/skills/sf-agentforce-development/SKILL.md +385 -348
  30. package/skills/sf-cli-reference/SKILL.md +225 -0
  31. package/skills/sf-harness-audit/SKILL.md +2 -2
  32. package/skills/sf-quickstart/SKILL.md +1 -1
  33. package/.cursor/hooks/adapter.js +0 -81
  34. package/.cursor/hooks/after-file-edit.js +0 -26
  35. package/.cursor/hooks/after-mcp-execution.js +0 -12
  36. package/.cursor/hooks/after-shell-execution.js +0 -30
  37. package/.cursor/hooks/after-tab-file-edit.js +0 -12
  38. package/.cursor/hooks/before-mcp-execution.js +0 -11
  39. package/.cursor/hooks/before-read-file.js +0 -13
  40. package/.cursor/hooks/before-shell-execution.js +0 -29
  41. package/.cursor/hooks/before-submit-prompt.js +0 -23
  42. package/.cursor/hooks/pre-compact.js +0 -7
  43. package/.cursor/hooks/session-end.js +0 -10
  44. package/.cursor/hooks/session-start.js +0 -10
  45. package/.cursor/hooks/stop.js +0 -18
  46. package/.cursor/hooks/subagent-start.js +0 -10
  47. package/.cursor/hooks/subagent-stop.js +0 -10
@@ -308,7 +308,7 @@ public with sharing class AccountEditorLwcController {
308
308
 
309
309
  ## SCC Skills
310
310
 
311
- - `/sf-visualforce-development` -- audit a Visualforce page for migration readiness
312
- - `/sf-lwc-development` -- review the migrated LWC component for best practices
313
- - `/sf-apex-best-practices` -- review the simplified Apex controller
314
- - `/sf-security` -- verify security enforcement in the new component
311
+ - `sf-visualforce-development` -- audit a Visualforce page for migration readiness
312
+ - `sf-lwc-development` -- review the migrated LWC component for best practices
313
+ - `sf-apex-best-practices` -- review the simplified Apex controller
314
+ - `sf-security` -- verify security enforcement in the new component
@@ -24,8 +24,12 @@
24
24
  "targets": { "claude": ".claude/skills/", "cursor": ".cursor/skills/" }
25
25
  },
26
26
  {
27
- "paths": ["scripts/hooks/"],
28
- "targets": { "claude": ".claude/", "cursor": ".cursor/" },
27
+ "paths": ["scripts/hooks/", "scripts/lib/"],
28
+ "destMap": { "hooks": "scripts" },
29
+ "includeOnly": {
30
+ "scripts/lib/": ["utils.js", "hook-input.js", "apex-analysis.js", "hook-flags.js"]
31
+ },
32
+ "targets": { "claude": ".claude/hooks/", "cursor": ".cursor/hooks/" },
29
33
  "installType": "hooks",
30
34
  "hooksSource": "hooks/hooks.json"
31
35
  }
@@ -151,7 +155,8 @@
151
155
  "paths": [
152
156
  "skills/sf-devops-ci-cd/",
153
157
  "skills/sf-deployment/",
154
- "skills/sf-deployment-constraints/"
158
+ "skills/sf-deployment-constraints/",
159
+ "skills/sf-cli-reference/"
155
160
  ],
156
161
  "targets": { "claude": ".claude/skills/", "cursor": ".cursor/skills/" }
157
162
  }
@@ -169,6 +174,7 @@
169
174
  {
170
175
  "paths": [
171
176
  "skills/sf-security/",
177
+ "skills/sf-2gp-security-review/",
172
178
  "skills/sf-governor-limits/",
173
179
  "skills/sf-soql-optimization/",
174
180
  "skills/sf-security-constraints/"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "scc-universal",
3
- "version": "1.2.1",
3
+ "version": "1.3.0",
4
4
  "description": "Complete collection of production-ready Salesforce agents, skills, hooks, and MCP configurations for Claude Code and other AI harnesses. Salesforce Claude Code (SCC) — your AI-powered Salesforce development partner.",
5
5
  "keywords": [
6
6
  "salesforce",
@@ -66,7 +66,7 @@
66
66
  "build:cursor-agents": "node scripts/dev/build-cursor-agents.js",
67
67
  "test": "npm run build && node scripts/ci/validate-agents.js && node scripts/ci/validate-commands.js && node scripts/ci/validate-skills.js && node scripts/ci/validate-hooks.js && node scripts/ci/validate-install-manifests.js && node scripts/ci/validate-no-personal-paths.js && node tests/run-all.js",
68
68
  "smoke": "bash scripts/ci/smoke-test.sh",
69
- "lint": "eslint . && markdownlint '**/*.md' --ignore node_modules",
69
+ "lint": "eslint . && markdownlint '**/*.md' --ignore node_modules --ignore CHANGELOG.md",
70
70
  "coverage": "c8 --all --include=\"scripts/**/*.js\" --exclude=\"scripts/scc.js\" --reporter=text --reporter=lcov --check-coverage --lines 80 --functions 80 --branches 80 --statements 80 node tests/run-all.js",
71
71
  "harness:audit": "node scripts/dev/harness-audit.js",
72
72
  "orchestrate:status": "node scripts/dev/orchestration-status.js",
@@ -144,7 +144,7 @@ function isAgentFile(srcRelative) {
144
144
  * @param {string} targetName - install target ('claude' or 'cursor')
145
145
  * @returns {Array} installed file records
146
146
  */
147
- function installPaths(pathsList, destDir, pluginRoot, moduleName, dryRun, targetName) {
147
+ function installPaths(pathsList, destDir, pluginRoot, moduleName, dryRun, targetName, destMap, includeOnly) {
148
148
  const installed = [];
149
149
 
150
150
  for (const srcRelative of pathsList) {
@@ -157,7 +157,11 @@ function installPaths(pathsList, destDir, pluginRoot, moduleName, dryRun, target
157
157
  continue;
158
158
  }
159
159
 
160
- const dirName = path.basename(srcRelative.slice(0, -1));
160
+ let dirName = path.basename(srcRelative.slice(0, -1));
161
+ // Allow manifest destMap to override the destination directory name
162
+ if (destMap && destMap[dirName]) {
163
+ dirName = destMap[dirName];
164
+ }
161
165
  const destSubDir = path.join(destDir, dirName);
162
166
 
163
167
  // Use skill adapter for Cursor target when source is a skill directory
@@ -171,8 +175,11 @@ function installPaths(pathsList, destDir, pluginRoot, moduleName, dryRun, target
171
175
  continue;
172
176
  }
173
177
 
178
+ // Filter files if includeOnly is specified for this source directory
179
+ const allowList = includeOnly && includeOnly[srcRelative];
174
180
  const entries = fs.readdirSync(srcPath);
175
181
  for (const entry of entries) {
182
+ if (allowList && !allowList.includes(entry)) continue;
176
183
  const fullSrc = path.join(srcPath, entry);
177
184
  if (fs.statSync(fullSrc).isFile()) {
178
185
  const record = installFile(fullSrc, destSubDir, entry, moduleName, dryRun);
@@ -201,7 +208,11 @@ function installPaths(pathsList, destDir, pluginRoot, moduleName, dryRun, target
201
208
 
202
209
  /**
203
210
  * Remap hook commands from plugin paths to project-local paths.
204
- * ${CLAUDE_PLUGIN_ROOT}/scripts/hooks/foo.js → "$CLAUDE_PROJECT_DIR"/.claude/hooks/foo.js
211
+ * ${CLAUDE_PLUGIN_ROOT}/scripts/hooks/foo.js → "$CLAUDE_PROJECT_DIR"/.claude/hooks/scripts/foo.js
212
+ *
213
+ * Install copies scripts/hooks/ → .claude/hooks/scripts/ (via destMap) and
214
+ * scripts/lib/ → .claude/hooks/lib/ so that require('../lib/...') resolves
215
+ * correctly from the installed location.
205
216
  */
206
217
  function remapHookCommandForProject(command) {
207
218
  // Strip run-with-flags wrapper and extract the actual script
@@ -209,7 +220,7 @@ function remapHookCommandForProject(command) {
209
220
  /node\s+"?\$\{CLAUDE_PLUGIN_ROOT\}\/scripts\/hooks\/run-with-flags\.js"?\s+\S+\s+\S+\s+"?\$\{CLAUDE_PLUGIN_ROOT\}\/scripts\/hooks\/([^"]+)"?/
210
221
  );
211
222
  if (runWithFlagsMatch) {
212
- return `node "$CLAUDE_PROJECT_DIR"/.claude/hooks/${runWithFlagsMatch[1]}`;
223
+ return `node "$CLAUDE_PROJECT_DIR"/.claude/hooks/scripts/${runWithFlagsMatch[1]}`;
213
224
  }
214
225
 
215
226
  // Shell flags wrapper
@@ -217,7 +228,7 @@ function remapHookCommandForProject(command) {
217
228
  /bash\s+"?\$\{CLAUDE_PLUGIN_ROOT\}\/scripts\/hooks\/run-with-flags-shell\.sh"?\s+\S+\s+"?scripts\/hooks\/([^"]+)"?\s+\S+/
218
229
  );
219
230
  if (shellFlagsMatch) {
220
- return `bash "$CLAUDE_PROJECT_DIR"/.claude/hooks/${shellFlagsMatch[1]}`;
231
+ return `bash "$CLAUDE_PROJECT_DIR"/.claude/hooks/scripts/${shellFlagsMatch[1]}`;
221
232
  }
222
233
 
223
234
  // Direct script reference
@@ -225,7 +236,7 @@ function remapHookCommandForProject(command) {
225
236
  /node\s+"?\$\{CLAUDE_PLUGIN_ROOT\}\/scripts\/hooks\/([^"]+)"?/
226
237
  );
227
238
  if (directMatch) {
228
- return `node "$CLAUDE_PROJECT_DIR"/.claude/hooks/${directMatch[1]}`;
239
+ return `node "$CLAUDE_PROJECT_DIR"/.claude/hooks/scripts/${directMatch[1]}`;
229
240
  }
230
241
 
231
242
  // npx commands pass through
@@ -233,7 +244,7 @@ function remapHookCommandForProject(command) {
233
244
  return command;
234
245
  }
235
246
 
236
- return command.replace(/\$\{CLAUDE_PLUGIN_ROOT\}\/scripts\/hooks\//g, '"$CLAUDE_PROJECT_DIR"/.claude/hooks/');
247
+ return command.replace(/\$\{CLAUDE_PLUGIN_ROOT\}\/scripts\/hooks\//g, '"$CLAUDE_PROJECT_DIR"/.claude/hooks/scripts/');
237
248
  }
238
249
 
239
250
  /**
@@ -256,7 +267,7 @@ function installHooks(group, pluginRoot, targetName, projectRoot, moduleName, dr
256
267
  const destRelative = (group.targets || {})[targetName];
257
268
  if (destRelative) {
258
269
  const destDir = path.join(projectRoot, destRelative);
259
- installed.push(...installPaths(group.paths || [], destDir, pluginRoot, moduleName, dryRun, targetName));
270
+ installed.push(...installPaths(group.paths || [], destDir, pluginRoot, moduleName, dryRun, targetName, group.destMap, group.includeOnly));
260
271
  }
261
272
 
262
273
  // Step 2: For Claude Code target, merge hooks into .claude/settings.json
@@ -318,13 +329,13 @@ function installHooks(group, pluginRoot, targetName, projectRoot, moduleName, dr
318
329
  const cursorHooksPath = path.join(projectRoot, '.cursor', 'hooks.json');
319
330
  const cursorHooks = transformHooks(hooksJson);
320
331
 
321
- // Remap adapter paths from scripts/hooks/ to .cursor/hooks/
322
- // (adapter outputs plugin-relative paths, but install copies to .cursor/hooks/)
332
+ // Remap adapter paths from scripts/hooks/ to .cursor/hooks/scripts/
333
+ // (adapter outputs plugin-relative paths, but install copies to .cursor/hooks/scripts/)
323
334
  for (const hooks of Object.values(cursorHooks.hooks)) {
324
335
  for (const hook of hooks) {
325
336
  if (hook.command) {
326
- hook.command = hook.command.replace(/\bnode scripts\/hooks\//g, 'node "$CURSOR_PROJECT_DIR"/.cursor/hooks/');
327
- hook.command = hook.command.replace(/\bbash scripts\/hooks\//g, 'bash "$CURSOR_PROJECT_DIR"/.cursor/hooks/');
337
+ hook.command = hook.command.replace(/\bnode scripts\/hooks\//g, 'node "$CURSOR_PROJECT_DIR"/.cursor/hooks/scripts/');
338
+ hook.command = hook.command.replace(/\bbash scripts\/hooks\//g, 'bash "$CURSOR_PROJECT_DIR"/.cursor/hooks/scripts/');
328
339
  }
329
340
  }
330
341
  }