diff --git a/.gemini/agents/tier1-orchestrator.md b/.gemini/agents/tier1-orchestrator.md index 8aaad5c..acb50b6 100644 --- a/.gemini/agents/tier1-orchestrator.md +++ b/.gemini/agents/tier1-orchestrator.md @@ -5,17 +5,16 @@ model: gemini-3.1-pro-preview tools: - read_file - list_directory - - discovered_tool_search_files + - search_files - grep_search - - discovered_tool_get_file_summary - - discovered_tool_get_python_skeleton - - discovered_tool_get_code_outline - - discovered_tool_get_git_diff - - discovered_tool_web_search - - discovered_tool_fetch_url + - get_file_summary + - get_python_skeleton + - get_code_outline + - get_git_diff + - web_search + - fetch_url - activate_skill - - discovered_tool_run_powershell - - tier3-worker + - run_powershell --- STRICT SYSTEM DIRECTIVE: You are a Tier 1 Orchestrator. Focused on product alignment, high-level planning, and track initialization. diff --git a/.gemini/agents/tier2-tech-lead.md b/.gemini/agents/tier2-tech-lead.md index 9db2d3b..792a755 100644 --- a/.gemini/agents/tier2-tech-lead.md +++ b/.gemini/agents/tier2-tech-lead.md @@ -7,18 +7,16 @@ tools: - write_file - replace - list_directory - - discovered_tool_search_files + - search_files - grep_search - - discovered_tool_get_file_summary - - discovered_tool_get_python_skeleton - - discovered_tool_get_code_outline - - discovered_tool_get_git_diff - - discovered_tool_web_search - - discovered_tool_fetch_url + - get_file_summary + - get_python_skeleton + - get_code_outline + - get_git_diff + - web_search + - fetch_url - activate_skill - - discovered_tool_run_powershell - - tier3-worker - - tier4-qa + - run_powershell --- STRICT SYSTEM DIRECTIVE: You are a Tier 2 Tech Lead. Focused on architectural design and track execution. diff --git a/.gemini/agents/tier3-worker.md b/.gemini/agents/tier3-worker.md index 4889193..0bc2c11 100644 --- a/.gemini/agents/tier3-worker.md +++ b/.gemini/agents/tier3-worker.md @@ -7,19 +7,19 @@ tools: - write_file - replace - list_directory - - discovered_tool_search_files + - search_files - grep_search - - discovered_tool_get_file_summary - - discovered_tool_get_python_skeleton - - discovered_tool_get_code_outline - - discovered_tool_get_git_diff - - discovered_tool_web_search - - discovered_tool_fetch_url + - get_file_summary + - get_python_skeleton + - get_code_outline + - get_git_diff + - web_search + - fetch_url - activate_skill - - discovered_tool_run_powershell + - run_powershell --- STRICT SYSTEM DIRECTIVE: You are a stateless Tier 3 Worker (Contributor). Your goal is to implement specific code changes or tests based on the provided task. You have access to tools for reading and writing files, codebase investigation, and web tools. -You CAN execute PowerShell scripts or run shell commands via discovered_tool_run_powershell for verification and testing. +You CAN execute PowerShell scripts or run shell commands via run_powershell for verification and testing. Follow TDD and return success status or code changes. No pleasantries, no conversational filler. diff --git a/.gemini/agents/tier4-qa.md b/.gemini/agents/tier4-qa.md index fd16830..1c12d35 100644 --- a/.gemini/agents/tier4-qa.md +++ b/.gemini/agents/tier4-qa.md @@ -5,19 +5,19 @@ model: gemini-2.5-flash-lite tools: - read_file - list_directory - - discovered_tool_search_files + - search_files - grep_search - - discovered_tool_get_file_summary - - discovered_tool_get_python_skeleton - - discovered_tool_get_code_outline - - discovered_tool_get_git_diff - - discovered_tool_web_search - - discovered_tool_fetch_url + - get_file_summary + - get_python_skeleton + - get_code_outline + - get_git_diff + - web_search + - fetch_url - activate_skill - - discovered_tool_run_powershell + - run_powershell --- STRICT SYSTEM DIRECTIVE: You are a stateless Tier 4 QA Agent. Your goal is to analyze errors, summarize logs, or verify tests. You have access to tools for reading files, exploring the codebase, and web tools. -You CAN execute PowerShell scripts or run shell commands via discovered_tool_run_powershell for diagnostics. +You CAN execute PowerShell scripts or run shell commands via run_powershell for diagnostics. ONLY output the requested analysis. No pleasantries. diff --git a/.gemini/settings.json b/.gemini/settings.json index 13dbaf2..d532ab3 100644 --- a/.gemini/settings.json +++ b/.gemini/settings.json @@ -3,11 +3,11 @@ "enableAgents": true }, "tools": { - "discoveryCommand": "uv run python C:/projects/manual_slop/scripts/tool_discovery.py", - "callCommand": "uv run python C:/projects/manual_slop/scripts/tool_call.py", "whitelist": [ "*" - ] + ], + "discoveryCommand": "type .gemini\\tools.json", + "callCommand": "python scripts/tool_call.py" }, "hooks": { "BeforeTool": [ diff --git a/.gemini/tools.json b/.gemini/tools.json new file mode 100644 index 0000000..ec68e20 --- /dev/null +++ b/.gemini/tools.json @@ -0,0 +1,143 @@ +[ + { + "name": "fetch_url", + "description": "Fetch the full text content of a URL (stripped of HTML tags).", + "parameters": { + "type": "object", + "properties": { + "url": { + "type": "string", + "description": "The full URL to fetch." + } + }, + "required": [ + "url" + ] + } + }, + { + "name": "get_code_outline", + "description": "Get a hierarchical outline of a code file. This returns classes, functions, and methods with their line ranges and brief docstrings. Use this to quickly map out a file's structure before reading specific sections.", + "parameters": { + "type": "object", + "properties": { + "path": { + "type": "string", + "description": "Path to the code file (currently supports .py)." + } + }, + "required": [ + "path" + ] + } + }, + { + "name": "get_file_summary", + "description": "Get a compact heuristic summary of a file without reading its full content. For Python: imports, classes, methods, functions, constants. For TOML: table keys. For Markdown: headings. Others: line count + preview. Use this before read_file to decide if you need the full content.", + "parameters": { + "type": "object", + "properties": { + "path": { + "type": "string", + "description": "Absolute or relative path to the file to summarise." + } + }, + "required": [ + "path" + ] + } + }, + { + "name": "get_git_diff", + "description": "Returns the git diff for a file or directory. Use this to review changes efficiently without reading entire files.", + "parameters": { + "type": "object", + "properties": { + "path": { + "type": "string", + "description": "Path to the file or directory." + }, + "base_rev": { + "type": "string", + "description": "Base revision (e.g. 'HEAD', 'HEAD~1', or a commit hash). Defaults to 'HEAD'." + }, + "head_rev": { + "type": "string", + "description": "Head revision (optional)." + } + }, + "required": [ + "path" + ] + } + }, + { + "name": "get_python_skeleton", + "description": "Get a skeleton view of a Python file. This returns all classes and function signatures with their docstrings, but replaces function bodies with '...'. Use this to understand module interfaces without reading the full implementation.", + "parameters": { + "type": "object", + "properties": { + "path": { + "type": "string", + "description": "Path to the .py file." + } + }, + "required": [ + "path" + ] + } + }, + { + "name": "run_powershell", + "description": "Run a PowerShell script within the project base_dir. Use this to create, edit, rename, or delete files and directories. stdout and stderr are returned to you as the result.", + "parameters": { + "type": "object", + "properties": { + "script": { + "type": "string", + "description": "The PowerShell script to execute." + } + }, + "required": [ + "script" + ] + } + }, + { + "name": "search_files", + "description": "Search for files matching a glob pattern within an allowed directory. Supports recursive patterns like '**/*.py'. Use this to find files by extension or name pattern.", + "parameters": { + "type": "object", + "properties": { + "path": { + "type": "string", + "description": "Absolute path to the directory to search within." + }, + "pattern": { + "type": "string", + "description": "Glob pattern, e.g. '*.py', '**/*.toml', 'src/**/*.rs'." + } + }, + "required": [ + "path", + "pattern" + ] + } + }, + { + "name": "web_search", + "description": "Search the web using DuckDuckGo. Returns the top 5 search results with titles, URLs, and snippets.", + "parameters": { + "type": "object", + "properties": { + "query": { + "type": "string", + "description": "The search query." + } + }, + "required": [ + "query" + ] + } + } +] diff --git a/.gemini/tools/fetch_url.json b/.gemini/tools/fetch_url.json new file mode 100644 index 0000000..4e79edd --- /dev/null +++ b/.gemini/tools/fetch_url.json @@ -0,0 +1,17 @@ +{ + "name": "fetch_url", + "description": "Fetch the full text content of a URL (stripped of HTML tags).", + "parameters": { + "type": "object", + "properties": { + "url": { + "type": "string", + "description": "The full URL to fetch." + } + }, + "required": [ + "url" + ] + }, + "command": "python scripts/tool_call.py fetch_url" +} diff --git a/.gemini/tools/get_code_outline.json b/.gemini/tools/get_code_outline.json new file mode 100644 index 0000000..1bbe8ce --- /dev/null +++ b/.gemini/tools/get_code_outline.json @@ -0,0 +1,17 @@ +{ + "name": "get_code_outline", + "description": "Get a hierarchical outline of a code file. This returns classes, functions, and methods with their line ranges and brief docstrings. Use this to quickly map out a file's structure before reading specific sections.", + "parameters": { + "type": "object", + "properties": { + "path": { + "type": "string", + "description": "Path to the code file (currently supports .py)." + } + }, + "required": [ + "path" + ] + }, + "command": "python scripts/tool_call.py get_code_outline" +} diff --git a/.gemini/tools/get_file_summary.json b/.gemini/tools/get_file_summary.json new file mode 100644 index 0000000..bd1bd4c --- /dev/null +++ b/.gemini/tools/get_file_summary.json @@ -0,0 +1,17 @@ +{ + "name": "get_file_summary", + "description": "Get a compact heuristic summary of a file without reading its full content. For Python: imports, classes, methods, functions, constants. For TOML: table keys. For Markdown: headings. Others: line count + preview. Use this before read_file to decide if you need the full content.", + "parameters": { + "type": "object", + "properties": { + "path": { + "type": "string", + "description": "Absolute or relative path to the file to summarise." + } + }, + "required": [ + "path" + ] + }, + "command": "python scripts/tool_call.py get_file_summary" +} diff --git a/.gemini/tools/get_git_diff.json b/.gemini/tools/get_git_diff.json new file mode 100644 index 0000000..c9fa04c --- /dev/null +++ b/.gemini/tools/get_git_diff.json @@ -0,0 +1,25 @@ +{ + "name": "get_git_diff", + "description": "Returns the git diff for a file or directory. Use this to review changes efficiently without reading entire files.", + "parameters": { + "type": "object", + "properties": { + "path": { + "type": "string", + "description": "Path to the file or directory." + }, + "base_rev": { + "type": "string", + "description": "Base revision (e.g. 'HEAD', 'HEAD~1', or a commit hash). Defaults to 'HEAD'." + }, + "head_rev": { + "type": "string", + "description": "Head revision (optional)." + } + }, + "required": [ + "path" + ] + }, + "command": "python scripts/tool_call.py get_git_diff" +} diff --git a/.gemini/tools/get_python_skeleton.json b/.gemini/tools/get_python_skeleton.json new file mode 100644 index 0000000..ee1dd10 --- /dev/null +++ b/.gemini/tools/get_python_skeleton.json @@ -0,0 +1,17 @@ +{ + "name": "get_python_skeleton", + "description": "Get a skeleton view of a Python file. This returns all classes and function signatures with their docstrings, but replaces function bodies with '...'. Use this to understand module interfaces without reading the full implementation.", + "parameters": { + "type": "object", + "properties": { + "path": { + "type": "string", + "description": "Path to the .py file." + } + }, + "required": [ + "path" + ] + }, + "command": "python scripts/tool_call.py get_python_skeleton" +} diff --git a/.gemini/tools/run_powershell.json b/.gemini/tools/run_powershell.json new file mode 100644 index 0000000..8b6ea96 --- /dev/null +++ b/.gemini/tools/run_powershell.json @@ -0,0 +1,17 @@ +{ + "name": "run_powershell", + "description": "Run a PowerShell script within the project base_dir. Use this to create, edit, rename, or delete files and directories. stdout and stderr are returned to you as the result.", + "parameters": { + "type": "object", + "properties": { + "script": { + "type": "string", + "description": "The PowerShell script to execute." + } + }, + "required": [ + "script" + ] + }, + "command": "python scripts/tool_call.py run_powershell" +} diff --git a/.gemini/tools/search_files.json b/.gemini/tools/search_files.json new file mode 100644 index 0000000..b1ac469 --- /dev/null +++ b/.gemini/tools/search_files.json @@ -0,0 +1,22 @@ +{ + "name": "search_files", + "description": "Search for files matching a glob pattern within an allowed directory. Supports recursive patterns like '**/*.py'. Use this to find files by extension or name pattern.", + "parameters": { + "type": "object", + "properties": { + "path": { + "type": "string", + "description": "Absolute path to the directory to search within." + }, + "pattern": { + "type": "string", + "description": "Glob pattern, e.g. '*.py', '**/*.toml', 'src/**/*.rs'." + } + }, + "required": [ + "path", + "pattern" + ] + }, + "command": "python scripts/tool_call.py search_files" +} diff --git a/.gemini/tools/web_search.json b/.gemini/tools/web_search.json new file mode 100644 index 0000000..f554d27 --- /dev/null +++ b/.gemini/tools/web_search.json @@ -0,0 +1,17 @@ +{ + "name": "web_search", + "description": "Search the web using DuckDuckGo. Returns the top 5 search results with titles, URLs, and snippets.", + "parameters": { + "type": "object", + "properties": { + "query": { + "type": "string", + "description": "The search query." + } + }, + "required": [ + "query" + ] + }, + "command": "python scripts/tool_call.py web_search" +} diff --git a/conductor/tracks/tiered_context_scoping_hitl_approval/plan.md b/conductor/tracks/tiered_context_scoping_hitl_approval/plan.md index 3223b8b..78e6229 100644 --- a/conductor/tracks/tiered_context_scoping_hitl_approval/plan.md +++ b/conductor/tracks/tiered_context_scoping_hitl_approval/plan.md @@ -1,7 +1,7 @@ # Implementation Plan: Tiered Context Scoping & HITL Approval ## Phase 1: Context Subsetting -- [ ] Task: Refactor `aggregate.py` to support targeted context builds (e.g., `build_tier1_context`, `build_tier3_context`). +- [~] Task: Refactor `aggregate.py` to support targeted context builds (e.g., `build_tier1_context`, `build_tier3_context`). - [ ] Task: Integrate AST skeleton extraction into the standard Tier 3 context build. - [ ] Task: Update the project state to track which files are assigned to which tier. diff --git a/project_manager.py b/project_manager.py index 0618c3f..05d3841 100644 --- a/project_manager.py +++ b/project_manager.py @@ -98,7 +98,7 @@ def default_project(name: str = "unnamed") -> dict: return { "project": {"name": name, "git_dir": "", "system_prompt": "", "main_context": ""}, "output": {"output_dir": "./md_gen"}, - "files": {"base_dir": ".", "paths": []}, + "files": {"base_dir": ".", "paths": [], "tier_assignments": {}}, "screenshots": {"base_dir": ".", "paths": []}, "gemini_cli": {"binary_path": "gemini"}, "deepseek": {"reasoning_effort": "medium"}, diff --git a/scripts/mma_exec.py b/scripts/mma_exec.py index 0ca0af0..897b759 100644 --- a/scripts/mma_exec.py +++ b/scripts/mma_exec.py @@ -177,16 +177,16 @@ def execute_agent(role: str, prompt: str, docs: list[str]) -> str: system_directive = "STRICT SYSTEM DIRECTIVE: You are a stateless Tier 3 Worker (Contributor). " \ "Your goal is to implement specific code changes or tests based on the provided task. " \ "You have access to tools for reading and writing files (e.g., read_file, write_file, replace), " \ - "codebase investigation (discovered_tool_get_code_outline, discovered_tool_get_python_skeleton), " \ - "version control (discovered_tool_get_git_diff), and web tools (discovered_tool_web_search, discovered_tool_fetch_url). " \ - "You CAN execute PowerShell scripts via discovered_tool_run_powershell for verification and testing. " \ + "codebase investigation (get_code_outline, get_python_skeleton), " \ + "version control (get_git_diff), and web tools (web_search, fetch_url). " \ + "You CAN execute PowerShell scripts via run_powershell for verification and testing. " \ "Follow TDD and return success status or code changes. No pleasantries, no conversational filler." elif role in ['tier4', 'tier4-qa']: system_directive = "STRICT SYSTEM DIRECTIVE: You are a stateless Tier 4 QA Agent. " \ "Your goal is to analyze errors, summarize logs, or verify tests. " \ - "You have access to tools for reading files, exploring the codebase (discovered_tool_get_code_outline, discovered_tool_get_python_skeleton), " \ - "version control (discovered_tool_get_git_diff), and web tools (discovered_tool_web_search, discovered_tool_fetch_url). " \ - "You CAN execute PowerShell scripts via discovered_tool_run_powershell for diagnostics. " \ + "You have access to tools for reading files, exploring the codebase (get_code_outline, get_python_skeleton), " \ + "version control (get_git_diff), and web tools (web_search, fetch_url). " \ + "You CAN execute PowerShell scripts via run_powershell for diagnostics. " \ "ONLY output the requested analysis. No pleasantries." else: system_directive = f"STRICT SYSTEM DIRECTIVE: You are a stateless {role}. " \ @@ -209,8 +209,7 @@ def execute_agent(role: str, prompt: str, docs: list[str]) -> str: # Use subprocess with input to pipe the prompt via stdin, avoiding WinError 206. # We use -p 'mma_task' to ensure non-interactive (headless) mode and valid parsing. # Whitelist tools to ensure they are available to the model in headless mode. - # Using 'discovered_tool_*' names as they are provided by tool_discovery.py - allowed_tools = "read_file,write_file,replace,list_directory,glob,grep_search,discovered_tool_search_files,discovered_tool_get_file_summary,discovered_tool_get_python_skeleton,discovered_tool_get_code_outline,discovered_tool_get_git_diff,discovered_tool_run_powershell,activate_skill,codebase_investigator,discovered_tool_web_search,discovered_tool_fetch_url" + allowed_tools = "read_file,write_file,replace,list_directory,glob,grep_search,search_files,get_file_summary,get_python_skeleton,get_code_outline,get_git_diff,run_powershell,activate_skill,codebase_investigator,web_search,fetch_url" ps_command = ( f"if (Test-Path 'C:\\projects\\misc\\setup_gemini.ps1') {{ . 'C:\\projects\\misc\\setup_gemini.ps1' }}; " f"gemini -p 'mma_task' --allowed-tools {allowed_tools} --output-format json --model {model}" diff --git a/scripts/tool_call.py b/scripts/tool_call.py index bc5d16c..6f155bd 100644 --- a/scripts/tool_call.py +++ b/scripts/tool_call.py @@ -7,8 +7,9 @@ sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))) try: import mcp_client + import shell_runner except ImportError: - print(json.dumps({"error": "Failed to import mcp_client"})) + print(json.dumps({"error": "Failed to import required modules"})) sys.exit(1) def main(): @@ -30,14 +31,15 @@ def main(): sys.exit(1) try: - # Note: mcp_client.configure() is usually called by the GUI before each session, - # but for direct CLI calls, we might need a basic configuration. - # However, mcp_client tools generally resolve paths relative to CWD if not configured. - result = mcp_client.dispatch(tool_name, tool_input) + if tool_name == "run_powershell": + script = tool_input.get("script", "") + # We use the current directory as base_dir for CLI calls + result = shell_runner.run_powershell(script, os.getcwd()) + else: + # mcp_client tools generally resolve paths relative to CWD if not configured. + result = mcp_client.dispatch(tool_name, tool_input) - # We wrap the result in a JSON object for consistency if needed, - # but the CLI often expects just the string result from stdout. - # Actually, let's just print the raw result string as that's what mcp_client returns. + # We print the raw result string as that's what gemini-cli expects. print(result) except Exception as e: print(f"ERROR executing tool {tool_name}: {e}") diff --git a/scripts/tool_discovery.py b/scripts/tool_discovery.py deleted file mode 100644 index a5316c6..0000000 --- a/scripts/tool_discovery.py +++ /dev/null @@ -1,42 +0,0 @@ -import json -import sys -import os - -# Add project root to sys.path -sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))) - -try: - import mcp_client -except ImportError: - print("[]") - sys.exit(0) - -def main(): - specs = list(mcp_client.MCP_TOOL_SPECS) - - # Add run_powershell (manually define to match ai_client.py) - specs.append({ - "name": "run_powershell", - "description": ( - "Run a PowerShell script within the project base_dir. " - "Use this to create, edit, rename, or delete files and directories. " - "The working directory is set to base_dir automatically. " - "stdout and stderr are returned to you as the result." - ), - "parameters": { - "type": "object", - "properties": { - "script": { - "type": "string", - "description": "The PowerShell script to execute." - } - }, - "required": ["script"] - } - }) - - # Output as JSON array of FunctionDeclarations - print(json.dumps(specs, indent=2)) - -if __name__ == "__main__": - main()