Enhance sandbox functionality and MCP tools

This commit enhances the sandbox functionality by:
- Adding a new jj_log tool to retrieve commit history
- Refactoring sandbox tools into dedicated modules
- Improving project management with session-based active projects
- Updating Docker configuration to properly mount the sandbox volume
- Adding proper error handling and documentation for all tools
- Updating dependencies and configuration files
This commit is contained in:
2026-01-25 21:26:22 +01:00
parent 766b90a548
commit bc66c794a5
13 changed files with 281 additions and 81 deletions

View File

@@ -1 +1,39 @@
import os
from sys import implementation
from json_extract import structure_to_json
from jujutsu.command import jj_log as jj_log_command
from .command import jj
def jj_log(working_dir=None):
"""
Execute jj log command for a project and return structured data as JSON.
Args:
project_path (str): The path of the project
Returns:
dict: JSON structure with commit history
"""
# Execute jj log command with working_dir parameter
log_output = jj_log_command(working_dir=working_dir)
# Define the schema for the JSON structure
schema = {
"type": "array",
"items": {
"type": "object",
"properties": {
"hash": {"type": "string"},
"author": {"type": "string"},
"date": {"type": "string"},
"message": {"type": "string"},
},
"required": ["hash", "author", "date", "message"],
},
}
# Convert the text output to JSON using the schema
return structure_to_json(log_output, schema)

View File

@@ -1,4 +1,5 @@
import json
import os
import subprocess
from typing import List, Optional
@@ -8,6 +9,7 @@ def jj(
options: Optional[List[str]] = None,
args: Optional[List[str]] = None,
template: Optional[str] = None,
working_dir: Optional[str] = None,
) -> str:
"""
Lance une commande jj.
@@ -17,6 +19,7 @@ def jj(
options: Liste des options (ex: ['--limit', '5'])
args: Liste des arguments additionnels
template: Template jj à utiliser (ex: 'builtin_log_compact')
working_dir: Répertoire de travail optionnel
Returns:
str: sortie de la commande
@@ -32,7 +35,16 @@ def jj(
if args:
cmd.extend(args)
result = subprocess.run(cmd, capture_output=True, text=True)
# Si un répertoire de travail est spécifié, on le change temporairement
if working_dir is not None:
original_cwd = os.getcwd()
try:
os.chdir(working_dir)
result = subprocess.run(cmd, capture_output=True, text=True)
finally:
os.chdir(original_cwd)
else:
result = subprocess.run(cmd, capture_output=True, text=True)
if result.returncode != 0:
raise RuntimeError(
@@ -42,7 +54,7 @@ def jj(
return result.stdout
def jj_log(options=None, args=None, template=None):
def jj_log(options=None, args=None, template=None, working_dir: Optional[str] = None):
"""
Execute jj log command with optional arguments.
@@ -50,14 +62,15 @@ def jj_log(options=None, args=None, template=None):
options: List of options to pass to jj log (ex: ['--limit', '5'])
args: List of additional arguments
template: Template to use (ex: 'builtin_log_compact')
working_dir: Working directory for the command (optional)
Returns:
str: Output of the jj log command
"""
return jj("log", options, args, template)
return jj("log", options, args, template, working_dir=working_dir)
def jj_clone(url, destination=None, options=None):
def jj_clone(url, destination=None, options=None, working_dir: Optional[str] = None):
"""
Execute jj git clone command.
@@ -65,23 +78,26 @@ def jj_clone(url, destination=None, options=None):
url: The repository URL to clone
destination: The destination directory (optional)
options: List of additional options for jj git clone
working_dir: Working directory for the command (optional)
Returns:
str: Output of the jj git clone command
"""
cmd = ["jj", "git", "clone", url]
# For jj git clone, we build the full command and pass it to jj function
# The subcommand "git clone" is handled by jj itself
cmd_args = ["git", "clone", url]
if destination:
cmd.append(destination)
cmd_args.append(destination)
if options:
cmd.extend(options)
cmd_args.extend(options)
result = subprocess.run(cmd, capture_output=True, text=True)
if result.returncode != 0:
raise RuntimeError(
f"Commande jj git clone échouée: {' '.join(cmd)}\nstderr: {result.stderr}"
)
return result.stdout
# Call the main jj function with subcommand "git clone"
return jj(
"git",
options=["clone", url],
args=destination,
template=None,
working_dir=working_dir,
)