tsk binary format version 0
type State = {
header : StateHeader,
data : {
current : Set StateId,
tasks : Map TaskId Task,
taskMetadata : Map TaskId TaskMetadata,
comments : Map CommentId Comment,
commentMetadata : Map CommentId CommentMetadata,
history : Map StateId Commit
}
}
type = {
fileType : "tsk;",
version : "version=https://tsk.ielliott.io/v0;",
endOfHeader : "\n"
}
# The `List` is sorted in ascending order.
type Set a = List a
type List a = {
len : Word64,
items : Vector len a
}
prim Word64 is "an 8 byte natural number (big endian)"
prim Vector len a is "`len` consecutive `a`s"
type StateId = MD5
type MD5 = {
0 : Word64,
1 : Word64
}
# The `List` is sorted in ascending order on the first element of the pair
type Map k v = List (Pair k v)
type Pair a b = {
fst : a,
snd : b
}
type TaskId = GID
type GID = {
0 : Word16,
1 : Word16,
2 : Word16,
3 : Word16,
4 : Word16
}
prim Word16 is "a 2 byte natural number (big endian)"
type Task = {
status : Map StateId Utf8,
labels : Map StateId (Set Utf8),
title : Map StateId Utf8,
description : Map StateId Utf8
}
type Utf8 = {
length : Word64,
bytes : Vector length Word8
}
prim Word8 is "a byte (big endian)"
type TaskMetadata = {
createdAt : UTCTime
}
# Milliseconds since 1970-01-01T00:00Z
type UTCTime = Word64
type = GID
type = {
description : Map StateId Utf8
}
type = {
createdAt : UTCTime,
replyTo : ReplyId
}
type ReplyId = {
tag : Word64,
value : match tag {
0 => TaskId,
1 => CommentId
}
}
type Commit = {
parents : Set StateId,
change : Change
}
type Change = {
tag : Word64,
value : match tag {
0 => {
status : Utf8,
labels : Set Utf8,
title : Utf8,
description : Utf8
},
1 => {
taskId : TaskId,
updateTask : {
status : Update Utf8,
labels : Update (Set Utf8),
title : Update Utf8,
description : Update Utf8
}
},
2 => {
replyTo : ReplyId,
comment : {
description : Utf8
}
},
3 => {
commentId : CommentId,
updateComment : {
description : Update Utf8
}
}
}
}
type Update a = {
tag : Word64,
value : match tag {
0 => {},
1 => a,
2 => StateId
}
}