Documentation
¶
Overview ¶
Package schemas defines the typed payload structs for every `--json`-emitting bones CLI verb (ADR 0053). Each verb has one Go struct here; the `cmd/bones-schemagen` binary reflects these structs and writes derived JSON Schema files into the repo-root `schemas/` directory.
Go types in this package are the source of truth for the external `--json` contract. Types here are intentionally separate from the internal storage types under `internal/tasks`, `internal/swarm`, etc.; the duplication pins the external surface so internal types can evolve freely behind it.
The envelope below is universal: every emitter wraps its payload in `Envelope[T]` so consumers can write one parser that handles every verb. The single carve-out (`bones logs --json`, which passthrough-emits substrate event-log NDJSON) is documented in ADR 0053 and uses the substrate's own contract per ADR 0052.
Index ¶
- Variables
- func Emit[T any](w io.Writer, env Envelope[T]) error
- func EmitIndent[T any](w io.Writer, env Envelope[T]) error
- func VersionFor(verb string) string
- type DoctorAllPayload
- type DoctorWorkspaceRow
- type Edge
- type Envelope
- type Schema
- type StatusAllPayload
- type StatusWorkspaceRow
- type SwarmDispatchPayload
- type SwarmStatusPayload
- type SwarmStatusRow
- type SwarmTasksPayload
- type Task
- type TasksAggregatePayload
- type TasksAggregateSlot
- type TasksBySlotPayload
- type TasksClaimPayload
- type TasksClosePayload
- type TasksCreatePayload
- type TasksLinkPayload
- type TasksListPayload
- type TasksPrimePayload
- type TasksPrimePresence
- type TasksPrimeTask
- type TasksPrimeThread
- type TasksReadyPayload
- type TasksShowPayload
- type TasksSlotGroup
- type TasksUpdatePayload
- type UpAction
- type UpPayload
- type UpSummary
- type VerbInfo
- type WorkspacesGetPayload
- type WorkspacesListPayload
- type WorkspacesRow
Constants ¶
This section is empty.
Variables ¶
var Verbs = []VerbInfo{
{Verb: "doctor", CurrentVersion: "v1", PayloadName: "DoctorAllPayload"},
{Verb: "status", CurrentVersion: "v1", PayloadName: "StatusAllPayload"},
{Verb: "swarm.dispatch", CurrentVersion: "v1", PayloadName: "SwarmDispatchPayload"},
{Verb: "swarm.status", CurrentVersion: "v1", PayloadName: "SwarmStatusPayload"},
{Verb: "swarm.tasks", CurrentVersion: "v1", PayloadName: "SwarmTasksPayload"},
{Verb: "tasks.aggregate", CurrentVersion: "v1", PayloadName: "TasksAggregatePayload"},
{Verb: "tasks.bySlot", CurrentVersion: "v1", PayloadName: "TasksBySlotPayload"},
{Verb: "tasks.claim", CurrentVersion: "v1", PayloadName: "TasksClaimPayload"},
{Verb: "tasks.close", CurrentVersion: "v1", PayloadName: "TasksClosePayload"},
{Verb: "tasks.create", CurrentVersion: "v1", PayloadName: "TasksCreatePayload"},
{Verb: "tasks.link", CurrentVersion: "v1", PayloadName: "TasksLinkPayload"},
{Verb: "tasks.list", CurrentVersion: "v2", PayloadName: "TasksListPayload"},
{Verb: "tasks.prime", CurrentVersion: "v1", PayloadName: "TasksPrimePayload"},
{Verb: "tasks.ready", CurrentVersion: "v1", PayloadName: "TasksReadyPayload"},
{Verb: "tasks.show", CurrentVersion: "v1", PayloadName: "TasksShowPayload"},
{Verb: "tasks.update", CurrentVersion: "v1", PayloadName: "TasksUpdatePayload"},
{Verb: "up", CurrentVersion: "v1", PayloadName: "UpPayload"},
{Verb: "workspaces.get", CurrentVersion: "v1", PayloadName: "WorkspacesGetPayload"},
{Verb: "workspaces.list", CurrentVersion: "v1", PayloadName: "WorkspacesListPayload"},
}
Verbs is the canonical registry. Order is alphabetical by verb name; the generator iterates this slice and writes schemas/<verb>.<version>.json per entry.
When adding a new verb: append an entry here, define the payload struct below, run `make schemas`, and add the per-verb test in cli/schemas_test.go.
Functions ¶
func Emit ¶
Emit marshals env as compact JSON to w with a trailing newline. Mirrors the pre-existing `emitJSON` helper's wire shape so a `--json`-emitting verb wrapped by this helper byte-for-byte matches the pre-envelope shape (modulo the wrap).
Compact output is the bones default; emitters that previously used indented output (`json.NewEncoder.SetIndent`) keep their indented shape via EmitIndent. A future v2 may unify these, but v1 pins today's per-verb shape.
func EmitIndent ¶
EmitIndent marshals env as indented (2-space) JSON to w with a trailing newline emitted by the encoder. Used by verbs whose pre-envelope shape was `json.NewEncoder.SetIndent(""," ")` — `swarm.status`, `workspaces.list`, `workspaces.get` — so v1 preserves their human-readable indentation.
func VersionFor ¶
VersionFor returns the current version string for verb. Falls back to "v1" for unknown verbs so the generator and emitters share one lookup. (CI gates that every emitter's verb is in this registry, so the fallback only fires on coding errors.)
Types ¶
type DoctorAllPayload ¶
type DoctorAllPayload struct {
Workspaces []DoctorWorkspaceRow `json:"workspaces"`
}
DoctorAllPayload is the payload for `bones doctor --all --json`. Mirrors the per-workspace row shape `renderDoctorAllJSON` emits.
type DoctorWorkspaceRow ¶
type DoctorWorkspaceRow struct {
Name string `json:"name"`
Cwd string `json:"cwd"`
HubAlive bool `json:"hub_alive"`
Issues int `json:"issues"`
}
DoctorWorkspaceRow is one row of the doctor --all summary.
type Edge ¶
Edge mirrors the on-the-wire edge shape from internal/tasks.Edge. Re-declared here so cli/schemas owns the external contract; the internal Edge type may evolve behind it.
type Envelope ¶
Envelope wraps every `--json` payload. T is the verb-specific typed payload struct defined elsewhere in this package.
Generic over T so the compiler enforces that the wrapped payload matches what the schemagen generator reflected for the named verb; a copy/paste mismatch (wrapping a TasksListPayload under a schema verb of "tasks.show") becomes a build error.
type Schema ¶
Schema is the meta-block stamped on every bones `--json` emit. Verb is the dotted CLI command path (e.g. "tasks.list", "swarm.dispatch"). Version is "v" followed by an integer (e.g. "v1"); the ADR 0053 hard-cut migration policy means a single version of bones emits exactly one version per verb.
type StatusAllPayload ¶
type StatusAllPayload struct {
Workspaces []StatusWorkspaceRow `json:"workspaces"`
}
StatusAllPayload is the payload for `bones status --all --json`. Mirrors `renderStatusAllJSON`: live registry rows only.
type StatusWorkspaceRow ¶
type StatusWorkspaceRow struct {
Cwd string `json:"cwd"`
Name string `json:"name"`
HubURL string `json:"hub_url"`
State string `json:"state"`
Sessions int `json:"sessions"`
StartedAt timefmt.LoggedTime `json:"started_at"`
}
StatusWorkspaceRow is one row of the status --all view.
State (#305) is one of "active" (live hub, PID alive + HTTP probe ok), "idle" (PID=0, registered by `bones up` but no hub serving), or "paused" (PID > 0 but probe failed). Scripts branching on the row should match this field rather than reading HubPID directly.
type SwarmDispatchPayload ¶
type SwarmDispatchPayload struct {
ManifestPath string `json:"manifest_path"`
TaskCount int `json:"task_count"`
PlanSHA256 string `json:"plan_sha256"`
}
SwarmDispatchPayload is the payload for `bones swarm dispatch --json`. Mirrors `dispatchSummaryJSON`: manifest path + plan hash + task count for the just-built dispatch.
type SwarmStatusPayload ¶
type SwarmStatusPayload []SwarmStatusRow
SwarmStatusPayload is the payload for `bones swarm status --json`. Mirrors `[]statusRow` — every active swarm-session record.
type SwarmStatusRow ¶
type SwarmStatusRow struct {
Slot string `json:"slot"`
TaskID string `json:"task_id"`
AgentID string `json:"agent_id"`
Host string `json:"host"`
LeafPID int `json:"leaf_pid"`
StartedAt timefmt.LoggedTime `json:"started_at"`
LastRenewed timefmt.LoggedTime `json:"last_renewed"`
State string `json:"state"`
StaleSeconds int64 `json:"stale_seconds"`
}
SwarmStatusRow is one swarm-session row.
type SwarmTasksPayload ¶
type SwarmTasksPayload []Task
SwarmTasksPayload is the payload for `bones swarm tasks --json`. Mirrors the `[]tasks.Task` shape returned by the slot-scoped readiness filter.
type Task ¶
type Task struct {
ID string `json:"id"`
Title string `json:"title"`
Status string `json:"status"`
ClaimedBy string `json:"claimed_by,omitempty"`
Files []string `json:"files"`
Parent string `json:"parent,omitempty"`
Edges []Edge `json:"edges,omitempty"`
Context map[string]string `json:"context,omitempty"`
CreatedAt timefmt.LoggedTime `json:"created_at"`
UpdatedAt timefmt.LoggedTime `json:"updated_at"`
DeferUntil *timefmt.LoggedTime `json:"defer_until,omitempty"`
ClosedAt *timefmt.LoggedTime `json:"closed_at,omitempty"`
ClosedBy string `json:"closed_by,omitempty"`
ClosedReason string `json:"closed_reason,omitempty"`
ClaimEpoch uint64 `json:"claim_epoch,omitempty"`
OriginalSize uint64 `json:"original_size,omitempty"`
CompactLevel uint8 `json:"compact_level,omitempty"`
CompactedAt *timefmt.LoggedTime `json:"compacted_at,omitempty"`
SchemaVersion int `json:"schema_version"`
LastEventSeq uint64 `json:"last_event_seq,omitempty"`
}
Task is the on-the-wire shape every task-emitting verb writes. Mirrors internal/tasks.Task field-for-field including JSON tags (`omitempty` markers preserved); see ADR 0005 and ADR 0014 for the canonical schema.
Per #324 every time field is timefmt.LoggedTime so the marshal path emits UTC RFC3339 rather than RFC3339Nano-with-local-offset. Pointer-time fields stay pointer-typed so an absent value omits cleanly under omitempty rather than serializing the zero value.
type TasksAggregatePayload ¶
type TasksAggregatePayload struct {
Since string `json:"since"`
TotalTasks int `json:"total_tasks"`
TotalSlots int `json:"total_slots"`
ActiveSlots int `json:"active_slots"`
Slots []TasksAggregateSlot `json:"slots"`
}
TasksAggregatePayload is the payload for `bones tasks aggregate --json`. Mirrors `aggregateResult`: window summary + per-slot breakdown.
type TasksAggregateSlot ¶
type TasksAggregateSlot struct {
SlotID string `json:"slot_id"`
Tasks int `json:"tasks"`
Files []string `json:"files"`
Status string `json:"status"`
}
TasksAggregateSlot is the per-slot summary row inside a tasks.aggregate payload.
type TasksBySlotPayload ¶
type TasksBySlotPayload struct {
Slots []TasksSlotGroup `json:"slots"`
HotThreshold int `json:"hot_threshold"`
}
TasksBySlotPayload is the payload for `bones tasks list --by-slot --json`. Distinct verb name from `tasks.list` because the shape diverges: `tasks.list` emits `[]Task`; `tasks.bySlot` emits a per-slot grouping with the hot-threshold context.
type TasksClaimPayload ¶
type TasksClaimPayload = Task
TasksClaimPayload is the payload for `bones tasks claim --json`. Emits the post-claim Task record.
type TasksClosePayload ¶
type TasksClosePayload = Task
TasksClosePayload is the payload for `bones tasks close --json`. Emits the post-close Task record.
type TasksCreatePayload ¶
type TasksCreatePayload = Task
TasksCreatePayload is the payload for `bones tasks create --json`. Emits the just-created Task record.
type TasksLinkPayload ¶
type TasksLinkPayload struct {
From string `json:"from"`
To string `json:"to"`
Type string `json:"type"`
}
TasksLinkPayload is the payload for `bones tasks link --json`. Emits a link-confirmation tuple.
type TasksListPayload ¶
type TasksListPayload struct {
Tasks []Task `json:"tasks"`
}
TasksListPayload is the payload for `bones tasks list --json`. Emits a (possibly filtered) list of tasks. Default-mode list only; the `--by-slot` mode emits the `tasks.bySlot` shape instead.
v2 (#NNN): wrapped the array in a named field for shape consistency with every other envelope (`status`, `workspaces.list`, `swarm.status`, etc., all use `data.<resource>`). v1 returned the array as `data` directly. Consumers using `.data[]` against v1 migrate to `.data.tasks[]` against v2.
type TasksPrimePayload ¶
type TasksPrimePayload struct {
OpenTasks []TasksPrimeTask `json:"open_tasks"`
ReadyTasks []TasksPrimeTask `json:"ready_tasks"`
ClaimedTasks []TasksPrimeTask `json:"claimed_tasks"`
Threads []TasksPrimeThread `json:"threads"`
Peers []TasksPrimePresence `json:"peers"`
}
TasksPrimePayload is the payload for `bones tasks prime --json`. Mirrors `primeResultJSON`: the agent's open/ready/claimed task view + recent threads + online peers.
type TasksPrimePresence ¶
type TasksPrimePresence struct {
AgentID string `json:"agent_id"`
Project string `json:"project"`
StartedAt timefmt.LoggedTime `json:"started_at"`
LastSeen timefmt.LoggedTime `json:"last_seen"`
}
TasksPrimePresence is the peer-presence row inside a tasks.prime payload.
type TasksPrimeTask ¶
type TasksPrimeTask struct {
ID string `json:"id"`
Title string `json:"title"`
Files []string `json:"files,omitempty"`
ClaimedBy string `json:"claimed_by,omitempty"`
CreatedAt timefmt.LoggedTime `json:"created_at"`
UpdatedAt timefmt.LoggedTime `json:"updated_at"`
}
TasksPrimeTask is the trimmed task shape used inside a tasks.prime payload — coord.Task projection without storage-internal fields.
type TasksPrimeThread ¶
type TasksPrimeThread struct {
ThreadShort string `json:"thread_short"`
LastActivity timefmt.LoggedTime `json:"last_activity"`
MessageCount int `json:"message_count"`
LastBody string `json:"last_body"`
}
TasksPrimeThread is the chat-thread row inside a tasks.prime payload.
type TasksReadyPayload ¶
type TasksReadyPayload []Task
TasksReadyPayload is the payload for `bones tasks ready --json`. Always emits an array (never null); empty result yields `[]`.
type TasksShowPayload ¶
type TasksShowPayload = Task
TasksShowPayload is the payload for `bones tasks show --json`. Single Task record.
type TasksSlotGroup ¶
type TasksSlotGroup struct {
Slot string `json:"slot"`
OpenCount int `json:"open_count"`
Hot bool `json:"hot"`
TaskIDs []string `json:"task_ids"`
}
TasksSlotGroup is one slot's grouping row.
type TasksUpdatePayload ¶
type TasksUpdatePayload = Task
TasksUpdatePayload is the payload for `bones tasks update --json`. Post-update Task record (or pre-update record when the update was a no-op).
type UpAction ¶
type UpAction struct {
Category string `json:"category"`
Action string `json:"action"`
Target string `json:"target"`
From string `json:"from,omitempty"`
To string `json:"to,omitempty"`
}
UpAction is one structured action `bones up` performed during this invocation. Category is one of the pinned set (gitignore, hooks, skills, manifest); Action is the verb (added, refreshed, installed, rewrote, synced, bumped); Target is the object (gitignore entry, hook event + command, skill count, schema version stamp).
From / To are populated only for `rewrote` actions — the legacy command and the canonical replacement, respectively. They are `omitempty` so non-rewrite rows don't carry empty string noise.
type UpPayload ¶
UpPayload is the payload for `bones up --json` (issue #314). Mirrors the per-action structured output emitted on the human path, plus a summary block carrying the workspace path and total action count so the envelope is self-describing.
The shape is generic over action category — `gitignore`, `hooks`, `skills`, `manifest` — to keep the typed wire surface stable as future actions enter the categories. Adding a brand-new category is intentional friction (per the issue's trap-3 guidance) but requires no schema change here.
type UpSummary ¶
UpSummary is the trailing summary block of an UpPayload. Mirrors the human-path success signature emitted via uxprint.Up: workspace path + action count.
type VerbInfo ¶
type VerbInfo struct {
Verb string
CurrentVersion string
// PayloadName is the Go type name of the payload struct,
// matched against the schemagen reflector's output. Lets the
// generator drive entirely off this slice instead of walking
// the AST.
PayloadName string
}
Verb identifies one CLI emit site. The dotted name matches the command path (`tasks.list` ↔ `bones tasks list`); CurrentVersion is the version this binary emits.
All verbs start at "v1" per ADR 0053's hard-cut migration policy.
type WorkspacesGetPayload ¶
type WorkspacesGetPayload = WorkspacesRow
WorkspacesGetPayload is the payload for `bones workspaces show <name> --json`. Single registry row.
type WorkspacesListPayload ¶
type WorkspacesListPayload []WorkspacesRow
WorkspacesListPayload is the payload for `bones workspaces ls --json`. All registry rows in the deterministic sort order ListInfo applies.
type WorkspacesRow ¶
type WorkspacesRow struct {
ID string `json:"id"`
Name string `json:"name"`
Cwd string `json:"cwd"`
HubStatus string `json:"hub_status"`
LastTouched string `json:"last_touched"`
AgentID string `json:"agent_id"`
NATSURL string `json:"nats_url"`
HubURL string `json:"hub_url"`
}
WorkspacesRow is one registry entry as serialized by both `workspaces.list` and `workspaces.get`.