mirror of
https://github.com/usestrix/strix.git
synced 2026-08-22 11:02:08 +02:00
Open-source release for Alpha version
This commit is contained in:
@@ -0,0 +1,14 @@
|
||||
from .notes_actions import (
|
||||
create_note,
|
||||
delete_note,
|
||||
list_notes,
|
||||
update_note,
|
||||
)
|
||||
|
||||
|
||||
__all__ = [
|
||||
"create_note",
|
||||
"delete_note",
|
||||
"list_notes",
|
||||
"update_note",
|
||||
]
|
||||
@@ -0,0 +1,191 @@
|
||||
import uuid
|
||||
from datetime import UTC, datetime
|
||||
from typing import Any
|
||||
|
||||
from strix.tools.registry import register_tool
|
||||
|
||||
|
||||
_notes_storage: dict[str, dict[str, Any]] = {}
|
||||
|
||||
|
||||
def _filter_notes(
|
||||
category: str | None = None,
|
||||
tags: list[str] | None = None,
|
||||
priority: str | None = None,
|
||||
search_query: str | None = None,
|
||||
) -> list[dict[str, Any]]:
|
||||
filtered_notes = []
|
||||
|
||||
for note_id, note in _notes_storage.items():
|
||||
if category and note.get("category") != category:
|
||||
continue
|
||||
|
||||
if priority and note.get("priority") != priority:
|
||||
continue
|
||||
|
||||
if tags:
|
||||
note_tags = note.get("tags", [])
|
||||
if not any(tag in note_tags for tag in tags):
|
||||
continue
|
||||
|
||||
if search_query:
|
||||
search_lower = search_query.lower()
|
||||
title_match = search_lower in note.get("title", "").lower()
|
||||
content_match = search_lower in note.get("content", "").lower()
|
||||
if not (title_match or content_match):
|
||||
continue
|
||||
|
||||
note_with_id = note.copy()
|
||||
note_with_id["note_id"] = note_id
|
||||
filtered_notes.append(note_with_id)
|
||||
|
||||
filtered_notes.sort(key=lambda x: x.get("created_at", ""), reverse=True)
|
||||
return filtered_notes
|
||||
|
||||
|
||||
@register_tool
|
||||
def create_note(
|
||||
title: str,
|
||||
content: str,
|
||||
category: str = "general",
|
||||
tags: list[str] | None = None,
|
||||
priority: str = "normal",
|
||||
) -> dict[str, Any]:
|
||||
try:
|
||||
if not title or not title.strip():
|
||||
return {"success": False, "error": "Title cannot be empty", "note_id": None}
|
||||
|
||||
if not content or not content.strip():
|
||||
return {"success": False, "error": "Content cannot be empty", "note_id": None}
|
||||
|
||||
valid_categories = ["general", "findings", "methodology", "todo", "questions", "plan"]
|
||||
if category not in valid_categories:
|
||||
return {
|
||||
"success": False,
|
||||
"error": f"Invalid category. Must be one of: {', '.join(valid_categories)}",
|
||||
"note_id": None,
|
||||
}
|
||||
|
||||
valid_priorities = ["low", "normal", "high", "urgent"]
|
||||
if priority not in valid_priorities:
|
||||
return {
|
||||
"success": False,
|
||||
"error": f"Invalid priority. Must be one of: {', '.join(valid_priorities)}",
|
||||
"note_id": None,
|
||||
}
|
||||
|
||||
note_id = str(uuid.uuid4())[:5]
|
||||
timestamp = datetime.now(UTC).isoformat()
|
||||
|
||||
note = {
|
||||
"title": title.strip(),
|
||||
"content": content.strip(),
|
||||
"category": category,
|
||||
"tags": tags or [],
|
||||
"priority": priority,
|
||||
"created_at": timestamp,
|
||||
"updated_at": timestamp,
|
||||
}
|
||||
|
||||
_notes_storage[note_id] = note
|
||||
|
||||
except (ValueError, TypeError) as e:
|
||||
return {"success": False, "error": f"Failed to create note: {e}", "note_id": None}
|
||||
else:
|
||||
return {
|
||||
"success": True,
|
||||
"note_id": note_id,
|
||||
"message": f"Note '{title}' created successfully",
|
||||
}
|
||||
|
||||
|
||||
@register_tool
|
||||
def list_notes(
|
||||
category: str | None = None,
|
||||
tags: list[str] | None = None,
|
||||
priority: str | None = None,
|
||||
search: str | None = None,
|
||||
) -> dict[str, Any]:
|
||||
try:
|
||||
filtered_notes = _filter_notes(
|
||||
category=category, tags=tags, priority=priority, search_query=search
|
||||
)
|
||||
|
||||
return {
|
||||
"success": True,
|
||||
"notes": filtered_notes,
|
||||
"total_count": len(filtered_notes),
|
||||
}
|
||||
|
||||
except (ValueError, TypeError) as e:
|
||||
return {
|
||||
"success": False,
|
||||
"error": f"Failed to list notes: {e}",
|
||||
"notes": [],
|
||||
"total_count": 0,
|
||||
}
|
||||
|
||||
|
||||
@register_tool
|
||||
def update_note(
|
||||
note_id: str,
|
||||
title: str | None = None,
|
||||
content: str | None = None,
|
||||
tags: list[str] | None = None,
|
||||
priority: str | None = None,
|
||||
) -> dict[str, Any]:
|
||||
try:
|
||||
if note_id not in _notes_storage:
|
||||
return {"success": False, "error": f"Note with ID '{note_id}' not found"}
|
||||
|
||||
note = _notes_storage[note_id]
|
||||
|
||||
if title is not None:
|
||||
if not title.strip():
|
||||
return {"success": False, "error": "Title cannot be empty"}
|
||||
note["title"] = title.strip()
|
||||
|
||||
if content is not None:
|
||||
if not content.strip():
|
||||
return {"success": False, "error": "Content cannot be empty"}
|
||||
note["content"] = content.strip()
|
||||
|
||||
if tags is not None:
|
||||
note["tags"] = tags
|
||||
|
||||
if priority is not None:
|
||||
valid_priorities = ["low", "normal", "high", "urgent"]
|
||||
if priority not in valid_priorities:
|
||||
return {
|
||||
"success": False,
|
||||
"error": f"Invalid priority. Must be one of: {', '.join(valid_priorities)}",
|
||||
}
|
||||
note["priority"] = priority
|
||||
|
||||
note["updated_at"] = datetime.now(UTC).isoformat()
|
||||
|
||||
return {
|
||||
"success": True,
|
||||
"message": f"Note '{note['title']}' updated successfully",
|
||||
}
|
||||
|
||||
except (ValueError, TypeError) as e:
|
||||
return {"success": False, "error": f"Failed to update note: {e}"}
|
||||
|
||||
|
||||
@register_tool
|
||||
def delete_note(note_id: str) -> dict[str, Any]:
|
||||
try:
|
||||
if note_id not in _notes_storage:
|
||||
return {"success": False, "error": f"Note with ID '{note_id}' not found"}
|
||||
|
||||
note_title = _notes_storage[note_id]["title"]
|
||||
del _notes_storage[note_id]
|
||||
|
||||
except (ValueError, TypeError) as e:
|
||||
return {"success": False, "error": f"Failed to delete note: {e}"}
|
||||
else:
|
||||
return {
|
||||
"success": True,
|
||||
"message": f"Note '{note_title}' deleted successfully",
|
||||
}
|
||||
@@ -0,0 +1,150 @@
|
||||
<tools>
|
||||
<tool name="create_note">
|
||||
<description>Create a personal note for TODOs, side notes, plans, and organizational purposes during
|
||||
the scan.</description>
|
||||
<details>Use this tool for quick reminders, action items, planning thoughts, and organizational notes
|
||||
rather than formal vulnerability reports or detailed findings. This is your personal notepad
|
||||
for keeping track of tasks, ideas, and things to remember or follow up on.</details>
|
||||
<parameters>
|
||||
<parameter name="title" type="string" required="true">
|
||||
<description>Title of the note</description>
|
||||
</parameter>
|
||||
<parameter name="content" type="string" required="true">
|
||||
<description>Content of the note</description>
|
||||
</parameter>
|
||||
<parameter name="category" type="string" required="false">
|
||||
<description>Category to organize the note (default: "general", "findings", "methodology", "todo", "questions", "plan")</description>
|
||||
</parameter>
|
||||
<parameter name="tags" type="string" required="false">
|
||||
<description>Tags for categorization</description>
|
||||
</parameter>
|
||||
<parameter name="priority" type="string" required="false">
|
||||
<description>Priority level of the note ("low", "normal", "high", "urgent")</description>
|
||||
</parameter>
|
||||
</parameters>
|
||||
<returns type="Dict[str, Any]">
|
||||
<description>Response containing: - note_id: ID of the created note - success: Whether the note was created successfully</description>
|
||||
</returns>
|
||||
<examples>
|
||||
# Create a TODO reminder
|
||||
<function=create_note>
|
||||
<parameter=title>TODO: Check SSL Certificate Details</parameter>
|
||||
<parameter=content>Remember to verify SSL certificate validity and check for weak ciphers
|
||||
on the HTTPS service discovered on port 443. Also check for certificate
|
||||
transparency logs.</parameter>
|
||||
<parameter=category>todo</parameter>
|
||||
<parameter=tags>["ssl", "certificate", "followup"]</parameter>
|
||||
<parameter=priority>normal</parameter>
|
||||
</function>
|
||||
|
||||
# Planning note
|
||||
<function=create_note>
|
||||
<parameter=title>Scan Strategy Planning</parameter>
|
||||
<parameter=content>Plan for next phase: 1) Complete subdomain enumeration 2) Test discovered
|
||||
web apps for OWASP Top 10 3) Check database services for default creds
|
||||
4) Review any custom applications for business logic flaws</parameter>
|
||||
<parameter=category>plan</parameter>
|
||||
<parameter=tags>["planning", "strategy", "next_steps"]</parameter>
|
||||
</function>
|
||||
|
||||
# Side note for later investigation
|
||||
<function=create_note>
|
||||
<parameter=title>Interesting Directory Found</parameter>
|
||||
<parameter=content>Found /backup/ directory that might contain sensitive files. Low priority
|
||||
for now but worth checking if time permits. Directory listing seems
|
||||
disabled.</parameter>
|
||||
<parameter=category>findings</parameter>
|
||||
<parameter=tags>["directory", "backup", "low_priority"]</parameter>
|
||||
<parameter=priority>low</parameter>
|
||||
</function>
|
||||
</examples>
|
||||
</tool>
|
||||
<tool name="delete_note">
|
||||
<description>Delete a note.</description>
|
||||
<parameters>
|
||||
<parameter name="note_id" type="string" required="true">
|
||||
<description>ID of the note to delete</description>
|
||||
</parameter>
|
||||
</parameters>
|
||||
<returns type="Dict[str, Any]">
|
||||
<description>Response containing: - success: Whether the note was deleted successfully</description>
|
||||
</returns>
|
||||
<examples>
|
||||
<function=delete_note>
|
||||
<parameter=note_id>note_123</parameter>
|
||||
</function>
|
||||
</examples>
|
||||
</tool>
|
||||
<tool name="list_notes">
|
||||
<description>List existing notes with optional filtering and search.</description>
|
||||
<parameters>
|
||||
<parameter name="category" type="string" required="false">
|
||||
<description>Filter by category</description>
|
||||
</parameter>
|
||||
<parameter name="tags" type="string" required="false">
|
||||
<description>Filter by tags (returns notes with any of these tags)</description>
|
||||
</parameter>
|
||||
<parameter name="priority" type="string" required="false">
|
||||
<description>Filter by priority level</description>
|
||||
</parameter>
|
||||
<parameter name="search" type="string" required="false">
|
||||
<description>Search query to find in note titles and content</description>
|
||||
</parameter>
|
||||
</parameters>
|
||||
<returns type="Dict[str, Any]">
|
||||
<description>Response containing: - notes: List of matching notes - total_count: Total number of notes found</description>
|
||||
</returns>
|
||||
<examples>
|
||||
# List all findings
|
||||
<function=list_notes>
|
||||
<parameter=category>findings</parameter>
|
||||
</function>
|
||||
|
||||
# List high priority items
|
||||
<function=list_notes>
|
||||
<parameter=priority>high</parameter>
|
||||
</function>
|
||||
|
||||
# Search for SQL injection related notes
|
||||
<function=list_notes>
|
||||
<parameter=search>SQL injection</parameter>
|
||||
</function>
|
||||
|
||||
# Search within a specific category
|
||||
<function=list_notes>
|
||||
<parameter=search>admin</parameter>
|
||||
<parameter=category>findings</parameter>
|
||||
</function>
|
||||
</examples>
|
||||
</tool>
|
||||
<tool name="update_note">
|
||||
<description>Update an existing note.</description>
|
||||
<parameters>
|
||||
<parameter name="note_id" type="string" required="true">
|
||||
<description>ID of the note to update</description>
|
||||
</parameter>
|
||||
<parameter name="title" type="string" required="false">
|
||||
<description>New title for the note</description>
|
||||
</parameter>
|
||||
<parameter name="content" type="string" required="false">
|
||||
<description>New content for the note</description>
|
||||
</parameter>
|
||||
<parameter name="tags" type="string" required="false">
|
||||
<description>New tags for the note</description>
|
||||
</parameter>
|
||||
<parameter name="priority" type="string" required="false">
|
||||
<description>New priority level</description>
|
||||
</parameter>
|
||||
</parameters>
|
||||
<returns type="Dict[str, Any]">
|
||||
<description>Response containing: - success: Whether the note was updated successfully</description>
|
||||
</returns>
|
||||
<examples>
|
||||
<function=update_note>
|
||||
<parameter=note_id>note_123</parameter>
|
||||
<parameter=content>Updated content with new findings...</parameter>
|
||||
<parameter=priority>urgent</parameter>
|
||||
</function>
|
||||
</examples>
|
||||
</tool>
|
||||
</tools>
|
||||
Reference in New Issue
Block a user