Skip to content
Open
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
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,10 @@ yarn-error.log*
*.temp
.cache/
repomix-output.*

# CodeGuardian
.repomixignore
repomix.config.json

# Newton
.newton
16 changes: 16 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,22 @@

All notable changes to Code Guardian will be documented in this file.

## [0.1.0-beta.10] - 2025-03-03

### Added
- **`codeguardian edit` command**: Web UI for editing rule files
- `codeguardian edit [file]` starts a local server (default port 3847) and opens the rule editor in the browser; default file is `.codeguardian/development-rules.cg.yaml` when `[file]` is omitted
- Options: `--port`, `--host`, `--no-open` (print URL only, do not open browser)
- Form-based editing for rule id, description, and full rule tree (combinators, selectors, assertions)
- Tooltips and inline hints on fields (path pattern, exclude pattern, status, message, suggestion, etc.)
- **Open** button: load another rule file by path (relative to project root); API supports `GET /api/rule?file=` and `PUT /api/rule` with optional `filePath` in body
- **Validate** button: `POST /api/validate` checks that the rule definition parses and builds using the existing rule factory
- **View YAML**: full serialization of the current rule, including all assertion properties (operator, max_lines, message, suggestion, documentation)
- **Message and Suggestion** tooltips in the rule editor explaining custom failure message vs actionable suggestion

### Fixed
- View YAML in the rule editor now outputs full assertion content (e.g. `operator`, `max_lines`, `message`, `suggestion`) instead of stopping after the assertion type line

## [0.1.0-beta.9] - 2025-01-06

### Added
Expand Down
62 changes: 18 additions & 44 deletions Cheat_Sheet.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,10 @@ rule:
# ... rule configuration
```

### Editing rules in the browser

Rule files can be edited visually with `codeguardian edit [file]`. The web UI shows forms for combinators, selectors, and assertions, with tooltips on fields. It supports **Open** (load another file by path), **Validate** (check the rule definition), and **View YAML** (preview generated YAML). See the README for the edit command and options. The same YAML can be authored in an editor or via this UI.

---

### 3. Selectors (Finding _What_ to Check)
Expand Down Expand Up @@ -139,6 +143,15 @@ language: 'typescript' # Required. The language to parse.

### 4. Assertions (Checking a Condition)

#### Message and Suggestion

Many assertions support optional **message** and **suggestion** fields:

- **message**: Custom main failure line when the assertion fails. Overrides the default engine message where supported (e.g. `assert_line_count`). Shown in CLI and reports.
- **suggestion**: Actionable guidance when the rule fails. Displayed as "Suggestion: ..." in console output. Use for short, actionable fixes (e.g. "Move to scripts/" or "Use parameterized queries").

Supported on: `assert_match`, `assert_line_count`, `assert_command_output`. Not supported on `assert_property` (see note there).

#### `assert_match`

Checks if an item's text content matches a regular expression.
Expand Down Expand Up @@ -383,7 +396,7 @@ rule:

```

**Use Case:** Perfect for tasks that should only refactor, fix bugs, or update existing functionality without adding new files. This helps enforce that AI-generated code stays within the intended scope of changes.
**Use Case:** Refactors or bugfixes that must not add new files.

#### Pattern 6: Control File Change Magnitude

Expand All @@ -405,7 +418,7 @@ rule:

```

**Use Case:** Essential for maintaining code stability, preventing AI from completely rewriting files, and ensuring changes are reviewable. Particularly useful for protecting critical configuration files and enforcing incremental development practices.
**Use Case:** Protect critical config from large rewrites; keep changes reviewable.

#### Pattern 7: File Size Validation

Expand All @@ -426,33 +439,9 @@ rule:
max_lines: 450
message: "Go file exceeds maximum line limit of 450 lines"
suggestion: "Consider breaking this file into smaller modules or extracting functionality"

# Example 2: Multiple language file size limits
id: file-size-limits
description: Enforce different line limits per language
rule:
type: all_of
rules:
- type: for_each
select:
type: select_files
path_pattern: '**/*.go'
assert:
type: assert_line_count
operator: '<='
max_lines: 450
- type: for_each
select:
type: select_files
path_pattern: '**/*.{ts,js}'
assert:
type: assert_line_count
operator: '<='
max_lines: 300
suggestion: "TypeScript/JavaScript files should be under 300 lines"
```

**Use Case:** Prevents overly large files that are hard to review, maintain, and understand. Encourages modular code organization and helps teams maintain consistent code quality standards.
**Use Case:** Prevents overly large files; use `all_of` with multiple `for_each` blocks for different path patterns if you need per-language limits.

---

Expand Down Expand Up @@ -676,25 +665,10 @@ rule:
pattern: '.*'
should_match: true
message: 'Found file with "_improved" suffix. Please update the original file instead.'

# Example 2: Check in --mode all (for existing files)
# Run with: codeguardian check --mode all
id: no-alternative-versions
description: Detect any alternative file versions in the entire codebase
rule:
type: none_of
rules:
- type: for_each
select:
type: select_files
path_pattern: '**/*[-_](improved|enhanced|new|v2|copy|backup|old)\.*'
assert:
type: assert_match
pattern: '.*'
should_match: true
message: 'Found alternative file version. Update the original file instead of creating duplicates.'
```

Use a broader `path_pattern` (e.g. `**/*[-_](improved|enhanced|v2|copy|backup|old)*`) and `select_all: true` to catch alternatives across the whole repo.

**Important Note about `assert_count` with `for_each`:**
The `assert_count` assertion counts items within each file separately when used inside `for_each`. It does NOT count the total number of files selected. To check if ANY files match a pattern, use the `none_of` combinator pattern shown above.

Expand Down
24 changes: 24 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ Code Guardian is a validation tool that helps you maintain code quality and arch
- 📦 **Zero Config** - Sensible defaults with full customization when needed
- 🛡️ **Git-Native** - Works seamlessly with branches, commits, and diffs
- 🚫 **Smart Exclusions** - Use `.cg-ignore` files to skip directories
- 📝 **Rule Editor** - Web UI to edit rule files with forms, tooltips, and validation (run `codeguardian edit`)

## 🚀 Quick Start

Expand Down Expand Up @@ -253,6 +254,16 @@ assert:
message: 'New files must use PascalCase'
```

### Editing rules (web UI)

Run `codeguardian edit [file]` to start a local server and open the rule editor in your browser. If you omit `[file]`, the editor loads `.codeguardian/development-rules.cg.yaml` by default. The web UI provides form-based editing for combinators, selectors, and assertions, with tooltips on fields. Use **Open** to load another rule file, **Validate** to check the rule definition, **View YAML** to see the generated YAML, and **Save** / **Revert** to persist or discard changes.

```bash
codeguardian edit .codeguardian/my-rules.cg.yaml
```

Options: `--port`, `--host`, `--no-open` (see CLI Reference below).

## 🤝 AI Integration Workflow

When using AI coding assistants:
Expand Down Expand Up @@ -290,6 +301,7 @@ Code Guardian uses simple primitives that compose into powerful rules:
- **[Claude Code Integration](docs/claude-code-integration.md)** - Automatic validation with Claude Code hooks
- **[Cheat Sheet](Cheat_Sheet.md)** - Complete syntax reference with examples
- **[Examples](examples/)** - Real-world rule configurations
- **Rule editor**: run `codeguardian edit` to edit rule files in the browser

### Generate Rules with AI

Expand All @@ -306,6 +318,8 @@ For more sophisticated AI integration, check out our [Claude command definitions

## 🛠️ CLI Reference

### codeguardian check

```bash
codeguardian check [options]

Expand All @@ -322,6 +336,15 @@ Options:
--claude-code-hook Claude Code hook mode (exit 2 on errors, silent on success)
```

### codeguardian edit

```bash
codeguardian edit [options] [file]
```

- **`[file]`**: Path to a single `.cg.yaml` or `.codeguardian.yaml` file (optional). Default: `.codeguardian/development-rules.cg.yaml`.
- **Options**: `--port <port>` (default 3847), `--host <host>` (default 127.0.0.1), `--no-open` (do not open browser, only print URL).

### Repository Auto-Discovery

Code Guardian automatically finds your Git repository root when run from any subdirectory:
Expand All @@ -348,6 +371,7 @@ codeguardian check --repo /path/to/repo
- ✅ Basic assertions and combinators
- ✅ Git integration
- ✅ CLI interface
- ✅ Rule editor (web UI) for editing rule files

## 🤝 Contributing

Expand Down
97 changes: 50 additions & 47 deletions eslint.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -3,53 +3,56 @@ import eslint from '@eslint/js';
import tseslint from 'typescript-eslint';

export default tseslint.config(
{
// Ignore patterns
ignores: ['**/dist/**', '**/node_modules/**', 'jest.config.js', '*.md'],
},
eslint.configs.recommended,
...tseslint.configs.recommended,
{
files: ['**/*.ts'],
languageOptions: {
parser: tseslint.parser,
parserOptions: {
project: './tsconfig.json',
},
{
// Ignore patterns
ignores: ['**/dist/**', '**/node_modules/**', 'jest.config.js', '*.md', 'src/edit-ui/**'],
},
rules: {
// TypeScript specific rules
'@typescript-eslint/explicit-function-return-type': 'off',
'@typescript-eslint/no-explicit-any': 'warn',
'@typescript-eslint/no-unused-vars': ['error', {
argsIgnorePattern: '^_',
varsIgnorePattern: '^_'
}],
'@typescript-eslint/no-non-null-assertion': 'warn',

// General rules
'no-console': 'warn',
'no-debugger': 'error',
},
},
{
// Test files specific config
files: ['**/*.test.ts', '**/*.spec.ts'],
languageOptions: {
parserOptions: {
project: false,
},
},
rules: {
'@typescript-eslint/no-explicit-any': 'off',
'no-console': 'off',
eslint.configs.recommended,
...tseslint.configs.recommended,
{
files: ['**/*.ts'],
languageOptions: {
parser: tseslint.parser,
parserOptions: {
project: './tsconfig.json',
},
},
rules: {
// TypeScript specific rules
'@typescript-eslint/explicit-function-return-type': 'off',
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/no-unused-vars': [
'error',
{
argsIgnorePattern: '^_',
varsIgnorePattern: '^_',
},
],
'@typescript-eslint/no-non-null-assertion': 'off',

// General rules
'no-console': 'off',
'no-debugger': 'error',
},
},
},
{
// CLI files - allow console
files: ['**/cli/**/*.ts'],
rules: {
'no-console': 'off',
{
// Test files specific config
files: ['**/*.test.ts', '**/*.spec.ts'],
languageOptions: {
parserOptions: {
project: false,
},
},
rules: {
'@typescript-eslint/no-explicit-any': 'off',
'no-console': 'off',
},
},
},
);
{
// CLI files - allow console
files: ['**/cli/**/*.ts'],
rules: {
'no-console': 'off',
},
}
);
Loading