Files
HarborForge/archive/achieve/harborforge-cli-go-plan.md

27 KiB

HarborForge CLI (hf) Plan

Goal

Build a Go-based HarborForge CLI binary named:

hf

This CLI should work well in two environments:

  1. With padded-cell / pass_mgr available
    • agents can execute commands directly
    • secrets and generated credentials are resolved automatically
  2. 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.py as-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: use codes/names instead of internal numeric ids
    • project-code
    • milestone-code
    • task-code
    • meeting-code
    • support-code
    • propose-code
    • role-name
    • username

Resource Code Policy

Resource codes are now the canonical user-facing identifiers.

Rules

  • all resource codes are assumed to be unique
  • code format rules are assumed to be defined by the backend already
  • the CLI must accept codes only for resource-oriented commands
  • the CLI must not accept internal numeric ids for those resources
  • CLI list responses must include the resource code for every code-bearing resource

Scope

This applies to:

  • project-code
  • milestone-code
  • task-code
  • meeting-code
  • support-code
  • propose-code

Backend implication

Most backend APIs currently still accept only ids. The backend roadmap should add first-class support for code-based lookup and mutation across these resources.

Additionally:

  • list APIs used by the CLI should always return the resource code in their payloads
  • get/update/delete/action endpoints should support code-based addressing for CLI-targeted resources
  • new CLI-targeted API surface should treat codes as canonical identifiers

Frontend implication

The frontend should also migrate toward code-first lookup and display:

  • prefer code-based routing / lookup over id-based lookup
  • stop surfacing raw ids as primary identifiers in UI
  • update resource detail/list pages to display codes consistently
  • replace existing id-based displays with code-based displays wherever resources already have codes

This is an intentional cross-project requirement and should be applied broadly, not only inside the CLI.


OpenClaw Plugin / Monitor Integration Requirements

This CLI plan now also carries cross-project integration constraints for:

  • HarborForge.OpenclawPlugin
  • HarborForge.Monitor
  • HarborForge.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 server component
  • 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:

  1. build HarborForge.Cli
  2. produce the hf binary
  3. copy the binary into the OpenClaw profile bin directory
  4. chmod +x the 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 copy skills/hf/ into the OpenClaw profile skills directory
  • if installer is run with --install-cli, then skills/hf/ should be copied together with the CLI installation flow

In other words:

  • normal plugin install copies regular plugin skills
  • hf skill 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 hf is 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 --help when 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.Cli
  • HarborForge.OpenclawPlugin
  • HarborForge.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 --token or --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 permitted message 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 create special requirements

Permission Introspection Strategy

The permission introspection strategy is now considered decided.

Normal command permission model

For normal authenticated commands, the CLI should determine permissions through the authenticated user context derived from the token:

  1. resolve the current user from the token
  2. obtain the user's role
  3. obtain that role's permissions
  4. use those effective permissions to determine:
    • --help output
    • --help-brief output
    • whether a subcommand is shown normally or marked (not permitted)

This applies to normal command groups such as:

  • user (except user create)
  • role
  • project
  • milestone
  • task
  • meeting
  • support
  • propose
  • monitor

Special-flow exception: hf user create

hf user create does not use the normal user-token permission model. It remains a special account-manager-token flow.

That means:

  • normal permission introspection from the current user token should not be the gating mechanism for hf user create
  • hf user create help visibility should be handled independently of ordinary user.write capability

Backend implication

Backend support for this strategy should ensure the CLI can derive:

  • current user identity
  • current user's role
  • current role permissions

Whether this comes from one endpoint or multiple backend calls is an implementation detail. The strategy itself is settled: token → user → role → permissions.


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-token must be shown in help
  • --pass may 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-url in <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> [--token <token>]

hf user update

hf user update <username> [--email <email>] [--full-name <name>] [--pass <password>] [--active <true|false>] [--token <token>]

hf user activate

hf user activate <username> [--token <token>]

hf user deactivate

hf user deactivate <username> [--token <token>]

hf user delete

hf user delete <username> [--token <token>]

hf user worklogs is 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 --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> [--token <token>]

hf propose create

hf propose create --project <project-code> --title <title> --desc <desc> [--token <token>]

hf propose update

hf propose update <propose-code> [--title <title>] [--desc <desc>] [--token <token>]

hf propose accept

hf propose accept <propose-code> --milestone <milestone-code> [--token <token>]

hf propose reject

hf propose reject <propose-code> [--reason <reason>] [--token <token>]

hf propose reopen

hf propose reopen <propose-code> [--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 <identifier> [--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> [--token <token>]

hf monitor api-key generate

hf monitor api-key generate <identifier> [--token <token>]

hf monitor api-key revoke

hf monitor api-key revoke <identifier> [--token <token>]

Backend / Permission Requirements

The CLI design depends on backend support for a narrow account-manager capability.

Required protected roles

In addition to:

  • admin
  • guest

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 guest assignment 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.json load/save
  • implement runtime mode detection via which pass_mgr
  • implement help renderer (--help and --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 version
  • hf health
  • hf config --url
  • hf config --acc-mgr-token

Phase 4 — User / Role / Project Baseline

  • hf user create
  • hf user list
  • hf user get
  • hf user update
  • hf user activate
  • hf user deactivate
  • hf user delete
  • hf role list
  • hf role get
  • hf project list
  • hf 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 hf into OpenClaw profile bin/
  • copy plugin skills/ into OpenClaw profile skills/

Phase 7 — Monitor / Plugin Local Bridge

  • add MONITOR_PORT to 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_mgr present / 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

Legacy Python CLI Retirement

After the new hf CLI is complete and functionally replaces the old workflow, the old Python CLI in the backend project should be removed.

That means:

  • remove the legacy backend CLI implementation (currently under HarborForge.Backend)
  • update backend docs so they no longer point users to the old Python CLI
  • treat the Go-based hf binary as the canonical HarborForge CLI going forward

This removal should happen only after the new CLI is sufficiently complete for the intended workflows.


Non-Goals (for now)

  • do not directly port the old Python CLI architecture
  • do not add a separate auth command 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