Documentation
¶
Index ¶
- Variables
- func ExtractContent(resp *mcp.JSONRPCResponse) (map[string]any, error)
- func PrintError(format string, args ...any)
- func RenderKeyValue(w io.Writer, item map[string]any)
- func RenderTSV(w io.Writer, columns []Column, rows []map[string]any)
- func RenderTable(w io.Writer, columns []Column, rows []map[string]any)
- func ToRows(data map[string]any, key string) []map[string]any
- type Column
- type Format
- type Formatter
- func (f *Formatter) PrintDryRun(action string, data map[string]any) error
- func (f *Formatter) PrintDryRunValidated(action string, data map[string]any, v *mcp.ValidationResult) error
- func (f *Formatter) PrintItem(item map[string]any) error
- func (f *Formatter) PrintList(entity string, columns []Column, rows []map[string]any) error
- func (f *Formatter) PrintMutation(msg string, data map[string]any) error
- func (f *Formatter) PrintRaw(resp *mcp.JSONRPCResponse) error
Constants ¶
This section is empty.
Variables ¶
var APIDiscoverColumns = []Column{ {Header: "NAME", Width: 30, Extract: func(row map[string]any) string { return getString(row, "name") }}, {Header: "URL", Width: 60, Extract: func(row map[string]any) string { return getString(row, "url") }}, {Header: "SCOPE", Width: 30, Extract: func(row map[string]any) string { return getString(row, "scope") }}, }
APIDiscoverColumns defines columns for discovered servers.
var APIServerColumns = []Column{ {Header: "SERVICE", Width: 15, Extract: func(row map[string]any) string { return getString(row, "service") }}, {Header: "SERVER", Width: 0, Extract: func(row map[string]any) string { return getString(row, "server") }}, }
APIServerColumns defines columns for the server list.
var APIServerProbeColumns = []Column{ {Header: "SERVICE", Width: 15, Extract: func(row map[string]any) string { return getString(row, "service") }}, {Header: "SERVER", Width: 30, Extract: func(row map[string]any) string { return getString(row, "server") }}, {Header: "TOOLS", Width: 5, Extract: func(row map[string]any) string { return getString(row, "tools") }}, {Header: "STATUS", Width: 0, Extract: func(row map[string]any) string { return getString(row, "status") }}, }
APIServerProbeColumns defines columns for the probed server list.
var APIToolColumns = []Column{ {Header: "TOOL", Width: 40, Extract: func(row map[string]any) string { return getString(row, "name") }}, {Header: "REQUIRED", Width: 30, Extract: func(row map[string]any) string { return getString(row, "required") }}, {Header: "DESCRIPTION", Width: 60, Extract: func(row map[string]any) string { return truncate(getString(row, "description"), 60) }}, }
APIToolColumns defines columns for the tool list.
var CalendarColumns = []Column{ {Header: "START", Width: 16, Extract: func(row map[string]any) string { start, ok := row["start"] if !ok || start == nil { return formatTime(getString(row, "startDateTime")) } sm, ok := start.(map[string]any) if !ok { return "" } return formatTime(getString(sm, "dateTime")) }}, {Header: "SUBJECT", Width: 40, Extract: func(row map[string]any) string { return truncate(getString(row, "subject"), 40) }}, {Header: "ORGANIZER", Width: 25, Extract: func(row map[string]any) string { org, ok := row["organizer"] if !ok || org == nil { return "" } om, ok := org.(map[string]any) if !ok { return "" } ea, ok := om["emailAddress"] if !ok || ea == nil { return "" } eam, ok := ea.(map[string]any) if !ok { return "" } name := getString(eam, "name") if name != "" { return truncate(name, 25) } return truncate(getString(eam, "address"), 25) }}, {Header: "ID", Width: 0, Extract: func(row map[string]any) string { return getString(row, "id") }}, }
CalendarColumns defines display columns for calendar events.
var ChannelsColumns = []Column{ {Header: "DISPLAY NAME", Width: 35, Extract: func(row map[string]any) string { return getString(row, "displayName") }}, {Header: "ID", Width: 0, Extract: func(row map[string]any) string { return getString(row, "id") }}, {Header: "TYPE", Width: 10, Extract: func(row map[string]any) string { return getString(row, "membershipType") }}, {Header: "CREATED", Width: 10, Extract: func(row map[string]any) string { return formatTime(getString(row, "createdDateTime")) }}, }
ChannelsColumns defines display columns for channels list.
var ChatsColumns = []Column{ {Header: "TOPIC", Width: 35, Extract: func(row map[string]any) string { topic := getString(row, "topic") if topic != "" { return topic } members, ok := row["members"] if !ok { return "(no topic)" } arr, ok := members.([]any) if !ok || len(arr) == 0 { return "(no topic)" } var names []string for _, m := range arr { if mm, ok := m.(map[string]any); ok { name := getString(mm, "displayName") if name != "" { names = append(names, name) } } } return strings.Join(names, ", ") }}, {Header: "ID", Width: 0, Extract: func(row map[string]any) string { return getString(row, "id") }}, {Header: "TYPE", Width: 10, Extract: func(row map[string]any) string { return getString(row, "chatType") }}, {Header: "UPDATED", Width: 10, Extract: func(row map[string]any) string { return formatTime(getString(row, "lastUpdatedDateTime")) }}, }
ChatsColumns defines display columns for chats list.
var CopilotAgentColumns = []Column{ {Header: "NAME", Width: 32, Extract: func(row map[string]any) string { return truncate(getString(row, "name"), 32) }}, {Header: "SELECTOR", Width: 20, Extract: func(row map[string]any) string { selector := getString(row, "selector") if selector != "" { return selector } return getString(row, "agentId") }}, {Header: "STATUS", Width: 10, Extract: func(row map[string]any) string { status := getString(row, "status") if status != "" { return status } if shared, ok := row["sharedSelector"].(bool); ok && shared { return "shared" } if targetable, ok := row["targetable"].(bool); ok && targetable { return "ok" } return "" }}, {Header: "TITLE ID", Width: 0, Extract: func(row map[string]any) string { return getString(row, "titleId") }}, }
CopilotAgentColumns defines display columns for Copilot agent lists.
var MailColumns = []Column{ {Header: "DATE", Width: 10, Extract: func(row map[string]any) string { return formatTime(getString(row, "receivedDateTime")) }}, {Header: "FROM", Width: 25, Extract: func(row map[string]any) string { from, ok := row["from"] if !ok || from == nil { return "" } fm, ok := from.(map[string]any) if !ok { return "" } ea, ok := fm["emailAddress"] if !ok || ea == nil { return getString(fm, "name") } eam, ok := ea.(map[string]any) if !ok { return "" } name := getString(eam, "name") if name != "" { return truncate(name, 25) } return truncate(getString(eam, "address"), 25) }}, {Header: "SUBJECT", Width: 50, Extract: func(row map[string]any) string { return truncate(getString(row, "subject"), 50) }}, {Header: "READ", Width: 4, Extract: func(row map[string]any) string { v, ok := row["isRead"] if !ok { return "" } if b, ok := v.(bool); ok && b { return "yes" } return "no" }}, {Header: "ID", Width: 0, Extract: func(row map[string]any) string { return getString(row, "id") }}, }
MailColumns defines display columns for email lists.
var MembersColumns = []Column{ {Header: "DISPLAY NAME", Width: 30, Extract: func(row map[string]any) string { return getString(row, "displayName") }}, {Header: "EMAIL", Width: 35, Extract: func(row map[string]any) string { return getString(row, "email") }}, {Header: "ID", Width: 36, Extract: func(row map[string]any) string { return getString(row, "id") }}, {Header: "ROLES", Width: 10, Extract: func(row map[string]any) string { roles, ok := row["roles"] if !ok || roles == nil { return "" } arr, ok := roles.([]any) if !ok { return "" } var rs []string for _, r := range arr { if s, ok := r.(string); ok { rs = append(rs, s) } } return strings.Join(rs, ",") }}, }
MembersColumns defines display columns for member lists.
var MessagesColumns = []Column{ {Header: "DATE", Width: 10, Extract: func(row map[string]any) string { return formatTime(getString(row, "createdDateTime")) }}, {Header: "FROM", Width: 20, Extract: func(row map[string]any) string { return truncate(getNestedString(row, "from", "displayName"), 20) }}, {Header: "CONTENT", Width: 80, Extract: func(row map[string]any) string { body, ok := row["body"] if !ok || body == nil { return "" } bm, ok := body.(map[string]any) if !ok { return "" } content := getString(bm, "content") content = stripHTML(content) return truncate(content, 80) }}, {Header: "ID", Width: 0, Extract: func(row map[string]any) string { return getString(row, "id") }}, }
MessagesColumns defines display columns for message lists.
var PlannerPlanColumns = []Column{ {Header: "TITLE", Width: 40, Extract: func(row map[string]any) string { return truncate(getString(row, "title"), 40) }}, {Header: "ID", Width: 36, Extract: func(row map[string]any) string { return getString(row, "id") }}, {Header: "CREATED", Width: 10, Extract: func(row map[string]any) string { return formatTime(getString(row, "createdDateTime")) }}, }
PlannerPlanColumns defines display columns for planner plans.
var PlannerTaskColumns = []Column{ {Header: "TITLE", Width: 40, Extract: func(row map[string]any) string { return truncate(getString(row, "title"), 40) }}, {Header: "ID", Width: 36, Extract: func(row map[string]any) string { return getString(row, "id") }}, {Header: "STATUS", Width: 12, Extract: func(row map[string]any) string { pct := row["percentComplete"] if pct == nil { return "" } switch v := pct.(type) { case float64: if v == 100 { return "completed" } else if v > 0 { return "in progress" } return "not started" default: return fmt.Sprintf("%v", v) } }}, {Header: "PRIORITY", Width: 8, Extract: func(row map[string]any) string { p := row["priority"] if p == nil { return "" } switch v := p.(type) { case float64: switch int(v) { case 1: return "urgent" case 3: return "important" case 5: return "medium" case 9: return "low" default: return fmt.Sprintf("%d", int(v)) } default: return fmt.Sprintf("%v", v) } }}, }
PlannerTaskColumns defines display columns for planner tasks.
var SearchColumns = []Column{ {Header: "DATE", Width: 10, Extract: func(row map[string]any) string { return formatTime(getString(row, "createdDateTime")) }}, {Header: "FROM", Width: 20, Extract: func(row map[string]any) string { return truncate(getNestedString(row, "from", "displayName"), 20) }}, {Header: "PREVIEW", Width: 60, Extract: func(row map[string]any) string { summary := getString(row, "summary") if summary != "" { return truncate(stripHTML(summary), 60) } body, ok := row["body"] if !ok || body == nil { return "" } bm, ok := body.(map[string]any) if !ok { return "" } return truncate(stripHTML(getString(bm, "content")), 60) }}, }
SearchColumns defines display columns for search results.
var TeamsColumns = []Column{ {Header: "DISPLAY NAME", Width: 40, Extract: func(row map[string]any) string { return getString(row, "displayName") }}, {Header: "ID", Width: 36, Extract: func(row map[string]any) string { return getString(row, "id") }}, {Header: "DESCRIPTION", Width: 50, Extract: func(row map[string]any) string { return truncate(getString(row, "description"), 50) }}, }
TeamsColumns defines display columns for teams list.
var UserColumns = []Column{ {Header: "DISPLAY NAME", Width: 30, Extract: func(row map[string]any) string { return getString(row, "displayName") }}, {Header: "UPN", Width: 35, Extract: func(row map[string]any) string { upn := getString(row, "userPrincipalName") if upn != "" { return upn } return getString(row, "mail") }}, {Header: "JOB TITLE", Width: 25, Extract: func(row map[string]any) string { return truncate(getString(row, "jobTitle"), 25) }}, {Header: "ID", Width: 36, Extract: func(row map[string]any) string { return getString(row, "id") }}, }
UserColumns defines display columns for user lists.
Functions ¶
func ExtractContent ¶
func ExtractContent(resp *mcp.JSONRPCResponse) (map[string]any, error)
ExtractContent unwraps the MCP JSON-RPC response to get the domain data. It parses Content[].Text JSON strings into a map[string]any.
func PrintError ¶
PrintError outputs an error message to stderr.
func RenderKeyValue ¶
RenderKeyValue writes an item as sorted key: value pairs.
func RenderTable ¶
RenderTable writes rows as an aligned table with headers using tabwriter.
For columns with Width > 0, the configured width acts as the minimum display width for alignment in addition to being the truncation width. Columns with Width == 0 are auto-sized from their observed content.
Types ¶
type Column ¶
type Column struct {
Header string // Display header, e.g. "DISPLAY NAME"
Width int // Max chars for table display (0 = unlimited)
Extract func(row map[string]any) string // Pull value from row
}
Column defines a column for table/TSV output.
type Formatter ¶
Formatter handles output rendering in one of three modes.
func NewFormatter ¶
NewFormatter creates a new output formatter from a format string. "json" → FormatJSON, "tsv" or "plain" → FormatPlain, anything else → FormatHuman.
func (*Formatter) PrintDryRun ¶
PrintDryRun outputs what WOULD happen without executing.
func (*Formatter) PrintDryRunValidated ¶ added in v0.2.0
func (f *Formatter) PrintDryRunValidated(action string, data map[string]any, v *mcp.ValidationResult) error
PrintDryRunValidated outputs what WOULD happen, with optional schema validation results. If validation is nil, a "validation skipped" warning is shown. Returns an error when validation fails (for non-zero exit code).
func (*Formatter) PrintList ¶
PrintList outputs a list of items with the given entity name and column definitions.
func (*Formatter) PrintMutation ¶
PrintMutation outputs the result of a write operation.