{"openapi":"3.0.3","info":{"title":"Ninja AI Agent REST API","description":"Distributed REST API exposing all ninja tools","version":"0.1.0"},"servers":[{"url":"http://localhost:13370"}],"paths":{"/api/tools/source_symbols":{"post":{"summary":"Extract symbols (functions, classes, variables, types, etc.) from source code files using AI analysis. Accepts multiple files and returns structured symbol information for each.","operationId":"source_symbols","parameters":[{"name":"X-Ninja-User","in":"header","required":false,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"filenames":{"type":"array","description":"Array of file paths to analyze.","items":{"type":"string"}}},"required":["filenames"]}}}},"responses":{"200":{"description":"Tool execution result","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"object"},"ninja_user":{"type":"string"},"timestamp":{"type":"integer"}}}}}}}}},"/api/tools/xdg_open":{"post":{"summary":"Open a file or directory using the system default application (e.g., PDF viewer, image viewer, file manager).","operationId":"xdg_open","parameters":[{"name":"X-Ninja-User","in":"header","required":false,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"path":{"type":"string","description":"Path to the file or directory to open."}},"required":["path"]}}}},"responses":{"200":{"description":"Tool execution result","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"object"},"ninja_user":{"type":"string"},"timestamp":{"type":"integer"}}}}}}}}},"/api/tools/list_directory":{"post":{"summary":"List contents of a directory with optional pattern filtering.","operationId":"list_directory","parameters":[{"name":"X-Ninja-User","in":"header","required":false,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"path":{"type":"string","description":"The directory path to list (default: current directory)."},"pattern":{"type":"string","description":"Filter pattern (default: *)."}}}}}},"responses":{"200":{"description":"Tool execution result","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"object"},"ninja_user":{"type":"string"},"timestamp":{"type":"integer"}}}}}}}}},"/api/tools/fetch_url":{"post":{"summary":"Fetch the content of a URL as text. Useful for reading web pages, API responses, documentation, and other text content. HTML tags are stripped by default.","operationId":"fetch_url","parameters":[{"name":"X-Ninja-User","in":"header","required":false,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","description":"The URL to fetch content from."},"strip_html":{"type":"boolean","description":"Strip HTML tags from response. Default: true."}},"required":["url"]}}}},"responses":{"200":{"description":"Tool execution result","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"object"},"ninja_user":{"type":"string"},"timestamp":{"type":"integer"}}}}}}}}},"/api/tools/service_manage":{"post":{"summary":"Manage persistent services (tunnels and commands). Actions: create, start, stop, restart, delete, list, status, logs, update.","operationId":"service_manage","parameters":[{"name":"X-Ninja-User","in":"header","required":false,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"action":{"type":"string","description":"Action to perform: create, start, stop, restart, delete, list, status, logs, update"},"name":{"type":"string","description":"Service name (required for all actions except list)"},"ninja_user":{"type":"string","description":"Ninja user owning the service"},"service_type":{"type":"string","description":"Service type: tunnel or command (required for create)"},"subdomain":{"type":"string","description":"Subdomain for tunnel services"},"local_port":{"type":"integer","description":"Local port for tunnel services"},"command":{"type":"string","description":"Shell command for command services"},"working_directory":{"type":"string","description":"Working directory for command services"},"config":{"type":"object","description":"Full config JSON (alternative to individual fields)"},"auto_start":{"type":"boolean","description":"Auto-start on boot"},"auto_restart":{"type":"boolean","description":"Auto-restart on crash"},"retry_limit":{"type":"integer","description":"Max restart retries"},"restart_delay_ms":{"type":"integer","description":"Delay between retries in ms"},"limit":{"type":"integer","description":"Log entry limit for logs action"},"environment":{"type":"object","description":"Environment variables for command services"},"basic_auth_user":{"type":"string","description":"Basic auth username for tunnel"},"basic_auth_pass":{"type":"string","description":"Basic auth password for tunnel"}},"required":["action"]}}}},"responses":{"200":{"description":"Tool execution result","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"object"},"ninja_user":{"type":"string"},"timestamp":{"type":"integer"}}}}}}}}},"/api/tools/cloud_share":{"post":{"summary":"Share a local file or directory via Ninja Cloud with a public URL. Creates a static share accessible at static.ninja.molodetz.nl/{slug}. Only use when user explicitly mentions sharing via ninja cloud.","operationId":"cloud_share","parameters":[{"name":"X-Ninja-User","in":"header","required":false,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"path":{"type":"string","description":"Path to local file or directory to share"},"slug":{"type":"string","description":"Custom URL slug (auto-generated if omitted)"},"username":{"type":"string","description":"Basic auth username for password protection"},"password":{"type":"string","description":"Basic auth password for password protection"},"expires_in":{"type":"integer","description":"Expiration time in seconds from now (0 = never)"}},"required":["path"]}}}},"responses":{"200":{"description":"Tool execution result","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"object"},"ninja_user":{"type":"string"},"timestamp":{"type":"integer"}}}}}}}}},"/api/tools/cloud_storage":{"post":{"summary":"Show Ninja Cloud storage usage summary. Only use when user asks about their cloud storage.","operationId":"cloud_storage","parameters":[{"name":"X-Ninja-User","in":"header","required":false,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{}}}}},"responses":{"200":{"description":"Tool execution result","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"object"},"ninja_user":{"type":"string"},"timestamp":{"type":"integer"}}}}}}}}},"/api/tools/websearch":{"post":{"summary":"Search the web for current information. Use this for news, documentation, technology questions, or anything where up-to-date information matters.","operationId":"websearch","parameters":[{"name":"X-Ninja-User","in":"header","required":false,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"query":{"type":"string","description":"The search query string."}},"required":["query"]}}}},"responses":{"200":{"description":"Tool execution result","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"object"},"ninja_user":{"type":"string"},"timestamp":{"type":"integer"}}}}}}}}},"/api/tools/download_file":{"post":{"summary":"Download a file from a URL and save it to disk. Use this for binary files like images, archives, or any file that needs to be saved locally.","operationId":"download_file","parameters":[{"name":"X-Ninja-User","in":"header","required":false,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","description":"The URL to download from."},"path":{"type":"string","description":"The file path to save the downloaded file to."}},"required":["url","path"]}}}},"responses":{"200":{"description":"Tool execution result","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"object"},"ninja_user":{"type":"string"},"timestamp":{"type":"integer"}}}}}}}}},"/api/tools/search_files":{"post":{"summary":"Search for files containing a specific pattern.","operationId":"search_files","parameters":[{"name":"X-Ninja-User","in":"header","required":false,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"pattern":{"type":"string","description":"The text pattern to search for."},"directory":{"type":"string","description":"The directory to search (default: current)."}},"required":["pattern"]}}}},"responses":{"200":{"description":"Tool execution result","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"object"},"ninja_user":{"type":"string"},"timestamp":{"type":"integer"}}}}}}}}},"/api/tools/execute_python":{"post":{"summary":"Execute Python code and return the output.","operationId":"execute_python","parameters":[{"name":"X-Ninja-User","in":"header","required":false,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","description":"The Python code to execute."}},"required":["code"]}}}},"responses":{"200":{"description":"Tool execution result","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"object"},"ninja_user":{"type":"string"},"timestamp":{"type":"integer"}}}}}}}}},"/api/tools/prompt":{"post":{"summary":"Send a task to an AI sub-conversation in a fresh context window. Useful for content processing, summarization, translation, or any task that benefits from a clean context. No tool access in sub-conversation.","operationId":"prompt","parameters":[{"name":"X-Ninja-User","in":"header","required":false,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"task":{"type":"string","description":"The task for the AI to complete."},"context":{"type":"string","description":"Additional context or data to include with the task."}},"required":["task"]}}}},"responses":{"200":{"description":"Tool execution result","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"object"},"ninja_user":{"type":"string"},"timestamp":{"type":"integer"}}}}}}}}},"/api/tools/upsert_tool":{"post":{"summary":"Create or update a custom tool. Supports two types: 'script' (generates and executes Python/Bash scripts) and 'prompt' (AI-powered, sends system prompt to AI). Script tools are auto-generated, syntax-verified, and persisted. Prompt tools delegate to AI on invocation.","operationId":"upsert_tool","parameters":[{"name":"X-Ninja-User","in":"header","required":false,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","description":"Unique tool name (lowercase, underscores). Must not conflict with built-in tools."},"description":{"type":"string","description":"What the tool does. Shown in tool listings."},"type":{"type":"string","enum":["prompt","script"],"description":"Tool type: 'script' for executable Python/Bash tools, 'prompt' for AI-powered tools. Default: prompt."},"language":{"type":"string","enum":["python","bash"],"description":"Script language. Only used when type=script. Default: python."},"prompt":{"type":"string","description":"System prompt defining the tool's behavior. Required for type=prompt."},"script_description":{"type":"string","description":"Detailed description of what the script should do. Used for AI-powered script generation when type=script. Falls back to description if omitted."},"parameters":{"type":"object","description":"JSON schema for tool parameters. Optional."},"return_description":{"type":"string","description":"Description of what the tool returns. Optional."}},"required":["name","description"]}}}},"responses":{"200":{"description":"Tool execution result","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"object"},"ninja_user":{"type":"string"},"timestamp":{"type":"integer"}}}}}}}}},"/api/tools/generate_document":{"post":{"summary":"Generate a well-formatted document using AI. Supports markdown, html, json, yaml, xml, csv, and other text formats. Optionally saves to disk.","operationId":"generate_document","parameters":[{"name":"X-Ninja-User","in":"header","required":false,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"content_type":{"type":"string","description":"Document format: markdown, html, json, yaml, xml, csv, etc."},"content":{"type":"string","description":"Description of what the document should contain."},"filename":{"type":"string","description":"File path to save the document. If omitted, content is returned directly."}},"required":["content_type","content"]}}}},"responses":{"200":{"description":"Tool execution result","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"object"},"ninja_user":{"type":"string"},"timestamp":{"type":"integer"}}}}}}}}},"/api/tools/orchestrate":{"post":{"summary":"Execute multiple tool calls in sequence with progress tracking and timeout. Use for batch operations that require running several tools. Each task specifies a tool name and its arguments.","operationId":"orchestrate","parameters":[{"name":"X-Ninja-User","in":"header","required":false,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"tasks":{"type":"array","description":"Array of {tool, args} objects to execute.","items":{"type":"object"}},"timeout_seconds":{"type":"integer","description":"Hard timeout for all tasks combined. Default: 300."}},"required":["tasks"]}}}},"responses":{"200":{"description":"Tool execution result","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"object"},"ninja_user":{"type":"string"},"timestamp":{"type":"integer"}}}}}}}}},"/api/tools/delete_file":{"post":{"summary":"Delete a file at the given path.","operationId":"delete_file","parameters":[{"name":"X-Ninja-User","in":"header","required":false,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"path":{"type":"string","description":"The file path to delete."}},"required":["path"]}}}},"responses":{"200":{"description":"Tool execution result","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"object"},"ninja_user":{"type":"string"},"timestamp":{"type":"integer"}}}}}}}}},"/api/tools/set_ninja_user":{"post":{"summary":"Set the ninja user identity for this instance","operationId":"set_ninja_user","parameters":[{"name":"X-Ninja-User","in":"header","required":false,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"username":{"type":"string","description":"Username (alphanumeric, underscore, hyphen, max 64 chars)","maxLength":64}},"required":["username"]}}}},"responses":{"200":{"description":"Tool execution result","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"object"},"ninja_user":{"type":"string"},"timestamp":{"type":"integer"}}}}}}}}},"/api/tools/git_status":{"post":{"summary":"Show the working tree status (read-only git operation).","operationId":"git_status","parameters":[{"name":"X-Ninja-User","in":"header","required":false,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"directory":{"type":"string","description":"The git repository directory (default: current)."}}}}}},"responses":{"200":{"description":"Tool execution result","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"object"},"ninja_user":{"type":"string"},"timestamp":{"type":"integer"}}}}}}}}},"/api/tools/delete_tool":{"post":{"summary":"Delete a custom tool. Asks for user confirmation before deleting. Removes both the JSON definition and any associated script file.","operationId":"delete_tool","parameters":[{"name":"X-Ninja-User","in":"header","required":false,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","description":"Name of the custom tool to delete."}},"required":["name"]}}}},"responses":{"200":{"description":"Tool execution result","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"object"},"ninja_user":{"type":"string"},"timestamp":{"type":"integer"}}}}}}}}},"/api/tools/port_info":{"post":{"summary":"Get information about what process is using a given network port.","operationId":"port_info","parameters":[{"name":"X-Ninja-User","in":"header","required":false,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"port":{"type":"integer","description":"The port number to check (1-65535)."}},"required":["port"]}}}},"responses":{"200":{"description":"Tool execution result","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"object"},"ninja_user":{"type":"string"},"timestamp":{"type":"integer"}}}}}}}}},"/api/tools/cloud_upload":{"post":{"summary":"Upload a local directory or file to Ninja Cloud. Creates a versioned, git-backed cloud resource. Only use when user explicitly mentions 'ninja cloud' or cloud context.","operationId":"cloud_upload","parameters":[{"name":"X-Ninja-User","in":"header","required":false,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"path":{"type":"string","description":"Path to local directory or file to upload"},"name":{"type":"string","description":"Name for the cloud resource (defaults to directory name)"},"type":{"type":"string","description":"Resource type: project, backup, or static (default: project)"}},"required":["path"]}}}},"responses":{"200":{"description":"Tool execution result","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"object"},"ninja_user":{"type":"string"},"timestamp":{"type":"integer"}}}}}}}}},"/api/tools/describe_image":{"post":{"summary":"Analyze an image and return structured JSON with description, objects, colors, text content, and confidence. Supports file paths and URLs.","operationId":"describe_image","parameters":[{"name":"X-Ninja-User","in":"header","required":false,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"image":{"type":"string","description":"File path or URL of the image to analyze"},"prompt":{"type":"string","description":"What to extract or describe from the image"}},"required":["image","prompt"]}}}},"responses":{"200":{"description":"Tool execution result","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"object"},"ninja_user":{"type":"string"},"timestamp":{"type":"integer"}}}}}}}}},"/api/tools/execute_plan":{"post":{"summary":"Execute a validated plan tree with dependency ordering, progress tracking, timeouts, and error isolation. Failed tasks do not crash the plan; dependents are skipped.","operationId":"execute_plan","parameters":[{"name":"X-Ninja-User","in":"header","required":false,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"plan":{"type":"string","description":"The JSON plan string from create_plan."}},"required":["plan"]}}}},"responses":{"200":{"description":"Tool execution result","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"object"},"ninja_user":{"type":"string"},"timestamp":{"type":"integer"}}}}}}}}},"/api/tools/ask_user":{"post":{"summary":"Ask the user a question and wait for their response. Use only for critical clarifications where you cannot proceed without user input. Always provide a sensible default_value.","operationId":"ask_user","parameters":[{"name":"X-Ninja-User","in":"header","required":false,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"question":{"type":"string","description":"The question to ask the user."},"default_value":{"type":"string","description":"Default answer if user presses Enter without typing."},"timeout_seconds":{"type":"integer","description":"Timeout in seconds. Default: 60."}},"required":["question"]}}}},"responses":{"200":{"description":"Tool execution result","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"object"},"ninja_user":{"type":"string"},"timestamp":{"type":"integer"}}}}}}}}},"/api/tools/repair_file":{"post":{"summary":"Repair a file by fixing format errors using AI. Overwrites the file with corrected content and validates the result.","operationId":"repair_file","parameters":[{"name":"X-Ninja-User","in":"header","required":false,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"filename":{"type":"string","description":"Path to the file to repair."},"content_type":{"type":"string","description":"Expected format: json, yaml, xml, html, markdown, csv, toml, ini, etc."}},"required":["filename","content_type"]}}}},"responses":{"200":{"description":"Tool execution result","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"object"},"ninja_user":{"type":"string"},"timestamp":{"type":"integer"}}}}}}}}},"/api/tools/create_plan":{"post":{"summary":"Recursively decompose a complex objective into a validated, dependency-aware task tree with AI validation. Returns structured JSON plan. Use for deep, multi-step tasks with inter-task dependencies.","operationId":"create_plan","parameters":[{"name":"X-Ninja-User","in":"header","required":false,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"objective":{"type":"string","description":"The complex objective to decompose into a task tree."},"context":{"type":"string","description":"Additional context, constraints, or requirements for planning."},"execute":{"type":"boolean","description":"If true, immediately execute the plan after creation. Default: false."}},"required":["objective"]}}}},"responses":{"200":{"description":"Tool execution result","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"object"},"ninja_user":{"type":"string"},"timestamp":{"type":"integer"}}}}}}}}},"/api/tools/git_log":{"post":{"summary":"Show commit logs (read-only git operation).","operationId":"git_log","parameters":[{"name":"X-Ninja-User","in":"header","required":false,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"directory":{"type":"string","description":"The git repository directory (default: current)."},"max_count":{"type":"integer","description":"Maximum number of commits to show (default: 10)."}}}}}},"responses":{"200":{"description":"Tool execution result","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"object"},"ninja_user":{"type":"string"},"timestamp":{"type":"integer"}}}}}}}}},"/api/tools/plan":{"post":{"summary":"Decompose a complex task into a structured sequence of subtasks using AI. Returns a JSON plan with tool calls, dependencies, and execution order. Use this before orchestrate for complex multi-step tasks.","operationId":"plan","parameters":[{"name":"X-Ninja-User","in":"header","required":false,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"task_description":{"type":"string","description":"Detailed description of the task to decompose into subtasks."}},"required":["task_description"]}}}},"responses":{"200":{"description":"Tool execution result","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"object"},"ninja_user":{"type":"string"},"timestamp":{"type":"integer"}}}}}}}}},"/api/tools/validate_plan_results":{"post":{"summary":"Verify each task's output against its validation criteria using AI. Returns only failures with recommendations.","operationId":"validate_plan_results","parameters":[{"name":"X-Ninja-User","in":"header","required":false,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"plan":{"type":"string","description":"The original plan JSON string."},"results":{"type":"string","description":"The execution results JSON string from execute_plan."}},"required":["plan","results"]}}}},"responses":{"200":{"description":"Tool execution result","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"object"},"ninja_user":{"type":"string"},"timestamp":{"type":"integer"}}}}}}}}},"/api/tools/cloud_list":{"post":{"summary":"List cloud resources (projects, backups, static files) stored in Ninja Cloud. Only use when user asks about their cloud resources.","operationId":"cloud_list","parameters":[{"name":"X-Ninja-User","in":"header","required":false,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string","description":"Filter by type: project, backup, or static (all types if omitted)"}}}}}},"responses":{"200":{"description":"Tool execution result","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"object"},"ninja_user":{"type":"string"},"timestamp":{"type":"integer"}}}}}}}}},"/api/tools/ask_user_form":{"post":{"summary":"Present a structured form to the user with multiple fields. Use for collecting multiple inputs at once. Field types: text, select, multiselect, confirm, number.","operationId":"ask_user_form","parameters":[{"name":"X-Ninja-User","in":"header","required":false,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"fields":{"type":"array","description":"Array of field specs. Each field: {name, field_type, label, description, required, default, options (for select/multiselect), min/max/step (for number)}.","items":{"type":"object","properties":{"name":{"type":"string"},"field_type":{"type":"string","enum":["text","select","multiselect","confirm","number"]},"label":{"type":"string"},"description":{"type":"string"},"required":{"type":"boolean"},"default":{},"options":{"type":"array","items":{"type":"string"}},"min":{"type":"number"},"max":{"type":"number"},"step":{"type":"number"}}}},"title":{"type":"string","description":"Form title."},"description":{"type":"string","description":"Form description text."}},"required":["fields"]}}}},"responses":{"200":{"description":"Tool execution result","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"object"},"ninja_user":{"type":"string"},"timestamp":{"type":"integer"}}}}}}}}},"/api/tools/folder_stats":{"post":{"summary":"Analyze a directory and return comprehensive statistics: per-language lines of code, file categories (source, images, videos, executables, misc), project type detection, size breakdowns in human-readable and byte formats, modification dates, and path information. Skips dependency directories (node_modules, .venv, vendor, target, etc.) and only counts LOC for files under 200KB.","operationId":"folder_stats","parameters":[{"name":"X-Ninja-User","in":"header","required":false,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"path":{"type":"string","description":"The directory path to analyze (default: working directory)."}}}}}},"responses":{"200":{"description":"Tool execution result","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"object"},"ninja_user":{"type":"string"},"timestamp":{"type":"integer"}}}}}}}}},"/api/tools/write_file":{"post":{"summary":"Write content to a file at the given path, overwriting if exists.","operationId":"write_file","parameters":[{"name":"X-Ninja-User","in":"header","required":false,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"path":{"type":"string","description":"The file path to write."},"content":{"type":"string","description":"The content to write."}},"required":["path","content"]}}}},"responses":{"200":{"description":"Tool execution result","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"object"},"ninja_user":{"type":"string"},"timestamp":{"type":"integer"}}}}}}}}},"/api/tools/commit_message":{"post":{"summary":"Generate an AI-powered git commit message from the current diff in a directory.","operationId":"commit_message","parameters":[{"name":"X-Ninja-User","in":"header","required":false,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"directory":{"type":"string","description":"Git repository directory (defaults to working directory)"}}}}}},"responses":{"200":{"description":"Tool execution result","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"object"},"ninja_user":{"type":"string"},"timestamp":{"type":"integer"}}}}}}}}},"/api/tools/validate_file":{"post":{"summary":"Validate a file against its expected format using AI analysis. Returns validity status with errors and warnings.","operationId":"validate_file","parameters":[{"name":"X-Ninja-User","in":"header","required":false,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"filename":{"type":"string","description":"Path to the file to validate."},"content_type":{"type":"string","description":"Expected format: json, yaml, xml, html, markdown, csv, toml, ini, etc."}},"required":["filename","content_type"]}}}},"responses":{"200":{"description":"Tool execution result","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"object"},"ninja_user":{"type":"string"},"timestamp":{"type":"integer"}}}}}}}}},"/api/tools/read_file":{"post":{"summary":"Read the content of a file at the given path.","operationId":"read_file","parameters":[{"name":"X-Ninja-User","in":"header","required":false,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"path":{"type":"string","description":"The file path to read."}},"required":["path"]}}}},"responses":{"200":{"description":"Tool execution result","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"object"},"ninja_user":{"type":"string"},"timestamp":{"type":"integer"}}}}}}}}},"/api/tools/port_kill":{"post":{"summary":"Kill the process occupying a given network port. Sends SIGTERM first, then SIGKILL if needed.","operationId":"port_kill","parameters":[{"name":"X-Ninja-User","in":"header","required":false,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"port":{"type":"integer","description":"The port number whose process to kill (1-65535)."}},"required":["port"]}}}},"responses":{"200":{"description":"Tool execution result","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"object"},"ninja_user":{"type":"string"},"timestamp":{"type":"integer"}}}}}}}}},"/api/tools/execute_shell":{"post":{"summary":"Execute a shell command and return the output.","operationId":"execute_shell","parameters":[{"name":"X-Ninja-User","in":"header","required":false,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"command":{"type":"string","description":"The shell command to execute."}},"required":["command"]}}}},"responses":{"200":{"description":"Tool execution result","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"object"},"ninja_user":{"type":"string"},"timestamp":{"type":"integer"}}}}}}}}},"/api/tools/git_diff":{"post":{"summary":"Show changes between commits (read-only git operation).","operationId":"git_diff","parameters":[{"name":"X-Ninja-User","in":"header","required":false,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"directory":{"type":"string","description":"The git repository directory (default: current)."},"args":{"type":"string","description":"Additional arguments to pass to git diff."}}}}}},"responses":{"200":{"description":"Tool execution result","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"object"},"ninja_user":{"type":"string"},"timestamp":{"type":"integer"}}}}}}}}},"/api/tools/append_to_file":{"post":{"summary":"Append text to a file at the given path.","operationId":"append_to_file","parameters":[{"name":"X-Ninja-User","in":"header","required":false,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"path":{"type":"string","description":"The file path to append to."},"text":{"type":"string","description":"The text to append."}},"required":["path","text"]}}}},"responses":{"200":{"description":"Tool execution result","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"object"},"ninja_user":{"type":"string"},"timestamp":{"type":"integer"}}}}}}}}},"/api/tools/create_directory":{"post":{"summary":"Create a directory, optionally recursively creating parent directories.","operationId":"create_directory","parameters":[{"name":"X-Ninja-User","in":"header","required":false,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"path":{"type":"string","description":"The directory path to create."},"recursive":{"type":"boolean","description":"Create parent directories (default: true)."}},"required":["path"]}}}},"responses":{"200":{"description":"Tool execution result","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"object"},"ninja_user":{"type":"string"},"timestamp":{"type":"integer"}}}}}}}}},"/api/tools":{"get":{"summary":"List all available tools with schemas","operationId":"listTools","responses":{"200":{"description":"List of tools"}}}},"/api/health":{"get":{"summary":"Health check","operationId":"health","responses":{"200":{"description":"Server health status"}}}},"/api/stats":{"get":{"summary":"All pre-computed statistics","operationId":"allStats","responses":{"200":{"description":"Statistics"}}}},"/api/stats/{tool_name}":{"get":{"summary":"Statistics for a specific tool","operationId":"statsByTool","parameters":[{"name":"tool_name","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Tool statistics"}}}},"/api/stats/user/{user}":{"get":{"summary":"Statistics for a specific user","operationId":"statsByUser","parameters":[{"name":"user","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"User statistics"}}}},"/api/audit":{"get":{"summary":"Recent audit log entries","operationId":"recentAudit","responses":{"200":{"description":"Audit log entries"}}}},"/api/audit/{tool_name}":{"get":{"summary":"Audit log filtered by tool","operationId":"auditByTool","parameters":[{"name":"tool_name","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Filtered audit entries"}}}},"/api/peers":{"get":{"summary":"List known peers","operationId":"listPeers","responses":{"200":{"description":"Peer list"}}}},"/api/peers/register":{"post":{"summary":"Register a peer","operationId":"registerPeer","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"address":{"type":"string"},"ninja_user":{"type":"string"}},"required":["address","ninja_user"]}}}},"responses":{"200":{"description":"Registration result"}}}},"/api/peers/main":{"get":{"summary":"Current main server address","operationId":"mainPeer","responses":{"200":{"description":"Main server info"}}}},"/":{"get":{"summary":"Web dashboard","operationId":"dashboard","responses":{"200":{"description":"HTML dashboard page","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/auth/status":{"get":{"summary":"Check authentication status","operationId":"authStatus","responses":{"200":{"description":"Authentication state"}}}},"/auth/login":{"post":{"summary":"Login with password","operationId":"authLogin","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"password":{"type":"string"}},"required":["password"]}}}},"responses":{"200":{"description":"Login result"}}}},"/auth/logout":{"post":{"summary":"Logout and clear session","operationId":"authLogout","responses":{"200":{"description":"Logout result"}}}},"/api/stats/dashboard":{"get":{"summary":"Aggregated dashboard statistics","operationId":"dashboardStats","responses":{"200":{"description":"Dashboard aggregate data"}}}},"/api/audit/user/{user}":{"get":{"summary":"Audit log filtered by user","operationId":"auditByUser","parameters":[{"name":"user","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"User audit entries"}}}},"/api/peers/heartbeat":{"post":{"summary":"Peer heartbeat","operationId":"peerHeartbeat","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"address":{"type":"string"}},"required":["address"]}}}},"responses":{"200":{"description":"Heartbeat acknowledged"}}}}}}