# Mithril (Node.js)

Minimal Infrastructure-as-a-Service CLI for Foundry Cloud Platform (FCP).

> **Note**: This is the Node.js implementation. For the Python implementation, see [mithril](../mithril/).

## Overview

Mithril-js provides a lightweight command-line interface for managing GPU compute instances on FCP. Built with Node.js for enhanced terminal experience while maintaining the same minimalist philosophy as the Python implementation.

## Installation

### Global Installation
```bash
npm install -g @flow-sdk/mithril
```

### Direct Execution
```bash
npx @flow-sdk/mithril
```

### From Source
```bash
git clone <repository-url>
cd mithril-js
npm install
npm link
```

## Configuration

### Quick Setup (Recommended)
First, ensure Flow SDK is installed:
```bash
# From the root of this repository
pip install -e .
# Or: uv pip install -e .
```

Then run the setup wizard:
```bash
uv run flow init
```

This interactive wizard sets up authentication for all Flow tools including mithril-js.

### Alternative: Environment Variables
```bash
export FCP_API_KEY=<your-api-key>      # FCP API authentication key
export FCP_PROJECT=<your-project-id>   # FCP project identifier
```

### Optional Environment Variables
```bash
export FCP_API_URL=<api-endpoint>      # Override default API endpoint
export MITHRIL_SSH_KEY=<path>          # Default SSH key path
```

**Note**: mithril-js automatically reads Flow SDK configuration from `~/.flow/config.yaml` if environment variables are not set.

## Command Reference

### List Available Instances
Display available GPU instances with capacity and pricing:
```bash
mithril list
```

Output format:
```
┌─────────────┬──────────────┬─────┬──────────┬───────────┐
│ TYPE        │ REGION       │ GPU │ PRICE    │ AVAILABLE │
├─────────────┼──────────────┼─────┼──────────┼───────────┤
│ gpu.h100.8x │ us-central1-b│ 8   │ $25.60   │ 3         │
│ gpu.a100.8x │ us-central1-a│ 8   │ $18.00   │ 5         │
└─────────────┴──────────────┴─────┴──────────┴───────────┘
```

### Create Instance
Submit spot bid for GPU instance:
```bash
mithril create <instance-type> [options]

Options:
  --region <region>    Specify region (default: auto-select)
  --ssh-key <path>     SSH public key path
```

Example:
```bash
mithril create gpu.h100.8x --region us-central1-b
```

### Check Instance Status
Retrieve instance details including IP addresses:
```bash
mithril status <instance-id>
```

Output includes:
- Instance ID and type
- Current status (PENDING, RUNNING, TERMINATED)
- Public and private IP addresses
- Region and creation time

### SSH Connection
Connect to running instance:
```bash
mithril ssh <instance-id> [options]

Options:
  --port <port>        SSH port (default: 22)
  --user <username>    SSH user (default: ubuntu)
  --key <path>         SSH private key path
```

### Delete Instance
Terminate instance and release resources:
```bash
mithril delete <instance-id>
```

## Architecture

### Core Components

**cli.js** (94 lines)
- Command-line interface definition using Commander.js
- Argument parsing and validation
- User interaction and error handling

**client.js** (142 lines)
- Direct FCP API client implementation
- Got-based HTTP communication
- Automatic retry and error handling
- Instance type resolution (FID to human-readable)

**format.js** (44 lines)
- Terminal output formatting
- Table rendering with cli-table3
- Color-coded status indicators
- Progress spinners for long operations

### Design Principles

1. **Minimal Dependencies**: Only essential packages (commander, got, cli-table3, chalk, ora)
2. **Direct API Access**: No abstraction layers between CLI and FCP API
3. **Fail-Fast**: Clear error messages with actionable information
4. **Async-First**: Native async/await throughout the codebase
5. **Single Responsibility**: Each module handles one specific concern

## Instance Types

### GPU Instances
- `gpu.h100.8x` - 8x NVIDIA H100 80GB
- `gpu.h100.4x` - 4x NVIDIA H100 80GB
- `gpu.a100.8x` - 8x NVIDIA A100 80GB
- `gpu.a100.4x` - 4x NVIDIA A100 80GB
- `gpu.a100.2x` - 2x NVIDIA A100 80GB
- `gpu.a100.1x` - 1x NVIDIA A100 80GB

### Regions
- `us-central1-a` - US Central (Zone A)
- `us-central1-b` - US Central (Zone B)
- `na-east1-a` - North America East (Zone A)
- `na-east1-b` - North America East (Zone B)
- `eu-central1-a` - Europe Central (Zone A)

## Error Handling

### Common Error Codes
- `401` - Invalid or missing API key
- `403` - Insufficient permissions or quota
- `404` - Instance not found
- `409` - Resource conflict (e.g., duplicate bid)
- `429` - Rate limit exceeded
- `503` - Service temporarily unavailable

### Debugging
Enable debug output:
```bash
DEBUG=mithril:* mithril list
```

## Examples

### H100 Instance Management
```bash
# List available H100s
mithril list | grep h100

# Create H100 instance in specific region
mithril create gpu.h100.8x --region us-central1-b

# Monitor instance status
mithril status inst-abc123

# Connect when running
mithril ssh inst-abc123
```

### Automated Workflows
```bash
# Create instance and wait for ready state
INSTANCE_ID=$(mithril create gpu.a100.1x | grep -o 'inst-[a-z0-9]*')
while [[ $(mithril status $INSTANCE_ID | grep -c RUNNING) -eq 0 ]]; do
  sleep 10
done
mithril ssh $INSTANCE_ID
```

## Performance Characteristics

- List operations: <500ms typical response time
- Create operations: 2-5s for bid submission
- Status checks: <300ms typical response time
- Network retry: 3 attempts with exponential backoff

## Security Considerations

1. API keys are never logged or displayed
2. SSH keys are validated before transmission
3. All API communication uses HTTPS
4. No credentials stored locally

## Comparison with Python Version

| Feature | Node.js | Python |
|---------|---------|---------|
| Lines of Code | ~280 | ~850 |
| Dependencies | 5 | 1 |
| Startup Time | ~150ms | ~50ms |
| Terminal UX | Rich (colors, tables) | Basic |
| Async Handling | Native | AsyncIO |

## Development

### Running Tests
```bash
npm test
```

### Linting
```bash
npm run lint
```

### Building
```bash
npm run build
```

## License

See LICENSE file in the root of the Flow SDK repository.

## Contributing

Contributions should maintain the minimal philosophy:
1. No unnecessary abstractions
2. Direct API interactions only
3. Clear, concise error messages
4. Comprehensive error handling
5. Performance-conscious implementation