Add meta-tools, collections, and attribution features
Meta-tools: - Add ToolStep dataclass for tools calling other tools - Implement execute_tool_step() with recursion depth limiting - Add check_dependencies() for validating tool dependencies - Add 'cmdforge check' command for dependency verification Collections: - Add collections API endpoints and database schema - Create collections web UI (list and detail pages) - Add collections to navigation header and homepage - Document collections in REGISTRY.md Attribution: - Add source attribution fields to tool detail page - Document source types (original, adapted, imported) - Add license field documentation Documentation updates across README, DESIGN.md, REGISTRY.md, and new META_TOOLS.md design document. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <[email protected]>
This commit is contained in:
@@ -7,7 +7,7 @@ from .. import __version__
|
||||
|
||||
from .tool_commands import (
|
||||
cmd_list, cmd_create, cmd_edit, cmd_delete, cmd_test, cmd_run,
|
||||
cmd_ui, cmd_refresh, cmd_docs
|
||||
cmd_ui, cmd_refresh, cmd_docs, cmd_check
|
||||
)
|
||||
from .provider_commands import cmd_providers
|
||||
from .registry_commands import cmd_registry
|
||||
@@ -84,6 +84,11 @@ def main():
|
||||
p_docs.add_argument("-e", "--edit", action="store_true", help="Edit/create README in $EDITOR")
|
||||
p_docs.set_defaults(func=cmd_docs)
|
||||
|
||||
# 'check' command
|
||||
p_check = subparsers.add_parser("check", help="Check dependencies for a tool (meta-tools)")
|
||||
p_check.add_argument("name", help="Tool name")
|
||||
p_check.set_defaults(func=cmd_check)
|
||||
|
||||
# 'providers' command
|
||||
p_providers = subparsers.add_parser("providers", help="Manage AI providers")
|
||||
providers_sub = p_providers.add_subparsers(dest="providers_cmd", help="Provider commands")
|
||||
|
||||
@@ -5,7 +5,7 @@ from pathlib import Path
|
||||
|
||||
from ..tool import (
|
||||
list_tools, load_tool, save_tool, delete_tool, get_tools_dir,
|
||||
Tool, ToolArgument, PromptStep, CodeStep
|
||||
Tool, ToolArgument, PromptStep, CodeStep, ToolStep
|
||||
)
|
||||
from ..ui import run_ui
|
||||
|
||||
@@ -39,6 +39,8 @@ def cmd_list(args):
|
||||
step_info.append(f"PROMPT[{step.provider}]")
|
||||
elif isinstance(step, CodeStep):
|
||||
step_info.append("CODE")
|
||||
elif isinstance(step, ToolStep):
|
||||
step_info.append(f"TOOL[{step.tool}]")
|
||||
print(f" Steps: {' -> '.join(step_info)}")
|
||||
|
||||
print()
|
||||
@@ -331,3 +333,55 @@ echo "input" | {args.name}
|
||||
|
||||
print(readme_path.read_text())
|
||||
return 0
|
||||
|
||||
|
||||
def cmd_check(args):
|
||||
"""Check dependencies for a tool (meta-tools)."""
|
||||
from ..runner import check_dependencies
|
||||
from ..tool import ToolStep
|
||||
|
||||
tool = load_tool(args.name)
|
||||
if not tool:
|
||||
print(f"Error: Tool '{args.name}' not found.")
|
||||
return 1
|
||||
|
||||
# Check if this is a meta-tool
|
||||
has_tool_steps = any(isinstance(s, ToolStep) for s in tool.steps)
|
||||
has_deps = bool(tool.dependencies)
|
||||
|
||||
if not has_tool_steps and not has_deps:
|
||||
print(f"Tool '{args.name}' has no dependencies (not a meta-tool).")
|
||||
return 0
|
||||
|
||||
print(f"Checking dependencies for '{args.name}'...")
|
||||
print()
|
||||
|
||||
# Show declared dependencies
|
||||
if tool.dependencies:
|
||||
print("Declared dependencies:")
|
||||
for dep in tool.dependencies:
|
||||
print(f" - {dep}")
|
||||
print()
|
||||
|
||||
# Show tool steps
|
||||
if has_tool_steps:
|
||||
print("Tool steps (implicit dependencies):")
|
||||
for i, step in enumerate(tool.steps):
|
||||
if isinstance(step, ToolStep):
|
||||
print(f" Step {i+1}: {step.tool}")
|
||||
print()
|
||||
|
||||
# Check which are missing
|
||||
missing = check_dependencies(tool)
|
||||
|
||||
if missing:
|
||||
print(f"Missing dependencies ({len(missing)}):")
|
||||
for dep in missing:
|
||||
print(f" - {dep}")
|
||||
print()
|
||||
print("Install with:")
|
||||
print(f" cmdforge install {' '.join(missing)}")
|
||||
return 1
|
||||
else:
|
||||
print("All dependencies are satisfied.")
|
||||
return 0
|
||||
|
||||
Reference in New Issue
Block a user