Skip to main content
Use ProjectCLI to expose your installed packs through a company-owned executable. It uses the same planning API available to custom interfaces.

Register the entrypoint

cli.py
Register main as a console script in your company package:
pyproject.toml
The packs order is the execution order. Their names must be unique. Install the Harnest executable alongside the company CLI, or select it explicitly:
Pin that executable and the Python Harnest package to the same release. Initialization uses the executable’s scaffold; upgrades use the Python migration engine.

Commands and flags

A later --apply command builds a fresh plan; the CLI does not persist and replay an earlier preview. --json prints a plan without file contents or option values. It can be combined with application flags and does not itself make the command read-only.

Initialize from a template

Pass a Harnest template to your team’s CLI:
--template accepts the same template project name, short slug, or HTTPS wheel URL as harnest init. For an HTTPS wheel, optionally pin its contents:
The planner calls harnest init with those template options in a temporary staging directory, then runs the pack initializers against the resulting files. The template supplies the initial agent structure, instructions, skills, framework, and mode. Packs apply their project customizations afterward. Existing pack ownership and write policies still govern conflicts. --template cannot be combined with an explicit --framework or --minimal. --template-sha256 requires --template. Without a template, the framework still defaults to ADK. Use --dry-run to review the combined template and pack changes before creating the project. Planning can download the template; it does not modify the requested destination. A template download or validation failure prevents pack hooks from running and leaves that destination unchanged.

Typed pack options

Declare a Pydantic options model when creating the pack. String, integer, and number fields become typed flags. Enums become choices; defaults and validation remain in the Pydantic model. Use explicit JSON literals for booleans and structured inputs. Avoid field names reserved by the CLI, such as framework, minimal, template, template_sha256, json, and apply. With multiple packs, flags gain the pack name prefix: --acme-team, --platform-region. Underscores in field names become hyphens in flags. Options are validated before that pack’s callbacks execute and are not stored in harnest-packs.lock. During upgrades, a pack receives context.options = None unless its options were supplied; read persisted company choices from its configuration file.

Add a company command

add_command returns an argparse.ArgumentParser. Add your arguments and return an integer exit code from the handler:
Custom handlers own their work and error handling; they do not automatically participate in the project transaction. Other Harnest commands are not automatically forwarded. To expose them, register an explicit company handler. cli.run(arguments, stdout=..., stderr=...) supports embedded callers and tests. It returns an exit code for normal command execution; argparse retains its usual exit behavior for help and invalid arguments.