diff --git a/src/cmdforge/web/docs_content.py b/src/cmdforge/web/docs_content.py index 150f4aa..b246b4d 100644 --- a/src/cmdforge/web/docs_content.py +++ b/src/cmdforge/web/docs_content.py @@ -2414,6 +2414,822 @@ application that lets you create, edit, and manage tools with a visual interface ("next-up", "Next Up"), ], }, + + "registry-usage": { + "title": "Discovering Community Tools", + "description": "Find, install, and use tools created by the community", + "content": """ +

Why build everything from scratch? The CmdForge Registry is a treasure trove of +ready-to-use tools built by developers just like you. In minutes, you can have a fully-equipped +command line without writing a single line of YAML.

+ +
+

What You'll Learn

+ +
+ +

Browsing the Registry

+ +

Think of the registry as an app store for your terminal. Every tool has been reviewed, tested, +and is ready to use. There are two ways to explore:

+ +
+
+

Visual Builder

+

Run cmdforge and click Registry + in the sidebar. Browse by category, search by keyword, and install with one click.

+
+
+

Command Line

+

Use cmdforge registry search for quick + lookups when you know what you want.

+
+
+ +

Searching from the Command Line

+ +
# Search by keyword
+cmdforge registry search "code review"
+
+# Browse a category
+cmdforge registry search --category Developer
+
+# Find popular tools
+cmdforge registry search --sort downloads
+
+# Combine filters
+cmdforge registry search "translate" --category Text --sort downloads
+ +

Each result shows you the tool name, author, description, and download count—everything you need to decide if it's right for you.

+ +

Installing Tools

+ +

Found something you like? Installation is one command:

+ +
# Install a tool
+cmdforge registry install official/summarize
+
+# Install a specific version
+cmdforge registry install official/summarize@1.2.0
+
+# Install multiple tools at once
+cmdforge registry install official/summarize official/translate official/fix-grammar
+ +

That's it. The tool is now available as a command. Try it:

+ +
# Use your newly installed tool
+echo "The quick brown fox jumps over the lazy dog" | summarize
+ +
+

What Just Happened?

+

CmdForge downloaded the tool config to ~/.cmdforge/summarize/ + and created a wrapper script in ~/.local/bin/. The tool is now part of your system + just like grep or cat.

+
+ +

Inspecting Tools Before Installing

+ +

Not sure what a tool does? Peek inside before you commit:

+ +
# View tool details
+cmdforge registry info official/explain-code
+
+# See what you'll get:
+# - Description
+# - Available arguments
+# - Required providers
+# - Version history
+# - Download count
+ +

In the Visual Builder, just click on any tool to see its full details in the right panel.

+ +

Using Installed Tools

+ +

Every installed tool works like a Unix command. The universal pattern:

+ +
# Pipe input
+cat file.txt | toolname
+
+# Pass a file directly
+toolname file.txt
+
+# Use arguments
+cat file.txt | toolname --flag value
+
+# Chain tools together
+cat article.txt | summarize | translate --lang Spanish
+ +

Discovering Arguments

+ +

Every tool comes with built-in help:

+ +
# See what arguments a tool accepts
+summarize --help
+
+# Output:
+# Usage: summarize [OPTIONS] [INPUT]
+#
+# Summarize text using AI
+#
+# Options:
+#   --max-length TEXT  Maximum summary length in words [default: 200]
+#   --provider TEXT    Override the AI provider
+#   --help             Show this message
+ +

Managing Your Tools

+ +

List Installed Tools

+
# See everything you have installed
+cmdforge list
+
+# Filter by category
+cmdforge list --category Developer
+ +

Update Tools

+
# Check for updates
+cmdforge registry check-updates
+
+# Update a specific tool
+cmdforge registry install official/summarize@latest
+
+# Update all tools (coming soon)
+cmdforge registry update-all
+ +

Remove Tools

+
# Remove a tool you no longer need
+cmdforge delete summarize
+ +

A Note on Providers

+ +

Registry tools specify which AI provider they use. If you don't have that provider configured, +you have two options:

+ +
+
+

Option 1: Configure the Provider

+

Follow our Providers Guide + to set up the required provider.

+
+
+

Option 2: Override at Runtime

+

Use a provider you already have: + cat file.txt | summarize --provider ollama

+
+
+ +

Quick Start: The Starter Collection

+ +

Not sure where to begin? Install our curated starter pack:

+ +
# Install the essentials
+cmdforge collections install starter
+ +

This gives you:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ToolWhat It Does
summarizeCondense long text into key points
translateTranslate to any language
fix-grammarFix spelling and grammar issues
explain-errorDecode cryptic error messages
commit-msgGenerate commit messages from diffs
+ +

What's Next?

+ +

Now that you've got tools from the registry:

+ + +""", + "headings": [ + ("browsing", "Browsing the Registry"), + ("installing", "Installing Tools"), + ("tool-info", "Inspecting Tools Before Installing"), + ("using-tools", "Using Installed Tools"), + ("managing", "Managing Your Tools"), + ("providers", "A Note on Providers"), + ("starter-collection", "Quick Start: The Starter Collection"), + ("next-steps", "What's Next?"), + ], + }, + + "tool-steps": { + "title": "Tools Within Tools", + "description": "Build powerful workflows by combining existing tools", + "content": """ +

Here's a secret that changes everything: tools can call other tools. That +summarize command you installed from the registry? You can use it as a building +block inside your own creations. It's like having LEGO bricks that already do something cool.

+ +
+

What You'll Learn

+ +
+ +

Why Compose Tools?

+ +

Let's say you want a tool that:

+
    +
  1. Summarizes an article
  2. +
  3. Translates the summary to Spanish
  4. +
  5. Fixes any grammar issues
  6. +
+ +

You could write three prompt steps from scratch. Or you could stand on the shoulders +of giants and reuse tools that already exist:

+ +
name: spanish-summary
+version: "1.0.0"
+description: Summarize text and translate to Spanish
+
+steps:
+  - type: tool
+    tool: summarize
+    output_var: summary
+
+  - type: tool
+    tool: translate
+    input: "{summary}"
+    args:
+      lang: Spanish
+    output_var: translated
+
+  - type: tool
+    tool: fix-grammar
+    input: "{translated}"
+    output_var: final
+
+output: "{final}"
+ +

Three lines per step. Each one leverages a battle-tested tool from the registry. The prompts, +the edge cases, the provider configs—all handled.

+ +
+

The Power of Composition

+

When the summarize tool gets updated with better prompts, + your tool automatically benefits. You're not copying code—you're building on it.

+
+ +

Anatomy of a Tool Step

+ +

A tool step has four parts:

+ +
- type: tool              # This is a tool step
+  tool: owner/name        # Which tool to call (or just "name" for local tools)
+  input: "{variable}"     # What to send as input (optional, defaults to {input})
+  args:                   # Arguments to pass (optional)
+    flag-name: value
+  output_var: result      # Where to store the output
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldRequiredDescription
typeYesMust be tool
toolYesTool name or owner/name for registry tools
inputNoInput template (defaults to {input})
argsNoKey-value pairs for tool arguments
output_varYesVariable name to store the result
+ +

Passing Data Between Tools

+ +

The input field supports variable substitution, just like prompt templates:

+ +
steps:
+  # Step 1: Use original input
+  - type: tool
+    tool: extract-keywords
+    input: "{input}"           # The original stdin input
+    output_var: keywords
+
+  # Step 2: Use output from step 1
+  - type: tool
+    tool: expand-topic
+    input: "{keywords}"        # Output from previous step
+    output_var: expanded
+
+  # Step 3: Combine multiple variables
+  - type: tool
+    tool: write-article
+    input: |
+      Topic: {keywords}
+
+      Research:
+      {expanded}
+    output_var: article
+ +

Passing Arguments

+ +

Most tools accept arguments. Pass them through the args field:

+ +
- type: tool
+  tool: translate
+  input: "{input}"
+  args:
+    lang: French          # --lang French
+    formal: "true"        # --formal true
+  output_var: french_text
+ +
+

Variable Arguments

+

Arguments can use variables too! This is incredibly powerful:

+
args:
+  lang: "{target_language}"    # From a previous step or tool argument
+
+ +

Local vs Registry Tools

+ +

You can call both your own tools and registry tools:

+ +
steps:
+  # Call a local tool (in your ~/.cmdforge/)
+  - type: tool
+    tool: my-custom-extractor
+    output_var: extracted
+
+  # Call a registry tool
+  - type: tool
+    tool: official/summarize
+    input: "{extracted}"
+    output_var: summary
+ +

Real-World Patterns

+ +

Pattern 1: The Pipeline

+

Chain tools in sequence, each transforming the output of the last:

+ +
name: polish-writing
+description: Clean up rough drafts
+
+steps:
+  - type: tool
+    tool: fix-grammar
+    output_var: fixed
+
+  - type: tool
+    tool: simplify
+    input: "{fixed}"
+    args:
+      level: "high school"
+    output_var: simple
+
+  - type: tool
+    tool: tone-shift
+    input: "{simple}"
+    args:
+      tone: professional
+    output_var: polished
+
+output: "{polished}"
+ +

Pattern 2: The Fork

+

Send the same input to multiple tools, then combine results:

+ +
name: multi-perspective
+description: Get analysis from different angles
+
+steps:
+  - type: tool
+    tool: summarize
+    output_var: summary
+
+  - type: tool
+    tool: extract-keywords
+    input: "{input}"        # Same original input
+    output_var: keywords
+
+  - type: tool
+    tool: sentiment-analysis
+    input: "{input}"        # Same original input
+    output_var: sentiment
+
+  - type: prompt
+    provider: claude
+    prompt: |
+      Combine these analyses into a report:
+
+      Summary: {summary}
+      Keywords: {keywords}
+      Sentiment: {sentiment}
+    output_var: report
+
+output: "{report}"
+ +

Pattern 3: The Conditional

+

Use code steps to route data to different tools:

+ +
name: smart-translate
+description: Only translate if not already in English
+
+steps:
+  - type: tool
+    tool: detect-language
+    output_var: detected_lang
+
+  - type: code
+    code: |
+      needs_translation = detected_lang.strip().lower() != "english"
+    output_vars: [needs_translation]
+
+  - type: tool
+    tool: translate
+    input: "{input}"
+    args:
+      lang: English
+    output_var: translated
+    # Note: Tool runs but you can use code to choose output
+
+  - type: code
+    code: |
+      if needs_translation:
+          result = translated
+      else:
+          result = input
+    output_vars: [result]
+
+output: "{result}"
+ +

Provider Overrides

+ +

Need to use a different AI provider than what the tool specifies? Override it:

+ +
- type: tool
+  tool: summarize
+  provider: ollama          # Use local Ollama instead of cloud
+  output_var: summary
+ +

Debugging Composed Tools

+ +

When things go wrong, test each tool step individually:

+ +
# Test the first tool manually
+echo "your input" | summarize
+
+# Check what's going into step 2
+echo "your input" | summarize | cat
+
+# Then test step 2
+echo "output from step 1" | translate --lang Spanish
+ +

Or use the Testing Sandbox in the Visual Builder to step through each tool interactively.

+ +

Next Steps

+ + +""", + "headings": [ + ("why-compose", "Why Compose Tools?"), + ("tool-step-anatomy", "Anatomy of a Tool Step"), + ("passing-data", "Passing Data Between Tools"), + ("passing-args", "Passing Arguments"), + ("local-vs-registry", "Local vs Registry Tools"), + ("real-patterns", "Real-World Patterns"), + ("provider-override", "Provider Overrides"), + ("debugging", "Debugging Composed Tools"), + ("next", "Next Steps"), + ], + }, + + "testing-steps": { + "title": "The Testing Sandbox", + "description": "Test your tool steps before deploying to the real world", + "content": """ +

There's nothing worse than deploying a tool and watching it fail on real data. +The Testing Sandbox lets you run individual steps, inspect variables, and squash bugs—all +without burning through API credits or waiting for full pipeline runs.

+ +
+

What You'll Learn

+ +
+ +

Why Test Steps Individually?

+ +

Imagine a 5-step tool that's failing. Is it step 1? Step 4? The output template? Running +the whole thing over and over is slow and expensive. Step-by-step testing lets you:

+ +
+
+
🎯
+

Isolate Problems

+

Test one step at a time

+
+
+
💰
+

Save Money

+

Only call APIs when ready

+
+
+
+

Iterate Fast

+

Quick feedback loops

+
+
+ +

Opening the Testing Sandbox

+ +

The Testing Sandbox is built into the Visual Builder. Here's how to access it:

+ +
    +
  1. Open the Visual Builder: cmdforge
  2. +
  3. Navigate to My Tools and select a tool (or create a new one)
  4. +
  5. Click Edit to open the tool builder
  6. +
  7. Find the step you want to test
  8. +
  9. Click the Test button on that step
  10. +
+ +

The Testing Sandbox dialog opens with everything you need:

+ +
+
+
+

Input Section

+
    +
  • Test input text area
  • +
  • Variable table for setting values
  • +
  • Provider override dropdown
  • +
+
+
+

Output Section

+
    +
  • Step output display
  • +
  • Output variables table
  • +
  • Execution time
  • +
  • Success/error status
  • +
+
+
+
+ +

Testing a Prompt Step

+ +

Prompt steps call your AI provider. Here's how to test one:

+ +

1. Set Your Test Input

+

In the input text area, enter the text you want to process:

+ +
The quick brown fox jumps over the lazy dog.
+This is a sample sentence for testing purposes.
+ +

2. Set Variables

+

If your prompt uses variables like {language} or {max_length}, +fill them in the variables table:

+ + + + + + + + + + + + + + + + + + + + + + +
VariableValue
input(auto-filled from test input)
languageSpanish
max_length100
+ +

3. Choose a Provider

+

Select which provider to use for this test. You can:

+ + +

4. Run the Test

+

Click Run Test and watch the magic happen. You'll see:

+ + + +

Testing a Code Step

+ +

Code steps run Python. The sandbox lets you verify your logic:

+ +

Set Up Variables

+

Code steps often depend on outputs from previous steps. Enter those values manually:

+ + + + + + + + + + + + + + + + + + +
VariableValue
emails_rawjohn@example.com, jane@example.com, invalid-email
count3
+ +

View All Output Variables

+

After running, you'll see every variable your code step creates:

+ +
emails = ['john@example.com', 'jane@example.com']
+unique_count = 2
+is_valid = True
+ +
+

Debugging Tip

+

If your code step isn't working, add temporary print() + statements. The output will appear in the error/output section, helping you trace what's happening.

+
+ +

Testing a Tool Step

+ +

Tool steps call other tools. Testing them works the same way:

+ +
    +
  1. Set the input that will be sent to the tool
  2. +
  3. Configure any arguments the tool needs
  4. +
  5. Optionally override the provider
  6. +
  7. Run and verify the output
  8. +
+ +

This is incredibly useful for debugging composed tools—you can verify each tool in the chain +is receiving and producing the right data.

+ +

Testing Without API Calls

+ +

Don't want to burn through API credits while iterating? Use the mock provider:

+ +

Option 1: Override in the Sandbox

+

Select mock from the provider dropdown before running your test.

+ +

Option 2: Create a Smart Mock

+

Add a mock provider that returns realistic test data:

+ +
# In ~/.cmdforge/providers.yaml
+providers:
+  - name: mock
+    command: 'echo "This is a mock response for testing"'
+
+  - name: mock-json
+    command: 'echo "{\"status\": \"ok\", \"count\": 42}"'
+
+  - name: mock-summary
+    command: 'echo "This is a summary of the input text."'
+ +
+

Pro Tip: Echo the Input

+

For testing variable flow, create a mock that echoes its input:

+
- name: echo-mock
+  command: 'cat'  # Just returns whatever is piped in
+
+ +

Common Testing Scenarios

+ +

Scenario: "My variable is empty"

+

Check these in order:

+
    +
  1. Is the variable name spelled correctly? (output_var matches what you're using)
  2. +
  3. Did the previous step actually set it? (Test that step first)
  4. +
  5. Are you using the right syntax? ({varname} not $varname)
  6. +
+ +

Scenario: "Provider call failed"

+

Verify:

+
    +
  1. Is the provider configured in ~/.cmdforge/providers.yaml?
  2. +
  3. Does the provider CLI work on its own? Try: echo "test" | claude -p
  4. +
  5. Are API keys/auth set up correctly?
  6. +
+ +

Scenario: "Code step error"

+

The error message shows the Python exception. Common causes:

+ + +

The Testing Workflow

+ +

Here's how the pros do it:

+ +
+
    +
  1. 1. Test Step 1 with mock provider - Verify input handling
  2. +
  3. 2. Test Step 1 with real provider - Confirm AI output format
  4. +
  5. 3. Copy Step 1's output, paste as Step 2's input - Test the handoff
  6. +
  7. 4. Repeat for each step - Build confidence layer by layer
  8. +
  9. 5. Run the full tool - Everything should work!
  10. +
+
+ +

Next Steps

+ + +""", + "headings": [ + ("why-test", "Why Test Steps Individually?"), + ("opening-sandbox", "Opening the Testing Sandbox"), + ("testing-prompt", "Testing a Prompt Step"), + ("testing-code", "Testing a Code Step"), + ("testing-tool", "Testing a Tool Step"), + ("mock-testing", "Testing Without API Calls"), + ("common-issues", "Common Testing Scenarios"), + ("workflow", "The Testing Workflow"), + ("next", "Next Steps"), + ], + }, } @@ -2434,10 +3250,13 @@ def get_toc(): SimpleNamespace(slug="visual-builder", title="Visual Builder"), SimpleNamespace(slug="yaml-config", title="YAML Config"), ]), + SimpleNamespace(slug="registry-usage", title="Using the Registry", children=[]), SimpleNamespace(slug="arguments", title="Custom Arguments", children=[]), SimpleNamespace(slug="multi-step", title="Multi-Step Workflows", children=[ SimpleNamespace(slug="code-steps", title="Code Steps"), + SimpleNamespace(slug="tool-steps", title="Tools Within Tools"), ]), + SimpleNamespace(slug="testing-steps", title="Testing Sandbox", children=[]), SimpleNamespace(slug="providers", title="Providers", children=[]), SimpleNamespace(slug="publishing", title="Publishing", children=[]), SimpleNamespace(slug="advanced-workflows", title="Advanced Workflows", children=[