rebar-mcp 2.4.0 → 2.4.2

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 (33) hide show
  1. package/.claude/settings.json +9 -0
  2. package/.claude/skills/bmmovop8dxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/SKILL.md +21 -0
  3. package/.claude/skills/bmmxlvoqnxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/SKILL.md +21 -0
  4. package/.claude/skills/bnd-mmovop8h/SKILL.md +21 -0
  5. package/.claude/skills/bnd-mmxlvoqs/SKILL.md +21 -0
  6. package/.claude/skills/nl-mmovop8r/SKILL.md +25 -0
  7. package/.claude/skills/nl-mmxlvor0/SKILL.md +25 -0
  8. package/.dockerignore +7 -0
  9. package/.rebar/decisions/2026-03-19/001_write__tmp_test-secret.ts.json +13 -0
  10. package/.rebar/decisions/2026-03-19/002_write__tmp_test.ts.json +13 -0
  11. package/.rebar/decisions/2026-03-19/003_write__tmp_test.ts.json +13 -0
  12. package/.rebar/decisions/2026-03-19/004_write__tmp_test.ts.json +20 -0
  13. package/Dockerfile +25 -0
  14. package/README.md +187 -0
  15. package/dist/cli.d.ts.map +1 -1
  16. package/dist/cli.js +113 -28
  17. package/dist/cli.js.map +1 -1
  18. package/dist/index.js +16 -4
  19. package/dist/index.js.map +1 -1
  20. package/dist/schemas/scaffolding.d.ts +1 -1
  21. package/dist/services/prereview-analytics.d.ts +63 -0
  22. package/dist/services/prereview-analytics.d.ts.map +1 -0
  23. package/dist/services/prereview-analytics.js +323 -0
  24. package/dist/services/prereview-analytics.js.map +1 -0
  25. package/package.json +1 -1
  26. package/src/cli.ts +132 -26
  27. package/src/index.ts +17 -4
  28. package/src/services/prereview-analytics.ts +439 -0
  29. package/templates/knowledge/adr.md +50 -0
  30. package/templates/knowledge/api.md +100 -0
  31. package/templates/knowledge/runbook.md +71 -0
  32. package/templates/knowledge/schema.md +92 -0
  33. package/templates/knowledge/style.md +187 -0
@@ -30,6 +30,15 @@
30
30
  }
31
31
  ],
32
32
  "PreToolCall": [
33
+ {
34
+ "matcher": "Write|Edit|Bash",
35
+ "hooks": [
36
+ {
37
+ "type": "command",
38
+ "command": "rebar prereview"
39
+ }
40
+ ]
41
+ },
33
42
  {
34
43
  "matcher": "Bash",
35
44
  "hooks": [
@@ -0,0 +1,21 @@
1
+ ---
2
+ name: bmmovop8dxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
3
+ description: A test skill
4
+ invocation: undefined
5
+ context: undefined
6
+ ---
7
+
8
+ # bmmovop8dxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
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: bmmxlvoqnxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
3
+ description: A test skill
4
+ invocation: undefined
5
+ context: undefined
6
+ ---
7
+
8
+ # bmmxlvoqnxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
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-mmovop8h
3
+ description: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
4
+ invocation: undefined
5
+ context: undefined
6
+ ---
7
+
8
+ # bnd-mmovop8h
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-mmxlvoqs
3
+ description: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
4
+ invocation: undefined
5
+ context: undefined
6
+ ---
7
+
8
+ # bnd-mmxlvoqs
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-mmovop8r
3
+ description: Line one
4
+ Line two
5
+ Line three
6
+ invocation: undefined
7
+ context: undefined
8
+ ---
9
+
10
+ # nl-mmovop8r
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-mmxlvor0
3
+ description: Line one
4
+ Line two
5
+ Line three
6
+ invocation: undefined
7
+ context: undefined
8
+ ---
9
+
10
+ # nl-mmxlvor0
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
+
package/.dockerignore ADDED
@@ -0,0 +1,7 @@
1
+ node_modules
2
+ .git
3
+ .github
4
+ .claude
5
+ .rebar
6
+ *.md
7
+ !README.md
@@ -0,0 +1,13 @@
1
+ {
2
+ "id": "prereview_2026-03-19_001",
3
+ "timestamp": "2026-03-19T14:04:30.725Z",
4
+ "operation": "write",
5
+ "target": "/tmp/test-secret.ts",
6
+ "decision": "approve",
7
+ "severity": "info",
8
+ "tier": "pro",
9
+ "engine": "local",
10
+ "latencyMs": 0,
11
+ "patterns": [],
12
+ "reasoning": "No issues detected"
13
+ }
@@ -0,0 +1,13 @@
1
+ {
2
+ "id": "prereview_2026-03-19_002",
3
+ "timestamp": "2026-03-19T14:54:17.648Z",
4
+ "operation": "write",
5
+ "target": "/tmp/test.ts",
6
+ "decision": "approve",
7
+ "severity": "info",
8
+ "tier": "pro",
9
+ "engine": "local",
10
+ "latencyMs": 0,
11
+ "patterns": [],
12
+ "reasoning": "No issues detected"
13
+ }
@@ -0,0 +1,13 @@
1
+ {
2
+ "id": "prereview_2026-03-19_003",
3
+ "timestamp": "2026-03-19T14:54:53.876Z",
4
+ "operation": "write",
5
+ "target": "/tmp/test.ts",
6
+ "decision": "approve",
7
+ "severity": "info",
8
+ "tier": "pro",
9
+ "engine": "local",
10
+ "latencyMs": 0,
11
+ "patterns": [],
12
+ "reasoning": "No issues detected"
13
+ }
@@ -0,0 +1,20 @@
1
+ {
2
+ "id": "prereview_2026-03-19_004",
3
+ "timestamp": "2026-03-19T15:05:54.120Z",
4
+ "operation": "write",
5
+ "target": "/tmp/test.ts",
6
+ "decision": "block",
7
+ "severity": "critical",
8
+ "tier": "pro",
9
+ "engine": "local",
10
+ "latencyMs": 0,
11
+ "patterns": [
12
+ {
13
+ "id": "secret-0",
14
+ "name": "Secret Detection",
15
+ "severity": "critical",
16
+ "message": "Potential secret or API key detected"
17
+ }
18
+ ],
19
+ "reasoning": "1 critical issue(s): Secret Detection"
20
+ }
package/Dockerfile ADDED
@@ -0,0 +1,25 @@
1
+ FROM node:20-slim AS builder
2
+
3
+ WORKDIR /app
4
+
5
+ COPY package*.json ./
6
+ RUN npm ci
7
+
8
+ COPY tsconfig.json ./
9
+ COPY src/ ./src/
10
+
11
+ RUN npm run build
12
+
13
+ FROM node:20-slim
14
+
15
+ WORKDIR /app
16
+
17
+ COPY package*.json ./
18
+ RUN npm ci --only=production
19
+
20
+ COPY --from=builder /app/dist ./dist
21
+ COPY templates/ ./templates/
22
+
23
+ EXPOSE 3000
24
+
25
+ ENTRYPOINT ["node", "dist/index.js", "--http", "--port", "3000"]
package/README.md CHANGED
@@ -271,6 +271,193 @@ npx rebar-mcp prereview-rules --add "pattern=TODO" --severity warning
271
271
 
272
272
  ---
273
273
 
274
+ ## LLM-Powered Semantic Analysis (Pro/Team)
275
+
276
+ Local regex patterns catch obvious issues. LLM review catches the hard stuff:
277
+
278
+ | Issue Type | Local (Free) | LLM (Paid) |
279
+ |------------|--------------|------------|
280
+ | Hardcoded secrets | ✓ | ✓ |
281
+ | Dangerous commands | ✓ | ✓ |
282
+ | N+1 query patterns | ✗ | ✓ |
283
+ | Race conditions | ✗ | ✓ |
284
+ | Business logic violations | ✗ | ✓ |
285
+ | Architecture drift | ✗ | ✓ |
286
+ | Context-aware review | ✗ | ✓ |
287
+
288
+ ### Setup
289
+
290
+ ```bash
291
+ # Set your Anthropic API key
292
+ export REBAR_API_KEY=sk-ant-...
293
+
294
+ # Choose your tier
295
+ export REBAR_TIER=pro # 1,000 LLM reviews/month
296
+ # or
297
+ export REBAR_TIER=team # 5,000 LLM reviews/month
298
+ ```
299
+
300
+ ### How It Works
301
+
302
+ 1. **Context Building** — Extracts CLAUDE.md rules, recent blocks, and project conventions
303
+ 2. **Hybrid Review** — Runs local patterns first, then LLM for deeper analysis
304
+ 3. **Learning** — Records blocked patterns for future reference
305
+ 4. **Fallback** — Gracefully falls back to local if LLM unavailable
306
+
307
+ ```bash
308
+ # Check license status
309
+ npx rebar-mcp license
310
+ ```
311
+
312
+ ---
313
+
314
+ ## Cross-Session Memory
315
+
316
+ Rebar learns from your project's decision history and applies that knowledge to future reviews.
317
+
318
+ ### What Gets Learned
319
+
320
+ - **Pattern Frequency** — Patterns blocked 5+ times escalate from warning to critical
321
+ - **Project Insights** — Common issues in specific directories
322
+ - **Review Statistics** — Block rates, latency metrics
323
+
324
+ ### Commands
325
+
326
+ ```bash
327
+ # View current memory
328
+ npx rebar-mcp memory show
329
+
330
+ # Learn from decision history
331
+ npx rebar-mcp memory learn
332
+
333
+ # Clear memory (start fresh)
334
+ npx rebar-mcp memory clear
335
+
336
+ # Export memory as JSON
337
+ npx rebar-mcp memory export
338
+ ```
339
+
340
+ ### Memory Storage
341
+
342
+ Memory is persisted to `.rebar/memory.json`:
343
+
344
+ ```json
345
+ {
346
+ "version": 1,
347
+ "learnedPatterns": [
348
+ {
349
+ "id": "aws-key",
350
+ "name": "AWS Access Key",
351
+ "blockCount": 12,
352
+ "severity": "critical",
353
+ "lastSeen": "2024-01-15T14:30:00Z"
354
+ }
355
+ ],
356
+ "projectInsights": [
357
+ {
358
+ "id": "api-dir-issues",
359
+ "description": "src/api/ frequently has SQL injection patterns",
360
+ "affectedFiles": ["src/api/users.ts", "src/api/orders.ts"],
361
+ "confidence": 0.85
362
+ }
363
+ ]
364
+ }
365
+ ```
366
+
367
+ ---
368
+
369
+ ## Analytics Dashboard
370
+
371
+ Analyze trends and generate insights from your pre-review history.
372
+
373
+ ```bash
374
+ # Last 30 days (default)
375
+ npx rebar-mcp analytics
376
+
377
+ # Last 7 days
378
+ npx rebar-mcp analytics 7
379
+
380
+ # JSON export for dashboards
381
+ npx rebar-mcp analytics --format json
382
+ ```
383
+
384
+ ### Sample Output
385
+
386
+ ```
387
+ Pre-Review Analytics Report
388
+ ===========================
389
+
390
+ Period: 2024-01-01 to 2024-01-31 (30 days)
391
+
392
+ Summary
393
+ -------
394
+ Total reviews: 247
395
+ Blocked: 23 (9.3%)
396
+ Warned: 41 (16.6%)
397
+ Approved: 183
398
+
399
+ Performance
400
+ -----------
401
+ Avg latency: 45ms
402
+ P50 latency: 32ms
403
+ P95 latency: 156ms
404
+
405
+ Top Patterns
406
+ ------------
407
+ ↑ AWS Access Key: 12x (0.4/day)
408
+ → Empty Catch Block: 8x (0.3/day)
409
+ ↓ any Type Usage: 5x (0.2/day)
410
+
411
+ Recent Activity (last 7 days)
412
+ -----------------------------
413
+ 2024-01-25: ████ 4 (1B/0W)
414
+ 2024-01-26: ██████████ 10 (2B/3W)
415
+ 2024-01-27: ████████ 8 (1B/2W)
416
+
417
+ Insights
418
+ --------
419
+ • Low block rate (9.3%) - code quality is good!
420
+ • "AWS Access Key" is trending upward - review recent code
421
+ • Excellent review speed: 45ms average
422
+ ```
423
+
424
+ ---
425
+
426
+ ## Pricing Tiers
427
+
428
+ | Feature | Free | Pro ($19/mo) | Team ($49/user/mo) |
429
+ |---------|------|--------------|-------------------|
430
+ | Regex patterns | Unlimited | Unlimited | Unlimited |
431
+ | LLM reviews | 0 | 1,000/month | 5,000/month |
432
+ | Cross-session memory | ✗ | ✓ | ✓ |
433
+ | Analytics | Basic | Full | Full |
434
+ | Audit retention | 7 days | 90 days | 1 year |
435
+ | Support | Community | Email | Priority |
436
+
437
+ ---
438
+
439
+ ## CLI Reference
440
+
441
+ ```bash
442
+ rebar init [options] # Initialize Rebar enforcement
443
+ rebar audit [options] # Run quality audit
444
+ rebar doctor [options] # Check setup health
445
+ rebar set-strictness <level> # Change enforcement level
446
+ rebar metrics [options] # View quality score history
447
+ rebar badge [options] # Generate quality badge SVG
448
+
449
+ # Pre-Review
450
+ rebar prereview [options] # Run pre-review (invoked by hooks)
451
+ rebar prereview-stats # View decision statistics
452
+
453
+ # LLM & Memory
454
+ rebar license # View license and usage
455
+ rebar memory [action] # Manage cross-session memory
456
+ rebar analytics [days] # View trends and insights
457
+ ```
458
+
459
+ ---
460
+
274
461
  ## License
275
462
 
276
463
  MIT
package/dist/cli.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAshCA,wBAAsB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAgI5D"}
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AA2mCA,wBAAsB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAqJ5D"}
package/dist/cli.js CHANGED
@@ -19,12 +19,57 @@ import { generateCursorConfig } from "./services/cursor-generator.js";
19
19
  import { generateWindsurfConfig } from "./services/windsurf-generator.js";
20
20
  import { generateCodexConfig } from "./services/codex-generator.js";
21
21
  import { atomicWrite } from "./services/file-ops.js";
22
+ import { createInterface } from "node:readline";
22
23
  import { CONTEXT_WINDOW_TOKENS } from "./constants.js";
23
24
  import { runPrereview, loadPrereviewConfig, } from "./services/prereview-engine.js";
24
25
  import { runHybridPrereview } from "./services/prereview-llm.js";
25
26
  import { loadLicense, loadUsage, canUseLLMReview } from "./services/license.js";
26
27
  import { loadMemory, clearMemory, learnFromHistory, exportMemorySummary, } from "./services/prereview-memory.js";
27
- const VERSION = "2.4.0";
28
+ import { analyzeDecisionHistory, formatAnalyticsReport, exportAnalyticsJSON, generateBlockRateChart, } from "./services/prereview-analytics.js";
29
+ const VERSION = "2.4.2";
30
+ /**
31
+ * Read stdin if available (non-blocking check)
32
+ * Returns the parsed JSON if it's a valid hook input, null otherwise
33
+ */
34
+ async function readStdinHookInput() {
35
+ // Check if stdin has data (is a pipe, not a TTY)
36
+ if (process.stdin.isTTY) {
37
+ return null;
38
+ }
39
+ return new Promise((resolve) => {
40
+ let data = "";
41
+ const rl = createInterface({
42
+ input: process.stdin,
43
+ terminal: false,
44
+ });
45
+ const timeout = setTimeout(() => {
46
+ rl.close();
47
+ resolve(null);
48
+ }, 100); // 100ms timeout for stdin
49
+ rl.on("line", (line) => {
50
+ data += line;
51
+ });
52
+ rl.on("close", () => {
53
+ clearTimeout(timeout);
54
+ if (!data) {
55
+ resolve(null);
56
+ return;
57
+ }
58
+ try {
59
+ const parsed = JSON.parse(data);
60
+ if (parsed.tool_name && parsed.tool_input) {
61
+ resolve(parsed);
62
+ }
63
+ else {
64
+ resolve(null);
65
+ }
66
+ }
67
+ catch {
68
+ resolve(null);
69
+ }
70
+ });
71
+ });
72
+ }
28
73
  function parseArgs(args) {
29
74
  const options = {
30
75
  path: ".",
@@ -528,10 +573,10 @@ async function cmdMetrics(options) {
528
573
  return 1;
529
574
  }
530
575
  }
531
- async function cmdPrereview(options, operation, filePath, command) {
576
+ async function cmdPrereview(options, operation, filePath, command, stdinContent) {
532
577
  const projectPath = resolveProjectPath(options.path);
533
578
  // Load config
534
- let config = await loadPrereviewConfig(projectPath);
579
+ const config = await loadPrereviewConfig(projectPath);
535
580
  if (!config) {
536
581
  // Pre-review not enabled, pass through
537
582
  return 0;
@@ -549,9 +594,12 @@ async function cmdPrereview(options, operation, filePath, command) {
549
594
  if (op === "bash") {
550
595
  content = command || "";
551
596
  }
597
+ else if (stdinContent) {
598
+ // Use content from stdin (PreToolCall hook provides this)
599
+ content = stdinContent;
600
+ }
552
601
  else if (filePath) {
553
- // For write/edit, we'd ideally get the content being written
554
- // For now, read the file if it exists (for edit operations)
602
+ // Fallback: read existing file (only useful for Edit, not Write)
555
603
  const existing = await readFileSafe(filePath);
556
604
  content = existing || "";
557
605
  }
@@ -838,6 +886,23 @@ async function cmdMemory(options, action) {
838
886
  return 1;
839
887
  }
840
888
  }
889
+ async function cmdAnalytics(options, daysBack) {
890
+ const projectPath = resolveProjectPath(options.path);
891
+ console.error("Analyzing decision history...");
892
+ const analysis = await analyzeDecisionHistory(projectPath, daysBack);
893
+ if (options.format === "json") {
894
+ console.log(exportAnalyticsJSON(analysis));
895
+ }
896
+ else {
897
+ console.log(formatAnalyticsReport(analysis));
898
+ // Add block rate chart if we have data
899
+ if (analysis.daily.length > 0) {
900
+ console.log();
901
+ console.log(generateBlockRateChart(analysis.daily));
902
+ }
903
+ }
904
+ return 0;
905
+ }
841
906
  async function cmdBadge(options) {
842
907
  const projectPath = resolveProjectPath(options.path);
843
908
  // Run audit to get current score
@@ -941,36 +1006,49 @@ export async function runCLI(args) {
941
1006
  case "badge":
942
1007
  return cmdBadge(options);
943
1008
  case "prereview": {
944
- // Parse prereview-specific args
1009
+ // Try to read hook input from stdin first (Claude Code PreToolCall format)
1010
+ const hookInput = await readStdinHookInput();
945
1011
  let op = "";
946
1012
  let file = "";
947
1013
  let cmd = "";
948
- for (let i = 0; i < positional.length; i++) {
949
- const arg = positional[i];
950
- if (arg === "--op" && positional[i + 1]) {
951
- op = positional[++i];
952
- }
953
- else if (arg === "--file" && positional[i + 1]) {
954
- file = positional[++i];
955
- }
956
- else if (arg === "--cmd" && positional[i + 1]) {
957
- cmd = positional[++i];
958
- }
1014
+ let content = "";
1015
+ if (hookInput) {
1016
+ // Extract from stdin JSON (PreToolCall hook format)
1017
+ op = hookInput.tool_name;
1018
+ const toolInput = hookInput.tool_input;
1019
+ file = toolInput.file_path || "";
1020
+ content = toolInput.content || "";
1021
+ cmd = toolInput.command || "";
959
1022
  }
960
- // Also check original args for flags
961
- const allArgs = process.argv.slice(2);
962
- for (let i = 0; i < allArgs.length; i++) {
963
- if (allArgs[i] === "--op" && allArgs[i + 1]) {
964
- op = allArgs[++i];
965
- }
966
- else if (allArgs[i] === "--file" && allArgs[i + 1]) {
967
- file = allArgs[++i];
1023
+ else {
1024
+ // Fallback to command-line args
1025
+ for (let i = 0; i < positional.length; i++) {
1026
+ const arg = positional[i];
1027
+ if (arg === "--op" && positional[i + 1]) {
1028
+ op = positional[++i];
1029
+ }
1030
+ else if (arg === "--file" && positional[i + 1]) {
1031
+ file = positional[++i];
1032
+ }
1033
+ else if (arg === "--cmd" && positional[i + 1]) {
1034
+ cmd = positional[++i];
1035
+ }
968
1036
  }
969
- else if (allArgs[i] === "--cmd" && allArgs[i + 1]) {
970
- cmd = allArgs[++i];
1037
+ // Also check original args for flags
1038
+ const allArgs = process.argv.slice(2);
1039
+ for (let i = 0; i < allArgs.length; i++) {
1040
+ if (allArgs[i] === "--op" && allArgs[i + 1]) {
1041
+ op = allArgs[++i];
1042
+ }
1043
+ else if (allArgs[i] === "--file" && allArgs[i + 1]) {
1044
+ file = allArgs[++i];
1045
+ }
1046
+ else if (allArgs[i] === "--cmd" && allArgs[i + 1]) {
1047
+ cmd = allArgs[++i];
1048
+ }
971
1049
  }
972
1050
  }
973
- return cmdPrereview(options, op, file, cmd);
1051
+ return cmdPrereview(options, op, file, cmd, content);
974
1052
  }
975
1053
  case "prereview-stats":
976
1054
  return cmdPrereviewStats(options);
@@ -978,6 +1056,10 @@ export async function runCLI(args) {
978
1056
  return cmdLicense(options);
979
1057
  case "memory":
980
1058
  return cmdMemory(options, positional[0] || "show");
1059
+ case "analytics": {
1060
+ const days = positional[0] ? parseInt(positional[0], 10) : 30;
1061
+ return cmdAnalytics(options, days);
1062
+ }
981
1063
  case "version":
982
1064
  case "--version":
983
1065
  case "-v":
@@ -1000,6 +1082,7 @@ Usage:
1000
1082
  rebar prereview-stats View pre-review decision statistics
1001
1083
  rebar license View license status and LLM usage
1002
1084
  rebar memory [action] Manage cross-session memory (show|learn|clear|export)
1085
+ rebar analytics [days] View trend analysis and insights (default: 30 days)
1003
1086
  rebar version Print version
1004
1087
  rebar help Show this help
1005
1088
 
@@ -1019,6 +1102,8 @@ Examples:
1019
1102
  rebar init --strictness strict --platforms all
1020
1103
  rebar audit --threshold 80 --format json
1021
1104
  rebar doctor
1105
+ rebar analytics 7 # Last 7 days of trends
1106
+ rebar analytics --format json # JSON export for dashboards
1022
1107
  rebar prereview-stats
1023
1108
  npx rebar-mcp audit --threshold 70 # CI/CD usage
1024
1109