24 KiB
HarborForge CLI (hf) Plan
Goal
Build a Go-based HarborForge CLI binary named:
hf
This CLI should work well in two environments:
- With padded-cell /
pass_mgravailable- agents can execute commands directly
- secrets and generated credentials are resolved automatically
- Without padded-cell installed
- humans can still use the CLI manually by explicitly passing tokens or account-manager credentials
Important: do not directly migrate the old Python CLI from
HarborForge.Backend/cli.pyas-is. That old CLI is only a reference for command inventory. The new CLI must be a standalone Go binary.
High-Level Direction
- Language: Go
- Delivery: single binary
- Config file:
.hf-config.json - Config location: same directory as the CLI binary
- Secret integration:
pass_mgr - Command style: grouped subcommands (
hf user ...,hf task ...,hf monitor ...) - Identifiers: prefer codes/names instead of internal numeric ids whenever possible
project-codemilestone-codetask-codemeeting-codesupport-coderole-nameusername
OpenClaw Plugin / Monitor Integration Requirements
This CLI plan now also carries cross-project integration constraints for:
HarborForge.OpenclawPluginHarborForge.MonitorHarborForge.Cli
These requirements should be treated as part of the same roadmap because the CLI, plugin installation flow, and monitor data path are now coupled.
1. OpenClaw plugin registration name
The plugin currently known as HarborForge.OpenclawPlugin should register under the plugin name:
harbor-forge
This should replace the old plugin registration name used previously.
2. Remove plugin sidecar server
The plugin should no longer keep a separate server/ sidecar process for telemetry collection.
That means:
- remove the plugin-side
servercomponent - remove the architecture where plugin telemetry is uploaded by a dedicated sidecar process
- any OpenClaw-specific monitor data should instead be served directly by the plugin via the plugin/runtime communication path described below
3. Plugin install script: --install-cli
The OpenClaw plugin install script should support:
--install-cli
If present, the installer should:
- build
HarborForge.Cli - produce the
hfbinary - copy the binary into the OpenClaw profile
bindirectory chmod +xthe installed binary
Default target location:
~/.openclaw/bin/hf
The implementation should allow profile-aware resolution, but default to:
~/.openclaw/bin
4. Plugin config: add monitor_port
The OpenClaw plugin configuration should add a new field:
monitor_port
This port is used for local communication between HarborForge.Monitor and the plugin.
5. HarborForge.Monitor Docker env: MONITOR_PORT
HarborForge.Monitor should add a Docker environment variable:
MONITOR_PORT
Behavior:
- Monitor listens on
127.0.0.1:<MONITOR_PORT> - docker-compose should expose this port to the host on
127.0.0.1 - the OpenClaw plugin communicates with Monitor through this local port
This communication channel is specifically for supplementing OpenClaw-related telemetry, such as:
- OpenClaw version
- plugin version
- agent information
- other OpenClaw runtime metadata that used to come from the plugin-side sidecar telemetry path
6. Monitor heartbeat behavior stays independent
HarborForge.Monitor startup / heartbeat / telemetry upload must not depend on successful communication with the plugin over MONITOR_PORT.
Required behavior:
- if no plugin communication happens, Monitor should behave exactly like it does now
- if plugin communication succeeds, Monitor should enrich uploaded telemetry with:
- OpenClaw version
- plugin version
- agent list / agent metadata
- related OpenClaw-side monitor fields
In other words:
- hardware/host telemetry path remains primary and independent
- OpenClaw-side metadata becomes optional enrichment
7. Plugin skills/ folder deployment
HarborForge.OpenclawPlugin should include a skills/ directory.
During plugin installation, installer logic should copy everything under that directory into the OpenClaw profile skills directory.
Default target location:
~/.openclaw/skills
The implementation should be profile-aware, but default to the standard OpenClaw profile path above.
Special rule for skills/hf/
The plugin skills/ directory should include an hf/ subfolder.
However:
- if installer is run without
--install-cli, do not copyskills/hf/into the OpenClaw profile skills directory - if installer is run with
--install-cli, thenskills/hf/should be copied together with the CLI installation flow
In other words:
- normal plugin install copies regular plugin skills
hfskill content is gated behind--install-cli
skills/hf/SKILL.md content requirement
skills/hf/ should contain a SKILL.md file.
That skill file should:
- introduce the basic usage of
hf - explain that
hfis the HarborForge CLI - encourage agents to use:
hf --help-brief
when they want a concise view of the currently permitted command surface
- point agents to normal
--helpwhen they need the full command tree including(not permitted)entries
8. Implication for implementation planning
This means the CLI plan is no longer only about hf command syntax.
It also implies follow-up implementation work in:
HarborForge.CliHarborForge.OpenclawPluginHarborForge.Monitor- Docker / install scripts / plugin packaging
Binary / Config Model
CLI name
hf
Config file location
hf must resolve its config file relative to the binary directory, not cwd and not home directory.
The command:
hf config --url <hf-url>
must write:
{
"base-url": "<hf-url>"
}
into:
<binary-dir>/.hf-config.json
Initial config structure
{
"base-url": "http://127.0.0.1:8000"
}
The config file should remain intentionally minimal at first.
Runtime Mode Detection
At startup, the CLI must check whether pass_mgr exists:
which pass_mgr
This determines the CLI mode.
Mode A — padded-cell / pass_mgr installed
If which pass_mgr succeeds:
- the CLI runs in automatic secret mode
- users/agents should not explicitly provide
--tokenor--acc-mgr-token - help output should not show those flags
- if a caller explicitly provides such flags, terminate with:
padded-cell installed, --token flag disabled, use command directly
This message is also used for other manual credential flags that should be suppressed in padded-cell mode.
Token sources in padded-cell mode
For normal authenticated commands:
pass_mgr get-secret --key hf-token
For account-manager flow:
pass_mgr get-secret --public --key hf-acc-mgr-token
For password generation during user creation:
pass_mgr generate --key hf --username <username>
Mode B — no padded-cell / no pass_mgr
If which pass_mgr fails:
- assume padded-cell is not installed
- manual auth flags become required where needed
- help output must explicitly show the required flags
- commands that require token/account-manager credentials must state that clearly in
--help
Help System Rules
1. hf --help
- does not require
--token - does not require
pcexec - shows all top-level command groups
2. hf --help-brief
- does not require
--token - does not require
pcexec - shows only currently permitted top-level command groups
3. hf <group> --help
Show all subcommands in the group.
- If permitted: show subcommand name + description
- If not permitted: show subcommand name +
(not permitted) - For not-permitted subcommands, do not show detailed usage or flag descriptions
Example:
hf user --help
list List users
get Show a user by username or id
create Create a user account (uses account-manager token flow)
update (not permitted)
activate (not permitted)
deactivate (not permitted)
delete (not permitted)
4. hf <group> --help-brief
Show only currently permitted subcommands.
Example:
hf user --help-brief
list List users
get Show a user by username or id
create Create a user account (uses account-manager token flow)
5. hf <group> <subcommand> --help
- If permitted: show full help
- If not permitted: show only a short message such as:
hf user update: not permitted
No detailed usage, no flags, no examples.
6. hf <group> <subcommand> --help-brief
For leaf commands, this behaves the same as --help:
- permitted → full help
- not permitted → short
not permittedmessage only
7. Mode-sensitive help
padded-cell mode
- hide
--token - hide
--acc-mgr-token - hide other manual credential flags that should not be used directly
manual mode
- show required credential flags where needed
- clearly indicate commands that require
--token - clearly indicate
user createspecial requirements
Credential / Auth Rules
Normal authenticated commands
For most resource commands, auth behaves like this:
padded-cell mode
- do not accept
--token - auto-read token using:
pass_mgr get-secret --key hf-token
manual mode
--token <token>becomes required- if missing, terminate with:
--token <token> required or execute this with pcexec
Special command: hf user create
hf user create is special.
It does not use the normal user token flow. It uses account-manager token flow.
Command shape:
hf user create --user <username> [--pass <password>] [--email <email>] [--full-name <name>] [--acc-mgr-token <token>]
Rules
- no
--token - no
--role - default role is always
guest
padded-cell mode
- do not show
--acc-mgr-token - do not allow callers to pass
--acc-mgr-token - password fallback:
pass_mgr generate --key hf --username <username>
- account-manager token fallback:
pass_mgr get-secret --public --key hf-acc-mgr-token
If password generation fails:
--pass <password> required or execute with pcexec
If account-manager token lookup fails:
--acc-mgr-token <token> required or execute with pcexec
manual mode
--acc-mgr-tokenmust be shown in help--passmay be omitted only if running with pcexec / pass_mgr-compatible flow- otherwise use the same exact failure messages above
Special help behavior
Even if the current user token lacks normal user-write permission, hf user create may still appear as available because it is a distinct account-manager token flow.
Config Commands
1. Configure HarborForge URL
hf config --url <hf-url>
Behavior:
- write/update
base-urlin<binary-dir>/.hf-config.json
2. Configure account-manager token
hf config --acc-mgr-token <token>
Behavior:
- execute:
pass_mgr set --public --key hf-acc-mgr-token --secret <token>
If this fails:
--acc-mgr-token can only be set with padded-cell plugin
Supported Command Tree
This section defines the intended command surface.
A. Base Commands
hf version
hf version
hf health
hf health
No separate auth/login command group is planned. Authentication is entirely handled through padded-cell/pass_mgr mode or explicit manual flags.
B. User Commands
hf user create
hf user create --user <username> [--pass <password>] [--email <email>] [--full-name <name>] [--acc-mgr-token <token>]
hf user list
hf user list [--token <token>]
hf user get
hf user get <username|user-id> [--token <token>]
hf user update
hf user update <username|user-id> [--email <email>] [--full-name <name>] [--pass <password>] [--active <true|false>] [--token <token>]
hf user activate
hf user activate <username|user-id> [--token <token>]
hf user deactivate
hf user deactivate <username|user-id> [--token <token>]
hf user delete
hf user delete <username|user-id> [--token <token>]
hf user worklogsis not planned.
C. Role / Permission Commands
hf role list
hf role list [--token <token>]
hf role get
hf role get <role-name> [--token <token>]
hf role create
hf role create --name <role-name> [--desc <desc>] [--global <true|false>] [--token <token>]
hf role update
hf role update <role-name> [--desc <desc>] [--token <token>]
hf role delete
hf role delete <role-name> [--token <token>]
hf permission list
hf permission list [--token <token>]
hf role set-permissions
hf role set-permissions <role-name> --permission <perm> [--permission <perm> ...] [--token <token>]
hf role add-permissions
hf role add-permissions <role-name> --permission <perm> [--permission <perm> ...] [--token <token>]
hf role remove-permissions
hf role remove-permissions <role-name> --permission <perm> [--permission <perm> ...] [--token <token>]
D. Project Commands
hf project list
hf project list [--owner <username>] [--order-by <created|name>] [--order-by <...>] [--token <token>]
hf project get
hf project get <project-code> [--token <token>]
hf project create
hf project create --name <name> [--desc <desc>] [--repo <repo>] [--token <token>]
hf project update
hf project update <project-code> [--name <name>] [--desc <desc>] [--repo <repo>] [--token <token>]
hf project delete
hf project delete <project-code> [--token <token>]
hf project members
hf project members <project-code> [--token <token>]
hf project add-member
hf project add-member <project-code> --user <username> --role <role-name> [--token <token>]
hf project remove-member
hf project remove-member <project-code> --user <username> [--token <token>]
E. Milestone Commands
hf milestone list
hf milestone list --project <project-code> [--status <status>] [--order-by <due-date|created|name>] [--order-by <...>] [--token <token>]
hf milestone get
hf milestone get <milestone-code> [--token <token>]
hf milestone create
hf milestone create --project <project-code> --title <title> [--desc <desc>] [--due <date>] [--token <token>]
hf milestone update
hf milestone update <milestone-code> [--title <title>] [--desc <desc>] [--status <status>] [--due <date>] [--token <token>]
hf milestone delete
hf milestone delete <milestone-code> [--token <token>]
hf milestone progress
hf milestone progress <milestone-code> [--token <token>]
F. Task Commands
hf task list
hf task list [--project <project-code>] [--milestone <milestone-code>] [--status <status>] [--taken-by <me|null|username>] [--due-today <true|false>] [--order-by <due-date|priority|created|name>] [--order-by <...>] [--token <token>]
Defaults:
--taken-by me--due-today false--order-by due-date
hf task get
hf task get <task-code> [--token <token>]
hf task create
hf task create --project <project-code> --title <title> [--milestone <milestone-code>] [--type <type>] [--priority <priority>] [--desc <desc>] [--token <token>]
hf task update
hf task update <task-code> [--title <title>] [--desc <desc>] [--status <status>] [--priority <priority>] [--assignee <username|null>] [--token <token>]
hf task transition
hf task transition <task-code> <status> [--token <token>]
hf task take
hf task take <task-code> [--token <token>]
Behavior:
- assign the task to the current user
- if already taken by another user or permission rules block the change, return a clear error
hf task delete
hf task delete <task-code> [--token <token>]
hf task search
hf task search --query <text> [--project <project-code>] [--status <status>] [--token <token>]
G. Meeting Commands
Meeting logic is task-like, but the special action is attend, not take.
hf meeting list
hf meeting list [--project <project-code>] [--status <status>] [--order-by <created|due-date|name>] [--order-by <...>] [--token <token>]
hf meeting get
hf meeting get <meeting-code> [--token <token>]
hf meeting create
hf meeting create --project <project-code> --title <title> [--milestone <milestone-code>] [--desc <desc>] [--time <datetime>] [--token <token>]
hf meeting update
hf meeting update <meeting-code> [--title <title>] [--desc <desc>] [--status <status>] [--time <datetime>] [--token <token>]
hf meeting attend
hf meeting attend <meeting-code> [--token <token>]
Behavior:
- add the current user to the meeting participant list
hf meeting delete
hf meeting delete <meeting-code> [--token <token>]
H. Support Commands
Support logic is also task-like.
hf support list
hf support list [--taken-by <me|null|username>] [--status <status>] [--order-by <due-date|priority|created|name>] [--order-by <...>] [--token <token>]
hf support get
hf support get <support-code> [--token <token>]
hf support create
hf support create --title <title> [--project <project-code>] [--desc <desc>] [--priority <priority>] [--token <token>]
hf support update
hf support update <support-code> [--title <title>] [--desc <desc>] [--status <status>] [--priority <priority>] [--token <token>]
hf support take
hf support take <support-code> [--token <token>]
hf support transition
hf support transition <support-code> <status> [--token <token>]
hf support delete
hf support delete <support-code> [--token <token>]
I. Comment / Worklog Commands
hf comment add
hf comment add --task <task-code> --content <text> [--token <token>]
hf comment list
hf comment list --task <task-code> [--token <token>]
hf worklog add
hf worklog add --task <task-code> --hours <n> [--desc <text>] [--date <yyyy-mm-dd>] [--token <token>]
hf worklog list
hf worklog list [--task <task-code>] [--user <username>] [--token <token>]
J. Propose Commands
hf propose list
hf propose list --project <project-code> [--status <status>] [--order-by <created|name>] [--order-by <...>] [--token <token>]
hf propose get
hf propose get <propose-code|propose-id> [--token <token>]
If propose code does not exist yet in backend, the CLI may temporarily accept ids, but code-based lookup is the target direction.
hf propose create
hf propose create --project <project-code> --title <title> --desc <desc> [--token <token>]
hf propose update
hf propose update <propose-code|propose-id> [--title <title>] [--desc <desc>] [--token <token>]
hf propose accept
hf propose accept <propose-code|propose-id> --milestone <milestone-code> [--token <token>]
hf propose reject
hf propose reject <propose-code|propose-id> [--reason <reason>] [--token <token>]
hf propose reopen
hf propose reopen <propose-code|propose-id> [--token <token>]
K. Monitor Commands
hf monitor overview
hf monitor overview [--token <token>]
hf monitor server list
hf monitor server list [--token <token>]
hf monitor server get
hf monitor server get <server-identifier|server-id> [--token <token>]
hf monitor server create
hf monitor server create --identifier <identifier> [--name <display-name>] [--token <token>]
hf monitor server delete
hf monitor server delete <identifier|server-id> [--token <token>]
hf monitor api-key generate
hf monitor api-key generate <identifier|server-id> [--token <token>]
hf monitor api-key revoke
hf monitor api-key revoke <identifier|server-id> [--token <token>]
Backend / Permission Requirements
The CLI design depends on backend support for a narrow account-manager capability.
Required protected roles
In addition to:
adminguest
also protect:
account-manager
account-manager semantics
- default seeded role
- cannot be deleted
- should only have the permission:
account.create
- should not inherit general admin powers
Current alignment
The backend should support:
- single global role per account
- default
guestassignment for normal account creation - admin role protected from normal user-management reassignment
- account-manager flow for creating accounts
Planned Implementation Phases
Phase 1 — Foundation
- create Go module
- add binary entrypoint for
hf - implement config file resolution relative to binary directory
- add
.hf-config.jsonload/save - implement runtime mode detection via
which pass_mgr - implement help renderer (
--helpand--help-brief) - add HTTP client wrapper
Phase 2 — Secrets / Mode Behavior
- implement padded-cell mode flag suppression
- implement manual mode required credential flags
- implement normal token resolution rules
- implement account-manager token resolution rules
- enforce exact failure messages
Phase 3 — Config + Core Commands
hf versionhf healthhf config --urlhf config --acc-mgr-token
Phase 4 — User / Role / Project Baseline
hf user createhf user listhf user gethf user updatehf user activatehf user deactivatehf user deletehf role listhf role gethf project listhf project get
Phase 5 — Task / Milestone / Propose / Monitor
- task commands
- milestone commands
- propose commands
- monitor commands
- meeting commands
- support commands
Phase 6 — Plugin / Install Integration
- rename OpenClaw plugin registration to
harbor-forge - remove plugin-side telemetry
server/sidecar architecture - add plugin config field
monitor_port - add plugin installer flag
--install-cli - build and install
hfinto OpenClaw profilebin/ - copy plugin
skills/into OpenClaw profileskills/
Phase 7 — Monitor / Plugin Local Bridge
- add
MONITOR_PORTto HarborForge.Monitor Docker runtime - expose
127.0.0.1:<MONITOR_PORT>to host in compose - let Monitor query plugin over this local port for OpenClaw metadata
- keep hardware heartbeat / telemetry upload independent of plugin communication
- enrich Monitor uploads with OpenClaw version / plugin version / agent metadata when available
Phase 8 — Hardening
- tests for config-path behavior
- tests for mode switching (
pass_mgrpresent / absent) - tests for exact stderr messages
- tests for help and help-brief rendering
- tests for permission-aware help visibility
- tests for plugin installer behavior (
--install-cli, skills copy) - tests for monitor local bridge behavior with and without plugin connectivity
- binary packaging / release pipeline
Non-Goals (for now)
- do not directly port the old Python CLI architecture
- do not add a separate
authcommand group - do not store normal auth token in
.hf-config.json - do not expose admin role assignment through
hf user create - do not broaden account-manager beyond account creation in the first design