package help import ( "encoding/json" "git.hangman-lab.top/zhi/HarborForge.Cli/internal/client" "git.hangman-lab.top/zhi/HarborForge.Cli/internal/config" "git.hangman-lab.top/zhi/HarborForge.Cli/internal/mode" "git.hangman-lab.top/zhi/HarborForge.Cli/internal/passmgr" ) type permissionState struct { Known bool Permissions map[string]struct{} } type permissionIntrospectionResponse struct { Username string `json:"username"` RoleName *string `json:"role_name"` IsAdmin bool `json:"is_admin"` Permissions []string `json:"permissions"` } func CommandSurface() []Group { perms := detectPermissionState() groups := []Group{ {Name: "version", Description: "Show CLI version", Permitted: true}, {Name: "health", Description: "Check API health", Permitted: true}, {Name: "config", Description: "View and manage CLI configuration", Permitted: true}, { Name: "user", Description: "Manage users", SubCommands: []Command{ {Name: "create", Description: "Create a user account (uses account-manager token flow)", Permitted: true}, {Name: "list", Description: "List users", Permitted: has(perms, "user.manage")}, {Name: "get", Description: "Show a user by username", Permitted: has(perms, "user.manage")}, {Name: "update", Description: "Update a user", Permitted: has(perms, "user.manage")}, {Name: "activate", Description: "Activate a user", Permitted: has(perms, "user.manage")}, {Name: "deactivate", Description: "Deactivate a user", Permitted: has(perms, "user.manage")}, {Name: "delete", Description: "Delete a user", Permitted: has(perms, "user.manage")}, }, }, { Name: "role", Description: "Manage roles and permissions", SubCommands: []Command{ {Name: "list", Description: "List roles", Permitted: has(perms, "role.manage")}, {Name: "get", Description: "Show a role by name", Permitted: has(perms, "role.manage")}, {Name: "create", Description: "Create a role", Permitted: has(perms, "role.manage")}, {Name: "update", Description: "Update a role", Permitted: has(perms, "role.manage")}, {Name: "delete", Description: "Delete a role", Permitted: has(perms, "role.manage")}, {Name: "set-permissions", Description: "Replace role permissions", Permitted: has(perms, "role.manage")}, {Name: "add-permissions", Description: "Add permissions to a role", Permitted: has(perms, "role.manage")}, {Name: "remove-permissions", Description: "Remove permissions from a role", Permitted: has(perms, "role.manage")}, }, }, { Name: "permission", Description: "List permissions", SubCommands: []Command{{Name: "list", Description: "List permissions", Permitted: has(perms, "role.manage")}}, }, { Name: "project", Description: "Manage projects", SubCommands: []Command{ {Name: "list", Description: "List projects", Permitted: has(perms, "project.read")}, {Name: "get", Description: "Show a project by code", Permitted: has(perms, "project.read")}, {Name: "create", Description: "Create a project", Permitted: has(perms, "project.write")}, {Name: "update", Description: "Update a project", Permitted: has(perms, "project.write")}, {Name: "delete", Description: "Delete a project", Permitted: has(perms, "project.delete")}, {Name: "members", Description: "List project members", Permitted: has(perms, "project.read")}, {Name: "add-member", Description: "Add a project member", Permitted: has(perms, "project.manage_members")}, {Name: "remove-member", Description: "Remove a project member", Permitted: has(perms, "project.manage_members")}, }, }, { Name: "milestone", Description: "Manage milestones", SubCommands: []Command{ {Name: "list", Description: "List milestones", Permitted: has(perms, "milestone.read")}, {Name: "get", Description: "Show a milestone by code", Permitted: has(perms, "milestone.read")}, {Name: "create", Description: "Create a milestone", Permitted: has(perms, "milestone.create")}, {Name: "update", Description: "Update a milestone", Permitted: has(perms, "milestone.write")}, {Name: "delete", Description: "Delete a milestone", Permitted: has(perms, "milestone.delete")}, {Name: "progress", Description: "Show milestone progress", Permitted: has(perms, "milestone.read")}, }, }, { Name: "task", Description: "Manage tasks", SubCommands: []Command{ {Name: "list", Description: "List tasks", Permitted: has(perms, "task.read")}, {Name: "get", Description: "Show a task by code", Permitted: has(perms, "task.read")}, {Name: "create", Description: "Create a task", Permitted: has(perms, "task.create")}, {Name: "update", Description: "Update a task", Permitted: has(perms, "task.write")}, {Name: "transition", Description: "Transition a task to a new status", Permitted: has(perms, "task.write")}, {Name: "take", Description: "Assign a task to the current user", Permitted: has(perms, "task.write")}, {Name: "delete", Description: "Delete a task", Permitted: has(perms, "task.delete")}, {Name: "search", Description: "Search tasks", Permitted: has(perms, "task.read")}, }, }, { Name: "meeting", Description: "Manage meetings", SubCommands: []Command{ {Name: "list", Description: "List meetings", Permitted: has(perms, "task.read")}, {Name: "get", Description: "Show a meeting by code", Permitted: has(perms, "task.read")}, {Name: "create", Description: "Create a meeting", Permitted: has(perms, "task.create")}, {Name: "update", Description: "Update a meeting", Permitted: has(perms, "task.write")}, {Name: "attend", Description: "Attend a meeting", Permitted: has(perms, "task.write")}, {Name: "delete", Description: "Delete a meeting", Permitted: has(perms, "task.delete")}, }, }, { Name: "support", Description: "Manage support tickets", SubCommands: []Command{ {Name: "list", Description: "List support tickets", Permitted: has(perms, "task.read")}, {Name: "get", Description: "Show a support ticket by code", Permitted: has(perms, "task.read")}, {Name: "create", Description: "Create a support ticket", Permitted: has(perms, "task.create")}, {Name: "update", Description: "Update a support ticket", Permitted: has(perms, "task.write")}, {Name: "take", Description: "Assign a support ticket to the current user", Permitted: has(perms, "task.write")}, {Name: "transition", Description: "Transition a support ticket to a new status", Permitted: has(perms, "task.write")}, {Name: "delete", Description: "Delete a support ticket", Permitted: has(perms, "task.delete")}, }, }, { Name: "propose", Description: "Manage proposals", SubCommands: []Command{ {Name: "list", Description: "List proposals", Permitted: has(perms, "project.read")}, {Name: "get", Description: "Show a proposal by code", Permitted: has(perms, "project.read")}, {Name: "create", Description: "Create a proposal", Permitted: has(perms, "task.create")}, {Name: "update", Description: "Update a proposal", Permitted: has(perms, "task.write")}, {Name: "accept", Description: "Accept a proposal", Permitted: has(perms, "propose.accept")}, {Name: "reject", Description: "Reject a proposal", Permitted: has(perms, "propose.reject")}, {Name: "reopen", Description: "Reopen a proposal", Permitted: has(perms, "propose.reopen")}, }, }, { Name: "comment", Description: "Manage task comments", SubCommands: []Command{ {Name: "add", Description: "Add a comment to a task", Permitted: has(perms, "task.read")}, {Name: "list", Description: "List comments for a task", Permitted: has(perms, "task.read")}, }, }, { Name: "worklog", Description: "Manage work logs", SubCommands: []Command{ {Name: "add", Description: "Add a work log entry", Permitted: has(perms, "task.read")}, {Name: "list", Description: "List work logs by task or user", Permitted: has(perms, "task.read")}, }, }, { Name: "monitor", Description: "Monitor servers and API keys", SubCommands: []Command{ {Name: "overview", Description: "Show monitor overview", Permitted: has(perms, "monitor.read")}, {Name: "server", Description: "Manage monitor servers", Permitted: has(perms, "monitor.manage") || has(perms, "monitor.read")}, {Name: "api-key", Description: "Manage monitor API keys", Permitted: has(perms, "monitor.manage")}, }, }, } for i := range groups { groups[i].Permitted = groupPermitted(groups[i]) } return groups } func detectPermissionState() permissionState { if mode.IsPaddedCell() { token, err := passmgr.GetToken() if err != nil || token == "" { return permissionState{Known: false, Permissions: map[string]struct{}{}} } return loadPermissionState(token) } return permissionState{Known: false, Permissions: map[string]struct{}{}} } func loadPermissionState(token string) permissionState { cfg, err := config.Load() if err != nil || cfg.BaseURL == "" { return permissionState{Known: false, Permissions: map[string]struct{}{}} } c := client.New(cfg.BaseURL, token) data, err := c.Get("/auth/me/permissions") if err != nil { return permissionState{Known: false, Permissions: map[string]struct{}{}} } var resp permissionIntrospectionResponse if err := json.Unmarshal(data, &resp); err != nil { return permissionState{Known: false, Permissions: map[string]struct{}{}} } perms := make(map[string]struct{}, len(resp.Permissions)) for _, perm := range resp.Permissions { perms[perm] = struct{}{} } return permissionState{Known: true, Permissions: perms} } func has(state permissionState, perm string) bool { if !state.Known { return false } _, ok := state.Permissions[perm] return ok } func groupPermitted(group Group) bool { if len(group.SubCommands) == 0 { return group.Permitted } for _, cmd := range group.SubCommands { if cmd.Permitted { return true } } return false }