v1.9.0
Fixed
-
MCP server entry constant no longer contains bare command name (Issue #800)
- Removed bare
"command": "ai-guardian"from_MCP_SERVER_ENTRYconstant - Command is always resolved to absolute path via
_resolve_binary_path()at setup time - Prevents MCP server startup failures when venv is not activated
- Removed bare
-
daemon statusanddaemon stopno longer cause daemon auto-restart (Issue #775)daemon stopwrites a stop-requested marker that suppresses auto-startstart_daemon_background()respects the marker as a final guarddaemon startclears the marker so auto-start resumes after explicit start- Prevents background CLI invocations from restarting a stopped daemon
Changed
-
README install section warns against installing from main branch (Issue #755)
- PyPI is the stable channel; main branch contains unreleased dev code
- CI wheel artifacts renamed from
ai-guardian-wheeltoai-guardian-dev-wheel
-
Tray menu layout reorganization (Issue #706)
- Shell in its own separated section above daemon operations
- Custom plugin menus in their own separated section
- Pause/Resume and Start/Stop/Restart daemon grouped together (both are daemon operations)
Added
-
Tag-based tray plugin filtering per daemon (Issue #790)
- Plugins can declare
tags(array of strings) to target specific daemons - Daemons declare
menu_tags(array of strings) inai-guardian.json - Untagged plugins always show; tagged plugins only show on daemons with at least one matching tag
- N-to-N relationship: plugins and daemons can each have multiple tags
menu_tagsexposed via/api/statusand/api/statsfor remote daemon support- Plugin schema (
tray-plugin.schema.json) and config schema updated - New
filter_plugins_by_tags()function intray_plugins.py
- Plugins can declare
-
JSON schema for tray plugin files (Issue #783)
- New
src/ai_guardian/schemas/tray-plugin.schema.jsonvalidates plugin structure - Covers all fields: name, items, label, command (string or platform map), type, run_on_target, params
- Enables IDE autocompletion and inline validation when
$schemais referenced in plugin files - Schema tests in
tests/unit/test_tray_plugin_schema.py
- New
-
Plugin commands: built-in target variables and run_on_target flag (Issue #780)
- Target variables (
{container_id},{container_engine},{host},{port},{name},{pod_name},{namespace}) automatically substituted from DaemonTarget run_on_targetflag wraps commands for the target runtime (container exec, kubectl/oc exec, or local)- Container runtime uses
target.container_engine(podman or docker) for exec wrapping - Kubernetes runtime auto-detects
oc(OpenShift) or falls back tokubectl - Both features coexist: target vars substituted first, then run_on_target wrapping applied
- Target variables (
-
About menu item in system tray (Issue #766)
- Shows version, Python, platform, config path, scanner versions, and project URL
- Displayed via pystray notification for cross-platform support
- Multi-daemon mode: global About lists connected daemons with versions
- Per-daemon About in each daemon's submenu shows daemon-specific info
- New
/api/aboutREST endpoint and shareddaemon/about.pymodule
-
Version mismatch detection between tray and daemons (Issue #766)
- Tray warns when a connected daemon runs an older version
- OS notification sent once per daemon with upgrade recommendation
- Daemon status label shows version indicator (⟳) on mismatch
- Version field added to
DaemonState.get_stats()and/api/stats - Backward compatibility contract documented in AGENTS.md
-
Release-readiness CI workflow (Issue #761)
- New
release-readiness.ymlworkflow with 7 validation jobs - Fresh install test across Python 3.9–3.14
- Upgrade path test from previous stable release (v1.8.1)
- Multi-agent IDE setup validation (claude, cursor, copilot, gemini, codex, windsurf, cline, augment, kiro)
- Daemon lifecycle test (start/status/reload/pause/resume/stop + REST API)
- End-to-end detection test (secrets, PII, prompt injection, false positives)
- Config validation (profiles, migration, doctor, show-config)
- MCP server initialization and tool call response test
- Release skill updated to trigger workflow before releasing
- New
-
Build wheel artifact workflow (Issue #515)
- New GitHub Actions workflow builds and uploads a wheel on PRs, merges to main, and on-demand
- PEP 440 local version identifiers for traceability (
+pr123,+main.abc1234,+username) - Merges and on-demand builds create
rc-*pre-releases with wheel as downloadable release asset - PR builds upload wheel as Actions artifact only (7-day retention)
- Fork PRs blocked to prevent abuse; uses
rc-*tags to avoid triggering PyPI publish
-
Daemon troubleshooting guide (Issue #737)
- New
docs/TROUBLESHOOTING.mdcovering daemon startup, tray display, container, and general issues - Covers stale lock files, port conflicts, config reload, auto-start failures, and container race conditions
- New
-
Built-in Shell menu item in tray (Issue #706)
- Opens an interactive terminal shell matching the daemon's runtime type
- Local daemon: opens user's default shell (
$SHELLor/bin/sh) - Container daemon: runs
podman/docker exec -it {container_id} /bin/sh - Kubernetes daemon: runs
kubectl exec -it {pod} -n {namespace} -- /bin/sh - Present in both single-daemon (flat) and multi-daemon (per-daemon submenu) layouts
- No configuration required — auto-detects runtime from discovery
-
Tray menu plugin system (Issue #590)
- Custom menu items via JSON files in
~/.config/ai-guardian/tray-plugins/ - Four command types:
terminal,background,notification,clipboard - Interactive parameters with Textual form (text inputs and dropdowns)
- Platform-aware commands via platform map (
darwin/linux/windows/default) - REST API endpoint
GET /api/tray-pluginsfor multi-daemon plugin discovery - Local plugins load even when daemon is stopped
_resolve_cli_cmdnow usessys.executableto guarantee same virtualenv as tray- AppleScript command escaping fix for double quotes in terminal launches
- Custom menu items via JSON files in
-
Auto-install tray on first run (Issue #728)
- First
ai-guardianCLI invocation auto-installs desktop shortcut, configures login autostart, and starts tray in background - Silent and non-blocking — log messages only, no interactive prompts
- Skipped on headless servers (no DISPLAY), CI/CD environments, and when pystray is not available
- Opt-out via config:
{"daemon": {"tray": {"auto_install": false}}} - Works on macOS (LaunchAgent + .app bundle), Linux (.desktop files), and Windows (Start Menu shortcuts)
- First
-
Multi-agent hook adapter architecture (Issue #633)
- New
hook_adapterspackage with abstractHookAdapterbase class andNormalizedHookInputdataclass - Concrete adapters for all 12 supported agents: Claude Code, Cursor, GitHub Copilot, Codex, Windsurf, Gemini CLI, Cline/ZooCode, Kiro, Augment Code, AiderDesk, OpenClaw, Junie
- Adapter registry with auto-detection from hook input structure and
AI_GUARDIAN_IDE_TYPEenv var override response_format.pyrefactored to delegate to adapters (backward-compatible wrappers preserved)process_hook_data()uses single-pass adapter detection and normalization- New
docs/AGENT_SUPPORT.mdwith full agent capability matrix, hook event mapping, and response format documentation - 104 new tests covering detection, normalization, response formatting, and backward compatibility
- New
-
OpenClaw plugin-based integration (Issue #640)
- New integration using OpenClaw's TypeScript plugin system (
definePluginEntry) ai-guardian setup --ide openclawinstalls plugin to~/.openclaw/plugins/ai-guardian/- Plugin hooks: before_tool_call (blocking), after_tool_call, message_received, session lifecycle
- Plugin delegates to
ai-guardianCLI via child_process, reusing Kiro exit-code response format AI_GUARDIAN_IDE_TYPE=openclawenv var override supported- MCP server configuration support for OpenClaw
- SOUL.md security guidelines injection via
--rulesflag - Phase 1 only (plugin-level); Phase 2 (
tool:preinternal hook) pending upstream #12311
- New integration using OpenClaw's TypeScript plugin system (
-
AiderDesk Extension support (Issue #639)
- New integration type: "extension-based" for IDEs using TypeScript/JS extension systems
ai-guardian setup --ide aiderdeskinstalls TypeScript extension to~/.aider-desk/extensions/ai-guardian/- Extension hooks: onToolApproval, onToolCalled, onToolFinished, onPromptStarted, onFilesAdded, onBeforeCommit
- Extension delegates to
ai-guardianCLI via child_process, reusing Kiro exit-code response format AI_GUARDIAN_IDE_TYPE=aiderdeskenv var override supported- MCP server configuration support for AiderDesk
- Note: AiderDesk uses JS/TS extensions (not shell hooks) — requires Node.js and
npm install
-
Junie (JetBrains) MCP-only integration (Issue #637)
ai-guardian setup --ide junie --mcpregisters MCP server at~/.junie/mcp.jsonai-guardian setup --ide junie --rulesinstalls security guidelines file at.junie/guidelines.md- New
--rulesCLI flag for installing AI guidelines/rules files instructing agents to use MCP tools - MCP-only: Junie does not support hooks, integration is advisory via MCP tools and guidelines
.junie/guidelines.mdadded to config scanner patterns for prompt injection detection
-
Updated CONTRIBUTING.md with contribution paths (Issue #727)
- Explain how to contribute via GitHub Discussions (bug reports, feature requests, questions)
- Explain fork + PR workflow (not affected by interaction limits)
- Explain how to become a collaborator
- README.md updated to link to Discussions for bug reports and feature requests
-
Kiro (AWS) hook support (Issue #636)
- New
IDEType.KIROwith exit code-based blocking (exit 0 = allow, exit 1 = block) - Kiro sends stdout to agent context on success, stderr on error
- Auto-detect Kiro via
kiro_hook_typeorkiro_versionfields in hook input AI_GUARDIAN_IDE_TYPE=kiroenv var override supported- Hook event mapping:
prompt_submit,pre_tool_use,post_tool_use,agent_stop ai-guardian setup --ide kirogenerates hook scripts in.kiro/hooks/- MCP server configuration for Kiro
- New
-
Augment Code hook support (Issue #638)
- Auto-detect Augment via
is_mcp_toolfield in hook input - Uses Claude Code response format (JSON + exit code 2 for blocking)
- Tool name mapping:
launch-process→ Bash,str-replace-editor→ Edit,save-file→ Write,view→ Read - MCP tool support via
mcp:*prefix mapping tomcp__*convention ai-guardian setup --ide augmentgenerates~/.augment/settings.jsonhook configAI_GUARDIAN_IDE_TYPE=augmentenv var override supported- Enterprise deployment: system-level
/etc/augment/settings.jsonimmutable hooks
- Auto-detect Augment via
-
Cline / ZooCode hook support (Issue #635)
- Auto-detect Cline via
clineVersionfield in hook input - Response format:
{"cancel": true, "reason": "..."}for blocking - Event mapping: PreToolUse, PostToolUse, UserPromptSubmit via
hookNamefield ai-guardian setup --ide clineinstalls executable hook scripts in.clinerules/hooks/ai-guardian setup --ide zoocodesupported as alias (same hook format)- MCP server configuration for Cline/ZooCode
- Auto-detect Cline via
Fixed
-
MCP tray check works for remote daemons (Issue #756)
- Daemon now self-reports
mcp_installedstatus in/api/statsand/api/statusresponses - Tray queries each daemon for its MCP installation status instead of checking only local filesystem
- MCP Proactive menu correctly shown/hidden per daemon in multi-daemon mode
- MCP check also looks in
~/.claude/settings.jsonfor users who configured MCP there ai-guardian setup --mcpnow warns if MCP entry found in~/.claude/settings.json(hooks file)
- Daemon now self-reports
-
MCP Proactive menu hidden in multi-daemon tray (Issue #706)
- Closure-in-loop bug: visibility lambda closed over
_is_slot_runningname instead of capturing the slot index - All daemon submenus referenced the last loop iteration's slot (slot 7), causing
7 < len(targets)to be False - Fixed by capturing slot via default argument:
lambda _i, s=idx: _is_slot_running(_i, s)
- Closure-in-loop bug: visibility lambda closed over
-
Config merge silently drops permissions when user-level and project-level use different formats (Issue #724)
- Old list-format permissions (
"permissions": [...]) now auto-normalized to dict format before merge - User-level (list) + project-level (dict) merge preserves both rule sets
- Deprecation warning logged when old format detected
- Fixes block-reinject loop that caused security rules to appear on every prompt
- Old list-format permissions (
-
Daemon start -b silently fails in containers (stale PID file) (Issue #715)
_cleanup_stale()now verifies socket connectivity when PID is alive, handling PID recycling in containersdaemon statuscleans up stale PID files when daemon is not runningstart_daemon_background()cleans up stale PID/socket files before spawning- New
cleanup_stale_pid()utility for consistent stale file cleanup
-
Tray icon remains functional after system wake from sleep/hibernate (Issue #703)
- Cross-platform wake detection via wall-clock timer gap in stats refresh loop
- macOS immediate wake handler via
NSWorkspaceDidWakeNotification - Rebuilds icon and menu automatically on wake; graceful degradation if OS APIs unavailable
-
IBAN space-separated format detection (Issue #677)
- IBAN regex now matches both compact (
GB29NWBK60161331926819) and space-separated (GB29 NWBK 6016 1331 9268 19) formats - IBAN validator already stripped spaces; the fix is in the regex pattern in
pii.toml
- IBAN regex now matches both compact (
Added
-
Gemini CLI Hook Support (Issue #634)
ai-guardian setup --ide geminiinstalls hooks to~/.gemini/settings.json- BeforeAgent, BeforeTool, and AfterTool hooks configured with
.*matcher - Auto-detection via
transcript_pathfield (unique to Gemini CLI) - Hook event mapping:
BeforeTool→ PRE_TOOL_USE,AfterTool→ POST_TOOL_USE,BeforeAgent→ PROMPT - New
IDEType.GEMINI_CLIwith structured JSON response format (decision: "deny",reason,systemMessage) AI_GUARDIAN_IDE_TYPE=geminienv var override supported- MCP server registration at
~/.gemini/settings.json
-
Windsurf Hook Support (Issue #674)
ai-guardian setup --ide windsurfinstalls hooks to~/.codeium/windsurf/hooks.json- All pre-hooks configured:
pre_user_prompt,pre_run_command,pre_read_code,pre_write_code,pre_mcp_tool_use - All post-hooks configured:
post_run_command,post_read_code,post_write_code,post_mcp_tool_use - Auto-detection via
agent_action_namefield (unique to Windsurf) - Hook event mapping: snake_case Windsurf events → ai-guardian HookEvent enum
- MCP server registration at
~/.windsurf/mcp.json - Windsurf automatically appears in tray "Local Setup..." submenu
-
Codex Hook Support (Issue #673)
ai-guardian setup --ide codexinstalls hooks to~/.codex/hooks.json- PreToolUse, PostToolUse, UserPromptSubmit hooks configured with 30s timeout
- Codex added to tray "Local Setup..." menu automatically via IDE_CONFIGS
- MCP server registration for Codex projects (project-level
codex.json) - Codex uses Claude Code response format (identical input/output schema)
AI_GUARDIAN_IDE_TYPE=codexenv var override supportedai-guardian doctorcounts Codex hooks
-
PII pattern server support (Issue #644)
- New
PIIPatternLoaderclass for loading PII patterns from a remote pattern server scan_pii.pattern_serverconfig option with URL, endpoint, auth, and cache settings- Three-tier merge: server patterns extend or replace bundled defaults by matching
id - Local
additional_pii_patternsalways additive on top of server/default patterns - Same architecture as secret scanning, SSRF, and Unicode pattern servers
- Fallback chain: pattern server → cache → bundled
pii.toml
- New
-
Parser Compatibility CI — weekly GitHub Actions workflow verifying pattern server parser compatibility (Issue #685)
parser-compat-checkjob: fetches patterns, parses viaPARSER_REGISTRY, compiles viaPatternCacheformat-version-checkjob: detects schema drift, creates/updates GitHub issues withparser-compatlabel- New script:
scripts/check_parser_compat.pywith--compat-checkand--format-version-checkmodes - Fixture:
tests/fixtures/ai_guardian_native_patterns.tomlfor ai-guardian native format testing
-
Internal Python scanner with TOML patterns (Issue #678)
- New
toml-patternsscanner engine — runs in-process (~1-5ms), no binary required - 267 bundled pattern rules across 6 TOML files: secrets (44), PII (13),
prompt injection (73), unicode attacks (107), config exfiltration (8), SSRF (22) PatternCacheclass with pre-compiled matchers for regex, literal, CIDR, range, and glob- Multi-format pattern server support via
pattern_serversconfig array - Parser registry with
ai-guardianandgitleaksformat parsers (extensible) - Luhn and IBAN validators extracted to
patterns/validators.py - RE2 regex compatibility validation at load time
- All existing config keys preserved (allowlists, ignore files, annotations, action levels)
- Pattern lister (
ai-guardian patterns list) now reads counts from TOML files - Configure via:
"engines": ["toml-patterns"](works without gitleaks/betterleaks installed)
- New