18 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
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 — 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
- 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