g1t work: the workspace's work items in the CLI
g1t issue is gone: g1t work list, view, new, comment, edit, close, reopen, link and unlink work on the current repository's workspace or --workspace, and print {site}/{workspace}/-/work/{n}. work view is the whole work context (was work context), work status the claims and sessions here (was work list), and --item replaces --issue on pr create, session start, touch, list and attach and work events. The CLI is 0.4.0, as the Claude Code plugin's hooks ask.
- G1T-Session:
- ses_01m566353xebrscb7pf471bnn1
24 files+2016−16620/24 viewed
| 1396 | 1396 | ||
| 1397 | 1397 | [[package]] | |
| 1398 | 1398 | name = "g1t" | |
| 1399 | − | version = "0.3.7" | |
| 1399 | + | version = "0.4.0" | |
| 1400 | 1400 | dependencies = [ | |
| 1401 | 1401 | "anstyle-query", | |
| 1402 | 1402 | "base64 0.22.1", |
| 243 | 243 | ||
| 244 | 244 | Calls [`detach_fork`](/reference/api/repositories/detach-fork/). | |
| 245 | 245 | ||
| 246 | − | ## g1t issue | |
| 247 | − | ||
| 248 | − | Issues: list, view, create, comment, close, reopen, edit. | |
| 249 | − | ||
| 250 | − | ### g1t issue list | |
| 251 | − | ||
| 252 | − | List issues. | |
| 253 | − | ||
| 254 | − | ```text | |
| 255 | − | g1t issue list [OPTIONS] | |
| 256 | − | ``` | |
| 257 | − | ||
| 258 | − | | Argument or flag | | | |
| 259 | − | | --- | --- | | |
| 260 | − | | `-s, --state <STATE>` | One of `open`, `closed`, `all`. Default: `open`. | | |
| 261 | − | | `-l, --label <LABEL>` | Only issues with this label. | | |
| 262 | − | | `-m, --milestone <MILESTONE>` | Only issues in the milestone of this number. | | |
| 263 | − | | `-a, --assignee <ASSIGNEE>` | Only issues assigned to this person (@me for you). | | |
| 264 | − | | `-A, --author <AUTHOR>` | Only issues opened by this person (@me for you). | | |
| 265 | − | | `-L, --limit <LIMIT>` | Default: `20`. | | |
| 266 | − | ||
| 267 | − | Calls [`list_issues`](/reference/api/issues/list-issues/). | |
| 268 | − | ||
| 269 | − | ### g1t issue view | |
| 270 | − | ||
| 271 | − | Show an issue, with its comments. | |
| 272 | − | ||
| 273 | − | ```text | |
| 274 | − | g1t issue view [OPTIONS] <NUMBER> | |
| 275 | − | ``` | |
| 276 | − | ||
| 277 | − | | Argument or flag | | | |
| 278 | − | | --- | --- | | |
| 279 | − | | `<NUMBER>` | The issue's number. | | |
| 280 | − | | `-c, --comments` | Show its comments too. | | |
| 281 | − | | `-w, --web` | Open it in the browser. | | |
| 282 | − | ||
| 283 | − | Calls [`get_issue`](/reference/api/issues/get-issue/). | |
| 284 | − | ||
| 285 | − | ### g1t issue create | |
| 286 | − | ||
| 287 | − | Open an issue. | |
| 288 | − | ||
| 289 | − | ```text | |
| 290 | − | g1t issue create [OPTIONS] | |
| 291 | − | ``` | |
| 292 | − | ||
| 293 | − | | Argument or flag | | | |
| 294 | − | | --- | --- | | |
| 295 | − | | `-t, --title <TITLE>` | | | |
| 296 | − | | `-b, --body <BODY>` | The text. Markdown. | | |
| 297 | − | | `-F, --body-file <FILE>` | Read the text from a file, or - for stdin. | | |
| 298 | − | | `--attach <FILE>` | An image to show after the text (PNG, JPEG, GIF or WebP, at most 10 MB): uploaded, and its Markdown added. Repeat for more. | | |
| 299 | − | | `-l, --label <LABEL>` | A label; repeat for more. | | |
| 300 | − | | `-a, --assignee <ASSIGNEE>` | Someone to assign; repeat for more (@me for you). | | |
| 301 | − | | `-m, --milestone <MILESTONE>` | A milestone's number. | | |
| 302 | − | | `-w, --web` | Open the new-issue page in the browser instead. | | |
| 303 | − | ||
| 304 | − | Calls [`create_issue`](/reference/api/issues/create-issue/), [`update_issue`](/reference/api/issues/update-issue/), [`upload_attachment`](/reference/api/issues/upload-attachment/). | |
| 305 | − | ||
| 306 | − | ### g1t issue comment | |
| 307 | − | ||
| 308 | − | Comment on an issue. | |
| 309 | − | ||
| 310 | − | ```text | |
| 311 | − | g1t issue comment [OPTIONS] [NUMBER] | |
| 312 | − | ``` | |
| 313 | − | ||
| 314 | − | | Argument or flag | | | |
| 315 | − | | --- | --- | | |
| 316 | − | | `[NUMBER]` | The number; for a pull request, the current branch's when left out. | | |
| 317 | − | | `-b, --body <BODY>` | The text. Markdown. | | |
| 318 | − | | `-F, --body-file <FILE>` | Read the text from a file, or - for stdin. | | |
| 319 | − | | `--attach <FILE>` | An image to show after the text (PNG, JPEG, GIF or WebP, at most 10 MB): uploaded, and its Markdown added. Repeat for more. | | |
| 320 | − | ||
| 321 | − | Calls [`add_comment`](/reference/api/issues/add-comment/), [`upload_attachment`](/reference/api/issues/upload-attachment/). | |
| 322 | − | ||
| 323 | − | ### g1t issue close | |
| 324 | − | ||
| 325 | − | Close an issue. | |
| 326 | − | ||
| 327 | − | ```text | |
| 328 | − | g1t issue close [OPTIONS] <NUMBER> | |
| 329 | − | ``` | |
| 330 | − | ||
| 331 | − | | Argument or flag | | | |
| 332 | − | | --- | --- | | |
| 333 | − | | `<NUMBER>` | | | |
| 334 | − | | `-r, --reason <REASON>` | One of `completed`, `not_planned`. | | |
| 335 | − | | `-c, --comment <COMMENT>` | Leave a comment as it closes. | | |
| 336 | − | | `--commit <COMMIT>` | The commit on the default branch that closed it: its message names the issue after a closing keyword (Fixes #12). Its full hash. | | |
| 337 | − | ||
| 338 | − | Calls [`close_issue`](/reference/api/issues/close-issue/), [`add_comment`](/reference/api/issues/add-comment/). | |
| 339 | − | ||
| 340 | − | ### g1t issue reopen | |
| 341 | − | ||
| 342 | − | Reopen an issue. | |
| 343 | − | ||
| 344 | − | ```text | |
| 345 | − | g1t issue reopen [OPTIONS] <NUMBER> | |
| 346 | − | ``` | |
| 347 | − | ||
| 348 | − | | Argument or flag | | | |
| 349 | − | | --- | --- | | |
| 350 | − | | `<NUMBER>` | | | |
| 351 | − | | `-c, --comment <COMMENT>` | Leave a comment as it reopens. | | |
| 352 | − | ||
| 353 | − | Calls [`reopen_issue`](/reference/api/issues/reopen-issue/), [`add_comment`](/reference/api/issues/add-comment/). | |
| 354 | − | ||
| 355 | − | ### g1t issue edit | |
| 356 | − | ||
| 357 | − | Change an issue's title, body, labels, assignees or milestone. | |
| 358 | − | ||
| 359 | − | ```text | |
| 360 | − | g1t issue edit [OPTIONS] <NUMBER> | |
| 361 | − | ``` | |
| 362 | − | ||
| 363 | − | | Argument or flag | | | |
| 364 | − | | --- | --- | | |
| 365 | − | | `<NUMBER>` | | | |
| 366 | − | | `-t, --title <TITLE>` | | | |
| 367 | − | | `-b, --body <BODY>` | The text. Markdown. | | |
| 368 | − | | `-F, --body-file <FILE>` | Read the text from a file, or - for stdin. | | |
| 369 | − | | `--add-label <LABEL>` | | | |
| 370 | − | | `--remove-label <LABEL>` | | | |
| 371 | − | | `--add-assignee <LOGIN>` | | | |
| 372 | − | | `--remove-assignee <LOGIN>` | | | |
| 373 | − | | `-m, --milestone <MILESTONE>` | A milestone's number. | | |
| 374 | − | | `--remove-milestone` | Take it out of its milestone. | | |
| 375 | − | ||
| 376 | − | Calls [`update_issue`](/reference/api/issues/update-issue/), [`get_issue`](/reference/api/issues/get-issue/). | |
| 377 | − | ||
| 378 | 246 | ## g1t pr | |
| 379 | 247 | ||
| 380 | 248 | Pull requests: list, view, create, check out, diff, checks, review, merge. | |
| ⋯ | |||
| 416 | 284 | ||
| 417 | 285 | ### g1t pr create | |
| 418 | 286 | ||
| 419 | − | Open a pull request from a branch, or start one for an issue. | |
| 287 | + | Open a pull request from a branch, or start one for a work item. | |
| 420 | 288 | ||
| 421 | 289 | ```text | |
| 422 | 290 | g1t pr create [OPTIONS] | |
| ⋯ | |||
| 430 | 298 | | `--attach <FILE>` | An image to show after the text (PNG, JPEG, GIF or WebP, at most 10 MB): uploaded, and its Markdown added. Repeat for more. | | |
| 431 | 299 | | `-B, --base <BASE>` | The branch to merge into; the default branch when left out. | | |
| 432 | 300 | | `-H, --head <HEAD>` | The branch with the changes; the current one when left out. | | |
| 433 | − | | `-i, --issue <ISSUE>` | The issue it is for. Without a branch, starts a draft in a working copy of its own. | | |
| 301 | + | | `-i, --item <ITEM>` | The work item it is for, by its number in the workspace. Without a branch, starts a draft in a working copy of its own. | | |
| 434 | 302 | | `-f, --fill` | Take the title and body from the branch's commits. | | |
| 435 | 303 | | `-d, --draft` | Open it as a draft. | | |
| 436 | 304 | | `--no-push` | Do not push the branch first. | | |
| 437 | 305 | | `--head-repo <OWNER/NAME>` | The fork, OWNER/NAME, that holds the branch. In a clone of your fork (origin) whose upstream is the repository, origin when left out. | | |
| 438 | 306 | ||
| 439 | − | Calls [`create_pull_request`](/reference/api/pull-requests/create-pull-request/), [`get_repo`](/reference/api/repositories/get-repo/), [`convert_pull_request_to_draft`](/reference/api/pull-requests/convert-pull-request-to-draft/), [`upload_attachment`](/reference/api/issues/upload-attachment/). | |
| 307 | + | Calls [`create_pull_request`](/reference/api/pull-requests/create-pull-request/), [`get_repo`](/reference/api/repositories/get-repo/), [`convert_pull_request_to_draft`](/reference/api/pull-requests/convert-pull-request-to-draft/), [`upload_attachment`](/reference/api/work-items/upload-attachment/). | |
| 440 | 308 | ||
| 441 | 309 | ### g1t pr checkout | |
| 442 | 310 | ||
| ⋯ | |||
| 504 | 372 | | `-b, --body <BODY>` | The text. Markdown. | | |
| 505 | 373 | | `-F, --body-file <FILE>` | Read the text from a file, or - for stdin. | | |
| 506 | 374 | ||
| 507 | − | Calls [`review_pull_request`](/reference/api/pull-requests/review-pull-request/), [`add_comment`](/reference/api/issues/add-comment/). | |
| 375 | + | Calls [`review_pull_request`](/reference/api/pull-requests/review-pull-request/), [`add_comment`](/reference/api/pull-requests/add-comment/). | |
| 508 | 376 | ||
| 509 | 377 | ### g1t pr merge | |
| 510 | 378 | ||
| ⋯ | |||
| 526 | 394 | | `-F, --body-file <FILE>` | Read the text from a file, or - for stdin. | | |
| 527 | 395 | | `--auto` | Merge on its own once its checks, reviews and rules allow. | | |
| 528 | 396 | | `--disable-auto` | Turn its auto-merge off. | | |
| 529 | − | | `--keep-issue-open` | Leave the issue it is for open. | | |
| 397 | + | | `--keep-item-open` | Do not land the work item it is for: it is only part of the work. | | |
| 530 | 398 | | `--admin` | Merge past failing required checks and rules (needs the Admin role). | | |
| 531 | 399 | | `-d, --delete-branch` | Delete its branch once merged, and the local branch. The repository's setting when left out. | | |
| 532 | 400 | | `--keep-branch` | Keep its branch, whatever the repository's setting. | | |
| ⋯ | |||
| 564 | 432 | | `--attach <FILE>` | An image to show after the summary (PNG, JPEG, GIF or WebP, at most 10 MB): uploaded, and its Markdown added. Repeat for more. | | |
| 565 | 433 | | `--undo` | Turn it back into a draft. | | |
| 566 | 434 | ||
| 567 | − | Calls [`mark_pull_request_ready`](/reference/api/pull-requests/mark-pull-request-ready/), [`convert_pull_request_to_draft`](/reference/api/pull-requests/convert-pull-request-to-draft/), [`upload_attachment`](/reference/api/issues/upload-attachment/). | |
| 435 | + | Calls [`mark_pull_request_ready`](/reference/api/pull-requests/mark-pull-request-ready/), [`convert_pull_request_to_draft`](/reference/api/pull-requests/convert-pull-request-to-draft/), [`upload_attachment`](/reference/api/work-items/upload-attachment/). | |
| 568 | 436 | ||
| 569 | 437 | ### g1t pr comment | |
| 570 | 438 | ||
| ⋯ | |||
| 576 | 444 | ||
| 577 | 445 | | Argument or flag | | | |
| 578 | 446 | | --- | --- | | |
| 579 | − | | `[NUMBER]` | The number; for a pull request, the current branch's when left out. | | |
| 447 | + | | `[NUMBER]` | The pull request's number; the current branch's when left out. | | |
| 580 | 448 | | `-b, --body <BODY>` | The text. Markdown. | | |
| 581 | 449 | | `-F, --body-file <FILE>` | Read the text from a file, or - for stdin. | | |
| 582 | 450 | | `--attach <FILE>` | An image to show after the text (PNG, JPEG, GIF or WebP, at most 10 MB): uploaded, and its Markdown added. Repeat for more. | | |
| 583 | 451 | ||
| 584 | − | Calls [`add_comment`](/reference/api/issues/add-comment/), [`upload_attachment`](/reference/api/issues/upload-attachment/). | |
| 452 | + | Calls [`add_comment`](/reference/api/pull-requests/add-comment/), [`upload_attachment`](/reference/api/work-items/upload-attachment/). | |
| 585 | 453 | ||
| 586 | 454 | ### g1t pr close | |
| 587 | 455 | ||
| ⋯ | |||
| 1021 | 889 | ||
| 1022 | 890 | ## g1t status | |
| 1023 | 891 | ||
| 1024 | − | What needs you: your pull requests, reviews asked of you, your issues, failing checks, and your sessions and claims here. | |
| 892 | + | What needs you: your pull requests, reviews asked of you, failing checks, and your sessions and claims here. | |
| 1025 | 893 | ||
| 1026 | 894 | ```text | |
| 1027 | 895 | g1t status [OPTIONS] | |
| 1028 | 896 | ``` | |
| 1029 | 897 | ||
| 1030 | − | Calls [`search`](/reference/api/search/search/), [`list_notifications`](/reference/api/notifications/list-notifications/), [`get_pull_request`](/reference/api/pull-requests/get-pull-request/), [`list_sessions`](/reference/api/sessions/list-sessions/), [`list_claims`](/reference/api/claims-and-work/list-claims/). | |
| 898 | + | Calls [`search`](/reference/api/search/search/), [`list_notifications`](/reference/api/notifications/list-notifications/), [`get_pull_request`](/reference/api/pull-requests/get-pull-request/), [`list_sessions`](/reference/api/sessions/list-sessions/), [`list_claims`](/reference/api/work-items/list-claims/). | |
| 1031 | 899 | ||
| 1032 | 900 | ## g1t session | |
| 1033 | 901 | ||
| ⋯ | |||
| 1043 | 911 | ||
| 1044 | 912 | | Argument or flag | | | |
| 1045 | 913 | | --- | --- | | |
| 1046 | − | | `-i, --issue <ISSUE>` | The issue it works on. | | |
| 914 | + | | `-i, --item <ITEM>` | The work item it works on, by its number in the workspace. | | |
| 1047 | 915 | | `-p, --pull <PULL>` | The pull request it works on. | | |
| 1048 | 916 | | `--harness <HARNESS>` | The harness running it. One of `claude_code`, `codex`, `cursor`, `copilot`, `other`. Default: `other`. | | |
| 1049 | 917 | | `--harness-session-id <ID>` | The harness's own id for the run, which makes starting again return the same session. | | |
| ⋯ | |||
| 1092 | 960 | ||
| 1093 | 961 | ### g1t session attach | |
| 1094 | 962 | ||
| 1095 | − | Attach the current session to an issue, a pull request or a branch, or give it a title. | |
| 963 | + | Attach the current session to a work item, a pull request or a branch, or give it a title. | |
| 1096 | 964 | ||
| 1097 | 965 | ```text | |
| 1098 | − | g1t session attach [OPTIONS] <--issue <ISSUE>|--pull <PULL>|--branch <BRANCH>|--head-commit <SHA>|--title <TITLE>> | |
| 966 | + | g1t session attach [OPTIONS] <--item <ITEM>|--pull <PULL>|--branch <BRANCH>|--head-commit <SHA>|--title <TITLE>> | |
| 1099 | 967 | ``` | |
| 1100 | 968 | ||
| 1101 | 969 | | Argument or flag | | | |
| 1102 | 970 | | --- | --- | | |
| 1103 | − | | `-i, --issue <ISSUE>` | | | |
| 971 | + | | `-i, --item <ITEM>` | A work item, by its number in the workspace. | | |
| 1104 | 972 | | `-p, --pull <PULL>` | | | |
| 1105 | 973 | | `-b, --branch <BRANCH>` | | | |
| 1106 | 974 | | `--head-commit <SHA>` | The commit it pushed last. | | |
| ⋯ | |||
| 1134 | 1002 | | Argument or flag | | | |
| 1135 | 1003 | | --- | --- | | |
| 1136 | 1004 | | `-s, --state <STATE>` | Only sessions in this state. One of `active`, `idle`, `ended`. | | |
| 1137 | − | | `-i, --issue <ISSUE>` | | | |
| 1005 | + | | `-i, --item <ITEM>` | Only sessions on this work item. | | |
| 1138 | 1006 | | `-p, --pull <PULL>` | | | |
| 1139 | 1007 | | `-L, --limit <LIMIT>` | Default: `20`. | | |
| 1140 | 1008 | | `--path <PATH>` | Only sessions that touched this file, or any under it when it ends in /. | | |
| ⋯ | |||
| 1194 | 1062 | ||
| 1195 | 1063 | ### g1t session touch | |
| 1196 | 1064 | ||
| 1197 | − | Say what the current session touched: files, commits, branches, pull requests, issues. | |
| 1065 | + | Say what the current session touched: files, commits, branches, pull requests, work items. | |
| 1198 | 1066 | ||
| 1199 | 1067 | ```text | |
| 1200 | − | g1t session touch [OPTIONS] <--file <FILE>|--commit <COMMIT>|--branch <BRANCH>|--pull <PULL>|--issue <ISSUE>> | |
| 1068 | + | g1t session touch [OPTIONS] <--file <FILE>|--commit <COMMIT>|--branch <BRANCH>|--pull <PULL>|--item <ITEM>> | |
| 1201 | 1069 | ``` | |
| 1202 | 1070 | ||
| 1203 | 1071 | | Argument or flag | | | |
| ⋯ | |||
| 1206 | 1074 | | `--commit <COMMIT>` | A commit it made. | | |
| 1207 | 1075 | | `--branch <BRANCH>` | A branch it pushed. | | |
| 1208 | 1076 | | `--pull <PULL>` | A pull request it opened. | | |
| 1209 | − | | `--issue <ISSUE>` | An issue it named. | | |
| 1077 | + | | `--item <ITEM>` | A work item it named, by its number in the workspace. | | |
| 1210 | 1078 | ||
| 1211 | 1079 | ```text | |
| 1212 | 1080 | Each is kept once. A file another active session touched too (a sibling subagent's included) | |
| 1213 | − | is an overlap.detected event for both. Pull requests and issues tie the session to them. | |
| 1081 | + | is an overlap.detected event for both. Pull requests and work items tie the session to them. | |
| 1214 | 1082 | ``` | |
| 1215 | 1083 | ||
| 1216 | 1084 | Calls [`record_session_entries`](/reference/api/sessions/record-session-entries/). | |
| 1217 | 1085 | ||
| 1218 | 1086 | ## g1t work | |
| 1219 | 1087 | ||
| 1220 | − | Coordinate work on issues: context, claims, hand-offs, dependencies, events. | |
| 1088 | + | Work items: list, view, open, edit, link, close; claims, hand-offs, dependencies, events. | |
| 1221 | 1089 | ||
| 1222 | − | ### g1t work context | |
| 1090 | + | ### g1t work list | |
| 1223 | 1091 | ||
| 1224 | − | Everything about an issue's work: claims, sessions, pull requests, dependencies, decisions. | |
| 1092 | + | List the workspace's work items; with --repo, those linked to that repository. | |
| 1225 | 1093 | ||
| 1226 | 1094 | ```text | |
| 1227 | − | g1t work context [OPTIONS] <NUMBER> | |
| 1095 | + | g1t work list [OPTIONS] | |
| 1228 | 1096 | ``` | |
| 1229 | 1097 | ||
| 1230 | 1098 | | Argument or flag | | | |
| 1231 | 1099 | | --- | --- | | |
| 1232 | − | | `<NUMBER>` | The issue's number. | | |
| 1100 | + | | `-s, --state <STATE>` | One of `open`, `closed`, `all`. Default: `open`. | | |
| 1101 | + | | `-l, --label <LABEL>` | Only work items with this label. | | |
| 1102 | + | | `-m, --milestone <MILESTONE>` | Only work items in the workspace milestone of this number. | | |
| 1103 | + | | `-a, --assignee <ASSIGNEE>` | Only work items assigned to this person (@me for you). | | |
| 1104 | + | | `-A, --author <AUTHOR>` | Only work items opened by this person (@me for you). | | |
| 1105 | + | | `--role <ROLE>` | With --repo: only those linked to it this way. One of `origin`, `target`, `touched`. | | |
| 1106 | + | | `-L, --limit <LIMIT>` | Default: `20`. | | |
| 1233 | 1107 | ||
| 1234 | − | Calls [`get_work`](/reference/api/claims-and-work/get-work/). | |
| 1108 | + | Calls [`list_work_items`](/reference/api/work-items/list-work-items/). | |
| 1235 | 1109 | ||
| 1110 | + | ### g1t work view | |
| 1111 | + | ||
| 1112 | + | Show a work item with everything about its work: repositories and what landed, claims, sessions, pull requests, what it waits on, decisions. | |
| 1113 | + | ||
| 1114 | + | ```text | |
| 1115 | + | g1t work view [OPTIONS] <NUMBER> | |
| 1116 | + | ``` | |
| 1117 | + | ||
| 1118 | + | | Argument or flag | | | |
| 1119 | + | | --- | --- | | |
| 1120 | + | | `<NUMBER>` | The work item's number. | | |
| 1121 | + | | `-c, --comments` | Show its comments too. | | |
| 1122 | + | | `-w, --web` | Open it in the browser. | | |
| 1123 | + | ||
| 1124 | + | Calls [`get_work`](/reference/api/work-items/get-work/), [`get_work_item`](/reference/api/work-items/get-work-item/). | |
| 1125 | + | ||
| 1126 | + | ### g1t work new | |
| 1127 | + | ||
| 1128 | + | Open a work item, with the current repository as its origin. | |
| 1129 | + | ||
| 1130 | + | ```text | |
| 1131 | + | g1t work new [OPTIONS] | |
| 1132 | + | ``` | |
| 1133 | + | ||
| 1134 | + | | Argument or flag | | | |
| 1135 | + | | --- | --- | | |
| 1136 | + | | `-t, --title <TITLE>` | | | |
| 1137 | + | | `-b, --body <BODY>` | The text. Markdown. | | |
| 1138 | + | | `-F, --body-file <FILE>` | Read the text from a file, or - for stdin. | | |
| 1139 | + | | `--attach <FILE>` | An image to show after the text (PNG, JPEG, GIF or WebP, at most 10 MB): uploaded, and its Markdown added. Repeat for more. | | |
| 1140 | + | | `--target <OWNER/NAME>` | A repository of the workspace where the work is meant to land, OWNER/NAME; repeat for more. | | |
| 1141 | + | | `-l, --label <LABEL>` | A label; repeat for more. | | |
| 1142 | + | | `-a, --assignee <ASSIGNEE>` | Someone to assign; repeat for more (@me for you). | | |
| 1143 | + | | `-m, --milestone <MILESTONE>` | A workspace milestone's number. | | |
| 1144 | + | | `-w, --web` | Open the new work item page in the browser instead. | | |
| 1145 | + | ||
| 1146 | + | ```text | |
| 1147 | + | In a repository, the work item is filed from it (its origin). With --workspace and no | |
| 1148 | + | repository of that workspace here, it is filed in the workspace alone. --target names a repository | |
| 1149 | + | where the work is meant to land; repeat it for more. | |
| 1150 | + | Examples: | |
| 1151 | + | g1t work new --title "Sign-in times out on slow networks" --body "..." | |
| 1152 | + | g1t work new --title "Rename the flag" --target acme/api --target acme/docs | |
| 1153 | + | ``` | |
| 1154 | + | ||
| 1155 | + | Calls [`open_work_item`](/reference/api/work-items/open-work-item/), [`update_work_item`](/reference/api/work-items/update-work-item/), [`upload_attachment`](/reference/api/work-items/upload-attachment/). | |
| 1156 | + | ||
| 1157 | + | ### g1t work comment | |
| 1158 | + | ||
| 1159 | + | Comment on a work item. | |
| 1160 | + | ||
| 1161 | + | ```text | |
| 1162 | + | g1t work comment [OPTIONS] <NUMBER> | |
| 1163 | + | ``` | |
| 1164 | + | ||
| 1165 | + | | Argument or flag | | | |
| 1166 | + | | --- | --- | | |
| 1167 | + | | `<NUMBER>` | The work item's number. | | |
| 1168 | + | | `-b, --body <BODY>` | The text. Markdown. | | |
| 1169 | + | | `-F, --body-file <FILE>` | Read the text from a file, or - for stdin. | | |
| 1170 | + | | `--attach <FILE>` | An image to show after the text (PNG, JPEG, GIF or WebP, at most 10 MB): uploaded, and its Markdown added. Repeat for more. | | |
| 1171 | + | ||
| 1172 | + | Calls [`add_work_item_comment`](/reference/api/work-items/add-work-item-comment/), [`upload_attachment`](/reference/api/work-items/upload-attachment/). | |
| 1173 | + | ||
| 1174 | + | ### g1t work edit | |
| 1175 | + | ||
| 1176 | + | Change a work item's title, body, labels, assignees or milestone. | |
| 1177 | + | ||
| 1178 | + | ```text | |
| 1179 | + | g1t work edit [OPTIONS] <NUMBER> | |
| 1180 | + | ``` | |
| 1181 | + | ||
| 1182 | + | | Argument or flag | | | |
| 1183 | + | | --- | --- | | |
| 1184 | + | | `<NUMBER>` | | | |
| 1185 | + | | `-t, --title <TITLE>` | | | |
| 1186 | + | | `-b, --body <BODY>` | The text. Markdown. | | |
| 1187 | + | | `-F, --body-file <FILE>` | Read the text from a file, or - for stdin. | | |
| 1188 | + | | `--add-label <LABEL>` | | | |
| 1189 | + | | `--remove-label <LABEL>` | | | |
| 1190 | + | | `--add-assignee <LOGIN>` | | | |
| 1191 | + | | `--remove-assignee <LOGIN>` | | | |
| 1192 | + | | `-m, --milestone <MILESTONE>` | A workspace milestone's number. | | |
| 1193 | + | | `--remove-milestone` | Take it out of its milestone. | | |
| 1194 | + | ||
| 1195 | + | Calls [`update_work_item`](/reference/api/work-items/update-work-item/), [`get_work_item`](/reference/api/work-items/get-work-item/). | |
| 1196 | + | ||
| 1197 | + | ### g1t work close | |
| 1198 | + | ||
| 1199 | + | Close a work item. | |
| 1200 | + | ||
| 1201 | + | ```text | |
| 1202 | + | g1t work close [OPTIONS] <NUMBER> | |
| 1203 | + | ``` | |
| 1204 | + | ||
| 1205 | + | | Argument or flag | | | |
| 1206 | + | | --- | --- | | |
| 1207 | + | | `<NUMBER>` | | | |
| 1208 | + | | `-r, --reason <REASON>` | One of `completed`, `not_planned`. | | |
| 1209 | + | | `-c, --comment <COMMENT>` | Leave a comment as it closes. | | |
| 1210 | + | | `--commit <COMMIT>` | The commit on the repository's default branch that did it: its message names the work item after a closing keyword (Fixes #12). Its full hash. It lands there; the work item closes when nothing else is left to land. | | |
| 1211 | + | ||
| 1212 | + | Calls [`close_work_item`](/reference/api/work-items/close-work-item/), [`add_work_item_comment`](/reference/api/work-items/add-work-item-comment/). | |
| 1213 | + | ||
| 1214 | + | ### g1t work reopen | |
| 1215 | + | ||
| 1216 | + | Reopen a work item. | |
| 1217 | + | ||
| 1218 | + | ```text | |
| 1219 | + | g1t work reopen [OPTIONS] <NUMBER> | |
| 1220 | + | ``` | |
| 1221 | + | ||
| 1222 | + | | Argument or flag | | | |
| 1223 | + | | --- | --- | | |
| 1224 | + | | `<NUMBER>` | | | |
| 1225 | + | | `-c, --comment <COMMENT>` | Leave a comment as it reopens. | | |
| 1226 | + | ||
| 1227 | + | Calls [`reopen_work_item`](/reference/api/work-items/reopen-work-item/), [`add_work_item_comment`](/reference/api/work-items/add-work-item-comment/). | |
| 1228 | + | ||
| 1229 | + | ### g1t work link | |
| 1230 | + | ||
| 1231 | + | Link a repository to a work item: where the work must land (target), or touched. | |
| 1232 | + | ||
| 1233 | + | ```text | |
| 1234 | + | g1t work link [OPTIONS] <NUMBER> | |
| 1235 | + | ``` | |
| 1236 | + | ||
| 1237 | + | | Argument or flag | | | |
| 1238 | + | | --- | --- | | |
| 1239 | + | | `<NUMBER>` | The work item's number. | | |
| 1240 | + | | `--role <ROLE>` | How the repository is linked. One of `target`, `touched`. Default: `target`. | | |
| 1241 | + | ||
| 1242 | + | ```text | |
| 1243 | + | The repository is the current one, or --repo OWNER/NAME. A work item with targets closes once it | |
| 1244 | + | has landed in every one. | |
| 1245 | + | Examples: | |
| 1246 | + | g1t work link 12 --repo acme/api | |
| 1247 | + | g1t work link 12 --role touched | |
| 1248 | + | ``` | |
| 1249 | + | ||
| 1250 | + | Calls [`link_work_item`](/reference/api/work-items/link-work-item/). | |
| 1251 | + | ||
| 1252 | + | ### g1t work unlink | |
| 1253 | + | ||
| 1254 | + | Unlink a repository from a work item (never its origin). | |
| 1255 | + | ||
| 1256 | + | ```text | |
| 1257 | + | g1t work unlink [OPTIONS] <NUMBER> | |
| 1258 | + | ``` | |
| 1259 | + | ||
| 1260 | + | | Argument or flag | | | |
| 1261 | + | | --- | --- | | |
| 1262 | + | | `<NUMBER>` | The work item's number. | | |
| 1263 | + | ||
| 1264 | + | Calls [`unlink_work_item`](/reference/api/work-items/unlink-work-item/). | |
| 1265 | + | ||
| 1236 | 1266 | ### g1t work claim | |
| 1237 | 1267 | ||
| 1238 | − | Claim an issue: say you are working on it. Others are told, never stopped. | |
| 1268 | + | Claim a work item: say you are working on it. Others are told, never stopped. | |
| 1239 | 1269 | ||
| 1240 | 1270 | ```text | |
| 1241 | 1271 | g1t work claim [OPTIONS] <NUMBER|--title <TITLE>> | |
| ⋯ | |||
| 1243 | 1273 | ||
| 1244 | 1274 | | Argument or flag | | | |
| 1245 | 1275 | | --- | --- | | |
| 1246 | − | | `[NUMBER]` | The issue's number. | | |
| 1247 | − | | `--title <TITLE>` | Open a new issue with this title and claim it; the current session is attached to it. | | |
| 1248 | − | | `--body <BODY>` | The new issue's description. | | |
| 1276 | + | | `[NUMBER]` | The work item's number. | | |
| 1277 | + | | `--title <TITLE>` | Open a new work item with this title and claim it; the current session is attached to it. | | |
| 1278 | + | | `--body <BODY>` | The new work item's description. | | |
| 1249 | 1279 | | `-n, --note <NOTE>` | What you are doing about it. | | |
| 1250 | 1280 | | `--ttl <DURATION>` | How long the claim lasts unless renewed: 30m, 2h (at most 4h). | | |
| 1251 | 1281 | ||
| 1252 | 1282 | ```text | |
| 1253 | − | With --title instead of a number, a new issue is opened and claimed in one step, and the | |
| 1254 | − | current session is attached to it: for work that became a change others should know about. | |
| 1283 | + | With --title instead of a number, a new work item is opened (filed from the current repository) | |
| 1284 | + | and claimed in one step, and the current session is attached to it: for work that became a change | |
| 1285 | + | others should know about. | |
| 1255 | 1286 | Examples: | |
| 1256 | 1287 | g1t work claim 12 --note "Rewriting the retry loop" | |
| 1257 | 1288 | g1t work claim --title "Preview builds time out on large repositories" | |
| 1258 | 1289 | ``` | |
| 1259 | 1290 | ||
| 1260 | − | Calls [`claim_issue`](/reference/api/claims-and-work/claim-issue/), [`claim_new_issue`](/reference/api/claims-and-work/claim-new-issue/). | |
| 1291 | + | Calls [`claim_work_item`](/reference/api/work-items/claim-work-item/), [`claim_new_work_item`](/reference/api/work-items/claim-new-work-item/). | |
| 1261 | 1292 | ||
| 1262 | 1293 | ### g1t work release | |
| 1263 | 1294 | ||
| 1264 | − | Release your claim on an issue. | |
| 1295 | + | Release your claim on a work item. | |
| 1265 | 1296 | ||
| 1266 | 1297 | ```text | |
| 1267 | 1298 | g1t work release [OPTIONS] <NUMBER> | |
| ⋯ | |||
| 1272 | 1303 | | `<NUMBER>` | | | |
| 1273 | 1304 | | `-r, --reason <REASON>` | Why: done, blocked, abandoned... | | |
| 1274 | 1305 | ||
| 1275 | − | Calls [`release_claim`](/reference/api/claims-and-work/release-claim/). | |
| 1306 | + | Calls [`release_claim`](/reference/api/work-items/release-claim/). | |
| 1276 | 1307 | ||
| 1277 | 1308 | ### g1t work handoff | |
| 1278 | 1309 | ||
| 1279 | − | Hand an issue over to someone else, or to anyone. | |
| 1310 | + | Hand a work item over to someone else, or to anyone. | |
| 1280 | 1311 | ||
| 1281 | 1312 | ```text | |
| 1282 | 1313 | g1t work handoff [OPTIONS] --note <NOTE> <NUMBER> | |
| ⋯ | |||
| 1288 | 1319 | | `--to <LOGIN>` | Who takes it over; anyone when left out. | | |
| 1289 | 1320 | | `-n, --note <NOTE>` | Where it stands and what is left, for whoever takes it. | | |
| 1290 | 1321 | ||
| 1291 | − | Calls [`hand_off_issue`](/reference/api/claims-and-work/hand-off-issue/). | |
| 1322 | + | Calls [`hand_off_work_item`](/reference/api/work-items/hand-off-work-item/). | |
| 1292 | 1323 | ||
| 1293 | − | ### g1t work list | |
| 1324 | + | ### g1t work status | |
| 1294 | 1325 | ||
| 1295 | 1326 | Active claims and sessions in the repository. | |
| 1296 | 1327 | ||
| 1297 | 1328 | ```text | |
| 1298 | − | g1t work list [OPTIONS] | |
| 1329 | + | g1t work status [OPTIONS] | |
| 1299 | 1330 | ``` | |
| 1300 | 1331 | ||
| 1301 | − | Calls [`list_claims`](/reference/api/claims-and-work/list-claims/), [`list_sessions`](/reference/api/sessions/list-sessions/). | |
| 1332 | + | Calls [`list_claims`](/reference/api/work-items/list-claims/), [`list_sessions`](/reference/api/sessions/list-sessions/). | |
| 1302 | 1333 | ||
| 1303 | 1334 | ### g1t work block | |
| 1304 | 1335 | ||
| 1305 | − | Say an issue waits on others: it is blocked by them. | |
| 1336 | + | Say a work item waits on others: it is blocked by them. | |
| 1306 | 1337 | ||
| 1307 | 1338 | ```text | |
| 1308 | 1339 | g1t work block [OPTIONS] --by <NUMBER> <NUMBER> | |
| ⋯ | |||
| 1310 | 1341 | ||
| 1311 | 1342 | | Argument or flag | | | |
| 1312 | 1343 | | --- | --- | | |
| 1313 | − | | `<NUMBER>` | The issue that waits. | | |
| 1314 | − | | `--by <NUMBER>` | The issue it waits on; repeat for more. | | |
| 1344 | + | | `<NUMBER>` | The work item that waits. | | |
| 1345 | + | | `--by <NUMBER>` | The work item it waits on; repeat for more. | | |
| 1315 | 1346 | ||
| 1316 | − | Calls [`get_issue`](/reference/api/issues/get-issue/), [`update_issue`](/reference/api/issues/update-issue/). | |
| 1347 | + | Calls [`get_work_item`](/reference/api/work-items/get-work-item/), [`update_work_item`](/reference/api/work-items/update-work-item/). | |
| 1317 | 1348 | ||
| 1318 | 1349 | ### g1t work unblock | |
| 1319 | 1350 | ||
| 1320 | − | Say an issue no longer waits on others. | |
| 1351 | + | Say a work item no longer waits on others. | |
| 1321 | 1352 | ||
| 1322 | 1353 | ```text | |
| 1323 | 1354 | g1t work unblock [OPTIONS] --by <NUMBER> <NUMBER> | |
| ⋯ | |||
| 1325 | 1356 | ||
| 1326 | 1357 | | Argument or flag | | | |
| 1327 | 1358 | | --- | --- | | |
| 1328 | − | | `<NUMBER>` | The issue that waits. | | |
| 1329 | − | | `--by <NUMBER>` | The issue it waits on; repeat for more. | | |
| 1359 | + | | `<NUMBER>` | The work item that waits. | | |
| 1360 | + | | `--by <NUMBER>` | The work item it waits on; repeat for more. | | |
| 1330 | 1361 | ||
| 1331 | − | Calls [`get_issue`](/reference/api/issues/get-issue/), [`update_issue`](/reference/api/issues/update-issue/). | |
| 1362 | + | Calls [`get_work_item`](/reference/api/work-items/get-work-item/), [`update_work_item`](/reference/api/work-items/update-work-item/). | |
| 1332 | 1363 | ||
| 1333 | 1364 | ### g1t work events | |
| 1334 | 1365 | ||
| ⋯ | |||
| 1342 | 1373 | | --- | --- | | |
| 1343 | 1374 | | `-f, --follow` | Keep printing events as they happen, until stopped. | | |
| 1344 | 1375 | | `-t, --type <TYPE>` | Only events of this type; repeat for more. | | |
| 1345 | − | | `-i, --issue <NUMBER>` | Only events about this issue or pull request; repeat for more. | | |
| 1376 | + | | `-i, --item <NUMBER>` | Only events about this work item or pull request; repeat for more. | | |
| 1346 | 1377 | | `-s, --since <SINCE>` | Only events since then: 15m, 2h, 1d, or a time like 2026-10-12T09:00:00Z. | | |
| 1347 | 1378 | | `--after <EVENT_ID>` | Start after this event id, as a follow that stopped would resume. | | |
| 1348 | 1379 | | `-L, --limit <LIMIT>` | How many past events to show first. Default: `20`. | | |
| 1349 | 1380 | ||
| 1350 | 1381 | ```text | |
| 1351 | 1382 | Examples: | |
| 1352 | − | g1t work events --follow --issue 12 | |
| 1383 | + | g1t work events --follow --item 12 | |
| 1353 | 1384 | g1t work events --follow --type integration.failed --type overlap.detected --json | |
| 1354 | 1385 | With --json, each event is one JSON object on a line of its own. | |
| 1355 | 1386 | ``` | |
| ⋯ | |||
| 1358 | 1389 | ||
| 1359 | 1390 | ### g1t work dispatch | |
| 1360 | 1391 | ||
| 1361 | − | Start work on an issue in a session on your own Claude, or print the Claude Code command for it. | |
| 1392 | + | Start work on a work item in a session on your own Claude, or print the Claude Code command for it. | |
| 1362 | 1393 | ||
| 1363 | 1394 | ```text | |
| 1364 | 1395 | g1t work dispatch [OPTIONS] <NUMBER|--title <TITLE>> | |
| ⋯ | |||
| 1366 | 1397 | ||
| 1367 | 1398 | | Argument or flag | | | |
| 1368 | 1399 | | --- | --- | | |
| 1369 | − | | `[NUMBER]` | The issue's number. | | |
| 1370 | − | | `--title <TITLE>` | Open a new issue with this title and work on it. | | |
| 1371 | − | | `--body <BODY>` | The new issue's description. | | |
| 1372 | − | | `-i, --instruction <INSTRUCTION>` | What to do beyond what the issue says. | | |
| 1400 | + | | `[NUMBER]` | The work item's number. | | |
| 1401 | + | | `--title <TITLE>` | Open a new work item with this title and work on it. | | |
| 1402 | + | | `--body <BODY>` | The new work item's description. | | |
| 1403 | + | | `-i, --instruction <INSTRUCTION>` | What to do beyond what the work item says. | | |
| 1373 | 1404 | | `-m, --mode <MODE>` | What kind of work. One of `plan`, `implement`, `review`. | | |
| 1374 | 1405 | | `--handoff` | Print the Claude Code command to run yourself; start nothing. | | |
| 1375 | 1406 | | `--managed` | Start it on the workspace's Anthropic account, or fail. | | |
| ⋯ | |||
| 1377 | 1408 | ```text | |
| 1378 | 1409 | With the workspace's Anthropic AI provider, a Claude Managed Agents session starts on that | |
| 1379 | 1410 | account and is recorded on g1t; otherwise (or with --handoff) this prints a `claude` command | |
| 1380 | − | to run with g1t's plugin, whose session attaches to the issue as it starts. | |
| 1411 | + | to run with g1t's plugin, whose session attaches to the work item as it starts. | |
| 1381 | 1412 | Examples: | |
| 1382 | 1413 | g1t work dispatch 12 | |
| 1383 | 1414 | g1t work dispatch 12 --mode plan --instruction "Keep the old flag" | |
| ⋯ | |||
| 1388 | 1419 | ||
| 1389 | 1420 | ## g1t why | |
| 1390 | 1421 | ||
| 1391 | − | Why a file or line is as it is: its commit, pull request, issue, decisions and sessions. | |
| 1422 | + | Why a file or line is as it is: its commit, pull request, work item, decisions and sessions. | |
| 1392 | 1423 | ||
| 1393 | 1424 | ```text | |
| 1394 | 1425 | g1t why [OPTIONS] <TARGET> | |
| ⋯ | |||
| 1403 | 1434 | ||
| 1404 | 1435 | ## g1t attach | |
| 1405 | 1436 | ||
| 1406 | − | Upload images, such as a screenshot, to show in an issue, a pull request or a comment; prints their Markdown. | |
| 1437 | + | Upload images, such as a screenshot, to show in a work item, a pull request or a comment; prints their Markdown. | |
| 1407 | 1438 | ||
| 1408 | 1439 | ```text | |
| 1409 | 1440 | g1t attach [OPTIONS] <FILE>... | |
| ⋯ | |||
| 1417 | 1448 | Prints each image's Markdown, , to paste into a description or a comment; --json prints | |
| 1418 | 1449 | { id, name, url, markdown, content_type, size } (a list for several files). The image is served from | |
| 1419 | 1450 | g1t's usercontent address, and anyone given that address can see it, even from a private repository. | |
| 1420 | − | --attach FILE on g1t issue create, g1t issue comment, g1t pr create, g1t pr comment and g1t pr ready | |
| 1451 | + | --attach FILE on g1t work new, g1t work comment, g1t pr create, g1t pr comment and g1t pr ready | |
| 1421 | 1452 | uploads and adds the Markdown for you: | |
| 1422 | 1453 | g1t attach preview.png | |
| 1423 | 1454 | g1t pr comment --body 'The preview, after the fix:' --attach preview.png | |
| 1424 | 1455 | ``` | |
| 1425 | 1456 | ||
| 1426 | − | Calls [`upload_attachment`](/reference/api/issues/upload-attachment/). | |
| 1457 | + | Calls [`upload_attachment`](/reference/api/work-items/upload-attachment/). | |
| 1427 | 1458 | ||
| 1428 | 1459 | ## g1t api | |
| 1429 | 1460 | ||
| ⋯ | |||
| 1448 | 1479 | | `--silent` | Print nothing on success. | | |
| 1449 | 1480 | ||
| 1450 | 1481 | ```text | |
| 1451 | − | ENDPOINT is an operation's name (list_issues) or a path (/repos/{owner}/{name}/issues). | |
| 1482 | + | ENDPOINT is an operation's name (list_work_items) or a path (/workspaces/{workspace}/work). | |
| 1452 | 1483 | {owner}, {name}, {repo} and {workspace} are filled in from the current repository, | |
| 1453 | 1484 | and an operation's other path parameters from -f/-F fields of the same name. | |
| 1454 | 1485 | ||
| 1455 | 1486 | Examples: | |
| 1456 | − | g1t api list_issues -f state=closed | |
| 1487 | + | g1t api list_work_items -f state=closed | |
| 1457 | 1488 | g1t api /user --jq .username | |
| 1458 | − | g1t api create_issue -f title='Broken link' -f labels[]=docs | |
| 1489 | + | g1t api open_work_item -f title='Broken link' -f labels[]=docs | |
| 1459 | 1490 | g1t api list_workflow_runs --paginate --jq '.[].conclusion' | |
| 1460 | − | g1t api --list issue | |
| 1491 | + | g1t api --list work | |
| 1461 | 1492 | ``` | |
| 1462 | 1493 | ||
| 1463 | 1494 | ## g1t browse | |
| 1464 | 1495 | ||
| 1465 | − | Open the repository, an issue or a pull request in the browser. | |
| 1496 | + | Open the repository, a work item or a pull request in the browser. | |
| 1466 | 1497 | ||
| 1467 | 1498 | ```text | |
| 1468 | 1499 | g1t browse [OPTIONS] [TARGET] | |
| ⋯ | |||
| 1470 | 1501 | ||
| 1471 | 1502 | | Argument or flag | | | |
| 1472 | 1503 | | --- | --- | | |
| 1473 | − | | `[TARGET]` | An issue or pull request number, a file path (path:line), or a commit. | | |
| 1504 | + | | `[TARGET]` | A work item or pull request number, a file path (path:line), or a commit. | | |
| 1474 | 1505 | | `-b, --branch <BRANCH>` | The branch to show files on. | | |
| 1475 | 1506 | | `-s, --settings` | | | |
| 1476 | − | | `--issues` | | | |
| 1507 | + | | `--work` | The repository's work items: the workspace's Work list, filtered to it. | | |
| 1477 | 1508 | | `--pulls` | | | |
| 1478 | 1509 | | `--actions` | | | |
| 1479 | 1510 | | `-n, --no-browser` | Print the address instead of opening it. | | |
| 1480 | 1511 | ||
| 1512 | + | Calls [`resolve_ref`](/reference/api/work-items/resolve-ref/). | |
| 1513 | + | ||
| 1481 | 1514 | ## g1t alias | |
| 1482 | 1515 | ||
| 1483 | 1516 | Shortcuts for commands you type often. | |
| 1 | 1 | [package] | |
| 2 | 2 | name = "g1t" | |
| 3 | − | version = "0.3.7" | |
| 3 | + | version = "0.4.0" | |
| 4 | 4 | edition.workspace = true | |
| 5 | 5 | license.workspace = true | |
| 6 | 6 | repository.workspace = true | |
| 7 | − | description = "The g1t command line: repositories, issues, pull requests, workflow runs, deployments, secrets and logs on g1t, from a terminal or an agent's shell." | |
| 7 | + | description = "The g1t command line: repositories, work items, pull requests, workflow runs, deployments, secrets and logs on g1t, from a terminal or an agent's shell." | |
| 8 | 8 | ||
| 9 | 9 | [[bin]] | |
| 10 | 10 | name = "g1t" |
| 8 | 8 | pub const AFTER_HELP: &str = "\ | |
| 9 | 9 | Examples: | |
| 10 | 10 | g1t auth login | |
| 11 | − | g1t issue list --label bug | |
| 11 | + | g1t work list --label bug | |
| 12 | 12 | g1t pr create --fill | |
| 13 | 13 | g1t pr checks --watch --fail-fast | |
| 14 | 14 | g1t run logs --failed | |
| 15 | 15 | g1t workflow run release.yml -f channel=stable | |
| 16 | − | g1t api list_issues --jq '.[].title' | |
| 16 | + | g1t api list_work_items --jq '.[].title' | |
| 17 | 17 | ||
| 18 | 18 | Environment: | |
| 19 | 19 | G1T_TOKEN A token to use instead of the stored one | |
| ⋯ | |||
| 83 | 83 | /// Repositories: view, clone, create, list, fork, sync. | |
| 84 | 84 | #[command(subcommand)] | |
| 85 | 85 | Repo(RepoCommand), | |
| 86 | − | /// Issues: list, view, create, comment, close, reopen, edit. | |
| 87 | − | #[command(subcommand)] | |
| 88 | − | Issue(IssueCommand), | |
| 89 | 86 | /// Pull requests: list, view, create, check out, diff, checks, review, merge. | |
| 90 | 87 | #[command(subcommand)] | |
| 91 | 88 | Pr(PrCommand), | |
| ⋯ | |||
| 106 | 103 | Deploy(DeployCommand), | |
| 107 | 104 | /// A project's logs and errors. | |
| 108 | 105 | Logs(LogsArgs), | |
| 109 | − | /// What needs you: your pull requests, reviews asked of you, your issues, failing checks, and your sessions and claims here. | |
| 106 | + | /// What needs you: your pull requests, reviews asked of you, failing checks, and your sessions and claims here. | |
| 110 | 107 | Status(StatusArgs), | |
| 111 | 108 | /// Sessions: one run of an agent's harness, recorded as it works. | |
| 112 | 109 | #[command(subcommand)] | |
| 113 | 110 | Session(SessionCommand), | |
| 114 | − | /// Coordinate work on issues: context, claims, hand-offs, dependencies, events. | |
| 115 | − | #[command(subcommand)] | |
| 116 | − | Work(WorkCommand), | |
| 117 | − | /// Why a file or line is as it is: its commit, pull request, issue, decisions and sessions. | |
| 111 | + | /// Work items: list, view, open, edit, link, close; claims, hand-offs, dependencies, events. | |
| 112 | + | Work(WorkArgs), | |
| 113 | + | /// Why a file or line is as it is: its commit, pull request, work item, decisions and sessions. | |
| 118 | 114 | Why(WhyArgs), | |
| 119 | − | /// Upload images, such as a screenshot, to show in an issue, a pull request or a comment; prints their Markdown. | |
| 115 | + | /// Upload images, such as a screenshot, to show in a work item, a pull request or a comment; prints their Markdown. | |
| 120 | 116 | Attach(AttachArgs), | |
| 121 | 117 | /// Call any API operation or path, with your token. | |
| 122 | 118 | Api(ApiArgs), | |
| 123 | − | /// Open the repository, an issue or a pull request in the browser. | |
| 119 | + | /// Open the repository, a work item or a pull request in the browser. | |
| 124 | 120 | Browse(BrowseArgs), | |
| 125 | 121 | /// Shortcuts for commands you type often. | |
| 126 | 122 | #[command(subcommand)] | |
| ⋯ | |||
| 336 | 332 | pub limit: usize, | |
| 337 | 333 | } | |
| 338 | 334 | ||
| 339 | − | // --- issue ------------------------------------------------------------ | |
| 340 | − | ||
| 341 | − | #[derive(Debug, Subcommand)] | |
| 342 | − | pub enum IssueCommand { | |
| 343 | − | /// List issues. | |
| 344 | − | List(IssueListArgs), | |
| 345 | − | /// Show an issue, with its comments. | |
| 346 | − | View(IssueViewArgs), | |
| 347 | − | /// Open an issue. | |
| 348 | − | Create(IssueCreateArgs), | |
| 349 | − | /// Comment on an issue. | |
| 350 | − | Comment(CommentArgs), | |
| 351 | − | /// Close an issue. | |
| 352 | − | Close(IssueCloseArgs), | |
| 353 | − | /// Reopen an issue. | |
| 354 | − | Reopen(ReopenArgs), | |
| 355 | − | /// Change an issue's title, body, labels, assignees or milestone. | |
| 356 | − | Edit(IssueEditArgs), | |
| 357 | − | } | |
| 358 | − | ||
| 359 | − | #[derive(Clone, Copy, Debug, PartialEq, Eq, ValueEnum)] | |
| 360 | − | pub enum IssueState { | |
| 361 | − | Open, | |
| 362 | − | Closed, | |
| 363 | − | All, | |
| 364 | − | } | |
| 365 | − | ||
| 366 | − | #[derive(Debug, Args)] | |
| 367 | − | pub struct IssueListArgs { | |
| 368 | − | #[arg(short, long, value_enum, default_value_t = IssueState::Open)] | |
| 369 | − | pub state: IssueState, | |
| 370 | − | /// Only issues with this label. | |
| 371 | − | #[arg(short, long)] | |
| 372 | − | pub label: Option<String>, | |
| 373 | − | /// Only issues in the milestone of this number. | |
| 374 | − | #[arg(short, long)] | |
| 375 | − | pub milestone: Option<u64>, | |
| 376 | − | /// Only issues assigned to this person (@me for you). | |
| 377 | − | #[arg(short, long)] | |
| 378 | − | pub assignee: Option<String>, | |
| 379 | − | /// Only issues opened by this person (@me for you). | |
| 380 | − | #[arg(short = 'A', long)] | |
| 381 | − | pub author: Option<String>, | |
| 382 | − | #[arg(short = 'L', long, default_value_t = 20)] | |
| 383 | − | pub limit: usize, | |
| 384 | − | } | |
| 385 | − | ||
| 386 | − | #[derive(Debug, Args)] | |
| 387 | − | pub struct IssueViewArgs { | |
| 388 | − | /// The issue's number. | |
| 389 | − | pub number: u64, | |
| 390 | − | /// Show its comments too. | |
| 391 | − | #[arg(short, long)] | |
| 392 | − | pub comments: bool, | |
| 393 | − | /// Open it in the browser. | |
| 394 | − | #[arg(short, long)] | |
| 395 | − | pub web: bool, | |
| 396 | − | } | |
| 335 | + | // --- shared ----------------------------------------------------------- | |
| 397 | 336 | ||
| 398 | 337 | #[derive(Debug, Args)] | |
| 399 | 338 | pub struct BodyArgs { | |
| ⋯ | |||
| 403 | 342 | /// Read the text from a file, or - for stdin. | |
| 404 | 343 | #[arg(short = 'F', long, value_name = "FILE")] | |
| 405 | 344 | pub body_file: Option<String>, | |
| 406 | − | } | |
| 407 | − | ||
| 408 | − | #[derive(Debug, Args)] | |
| 409 | − | pub struct IssueCreateArgs { | |
| 410 | − | #[arg(short, long)] | |
| 411 | − | pub title: Option<String>, | |
| 412 | − | #[command(flatten)] | |
| 413 | − | pub body: BodyArgs, | |
| 414 | − | /// An image to show after the text (PNG, JPEG, GIF or WebP, at most 10 MB): uploaded, and its Markdown added. Repeat for more. | |
| 415 | − | #[arg(long, value_name = "FILE")] | |
| 416 | − | pub attach: Vec<PathBuf>, | |
| 417 | − | /// A label; repeat for more. | |
| 418 | − | #[arg(short, long)] | |
| 419 | − | pub label: Vec<String>, | |
| 420 | − | /// Someone to assign; repeat for more (@me for you). | |
| 421 | − | #[arg(short, long)] | |
| 422 | − | pub assignee: Vec<String>, | |
| 423 | − | /// A milestone's number. | |
| 424 | − | #[arg(short, long)] | |
| 425 | − | pub milestone: Option<u64>, | |
| 426 | − | /// Open the new-issue page in the browser instead. | |
| 427 | − | #[arg(short, long)] | |
| 428 | − | pub web: bool, | |
| 429 | 345 | } | |
| 430 | 346 | ||
| 431 | 347 | #[derive(Debug, Args)] | |
| 432 | 348 | pub struct CommentArgs { | |
| 433 | − | /// The number; for a pull request, the current branch's when left out. | |
| 349 | + | /// The pull request's number; the current branch's when left out. | |
| 434 | 350 | pub number: Option<u64>, | |
| 435 | 351 | #[command(flatten)] | |
| 436 | 352 | pub body: BodyArgs, | |
| 437 | 353 | /// An image to show after the text (PNG, JPEG, GIF or WebP, at most 10 MB): uploaded, and its Markdown added. Repeat for more. | |
| 438 | 354 | #[arg(long, value_name = "FILE")] | |
| 439 | 355 | pub attach: Vec<PathBuf>, | |
| 440 | − | } | |
| 441 | − | ||
| 442 | − | #[derive(Clone, Copy, Debug, PartialEq, Eq, ValueEnum)] | |
| 443 | − | pub enum CloseReason { | |
| 444 | − | Completed, | |
| 445 | − | // Spelled as the API spells it. | |
| 446 | − | #[value(name = "not_planned", alias = "not-planned")] | |
| 447 | − | NotPlanned, | |
| 448 | 356 | } | |
| 449 | 357 | ||
| 450 | 358 | #[derive(Debug, Args)] | |
| 451 | − | pub struct IssueCloseArgs { | |
| 452 | − | pub number: u64, | |
| 453 | − | #[arg(short, long, value_enum)] | |
| 454 | − | pub reason: Option<CloseReason>, | |
| 455 | − | /// Leave a comment as it closes. | |
| 456 | − | #[arg(short, long)] | |
| 457 | − | pub comment: Option<String>, | |
| 458 | − | /// The commit on the default branch that closed it: its message names | |
| 459 | − | /// the issue after a closing keyword (Fixes #12). Its full hash. | |
| 460 | − | #[arg(long)] | |
| 461 | − | pub commit: Option<String>, | |
| 462 | − | } | |
| 463 | − | ||
| 464 | − | #[derive(Debug, Args)] | |
| 465 | 359 | pub struct ReopenArgs { | |
| 466 | 360 | pub number: u64, | |
| 467 | 361 | /// Leave a comment as it reopens. | |
| 468 | 362 | #[arg(short, long)] | |
| 469 | 363 | pub comment: Option<String>, | |
| 470 | − | } | |
| 471 | − | ||
| 472 | − | #[derive(Debug, Args)] | |
| 473 | − | pub struct IssueEditArgs { | |
| 474 | − | pub number: u64, | |
| 475 | − | #[arg(short, long)] | |
| 476 | − | pub title: Option<String>, | |
| 477 | − | #[command(flatten)] | |
| 478 | − | pub body: BodyArgs, | |
| 479 | − | #[arg(long, value_name = "LABEL")] | |
| 480 | − | pub add_label: Vec<String>, | |
| 481 | − | #[arg(long, value_name = "LABEL")] | |
| 482 | − | pub remove_label: Vec<String>, | |
| 483 | − | #[arg(long, value_name = "LOGIN")] | |
| 484 | − | pub add_assignee: Vec<String>, | |
| 485 | − | #[arg(long, value_name = "LOGIN")] | |
| 486 | − | pub remove_assignee: Vec<String>, | |
| 487 | − | /// A milestone's number. | |
| 488 | − | #[arg(short, long)] | |
| 489 | − | pub milestone: Option<u64>, | |
| 490 | − | /// Take it out of its milestone. | |
| 491 | − | #[arg(long, conflicts_with = "milestone")] | |
| 492 | − | pub remove_milestone: bool, | |
| 493 | 364 | } | |
| 494 | 365 | ||
| 495 | 366 | // --- pr --------------------------------------------------------------- | |
| ⋯ | |||
| 500 | 371 | List(PrListArgs), | |
| 501 | 372 | /// Show a pull request. | |
| 502 | 373 | View(PrViewArgs), | |
| 503 | − | /// Open a pull request from a branch, or start one for an issue. | |
| 374 | + | /// Open a pull request from a branch, or start one for a work item. | |
| 504 | 375 | Create(PrCreateArgs), | |
| 505 | 376 | /// Check a pull request's changes out locally. | |
| 506 | 377 | Checkout(PrCheckoutArgs), | |
| ⋯ | |||
| 582 | 453 | /// The branch with the changes; the current one when left out. | |
| 583 | 454 | #[arg(short = 'H', long)] | |
| 584 | 455 | pub head: Option<String>, | |
| 585 | − | /// The issue it is for. Without a branch, starts a draft in a working copy of its own. | |
| 456 | + | /// The work item it is for, by its number in the workspace. Without a branch, starts a draft | |
| 457 | + | /// in a working copy of its own. | |
| 586 | 458 | #[arg(short, long)] | |
| 587 | − | pub issue: Option<u64>, | |
| 459 | + | pub item: Option<u64>, | |
| 588 | 460 | /// Take the title and body from the branch's commits. | |
| 589 | 461 | #[arg(short, long)] | |
| 590 | 462 | pub fill: bool, | |
| ⋯ | |||
| 674 | 546 | #[command(flatten)] | |
| 675 | 547 | pub body: BodyArgs, | |
| 676 | 548 | /// Merge on its own once its checks, reviews and rules allow. | |
| 677 | − | #[arg(long, conflicts_with_all = ["disable_auto", "keep_issue_open", "admin", "delete_branch", "keep_branch", "match_head_commit"])] | |
| 549 | + | #[arg(long, conflicts_with_all = ["disable_auto", "keep_item_open", "admin", "delete_branch", "keep_branch", "match_head_commit"])] | |
| 678 | 550 | pub auto: bool, | |
| 679 | 551 | /// Turn its auto-merge off. | |
| 680 | − | #[arg(long, conflicts_with_all = ["method", "subject", "body", "body_file", "keep_issue_open", "admin", "delete_branch", "keep_branch", "match_head_commit"])] | |
| 552 | + | #[arg(long, conflicts_with_all = ["method", "subject", "body", "body_file", "keep_item_open", "admin", "delete_branch", "keep_branch", "match_head_commit"])] | |
| 681 | 553 | pub disable_auto: bool, | |
| 682 | − | /// Leave the issue it is for open. | |
| 554 | + | /// Do not land the work item it is for: it is only part of the work. | |
| 683 | 555 | #[arg(long)] | |
| 684 | − | pub keep_issue_open: bool, | |
| 556 | + | pub keep_item_open: bool, | |
| 685 | 557 | /// Merge past failing required checks and rules (needs the Admin role). | |
| 686 | 558 | #[arg(long)] | |
| 687 | 559 | pub admin: bool, | |
| ⋯ | |||
| 1142 | 1014 | Heartbeat, | |
| 1143 | 1015 | /// Record a note, prompt or message in the current session. | |
| 1144 | 1016 | Log(SessionLogArgs), | |
| 1145 | − | /// Attach the current session to an issue, a pull request or a branch, or give it a title. | |
| 1017 | + | /// Attach the current session to a work item, a pull request or a branch, or give it a title. | |
| 1146 | 1018 | Attach(SessionAttachArgs), | |
| 1147 | 1019 | /// End the current session. | |
| 1148 | 1020 | End(SessionEndArgs), | |
| ⋯ | |||
| 1158 | 1030 | Updates(SessionViewArgs), | |
| 1159 | 1031 | /// Record your decision, then acknowledge exact coordination update IDs. | |
| 1160 | 1032 | Acknowledge(SessionAcknowledgeArgs), | |
| 1161 | − | /// Say what the current session touched: files, commits, branches, pull requests, issues. | |
| 1033 | + | /// Say what the current session touched: files, commits, branches, pull requests, work items. | |
| 1162 | 1034 | #[command(after_help = "\nEach is kept once. A file another active session touched too (a sibling subagent's included) | |
| 1163 | − | is an overlap.detected event for both. Pull requests and issues tie the session to them.")] | |
| 1035 | + | is an overlap.detected event for both. Pull requests and work items tie the session to them.")] | |
| 1164 | 1036 | Touch(SessionTouchArgs), | |
| 1165 | 1037 | } | |
| 1166 | 1038 | ||
| 1167 | 1039 | #[derive(Debug, Args)] | |
| 1168 | − | #[command(group(clap::ArgGroup::new("what").required(true).multiple(true).args(["file", "commit", "branch", "pull", "issue"])))] | |
| 1040 | + | #[command(group(clap::ArgGroup::new("what").required(true).multiple(true).args(["file", "commit", "branch", "pull", "item"])))] | |
| 1169 | 1041 | pub struct SessionTouchArgs { | |
| 1170 | 1042 | /// A file it wrote, from the repository's root. Repeat for more. | |
| 1171 | 1043 | #[arg(long)] | |
| ⋯ | |||
| 1179 | 1051 | /// A pull request it opened. | |
| 1180 | 1052 | #[arg(long)] | |
| 1181 | 1053 | pub pull: Vec<u64>, | |
| 1182 | − | /// An issue it named. | |
| 1054 | + | /// A work item it named, by its number in the workspace. | |
| 1183 | 1055 | #[arg(long)] | |
| 1184 | − | pub issue: Vec<u64>, | |
| 1056 | + | pub item: Vec<u64>, | |
| 1185 | 1057 | } | |
| 1186 | 1058 | ||
| 1187 | 1059 | #[derive(Debug, Args)] | |
| 1188 | 1060 | pub struct SessionStartArgs { | |
| 1189 | − | /// The issue it works on. | |
| 1061 | + | /// The work item it works on, by its number in the workspace. | |
| 1190 | 1062 | #[arg(short, long)] | |
| 1191 | − | pub issue: Option<u64>, | |
| 1063 | + | pub item: Option<u64>, | |
| 1192 | 1064 | /// The pull request it works on. | |
| 1193 | 1065 | #[arg(short, long)] | |
| 1194 | 1066 | pub pull: Option<u64>, | |
| ⋯ | |||
| 1262 | 1134 | } | |
| 1263 | 1135 | ||
| 1264 | 1136 | #[derive(Debug, Args)] | |
| 1265 | − | #[command(group(clap::ArgGroup::new("what").required(true).multiple(true).args(["issue", "pull", "branch", "head_commit", "title"])))] | |
| 1137 | + | #[command(group(clap::ArgGroup::new("what").required(true).multiple(true).args(["item", "pull", "branch", "head_commit", "title"])))] | |
| 1266 | 1138 | pub struct SessionAttachArgs { | |
| 1139 | + | /// A work item, by its number in the workspace. | |
| 1267 | 1140 | #[arg(short, long)] | |
| 1268 | − | pub issue: Option<u64>, | |
| 1141 | + | pub item: Option<u64>, | |
| 1269 | 1142 | #[arg(short, long)] | |
| 1270 | 1143 | pub pull: Option<u64>, | |
| 1271 | 1144 | #[arg(short, long)] | |
| ⋯ | |||
| 1300 | 1173 | /// Only sessions in this state. | |
| 1301 | 1174 | #[arg(short, long, value_enum)] | |
| 1302 | 1175 | pub state: Option<SessionState>, | |
| 1176 | + | /// Only sessions on this work item. | |
| 1303 | 1177 | #[arg(short, long)] | |
| 1304 | − | pub issue: Option<u64>, | |
| 1178 | + | pub item: Option<u64>, | |
| 1305 | 1179 | #[arg(short, long)] | |
| 1306 | 1180 | pub pull: Option<u64>, | |
| 1307 | 1181 | #[arg(short = 'L', long, default_value_t = 20)] | |
| ⋯ | |||
| 1335 | 1209 | ||
| 1336 | 1210 | // --- work ------------------------------------------------------------- | |
| 1337 | 1211 | ||
| 1212 | + | #[derive(Debug, Args)] | |
| 1213 | + | pub struct WorkArgs { | |
| 1214 | + | /// The workspace, by its slug; the current repository's when left out. | |
| 1215 | + | #[arg(long, global = true, value_name = "SLUG", env = "G1T_WORKSPACE")] | |
| 1216 | + | pub workspace: Option<String>, | |
| 1217 | + | #[command(subcommand)] | |
| 1218 | + | pub command: WorkCommand, | |
| 1219 | + | } | |
| 1220 | + | ||
| 1338 | 1221 | #[derive(Debug, Subcommand)] | |
| 1339 | 1222 | pub enum WorkCommand { | |
| 1340 | − | /// Everything about an issue's work: claims, sessions, pull requests, dependencies, decisions. | |
| 1341 | − | Context(WorkNumber), | |
| 1342 | − | /// Claim an issue: say you are working on it. Others are told, never stopped. | |
| 1343 | − | #[command(after_help = "\nWith --title instead of a number, a new issue is opened and claimed in one step, and the | |
| 1344 | − | current session is attached to it: for work that became a change others should know about. | |
| 1223 | + | /// List the workspace's work items; with --repo, those linked to that repository. | |
| 1224 | + | List(WorkListArgs), | |
| 1225 | + | /// Show a work item with everything about its work: repositories and what landed, claims, | |
| 1226 | + | /// sessions, pull requests, what it waits on, decisions. | |
| 1227 | + | View(WorkViewArgs), | |
| 1228 | + | /// Open a work item, with the current repository as its origin. | |
| 1229 | + | #[command(after_help = "\nIn a repository, the work item is filed from it (its origin). With --workspace and no | |
| 1230 | + | repository of that workspace here, it is filed in the workspace alone. --target names a repository | |
| 1231 | + | where the work is meant to land; repeat it for more. | |
| 1232 | + | Examples: | |
| 1233 | + | g1t work new --title \"Sign-in times out on slow networks\" --body \"...\" | |
| 1234 | + | g1t work new --title \"Rename the flag\" --target acme/api --target acme/docs")] | |
| 1235 | + | New(WorkNewArgs), | |
| 1236 | + | /// Comment on a work item. | |
| 1237 | + | Comment(WorkCommentArgs), | |
| 1238 | + | /// Change a work item's title, body, labels, assignees or milestone. | |
| 1239 | + | Edit(WorkEditArgs), | |
| 1240 | + | /// Close a work item. | |
| 1241 | + | Close(WorkCloseArgs), | |
| 1242 | + | /// Reopen a work item. | |
| 1243 | + | Reopen(ReopenArgs), | |
| 1244 | + | /// Link a repository to a work item: where the work must land (target), or touched. | |
| 1245 | + | #[command(after_help = "\nThe repository is the current one, or --repo OWNER/NAME. A work item with targets closes once it | |
| 1246 | + | has landed in every one. | |
| 1247 | + | Examples: | |
| 1248 | + | g1t work link 12 --repo acme/api | |
| 1249 | + | g1t work link 12 --role touched")] | |
| 1250 | + | Link(WorkLinkArgs), | |
| 1251 | + | /// Unlink a repository from a work item (never its origin). | |
| 1252 | + | Unlink(WorkNumber), | |
| 1253 | + | /// Claim a work item: say you are working on it. Others are told, never stopped. | |
| 1254 | + | #[command(after_help = "\nWith --title instead of a number, a new work item is opened (filed from the current repository) | |
| 1255 | + | and claimed in one step, and the current session is attached to it: for work that became a change | |
| 1256 | + | others should know about. | |
| 1345 | 1257 | Examples: | |
| 1346 | 1258 | g1t work claim 12 --note \"Rewriting the retry loop\" | |
| 1347 | 1259 | g1t work claim --title \"Preview builds time out on large repositories\"")] | |
| 1348 | 1260 | Claim(WorkClaimArgs), | |
| 1349 | − | /// Release your claim on an issue. | |
| 1261 | + | /// Release your claim on a work item. | |
| 1350 | 1262 | Release(WorkReleaseArgs), | |
| 1351 | − | /// Hand an issue over to someone else, or to anyone. | |
| 1263 | + | /// Hand a work item over to someone else, or to anyone. | |
| 1352 | 1264 | Handoff(WorkHandoffArgs), | |
| 1353 | 1265 | /// Active claims and sessions in the repository. | |
| 1354 | − | List, | |
| 1355 | − | /// Say an issue waits on others: it is blocked by them. | |
| 1266 | + | Status, | |
| 1267 | + | /// Say a work item waits on others: it is blocked by them. | |
| 1356 | 1268 | Block(WorkBlockArgs), | |
| 1357 | − | /// Say an issue no longer waits on others. | |
| 1269 | + | /// Say a work item no longer waits on others. | |
| 1358 | 1270 | Unblock(WorkBlockArgs), | |
| 1359 | 1271 | /// The repository's events; --follow keeps printing them as they happen. | |
| 1360 | 1272 | #[command(after_help = "\ | |
| 1361 | 1273 | Examples: | |
| 1362 | − | g1t work events --follow --issue 12 | |
| 1274 | + | g1t work events --follow --item 12 | |
| 1363 | 1275 | g1t work events --follow --type integration.failed --type overlap.detected --json | |
| 1364 | 1276 | With --json, each event is one JSON object on a line of its own.")] | |
| 1365 | 1277 | Events(WorkEventsArgs), | |
| 1366 | − | /// Start work on an issue in a session on your own Claude, or print the Claude Code command for it. | |
| 1278 | + | /// Start work on a work item in a session on your own Claude, or print the Claude Code command for it. | |
| 1367 | 1279 | #[command(after_help = "\nWith the workspace's Anthropic AI provider, a Claude Managed Agents session starts on that | |
| 1368 | 1280 | account and is recorded on g1t; otherwise (or with --handoff) this prints a `claude` command | |
| 1369 | − | to run with g1t's plugin, whose session attaches to the issue as it starts. | |
| 1281 | + | to run with g1t's plugin, whose session attaches to the work item as it starts. | |
| 1370 | 1282 | Examples: | |
| 1371 | 1283 | g1t work dispatch 12 | |
| 1372 | 1284 | g1t work dispatch 12 --mode plan --instruction \"Keep the old flag\" | |
| ⋯ | |||
| 1375 | 1287 | } | |
| 1376 | 1288 | ||
| 1377 | 1289 | #[derive(Clone, Copy, Debug, PartialEq, Eq, ValueEnum)] | |
| 1290 | + | pub enum ItemState { | |
| 1291 | + | Open, | |
| 1292 | + | Closed, | |
| 1293 | + | All, | |
| 1294 | + | } | |
| 1295 | + | ||
| 1296 | + | #[derive(Clone, Copy, Debug, PartialEq, Eq, ValueEnum)] | |
| 1297 | + | pub enum LinkRole { | |
| 1298 | + | Origin, | |
| 1299 | + | Target, | |
| 1300 | + | Touched, | |
| 1301 | + | } | |
| 1302 | + | ||
| 1303 | + | impl LinkRole { | |
| 1304 | + | pub fn name(self) -> &'static str { | |
| 1305 | + | match self { | |
| 1306 | + | LinkRole::Origin => "origin", | |
| 1307 | + | LinkRole::Target => "target", | |
| 1308 | + | LinkRole::Touched => "touched", | |
| 1309 | + | } | |
| 1310 | + | } | |
| 1311 | + | } | |
| 1312 | + | ||
| 1313 | + | /// The roles a repository can be linked in by hand: the origin is where a | |
| 1314 | + | /// work item was filed. | |
| 1315 | + | #[derive(Clone, Copy, Debug, PartialEq, Eq, ValueEnum)] | |
| 1316 | + | pub enum LinkAs { | |
| 1317 | + | Target, | |
| 1318 | + | Touched, | |
| 1319 | + | } | |
| 1320 | + | ||
| 1321 | + | impl LinkAs { | |
| 1322 | + | pub fn name(self) -> &'static str { | |
| 1323 | + | match self { | |
| 1324 | + | LinkAs::Target => "target", | |
| 1325 | + | LinkAs::Touched => "touched", | |
| 1326 | + | } | |
| 1327 | + | } | |
| 1328 | + | } | |
| 1329 | + | ||
| 1330 | + | #[derive(Debug, Args)] | |
| 1331 | + | pub struct WorkListArgs { | |
| 1332 | + | #[arg(short, long, value_enum, default_value_t = ItemState::Open)] | |
| 1333 | + | pub state: ItemState, | |
| 1334 | + | /// Only work items with this label. | |
| 1335 | + | #[arg(short, long)] | |
| 1336 | + | pub label: Option<String>, | |
| 1337 | + | /// Only work items in the workspace milestone of this number. | |
| 1338 | + | #[arg(short, long)] | |
| 1339 | + | pub milestone: Option<u64>, | |
| 1340 | + | /// Only work items assigned to this person (@me for you). | |
| 1341 | + | #[arg(short, long)] | |
| 1342 | + | pub assignee: Option<String>, | |
| 1343 | + | /// Only work items opened by this person (@me for you). | |
| 1344 | + | #[arg(short = 'A', long)] | |
| 1345 | + | pub author: Option<String>, | |
| 1346 | + | /// With --repo: only those linked to it this way. | |
| 1347 | + | #[arg(long, value_enum)] | |
| 1348 | + | pub role: Option<LinkRole>, | |
| 1349 | + | #[arg(short = 'L', long, default_value_t = 20)] | |
| 1350 | + | pub limit: usize, | |
| 1351 | + | } | |
| 1352 | + | ||
| 1353 | + | #[derive(Debug, Args)] | |
| 1354 | + | pub struct WorkViewArgs { | |
| 1355 | + | /// The work item's number. | |
| 1356 | + | pub number: u64, | |
| 1357 | + | /// Show its comments too. | |
| 1358 | + | #[arg(short, long)] | |
| 1359 | + | pub comments: bool, | |
| 1360 | + | /// Open it in the browser. | |
| 1361 | + | #[arg(short, long)] | |
| 1362 | + | pub web: bool, | |
| 1363 | + | } | |
| 1364 | + | ||
| 1365 | + | #[derive(Debug, Args)] | |
| 1366 | + | pub struct WorkNewArgs { | |
| 1367 | + | #[arg(short, long)] | |
| 1368 | + | pub title: Option<String>, | |
| 1369 | + | #[command(flatten)] | |
| 1370 | + | pub body: BodyArgs, | |
| 1371 | + | /// An image to show after the text (PNG, JPEG, GIF or WebP, at most 10 MB): uploaded, and its Markdown added. Repeat for more. | |
| 1372 | + | #[arg(long, value_name = "FILE")] | |
| 1373 | + | pub attach: Vec<PathBuf>, | |
| 1374 | + | /// A repository of the workspace where the work is meant to land, OWNER/NAME; repeat for more. | |
| 1375 | + | #[arg(long, value_name = "OWNER/NAME")] | |
| 1376 | + | pub target: Vec<String>, | |
| 1377 | + | /// A label; repeat for more. | |
| 1378 | + | #[arg(short, long)] | |
| 1379 | + | pub label: Vec<String>, | |
| 1380 | + | /// Someone to assign; repeat for more (@me for you). | |
| 1381 | + | #[arg(short, long)] | |
| 1382 | + | pub assignee: Vec<String>, | |
| 1383 | + | /// A workspace milestone's number. | |
| 1384 | + | #[arg(short, long)] | |
| 1385 | + | pub milestone: Option<u64>, | |
| 1386 | + | /// Open the new work item page in the browser instead. | |
| 1387 | + | #[arg(short, long)] | |
| 1388 | + | pub web: bool, | |
| 1389 | + | } | |
| 1390 | + | ||
| 1391 | + | #[derive(Debug, Args)] | |
| 1392 | + | pub struct WorkCommentArgs { | |
| 1393 | + | /// The work item's number. | |
| 1394 | + | pub number: u64, | |
| 1395 | + | #[command(flatten)] | |
| 1396 | + | pub body: BodyArgs, | |
| 1397 | + | /// An image to show after the text (PNG, JPEG, GIF or WebP, at most 10 MB): uploaded, and its Markdown added. Repeat for more. | |
| 1398 | + | #[arg(long, value_name = "FILE")] | |
| 1399 | + | pub attach: Vec<PathBuf>, | |
| 1400 | + | } | |
| 1401 | + | ||
| 1402 | + | #[derive(Clone, Copy, Debug, PartialEq, Eq, ValueEnum)] | |
| 1403 | + | pub enum CloseReason { | |
| 1404 | + | Completed, | |
| 1405 | + | // Spelled as the API spells it. | |
| 1406 | + | #[value(name = "not_planned", alias = "not-planned")] | |
| 1407 | + | NotPlanned, | |
| 1408 | + | } | |
| 1409 | + | ||
| 1410 | + | #[derive(Debug, Args)] | |
| 1411 | + | pub struct WorkCloseArgs { | |
| 1412 | + | pub number: u64, | |
| 1413 | + | #[arg(short, long, value_enum)] | |
| 1414 | + | pub reason: Option<CloseReason>, | |
| 1415 | + | /// Leave a comment as it closes. | |
| 1416 | + | #[arg(short, long)] | |
| 1417 | + | pub comment: Option<String>, | |
| 1418 | + | /// The commit on the repository's default branch that did it: its message names the work item | |
| 1419 | + | /// after a closing keyword (Fixes #12). Its full hash. It lands there; the work item closes when | |
| 1420 | + | /// nothing else is left to land. | |
| 1421 | + | #[arg(long)] | |
| 1422 | + | pub commit: Option<String>, | |
| 1423 | + | } | |
| 1424 | + | ||
| 1425 | + | #[derive(Debug, Args)] | |
| 1426 | + | pub struct WorkEditArgs { | |
| 1427 | + | pub number: u64, | |
| 1428 | + | #[arg(short, long)] | |
| 1429 | + | pub title: Option<String>, | |
| 1430 | + | #[command(flatten)] | |
| 1431 | + | pub body: BodyArgs, | |
| 1432 | + | #[arg(long, value_name = "LABEL")] | |
| 1433 | + | pub add_label: Vec<String>, | |
| 1434 | + | #[arg(long, value_name = "LABEL")] | |
| 1435 | + | pub remove_label: Vec<String>, | |
| 1436 | + | #[arg(long, value_name = "LOGIN")] | |
| 1437 | + | pub add_assignee: Vec<String>, | |
| 1438 | + | #[arg(long, value_name = "LOGIN")] | |
| 1439 | + | pub remove_assignee: Vec<String>, | |
| 1440 | + | /// A workspace milestone's number. | |
| 1441 | + | #[arg(short, long)] | |
| 1442 | + | pub milestone: Option<u64>, | |
| 1443 | + | /// Take it out of its milestone. | |
| 1444 | + | #[arg(long, conflicts_with = "milestone")] | |
| 1445 | + | pub remove_milestone: bool, | |
| 1446 | + | } | |
| 1447 | + | ||
| 1448 | + | #[derive(Debug, Args)] | |
| 1449 | + | pub struct WorkLinkArgs { | |
| 1450 | + | /// The work item's number. | |
| 1451 | + | pub number: u64, | |
| 1452 | + | /// How the repository is linked. | |
| 1453 | + | #[arg(long, value_enum, default_value_t = LinkAs::Target)] | |
| 1454 | + | pub role: LinkAs, | |
| 1455 | + | } | |
| 1456 | + | ||
| 1457 | + | #[derive(Clone, Copy, Debug, PartialEq, Eq, ValueEnum)] | |
| 1378 | 1458 | pub enum DispatchMode { | |
| 1379 | 1459 | Plan, | |
| 1380 | 1460 | Implement, | |
| ⋯ | |||
| 1394 | 1474 | #[derive(Debug, Args)] | |
| 1395 | 1475 | #[command(group(clap::ArgGroup::new("which").required(true).args(["number", "title"])))] | |
| 1396 | 1476 | pub struct WorkDispatchArgs { | |
| 1397 | − | /// The issue's number. | |
| 1477 | + | /// The work item's number. | |
| 1398 | 1478 | pub number: Option<u64>, | |
| 1399 | − | /// Open a new issue with this title and work on it. | |
| 1479 | + | /// Open a new work item with this title and work on it. | |
| 1400 | 1480 | #[arg(long, conflicts_with = "number")] | |
| 1401 | 1481 | pub title: Option<String>, | |
| 1402 | − | /// The new issue's description. | |
| 1482 | + | /// The new work item's description. | |
| 1403 | 1483 | #[arg(long, requires = "title")] | |
| 1404 | 1484 | pub body: Option<String>, | |
| 1405 | − | /// What to do beyond what the issue says. | |
| 1485 | + | /// What to do beyond what the work item says. | |
| 1406 | 1486 | #[arg(short, long)] | |
| 1407 | 1487 | pub instruction: Option<String>, | |
| 1408 | 1488 | /// What kind of work. | |
| ⋯ | |||
| 1418 | 1498 | ||
| 1419 | 1499 | #[derive(Debug, Args)] | |
| 1420 | 1500 | pub struct WorkNumber { | |
| 1421 | − | /// The issue's number. | |
| 1501 | + | /// The work item's number. | |
| 1422 | 1502 | pub number: u64, | |
| 1423 | 1503 | } | |
| 1424 | 1504 | ||
| 1425 | 1505 | #[derive(Debug, Args)] | |
| 1426 | 1506 | #[command(group(clap::ArgGroup::new("which").required(true).args(["number", "title"])))] | |
| 1427 | 1507 | pub struct WorkClaimArgs { | |
| 1428 | − | /// The issue's number. | |
| 1508 | + | /// The work item's number. | |
| 1429 | 1509 | pub number: Option<u64>, | |
| 1430 | − | /// Open a new issue with this title and claim it; the current session is attached to it. | |
| 1510 | + | /// Open a new work item with this title and claim it; the current session is attached to it. | |
| 1431 | 1511 | #[arg(long, conflicts_with = "number")] | |
| 1432 | 1512 | pub title: Option<String>, | |
| 1433 | − | /// The new issue's description. | |
| 1513 | + | /// The new work item's description. | |
| 1434 | 1514 | #[arg(long, requires = "title")] | |
| 1435 | 1515 | pub body: Option<String>, | |
| 1436 | 1516 | /// What you are doing about it. | |
| ⋯ | |||
| 1462 | 1542 | ||
| 1463 | 1543 | #[derive(Debug, Args)] | |
| 1464 | 1544 | pub struct WorkBlockArgs { | |
| 1465 | − | /// The issue that waits. | |
| 1545 | + | /// The work item that waits. | |
| 1466 | 1546 | pub number: u64, | |
| 1467 | − | /// The issue it waits on; repeat for more. | |
| 1547 | + | /// The work item it waits on; repeat for more. | |
| 1468 | 1548 | #[arg(long = "by", value_name = "NUMBER", required = true)] | |
| 1469 | 1549 | pub by: Vec<u64>, | |
| 1470 | 1550 | } | |
| ⋯ | |||
| 1477 | 1557 | /// Only events of this type; repeat for more. | |
| 1478 | 1558 | #[arg(short = 't', long = "type", value_name = "TYPE")] | |
| 1479 | 1559 | pub types: Vec<String>, | |
| 1480 | − | /// Only events about this issue or pull request; repeat for more. | |
| 1481 | − | #[arg(short, long = "issue", value_name = "NUMBER")] | |
| 1482 | − | pub issues: Vec<u64>, | |
| 1560 | + | /// Only events about this work item or pull request; repeat for more. | |
| 1561 | + | #[arg(short = 'i', long = "item", value_name = "NUMBER")] | |
| 1562 | + | pub items: Vec<u64>, | |
| 1483 | 1563 | /// Only events since then: 15m, 2h, 1d, or a time like 2026-10-12T09:00:00Z. | |
| 1484 | 1564 | #[arg(short, long)] | |
| 1485 | 1565 | pub since: Option<String>, | |
| ⋯ | |||
| 1515 | 1595 | Prints each image's Markdown, , to paste into a description or a comment; --json prints | |
| 1516 | 1596 | { id, name, url, markdown, content_type, size } (a list for several files). The image is served from | |
| 1517 | 1597 | g1t's usercontent address, and anyone given that address can see it, even from a private repository. | |
| 1518 | − | --attach FILE on g1t issue create, g1t issue comment, g1t pr create, g1t pr comment and g1t pr ready | |
| 1598 | + | --attach FILE on g1t work new, g1t work comment, g1t pr create, g1t pr comment and g1t pr ready | |
| 1519 | 1599 | uploads and adds the Markdown for you: | |
| 1520 | 1600 | g1t attach preview.png | |
| 1521 | 1601 | g1t pr comment --body 'The preview, after the fix:' --attach preview.png")] | |
| ⋯ | |||
| 1543 | 1623 | ||
| 1544 | 1624 | #[derive(Debug, Args)] | |
| 1545 | 1625 | #[command(after_help = "\ | |
| 1546 | − | ENDPOINT is an operation's name (list_issues) or a path (/repos/{owner}/{name}/issues). | |
| 1626 | + | ENDPOINT is an operation's name (list_work_items) or a path (/workspaces/{workspace}/work). | |
| 1547 | 1627 | {owner}, {name}, {repo} and {workspace} are filled in from the current repository, | |
| 1548 | 1628 | and an operation's other path parameters from -f/-F fields of the same name. | |
| 1549 | 1629 | ||
| 1550 | 1630 | Examples: | |
| 1551 | − | g1t api list_issues -f state=closed | |
| 1631 | + | g1t api list_work_items -f state=closed | |
| 1552 | 1632 | g1t api /user --jq .username | |
| 1553 | − | g1t api create_issue -f title='Broken link' -f labels[]=docs | |
| 1633 | + | g1t api open_work_item -f title='Broken link' -f labels[]=docs | |
| 1554 | 1634 | g1t api list_workflow_runs --paginate --jq '.[].conclusion' | |
| 1555 | − | g1t api --list issue")] | |
| 1635 | + | g1t api --list work")] | |
| 1556 | 1636 | pub struct ApiArgs { | |
| 1557 | 1637 | /// An operation's name, or a path. | |
| 1558 | 1638 | pub endpoint: Option<String>, | |
| ⋯ | |||
| 1590 | 1670 | ||
| 1591 | 1671 | #[derive(Debug, Args)] | |
| 1592 | 1672 | pub struct BrowseArgs { | |
| 1593 | − | /// An issue or pull request number, a file path (path:line), or a commit. | |
| 1673 | + | /// A work item or pull request number, a file path (path:line), or a commit. | |
| 1594 | 1674 | pub target: Option<String>, | |
| 1595 | 1675 | /// The branch to show files on. | |
| 1596 | 1676 | #[arg(short, long)] | |
| 1597 | 1677 | pub branch: Option<String>, | |
| 1598 | 1678 | #[arg(short, long)] | |
| 1599 | 1679 | pub settings: bool, | |
| 1680 | + | /// The repository's work items: the workspace's Work list, filtered to it. | |
| 1600 | 1681 | #[arg(long)] | |
| 1601 | − | pub issues: bool, | |
| 1682 | + | pub work: bool, | |
| 1602 | 1683 | #[arg(long)] | |
| 1603 | 1684 | pub pulls: bool, | |
| 1604 | 1685 | #[arg(long)] | |
| ⋯ | |||
| 1792 | 1873 | } | |
| 1793 | 1874 | } | |
| 1794 | 1875 | ||
| 1795 | − | /// `work claim` takes an issue's number, or a title for a new one, never both. | |
| 1876 | + | /// `work claim` takes a work item's number, or a title for a new one, never both. | |
| 1796 | 1877 | #[test] | |
| 1797 | − | fn a_claim_names_an_issue_or_a_title_for_a_new_one() { | |
| 1878 | + | fn a_claim_names_a_work_item_or_a_title_for_a_new_one() { | |
| 1798 | 1879 | let claim = |argv: &[&str]| { | |
| 1799 | 1880 | let mut all = vec!["g1t", "work", "claim"]; | |
| 1800 | 1881 | all.extend_from_slice(argv); | |
| 1801 | 1882 | Cli::try_parse_from(all).map(|cli| match cli.command { | |
| 1802 | − | super::Command::Work(super::WorkCommand::Claim(args)) => args, | |
| 1883 | + | super::Command::Work(super::WorkArgs { command: super::WorkCommand::Claim(args), .. }) => args, | |
| 1803 | 1884 | _ => panic!("not work claim"), | |
| 1804 | 1885 | }) | |
| 1805 | 1886 | }; | |
| ⋯ | |||
| 1834 | 1915 | assert!(Cli::try_parse_from(["g1t", "session", "acknowledge", "--note", "No IDs"]).is_err()); | |
| 1835 | 1916 | } | |
| 1836 | 1917 | ||
| 1918 | + | ||
| 1919 | + | #[test] | |
| 1920 | + | fn work_items_take_a_workspace_and_there_is_no_issue_command() { | |
| 1921 | + | let cli = Cli::try_parse_from(["g1t", "work", "list", "--workspace", "acme", "--label", "bug"]).unwrap(); | |
| 1922 | + | let super::Command::Work(work) = cli.command else { panic!("not work") }; | |
| 1923 | + | assert_eq!(work.workspace.as_deref(), Some("acme")); | |
| 1924 | + | assert!(Cli::try_parse_from(["g1t", "work", "view", "12", "--workspace", "acme"]).is_ok()); | |
| 1925 | + | assert!(Cli::try_parse_from(["g1t", "work", "link", "12", "--role", "touched", "-R", "acme/api"]).is_ok()); | |
| 1926 | + | assert!(Cli::try_parse_from(["g1t", "work", "link", "12", "--role", "origin"]).is_err()); | |
| 1927 | + | assert!(Cli::try_parse_from(["g1t", "work", "close", "12", "--commit", "9f2c4e1"]).is_ok()); | |
| 1928 | + | assert!(Cli::try_parse_from(["g1t", "work", "events", "-i", "12"]).is_ok()); | |
| 1929 | + | assert!(Cli::try_parse_from(["g1t", "pr", "create", "--item", "12"]).is_ok()); | |
| 1930 | + | assert!(Cli::try_parse_from(["g1t", "issue", "list"]).is_err()); | |
| 1931 | + | assert!(Cli::try_parse_from(["g1t", "pr", "create", "--issue", "12"]).is_err()); | |
| 1932 | + | } | |
| 1837 | 1933 | } | |
| 354 | 354 | owner: "acme".into(), | |
| 355 | 355 | name: "web".into(), | |
| 356 | 356 | }; | |
| 357 | − | let call = client.op("get_issue").repo(&repo).arg("number", 12); | |
| 358 | − | assert_eq!(call.path(), "/repos/acme/web/issues/12"); | |
| 357 | + | let call = client.op("get_pull_request").repo(&repo).arg("number", 12); | |
| 358 | + | assert_eq!(call.path(), "/repos/acme/web/pulls/12"); | |
| 359 | + | let call = client.op("get_work_item").arg("workspace", "acme").arg("number", 12); | |
| 360 | + | assert_eq!(call.path(), "/workspaces/acme/work/12"); | |
| 359 | 361 | } | |
| 360 | 362 | } |
| 192 | 192 | fn words_split_like_a_shell() { | |
| 193 | 193 | assert_eq!(split("pr checkout").unwrap(), v(&["pr", "checkout"])); | |
| 194 | 194 | assert_eq!( | |
| 195 | − | split(r#"issue list --label "good first issue""#).unwrap(), | |
| 196 | − | v(&["issue", "list", "--label", "good first issue"]) | |
| 195 | + | split(r#"work list --label "good first issue""#).unwrap(), | |
| 196 | + | v(&["work", "list", "--label", "good first issue"]) | |
| 197 | 197 | ); | |
| 198 | 198 | assert_eq!( | |
| 199 | 199 | split("api '/repos/{owner}/{name}'").unwrap(), | |
| ⋯ | |||
| 212 | 212 | ); | |
| 213 | 213 | assert_eq!( | |
| 214 | 214 | substitute( | |
| 215 | − | &v(&["issue", "list", "--label", "$1"]), | |
| 215 | + | &v(&["work", "list", "--label", "$1"]), | |
| 216 | 216 | &v(&["bug", "-L", "5"]) | |
| 217 | 217 | ), | |
| 218 | − | v(&["issue", "list", "--label", "bug", "-L", "5"]) | |
| 218 | + | v(&["work", "list", "--label", "bug", "-L", "5"]) | |
| 219 | 219 | ); | |
| 220 | 220 | } | |
| 221 | 221 | ||
| 526 | 526 | ||
| 527 | 527 | #[test] | |
| 528 | 528 | fn operations_fill_their_paths_from_the_repository() { | |
| 529 | − | let op = ops::get("list_issues"); | |
| 529 | + | let op = ops::get("list_repo_work_items"); | |
| 530 | 530 | let mut given = Map::new(); | |
| 531 | 531 | given.insert("state".into(), json!("closed")); | |
| 532 | 532 | let plan = plan_op(op, None, given, &repo).unwrap(); | |
| ⋯ | |||
| 534 | 534 | plan, | |
| 535 | 535 | Plan { | |
| 536 | 536 | method: "GET".into(), | |
| 537 | − | path: "/repos/acme/web/issues".into(), | |
| 537 | + | path: "/repos/acme/web/work".into(), | |
| 538 | 538 | query: vec![("state".into(), "closed".into())], | |
| 539 | 539 | body: None | |
| 540 | 540 | } | |
| 541 | 541 | ); | |
| 542 | + | // A workspace's operations take the repository's. | |
| 543 | + | let plan = plan_op(ops::get("list_work_items"), None, Map::new(), &repo).unwrap(); | |
| 544 | + | assert_eq!(plan.path, "/workspaces/acme/work"); | |
| 542 | 545 | ||
| 543 | − | let op = ops::get("create_issue"); | |
| 546 | + | let op = ops::get("open_work_item"); | |
| 544 | 547 | let mut given = Map::new(); | |
| 545 | 548 | given.insert("title".into(), json!("Broken")); | |
| 546 | 549 | let plan = plan_op(op, None, given, &repo).unwrap(); | |
| 547 | 550 | assert_eq!(plan.method, "POST"); | |
| 548 | 551 | assert_eq!(plan.body, Some(json!({ "title": "Broken" }))); | |
| 549 | 552 | ||
| 550 | − | let op = ops::get("get_issue"); | |
| 553 | + | let op = ops::get("get_work_item"); | |
| 551 | 554 | let err = plan_op(op, None, Map::new(), &repo).unwrap_err(); | |
| 552 | 555 | assert!(err.message.contains("number"), "{}", err.message); | |
| 553 | − | let err = plan_op(ops::get("list_issues"), None, Map::new(), &no_repo).unwrap_err(); | |
| 556 | + | let err = plan_op(ops::get("list_repo_work_items"), None, Map::new(), &no_repo).unwrap_err(); | |
| 554 | 557 | assert_eq!(err.kind, Kind::Usage); | |
| 555 | 558 | } | |
| 556 | 559 | ||
| 557 | 560 | #[test] | |
| 558 | 561 | fn paths_fill_placeholders() { | |
| 559 | − | let plan = plan_path("repos/{owner}/{repo}/issues", None, Map::new(), &repo).unwrap(); | |
| 560 | − | assert_eq!(plan.path, "/repos/acme/web/issues"); | |
| 562 | + | let plan = plan_path("repos/{owner}/{repo}/work", None, Map::new(), &repo).unwrap(); | |
| 563 | + | assert_eq!(plan.path, "/repos/acme/web/work"); | |
| 561 | 564 | assert_eq!(plan.method, "GET"); | |
| 562 | 565 | let mut given = Map::new(); | |
| 563 | 566 | given.insert("title".into(), json!("x")); | |
| 564 | − | let plan = plan_path("/repos/acme/web/issues", None, given, &no_repo).unwrap(); | |
| 567 | + | let plan = plan_path("/workspaces/acme/work", None, given, &no_repo).unwrap(); | |
| 565 | 568 | assert_eq!(plan.method, "POST"); | |
| 566 | 569 | assert_eq!(plan.body, Some(json!({ "title": "x" }))); | |
| 567 | 570 | } | |
| 1 | − | //! `g1t attach FILE...`: upload images to show in an issue, a pull request | |
| 1 | + | //! `g1t attach FILE...`: upload images to show in a work item, a pull request | |
| 2 | 2 | //! or a comment, and print the Markdown that shows each. `--attach FILE` | |
| 3 | − | //! on `g1t issue create`, `g1t issue comment`, `g1t pr create`, `g1t pr | |
| 3 | + | //! on `g1t work new`, `g1t work comment`, `g1t pr create`, `g1t pr | |
| 4 | 4 | //! comment` and `g1t pr ready` does the same and adds the Markdown to the | |
| 5 | 5 | //! text ([`with_attachments`]). An agent shows a screenshot of its preview | |
| 6 | 6 | //! this way, instead of committing the image to the repository. |
| 3 | 3 | use crate::cli::BrowseArgs; | |
| 4 | 4 | use crate::context::Ctx; | |
| 5 | 5 | use crate::error::Result; | |
| 6 | + | use crate::output::s; | |
| 6 | 7 | use crate::repo::Repo; | |
| 7 | 8 | ||
| 8 | 9 | /// Opens `url` in the browser at a terminal; prints it otherwise. | |
| ⋯ | |||
| 21 | 22 | if args.settings { | |
| 22 | 23 | return format!("{base}/settings"); | |
| 23 | 24 | } | |
| 24 | − | if args.issues { | |
| 25 | − | return format!("{base}/issues"); | |
| 25 | + | if args.work { | |
| 26 | + | return format!("{site}/{}/-/work?repo={}", repo.owner, repo.name); | |
| 26 | 27 | } | |
| 27 | 28 | if args.pulls { | |
| 28 | 29 | return format!("{base}/pulls"); | |
| ⋯ | |||
| 38 | 39 | }; | |
| 39 | 40 | let target = target.trim_start_matches('#'); | |
| 40 | 41 | if target.chars().all(|c| c.is_ascii_digit()) { | |
| 41 | − | // Issues and pull requests share numbers; the issue page sends a | |
| 42 | − | // pull request's number on to it. | |
| 43 | − | return format!("{base}/issues/{target}"); | |
| 42 | + | // What the number names is found first (`run`); this is a pull | |
| 43 | + | // request of the repository. | |
| 44 | + | return format!("{base}/pull/{target}"); | |
| 44 | 45 | } | |
| 45 | 46 | if target.len() >= 7 | |
| 46 | 47 | && target.len() <= 40 | |
| ⋯ | |||
| 74 | 75 | } else { | |
| 75 | 76 | None | |
| 76 | 77 | }; | |
| 77 | − | let url = address(&client.host.site, &repo, &args, branch.as_deref()); | |
| 78 | + | let mut url = address(&client.host.site, &repo, &args, branch.as_deref()); | |
| 79 | + | // `#N` here: a pull request of the repository, or a work item of its | |
| 80 | + | // workspace (an old issue number of the repository included). | |
| 81 | + | if let Some(number) = args.target.as_deref().map(|t| t.trim_start_matches('#')).filter(|t| !t.is_empty() && t.chars().all(|c| c.is_ascii_digit())) | |
| 82 | + | && let Ok(found) = client.op("resolve_ref").repo(&repo).arg("number", number).send() | |
| 83 | + | { | |
| 84 | + | url = match found["kind"].as_str() { | |
| 85 | + | Some("work_item") => format!("{}/{}/-/work/{}", client.host.site, s(&found, "workspace"), found["number"]), | |
| 86 | + | Some("pull") => format!("{}/{}/pull/{}", client.host.site, s(&found, "repo"), found["number"]), | |
| 87 | + | _ => url, | |
| 88 | + | }; | |
| 89 | + | } | |
| 78 | 90 | if args.no_browser { | |
| 79 | 91 | println!("{url}"); | |
| 80 | 92 | return Ok(()); | |
| ⋯ | |||
| 91 | 103 | target: target.map(str::to_owned), | |
| 92 | 104 | branch: None, | |
| 93 | 105 | settings: false, | |
| 94 | − | issues: false, | |
| 106 | + | work: false, | |
| 95 | 107 | pulls: false, | |
| 96 | 108 | actions: false, | |
| 97 | 109 | no_browser: true, | |
| ⋯ | |||
| 112 | 124 | ); | |
| 113 | 125 | assert_eq!( | |
| 114 | 126 | address(site, &repo, &args(Some("12")), None), | |
| 115 | − | "https://g1t.sh/acme/web/issues/12" | |
| 127 | + | "https://g1t.sh/acme/web/pull/12" | |
| 116 | 128 | ); | |
| 117 | 129 | assert_eq!( | |
| 118 | 130 | address(site, &repo, &args(Some("src/main.rs:41")), Some("dev")), | |
| ⋯ | |||
| 122 | 134 | address(site, &repo, &args(Some("9f2c4e1")), None), | |
| 123 | 135 | "https://g1t.sh/acme/web/commit/9f2c4e1" | |
| 124 | 136 | ); | |
| 137 | + | let mut work = args(None); | |
| 138 | + | work.work = true; | |
| 139 | + | assert_eq!(address(site, &repo, &work, None), "https://g1t.sh/acme/-/work?repo=web"); | |
| 125 | 140 | let mut settings = args(None); | |
| 126 | 141 | settings.settings = true; | |
| 127 | 142 | assert_eq!( | |
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…
A large diff (1,417 lines) is not shown until you ask for it.
Loading the diff…
Comments
Sign in to comment.