Documentation
¶
Overview ¶
Package journal is the CLI's local action journal: a SQLite database under the CLI home that records what the tool did, in three linked tables. An operations row groups the one-or-more API calls a single logical operation makes (a place reconcile sends and then looks up; a history walk pages); an api_calls row records each underlying HTTP call (linked to its operation, with a 1-based sequence within it); and an orders row holds a dedicated record per placed order (minted at clientOrderId time and updated with the server order id once the placement resolves, linked to its operation).
It exists for two audiences. First, the AI agents this CLI is built for: an agent can make mistakes, so the CLI keeps an automatic, durable source of truth of what it actually did — when a human asks "what did you do?", the agent can read the journal back instead of guessing. Second, support: when a user hits a problem, the journal (or a redacted `debug bundle` of it) is the diagnostic record to send to Korbit.
It never stores secrets — only the public API-key id and the pre-signing request parameters (the ED25519 signature and private key never reach here).
Index ¶
- Constants
- func DefaultPath(home string) string
- func Disabled(getenv func(string) string) bool
- type CallRecord
- type CallRow
- type Logger
- func (l *Logger) Close() error
- func (l *Logger) FinishOperation(id int64, f OperationFinish) error
- func (l *Logger) FinishOrder(id int64, f OrderFinish) error
- func (l *Logger) LogCall(r CallRecord) (int64, error)
- func (l *Logger) Path() string
- func (l *Logger) RecentCalls(limit int) ([]CallRow, error)
- func (l *Logger) RecentOperations(limit int) ([]OperationRow, error)
- func (l *Logger) RecentOrders(limit int) ([]OrderRow, error)
- func (l *Logger) StartOperation(o OperationStart) (int64, error)
- func (l *Logger) StartOrder(o OrderStart) (int64, error)
- type OperationFinish
- type OperationRow
- type OperationStart
- type OrderFinish
- type OrderRow
- type OrderStart
Constants ¶
const FileName = "korbit-cli.db"
FileName is the journal database file under the CLI home.
Variables ¶
This section is empty.
Functions ¶
func DefaultPath ¶
DefaultPath returns the journal database path under home.
Types ¶
type CallRecord ¶
type CallRecord struct {
OperationID int64 // the operations row this call belongs to (0 => NULL)
Seq int // 1-based within the operation; 0 for ad-hoc calls
StartedAtMs int64
FinishedAtMs int64
Method string
Path string
BaseURL string
Auth bool
KeyName string
APIKeyID string
ParamsJSON string
HTTPStatus *int // nil when no HTTP response was received (network failure / success)
Success bool
ErrorCode string
ErrorMessage string
RetryCount int
DurationMs int64
CLIVersion string
}
CallRecord is one API-call outcome to record in api_calls. OperationID links the call to the operation that issued it (0 ⇒ a NULL link, for an ad-hoc call), and Seq is its 1-based position within that operation (0 for ad-hoc).
type CallRow ¶
type CallRow struct {
ID int64 `json:"id"`
OperationID *int64 `json:"operationId,omitempty"`
Seq int `json:"seq"`
StartedAtMs int64 `json:"startedAtMs"`
FinishedAtMs *int64 `json:"finishedAtMs,omitempty"`
Method string `json:"method"`
Path string `json:"path"`
BaseURL string `json:"baseUrl"`
Auth bool `json:"auth"`
KeyName string `json:"keyName,omitempty"`
APIKeyID string `json:"apiKeyId,omitempty"`
Params json.RawMessage `json:"params,omitempty"`
HTTPStatus *int `json:"httpStatus,omitempty"`
Success bool `json:"success"`
ErrorCode string `json:"errorCode,omitempty"`
ErrorMessage string `json:"errorMessage,omitempty"`
RetryCount int `json:"retryCount"`
DurationMs *int64 `json:"durationMs,omitempty"`
CLIVersion string `json:"cliVersion,omitempty"`
}
CallRow is a recorded api_calls row, shaped for JSON output and the support bundle. Absent/empty fields are omitted.
type Logger ¶
type Logger struct {
// contains filtered or unexported fields
}
Logger is a handle to the journal database.
func Open ¶
Open opens (creating if needed) the journal database at path and ensures the schema exists. It enables WAL so concurrent korbit-cli invocations can read while one writes, and a busy_timeout so a writer waits for the lock instead of failing with SQLITE_BUSY. A single pooled connection (SetMaxOpenConns(1)) serializes all in-process access, so no additional application-level locking is needed; WAL + busy_timeout cover the cross-process case.
noFsync sets PRAGMA synchronous=OFF: writes are not flushed to disk, which is faster but means a power loss or OS crash may lose or corrupt recent writes. The pre-send ordering guarantee (a journaled row is written before the request proceeds) is unaffected — only crash-durability is traded for speed.
log receives operational diagnostics (the path, pragmas, schema-version reconciliation, and an Info milestone once opened); nil is silent (logging.Or).
func (*Logger) FinishOperation ¶
func (l *Logger) FinishOperation(id int64, f OperationFinish) error
FinishOperation updates the operations row identified by id with the result.
func (*Logger) FinishOrder ¶
func (l *Logger) FinishOrder(id int64, f OrderFinish) error
FinishOrder updates the order row identified by id with the placement result. 'accepted' is positive proof the order landed, so it is sticky: a later result of 'failed' or 'unknown' never downgrades it, and the previously-recorded order_id is kept when the new result carries none. So reusing a clientOrderId to retry an order that already went through — which the server answers with DUPLICATE_CLIENT_ORDER_ID, or which a later ambiguous attempt can only call UNKNOWN — doesn't erase the truth that the order is live. The CASE clauses read the row's pre-update status, so the guard compares against the existing value. Every per-attempt outcome is still preserved in full in api_calls.
func (*Logger) LogCall ¶
func (l *Logger) LogCall(r CallRecord) (int64, error)
LogCall inserts an api_calls row and returns its id.
func (*Logger) RecentCalls ¶
RecentCalls returns the most recent api_calls rows, newest first.
func (*Logger) RecentOperations ¶
func (l *Logger) RecentOperations(limit int) ([]OperationRow, error)
RecentOperations returns the most recent operations rows, newest first.
func (*Logger) RecentOrders ¶
RecentOrders returns the most recent orders rows, newest first.
func (*Logger) StartOperation ¶
func (l *Logger) StartOperation(o OperationStart) (int64, error)
StartOperation inserts an operations row with outcome 'running' and returns its id, to be folded with FinishOperation once the operation completes.
func (*Logger) StartOrder ¶
func (l *Logger) StartOrder(o OrderStart) (int64, error)
StartOrder records (or, when the clientOrderId is being reused to retry the same order, refreshes) the order's mint-time row and returns its id. Reusing a clientOrderId bumps attempt_count and re-arms the row rather than inserting a duplicate — honoring both the UNIQUE(client_order_id) index and the documented idempotent-retry flow.
type OperationFinish ¶
type OperationFinish struct {
FinishedAtMs int64
Outcome string // ok|failed|unknown
ErrorCode string
Attempts int // total api_calls issued under this operation
}
OperationFinish is the result folded into an operations row once the operation completes.
type OperationRow ¶
type OperationRow struct {
ID int64 `json:"id"`
StartedAtMs int64 `json:"startedAtMs"`
FinishedAtMs *int64 `json:"finishedAtMs,omitempty"`
OpID string `json:"opId"`
Surface string `json:"surface"`
Safety string `json:"safety,omitempty"`
Outcome string `json:"outcome"`
ErrorCode string `json:"errorCode,omitempty"`
Attempts int `json:"attempts"`
KeyName string `json:"keyName,omitempty"`
APIKeyID string `json:"apiKeyId,omitempty"`
CLIVersion string `json:"cliVersion,omitempty"`
}
OperationRow is a recorded operations row, shaped for JSON output and the support bundle. Absent/empty fields are omitted.
type OperationStart ¶
type OperationStart struct {
StartedAtMs int64
OpID string // dotted operation id, e.g. "order.place"
Surface string // cli|monitor|mcp|...
Safety string // read-only|idempotent|non-idempotent
KeyName string
APIKeyID string
CLIVersion string
}
OperationStart is the operations row written when an operation begins, before any of its calls are sent. outcome is set to 'running'; FinishOperation folds in the result.
type OrderFinish ¶
type OrderFinish struct {
FinishedAtMs int64
Status string
OrderID string
ErrorCode string
RetryCount int
}
OrderFinish is the outcome to fold into the order's row once the placement call has returned.
type OrderRow ¶
type OrderRow struct {
ID int64 `json:"id"`
OperationID *int64 `json:"operationId,omitempty"`
CreatedAtMs int64 `json:"createdAtMs"`
FinishedAtMs *int64 `json:"finishedAtMs,omitempty"`
ClientOrderID string `json:"clientOrderId"`
Symbol string `json:"symbol,omitempty"`
Side string `json:"side,omitempty"`
OrderType string `json:"type,omitempty"`
Price string `json:"price,omitempty"`
Qty string `json:"qty,omitempty"`
Amt string `json:"amt,omitempty"`
Tif string `json:"tif,omitempty"`
Params json.RawMessage `json:"params,omitempty"`
KeyName string `json:"keyName,omitempty"`
APIKeyID string `json:"apiKeyId,omitempty"`
Status string `json:"status"`
OrderID string `json:"orderId,omitempty"`
ErrorCode string `json:"errorCode,omitempty"`
AttemptCount int `json:"attemptCount"`
RetryCount int `json:"retryCount"`
}
OrderRow is a recorded orders row, shaped for JSON output and the bundle.
type OrderStart ¶
type OrderStart struct {
CreatedAtMs int64
OperationID int64 // the operations row this order belongs to (0 => NULL)
ClientOrderID string
Symbol string
Side string
OrderType string
Price string
Qty string
Amt string
Tif string
ParamsJSON string
KeyName string
APIKeyID string
}
OrderStart is the mint-time order intent, recorded before the placement call is sent (so a crash mid-call still leaves a record of what was attempted). OperationID links the order to the operation that placed it.