Skip to content

Agentic Mode: support --agentic flag for use in Agents that support tool hooks#48

Merged
erichs merged 20 commits intomainfrom
agentic
Dec 20, 2025
Merged

Agentic Mode: support --agentic flag for use in Agents that support tool hooks#48
erichs merged 20 commits intomainfrom
agentic

Conversation

@erichs
Copy link
Owner

@erichs erichs commented Dec 19, 2025

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

…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/
Copilot AI review requested due to automatic review settings December 19, 2025 18:20
@codecov-commenter
Copy link

codecov-commenter commented Dec 19, 2025

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

❌ Patch coverage is 85.07317% with 153 lines in your changes missing coverage. Please review.
✅ Project coverage is 86.83%. Comparing base (faf2a00) to head (50b177d).

Files with missing lines Patch % Lines
src/agentic/threats.go 85.44% 35 Missing and 19 partials ⚠️
src/main.go 47.57% 49 Missing and 5 partials ⚠️
src/agentic/analyzer.go 85.48% 6 Missing and 3 partials ⚠️
src/agentic/cursor.go 89.28% 8 Missing and 1 partial ⚠️
src/agentic/heuristics.go 95.20% 7 Missing and 1 partial ⚠️
src/signals/internal/fileutil/fileutil.go 82.60% 2 Missing and 2 partials ⚠️
src/signals/unsafe_workflow.go 78.57% 1 Missing and 2 partials ⚠️
src/agentic/agent.go 92.00% 1 Missing and 1 partial ⚠️
src/signals/cargo_path_deps.go 71.42% 2 Missing ⚠️
src/signals/go_replace.go 71.42% 2 Missing ⚠️
... and 3 more
❗ Your organization needs to install the Codecov GitHub app to enable full functionality.
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     
Flag Coverage Δ
unittests 86.83% <85.07%> (-0.32%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 --agentic flag 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)
@erichs erichs merged commit b6d8aa1 into main Dec 20, 2025
5 checks passed
@erichs erichs deleted the agentic branch December 20, 2025 03:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

Comments