use serde_json::Value;
use super::Verb;
pub mod edit;
pub(crate) const PROJECT: &str = "project";
pub(crate) const ID: &str = "id";
pub(crate) const NAME: &str = "name";
pub const BALLS: Verb = Verb {
word: "balls",
params: &[],
flags: &[],
summary: "every ball⇄workspace binding fact",
detail: "The join rows: which ball is claimed by which workspace, in which \
state. It names no workspace, so its subject is EVERY channel this \
box holds, and the pane is the union — the same fanned shape \
`workspaces` and the decision queue keep. A ball nobody holds \
names no claimant and no wall, which is a reading rather than a \
blank.",
};
pub const BOARD: Verb = Verb {
word: "board",
params: &[],
flags: &[],
summary: "the fleet board — every live ball in its column",
detail: "The balls as columns: ready, gated, claimed, blocked. Gated is \
balls' own close-blocker rule — a ball you could claim but could \
not deliver — shown with the ball whose close mints its gate. \
Each claimed row names the conversations working it and carries \
what it has cost. It is also the ONLY answer carrying an armed \
loop's own facts: there is no `fleet` read on this wire, and a \
box running nothing leaves the array out rather than answering an \
empty one.",
};
pub const WORKSPACE_BALLS: Verb = Verb {
word: "workspace-balls",
params: &["workspace"],
flags: &[],
summary: "the balls one workspace holds, with what each has cost",
detail: "Every ball bound to the named workspace: its id, its badge, the \
project its `bl` verbs run in, the name they stamp `--as`, and \
the tokens and money its conversations have spent on it. `balls` \
answers the whole box's binding table; this answers one wall.",
};
pub const MARKS: Verb = Verb {
word: "marks",
params: &["workspace"],
flags: &[],
summary: "the branch this workspace tracks its tasks on",
detail: "Each agent tracks on a balls branch of its own, in a task space \
of its own, so two agents' task churn never collides. \
`balls/tasks` is the project's shared board, which is where a \
workspace raised to work an existing project is pointed. This is \
the read; the form that amends the branch is a write this seat \
does not compose.",
};
pub const ASSIGN: Verb = Verb {
word: "assign",
params: &[PROJECT, ID, NAME],
flags: &[],
summary: "claim a ready ball for a workspace",
detail: "Claims a ready ball (`bl claim`), which is what BINDS it to a \
workspace: a bound ball is one a workspace holds, and the join is \
on the name stamped here. So `name` is the claiming workspace's \
own name as its engine spells it, never the operator's login. It \
names no workspace field, so nothing routes it — the control that \
fires it names the channel its row came down (DESIGN §4.35).",
};
pub const RELEASE: Verb = Verb {
word: "release",
params: &[PROJECT, ID, NAME],
flags: &[],
summary: "unclaim a ball a workspace holds",
detail: "Lets a ball go (`bl unclaim`): the workspace stops holding it and \
anyone can claim it again. Nothing already committed in its \
worktree is lost, which is what makes it the undoing of `assign` \
rather than an unmaking of its own.",
};
pub const CLOSE: Verb = Verb {
word: "close",
params: &[PROJECT, ID, NAME],
flags: &[],
summary: "close a ball and deliver its work",
detail: "Delivers a ball (`bl close`): folds `main` into its worktree, \
runs the project's pre-commit gate, squashes the work onto the \
target branch and removes the worktree. A failing gate aborts and \
leaves the ball claimed. It is the one of the five with no verb \
that undoes it, which is why the control that fires it is armed \
(DESIGN §4.35).",
};
pub fn balls() -> Value {
BALLS.built(Vec::new(), &[])
}
pub fn board() -> Value {
BOARD.built(Vec::new(), &[])
}
pub fn workspace_balls(workspace: String) -> Value {
WORKSPACE_BALLS.built(vec![workspace], &[])
}
pub fn marks(workspace: String) -> Value {
MARKS.built(vec![workspace], &[])
}
pub fn assign(project: String, id: String, name: String) -> Value {
ASSIGN.built(vec![project, id, name], &[])
}
pub fn release(project: String, id: String, name: String) -> Value {
RELEASE.built(vec![project, id, name], &[])
}
pub fn close(project: String, id: String, name: String) -> Value {
CLOSE.built(vec![project, id, name], &[])
}
#[cfg(test)]
mod tests;