diff --git a/HarborForge.Backend b/HarborForge.Backend index 7d42d56..271d514 160000 --- a/HarborForge.Backend +++ b/HarborForge.Backend @@ -1 +1 @@ -Subproject commit 7d42d567d1c33ab6fef5bcc1b720a3877516543c +Subproject commit 271d5140e63a7c961b6a964b8aed91e6d30b40b4 diff --git a/HarborForge.Frontend b/HarborForge.Frontend index 50563f2..fd28bb6 160000 --- a/HarborForge.Frontend +++ b/HarborForge.Frontend @@ -1 +1 @@ -Subproject commit 50563f2b3d9780307d9bc94ef4328ea231a8e3b2 +Subproject commit fd28bb6b6f580110fa9338f6b72da9fa53b41d3c diff --git a/ZHI_TASKS.md b/archive/completed-plans/ZHI_TASKS.md similarity index 100% rename from ZHI_TASKS.md rename to archive/completed-plans/ZHI_TASKS.md diff --git a/plans/harborforge-cli-go-plan.md b/plans/harborforge-cli-go-plan.md new file mode 100644 index 0000000..cf0f92c --- /dev/null +++ b/plans/harborforge-cli-go-plan.md @@ -0,0 +1,325 @@ +# HarborForge CLI (Go Binary) Plan + +## Goal + +Build a **Go-based HarborForge CLI binary**. + +This CLI is intended to work in two modes: + +1. **With padded-cell / pass_mgr available** + - agents can use it directly + - secrets and generated credentials can be managed automatically +2. **Without padded-cell installed** + - humans can still use it by explicitly passing tokens/passwords + +> 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. + +--- + +## High-Level Direction + +- Language: **Go** +- 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 + +--- + +## Binary / Config Model + +Assume CLI name is placeholder `` for now. + +### Config file location + +The command: + +```bash + config --url +``` + +must write: + +```json +{ + "base-url": "" +} +``` + +into: + +```text +/.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) + +```json +{ + "base-url": "http://127.0.0.1:8000" +} +``` + +Initial config scope is intentionally small. + +--- + +## CLI Command Requirements + +## 1. Config command + +### Set HarborForge base URL + +```bash + config --url +``` + +Behavior: +- write/update `base-url` in `/.hf-config.json` + +### Set account-manager token through pass_mgr + +```bash + config --acc-mgr-token +``` + +Behavior: +- execute: + +```bash +pass_mgr set --public --key hf-acc-mgr-token --secret $token +``` + +If this fails, terminate with: + +```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. + +--- + +## 2. Normal authenticated commands + +General form: + +```bash + [--token ] +``` + +### Token resolution order + +1. If `--token ` is explicitly provided, use it. +2. Otherwise try: + +```bash +pass_mgr get-secret --key hf-token +``` + +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` + +--- + +## 3. Special command: create-account + +Command shape: + +```bash + create-account --user [--pass ] [--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: + +```bash +pass_mgr generate --key hf --username $username +``` + +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: + +```bash +pass_mgr get-secret --public --key hf-acc-mgr-token +``` + +If this fails, print stderr and terminate with exactly: + +```text +--acc-mgr-token required or execute with pcexec +``` + +### Purpose + +This command is meant to work very naturally with padded-cell-driven agent flows while still allowing manual operator input. + +--- + +## pass_mgr Integration Rules + +The CLI should treat `pass_mgr` as an optional capability. + +### With padded-cell / pass_mgr + +Expected conveniences: +- persistent token lookup from `hf-token` +- public account-manager token lookup from `hf-acc-mgr-token` +- password generation via `pass_mgr generate` + +### Without padded-cell / pass_mgr + +Expected fallback: +- users manually pass `--token` +- users manually pass `--pass` +- users manually pass `--acc-mgr-token` + +### Error philosophy + +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. + +--- + +## Backend / Permission Requirements + +The new CLI plan implies backend support for an **account-manager** capability. + +### New protected default role + +In addition to existing undeletable default roles: +- `admin` +- `guest` + +add: +- `account-manager` + +### account-manager semantics + +- role is part of initial bootstrap/default roles +- role cannot be deleted +- role permissions should be limited to: + - **create account** + +This is intentionally narrow. +It should not inherit general admin privileges. + +### 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 + +--- + +## Proposed CLI Implementation Phases + +## Phase 1 — Foundation + +- create Go module +- add binary entrypoint +- add config loader/saver for `/.hf-config.json` +- add HTTP client wrapper +- add token resolution helpers +- add pass_mgr execution wrapper +- define clear error handling / stderr behavior + +## Phase 2 — Auth + Config Flows + +- implement `config --url` +- implement `config --acc-mgr-token` +- implement shared `--token` resolution behavior +- implement request auth injection + +## Phase 3 — Account Creation Flow + +- implement `create-account` +- support `--user` +- support optional `--pass` +- support optional `--acc-mgr-token` +- add pass_mgr-backed fallback logic +- enforce exact required error messages + +## Phase 4 — Command Expansion + +Use existing `HarborForge.Backend/cli.py` only as feature inventory reference. +Do **not** copy its architecture directly. + +Potential later commands: +- projects +- users +- milestones +- tasks +- proposes +- monitor-related commands +- health / version + +## Phase 5 — Hardening + +- tests for config path resolution +- tests for pass_mgr failure behavior +- tests for explicit token/password override behavior +- 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. + +--- + +## 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