scc-universal 1.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.
Files changed (271) hide show
  1. package/.claude-plugin/plugin.json +44 -0
  2. package/.cursor/agents/deep-researcher.md +142 -0
  3. package/.cursor/agents/doc-updater.md +219 -0
  4. package/.cursor/agents/eval-runner.md +335 -0
  5. package/.cursor/agents/learning-engine.md +210 -0
  6. package/.cursor/agents/loop-operator.md +245 -0
  7. package/.cursor/agents/refactor-cleaner.md +119 -0
  8. package/.cursor/agents/sf-admin-agent.md +127 -0
  9. package/.cursor/agents/sf-agentforce-agent.md +126 -0
  10. package/.cursor/agents/sf-apex-agent.md +117 -0
  11. package/.cursor/agents/sf-architect.md +426 -0
  12. package/.cursor/agents/sf-aura-reviewer.md +369 -0
  13. package/.cursor/agents/sf-bugfix-agent.md +101 -0
  14. package/.cursor/agents/sf-flow-agent.md +155 -0
  15. package/.cursor/agents/sf-integration-agent.md +141 -0
  16. package/.cursor/agents/sf-lwc-agent.md +123 -0
  17. package/.cursor/agents/sf-review-agent.md +357 -0
  18. package/.cursor/agents/sf-visualforce-reviewer.md +465 -0
  19. package/.cursor/hooks/adapter.js +81 -0
  20. package/.cursor/hooks/after-file-edit.js +26 -0
  21. package/.cursor/hooks/after-mcp-execution.js +12 -0
  22. package/.cursor/hooks/after-shell-execution.js +30 -0
  23. package/.cursor/hooks/after-tab-file-edit.js +12 -0
  24. package/.cursor/hooks/before-mcp-execution.js +11 -0
  25. package/.cursor/hooks/before-read-file.js +13 -0
  26. package/.cursor/hooks/before-shell-execution.js +29 -0
  27. package/.cursor/hooks/before-submit-prompt.js +23 -0
  28. package/.cursor/hooks/pre-compact.js +7 -0
  29. package/.cursor/hooks/session-end.js +10 -0
  30. package/.cursor/hooks/session-start.js +10 -0
  31. package/.cursor/hooks/stop.js +18 -0
  32. package/.cursor/hooks/subagent-start.js +10 -0
  33. package/.cursor/hooks/subagent-stop.js +10 -0
  34. package/.cursor/hooks.json +107 -0
  35. package/.cursor/skills/aside/SKILL.md +115 -0
  36. package/.cursor/skills/checkpoint/SKILL.md +50 -0
  37. package/.cursor/skills/configure-scc/SKILL.md +160 -0
  38. package/.cursor/skills/continuous-agent-loop/SKILL.md +260 -0
  39. package/.cursor/skills/mcp-server-patterns/SKILL.md +142 -0
  40. package/.cursor/skills/model-route/SKILL.md +81 -0
  41. package/.cursor/skills/prompt-optimizer/SKILL.md +366 -0
  42. package/.cursor/skills/refactor-clean/SKILL.md +133 -0
  43. package/.cursor/skills/resume-session/SKILL.md +111 -0
  44. package/.cursor/skills/save-session/SKILL.md +183 -0
  45. package/.cursor/skills/search-first/SKILL.md +140 -0
  46. package/.cursor/skills/security-scan/SKILL.md +142 -0
  47. package/.cursor/skills/sessions/SKILL.md +124 -0
  48. package/.cursor/skills/sf-agentforce-development/SKILL.md +449 -0
  49. package/.cursor/skills/sf-apex-async-patterns/SKILL.md +324 -0
  50. package/.cursor/skills/sf-apex-best-practices/SKILL.md +421 -0
  51. package/.cursor/skills/sf-apex-constraints/SKILL.md +79 -0
  52. package/.cursor/skills/sf-apex-cursor/SKILL.md +336 -0
  53. package/.cursor/skills/sf-apex-enterprise-patterns/SKILL.md +344 -0
  54. package/.cursor/skills/sf-apex-testing/SKILL.md +407 -0
  55. package/.cursor/skills/sf-api-design/SKILL.md +237 -0
  56. package/.cursor/skills/sf-approval-processes/SKILL.md +312 -0
  57. package/.cursor/skills/sf-aura-development/SKILL.md +260 -0
  58. package/.cursor/skills/sf-build-fix/SKILL.md +120 -0
  59. package/.cursor/skills/sf-data-modeling/SKILL.md +274 -0
  60. package/.cursor/skills/sf-debugging/SKILL.md +362 -0
  61. package/.cursor/skills/sf-deployment/SKILL.md +291 -0
  62. package/.cursor/skills/sf-deployment-constraints/SKILL.md +153 -0
  63. package/.cursor/skills/sf-devops-ci-cd/SKILL.md +322 -0
  64. package/.cursor/skills/sf-docs-lookup/SKILL.md +100 -0
  65. package/.cursor/skills/sf-e2e-testing/SKILL.md +321 -0
  66. package/.cursor/skills/sf-experience-cloud/SKILL.md +248 -0
  67. package/.cursor/skills/sf-flow-development/SKILL.md +376 -0
  68. package/.cursor/skills/sf-governor-limits/SKILL.md +319 -0
  69. package/.cursor/skills/sf-harness-audit/SKILL.md +139 -0
  70. package/.cursor/skills/sf-help/SKILL.md +156 -0
  71. package/.cursor/skills/sf-integration/SKILL.md +479 -0
  72. package/.cursor/skills/sf-lwc-constraints/SKILL.md +128 -0
  73. package/.cursor/skills/sf-lwc-development/SKILL.md +302 -0
  74. package/.cursor/skills/sf-lwc-testing/SKILL.md +387 -0
  75. package/.cursor/skills/sf-metadata-management/SKILL.md +285 -0
  76. package/.cursor/skills/sf-platform-events-cdc/SKILL.md +372 -0
  77. package/.cursor/skills/sf-quickstart/SKILL.md +170 -0
  78. package/.cursor/skills/sf-security/SKILL.md +330 -0
  79. package/.cursor/skills/sf-security-constraints/SKILL.md +125 -0
  80. package/.cursor/skills/sf-soql-constraints/SKILL.md +129 -0
  81. package/.cursor/skills/sf-soql-optimization/SKILL.md +353 -0
  82. package/.cursor/skills/sf-tdd-workflow/SKILL.md +332 -0
  83. package/.cursor/skills/sf-testing-constraints/SKILL.md +198 -0
  84. package/.cursor/skills/sf-trigger-constraints/SKILL.md +88 -0
  85. package/.cursor/skills/sf-trigger-frameworks/SKILL.md +343 -0
  86. package/.cursor/skills/sf-visualforce-development/SKILL.md +259 -0
  87. package/.cursor/skills/strategic-compact/SKILL.md +205 -0
  88. package/.cursor/skills/update-docs/SKILL.md +162 -0
  89. package/.cursor/skills/update-platform-docs/SKILL.md +86 -0
  90. package/.cursor-plugin/plugin.json +26 -0
  91. package/LICENSE +21 -0
  92. package/README.md +522 -0
  93. package/agents/deep-researcher.md +145 -0
  94. package/agents/doc-updater.md +222 -0
  95. package/agents/eval-runner.md +340 -0
  96. package/agents/learning-engine.md +211 -0
  97. package/agents/loop-operator.md +247 -0
  98. package/agents/refactor-cleaner.md +122 -0
  99. package/agents/sf-admin-agent.md +131 -0
  100. package/agents/sf-agentforce-agent.md +132 -0
  101. package/agents/sf-apex-agent.md +124 -0
  102. package/agents/sf-architect.md +435 -0
  103. package/agents/sf-aura-reviewer.md +372 -0
  104. package/agents/sf-bugfix-agent.md +105 -0
  105. package/agents/sf-flow-agent.md +159 -0
  106. package/agents/sf-integration-agent.md +146 -0
  107. package/agents/sf-lwc-agent.md +127 -0
  108. package/agents/sf-review-agent.md +366 -0
  109. package/agents/sf-visualforce-reviewer.md +468 -0
  110. package/assets/logo.svg +18 -0
  111. package/docs/ARCHITECTURE.md +133 -0
  112. package/docs/authoring-guide.md +373 -0
  113. package/docs/hook-development.md +578 -0
  114. package/docs/token-optimization.md +139 -0
  115. package/docs/workflow-examples.md +645 -0
  116. package/examples/agentforce-action/README.md +227 -0
  117. package/examples/apex-trigger-handler/README.md +114 -0
  118. package/examples/devops-pipeline/README.md +325 -0
  119. package/examples/flow-automation/README.md +188 -0
  120. package/examples/integration-pattern/README.md +416 -0
  121. package/examples/lwc-component/README.md +180 -0
  122. package/examples/platform-events/README.md +492 -0
  123. package/examples/scratch-org-setup/README.md +138 -0
  124. package/examples/security-audit/README.md +244 -0
  125. package/examples/visualforce-migration/README.md +314 -0
  126. package/hooks/hooks.json +338 -0
  127. package/hooks/memory-persistence/README.md +73 -0
  128. package/manifests/install-modules.json +217 -0
  129. package/manifests/install-profiles.json +17 -0
  130. package/mcp-configs/mcp-servers.json +19 -0
  131. package/package.json +89 -0
  132. package/schemas/hooks.schema.json +123 -0
  133. package/schemas/install-modules.schema.json +76 -0
  134. package/schemas/install-profiles.schema.json +28 -0
  135. package/schemas/install-state.schema.json +73 -0
  136. package/schemas/package-manager.schema.json +18 -0
  137. package/schemas/plugin.schema.json +112 -0
  138. package/schemas/scc-install-config.schema.json +29 -0
  139. package/schemas/state-store.schema.json +111 -0
  140. package/scripts/cli/install-apply.js +170 -0
  141. package/scripts/cli/uninstall.js +193 -0
  142. package/scripts/hooks/check-console-log.js +101 -0
  143. package/scripts/hooks/check-hook-enabled.js +17 -0
  144. package/scripts/hooks/check-platform-docs-age.js +48 -0
  145. package/scripts/hooks/cost-tracker.js +78 -0
  146. package/scripts/hooks/doc-file-warning.js +63 -0
  147. package/scripts/hooks/evaluate-session.js +98 -0
  148. package/scripts/hooks/governor-check.js +220 -0
  149. package/scripts/hooks/learning-observe.sh +206 -0
  150. package/scripts/hooks/mcp-health-check.js +588 -0
  151. package/scripts/hooks/post-bash-build-complete.js +34 -0
  152. package/scripts/hooks/post-bash-pr-created.js +43 -0
  153. package/scripts/hooks/post-edit-console-warn.js +61 -0
  154. package/scripts/hooks/post-edit-format.js +79 -0
  155. package/scripts/hooks/post-edit-typecheck.js +98 -0
  156. package/scripts/hooks/post-write.js +168 -0
  157. package/scripts/hooks/pre-bash-git-push-reminder.js +35 -0
  158. package/scripts/hooks/pre-bash-tmux-reminder.js +47 -0
  159. package/scripts/hooks/pre-compact.js +51 -0
  160. package/scripts/hooks/pre-tool-use.js +163 -0
  161. package/scripts/hooks/pre-write-doc-warn.js +9 -0
  162. package/scripts/hooks/quality-gate.js +251 -0
  163. package/scripts/hooks/run-with-flags-shell.sh +32 -0
  164. package/scripts/hooks/run-with-flags.js +135 -0
  165. package/scripts/hooks/session-end-marker.js +29 -0
  166. package/scripts/hooks/session-end.js +311 -0
  167. package/scripts/hooks/session-start.js +202 -0
  168. package/scripts/hooks/sfdx-scanner-check.js +142 -0
  169. package/scripts/hooks/sfdx-validate.js +119 -0
  170. package/scripts/hooks/stop-hook.js +170 -0
  171. package/scripts/hooks/suggest-compact.js +67 -0
  172. package/scripts/lib/agent-adapter.js +82 -0
  173. package/scripts/lib/apex-analysis.js +194 -0
  174. package/scripts/lib/hook-flags.js +74 -0
  175. package/scripts/lib/install-config.js +73 -0
  176. package/scripts/lib/install-executor.js +363 -0
  177. package/scripts/lib/install-state.js +121 -0
  178. package/scripts/lib/orchestration-session.js +299 -0
  179. package/scripts/lib/package-manager.js +124 -0
  180. package/scripts/lib/project-detect.js +228 -0
  181. package/scripts/lib/schema-validator.js +190 -0
  182. package/scripts/lib/skill-adapter.js +100 -0
  183. package/scripts/lib/state-store.js +376 -0
  184. package/scripts/lib/tmux-worktree-orchestrator.js +598 -0
  185. package/scripts/lib/utils.js +313 -0
  186. package/scripts/scc.js +164 -0
  187. package/skills/_reference/AGENTFORCE_PATTERNS.md +112 -0
  188. package/skills/_reference/APEX_CURSOR.md +159 -0
  189. package/skills/_reference/API_VERSIONS.md +78 -0
  190. package/skills/_reference/APPROVAL_PROCESSES.md +105 -0
  191. package/skills/_reference/ASYNC_PATTERNS.md +163 -0
  192. package/skills/_reference/AURA_COMPONENTS.md +146 -0
  193. package/skills/_reference/DATA_MIGRATION_PATTERNS.md +151 -0
  194. package/skills/_reference/DATA_MODELING.md +124 -0
  195. package/skills/_reference/DEBUGGING_TOOLS.md +140 -0
  196. package/skills/_reference/DEPLOYMENT_CHECKLIST.md +87 -0
  197. package/skills/_reference/DEPRECATIONS.md +79 -0
  198. package/skills/_reference/DOCKER_CI_PATTERNS.md +138 -0
  199. package/skills/_reference/ENTERPRISE_PATTERNS.md +122 -0
  200. package/skills/_reference/EXPERIENCE_CLOUD.md +143 -0
  201. package/skills/_reference/FLOW_PATTERNS.md +113 -0
  202. package/skills/_reference/GOVERNOR_LIMITS.md +77 -0
  203. package/skills/_reference/INTEGRATION_PATTERNS.md +105 -0
  204. package/skills/_reference/LWC_PATTERNS.md +79 -0
  205. package/skills/_reference/METADATA_TYPES.md +115 -0
  206. package/skills/_reference/NAMING_CONVENTIONS.md +84 -0
  207. package/skills/_reference/PACKAGE_DEVELOPMENT.md +150 -0
  208. package/skills/_reference/PLATFORM_EVENTS.md +121 -0
  209. package/skills/_reference/REPORTING_API.md +143 -0
  210. package/skills/_reference/SCRATCH_ORG_PATTERNS.md +126 -0
  211. package/skills/_reference/SECURITY_PATTERNS.md +127 -0
  212. package/skills/_reference/SHARING_MODEL.md +120 -0
  213. package/skills/_reference/SOQL_PATTERNS.md +119 -0
  214. package/skills/_reference/TESTING_STANDARDS.md +96 -0
  215. package/skills/_reference/TRIGGER_PATTERNS.md +114 -0
  216. package/skills/_reference/VISUALFORCE_PATTERNS.md +121 -0
  217. package/skills/aside/SKILL.md +118 -0
  218. package/skills/checkpoint/SKILL.md +53 -0
  219. package/skills/configure-scc/SKILL.md +163 -0
  220. package/skills/continuous-agent-loop/SKILL.md +264 -0
  221. package/skills/mcp-server-patterns/SKILL.md +146 -0
  222. package/skills/model-route/SKILL.md +84 -0
  223. package/skills/prompt-optimizer/SKILL.md +369 -0
  224. package/skills/refactor-clean/SKILL.md +136 -0
  225. package/skills/resume-session/SKILL.md +114 -0
  226. package/skills/save-session/SKILL.md +186 -0
  227. package/skills/search-first/SKILL.md +144 -0
  228. package/skills/security-scan/SKILL.md +146 -0
  229. package/skills/sessions/SKILL.md +127 -0
  230. package/skills/sf-agentforce-development/SKILL.md +450 -0
  231. package/skills/sf-apex-async-patterns/SKILL.md +326 -0
  232. package/skills/sf-apex-best-practices/SKILL.md +425 -0
  233. package/skills/sf-apex-constraints/SKILL.md +81 -0
  234. package/skills/sf-apex-cursor/SKILL.md +338 -0
  235. package/skills/sf-apex-enterprise-patterns/SKILL.md +348 -0
  236. package/skills/sf-apex-testing/SKILL.md +409 -0
  237. package/skills/sf-api-design/SKILL.md +238 -0
  238. package/skills/sf-approval-processes/SKILL.md +315 -0
  239. package/skills/sf-aura-development/SKILL.md +263 -0
  240. package/skills/sf-build-fix/SKILL.md +121 -0
  241. package/skills/sf-data-modeling/SKILL.md +278 -0
  242. package/skills/sf-debugging/SKILL.md +363 -0
  243. package/skills/sf-deployment/SKILL.md +295 -0
  244. package/skills/sf-deployment-constraints/SKILL.md +155 -0
  245. package/skills/sf-devops-ci-cd/SKILL.md +325 -0
  246. package/skills/sf-docs-lookup/SKILL.md +103 -0
  247. package/skills/sf-e2e-testing/SKILL.md +324 -0
  248. package/skills/sf-experience-cloud/SKILL.md +249 -0
  249. package/skills/sf-flow-development/SKILL.md +377 -0
  250. package/skills/sf-governor-limits/SKILL.md +323 -0
  251. package/skills/sf-harness-audit/SKILL.md +142 -0
  252. package/skills/sf-help/SKILL.md +159 -0
  253. package/skills/sf-integration/SKILL.md +483 -0
  254. package/skills/sf-lwc-constraints/SKILL.md +130 -0
  255. package/skills/sf-lwc-development/SKILL.md +303 -0
  256. package/skills/sf-lwc-testing/SKILL.md +388 -0
  257. package/skills/sf-metadata-management/SKILL.md +288 -0
  258. package/skills/sf-platform-events-cdc/SKILL.md +375 -0
  259. package/skills/sf-quickstart/SKILL.md +173 -0
  260. package/skills/sf-security/SKILL.md +334 -0
  261. package/skills/sf-security-constraints/SKILL.md +127 -0
  262. package/skills/sf-soql-constraints/SKILL.md +131 -0
  263. package/skills/sf-soql-optimization/SKILL.md +354 -0
  264. package/skills/sf-tdd-workflow/SKILL.md +336 -0
  265. package/skills/sf-testing-constraints/SKILL.md +200 -0
  266. package/skills/sf-trigger-constraints/SKILL.md +90 -0
  267. package/skills/sf-trigger-frameworks/SKILL.md +347 -0
  268. package/skills/sf-visualforce-development/SKILL.md +260 -0
  269. package/skills/strategic-compact/SKILL.md +208 -0
  270. package/skills/update-docs/SKILL.md +165 -0
  271. package/skills/update-platform-docs/SKILL.md +90 -0
@@ -0,0 +1,61 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * PostToolUse Hook: Warn about console.log statements after edits
4
+ *
5
+ * Cross-platform (Windows, macOS, Linux)
6
+ *
7
+ * Runs after Edit tool use. If the edited JS/TS file (especially LWC)
8
+ * contains console.log statements, warns with line numbers to help
9
+ * remove debug statements before committing.
10
+ */
11
+
12
+ const fs = require('fs');
13
+
14
+ const MAX_STDIN = 1024 * 1024; // 1MB limit
15
+ let data = '';
16
+ process.stdin.setEncoding('utf8');
17
+
18
+ process.stdin.on('data', chunk => {
19
+ if (data.length < MAX_STDIN) {
20
+ const remaining = MAX_STDIN - data.length;
21
+ data += chunk.substring(0, remaining);
22
+ }
23
+ });
24
+
25
+ process.stdin.on('end', () => {
26
+ try {
27
+ const input = JSON.parse(data);
28
+ const filePath = input.tool_input?.file_path;
29
+
30
+ if (filePath && /\.(ts|tsx|js|jsx)$/.test(filePath)) {
31
+ let content;
32
+ try {
33
+ content = fs.readFileSync(filePath, 'utf8');
34
+ } catch {
35
+ process.stdout.write(data);
36
+ process.exit(0);
37
+ }
38
+
39
+ if (!content) { process.stdout.write(data); process.exit(0); }
40
+ const lines = content.split('\n');
41
+ const matches = [];
42
+
43
+ lines.forEach((line, idx) => {
44
+ if (/console\.log/.test(line)) {
45
+ matches.push((idx + 1) + ': ' + line.trim());
46
+ }
47
+ });
48
+
49
+ if (matches.length > 0) {
50
+ console.error('[Hook] WARNING: console.log found in ' + filePath);
51
+ matches.slice(0, 5).forEach(m => console.error(m));
52
+ console.error('[Hook] Remove console.log before committing');
53
+ }
54
+ }
55
+ } catch {
56
+ // Invalid input — pass through
57
+ }
58
+
59
+ process.stdout.write(data);
60
+ process.exit(0);
61
+ });
@@ -0,0 +1,79 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Post-Edit Format Hook
4
+ *
5
+ * Auto-formats files after edits using Prettier or sfdx-scanner.
6
+ * Runs on PostToolUse for Edit operations.
7
+ */
8
+
9
+ 'use strict';
10
+
11
+ const fs = require('fs');
12
+ const path = require('path');
13
+ const { spawnSync } = require('child_process');
14
+
15
+ const MAX_STDIN = 1024 * 1024;
16
+
17
+ function log(msg) {
18
+ process.stderr.write(`${msg}\n`);
19
+ }
20
+
21
+ function tryFormat(filePath) {
22
+ if (!filePath || !fs.existsSync(filePath)) return;
23
+
24
+ filePath = path.resolve(filePath);
25
+ const ext = path.extname(filePath).toLowerCase();
26
+
27
+ // JavaScript/TypeScript/JSON/HTML/CSS — try Prettier
28
+ if (['.js', '.ts', '.jsx', '.tsx', '.json', '.html', '.css'].includes(ext)) {
29
+ const result = spawnSync('npx', ['prettier', '--write', filePath], {
30
+ encoding: 'utf8',
31
+ timeout: 15000,
32
+ stdio: ['pipe', 'pipe', 'pipe'],
33
+ });
34
+ if (result.status === 0) {
35
+ log(`[SCC Format] Formatted ${path.basename(filePath)} with Prettier`);
36
+ }
37
+ return;
38
+ }
39
+
40
+ // Apex — try Prettier with apex plugin
41
+ if (ext === '.cls' || ext === '.trigger') {
42
+ const result = spawnSync('npx', ['prettier', '--write', '--plugin', 'prettier-plugin-apex', filePath], {
43
+ encoding: 'utf8',
44
+ timeout: 15000,
45
+ stdio: ['pipe', 'pipe', 'pipe'],
46
+ });
47
+ if (result.status === 0) {
48
+ log(`[SCC Format] Formatted ${path.basename(filePath)} with Prettier (Apex)`);
49
+ }
50
+ return;
51
+ }
52
+ }
53
+
54
+ function run(rawInput) {
55
+ try {
56
+ const input = JSON.parse(rawInput);
57
+ const filePath = String(input.tool_input?.file_path || '');
58
+ tryFormat(filePath);
59
+ } catch {
60
+ // Ignore errors
61
+ }
62
+ return rawInput;
63
+ }
64
+
65
+ if (require.main === module) {
66
+ let raw = '';
67
+ process.stdin.setEncoding('utf8');
68
+ process.stdin.on('data', chunk => {
69
+ if (raw.length < MAX_STDIN) {
70
+ raw += chunk.substring(0, MAX_STDIN - raw.length);
71
+ }
72
+ });
73
+ process.stdin.on('end', () => {
74
+ const result = run(raw);
75
+ process.stdout.write(result);
76
+ });
77
+ }
78
+
79
+ module.exports = { run };
@@ -0,0 +1,98 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Post-Edit Type Check Hook
4
+ *
5
+ * Runs type checking after editing TypeScript or LWC files.
6
+ * For LWC: validates component structure.
7
+ * For TS: runs tsc --noEmit on the file.
8
+ */
9
+
10
+ 'use strict';
11
+
12
+ const fs = require('fs');
13
+ const path = require('path');
14
+ const { spawnSync } = require('child_process');
15
+
16
+ const MAX_STDIN = 1024 * 1024;
17
+
18
+ function log(msg) {
19
+ process.stderr.write(`${msg}\n`);
20
+ }
21
+
22
+ function checkFile(filePath) {
23
+ if (!filePath || !fs.existsSync(filePath)) return;
24
+
25
+ filePath = path.resolve(filePath);
26
+ const ext = path.extname(filePath).toLowerCase();
27
+
28
+ // TypeScript files — run tsc
29
+ if (ext === '.ts' || ext === '.tsx') {
30
+ const result = spawnSync('npx', ['tsc', '--noEmit', '--pretty', filePath], {
31
+ encoding: 'utf8',
32
+ timeout: 30000,
33
+ stdio: ['pipe', 'pipe', 'pipe'],
34
+ });
35
+ if (result.status !== 0 && result.stderr) {
36
+ log(`[SCC TypeCheck] Type errors in ${path.basename(filePath)}:`);
37
+ const lines = result.stderr.split('\n').slice(0, 5);
38
+ for (const line of lines) {
39
+ if (line.trim()) log(` ${line}`);
40
+ }
41
+ }
42
+ return;
43
+ }
44
+
45
+ // LWC JavaScript — validate basic structure
46
+ if (ext === '.js' && filePath.includes('/lwc/')) {
47
+ try {
48
+ const content = fs.readFileSync(filePath, 'utf8');
49
+ const issues = [];
50
+
51
+ // Check for default export
52
+ if (!content.includes('export default class')) {
53
+ issues.push('Missing default class export — LWC requires `export default class`');
54
+ }
55
+
56
+ // Check for LightningElement extension
57
+ if (content.includes('export default class') && !content.includes('LightningElement')) {
58
+ issues.push('LWC class should extend LightningElement');
59
+ }
60
+
61
+ if (issues.length > 0) {
62
+ log(`[SCC TypeCheck] LWC issues in ${path.basename(filePath)}:`);
63
+ for (const issue of issues) {
64
+ log(` - ${issue}`);
65
+ }
66
+ }
67
+ } catch {
68
+ // Ignore read errors
69
+ }
70
+ }
71
+ }
72
+
73
+ function run(rawInput) {
74
+ try {
75
+ const input = JSON.parse(rawInput);
76
+ const filePath = String(input.tool_input?.file_path || '');
77
+ checkFile(filePath);
78
+ } catch {
79
+ // Ignore parse errors
80
+ }
81
+ return rawInput;
82
+ }
83
+
84
+ if (require.main === module) {
85
+ let raw = '';
86
+ process.stdin.setEncoding('utf8');
87
+ process.stdin.on('data', chunk => {
88
+ if (raw.length < MAX_STDIN) {
89
+ raw += chunk.substring(0, MAX_STDIN - raw.length);
90
+ }
91
+ });
92
+ process.stdin.on('end', () => {
93
+ const result = run(raw);
94
+ process.stdout.write(result);
95
+ });
96
+ }
97
+
98
+ module.exports = { run };
@@ -0,0 +1,168 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+
4
+ /**
5
+ * post-write.js — PostToolUse hook for Write operations.
6
+ *
7
+ * Detects Salesforce-specific file writes and provides guidance:
8
+ * - .cls / .trigger files → remind about 75% Apex test coverage
9
+ * - LWC .js files → remind about Jest unit tests
10
+ * - .page, .component (Visualforce) → note about test considerations
11
+ */
12
+
13
+ const path = require('path');
14
+ const readline = require('readline');
15
+
16
+ /**
17
+ * Classify a written file path into Salesforce content type.
18
+ */
19
+ function classifyFile(filePath) {
20
+ if (!filePath) return null;
21
+ const ext = path.extname(filePath).toLowerCase();
22
+ const base = path.basename(filePath).toLowerCase();
23
+ const parts = filePath.split(path.sep);
24
+
25
+ // Apex class
26
+ if (ext === '.cls') return 'apex-class';
27
+ // Apex trigger
28
+ if (ext === '.trigger') return 'apex-trigger';
29
+ // Apex test class (may already have test annotations but remind anyway)
30
+ if (ext === '.cls' && base.includes('test')) return 'apex-test';
31
+
32
+ // LWC: check if the file is inside an lwc directory
33
+ const lwcIdx = parts.findIndex(p => p === 'lwc');
34
+ if (lwcIdx !== -1) {
35
+ if (ext === '.js' && !base.endsWith('.test.js') && !base.endsWith('.spec.js')) return 'lwc-js';
36
+ if (ext === '.html') return 'lwc-html';
37
+ if (ext === '.css') return 'lwc-css';
38
+ if (ext === '.js' && (base.endsWith('.test.js') || base.endsWith('.spec.js'))) return 'lwc-test';
39
+ }
40
+
41
+ // Aura component
42
+ const auraIdx = parts.findIndex(p => p === 'aura');
43
+ if (auraIdx !== -1 && ext === '.js') return 'aura-js';
44
+
45
+ // Visualforce
46
+ if (ext === '.page') return 'visualforce-page';
47
+ if (ext === '.component') return 'visualforce-component';
48
+
49
+ // Flow
50
+ if (ext === '.flow' || ext === '.flow-meta.xml') return 'flow';
51
+
52
+ // Permission set / profile
53
+ if (filePath.includes('permissionsets') || ext === '.permissionset-meta.xml') return 'permission-set';
54
+
55
+ return null;
56
+ }
57
+
58
+ const REMINDERS = {
59
+ 'apex-class': {
60
+ emoji: '',
61
+ title: 'Apex Class Written',
62
+ messages: [
63
+ 'Apex classes require 75% code coverage across your org to deploy to production.',
64
+ 'Create or update a corresponding test class (e.g., MyClass_Test.cls or MyClassTest.cls).',
65
+ 'Use @isTest annotation and System.assert/assertEquals for assertions.',
66
+ 'Run tests: sf apex run test --class-names MyClassTest --result-format human',
67
+ ],
68
+ },
69
+ 'apex-trigger': {
70
+ emoji: '',
71
+ title: 'Apex Trigger Written',
72
+ messages: [
73
+ 'Triggers require 75% code coverage to deploy to production.',
74
+ 'Best practice: keep trigger logic minimal — delegate to a handler class.',
75
+ 'Create a test class that fires the trigger with both insert and update scenarios.',
76
+ 'Consider using a TriggerHandler framework for maintainability.',
77
+ 'Run tests: sf apex run test --class-names MyTriggerTest --result-format human',
78
+ ],
79
+ },
80
+ 'lwc-js': {
81
+ emoji: '',
82
+ title: 'LWC JavaScript Written',
83
+ messages: [
84
+ 'LWC components should have Jest unit tests.',
85
+ 'Test file convention: __tests__/myComponent.test.js',
86
+ 'Run Jest tests: npm run test:unit (or sf lightning generate component for scaffolding)',
87
+ 'Use @salesforce/lwc-jest or @lwc/jest-transformer for testing.',
88
+ 'Mock Salesforce imports with jest.mock() or @salesforce/jest-mocks.',
89
+ ],
90
+ },
91
+ 'lwc-html': {
92
+ emoji: '',
93
+ title: 'LWC Template Written',
94
+ messages: [
95
+ 'Update Jest tests if you added new elements, slots, or event handlers.',
96
+ 'Validate template with: sf project deploy start --dry-run',
97
+ ],
98
+ },
99
+ 'aura-js': {
100
+ emoji: '',
101
+ title: 'Aura Component Written',
102
+ messages: [
103
+ 'Consider migrating Aura components to LWC for better performance and maintainability.',
104
+ 'Aura components can coexist with LWC but LWC is the recommended approach for new development.',
105
+ ],
106
+ },
107
+ 'visualforce-page': {
108
+ emoji: '',
109
+ title: 'Visualforce Page Written',
110
+ messages: [
111
+ 'Visualforce pages used with Apex controllers require controller test coverage.',
112
+ 'Consider whether this functionality could be implemented with LWC instead.',
113
+ ],
114
+ },
115
+ 'flow': {
116
+ emoji: '',
117
+ title: 'Flow Metadata Written',
118
+ messages: [
119
+ 'Test Flows using Flow Interview tests in Apex or through the UI.',
120
+ 'Ensure Flow is activated before deploying to production.',
121
+ ],
122
+ },
123
+ };
124
+
125
+ function generateReminder(fileType, filePath) {
126
+ const reminder = REMINDERS[fileType];
127
+ if (!reminder) return null;
128
+
129
+ const lines = [];
130
+ lines.push(`[SCC] ${reminder.title}: ${path.basename(filePath)}`);
131
+ for (const msg of reminder.messages) {
132
+ lines.push(` • ${msg}`);
133
+ }
134
+ return lines.join('\n');
135
+ }
136
+
137
+ // ── Main ─────────────────────────────────────────────────────────────────────
138
+
139
+ let rawInput = '';
140
+ const rl = readline.createInterface({ input: process.stdin });
141
+ rl.on('line', line => { rawInput += line + '\n'; });
142
+
143
+ rl.on('close', () => {
144
+ let input = {};
145
+ try {
146
+ input = JSON.parse(rawInput.trim() || '{}');
147
+ } catch {
148
+ process.exit(0);
149
+ }
150
+
151
+ // Only process Write tool
152
+ if (input.tool_name !== 'Write' && input.tool_name !== 'write') {
153
+ process.exit(0);
154
+ }
155
+
156
+ const filePath = (input.tool_input && input.tool_input.file_path) || '';
157
+ if (!filePath) process.exit(0);
158
+
159
+ const fileType = classifyFile(filePath);
160
+ if (!fileType) process.exit(0);
161
+
162
+ const reminder = generateReminder(fileType, filePath);
163
+ if (reminder) {
164
+ console.log('\n' + reminder + '\n');
165
+ }
166
+
167
+ process.exit(0);
168
+ });
@@ -0,0 +1,35 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+
4
+ /**
5
+ * PreToolUse Hook: Remind to review changes before git push
6
+ *
7
+ * Detects `git push` commands and logs a reminder to review
8
+ * changes before pushing.
9
+ */
10
+
11
+ const MAX_STDIN = 1024 * 1024;
12
+ let raw = '';
13
+
14
+ process.stdin.setEncoding('utf8');
15
+ process.stdin.on('data', chunk => {
16
+ if (raw.length < MAX_STDIN) {
17
+ const remaining = MAX_STDIN - raw.length;
18
+ raw += chunk.substring(0, remaining);
19
+ }
20
+ });
21
+
22
+ process.stdin.on('end', () => {
23
+ try {
24
+ const input = JSON.parse(raw);
25
+ const cmd = String(input.tool_input?.command || '');
26
+ if (/\bgit\s+push\b/.test(cmd)) {
27
+ console.error('[Hook] Review changes before push...');
28
+ console.error('[Hook] Continuing with push (remove this hook to add interactive review)');
29
+ }
30
+ } catch {
31
+ // ignore parse errors and pass through
32
+ }
33
+
34
+ process.stdout.write(raw);
35
+ });
@@ -0,0 +1,47 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+
4
+ /**
5
+ * pre-bash-tmux-reminder.js — PreToolUse (Bash) hook.
6
+ *
7
+ * Reminds the user to run long-running Salesforce CLI commands inside tmux
8
+ * so that session disconnection doesn't kill deploys or test runs.
9
+ *
10
+ * Fires on: sf project deploy, sfdx force:source:deploy, sf apex run test,
11
+ * sfdx force:apex:test:run, sf org create scratch, npm test, jest
12
+ *
13
+ * Profile: strict (only fires when SCC_HOOK_PROFILE=strict)
14
+ * Wired via run-with-flags.js — gating is handled externally.
15
+ */
16
+
17
+ const MAX_STDIN = 1024 * 1024;
18
+ let raw = '';
19
+
20
+ process.stdin.setEncoding('utf8');
21
+ process.stdin.on('data', chunk => {
22
+ if (raw.length < MAX_STDIN) {
23
+ const remaining = MAX_STDIN - raw.length;
24
+ raw += chunk.substring(0, remaining);
25
+ }
26
+ });
27
+
28
+ process.stdin.on('end', () => {
29
+ try {
30
+ const input = JSON.parse(raw);
31
+ const cmd = String(input.tool_input?.command || '');
32
+
33
+ if (
34
+ process.platform !== 'win32' &&
35
+ !process.env.TMUX &&
36
+ /\b(sf project deploy|sfdx force:source:deploy|sfdx force:mdapi:deploy|sf apex run test|sfdx force:apex:test:run|sf org create scratch|sfdx force:org:create|npm test\b|jest\b)/.test(cmd)
37
+ ) {
38
+ console.error('[SCC] Long-running Salesforce command detected. Consider running in tmux:');
39
+ console.error('[SCC] tmux new -s sf-dev | tmux attach -t sf-dev');
40
+ console.error('[SCC] This prevents session disconnection from killing deploys or test runs.');
41
+ }
42
+ } catch {
43
+ // ignore parse errors and pass through
44
+ }
45
+
46
+ process.stdout.write(raw);
47
+ });
@@ -0,0 +1,51 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * PreCompact Hook — Save state before context compaction.
4
+ *
5
+ * Logs compaction events and annotates active session files
6
+ * so post-compaction context has a record of what happened.
7
+ */
8
+
9
+ 'use strict';
10
+
11
+ const fs = require('fs');
12
+ const path = require('path');
13
+ const { ensureDir } = require('../lib/utils');
14
+
15
+ function getClaudeDir() {
16
+ return path.join(process.env.HOME || process.env.USERPROFILE || '/tmp', '.claude');
17
+ }
18
+
19
+ function getDateTimeString() {
20
+ return new Date().toISOString().replace('T', ' ').slice(0, 19);
21
+ }
22
+
23
+ async function main() {
24
+ const sessionsDir = path.join(getClaudeDir(), 'sessions');
25
+ const compactionLog = path.join(sessionsDir, 'compaction-log.txt');
26
+
27
+ ensureDir(sessionsDir);
28
+
29
+ const timestamp = getDateTimeString();
30
+ fs.appendFileSync(compactionLog, `[${timestamp}] Context compaction triggered\n`);
31
+
32
+ // Annotate active session files
33
+ try {
34
+ const entries = fs.readdirSync(sessionsDir);
35
+ const sessionFiles = entries.filter(f => f.endsWith('-session.tmp'));
36
+ if (sessionFiles.length > 0) {
37
+ const activeSession = path.join(sessionsDir, sessionFiles[0]);
38
+ fs.appendFileSync(activeSession, `\n---\n**[Compaction at ${timestamp}]** — Context was summarized\n`);
39
+ }
40
+ } catch {
41
+ // Ignore errors
42
+ }
43
+
44
+ process.stderr.write('[SCC PreCompact] State saved before compaction\n');
45
+ process.exit(0);
46
+ }
47
+
48
+ main().catch(err => {
49
+ console.error('[SCC PreCompact] Error:', err.message);
50
+ process.exit(0);
51
+ });