rebar-mcp 2.2.0 → 2.4.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/settings.json +49 -19
- package/.claude/skills/bmmov0lh5xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/SKILL.md +21 -0
- package/.claude/skills/bmmovah7zxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/SKILL.md +21 -0
- package/.claude/skills/bnd-mmov0lh8/SKILL.md +21 -0
- package/.claude/skills/bnd-mmovah83/SKILL.md +21 -0
- package/.claude/skills/nl-mmov0lhi/SKILL.md +25 -0
- package/.claude/skills/nl-mmovah8b/SKILL.md +25 -0
- package/.rebar/prereview.json +9 -0
- package/CLAUDE.md +17 -67
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +165 -5
- package/dist/cli.js.map +1 -1
- package/dist/index.js +1 -1
- package/dist/services/context-builder.d.ts +41 -0
- package/dist/services/context-builder.d.ts.map +1 -0
- package/dist/services/context-builder.js +248 -0
- package/dist/services/context-builder.js.map +1 -0
- package/dist/services/license.d.ts +52 -0
- package/dist/services/license.d.ts.map +1 -0
- package/dist/services/license.js +194 -0
- package/dist/services/license.js.map +1 -0
- package/dist/services/prereview-llm.d.ts +15 -0
- package/dist/services/prereview-llm.d.ts.map +1 -0
- package/dist/services/prereview-llm.js +266 -0
- package/dist/services/prereview-llm.js.map +1 -0
- package/dist/services/prereview-memory.d.ts +101 -0
- package/dist/services/prereview-memory.d.ts.map +1 -0
- package/dist/services/prereview-memory.js +301 -0
- package/dist/services/prereview-memory.js.map +1 -0
- package/package.json +1 -1
- package/src/cli.ts +200 -5
- package/src/index.ts +1 -1
- package/src/services/context-builder.ts +325 -0
- package/src/services/license.ts +252 -0
- package/src/services/prereview-llm.ts +365 -0
- package/src/services/prereview-memory.ts +439 -0
package/.claude/settings.json
CHANGED
|
@@ -1,24 +1,54 @@
|
|
|
1
1
|
{
|
|
2
|
-
"permissions": {
|
|
3
|
-
"allow": [
|
|
4
|
-
"Bash(npm run build)",
|
|
5
|
-
"Bash(npm run lint)",
|
|
6
|
-
"Bash(npm run test *)",
|
|
7
|
-
"Bash(npm run dev)",
|
|
8
|
-
"Bash(npx tsc --noEmit)",
|
|
9
|
-
"Bash(git status)",
|
|
10
|
-
"Bash(git diff *)",
|
|
11
|
-
"Bash(git log *)",
|
|
12
|
-
"Bash(git add *)",
|
|
13
|
-
"Bash(git commit *)"
|
|
14
|
-
],
|
|
15
|
-
"deny": [
|
|
16
|
-
"Bash(rm -rf *)",
|
|
17
|
-
"Read(./.env)",
|
|
18
|
-
"Read(./.env.*)"
|
|
19
|
-
]
|
|
20
|
-
},
|
|
21
2
|
"hooks": {
|
|
3
|
+
"PostToolCall": [
|
|
4
|
+
{
|
|
5
|
+
"matcher": "Write(*.ts)|Write(*.tsx)|Write(*.js)|Write(*.jsx)",
|
|
6
|
+
"hooks": [
|
|
7
|
+
{
|
|
8
|
+
"type": "command",
|
|
9
|
+
"command": "npm run format \"$CLAUDE_FILE_PATH\" 2>/dev/null || true"
|
|
10
|
+
}
|
|
11
|
+
]
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
"matcher": "Write(*.ts)|Write(*.tsx)|Write(*.js)|Write(*.jsx)",
|
|
15
|
+
"hooks": [
|
|
16
|
+
{
|
|
17
|
+
"type": "command",
|
|
18
|
+
"command": "RESULT=$(npm run lint \"$CLAUDE_FILE_PATH\" 2>&1); EXITCODE=$?; if [ $EXITCODE -ne 0 ]; then echo \"$RESULT\" | head -20; echo '\\n❌ LINT ERRORS — Fix these before continuing.' >&2; exit 2; fi; exit 0"
|
|
19
|
+
}
|
|
20
|
+
]
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
"matcher": "Write(*.ts)|Write(*.tsx)|Write(*.js)|Write(*.jsx)|Edit(*.ts)|Edit(*.tsx)|Edit(*.js)|Edit(*.jsx)",
|
|
24
|
+
"hooks": [
|
|
25
|
+
{
|
|
26
|
+
"type": "command",
|
|
27
|
+
"command": "node --test dist/**/*.test.js 2>&1 | tail -10; EXIT_CODE=${PIPESTATUS[0]}; if [ $EXIT_CODE -ne 0 ]; then echo '\\n❌ TESTS FAILED — Fix failing tests before continuing. Do not move to the next task.' >&2; exit 2; fi; exit 0"
|
|
28
|
+
}
|
|
29
|
+
]
|
|
30
|
+
}
|
|
31
|
+
],
|
|
32
|
+
"PreToolCall": [
|
|
33
|
+
{
|
|
34
|
+
"matcher": "Bash",
|
|
35
|
+
"hooks": [
|
|
36
|
+
{
|
|
37
|
+
"type": "command",
|
|
38
|
+
"command": "BLOCKED='rm -rf|rm -fr|git push --force|git push -f|DROP TABLE|DROP DATABASE|TRUNCATE TABLE|chmod -R 777'; if echo \"$CLAUDE_BASH_COMMAND\" | grep -qiE \"$BLOCKED\"; then echo 'BLOCKED: Destructive command detected. Ask the developer for explicit approval.' >&2; exit 2; fi; exit 0"
|
|
39
|
+
}
|
|
40
|
+
]
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
"matcher": "Bash(git commit*)|Bash(git add*)",
|
|
44
|
+
"hooks": [
|
|
45
|
+
{
|
|
46
|
+
"type": "command",
|
|
47
|
+
"command": "STAGED=$(git diff --cached --name-only 2>/dev/null); if [ -z \"$STAGED\" ]; then exit 0; fi; SECRETS=$(git diff --cached | grep -inE '(api[_-]?key|secret|password|token|private[_-]?key|aws_access|AKIA[A-Z0-9]{16})\\s*[:=]\\s*[\"\\x27]?[A-Za-z0-9+/=_-]{8,}' | head -5); if [ -n \"$SECRETS\" ]; then echo \"BLOCKED: Potential secrets in staged files:\" >&2; echo \"$SECRETS\" >&2; exit 2; fi; exit 0"
|
|
48
|
+
}
|
|
49
|
+
]
|
|
50
|
+
}
|
|
51
|
+
],
|
|
22
52
|
"InvalidEvent": [
|
|
23
53
|
{
|
|
24
54
|
"description": "A test hook",
|
package/.claude/skills/bmmov0lh5xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/SKILL.md
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: bmmov0lh5xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
|
3
|
+
description: A test skill
|
|
4
|
+
invocation: undefined
|
|
5
|
+
context: undefined
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# bmmov0lh5xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
|
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/bmmovah7zxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/SKILL.md
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: bmmovah7zxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
|
3
|
+
description: A test skill
|
|
4
|
+
invocation: undefined
|
|
5
|
+
context: undefined
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# bmmovah7zxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
|
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-mmov0lh8
|
|
3
|
+
description: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
|
4
|
+
invocation: undefined
|
|
5
|
+
context: undefined
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# bnd-mmov0lh8
|
|
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-mmovah83
|
|
3
|
+
description: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
|
4
|
+
invocation: undefined
|
|
5
|
+
context: undefined
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# bnd-mmovah83
|
|
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-mmov0lhi
|
|
3
|
+
description: Line one
|
|
4
|
+
Line two
|
|
5
|
+
Line three
|
|
6
|
+
invocation: undefined
|
|
7
|
+
context: undefined
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# nl-mmov0lhi
|
|
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-mmovah8b
|
|
3
|
+
description: Line one
|
|
4
|
+
Line two
|
|
5
|
+
Line three
|
|
6
|
+
invocation: undefined
|
|
7
|
+
context: undefined
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# nl-mmovah8b
|
|
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/CLAUDE.md
CHANGED
|
@@ -1,76 +1,26 @@
|
|
|
1
1
|
# rebar-mcp
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
Reinforcement for AI-generated code. An MCP server that generates, validates, and manages Claude Code configuration artifacts (CLAUDE.md, skills, agents, hooks, commands, MCP configs, knowledge docs) with enforcement hooks that prevent AI coding tools from shipping broken code.
|
|
3
|
+
Reinforcement for AI-generated code. Enforcement hooks, quality audits, and opinionated templates that prevent AI coding tools from shipping broken code.
|
|
5
4
|
|
|
6
5
|
## Tech Stack
|
|
7
|
-
- TypeScript (strict mode)
|
|
8
|
-
- Node.js 18+ runtime
|
|
9
|
-
- @modelcontextprotocol/sdk for MCP server
|
|
10
|
-
- Zod for input validation
|
|
11
|
-
- stdio transport (primary), streamable HTTP (secondary)
|
|
6
|
+
- TypeScript (strict mode)
|
|
12
7
|
|
|
13
8
|
## Architecture Rules
|
|
14
|
-
-
|
|
15
|
-
-
|
|
16
|
-
-
|
|
17
|
-
-
|
|
18
|
-
- All async functions have explicit Promise<T> return types
|
|
19
|
-
- Log to stderr ONLY (stdout is reserved for MCP protocol)
|
|
20
|
-
- Never use console.log() — use console.error() for debug output
|
|
21
|
-
- All file writes are atomic (write to temp, then rename)
|
|
22
|
-
- Never overwrite files without checking merge_existing flag
|
|
23
|
-
|
|
24
|
-
## Tool Annotations
|
|
25
|
-
Every tool MUST include annotations:
|
|
26
|
-
- readOnlyHint: true for read operations, false for writes
|
|
27
|
-
- destructiveHint: false (we never delete without explicit request)
|
|
28
|
-
- idempotentHint: true if re-running produces same result
|
|
29
|
-
- openWorldHint: false (we only touch local filesystem)
|
|
30
|
-
|
|
31
|
-
## File Structure
|
|
32
|
-
- src/index.ts — Entry point, server init, transport
|
|
33
|
-
- src/types.ts — Shared TypeScript interfaces
|
|
34
|
-
- src/constants.ts — Enums, defaults, limits
|
|
35
|
-
- src/tools/*.ts — Tool implementations (one file per domain)
|
|
36
|
-
- src/services/*.ts — Shared utilities (file ops, templates, validation)
|
|
37
|
-
- src/schemas/*.ts — Zod schemas
|
|
38
|
-
- templates/**/*.md — Raw template files
|
|
9
|
+
- No use of `any` type — use `unknown` with type narrowing or proper generics
|
|
10
|
+
- Prefer `interface` for object shapes, `type` for unions and intersections
|
|
11
|
+
- Never store secrets in code, config files, or version control
|
|
12
|
+
- All external data (user input, API responses, env vars) must be validated before use
|
|
39
13
|
|
|
40
14
|
## Build & Test
|
|
41
|
-
- Build: `npm run build` (
|
|
42
|
-
-
|
|
43
|
-
- Test: `npm run test`
|
|
44
|
-
- Dev: `npx tsx src/index.ts` (for local MCP testing)
|
|
45
|
-
|
|
46
|
-
## Template Conventions
|
|
47
|
-
- Variables: `{{variable_name}}` (double curly braces)
|
|
48
|
-
- Conditionals: `{{#if condition}}...{{/if}}`
|
|
49
|
-
- Templates are plain markdown with substitution markers
|
|
50
|
-
- All generated YAML must parse cleanly
|
|
51
|
-
- All generated JSON must be valid
|
|
52
|
-
- Skills MUST have name (max 64 chars) and description (max 200 chars)
|
|
15
|
+
- Build: `npm run build` (runs: `tsc`)
|
|
16
|
+
- Test: `npm run test` (runs: `node --test dist/**/*.test.js`)
|
|
53
17
|
|
|
54
|
-
##
|
|
55
|
-
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
-
|
|
59
|
-
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
-
|
|
63
|
-
- Tool descriptions must include: purpose summary, all args with types, return schema with field descriptions, 2-3 usage examples, and error handling notes
|
|
64
|
-
- Support both JSON and Markdown response formats where applicable
|
|
65
|
-
- Paginate list results with has_more, next_offset, total_count
|
|
66
|
-
- Return { isError: true, content: [...] } for recoverable errors with actionable suggestions
|
|
67
|
-
|
|
68
|
-
## Implementation Priority
|
|
69
|
-
1. src/index.ts + transport setup
|
|
70
|
-
2. src/services/ (file-ops, template-engine, validation)
|
|
71
|
-
3. src/types.ts + src/constants.ts + src/schemas/
|
|
72
|
-
4. src/tools/scaffolding.ts (init_project, generate_claudemd, create_skill, create_agent, create_hook, create_command)
|
|
73
|
-
5. templates/ (CLAUDE.md templates, skill templates, agent templates, hook templates)
|
|
74
|
-
6. src/tools/knowledge.ts (create_knowledge, create_adr)
|
|
75
|
-
7. src/tools/management.ts (list_artifacts, validate_config, audit_context)
|
|
76
|
-
8. src/tools/enterprise.ts (apply_compliance, create_ci_workflow, create_security_hook, generate_mcp_config)
|
|
18
|
+
## File Structure
|
|
19
|
+
- `src/` — Source code
|
|
20
|
+
|
|
21
|
+
## Code Conventions
|
|
22
|
+
- TypeScript strict mode with no `any` types
|
|
23
|
+
- Prefer named exports over default exports
|
|
24
|
+
- Interface names: `PascalCase` (no `I` prefix)
|
|
25
|
+
- Constants: `UPPER_SNAKE_CASE`
|
|
26
|
+
- Zod schemas for runtime validation of external data
|
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":";AAshCA,wBAAsB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAgI5D"}
|
package/dist/cli.js
CHANGED
|
@@ -21,7 +21,10 @@ import { generateCodexConfig } from "./services/codex-generator.js";
|
|
|
21
21
|
import { atomicWrite } from "./services/file-ops.js";
|
|
22
22
|
import { CONTEXT_WINDOW_TOKENS } from "./constants.js";
|
|
23
23
|
import { runPrereview, loadPrereviewConfig, } from "./services/prereview-engine.js";
|
|
24
|
-
|
|
24
|
+
import { runHybridPrereview } from "./services/prereview-llm.js";
|
|
25
|
+
import { loadLicense, loadUsage, canUseLLMReview } from "./services/license.js";
|
|
26
|
+
import { loadMemory, clearMemory, learnFromHistory, exportMemorySummary, } from "./services/prereview-memory.js";
|
|
27
|
+
const VERSION = "2.4.0";
|
|
25
28
|
function parseArgs(args) {
|
|
26
29
|
const options = {
|
|
27
30
|
path: ".",
|
|
@@ -555,8 +558,20 @@ async function cmdPrereview(options, operation, filePath, command) {
|
|
|
555
558
|
if (!content) {
|
|
556
559
|
return 0;
|
|
557
560
|
}
|
|
558
|
-
// Run pre-review
|
|
559
|
-
const
|
|
561
|
+
// Run local pre-review first
|
|
562
|
+
const localResult = runPrereview(content, op, filePath, config);
|
|
563
|
+
// Try hybrid review (LLM + local) if tier supports it
|
|
564
|
+
let result = localResult;
|
|
565
|
+
let engine = "local";
|
|
566
|
+
if (config.tier !== "free") {
|
|
567
|
+
const hybridResult = await runHybridPrereview(projectPath, op, filePath || "", content, undefined, // existingContent for diffs
|
|
568
|
+
localResult);
|
|
569
|
+
// Check if LLM was actually used
|
|
570
|
+
if ("engine" in hybridResult && hybridResult.engine === "llm") {
|
|
571
|
+
engine = "hybrid";
|
|
572
|
+
result = hybridResult;
|
|
573
|
+
}
|
|
574
|
+
}
|
|
560
575
|
// Write to audit trail
|
|
561
576
|
if (config.auditEnabled) {
|
|
562
577
|
const now = new Date();
|
|
@@ -578,7 +593,7 @@ async function cmdPrereview(options, operation, filePath, command) {
|
|
|
578
593
|
decision: result.decision,
|
|
579
594
|
severity: result.severity,
|
|
580
595
|
tier: config.tier,
|
|
581
|
-
engine
|
|
596
|
+
engine,
|
|
582
597
|
latencyMs: result.latencyMs,
|
|
583
598
|
patterns: result.patterns.map((p) => ({
|
|
584
599
|
id: p.id,
|
|
@@ -686,9 +701,143 @@ async function cmdPrereviewStats(options) {
|
|
|
686
701
|
console.log(` • ${name}: ${count}`);
|
|
687
702
|
}
|
|
688
703
|
}
|
|
704
|
+
// Show LLM usage info
|
|
705
|
+
const license = await loadLicense(projectPath);
|
|
706
|
+
const usage = await loadUsage(projectPath);
|
|
707
|
+
console.log();
|
|
708
|
+
console.log("LLM Review Usage");
|
|
709
|
+
console.log("----------------");
|
|
710
|
+
console.log(`Tier: ${license.tier}`);
|
|
711
|
+
console.log(`LLM reviews this month: ${usage.llmReviews}/${license.monthlyLimit || "∞"}`);
|
|
712
|
+
const llmCheck = await canUseLLMReview(projectPath);
|
|
713
|
+
if (!llmCheck.allowed) {
|
|
714
|
+
console.log(`Status: ${llmCheck.reason}`);
|
|
715
|
+
}
|
|
716
|
+
else {
|
|
717
|
+
console.log(`Remaining: ${llmCheck.remaining}`);
|
|
718
|
+
}
|
|
689
719
|
}
|
|
690
720
|
return 0;
|
|
691
721
|
}
|
|
722
|
+
async function cmdLicense(options) {
|
|
723
|
+
const projectPath = resolveProjectPath(options.path);
|
|
724
|
+
const license = await loadLicense(projectPath);
|
|
725
|
+
const usage = await loadUsage(projectPath);
|
|
726
|
+
const llmCheck = await canUseLLMReview(projectPath);
|
|
727
|
+
if (options.format === "json") {
|
|
728
|
+
console.log(JSON.stringify({
|
|
729
|
+
tier: license.tier,
|
|
730
|
+
features: license.features,
|
|
731
|
+
usage: {
|
|
732
|
+
llmReviews: usage.llmReviews,
|
|
733
|
+
localReviews: usage.localReviews,
|
|
734
|
+
blockedCount: usage.blockedCount,
|
|
735
|
+
month: usage.month,
|
|
736
|
+
},
|
|
737
|
+
limits: {
|
|
738
|
+
monthlyLimit: license.monthlyLimit,
|
|
739
|
+
remaining: llmCheck.remaining,
|
|
740
|
+
},
|
|
741
|
+
llmAvailable: llmCheck.allowed,
|
|
742
|
+
reason: llmCheck.reason,
|
|
743
|
+
}, null, 2));
|
|
744
|
+
}
|
|
745
|
+
else {
|
|
746
|
+
console.log("Rebar License Status");
|
|
747
|
+
console.log("====================");
|
|
748
|
+
console.log();
|
|
749
|
+
console.log(`Tier: ${license.tier.toUpperCase()}`);
|
|
750
|
+
console.log();
|
|
751
|
+
console.log("Features:");
|
|
752
|
+
console.log(` • LLM Review: ${license.features.llmReview ? "✓" : "✗"}`);
|
|
753
|
+
console.log(` • Cross-session Memory: ${license.features.crossSessionMemory ? "✓" : "✗"}`);
|
|
754
|
+
console.log(` • Audit Retention: ${license.features.auditRetentionDays} days`);
|
|
755
|
+
console.log();
|
|
756
|
+
console.log(`Usage (${usage.month}):`);
|
|
757
|
+
console.log(` • LLM Reviews: ${usage.llmReviews}/${license.monthlyLimit || "N/A"}`);
|
|
758
|
+
console.log(` • Local Reviews: ${usage.localReviews}`);
|
|
759
|
+
console.log(` • Blocked: ${usage.blockedCount}`);
|
|
760
|
+
console.log();
|
|
761
|
+
if (llmCheck.allowed) {
|
|
762
|
+
console.log(`LLM Status: Available (${llmCheck.remaining} reviews remaining)`);
|
|
763
|
+
}
|
|
764
|
+
else {
|
|
765
|
+
console.log(`LLM Status: ${llmCheck.reason}`);
|
|
766
|
+
}
|
|
767
|
+
if (license.tier === "free") {
|
|
768
|
+
console.log();
|
|
769
|
+
console.log("Upgrade to Pro for LLM-powered semantic analysis:");
|
|
770
|
+
console.log(" export REBAR_API_KEY=your_anthropic_key");
|
|
771
|
+
console.log(" export REBAR_TIER=pro");
|
|
772
|
+
}
|
|
773
|
+
}
|
|
774
|
+
return 0;
|
|
775
|
+
}
|
|
776
|
+
async function cmdMemory(options, action) {
|
|
777
|
+
const projectPath = resolveProjectPath(options.path);
|
|
778
|
+
switch (action) {
|
|
779
|
+
case "show":
|
|
780
|
+
case "": {
|
|
781
|
+
const memory = await loadMemory(projectPath);
|
|
782
|
+
if (options.format === "json") {
|
|
783
|
+
console.log(await exportMemorySummary(projectPath));
|
|
784
|
+
}
|
|
785
|
+
else {
|
|
786
|
+
console.log("Pre-Review Memory");
|
|
787
|
+
console.log("=================");
|
|
788
|
+
console.log();
|
|
789
|
+
console.log(`Last updated: ${memory.updatedAt}`);
|
|
790
|
+
console.log();
|
|
791
|
+
console.log("Statistics:");
|
|
792
|
+
console.log(` • Total reviews: ${memory.stats.totalReviews}`);
|
|
793
|
+
console.log(` • Blocks: ${memory.stats.totalBlocks}`);
|
|
794
|
+
console.log(` • Warnings: ${memory.stats.totalWarns}`);
|
|
795
|
+
console.log(` • Avg latency: ${memory.stats.avgLatencyMs.toFixed(0)}ms`);
|
|
796
|
+
console.log();
|
|
797
|
+
if (memory.learnedPatterns.length > 0) {
|
|
798
|
+
console.log("Learned Patterns:");
|
|
799
|
+
const topPatterns = memory.learnedPatterns
|
|
800
|
+
.sort((a, b) => b.blockCount - a.blockCount)
|
|
801
|
+
.slice(0, 5);
|
|
802
|
+
for (const p of topPatterns) {
|
|
803
|
+
console.log(` • ${p.name} (${p.blockCount}x, ${p.severity})`);
|
|
804
|
+
}
|
|
805
|
+
console.log();
|
|
806
|
+
}
|
|
807
|
+
if (memory.projectInsights.length > 0) {
|
|
808
|
+
console.log("Project Insights:");
|
|
809
|
+
const topInsights = memory.projectInsights
|
|
810
|
+
.filter((i) => i.confidence >= 0.7)
|
|
811
|
+
.slice(0, 3);
|
|
812
|
+
for (const i of topInsights) {
|
|
813
|
+
console.log(` • ${i.description}`);
|
|
814
|
+
}
|
|
815
|
+
}
|
|
816
|
+
}
|
|
817
|
+
return 0;
|
|
818
|
+
}
|
|
819
|
+
case "learn": {
|
|
820
|
+
console.log("Learning from decision history...");
|
|
821
|
+
const result = await learnFromHistory(projectPath);
|
|
822
|
+
console.log(`✓ Learned ${result.patternsLearned} patterns`);
|
|
823
|
+
console.log(`✓ Generated ${result.insightsGenerated} insights`);
|
|
824
|
+
return 0;
|
|
825
|
+
}
|
|
826
|
+
case "clear": {
|
|
827
|
+
await clearMemory(projectPath);
|
|
828
|
+
console.log("✓ Memory cleared");
|
|
829
|
+
return 0;
|
|
830
|
+
}
|
|
831
|
+
case "export": {
|
|
832
|
+
console.log(await exportMemorySummary(projectPath));
|
|
833
|
+
return 0;
|
|
834
|
+
}
|
|
835
|
+
default:
|
|
836
|
+
console.error(`Unknown memory action: ${action}`);
|
|
837
|
+
console.error("Usage: rebar memory [show|learn|clear|export]");
|
|
838
|
+
return 1;
|
|
839
|
+
}
|
|
840
|
+
}
|
|
692
841
|
async function cmdBadge(options) {
|
|
693
842
|
const projectPath = resolveProjectPath(options.path);
|
|
694
843
|
// Run audit to get current score
|
|
@@ -825,6 +974,10 @@ export async function runCLI(args) {
|
|
|
825
974
|
}
|
|
826
975
|
case "prereview-stats":
|
|
827
976
|
return cmdPrereviewStats(options);
|
|
977
|
+
case "license":
|
|
978
|
+
return cmdLicense(options);
|
|
979
|
+
case "memory":
|
|
980
|
+
return cmdMemory(options, positional[0] || "show");
|
|
828
981
|
case "version":
|
|
829
982
|
case "--version":
|
|
830
983
|
case "-v":
|
|
@@ -845,6 +998,8 @@ Usage:
|
|
|
845
998
|
rebar badge [options] Generate quality score badge SVG
|
|
846
999
|
rebar prereview [options] Run pre-review analysis (invoked by hooks)
|
|
847
1000
|
rebar prereview-stats View pre-review decision statistics
|
|
1001
|
+
rebar license View license status and LLM usage
|
|
1002
|
+
rebar memory [action] Manage cross-session memory (show|learn|clear|export)
|
|
848
1003
|
rebar version Print version
|
|
849
1004
|
rebar help Show this help
|
|
850
1005
|
|
|
@@ -870,7 +1025,12 @@ Examples:
|
|
|
870
1025
|
Strictness Levels:
|
|
871
1026
|
standard - Notify on issues (tests, lint, secrets)
|
|
872
1027
|
strict - Block on test/lint failures
|
|
873
|
-
paranoid - Block + file size limits + TODO guards
|
|
1028
|
+
paranoid - Block + file size limits + TODO guards
|
|
1029
|
+
|
|
1030
|
+
LLM Review (Pro/Team tier):
|
|
1031
|
+
export REBAR_API_KEY=your_anthropic_key
|
|
1032
|
+
export REBAR_TIER=pro # 1,000 LLM reviews/month
|
|
1033
|
+
export REBAR_TIER=team # 5,000 LLM reviews/month`);
|
|
874
1034
|
return 0;
|
|
875
1035
|
default:
|
|
876
1036
|
console.error(`Unknown command: ${command}`);
|