feat: enhancement workflow preset system with multi-target CLI

- Add YAML-based enhancement workflow presets shipped inside the package
  (default, minimal, security-focus, architecture-comprehensive, api-documentation)
- Add `skill-seekers workflows` subcommand: list, show, copy, add, remove, validate
- copy/add/remove all accept multiple names/files in one invocation with partial-failure behaviour
- `add --name` override restricted to single-file operations
- Add 5 MCP tools: list_workflows, get_workflow, create_workflow, update_workflow, delete_workflow
- Fix: create command _add_common_args() now correctly forwards each --enhance-workflow
  as a separate flag instead of passing the whole list as a single argument
- Update README: reposition as "data layer for AI systems" with AI Skills front and centre
- Update CHANGELOG, QUICK_REFERENCE, CLAUDE.md with workflow preset details
- 1,880+ tests passing

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
yusyus
2026-02-18 21:22:16 +03:00
parent a9b51ab3fe
commit 265214ac27
25 changed files with 2381 additions and 201 deletions

View File

@@ -103,6 +103,12 @@ try:
submit_config_impl,
upload_skill_impl,
validate_config_impl,
# Workflow tools
list_workflows_impl,
get_workflow_impl,
create_workflow_impl,
update_workflow_impl,
delete_workflow_impl,
)
except ImportError:
# Fallback for direct script execution
@@ -137,6 +143,11 @@ except ImportError:
submit_config_impl,
upload_skill_impl,
validate_config_impl,
list_workflows_impl,
get_workflow_impl,
create_workflow_impl,
update_workflow_impl,
delete_workflow_impl,
)
# Initialize FastMCP server
@@ -1178,6 +1189,100 @@ async def export_to_qdrant(
return str(result)
# ============================================================================
# WORKFLOW TOOLS (5 tools)
# ============================================================================
@safe_tool_decorator(
description="List all available enhancement workflows (bundled defaults + user-created). Returns name, description, and source (bundled/user) for each."
)
async def list_workflows() -> str:
"""List all available enhancement workflow presets."""
result = list_workflows_impl({})
if isinstance(result, list) and result:
return result[0].text if hasattr(result[0], "text") else str(result[0])
return str(result)
@safe_tool_decorator(
description="Get the full YAML content of a named enhancement workflow. Searches user dir first, then bundled defaults."
)
async def get_workflow(name: str) -> str:
"""
Get full YAML content of a workflow.
Args:
name: Workflow name (e.g. 'security-focus', 'default')
Returns:
YAML content of the workflow, or error message if not found.
"""
result = get_workflow_impl({"name": name})
if isinstance(result, list) and result:
return result[0].text if hasattr(result[0], "text") else str(result[0])
return str(result)
@safe_tool_decorator(
description="Create a new user workflow from YAML content. The workflow is saved to ~/.config/skill-seekers/workflows/."
)
async def create_workflow(name: str, content: str) -> str:
"""
Create a new user workflow.
Args:
name: Workflow name (becomes the filename stem, e.g. 'my-custom')
content: Full YAML content of the workflow
Returns:
Success message with file path, or error message.
"""
result = create_workflow_impl({"name": name, "content": content})
if isinstance(result, list) and result:
return result[0].text if hasattr(result[0], "text") else str(result[0])
return str(result)
@safe_tool_decorator(
description="Update (overwrite) an existing user workflow. Cannot update bundled workflows."
)
async def update_workflow(name: str, content: str) -> str:
"""
Update an existing user workflow.
Args:
name: Workflow name to update
content: New YAML content
Returns:
Success message, or error if workflow is bundled or invalid.
"""
result = update_workflow_impl({"name": name, "content": content})
if isinstance(result, list) and result:
return result[0].text if hasattr(result[0], "text") else str(result[0])
return str(result)
@safe_tool_decorator(
description="Delete a user workflow by name. Bundled workflows cannot be deleted."
)
async def delete_workflow(name: str) -> str:
"""
Delete a user workflow.
Args:
name: Workflow name to delete
Returns:
Success message, or error if workflow is bundled or not found.
"""
result = delete_workflow_impl({"name": name})
if isinstance(result, list) and result:
return result[0].text if hasattr(result[0], "text") else str(result[0])
return str(result)
# ============================================================================
# MAIN ENTRY POINT
# ============================================================================