Files

226 lines
7.3 KiB
Diff
Raw Permalink Normal View History

diff --git a/bin/jj-ai-commit.sh b/bin/jj-ai-commit.sh
new file mode 100755
index 0000000000..b89444b55d
--- /dev/null
+++ b/bin/jj-ai-commit.sh
@@ -0,0 +1,37 @@
+#!/usr/bin/env bash
+set -euo pipefail
+
+if [ -z "${LOCAL_LLM_API:-}" ]; then
+ echo "Error: LOCAL_LLM_API environment variable is not set."
+ exit 1
+fi
+
+MODEL="qwen/qwen3-coder-next"
+
+# Capture seulement les lignes modifiées pour limiter la taille
+diff="$(jj diff --git | grep '^[+-]' | head -n 500)"
+
+request_json=$(jq -n \
+ --arg model "$MODEL" \
+ --arg diff "$diff" \
+'{
+ model: $model,
+ temperature: 0.2,
+ response_format: { type: "json_object" },
+ messages: [
+ {
+ role: "user",
+ content: (
+ "Analyse ce diff et réponds UNIQUEMENT avec un objet JSON valide contenant \"title\" (string) et \"message\" (string). Pas de texte avant ou après le JSON.\n\n" + $diff
+ )
+ }
+ ]
+}')
+
+response=$(curl -s "$LOCAL_LLM_API/chat/completions" \
+ -H "Content-Type: application/json" \
+ -H "Authorization: Bearer dummy" \
+ -d "$request_json")
+
+# Récupérer et formater le commit message
+echo "$response" | jq -r '.choices[0].message.content' | jq -r '.title + "\n\n" + .message'
diff --git a/pyproject.toml b/pyproject.toml
index 4d15816f39..cd40d11e6a 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -4,7 +4,6 @@
description = "A crazy MCP server"
requires-python = ">=3.10"
dependencies = [
- "crazy-mcp>=0.1.0",
]
[project.optional-dependencies]
diff --git a/src/PMOCrazyCoder.py b/src/PMOCrazyCoder.py
index 4a10aa6427..fd9bf4a774 100644
--- a/src/PMOCrazyCoder.py
+++ b/src/PMOCrazyCoder.py
@@ -22,9 +22,8 @@
@mcp.tool
async def increment(ctx: Context) -> tuple[int, str]:
- count = ctx.get_state("count") or 0
- ctx.set_state("count", count + 1)
- return count + 1, ctx.session_id
+ count = await ctx.get_state("count") or 0
+ return int(count) + 1, ctx.session_id
# Lancement du serveur MCP
diff --git a/src/crazy_mcp/__init__.py b/src/crazy_mcp/__init__.py
new file mode 100644
index 0000000000..bda4dfa2ca
--- /dev/null
+++ b/src/crazy_mcp/__init__.py
@@ -0,0 +1,3 @@
+from fastmcp import Context, FastMCP
+
+mcp = FastMCP("PMO Crazy coder")
diff --git a/src/crazy_mcp/tools/__init__.py b/src/crazy_mcp/tools/__init__.py
new file mode 100644
index 0000000000..23a3da5bd9
--- /dev/null
+++ b/src/crazy_mcp/tools/__init__.py
@@ -0,0 +1,2 @@
+from .jj import *
+from .sandbox import *
diff --git a/src/crazy_mcp/tools/jj.py b/src/crazy_mcp/tools/jj.py
new file mode 100644
index 0000000000..f6bbed95c8
--- /dev/null
+++ b/src/crazy_mcp/tools/jj.py
@@ -0,0 +1,33 @@
+from crazy_mcp import Context, mcp
+from jujutsu import jj_log
+from sandbox import get_active_project, get_project_path
+
+
+@mcp.tool(description="Get the commit history for a project")
+def jj_log_tool(project_name: str | None = None, ctx: Context = None) -> dict:
+ """
+ Get the commit history for a project.
+
+ Args:
+ project_name (str, optional): The name of the project. If None, uses the active project.
+ ctx (Context): The MCP context object containing session information
+
+ Returns:
+ dict: The commit history as JSON structure
+ """
+ # If no project name is provided, try to get the active project
+ if project_name is None:
+ if ctx is None:
+ raise ValueError("ctx is required when project_name is None")
+
+ project_info = get_active_project(ctx.session_id)
+ if project_info is None:
+ raise ValueError("No active project set and no project name provided")
+ project_path = project_info[1]
+ else:
+ project_path = get_project_path(project_name)
+ if project_path is None:
+ raise ValueError(f"Project '{project_name}' not found")
+
+ # Call the jj_log function from jujutsu module
+ return jj_log(project_path)
diff --git a/src/crazy_mcp/tools/sandbox.py b/src/crazy_mcp/tools/sandbox.py
new file mode 100644
index 0000000000..68da135db1
--- /dev/null
+++ b/src/crazy_mcp/tools/sandbox.py
@@ -0,0 +1,89 @@
+from crazy_mcp import Context, mcp
+from sandbox import (
+ get_active_project,
+ install_project,
+ remove_project,
+ sandboxed_project_list,
+ set_active_project,
+)
+
+
+@mcp.tool(
+ description="Clone a Git repository into the sandbox. Note: Access to the cloned project is only possible through MCP tools of this server. WARNING: This operation creates a sandboxed environment that prevents direct filesystem access to the project contents. Any attempt to access project files outside of the MCP tools will be blocked by security restrictions."
+)
+def install_project_tool(url: str, project_name: str = None) -> str:
+ """
+ Install a Git project into the sandbox environment.
+
+ Args:
+ url: The Git repository URL to clone
+ project_name: Optional project name (if None, derived from URL)
+
+ Returns:
+ str: Confirmation message with project name
+ """
+ project_name = install_project(url, project_name)
+ return f"Project '{project_name}' installed successfully in sandbox"
+
+
+@mcp.tool(
+ description="Remove a project from the sandbox. Note: Access to the cloned project is only possible through MCP tools of this server. WARNING: This operation removes the entire project sandboxed environment and all associated security restrictions will be enforced."
+)
+def remove_project_tool(project_name: str) -> str:
+ """
+ Remove a project from the sandbox environment.
+
+ Args:
+ project_name (str): The name of the project to remove
+
+ Returns:
+ str: Confirmation message with project name
+ """
+ success = remove_project(project_name)
+ if success:
+ return f"Project '{project_name}' removed successfully from sandbox"
+ else:
+ return f"Failed to remove project '{project_name}' from sandbox"
+
+
+@mcp.tool(
+ description="List all projects available in the sandbox. Note: Direct filesystem access to project contents is forbidden. All project interactions must be done through MCP tools."
+)
+def list_sandboxed_projects() -> list:
+ """
+ Get a list of all projects available in the sandbox.
+
+ Returns:
+ list: A list of project names
+ """
+ return sandboxed_project_list()
+
+
+@mcp.tool(description="Set the active project for a given session ID")
+def set_active_project_tool(project_name: str, ctx: Context) -> bool:
+ """
+ Set the active project for a given session ID.
+
+ Args:
+ project_name (str): The name of the project to set as active
+ ctx (Context): The MCP context object containing session information
+
+ Returns:
+ bool: True if successful, False if the project doesn't exist
+ """
+ return set_active_project(ctx.session_id, project_name)
+
+
+@mcp.tool(description="Get the active project for a given session ID")
+def get_active_project_tool(ctx: Context) -> tuple[str, str] | None:
+ """
+ Get the active project for a given session ID.
+
+ Args:
+ ctx (Context): The MCP context object containing session information
+
+ Returns:
+ tuple: (project_name, project_path) if session exists, None otherwise
+ """
+ project_info = get_active_project(ctx.session_id)
+ return project_info
diff --git a/toto.diff b/toto.diff
new file mode 100644
index 0000000000..e69de29bb2