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
- Variables
- func FindSessions(root string) ([]string, error)
- func Float(raw json.RawMessage) (float64, bool)
- func Int(raw json.RawMessage) (n int64, exact, ok bool)
- func IsNull(raw json.RawMessage) bool
- func IsTaskFile(path string) bool
- func Millis(raw json.RawMessage) (time.Time, bool)
- func Names(calls []XMLToolCall) []string
- func ParentTask(taskDir string) string
- func Range(raw json.RawMessage) (r [2]int, ok bool)
- func TaskDir(path string) (string, error)
- type Array
- type Block
- type Content
- type ContextUpdate
- type Environment
- type HistoryItem
- type MediaSource
- type Members
- type Message
- type MetricTokens
- type Metrics
- type ModelInfo
- type ModelUsage
- type ReqInfo
- type Task
- type TaskMetadata
- type UIMessage
- func (m *UIMessage) DeletedRange() (r [2]int, ok bool)
- func (m *UIMessage) HistoryIndex() (int, bool)
- func (m *UIMessage) Kind() string
- func (m UIMessage) MarshalJSON() ([]byte, error)
- func (m *UIMessage) ReqInfo() *ReqInfo
- func (m *UIMessage) Time() (time.Time, bool)
- func (m *UIMessage) UnmarshalJSON(data []byte) error
- type Variant
- type XMLToolCall
Constants ¶
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.
const ( StorageClassic = "saoudrizwan.claude-dev" StorageRoo = "rooveterinaryinc.roo-cline" )
Storage directory names, the VS Code extension IDs, lowercased as VS Code writes them.
const ( RoleUser = "user" RoleAssistant = "assistant" )
Roles of an API message.
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.
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 ¶
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 ¶
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 IsTaskFile ¶
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 ¶
ParentTask reads the parent task ID a Roo task's history_item.json names; empty when there is none.
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 ¶
ParseMessages reads an api_conversation_history.json from its bytes.
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 ¶
MarshalJSON writes the block back as it was read.
func (*Block) UnmarshalJSON ¶
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) MarshalJSON ¶
MarshalJSON writes the string, the blocks, or what was read.
func (*Content) UnmarshalJSON ¶
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.
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 ¶
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 ¶
IsStandaloneReasoning reports whether the element is Roo's reasoning item written on its own, with no role.
func (Message) MarshalJSON ¶
MarshalJSON writes the message back as it was read.
func (*Message) UnmarshalJSON ¶
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 ¶
MarshalJSON writes the metrics back as they were read.
func (*Metrics) UnmarshalJSON ¶
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 ¶
MarshalJSON writes the model info back as it was read.
func (*ModelInfo) UnmarshalJSON ¶
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) MarshalJSON ¶
MarshalJSON writes the info back as it was read.
func (*ReqInfo) UnmarshalJSON ¶
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 ¶
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.
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 ¶
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 ¶
HistoryIndex is conversationHistoryIndex, the index of the last API message when the UI message was written; false when absent.
func (UIMessage) MarshalJSON ¶
MarshalJSON writes the message back as it was read.
func (*UIMessage) 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) UnmarshalJSON ¶
UnmarshalJSON decodes a UI message, keeping undeclared members; an element that is not an object is kept with Err set.
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.