Metadata-Version: 2.1
Name: lucihub-cli
Version: 0.1.2
Summary: Command-line interface for LuciHub system
Author-Email: Anabrid <info@anabrid.com>
Requires-Python: <4.0,>=3.11
Requires-Dist: click<9.0.0,>=8.1.7
Requires-Dist: httpx<1.0.0,>=0.25.0
Requires-Dist: lucihub-common>=0.1.0
Requires-Dist: numpy>=2.4
Requires-Dist: pydantic<3.0.0,>=2.0.0
Requires-Dist: rich<14.0.0,>=13.0.0
Requires-Dist: sympy>=1.14.0
Description-Content-Type: text/markdown

# LuciHub CLI

Command-line interface for the LuciHub analog computing system.

## Overview

The LuciHub CLI provides a convenient command-line interface to interact with LuciHub's analog computing devices through the REST API. You can submit tasks, monitor their progress, and retrieve results directly from your terminal.

## Installation

1. Navigate to the CLI directory:
   ```bash
   cd components/cli
   ```

2. Install using Poetry:
   ```bash
   poetry install
   ```

3. The CLI tool will be available as `lucihub` command after installation.

## Usage

### Basic Commands

The CLI connects to a LuciHub API server. By default, it connects to `localhost:8000`, but you can specify different host and port:

```bash
# Connect to default server
lucihub status

# Connect to different server
lucihub -h 192.168.1.100 -p 8080 status
```

### Available Commands

#### 1. System Status
Get system information and connected devices:
```bash
lucihub status
```

#### 2. Run Tasks
Execute a configuration on physical LUCIDAC device:
```bash
# Basic run
lucihub run config.json

# With custom parameters
lucihub run config.json --sample-rate 20000 --op-time 0.5 --device device1
```

Options:
- `--sample-rate`: Number of samples per second (default: 10000)
- `--op-time`: Integration time in seconds (default: 0.1)
- `--device`: Specific device ID (auto-detected if not specified)

#### 3. Simulate Tasks
Execute a configuration on the built-in simulator:
```bash
# Basic simulation
lucihub simulate config.json

# With simulator options
lucihub simulate config.json --k0 1000 --with-limits --op-time 1.0
```

Options:
- `--sample-rate`: Number of samples per second (default: 10000)
- `--op-time`: Integration time in seconds (default: 0.1)
- `--k0`: Acceleration factor (choices: 1, 10, 100, 1000, 10000; default: 10000)
- `--with-limits`: Enable integrator capacity limits
- `--device`: Device context (auto-detected if not specified)

#### 4. Compile Tasks
Compile an ODE specification to device configuration:
```bash
# Basic compilation
lucihub compiler ode.json
```

#### 5. Async submission with `--follow / --no-follow`

`compile` and `run` are interactive by default (`--follow`): the CLI
submits the task, polls the server, and prints logs and results in
place. For pipelines and long-running jobs use `--no-follow`:

```bash
# Fire and forget — print only the UUID on stdout
TASK_ID=$(lucihub run config.json --no-follow)

# Use the id with task subcommands later
lucihub task wait "$TASK_ID"
lucihub task result "$TASK_ID" -o result.json
```

In `--no-follow` mode stdout is **strictly** the UUID; the "Task
submitted" notice goes to stderr so it does not corrupt pipelines.

### Task management — `lucihub task`

The `task` subcommand group inspects, awaits, and withdraws tasks
asynchronously. Output is TTY-aware: interactive terminals get Rich
panels and tables, pipes get JSON (or raw text for `task logs`).

```bash
lucihub task list      [--state S] [--type T] [--limit N] [--offset N]
                       [--ids-only] [--format text|json]
lucihub task info      <id> [--format text|json]
lucihub task status    <id> [--format text|json]
lucihub task logs      <id> [--follow] [--format text|json]
lucihub task result    <id> [-o FILE]
lucihub task wait      <id> [--poll-interval S] [--timeout S]
lucihub task revoke    <id>
lucihub task delete    <id>
```

- `task list` enumerates tasks visible to your API key. Use
  `--ids-only` to emit one UUID per line for shell loops; use
  `--format json` for a structured dump.
- `task info` shows the full detail record (type-specific fields for
  compile vs run).
- `task status` shows the current state and the state-transition
  history.
- `task logs` prints the captured log output. With `--follow` the
  command polls every second and emits only newly appended lines until
  the task reaches a terminal state. Off a TTY the snapshot defaults
  to raw text so `grep` works.
- `task result` writes the task's result payload. Compile tasks
  produce binary device configurations (written to `-o FILE` or to
  binary stdout); run tasks produce JSON (pretty-printed, written to
  `-o FILE` or stdout).
- `task wait` blocks until the task reaches a terminal state and
  carries the outcome via the exit code — stdout is left empty so the
  shell can branch on `$?` without parsing output.
- `task revoke` withdraws a `QUEUED` task. It does *not* abort a task
  that is already running (the worker keeps it). The wire-level
  endpoint remains `POST /tasks/{id}/cancel`; the CLI verb is named
  `revoke` because that better reflects the user-visible semantic.
- `task delete` removes a task and its blobs. The server refuses
  `DELETE` on an `INPROGRESS` task whose worker run is less than two
  minutes old, to protect the worker.

#### Exit-code contract

Shell scripts can rely on the following exit codes:

| Code | Meaning |
|------|---------|
| 0    | success / `SUCCEEDED` |
| 1    | task `FAILED` (for `wait`) |
| 2    | task `CANCELLED` (for `wait`) |
| 3    | transport / API error (connection refused, 5xx, etc.) |
| 4    | state conflict — e.g. `revoke` on a non-`QUEUED` task, or `delete` inside the worker grace window (HTTP 409) |
| 124  | timeout (matches GNU `timeout`); emitted by `task wait --timeout S` |

Example: revoke a queued task only if it is still queued, otherwise
fall through to waiting on it:

```bash
if ! lucihub task revoke "$TASK_ID" 2>/dev/null; then
    case $? in
        4) lucihub task wait "$TASK_ID" ;;  # already running — wait it out
        *) exit $? ;;
    esac
fi
```

### File Formats

#### Configuration Files (for run/simulate)
JSON files containing analog circuit configurations:
```json
{
  "integrators": {
    "int0": {"initial_value": 1.0}
  },
  "constants": {
    "k1": 2.5
  },
  "connections": []
}
```

#### ODE Files (for compiler)
JSON files containing ODE specifications:
```json
{
  "variables": ["x", "y"],
  "equations": {
    "x": "-y",
    "y": "x"
  },
  "initial_conditions": {
    "x": 1.0,
    "y": 0.0
  }
}
```

### Example Workflow

1. Check system status:
   ```bash
   lucihub status
   ```

2. Compile an ODE to configuration:
   ```bash
   lucihub compiler my_ode.json
   # Save the output to compiled_config.json when prompted
   ```

3. Run the compiled configuration:
   ```bash
   lucihub run compiled_config.json --sample-rate 25000 --op-time 0.2
   ```

4. Or simulate instead:
   ```bash
   lucihub simulate compiled_config.json --k0 1000 --with-limits
   ```

## Development

### Running Tests
```bash
poetry run pytest
```

### Code Formatting
```bash
poetry run black .
```

## Dependencies

- **click**: Command-line interface framework
- **httpx**: HTTP client for API communication
- **pydantic**: Data validation using the shared models
- **rich**: Rich text and beautiful formatting in the terminal
- **lucihub-common**: Shared models and utilities

## Error Handling

The CLI provides user-friendly error messages for common issues:
- Connection errors to the API server
- Invalid JSON files
- Missing files
- API errors with detailed messages

Progress indicators show task status during execution, and results are displayed in a formatted, readable way.