Commit Graph

7 Commits

Author SHA1 Message Date
3c436fda54 feat(tools): implement M10 Jupyter notebook support
Add tools-notebook crate with full Jupyter notebook (.ipynb) support:

- Core data structures: Notebook, Cell, NotebookMetadata, Output
- Read/write operations with metadata preservation
- Edit operations: EditCell, AddCell, DeleteCell
- Helper functions: new_code_cell, new_markdown_cell, cell_source_as_string
- Comprehensive test suite: 9 tests covering round-trip, editing, and error handling
- Permission integration: NotebookRead (plan mode), NotebookEdit (acceptedits mode)

Implements M10 from AGENTS.md for LLM-driven notebook editing.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-01 20:33:28 +01:00
173403379f feat(M9): implement WebFetch and WebSearch with domain filtering and pluggable providers
Milestone M9 implementation adds web access tools with security controls.

New crate: crates/tools/web

WebFetch Features:
- HTTP client using reqwest
- Domain allowlist/blocklist filtering
  * Empty allowlist = allow all domains (except blocked)
  * Non-empty allowlist = only allow specified domains
  * Blocklist always takes precedence
- Redirect detection and blocking
  * Redirects to unapproved domains are blocked
  * Manual redirect policy (no automatic following)
  * Returns error message with redirect URL
- Response capture with metadata
  * Status code, content, content-type
  * Original URL preserved

WebSearch Features:
- Pluggable provider trait using async-trait
- SearchProvider trait for implementing search APIs
- StubSearchProvider for testing
- SearchResult structure with title, URL, snippet
- Provider name identification

Security Features:
- Case-insensitive domain matching
- Host extraction from URLs
- Relative redirect URL resolution
- Domain validation before requests
- Explicit approval required for cross-domain redirects

Tests added (9 new tests):
Unit tests:
1. domain_filtering_allowlist - Verifies allowlist-only mode
2. domain_filtering_blocklist - Verifies blocklist takes precedence
3. domain_filtering_case_insensitive - Verifies case handling

Integration tests with wiremock:
4. webfetch_domain_whitelist_only - Tests allowlist enforcement
5. webfetch_redirect_to_unapproved_domain - Blocks bad redirects
6. webfetch_redirect_to_approved_domain - Detects good redirects
7. webfetch_blocklist_overrides_allowlist - Blocklist priority
8. websearch_pluggable_provider - Provider pattern works
9. webfetch_successful_request - Basic fetch operation

All 84 tests passing (up from 75).

Note: CLI integration deferred - infrastructure is complete and tested.
Future work will add CLI commands for web-fetch and web-search with
domain configuration.

Dependencies: reqwest 0.12, async-trait 0.1, wiremock 0.6 (test)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-01 20:23:29 +01:00
5134462deb feat(tools): implement Slash Commands with frontmatter and file refs (M5 complete)
This commit implements the complete M5 milestone (Slash Commands) including:

Slash Command Parser (tools-slash):
- YAML frontmatter parsing with serde_yaml
- Metadata extraction (description, author, tags, version)
- Arbitrary frontmatter fields via flattened HashMap
- Graceful fallback for commands without frontmatter

Argument Substitution:
- $ARGUMENTS - all arguments joined by space
- $1, $2, $3, etc. - positional arguments
- Unmatched placeholders remain unchanged
- Empty arguments result in empty string for $ARGUMENTS

File Reference Resolution:
- @path syntax to include file contents inline
- Regex-based matching for file references
- Multiple file references supported
- Clear error messages for missing files

CLI Integration:
- Added `slash` subcommand: `owlen slash <command> <args...>`
- Loads commands from `.claude/commands/<name>.md`
- Permission checks for SlashCommand tool
- Automatic file reference resolution before output

Command Structure:
---
description: "Command description"
author: "Author name"
tags:
  - tag1
  - tag2
---
Command body with $ARGUMENTS and @file.txt references

Permission Enforcement:
- Plan mode: SlashCommand allowed (utility tool)
- All modes: SlashCommand respects permissions
- File references respect filesystem permissions

Testing:
- 10 tests in tools-slash for parser functionality
  - Frontmatter parsing with complex YAML
  - Argument substitution (all variants)
  - File reference resolution (single and multiple)
  - Edge cases (no frontmatter, empty args, etc.)
- 3 new tests in CLI for integration
  - slash_command_works (with args and frontmatter)
  - slash_command_file_refs (file inclusion)
  - slash_command_not_found (error handling)
- All 56 workspace tests passing 

Dependencies Added:
- serde_yaml 0.9 for YAML frontmatter parsing
- regex 1.12 for file reference pattern matching

M5 milestone complete! 

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-01 19:41:42 +01:00
d7ddc365ec feat(tools): implement Bash tool with persistent sessions and timeouts (M4 complete)
This commit implements the complete M4 milestone (Bash tool) including:

Bash Session:
- Persistent bash session using tokio::process
- Environment variables persist between commands
- Current working directory persists between commands
- Session-based execution (not one-off commands)
- Automatic cleanup on session close

Key Features:
- Command timeout support (default: 2 minutes, configurable per-command)
- Output truncation (max 2000 lines for stdout/stderr)
- Exit code capture and propagation
- Stderr capture alongside stdout
- Command delimiter system to reliably detect command completion
- Automatic backup of exit codes to temp files

Implementation Details:
- Uses tokio::process for async command execution
- BashSession maintains single bash process across multiple commands
- stdio handles (stdin/stdout/stderr) are taken and restored for each command
- Non-blocking stderr reading with timeout to avoid deadlocks
- Mutex protection for concurrent access safety

CLI Integration:
- Added `bash` subcommand: `owlen bash <command> [--timeout <ms>]`
- Permission checks with command context for pattern matching
- Stdout/stderr properly routed to respective streams
- Exit code propagation (exits with same code as bash command)

Permission Enforcement:
- Plan mode (default): blocks Bash (asks for approval)
- Code mode: allows Bash
- Pattern matching support for command-specific rules (e.g., "npm test*")

Testing:
- 7 tests in tools-bash for session behavior
  - bash_persists_env_between_calls 
  - bash_persists_cwd_between_calls 
  - bash_command_timeout 
  - bash_output_truncation 
  - bash_command_failure_returns_error_code 
  - bash_stderr_captured 
  - bash_multiple_commands_in_sequence 
- 3 new tests in CLI for permission enforcement
  - plan_mode_blocks_bash_operations 
  - code_mode_allows_bash 
  - bash_command_timeout_works 
- All 43 workspace tests passing 

Dependencies Added:
- tokio with process, io-util, time, sync features

M4 milestone complete! 

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-01 19:31:36 +01:00
6108b9e3d1 feat(tools): implement Edit and Write tools with deterministic patches (M3 complete)
This commit implements the complete M3 milestone (Edit & Write tools) including:

Write tool:
- Creates new files with parent directory creation
- Overwrites existing files safely
- Simple and straightforward implementation

Edit tool:
- Exact string replacement with uniqueness enforcement
- Detects ambiguous matches (multiple occurrences) and fails safely
- Detects no-match scenarios and fails with clear error
- Automatic backup before modification
- Rollback on write failure (restores from backup)
- Supports multiline string replacements

CLI integration:
- Added `write` subcommand: `owlen write <path> <content>`
- Added `edit` subcommand: `owlen edit <path> <old_string> <new_string>`
- Permission checks for both Write and Edit tools
- Clear error messages for permission denials

Permission enforcement:
- Plan mode (default): blocks Write and Edit (asks for approval)
- AcceptEdits mode: allows Write and Edit
- Code mode: allows all operations

Testing:
- 6 new tests in tools-fs for Write/Edit functionality
- 5 new tests in CLI for permission enforcement with Edit/Write
- Tests verify plan mode blocks, acceptEdits allows, code mode allows all
- All 32 workspace tests passing

Dependencies:
- Added `similar` crate for future diff/patch enhancements

M3 milestone complete! 

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-01 19:19:49 +01:00
a6cf8585ef feat(permissions): implement permission system with plan mode enforcement (M1 complete)
This commit implements the complete M1 milestone (Config & Permissions) including:

- New permissions crate with Tool, Action, Mode, and PermissionManager
- Three permission modes: Plan (read-only default), AcceptEdits, Code
- Pattern matching for permission rules (exact match and prefix with *)
- Integration with config-agent for mode-based permission management
- CLI integration with --mode flag to override configured mode
- Permission checks for Read, Glob, and Grep operations
- Comprehensive test suite (10 tests in permissions, 4 in config, 4 in CLI)

Also fixes:
- Fixed failing test in tools-fs (glob pattern issue)
- Improved glob_list() root extraction to handle patterns like "/*.txt"

All 21 workspace tests passing.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-01 19:14:54 +01:00
7f39bf1eca feat(tools): add filesystem tools crate with glob pattern support
- Add new tools-fs crate with read, glob, and grep utilities
- Fix glob command to support actual glob patterns (**, *) instead of just directory walking
- Rename binary from "code" to "owlen" to match package name
- Fix test to reference correct binary name "owlen"
- Add API key support to OllamaClient for authentication

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-01 18:40:57 +01:00