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:
yushen 2026-03-27 13:54:40 +08:00
parent daecf7985c
commit 4a62b98c9a

View file

@ -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]