Skip to content

Where people and agents ship software together. The open-source git platform for the whole job: issues, agents, checks and deploys to the edge.

Commit

The plan: horizons, rank and appetite replace the endless backlog (Part of #204)

Every open work item now stands on one horizon (triage, now, next, later or set_aside), and within a horizon its place is its priority: a fractional rank, so moving one item rewrites only that item. New work items start in Triage. Each view is bounded: Now has a soft cap (6, set per workspace with configure_plan), Next shows its top 10, Later is grouped by repository, Set aside only counts. Appetite (small, medium, large), a dollar budget and urgent (first in Now until it closes) are optional. Work service: migration 0056_plan (work_items.horizon, rank, appetite, budget_usd, urgent, planned_at; plan_settings), and plan_work_item, get_plan, next_work_item (the first unclaimed in Now, else the top of Next, skipping blocked, claimed and others' work) and configure_plan; list_work_items takes horizon and limit. Triage on the item plans; moving into or out of Now, ranking Now and urgent need the right to manage labels and milestones. Each move publishes work_item.planned and notes a horizon change in the conversation. API and MCP: POST /workspaces/{workspace}/work/{number}/plan, GET and PATCH /workspaces/{workspace}/plan, GET /workspaces/{workspace}/plan/next; work_item actions plan, next and get_plan, workspace action configure_plan; scopes, webhooks and Actions events. CLI 0.4.2: g1t work plan (show, or move with --now/--next/--later/--set-aside/--triage, --before/--after/--top, --appetite, --budget, --urgent), g1t work next [--claim], g1t work list --horizon, and g1t work dispatch with no number takes what is next. Web: -/work opens on the Plan (drag and drop, and a menu for every move), with tabs Plan, Board, Triage, All items, Milestones and Sessions; the list moves to -/work/all (old filtered links redirect) with Newer/Older paging and a horizon filter; Triage has quick actions; an item's sidebar has a Plan box. The Board's unbounded Backlog becomes Up next (Now not started, then the top of Next) and it reads about 200 open items instead of 1,000. Home's Start here falls back to what is next, and your Now items join Your move. Docs: work/plan (new), board, home, cli, agents, webhooks and the MCP and CLI references; plugin 0.3.2's work-on-item skill takes g1t work next when no item is named.

Checked:
cargo test -p g1t-work --lib (298), -p g1t-api (222), -p g1t-contracts --lib (352), -p g1t-actions, -p g1t (117 unit; cli integration test any_harness_checking_its_updates_says_which_files_it_changed fails the same on main here); cargo check --workspace --tests; cargo check -p g1t-api -p g1t-work --target wasm32-unknown-unknown; apps/web npm run typecheck and npm test (1117); packages/contracts tsc and tests; prettier; docs build. Pages rendered with mock data in headless Chrome at desktop and 375px, dark and light; drag and drop not yet tried in a real browser.
G1t-Session:
ses_01m5bgsckce7gt943v64h219yy
syntaqxcommitted Parentd0e4fcaBrowse files
70 files+317−1654 files not counted0/70 viewed
+1−1
77 "name": "g1t",
88 "source": "./plugins/claude-code",
99 "description": "Work on g1t work items from Claude Code: records your sessions on g1t, loads a work item's work context, claims and hands off work, and connects g1t's MCP server.",
10− "version": "0.3.1",
10+ "version": "0.3.2",
1111 "category": "development"
1212 }
1313 ]
+1−1
13961396
13971397 [[package]]
13981398 name = "g1t"
1399−version = "0.4.1"
1399+version = "0.4.2"
14001400 dependencies = [
14011401 "anstyle-query",
14021402 "base64 0.22.1",
+1−1
1212
1313 const INSTRUCTIONS: &str = "g1t is where your code, its history and the work around it live: repositories, work items, pull requests, workflows, deployments and packages. You bring your own agent; these tools are how it reads and changes what is on g1t, as the person or token it acts for. Repositories are named \"owner/name\" and belong to a workspace. A work item is any tracked work (a feature, a bug, a chore) of a workspace, linked to the repositories it concerns: where it was filed (origin), where the work is meant to land (targets) and where it touched. A workspace numbers its work items and new pull requests in one sequence; pull requests live in their repository.
1414 Tools are resources, each with an `action`: search, repository, work_item, pull_request, session, workflow, observability, package, secret, webhook, access, team, workspace, ai, billing, security, notifications, account, artifact. The `action` field lists each action and the fields it needs. You see only what your token's scopes allow; a refusal names the scope it needs.
15−Find a repository: account whoami lists your workspaces; repository list or search finds one. Find work: work_item list in a workspace (or with repo, the work items linked to it).
15+Find a repository: account whoami lists your workspaces; repository list or search finds one. Find work: work_item next gives the work item to take next in a workspace (the first in the plan's Now nobody is on, else the top of Next), and work_item list the rest (with repo, the work items linked to it; with horizon, one horizon of the plan).
1616 Work on a work item: work_item work (everything about it: what done means, each repository with its pull requests and whether the work landed there, the targets still missing and suggested ones, who is on it, what it waits on), work_item claim (advisory: it tells you who else is on it), then pull_request create in a target repository with the work item's number as `item`: you get a draft with its own fork to clone and push to. Push your commits, then pull_request ready with a summary. Watch `overlaps` and `behind` on pull_request get, and its checks there: `statuses` from the repository's workflows and `required_checks`, which must pass before it merges. If one fails, read why with workflow get_run and job_logs, push a fix, and the checks run again. Merging lands the work item in that repository; it closes once it has landed in every target (or, with none, once anything that closes it lands). A commit pushed straight to a default branch lands it only when its message says `Closes #N` (or Fixes, Resolves), never with a bare `(#N)`; `Part of #N` ties work to it without closing it; and work_item close with commit (and repo) lands one after the fact. When the work must land in another repository too, work_item link it as a target.
1717 Coordinate: session start once per run of your harness (harness_session_id makes it idempotent), session update as a heartbeat, session get between work steps to read pending updates. Reading does not acknowledge: consider relevant changes, record a public decision summary, then session record with acknowledge containing only the exact update IDs considered. Keep your own session ID explicit, especially when sharing a checkout. Separate scopes may proceed concurrently; agree ownership before overlapping edits. session end when done; work_item release or handoff (with a note) when you stop.
1818 Record public summaries only, never private chain-of-thought, credentials or secrets. As you work, pull_request record_session appends user-facing decisions, evidence and tool activity to the pull request's session, so reviewers see why the change is what it is; pull_request read_session reads it back. pull_request record_decision keeps a decision (why the change is made this way, or what fixed a failure) and list_decisions reads them; repository why says why a line of code is the way it is.
+8−0
371371 Op::UpdateWorkItem,
372372 Op::CloseWorkItem,
373373 Op::ReopenWorkItem,
374+ Op::PlanWorkItem,
375+ Op::GetPlan,
376+ Op::NextWorkItem,
377+ Op::ConfigurePlan,
374378 Op::ListWorkItemLinks,
375379 Op::LinkWorkItem,
376380 Op::UnlinkWorkItem,
743747 Op::UpdateWorkItem => "Update a work item",
744748 Op::CloseWorkItem => "Close a work item",
745749 Op::ReopenWorkItem => "Reopen a work item",
750+ Op::PlanWorkItem => "Plan a work item",
751+ Op::GetPlan => "Get a workspace's plan",
752+ Op::NextWorkItem => "Get the work item to take next",
753+ Op::ConfigurePlan => "Configure a workspace's plan",
746754 Op::ListWorkItemLinks => "List a work item's repositories",
747755 Op::LinkWorkItem => "Link a repository to a work item",
748756 Op::UnlinkWorkItem => "Unlink a repository from a work item",
+151−2
175175 UpdateWorkItem,
176176 CloseWorkItem,
177177 ReopenWorkItem,
178+ PlanWorkItem,
179+ GetPlan,
180+ NextWorkItem,
181+ ConfigurePlan,
178182 ListWorkItemLinks,
179183 LinkWorkItem,
180184 UnlinkWorkItem,
680684 }
681685 }
682686
687+/// A horizon of the plan given as `horizon`: none when it was not given,
688+/// or why it is not one.
689+fn horizon_input(input: &Value) -> std::result::Result<Option<Horizon>, &'static str> {
690+ match optional_text(input, "horizon") {
691+ None => Ok(None),
692+ Some(name) => Horizon::parse(&name).map(Some).ok_or("horizon is triage, now, next, later or set_aside."),
693+ }
694+}
695+
683696 fn repo_schema() -> Value {
684697 json!({
685698 "type": "string",
868881 }
869882
870883 impl Op {
871− pub const ALL: [Op; 430] = [
884+ pub const ALL: [Op; 434] = [
872885 Op::Whoami,
873886 Op::GetWorkspace,
874887 Op::CreateWorkspace,
926939 Op::UpdateWorkItem,
927940 Op::CloseWorkItem,
928941 Op::ReopenWorkItem,
942+ Op::PlanWorkItem,
943+ Op::GetPlan,
944+ Op::NextWorkItem,
945+ Op::ConfigurePlan,
929946 Op::ListWorkItemLinks,
930947 Op::LinkWorkItem,
931948 Op::UnlinkWorkItem,
13651382 Op::UpdateWorkItem => "update_work_item",
13661383 Op::CloseWorkItem => "close_work_item",
13671384 Op::ReopenWorkItem => "reopen_work_item",
1385+ Op::PlanWorkItem => "plan_work_item",
1386+ Op::GetPlan => "get_plan",
1387+ Op::NextWorkItem => "next_work_item",
1388+ Op::ConfigurePlan => "configure_plan",
13681389 Op::ListWorkItemLinks => "list_work_item_links",
13691390 Op::LinkWorkItem => "link_work_item",
13701391 Op::UnlinkWorkItem => "unlink_work_item",
16951716 "Create a repository in one of your workspaces, empty or as a copy of a public git repository elsewhere. It gets a project of its own name; description is that project's. With deploy true, its project's g1t.page Deployments are turned on as soon as it is made, as update_deployment_settings with enabled true does: its first push to the default branch deploys production. The repository is made either way: the response has `deployments` (the settings, with production_url) when they are on, or `deploy_error` saying why not (the workspace has no g1t plan, or your role is too low)."
16961717 }
16971718 Op::ListWorkItems => {
1698− "A workspace's work items, newest first. A work item is any tracked work (a feature, a bug, a chore) of the workspace, numbered in its sequence with new pull requests, and linked to the repositories it concerns: its `origin` (where it was filed, if it was filed in one), its `target`s (where the work is meant to land) and those it `touched` (where a pull request or commit for it landed or is under way). Filter by state, by a label's name, by a milestone's number, by assignee, and with repo by a repository it is linked to (role narrows it to one kind of link). Members see every work item; anyone who can read a repository sees the work items filed in it."
1719+ "A workspace's work items, newest first. A work item is any tracked work (a feature, a bug, a chore) of the workspace, numbered in its sequence with new pull requests, and linked to the repositories it concerns: its `origin` (where it was filed, if it was filed in one), its `target`s (where the work is meant to land) and those it `touched` (where a pull request or commit for it landed or is under way). Filter by state, by a label's name, by a milestone's number, by assignee, and with repo by a repository it is linked to (role narrows it to one kind of link). With horizon, only the open work items on that horizon of the plan, in the plan's order: urgent first, then by rank (triage newest first). limit is how many, 1 to 100 (100 if left out). Each work item says where it stands in the plan: `horizon`, `appetite`, `budget_usd`, `urgent` and `planned_at`. Members see every work item; anyone who can read a repository sees the work items filed in it."
16991720 }
17001721 Op::ListRepoWorkItems => {
17011722 "The work items linked to a repository, in any role (origin, target or touched) or in role: the workspace's work list filtered to it. Read only: work items are opened in the workspace (open_work_item, with repo as their origin)."
17151736 Op::ReopenWorkItem => {
17161737 "Reopen a closed work item. Its author may reopen their own work item, as may the person g1t filed one for; anyone else needs the Triage role. The workspace is `workspace`, its slug; with only `repo`, the repository's workspace."
17171738 }
1739+ Op::PlanWorkItem => {
1740+ "Move an open work item in its workspace's plan, or set what the plan says of it. Every open work item is on one horizon: triage (not placed yet; where new ones start), now (what the workspace is on), next (ranked: the top is taken next), later (wanted, not ranked yet) or set_aside (out of every view but search). Only the fields given change. horizon moves it, last there unless a position is given; before or after (another open work item's number) puts it next to that one, on that one's horizon; top puts it first on its horizon. Give at most one of before, after and top; triage takes none, since it is in the order work items came in. appetite (small, medium or large) is how much the work is worth and budget_usd what an agent on it may spend (in dollars, above 0 and up to 100000); null clears either. urgent true puts it first in Now, ahead of its rank, until it closes. Needs the Triage role on the work item; moving it into or out of Now, ranking it within Now, and urgent need the Write role through workspace membership, the right to manage milestones. A closed work item is refused with `409`. Returns the work item. A work_item.planned event, with horizon, from_horizon when it moved, appetite and urgent."
1741+ }
1742+ Op::GetPlan => {
1743+ "A workspace's plan, as you may see it: `now` in full (urgent first, then by rank, at most 100) with `now_cap`, how many Now holds before the plan says it is over; `next` by rank, its top 10 (with all, up to 100) and `next_total`; then counts only: `triage_total`, `later_total` with `later` grouped by the repository each is filed in (`repo` \"owner/name\", none for those filed in the workspace; the largest 50 groups), and `set_aside_total`. With repo, only work items linked to it. Members see every work item; anyone who can read a repository sees those filed in it. list_work_items with horizon lists one horizon, such as Later or Triage, in the plan's order."
1744+ }
1745+ Op::NextWorkItem => {
1746+ "The work item to take next in a workspace, for you: the first in Now nobody is on, else the top of Next, leaving out any blocked by open work, claimed by someone, or assigned to someone other than you. With repo, only work items linked to it. Returns the work item, or null when nothing is ready. This is how an agent picks up work: read it, then claim_work_item it. Reading it claims nothing."
1747+ }
1748+ Op::ConfigurePlan => {
1749+ "Set how many work items a workspace's Now holds before its plan says it is over: now_cap, 1 to 50 (6 until it is set). Past the cap, g1t warns; it never refuses a move. Needs the Write role through workspace membership, the right to manage milestones. Returns the plan's settings: `now_cap`, with no work items or counts."
1750+ }
17181751 Op::ListWorkItemLinks => {
17191752 "The repositories a work item is linked to: its origin first, then its targets, then those it touched, each with its `role`, its `legacy_number` (the issue number it had in its origin before work items) and whether the work `landed` there. `missing` lists the targets it has not landed in yet. The workspace is `workspace`, its slug."
17201753 }
27672800 "enum": ["origin", "target", "touched"],
27682801 "description": "With repo: only work items linked to it this way.",
27692802 },
2803+ "horizon": {
2804+ "type": "string",
2805+ "enum": Horizon::ALL.map(Horizon::as_str),
2806+ "description": "A horizon of the plan: triage (not placed yet), now, next, later or set_aside. Only the open work items on it, in the plan's order instead of the newest first.",
2807+ },
2808+ "limit": { "type": "integer", "minimum": 1, "maximum": 100, "description": "At most this many, 1 to 100 (100 if left out)." },
27702809 }),
27712810 &[],
27722811 ),
28512890 })),
28522891 &["number"],
28532892 ),
2893+ Op::PlanWorkItem => object(
2894+ item_numbered(json!({
2895+ "horizon": {
2896+ "type": "string",
2897+ "enum": Horizon::ALL.map(Horizon::as_str),
2898+ "description": "Where to move it: last there, unless before, after or top says where. Into or out of now needs the Write role.",
2899+ },
2900+ "before": { "type": "integer", "description": "The number of the open work item to put it just before, on that one's horizon." },
2901+ "after": { "type": "integer", "description": "The number of the open work item to put it just after, on that one's horizon." },
2902+ "top": { "type": "boolean", "description": "First on its horizon (or on horizon, when given)." },
2903+ "appetite": {
2904+ "type": ["string", "null"],
2905+ "enum": [Appetite::Small.as_str(), Appetite::Medium.as_str(), Appetite::Large.as_str(), null],
2906+ "description": "How much the work is worth: small (one session), medium (a few, about a week) or large (a phase, broken into smaller work items before it is taken on). null clears it.",
2907+ },
2908+ "budget_usd": {
2909+ "type": ["number", "null"],
2910+ "description": "What an agent working on it may spend, in dollars, above 0 and up to 100000. null clears it.",
2911+ },
2912+ "urgent": { "type": "boolean", "description": "true puts it first in Now, ahead of its rank, until it closes; false takes that away. Needs the Write role." },
2913+ })),
2914+ &["number"],
2915+ ),
2916+ Op::GetPlan => object(
2917+ json!({
2918+ "workspace": workspace_schema(),
2919+ "repo": { "type": "string", "description": "Only work items linked to this repository (\"owner/name\"). Given without workspace, its workspace's." },
2920+ "all": { "type": "boolean", "description": "Every one of Next (up to 100), not only its top 10." },
2921+ }),
2922+ &[],
2923+ ),
2924+ Op::NextWorkItem => object(
2925+ json!({
2926+ "workspace": workspace_schema(),
2927+ "repo": { "type": "string", "description": "Only work items linked to this repository (\"owner/name\"), such as the one your checkout is of. Given without workspace, its workspace's." },
2928+ }),
2929+ &[],
2930+ ),
2931+ Op::ConfigurePlan => object(
2932+ json!({
2933+ "workspace": workspace_schema(),
2934+ "now_cap": { "type": "integer", "minimum": 1, "maximum": MAX_NOW_CAP, "description": "How many work items Now holds before the plan says it is over, 1 to 50." },
2935+ }),
2936+ &["workspace", "now_cap"],
2937+ ),
28542938 Op::CloseWorkItem => object(
28552939 json!({
28562940 "workspace": workspace_schema(),
40464130 | Op::ListRepoWorkItems
40474131 | Op::GetWorkItem
40484132 | Op::ListWorkItemLinks
4133+ | Op::GetPlan
4134+ | Op::NextWorkItem
40494135 | Op::ResolveRef
40504136 | Op::ListWorkItemDecisions
40514137 | Op::ListLabels
42564342 | Op::UpdateWorkItem
42574343 | Op::CloseWorkItem
42584344 | Op::ReopenWorkItem
4345+ | Op::PlanWorkItem
4346+ | Op::GetPlan
4347+ | Op::NextWorkItem
4348+ | Op::ConfigurePlan
42594349 | Op::ListWorkItemLinks
42604350 | Op::LinkWorkItem
42614351 | Op::UnlinkWorkItem
52975387 None => return failed(FailureCode::Invalid, "role is origin, target or touched."),
52985388 },
52995389 };
5390+ let horizon = match horizon_input(input) {
5391+ Ok(horizon) => horizon,
5392+ Err(message) => return failed(FailureCode::Invalid, message),
5393+ };
53005394 // On the workspace's list, a repository may be named by
53015395 // its name alone, as the site's Work list does.
53025396 let filter = given_repo().or_else(|| {
53165410 label: optional_text(input, "label"),
53175411 milestone: integer(input, "milestone"),
53185412 assignee: optional_text(input, "assignee"),
5413+ horizon,
5414+ limit: integer(input, "limit"),
53195415 before: None,
53205416 closed_since: None,
53215417 },
53915487 }
53925488 pass(work, "close_work_item", &CloseWorkItemArgs { item, repo: given_repo(), commit }).await
53935489 }
5490+ Op::PlanWorkItem => {
5491+ let horizon = match horizon_input(input) {
5492+ Ok(horizon) => horizon,
5493+ Err(message) => return failed(FailureCode::Invalid, message),
5494+ };
5495+ let appetite = match input.get("appetite") {
5496+ None => None,
5497+ Some(Value::Null) => Some(None),
5498+ Some(given) => match given.as_str().and_then(Appetite::parse) {
5499+ Some(appetite) => Some(Some(appetite)),
5500+ None => return failed(FailureCode::Invalid, "appetite is small, medium or large, or null to clear it."),
5501+ },
5502+ };
5503+ let budget_usd = match input.get("budget_usd") {
5504+ None => None,
5505+ Some(Value::Null) => Some(None),
5506+ Some(given) => match given.as_f64().or_else(|| given.as_str().and_then(|text| text.trim().parse().ok())) {
5507+ Some(dollars) => Some(Some(dollars)),
5508+ None => return failed(FailureCode::Invalid, "budget_usd is a number of dollars, or null to clear it."),
5509+ },
5510+ };
5511+ pass(
5512+ work,
5513+ "plan_work_item",
5514+ &PlanWorkItemArgs {
5515+ actor: actor(),
5516+ workspace: item_ws(),
5517+ number,
5518+ horizon,
5519+ before: integer(input, "before"),
5520+ after: integer(input, "after"),
5521+ top: yes(input, "top") == Some(true),
5522+ appetite,
5523+ budget_usd,
5524+ urgent: yes(input, "urgent"),
5525+ },
5526+ )
5527+ .await
5528+ }
5529+ Op::GetPlan => {
5530+ let asked =
5531+ GetPlanArgs { workspace: item_ws(), viewer: viewer.clone(), repo: given_repo(), all: yes(input, "all") == Some(true) };
5532+ pass(work, "get_plan", &asked).await
5533+ }
5534+ Op::NextWorkItem => {
5535+ pass(work, "next_work_item", &NextWorkItemArgs { workspace: item_ws(), viewer: viewer.clone(), repo: given_repo() }).await
5536+ }
5537+ Op::ConfigurePlan => {
5538+ let Some(now_cap) = integer(input, "now_cap") else {
5539+ return failed(FailureCode::Invalid, &format!("Give now_cap, a number from 1 to {MAX_NOW_CAP}."));
5540+ };
5541+ pass(work, "configure_plan", &ConfigurePlanArgs { actor: actor(), workspace: item_ws(), now_cap }).await
5542+ }
53945543 Op::LinkWorkItem | Op::UnlinkWorkItem => {
53955544 let Some(linked) = given_repo() else {
53965545 return failed(FailureCode::Invalid, "Give repo, the repository to link, as owner/name.");
+0−0

Binary or large file; its contents are not shown.

+3−0
185185 | Op::UpdateWorkItem
186186 | Op::CloseWorkItem
187187 | Op::ReopenWorkItem
188+ | Op::PlanWorkItem
188189 | Op::LinkWorkItem
189190 | Op::UnlinkWorkItem => through::<work::WorkItem>(op, sent),
191+ Op::GetPlan | Op::ConfigurePlan => through::<work::Plan>(op, sent),
192+ Op::NextWorkItem => through::<Option<work::WorkItem>>(op, sent),
190193 Op::GetWorkItem => through::<work::WorkItemDetail>(op, sent),
191194 Op::ResolveRef => through::<work::RefTarget>(op, sent),
192195 Op::ListWorkItemDecisions => through::<Vec<g1t_contracts::decisions::Decision>>(op, sent),
+20−1
603603 "GET",
604604 "/workspaces/:workspace/work",
605605 Op::ListWorkItems,
606− &[("state", "state"), ("label", "label"), ("milestone", "milestone"), ("assignee", "assignee"), ("repo", "repo"), ("role", "role")],
606+ &[
607+ ("state", "state"),
608+ ("label", "label"),
609+ ("milestone", "milestone"),
610+ ("assignee", "assignee"),
611+ ("repo", "repo"),
612+ ("role", "role"),
613+ ("horizon", "horizon"),
614+ ("limit", "limit"),
615+ ],
607616 ),
608617 route("POST", "/workspaces/:workspace/work", Op::OpenWorkItem, &[]),
609618 route("POST", "/workspaces/:workspace/work/import", Op::ImportWorkItems, &[]),
613622 route("PATCH", "/workspaces/:workspace/work/:number", Op::UpdateWorkItem, &[]),
614623 route("POST", "/workspaces/:workspace/work/:number/close", Op::CloseWorkItem, &[]),
615624 route("POST", "/workspaces/:workspace/work/:number/reopen", Op::ReopenWorkItem, &[]),
625+ route("POST", "/workspaces/:workspace/work/:number/plan", Op::PlanWorkItem, &[]),
626+ // The plan: where each open work item stands, and in what order the
627+ // work is taken.
628+ route("GET", "/workspaces/:workspace/plan", Op::GetPlan, &[("repo", "repo"), ("all", "all")]),
629+ route("PATCH", "/workspaces/:workspace/plan", Op::ConfigurePlan, &[]),
630+ route("GET", "/workspaces/:workspace/plan/next", Op::NextWorkItem, &[("repo", "repo")]),
616631 route("GET", "/workspaces/:workspace/work/:number/links", Op::ListWorkItemLinks, &[]),
617632 route("POST", "/workspaces/:workspace/work/:number/links", Op::LinkWorkItem, &[]),
618633 route("DELETE", "/workspaces/:workspace/work/:number/links", Op::UnlinkWorkItem, &[("repo", "repo")]),
16451660 assert_eq!(op("PATCH", "/workspaces/acme/work/12"), Op::UpdateWorkItem);
16461661 assert_eq!(op("POST", "/workspaces/acme/work/12/close"), Op::CloseWorkItem);
16471662 assert_eq!(op("POST", "/workspaces/acme/work/12/reopen"), Op::ReopenWorkItem);
1663+ assert_eq!(op("POST", "/workspaces/acme/work/12/plan"), Op::PlanWorkItem);
1664+ assert_eq!(op("GET", "/workspaces/acme/plan"), Op::GetPlan);
1665+ assert_eq!(op("PATCH", "/workspaces/acme/plan"), Op::ConfigurePlan);
1666+ assert_eq!(op("GET", "/workspaces/acme/plan/next"), Op::NextWorkItem);
16481667 assert_eq!(op("GET", "/workspaces/acme/work/12/links"), Op::ListWorkItemLinks);
16491668 assert_eq!(op("POST", "/workspaces/acme/work/12/links"), Op::LinkWorkItem);
16501669 let (route, input) = resolve("DELETE", "/workspaces/acme/work/12/links", &[("repo".to_owned(), "acme/api".to_owned())], Value::Null).unwrap();
+8−4
141141 Tool {
142142 name: "work_item",
143143 title: "Work items",
144− description: "Work items: any tracked work of a workspace (a feature, a bug, a chore), numbered in the workspace with its new pull requests, and linked to the repositories it concerns: its origin (where it was filed), its targets (where the work is meant to land) and those it touched. Name one by `workspace` and `number`; `repo` alone names the workspace too (and on `list` filters, on `create` is the origin). Before working on one, `work` gives everything about it (definition of done, each repository with its pull requests and whether the work landed there, what is missing, suggested targets, who is on it, what it waits on); `claim` says you are on it (advisory and expiring, never a lock), `release` or `handoff` when you stop. `link` a repository as a target to say the work must land there too. `update` with blocked_by sets the work items that must land first. `attach` uploads an image (a screenshot) whose markdown goes in a body or a comment.",
144+ description: "Work items: any tracked work of a workspace (a feature, a bug, a chore), numbered in the workspace with its new pull requests, and linked to the repositories it concerns: its origin (where it was filed), its targets (where the work is meant to land) and those it touched. Name one by `workspace` and `number`; `repo` alone names the workspace too (and on `list` filters, on `create` is the origin). To pick up work, `next` gives the work item to take next from the workspace's plan (Now, then Next); `get_plan` reads the plan and `plan` moves one in it. Before working on one, `work` gives everything about it (definition of done, each repository with its pull requests and whether the work landed there, what is missing, suggested targets, who is on it, what it waits on); `claim` says you are on it (advisory and expiring, never a lock), `release` or `handoff` when you stop. `link` a repository as a target to say the work must land there too. `update` with blocked_by sets the work items that must land first. `attach` uploads an image (a screenshot) whose markdown goes in a body or a comment.",
145145 default_action: None,
146146 actions: &[
147− a("list", Op::ListWorkItems, "A workspace's work items, newest first; by state, label, milestone, assignee, or a repository linked to them"),
147+ a("list", Op::ListWorkItems, "A workspace's work items, newest first; by state, label, milestone, assignee, or a repository linked to them; with horizon, one horizon of the plan in its order, at most limit"),
148148 a("get", Op::GetWorkItem, "One work item with its repositories, comments and pull requests"),
149149 a("create", Op::OpenWorkItem, "Open a work item, filed from repo or in the workspace, with targets"),
150150 a("update", Op::UpdateWorkItem, "Change title, body, labels, milestone, assignees or blocked_by"),
151151 a("close", Op::CloseWorkItem, "Close it without a pull request; commit (with repo) names the default-branch commit that did it"),
152152 a("reopen", Op::ReopenWorkItem, "Reopen it"),
153+ a("next", Op::NextWorkItem, "The work item to take next, for you: the first in Now nobody is on, else the top of Next, never one blocked, claimed or assigned to someone else; repo narrows it to one repository. Picking up work? Call this, then claim what it gives"),
154+ a("get_plan", Op::GetPlan, "The workspace's plan: Now in full with its cap, the top 10 of Next (all for every one), and how many are in Triage, Later (by repository) and Set aside; repo narrows it"),
155+ a("plan", Op::PlanWorkItem, "Move it in the plan: horizon (triage, now, next, later, set_aside), at most one of before or after (another's number) or top; set appetite (small, medium, large), budget_usd or urgent (first in Now); null clears appetite or budget_usd. Triage role; Now and urgent need the Write role"),
153156 a("links", Op::ListWorkItemLinks, "The repositories it is linked to, with roles and where it landed"),
154157 a("link", Op::LinkWorkItem, "Link a repository as a target (or touched)"),
155158 a("unlink", Op::UnlinkWorkItem, "Unlink a repository it no longer concerns"),
421424 Tool {
422425 name: "workspace",
423426 title: "Workspaces",
424− description: "Workspaces own repositories (g1t.sh/{workspace}/{repo}) and work items (g1t.sh/{workspace}/-/work): read what happened across its repositories (`activity`: what merged, shipped and deployed, by whom, over a span), create, update or delete one, invite members, manage its labels and milestones (which its work items and pull requests carry), connect integrations, set rulesets that hold across its repositories, read and change its projects (what each is, where it runs, its links), and keep your own pinned projects at the top of its sidebar.",
427+ description: "Workspaces own repositories (g1t.sh/{workspace}/{repo}) and work items (g1t.sh/{workspace}/-/work): read what happened across its repositories (`activity`: what merged, shipped and deployed, by whom, over a span), create, update or delete one, invite members, manage its labels and milestones (which its work items and pull requests carry) and how many work items its plan's Now holds, connect integrations, set rulesets that hold across its repositories, read and change its projects (what each is, where it runs, its links), and keep your own pinned projects at the top of its sidebar.",
425428 default_action: None,
426429 actions: &[
427430 a("get", Op::GetWorkspace, "A workspace's details and settings"),
446449 a("create_milestone", Op::CreateMilestone, "Create a milestone"),
447450 a("update_milestone", Op::UpdateMilestone, "Change a milestone's title, description, due date or state"),
448451 a("delete_milestone", Op::DeleteMilestone, "Delete a milestone"),
452+ a("configure_plan", Op::ConfigurePlan, "Set now_cap, how many work items its plan's Now holds before it says it is over (1 to 50)"),
449453 a("list_integrations", Op::ListIntegrations, "Alert sources and issue trackers"),
450454 a("connect_integration", Op::ConnectIntegration, "Connect one"),
451455 a("update_integration", Op::UpdateIntegration, "Change one: rotate its key or its settings"),
10401044 let work_item = tools.iter().find(|tool| tool["name"] == "work_item").unwrap();
10411045 assert_eq!(
10421046 work_item["inputSchema"]["properties"]["action"]["enum"],
1043− json!(["list", "get", "links", "labels", "decisions", "resolve", "work", "list_claims"])
1047+ json!(["list", "get", "next", "get_plan", "links", "labels", "decisions", "resolve", "work", "list_claims"])
10441048 );
10451049 }
10461050
+1−0
174174 items: [
175175 { label: "Work", slug: "work" },
176176 { label: "Work items", slug: "work/work-items" },
177+ { label: "The plan", slug: "work/plan" },
177178 { label: "The Board", slug: "work/board" },
178179 { label: "Closing work items", slug: "work/closing" },
179180 { label: "Labels", slug: "work/labels" },
+29−0
264264 `g1t work new` without `--title` asks for one and opens your editor for
265265 the body.
266266
267+### The plan
268+
269+```sh
270+g1t work plan # Now and Next, and how many wait in Triage, Later and Set aside
271+g1t work plan --all # every one of Next, not only its top 10
272+g1t work plan 191 --next --before 197 # move #191 to Next, just ahead of #197
273+g1t work plan 203 --now --top # first in Now
274+g1t work plan 186 --later --appetite M # to Later, worth about a week
275+g1t work plan 195 --urgent # a fire: first in Now until it closes
276+g1t work plan 59 --set-aside # let it go; back with --next or --later
277+g1t work list --horizon triage # one horizon, in the plan's order
278+g1t work next # the work item to take next
279+g1t work next --claim # and claim it
280+g1t work dispatch # start a session on what's next
281+```
282+
283+[The plan](/work/plan/) says where each open work item stands: Triage,
284+Now, Next, Later or Set aside, and within a horizon its place is its
285+priority. `g1t work plan` with a number moves that work item: to a
286+horizon (`--now`, `--next`, `--later`, `--set-aside`, `--triage`), where
287+on it (`--before N`, `--after N`, `--top`; with only a horizon it goes
288+last), and what the plan says of it: `--appetite S|M|L|none`,
289+`--budget DOLLARS|none`, and `--urgent` or `--not-urgent`.
290+
291+`g1t work next` prints the work item to take next: the first in Now that
292+nobody is on, else the top of Next, skipping work items that are blocked,
293+claimed, or assigned to someone else. `g1t work dispatch` with neither a
294+number nor `--title` starts a session on that work item.
295+
267296 ### Images in descriptions and comments
268297
269298 `g1t attach` uploads images, such as a screenshot of a preview, and prints the
+7−0
126126 | Code | A failed production build; your open pull request that can't land until you act (it conflicts, a required check fails, someone asked for changes, approvals are missing); your pull request that meets everything its branch asks for, ready for you to merge; a review asked of you by name; an invitation to a repository; a job waiting for a self-hosted runner |
127127 | Notifications | An unread notification in this workspace that is a warning (someone or something is waiting) or a failure. One whose cause is over, such as a workflow that has passed since or a pull request that merged, has [settled](/guides/notifications/#threads-that-settle-themselves) and is not here |
128128 | Chat | A conversation that mentions you, or a direct message you haven't read. Muted conversations are left out |
129+| Work | A work item in [the plan](/work/plan/)'s Now that is assigned to you or that you claimed, in Now's order |
129130
130131 A notification about something already on the list, such as a pull
131132 request whose row is there, is left out.
149150 4. Something that may be stuck: a job without a runner.
150151 5. Unread warnings and failures in your notifications.
151152 6. Mentions and direct messages.
153+7. Your work items in Now.
152154
153155 The list shows the first eight rows; **Show more** opens the rest. The
154156 line under its heading says how many things need you.
169171 request**; you merge or review there. For anything else it names the
170172 action, such as **See the build** or **Respond**.
171173
174+When nothing needs you, Start here shows the work item to take next from
175+[the plan](/work/plan/#what-to-take-next): the first in Now that nobody
176+is on, or the top of Next, with why ("Top of the plan's Next, ready and
177+unclaimed") and **Open work item**.
178+
172179 ## Since you were last here
173180
174181 Home remembers when you were last on it, for each workspace, with your
+1−0
9393 | `repo.deleted`, `repo.restored`, `repo.purged` | It was deleted, restored within its 30 days, or removed for good. |
9494 | `work_item.labeled`, `work_item.unlabeled`, `pull.labeled`, `pull.unlabeled` | A [label](/work/labels/) was put on a work item or a pull request, or taken off: one event for each label. `data.number` and `data.label` (`name` and `color`). |
9595 | `work_item.milestoned`, `work_item.demilestoned`, `pull.milestoned`, `pull.demilestoned` | A work item or a pull request was put in a [milestone](/work/milestones/), or taken out of one. `data.milestone` (`number` and `title`). Moving it from one to another is both. |
96+| `work_item.planned` | A work item moved in the [plan](/work/plan/), or what the plan says of it changed. `data.workspace`, `data.number`, `data.item_id`, `data.horizon` (where it stands now: `triage`, `now`, `next`, `later` or `set_aside`), `data.from_horizon` when it moved from another, `data.appetite` when it has one, and `data.urgent`. |
9697 | `pull.base_changed` | The branch a pull request merges into changed. `data.base` names it. See [pull requests into other branches](/guides/base-branches/). |
9798 | `work_item.opened`, `work_item.updated`, `work_item.assigned`, `work_item.closed`, `work_item.reopened` | A [work item](/work/work-items/) changed. `data.workspace`, `data.number`, `data.item_id`, `data.repo_ids` and `data.author` (`id` and `username`); on close, `data.reason`, `data.resolution` when a landing closed it (the `repo` and the `pull` request or default-branch `commit` that landed it), and `data.session` when it was closed in a session; on assignment, `data.assignees` and the newly assigned `data.added`. |
9899 | `work_item.linked`, `work_item.unlinked` | A repository was linked to a work item in a role, or unlinked. `data.workspace`, `data.number`, `data.item_id`, `data.repo_ids`, `data.repo` (`owner/name`) and `data.role`. |
+66−3
11241124 | `-a, --assignee <ASSIGNEE>` | Only work items assigned to this person (@me for you). |
11251125 | `-A, --author <AUTHOR>` | Only work items opened by this person (@me for you). |
11261126 | `--role <ROLE>` | With --repo: only those linked to it this way. One of `origin`, `target`, `touched`. |
1127+| `-H, --horizon <HORIZON>` | Only open work items on this horizon of the plan, in the plan's order. One of `triage`, `now`, `next`, `later`, `set-aside`. |
11271128 | `-L, --limit <LIMIT>` | Default: `20`. |
11281129
11291130 Calls [`list_work_items`](/reference/api/work-items/list-work-items/).
14081409
14091410 Calls [`list_events`](/reference/api/repositories/list-events/).
14101411
1412+### g1t work plan
1413+
1414+Show the workspace's plan (Now and Next), or move a work item in it.
1415+
1416+```text
1417+g1t work plan [OPTIONS] [NUMBER]
1418+```
1419+
1420+| Argument or flag | |
1421+| --- | --- |
1422+| `[NUMBER]` | The work item to move; leave it out to show the plan. |
1423+| `--now` | Move it to Now: what the workspace is on. |
1424+| `--next` | Move it to Next: ranked, the top taken first. |
1425+| `--later` | Move it to Later: wanted, not ranked against Next yet. |
1426+| `--set-aside` | Set it aside: out of every view but search. |
1427+| `--triage` | Move it back to Triage. |
1428+| `--before <NUMBER>` | Put it just before this work item, on that one's horizon. |
1429+| `--after <NUMBER>` | Put it just after this work item, on that one's horizon. |
1430+| `--top` | Put it first on its horizon. |
1431+| `--appetite <S\|M\|L\|none>` | How much the work is worth: S (one session), M (about a week), L (a phase), or none. |
1432+| `--budget <DOLLARS\|none>` | What an agent working on it may spend, in dollars, or none. |
1433+| `--urgent` | Mark it urgent: first in Now until it closes. |
1434+| `--not-urgent` | It is no longer urgent. |
1435+| `--all` | With no number: every one of Next, not only its top 10. |
1436+
1437+```text
1438+Every open work item stands on one horizon: triage, now, next, later or set-aside. Within a
1439+horizon its place is its priority. With no number, this prints Now and Next and how many wait in
1440+Triage, Later and Set aside. With a number, it moves that work item: to a horizon (last there,
1441+unless --before, --after or --top says where), and sets its appetite, budget or urgent.
1442+Examples:
1443+ g1t work plan
1444+ g1t work plan 191 --next --before 197
1445+ g1t work plan 203 --now --top --appetite L
1446+ g1t work plan 195 --urgent
1447+```
1448+
1449+Calls [`get_plan`](/reference/api/work-items/get-plan/), [`plan_work_item`](/reference/api/work-items/plan-work-item/).
1450+
1451+### g1t work next
1452+
1453+The work item to take next: the first in Now nobody is on, else the top of Next.
1454+
1455+```text
1456+g1t work next [OPTIONS]
1457+```
1458+
1459+| Argument or flag | |
1460+| --- | --- |
1461+| `--claim` | Claim it too. |
1462+
1463+```text
1464+Work items blocked by open work, claimed by someone, or assigned to someone else are skipped.
1465+Examples:
1466+ g1t work next
1467+ g1t work next --claim
1468+```
1469+
1470+Calls [`next_work_item`](/reference/api/work-items/next-work-item/), [`claim_work_item`](/reference/api/work-items/claim-work-item/).
1471+
14111472 ### g1t work dispatch
14121473
14131474 Start work on a work item in a session on your own Claude, or print the Claude Code command for it.
14141475
14151476 ```text
1416−g1t work dispatch [OPTIONS] <NUMBER|--title <TITLE>>
1477+g1t work dispatch [OPTIONS] [NUMBER]
14171478 ```
14181479
14191480 | Argument or flag | |
14291490 ```text
14301491 With the workspace's Anthropic AI provider, a Claude Managed Agents session starts on that
14311492 account and is recorded on g1t; otherwise (or with --handoff) this prints a `claude` command
1432−to run with g1t's plugin, whose session attaches to the work item as it starts.
1493+to run with g1t's plugin, whose session attaches to the work item as it starts. With neither a
1494+number nor --title, it takes the work item `g1t work next` gives.
14331495 Examples:
1496+ g1t work dispatch
14341497 g1t work dispatch 12
14351498 g1t work dispatch 12 --mode plan --instruction "Keep the old flag"
14361499 g1t work dispatch --title "Add a healthcheck" --handoff
14371500 ```
14381501
1439−Calls [`start_agent_session`](/reference/api/sessions/start-agent-session/).
1502+Calls [`start_agent_session`](/reference/api/sessions/start-agent-session/), [`next_work_item`](/reference/api/work-items/next-work-item/).
14401503
14411504 ## g1t why
14421505
+9−3
337337 a chore. A work item belongs to a workspace and links the repositories it
338338 starts in and lands in. Each action takes `workspace` and the item's
339339 `number`; `repo` is optional: the origin of a new work item, a filter, or
340−in place of `workspace`, which is then the repository's. Before working on
341−one, `work` gives everything about it, and `claim` says you are on it; see
340+in place of `workspace`, which is then the repository's. To pick up work,
341+`next` gives the work item to take next from the workspace's
342+[plan](/work/plan/); `get_plan` reads the plan, and `plan` moves a work item
343+in it. Before working on one, `work` gives everything about it, and `claim` says you are on it; see
342344 [claims and dependencies](/work/claims-and-dependencies/). Work items and pull
343345 requests share numbers in a workspace; a pull request's comments, labels
344346 and reactions are on the [`pull_request`](#pull_request) tool. `resolve`
348350
349351 | Action | What it does | Required | Scope |
350352 | ----------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------- | ------------ |
351−| [`list`](/reference/api/work-items/list-work-items/) | Work items, newest first, by `state`, `label`, `milestone` (its number), `assignee`, and `repo` (the items linked to it, in any role). | `workspace` or `repo` | `work:read` |
353+| [`list`](/reference/api/work-items/list-work-items/) | Work items, newest first, by `state`, `label`, `milestone` (its number), `assignee`, and `repo` (the items linked to it, in any role). With `horizon`, only the open ones on that horizon of the [plan](/work/plan/), in its order; `limit` takes fewer than 100. | `workspace` or `repo` | `work:read` |
352354 | [`get`](/reference/api/work-items/get-work-item/) | A work item: description (which may say what done means, under **Definition of done**), labels, comments, its `repos` with their roles and whether each `landed`, its `resolutions`, and every pull request made for it. | `workspace`, `number` | `work:read` |
353355 | [`create`](/reference/api/work-items/open-work-item/) | Open a work item, with `body`, `labels`, `milestone`, `repo` (its origin) and `targets` (the repositories it should land in). A label the workspace lacks is created for someone with the Write role. Say what done means in `body`, under a **Definition of done** heading. | `workspace` or `repo`, `title` | `work:write` |
354356 | [`update`](/reference/api/work-items/update-work-item/) | Change its title, body, labels, milestone, assignees or `blocked_by` (the work items that must land first). Labels, assignees and `blocked_by` each replace the whole set; `milestone` `null` or `0` takes it out of its milestone. A `blocked_by` that names the work item itself, something not a work item of the workspace, or makes a cycle is refused. | `workspace`, `number` | `work:write` |
361363 | [`remove_labels`](/reference/api/work-items/remove-work-item-labels/) | Take `label`, or several `labels`, off it; with neither, all of them. | `workspace`, `number` | `work:write` |
362364 | [`close`](/reference/api/work-items/close-work-item/) | Close it as `completed` or `not_planned`; with `commit` and `repo`, a commit already on that repository's default branch that names it after a closing keyword lands it there, as its push would have. | `workspace`, `number` | `work:write` |
363365 | [`reopen`](/reference/api/work-items/reopen-work-item/) | Reopen a closed work item. Its resolutions are cleared. | `workspace`, `number` | `work:write` |
366+| [`next`](/reference/api/work-items/next-work-item/) | The work item to take next, for you: the first in Now nobody is on, else the top of Next, leaving out any blocked by open work, claimed, or assigned to someone else. `repo` narrows it to the items linked to one repository. `null` when nothing is ready. This is how an agent picks up work: call `next`, then `claim` what it gives. | `workspace` or `repo` | `work:read` |
367+| [`get_plan`](/reference/api/work-items/get-plan/) | The workspace's [plan](/work/plan/): Now in full with `now_cap`, the top 10 of Next (`all` for every one, up to 100) with `next_total`, and counts of Triage, Later (grouped by repository) and Set aside. `repo` narrows it. | `workspace` or `repo` | `work:read` |
368+| [`plan`](/reference/api/work-items/plan-work-item/) | Move it in the plan: `horizon` (`triage`, `now`, `next`, `later` or `set_aside`), and at most one of `before` or `after` (another open work item's number) or `top`. Set `appetite` (`small`, `medium` or `large`), `budget_usd`, or `urgent` (first in Now until it closes); `null` clears `appetite` or `budget_usd`. Triage role; moving into or out of Now, ranking Now and `urgent` need the Write role in the workspace. Sends `work_item.planned`. | `workspace`, `number` | `work:write` |
364369 | [`comment`](/reference/api/work-items/add-work-item-comment/) | Comment on it, in Markdown. | `workspace`, `number`, `body` | `work:write` |
365370 | [`edit_comment`](/reference/api/work-items/edit-work-item-comment/) | Change a comment's text, by its id from `get`. Your own, or anyone's with the Maintain role or higher. Notes of what happened cannot be edited. | `workspace`, `comment_id`, `body` | `work:write` |
366371 | [`delete_comment`](/reference/api/work-items/delete-work-item-comment/) | Delete a comment, by its id. Your own, or anyone's with the Maintain role or higher. | `workspace`, `comment_id` | `work:write` |
748753 | [`create_milestone`](/reference/api/labels-and-milestones/create-milestone/) | Create a milestone with `title`, `description` and `due_on` (`YYYY-MM-DD`). Write role in the workspace. | `workspace`, `title` | `work:write` |
749754 | [`update_milestone`](/reference/api/labels-and-milestones/update-milestone/) | Change its `title`, `description`, `due_on` (`""` clears it) or `state` (`open` or `closed`). Write role in the workspace. | `workspace`, `milestone` | `work:write` |
750755 | [`delete_milestone`](/reference/api/labels-and-milestones/delete-milestone/) | Delete a milestone; what was in it is in none. Write role in the workspace. | `workspace`, `milestone` | `work:write` |
756+| [`configure_plan`](/reference/api/work-items/configure-plan/) | Set `now_cap`, how many work items the [plan](/work/plan/)'s Now holds before it says it is over: 1 to 50, 6 until set. Past it, g1t warns; it never refuses a move. Write role in the workspace. | `workspace`, `now_cap` | `work:write` |
751757 | [`list_projects`](/reference/api/projects/list-projects/) | Its projects you can see, by name: each with its `kind` and `kind_reason`, where it `runs` and its `production_url`, its repository and `root_dir`, and its `links`. | `workspace` | `repo:read` |
752758 | [`get_project`](/reference/api/projects/get-project/) | One project, with what a person set (`setting`) and what detection decides (`detected`). | `workspace`, `project` | `repo:read` |
753759 | [`update_project`](/reference/api/projects/update-project/) | Change its `name`, `description`, `root_dir`, `kind`, `runs`, `production_url`, `homepage`, `docs_url` or `links`; only what you give changes. `auto` leaves `kind` or `runs` to detection, null clears a link (the homepage goes back to the repository's website), and `links` replaces its other links (at most 10). Maintain role or higher. | `workspace`, `project` | `repo:write` |
+11−0
3434 [coordination updates](/work/claims-and-dependencies/#coordination-updates)
3535 say what changed around it.
3636
37+## Find what to take next
38+
39+When nobody has said which work item to take, the
40+[plan](/work/plan/) does: the first one in **Now** that nobody is on, or
41+else the top of **Next**, skipping work items that are blocked, claimed,
42+or assigned to someone else. Ask for it with `g1t work next` (`--claim`
43+claims it too), `work_item` with `"action": "next"` over MCP, or
44+[`next_work_item`](/reference/api/work-items/next-work-item/). Nothing ready
45+answers with none: then ask a person what to do, rather than picking
46+something from Triage or Later.
47+
3748 ## Pick up a work item
3849
3950 A work item's **work context** is everything about it in one call:
Loading the diff…
Loading the diff…
Loading the diff…
Loading the diff…
Loading the diff…
Loading the diff…
Loading the diff…
Loading the diff…
Loading the diff…
Loading the diff…
Loading the diff…
Loading the diff…
Loading the diff…
Loading the diff…
Loading the diff…
Loading the diff…
Loading the diff…
Loading the diff…
Loading the diff…
Loading the diff…
Loading the diff…
Loading the diff…
Loading the diff…
Loading the diff…
Loading the diff…
Loading the diff…
Loading the diff…
Loading the diff…
Loading the diff…
Loading the diff…
Loading the diff…
Loading the diff…
Loading the diff…
Loading the diff…
Loading the diff…
Loading the diff…
Loading the diff…
Loading the diff…
Loading the diff…
Loading the diff…
Loading the diff…
Loading the diff…
Loading the diff…
Loading the diff…
Loading the diff…
Loading the diff…
Loading the diff…
Loading the diff…
Loading the diff…
Loading the diff…
Loading the diff…
Loading the diff…
Loading the diff…
Loading the diff…

Comments

Sign in to comment.