note

package
v1.0.53 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 12, 2026 License: MIT Imports: 17 Imported by: 0

Documentation

Overview

Package note owns the Note domain: querying note detail and the unified transcript by a known note_id. The vc domain locates a note_id from meeting context and delegates note-detail parsing here, so the parsing logic lives in exactly one place.

Index

Constants

View Source
const NoNoteReadPermissionCode = 121005

NoNoteReadPermissionCode is returned when the caller lacks read permission for the requested note.

Variables

View Source
var ErrEmptyDetail = errors.New("note detail is empty")

ErrEmptyDetail identifies note detail responses that do not contain a note object. Callers should use errors.Is instead of matching the display message.

View Source
var NoteDetail = common.Shortcut{
	Service:     "note",
	Command:     "+detail",
	Description: "Get note detail (display type, document tokens) by note_id",
	Risk:        "read",
	Scopes:      []string{"vc:note:read"},
	AuthTypes:   []string{"user"},
	Flags: []common.Flag{
		{Name: "note-id", Desc: "note ID", Required: true},
	},
	Validate: func(_ context.Context, runtime *common.RuntimeContext) error {
		noteID := strings.TrimSpace(runtime.Str("note-id"))
		if noteID == "" {
			return errs.NewValidationError(errs.SubtypeInvalidArgument, "--note-id is required").WithParam("--note-id")
		}
		if err := validate.ResourceName(noteID, "--note-id"); err != nil {
			return errs.NewValidationError(errs.SubtypeInvalidArgument, "%s", err).WithParam("--note-id").WithCause(err)
		}
		return nil
	},
	DryRun: func(_ context.Context, runtime *common.RuntimeContext) *common.DryRunAPI {
		noteID := strings.TrimSpace(runtime.Str("note-id"))
		return common.NewDryRunAPI().
			GET(fmt.Sprintf("/open-apis/vc/v1/notes/%s", validate.EncodePathSegment(noteID)))
	},
	Execute: func(ctx context.Context, runtime *common.RuntimeContext) error {
		noteID := strings.TrimSpace(runtime.Str("note-id"))
		detail, err := FetchDetail(ctx, runtime, noteID)
		if err != nil {
			return mapNoteError(err)
		}
		runtime.OutFormat(map[string]any{"note": detail.ToMap()}, nil, nil)
		return nil
	},
}

NoteDetail queries note metadata, display type and document tokens by note_id.

View Source
var NoteTranscript = common.Shortcut{
	Service:     "note",
	Command:     "+transcript",
	Description: "Fetch the unified note transcript and save it to a file",
	Risk:        "read",
	Scopes:      []string{"vc:note:read"},
	AuthTypes:   []string{"user"},
	Flags: []common.Flag{
		{Name: "note-id", Desc: "note ID", Required: true},
		{Name: "transcript-format", Desc: "transcript content format", Default: transcriptFormatMarkdown, Enum: []string{transcriptFormatMarkdown, transcriptFormatPlainText}},
		{Name: "locale", Desc: "transcript locale, e.g. zh_cn, en_us, ja_jp (default follows profile language or brand)"},
		{Name: "output", Desc: "output file path (default: ./notes/{note_id}/unified_transcript.{md,txt})"},
		{Name: "overwrite", Type: "bool", Desc: "overwrite an existing output file"},
	},
	Validate: func(_ context.Context, runtime *common.RuntimeContext) error {
		noteID := strings.TrimSpace(runtime.Str("note-id"))
		if noteID == "" {
			return errs.NewValidationError(errs.SubtypeInvalidArgument, "--note-id is required").WithParam("--note-id")
		}
		if err := validate.ResourceName(noteID, "--note-id"); err != nil {
			return errs.NewValidationError(errs.SubtypeInvalidArgument, "%s", err).WithParam("--note-id").WithCause(err)
		}
		if out := strings.TrimSpace(runtime.Str("output")); out != "" {
			if err := common.ValidateSafePathTyped(runtime.FileIO(), out); err != nil {
				return err
			}
		}
		return nil
	},
	DryRun: func(_ context.Context, runtime *common.RuntimeContext) *common.DryRunAPI {
		noteID := strings.TrimSpace(runtime.Str("note-id"))
		transcriptFormat := runtime.Str("transcript-format")
		locale := resolveTranscriptLocale(runtime)
		return common.NewDryRunAPI().
			GET(fmt.Sprintf("/open-apis/vc/v1/notes/%s", validate.EncodePathSegment(noteID))).
			Desc("[1] Check note_display_type and verbatim_doc_token before transcript fetch").
			GET(fmt.Sprintf("/open-apis/vc/v1/notes/%s/unified_note_transcript", validate.EncodePathSegment(noteID))).
			Desc("[2] Fetch unified note transcript pages; subsequent pages add cursor_id internally").
			Params(map[string]interface{}{
				"format":    transcriptFormat,
				"page_size": transcriptPageSize,
				"locale":    locale,
			}).
			Set("transcript_format", transcriptFormat).
			Set("locale", locale).
			Set("note", "CLI first checks note_display_type via note detail, then paginates internally (cursor_id) and saves the full unified transcript to a file")
	},
	Execute: func(ctx context.Context, runtime *common.RuntimeContext) error {
		noteID := strings.TrimSpace(runtime.Str("note-id"))
		transcriptFormat := runtime.Str("transcript-format")
		locale := resolveTranscriptLocale(runtime)

		outPath := strings.TrimSpace(runtime.Str("output"))
		if outPath == "" {
			outPath = defaultTranscriptPath(noteID, transcriptFormat)
		}
		if !runtime.Bool("overwrite") {
			if _, statErr := runtime.FileIO().Stat(outPath); statErr == nil {
				precondition := errs.NewValidationError(errs.SubtypeFailedPrecondition, "output file already exists: %s", outPath).
					WithHint("Pass --overwrite to replace the existing file")
				if strings.TrimSpace(runtime.Str("output")) != "" {
					precondition = precondition.WithParam("--output")
				}
				return precondition
			}
		}

		if err := ensureUnifiedNote(ctx, runtime, noteID); err != nil {
			return err
		}

		content, err := fetchUnifiedTranscript(ctx, runtime, noteID, transcriptFormat, locale)
		if err != nil {
			return err
		}

		saved, err := runtime.FileIO().Save(outPath, fileio.SaveOptions{}, bytes.NewReader(content))
		if err != nil {
			return common.WrapSaveErrorTyped(err)
		}
		resolved, rerr := runtime.FileIO().ResolvePath(outPath)
		if rerr != nil || resolved == "" {
			resolved = outPath
		}

		runtime.OutFormat(map[string]any{
			"note_id":           noteID,
			"transcript_format": transcriptFormat,
			"transcript_file":   resolved,
			"size_bytes":        saved.Size(),
		}, nil, nil)
		return nil
	},
}

NoteTranscript fetches the full unified transcript and saves it to a file.

Functions

func Shortcuts

func Shortcuts() []common.Shortcut

Shortcuts returns all note-domain shortcuts.

Types

type Detail

type Detail struct {
	NoteID           string
	CreatorID        string
	CreateTime       string
	DisplayType      string // unknown | normal | unified
	NoteDocToken     string
	VerbatimDocToken string
	SharedDocTokens  []string
}

Detail is the parsed note detail shared by `note +detail` and `vc +notes`.

func FetchDetail

func FetchDetail(_ context.Context, runtime *common.RuntimeContext, noteID string) (*Detail, error)

FetchDetail queries GET /open-apis/vc/v1/notes/{note_id} and parses the note object. API errors are returned as typed errs.* values so callers can enrich user guidance without downgrading the envelope.

func (*Detail) ToMap

func (d *Detail) ToMap() map[string]any

ToMap renders the detail as the field map consumed by `vc +notes`, keeping the historical key set (shared_doc_tokens omitted when empty) and adding the note_id / note_display_type fields.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL