Files
Enterprise-Knowledge-Base/cli/cmd/session/view.go
T
nullkey 26fa43e2cc fix(cli): post-audit fixes (MCP MatchCount + sessions + auth + view)
Four unrelated shipped-code drifts found during v0.5 audit cycles:

1. MCP search_chunks tool omitted MatchCount from SearchParams. Server
   fell back to its default cap; agents asking for limit:50 silently
   got fewer results. Adds MatchCount: limit to the struct literal.

2. search sessions printed UpdatedAt as raw RFC3339 while session list
   used a fuzzy "X hours ago" render — same SDK field, two human
   renderings. Switches to the shared text.FuzzyAgoStr helper for
   parity.

3. auth status --json omitted three operationally-meaningful AuthUser
   fields (username, is_active, can_access_all_tenants). Agents
   branching on can_access_all_tenants previously needed a second
   round-trip.

4. session view Long help claimed the SDK doesn't wrap session_messages;
   it does (LoadMessages / GetMessagesBefore / GetRecentMessages all
   exist in client/message.go). Rewrites the comment to be accurate.
2026-05-16 16:56:33 +08:00

93 lines
2.5 KiB
Go

package sessioncmd
import (
"context"
"fmt"
"time"
"github.com/spf13/cobra"
"github.com/Tencent/WeKnora/cli/internal/cmdutil"
"github.com/Tencent/WeKnora/cli/internal/iostreams"
sdk "github.com/Tencent/WeKnora/client"
)
// sessionViewFields enumerates the fields surfaced for `--json` discovery on
// `session view`. Mirrors sdk.Session json tags.
var sessionViewFields = []string{
"id", "tenant_id", "title", "description", "created_at", "updated_at",
}
type ViewOptions struct{}
// ViewService is the narrow SDK surface this command depends on.
type ViewService interface {
GetSession(ctx context.Context, id string) (*sdk.Session, error)
}
// NewCmdView builds `weknora session view <id>`. Renders session metadata
// only (title/description/timestamps). Full chat-history retrieval is a
// separate concern (the SDK has LoadMessages / GetMessagesBefore for it);
// surfacing it as `session view --full` is queued for v0.6.
func NewCmdView(f *cmdutil.Factory) *cobra.Command {
opts := &ViewOptions{}
cmd := &cobra.Command{
Use: "view <id>",
Short: "Show a chat session by ID",
Args: cobra.ExactArgs(1),
RunE: func(c *cobra.Command, args []string) error {
jopts, err := cmdutil.CheckJSONFlags(c)
if err != nil {
return err
}
cli, err := f.Client()
if err != nil {
return err
}
return runView(c.Context(), opts, jopts, cli, args[0])
},
}
cmdutil.AddJSONFlags(cmd, sessionViewFields)
return cmd
}
func runView(ctx context.Context, opts *ViewOptions, jopts *cmdutil.JSONOptions, svc ViewService, id string) error {
s, err := svc.GetSession(ctx, id)
if err != nil {
return cmdutil.WrapHTTP(err, "get session %q", id)
}
if jopts.Enabled() {
return jopts.Emit(iostreams.IO.Out, s)
}
w := iostreams.IO.Out
fmt.Fprintf(w, "ID: %s\n", s.ID)
if s.Title != "" {
fmt.Fprintf(w, "TITLE: %s\n", s.Title)
}
if s.Description != "" {
fmt.Fprintf(w, "DESC: %s\n", s.Description)
}
if t, ok := parseTS(s.CreatedAt); ok {
fmt.Fprintf(w, "CREATED: %s\n", t.Format("2006-01-02 15:04:05"))
} else if s.CreatedAt != "" {
fmt.Fprintf(w, "CREATED: %s\n", s.CreatedAt)
}
if t, ok := parseTS(s.UpdatedAt); ok {
fmt.Fprintf(w, "UPDATED: %s\n", t.Format("2006-01-02 15:04:05"))
} else if s.UpdatedAt != "" {
fmt.Fprintf(w, "UPDATED: %s\n", s.UpdatedAt)
}
return nil
}
func parseTS(s string) (time.Time, bool) {
if s == "" {
return time.Time{}, false
}
t, err := time.Parse(time.RFC3339, s)
if err != nil {
return time.Time{}, false
}
return t, true
}