cline

package
v0.0.2 Latest Latest
Warning

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

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

Documentation

Overview

Package cline reads the task directories of classic Cline (the VS Code extension before 4.0, and the standalone hosts that kept its layout) and of Roo Code, which forked from it: one directory per task under <storage>/tasks/<id>, holding the model's context as a JSON array of Anthropic messages (api_conversation_history.json), the chat view's messages (ui_messages.json), and, per variant, the task's metadata, classic's context-window edits (context_history.json) and Roo's index entry (history_item.json). Classic's index entries are in <storage>/state/taskHistory.json. It imports the standard library alone. Cline 4's SDK session store is another format.

The files are whole JSON documents, rewritten on every change, not logs. Each array is read element by element: an element that is not an object is kept with its error and its neighbours still read, and an array cut short keeps the elements that end before the cut. Every object keeps the members it does not declare and writes them back, so an element read and written again is the same JSON value.

ReadTask reads a task directory, ParseTask its files' contents; FindSessions lists the task directories under a storage directory. Neither format records a version; the variant is told by the storage directory's name, else by shapes only one of them writes, and the task says which. ParseXMLTools reads the tool calls a model wrote as XML in its text. The reader does not interpret: rebuilding what the model saw, and converting to the Agent Session Format, are the convert subpackage's; docs/formats/cline.md is the mapping.

Index

Constants

View Source
const (
	FileAPI            = "api_conversation_history.json"
	FileUI             = "ui_messages.json"
	FileLegacy         = "claude_messages.json"
	FileMetadata       = "task_metadata.json"
	FileContextHistory = "context_history.json"
	FileSettings       = "settings.json"
	// FileHistoryItem is Roo's per-task index entry.
	FileHistoryItem = "history_item.json"
	// FileTaskHistory is classic Cline's index, state/taskHistory.json
	// under the storage directory.
	FileTaskHistory = "taskHistory.json"
)

File names in a task directory.

View Source
const (
	StorageClassic = "saoudrizwan.claude-dev"
	StorageRoo     = "rooveterinaryinc.roo-cline"
)

Storage directory names, the VS Code extension IDs, lowercased as VS Code writes them.

View Source
const (
	RoleUser      = "user"
	RoleAssistant = "assistant"
)

Roles of an API message.

View Source
const (
	BlockText             = "text"
	BlockImage            = "image"
	BlockDocument         = "document"
	BlockToolUse          = "tool_use"
	BlockToolResult       = "tool_result"
	BlockThinking         = "thinking"
	BlockRedactedThinking = "redacted_thinking"
	BlockReasoning        = "reasoning"
	BlockThoughtSignature = "thoughtSignature"
)

Content block types. Reasoning and ThoughtSignature are Roo's.

View Source
const MaxSize = 1 << 30

MaxSize bounds a file the reader reads. A larger file is refused rather than read into memory, and reported as malformed.

Variables

View Source
var ToolNames = []string{

	"execute_command", "read_file", "write_to_file", "search_files",
	"list_files", "list_code_definition_names", "browser_action",
	"use_mcp_tool", "access_mcp_resource", "ask_followup_question",
	"attempt_completion", "new_task",

	"replace_in_file", "plan_mode_respond", "act_mode_respond",
	"load_mcp_documentation", "condense", "summarize_task", "report_bug",
	"new_rule", "web_fetch", "web_search", "use_subagents", "focus_chain",

	"apply_diff", "insert_content", "search_and_replace", "codebase_search",
	"switch_mode", "update_todo_list", "fetch_instructions",
	"run_slash_command", "generate_image", "search_replace", "edit_file",
	"apply_patch",
}

ToolNames are the tools classic Cline and Roo let a model call in the XML style, writing <tool><param>value</param></tool> in its text.

Functions

func FindSessions

func FindSessions(root string) ([]string, error)

FindSessions returns the task directories under root as the path of each one's main file: its API history, or its UI messages when it has none, sorted. root may be a storage directory, its tasks directory, one task directory, or a file in one, which is returned as it is. Checkpoint repositories are not walked, nor is a task directory below its own level; a directory that cannot be read is skipped.

func Float

func Float(raw json.RawMessage) (float64, bool)

Float reads a number written as a number or a string of one.

func Int

func Int(raw json.RawMessage) (n int64, exact, ok bool)

Int reads an integer written as a number, possibly 12.0, or a string of one. exact is false when a fraction was dropped.

func IsNull

func IsNull(raw json.RawMessage) bool

IsNull reports whether raw is absent or null.

func IsTaskFile

func IsTaskFile(path string) bool

IsTaskFile reports whether path is a file a task directory is found by, in a task directory inside a tasks directory.

func Millis

func Millis(raw json.RawMessage) (time.Time, bool)

Millis reads a ms epoch timestamp written as a number, or a string of one; false for anything else, or one outside the years 1970 to 9999.

func Names

func Names(calls []XMLToolCall) []string

Names lists the distinct tool names of calls, sorted.

func ParentTask

func ParentTask(taskDir string) string

ParentTask reads the parent task ID a Roo task's history_item.json names; empty when there is none.

func Range

func Range(raw json.RawMessage) (r [2]int, ok bool)

Range reads a deleted range, two integers [start, end] with start at most end; false for anything else.

func TaskDir

func TaskDir(path string) (string, error)

TaskDir returns the task directory a path names: the path itself when it is a directory, else the directory of the file.

Types

type Array

type Array[T any] struct {
	// Name is the file's name in the task directory; empty when the
	// task has no such file.
	Name string
	// Elems are the elements read, in order.
	Elems []T
	// Err is set when the file could not be read whole: it does not
	// parse, it is not an array, or it is cut short. Elems then holds
	// the elements that end before the fault. The file counts one
	// malformed unit for it.
	Err error
}

Array is one of a task's JSON array files, read element by element.

func ParseContextHistory

func ParseContextHistory(data []byte) Array[*ContextUpdate]

ParseContextHistory reads a context_history.json: a serialised Map<messageIndex, [editType, Map<blockIndex, ContextUpdate[]>]>, as nested arrays. Each update is a unit; a message or block entry that does not read is one unit with Err set.

func ParseMessages

func ParseMessages(data []byte) Array[*Message]

ParseMessages reads an api_conversation_history.json from its bytes.

func ParseUI

func ParseUI(data []byte) Array[*UIMessage]

ParseUI reads a ui_messages.json from its bytes.

func (*Array[T]) Present

func (a *Array[T]) Present() bool

Present reports whether the task has the file.

func (*Array[T]) Units

func (a *Array[T]) Units() int

Units is the number of units the file accounts for: each element, and one for a fault.

type Block

type Block struct {
	Type string `json:"type"`

	// text, Roo plain reasoning
	Text string `json:"text"`
	// thinking
	Thinking  string `json:"thinking"`
	Signature string `json:"signature"`
	// redacted_thinking
	Data string `json:"data"`
	// tool_use; id is also a Roo reasoning item's
	ID    string          `json:"id"`
	Name  string          `json:"name"`
	Input json.RawMessage `json:"input"`
	// tool_result
	ToolUseID string   `json:"tool_use_id"`
	Content   *Content `json:"content"`
	IsError   bool     `json:"is_error"`
	// image, document
	Source *MediaSource `json:"source"`
	// Roo encrypted reasoning
	EncryptedContent string `json:"encrypted_content"`
	// Roo thoughtSignature
	ThoughtSignature string `json:"thoughtSignature"`

	Members

	// Raw and Err are set for a block that is not an object, or whose
	// members do not decode as declared; Type is read when it can be.
	Raw json.RawMessage `json:"-"`
	Err error           `json:"-"`
}

Block is one content block: Anthropic's, with Cline's and Roo's members. Type says which members apply.

func (Block) MarshalJSON

func (b Block) MarshalJSON() ([]byte, error)

MarshalJSON writes the block back as it was read.

func (*Block) UnmarshalJSON

func (b *Block) UnmarshalJSON(data []byte) error

UnmarshalJSON decodes a block, keeping undeclared members and those of another JSON type. It never fails: a value that is not an object is kept in Raw with Err set.

type Content

type Content struct {
	Text   string
	IsText bool
	Blocks []*Block
	// Raw and Err are set for content that is neither: a number, an
	// object, null. Raw is written back.
	Raw json.RawMessage
	Err error
}

Content is a message's content: a string, or a list of blocks, each decoded on its own.

func (Content) IsZero

func (c Content) IsZero() bool

IsZero reports whether the content was absent, so it is not written back.

func (Content) MarshalJSON

func (c Content) MarshalJSON() ([]byte, error)

MarshalJSON writes the string, the blocks, or what was read.

func (*Content) UnmarshalJSON

func (c *Content) UnmarshalJSON(data []byte) error

UnmarshalJSON accepts a string or an array of blocks; anything else is kept in Raw with Err set.

type ContextUpdate

type ContextUpdate struct {
	Message  int
	EditType json.RawMessage
	Block    int
	TS       json.RawMessage
	// Kind is the update's type; Cline writes "text" alone.
	Kind string
	// Text is the new text; Cline writes one.
	Text     []string
	Metadata json.RawMessage
	// Raw is the update as read, and Err why it does not decode. A
	// message or block entry that does not decode is one update with
	// Err set and Message or Block -1.
	Raw json.RawMessage
	Err error
}

ContextUpdate is one update of a classic task's context_history.json: from TS on, every request sends block Block of API message Message with Text in place of its text. The latest update of a block wins.

func (*ContextUpdate) NewText

func (u *ContextUpdate) NewText() string

NewText is the replacement text, the update's first.

func (*ContextUpdate) Time

func (u *ContextUpdate) Time() (time.Time, bool)

Time is the update's ts; false when it has none.

type Environment

type Environment struct {
	TS           json.RawMessage `json:"ts"`
	ClineVersion string          `json:"cline_version"`

	Members
}

Environment is one environment the task ran in: the only place a classic task records the Cline version.

func (Environment) MarshalJSON

func (e Environment) MarshalJSON() ([]byte, error)

MarshalJSON writes the record back as it was read.

func (*Environment) UnmarshalJSON

func (e *Environment) UnmarshalJSON(data []byte) error

UnmarshalJSON decodes the record, keeping undeclared members.

type HistoryItem

type HistoryItem struct {
	ID                              string          `json:"id"`
	TS                              json.RawMessage `json:"ts"`
	Task                            string          `json:"task"`
	ConversationHistoryDeletedRange json.RawMessage `json:"conversationHistoryDeletedRange"`
	CWDOnTaskInitialization         string          `json:"cwdOnTaskInitialization"`
	ShadowGitConfigWorkTree         string          `json:"shadowGitConfigWorkTree"`
	ModelID                         string          `json:"modelId"`
	// Roo.
	RootTaskID              string   `json:"rootTaskId"`
	ParentTaskID            string   `json:"parentTaskId"`
	Workspace               string   `json:"workspace"`
	Mode                    string   `json:"mode"`
	APIConfigName           string   `json:"apiConfigName"`
	Status                  string   `json:"status"`
	ChildIDs                []string `json:"childIds"`
	CompletionResultSummary string   `json:"completionResultSummary"`

	Members

	// Raw is the item as read.
	Raw json.RawMessage `json:"-"`
}

HistoryItem is a task's index entry: classic Cline's element of state/taskHistory.json, Roo's history_item.json.

func FindHistory

func FindHistory(data []byte, id string) (h *HistoryItem, found bool, err error)

FindHistory returns the element of a taskHistory.json whose id is id. found is false when no element names it; err is set when the one that does is not an object of the item's members.

func (*HistoryItem) DeletedRange

func (h *HistoryItem) DeletedRange() ([2]int, bool)

DeletedRange is the item's conversationHistoryDeletedRange.

func (HistoryItem) MarshalJSON

func (h HistoryItem) MarshalJSON() ([]byte, error)

MarshalJSON writes the item back as it was read.

func (*HistoryItem) UnmarshalJSON

func (h *HistoryItem) UnmarshalJSON(data []byte) error

UnmarshalJSON decodes the item, keeping undeclared members and those of another JSON type.

type MediaSource

type MediaSource struct {
	Type      string `json:"type"`
	MediaType string `json:"media_type"`
	Data      string `json:"data"`
	URL       string `json:"url"`

	Members
}

MediaSource is where an image's or a document's bytes are.

func (MediaSource) MarshalJSON

func (s MediaSource) MarshalJSON() ([]byte, error)

MarshalJSON writes the source back as it was read.

func (*MediaSource) UnmarshalJSON

func (s *MediaSource) UnmarshalJSON(data []byte) error

UnmarshalJSON decodes a source, keeping undeclared members.

type Members

type Members = jsonline.Members

Members is embedded in every object this package decodes. It keeps the members the Go type does not declare, and remembers which declared members the input carried and which were null, so an object decoded and encoded again is the same JSON value.

type Message

type Message struct {
	Role    string          `json:"role"`
	Content Content         `json:"content"`
	ID      string          `json:"id"`
	TS      json.RawMessage `json:"ts"`

	// Cline classic, on an assistant message.
	ModelInfo *ModelInfo `json:"modelInfo"`
	Metrics   *Metrics   `json:"metrics"`

	// Roo.
	IsSummary          bool            `json:"isSummary"`
	CondenseID         string          `json:"condenseId"`
	CondenseParent     string          `json:"condenseParent"`
	TruncationID       string          `json:"truncationId"`
	TruncationParent   string          `json:"truncationParent"`
	IsTruncationMarker bool            `json:"isTruncationMarker"`
	Type               string          `json:"type"`
	EncryptedContent   string          `json:"encrypted_content"`
	Summary            json.RawMessage `json:"summary"`
	ReasoningDetails   json.RawMessage `json:"reasoning_details"`
	ReasoningContent   json.RawMessage `json:"reasoning_content"`

	Members

	// Raw is the element as read, and Err why it did not decode, for an
	// element that is not an object; nothing else is then set.
	Raw json.RawMessage `json:"-"`
	Err error           `json:"-"`
}

Message is one element of api_conversation_history.json: an Anthropic MessageParam and the members Cline and Roo add to it. Roo also writes elements with no role, a reasoning item on its own (Type "reasoning").

func (*Message) IsStandaloneReasoning

func (m *Message) IsStandaloneReasoning() bool

IsStandaloneReasoning reports whether the element is Roo's reasoning item written on its own, with no role.

func (Message) MarshalJSON

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

MarshalJSON writes the message back as it was read.

func (*Message) Time

func (m *Message) Time() (time.Time, bool)

Time is the message's ts; false when it has none.

func (*Message) ToolUses

func (m *Message) ToolUses() []*Block

ToolUses returns the message's tool_use blocks that decoded.

func (*Message) UnmarshalJSON

func (m *Message) UnmarshalJSON(data []byte) error

UnmarshalJSON decodes a message, keeping undeclared members and members of another JSON type; an element that is not an object is kept with Err set.

type MetricTokens

type MetricTokens struct {
	Prompt     json.RawMessage `json:"prompt"`
	Completion json.RawMessage `json:"completion"`
	Cached     json.RawMessage `json:"cached"`

	Members
}

MetricTokens are the counts of Metrics, kept as written.

func (MetricTokens) MarshalJSON

func (x MetricTokens) MarshalJSON() ([]byte, error)

MarshalJSON writes the counts back as they were read.

func (*MetricTokens) UnmarshalJSON

func (x *MetricTokens) UnmarshalJSON(data []byte) error

UnmarshalJSON decodes the counts, keeping undeclared members.

type Metrics

type Metrics struct {
	Tokens *MetricTokens   `json:"tokens"`
	Cost   json.RawMessage `json:"cost"`

	Members
}

Metrics is a classic assistant message's usage: prompt is the provider's input tokens, whose meaning differs by provider, and cached the cache writes and reads added together.

func (Metrics) MarshalJSON

func (x Metrics) MarshalJSON() ([]byte, error)

MarshalJSON writes the metrics back as they were read.

func (*Metrics) UnmarshalJSON

func (x *Metrics) UnmarshalJSON(data []byte) error

UnmarshalJSON decodes the metrics, keeping undeclared members.

type ModelInfo

type ModelInfo struct {
	ModelID    string `json:"modelId"`
	ProviderID string `json:"providerId"`
	Mode       string `json:"mode"`

	Members
}

ModelInfo is the model a classic assistant message was written with.

func (ModelInfo) MarshalJSON

func (i ModelInfo) MarshalJSON() ([]byte, error)

MarshalJSON writes the model info back as it was read.

func (*ModelInfo) UnmarshalJSON

func (i *ModelInfo) UnmarshalJSON(data []byte) error

UnmarshalJSON decodes the model info, keeping undeclared members.

type ModelUsage

type ModelUsage struct {
	TS              json.RawMessage `json:"ts"`
	ModelID         string          `json:"model_id"`
	ModelProviderID string          `json:"model_provider_id"`
	Mode            string          `json:"mode"`

	Members
}

ModelUsage is one model switch the metadata records.

func (ModelUsage) MarshalJSON

func (u ModelUsage) MarshalJSON() ([]byte, error)

MarshalJSON writes the record back as it was read.

func (*ModelUsage) UnmarshalJSON

func (u *ModelUsage) UnmarshalJSON(data []byte) error

UnmarshalJSON decodes the record, keeping undeclared members.

type ReqInfo

type ReqInfo struct {
	Request                string          `json:"request"`
	TokensIn               json.RawMessage `json:"tokensIn"`
	TokensOut              json.RawMessage `json:"tokensOut"`
	CacheWrites            json.RawMessage `json:"cacheWrites"`
	CacheReads             json.RawMessage `json:"cacheReads"`
	Cost                   json.RawMessage `json:"cost"`
	CancelReason           string          `json:"cancelReason"`
	StreamingFailedMessage string          `json:"streamingFailedMessage"`
	APIProtocol            string          `json:"apiProtocol"`

	Members
}

ReqInfo is ClineApiReqInfo: one request's usage, the text of an api_req_started message. Counts are kept as written.

func (*ReqInfo) HasUsage

func (r *ReqInfo) HasUsage() bool

HasUsage reports whether the info carries any count or a cost.

func (ReqInfo) MarshalJSON

func (r ReqInfo) MarshalJSON() ([]byte, error)

MarshalJSON writes the info back as it was read.

func (*ReqInfo) UnmarshalJSON

func (r *ReqInfo) UnmarshalJSON(data []byte) error

UnmarshalJSON decodes the info, keeping undeclared members.

type Task

type Task struct {
	// Dir is the task directory, and ID its name, the task's ID.
	Dir string
	ID  string
	// Variant is which agent wrote the task; VariantBy says how it was
	// told, and Guessed that it was told by shape rather than by the
	// storage directory's name.
	Variant   Variant
	VariantBy string
	Guessed   bool

	API Array[*Message]
	UI  Array[*UIMessage]
	// Context holds context_history.json's updates, each a unit.
	Context Array[*ContextUpdate]

	// Metadata is task_metadata.json; MetadataErr why it did not read.
	Metadata    *TaskMetadata
	MetadataRaw json.RawMessage
	MetadataErr error
	HasMetadata bool

	// Settings is settings.json as read, a per-task settings snapshot
	// some classic releases write; SettingsErr why it did not parse.
	Settings    json.RawMessage
	SettingsErr error
	HasSettings bool

	// History is the task's index entry: Roo's history_item.json, or
	// the element of classic's state/taskHistory.json naming this task.
	// HistoryFile is where it was read from, relative to the storage
	// directory; HistoryErr why it did not read. A history_item.json is
	// a unit of the task; an entry of taskHistory.json is one when it
	// was found.
	History     *HistoryItem
	HistoryFile string
	HistoryErr  error
	HistoryUnit bool

	// Others lists the other files in the task directory, each a unit
	// the converter does not read: a hook's leftover transcript, a
	// temporary file, a newer release's. Dirs lists its directories.
	Others []string
	Dirs   []string
}

Task is one task directory as read.

func ParseTask

func ParseTask(id string, files map[string][]byte) *Task

ParseTask reads a task from its files' contents, by name, without touching the file system: the task's index entry beside the directory and the variant by the storage directory are left to ReadTask, so the variant is told by shape. A claude_messages.json, the name the earliest releases gave a file, is read as UI messages, or as the API history when its elements have a role.

func ReadTask

func ReadTask(path string) (*Task, error)

ReadTask reads the task directory path names, or the directory of the file it names. A file that cannot be read or parsed is recorded on the task, never fatal: ReadTask fails only when the directory cannot be listed or holds neither an API history nor UI messages.

func (*Task) Units

func (t *Task) Units() int

Units is the number of units the task accounts for.

type TaskMetadata

type TaskMetadata struct {
	FilesInContext     json.RawMessage `json:"files_in_context"`
	ModelUsage         []*ModelUsage   `json:"model_usage"`
	EnvironmentHistory []*Environment  `json:"environment_history"`

	Members
}

TaskMetadata is a classic task's task_metadata.json, or Roo's, which holds files_in_context alone.

func (TaskMetadata) MarshalJSON

func (t TaskMetadata) MarshalJSON() ([]byte, error)

MarshalJSON writes the metadata back as it was read.

func (*TaskMetadata) UnmarshalJSON

func (t *TaskMetadata) UnmarshalJSON(data []byte) error

UnmarshalJSON decodes the metadata, keeping undeclared members and those of another JSON type.

type UIMessage

type UIMessage struct {
	TS                              json.RawMessage `json:"ts"`
	Type                            string          `json:"type"`
	Ask                             string          `json:"ask"`
	Say                             string          `json:"say"`
	Text                            string          `json:"text"`
	Partial                         bool            `json:"partial"`
	ConversationHistoryIndex        json.RawMessage `json:"conversationHistoryIndex"`
	ConversationHistoryDeletedRange json.RawMessage `json:"conversationHistoryDeletedRange"`
	// Roo.
	APIProtocol       string          `json:"apiProtocol"`
	ContextCondense   json.RawMessage `json:"contextCondense"`
	ContextTruncation json.RawMessage `json:"contextTruncation"`

	Members

	Raw json.RawMessage `json:"-"`
	Err error           `json:"-"`
}

UIMessage is one element of ui_messages.json: what the chat view shows, an ask or a say.

func (*UIMessage) DeletedRange

func (m *UIMessage) DeletedRange() (r [2]int, ok bool)

DeletedRange is conversationHistoryDeletedRange, the range of API messages a request left out when the UI message was written. ok is false when it is absent or not two integers; set says it was there.

func (*UIMessage) HistoryIndex

func (m *UIMessage) HistoryIndex() (int, bool)

HistoryIndex is conversationHistoryIndex, the index of the last API message when the UI message was written; false when absent.

func (*UIMessage) Kind

func (m *UIMessage) Kind() string

Kind is the message's ask or say, whichever its type names.

func (UIMessage) MarshalJSON

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

MarshalJSON writes the message back as it was read.

func (*UIMessage) ReqInfo

func (m *UIMessage) ReqInfo() *ReqInfo

ReqInfo decodes the text of an api_req_started or deleted_api_reqs message; nil when it is not a JSON object.

func (*UIMessage) Time

func (m *UIMessage) Time() (time.Time, bool)

Time is the message's ts; false when it has none.

func (*UIMessage) UnmarshalJSON

func (m *UIMessage) UnmarshalJSON(data []byte) error

UnmarshalJSON decodes a UI message, keeping undeclared members; an element that is not an object is kept with Err set.

type Variant

type Variant string

Variant is which agent wrote a task directory.

const (
	// Classic is Cline before 4.0, the VS Code extension's task
	// directories, and the standalone hosts that kept the layout.
	Classic Variant = "classic"
	// Roo is Roo Code, forked from classic Cline.
	Roo Variant = "roo"
)

type XMLToolCall

type XMLToolCall struct {
	Name   string            `json:"name"`
	Params map[string]string `json:"params,omitempty"`
	// Partial says the call has no closing tag: the text ends inside
	// it.
	Partial bool `json:"partial,omitempty"`
}

XMLToolCall is one tool call a model wrote as XML in its text.

func ParseXMLTools

func ParseXMLTools(text string) []XMLToolCall

ParseXMLTools reads the tool calls a text holds in the XML style, as Cline's parser reads them: a known tool's opening tag, its parameters as child elements, its closing tag. Text outside a call is left alone. It reads what it can and never fails.

Directories

Path Synopsis
Package convert converts classic Cline and Roo Code task directories into the Agent Session Format.
Package convert converts classic Cline and Roo Code task directories into the Agent Session Format.

Jump to

Keyboard shortcuts

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