208 lines
6.6 KiB
HTML
208 lines
6.6 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>CmdForge Architecture</title>
|
|
<style>
|
|
:root {
|
|
--bg: #1a1a2e;
|
|
--surface: #16213e;
|
|
--primary: #0f3460;
|
|
--accent: #e94560;
|
|
--text: #eaeaea;
|
|
--text-muted: #a0a0a0;
|
|
--code-bg: #0d1117;
|
|
}
|
|
* { margin: 0; padding: 0; box-sizing: border-box; }
|
|
body {
|
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
background: var(--bg);
|
|
color: var(--text);
|
|
line-height: 1.7;
|
|
padding: 2rem;
|
|
}
|
|
.container { max-width: 900px; margin: 0 auto; }
|
|
a { color: var(--accent); }
|
|
h1, h2, h3, h4 { margin: 1.5rem 0 1rem; color: var(--text); }
|
|
h1 { font-size: 2rem; border-bottom: 2px solid var(--accent); padding-bottom: 0.5rem; }
|
|
h2 { font-size: 1.5rem; border-bottom: 1px solid var(--primary); padding-bottom: 0.3rem; }
|
|
h3 { font-size: 1.25rem; }
|
|
p { margin: 1rem 0; }
|
|
pre {
|
|
background: var(--code-bg);
|
|
padding: 1rem;
|
|
border-radius: 8px;
|
|
overflow-x: auto;
|
|
margin: 1rem 0;
|
|
}
|
|
code {
|
|
font-family: 'Fira Code', 'Consolas', 'Monaco', monospace;
|
|
font-size: 0.9rem;
|
|
}
|
|
:not(pre) > code {
|
|
background: var(--code-bg);
|
|
padding: 0.2rem 0.4rem;
|
|
border-radius: 4px;
|
|
}
|
|
table {
|
|
width: 100%;
|
|
border-collapse: collapse;
|
|
margin: 1rem 0;
|
|
}
|
|
th, td {
|
|
border: 1px solid var(--primary);
|
|
padding: 0.75rem;
|
|
text-align: left;
|
|
}
|
|
th { background: var(--surface); }
|
|
.back-link {
|
|
display: inline-block;
|
|
margin-bottom: 1rem;
|
|
color: var(--text-muted);
|
|
text-decoration: none;
|
|
}
|
|
.back-link:hover { color: var(--accent); }
|
|
ul, ol { margin: 1rem 0; padding-left: 2rem; }
|
|
li { margin: 0.5rem 0; }
|
|
strong { color: var(--text); }
|
|
blockquote {
|
|
border-left: 4px solid var(--accent);
|
|
margin: 1rem 0;
|
|
padding-left: 1rem;
|
|
color: var(--text-muted);
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div class="container">
|
|
<a href="./" class="back-link">← Back to Index</a>
|
|
<article>
|
|
<h1>CmdForge Architecture</h1>
|
|
<h2>Module Structure</h2>
|
|
<pre><code>src/cmdforge/
|
|
├── cli/ # CLI commands
|
|
│ ├── __init__.py
|
|
│ ├── tool_commands.py # list, create, edit, delete
|
|
│ ├── provider_commands.py # providers management
|
|
│ └── registry_commands.py # publish, install
|
|
├── registry/ # Registry API
|
|
│ ├── app.py # Flask API endpoints
|
|
│ ├── db.py # SQLite schema and queries
|
|
│ ├── sync.py # Git repo sync
|
|
│ └── rate_limit.py
|
|
├── web/ # Web UI
|
|
│ ├── app.py # Flask app factory
|
|
│ ├── routes.py # Page routes
|
|
│ ├── auth.py # User authentication
|
|
│ ├── forum/ # Forum feature
|
|
│ ├── templates/ # Jinja2 templates
|
|
│ └── static/ # CSS, JS
|
|
├── ui_urwid/ # Terminal UI
|
|
│ ├── __init__.py # Main TUI
|
|
│ ├── widgets.py # Custom widgets
|
|
│ └── palette.py # Color scheme
|
|
├── tool.py # Tool dataclass and loading
|
|
├── runner.py # Tool execution engine
|
|
└── providers.py # AI provider abstraction
|
|
</code></pre>
|
|
<h2>Data Flow</h2>
|
|
<h3>CLI Tool Execution</h3>
|
|
<pre><code>User Input (stdin)
|
|
│
|
|
▼
|
|
┌─────────────┐
|
|
│ runner.py │ ──── Loads tool from ~/.cmdforge/<name>/config.yaml
|
|
└─────────────┘
|
|
│
|
|
▼
|
|
┌─────────────┐
|
|
│ Steps │
|
|
│ (prompt/ │ ──── For prompt steps, calls providers.py
|
|
│ code) │ ──── For code steps, exec() Python
|
|
└─────────────┘
|
|
│
|
|
▼
|
|
Output (stdout)
|
|
</code></pre>
|
|
<h3>Web UI Request Flow</h3>
|
|
<pre><code>Browser Request
|
|
│
|
|
▼
|
|
┌─────────────────┐
|
|
│ Cloudflare │ ──── HTTPS termination
|
|
└─────────────────┘
|
|
│
|
|
▼
|
|
┌─────────────────┐
|
|
│ Flask :5050 │ ──── web/app.py
|
|
└─────────────────┘
|
|
│
|
|
├──── /api/* → registry/app.py (API)
|
|
└──── /* → web/routes.py (Pages)
|
|
│
|
|
▼
|
|
┌─────────────┐
|
|
│ SQLite DB │
|
|
└─────────────┘
|
|
</code></pre>
|
|
<h2>Key Classes</h2>
|
|
<h3>Tool (tool.py)</h3>
|
|
<pre><code class="language-python">@dataclass
|
|
class Tool:
|
|
name: str
|
|
description: str
|
|
category: str
|
|
arguments: List[ToolArgument]
|
|
steps: List[Step] # PromptStep | CodeStep | ToolStep
|
|
output: str
|
|
dependencies: List[str]
|
|
source: Optional[ToolSource] # Attribution for imports
|
|
version: str
|
|
</code></pre>
|
|
<h3>ToolSource (tool.py)</h3>
|
|
<pre><code class="language-python">@dataclass
|
|
class ToolSource:
|
|
type: str # "original", "imported", "forked"
|
|
license: str
|
|
url: str
|
|
author: str
|
|
original_tool: str # e.g., "fabric/patterns/extract_wisdom"
|
|
</code></pre>
|
|
<h3>Provider (providers.py)</h3>
|
|
<pre><code class="language-python">@dataclass
|
|
class Provider:
|
|
name: str # e.g., "opencode-pickle"
|
|
command: str # e.g., "$HOME/.opencode/bin/opencode run --model ..."
|
|
description: str
|
|
</code></pre>
|
|
<h2>Configuration Files</h2>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>File</th>
|
|
<th>Location</th>
|
|
<th>Purpose</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody><tr>
|
|
<td>Tool config</td>
|
|
<td><code>~/.cmdforge/<name>/config.yaml</code></td>
|
|
<td>Tool definition</td>
|
|
</tr>
|
|
<tr>
|
|
<td>Providers</td>
|
|
<td><code>~/.cmdforge/providers.yaml</code></td>
|
|
<td>AI provider commands</td>
|
|
</tr>
|
|
<tr>
|
|
<td>Main config</td>
|
|
<td><code>~/.cmdforge/config.yaml</code></td>
|
|
<td>Registry URL, client ID</td>
|
|
</tr>
|
|
</tbody></table>
|
|
|
|
</article>
|
|
</div>
|
|
</body>
|
|
</html> |