[PR #10090] feat(smart-rules): add context-aware rule injection system with Claude Code compatibility #13333

Open
opened 2026-02-16 18:18:11 -05:00 by yindo · 0 comments
Owner

Original Pull Request: https://github.com/anomalyco/opencode/pull/10090

State: open
Merged: No


Summary

This PR implements a Smart Rule system that intelligently injects context-specific instructions into the system prompt based on the files being worked with during a session.
Closes #10096

Key Features

  • Context-aware rule loading: Rules are matched against file glob patterns and only included when relevant files are read
  • Cross-compatible directories: Native support for both .opencode/rules/ and .claude/rules/ (Claude Code compatibility)
  • Hierarchical precedence: OpenCode project rules > Claude project rules > Global rules
  • Always-apply rules: Support for rules that should always be included regardless of file patterns
  • Performance optimized:
    • Lazy evaluation - skip all work if feature disabled
    • Discovery caching via Instance.state() - rules loaded once per project
    • Pre-compiled minimatch patterns at rule load time
    • Piggyback tracking on existing FileTime.read() - no new hooks needed

How It Works

┌─────────────────────────────────────────────────────────────────────┐
│                     System Prompt Flow                              │
├─────────────────────────────────────────────────────────────────────┤
│  Tool calls (read/edit/write)                                       │
│        │                                                            │
│        ▼                                                            │
│  FileTime.read() ────▶ SmartRule.track()                           │
│                              │                                      │
│                              ▼                                      │
│                    SmartRule.state.files[sessionID]                │
│                              │                                      │
│                              │  On prompt generation                │
│                              ▼                                      │
│  SystemPrompt.smartRules(sessionID)                                │
│        │                                                            │
│        ├──▶ Check flag (early exit if disabled)                    │
│        ├──▶ Check files tracked (early exit if none)               │
│        ├──▶ SmartRule.discover() ◀── Cached via Instance.state()  │
│        └──▶ SmartRule.match() ──▶ Return matched rules             │
└─────────────────────────────────────────────────────────────────────┘

Configuration

Enable with environment variables:

export OPENCODE_EXPERIMENTAL_SMART_RULES=true
# or
export OPENCODE_EXPERIMENTAL=true  # enables all experimental features

Rule File Format

Rules are markdown files with YAML frontmatter:

---
description: "TypeScript formatting guidelines"
paths:
  - "**/*.ts"
  - "**/*.tsx"
---

# TypeScript Guidelines

- Use strict mode
- Prefer interfaces over types
- Use meaningful variable names

Supported frontmatter fields:

Field Type Description
description string Human-readable description of the rule
paths string[] Glob patterns to match files (primary)
globs string[] Alias for paths
patterns string[] Alias for paths
alwaysApply boolean If true, rule is always included

Rule Discovery Locations

Rules are discovered from (in order of increasing precedence):

  1. ~/.config/opencode/rules/ (global)
  2. ~/.claude/rules/ (global, Claude Code compatibility)
  3. .claude/rules/ in project hierarchy
  4. .opencode/rules/ in project hierarchy (highest precedence)

Files Changed

File Change
src/smart-rule/index.ts New - SmartRule namespace with discovery, tracking, and injection
src/flag/flag.ts Add OPENCODE_EXPERIMENTAL_SMART_RULES flag
src/file/time.ts Add SmartRule.track() call in read() function
src/session/system.ts Add smartRules(sessionID) function
src/session/prompt.ts Include smart rules in system prompt array

Test Plan

  • Enable feature with OPENCODE_EXPERIMENTAL_SMART_RULES=true
  • Create test rule in .opencode/rules/typescript.md with paths: ["**/*.ts"]
  • Start opencode and read a .ts file
  • Verify rule content appears in system prompt (check logs)
  • Test .claude/rules/ compatibility
  • Test alwaysApply: true rules
  • Verify no impact when feature is disabled
  • Verify rules are cached (check logs for single "discovered rules" message)

Related

  • Provides compatibility layer for Claude Code's .claude/rules/ directory structure
  • Follows existing patterns from FileTime, Instance.state(), and ConfigMarkdown
**Original Pull Request:** https://github.com/anomalyco/opencode/pull/10090 **State:** open **Merged:** No --- ## Summary This PR implements a **Smart Rule** system that intelligently injects context-specific instructions into the system prompt based on the files being worked with during a session. Closes #10096 ### Key Features - **Context-aware rule loading**: Rules are matched against file glob patterns and only included when relevant files are read - **Cross-compatible directories**: Native support for both `.opencode/rules/` and `.claude/rules/` (Claude Code compatibility) - **Hierarchical precedence**: OpenCode project rules > Claude project rules > Global rules - **Always-apply rules**: Support for rules that should always be included regardless of file patterns - **Performance optimized**: - Lazy evaluation - skip all work if feature disabled - Discovery caching via `Instance.state()` - rules loaded once per project - Pre-compiled `minimatch` patterns at rule load time - Piggyback tracking on existing `FileTime.read()` - no new hooks needed ### How It Works ``` ┌─────────────────────────────────────────────────────────────────────┐ │ System Prompt Flow │ ├─────────────────────────────────────────────────────────────────────┤ │ Tool calls (read/edit/write) │ │ │ │ │ ▼ │ │ FileTime.read() ────▶ SmartRule.track() │ │ │ │ │ ▼ │ │ SmartRule.state.files[sessionID] │ │ │ │ │ │ On prompt generation │ │ ▼ │ │ SystemPrompt.smartRules(sessionID) │ │ │ │ │ ├──▶ Check flag (early exit if disabled) │ │ ├──▶ Check files tracked (early exit if none) │ │ ├──▶ SmartRule.discover() ◀── Cached via Instance.state() │ │ └──▶ SmartRule.match() ──▶ Return matched rules │ └─────────────────────────────────────────────────────────────────────┘ ``` ### Configuration Enable with environment variables: ```bash export OPENCODE_EXPERIMENTAL_SMART_RULES=true # or export OPENCODE_EXPERIMENTAL=true # enables all experimental features ``` ### Rule File Format Rules are markdown files with YAML frontmatter: ```markdown --- description: "TypeScript formatting guidelines" paths: - "**/*.ts" - "**/*.tsx" --- # TypeScript Guidelines - Use strict mode - Prefer interfaces over types - Use meaningful variable names ``` **Supported frontmatter fields:** | Field | Type | Description | |-------|------|-------------| | `description` | string | Human-readable description of the rule | | `paths` | string[] | Glob patterns to match files (primary) | | `globs` | string[] | Alias for `paths` | | `patterns` | string[] | Alias for `paths` | | `alwaysApply` | boolean | If true, rule is always included | ### Rule Discovery Locations Rules are discovered from (in order of increasing precedence): 1. `~/.config/opencode/rules/` (global) 2. `~/.claude/rules/` (global, Claude Code compatibility) 3. `.claude/rules/` in project hierarchy 4. `.opencode/rules/` in project hierarchy (highest precedence) ### Files Changed | File | Change | |------|--------| | `src/smart-rule/index.ts` | **New** - SmartRule namespace with discovery, tracking, and injection | | `src/flag/flag.ts` | Add `OPENCODE_EXPERIMENTAL_SMART_RULES` flag | | `src/file/time.ts` | Add `SmartRule.track()` call in `read()` function | | `src/session/system.ts` | Add `smartRules(sessionID)` function | | `src/session/prompt.ts` | Include smart rules in system prompt array | ## Test Plan - [x] Enable feature with `OPENCODE_EXPERIMENTAL_SMART_RULES=true` - [x] Create test rule in `.opencode/rules/typescript.md` with `paths: ["**/*.ts"]` - [x] Start opencode and read a `.ts` file - [x] Verify rule content appears in system prompt (check logs) - [x] Test `.claude/rules/` compatibility - [x] Test `alwaysApply: true` rules - [x] Verify no impact when feature is disabled - [x] Verify rules are cached (check logs for single "discovered rules" message) ## Related - Provides compatibility layer for Claude Code's `.claude/rules/` directory structure - Follows existing patterns from `FileTime`, `Instance.state()`, and `ConfigMarkdown`
yindo added the pull-request label 2026-02-16 18:18:11 -05:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: anomalyco/opencode#13333