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.
- package/.claude-plugin/plugin.json +1 -1
- package/.cursor/agents/sf-agentforce-agent.md +88 -40
- package/.cursor/skills/prompt-optimizer/SKILL.md +21 -21
- package/.cursor/skills/sf-2gp-security-review/SKILL.md +167 -0
- package/.cursor/skills/sf-agentforce-development/SKILL.md +385 -348
- package/.cursor/skills/sf-cli-reference/SKILL.md +221 -0
- package/.cursor/skills/sf-harness-audit/SKILL.md +2 -2
- package/.cursor/skills/sf-quickstart/SKILL.md +1 -1
- package/.cursor-plugin/plugin.json +1 -1
- package/README.md +8 -38
- package/agents/sf-agentforce-agent.md +88 -40
- package/docs/ARCHITECTURE.md +4 -3
- package/docs/authoring-guide.md +1 -1
- package/docs/hook-development.md +1 -1
- package/examples/agentforce-action/README.md +4 -4
- package/examples/devops-pipeline/README.md +4 -4
- package/examples/integration-pattern/README.md +4 -4
- package/examples/platform-events/README.md +4 -4
- package/examples/security-audit/README.md +3 -3
- package/examples/visualforce-migration/README.md +4 -4
- package/manifests/install-modules.json +9 -3
- package/package.json +2 -2
- package/scripts/lib/install-executor.js +23 -12
- package/skills/_reference/AGENTFORCE_PATTERNS.md +433 -51
- package/skills/_reference/APPEXCHANGE_REVIEW.md +427 -0
- package/skills/_reference/SF_CLI_COMMANDS.md +812 -0
- package/skills/prompt-optimizer/SKILL.md +21 -21
- package/skills/sf-2gp-security-review/SKILL.md +168 -0
- package/skills/sf-agentforce-development/SKILL.md +385 -348
- package/skills/sf-cli-reference/SKILL.md +225 -0
- package/skills/sf-harness-audit/SKILL.md +2 -2
- package/skills/sf-quickstart/SKILL.md +1 -1
- package/.cursor/hooks/adapter.js +0 -81
- package/.cursor/hooks/after-file-edit.js +0 -26
- package/.cursor/hooks/after-mcp-execution.js +0 -12
- package/.cursor/hooks/after-shell-execution.js +0 -30
- package/.cursor/hooks/after-tab-file-edit.js +0 -12
- package/.cursor/hooks/before-mcp-execution.js +0 -11
- package/.cursor/hooks/before-read-file.js +0 -13
- package/.cursor/hooks/before-shell-execution.js +0 -29
- package/.cursor/hooks/before-submit-prompt.js +0 -23
- package/.cursor/hooks/pre-compact.js +0 -7
- package/.cursor/hooks/session-end.js +0 -10
- package/.cursor/hooks/session-start.js +0 -10
- package/.cursor/hooks/stop.js +0 -18
- package/.cursor/hooks/subagent-start.js +0 -10
- package/.cursor/hooks/subagent-stop.js +0 -10
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: sf-cli-reference
|
|
3
|
+
description: >-
|
|
4
|
+
Use when looking up Salesforce CLI sf commands — org login, project deploy,
|
|
5
|
+
apex run test, data query, package install, scratch org creation.
|
|
6
|
+
Do NOT use for web documentation lookup or Apex code patterns.
|
|
7
|
+
origin: SCC
|
|
8
|
+
user-invocable: true
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# SF CLI Command Reference
|
|
12
|
+
|
|
13
|
+
Reference: @../_reference/SF_CLI_COMMANDS.md
|
|
14
|
+
|
|
15
|
+
## When to Use
|
|
16
|
+
|
|
17
|
+
- When you need to find the right `sf` command for a Salesforce task
|
|
18
|
+
- When constructing CLI commands with correct flags and syntax
|
|
19
|
+
- When choosing between similar commands (e.g., deploy start vs deploy validate)
|
|
20
|
+
- When setting up org authentication (web, jwt, sfdx-url)
|
|
21
|
+
- When running Apex tests or querying data from the command line
|
|
22
|
+
- When managing scratch orgs, packages, or metadata via CLI
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## Command Decision Tree
|
|
27
|
+
|
|
28
|
+
### Authenticate to an Org
|
|
29
|
+
|
|
30
|
+
| Scenario | Command | Key Flags |
|
|
31
|
+
|---|---|---|
|
|
32
|
+
| Interactive browser login | `sf org login web` | `--alias`, `--set-default` |
|
|
33
|
+
| CI/CD non-interactive login | `sf org login jwt` | `--client-id`, `--jwt-key-file`, `--username` |
|
|
34
|
+
| Auth URL from file | `sf org login sfdx-url` | `--sfdx-url-file` |
|
|
35
|
+
| Log out of an org | `sf org logout` | `--target-org`, `--no-prompt` |
|
|
36
|
+
| List all connected orgs | `sf org list` | `--all` |
|
|
37
|
+
| Open org in browser | `sf org open` | `--target-org`, `--path` |
|
|
38
|
+
| Display org details | `sf org display` | `--target-org`, `--verbose` |
|
|
39
|
+
|
|
40
|
+
### Deploy or Retrieve Source
|
|
41
|
+
|
|
42
|
+
| Scenario | Command | Key Flags |
|
|
43
|
+
|---|---|---|
|
|
44
|
+
| Deploy source directory | `sf project deploy start` | `--source-dir`, `--target-org` |
|
|
45
|
+
| Deploy with manifest | `sf project deploy start` | `--manifest`, `--target-org` |
|
|
46
|
+
| Deploy specific metadata | `sf project deploy start` | `--metadata "ApexClass:MyClass"` |
|
|
47
|
+
| Validate without deploying | `sf project deploy validate` | `--test-level`, `--target-org` |
|
|
48
|
+
| Quick deploy after validation | `sf project deploy quick` | `--job-id`, `--target-org` |
|
|
49
|
+
| Check deploy status | `sf project deploy report` | `--job-id` |
|
|
50
|
+
| Resume failed deploy | `sf project deploy resume` | `--job-id` |
|
|
51
|
+
| Cancel in-progress deploy | `sf project deploy cancel` | `--job-id` |
|
|
52
|
+
| Retrieve from org | `sf project retrieve start` | `--source-dir`, `--target-org` |
|
|
53
|
+
| Retrieve by manifest | `sf project retrieve start` | `--manifest` |
|
|
54
|
+
| Preview retrieval | `sf project retrieve preview` | `--target-org` |
|
|
55
|
+
| Generate manifest | `sf project generate manifest` | `--source-dir`, `--output-dir` |
|
|
56
|
+
| Convert source to mdapi | `sf project convert source` | `--root-dir`, `--output-dir` |
|
|
57
|
+
| Convert mdapi to source | `sf project convert mdapi` | `--root-dir`, `--output-dir` |
|
|
58
|
+
| Create new project | `sf project generate` | `--name`, `--template` |
|
|
59
|
+
|
|
60
|
+
### Run Apex Code and Tests
|
|
61
|
+
|
|
62
|
+
| Scenario | Command | Key Flags |
|
|
63
|
+
|---|---|---|
|
|
64
|
+
| Execute anonymous Apex | `sf apex run` | `--file`, `--target-org` |
|
|
65
|
+
| Run all local tests | `sf apex run test` | `--test-level RunLocalTests` |
|
|
66
|
+
| Run specific test classes | `sf apex run test` | `--class-names "MyTest,OtherTest"` |
|
|
67
|
+
| Run specific test methods | `sf apex run test` | `--tests "MyTest.testMethod"` |
|
|
68
|
+
| Run tests with coverage | `sf apex run test` | `--code-coverage`, `--output-dir` |
|
|
69
|
+
| Run test suite | `sf apex run test` | `--suite-names "MySuite"` |
|
|
70
|
+
| Stream debug logs live | `sf apex tail log` | `--target-org`, `--debug-level` |
|
|
71
|
+
| Get a specific log | `sf apex get log` | `--log-id` |
|
|
72
|
+
| List recent logs | `sf apex list log` | `--target-org` |
|
|
73
|
+
|
|
74
|
+
### Work with Data
|
|
75
|
+
|
|
76
|
+
| Scenario | Command | Key Flags |
|
|
77
|
+
|---|---|---|
|
|
78
|
+
| Run SOQL query | `sf data query` | `--query`, `--target-org` |
|
|
79
|
+
| Run SOQL from file | `sf data query` | `--file`, `--result-format` |
|
|
80
|
+
| Bulk SOQL query | `sf data query` | `--query`, `--bulk`, `--wait` |
|
|
81
|
+
| Run SOSL search | `sf data search` | `--query` |
|
|
82
|
+
| Create a record | `sf data create record` | `--sobject`, `--values` |
|
|
83
|
+
| Update a record | `sf data update record` | `--sobject`, `--record-id`, `--values` |
|
|
84
|
+
| Delete a record | `sf data delete record` | `--sobject`, `--record-id` |
|
|
85
|
+
| Bulk upsert from CSV | `sf data upsert bulk` | `--file`, `--sobject`, `--external-id` |
|
|
86
|
+
| Bulk delete from CSV | `sf data delete bulk` | `--file`, `--sobject` |
|
|
87
|
+
| Export data as tree | `sf data export tree` | `--query`, `--plan` |
|
|
88
|
+
| Import tree data | `sf data import tree` | `--plan`, `--target-org` |
|
|
89
|
+
|
|
90
|
+
### Manage Scratch Orgs and Sandboxes
|
|
91
|
+
|
|
92
|
+
| Scenario | Command | Key Flags |
|
|
93
|
+
|---|---|---|
|
|
94
|
+
| Create scratch org | `sf org create scratch` | `--definition-file`, `--alias`, `--duration-days` |
|
|
95
|
+
| Delete scratch org | `sf org delete scratch` | `--target-org`, `--no-prompt` |
|
|
96
|
+
| Create sandbox | `sf org create sandbox` | `--name`, `--definition-file`, `--alias` |
|
|
97
|
+
| Clone sandbox | `sf org create sandbox` | `--clone`, `--name` |
|
|
98
|
+
| Delete sandbox | `sf org delete sandbox` | `--target-org`, `--no-prompt` |
|
|
99
|
+
| Resume sandbox creation | `sf org resume sandbox` | `--name`, `--target-org` |
|
|
100
|
+
| Assign permission set | `sf org assign permset` | `--name`, `--target-org` |
|
|
101
|
+
| Create user | `sf org create user` | `--definition-file`, `--target-org` |
|
|
102
|
+
|
|
103
|
+
### Manage Packages
|
|
104
|
+
|
|
105
|
+
| Scenario | Command | Key Flags |
|
|
106
|
+
|---|---|---|
|
|
107
|
+
| Create package | `sf package create` | `--name`, `--package-type`, `--path` |
|
|
108
|
+
| Create version | `sf package version create` | `--package`, `--installation-key`, `--code-coverage` |
|
|
109
|
+
| Promote version | `sf package version promote` | `--package` |
|
|
110
|
+
| Install package | `sf package install` | `--package`, `--target-org` |
|
|
111
|
+
| Uninstall package | `sf package uninstall` | `--package`, `--target-org` |
|
|
112
|
+
| List versions | `sf package version list` | `--packages`, `--verbose` |
|
|
113
|
+
| List installed | `sf package installed list` | `--target-org` |
|
|
114
|
+
|
|
115
|
+
### Work with Agentforce / AI Agents
|
|
116
|
+
|
|
117
|
+
| Scenario | Command | Key Flags |
|
|
118
|
+
|---|---|---|
|
|
119
|
+
| Create agent | `sf agent create` | `--target-org` |
|
|
120
|
+
| Generate agent spec | `sf agent generate spec` | `--output-dir` |
|
|
121
|
+
| Generate agent tests | `sf agent generate test` | `--spec-file`, `--output-dir` |
|
|
122
|
+
| Run agent tests | `sf agent test run` | `--name`, `--target-org` |
|
|
123
|
+
| Preview agent | `sf agent preview` | `--name`, `--target-org` |
|
|
124
|
+
| Activate agent | `sf agent activate` | `--target-org` |
|
|
125
|
+
| Deactivate agent | `sf agent deactivate` | `--target-org` |
|
|
126
|
+
|
|
127
|
+
> Note: `sf agent` commands are actively evolving. Run `sf agent <command> --help` for the latest flags.
|
|
128
|
+
|
|
129
|
+
### Generate Code from Templates
|
|
130
|
+
|
|
131
|
+
| Scenario | Command | Key Flags |
|
|
132
|
+
|---|---|---|
|
|
133
|
+
| Generate Apex class | `sf apex generate class` | `--name`, `--output-dir`, `--template` |
|
|
134
|
+
| Generate Apex trigger | `sf apex generate trigger` | `--name`, `--sobject`, `--output-dir` |
|
|
135
|
+
| Generate LWC | `sf lightning generate component` | `--name`, `--type lwc` |
|
|
136
|
+
| Generate Aura component | `sf lightning generate component` | `--name`, `--type aura` |
|
|
137
|
+
| Generate Lightning event | `sf lightning generate event` | `--name`, `--output-dir` |
|
|
138
|
+
| Generate SObject | `sf schema generate sobject` | `--label`, `--output-dir` |
|
|
139
|
+
| Generate field | `sf schema generate field` | `--label`, `--object` |
|
|
140
|
+
| Generate platform event | `sf schema generate platformevent` | `--label`, `--output-dir` |
|
|
141
|
+
| Generate project | `sf project generate` | `--name`, `--template` |
|
|
142
|
+
|
|
143
|
+
### Other Utilities
|
|
144
|
+
|
|
145
|
+
| Scenario | Command | Key Flags |
|
|
146
|
+
|---|---|---|
|
|
147
|
+
| Set default org | `sf config set` | `target-org=myOrg` |
|
|
148
|
+
| List config values | `sf config list` | |
|
|
149
|
+
| Set alias | `sf alias set` | `myAlias=user@org.com` |
|
|
150
|
+
| Describe SObject | `sf sobject describe` | `--sobject`, `--target-org` |
|
|
151
|
+
| List SObjects | `sf sobject list` | `--sobject-type`, `--target-org` |
|
|
152
|
+
| REST API request | `sf api request rest` | (URL path), `--method`, `--body` |
|
|
153
|
+
| GraphQL request | `sf api request graphql` | `--body` |
|
|
154
|
+
| Run Flow tests | `sf logic run test` | `--target-org` |
|
|
155
|
+
| Diagnose CLI issues | `sf doctor` | |
|
|
156
|
+
| Install plugin | `sf plugins install` | (plugin name) |
|
|
157
|
+
| Update CLI | `sf update` | |
|
|
158
|
+
| Show release notes | `sf info releasenotes display` | |
|
|
159
|
+
|
|
160
|
+
---
|
|
161
|
+
|
|
162
|
+
## Workflow Patterns
|
|
163
|
+
|
|
164
|
+
### Authentication + Deploy
|
|
165
|
+
|
|
166
|
+
```bash
|
|
167
|
+
# Login and deploy source
|
|
168
|
+
sf org login web --alias myOrg --set-default
|
|
169
|
+
sf project deploy start --source-dir force-app --target-org myOrg --wait 30
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
### CI/CD: Validate Then Quick Deploy
|
|
173
|
+
|
|
174
|
+
```bash
|
|
175
|
+
# Authenticate in CI
|
|
176
|
+
sf org login jwt \
|
|
177
|
+
--client-id $SF_CLIENT_ID \
|
|
178
|
+
--jwt-key-file server.key \
|
|
179
|
+
--username $SF_USERNAME \
|
|
180
|
+
--alias prod
|
|
181
|
+
|
|
182
|
+
# Validate (runs tests without committing)
|
|
183
|
+
sf project deploy validate \
|
|
184
|
+
--source-dir force-app \
|
|
185
|
+
--test-level RunLocalTests \
|
|
186
|
+
--target-org prod \
|
|
187
|
+
--wait 60
|
|
188
|
+
|
|
189
|
+
# Quick deploy after successful validation (use job ID from validation output)
|
|
190
|
+
sf project deploy quick --job-id $JOB_ID --target-org prod
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
### Scratch Org Development Cycle
|
|
194
|
+
|
|
195
|
+
```bash
|
|
196
|
+
# Create scratch org
|
|
197
|
+
sf org create scratch \
|
|
198
|
+
--definition-file config/project-scratch-def.json \
|
|
199
|
+
--alias dev \
|
|
200
|
+
--duration-days 7 \
|
|
201
|
+
--set-default
|
|
202
|
+
|
|
203
|
+
# Push source and assign permissions
|
|
204
|
+
sf project deploy start --source-dir force-app --target-org dev
|
|
205
|
+
sf org assign permset --name MyPermSet --target-org dev
|
|
206
|
+
|
|
207
|
+
# Import sample data
|
|
208
|
+
sf data import tree --plan data/sample-data-plan.json --target-org dev
|
|
209
|
+
|
|
210
|
+
# Run tests
|
|
211
|
+
sf apex run test --test-level RunLocalTests --target-org dev --code-coverage
|
|
212
|
+
|
|
213
|
+
# Clean up
|
|
214
|
+
sf org delete scratch --target-org dev --no-prompt
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
---
|
|
218
|
+
|
|
219
|
+
## Related
|
|
220
|
+
|
|
221
|
+
- **Skill**: `sf-deployment` -- detailed deployment strategies and error resolution
|
|
222
|
+
- **Skill**: `sf-devops-ci-cd` -- CI/CD pipeline setup with GitHub Actions
|
|
223
|
+
- **Skill**: `sf-debugging` -- debug log setup and analysis with CLI commands
|
|
224
|
+
- **Skill**: `sf-metadata-management` -- metadata types and source tracking
|
|
225
|
+
- **Skill**: `sf-docs-lookup` -- web search for official Salesforce documentation
|
|
@@ -27,7 +27,7 @@ Check what's installed in the current project:
|
|
|
27
27
|
|
|
28
28
|
```bash
|
|
29
29
|
# Check for SCC installation markers
|
|
30
|
-
ls -la .claude/hooks/ 2>/dev/null
|
|
30
|
+
ls -la .claude/hooks/scripts/ 2>/dev/null
|
|
31
31
|
ls -la .claude/agents/ 2>/dev/null
|
|
32
32
|
ls -la .claude/skills/ 2>/dev/null
|
|
33
33
|
```
|
|
@@ -47,7 +47,7 @@ Rate each category 0-10 using these rubrics:
|
|
|
47
47
|
| 7-8 | All standard profile hooks active |
|
|
48
48
|
| 9-10 | Strict profile enabled, all hooks active including Code Analyzer integration |
|
|
49
49
|
|
|
50
|
-
Check: `
|
|
50
|
+
Check: `npx scc-universal status` to see installed hooks and their profiles.
|
|
51
51
|
Check: `echo $SCC_HOOK_PROFILE` to verify profile level.
|
|
52
52
|
|
|
53
53
|
**Agent Coverage (0-10)**
|
|
@@ -105,7 +105,7 @@ Based on the project state, suggest 3-5 commands to start with:
|
|
|
105
105
|
| Low test coverage | `sf-apex-testing` skill -- analyze gaps |
|
|
106
106
|
| Deployment files present | `sf-deployment` skill -- pre-deployment check |
|
|
107
107
|
| Security review needed | `sf-security` skill -- full security audit |
|
|
108
|
-
| Build errors |
|
|
108
|
+
| Build errors | `sf-build-fix` -- fix build and deployment errors |
|
|
109
109
|
| Any project | `/sf-help` -- browse all available commands and skills |
|
|
110
110
|
|
|
111
111
|
### Step 5 — Verify SCC Installation
|
package/.cursor/hooks/adapter.js
DELETED
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
3
|
-
* Cursor-to-Claude Code Hook Adapter
|
|
4
|
-
* Transforms Cursor stdin JSON to Claude Code hook format,
|
|
5
|
-
* then delegates to existing scripts/hooks/*.js
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
const { execFileSync } = require('child_process');
|
|
9
|
-
const path = require('path');
|
|
10
|
-
|
|
11
|
-
const MAX_STDIN = 1024 * 1024;
|
|
12
|
-
|
|
13
|
-
function readStdin() {
|
|
14
|
-
return new Promise((resolve) => {
|
|
15
|
-
let data = '';
|
|
16
|
-
process.stdin.setEncoding('utf8');
|
|
17
|
-
process.stdin.on('data', chunk => {
|
|
18
|
-
if (data.length < MAX_STDIN) data += chunk.substring(0, MAX_STDIN - data.length);
|
|
19
|
-
});
|
|
20
|
-
process.stdin.on('end', () => resolve(data));
|
|
21
|
-
});
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
function getPluginRoot() {
|
|
25
|
-
return path.resolve(__dirname, '..', '..');
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
function transformToClaude(cursorInput, overrides = {}) {
|
|
29
|
-
return {
|
|
30
|
-
tool_input: {
|
|
31
|
-
command: cursorInput.command || cursorInput.args?.command || '',
|
|
32
|
-
file_path: cursorInput.path || cursorInput.file || cursorInput.args?.filePath || '',
|
|
33
|
-
...overrides.tool_input,
|
|
34
|
-
},
|
|
35
|
-
tool_output: {
|
|
36
|
-
output: cursorInput.output || cursorInput.result || '',
|
|
37
|
-
...overrides.tool_output,
|
|
38
|
-
},
|
|
39
|
-
transcript_path: cursorInput.transcript_path || cursorInput.transcriptPath || cursorInput.session?.transcript_path || '',
|
|
40
|
-
_cursor: {
|
|
41
|
-
conversation_id: cursorInput.conversation_id,
|
|
42
|
-
hook_event_name: cursorInput.hook_event_name,
|
|
43
|
-
workspace_roots: cursorInput.workspace_roots,
|
|
44
|
-
model: cursorInput.model,
|
|
45
|
-
},
|
|
46
|
-
};
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
function runExistingHook(scriptName, stdinData) {
|
|
50
|
-
const scriptPath = path.join(getPluginRoot(), 'scripts', 'hooks', scriptName);
|
|
51
|
-
try {
|
|
52
|
-
execFileSync('node', [scriptPath], {
|
|
53
|
-
input: typeof stdinData === 'string' ? stdinData : JSON.stringify(stdinData),
|
|
54
|
-
stdio: ['pipe', 'pipe', 'pipe'],
|
|
55
|
-
timeout: 15000,
|
|
56
|
-
cwd: process.cwd(),
|
|
57
|
-
});
|
|
58
|
-
} catch (e) {
|
|
59
|
-
if (e.status === 2) process.exit(2); // Forward blocking exit code
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
function hookEnabled(hookId, allowedProfiles = ['standard', 'strict']) {
|
|
64
|
-
const rawProfile = String(process.env.SCC_HOOK_PROFILE || 'standard').toLowerCase();
|
|
65
|
-
const profile = ['minimal', 'standard', 'strict'].includes(rawProfile) ? rawProfile : 'standard';
|
|
66
|
-
|
|
67
|
-
const disabled = new Set(
|
|
68
|
-
String(process.env.SCC_DISABLED_HOOKS || '')
|
|
69
|
-
.split(',')
|
|
70
|
-
.map(v => v.trim().toLowerCase())
|
|
71
|
-
.filter(Boolean)
|
|
72
|
-
);
|
|
73
|
-
|
|
74
|
-
if (disabled.has(String(hookId || '').toLowerCase())) {
|
|
75
|
-
return false;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
return allowedProfiles.includes(profile);
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
module.exports = { readStdin, getPluginRoot, transformToClaude, runExistingHook, hookEnabled };
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
const { readStdin, runExistingHook, transformToClaude, hookEnabled } = require('./adapter');
|
|
3
|
-
readStdin().then(raw => {
|
|
4
|
-
try {
|
|
5
|
-
const input = JSON.parse(raw);
|
|
6
|
-
const claudeInput = transformToClaude(input, {
|
|
7
|
-
tool_input: { file_path: input.path || input.file || '' }
|
|
8
|
-
});
|
|
9
|
-
const claudeStr = JSON.stringify(claudeInput);
|
|
10
|
-
|
|
11
|
-
// Run quality-gate, governor-check, console.log warning, and format sequentially
|
|
12
|
-
if (hookEnabled('post:edit:quality-gate', ['standard', 'strict'])) {
|
|
13
|
-
runExistingHook('quality-gate.js', claudeStr);
|
|
14
|
-
}
|
|
15
|
-
if (hookEnabled('post:edit:governor-check', ['standard', 'strict'])) {
|
|
16
|
-
runExistingHook('governor-check.js', claudeStr);
|
|
17
|
-
}
|
|
18
|
-
if (hookEnabled('post:edit:console-warn', ['standard', 'strict'])) {
|
|
19
|
-
runExistingHook('post-edit-console-warn.js', claudeStr);
|
|
20
|
-
}
|
|
21
|
-
if (hookEnabled('post:edit:format', ['strict'])) {
|
|
22
|
-
runExistingHook('post-edit-format.js', claudeStr);
|
|
23
|
-
}
|
|
24
|
-
} catch {}
|
|
25
|
-
process.stdout.write(raw);
|
|
26
|
-
}).catch(() => process.exit(0));
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
const { readStdin } = require('./adapter');
|
|
3
|
-
readStdin().then(raw => {
|
|
4
|
-
try {
|
|
5
|
-
const input = JSON.parse(raw);
|
|
6
|
-
const server = input.server || input.mcp_server || 'unknown';
|
|
7
|
-
const tool = input.tool || input.mcp_tool || 'unknown';
|
|
8
|
-
const success = input.error ? 'FAILED' : 'OK';
|
|
9
|
-
console.error(`[SCC] MCP result: ${server}/${tool} - ${success}`);
|
|
10
|
-
} catch {}
|
|
11
|
-
process.stdout.write(raw);
|
|
12
|
-
}).catch(() => process.exit(0));
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
const { readStdin, hookEnabled } = require('./adapter');
|
|
3
|
-
|
|
4
|
-
readStdin().then(raw => {
|
|
5
|
-
try {
|
|
6
|
-
const input = JSON.parse(raw || '{}');
|
|
7
|
-
const cmd = String(input.command || input.args?.command || '');
|
|
8
|
-
const output = String(input.output || input.result || '');
|
|
9
|
-
|
|
10
|
-
if (hookEnabled('post:bash:pr-created', ['standard', 'strict']) && /\bgh\s+pr\s+create\b/.test(cmd)) {
|
|
11
|
-
const m = output.match(/https:\/\/github\.com\/[^/]+\/[^/]+\/pull\/\d+/);
|
|
12
|
-
if (m) {
|
|
13
|
-
console.error('[SCC] PR created: ' + m[0]);
|
|
14
|
-
const repo = m[0].replace(/https:\/\/github\.com\/([^/]+\/[^/]+)\/pull\/\d+/, '$1');
|
|
15
|
-
const pr = m[0].replace(/.+\/pull\/(\d+)/, '$1');
|
|
16
|
-
console.error('[SCC] To review: gh pr review ' + pr + ' --repo ' + repo);
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
if (hookEnabled('post:bash:build-complete', ['standard', 'strict'])) {
|
|
21
|
-
if (/(sf\s+project\s+deploy|sf\s+deploy|sfdx\s+force:source:deploy|npm run build|pnpm build|yarn build)/.test(cmd)) {
|
|
22
|
-
console.error('[SCC] Build/deploy completed — review results above');
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
} catch {
|
|
26
|
-
// noop
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
process.stdout.write(raw);
|
|
30
|
-
}).catch(() => process.exit(0));
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
const { readStdin, runExistingHook, transformToClaude } = require('./adapter');
|
|
3
|
-
readStdin().then(raw => {
|
|
4
|
-
try {
|
|
5
|
-
const input = JSON.parse(raw);
|
|
6
|
-
const claudeInput = transformToClaude(input, {
|
|
7
|
-
tool_input: { file_path: input.path || input.file || '' }
|
|
8
|
-
});
|
|
9
|
-
runExistingHook('post-edit-format.js', JSON.stringify(claudeInput));
|
|
10
|
-
} catch {}
|
|
11
|
-
process.stdout.write(raw);
|
|
12
|
-
}).catch(() => process.exit(0));
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
const { readStdin } = require('./adapter');
|
|
3
|
-
readStdin().then(raw => {
|
|
4
|
-
try {
|
|
5
|
-
const input = JSON.parse(raw);
|
|
6
|
-
const server = input.server || input.mcp_server || 'unknown';
|
|
7
|
-
const tool = input.tool || input.mcp_tool || 'unknown';
|
|
8
|
-
console.error(`[SCC] MCP invocation: ${server}/${tool}`);
|
|
9
|
-
} catch {}
|
|
10
|
-
process.stdout.write(raw);
|
|
11
|
-
}).catch(() => process.exit(0));
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
const { readStdin } = require('./adapter');
|
|
3
|
-
readStdin().then(raw => {
|
|
4
|
-
try {
|
|
5
|
-
const input = JSON.parse(raw);
|
|
6
|
-
const filePath = input.path || input.file || '';
|
|
7
|
-
if (/\.(env|key|pem)$|\.env\.|credentials|secret/i.test(filePath)) {
|
|
8
|
-
console.error('[SCC] WARNING: Reading sensitive file: ' + filePath);
|
|
9
|
-
console.error('[SCC] Ensure this data is not exposed in outputs');
|
|
10
|
-
}
|
|
11
|
-
} catch {}
|
|
12
|
-
process.stdout.write(raw);
|
|
13
|
-
}).catch(() => process.exit(0));
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
const { readStdin, runExistingHook, transformToClaude, hookEnabled } = require('./adapter');
|
|
3
|
-
|
|
4
|
-
readStdin()
|
|
5
|
-
.then(raw => {
|
|
6
|
-
try {
|
|
7
|
-
const input = JSON.parse(raw || '{}');
|
|
8
|
-
const cmd = String(input.command || input.args?.command || '');
|
|
9
|
-
|
|
10
|
-
// SFDX validation
|
|
11
|
-
if (hookEnabled('pre:bash:sfdx-validate', ['standard', 'strict']) && (/\bsf\s/.test(cmd) || /\bsfdx\s/.test(cmd))) {
|
|
12
|
-
const claudeInput = transformToClaude(input, {
|
|
13
|
-
tool_input: { command: cmd }
|
|
14
|
-
});
|
|
15
|
-
claudeInput.tool_name = 'Bash';
|
|
16
|
-
runExistingHook('sfdx-validate.js', JSON.stringify(claudeInput));
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
// Git push reminder
|
|
20
|
-
if (hookEnabled('pre:bash:git-push-reminder', ['standard', 'strict']) && /\bgit\s+push\b/.test(cmd)) {
|
|
21
|
-
console.error('[SCC] Review changes before push: git diff origin/main...HEAD');
|
|
22
|
-
}
|
|
23
|
-
} catch {
|
|
24
|
-
// noop
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
process.stdout.write(raw);
|
|
28
|
-
})
|
|
29
|
-
.catch(() => process.exit(0));
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
const { readStdin } = require('./adapter');
|
|
3
|
-
readStdin().then(raw => {
|
|
4
|
-
try {
|
|
5
|
-
const input = JSON.parse(raw);
|
|
6
|
-
const prompt = input.prompt || input.content || input.message || '';
|
|
7
|
-
const secretPatterns = [
|
|
8
|
-
/sk-[a-zA-Z0-9]{20,}/, // OpenAI API keys
|
|
9
|
-
/ghp_[a-zA-Z0-9]{36,}/, // GitHub personal access tokens
|
|
10
|
-
/AKIA[A-Z0-9]{16}/, // AWS access keys
|
|
11
|
-
/xox[bpsa]-[a-zA-Z0-9-]+/, // Slack tokens
|
|
12
|
-
/-----BEGIN (RSA |EC )?PRIVATE KEY-----/, // Private keys
|
|
13
|
-
];
|
|
14
|
-
for (const pattern of secretPatterns) {
|
|
15
|
-
if (pattern.test(prompt)) {
|
|
16
|
-
console.error('[SCC] WARNING: Potential secret detected in prompt!');
|
|
17
|
-
console.error('[SCC] Remove secrets before submitting. Use environment variables instead.');
|
|
18
|
-
break;
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
} catch {}
|
|
22
|
-
process.stdout.write(raw);
|
|
23
|
-
}).catch(() => process.exit(0));
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
const { readStdin, runExistingHook, transformToClaude } = require('./adapter');
|
|
3
|
-
readStdin().then(raw => {
|
|
4
|
-
const claudeInput = JSON.parse(raw || '{}');
|
|
5
|
-
runExistingHook('pre-compact.js', transformToClaude(claudeInput));
|
|
6
|
-
process.stdout.write(raw);
|
|
7
|
-
}).catch(() => process.exit(0));
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
const { readStdin, runExistingHook, transformToClaude, hookEnabled } = require('./adapter');
|
|
3
|
-
readStdin().then(raw => {
|
|
4
|
-
const input = JSON.parse(raw || '{}');
|
|
5
|
-
const claudeInput = transformToClaude(input);
|
|
6
|
-
if (hookEnabled('session:end:marker', ['minimal', 'standard', 'strict'])) {
|
|
7
|
-
runExistingHook('session-end-marker.js', claudeInput);
|
|
8
|
-
}
|
|
9
|
-
process.stdout.write(raw);
|
|
10
|
-
}).catch(() => process.exit(0));
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
const { readStdin, runExistingHook, transformToClaude, hookEnabled } = require('./adapter');
|
|
3
|
-
readStdin().then(raw => {
|
|
4
|
-
const input = JSON.parse(raw || '{}');
|
|
5
|
-
const claudeInput = transformToClaude(input);
|
|
6
|
-
if (hookEnabled('session:start', ['minimal', 'standard', 'strict'])) {
|
|
7
|
-
runExistingHook('session-start.js', claudeInput);
|
|
8
|
-
}
|
|
9
|
-
process.stdout.write(raw);
|
|
10
|
-
}).catch(() => process.exit(0));
|
package/.cursor/hooks/stop.js
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
const { readStdin, runExistingHook, transformToClaude, hookEnabled } = require('./adapter');
|
|
3
|
-
readStdin().then(raw => {
|
|
4
|
-
const input = JSON.parse(raw || '{}');
|
|
5
|
-
const claudeInput = transformToClaude(input);
|
|
6
|
-
|
|
7
|
-
if (hookEnabled('stop:check-console-log', ['standard', 'strict'])) {
|
|
8
|
-
runExistingHook('check-console-log.js', claudeInput);
|
|
9
|
-
}
|
|
10
|
-
if (hookEnabled('stop:session-end', ['minimal', 'standard', 'strict'])) {
|
|
11
|
-
runExistingHook('session-end.js', claudeInput);
|
|
12
|
-
}
|
|
13
|
-
if (hookEnabled('stop:cost-tracker', ['minimal', 'standard', 'strict'])) {
|
|
14
|
-
runExistingHook('cost-tracker.js', claudeInput);
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
process.stdout.write(raw);
|
|
18
|
-
}).catch(() => process.exit(0));
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
const { readStdin } = require('./adapter');
|
|
3
|
-
readStdin().then(raw => {
|
|
4
|
-
try {
|
|
5
|
-
const input = JSON.parse(raw);
|
|
6
|
-
const agent = input.agent_name || input.agent || 'unknown';
|
|
7
|
-
console.error(`[SCC] Agent spawned: ${agent}`);
|
|
8
|
-
} catch {}
|
|
9
|
-
process.stdout.write(raw);
|
|
10
|
-
}).catch(() => process.exit(0));
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
const { readStdin } = require('./adapter');
|
|
3
|
-
readStdin().then(raw => {
|
|
4
|
-
try {
|
|
5
|
-
const input = JSON.parse(raw);
|
|
6
|
-
const agent = input.agent_name || input.agent || 'unknown';
|
|
7
|
-
console.error(`[SCC] Agent completed: ${agent}`);
|
|
8
|
-
} catch {}
|
|
9
|
-
process.stdout.write(raw);
|
|
10
|
-
}).catch(() => process.exit(0));
|