| name | ct |
| description | Guide for using the ct (CommonTools) binary to interact with charms, recipes, and the Common Fabric. Use this skill when deploying recipes, managing charms, linking data between charms, or debugging recipe execution. Triggers include requests to "deploy this recipe", "call a handler", "link these charms", "get data from charm", or "test this recipe locally". |
CT (CommonTools CLI)
Overview
The ct binary is the primary command-line interface for interacting with the CommonTools framework. Use this skill when working with recipes (TypeScript programs that define interactive data transformations), charms (deployed instances of recipes), and the Common Fabric (the distributed runtime for charms).
When to Use This Skill
Use this skill for:
- Starting, stopping, or restarting local development servers
- Deploying recipes as charms to a space
- Managing charm data (get/set fields, call handlers)
- Linking charms together for reactive data flow
- Testing and debugging recipes locally
- Managing identity and space configurations
- Visualizing charm relationships
Self-Documenting CLI Philosophy
IMPORTANT: The ct binary has comprehensive built-in help. Always use --help flags to discover current commands and syntax rather than relying on hardcoded documentation.
Discovering Commands
# Top-level commands
deno task ct --help
# Charm subcommands
deno task ct charm --help
# Specific command details
deno task ct charm get --help
deno task ct charm link --help
deno task ct dev --help
Why this matters: The tool's --help output is the authoritative source of truth. As new features are added or flags change, --help stays current automatically.
Running CT
The ct command is run via:
deno task ct [command]
This is the recommended approach for all users. If you use ct frequently, you can create a shell alias:
alias ct="deno task ct"
Local Development Servers
Always use the scripts — never use manual pkill or process management:
# Start both servers (backend + frontend)
./scripts/start-local-dev.sh
# Stop servers
./scripts/stop-local-dev.sh
# Restart (with optional flags)
./scripts/restart-local-dev.sh
./scripts/restart-local-dev.sh --clear-cache # Clear toolshed cache
./scripts/restart-local-dev.sh --force # Kill existing processes first
Local URLs:
- Backend API:
http://localhost:8000(use with-aflag) - Frontend/Shell:
http://localhost:5173(access spaces in browser) - Logs:
packages/shell/local-dev-shell.log,packages/toolshed/local-dev-toolshed.log
Example local deployment:
./scripts/restart-local-dev.sh --force
deno task ct charm new path/to/pattern.tsx \
-i claude.key -a http://localhost:8000 -s my-space
# Then open: http://localhost:5173/my-space
If scripts fail, see docs/common/LOCAL_DEV_SERVERS.md for troubleshooting.
Prerequisites and Setup
Identity Management
Check for existing identity:
ls -la claude.key
If missing, create one:
deno task ct id new > claude.key
To get the DID (Decentralized Identifier):
deno task ct id did claude.key
Recipe Development Setup
When working in a recipes repository, initialize TypeScript support:
deno task ct init
This creates/updates tsconfig.json with proper type definitions.
Standard Parameters
Most commands require these parameters:
--identity/-i: Path to identity keyfile (commonlyclaude.key)--api-url/-a: Fabric instance URL (commonlyhttps://toolshed.saga-castor.ts.net/)--space/-s: Space name or DID
Environment Variables: Set CT_API_URL and CT_IDENTITY to avoid repeating these parameters.
Important: For *.ts.net URLs, ensure connection to the CT Tailnet. Commands will hang/timeout if not connected.
Core Workflows
1. Testing Recipes Locally
Use deno task ct dev for rapid iteration during recipe development:
# Type check and execute
deno task ct dev ./recipe.tsx
# Type check only (no execution)
deno task ct dev ./recipe.tsx --no-run
Discover more options:
deno task ct dev --help
2. Deploying and Managing Charms
Workflow pattern:
- List charms →
deno task ct charm ls - Deploy new →
deno task ct charm new - Update existing →
deno task ct charm setsrc(faster than redeploying) - Inspect state →
deno task ct charm inspect
Discover commands:
deno task ct charm --help
3. Reading and Writing Charm Data
Key concepts:
- Result Cell (default): Computed output of the charm
- Input Cell: Input parameters passed to the charm
- Path syntax: Use forward slashes (e.g.,
items/0/name,config/database/host)
Commands:
deno task ct charm get- Read data from charmdeno task ct charm set- Direct field modificationdeno task ct charm call- Execute handler (for validation/side effects)
Decision guide:
- Use GET to inspect charm state
- Use SET for simple value updates without business logic
- Use CALL for operations that need validation, computation, or side effects
Important: Values must be valid JSON. Strings need quotes: '"text"' not 'text'
4. Linking Charms Together
Linking creates reactive data flow between charms:
- Source side: Reads from a charm's result/output field
- Target side: Writes to another charm's input field
- Syntax:
[source-charm]/[field] [target-charm]/[input-field] - Reactivity: When source updates, target automatically receives new data
Example pattern:
deno task ct charm link -i claude.key -a https://toolshed.saga-castor.ts.net/ -s space \
sourceCharmID/emails targetCharmID/emailData
Discover linking options:
deno task ct charm link --help
5. Visualizing Space Architecture
Use deno task ct charm map to understand charm relationships:
# ASCII map
deno task ct charm map -i claude.key -a https://toolshed.saga-castor.ts.net/ -s space
# Graphviz DOT format (for visualization tools)
deno task ct charm map -i claude.key -a https://toolshed.saga-castor.ts.net/ -s space --format dot
6. Testing Patterns via CLI
The CLI provides faster feedback than browser-based testing and isolates data logic from UI rendering issues.
Why CLI Testing Matters
- Faster feedback than browser refresh cycles
- Isolates data logic from UI rendering issues
- Scriptable and repeatable for regression testing
- Easier edge case testing - just pipe JSON
- Verifies reactivity - see computed values update immediately
The setsrc Workflow
Critical: After initial deployment, always use setsrc instead of new:
# First deployment only
deno task ct charm new pattern.tsx -i claude.key -a http://localhost:8000 -s my-space
# Output: Created charm bafy... ← Note this ID!
# ALL subsequent iterations - update in place
deno task ct charm setsrc --charm bafy... pattern.tsx -i claude.key -a http://localhost:8000 -s my-space
Why this matters: Using new repeatedly on the same file clutters the space with duplicate charms. setsrc updates the existing charm in place.
When to use each:
setsrc: Iterating on a single file/charm (same code evolving)charm new: Deploying separate sub-patterns for independent testing
All of these happen in the SAME space. A space holds many charms - think of it as a project workspace.
When to Create a New Space
Almost never during pattern development. Use a new space only for:
- Completely unrelated projects
- Clean-slate testing (no existing charms/data)
- Separate production vs development environments
Common mistake: Creating a new space when you want a new charm. Instead, use charm new in your existing space - both charms will coexist and you can test them independently or link them together.
See the pattern-dev skill for guidance on single-file evolution vs pattern composition approaches.
Stale Computed Values After charm set
Gotcha: charm set updates data but does NOT trigger computed re-evaluation. The CLI may return stale computed values until you run charm step.
# This workflow returns STALE computed values:
echo '[...]' | deno task ct charm set --charm ID expenses ...
deno task ct charm get --charm ID totalSpent ... # May return old value!
# Fix: Run charm step after set to trigger re-evaluation
echo '[...]' | deno task ct charm set --charm ID expenses ...
deno task ct charm step --charm ID ... # Runs scheduling step, triggers recompute
deno task ct charm get --charm ID totalSpent ... # Now returns correct value
charm step runs a single scheduling step (start → idle → synced → stop) which pushes changes through the reactive graph.
Complete Testing Workflow
1. Deploy initial version:
deno task ct charm new 01-data-layer.tsx -i claude.key -a http://localhost:8000 -s my-space
# Output: Created charm bafyreia...
# Save this ID for all subsequent commands
2. Set test input data + trigger recompute:
# Set an array of expenses
echo '[{"description":"Coffee","amount":5,"category":"food"},{"description":"Gas","amount":40,"category":"transport"}]' | \
deno task ct charm set --charm bafyreia... expenses -i claude.key -a http://localhost:8000 -s my-space
# Trigger computed re-evaluation (required for fresh values!)
deno task ct charm step --charm bafyreia... -i claude.key -a http://localhost:8000 -s my-space
3. Verify computed outputs:
# Check total calculation
deno task ct charm get --charm bafyreia... totalSpent -i claude.key -a http://localhost:8000 -s my-space
# Expected: 45
# Check category breakdown
deno task ct charm get --charm bafyreia... byCategory -i claude.key -a http://localhost:8000 -s my-space
# Expected: {"food":5,"transport":40}
4. Test handlers:
# Call addExpense handler
echo '{"description":"Lunch","amount":12,"category":"food"}' | \
deno task ct charm call --charm bafyreia... addExpense -i claude.key -a http://localhost:8000 -s my-space
# Verify it worked
deno task ct charm get --charm bafyreia... totalSpent -i claude.key -a http://localhost:8000 -s my-space
# Expected: 57
5. Inspect full state:
deno task ct charm inspect --charm bafyreia... -i claude.key -a http://localhost:8000 -s my-space
6. Iterate on code:
# Edit pattern file, then update the deployed charm:
deno task ct charm setsrc --charm bafyreia... 01-data-layer.tsx -i claude.key -a http://localhost:8000 -s my-space
# Repeat from step 2 to verify changes
Testing Each Layer
When following the layered development methodology (see pattern-dev skill):
Layer 1 (Data + Computeds):
- Set input data → verify all computed values are correct
- Test edge cases: empty arrays, missing fields, large numbers
Layer 2 (Handlers):
- Call each handler → inspect state before/after
- Test validation: invalid inputs, boundary conditions
Layer 3 (UI):
- Now use browser to verify visual rendering
- Data flow is already verified, so UI issues are isolated
Common Patterns and Gotchas
Path Format
Always use forward slashes:
- ✅
config/database/host - ❌
config.database.host
Array indices are numeric:
- ✅
items/0/name - ❌
items[0]/name
JSON Input Requirements
All values passed to set and call must be valid JSON:
# Strings (note the nested quotes)
echo '"hello world"' | deno task ct charm set ... title
# Numbers
echo '42' | deno task ct charm set ... count
# Objects
echo '{"name": "John"}' | deno task ct charm set ... user
Error Handling
Common issues:
- Commands hang/timeout → Not connected to CT Tailnet (for
*.ts.netURLs) - Permission denied → Check identity file permissions (
chmod 600 claude.key) - Invalid path → Verify forward slash syntax
- JSON parse error → Check JSON formatting (proper quotes, no trailing commas)
Debugging steps:
- For recipe errors: Run
deno task ct dev [recipe] --no-runto check syntax - For connection issues: Verify Tailnet connection for
*.ts.netURLs - For data issues: Use
deno task ct charm inspectto examine charm state - For linking issues: Use
deno task ct charm mapto visualize connections
Building Complex Applications
Composability Pattern:
- Create small, focused recipes (each does one thing well)
- Deploy recipes as separate charms
- Link charms together for data flow
- Use
deno task ct charm mapto visualize architecture - Add new functionality by deploying and linking new charms
Example architecture:
[User Input Form] → [Validator] → [Database Writer]
↓
[Email Notifier]
Implement by creating 4 recipes, deploying as charms, then linking them together.
Resources
references/well-known-ids.md
Documentation of well-known charm IDs (like allCharms) that provide access to system-level data. Reference when building tools that need space-wide information.
Remember
- Local servers - Always use
./scripts/restart-local-dev.sh, never manual pkill - Use
--helpflags - The tool itself is the documentation - Check
deno task ct charm --helpbefore asking about available commands - Path syntax - Always forward slashes, numeric array indices
- JSON format - All values must be valid JSON (strings need quotes)
- Environment variables - Set
CT_API_URLandCT_IDENTITYfor convenience