feat: add npm global package for one-command install

Add a Node.js CLI wrapper that allows installing AutoForge globally via
`npm install -g autoforge-ai` and running it with a single `autoforge`
command. The CLI handles Python detection, venv management, config
loading, and uvicorn server lifecycle automatically.

New files:
- package.json: npm package config with bin entry, files whitelist,
  and prepublishOnly script that builds the UI
- bin/autoforge.js: thin entry point that imports lib/cli.js
- lib/cli.js: main CLI module (~790 lines) with cross-platform Python
  3.11+ detection, composite venv marker for smart invalidation
  (requirements hash + Python version + path), .env config management
  at ~/.autoforge/.env, server startup with PID file and port detection,
  and signal handling with process tree cleanup
- requirements-prod.txt: runtime-only deps (excludes ruff, mypy, pytest)
- .npmignore: excludes dev files, tests, __pycache__, UI source

Modified files:
- ui/package.json: rename to autoforge-ui to avoid confusion with root
- .gitignore: add *.tgz for npm pack output
- README.md: add npm install as primary quick start method, document
  CLI commands, add Ollama/Vertex AI config sections, new troubleshooting
  entries for Python/venv issues
- GettingStarted.tsx: add Installation, Quick Start, and CLI Commands
  sections to in-app documentation with command reference table
- docsData.ts: add installation and cli-commands sidebar entries

Published as autoforge-ai@0.1.0 on npm.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Auto
2026-02-04 14:48:00 +02:00
parent 451a5a9d05
commit 4549840330
11 changed files with 1193 additions and 68 deletions

16
ui/package-lock.json generated
View File

@@ -1,11 +1,11 @@
{
"name": "autoforge",
"name": "autoforge-ui",
"version": "1.0.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "autoforge",
"name": "autoforge-ui",
"version": "1.0.0",
"dependencies": {
"@radix-ui/react-checkbox": "^1.3.3",
@@ -50,6 +50,18 @@
"vite": "^7.3.0"
}
},
"..": {
"name": "autoforge-ai",
"version": "0.1.0",
"extraneous": true,
"license": "AGPL-3.0",
"bin": {
"autoforge": "bin/autoforge.js"
},
"engines": {
"node": ">=20"
}
},
"node_modules/@babel/code-frame": {
"version": "7.27.1",
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz",

View File

@@ -1,5 +1,5 @@
{
"name": "autoforge",
"name": "autoforge-ui",
"private": true,
"version": "1.0.0",
"type": "module",

View File

@@ -35,12 +35,14 @@ export const DOC_SECTIONS: DocSection[] = [
icon: Rocket,
subsections: [
{ id: 'what-is-autoforge', title: 'What is AutoForge?' },
{ id: 'installation', title: 'Installation' },
{ id: 'quick-start', title: 'Quick Start' },
{ id: 'cli-commands', title: 'CLI Commands' },
{ id: 'creating-a-project', title: 'Creating a New Project' },
{ id: 'existing-project', title: 'Adding to an Existing Project' },
{ id: 'system-requirements', title: 'System Requirements' },
],
keywords: ['install', 'setup', 'start', 'begin', 'new', 'requirements', 'prerequisites'],
keywords: ['install', 'setup', 'start', 'begin', 'new', 'requirements', 'prerequisites', 'npm', 'config', 'port', 'repair'],
},
{
id: 'app-spec-setup',

View File

@@ -7,6 +7,25 @@
import { Badge } from '@/components/ui/badge'
/** CLI command descriptor for the reference table. */
interface CliCommand {
command: string
description: string
}
const CLI_COMMANDS: CliCommand[] = [
{ command: 'autoforge', description: 'Start the server (default)' },
{ command: 'autoforge config', description: 'Open ~/.autoforge/.env in your editor' },
{ command: 'autoforge config --path', description: 'Print config file path' },
{ command: 'autoforge config --show', description: 'Show active configuration values' },
{ command: 'autoforge --port PORT', description: 'Custom port (default: auto from 8888)' },
{ command: 'autoforge --host HOST', description: 'Custom host (default: 127.0.0.1)' },
{ command: 'autoforge --no-browser', description: "Don't auto-open browser" },
{ command: 'autoforge --repair', description: 'Delete and recreate virtual environment' },
{ command: 'autoforge --version', description: 'Print version' },
{ command: 'autoforge --help', description: 'Show help' },
]
export function GettingStarted() {
return (
<div>
@@ -33,24 +52,141 @@ export function GettingStarted() {
in real time.
</p>
{/* Installation */}
<h3 id="installation" className="text-lg font-semibold text-foreground mt-8 mb-3">
Installation
</h3>
<p className="text-muted-foreground mb-3">
Install AutoForge globally via npm:
</p>
<div className="bg-muted rounded-lg p-4 font-mono text-sm">
<pre><code>{`npm install -g autoforge-ai`}</code></pre>
</div>
<p className="text-muted-foreground mt-3">
This requires{' '}
<strong className="text-foreground">Node.js 20+</strong> and{' '}
<strong className="text-foreground">Python 3.11+</strong>.
Python is auto-detected on first run.
</p>
{/* Quick Start */}
<h3 id="quick-start" className="text-lg font-semibold text-foreground mt-8 mb-3">
Quick Start
</h3>
<p className="text-muted-foreground mb-3">
Launch AutoForge with a single command. The CLI menu lets you create or select a project,
while the Web UI provides a full dashboard experience.
After installing, start AutoForge with a single command:
</p>
<div className="bg-muted rounded-lg p-4 font-mono text-sm">
<pre><code>{`autoforge`}</code></pre>
</div>
<p className="text-muted-foreground mt-3 mb-2">
On first run, AutoForge automatically:
</p>
<ol className="list-decimal space-y-1 ml-4 text-muted-foreground">
<li>Checks for Python 3.11+</li>
<li>Creates a virtual environment at{' '}
<span className="bg-muted px-1.5 py-0.5 rounded text-sm font-mono">~/.autoforge/venv/</span>
</li>
<li>Installs Python dependencies</li>
<li>Copies a default config file to{' '}
<span className="bg-muted px-1.5 py-0.5 rounded text-sm font-mono">~/.autoforge/.env</span>
</li>
<li>Starts the server and opens your browser</li>
</ol>
<p className="text-muted-foreground mt-3">
On subsequent runs, AutoForge starts instantly &mdash; the environment is already set up.
</p>
<h4 className="text-base font-semibold text-foreground mt-6 mb-3">
Running from Source
</h4>
<p className="text-muted-foreground mb-3">
If you prefer to clone the repository (for development or contributing):
</p>
<div className="bg-muted rounded-lg p-4 font-mono text-sm">
<pre><code>{`# Windows
start.bat # CLI menu
start_ui.bat # Web UI
# macOS/Linux
./start.sh # CLI menu
./start_ui.sh # Web UI`}</code></pre>
</div>
{/* CLI Commands */}
<h3 id="cli-commands" className="text-lg font-semibold text-foreground mt-8 mb-3">
CLI Commands
</h3>
<p className="text-muted-foreground mb-3">
The{' '}
<span className="bg-muted px-1.5 py-0.5 rounded text-sm font-mono">autoforge</span>{' '}
command supports these options:
</p>
<table className="w-full text-sm mt-3">
<thead>
<tr className="bg-muted/50">
<th className="border border-border px-3 py-2 text-left font-medium text-foreground">
Command
</th>
<th className="border border-border px-3 py-2 text-left font-medium text-foreground">
Description
</th>
</tr>
</thead>
<tbody className="text-muted-foreground">
{CLI_COMMANDS.map((c) => (
<tr key={c.command}>
<td className="border border-border px-3 py-2">
<span className="bg-muted px-1.5 py-0.5 rounded text-sm font-mono">{c.command}</span>
</td>
<td className="border border-border px-3 py-2">{c.description}</td>
</tr>
))}
</tbody>
</table>
<h4 className="text-base font-semibold text-foreground mt-6 mb-3">
Configuration
</h4>
<p className="text-muted-foreground mb-3">
AutoForge reads configuration from a{' '}
<span className="bg-muted px-1.5 py-0.5 rounded text-sm font-mono">.env</span>{' '}
file. The location depends on your install method:
</p>
<table className="w-full text-sm mt-3">
<thead>
<tr className="bg-muted/50">
<th className="border border-border px-3 py-2 text-left font-medium text-foreground">
Install method
</th>
<th className="border border-border px-3 py-2 text-left font-medium text-foreground">
Config location
</th>
</tr>
</thead>
<tbody className="text-muted-foreground">
<tr>
<td className="border border-border px-3 py-2">npm (global)</td>
<td className="border border-border px-3 py-2">
<span className="bg-muted px-1.5 py-0.5 rounded text-sm font-mono">~/.autoforge/.env</span>
</td>
</tr>
<tr>
<td className="border border-border px-3 py-2">From source</td>
<td className="border border-border px-3 py-2">
<span className="bg-muted px-1.5 py-0.5 rounded text-sm font-mono">.env</span>{' '}
in the project root
</td>
</tr>
</tbody>
</table>
<p className="text-muted-foreground mt-3">
Run{' '}
<span className="bg-muted px-1.5 py-0.5 rounded text-sm font-mono">autoforge config</span>{' '}
to open the config file in your editor, or{' '}
<span className="bg-muted px-1.5 py-0.5 rounded text-sm font-mono">autoforge config --show</span>{' '}
to print the active values. See{' '}
<a href="#/docs/advanced-config" className="text-primary underline">Advanced Configuration</a>{' '}
for API provider setup (Ollama, Vertex AI, z.ai).
</p>
{/* Creating a New Project */}
<h3 id="creating-a-project" className="text-lg font-semibold text-foreground mt-8 mb-3">
Creating a New Project
@@ -102,17 +238,18 @@ start_ui.bat # Web UI
</tr>
</thead>
<tbody className="text-muted-foreground">
<tr>
<td className="border border-border px-3 py-2">Python</td>
<td className="border border-border px-3 py-2">
<Badge variant="secondary">3.11+</Badge>
</td>
</tr>
<tr>
<td className="border border-border px-3 py-2">Node.js</td>
<td className="border border-border px-3 py-2">
<Badge variant="secondary">20+</Badge>{' '}
<span className="text-xs">(for UI development)</span>
<span className="text-xs">(required for CLI and UI)</span>
</td>
</tr>
<tr>
<td className="border border-border px-3 py-2">Python</td>
<td className="border border-border px-3 py-2">
<Badge variant="secondary">3.11+</Badge>{' '}
<span className="text-xs">(auto-detected on first run)</span>
</td>
</tr>
<tr>