Rebase onto upstream (a4d95fd)
#12
@@ -301,9 +301,70 @@ class MemoryTool20250818(BaseAnthropicTool):
|
|||||||
error=""
|
error=""
|
||||||
)
|
)
|
||||||
|
|
||||||
async def _create(self, path: str | None, file_text: str | None) -> CLIResult:
|
async def _create(
|
||||||
"""Placeholder for create command."""
|
self,
|
||||||
return CLIResult(exit_code=1, output="", error="Not implemented yet")
|
path: str | None,
|
||||||
|
file_text: str | None,
|
||||||
|
) -> CLIResult:
|
||||||
|
"""Create a new file with content.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
path: File path to create
|
||||||
|
file_text: Content to write
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
CLIResult with success message or error
|
||||||
|
"""
|
||||||
|
if path is None:
|
||||||
|
return CLIResult(
|
||||||
|
exit_code=1,
|
||||||
|
output="",
|
||||||
|
error="Error: path is required for create command"
|
||||||
|
)
|
||||||
|
|
||||||
|
if file_text is None:
|
||||||
|
return CLIResult(
|
||||||
|
exit_code=1,
|
||||||
|
output="",
|
||||||
|
error="Error: file_text is required for create command"
|
||||||
|
)
|
||||||
|
|
||||||
|
path_str = path # Keep original for error messages
|
||||||
|
validated_path = self._validate_memory_path(path)
|
||||||
|
|
||||||
|
# Check if file already exists
|
||||||
|
if validated_path.exists():
|
||||||
|
return CLIResult(
|
||||||
|
exit_code=1,
|
||||||
|
output="",
|
||||||
|
error=f"Error: File {path_str} already exists"
|
||||||
|
)
|
||||||
|
|
||||||
|
# Create parent directories if needed
|
||||||
|
try:
|
||||||
|
validated_path.parent.mkdir(parents=True, exist_ok=True)
|
||||||
|
except Exception as e:
|
||||||
|
return CLIResult(
|
||||||
|
exit_code=1,
|
||||||
|
output="",
|
||||||
|
error=f"Error creating parent directories: {e}"
|
||||||
|
)
|
||||||
|
|
||||||
|
# Write file
|
||||||
|
try:
|
||||||
|
validated_path.write_text(file_text)
|
||||||
|
except Exception as e:
|
||||||
|
return CLIResult(
|
||||||
|
exit_code=1,
|
||||||
|
output="",
|
||||||
|
error=f"Error writing file: {e}"
|
||||||
|
)
|
||||||
|
|
||||||
|
return CLIResult(
|
||||||
|
exit_code=0,
|
||||||
|
output=f"File created successfully at: {path_str}",
|
||||||
|
error=""
|
||||||
|
)
|
||||||
|
|
||||||
async def _str_replace(
|
async def _str_replace(
|
||||||
self, path: str | None, old_str: str | None, new_str: str | None
|
self, path: str | None, old_str: str | None, new_str: str | None
|
||||||
|
|||||||
@@ -108,3 +108,74 @@ async def test_view_empty_directory(memory_tool):
|
|||||||
|
|
||||||
assert result.exit_code == 0
|
assert result.exit_code == 0
|
||||||
assert "/memories" in result.output
|
assert "/memories" in result.output
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
async def test_create_file(memory_tool, temp_workspace):
|
||||||
|
"""Test creating a new file."""
|
||||||
|
result = await memory_tool(
|
||||||
|
command="create",
|
||||||
|
path="/memories/notes.txt",
|
||||||
|
file_text="My notes\nLine 2\n"
|
||||||
|
)
|
||||||
|
|
||||||
|
assert result.exit_code == 0
|
||||||
|
assert result.error == ""
|
||||||
|
assert "File created successfully at: /memories/notes.txt" in result.output
|
||||||
|
|
||||||
|
# Verify file was created
|
||||||
|
created_file = temp_workspace / "memories" / "notes.txt"
|
||||||
|
assert created_file.exists()
|
||||||
|
assert created_file.read_text() == "My notes\nLine 2\n"
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
async def test_create_file_nested_directory(memory_tool, temp_workspace):
|
||||||
|
"""Test creating a file in a nested directory (auto-creates parent dirs)."""
|
||||||
|
result = await memory_tool(
|
||||||
|
command="create",
|
||||||
|
path="/memories/project/status.xml",
|
||||||
|
file_text="<status>ok</status>"
|
||||||
|
)
|
||||||
|
|
||||||
|
assert result.exit_code == 0
|
||||||
|
assert "File created successfully at: /memories/project/status.xml" in result.output
|
||||||
|
|
||||||
|
# Verify file and parent directory were created
|
||||||
|
created_file = temp_workspace / "memories" / "project" / "status.xml"
|
||||||
|
assert created_file.exists()
|
||||||
|
assert created_file.read_text() == "<status>ok</status>"
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
async def test_create_file_already_exists(memory_tool, temp_workspace):
|
||||||
|
"""Test creating a file that already exists."""
|
||||||
|
# Create file first
|
||||||
|
existing = temp_workspace / "memories" / "existing.txt"
|
||||||
|
existing.write_text("existing content")
|
||||||
|
|
||||||
|
result = await memory_tool(
|
||||||
|
command="create",
|
||||||
|
path="/memories/existing.txt",
|
||||||
|
file_text="new content"
|
||||||
|
)
|
||||||
|
|
||||||
|
assert result.exit_code == 1
|
||||||
|
assert result.output == ""
|
||||||
|
assert "Error: File /memories/existing.txt already exists" in result.error
|
||||||
|
|
||||||
|
# Verify original content unchanged
|
||||||
|
assert existing.read_text() == "existing content"
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
async def test_create_file_missing_text(memory_tool):
|
||||||
|
"""Test creating a file without file_text parameter."""
|
||||||
|
result = await memory_tool(
|
||||||
|
command="create",
|
||||||
|
path="/memories/notes.txt"
|
||||||
|
)
|
||||||
|
|
||||||
|
assert result.exit_code == 1
|
||||||
|
assert result.output == ""
|
||||||
|
assert "Error: file_text is required for create command" in result.error
|
||||||
|
|||||||
Reference in New Issue
Block a user