BREAKING:
- Flat oo verb-noun layout replaced with subject → verb, mirroring the
gitea `tea` CLI. Every subject is one file in cmd/oo/:
oo calendar list | events | add | delete
oo projects list | get | milestones | create | update | delete
oo tasks list | get | create | update | delete | subtask add
oo users list | self (alias: oo whoami)
oo contacts list | get | delete | info-add
oo persons list | create | delete
oo companies list | create | delete
oo opportunities list | get | create | delete | stages | member-add
oo cases list | create | delete | member-add
oo crm-tasks list | create | delete | categories
oo applications sync
- Global `--output/-o table|json` flag on the root command; every list uses
a single printTable helper that flattens nested bidCurrency → abbreviation
for readability, truncates long cells, and dumps verbatim in JSON mode.
Library additions surfaced in the CLI:
- oo users / oo whoami via SelfUserID + GetUsers.
- oo projects full CRUD via Create/Update/Delete/GetProjectByID/Milestones.
- oo crm-tasks and oo cases via ListCRMTasks/CreateCRMTask/DeleteCRMTask/
ListTaskCategories/ListCases/CreateCase/DeleteCase/AddCaseMember.
- oo contacts info-add via AddContactInfo.
- oo opportunities stages/member-add via ListDealStages/AddOpportunityMember.
Internal:
- cmd/oo/common.go — rootCmd, newOO (uses AuthenticateContext), printTable,
printObject, fmtCell, deref* helpers.
- cmd/oo/crm.go deleted; content split into contacts.go, opportunities.go,
cases.go, crm_tasks.go for locality.
Docs:
- README: new subject→verb table + migration note.
- AGENTS.md: CLI section rewritten; new rule enforcing subject→verb and
printTable/printObject routing.
- CHANGELOG: 0.5.0 entry with full old→new mapping.
Made-with: Cursor
94 lines
2.0 KiB
Go
94 lines
2.0 KiB
Go
package main
|
|
|
|
import (
|
|
"github.com/spf13/cobra"
|
|
)
|
|
|
|
var usersCmd = &cobra.Command{
|
|
Use: "users",
|
|
Short: "Portal / workspace users",
|
|
}
|
|
|
|
func init() {
|
|
rootCmd.AddCommand(usersCmd)
|
|
usersCmd.AddCommand(usersListCmd())
|
|
usersCmd.AddCommand(usersSelfCmd())
|
|
rootCmd.AddCommand(whoamiCmd())
|
|
}
|
|
|
|
func usersListCmd() *cobra.Command {
|
|
return &cobra.Command{
|
|
Use: "list",
|
|
Short: "List portal users",
|
|
RunE: func(cmd *cobra.Command, args []string) error {
|
|
c, err := newOO(cmd)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
users, err := c.GetUsers()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
rows := make([]map[string]any, 0, len(users))
|
|
for _, u := range users {
|
|
rows = append(rows, map[string]any{
|
|
"id": derefString(u.ID),
|
|
"userName": derefString(u.UserName),
|
|
"displayName": derefString(u.DisplayName),
|
|
"email": derefString(u.Email),
|
|
"isAdmin": derefBool(u.IsAdmin),
|
|
"status": derefInt(u.Status),
|
|
})
|
|
}
|
|
printTable([]string{"id", "userName", "displayName", "email", "isAdmin", "status"}, rows)
|
|
return nil
|
|
},
|
|
}
|
|
}
|
|
|
|
func usersSelfCmd() *cobra.Command {
|
|
return &cobra.Command{
|
|
Use: "self",
|
|
Short: "Show current user id (people/@self)",
|
|
RunE: func(cmd *cobra.Command, args []string) error {
|
|
c, err := newOO(cmd)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
id, err := c.SelfUserID(cmd.Context())
|
|
if err != nil {
|
|
return err
|
|
}
|
|
printObject(map[string]any{"id": id})
|
|
return nil
|
|
},
|
|
}
|
|
}
|
|
|
|
// whoamiCmd is a convenience shortcut at the root level.
|
|
func whoamiCmd() *cobra.Command {
|
|
return &cobra.Command{
|
|
Use: "whoami",
|
|
Short: "Alias for `oo users self`",
|
|
RunE: func(cmd *cobra.Command, args []string) error {
|
|
c, err := newOO(cmd)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
id, err := c.SelfUserID(cmd.Context())
|
|
if err != nil {
|
|
return err
|
|
}
|
|
printObject(map[string]any{"id": id})
|
|
return nil
|
|
},
|
|
}
|
|
}
|
|
|
|
func derefBool(p *bool) bool {
|
|
if p == nil {
|
|
return false
|
|
}
|
|
return *p
|
|
}
|