Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .claude-plugin/marketplace.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
"name": "matrix",
"source": "./",
"description": "Claude on Rails Tooling System - Persistent memory for Claude Code",
"version": "2.0.0"
"version": "2.0.1"
}
],
"version": "2.0.0"
"version": "2.0.1"
}
2 changes: 1 addition & 1 deletion .claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "matrix",
"description": "Claude on Rails Tooling System",
"version": "2.0.0",
"version": "2.0.1",
"author": {
"name": "Matrix Contributors"
},
Expand Down
15 changes: 12 additions & 3 deletions .github/workflows/release-plugin.yml
Original file line number Diff line number Diff line change
Expand Up @@ -164,11 +164,20 @@ jobs:
id: changelog
run: |
VERSION="${{ needs.check-release.outputs.version }}"
# Extract changelog section for this version
CHANGELOG=$(awk "/^## \[$VERSION\]/{flag=1; next} /^## \[/{flag=0} flag" CHANGELOG.md)
# Extract changelog for current version AND previous version for context
# count=0: not started, count=1: current version, count=2: previous version
CHANGELOG=$(awk '
/^## \[/ {
count++
if (count == 1) { print "# What'\''s New in v'"$VERSION"'"; print ""; next }
if (count == 2) { print ""; print "---"; print ""; print "# Previous Release"; print ""; }
if (count > 2) { exit }
}
count >= 1 && count <= 2 { print }
' CHANGELOG.md)
# Write to file for multiline content
echo "$CHANGELOG" > /tmp/changelog.md
echo "Changelog for v$VERSION:"
echo "Changelog for v$VERSION (with previous release):"
cat /tmp/changelog.md

- name: Create plugin archive
Expand Down
42 changes: 42 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,48 @@

All notable changes to Claude Matrix are documented here.

## [2.0.1] - 2025-01-09

### Added

#### Greptile-Style Code Review Output
- **Enhanced `/matrix:review`** - New output format inspired by Greptile
- Summary with 2-3 sentence overview
- Key Changes bullet list
- Critical Issues Found with numbered, detailed explanations
- Additional Issues for minor items
- Positive Aspects for good patterns
- **Confidence Score (1-5)** with explanation
- **Important Files Changed** table with per-file scores (1-5)
- Detailed File Analysis section

#### Pre-Commit Code Review
- **PreToolUse:Bash Hook** - Suggests Matrix review BEFORE commits
- Detects `git commit` and `jj commit/describe/new` commands
- Prompts Claude to consider running `/matrix:review staged [depth]`
- Non-blocking suggestion to catch issues before they're committed
- **Jujutsu (jj) Support** - Works with both Git and Jujutsu VCS
- **New Config** - `hooks.gitCommitReview`
- `enabled`: Toggle feature on/off (default: true)
- `depth`: Review depth - `'quick'` | `'standard'` | `'thorough'` (default: `'standard'`)

### Fixed

- **Rule Engine Integration** - User-defined rules now properly evaluated in all hooks
- `PreToolUse:Edit` - Evaluates edit rules before cursed file checks
- `PreToolUse:Read` - Evaluates read rules before sensitive file detection
- `UserPromptSubmit` - Evaluates prompt rules at start of analysis
- Previously, rules were only evaluated in `PreToolUse:Bash`

### Changed

- **Deep Research Save Location** - Now saves to session directory
- Primary: `$CLAUDE_SESSION_DIR/matrix-research-[slug]-[timestamp].md`
- Fallback: `./matrix-research-[slug]-[timestamp].md` (current working directory)
- Previously saved to `~/Downloads/`

---

## [2.0.0] - 2025-01-09

### Major Release - "Matrix v2"
Expand Down
4 changes: 3 additions & 1 deletion commands/deep-research.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,9 @@ Generate a polished markdown document:
...
```

Save to: `~/Downloads/matrix-research-[slug]-[timestamp].md`
Save to session directory: Use `$CLAUDE_SESSION_DIR/matrix-research-[slug]-[timestamp].md`

If `$CLAUDE_SESSION_DIR` is not available, fall back to current working directory: `./matrix-research-[slug]-[timestamp].md`

## Examples

Expand Down
83 changes: 61 additions & 22 deletions commands/review.md
Original file line number Diff line number Diff line change
Expand Up @@ -121,38 +121,77 @@ For each concern from Phase 3:

### Phase 5: Reflection & Consolidation

Generate final review output:
Generate final review output in Greptile-style format:

1. **Prioritize findings**
- Critical: Must fix before merge
- Important: Should fix, may defer
- Suggestion: Nice to have improvements
- Praise: Things done well
1. **Calculate Confidence Score (1-5)**
- 5/5: No issues, ready to merge
- 4/5: Minor suggestions only, approve with optional changes
- 3/5: Some issues that should be addressed but not blocking
- 2/5: Important issues that need attention before merge
- 1/5: Critical bugs or issues that will cause incorrect behavior

2. **Format review output**

2. **Format review comments**
```markdown
## Code Review Summary
# Matrix Review

## Summary
[2-3 sentence overview of what this PR/change does and its purpose]

## Key Changes
- [Change 1]: Brief description
- [Change 2]: Brief description
- [Change 3]: Brief description

## Critical Issues Found

### 1. [Issue Title]
[Detailed explanation of the issue, why it's critical, and what behavior it will cause]

### 2. [Issue Title]
[Detailed explanation]

## Additional Issues
- [Minor issue 1]
- [Minor issue 2]

**Change Type:** [bugfix|feature|refactor|...]
**Blast Radius:** [low|medium|high] - [N] files directly affected
**Overall Assessment:** [Approve|Request Changes|Comment]
## Positive Aspects
- [Good practice observed]
- [Well-implemented pattern]

### Critical Issues
- [File:Line] Issue description
Suggestion: How to fix
## Confidence Score: [N]/5

### Important Items
- [File:Line] Issue description
Suggestion: How to improve
[Explanation of why this score was given, referencing the critical issues]

### Suggestions
- [File:Line] Suggestion description
**Files requiring attention:** [file1.ts] (critical issue #1), [file2.ts] (critical issue #2)

### What's Done Well
- [Positive observation]
---

## Important Files Changed

| Filename | Score | Overview |
|----------|-------|----------|
| path/to/file1.ts | 2/5 | Brief description of issues in this file |
| path/to/file2.ts | 1/5 | Brief description of critical issues |
| path/to/file3.ts | 5/5 | No issues found, clean implementation |

### File Analysis

#### `path/to/file1.ts` — Score: 2/5
[Detailed analysis of this file's changes, issues found, and suggestions]

#### `path/to/file2.ts` — Score: 1/5
[Detailed analysis of this file's changes, issues found, and suggestions]
```

3. **Learning loop**
3. **Scoring Guidelines per File**
- 5/5: No issues, clean implementation
- 4/5: Minor style or documentation suggestions
- 3/5: Some improvements recommended
- 2/5: Has bugs or significant issues
- 1/5: Critical bugs that will cause incorrect behavior

4. **Learning loop**
- If reviewer spots a pattern that should be remembered:
Use `matrix_store` to save for future reviews
- If a recalled solution helped:
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "claude-matrix",
"version": "2.0.0",
"version": "2.0.1",
"description": "Claude on Rails Tooling System",
"type": "module",
"main": "src/index.ts",
Expand Down
17 changes: 17 additions & 0 deletions src/config/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,15 @@ export interface PromptAnalysisConfig {
};
}

// ═══════════════════════════════════════════════════════════════
// Pre-Commit Review Config
// ═══════════════════════════════════════════════════════════════
export interface GitCommitReviewConfig {
enabled: boolean;
/** Review depth: 'quick' | 'standard' | 'thorough' */
depth: 'quick' | 'standard' | 'thorough';
}

// ═══════════════════════════════════════════════════════════════
// User-Configurable Rules (v2.0)
// ═══════════════════════════════════════════════════════════════
Expand Down Expand Up @@ -147,6 +156,7 @@ export interface HooksConfig {
packageAuditor: PackageAuditorConfig;
cursedFiles: CursedFilesConfig;
promptAnalysis: PromptAnalysisConfig;
gitCommitReview: GitCommitReviewConfig;
// v2.0 User Rules
userRules: UserRulesConfig;
// v2.0 Hook Verbosity
Expand Down Expand Up @@ -317,6 +327,13 @@ export const DEFAULT_CONFIG: MatrixConfig = {
},
},

// ─── Pre-Commit Review (PreToolUse:Bash hook) ───
// Triggers Matrix review before git/jj commits
gitCommitReview: {
enabled: true,
depth: 'standard' as const,
},

// ─── User Rules (v2.0) ───
userRules: {
enabled: true,
Expand Down
76 changes: 69 additions & 7 deletions src/hooks/pre-tool-bash.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
#!/usr/bin/env bun
/**
* PreToolUse:Bash Hook (Package Auditor)
* PreToolUse:Bash Hook (Package Auditor + Pre-Commit Review)
*
* Runs before Bash tool executes.
* Detects package install commands and audits packages for:
* - CVEs (via OSV.dev)
* - Bundle size (via Bundlephobia, npm only)
* - Deprecation status (via npm registry)
* - Local warnings (Matrix database)
* Features:
* - Pre-commit code review: Suggests Matrix review before git/jj commits
* - Package auditing: CVEs, bundle size, deprecation, local warnings
*
* Exit codes:
* 0 = Success (allows tool to proceed)
Expand All @@ -28,6 +26,23 @@ import {
type Ecosystem,
} from './index.js';
import { matrixWarn, type WarnCheckResult, type WarnResult } from '../tools/warn.js';
import { getConfig } from '../config/index.js';
import { evaluateBashRules, formatRuleResult } from './rule-engine.js';

/**
* Check if command is a git or jj commit
*/
function isCommitCommand(command: string): { isCommit: boolean; vcs: 'git' | 'jj' | null } {
// Git: git commit, git commit -m, git commit -am, git commit --amend, etc.
if (/^\s*git\s+commit\b/.test(command)) {
return { isCommit: true, vcs: 'git' };
}
// Jujutsu: jj commit, jj describe (creates new commit), jj new (creates new change)
if (/^\s*jj\s+(commit|describe|new)\b/.test(command)) {
return { isCommit: true, vcs: 'jj' };
}
return { isCommit: false, vcs: null };
}

/**
* Type guard to check if a WarnResult is a WarnCheckResult
Expand Down Expand Up @@ -254,7 +269,54 @@ export async function run() {
process.exit(0);
}

// Parse package command
// ============================================
// STEP 1: Evaluate user-defined rules
// ============================================
const ruleResult = evaluateBashRules(command);

if (ruleResult.blocked) {
const output: HookOutput = {
hookSpecificOutput: {
hookEventName: 'PreToolUse',
permissionDecision: 'deny',
permissionDecisionReason: formatRuleResult(ruleResult),
},
};
outputJson(output);
process.exit(0);
}

if (ruleResult.warned) {
// Warnings don't block, but we could log them
console.error(formatRuleResult(ruleResult));
}

// ============================================
// STEP 2: Pre-commit review suggestion
// ============================================
const config = getConfig();
const gitReviewConfig = config.hooks.gitCommitReview;
const commitCheck = isCommitCommand(command);

if (gitReviewConfig?.enabled && commitCheck.isCommit) {
const depth = gitReviewConfig.depth ?? 'standard';
const vcsName = commitCheck.vcs === 'jj' ? 'Jujutsu' : 'Git';

// Suggest review before commit (non-blocking)
const output: HookOutput = {
hookSpecificOutput: {
hookEventName: 'PreToolUse',
additionalContext: `[Matrix] ${vcsName} commit detected. Consider running a code review first:\n\n/matrix:review staged ${depth}\n\nThis helps catch issues before they're committed.`,
},
};

outputJson(output);
process.exit(0);
}

// ============================================
// STEP 3: Package auditing
// ============================================
const parsed = parsePackageCommand(command);
if (!parsed || parsed.packages.length === 0) {
// Not a package install command
Expand Down
32 changes: 31 additions & 1 deletion src/hooks/pre-tool-edit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import {
type HookOutput,
} from './index.js';
import { matrixWarn, type WarnCheckResult } from '../tools/warn.js';
import { evaluateEditRules, formatRuleResult } from './rule-engine.js';

export async function run() {
try {
Expand All @@ -36,7 +37,36 @@ export async function run() {
process.exit(0);
}

// Check for file warnings
// Get content for pattern matching (Edit has old_string/new_string, Write has content)
const content = (input.tool_input.new_string as string) ||
(input.tool_input.content as string) ||
'';

// ============================================
// STEP 1: Evaluate user-defined rules
// ============================================
const ruleResult = evaluateEditRules(filePath, content);

if (ruleResult.blocked) {
const output: HookOutput = {
hookSpecificOutput: {
hookEventName: 'PreToolUse',
permissionDecision: 'deny',
permissionDecisionReason: formatRuleResult(ruleResult),
},
};
outputJson(output);
process.exit(0);
}

if (ruleResult.warned) {
// Warnings don't block, but log them
console.error(formatRuleResult(ruleResult));
}

// ============================================
// STEP 2: Check for file warnings (cursed files)
// ============================================
const result = await matrixWarn({
action: 'check',
type: 'file',
Expand Down
Loading