rebar-mcp 2.4.4 → 2.6.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/skills/bmn1us0t4xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/SKILL.md +21 -0
- package/.claude/skills/bmn1uzlg2xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/SKILL.md +21 -0
- package/.claude/skills/bnd-mn1us0t9/SKILL.md +21 -0
- package/.claude/skills/bnd-mn1uzlg6/SKILL.md +21 -0
- package/.claude/skills/nl-mn1us0tj/SKILL.md +25 -0
- package/.claude/skills/nl-mn1uzlgf/SKILL.md +25 -0
- package/.rebar/decisions/2026-03-22/001_write__app_api_test_route.ts.json +32 -0
- package/.rebar/decisions/2026-03-22/002_write__app_api_test_route.ts.json +26 -0
- package/.rebar/decisions/2026-03-22/003_write__lib_db.ts.json +26 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +199 -2
- package/dist/cli.js.map +1 -1
- package/dist/index.js +1 -1
- package/dist/services/prereview-engine.d.ts.map +1 -1
- package/dist/services/prereview-engine.js +310 -0
- package/dist/services/prereview-engine.js.map +1 -1
- package/dist/services/workflow-templates.d.ts +40 -0
- package/dist/services/workflow-templates.d.ts.map +1 -0
- package/dist/services/workflow-templates.js +312 -0
- package/dist/services/workflow-templates.js.map +1 -0
- package/package.json +1 -1
- package/src/cli.ts +241 -2
- package/src/index.ts +1 -1
- package/src/services/prereview-engine.ts +344 -0
- package/src/services/workflow-templates.ts +353 -0
package/.claude/skills/bmn1us0t4xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/SKILL.md
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: bmn1us0t4xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
|
3
|
+
description: A test skill
|
|
4
|
+
invocation: undefined
|
|
5
|
+
context: undefined
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# bmn1us0t4xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
|
9
|
+
|
|
10
|
+
A test skill
|
|
11
|
+
|
|
12
|
+
## Instructions
|
|
13
|
+
|
|
14
|
+
<!-- Replace this with your skill instructions.
|
|
15
|
+
Good skill instructions:
|
|
16
|
+
1. Define the agent's role clearly
|
|
17
|
+
2. Specify the exact output format
|
|
18
|
+
3. List what to check/do step by step
|
|
19
|
+
4. Include examples of good output
|
|
20
|
+
-->
|
|
21
|
+
|
package/.claude/skills/bmn1uzlg2xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/SKILL.md
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: bmn1uzlg2xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
|
3
|
+
description: A test skill
|
|
4
|
+
invocation: undefined
|
|
5
|
+
context: undefined
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# bmn1uzlg2xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
|
9
|
+
|
|
10
|
+
A test skill
|
|
11
|
+
|
|
12
|
+
## Instructions
|
|
13
|
+
|
|
14
|
+
<!-- Replace this with your skill instructions.
|
|
15
|
+
Good skill instructions:
|
|
16
|
+
1. Define the agent's role clearly
|
|
17
|
+
2. Specify the exact output format
|
|
18
|
+
3. List what to check/do step by step
|
|
19
|
+
4. Include examples of good output
|
|
20
|
+
-->
|
|
21
|
+
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: bnd-mn1us0t9
|
|
3
|
+
description: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
|
4
|
+
invocation: undefined
|
|
5
|
+
context: undefined
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# bnd-mn1us0t9
|
|
9
|
+
|
|
10
|
+
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
|
11
|
+
|
|
12
|
+
## Instructions
|
|
13
|
+
|
|
14
|
+
<!-- Replace this with your skill instructions.
|
|
15
|
+
Good skill instructions:
|
|
16
|
+
1. Define the agent's role clearly
|
|
17
|
+
2. Specify the exact output format
|
|
18
|
+
3. List what to check/do step by step
|
|
19
|
+
4. Include examples of good output
|
|
20
|
+
-->
|
|
21
|
+
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: bnd-mn1uzlg6
|
|
3
|
+
description: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
|
4
|
+
invocation: undefined
|
|
5
|
+
context: undefined
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# bnd-mn1uzlg6
|
|
9
|
+
|
|
10
|
+
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
|
11
|
+
|
|
12
|
+
## Instructions
|
|
13
|
+
|
|
14
|
+
<!-- Replace this with your skill instructions.
|
|
15
|
+
Good skill instructions:
|
|
16
|
+
1. Define the agent's role clearly
|
|
17
|
+
2. Specify the exact output format
|
|
18
|
+
3. List what to check/do step by step
|
|
19
|
+
4. Include examples of good output
|
|
20
|
+
-->
|
|
21
|
+
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: nl-mn1us0tj
|
|
3
|
+
description: Line one
|
|
4
|
+
Line two
|
|
5
|
+
Line three
|
|
6
|
+
invocation: undefined
|
|
7
|
+
context: undefined
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# nl-mn1us0tj
|
|
11
|
+
|
|
12
|
+
Line one
|
|
13
|
+
Line two
|
|
14
|
+
Line three
|
|
15
|
+
|
|
16
|
+
## Instructions
|
|
17
|
+
|
|
18
|
+
<!-- Replace this with your skill instructions.
|
|
19
|
+
Good skill instructions:
|
|
20
|
+
1. Define the agent's role clearly
|
|
21
|
+
2. Specify the exact output format
|
|
22
|
+
3. List what to check/do step by step
|
|
23
|
+
4. Include examples of good output
|
|
24
|
+
-->
|
|
25
|
+
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: nl-mn1uzlgf
|
|
3
|
+
description: Line one
|
|
4
|
+
Line two
|
|
5
|
+
Line three
|
|
6
|
+
invocation: undefined
|
|
7
|
+
context: undefined
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# nl-mn1uzlgf
|
|
11
|
+
|
|
12
|
+
Line one
|
|
13
|
+
Line two
|
|
14
|
+
Line three
|
|
15
|
+
|
|
16
|
+
## Instructions
|
|
17
|
+
|
|
18
|
+
<!-- Replace this with your skill instructions.
|
|
19
|
+
Good skill instructions:
|
|
20
|
+
1. Define the agent's role clearly
|
|
21
|
+
2. Specify the exact output format
|
|
22
|
+
3. List what to check/do step by step
|
|
23
|
+
4. Include examples of good output
|
|
24
|
+
-->
|
|
25
|
+
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "prereview_2026-03-22_001",
|
|
3
|
+
"timestamp": "2026-03-22T14:23:12.892Z",
|
|
4
|
+
"operation": "write",
|
|
5
|
+
"target": "/app/api/test/route.ts",
|
|
6
|
+
"decision": "block",
|
|
7
|
+
"severity": "critical",
|
|
8
|
+
"tier": "pro",
|
|
9
|
+
"engine": "local",
|
|
10
|
+
"latencyMs": 2,
|
|
11
|
+
"patterns": [
|
|
12
|
+
{
|
|
13
|
+
"id": "unvalidated-insert",
|
|
14
|
+
"name": "Unvalidated Database Insert",
|
|
15
|
+
"severity": "critical",
|
|
16
|
+
"message": "Database insert with unvalidated input - validate with Zod before inserting"
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"id": "unvalidated-request-body",
|
|
20
|
+
"name": "Unvalidated Request Body",
|
|
21
|
+
"severity": "warning",
|
|
22
|
+
"message": "Request body parsed without Zod validation"
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
"id": "api-missing-auth",
|
|
26
|
+
"name": "API Route Missing Auth",
|
|
27
|
+
"severity": "warning",
|
|
28
|
+
"message": "API route without visible authentication check"
|
|
29
|
+
}
|
|
30
|
+
],
|
|
31
|
+
"reasoning": "1 critical issue(s): Unvalidated Database Insert; 2 warning(s): Unvalidated Request Body, API Route Missing Auth"
|
|
32
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "prereview_2026-03-22_002",
|
|
3
|
+
"timestamp": "2026-03-22T14:23:33.241Z",
|
|
4
|
+
"operation": "write",
|
|
5
|
+
"target": "/app/api/test/route.ts",
|
|
6
|
+
"decision": "warn",
|
|
7
|
+
"severity": "warning",
|
|
8
|
+
"tier": "pro",
|
|
9
|
+
"engine": "local",
|
|
10
|
+
"latencyMs": 1,
|
|
11
|
+
"patterns": [
|
|
12
|
+
{
|
|
13
|
+
"id": "error-message-exposed",
|
|
14
|
+
"name": "Error Message Exposed",
|
|
15
|
+
"severity": "warning",
|
|
16
|
+
"message": "Raw error.message returned to client - may leak internal details"
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"id": "phi-console-error",
|
|
20
|
+
"name": "PHI Risk: Console Error Object",
|
|
21
|
+
"severity": "warning",
|
|
22
|
+
"message": "Console output with error object may leak PHI/PII in logs"
|
|
23
|
+
}
|
|
24
|
+
],
|
|
25
|
+
"reasoning": "2 warning(s): Error Message Exposed, PHI Risk: Console Error Object"
|
|
26
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "prereview_2026-03-22_003",
|
|
3
|
+
"timestamp": "2026-03-22T14:25:40.291Z",
|
|
4
|
+
"operation": "write",
|
|
5
|
+
"target": "/lib/db.ts",
|
|
6
|
+
"decision": "block",
|
|
7
|
+
"severity": "critical",
|
|
8
|
+
"tier": "pro",
|
|
9
|
+
"engine": "local",
|
|
10
|
+
"latencyMs": 1,
|
|
11
|
+
"patterns": [
|
|
12
|
+
{
|
|
13
|
+
"id": "sql-injection",
|
|
14
|
+
"name": "SQL Injection Risk",
|
|
15
|
+
"severity": "critical",
|
|
16
|
+
"message": "Potential SQL injection via template literal"
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"id": "sql-injection-where",
|
|
20
|
+
"name": "SQL Injection: WHERE Clause",
|
|
21
|
+
"severity": "critical",
|
|
22
|
+
"message": "SQL injection via string interpolation in WHERE clause"
|
|
23
|
+
}
|
|
24
|
+
],
|
|
25
|
+
"reasoning": "2 critical issue(s): SQL Injection Risk, SQL Injection: WHERE Clause"
|
|
26
|
+
}
|
package/dist/cli.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAykDA,wBAAsB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAqK5D"}
|
package/dist/cli.js
CHANGED
|
@@ -21,12 +21,13 @@ import { generateCodexConfig } from "./services/codex-generator.js";
|
|
|
21
21
|
import { atomicWrite } from "./services/file-ops.js";
|
|
22
22
|
import { createInterface } from "node:readline";
|
|
23
23
|
import { CONTEXT_WINDOW_TOKENS } from "./constants.js";
|
|
24
|
-
import { runPrereview, loadPrereviewConfig, } from "./services/prereview-engine.js";
|
|
24
|
+
import { runPrereview, loadPrereviewConfig, PREREVIEW_PATTERNS, } from "./services/prereview-engine.js";
|
|
25
25
|
import { runHybridPrereview } from "./services/prereview-llm.js";
|
|
26
26
|
import { loadLicense, loadUsage, canUseLLMReview } from "./services/license.js";
|
|
27
27
|
import { loadMemory, clearMemory, learnFromHistory, exportMemorySummary, } from "./services/prereview-memory.js";
|
|
28
28
|
import { analyzeDecisionHistory, formatAnalyticsReport, exportAnalyticsJSON, generateBlockRateChart, } from "./services/prereview-analytics.js";
|
|
29
|
-
|
|
29
|
+
import { COMMAND_COMMIT_PUSH_PR, COMMAND_SIMPLIFY, COMMAND_VERIFY, COMMAND_REVIEW_PLAN, COMMAND_FIX_TESTS, COMMAND_UPDATE_DOCS, AGENT_CODE_SIMPLIFIER, AGENT_VERIFIER, AGENT_EXPLAIN, AGENT_SECURITY_REVIEWER, AGENT_TEST_WRITER, getPostToolUseFormatHook, SAFE_BASH_PERMISSIONS, } from "./services/workflow-templates.js";
|
|
30
|
+
const VERSION = "2.6.0";
|
|
30
31
|
/**
|
|
31
32
|
* Read stdin if available (non-blocking check)
|
|
32
33
|
* Returns the parsed JSON if it's a valid hook input, null otherwise
|
|
@@ -1122,6 +1123,196 @@ async function cmdWhy(_options, category) {
|
|
|
1122
1123
|
console.log();
|
|
1123
1124
|
return 0;
|
|
1124
1125
|
}
|
|
1126
|
+
async function cmdPatterns(_options, filter) {
|
|
1127
|
+
// Group patterns by category
|
|
1128
|
+
const categories = {
|
|
1129
|
+
"Security - Secrets": PREREVIEW_PATTERNS.filter(p => p.id.startsWith("secret")),
|
|
1130
|
+
"Security - Dangerous Commands": PREREVIEW_PATTERNS.filter(p => p.id.startsWith("danger")),
|
|
1131
|
+
"Security - Injection": PREREVIEW_PATTERNS.filter(p => p.id.includes("injection") || p.id.includes("sql")),
|
|
1132
|
+
"Input Validation": PREREVIEW_PATTERNS.filter(p => p.id.includes("unvalidated") || p.id.includes("request-body")),
|
|
1133
|
+
"PHI/PII Protection": PREREVIEW_PATTERNS.filter(p => p.id.includes("phi") || p.id.includes("unencrypted")),
|
|
1134
|
+
"API Security": PREREVIEW_PATTERNS.filter(p => p.id.includes("auth") || p.id.includes("rate") || p.id.includes("cors") || p.id.includes("cron")),
|
|
1135
|
+
"Error Handling": PREREVIEW_PATTERNS.filter(p => p.id.includes("error") || p.id.includes("catch") || p.id.includes("swallowed")),
|
|
1136
|
+
"Code Quality": PREREVIEW_PATTERNS.filter(p => p.id.includes("any") || p.id.includes("console") || p.id.includes("todo") || p.id.includes("large")),
|
|
1137
|
+
"Supabase/Database": PREREVIEW_PATTERNS.filter(p => p.id.includes("supabase") || p.id.includes("service-role") || p.id.includes("user-filter")),
|
|
1138
|
+
"AI/Agent Security": PREREVIEW_PATTERNS.filter(p => p.id.includes("prompt") || p.id.includes("memory-injection")),
|
|
1139
|
+
"Framework Patterns": PREREVIEW_PATTERNS.filter(p => p.id.includes("nextjs") || p.id.includes("client-fetch")),
|
|
1140
|
+
"Configuration": PREREVIEW_PATTERNS.filter(p => p.id.includes("hardcoded") || p.id.includes("token")),
|
|
1141
|
+
};
|
|
1142
|
+
// Remove empty categories and patterns that are already categorized
|
|
1143
|
+
const categorizedIds = new Set(Object.values(categories).flat().map(p => p.id));
|
|
1144
|
+
const uncategorized = PREREVIEW_PATTERNS.filter(p => !categorizedIds.has(p.id));
|
|
1145
|
+
if (uncategorized.length > 0) {
|
|
1146
|
+
categories["Other"] = uncategorized;
|
|
1147
|
+
}
|
|
1148
|
+
// Filter by search term if provided
|
|
1149
|
+
const searchTerm = filter?.toLowerCase();
|
|
1150
|
+
console.log("Rebar Enterprise Patterns");
|
|
1151
|
+
console.log("=========================");
|
|
1152
|
+
console.log();
|
|
1153
|
+
let totalShown = 0;
|
|
1154
|
+
let totalBlocking = 0;
|
|
1155
|
+
for (const [category, patterns] of Object.entries(categories)) {
|
|
1156
|
+
const filteredPatterns = searchTerm
|
|
1157
|
+
? patterns.filter(p => p.name.toLowerCase().includes(searchTerm) ||
|
|
1158
|
+
p.id.toLowerCase().includes(searchTerm) ||
|
|
1159
|
+
p.message.toLowerCase().includes(searchTerm))
|
|
1160
|
+
: patterns;
|
|
1161
|
+
if (filteredPatterns.length === 0)
|
|
1162
|
+
continue;
|
|
1163
|
+
console.log(`\n${category} (${filteredPatterns.length} patterns)`);
|
|
1164
|
+
console.log("-".repeat(category.length + 15));
|
|
1165
|
+
for (const p of filteredPatterns) {
|
|
1166
|
+
const severityIcon = p.severity === "critical" ? "🔴" : p.severity === "warning" ? "🟡" : "🔵";
|
|
1167
|
+
const minLevel = p.minStrictness === "standard" ? "" : ` [${p.minStrictness}+]`;
|
|
1168
|
+
console.log(` ${severityIcon} ${p.name}${minLevel}`);
|
|
1169
|
+
console.log(` ${p.message}`);
|
|
1170
|
+
if (p.suggestion) {
|
|
1171
|
+
console.log(` → ${p.suggestion}`);
|
|
1172
|
+
}
|
|
1173
|
+
if (p.filePatterns && p.filePatterns.length > 0) {
|
|
1174
|
+
console.log(` Files: ${p.filePatterns.join(", ")}`);
|
|
1175
|
+
}
|
|
1176
|
+
totalShown++;
|
|
1177
|
+
if (p.severity === "critical")
|
|
1178
|
+
totalBlocking++;
|
|
1179
|
+
}
|
|
1180
|
+
}
|
|
1181
|
+
console.log();
|
|
1182
|
+
console.log(`Total: ${totalShown} patterns (${totalBlocking} blocking)`);
|
|
1183
|
+
console.log();
|
|
1184
|
+
console.log("Strictness levels:");
|
|
1185
|
+
console.log(" standard - All critical patterns enforced");
|
|
1186
|
+
console.log(" strict - Critical + warning patterns enforced");
|
|
1187
|
+
console.log(" paranoid - All patterns enforced, warnings become blocks");
|
|
1188
|
+
return 0;
|
|
1189
|
+
}
|
|
1190
|
+
async function cmdSetupWorkflow(options) {
|
|
1191
|
+
const projectPath = resolveProjectPath(options.path);
|
|
1192
|
+
console.log("Setting up enterprise workflow (Boris pattern)...");
|
|
1193
|
+
console.log();
|
|
1194
|
+
try {
|
|
1195
|
+
// Analyze project
|
|
1196
|
+
const analysis = await analyzeProject(projectPath);
|
|
1197
|
+
// Create .claude directories
|
|
1198
|
+
const claudeDir = path.join(projectPath, ".claude");
|
|
1199
|
+
const commandsDir = path.join(claudeDir, "commands");
|
|
1200
|
+
const agentsDir = path.join(claudeDir, "agents");
|
|
1201
|
+
await fs.mkdir(commandsDir, { recursive: true });
|
|
1202
|
+
await fs.mkdir(agentsDir, { recursive: true });
|
|
1203
|
+
// Write slash commands
|
|
1204
|
+
const commands = [
|
|
1205
|
+
{ name: "commit-push-pr.md", content: COMMAND_COMMIT_PUSH_PR },
|
|
1206
|
+
{ name: "simplify.md", content: COMMAND_SIMPLIFY },
|
|
1207
|
+
{ name: "verify.md", content: COMMAND_VERIFY },
|
|
1208
|
+
{ name: "review-plan.md", content: COMMAND_REVIEW_PLAN },
|
|
1209
|
+
{ name: "fix-tests.md", content: COMMAND_FIX_TESTS },
|
|
1210
|
+
{ name: "update-docs.md", content: COMMAND_UPDATE_DOCS },
|
|
1211
|
+
];
|
|
1212
|
+
for (const cmd of commands) {
|
|
1213
|
+
await atomicWrite(path.join(commandsDir, cmd.name), cmd.content);
|
|
1214
|
+
}
|
|
1215
|
+
console.log(`✓ Created ${commands.length} slash commands in .claude/commands/`);
|
|
1216
|
+
for (const cmd of commands) {
|
|
1217
|
+
console.log(` /${cmd.name.replace(".md", "")}`);
|
|
1218
|
+
}
|
|
1219
|
+
// Write subagents
|
|
1220
|
+
const agents = [
|
|
1221
|
+
{ name: "code-simplifier.md", content: AGENT_CODE_SIMPLIFIER },
|
|
1222
|
+
{ name: "verifier.md", content: AGENT_VERIFIER },
|
|
1223
|
+
{ name: "explain.md", content: AGENT_EXPLAIN },
|
|
1224
|
+
{ name: "security-reviewer.md", content: AGENT_SECURITY_REVIEWER },
|
|
1225
|
+
{ name: "test-writer.md", content: AGENT_TEST_WRITER },
|
|
1226
|
+
];
|
|
1227
|
+
for (const agent of agents) {
|
|
1228
|
+
await atomicWrite(path.join(agentsDir, agent.name), agent.content);
|
|
1229
|
+
}
|
|
1230
|
+
console.log(`✓ Created ${agents.length} subagents in .claude/agents/`);
|
|
1231
|
+
// Update settings.json with PostToolUse hook and permissions
|
|
1232
|
+
const settingsPath = path.join(claudeDir, "settings.json");
|
|
1233
|
+
let settings = {};
|
|
1234
|
+
const existingSettings = await readFileSafe(settingsPath);
|
|
1235
|
+
if (existingSettings) {
|
|
1236
|
+
try {
|
|
1237
|
+
settings = JSON.parse(existingSettings);
|
|
1238
|
+
}
|
|
1239
|
+
catch {
|
|
1240
|
+
// Start fresh
|
|
1241
|
+
}
|
|
1242
|
+
}
|
|
1243
|
+
// Add PostToolUse formatting hook if formatter detected
|
|
1244
|
+
const formatHook = getPostToolUseFormatHook(analysis.formatter);
|
|
1245
|
+
if (formatHook) {
|
|
1246
|
+
if (!settings.hooks)
|
|
1247
|
+
settings.hooks = {};
|
|
1248
|
+
const hooks = settings.hooks;
|
|
1249
|
+
if (!hooks.PostToolCall)
|
|
1250
|
+
hooks.PostToolCall = [];
|
|
1251
|
+
const postHooks = hooks.PostToolCall;
|
|
1252
|
+
// Check if format hook already exists
|
|
1253
|
+
const hasFormatHook = postHooks.some((h) => {
|
|
1254
|
+
const hooksArr = h.hooks;
|
|
1255
|
+
return hooksArr?.some((hook) => hook.command?.toString().includes("prettier") ||
|
|
1256
|
+
hook.command?.toString().includes("biome") ||
|
|
1257
|
+
hook.command?.toString().includes("black") ||
|
|
1258
|
+
hook.command?.toString().includes("gofmt"));
|
|
1259
|
+
});
|
|
1260
|
+
if (!hasFormatHook) {
|
|
1261
|
+
postHooks.push({
|
|
1262
|
+
matcher: formatHook.matcher,
|
|
1263
|
+
hooks: [
|
|
1264
|
+
{
|
|
1265
|
+
type: "command",
|
|
1266
|
+
command: formatHook.command,
|
|
1267
|
+
},
|
|
1268
|
+
],
|
|
1269
|
+
});
|
|
1270
|
+
console.log(`✓ Added PostToolCall formatting hook (${analysis.formatter})`);
|
|
1271
|
+
}
|
|
1272
|
+
}
|
|
1273
|
+
else {
|
|
1274
|
+
console.log("⚠ No formatter detected — add PostToolCall hook manually");
|
|
1275
|
+
}
|
|
1276
|
+
// Add safe bash permissions
|
|
1277
|
+
if (!settings.permissions)
|
|
1278
|
+
settings.permissions = {};
|
|
1279
|
+
const perms = settings.permissions;
|
|
1280
|
+
const existingAllow = perms.allow || [];
|
|
1281
|
+
const newPerms = SAFE_BASH_PERMISSIONS.filter((p) => !existingAllow.includes(p));
|
|
1282
|
+
perms.allow = [...existingAllow, ...newPerms];
|
|
1283
|
+
console.log(`✓ Added ${newPerms.length} safe bash permissions`);
|
|
1284
|
+
// Write updated settings
|
|
1285
|
+
await atomicWrite(settingsPath, JSON.stringify(settings, null, 2));
|
|
1286
|
+
console.log();
|
|
1287
|
+
console.log("Enterprise workflow setup complete!");
|
|
1288
|
+
console.log();
|
|
1289
|
+
console.log("Available commands:");
|
|
1290
|
+
console.log(" /commit-push-pr Stage, commit, push, and create PR");
|
|
1291
|
+
console.log(" /simplify Simplify recently changed code");
|
|
1292
|
+
console.log(" /verify Run full verification suite");
|
|
1293
|
+
console.log(" /review-plan Create implementation plan before coding");
|
|
1294
|
+
console.log(" /fix-tests Find and fix failing tests");
|
|
1295
|
+
console.log(" /update-docs Update CLAUDE.md with learnings");
|
|
1296
|
+
console.log();
|
|
1297
|
+
console.log("Available agents (invoke with Task tool):");
|
|
1298
|
+
console.log(" code-simplifier Reduce complexity without changing behavior");
|
|
1299
|
+
console.log(" verifier End-to-end verification");
|
|
1300
|
+
console.log(" explain Generate plain-English documentation");
|
|
1301
|
+
console.log(" security-reviewer Review code for vulnerabilities");
|
|
1302
|
+
console.log(" test-writer Generate comprehensive tests");
|
|
1303
|
+
console.log();
|
|
1304
|
+
console.log("Workflow tips:");
|
|
1305
|
+
console.log(" • Run /verify after every implementation");
|
|
1306
|
+
console.log(" • Run /simplify before committing");
|
|
1307
|
+
console.log(" • Use /review-plan for non-trivial tasks");
|
|
1308
|
+
console.log(" • Update CLAUDE.md when mistakes happen");
|
|
1309
|
+
return 0;
|
|
1310
|
+
}
|
|
1311
|
+
catch (err) {
|
|
1312
|
+
console.error(`Error: ${err instanceof Error ? err.message : String(err)}`);
|
|
1313
|
+
return 1;
|
|
1314
|
+
}
|
|
1315
|
+
}
|
|
1125
1316
|
async function cmdEnablePrereview(options) {
|
|
1126
1317
|
const projectPath = resolveProjectPath(options.path);
|
|
1127
1318
|
console.log("Enabling pre-review hooks...");
|
|
@@ -1201,12 +1392,16 @@ export async function runCLI(args) {
|
|
|
1201
1392
|
return cmdInit(options);
|
|
1202
1393
|
case "enable-prereview":
|
|
1203
1394
|
return cmdEnablePrereview(options);
|
|
1395
|
+
case "setup-workflow":
|
|
1396
|
+
return cmdSetupWorkflow(options);
|
|
1204
1397
|
case "doctor":
|
|
1205
1398
|
return cmdDoctor(options);
|
|
1206
1399
|
case "audit":
|
|
1207
1400
|
return cmdAudit(options);
|
|
1208
1401
|
case "why":
|
|
1209
1402
|
return cmdWhy(options, positional[0] || "");
|
|
1403
|
+
case "patterns":
|
|
1404
|
+
return cmdPatterns(options, positional[0]);
|
|
1210
1405
|
case "set-strictness":
|
|
1211
1406
|
if (positional.length === 0) {
|
|
1212
1407
|
console.error("Usage: rebar set-strictness <standard|strict|paranoid>");
|
|
@@ -1285,9 +1480,11 @@ export async function runCLI(args) {
|
|
|
1285
1480
|
|
|
1286
1481
|
Usage:
|
|
1287
1482
|
rebar init [options] Initialize Rebar enforcement in a project
|
|
1483
|
+
rebar setup-workflow Install enterprise workflow (commands, agents, hooks)
|
|
1288
1484
|
rebar enable-prereview Enable pre-review hooks (secret detection, etc.)
|
|
1289
1485
|
rebar audit [options] Run quality audit (exit 1 if below threshold)
|
|
1290
1486
|
rebar why <category> Explain what's being scored and why
|
|
1487
|
+
rebar patterns [filter] List all enterprise enforcement patterns
|
|
1291
1488
|
rebar doctor [options] Check Rebar setup health
|
|
1292
1489
|
rebar set-strictness <level> Change enforcement strictness
|
|
1293
1490
|
rebar metrics [options] View quality score history
|