71 files+317−1655 files not counted0/71 viewed
| 7 | 7 | "name": "g1t", | |
| 8 | 8 | "source": "./plugins/claude-code", | |
| 9 | 9 | "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", | |
| 11 | 11 | "category": "development" | |
| 12 | 12 | } | |
| 13 | 13 | ] |
| 1396 | 1396 | ||
| 1397 | 1397 | [[package]] | |
| 1398 | 1398 | name = "g1t" | |
| 1399 | − | version = "0.4.1" | |
| 1399 | + | version = "0.4.2" | |
| 1400 | 1400 | dependencies = [ | |
| 1401 | 1401 | "anstyle-query", | |
| 1402 | 1402 | "base64 0.22.1", |
| 12 | 12 | ||
| 13 | 13 | 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. | |
| 14 | 14 | 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). | |
| 16 | 16 | 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. | |
| 17 | 17 | 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. | |
| 18 | 18 | 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. |
| 371 | 371 | Op::UpdateWorkItem, | |
| 372 | 372 | Op::CloseWorkItem, | |
| 373 | 373 | Op::ReopenWorkItem, | |
| 374 | + | Op::PlanWorkItem, | |
| 375 | + | Op::GetPlan, | |
| 376 | + | Op::NextWorkItem, | |
| 377 | + | Op::ConfigurePlan, | |
| 374 | 378 | Op::ListWorkItemLinks, | |
| 375 | 379 | Op::LinkWorkItem, | |
| 376 | 380 | Op::UnlinkWorkItem, | |
| ⋯ | |||
| 743 | 747 | Op::UpdateWorkItem => "Update a work item", | |
| 744 | 748 | Op::CloseWorkItem => "Close a work item", | |
| 745 | 749 | 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", | |
| 746 | 754 | Op::ListWorkItemLinks => "List a work item's repositories", | |
| 747 | 755 | Op::LinkWorkItem => "Link a repository to a work item", | |
| 748 | 756 | Op::UnlinkWorkItem => "Unlink a repository from a work item", | |
| 175 | 175 | UpdateWorkItem, | |
| 176 | 176 | CloseWorkItem, | |
| 177 | 177 | ReopenWorkItem, | |
| 178 | + | PlanWorkItem, | |
| 179 | + | GetPlan, | |
| 180 | + | NextWorkItem, | |
| 181 | + | ConfigurePlan, | |
| 178 | 182 | ListWorkItemLinks, | |
| 179 | 183 | LinkWorkItem, | |
| 180 | 184 | UnlinkWorkItem, | |
| ⋯ | |||
| 680 | 684 | } | |
| 681 | 685 | } | |
| 682 | 686 | ||
| 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 | + | ||
| 683 | 696 | fn repo_schema() -> Value { | |
| 684 | 697 | json!({ | |
| 685 | 698 | "type": "string", | |
| ⋯ | |||
| 868 | 881 | } | |
| 869 | 882 | ||
| 870 | 883 | impl Op { | |
| 871 | − | pub const ALL: [Op; 430] = [ | |
| 884 | + | pub const ALL: [Op; 434] = [ | |
| 872 | 885 | Op::Whoami, | |
| 873 | 886 | Op::GetWorkspace, | |
| 874 | 887 | Op::CreateWorkspace, | |
| ⋯ | |||
| 926 | 939 | Op::UpdateWorkItem, | |
| 927 | 940 | Op::CloseWorkItem, | |
| 928 | 941 | Op::ReopenWorkItem, | |
| 942 | + | Op::PlanWorkItem, | |
| 943 | + | Op::GetPlan, | |
| 944 | + | Op::NextWorkItem, | |
| 945 | + | Op::ConfigurePlan, | |
| 929 | 946 | Op::ListWorkItemLinks, | |
| 930 | 947 | Op::LinkWorkItem, | |
| 931 | 948 | Op::UnlinkWorkItem, | |
| ⋯ | |||
| 1365 | 1382 | Op::UpdateWorkItem => "update_work_item", | |
| 1366 | 1383 | Op::CloseWorkItem => "close_work_item", | |
| 1367 | 1384 | 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", | |
| 1368 | 1389 | Op::ListWorkItemLinks => "list_work_item_links", | |
| 1369 | 1390 | Op::LinkWorkItem => "link_work_item", | |
| 1370 | 1391 | Op::UnlinkWorkItem => "unlink_work_item", | |
| ⋯ | |||
| 1695 | 1716 | "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)." | |
| 1696 | 1717 | } | |
| 1697 | 1718 | 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." | |
| 1699 | 1720 | } | |
| 1700 | 1721 | Op::ListRepoWorkItems => { | |
| 1701 | 1722 | "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)." | |
| ⋯ | |||
| 1715 | 1736 | Op::ReopenWorkItem => { | |
| 1716 | 1737 | "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." | |
| 1717 | 1738 | } | |
| 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 | + | } | |
| 1718 | 1751 | Op::ListWorkItemLinks => { | |
| 1719 | 1752 | "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." | |
| 1720 | 1753 | } | |
| ⋯ | |||
| 2767 | 2800 | "enum": ["origin", "target", "touched"], | |
| 2768 | 2801 | "description": "With repo: only work items linked to it this way.", | |
| 2769 | 2802 | }, | |
| 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)." }, | |
| 2770 | 2809 | }), | |
| 2771 | 2810 | &[], | |
| 2772 | 2811 | ), | |
| ⋯ | |||
| 2851 | 2890 | })), | |
| 2852 | 2891 | &["number"], | |
| 2853 | 2892 | ), | |
| 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 | + | ), | |
| 2854 | 2938 | Op::CloseWorkItem => object( | |
| 2855 | 2939 | json!({ | |
| 2856 | 2940 | "workspace": workspace_schema(), | |
| ⋯ | |||
| 4046 | 4130 | | Op::ListRepoWorkItems | |
| 4047 | 4131 | | Op::GetWorkItem | |
| 4048 | 4132 | | Op::ListWorkItemLinks | |
| 4133 | + | | Op::GetPlan | |
| 4134 | + | | Op::NextWorkItem | |
| 4049 | 4135 | | Op::ResolveRef | |
| 4050 | 4136 | | Op::ListWorkItemDecisions | |
| 4051 | 4137 | | Op::ListLabels | |
| ⋯ | |||
| 4256 | 4342 | | Op::UpdateWorkItem | |
| 4257 | 4343 | | Op::CloseWorkItem | |
| 4258 | 4344 | | Op::ReopenWorkItem | |
| 4345 | + | | Op::PlanWorkItem | |
| 4346 | + | | Op::GetPlan | |
| 4347 | + | | Op::NextWorkItem | |
| 4348 | + | | Op::ConfigurePlan | |
| 4259 | 4349 | | Op::ListWorkItemLinks | |
| 4260 | 4350 | | Op::LinkWorkItem | |
| 4261 | 4351 | | Op::UnlinkWorkItem | |
| ⋯ | |||
| 5297 | 5387 | None => return failed(FailureCode::Invalid, "role is origin, target or touched."), | |
| 5298 | 5388 | }, | |
| 5299 | 5389 | }; | |
| 5390 | + | let horizon = match horizon_input(input) { | |
| 5391 | + | Ok(horizon) => horizon, | |
| 5392 | + | Err(message) => return failed(FailureCode::Invalid, message), | |
| 5393 | + | }; | |
| 5300 | 5394 | // On the workspace's list, a repository may be named by | |
| 5301 | 5395 | // its name alone, as the site's Work list does. | |
| 5302 | 5396 | let filter = given_repo().or_else(|| { | |
| ⋯ | |||
| 5316 | 5410 | label: optional_text(input, "label"), | |
| 5317 | 5411 | milestone: integer(input, "milestone"), | |
| 5318 | 5412 | assignee: optional_text(input, "assignee"), | |
| 5413 | + | horizon, | |
| 5414 | + | limit: integer(input, "limit"), | |
| 5319 | 5415 | before: None, | |
| 5320 | 5416 | closed_since: None, | |
| 5321 | 5417 | }, | |
| ⋯ | |||
| 5391 | 5487 | } | |
| 5392 | 5488 | pass(work, "close_work_item", &CloseWorkItemArgs { item, repo: given_repo(), commit }).await | |
| 5393 | 5489 | } | |
| 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 | + | } | |
| 5394 | 5543 | Op::LinkWorkItem | Op::UnlinkWorkItem => { | |
| 5395 | 5544 | let Some(linked) = given_repo() else { | |
| 5396 | 5545 | return failed(FailureCode::Invalid, "Give repo, the repository to link, as owner/name."); | |
Binary or large file; its contents are not shown.
| 185 | 185 | | Op::UpdateWorkItem | |
| 186 | 186 | | Op::CloseWorkItem | |
| 187 | 187 | | Op::ReopenWorkItem | |
| 188 | + | | Op::PlanWorkItem | |
| 188 | 189 | | Op::LinkWorkItem | |
| 189 | 190 | | 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), | |
| 190 | 193 | Op::GetWorkItem => through::<work::WorkItemDetail>(op, sent), | |
| 191 | 194 | Op::ResolveRef => through::<work::RefTarget>(op, sent), | |
| 192 | 195 | Op::ListWorkItemDecisions => through::<Vec<g1t_contracts::decisions::Decision>>(op, sent), |
| 603 | 603 | "GET", | |
| 604 | 604 | "/workspaces/:workspace/work", | |
| 605 | 605 | 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 | + | ], | |
| 607 | 616 | ), | |
| 608 | 617 | route("POST", "/workspaces/:workspace/work", Op::OpenWorkItem, &[]), | |
| 609 | 618 | route("POST", "/workspaces/:workspace/work/import", Op::ImportWorkItems, &[]), | |
| ⋯ | |||
| 613 | 622 | route("PATCH", "/workspaces/:workspace/work/:number", Op::UpdateWorkItem, &[]), | |
| 614 | 623 | route("POST", "/workspaces/:workspace/work/:number/close", Op::CloseWorkItem, &[]), | |
| 615 | 624 | 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")]), | |
| 616 | 631 | route("GET", "/workspaces/:workspace/work/:number/links", Op::ListWorkItemLinks, &[]), | |
| 617 | 632 | route("POST", "/workspaces/:workspace/work/:number/links", Op::LinkWorkItem, &[]), | |
| 618 | 633 | route("DELETE", "/workspaces/:workspace/work/:number/links", Op::UnlinkWorkItem, &[("repo", "repo")]), | |
| ⋯ | |||
| 1645 | 1660 | assert_eq!(op("PATCH", "/workspaces/acme/work/12"), Op::UpdateWorkItem); | |
| 1646 | 1661 | assert_eq!(op("POST", "/workspaces/acme/work/12/close"), Op::CloseWorkItem); | |
| 1647 | 1662 | 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); | |
| 1648 | 1667 | assert_eq!(op("GET", "/workspaces/acme/work/12/links"), Op::ListWorkItemLinks); | |
| 1649 | 1668 | assert_eq!(op("POST", "/workspaces/acme/work/12/links"), Op::LinkWorkItem); | |
| 1650 | 1669 | let (route, input) = resolve("DELETE", "/workspaces/acme/work/12/links", &[("repo".to_owned(), "acme/api".to_owned())], Value::Null).unwrap(); | |
| 141 | 141 | Tool { | |
| 142 | 142 | name: "work_item", | |
| 143 | 143 | 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.", | |
| 145 | 145 | default_action: None, | |
| 146 | 146 | 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"), | |
| 148 | 148 | a("get", Op::GetWorkItem, "One work item with its repositories, comments and pull requests"), | |
| 149 | 149 | a("create", Op::OpenWorkItem, "Open a work item, filed from repo or in the workspace, with targets"), | |
| 150 | 150 | a("update", Op::UpdateWorkItem, "Change title, body, labels, milestone, assignees or blocked_by"), | |
| 151 | 151 | a("close", Op::CloseWorkItem, "Close it without a pull request; commit (with repo) names the default-branch commit that did it"), | |
| 152 | 152 | 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"), | |
| 153 | 156 | a("links", Op::ListWorkItemLinks, "The repositories it is linked to, with roles and where it landed"), | |
| 154 | 157 | a("link", Op::LinkWorkItem, "Link a repository as a target (or touched)"), | |
| 155 | 158 | a("unlink", Op::UnlinkWorkItem, "Unlink a repository it no longer concerns"), | |
| ⋯ | |||
| 421 | 424 | Tool { | |
| 422 | 425 | name: "workspace", | |
| 423 | 426 | 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.", | |
| 425 | 428 | default_action: None, | |
| 426 | 429 | actions: &[ | |
| 427 | 430 | a("get", Op::GetWorkspace, "A workspace's details and settings"), | |
| ⋯ | |||
| 446 | 449 | a("create_milestone", Op::CreateMilestone, "Create a milestone"), | |
| 447 | 450 | a("update_milestone", Op::UpdateMilestone, "Change a milestone's title, description, due date or state"), | |
| 448 | 451 | 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)"), | |
| 449 | 453 | a("list_integrations", Op::ListIntegrations, "Alert sources and issue trackers"), | |
| 450 | 454 | a("connect_integration", Op::ConnectIntegration, "Connect one"), | |
| 451 | 455 | a("update_integration", Op::UpdateIntegration, "Change one: rotate its key or its settings"), | |
| ⋯ | |||
| 1040 | 1044 | let work_item = tools.iter().find(|tool| tool["name"] == "work_item").unwrap(); | |
| 1041 | 1045 | assert_eq!( | |
| 1042 | 1046 | 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"]) | |
| 1044 | 1048 | ); | |
| 1045 | 1049 | } | |
| 1046 | 1050 | ||
| 174 | 174 | items: [ | |
| 175 | 175 | { label: "Work", slug: "work" }, | |
| 176 | 176 | { label: "Work items", slug: "work/work-items" }, | |
| 177 | + | { label: "The plan", slug: "work/plan" }, | |
| 177 | 178 | { label: "The Board", slug: "work/board" }, | |
| 178 | 179 | { label: "Closing work items", slug: "work/closing" }, | |
| 179 | 180 | { label: "Labels", slug: "work/labels" }, |
| 264 | 264 | `g1t work new` without `--title` asks for one and opens your editor for | |
| 265 | 265 | the body. | |
| 266 | 266 | ||
| 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 | + | ||
| 267 | 296 | ### Images in descriptions and comments | |
| 268 | 297 | ||
| 269 | 298 | `g1t attach` uploads images, such as a screenshot of a preview, and prints the |
| 126 | 126 | | 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 | | |
| 127 | 127 | | 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 | | |
| 128 | 128 | | 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 | | |
| 129 | 130 | ||
| 130 | 131 | A notification about something already on the list, such as a pull | |
| 131 | 132 | request whose row is there, is left out. | |
| ⋯ | |||
| 149 | 150 | 4. Something that may be stuck: a job without a runner. | |
| 150 | 151 | 5. Unread warnings and failures in your notifications. | |
| 151 | 152 | 6. Mentions and direct messages. | |
| 153 | + | 7. Your work items in Now. | |
| 152 | 154 | ||
| 153 | 155 | The list shows the first eight rows; **Show more** opens the rest. The | |
| 154 | 156 | line under its heading says how many things need you. | |
| ⋯ | |||
| 169 | 171 | request**; you merge or review there. For anything else it names the | |
| 170 | 172 | action, such as **See the build** or **Respond**. | |
| 171 | 173 | ||
| 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 | + | ||
| 172 | 179 | ## Since you were last here | |
| 173 | 180 | ||
| 174 | 181 | Home remembers when you were last on it, for each workspace, with your | |
| 93 | 93 | | `repo.deleted`, `repo.restored`, `repo.purged` | It was deleted, restored within its 30 days, or removed for good. | | |
| 94 | 94 | | `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`). | | |
| 95 | 95 | | `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`. | | |
| 96 | 97 | | `pull.base_changed` | The branch a pull request merges into changed. `data.base` names it. See [pull requests into other branches](/guides/base-branches/). | | |
| 97 | 98 | | `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`. | | |
| 98 | 99 | | `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`. | |
| 1124 | 1124 | | `-a, --assignee <ASSIGNEE>` | Only work items assigned to this person (@me for you). | | |
| 1125 | 1125 | | `-A, --author <AUTHOR>` | Only work items opened by this person (@me for you). | | |
| 1126 | 1126 | | `--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`. | | |
| 1127 | 1128 | | `-L, --limit <LIMIT>` | Default: `20`. | | |
| 1128 | 1129 | ||
| 1129 | 1130 | Calls [`list_work_items`](/reference/api/work-items/list-work-items/). | |
| ⋯ | |||
| 1408 | 1409 | ||
| 1409 | 1410 | Calls [`list_events`](/reference/api/repositories/list-events/). | |
| 1410 | 1411 | ||
| 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 | + | ||
| 1411 | 1472 | ### g1t work dispatch | |
| 1412 | 1473 | ||
| 1413 | 1474 | Start work on a work item in a session on your own Claude, or print the Claude Code command for it. | |
| 1414 | 1475 | ||
| 1415 | 1476 | ```text | |
| 1416 | − | g1t work dispatch [OPTIONS] <NUMBER|--title <TITLE>> | |
| 1477 | + | g1t work dispatch [OPTIONS] [NUMBER] | |
| 1417 | 1478 | ``` | |
| 1418 | 1479 | ||
| 1419 | 1480 | | Argument or flag | | | |
| ⋯ | |||
| 1429 | 1490 | ```text | |
| 1430 | 1491 | With the workspace's Anthropic AI provider, a Claude Managed Agents session starts on that | |
| 1431 | 1492 | 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. | |
| 1433 | 1495 | Examples: | |
| 1496 | + | g1t work dispatch | |
| 1434 | 1497 | g1t work dispatch 12 | |
| 1435 | 1498 | g1t work dispatch 12 --mode plan --instruction "Keep the old flag" | |
| 1436 | 1499 | g1t work dispatch --title "Add a healthcheck" --handoff | |
| 1437 | 1500 | ``` | |
| 1438 | 1501 | ||
| 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/). | |
| 1440 | 1503 | ||
| 1441 | 1504 | ## g1t why | |
| 1442 | 1505 | ||
| 337 | 337 | a chore. A work item belongs to a workspace and links the repositories it | |
| 338 | 338 | starts in and lands in. Each action takes `workspace` and the item's | |
| 339 | 339 | `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 | |
| 342 | 344 | [claims and dependencies](/work/claims-and-dependencies/). Work items and pull | |
| 343 | 345 | requests share numbers in a workspace; a pull request's comments, labels | |
| 344 | 346 | and reactions are on the [`pull_request`](#pull_request) tool. `resolve` | |
| ⋯ | |||
| 348 | 350 | ||
| 349 | 351 | | Action | What it does | Required | Scope | | |
| 350 | 352 | | ----------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------- | ------------ | | |
| 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` | | |
| 352 | 354 | | [`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` | | |
| 353 | 355 | | [`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` | | |
| 354 | 356 | | [`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` | | |
| ⋯ | |||
| 361 | 363 | | [`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` | | |
| 362 | 364 | | [`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` | | |
| 363 | 365 | | [`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` | | |
| 364 | 369 | | [`comment`](/reference/api/work-items/add-work-item-comment/) | Comment on it, in Markdown. | `workspace`, `number`, `body` | `work:write` | | |
| 365 | 370 | | [`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` | | |
| 366 | 371 | | [`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` | | |
| ⋯ | |||
| 748 | 753 | | [`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` | | |
| 749 | 754 | | [`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` | | |
| 750 | 755 | | [`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` | | |
| 751 | 757 | | [`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` | | |
| 752 | 758 | | [`get_project`](/reference/api/projects/get-project/) | One project, with what a person set (`setting`) and what detection decides (`detected`). | `workspace`, `project` | `repo:read` | | |
| 753 | 759 | | [`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` | | |
| 34 | 34 | [coordination updates](/work/claims-and-dependencies/#coordination-updates) | |
| 35 | 35 | say what changed around it. | |
| 36 | 36 | ||
| 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 | + | ||
| 37 | 48 | ## Pick up a work item | |
| 38 | 49 | ||
| 39 | 50 | 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…
Loading the diff…
Comments
Sign in to comment.