feat(cli): add workspace get and members commands
Expose workspace details (including context field) and member listing via the CLI so agents can dynamically query workspace context instead of relying on static snapshots. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
daecf7985c
commit
4a62b98c9a
1 changed files with 115 additions and 0 deletions
|
|
@ -6,6 +6,7 @@ import (
|
|||
"os"
|
||||
"text/tabwriter"
|
||||
"time"
|
||||
"unicode/utf8"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
|
|
@ -23,6 +24,20 @@ var workspaceListCmd = &cobra.Command{
|
|||
RunE: runWorkspaceList,
|
||||
}
|
||||
|
||||
var workspaceGetCmd = &cobra.Command{
|
||||
Use: "get [workspace-id]",
|
||||
Short: "Get workspace details",
|
||||
Args: cobra.MaximumNArgs(1),
|
||||
RunE: runWorkspaceGet,
|
||||
}
|
||||
|
||||
var workspaceMembersCmd = &cobra.Command{
|
||||
Use: "members [workspace-id]",
|
||||
Short: "List workspace members",
|
||||
Args: cobra.MaximumNArgs(1),
|
||||
RunE: runWorkspaceMembers,
|
||||
}
|
||||
|
||||
var workspaceWatchCmd = &cobra.Command{
|
||||
Use: "watch <workspace-id>",
|
||||
Short: "Add a workspace to the daemon watch list",
|
||||
|
|
@ -39,8 +54,13 @@ var workspaceUnwatchCmd = &cobra.Command{
|
|||
|
||||
func init() {
|
||||
workspaceCmd.AddCommand(workspaceListCmd)
|
||||
workspaceCmd.AddCommand(workspaceGetCmd)
|
||||
workspaceCmd.AddCommand(workspaceMembersCmd)
|
||||
workspaceCmd.AddCommand(workspaceWatchCmd)
|
||||
workspaceCmd.AddCommand(workspaceUnwatchCmd)
|
||||
|
||||
workspaceGetCmd.Flags().String("output", "json", "Output format: table or json")
|
||||
workspaceMembersCmd.Flags().String("output", "table", "Output format: table or json")
|
||||
}
|
||||
|
||||
func runWorkspaceList(cmd *cobra.Command, _ []string) error {
|
||||
|
|
@ -86,6 +106,101 @@ func runWorkspaceList(cmd *cobra.Command, _ []string) error {
|
|||
return w.Flush()
|
||||
}
|
||||
|
||||
func workspaceIDFromArgs(cmd *cobra.Command, args []string) string {
|
||||
if len(args) > 0 {
|
||||
return args[0]
|
||||
}
|
||||
return resolveWorkspaceID(cmd)
|
||||
}
|
||||
|
||||
func runWorkspaceGet(cmd *cobra.Command, args []string) error {
|
||||
wsID := workspaceIDFromArgs(cmd, args)
|
||||
if wsID == "" {
|
||||
return fmt.Errorf("workspace ID is required: pass as argument or set MULTICA_WORKSPACE_ID")
|
||||
}
|
||||
|
||||
serverURL := resolveServerURL(cmd)
|
||||
token := resolveToken()
|
||||
if token == "" {
|
||||
return fmt.Errorf("not authenticated: run 'multica auth login' first")
|
||||
}
|
||||
|
||||
client := cli.NewAPIClient(serverURL, "", token)
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
|
||||
defer cancel()
|
||||
|
||||
var ws map[string]any
|
||||
if err := client.GetJSON(ctx, "/api/workspaces/"+wsID, &ws); err != nil {
|
||||
return fmt.Errorf("get workspace: %w", err)
|
||||
}
|
||||
|
||||
output, _ := cmd.Flags().GetString("output")
|
||||
if output == "table" {
|
||||
desc := strVal(ws, "description")
|
||||
if utf8.RuneCountInString(desc) > 60 {
|
||||
runes := []rune(desc)
|
||||
desc = string(runes[:57]) + "..."
|
||||
}
|
||||
wsContext := strVal(ws, "context")
|
||||
if utf8.RuneCountInString(wsContext) > 60 {
|
||||
runes := []rune(wsContext)
|
||||
wsContext = string(runes[:57]) + "..."
|
||||
}
|
||||
headers := []string{"ID", "NAME", "SLUG", "DESCRIPTION", "CONTEXT"}
|
||||
rows := [][]string{{
|
||||
strVal(ws, "id"),
|
||||
strVal(ws, "name"),
|
||||
strVal(ws, "slug"),
|
||||
desc,
|
||||
wsContext,
|
||||
}}
|
||||
cli.PrintTable(os.Stdout, headers, rows)
|
||||
return nil
|
||||
}
|
||||
|
||||
return cli.PrintJSON(os.Stdout, ws)
|
||||
}
|
||||
|
||||
func runWorkspaceMembers(cmd *cobra.Command, args []string) error {
|
||||
wsID := workspaceIDFromArgs(cmd, args)
|
||||
if wsID == "" {
|
||||
return fmt.Errorf("workspace ID is required: pass as argument or set MULTICA_WORKSPACE_ID")
|
||||
}
|
||||
|
||||
serverURL := resolveServerURL(cmd)
|
||||
token := resolveToken()
|
||||
if token == "" {
|
||||
return fmt.Errorf("not authenticated: run 'multica auth login' first")
|
||||
}
|
||||
|
||||
client := cli.NewAPIClient(serverURL, "", token)
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
|
||||
defer cancel()
|
||||
|
||||
var members []map[string]any
|
||||
if err := client.GetJSON(ctx, "/api/workspaces/"+wsID+"/members", &members); err != nil {
|
||||
return fmt.Errorf("list members: %w", err)
|
||||
}
|
||||
|
||||
output, _ := cmd.Flags().GetString("output")
|
||||
if output == "json" {
|
||||
return cli.PrintJSON(os.Stdout, members)
|
||||
}
|
||||
|
||||
headers := []string{"USER ID", "NAME", "EMAIL", "ROLE"}
|
||||
rows := make([][]string, 0, len(members))
|
||||
for _, m := range members {
|
||||
rows = append(rows, []string{
|
||||
strVal(m, "user_id"),
|
||||
strVal(m, "name"),
|
||||
strVal(m, "email"),
|
||||
strVal(m, "role"),
|
||||
})
|
||||
}
|
||||
cli.PrintTable(os.Stdout, headers, rows)
|
||||
return nil
|
||||
}
|
||||
|
||||
func runWatch(cmd *cobra.Command, args []string) error {
|
||||
workspaceID := args[0]
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue