scc-universal 1.1.0 → 1.2.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 +2 -2
- package/.cursor/hooks.json +105 -64
- package/.cursor/skills/configure-scc/SKILL.md +20 -20
- package/.cursor/skills/mcp-server-patterns/SKILL.md +1 -1
- package/.cursor/skills/sf-harness-audit/SKILL.md +6 -6
- package/.cursor/skills/sf-quickstart/SKILL.md +7 -7
- package/.cursor-plugin/plugin.json +2 -2
- package/README.md +51 -37
- package/docs/ARCHITECTURE.md +4 -4
- package/docs/authoring-guide.md +2 -2
- package/docs/workflow-examples.md +38 -38
- package/hooks/hooks.json +56 -71
- package/manifests/install-modules.json +5 -3
- package/package.json +4 -3
- package/schemas/hooks.schema.json +83 -72
- package/schemas/plugin.schema.json +59 -21
- package/scripts/cli/install-apply.js +9 -9
- package/scripts/hooks/doc-file-warning.js +3 -1
- package/scripts/hooks/governor-check.js +3 -2
- package/scripts/hooks/post-bash-build-complete.js +3 -2
- package/scripts/hooks/post-bash-pr-created.js +4 -2
- package/scripts/hooks/post-edit-console-warn.js +3 -1
- package/scripts/hooks/post-edit-format.js +3 -2
- package/scripts/hooks/post-edit-typecheck.js +3 -2
- package/scripts/hooks/post-write.js +3 -1
- package/scripts/hooks/pre-bash-git-push-reminder.js +3 -2
- package/scripts/hooks/pre-bash-tmux-reminder.js +3 -1
- package/scripts/hooks/pre-tool-use.js +3 -1
- package/scripts/hooks/quality-gate.js +3 -2
- package/scripts/hooks/sfdx-scanner-check.js +3 -1
- package/scripts/hooks/sfdx-validate.js +3 -1
- package/scripts/lib/hook-input.js +105 -0
- package/scripts/lib/hooks-adapter.js +265 -0
- package/scripts/lib/install-executor.js +153 -1
- package/scripts/scc.js +14 -14
- package/skills/configure-scc/SKILL.md +20 -20
- package/skills/mcp-server-patterns/SKILL.md +1 -1
- package/skills/sf-harness-audit/SKILL.md +6 -6
- package/skills/sf-quickstart/SKILL.md +7 -7
|
@@ -5,119 +5,130 @@
|
|
|
5
5
|
"description": "JSON Schema for SCC hooks.json — defines Claude Code lifecycle hooks for Salesforce development",
|
|
6
6
|
"type": "object",
|
|
7
7
|
"required": ["hooks"],
|
|
8
|
-
"additionalProperties": false,
|
|
9
8
|
"properties": {
|
|
10
|
-
"
|
|
9
|
+
"description": {
|
|
11
10
|
"type": "string",
|
|
12
|
-
"description": "
|
|
11
|
+
"description": "Top-level description of this hooks configuration (plugin hooks only)"
|
|
13
12
|
},
|
|
14
13
|
"hooks": {
|
|
15
14
|
"type": "object",
|
|
16
15
|
"description": "Map of lifecycle event names to arrays of hook group definitions",
|
|
17
|
-
"additionalProperties": false,
|
|
18
16
|
"properties": {
|
|
19
|
-
"SessionStart": {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
},
|
|
23
|
-
"
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
},
|
|
27
|
-
"
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
},
|
|
31
|
-
"
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
},
|
|
35
|
-
"
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
},
|
|
39
|
-
"
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
},
|
|
43
|
-
"
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
}
|
|
17
|
+
"SessionStart": { "$ref": "#/definitions/hookGroupArray" },
|
|
18
|
+
"UserPromptSubmit": { "$ref": "#/definitions/hookGroupArray" },
|
|
19
|
+
"PreToolUse": { "$ref": "#/definitions/hookGroupArray" },
|
|
20
|
+
"PermissionRequest": { "$ref": "#/definitions/hookGroupArray" },
|
|
21
|
+
"PermissionDenied": { "$ref": "#/definitions/hookGroupArray" },
|
|
22
|
+
"PostToolUse": { "$ref": "#/definitions/hookGroupArray" },
|
|
23
|
+
"PostToolUseFailure": { "$ref": "#/definitions/hookGroupArray" },
|
|
24
|
+
"Notification": { "$ref": "#/definitions/hookGroupArray" },
|
|
25
|
+
"SubagentStart": { "$ref": "#/definitions/hookGroupArray" },
|
|
26
|
+
"SubagentStop": { "$ref": "#/definitions/hookGroupArray" },
|
|
27
|
+
"TaskCreated": { "$ref": "#/definitions/hookGroupArray" },
|
|
28
|
+
"TaskCompleted": { "$ref": "#/definitions/hookGroupArray" },
|
|
29
|
+
"Stop": { "$ref": "#/definitions/hookGroupArray" },
|
|
30
|
+
"StopFailure": { "$ref": "#/definitions/hookGroupArray" },
|
|
31
|
+
"TeammateIdle": { "$ref": "#/definitions/hookGroupArray" },
|
|
32
|
+
"InstructionsLoaded": { "$ref": "#/definitions/hookGroupArray" },
|
|
33
|
+
"ConfigChange": { "$ref": "#/definitions/hookGroupArray" },
|
|
34
|
+
"CwdChanged": { "$ref": "#/definitions/hookGroupArray" },
|
|
35
|
+
"FileChanged": { "$ref": "#/definitions/hookGroupArray" },
|
|
36
|
+
"WorktreeCreate": { "$ref": "#/definitions/hookGroupArray" },
|
|
37
|
+
"WorktreeRemove": { "$ref": "#/definitions/hookGroupArray" },
|
|
38
|
+
"PreCompact": { "$ref": "#/definitions/hookGroupArray" },
|
|
39
|
+
"PostCompact": { "$ref": "#/definitions/hookGroupArray" },
|
|
40
|
+
"Elicitation": { "$ref": "#/definitions/hookGroupArray" },
|
|
41
|
+
"ElicitationResult": { "$ref": "#/definitions/hookGroupArray" },
|
|
42
|
+
"SessionEnd": { "$ref": "#/definitions/hookGroupArray" }
|
|
43
|
+
},
|
|
44
|
+
"additionalProperties": false
|
|
48
45
|
}
|
|
49
46
|
},
|
|
50
47
|
"definitions": {
|
|
51
48
|
"hookGroupArray": {
|
|
52
49
|
"type": "array",
|
|
53
|
-
"items": {
|
|
54
|
-
"$ref": "#/definitions/hookGroup"
|
|
55
|
-
},
|
|
50
|
+
"items": { "$ref": "#/definitions/hookGroup" },
|
|
56
51
|
"minItems": 1
|
|
57
52
|
},
|
|
58
53
|
"hookGroup": {
|
|
59
54
|
"type": "object",
|
|
60
55
|
"required": ["hooks"],
|
|
61
|
-
"additionalProperties": false,
|
|
62
56
|
"properties": {
|
|
63
57
|
"matcher": {
|
|
64
58
|
"type": "string",
|
|
65
|
-
"description": "
|
|
59
|
+
"description": "Regex pattern to filter when hooks fire. Use tool name for tool events, source for SessionStart, etc."
|
|
66
60
|
},
|
|
67
61
|
"hooks": {
|
|
68
62
|
"type": "array",
|
|
69
|
-
"
|
|
70
|
-
"items": {
|
|
71
|
-
"$ref": "#/definitions/hookDefinition"
|
|
72
|
-
},
|
|
63
|
+
"items": { "$ref": "#/definitions/hookDefinition" },
|
|
73
64
|
"minItems": 1
|
|
74
|
-
},
|
|
75
|
-
"description": {
|
|
76
|
-
"type": "string",
|
|
77
|
-
"description": "Human-readable description of this hook group"
|
|
78
|
-
},
|
|
79
|
-
"profile": {
|
|
80
|
-
"type": "string",
|
|
81
|
-
"enum": ["minimal", "standard", "strict"],
|
|
82
|
-
"description": "Minimum profile level required for this hook group to run"
|
|
83
65
|
}
|
|
84
|
-
}
|
|
66
|
+
},
|
|
67
|
+
"additionalProperties": false
|
|
85
68
|
},
|
|
86
69
|
"hookDefinition": {
|
|
87
70
|
"type": "object",
|
|
88
|
-
"required": ["type"
|
|
89
|
-
"additionalProperties": false,
|
|
71
|
+
"required": ["type"],
|
|
90
72
|
"properties": {
|
|
91
73
|
"type": {
|
|
92
74
|
"type": "string",
|
|
93
|
-
"enum": ["command"],
|
|
94
|
-
"description": "Hook execution type
|
|
75
|
+
"enum": ["command", "http", "prompt", "agent"],
|
|
76
|
+
"description": "Hook execution type"
|
|
95
77
|
},
|
|
96
78
|
"command": {
|
|
97
79
|
"type": "string",
|
|
98
|
-
"description": "Shell command to execute
|
|
99
|
-
"minLength": 1
|
|
80
|
+
"description": "Shell command to execute (type: command)"
|
|
100
81
|
},
|
|
101
|
-
"
|
|
102
|
-
"type": "
|
|
103
|
-
"description": "
|
|
104
|
-
|
|
82
|
+
"url": {
|
|
83
|
+
"type": "string",
|
|
84
|
+
"description": "URL to POST to (type: http)"
|
|
85
|
+
},
|
|
86
|
+
"prompt": {
|
|
87
|
+
"type": "string",
|
|
88
|
+
"description": "Prompt text for LLM evaluation (type: prompt or agent)"
|
|
89
|
+
},
|
|
90
|
+
"model": {
|
|
91
|
+
"type": "string",
|
|
92
|
+
"description": "Model to use for prompt/agent hooks"
|
|
93
|
+
},
|
|
94
|
+
"if": {
|
|
95
|
+
"type": "string",
|
|
96
|
+
"description": "Permission rule syntax filter, e.g. Bash(git *) or Edit(*.cls)"
|
|
105
97
|
},
|
|
106
98
|
"timeout": {
|
|
107
99
|
"type": "integer",
|
|
108
|
-
"description": "Timeout in seconds
|
|
109
|
-
"minimum": 1
|
|
110
|
-
"maximum": 120,
|
|
111
|
-
"default": 30
|
|
100
|
+
"description": "Timeout in seconds",
|
|
101
|
+
"minimum": 1
|
|
112
102
|
},
|
|
113
|
-
"
|
|
103
|
+
"async": {
|
|
104
|
+
"type": "boolean",
|
|
105
|
+
"description": "Run in background without blocking (command hooks only)"
|
|
106
|
+
},
|
|
107
|
+
"shell": {
|
|
108
|
+
"type": "string",
|
|
109
|
+
"enum": ["bash", "powershell"],
|
|
110
|
+
"description": "Shell to use (command hooks only)"
|
|
111
|
+
},
|
|
112
|
+
"statusMessage": {
|
|
113
|
+
"type": "string",
|
|
114
|
+
"description": "Custom spinner message while hook runs"
|
|
115
|
+
},
|
|
116
|
+
"once": {
|
|
117
|
+
"type": "boolean",
|
|
118
|
+
"description": "Run only once per session (skills/agents only)"
|
|
119
|
+
},
|
|
120
|
+
"headers": {
|
|
114
121
|
"type": "object",
|
|
115
|
-
"description": "
|
|
116
|
-
"additionalProperties": {
|
|
117
|
-
|
|
118
|
-
|
|
122
|
+
"description": "HTTP headers (type: http)",
|
|
123
|
+
"additionalProperties": { "type": "string" }
|
|
124
|
+
},
|
|
125
|
+
"allowedEnvVars": {
|
|
126
|
+
"type": "array",
|
|
127
|
+
"description": "Env vars allowed in header interpolation (type: http)",
|
|
128
|
+
"items": { "type": "string" }
|
|
119
129
|
}
|
|
120
|
-
}
|
|
130
|
+
},
|
|
131
|
+
"additionalProperties": false
|
|
121
132
|
}
|
|
122
133
|
}
|
|
123
134
|
}
|
|
@@ -2,10 +2,9 @@
|
|
|
2
2
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
3
|
"$id": "https://scc-universal/schemas/plugin.schema.json",
|
|
4
4
|
"title": "SCC Plugin Manifest",
|
|
5
|
-
"description": "JSON Schema for
|
|
5
|
+
"description": "JSON Schema for plugin.json — describes the SCC plugin for Claude Code and Cursor marketplaces",
|
|
6
6
|
"type": "object",
|
|
7
|
-
"required": ["name", "version", "
|
|
8
|
-
"additionalProperties": false,
|
|
7
|
+
"required": ["name", "version", "description"],
|
|
9
8
|
"properties": {
|
|
10
9
|
"$schema": {
|
|
11
10
|
"type": "string",
|
|
@@ -35,13 +34,27 @@
|
|
|
35
34
|
"maxLength": 300
|
|
36
35
|
},
|
|
37
36
|
"author": {
|
|
38
|
-
"
|
|
39
|
-
|
|
37
|
+
"oneOf": [
|
|
38
|
+
{
|
|
39
|
+
"type": "string",
|
|
40
|
+
"description": "Plugin author name or organization"
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
"type": "object",
|
|
44
|
+
"description": "Plugin author details",
|
|
45
|
+
"required": ["name"],
|
|
46
|
+
"properties": {
|
|
47
|
+
"name": { "type": "string" },
|
|
48
|
+
"email": { "type": "string", "format": "email" },
|
|
49
|
+
"url": { "type": "string", "format": "uri" }
|
|
50
|
+
},
|
|
51
|
+
"additionalProperties": false
|
|
52
|
+
}
|
|
53
|
+
]
|
|
40
54
|
},
|
|
41
55
|
"license": {
|
|
42
56
|
"type": "string",
|
|
43
|
-
"description": "SPDX license identifier"
|
|
44
|
-
"enum": ["MIT", "Apache-2.0", "BSD-2-Clause", "BSD-3-Clause", "ISC", "GPL-3.0", "LGPL-3.0", "MPL-2.0"]
|
|
57
|
+
"description": "SPDX license identifier"
|
|
45
58
|
},
|
|
46
59
|
"keywords": {
|
|
47
60
|
"type": "array",
|
|
@@ -53,15 +66,17 @@
|
|
|
53
66
|
"minItems": 1,
|
|
54
67
|
"maxItems": 20
|
|
55
68
|
},
|
|
69
|
+
"logo": {
|
|
70
|
+
"type": "string",
|
|
71
|
+
"description": "Relative path to the plugin logo image (SVG or PNG)"
|
|
72
|
+
},
|
|
56
73
|
"engines": {
|
|
57
74
|
"type": "object",
|
|
58
75
|
"description": "Required harness versions",
|
|
59
|
-
"additionalProperties": false,
|
|
60
76
|
"properties": {
|
|
61
77
|
"claude-code": {
|
|
62
78
|
"type": "string",
|
|
63
|
-
"description": "Required Claude Code version (semver range)"
|
|
64
|
-
"pattern": "^[>=^~]?\\d+\\.\\d+\\.\\d+.*$"
|
|
79
|
+
"description": "Required Claude Code version (semver range)"
|
|
65
80
|
},
|
|
66
81
|
"node": {
|
|
67
82
|
"type": "string",
|
|
@@ -71,17 +86,37 @@
|
|
|
71
86
|
},
|
|
72
87
|
"main": {
|
|
73
88
|
"type": "string",
|
|
74
|
-
"description": "Relative path to the primary plugin entry file
|
|
89
|
+
"description": "Relative path to the primary plugin entry file",
|
|
75
90
|
"minLength": 1
|
|
76
91
|
},
|
|
77
92
|
"agents": {
|
|
78
|
-
"
|
|
79
|
-
|
|
93
|
+
"oneOf": [
|
|
94
|
+
{
|
|
95
|
+
"type": "string",
|
|
96
|
+
"description": "Relative path to agents directory"
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
"type": "array",
|
|
100
|
+
"description": "Array of relative paths to individual agent files",
|
|
101
|
+
"items": {
|
|
102
|
+
"type": "string",
|
|
103
|
+
"minLength": 1
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
]
|
|
80
107
|
},
|
|
81
108
|
"skills": {
|
|
82
109
|
"type": "string",
|
|
83
110
|
"description": "Relative path to skills directory"
|
|
84
111
|
},
|
|
112
|
+
"hooks": {
|
|
113
|
+
"type": "string",
|
|
114
|
+
"description": "Relative path to hooks configuration file"
|
|
115
|
+
},
|
|
116
|
+
"mcpServers": {
|
|
117
|
+
"type": "string",
|
|
118
|
+
"description": "Relative path to MCP servers configuration file"
|
|
119
|
+
},
|
|
85
120
|
"commands": {
|
|
86
121
|
"type": "string",
|
|
87
122
|
"description": "Relative path to commands directory"
|
|
@@ -91,17 +126,20 @@
|
|
|
91
126
|
"description": "Relative path to rules directory"
|
|
92
127
|
},
|
|
93
128
|
"repository": {
|
|
94
|
-
"
|
|
95
|
-
|
|
96
|
-
"properties": {
|
|
97
|
-
"type": {
|
|
129
|
+
"oneOf": [
|
|
130
|
+
{
|
|
98
131
|
"type": "string",
|
|
99
|
-
"
|
|
132
|
+
"description": "Repository URL"
|
|
100
133
|
},
|
|
101
|
-
|
|
102
|
-
"type": "
|
|
134
|
+
{
|
|
135
|
+
"type": "object",
|
|
136
|
+
"description": "Source repository information",
|
|
137
|
+
"properties": {
|
|
138
|
+
"type": { "type": "string", "enum": ["git", "svn"] },
|
|
139
|
+
"url": { "type": "string" }
|
|
140
|
+
}
|
|
103
141
|
}
|
|
104
|
-
|
|
142
|
+
]
|
|
105
143
|
},
|
|
106
144
|
"homepage": {
|
|
107
145
|
"type": "string",
|
|
@@ -17,11 +17,11 @@ const { loadInstallConfig } = require('../lib/install-config');
|
|
|
17
17
|
|
|
18
18
|
function showHelp(exitCode = 0) {
|
|
19
19
|
console.log(`
|
|
20
|
-
scc install — Install SCC content
|
|
20
|
+
scc-universal install — Install SCC content
|
|
21
21
|
|
|
22
22
|
Usage:
|
|
23
|
-
scc install [target] [options]
|
|
24
|
-
scc install --profile <name> --target <name>
|
|
23
|
+
scc-universal install [target] [options]
|
|
24
|
+
scc-universal install --profile <name> --target <name>
|
|
25
25
|
|
|
26
26
|
Shorthand targets:
|
|
27
27
|
apex Install Apex profile content
|
|
@@ -37,12 +37,12 @@ Options:
|
|
|
37
37
|
--help, -h Show this help
|
|
38
38
|
|
|
39
39
|
Examples:
|
|
40
|
-
scc install apex
|
|
41
|
-
scc install all
|
|
42
|
-
scc install --config scc-install.json
|
|
43
|
-
scc install --config scc-install.json --target cursor
|
|
44
|
-
scc install --profile security --target claude
|
|
45
|
-
scc install --profile lwc --target cursor --dry-run
|
|
40
|
+
scc-universal install apex
|
|
41
|
+
scc-universal install all
|
|
42
|
+
scc-universal install --config scc-install.json
|
|
43
|
+
scc-universal install --config scc-install.json --target cursor
|
|
44
|
+
scc-universal install --profile security --target claude
|
|
45
|
+
scc-universal install --profile lwc --target cursor --dry-run
|
|
46
46
|
`);
|
|
47
47
|
process.exit(exitCode);
|
|
48
48
|
}
|
|
@@ -48,7 +48,9 @@ process.stdin.on('data', c => {
|
|
|
48
48
|
process.stdin.on('end', () => {
|
|
49
49
|
try {
|
|
50
50
|
const input = JSON.parse(data);
|
|
51
|
-
const
|
|
51
|
+
const { normalizeInput } = require('../lib/hook-input');
|
|
52
|
+
const ctx = normalizeInput(input);
|
|
53
|
+
const filePath = ctx.filePath;
|
|
52
54
|
|
|
53
55
|
if (filePath && !isAllowedDocPath(filePath)) {
|
|
54
56
|
console.error('[Hook] WARNING: Non-standard documentation file detected');
|
|
@@ -195,8 +195,9 @@ function checkGovernorLimits(filePath) {
|
|
|
195
195
|
function run(rawInput) {
|
|
196
196
|
try {
|
|
197
197
|
const input = JSON.parse(rawInput);
|
|
198
|
-
const
|
|
199
|
-
|
|
198
|
+
const { normalizeInput } = require('../lib/hook-input');
|
|
199
|
+
const ctx = normalizeInput(input);
|
|
200
|
+
checkGovernorLimits(ctx.filePath);
|
|
200
201
|
} catch {
|
|
201
202
|
// Ignore errors
|
|
202
203
|
}
|
|
@@ -22,8 +22,9 @@ process.stdin.on('data', chunk => {
|
|
|
22
22
|
process.stdin.on('end', () => {
|
|
23
23
|
try {
|
|
24
24
|
const input = JSON.parse(raw);
|
|
25
|
-
const
|
|
26
|
-
|
|
25
|
+
const { normalizeInput } = require('../lib/hook-input');
|
|
26
|
+
const ctx = normalizeInput(input);
|
|
27
|
+
if (/(sf\s+project\s+deploy|sf\s+deploy|sfdx\s+force:source:deploy|npm run build|pnpm build|yarn build)/.test(ctx.command)) {
|
|
27
28
|
console.error('[Hook] Build/deploy completed - review results above');
|
|
28
29
|
}
|
|
29
30
|
} catch {
|
|
@@ -22,10 +22,12 @@ process.stdin.on('data', chunk => {
|
|
|
22
22
|
process.stdin.on('end', () => {
|
|
23
23
|
try {
|
|
24
24
|
const input = JSON.parse(raw);
|
|
25
|
-
const
|
|
25
|
+
const { normalizeInput } = require('../lib/hook-input');
|
|
26
|
+
const ctx = normalizeInput(input);
|
|
27
|
+
const cmd = ctx.command;
|
|
26
28
|
|
|
27
29
|
if (/\bgh\s+pr\s+create\b/.test(cmd)) {
|
|
28
|
-
const out =
|
|
30
|
+
const out = ctx.output;
|
|
29
31
|
const match = out.match(/https:\/\/github\.com\/[^/]+\/[^/]+\/pull\/\d+/);
|
|
30
32
|
if (match) {
|
|
31
33
|
const prUrl = match[0];
|
|
@@ -25,7 +25,9 @@ process.stdin.on('data', chunk => {
|
|
|
25
25
|
process.stdin.on('end', () => {
|
|
26
26
|
try {
|
|
27
27
|
const input = JSON.parse(data);
|
|
28
|
-
const
|
|
28
|
+
const { normalizeInput } = require('../lib/hook-input');
|
|
29
|
+
const ctx = normalizeInput(input);
|
|
30
|
+
const filePath = ctx.filePath;
|
|
29
31
|
|
|
30
32
|
if (filePath && /\.(ts|tsx|js|jsx)$/.test(filePath)) {
|
|
31
33
|
let content;
|
|
@@ -54,8 +54,9 @@ function tryFormat(filePath) {
|
|
|
54
54
|
function run(rawInput) {
|
|
55
55
|
try {
|
|
56
56
|
const input = JSON.parse(rawInput);
|
|
57
|
-
const
|
|
58
|
-
|
|
57
|
+
const { normalizeInput } = require('../lib/hook-input');
|
|
58
|
+
const ctx = normalizeInput(input);
|
|
59
|
+
tryFormat(ctx.filePath);
|
|
59
60
|
} catch {
|
|
60
61
|
// Ignore errors
|
|
61
62
|
}
|
|
@@ -73,8 +73,9 @@ function checkFile(filePath) {
|
|
|
73
73
|
function run(rawInput) {
|
|
74
74
|
try {
|
|
75
75
|
const input = JSON.parse(rawInput);
|
|
76
|
-
const
|
|
77
|
-
|
|
76
|
+
const { normalizeInput } = require('../lib/hook-input');
|
|
77
|
+
const ctx = normalizeInput(input);
|
|
78
|
+
checkFile(ctx.filePath);
|
|
78
79
|
} catch {
|
|
79
80
|
// Ignore parse errors
|
|
80
81
|
}
|
|
@@ -153,7 +153,9 @@ rl.on('close', () => {
|
|
|
153
153
|
process.exit(0);
|
|
154
154
|
}
|
|
155
155
|
|
|
156
|
-
const
|
|
156
|
+
const { normalizeInput } = require('../lib/hook-input');
|
|
157
|
+
const ctx = normalizeInput(input);
|
|
158
|
+
const filePath = ctx.filePath;
|
|
157
159
|
if (!filePath) process.exit(0);
|
|
158
160
|
|
|
159
161
|
const fileType = classifyFile(filePath);
|
|
@@ -22,8 +22,9 @@ process.stdin.on('data', chunk => {
|
|
|
22
22
|
process.stdin.on('end', () => {
|
|
23
23
|
try {
|
|
24
24
|
const input = JSON.parse(raw);
|
|
25
|
-
const
|
|
26
|
-
|
|
25
|
+
const { normalizeInput } = require('../lib/hook-input');
|
|
26
|
+
const ctx = normalizeInput(input);
|
|
27
|
+
if (/\bgit\s+push\b/.test(ctx.command)) {
|
|
27
28
|
console.error('[Hook] Review changes before push...');
|
|
28
29
|
console.error('[Hook] Continuing with push (remove this hook to add interactive review)');
|
|
29
30
|
}
|
|
@@ -28,7 +28,9 @@ process.stdin.on('data', chunk => {
|
|
|
28
28
|
process.stdin.on('end', () => {
|
|
29
29
|
try {
|
|
30
30
|
const input = JSON.parse(raw);
|
|
31
|
-
const
|
|
31
|
+
const { normalizeInput } = require('../lib/hook-input');
|
|
32
|
+
const ctx = normalizeInput(input);
|
|
33
|
+
const cmd = ctx.command;
|
|
32
34
|
|
|
33
35
|
if (
|
|
34
36
|
process.platform !== 'win32' &&
|
|
@@ -105,7 +105,9 @@ function processInput(input) {
|
|
|
105
105
|
return null;
|
|
106
106
|
}
|
|
107
107
|
|
|
108
|
-
const
|
|
108
|
+
const { normalizeInput } = require('../lib/hook-input');
|
|
109
|
+
const ctx = normalizeInput(input);
|
|
110
|
+
const command = ctx.command;
|
|
109
111
|
if (!command) return null;
|
|
110
112
|
|
|
111
113
|
// Skip if command doesn't involve SF/SFDX
|
|
@@ -226,8 +226,9 @@ function maybeRunQualityGate(filePath) {
|
|
|
226
226
|
function run(rawInput) {
|
|
227
227
|
try {
|
|
228
228
|
const input = JSON.parse(rawInput);
|
|
229
|
-
const
|
|
230
|
-
|
|
229
|
+
const { normalizeInput } = require('../lib/hook-input');
|
|
230
|
+
const ctx = normalizeInput(input);
|
|
231
|
+
maybeRunQualityGate(ctx.filePath);
|
|
231
232
|
} catch {
|
|
232
233
|
// Ignore parse errors
|
|
233
234
|
}
|
|
@@ -84,7 +84,9 @@ function runScanner(files) {
|
|
|
84
84
|
function run(rawInput) {
|
|
85
85
|
try {
|
|
86
86
|
const input = JSON.parse(rawInput);
|
|
87
|
-
const
|
|
87
|
+
const { normalizeInput } = require('../lib/hook-input');
|
|
88
|
+
const ctx = normalizeInput(input);
|
|
89
|
+
const command = ctx.command;
|
|
88
90
|
|
|
89
91
|
// Only intercept git push and sf deploy commands
|
|
90
92
|
const isGitPush = /\bgit\s+push\b/.test(command);
|
|
@@ -100,7 +100,9 @@ rl.on('close', () => {
|
|
|
100
100
|
process.exit(0);
|
|
101
101
|
}
|
|
102
102
|
|
|
103
|
-
const
|
|
103
|
+
const { normalizeInput } = require('../lib/hook-input');
|
|
104
|
+
const ctx = normalizeInput(input);
|
|
105
|
+
const command = ctx.command;
|
|
104
106
|
const warnings = validateCommand(command);
|
|
105
107
|
|
|
106
108
|
if (warnings.length === 0) {
|