Harumi

Commands

Full reference for every harumi CLI command, flag, and the Python library.

Every command accepts --api-url, --git-url, and --org to override the resolved configuration for a single invocation. Commands that act on a project take --project, -p; if you omit it, the CLI uses the .harumi binding written by harumi init (searched upward from the current directory).

Authentication

harumi login             # existing account: email + one-time code
harumi login --signup    # create the account first, then send the code
harumi whoami            # show the current user (email + id)
harumi logout            # clear the local session

Prop

Type

Discover kernels

Kernel specs determine the compute size and image your code runs on. List the ones available to you before passing --kernel to run:

harumi specs

Prints a table of name, display_name, cpu, memory, and whether the spec requires a subscription. Use the name value (e.g. or_python_small, gurobi_python_medium) as the --kernel argument.

Templates

List project templates, used to pre-configure a new project:

harumi templates

Prints a table of id, slug, name, description. Pass a template's id to projects create --template-id.

Projects

harumi projects create <NAME>                       # create + bind this directory
harumi projects create <NAME> --no-bind             # create without binding
harumi projects create <NAME> --personal            # create in your personal workspace
harumi projects create <NAME> --customer-id <id> --template-id <id>
harumi projects list                                # list your projects
harumi projects get <PROJECT_ID>                    # details for one project
harumi projects rename <PROJECT_ID> <NEW_NAME>      # rename a project
harumi projects delete <PROJECT_ID>                 # delete (confirms first)
harumi init --project <PROJECT_ID>                  # bind an existing project

Prop

Type

New projects are created in your configured organization (see Configuration), and create prints which workspace the project landed in. Pass --personal for a project in your personal workspace instead, or --customer-id to pick a different organization.

harumi init (and projects create when binding) writes .harumi/config.json with the project id and its Gitea repo, then configures a git remote named harumi for HTTPS + token pushes. projects create provisions the project's Gitea repo server-side and binds to it automatically. projects delete asks you to type the project name to confirm unless you pass --yes.

Import a project

Turn a downloaded project export into a brand-new Harumi project — an alternative entry point to projects create for projects that already have files (e.g. migrating from another tool, or re-importing an export).

harumi import                                          # import the current directory
harumi import ./my-project --project-name "New Name"
harumi import ./my-project --from-git https://github.com/org/repo.git
harumi import ./my-project --personal                  # import into your personal workspace

Prop

Type

Creates the project, pushes the whole folder as the repo's first commit, and (unless --no-bind) binds the directory — the same result as projects create, just seeded from your files instead of an empty repo.

Unzip the export first

import requires a real directory and fails with Not a directory: <path> if you point it at a .zip file directly. Download the export from the web app's project options menu, unzip it, then run harumi import from inside it.

Repository

Read and write the project's Harumi Git (Gitea) repo directly through harumi-api — no local clone needed for file edits. Every write lands in a single commit.

harumi repo ls                                   # list all files (recursive)
harumi repo dir <path>                            # one folder level (GitHub-style browser)
harumi repo cat <path>                            # print a file
harumi repo cat <path> --output ./local.py        # save it locally
harumi repo put ./local.py path/in/repo.py -m "msg"   # create or update a file
harumi repo rm <path> -m "msg"                    # delete a file or folder
harumi repo mv <from> <to> -m "msg"               # rename/move
harumi repo download --output ./repo.zip           # download the repo as a zip
harumi repo branches                               # list branches (live flagged)
harumi repo branch-create <name> --from main       # create a branch
harumi repo branch-rm <name>                       # delete a branch
harumi repo promote <name>                         # merge a branch into live
harumi repo commits                                # recent commit history, newest first
harumi repo commits <path> --ref <branch>          # history for one file/folder
harumi repo readiness                              # everything blocking this project from running

Prop

Type

repo readiness reports everything that would block harumi run before you run it — the same checks a run performs, surfaced up front.

Binary files

repo cat refuses to print non-text files to the terminal — pass --output <path> to save them instead.

Files

Upload, list, download, and delete files in the project's non-git storage — distinct from harumi repo (git-tracked, lands in a commit): uploads land in a shared bucket under the project's own prefix and appear at inputs/ inside every run's sandbox.

harumi files ls                                  # every file uploaded to this project
harumi files put ./data.csv                       # uploads as "data.csv"
harumi files put ./data.csv raw/data.csv           # uploads to a specific path
harumi files get raw/data.csv --output ./data.csv
harumi files rm raw/data.csv --yes

Prop

Type

Upload cap

files put refuses an upload that would push the project past 500 files or 500 MB total — the same limit a run enforces when it syncs these files into inputs/ — so a bad upload fails immediately instead of breaking every run afterward.

Run

harumi run
harumi run --branch <b> --commit <sha> --command <c> --kernel <k> --watch --output-dir <dir>

Prop

Type

See The run model for how scratch branches work.

Runs

Inspect and manage past and in-flight runs.

harumi runs list                                 # recent runs, newest first
harumi runs get <RUN_ID>                          # details + captured stdout/stderr/error
harumi runs cancel <RUN_ID>                        # cancel an in-flight run

Prop

Type

Outputs

A thin wrapper over runs, kept for convenience.

harumi outputs                                   # table of all runs
harumi outputs --latest                          # only the most recent
harumi outputs --download <RUN_ID> --output-dir ./out

Prop

Type

Data sources

Project-scoped database connections. These hit real, live endpoints today. Credentials are always prompted interactively (hidden input) — never passed as a flag — and the server never returns them.

harumi datasources list
harumi datasources get <name>
harumi datasources add <name> --type postgresql --host <host> --port 5432 --database <db> --username <user>
harumi datasources update <name> --host <new-host> --set-credentials
harumi datasources query <name> --sql "SELECT * FROM orders LIMIT 10" --csv ./out.csv
harumi datasources test --type postgresql --host <host> --port 5432 --database <db> --username <user>
harumi datasources remove <name> --yes

Prop

Type

Read-only queries

datasources query only allows SELECT/WITH; anything else is rejected with an explicit error naming the forbidden keyword, and results are capped server-side. Use it to validate SQL before wiring it into solver code.

Dashboard

Reference and validate the project's dashboard.toml widgets before committing it — the platform silently drops a widget it can't render instead of erroring, so validating locally is the only way to catch a typo up front. See Widgets for the same reference with fuller examples.

harumi dashboard widgets                              # every widget type + its keys
harumi dashboard widgets --type table                 # just one type
harumi dashboard validate                              # check ./dashboard.toml
harumi dashboard validate --against ./output/output.json
harumi dashboard validate --run <RUN_ID>              # check against a run's output
harumi dashboard validate --latest                    # check against the most recent run
harumi dashboard validate --ref <branch>              # validate the repo's copy instead of a local file

Prop

Type

dashboard validate reports every widget the platform would drop (unknown type, missing required key) and, when given --against/--run/--latest, flags dot-paths that won't resolve against that output.json.

Share

Manage a project's public, unauthenticated dashboard links. A project can have several links, each independently revocable, each with its own permissions and optional password. Every permission defaults to off on add, so creating a link never silently grants more than a bare read-only, latest-run-only dashboard view. run-control capabilities additionally require the viewer to be signed in. rotate/set-password invalidate previously issued viewer sessions for that link only.

harumi share list                                 # every link on this project
harumi share get <LINK_ID>                        # one link's full URL and permissions
harumi share add                                  # create a link (every permission off)
harumi share add --label "Client" --chat --run-history
harumi share update <LINK_ID> --run-control       # only the flags passed are changed
harumi share update <LINK_ID> --disable           # turn a link off without touching its permissions
harumi share remove <LINK_ID> --yes               # permanently delete
harumi share rotate <LINK_ID>                     # invalidate the current token, mint a new one
harumi share rotate <LINK_ID> --yes               # skip the confirmation prompt
harumi share set-password <LINK_ID>               # prompts for a password (hidden, min 8 chars)
harumi share rm-password <LINK_ID>                # make the link freely viewable again

Prop

Type

Schedules

Project-scoped cron schedules. Cron is a raw 5-field expression interpreted in UTC and validated server-side. There is no pause/enable flag — delete the schedule to stop it firing.

harumi schedules list
harumi schedules get <SCHEDULE_ID>
harumi schedules add --cron "0 9 * * *" --git-branch main --kernel or_python_small --email-to everyone
harumi schedules update <SCHEDULE_ID> --cron "0 6 * * 1-5"
harumi schedules remove <SCHEDULE_ID> --yes

Prop

Type

Secrets

Project-scoped environment variables, injected into your kernels at run time. Values are stored securely and never printed back. Setting an existing name overwrites it.

harumi secrets list                              # names only (values never shown)
harumi secrets set <NAME>                         # prompts for the value (hidden input)
harumi secrets rm <NAME> --yes

Prop

Type

Organizations

Manage the organizations you belong to and their members.

harumi org list
harumi org create "<BUSINESS_NAME>"
harumi org rename <ORG_ID> "<NEW_NAME>"
harumi org delete <ORG_ID> --yes
harumi org members <ORG_ID>
harumi org invite <ORG_ID> --email person@example.com --role member
harumi org role <ORG_ID> <USER_ID> --role admin
harumi org remove <ORG_ID> <USER_ID> --yes

Prop

Type

Profile

harumi profile show
harumi profile set --first-name Ana --last-name Silva --bio "Optimization engineer"

Prop

Type

Environments

The CLI targets a backend environment — production is the default and the only one visible to regular users.

harumi env list          # selectable environments (the active one is flagged)
harumi env list --all    # include internal (VPN-only) environments
harumi env current       # the active environment and its endpoints
harumi env use <name>    # persist a different default environment
harumi --env <name> run  # override the environment for a single command

Each environment keeps its own login session, so switching with env use doesn't log you out of the other — you still need harumi login at least once per environment. Harumi staff have additional internal environments available; they stay hidden from env list unless you pass --all.

Configuration

Every setting resolves in this order: CLI flag > environment variable > ~/.harumi config > default.

SettingEnv varDefault
API base URLHARUMI_API_URLhttps://api.harumi.io/api
Gitea URLHARUMI_GIT_URLhttps://git.harumi.io
OrganizationHARUMI_ORGnone (resolved at login)
harumi config set-org <ORG_ID>   # persist the org sent as X-Organization

The organization scopes which projects projects list returns, and is the workspace projects create and import create new projects in. Pass --personal to either command to create a project in your personal workspace instead.

Set HARUMI_HOME to relocate the whole config directory (credentials, config, and tokens all live under it).

Agent skills

Install the bundled harumi-cli and harumi-cli-setup agent skills onto this machine — see Agent skill for what they do and the other install methods (npx skills, the Claude Code/Cursor plugin marketplace).

harumi skill install            # auto-detects installed agents, global scope
harumi skill install --project  # writes to ./.agents/skills instead
harumi skill install --agent claude-code --dry-run
harumi skill path               # print the local directory containing the bundled skills

Prop

Type

Files the CLI uses

config.json
credentials.json
config.json
config.json
  • ~/.harumi/environments/production/credentials.json — session tokens and the Gitea token (mode 0600).
  • ~/.harumi/environments/production/config.json — resolved org_id (and any local api_url/git_url overrides).
  • <project>/.harumi/config.json — per-directory project binding (project_id + repo), searched upward from the current directory.

Python library

The same functionality is available as a library — useful in notebooks or your own automation.

from harumi import Client
from harumi.config import ProjectBinding

binding = ProjectBinding.load()   # reads .harumi/config.json
client = Client()                 # reads your stored session

response = client.execute_project(
    binding.project_id,
    branch="feature/solver-v2",
    command="python main.py",
)

from harumi.execution import wait_for_run, download_run_output
result = wait_for_run(client.api, binding.project_id, response.project_run_id)
print(result.status, result.succeeded)

download_run_output(client.api, binding.project_id, result, "./out")

On this page