Conversation
…Unicode This commit adds two new agentic security protections: 1. Claude Config Protection: Unconditionally blocks Write/Edit operations targeting .claude/ or CLAUDE.md files. These config writes could hijack agent behavior or achieve code execution. 2. Invisible Unicode Detection: Detects zero-width and invisible Unicode characters (ZWS, ZWNJ, ZWJ, BOM, RTL override, tag characters) in tool inputs. Blocks by default but respects DASHLIGHTS_AGENTIC_MODE=ask for user confirmation. Also expands Rule of Two heuristics with: - Alternative downloaders: aria2c, lynx -source, w3m -dump - Hex decode obfuscation: xxd -r Files changed: - src/ruleoftwo/threats.go (new) - Critical threat detection logic - src/ruleoftwo/threats_test.go (new) - Comprehensive tests - src/main.go - Integrate threat check before Rule of Two - src/ruleoftwo/heuristics.go - Add new patterns - src/ruleoftwo/heuristics_test.go - Tests for new patterns
Package renamed: ruleoftwo → agentic Changes: - Renamed directory src/ruleoftwo/ → src/agentic/ - Updated all package declarations from package ruleoftwo to package agentic - Updated import in main.go - Updated all ruleoftwo. references to agentic. - Updated package description in toolcall.go
In --agentic mode, for Bash: it now extracts likely write targets from redirects and tee and blocks if any match .claude/ or CLAUDE.md. This keeps the “always block” guarantee for obvious shell writes without adding a heavy parser. Changes are in src/agentic/threats.go. Details: - detectClaudeConfigWrite now checks Bash tool input and evaluates multiple target paths. - Added lightweight tokenization, redirection parsing, and tee target extraction. - Added token cleanup to handle quotes and common separators.
Add bounded file-read helpers and apply size caps to workflows, configs, and build files to prevent OOM/DoS. Limit agentic stdin size, harden env parsing, and align file access with gosec expectations.
New files:
- src/agentic/agent.go - Agent type detection (environment vars + input format heuristics)
- src/agentic/agent_test.go - Tests for agent detection
- src/agentic/cursor.go - Cursor input parsing and output formatting
- src/agentic/cursor_test.go - Tests for Cursor handling
Modified files:
- src/agentic/threats.go - Agent-agnostic config protection (Claude + Cursor paths, safe subdirs)
- src/main.go - Refactored runAgenticMode() to auto-detect agent and route accordingly
- src/main_test.go - Fixed tests for updated behavior
- docs/agentic_mode.md - Added Cursor documentation section
Key features:
1. Auto-detects agent type via CURSOR_AGENT=1 or CLAUDECODE=1 environment variables
2. Falls back to input format detection (Cursor has command field, Claude has tool_name)
3. Normalizes Cursor's {command, cwd} input to canonical HookInput with ToolName="Bash"
4. Generates Cursor-specific output: {permission: "allow"|"deny"|"ask", user_message, agent_message}
5. Protects both Claude (.claude/, CLAUDE.md) and Cursor (.cursor/) config files
6. Allows writes to safe subdirs like .claude/plans/ and .claude/todos/
|
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #48 +/- ##
==========================================
- Coverage 87.14% 86.83% -0.32%
==========================================
Files 46 54 +8
Lines 2474 3441 +967
==========================================
+ Hits 2156 2988 +832
- Misses 218 323 +105
- Partials 100 130 +30
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Pull request overview
This PR adds an "Agentic Mode" feature that enables dashlights to act as a security hook for AI coding assistants like Claude Code and Cursor. The implementation follows Meta's Rule of Two security framework to detect potentially dangerous combinations of capabilities in tool calls.
Key changes:
- Adds
--agenticflag that reads tool call JSON from stdin and performs security analysis - Implements critical threat detection (agent config writes, invisible Unicode) and Rule of Two analysis (combining untrustworthy input + sensitive access + state changes)
- Supports both Claude Code (PreToolUse hook) and Cursor (beforeShellExecution hook) with automatic agent detection
Reviewed changes
Copilot reviewed 27 out of 28 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| src/main.go | Adds agentic mode entry point with runAgenticMode() function and output helpers |
| src/main_test.go | Comprehensive tests for agentic mode including disabled mode, empty input, invalid JSON, and threat scenarios |
| src/signals/*.go | Adds context cancellation checks in loops to support timeouts in agentic mode |
| src/signals/internal/fileutil/fileutil.go | New bounded file reading helpers to prevent OOM attacks when reading potentially malicious files |
| src/agentic/analyzer.go | Core Rule of Two analyzer that runs capability detection and integrates with signals |
| src/agentic/heuristics.go | Capability detection heuristics for A (untrustworthy input), B (sensitive access), C (state changes) |
| src/agentic/threats.go | Critical threat detection for agent config writes and invisible Unicode with bash command parsing |
| src/agentic/output.go | Output formatting for Claude Code hook responses with mode handling |
| src/agentic/toolcall.go | Tool input parsing helpers for various tool types (Write, Edit, Bash, Read, etc.) |
| src/agentic/cursor.go | Cursor-specific input parsing and output formatting |
| src/agentic/agent.go | Agent type detection from environment variables and JSON structure |
| src/agentic/*_test.go | Extensive test coverage for all agentic components |
| docs/agentic_mode.md | Comprehensive documentation with configuration examples and security guidance |
| README.md | Updated with agentic mode overview and link to detailed docs |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
This fixes local test failures that were caused by Go 1.22.4 being incompatible with macOS 26 (Tahoe). The Go linker wasn't generating the LC_UUID load command in Mach-O binaries, which newer macOS versions require. Upgrading to Go 1.25.5 fixed the issue. Upgrade everywhere for consistency.
1. src/main.go:77-80 - Propagates --debug flag to DASHLIGHTS_DEBUG env var before agentic mode runs 2. src/agentic/output.go:46-49 - Added IsDebug() helper that checks DASHLIGHTS_DEBUG env var 3. src/agentic/cursor.go:168-170 - Logs marshal errors to stderr when debug mode is enabled 4. src/agentic/output_test.go:61-83 - Added test for IsDebug() Now both work: - dashlights --agentic --debug (CLI flag) - DASHLIGHTS_DEBUG=1 dashlights --agentic (env var)
Currently, we support Claude Code and Cursor, which explicitly support hooks.
Ideally, some of this security behavior will be directly written into the agents themselves. Until then, hooks at least give users a mechanism to apply deterministic checks prior to command execution, something not all agentic coding platforms seem to realize is necessary (many just try to add agentic prompt instructions, which is a failing strategy).
Implements #32