From 8086797a72712b4174daae7e405117de3187a758 Mon Sep 17 00:00:00 2001 From: zhi Date: Sat, 21 Mar 2026 11:15:20 +0000 Subject: [PATCH] docs: expand hf CLI plan and command specification --- plans/harborforge-cli-go-plan.md | 891 +++++++++++++++++++++++++------ 1 file changed, 716 insertions(+), 175 deletions(-) diff --git a/plans/harborforge-cli-go-plan.md b/plans/harborforge-cli-go-plan.md index cf0f92c..8c64b67 100644 --- a/plans/harborforge-cli-go-plan.md +++ b/plans/harborforge-cli-go-plan.md @@ -1,20 +1,23 @@ -# HarborForge CLI (Go Binary) Plan +# HarborForge CLI (hf) Plan ## Goal -Build a **Go-based HarborForge CLI binary**. +Build a **Go-based HarborForge CLI binary** named: -This CLI is intended to work in two modes: +```bash +hf +``` -1. **With padded-cell / pass_mgr available** - - agents can use it directly - - secrets and generated credentials can be managed automatically +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 it by explicitly passing tokens/passwords + - 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. -> The old CLI is only a reference for existing command coverage. -> The new CLI should be implemented as a standalone Go binary. +> That old CLI is only a reference for command inventory. The new CLI must be a standalone **Go binary**. --- @@ -24,23 +27,35 @@ This CLI is intended to work in two modes: - Delivery: **single binary** - Config file: `.hf-config.json` - Config location: **same directory as the CLI binary** -- Secret manager integration: `pass_mgr` -- Design goal: - - compatible with automated agent usage - - also usable manually without padded-cell/pass_mgr +- 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-code` + - `milestone-code` + - `task-code` + - `meeting-code` + - `support-code` + - `role-name` + - `username` --- ## Binary / Config Model -Assume CLI name is placeholder `` for now. +## CLI name -### Config file location +```bash +hf +``` + +## Config file location + +`hf` must resolve its config file relative to the **binary directory**, not cwd and not home directory. The command: ```bash - config --url +hf config --url ``` must write: @@ -57,9 +72,7 @@ into: /.hf-config.json ``` -That means config resolution is based on the **directory where the binary lives**, not cwd and not home directory. - -### Config contents (initial) +## Initial config structure ```json { @@ -67,259 +80,787 @@ That means config resolution is based on the **directory where the binary lives* } ``` -Initial config scope is intentionally small. +The config file should remain intentionally minimal at first. --- -## CLI Command Requirements +## Runtime Mode Detection -## 1. Config command - -### Set HarborForge base URL +At startup, the CLI must check whether `pass_mgr` exists: ```bash - config --url +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: + +```text +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: + +```bash +pass_mgr get-secret --key hf-token +``` + +For account-manager flow: + +```bash +pass_mgr get-secret --public --key hf-acc-mgr-token +``` + +For password generation during user creation: + +```bash +pass_mgr generate --key hf --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 --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: + +```text +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 --help-brief` + +Show only currently **permitted** subcommands. + +Example: + +```text +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 --help` + +- If permitted: show full help +- If not permitted: show only a short message such as: + +```text +hf user update: not permitted +``` + +No detailed usage, no flags, no examples. + +## 6. `hf --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 + +--- + +## 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: + +```bash +pass_mgr get-secret --key hf-token +``` + +### manual mode +- `--token ` becomes required +- if missing, terminate with: + +```text +--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: + +```bash +hf user create --user [--pass ] [--email ] [--full-name ] [--acc-mgr-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: + +```bash +pass_mgr generate --key hf --username +``` + +- account-manager token fallback: + +```bash +pass_mgr get-secret --public --key hf-acc-mgr-token +``` + +If password generation fails: + +```text +--pass required or execute with pcexec +``` + +If account-manager token lookup fails: + +```text +--acc-mgr-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 + +```bash +hf config --url ``` Behavior: - write/update `base-url` in `/.hf-config.json` -### Set account-manager token through pass_mgr +## 2. Configure account-manager token ```bash - config --acc-mgr-token +hf config --acc-mgr-token ``` Behavior: - execute: ```bash -pass_mgr set --public --key hf-acc-mgr-token --secret $token +pass_mgr set --public --key hf-acc-mgr-token --secret ``` -If this fails, terminate with: +If this fails: ```text --acc-mgr-token can only be set with padded-cell plugin ``` -This is intentionally a hard error because this path depends on `pass_mgr` availability. +--- + +## Supported Command Tree + +This section defines the intended command surface. --- -## 2. Normal authenticated commands - -General form: +## A. Base Commands +### `hf version` ```bash - [--token ] +hf version ``` -### Token resolution order - -1. If `--token ` is explicitly provided, use it. -2. Otherwise try: - +### `hf health` ```bash -pass_mgr get-secret --key hf-token +hf health ``` -If this fails, print stderr and terminate with exactly: - -```text ---token required or execute this with pcexec -``` - -### Notes - -- Normal API commands should support optional `--token` -- They should also support agent-oriented execution when `pass_mgr` exists -- They should remain usable manually when users explicitly provide `--token` +> No separate auth/login command group is planned. +> Authentication is entirely handled through padded-cell/pass_mgr mode or explicit manual flags. --- -## 3. Special command: create-account - -Command shape: +## B. User Commands +### `hf user create` ```bash - create-account --user [--pass ] [--acc-mgr-token ] +hf user create --user [--pass ] [--email ] [--full-name ] [--acc-mgr-token ] ``` -### Special rules - -- `create-account` **cannot** accept `--token` -- `create-account` should **not** attempt normal token auto-resolution -- It uses **account-manager token** instead of the normal user token flow - -### Password resolution - -If `--pass ` is not explicitly provided, try: - +### `hf user list` ```bash -pass_mgr generate --key hf --username $username +hf user list [--token ] ``` -If this fails, print stderr and terminate with exactly: - -```text ---pass required or execute with pcexec -``` - -### Account-manager token resolution - -If `--acc-mgr-token ` is not explicitly provided, try: - +### `hf user get` ```bash -pass_mgr get-secret --public --key hf-acc-mgr-token +hf user get [--token ] ``` -If this fails, print stderr and terminate with exactly: - -```text ---acc-mgr-token required or execute with pcexec +### `hf user update` +```bash +hf user update [--email ] [--full-name ] [--pass ] [--active ] [--token ] ``` -### Purpose +### `hf user activate` +```bash +hf user activate [--token ] +``` -This command is meant to work very naturally with padded-cell-driven agent flows while still allowing manual operator input. +### `hf user deactivate` +```bash +hf user deactivate [--token ] +``` + +### `hf user delete` +```bash +hf user delete [--token ] +``` + +> `hf user worklogs` is not planned. --- -## pass_mgr Integration Rules +## C. Role / Permission Commands -The CLI should treat `pass_mgr` as an optional capability. +### `hf role list` +```bash +hf role list [--token ] +``` -### With padded-cell / pass_mgr +### `hf role get` +```bash +hf role get [--token ] +``` -Expected conveniences: -- persistent token lookup from `hf-token` -- public account-manager token lookup from `hf-acc-mgr-token` -- password generation via `pass_mgr generate` +### `hf role create` +```bash +hf role create --name [--desc ] [--global ] [--token ] +``` -### Without padded-cell / pass_mgr +### `hf role update` +```bash +hf role update [--desc ] [--token ] +``` -Expected fallback: -- users manually pass `--token` -- users manually pass `--pass` -- users manually pass `--acc-mgr-token` +### `hf role delete` +```bash +hf role delete [--token ] +``` -### Error philosophy +### `hf permission list` +```bash +hf permission list [--token ] +``` -Do not silently ignore secret-manager failures. -If the command depends on pass_mgr fallback and it is unavailable, fail with the exact operator-facing messages defined above. +### `hf role set-permissions` +```bash +hf role set-permissions --permission [--permission ...] [--token ] +``` + +### `hf role add-permissions` +```bash +hf role add-permissions --permission [--permission ...] [--token ] +``` + +### `hf role remove-permissions` +```bash +hf role remove-permissions --permission [--permission ...] [--token ] +``` + +--- + +## D. Project Commands + +### `hf project list` +```bash +hf project list [--owner ] [--order-by ] [--order-by <...>] [--token ] +``` + +### `hf project get` +```bash +hf project get [--token ] +``` + +### `hf project create` +```bash +hf project create --name [--desc ] [--repo ] [--token ] +``` + +### `hf project update` +```bash +hf project update [--name ] [--desc ] [--repo ] [--token ] +``` + +### `hf project delete` +```bash +hf project delete [--token ] +``` + +### `hf project members` +```bash +hf project members [--token ] +``` + +### `hf project add-member` +```bash +hf project add-member --user --role [--token ] +``` + +### `hf project remove-member` +```bash +hf project remove-member --user [--token ] +``` + +--- + +## E. Milestone Commands + +### `hf milestone list` +```bash +hf milestone list --project [--status ] [--order-by ] [--order-by <...>] [--token ] +``` + +### `hf milestone get` +```bash +hf milestone get [--token ] +``` + +### `hf milestone create` +```bash +hf milestone create --project --title [--desc <desc>] [--due <date>] [--token <token>] +``` + +### `hf milestone update` +```bash +hf milestone update <milestone-code> [--title <title>] [--desc <desc>] [--status <status>] [--due <date>] [--token <token>] +``` + +### `hf milestone delete` +```bash +hf milestone delete <milestone-code> [--token <token>] +``` + +### `hf milestone progress` +```bash +hf milestone progress <milestone-code> [--token <token>] +``` + +--- + +## F. Task Commands + +### `hf task list` +```bash +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` +```bash +hf task get <task-code> [--token <token>] +``` + +### `hf task create` +```bash +hf task create --project <project-code> --title <title> [--milestone <milestone-code>] [--type <type>] [--priority <priority>] [--desc <desc>] [--token <token>] +``` + +### `hf task update` +```bash +hf task update <task-code> [--title <title>] [--desc <desc>] [--status <status>] [--priority <priority>] [--assignee <username|null>] [--token <token>] +``` + +### `hf task transition` +```bash +hf task transition <task-code> <status> [--token <token>] +``` + +### `hf task take` +```bash +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` +```bash +hf task delete <task-code> [--token <token>] +``` + +### `hf task search` +```bash +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` +```bash +hf meeting list [--project <project-code>] [--status <status>] [--order-by <created|due-date|name>] [--order-by <...>] [--token <token>] +``` + +### `hf meeting get` +```bash +hf meeting get <meeting-code> [--token <token>] +``` + +### `hf meeting create` +```bash +hf meeting create --project <project-code> --title <title> [--milestone <milestone-code>] [--desc <desc>] [--time <datetime>] [--token <token>] +``` + +### `hf meeting update` +```bash +hf meeting update <meeting-code> [--title <title>] [--desc <desc>] [--status <status>] [--time <datetime>] [--token <token>] +``` + +### `hf meeting attend` +```bash +hf meeting attend <meeting-code> [--token <token>] +``` + +Behavior: +- add the current user to the meeting participant list + +### `hf meeting delete` +```bash +hf meeting delete <meeting-code> [--token <token>] +``` + +--- + +## H. Support Commands + +Support logic is also task-like. + +### `hf support list` +```bash +hf support list [--taken-by <me|null|username>] [--status <status>] [--order-by <due-date|priority|created|name>] [--order-by <...>] [--token <token>] +``` + +### `hf support get` +```bash +hf support get <support-code> [--token <token>] +``` + +### `hf support create` +```bash +hf support create --title <title> [--project <project-code>] [--desc <desc>] [--priority <priority>] [--token <token>] +``` + +### `hf support update` +```bash +hf support update <support-code> [--title <title>] [--desc <desc>] [--status <status>] [--priority <priority>] [--token <token>] +``` + +### `hf support take` +```bash +hf support take <support-code> [--token <token>] +``` + +### `hf support transition` +```bash +hf support transition <support-code> <status> [--token <token>] +``` + +### `hf support delete` +```bash +hf support delete <support-code> [--token <token>] +``` + +--- + +## I. Comment / Worklog Commands + +### `hf comment add` +```bash +hf comment add --task <task-code> --content <text> [--token <token>] +``` + +### `hf comment list` +```bash +hf comment list --task <task-code> [--token <token>] +``` + +### `hf worklog add` +```bash +hf worklog add --task <task-code> --hours <n> [--desc <text>] [--date <yyyy-mm-dd>] [--token <token>] +``` + +### `hf worklog list` +```bash +hf worklog list [--task <task-code>] [--user <username>] [--token <token>] +``` + +--- + +## J. Propose Commands + +### `hf propose list` +```bash +hf propose list --project <project-code> [--status <status>] [--order-by <created|name>] [--order-by <...>] [--token <token>] +``` + +### `hf propose get` +```bash +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` +```bash +hf propose create --project <project-code> --title <title> --desc <desc> [--token <token>] +``` + +### `hf propose update` +```bash +hf propose update <propose-code|propose-id> [--title <title>] [--desc <desc>] [--token <token>] +``` + +### `hf propose accept` +```bash +hf propose accept <propose-code|propose-id> --milestone <milestone-code> [--token <token>] +``` + +### `hf propose reject` +```bash +hf propose reject <propose-code|propose-id> [--reason <reason>] [--token <token>] +``` + +### `hf propose reopen` +```bash +hf propose reopen <propose-code|propose-id> [--token <token>] +``` + +--- + +## K. Monitor Commands + +### `hf monitor overview` +```bash +hf monitor overview [--token <token>] +``` + +### `hf monitor server list` +```bash +hf monitor server list [--token <token>] +``` + +### `hf monitor server get` +```bash +hf monitor server get <server-identifier|server-id> [--token <token>] +``` + +### `hf monitor server create` +```bash +hf monitor server create --identifier <identifier> [--name <display-name>] [--token <token>] +``` + +### `hf monitor server delete` +```bash +hf monitor server delete <identifier|server-id> [--token <token>] +``` + +### `hf monitor api-key generate` +```bash +hf monitor api-key generate <identifier|server-id> [--token <token>] +``` + +### `hf monitor api-key revoke` +```bash +hf monitor api-key revoke <identifier|server-id> [--token <token>] +``` --- ## Backend / Permission Requirements -The new CLI plan implies backend support for an **account-manager** capability. +The CLI design depends on backend support for a narrow **account-manager** capability. -### New protected default role +## Required protected roles -In addition to existing undeletable default roles: +In addition to: - `admin` - `guest` -add: +also protect: - `account-manager` -### account-manager semantics +## account-manager semantics -- role is part of initial bootstrap/default roles -- role cannot be deleted -- role permissions should be limited to: - - **create account** +- default seeded role +- cannot be deleted +- should only have the permission: + - `account.create` +- should not inherit general admin powers -This is intentionally narrow. -It should not inherit general admin privileges. +## Current alignment -### Backend work implied by this plan - -- seed `account-manager` during initial role setup -- protect it from deletion the same way default protected roles are protected -- add a backend permission / route policy for account creation by account-manager -- make sure CLI `create-account` maps onto this backend capability cleanly +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 --- -## Proposed CLI Implementation Phases +## Planned Implementation Phases ## Phase 1 — Foundation - create Go module -- add binary entrypoint -- add config loader/saver for `<binary-dir>/.hf-config.json` +- 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 -- add token resolution helpers -- add pass_mgr execution wrapper -- define clear error handling / stderr behavior -## Phase 2 — Auth + Config Flows +## Phase 2 — Secrets / Mode Behavior -- implement `config --url` -- implement `config --acc-mgr-token` -- implement shared `--token` resolution behavior -- implement request auth injection +- 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 — Account Creation Flow +## Phase 3 — Config + Core Commands -- implement `create-account` -- support `--user` -- support optional `--pass` -- support optional `--acc-mgr-token` -- add pass_mgr-backed fallback logic -- enforce exact required error messages +- `hf version` +- `hf health` +- `hf config --url` +- `hf config --acc-mgr-token` -## Phase 4 — Command Expansion +## Phase 4 — User / Role / Project Baseline -Use existing `HarborForge.Backend/cli.py` only as feature inventory reference. -Do **not** copy its architecture directly. +- `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` -Potential later commands: -- projects -- users -- milestones -- tasks -- proposes -- monitor-related commands -- health / version +## Phase 5 — Task / Milestone / Propose / Monitor -## Phase 5 — Hardening +- task commands +- milestone commands +- propose commands +- monitor commands +- meeting commands +- support commands -- tests for config path resolution -- tests for pass_mgr failure behavior -- tests for explicit token/password override behavior +## Phase 6 — Hardening + +- tests for config-path behavior +- tests for mode switching (`pass_mgr` present / absent) - tests for exact stderr messages -- packaging / release pipeline for binary builds - ---- - -## Open Questions - -1. Final binary name: - - `harborforge` - - `hf` - - `harborforge-cli` - - or another name - -2. `create-account` backend API contract: - - new dedicated route? - - or reuse/extend current user creation route? - -3. Whether normal token lookup should support additional fallbacks later: - - env var - - config file token - - OS keychain - -Current plan intentionally keeps fallback logic narrow and explicit. +- 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 old Python CLI architecture -- do not require padded-cell for all usage -- do not store auth token in `.hf-config.json` -- do not make `account-manager` an admin-like role -- do not broaden account-manager permissions beyond account creation in the initial design +- 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