diff --git a/.github/workflows/dev.lock.yml b/.github/workflows/dev.lock.yml index 93b1d8c261..2db75f9b0d 100644 --- a/.github/workflows/dev.lock.yml +++ b/.github/workflows/dev.lock.yml @@ -2,7 +2,7 @@ # To update this file, edit the corresponding .md file and run: # gh aw compile -name: "Dev" +name: "dev" on: push: branches: @@ -15,7 +15,7 @@ permissions: {} concurrency: group: "gh-aw-${{ github.workflow }}-${{ github.ref }}" -run-name: "Dev" +run-name: "dev" jobs: task: @@ -120,6 +120,26 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v5 + # Cache memory file share configuration from frontmatter processed below + - name: Create cache-memory directory + run: | + mkdir -p /tmp/cache-memory + echo "Cache memory directory created at /tmp/cache-memory" + echo "This folder provides persistent file storage across workflow runs" + echo "LLMs and agentic tools can freely read and write files in this directory" + - name: Cache memory file share data + uses: actions/cache@v4 + with: + key: memory-${{ github.workflow }}-${{ github.run_id }} + path: /tmp/cache-memory + restore-keys: | + memory-${{ github.workflow }}- + memory- + - name: Upload cache-memory data as artifact + uses: actions/upload-artifact@v4 + with: + name: cache-memory + path: /tmp/cache-memory - name: Generate Claude Settings run: | mkdir -p /tmp/.claude @@ -724,8 +744,49 @@ jobs: run: | mkdir -p /tmp/aw-prompts cat > $GITHUB_AW_PROMPT << 'EOF' + # Development Assistant + + You are a development assistant that helps with coding tasks and maintains an execution plan. + + ## Task + Try to call a tool, `draw_pelican` that draws a pelican. + ## Execution Plan Management + + - **Check for existing plan**: Look for `/tmp/cache-memory/plan.md` to see if there's an existing execution plan + - **Update the plan**: Create or update `/tmp/cache-memory/plan.md` with your execution strategy + - **Remember progress**: Store any important findings, decisions, or progress in the cache folder + - **Recall previous work**: If a plan exists, reference it and continue from where you left off + + The plan should include: + 1. Current objectives + 2. Steps completed + 3. Next steps + 4. Any important discoveries or decisions + 5. Tools or approaches that worked well + + Please maintain this execution plan throughout your work to ensure continuity across workflow runs. + + + --- + + ## Cache Folder Available + + You have access to a persistent cache folder at `/tmp/cache-memory/` where you can read and write files to create memories and store information. + + - **Read/Write Access**: You can freely read from and write to any files in this folder + - **Persistence**: Files in this folder persist across workflow runs via GitHub Actions cache + - **Last Write Wins**: If multiple processes write to the same file, the last write will be preserved + - **File Share**: Use this as a simple file share - organize files as you see fit + + Examples of what you can store: + - `/tmp/cache-memory/notes.txt` - general notes and observations + - `/tmp/cache-memory/preferences.json` - user preferences and settings + - `/tmp/cache-memory/history.log` - activity history and logs + - `/tmp/cache-memory/state/` - organized state files in subdirectories + + Feel free to create, read, update, and organize files in this folder as needed for your tasks. --- @@ -753,7 +814,7 @@ jobs: engine_name: "Claude Code", model: "", version: "", - workflow_name: "Dev", + workflow_name: "dev", experimental: false, supports_tools_whitelist: true, supports_http_transport: true, @@ -784,15 +845,19 @@ jobs: - name: Execute Claude Code CLI id: agentic_execution # Allowed tools (sorted): + # - Edit(/tmp/cache-memory/*) # - ExitPlanMode # - Glob # - Grep # - LS + # - MultiEdit(/tmp/cache-memory/*) # - NotebookRead # - Read + # - Read(/tmp/cache-memory/*) # - Task # - TodoWrite # - Write + # - Write(/tmp/cache-memory/*) # - mcp__github__download_workflow_run_artifact # - mcp__github__get_code_scanning_alert # - mcp__github__get_commit @@ -841,7 +906,7 @@ jobs: run: | set -o pipefail # Execute Claude Code CLI with prompt from file - npx @anthropic-ai/claude-code@latest --print --max-turns 5 --mcp-config /tmp/mcp-config/mcp-servers.json --allowed-tools "ExitPlanMode,Glob,Grep,LS,NotebookRead,Read,Task,TodoWrite,Write,mcp__github__download_workflow_run_artifact,mcp__github__get_code_scanning_alert,mcp__github__get_commit,mcp__github__get_dependabot_alert,mcp__github__get_discussion,mcp__github__get_discussion_comments,mcp__github__get_file_contents,mcp__github__get_issue,mcp__github__get_issue_comments,mcp__github__get_job_logs,mcp__github__get_me,mcp__github__get_notification_details,mcp__github__get_pull_request,mcp__github__get_pull_request_comments,mcp__github__get_pull_request_diff,mcp__github__get_pull_request_files,mcp__github__get_pull_request_reviews,mcp__github__get_pull_request_status,mcp__github__get_secret_scanning_alert,mcp__github__get_tag,mcp__github__get_workflow_run,mcp__github__get_workflow_run_logs,mcp__github__get_workflow_run_usage,mcp__github__list_branches,mcp__github__list_code_scanning_alerts,mcp__github__list_commits,mcp__github__list_dependabot_alerts,mcp__github__list_discussion_categories,mcp__github__list_discussions,mcp__github__list_issues,mcp__github__list_notifications,mcp__github__list_pull_requests,mcp__github__list_secret_scanning_alerts,mcp__github__list_tags,mcp__github__list_workflow_jobs,mcp__github__list_workflow_run_artifacts,mcp__github__list_workflow_runs,mcp__github__list_workflows,mcp__github__search_code,mcp__github__search_issues,mcp__github__search_orgs,mcp__github__search_pull_requests,mcp__github__search_repositories,mcp__github__search_users" --debug --verbose --permission-mode bypassPermissions --output-format json --settings /tmp/.claude/settings.json "$(cat /tmp/aw-prompts/prompt.txt)" 2>&1 | tee /tmp/dev.log + npx @anthropic-ai/claude-code@latest --print --max-turns 5 --mcp-config /tmp/mcp-config/mcp-servers.json --allowed-tools "Edit(/tmp/cache-memory/*),ExitPlanMode,Glob,Grep,LS,MultiEdit(/tmp/cache-memory/*),NotebookRead,Read,Read(/tmp/cache-memory/*),Task,TodoWrite,Write,Write(/tmp/cache-memory/*),mcp__github__download_workflow_run_artifact,mcp__github__get_code_scanning_alert,mcp__github__get_commit,mcp__github__get_dependabot_alert,mcp__github__get_discussion,mcp__github__get_discussion_comments,mcp__github__get_file_contents,mcp__github__get_issue,mcp__github__get_issue_comments,mcp__github__get_job_logs,mcp__github__get_me,mcp__github__get_notification_details,mcp__github__get_pull_request,mcp__github__get_pull_request_comments,mcp__github__get_pull_request_diff,mcp__github__get_pull_request_files,mcp__github__get_pull_request_reviews,mcp__github__get_pull_request_status,mcp__github__get_secret_scanning_alert,mcp__github__get_tag,mcp__github__get_workflow_run,mcp__github__get_workflow_run_logs,mcp__github__get_workflow_run_usage,mcp__github__list_branches,mcp__github__list_code_scanning_alerts,mcp__github__list_commits,mcp__github__list_dependabot_alerts,mcp__github__list_discussion_categories,mcp__github__list_discussions,mcp__github__list_issues,mcp__github__list_notifications,mcp__github__list_pull_requests,mcp__github__list_secret_scanning_alerts,mcp__github__list_tags,mcp__github__list_workflow_jobs,mcp__github__list_workflow_run_artifacts,mcp__github__list_workflow_runs,mcp__github__list_workflows,mcp__github__search_code,mcp__github__search_issues,mcp__github__search_orgs,mcp__github__search_pull_requests,mcp__github__search_repositories,mcp__github__search_users" --debug --verbose --permission-mode bypassPermissions --output-format json --settings /tmp/.claude/settings.json "$(cat /tmp/aw-prompts/prompt.txt)" 2>&1 | tee /tmp/dev.log env: ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} DISABLE_TELEMETRY: "1" diff --git a/.github/workflows/dev.md b/.github/workflows/dev.md index 36f87303e2..7ae5049597 100644 --- a/.github/workflows/dev.md +++ b/.github/workflows/dev.md @@ -1,10 +1,13 @@ --- +name: "dev" on: workflow_dispatch: # do not remove this trigger push: branches: - copilot/* - pelikhan/* +tools: + cache-memory: true safe-outputs: missing-tool: staged: true @@ -14,4 +17,26 @@ engine: permissions: read-all --- -Try to call a tool, `draw_pelican` that draws a pelican. \ No newline at end of file +# Development Assistant + +You are a development assistant that helps with coding tasks and maintains an execution plan. + +## Task + +Try to call a tool, `draw_pelican` that draws a pelican. + +## Execution Plan Management + +- **Check for existing plan**: Look for `/tmp/cache-memory/plan.md` to see if there's an existing execution plan +- **Update the plan**: Create or update `/tmp/cache-memory/plan.md` with your execution strategy +- **Remember progress**: Store any important findings, decisions, or progress in the cache folder +- **Recall previous work**: If a plan exists, reference it and continue from where you left off + +The plan should include: +1. Current objectives +2. Steps completed +3. Next steps +4. Any important discoveries or decisions +5. Tools or approaches that worked well + +Please maintain this execution plan throughout your work to ensure continuity across workflow runs. \ No newline at end of file diff --git a/docs/src/content/docs/reference/cache-memory.md b/docs/src/content/docs/reference/cache-memory.md index e9014dc3c4..c9273ab831 100644 --- a/docs/src/content/docs/reference/cache-memory.md +++ b/docs/src/content/docs/reference/cache-memory.md @@ -1,17 +1,17 @@ --- title: Cache Memory -description: Complete guide to using cache-memory for persistent memory across workflow runs using GitHub Actions cache and MCP memory servers. +description: Complete guide to using cache-memory for persistent file storage across workflow runs using GitHub Actions cache and simple file operations. --- -The `cache-memory` feature enables agentic workflows to maintain persistent memory across workflow runs by integrating the Model Context Protocol (MCP) memory server with GitHub Actions cache. +The `cache-memory` feature enables agentic workflows to maintain persistent file storage across workflow runs using GitHub Actions cache infrastructure and simple file operations. ## Overview Cache Memory provides: -- **Persistent Memory**: AI agents can remember information across multiple workflow runs +- **Persistent File Storage**: AI agents can store and retrieve files across multiple workflow runs - **GitHub Actions Integration**: Built on top of GitHub Actions cache infrastructure -- **MCP Memory Server**: Uses the official Model Context Protocol memory server via npx +- **Simple File Operations**: Uses standard file system operations instead of specialized tools - **Automatic Configuration**: Seamlessly integrates with Claude and Custom engines - **Smart Caching**: Intelligent cache key generation and restoration strategies @@ -19,11 +19,11 @@ Cache Memory provides: When `cache-memory` is enabled, the workflow compiler automatically: -1. **Mounts Memory MCP Server**: Configures an official MCP memory server via npx -2. **Creates Cache Steps**: Adds GitHub Actions cache steps to restore and save memory data -3. **Persistent Storage**: Maps `/tmp/cache-memory` to store memory data files +1. **Creates Cache Directory**: Sets up `/tmp/cache-memory/` directory for file storage +2. **Creates Cache Steps**: Adds GitHub Actions cache steps to restore and save data +3. **Persistent Storage**: Maps `/tmp/cache-memory/` to store user data files 4. **Cache Key Management**: Generates intelligent cache keys with progressive fallback -5. **Tool Integration**: Adds "memory" tool to the MCP configuration for AI engines +5. **Prompts LLM**: Informs the AI agent about the available cache folder ## Enabling Cache Memory @@ -41,42 +41,40 @@ tools: This uses: - **Default cache key**: `memory-${{ github.workflow }}-${{ github.run_id }}` -- **Default setup**: Uses `npx @modelcontextprotocol/server-memory` -- **Default storage path**: `/tmp/cache-memory` for memory data files +- **Simple file access**: Uses standard file operations for read/write +- **Default storage path**: `/tmp/cache-memory/` for data files -## Prompting for Memory Operations +## Using the Cache Folder -Memory is accessed via the `memory` tool in your workflow steps. +The cache folder is accessible to AI agents and provides file system access for persistent storage. ### Storing Information -The AI agent can store information using the memory tool: +The AI agent can store information using standard file operations: ``` -Remember that the user prefers verbose error messages when debugging. +Please save this information to a file in the cache folder: "User prefers verbose error messages when debugging." ``` ### Retrieving Information -The AI agent can query its memory: +The AI agent can read files from the cache folder: ``` -What do I know about the user's debugging preferences? +Check what information I have stored in the cache folder from previous runs. ``` -### Memory Categories +### File Organization -The MCP memory server organizes information into categories: +The AI agent can organize files as needed: -- **Basic Identity**: User identification and context -- **Behaviors**: Observed patterns and preferences -- **Preferences**: Explicit user preferences -- **Goals**: Stated objectives and tasks -- **Relationships**: Connections between entities +- **Structured data**: JSON or YAML files for configuration and preferences +- **Text files**: Plain text for notes, logs, and observations +- **Directories**: Organize files into subdirectories for better structure ## Advanced Configuration -You can also use the more advanced configuration to customize cache key and artifact retention: +You can customize cache key and artifact retention: ```yaml --- @@ -92,7 +90,7 @@ tools: ### Artifact Retention -Configure how long memory data artifacts are retained: +Configure how long cache data artifacts are retained: ```yaml --- @@ -109,7 +107,7 @@ tools: The `retention-days` option controls the `actions/upload-artifact` retention period: - **Range**: 1-90 days - **Default**: Repository setting (if not specified) -- **Purpose**: Provides alternative access to memory data beyond cache expiration +- **Purpose**: Provides alternative access to cache data beyond cache expiration ## Cache Behavior and GitHub Actions Integration @@ -121,10 +119,10 @@ Cache Memory leverages GitHub Actions cache with these characteristics: - **LRU Eviction**: Least recently used caches are evicted when limits are reached #### Artifact Upload (Optional) -When `retention-days` is configured, memory data is also uploaded as artifacts: +When `retention-days` is configured, cache data is also uploaded as artifacts: - **Retention Period**: 1-90 days (configurable via `retention-days`) -- **Purpose**: Alternative access to memory data beyond cache expiration -- **Use Case**: Long-term memory persistence for workflows that run infrequently +- **Purpose**: Alternative access to cache data beyond cache expiration +- **Use Case**: Long-term persistence for workflows that run infrequently #### Cache Scoping - **Branch Scoping**: Caches are accessible across branches in the same repository @@ -151,20 +149,34 @@ custom- This ensures the most specific match is found first, with progressive fallbacks. -## MCP Server Configuration +## File Access and Organization -The memory from the cache is accessed via a memory server is implicitly configured using npx following official MCP documentation: +The cache folder provides standard file system access: -```json -"memory": { - "command": "npx", - "args": [ - "@modelcontextprotocol/server-memory" - ], - "env": { - "MEMORY_FILE_PATH": "/tmp/cache-memory/memory.json" - } -} +### File Operations +``` +/tmp/cache-memory/notes.txt # Simple text files +/tmp/cache-memory/config.json # Structured data +/tmp/cache-memory/logs/activity.log # Organized in subdirectories +/tmp/cache-memory/state/session.yaml # State management +``` + +### Best Practices for File Organization + +Use descriptive file names and directory structures: + +``` +/tmp/cache-memory/ +├── preferences/ +│ ├── user-settings.json +│ └── workflow-config.yaml +├── logs/ +│ ├── activity.log +│ └── errors.log +├── state/ +│ ├── last-run.txt +│ └── context.json +└── notes.md ``` ## Best Practices @@ -181,9 +193,9 @@ tools: ### Memory Scope -Consider the scope of memory needed: +Consider the scope of cache needed: -- **Workflow-specific**: Default behavior, memory per workflow +- **Workflow-specific**: Default behavior, cache per workflow - **Repository-wide**: Use repository name in cache key - **User-specific**: Include user information in cache key @@ -191,7 +203,7 @@ Consider the scope of memory needed: Be mindful of cache usage: -- **Memory Size**: Monitor memory data growth over time +- **File Size**: Monitor cache data growth over time - **Cache Limits**: Respect GitHub's 10GB repository cache limit - **Cleanup Strategy**: Consider periodic cache clearing for long-running projects @@ -199,15 +211,15 @@ Be mindful of cache usage: ### Common Issues -#### Memory Not Persisting +#### Files Not Persisting - **Check Cache Keys**: Ensure keys are consistent between runs -- **Verify Paths**: Confirm `/tmp/cache-memory` directory exists +- **Verify Paths**: Confirm `/tmp/cache-memory/` directory exists - **Review Logs**: Check workflow logs for cache restore/save messages -#### Package Installation Issues -- **npm Registry Access**: Verify runner can access npm registry -- **Package Availability**: Confirm `@modelcontextprotocol/server-memory` package exists -- **Network Access**: Ensure runner has internet connectivity for package installation +#### File Access Issues +- **Directory Creation**: Ensure subdirectories are created before use +- **Permissions**: Verify file write permissions in the cache folder +- **Path Resolution**: Use absolute paths within `/tmp/cache-memory/` #### Cache Size Issues - **Monitor Usage**: Track cache size growth over time @@ -230,29 +242,30 @@ timeout_minutes: 10 # Allow time for debugging Please debug the cache-memory functionality by: -1. Checking what's currently in memory -2. Storing a test message -3. Retrieving the stored message -4. Reporting on memory persistence +1. Checking what files exist in the cache folder +2. Creating a test file with current timestamp +3. Reading the test file back +4. Listing all files in the cache folder +5. Reporting on file persistence ``` ## Security Considerations ### Data Privacy -- **Sensitive Data**: Avoid storing sensitive information in memory -- **Access Control**: Memory data follows repository access permissions +- **Sensitive Data**: Avoid storing sensitive information in cache files +- **Access Control**: Cache data follows repository access permissions - **Audit Trail**: Cache access is logged in workflow execution logs -### Package Security +### File Security -- **Official Package**: Use only the official `@modelcontextprotocol/server-memory` package -- **Dependency Scanning**: npm automatically scans for vulnerabilities -- **Audit Trail**: Package installation is logged in workflow execution logs +- **Standard Permissions**: Files use standard GitHub Actions runner permissions +- **Temporary Storage**: Cache directory is temporary and cleaned between runs +- **No External Access**: Cache folder is only accessible within workflow execution ## Examples -### Basic Memory Usage +### Basic File Storage ```yaml --- @@ -260,8 +273,8 @@ engine: claude on: workflow_dispatch: inputs: - remember: - description: 'Information to remember' + note: + description: 'Note to remember' required: true tools: @@ -270,19 +283,19 @@ tools: allowed: [get_repository] --- -# Memory Test Workflow +# File Storage Test Workflow -Store and retrieve information across workflow runs. +Store and retrieve information using simple file operations. ## Task -1. Check what you remember from previous runs -2. Store the new information: "${{ inputs.remember }}" -3. List all stored memories -4. Provide a summary of memory persistence +1. Check what files exist in the cache folder from previous runs +2. Store the new note: "${{ inputs.note }}" in a timestamped file +3. List all files in the cache folder +4. Provide a summary of stored files and persistence ``` -### Project-Specific Memory +### Project-Specific Cache ```yaml --- @@ -296,27 +309,42 @@ tools: # Documentation Assistant -Use project-specific memory to maintain context about documentation updates. +Use project-specific cache to maintain context about documentation updates. +Store progress, preferences, and notes in organized files. ``` -### Multi-Workflow Memory Sharing +### Multi-Workflow File Sharing ```yaml --- engine: claude tools: cache-memory: - key: shared-memory-${{ github.repository }} + key: shared-cache-${{ github.repository }} --- -# Shared Memory Workflow +# Shared Cache Workflow -Share memory data across multiple workflows in the same repository. +Share cache data across multiple workflows in the same repository using files. ``` +## Migration from MCP Memory Server + +If migrating from the previous MCP memory server approach: + +### Changes +- **No MCP server**: Cache-memory no longer uses `@modelcontextprotocol/server-memory` +- **File operations**: Use standard file read/write instead of memory tools +- **Direct access**: Access files directly at `/tmp/cache-memory/` +- **No tools**: No `mcp__memory` tool is provided + +### Migration Steps +1. **Update workflow syntax**: Remove any `docker-image` configuration +2. **Modify prompts**: Update prompts to reference file operations instead of memory tools +3. **Test file access**: Verify file operations work as expected + ## Related Documentation - [Frontmatter Options](/gh-aw/reference/frontmatter/) - Complete frontmatter configuration guide -- [MCP Tools](/gh-aw/guides/mcps/) - Model Context Protocol integration - [Safe Outputs](/gh-aw/reference/safe-outputs/) - Output processing and automation - [GitHub Actions Cache Documentation](https://docs.github.com/en/actions/using-workflows/caching-dependencies-to-speed-up-workflows) - Official GitHub cache documentation \ No newline at end of file diff --git a/pkg/cli/workflows/test-claude-cache-memory.lock.yml b/pkg/cli/workflows/test-claude-cache-memory.lock.yml index bcf5c92e59..0529c8fcfe 100644 --- a/pkg/cli/workflows/test-claude-cache-memory.lock.yml +++ b/pkg/cli/workflows/test-claude-cache-memory.lock.yml @@ -2,7 +2,7 @@ # To update this file, edit the corresponding .md file and run: # gh aw compile -name: "Test Claude with Cache Memory and Custom Docker Image" +name: "Test Claude with Cache Memory File Share" on: workflow_dispatch: inputs: @@ -16,19 +16,23 @@ permissions: {} concurrency: group: "gh-aw-${{ github.workflow }}" -run-name: "Test Claude with Cache Memory and Custom Docker Image" +run-name: "Test Claude with Cache Memory File Share" jobs: - test-claude-with-cache-memory-and-custom-docker-image: + test-claude-with-cache-memory-file-share: runs-on: ubuntu-latest permissions: read-all steps: - name: Checkout repository uses: actions/checkout@v5 - # Cache memory MCP configuration from frontmatter processed below + # Cache memory file share configuration from frontmatter processed below - name: Create cache-memory directory - run: mkdir -p /tmp/cache-memory - - name: Cache memory MCP data + run: | + mkdir -p /tmp/cache-memory + echo "Cache memory directory created at /tmp/cache-memory" + echo "This folder provides persistent file storage across workflow runs" + echo "LLMs and agentic tools can freely read and write files in this directory" + - name: Cache memory file share data uses: actions/cache@v4 with: key: memory-${{ github.workflow }}-${{ github.run_id }} @@ -36,10 +40,10 @@ jobs: restore-keys: | memory-${{ github.workflow }}- memory- - - name: Upload memory MCP data as artifact + - name: Upload cache-memory data as artifact uses: actions/upload-artifact@v4 with: - name: cache-memory-data + name: cache-memory path: /tmp/cache-memory retention-days: 14 - name: Generate Claude Settings @@ -156,15 +160,6 @@ jobs: cat > /tmp/mcp-config/mcp-servers.json << 'EOF' { "mcpServers": { - "memory": { - "command": "npx", - "args": [ - "@modelcontextprotocol/server-memory" - ], - "env": { - "MEMORY_FILE_PATH": "/tmp/cache-memory/memory.json" - } - }, "github": { "command": "docker", "args": [ @@ -188,45 +183,64 @@ jobs: run: | mkdir -p /tmp/aw-prompts cat > $GITHUB_AW_PROMPT << 'EOF' - # Test Claude with Cache Memory and Custom Docker Image + # Test Claude with Cache Memory File Share - You are a test agent that demonstrates the cache-memory functionality with Claude engine using a custom Docker image. + You are a test agent that demonstrates the cache-memory functionality with Claude engine using a simple file share approach. ## Task Your job is to: - 1. **Store a test task** in your memory using the memory MCP server - 2. **Retrieve any previous tasks** that you've stored in memory - 3. **Report on the memory contents** including both current and historical tasks + 1. **Store a test task** in the cache folder using file operations + 2. **Retrieve any previous tasks** that you've stored in previous runs + 3. **Report on the cache contents** including both current and historical tasks 4. **Use GitHub tools** to get basic repository information ## Instructions - 1. First, use the memory tool to see what you already know from previous runs - 2. Store a new test task: "Test task for run ${{ github.run_number }}" in your memory - 3. List all tasks you now have in memory + 1. First, check what files exist in `/tmp/cache-memory/` from previous runs + 2. Store a new test task: "Test task for run ${{ github.run_number }}" in a file in the cache folder + 3. List all files and contents you now have in the cache folder 4. Get basic information about this repository using the GitHub tool 5. Provide a summary of: - - What you remembered from before + - What you found from before (if anything) - What you just stored - Basic repository information ## Expected Behavior - - **First run**: Should show empty memory, then store the new task - - **Subsequent runs**: Should show previously stored tasks, then add the new one - - **Memory persistence**: Tasks should persist across workflow runs thanks to cache-memory - - **Custom Docker image**: Uses ghcr.io/modelcontextprotocol/server-memory:v1.0.0 instead of latest - - **Artifact upload**: Memory data is also uploaded as artifact with 14-day retention + - **First run**: Should show empty cache folder, then store the new task + - **Subsequent runs**: Should show previously stored files, then add the new one + - **File persistence**: Files should persist across workflow runs thanks to cache-memory + - **Simple file access**: Uses standard file operations (no MCP server needed) + - **Artifact upload**: Cache data is also uploaded as artifact with 14-day retention This workflow tests that the cache-memory configuration properly: - - Mounts the memory MCP server with custom Docker image + - Creates a simple file share at `/tmp/cache-memory/` - Persists data between runs using GitHub Actions cache - - Uploads memory data as artifacts with configurable retention - - Works with Claude engine and MCP tools + - Uploads cache data as artifacts with configurable retention + - Works with Claude engine and file operations - Integrates with other tools like GitHub + + --- + + ## Cache Folder Available + + You have access to a persistent cache folder at `/tmp/cache-memory/` where you can read and write files to create memories and store information. + + - **Read/Write Access**: You can freely read from and write to any files in this folder + - **Persistence**: Files in this folder persist across workflow runs via GitHub Actions cache + - **Last Write Wins**: If multiple processes write to the same file, the last write will be preserved + - **File Share**: Use this as a simple file share - organize files as you see fit + + Examples of what you can store: + - `/tmp/cache-memory/notes.txt` - general notes and observations + - `/tmp/cache-memory/preferences.json` - user preferences and settings + - `/tmp/cache-memory/history.log` - activity history and logs + - `/tmp/cache-memory/state/` - organized state files in subdirectories + + Feel free to create, read, update, and organize files in this folder as needed for your tasks. EOF - name: Print prompt to step summary run: | @@ -248,7 +262,7 @@ jobs: engine_name: "Claude Code", model: "", version: "", - workflow_name: "Test Claude with Cache Memory and Custom Docker Image", + workflow_name: "Test Claude with Cache Memory File Share", experimental: false, supports_tools_whitelist: true, supports_http_transport: true, @@ -279,14 +293,18 @@ jobs: - name: Execute Claude Code CLI id: agentic_execution # Allowed tools (sorted): + # - Edit(/tmp/cache-memory/*) # - ExitPlanMode # - Glob # - Grep # - LS + # - MultiEdit(/tmp/cache-memory/*) # - NotebookRead # - Read + # - Read(/tmp/cache-memory/*) # - Task # - TodoWrite + # - Write(/tmp/cache-memory/*) # - mcp__github__download_workflow_run_artifact # - mcp__github__get_code_scanning_alert # - mcp__github__get_commit @@ -332,12 +350,11 @@ jobs: # - mcp__github__search_pull_requests # - mcp__github__search_repositories # - mcp__github__search_users - # - mcp__memory timeout-minutes: 5 run: | set -o pipefail # Execute Claude Code CLI with prompt from file - npx @anthropic-ai/claude-code@latest --print --mcp-config /tmp/mcp-config/mcp-servers.json --allowed-tools "ExitPlanMode,Glob,Grep,LS,NotebookRead,Read,Task,TodoWrite,mcp__github__download_workflow_run_artifact,mcp__github__get_code_scanning_alert,mcp__github__get_commit,mcp__github__get_dependabot_alert,mcp__github__get_discussion,mcp__github__get_discussion_comments,mcp__github__get_file_contents,mcp__github__get_issue,mcp__github__get_issue_comments,mcp__github__get_job_logs,mcp__github__get_me,mcp__github__get_notification_details,mcp__github__get_pull_request,mcp__github__get_pull_request_comments,mcp__github__get_pull_request_diff,mcp__github__get_pull_request_files,mcp__github__get_pull_request_reviews,mcp__github__get_pull_request_status,mcp__github__get_repository,mcp__github__get_secret_scanning_alert,mcp__github__get_tag,mcp__github__get_workflow_run,mcp__github__get_workflow_run_logs,mcp__github__get_workflow_run_usage,mcp__github__list_branches,mcp__github__list_code_scanning_alerts,mcp__github__list_commits,mcp__github__list_dependabot_alerts,mcp__github__list_discussion_categories,mcp__github__list_discussions,mcp__github__list_issues,mcp__github__list_notifications,mcp__github__list_pull_requests,mcp__github__list_secret_scanning_alerts,mcp__github__list_tags,mcp__github__list_workflow_jobs,mcp__github__list_workflow_run_artifacts,mcp__github__list_workflow_runs,mcp__github__list_workflows,mcp__github__search_code,mcp__github__search_issues,mcp__github__search_orgs,mcp__github__search_pull_requests,mcp__github__search_repositories,mcp__github__search_users,mcp__memory" --debug --verbose --permission-mode bypassPermissions --output-format json --settings /tmp/.claude/settings.json "$(cat /tmp/aw-prompts/prompt.txt)" 2>&1 | tee /tmp/test-claude-with-cache-memory-and-custom-docker-image.log + npx @anthropic-ai/claude-code@latest --print --mcp-config /tmp/mcp-config/mcp-servers.json --allowed-tools "Edit(/tmp/cache-memory/*),ExitPlanMode,Glob,Grep,LS,MultiEdit(/tmp/cache-memory/*),NotebookRead,Read,Read(/tmp/cache-memory/*),Task,TodoWrite,Write(/tmp/cache-memory/*),mcp__github__download_workflow_run_artifact,mcp__github__get_code_scanning_alert,mcp__github__get_commit,mcp__github__get_dependabot_alert,mcp__github__get_discussion,mcp__github__get_discussion_comments,mcp__github__get_file_contents,mcp__github__get_issue,mcp__github__get_issue_comments,mcp__github__get_job_logs,mcp__github__get_me,mcp__github__get_notification_details,mcp__github__get_pull_request,mcp__github__get_pull_request_comments,mcp__github__get_pull_request_diff,mcp__github__get_pull_request_files,mcp__github__get_pull_request_reviews,mcp__github__get_pull_request_status,mcp__github__get_repository,mcp__github__get_secret_scanning_alert,mcp__github__get_tag,mcp__github__get_workflow_run,mcp__github__get_workflow_run_logs,mcp__github__get_workflow_run_usage,mcp__github__list_branches,mcp__github__list_code_scanning_alerts,mcp__github__list_commits,mcp__github__list_dependabot_alerts,mcp__github__list_discussion_categories,mcp__github__list_discussions,mcp__github__list_issues,mcp__github__list_notifications,mcp__github__list_pull_requests,mcp__github__list_secret_scanning_alerts,mcp__github__list_tags,mcp__github__list_workflow_jobs,mcp__github__list_workflow_run_artifacts,mcp__github__list_workflow_runs,mcp__github__list_workflows,mcp__github__search_code,mcp__github__search_issues,mcp__github__search_orgs,mcp__github__search_pull_requests,mcp__github__search_repositories,mcp__github__search_users" --debug --verbose --permission-mode bypassPermissions --output-format json --settings /tmp/.claude/settings.json "$(cat /tmp/aw-prompts/prompt.txt)" 2>&1 | tee /tmp/test-claude-with-cache-memory-file-share.log env: ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} DISABLE_TELEMETRY: "1" @@ -348,15 +365,15 @@ jobs: if: always() run: | # Ensure log file exists - touch /tmp/test-claude-with-cache-memory-and-custom-docker-image.log + touch /tmp/test-claude-with-cache-memory-file-share.log # Show last few lines for debugging echo "=== Last 10 lines of Claude execution log ===" - tail -10 /tmp/test-claude-with-cache-memory-and-custom-docker-image.log || echo "No log content available" + tail -10 /tmp/test-claude-with-cache-memory-file-share.log || echo "No log content available" - name: Parse agent logs for step summary if: always() uses: actions/github-script@v7 env: - GITHUB_AW_AGENT_OUTPUT: /tmp/test-claude-with-cache-memory-and-custom-docker-image.log + GITHUB_AW_AGENT_OUTPUT: /tmp/test-claude-with-cache-memory-file-share.log with: script: | function main() { @@ -873,7 +890,7 @@ jobs: if: always() uses: actions/upload-artifact@v4 with: - name: test-claude-with-cache-memory-and-custom-docker-image.log - path: /tmp/test-claude-with-cache-memory-and-custom-docker-image.log + name: test-claude-with-cache-memory-file-share.log + path: /tmp/test-claude-with-cache-memory-file-share.log if-no-files-found: warn diff --git a/pkg/cli/workflows/test-claude-cache-memory.md b/pkg/cli/workflows/test-claude-cache-memory.md index 75ce252002..c937df10b2 100644 --- a/pkg/cli/workflows/test-claude-cache-memory.md +++ b/pkg/cli/workflows/test-claude-cache-memory.md @@ -10,7 +10,6 @@ on: tools: cache-memory: - docker-image: "ghcr.io/modelcontextprotocol/server-memory:v1.0.0" retention-days: 14 github: allowed: [get_repository] @@ -18,41 +17,41 @@ tools: timeout_minutes: 5 --- -# Test Claude with Cache Memory and Custom Docker Image +# Test Claude with Cache Memory File Share -You are a test agent that demonstrates the cache-memory functionality with Claude engine using a custom Docker image. +You are a test agent that demonstrates the cache-memory functionality with Claude engine using a simple file share approach. ## Task Your job is to: -1. **Store a test task** in your memory using the memory MCP server -2. **Retrieve any previous tasks** that you've stored in memory -3. **Report on the memory contents** including both current and historical tasks +1. **Store a test task** in the cache folder using file operations +2. **Retrieve any previous tasks** that you've stored in previous runs +3. **Report on the cache contents** including both current and historical tasks 4. **Use GitHub tools** to get basic repository information ## Instructions -1. First, use the memory tool to see what you already know from previous runs -2. Store a new test task: "Test task for run ${{ github.run_number }}" in your memory -3. List all tasks you now have in memory +1. First, check what files exist in `/tmp/cache-memory/` from previous runs +2. Store a new test task: "Test task for run ${{ github.run_number }}" in a file in the cache folder +3. List all files and contents you now have in the cache folder 4. Get basic information about this repository using the GitHub tool 5. Provide a summary of: - - What you remembered from before + - What you found from before (if anything) - What you just stored - Basic repository information ## Expected Behavior -- **First run**: Should show empty memory, then store the new task -- **Subsequent runs**: Should show previously stored tasks, then add the new one -- **Memory persistence**: Tasks should persist across workflow runs thanks to cache-memory -- **Custom Docker image**: Uses ghcr.io/modelcontextprotocol/server-memory:v1.0.0 instead of latest -- **Artifact upload**: Memory data is also uploaded as artifact with 14-day retention +- **First run**: Should show empty cache folder, then store the new task +- **Subsequent runs**: Should show previously stored files, then add the new one +- **File persistence**: Files should persist across workflow runs thanks to cache-memory +- **Simple file access**: Uses standard file operations (no MCP server needed) +- **Artifact upload**: Cache data is also uploaded as artifact with 14-day retention This workflow tests that the cache-memory configuration properly: -- Mounts the memory MCP server with custom Docker image +- Creates a simple file share at `/tmp/cache-memory/` - Persists data between runs using GitHub Actions cache -- Uploads memory data as artifacts with configurable retention -- Works with Claude engine and MCP tools +- Uploads cache data as artifacts with configurable retention +- Works with Claude engine and file operations - Integrates with other tools like GitHub \ No newline at end of file diff --git a/pkg/cli/workflows/test-claude-missing-tool.lock.yml b/pkg/cli/workflows/test-claude-missing-tool.lock.yml index 92d43c84d1..9d5cadbd57 100644 --- a/pkg/cli/workflows/test-claude-missing-tool.lock.yml +++ b/pkg/cli/workflows/test-claude-missing-tool.lock.yml @@ -27,10 +27,14 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v5 - # Cache memory MCP configuration from frontmatter processed below + # Cache memory file share configuration from frontmatter processed below - name: Create cache-memory directory - run: mkdir -p /tmp/cache-memory - - name: Cache memory MCP data + run: | + mkdir -p /tmp/cache-memory + echo "Cache memory directory created at /tmp/cache-memory" + echo "This folder provides persistent file storage across workflow runs" + echo "LLMs and agentic tools can freely read and write files in this directory" + - name: Cache memory file share data uses: actions/cache@v4 with: key: memory-${{ github.workflow }}-${{ github.run_id }} @@ -38,6 +42,11 @@ jobs: restore-keys: | memory-${{ github.workflow }}- memory- + - name: Upload cache-memory data as artifact + uses: actions/upload-artifact@v4 + with: + name: cache-memory + path: /tmp/cache-memory - name: Generate Claude Settings run: | mkdir -p /tmp/.claude @@ -610,15 +619,6 @@ jobs: cat > /tmp/mcp-config/mcp-servers.json << 'EOF' { "mcpServers": { - "memory": { - "command": "npx", - "args": [ - "@modelcontextprotocol/server-memory" - ], - "env": { - "MEMORY_FILE_PATH": "/tmp/cache-memory/memory.json" - } - }, "github": { "command": "docker", "args": [ @@ -691,6 +691,25 @@ jobs: - Safe output system handles missing tool scenarios correctly + --- + + ## Cache Folder Available + + You have access to a persistent cache folder at `/tmp/cache-memory/` where you can read and write files to create memories and store information. + + - **Read/Write Access**: You can freely read from and write to any files in this folder + - **Persistence**: Files in this folder persist across workflow runs via GitHub Actions cache + - **Last Write Wins**: If multiple processes write to the same file, the last write will be preserved + - **File Share**: Use this as a simple file share - organize files as you see fit + + Examples of what you can store: + - `/tmp/cache-memory/notes.txt` - general notes and observations + - `/tmp/cache-memory/preferences.json` - user preferences and settings + - `/tmp/cache-memory/history.log` - activity history and logs + - `/tmp/cache-memory/state/` - organized state files in subdirectories + + Feel free to create, read, update, and organize files in this folder as needed for your tasks. + --- ## Reporting Missing Tools or Functionality @@ -748,15 +767,19 @@ jobs: - name: Execute Claude Code CLI id: agentic_execution # Allowed tools (sorted): + # - Edit(/tmp/cache-memory/*) # - ExitPlanMode # - Glob # - Grep # - LS + # - MultiEdit(/tmp/cache-memory/*) # - NotebookRead # - Read + # - Read(/tmp/cache-memory/*) # - Task # - TodoWrite # - Write + # - Write(/tmp/cache-memory/*) # - mcp__github__download_workflow_run_artifact # - mcp__github__get_code_scanning_alert # - mcp__github__get_commit @@ -802,12 +825,11 @@ jobs: # - mcp__github__search_pull_requests # - mcp__github__search_repositories # - mcp__github__search_users - # - mcp__memory timeout-minutes: 5 run: | set -o pipefail # Execute Claude Code CLI with prompt from file - npx @anthropic-ai/claude-code@latest --print --mcp-config /tmp/mcp-config/mcp-servers.json --allowed-tools "ExitPlanMode,Glob,Grep,LS,NotebookRead,Read,Task,TodoWrite,Write,mcp__github__download_workflow_run_artifact,mcp__github__get_code_scanning_alert,mcp__github__get_commit,mcp__github__get_dependabot_alert,mcp__github__get_discussion,mcp__github__get_discussion_comments,mcp__github__get_file_contents,mcp__github__get_issue,mcp__github__get_issue_comments,mcp__github__get_job_logs,mcp__github__get_me,mcp__github__get_notification_details,mcp__github__get_pull_request,mcp__github__get_pull_request_comments,mcp__github__get_pull_request_diff,mcp__github__get_pull_request_files,mcp__github__get_pull_request_reviews,mcp__github__get_pull_request_status,mcp__github__get_repository,mcp__github__get_secret_scanning_alert,mcp__github__get_tag,mcp__github__get_workflow_run,mcp__github__get_workflow_run_logs,mcp__github__get_workflow_run_usage,mcp__github__list_branches,mcp__github__list_code_scanning_alerts,mcp__github__list_commits,mcp__github__list_dependabot_alerts,mcp__github__list_discussion_categories,mcp__github__list_discussions,mcp__github__list_issues,mcp__github__list_notifications,mcp__github__list_pull_requests,mcp__github__list_secret_scanning_alerts,mcp__github__list_tags,mcp__github__list_workflow_jobs,mcp__github__list_workflow_run_artifacts,mcp__github__list_workflow_runs,mcp__github__list_workflows,mcp__github__search_code,mcp__github__search_issues,mcp__github__search_orgs,mcp__github__search_pull_requests,mcp__github__search_repositories,mcp__github__search_users,mcp__memory" --debug --verbose --permission-mode bypassPermissions --output-format json --settings /tmp/.claude/settings.json "$(cat /tmp/aw-prompts/prompt.txt)" 2>&1 | tee /tmp/test-claude-with-missing-tool-safe-output-and-cache-memory.log + npx @anthropic-ai/claude-code@latest --print --mcp-config /tmp/mcp-config/mcp-servers.json --allowed-tools "Edit(/tmp/cache-memory/*),ExitPlanMode,Glob,Grep,LS,MultiEdit(/tmp/cache-memory/*),NotebookRead,Read,Read(/tmp/cache-memory/*),Task,TodoWrite,Write,Write(/tmp/cache-memory/*),mcp__github__download_workflow_run_artifact,mcp__github__get_code_scanning_alert,mcp__github__get_commit,mcp__github__get_dependabot_alert,mcp__github__get_discussion,mcp__github__get_discussion_comments,mcp__github__get_file_contents,mcp__github__get_issue,mcp__github__get_issue_comments,mcp__github__get_job_logs,mcp__github__get_me,mcp__github__get_notification_details,mcp__github__get_pull_request,mcp__github__get_pull_request_comments,mcp__github__get_pull_request_diff,mcp__github__get_pull_request_files,mcp__github__get_pull_request_reviews,mcp__github__get_pull_request_status,mcp__github__get_repository,mcp__github__get_secret_scanning_alert,mcp__github__get_tag,mcp__github__get_workflow_run,mcp__github__get_workflow_run_logs,mcp__github__get_workflow_run_usage,mcp__github__list_branches,mcp__github__list_code_scanning_alerts,mcp__github__list_commits,mcp__github__list_dependabot_alerts,mcp__github__list_discussion_categories,mcp__github__list_discussions,mcp__github__list_issues,mcp__github__list_notifications,mcp__github__list_pull_requests,mcp__github__list_secret_scanning_alerts,mcp__github__list_tags,mcp__github__list_workflow_jobs,mcp__github__list_workflow_run_artifacts,mcp__github__list_workflow_runs,mcp__github__list_workflows,mcp__github__search_code,mcp__github__search_issues,mcp__github__search_orgs,mcp__github__search_pull_requests,mcp__github__search_repositories,mcp__github__search_users" --debug --verbose --permission-mode bypassPermissions --output-format json --settings /tmp/.claude/settings.json "$(cat /tmp/aw-prompts/prompt.txt)" 2>&1 | tee /tmp/test-claude-with-missing-tool-safe-output-and-cache-memory.log env: ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} DISABLE_TELEMETRY: "1" diff --git a/pkg/console/console.go b/pkg/console/console.go index 1fa146f3fe..14816e6bce 100644 --- a/pkg/console/console.go +++ b/pkg/console/console.go @@ -225,8 +225,8 @@ func FormatWarningMessage(message string) string { var ( tableHeaderStyle = lipgloss.NewStyle(). Bold(true). - Foreground(lipgloss.Color("#BD93F9")). - Background(lipgloss.Color("#44475A")) + Foreground(lipgloss.Color("#FFFFFF")). + Background(lipgloss.Color("#34374A")) tableCellStyle = lipgloss.NewStyle(). Foreground(lipgloss.Color("#F8F8F2")) @@ -259,8 +259,7 @@ func RenderTable(config TableConfig) string { if config.Title != "" { titleStyle := lipgloss.NewStyle(). Bold(true). - Foreground(lipgloss.Color("#50FA7B")). - MarginBottom(1) + Foreground(lipgloss.Color("#50FA7B")) output.WriteString(applyStyle(titleStyle, config.Title)) output.WriteString("\n") } diff --git a/pkg/workflow/cache.go b/pkg/workflow/cache.go index 2c9bc20320..dc0d15d313 100644 --- a/pkg/workflow/cache.go +++ b/pkg/workflow/cache.go @@ -105,17 +105,22 @@ func generateCacheSteps(builder *strings.Builder, data *WorkflowData, verbose bo } // generateCacheMemorySteps generates cache steps for the cache-memory configuration +// Cache-memory provides a simple file share that LLMs can read/write freely func generateCacheMemorySteps(builder *strings.Builder, data *WorkflowData, verbose bool) { if data.CacheMemoryConfig == nil || !data.CacheMemoryConfig.Enabled { return } // Add comment indicating cache-memory configuration was processed - builder.WriteString(" # Cache memory MCP configuration from frontmatter processed below\n") + builder.WriteString(" # Cache memory file share configuration from frontmatter processed below\n") // Add step to create cache-memory directory builder.WriteString(" - name: Create cache-memory directory\n") - builder.WriteString(" run: mkdir -p /tmp/cache-memory\n") + builder.WriteString(" run: |\n") + builder.WriteString(" mkdir -p /tmp/cache-memory\n") + builder.WriteString(" echo \"Cache memory directory created at /tmp/cache-memory\"\n") + builder.WriteString(" echo \"This folder provides persistent file storage across workflow runs\"\n") + builder.WriteString(" echo \"LLMs and agentic tools can freely read and write files in this directory\"\n") // Use the parsed configuration cacheKey := data.CacheMemoryConfig.Key @@ -138,7 +143,7 @@ func generateCacheMemorySteps(builder *strings.Builder, data *WorkflowData, verb restoreKeys = append(restoreKeys, restoreKey) } - builder.WriteString(" - name: Cache memory MCP data\n") + builder.WriteString(" - name: Cache memory file share data\n") builder.WriteString(" uses: actions/cache@v4\n") builder.WriteString(" with:\n") fmt.Fprintf(builder, " key: %s\n", cacheKey) @@ -148,13 +153,14 @@ func generateCacheMemorySteps(builder *strings.Builder, data *WorkflowData, verb fmt.Fprintf(builder, " %s\n", key) } - // Add upload-artifact step if retention-days is configured + // Always add upload-artifact step for cache-memory (runs always) + builder.WriteString(" - name: Upload cache-memory data as artifact\n") + builder.WriteString(" uses: actions/upload-artifact@v4\n") + builder.WriteString(" with:\n") + builder.WriteString(" name: cache-memory\n") + builder.WriteString(" path: /tmp/cache-memory\n") + // Add retention-days if configured if data.CacheMemoryConfig.RetentionDays != nil { - builder.WriteString(" - name: Upload memory MCP data as artifact\n") - builder.WriteString(" uses: actions/upload-artifact@v4\n") - builder.WriteString(" with:\n") - builder.WriteString(" name: cache-memory-data\n") - builder.WriteString(" path: /tmp/cache-memory\n") fmt.Fprintf(builder, " retention-days: %d\n", *data.CacheMemoryConfig.RetentionDays) } } diff --git a/pkg/workflow/claude_engine.go b/pkg/workflow/claude_engine.go index 577f89dbf5..9356c8d6d5 100644 --- a/pkg/workflow/claude_engine.go +++ b/pkg/workflow/claude_engine.go @@ -448,11 +448,25 @@ func (e *ClaudeEngine) computeAllowedClaudeToolsString(tools map[string]any, saf // Skip the claude section as we've already processed it continue } else { - // Handle cache-memory as a special case first (can be boolean or map) + // Handle cache-memory as a special case - it provides file system access but no MCP tool if toolName == "cache-memory" { - // For cache-memory, it's configured as MCP server "memory" and has no allowed restrictions - // Default to wildcard access since cache-memory doesn't specify allowed tools - allowedTools = append(allowedTools, "mcp__memory") + // Cache-memory now provides simple file share access at /tmp/cache-memory/ + // Add path-specific Read and Write tools for the cache directory only + cacheDirPattern := "/tmp/cache-memory/*" + + // Add path-specific tools for cache directory access + if !slices.Contains(allowedTools, fmt.Sprintf("Read(%s)", cacheDirPattern)) { + allowedTools = append(allowedTools, fmt.Sprintf("Read(%s)", cacheDirPattern)) + } + if !slices.Contains(allowedTools, fmt.Sprintf("Write(%s)", cacheDirPattern)) { + allowedTools = append(allowedTools, fmt.Sprintf("Write(%s)", cacheDirPattern)) + } + if !slices.Contains(allowedTools, fmt.Sprintf("Edit(%s)", cacheDirPattern)) { + allowedTools = append(allowedTools, fmt.Sprintf("Edit(%s)", cacheDirPattern)) + } + if !slices.Contains(allowedTools, fmt.Sprintf("MultiEdit(%s)", cacheDirPattern)) { + allowedTools = append(allowedTools, fmt.Sprintf("MultiEdit(%s)", cacheDirPattern)) + } continue } @@ -652,23 +666,13 @@ func (e *ClaudeEngine) renderClaudeMCPConfig(yaml *strings.Builder, toolName str return nil } -// renderCacheMemoryMCPConfig generates the Memory MCP server configuration -// Uses npx-based @modelcontextprotocol/server-memory setup +// renderCacheMemoryMCPConfig handles cache-memory configuration without MCP server mounting +// Cache-memory is now a simple file share, not an MCP server func (e *ClaudeEngine) renderCacheMemoryMCPConfig(yaml *strings.Builder, isLast bool, workflowData *WorkflowData) { - yaml.WriteString(" \"memory\": {\n") - yaml.WriteString(" \"command\": \"npx\",\n") - yaml.WriteString(" \"args\": [\n") - yaml.WriteString(" \"@modelcontextprotocol/server-memory\"\n") - yaml.WriteString(" ],\n") - yaml.WriteString(" \"env\": {\n") - yaml.WriteString(" \"MEMORY_FILE_PATH\": \"/tmp/cache-memory/memory.json\"\n") - yaml.WriteString(" }\n") - - if isLast { - yaml.WriteString(" }\n") - } else { - yaml.WriteString(" },\n") - } + // Cache-memory no longer uses MCP server mounting + // The cache folder is available as a simple file share at /tmp/cache-memory/ + // The folder is created by the cache step and is accessible to all tools + // No MCP configuration is needed for simple file access } // renderSafeOutputsMCPConfig generates the Safe Outputs MCP server configuration diff --git a/pkg/workflow/claude_engine_tools_test.go b/pkg/workflow/claude_engine_tools_test.go index de422665c7..35f00adf1f 100644 --- a/pkg/workflow/claude_engine_tools_test.go +++ b/pkg/workflow/claude_engine_tools_test.go @@ -50,20 +50,20 @@ func TestClaudeEngineComputeAllowedTools(t *testing.T) { expected: "ExitPlanMode,Glob,Grep,LS,NotebookRead,Read,Task,TodoWrite,mcp__github__create_issue,mcp__github__list_issues", }, { - name: "cache-memory tool (should get wildcard access as mcp__memory)", + name: "cache-memory tool (provides file system access with path-specific cache tools)", tools: map[string]any{ "cache-memory": map[string]any{ "key": "test-memory-key", }, }, - expected: "ExitPlanMode,Glob,Grep,LS,NotebookRead,Read,Task,TodoWrite,mcp__memory", + expected: "Edit(/tmp/cache-memory/*),ExitPlanMode,Glob,Grep,LS,MultiEdit(/tmp/cache-memory/*),NotebookRead,Read,Read(/tmp/cache-memory/*),Task,TodoWrite,Write(/tmp/cache-memory/*)", }, { name: "cache-memory with boolean true", tools: map[string]any{ "cache-memory": true, }, - expected: "ExitPlanMode,Glob,Grep,LS,NotebookRead,Read,Task,TodoWrite,mcp__memory", + expected: "Edit(/tmp/cache-memory/*),ExitPlanMode,Glob,Grep,LS,MultiEdit(/tmp/cache-memory/*),NotebookRead,Read,Read(/tmp/cache-memory/*),Task,TodoWrite,Write(/tmp/cache-memory/*)", }, { name: "cache-memory with github tools", @@ -73,7 +73,7 @@ func TestClaudeEngineComputeAllowedTools(t *testing.T) { "allowed": []any{"get_repository"}, }, }, - expected: "ExitPlanMode,Glob,Grep,LS,NotebookRead,Read,Task,TodoWrite,mcp__github__get_repository,mcp__memory", + expected: "Edit(/tmp/cache-memory/*),ExitPlanMode,Glob,Grep,LS,MultiEdit(/tmp/cache-memory/*),NotebookRead,Read,Read(/tmp/cache-memory/*),Task,TodoWrite,Write(/tmp/cache-memory/*),mcp__github__get_repository", }, { name: "mixed neutral and mcp tools", diff --git a/pkg/workflow/compiler.go b/pkg/workflow/compiler.go index 62d28b23e8..5149d99cbc 100644 --- a/pkg/workflow/compiler.go +++ b/pkg/workflow/compiler.go @@ -156,7 +156,6 @@ type WorkflowData struct { type CacheMemoryConfig struct { Enabled bool `yaml:"enabled,omitempty"` // whether cache-memory is enabled Key string `yaml:"key,omitempty"` // custom cache key - DockerImage string `yaml:"docker-image,omitempty"` // deprecated: no longer used (npx is used instead) RetentionDays *int `yaml:"retention-days,omitempty"` // retention days for upload-artifact action } @@ -626,6 +625,12 @@ func (c *Compiler) parseWorkflowFile(markdownPath string) (*WorkflowData, error) return nil, fmt.Errorf("failed to extract workflow name: %w", err) } + // Check if frontmatter specifies a custom name and use it instead + frontmatterName := c.extractStringValue(result.Frontmatter, "name") + if frontmatterName != "" { + workflowName = frontmatterName + } + if c.verbose { fmt.Println(console.FormatInfoMessage(fmt.Sprintf("Extracted workflow name: '%s'", workflowName))) } @@ -636,7 +641,7 @@ func (c *Compiler) parseWorkflowFile(markdownPath string) (*WorkflowData, error) // Build workflow data workflowData := &WorkflowData{ Name: workflowName, - FrontmatterName: c.extractStringValue(result.Frontmatter, "name"), + FrontmatterName: frontmatterName, Tools: tools, MarkdownContent: markdownContent, AI: engineSetting, @@ -3528,6 +3533,29 @@ func (c *Compiler) generatePrompt(yaml *strings.Builder, data *WorkflowData) { yaml.WriteString(" " + line + "\n") } + // Add cache folder notification if cache-memory is enabled + if data.CacheMemoryConfig != nil && data.CacheMemoryConfig.Enabled { + yaml.WriteString(" \n") + yaml.WriteString(" ---\n") + yaml.WriteString(" \n") + yaml.WriteString(" ## Cache Folder Available\n") + yaml.WriteString(" \n") + yaml.WriteString(" You have access to a persistent cache folder at `/tmp/cache-memory/` where you can read and write files to create memories and store information.\n") + yaml.WriteString(" \n") + yaml.WriteString(" - **Read/Write Access**: You can freely read from and write to any files in this folder\n") + yaml.WriteString(" - **Persistence**: Files in this folder persist across workflow runs via GitHub Actions cache\n") + yaml.WriteString(" - **Last Write Wins**: If multiple processes write to the same file, the last write will be preserved\n") + yaml.WriteString(" - **File Share**: Use this as a simple file share - organize files as you see fit\n") + yaml.WriteString(" \n") + yaml.WriteString(" Examples of what you can store:\n") + yaml.WriteString(" - `/tmp/cache-memory/notes.txt` - general notes and observations\n") + yaml.WriteString(" - `/tmp/cache-memory/preferences.json` - user preferences and settings\n") + yaml.WriteString(" - `/tmp/cache-memory/history.log` - activity history and logs\n") + yaml.WriteString(" - `/tmp/cache-memory/state/` - organized state files in subdirectories\n") + yaml.WriteString(" \n") + yaml.WriteString(" Feel free to create, read, update, and organize files in this folder as needed for your tasks.\n") + } + if data.SafeOutputs != nil { // Add output instructions for all engines (GITHUB_AW_SAFE_OUTPUTS functionality) yaml.WriteString(" \n") @@ -3846,14 +3874,6 @@ func (c *Compiler) extractCacheMemoryConfig(tools map[string]any) *CacheMemoryCo } } - // Parse custom docker image (deprecated) - if dockerImage, exists := configMap["docker-image"]; exists { - if dockerImageStr, ok := dockerImage.(string); ok { - config.DockerImage = dockerImageStr - // Note: docker-image is deprecated and ignored when using npx - } - } - // Parse retention days if retentionDays, exists := configMap["retention-days"]; exists { if retentionDaysInt, ok := retentionDays.(int); ok { diff --git a/pkg/workflow/custom_engine.go b/pkg/workflow/custom_engine.go index 82bf621ef4..fd57c7bf95 100644 --- a/pkg/workflow/custom_engine.go +++ b/pkg/workflow/custom_engine.go @@ -244,32 +244,13 @@ func (e *CustomEngine) renderCustomMCPConfig(yaml *strings.Builder, toolName str // renderCacheMemoryMCPConfig generates the Memory MCP server configuration using shared logic // Uses Docker-based @modelcontextprotocol/server-memory setup +// renderCacheMemoryMCPConfig handles cache-memory configuration without MCP server mounting +// Cache-memory is now a simple file share, not an MCP server func (e *CustomEngine) renderCacheMemoryMCPConfig(yaml *strings.Builder, isLast bool, workflowData *WorkflowData) { - // Determine Docker image to use - dockerImage := "mcp/memory" // default from official documentation - if workflowData.CacheMemoryConfig != nil && workflowData.CacheMemoryConfig.DockerImage != "" { - dockerImage = workflowData.CacheMemoryConfig.DockerImage - } - - yaml.WriteString(" \"memory\": {\n") - yaml.WriteString(" \"command\": \"docker\",\n") - yaml.WriteString(" \"args\": [\n") - yaml.WriteString(" \"run\",\n") - yaml.WriteString(" \"-i\",\n") - yaml.WriteString(" \"--rm\",\n") - yaml.WriteString(" \"-v\",\n") - yaml.WriteString(" \"/tmp/cache-memory:/app/dist\",\n") - fmt.Fprintf(yaml, " \"%s\"\n", dockerImage) - yaml.WriteString(" ],\n") - yaml.WriteString(" \"env\": {\n") - yaml.WriteString(" \"MEMORY_FILE_PATH\": \"/app/dist/memory.json\"\n") - yaml.WriteString(" }\n") - - if isLast { - yaml.WriteString(" }\n") - } else { - yaml.WriteString(" },\n") - } + // Cache-memory no longer uses MCP server mounting + // The cache folder is available as a simple file share at /tmp/cache-memory/ + // The folder is created by the cache step and is accessible to all tools + // No MCP configuration is needed for simple file access } // renderSafeOutputsMCPConfig generates the Safe Outputs MCP server configuration