Add cmdforge list --json, --filter, and run-once for LLM-friendly one-shot execution
This commit is contained in:
parent
56cb34276e
commit
23723eaddb
|
|
@ -6,7 +6,7 @@ import sys
|
||||||
from .. import __version__
|
from .. import __version__
|
||||||
|
|
||||||
from .tool_commands import (
|
from .tool_commands import (
|
||||||
cmd_list, cmd_create, cmd_edit, cmd_delete, cmd_test, cmd_run,
|
cmd_list, cmd_create, cmd_edit, cmd_delete, cmd_test, cmd_run, cmd_run_once,
|
||||||
cmd_ui, cmd_refresh, cmd_docs, cmd_check
|
cmd_ui, cmd_refresh, cmd_docs, cmd_check
|
||||||
)
|
)
|
||||||
from .provider_commands import cmd_providers
|
from .provider_commands import cmd_providers
|
||||||
|
|
@ -33,6 +33,8 @@ def main():
|
||||||
# No command = launch UI
|
# No command = launch UI
|
||||||
# 'list' command
|
# 'list' command
|
||||||
p_list = subparsers.add_parser("list", help="List all tools")
|
p_list = subparsers.add_parser("list", help="List all tools")
|
||||||
|
p_list.add_argument("--json", action="store_true", help="Output as JSON")
|
||||||
|
p_list.add_argument("--filter", help="Filter by name or description (substring match)")
|
||||||
p_list.set_defaults(func=cmd_list)
|
p_list.set_defaults(func=cmd_list)
|
||||||
|
|
||||||
# 'create' command
|
# 'create' command
|
||||||
|
|
@ -77,6 +79,14 @@ def main():
|
||||||
p_run.add_argument("tool_args", nargs=argparse.REMAINDER, help="Additional tool-specific arguments (use -- to separate)")
|
p_run.add_argument("tool_args", nargs=argparse.REMAINDER, help="Additional tool-specific arguments (use -- to separate)")
|
||||||
p_run.set_defaults(func=cmd_run)
|
p_run.set_defaults(func=cmd_run)
|
||||||
|
|
||||||
|
# 'run-once' command — one-shot without creating a tool
|
||||||
|
p_run_once = subparsers.add_parser("run-once", help="Run a one-shot prompt through a provider without creating a tool")
|
||||||
|
p_run_once.add_argument("prompt", help="Prompt text (or '-' to read from stdin)")
|
||||||
|
p_run_once.add_argument("-p", "--provider", default="opencode-pickle", help="Provider to use")
|
||||||
|
p_run_once.add_argument("--max-tokens", type=int, help="Max output tokens")
|
||||||
|
p_run_once.add_argument("--timeout", type=int, default=60, help="Timeout in seconds")
|
||||||
|
p_run_once.set_defaults(func=cmd_run_once)
|
||||||
|
|
||||||
# 'ui' command (explicit)
|
# 'ui' command (explicit)
|
||||||
p_ui = subparsers.add_parser("ui", help="Launch interactive UI")
|
p_ui = subparsers.add_parser("ui", help="Launch interactive UI")
|
||||||
p_ui.set_defaults(func=cmd_ui)
|
p_ui.set_defaults(func=cmd_ui)
|
||||||
|
|
|
||||||
|
|
@ -12,8 +12,26 @@ from ..gui import run_gui
|
||||||
|
|
||||||
def cmd_list(args):
|
def cmd_list(args):
|
||||||
"""List all tools."""
|
"""List all tools."""
|
||||||
|
import json
|
||||||
|
import sys
|
||||||
|
|
||||||
tools = list_tools()
|
tools = list_tools()
|
||||||
|
|
||||||
|
filter_text = getattr(args, "filter", "") or ""
|
||||||
|
|
||||||
|
if getattr(args, "json", False):
|
||||||
|
result = []
|
||||||
|
for name in sorted(tools):
|
||||||
|
tool = load_tool(name)
|
||||||
|
if not tool:
|
||||||
|
continue
|
||||||
|
if filter_text and filter_text.lower() not in name.lower() and filter_text.lower() not in (tool.description or "").lower():
|
||||||
|
continue
|
||||||
|
result.append(tool.to_dict())
|
||||||
|
json.dump(result, sys.stdout, indent=2)
|
||||||
|
print()
|
||||||
|
return 0
|
||||||
|
|
||||||
if not tools:
|
if not tools:
|
||||||
print("No tools found.")
|
print("No tools found.")
|
||||||
print("Create your first tool with: cmdforge ui")
|
print("Create your first tool with: cmdforge ui")
|
||||||
|
|
@ -22,7 +40,11 @@ def cmd_list(args):
|
||||||
print(f"Available tools ({len(tools)}):\n")
|
print(f"Available tools ({len(tools)}):\n")
|
||||||
for name in tools:
|
for name in tools:
|
||||||
tool = load_tool(name)
|
tool = load_tool(name)
|
||||||
if tool:
|
if not tool:
|
||||||
|
continue
|
||||||
|
if filter_text and filter_text.lower() not in name.lower() and filter_text.lower() not in (tool.description or "").lower():
|
||||||
|
continue
|
||||||
|
|
||||||
# Show source indicator for imported tools
|
# Show source indicator for imported tools
|
||||||
source_marker = ""
|
source_marker = ""
|
||||||
if tool.source and tool.source.type == "imported":
|
if tool.source and tool.source.type == "imported":
|
||||||
|
|
@ -55,6 +77,32 @@ def cmd_list(args):
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
def cmd_run_once(args):
|
||||||
|
"""Run a one-shot prompt through a provider without creating a tool."""
|
||||||
|
import sys
|
||||||
|
from ..providers import call_provider
|
||||||
|
|
||||||
|
prompt = args.prompt
|
||||||
|
if prompt == "-":
|
||||||
|
prompt = sys.stdin.read()
|
||||||
|
|
||||||
|
if not prompt.strip():
|
||||||
|
print("Error: No prompt provided.", file=sys.stderr)
|
||||||
|
return 1
|
||||||
|
|
||||||
|
provider = args.provider or "opencode-pickle"
|
||||||
|
|
||||||
|
print(f"[run-once] Provider: {provider}", file=sys.stderr)
|
||||||
|
result = call_provider(provider, prompt, timeout=args.timeout, max_tokens=args.max_tokens)
|
||||||
|
|
||||||
|
if not result.success:
|
||||||
|
print(f"Error: {result.error}", file=sys.stderr)
|
||||||
|
return 1
|
||||||
|
|
||||||
|
print(result.text)
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
def cmd_create(args):
|
def cmd_create(args):
|
||||||
"""Create a new tool (basic CLI creation - use 'ui' for full builder)."""
|
"""Create a new tool (basic CLI creation - use 'ui' for full builder)."""
|
||||||
name = args.name
|
name = args.name
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue