cursortranscript

package
v0.2.0-rc.3 Latest Latest
Warning

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

Go to latest
Published: Nov 13, 2026 License: MIT Imports: 15 Imported by: 0

Documentation

Overview

Package cursortranscript reads Cursor's global SQLite conversation store as typed records. It classifies source records but does not decide what they mean in the shared session model; the cursorsession package owns that mapping.

Index

Constants

View Source
const (
	BubbleTypeUser      = 1
	BubbleTypeAssistant = 2
)
View Source
const TreePayloadVersion = "1"

Variables

This section is empty.

Functions

func DefaultStorePath

func DefaultStorePath() string

DefaultStorePath returns Cursor's global conversation database path.

func EncodeTreePayload

func EncodeTreePayload(tree *Tree) ([]byte, error)

Types

type AdditionalData

type AdditionalData struct {
	Status             string          `json:"status,omitempty"`
	TerminationReason  string          `json:"terminationReason,omitempty"`
	SubagentComposerID string          `json:"subagentComposerId,omitempty"`
	Raw                json.RawMessage `json:"-"`
}

func (AdditionalData) MarshalJSON

func (a AdditionalData) MarshalJSON() ([]byte, error)

func (*AdditionalData) UnmarshalJSON

func (a *AdditionalData) UnmarshalJSON(raw []byte) error

type Bubble

type Bubble struct {
	Key                           string               `json:"key"`
	ComposerID                    string               `json:"composer_id"`
	BubbleID                      string               `json:"bubbleId"`
	Type                          int                  `json:"type"`
	Version                       int                  `json:"_v"`
	Text                          string               `json:"text"`
	RichText                      json.RawMessage      `json:"richText"`
	Thinking                      json.RawMessage      `json:"thinking"`
	TokenCount                    *TokenCount          `json:"tokenCount"`
	ModelInfo                     *ModelInfo           `json:"modelInfo"`
	CapabilityType                *int                 `json:"capabilityType"`
	SubagentSpawnTaskToolCallID   string               `json:"subagentSpawnTaskToolCallId"`
	CreatedAt                     string               `json:"createdAt"`
	ErrorDetails                  json.RawMessage      `json:"errorDetails"`
	Context                       json.RawMessage      `json:"context"`
	ContextWindowStatusAtCreation *ContextWindowStatus `json:"contextWindowStatusAtCreation"`
	Tool                          *ToolRecord          `json:"toolFormerData"`
}

Bubble is one bubbleId:<composer-id>:<bubble-id> record.

func DecodeBubble

func DecodeBubble(raw []byte) (*Bubble, error)

type BubbleRef

type BubbleRef struct {
	BubbleID string `json:"bubbleId"`
	Type     int    `json:"type"`
}

type CodeBlockData

type CodeBlockData []CodeBlockRef

CodeBlockData is the diff-bearing subset of composerData.codeBlockData.

func (*CodeBlockData) UnmarshalJSON

func (d *CodeBlockData) UnmarshalJSON(raw []byte) error

type CodeBlockDiff

type CodeBlockDiff struct {
	DiffID                 string     `json:"diff_id"`
	NewModelDiffWrtV0      []DiffHunk `json:"newModelDiffWrtV0"`
	OriginalModelDiffWrtV0 []DiffHunk `json:"originalModelDiffWrtV0"`
}

CodeBlockDiff is one codeBlockDiff:<composer-id>:<diff-id> record.

func DecodeCodeBlockDiff

func DecodeCodeBlockDiff(raw []byte) (*CodeBlockDiff, error)

func (*CodeBlockDiff) UnmarshalJSON

func (d *CodeBlockDiff) UnmarshalJSON(raw []byte) error

type CodeBlockRef

type CodeBlockRef struct {
	BubbleID    string      `json:"bubbleId"`
	CodeBlockID string      `json:"codeblockId"`
	DiffID      string      `json:"diffId"`
	Status      string      `json:"status"`
	URI         ResourceURI `json:"uri"`
}

CodeBlockRef joins one structured diff to its bubble and file.

type Composer

type Composer struct {
	Header   *Header          `json:"header,omitempty"`
	Data     *ComposerData    `json:"data"`
	Bubbles  []*Bubble        `json:"bubbles"`
	Unlisted []*Bubble        `json:"unlisted_bubbles,omitempty"`
	Diffs    []*CodeBlockDiff `json:"-"`
}

Composer is one materialized composer and its ordered/unordered bubbles.

type ComposerData

type ComposerData struct {
	ComposerID           string               `json:"composerId"`
	Version              int                  `json:"_v"`
	Status               string               `json:"status"`
	Headers              []BubbleRef          `json:"fullConversationHeadersOnly"`
	CreatedAt            int64                `json:"createdAt"`
	LastUpdatedAt        *int64               `json:"lastUpdatedAt"`
	UnifiedMode          string               `json:"unifiedMode"`
	SubComposerIDs       []string             `json:"subComposerIds"`
	SubagentComposerIDs  []string             `json:"subagentComposerIds"`
	ModelConfig          *ModelConfig         `json:"modelConfig"`
	ContextTokensUsed    *int64               `json:"contextTokensUsed"`
	ContextTokenLimit    *int64               `json:"contextTokenLimit"`
	PromptTokenBreakdown json.RawMessage      `json:"promptTokenBreakdown"`
	WorkspaceIdentifier  *WorkspaceIdentifier `json:"workspaceIdentifier"`
	CreatedOnBranch      string               `json:"createdOnBranch"`
	CommittedToBranch    string               `json:"committedToBranch"`
	Name                 string               `json:"name"`
	AgentBackend         string               `json:"agentBackend"`
	CodeBlocks           CodeBlockData        `json:"codeBlockData,omitempty"`
}

ComposerData is one composerData:<composer-id> snapshot.

func DecodeComposerData

func DecodeComposerData(raw []byte) (*ComposerData, error)

func (ComposerData) MarshalJSON

func (d ComposerData) MarshalJSON() ([]byte, error)

type ContextWindowStatus

type ContextWindowStatus struct {
	TokensUsed int64 `json:"tokensUsed"`
	TokenLimit int64 `json:"tokenLimit"`
}

type DiffHunk

type DiffHunk struct {
	Original DiffRange `json:"original"`
	Modified []string  `json:"modified"`
}

func (*DiffHunk) UnmarshalJSON

func (h *DiffHunk) UnmarshalJSON(raw []byte) error

type DiffRange

type DiffRange struct {
	StartLineNumber        int `json:"startLineNumber"`
	EndLineNumberExclusive int `json:"endLineNumberExclusive"`
}

func (*DiffRange) UnmarshalJSON

func (r *DiffRange) UnmarshalJSON(raw []byte) error

type Discovery

type Discovery struct {
	Sessions []SessionRef `json:"sessions"`
	JunkRows int          `json:"junk_rows"`
	// contains filtered or unexported fields
}

Discovery is the deduplicated union of composerHeaders and composerData keys.

func (*Discovery) Roots

func (d *Discovery) Roots() []SessionRef

Roots returns composers not classified as listed or header-flagged subagents.

func (*Discovery) Session

func (d *Discovery) Session(composerID string) (SessionRef, bool)
type Header struct {
	ComposerID    string      `json:"composer_id"`
	WorkspaceID   string      `json:"workspace_id,omitempty"`
	CreatedAt     int64       `json:"created_at,omitempty"`
	LastUpdatedAt int64       `json:"last_updated_at,omitempty"`
	IsArchived    bool        `json:"is_archived"`
	IsSubagent    bool        `json:"is_subagent"`
	Value         HeaderValue `json:"value"`
}

Header is one composerHeaders index row and its denormalized JSON value.

type HeaderValue

type HeaderValue struct {
	Name                string               `json:"name,omitempty"`
	WorkspaceIdentifier *WorkspaceIdentifier `json:"workspaceIdentifier,omitempty"`
}

type ModelConfig

type ModelConfig struct {
	ModelName string          `json:"modelName,omitempty"`
	Raw       json.RawMessage `json:"-"`
}

func (ModelConfig) MarshalJSON

func (m ModelConfig) MarshalJSON() ([]byte, error)

func (*ModelConfig) UnmarshalJSON

func (m *ModelConfig) UnmarshalJSON(raw []byte) error

type ModelInfo

type ModelInfo struct {
	ModelName string `json:"modelName"`
}

type PortableBlock

type PortableBlock struct {
	Index int               `json:"index"`
	Kind  PortableBlockKind `json:"kind"`
	Text  string            `json:"text,omitempty"`
	Tool  *PortableToolUse  `json:"tool_use,omitempty"`
	Raw   json.RawMessage   `json:"raw"`
}

type PortableBlockKind

type PortableBlockKind string
const (
	PortableText      PortableBlockKind = "text"
	PortableToolBlock PortableBlockKind = "tool_use"
)

type PortableRecord

type PortableRecord struct {
	Ordinal int                `json:"ordinal"`
	Kind    PortableRecordKind `json:"kind"`
	Blocks  []PortableBlock    `json:"blocks,omitempty"`
	Status  string             `json:"status,omitempty"`
	Error   json.RawMessage    `json:"error,omitempty"`
	Raw     json.RawMessage    `json:"raw"`
}

func DecodePortable

func DecodePortable(r io.Reader) ([]PortableRecord, error)

type PortableRecordKind

type PortableRecordKind string
const (
	PortableUser      PortableRecordKind = "user"
	PortableAssistant PortableRecordKind = "assistant"
	PortableTurnEnd   PortableRecordKind = "turn_ended"
)

type PortableToolUse

type PortableToolUse struct {
	Name  string          `json:"name"`
	Input json.RawMessage `json:"input"`
}

type ResourceURI

type ResourceURI struct {
	FSPath string `json:"fsPath,omitempty"`
	Path   string `json:"path,omitempty"`
	Scheme string `json:"scheme,omitempty"`
}

func (ResourceURI) FilePath

func (u ResourceURI) FilePath() string

type SessionRef

type SessionRef struct {
	ComposerID          string               `json:"composer_id"`
	Title               string               `json:"title,omitempty"`
	WorkspaceID         string               `json:"workspace_id,omitempty"`
	WorkspaceIdentifier *WorkspaceIdentifier `json:"-"`
	CreatedAt           int64                `json:"created_at,omitempty"`
	LastUpdatedAt       int64                `json:"last_updated_at,omitempty"`
	HasHeader           bool                 `json:"has_header"`
	HasData             bool                 `json:"has_data"`
	IsSubagent          bool                 `json:"is_subagent"`
	Header              *Header              `json:"-"`
}

SessionRef is the store index entry for one composer.

type Shape

type Shape struct {
	Headers                    int            `json:"headers"`
	ComposerVersions           map[string]int `json:"composer_versions"`
	BubbleVersions             map[string]int `json:"bubble_versions"`
	BubbleTypes                map[string]int `json:"bubble_types"`
	ToolStatuses               map[string]int `json:"tool_statuses"`
	KeyFamilies                map[string]int `json:"key_families"`
	ComposersWithBubblesNoData int            `json:"composers_with_bubbles_without_data"`
	BubblesWithoutComposerData int            `json:"bubbles_without_composer_data"`
	JunkRows                   int            `json:"junk_rows"`
}

Shape counts the source variants observed while decoding a store.

type Store

type Store struct {
	// contains filtered or unexported fields
}

Store is an open, read-only Cursor global store.

func Open

func Open(path string) (*Store, error)

Open opens path read-only. SQLite applies the live WAL through sqliteread; this package never opens Cursor's stale .backup file.

func (*Store) Close

func (s *Store) Close() error

Close releases the read-only database handle.

func (*Store) Discover

func (s *Store) Discover() (*Discovery, error)

Discover indexes the DB-backed Cursor sessions in this store.

func (*Store) Name added in v0.2.0

func (s *Store) Name(composerID string) (string, error)

Name is the conversation name stored in the composer's own record, read without building its tree. It is what Tree(composerID).Composer.Data.Name holds.

func (*Store) RecordRevision added in v0.2.0

func (s *Store) RecordRevision(composerID string) (string, error)

RecordRevision fingerprints the composer's own record: its update time, status, name and the list of bubbles it holds.

func (*Store) Revision added in v0.2.0

func (s *Store) Revision(composerID string) (string, error)

Revision fingerprints what Tree(composerID) reads: the record of the composer and of every composer listed beneath it, and each of their bubble and code block diff rows. It changes when the conversation does, however Cursor edits it, and not when Cursor writes some other conversation to the same database file. Unlike Tree it decodes nothing and indexes nothing.

func (*Store) Survey

func (s *Store) Survey() (Shape, error)

func (*Store) Tree

func (s *Store) Tree(composerID string) (*Tree, error)

Tree reads one composer tree in authoritative header order.

type TokenCount

type TokenCount struct {
	InputTokens  int64 `json:"inputTokens"`
	OutputTokens int64 `json:"outputTokens"`
}

func (*TokenCount) HasUsage

func (t *TokenCount) HasUsage() bool

type ToolRecord

type ToolRecord struct {
	Tool           json.RawMessage `json:"tool"`
	Name           *string         `json:"name"`
	ToolCallID     string          `json:"toolCallId"`
	ModelCallID    string          `json:"modelCallId"`
	Status         string          `json:"status"`
	Params         json.RawMessage `json:"params"`
	RawArgs        json.RawMessage `json:"rawArgs"`
	Result         json.RawMessage `json:"result"`
	ToolIndex      *int            `json:"toolIndex"`
	UserDecision   string          `json:"userDecision"`
	Error          json.RawMessage `json:"error"`
	AdditionalData *AdditionalData `json:"additionalData"`
}

ToolRecord is Cursor's call-and-result record embedded in one bubble.

func (*ToolRecord) Degenerate

func (t *ToolRecord) Degenerate() bool

func (*ToolRecord) ToolName

func (t *ToolRecord) ToolName() string

type Tree

type Tree struct {
	Composer         *Composer `json:"composer"`
	Children         []*Tree   `json:"children,omitempty"`
	DanglingChildren []string  `json:"dangling_children,omitempty"`
}

Tree is one composer and every materialized child listed beneath it.

func DecodeHostedTreePayload

func DecodeHostedTreePayload(body []byte) (*Tree, error)

DecodeHostedTreePayload applies the appliance's validation of untrusted upload nodes before restoring raw fields. Local payload decoding retains its contract.

func DecodeTreePayload

func DecodeTreePayload(body []byte) (*Tree, error)

func (*Tree) ComposerID

func (t *Tree) ComposerID() string

func (*Tree) Composers

func (t *Tree) Composers() []*Composer

Composers returns the tree in parent-first order.

type TreePayload

type TreePayload struct {
	SchemaVersion string            `json:"schema_version"`
	Tree          *Tree             `json:"tree"`
	RawFields     map[string]string `json:"raw_fields,omitempty"`
}

type WorkspaceIdentifier

type WorkspaceIdentifier struct {
	ID  string          `json:"id,omitempty"`
	URI ResourceURI     `json:"uri"`
	Raw json.RawMessage `json:"-"`
}

func (WorkspaceIdentifier) MarshalJSON

func (w WorkspaceIdentifier) MarshalJSON() ([]byte, error)

func (*WorkspaceIdentifier) UnmarshalJSON

func (w *WorkspaceIdentifier) UnmarshalJSON(raw []byte) error

Jump to

Keyboard shortcuts

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