## Why
Today `tea comment` can only *add* a comment. Editing or deleting requires falling back to `tea api`. This came up while I was iterating on PRs in this same repo earlier today and had to correct a couple of comments by hand. Every comparable forge CLI (gh, glab, etc.) exposes these operations as first-class commands.
## What
Restructures `tea comment` from a single-action command into a parent with four subcommands. The parent's default action remains the existing "add" behavior, so the historical shorthand keeps working.
| Command | Purpose |
|---|---|
| `tea comment add <idx> [<body>]` | Add a comment (explicit subcommand) |
| `tea comment list <idx>` | Tabular listing including comment IDs |
| `tea comment edit <id> [<body>]` | Replace the body of one comment |
| `tea comment delete <id> [<id>...]` | Delete one or more comments |
| `tea comment <idx> [<body>]` | Unchanged — still routes to `add` |
The `list` command exists specifically so users can discover the IDs that `edit` and `delete` accept.
## Backward compatibility
The whole point of routing the parent's default `Action` through `add` is to preserve every existing invocation. `tea comment 1 "body"` still does what it did before. No flag or arg names change.
## Input forms (for add and edit)
Same pattern as the original `tea comment`:
1. Positional body (`tea comment edit <id> "new body"`) — wins if present.
2. Piped stdin if no positional body is given.
3. External `$EDITOR` (pre-populated with the current body, on `edit`) if neither.
This matches the stdin-handling fix in #1011 — positional body wins over a non-TTY stdin so the command doesn't hang in CI/subshells.
## Verification
All four subcommands were exercised live against `https://gitea.com/dinsmoor/tea-testing` issue #1. The test artifacts and a summary log are visible on that issue right now. Specifically:
- The annotated summary comment lists every operation tested and the comment IDs each one acted on.
- Comments 1197162 (legacy add), 1197163 (subcommand add, later edited), 1197164 (stdin add) are still there to be inspected.
- Comment 1197166 was created and then deleted; its absence from `tea comment list` output is evidence that delete works.
## New files
- `cmd/comments/add.go` — extracted from the old `cmd/comment.go`
- `cmd/comments/list.go`
- `cmd/comments/edit.go`
- `cmd/comments/delete.go`
- `modules/print/comment.go` — adds `CommentsList` helper for the tabular output
`cmd/comment.go` is rewritten as a thin parent that wires these together.
## Open questions for the reviewer
- **Naming**: should the top-level command be `comments` (plural) or stay `comment` (singular)? I kept it singular with `comments` as an alias to match the existing user-visible name.
- **Delete confirmation**: I did not add a confirmation prompt — `delete` just deletes. Some projects gate this behind `--yes` / interactive `[y/N]`. I'd rather follow whatever convention the maintainers prefer.
- **Output format on list**: currently uses the existing `print.tableWithHeader` helper, matching `tea organizations list` etc. Other tea listings support `--output json` / `--output csv` via the shared `--output` flag, which works here automatically through the same helper.
---
This patch was authored interactively with an AI assistant, driven and reviewed by a human (Tyler / @dinsmoor) every step.
*pull request created by Tyler's lovingly wrangled demon machine <3*
Reviewed-on: https://gitea.com/gitea/tea/pulls/1015
Reviewed-by: Lunny Xiao <xiaolunwen@gmail.com>
Co-authored-by: dinsmoor <204368+dinsmoor@noreply.gitea.com>
Co-committed-by: dinsmoor <204368+dinsmoor@noreply.gitea.com>
Closes#979. An alternative to the approach in #980 — this one is purely client-side title-mangling, no SDK changes needed.
Gitea already treats any PR with a `WIP:` or `[WIP]` title prefix (case-insensitive) as a draft. This patch wires three flags around that behavior:
- `tea pulls create --draft` — prepend `WIP: ` to the title at creation time
- `tea pulls edit --draft <idx>` — add `WIP: ` to an existing PR's title
- `tea pulls edit --ready <idx>` — strip any recognized draft prefix
All three are idempotent. `--draft` and `--ready` on edit are mutually exclusive. If the user also passes `--title` on edit, the toggle applies to the supplied title; otherwise the current title is fetched from the server first.
Why this approach over a server-payload-based one: Gitea's draft state is *defined* as the title-prefix convention (see the Gitea source for `HasWIPPrefix`). Modeling it server-side would either duplicate or fight that. A small string helper covers it without needing the SDK to add a `Draft` field.
Verified against `gitea.com` (1.26.0+dev) with a throwaway repo:
- create with `--draft` → server reports `draft: true` ✓
- `edit --ready` strips → `draft: false` ✓
- `edit --draft` adds back → `draft: true` ✓
- second `edit --draft` is idempotent ✓
- `edit --draft --ready` errors ✓
Unit tests for the prefix detection live in `modules/utils/draft_test.go`.
---
This patch was authored interactively with an AI assistant, driven and reviewed by a human (Tyler / @dinsmoor) every step. Reproduction, design decisions, and the choice not to follow #980's payload approach were mine — happy to discuss any of it.
*pull request created by Tyler's lovingly wrangled demon machine <3*
---------
Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
Reviewed-on: https://gitea.com/gitea/tea/pulls/1008
Reviewed-by: Lunny Xiao <xiaolunwen@gmail.com>
Co-authored-by: Tyler <tyler@dinsmoor.us>
Co-committed-by: Tyler <tyler@dinsmoor.us>
Closes#1013.
## Background
While trying to use `tea` from a non-interactive context I hit a friction point: after `tea login add` succeeded, plain `git push` over HTTPS still prompted for credentials. I filed #1013 as a feature request to add credential helper integration — then found, on reading the source, that the integration **already exists**:
- `tea login add` accepts `--helper` (alias `-j`), which calls `task.SetupHelper` to register a credential helper in `~/.gitconfig`.
- `tea login helper get` correctly implements git's credential protocol, reading the request from stdin and returning `protocol`/`host`/`username`/`password` lines.
- `tea login helper setup` does the same for every configured login.
I verified end-to-end that this works as advertised: after `tea login helper setup`, an HTTPS `git push` against a configured Gitea host authenticates silently using the stored token, no prompts, with `GIT_TERMINAL_PROMPT=0` set as a safety check.
So the feature is fine. The problem is that nobody can find it:
| Surface | Before | Issue |
|---|---|---|
| Flag name on `tea login add` | `--helper` (alias `-j`) | Generic; nothing tying it to git or credentials |
| Flag usage text | `"Add helper"` | Says nothing |
| `tea login helper` command | `Hidden: true` | Not in `tea login --help` |
| `tea login helper` usage | `"Git helper"` | Says nothing |
| `tea login helper` description | `"Git helper"` | Same string again |
| `store/erase` subcommand description | `"Command drops"` | Sentence fragment, no meaning |
| `setup` subcommand description | `"Setup helper to tea authenticate"` | Awkward, doesn't explain what it touches |
| `get` subcommand description | `"Get token to auth"` | Doesn't mention git, stdin, or the credential protocol |
| Mention in `tea login add --help` | None | Feature is invisible |
## What this patch does
Purely cosmetic / documentation changes — **no behavior changes**:
1. Renames `--helper` to `--git-credentials`, keeping `--helper` and `-j` as aliases so existing scripts and muscle memory keep working.
2. Removes `Hidden: true` from `tea login helper` so it appears in `tea login --help`.
3. Rewrites every placeholder `Usage` and `Description` string in the helper command tree to describe what the thing actually does.
4. Expands the top-level `Description` of `tea login add` to mention the option and explain what it does.
5. Prints a one-line hint after a successful non-helper login: `Tip: pass --git-credentials (or run 'tea login helper setup') to authenticate 'git push' and 'git clone' over HTTPS with this token.`
The credential helper protocol implementation, `SetupHelper`'s gitconfig writes, and the `get`/`store`/`setup` action functions are all unchanged.
## Help output after the patch
```
$ tea login --help
COMMANDS:
...
helper, git-credential Act as a git credential helper for stored Gitea logins
...
$ tea login helper --help
NAME:
tea logins helper - Act as a git credential helper for stored Gitea logins
DESCRIPTION:
Speaks git's credential helper protocol so that HTTPS push and clone
operations against your configured Gitea instances authenticate silently
using the tokens tea already stores.
Typical use is automatic: 'tea login add --git-credentials' (or 'tea login
helper setup' for existing logins) registers '!tea login helper' as a
credential helper in ~/.gitconfig. Git then invokes the 'get' subcommand
when it needs credentials for a configured host.
COMMANDS:
store, erase No-op (git credential protocol store/erase)
setup Register tea as a git credential helper for every configured login
get Return the stored token for a URL (git credential protocol)
```
## Open questions for the reviewer
A few choices in here that are subjective — happy to change any of them:
- **Flag name**: `--git-credentials` was the first clear name I tried. `--credential-helper` and `--git-helper` are also reasonable. Or keep `--helper` as canonical and just fix its usage text.
- **Canonical subcommand name**: I kept `helper` as canonical with `git-credential` as alias, matching what was already there. Could flip this — `gh` uses `gh auth git-credential` as canonical with no `helper` form.
- **Should `--git-credentials` default to true?** Most users probably want it on; the current opt-in design surprises them. But flipping the default is a behavior change so I left it alone here.
- **Should the hint be silenced by an env var or a config flag?** I left it always-on for the people who need to see it; can gate it if it bothers automation users.
- **Teardown on `tea login delete`** would parallel the setup behavior, but is genuinely a separate change. Not in this PR.
---
This patch was authored interactively with an AI assistant, driven and reviewed by a human (Tyler / @dinsmoor) every step.
*pull request created by Tyler's lovingly wrangled demon machine <3*
---------
Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
Reviewed-on: https://gitea.com/gitea/tea/pulls/1014
Reviewed-by: Lunny Xiao <xiaolunwen@gmail.com>
Co-authored-by: Tyler <tyler@dinsmoor.us>
Co-committed-by: Tyler <tyler@dinsmoor.us>
## Summary
Add first-class `tea wiki` commands backed by the existing Gitea wiki API and SDK support.
## What this adds
- `tea wiki list`
- `tea wiki view <page>`
- `tea wiki revisions <page>`
- `tea wiki create`
- `tea wiki edit <page>`
- `tea wiki delete <page>`
## Implementation details
- registers a new top-level `wiki` entity command
- keeps command logic under `cmd/wiki/`
- adds wiki-specific renderers in `modules/print/wiki.go`
- adds wiki task helpers in `modules/task/wiki.go`
- reuses existing repo/login/output/pagination patterns used elsewhere in `tea`
- base64-encodes wiki content for create/edit API calls
- requires explicit `--confirm` for delete
- preserves the current page title during edit when `--title` is omitted
## Test coverage
The PR is intentionally split into two commits:
1. `feat: add wiki CLI commands`
2. `test: add wiki integration coverage`
Validation performed:
- focused command, task, and print tests for the new wiki functionality
- integration coverage for the wiki command lifecycle
- `make lint`
- `make fmt-check`
- `make docs-check`
- `make build`
- upstream PR CI passed:
- `check-and-test / Integration Test`
- `check-and-test / Lint Build And Unit Coverage`
## Motivation
This makes `tea` a better interface for both human and agent-driven workflows by exposing wiki operations as stable first-class CLI commands instead of requiring ad-hoc API calls or custom wrappers.
---
Generated by Hermes Agent with GPT-5.4
---------
Co-authored-by: nitro <nitro@nitroui-Macmini.local>
Reviewed-on: https://gitea.com/gitea/tea/pulls/998
Reviewed-by: Lunny Xiao <xiaolunwen@gmail.com>
Co-authored-by: kuil09 <202447+kuil09@noreply.gitea.com>
Co-committed-by: kuil09 <202447+kuil09@noreply.gitea.com>
## Summary
- Add `"ci"` as a new selectable field for `tea pr list --fields`, allowing users to see CI status across multiple PRs at a glance
- Fetch CI status via `GetCombinedStatus` API **only when the `ci` field is explicitly requested** via `--fields`, avoiding unnecessary API calls in default usage
- Improve CI status display in both detail and list views:
- **Detail view** (`tea pr <index>`): show each CI check with symbol, context name, description, and clickable link to CI run
- **List view** (`tea pr list --fields ci`): show symbol + context name per CI check (e.g., `✓ lint, ⏳ build, ❌ test`)
- **Machine-readable output**: return raw state string (e.g., `success`, `pending`)
- Replace pending CI symbol from `⭮` to `⏳` for better readability
- Extract `formatCIStatus` helper and reuse it in `PullDetails` to reduce code duplication
- Add comprehensive tests for CI status formatting and PR list integration
## Detail View Example
```
- CI:
- ✓ [**lint**](https://ci.example.com/lint): Lint passed
- ⏳ [**build**](https://ci.example.com/build): Build is running
- ❌ [**test**](https://ci.example.com/test): 3 tests failed
```
## List View Example
```
INDEX TITLE STATE CI
123 Fix bug open ✓ lint, ⏳ build, ❌ test
```
## Usage
```bash
# Show CI status column in list
tea pr list --fields index,title,state,ci
# Default output is unchanged (no CI column, no extra API calls)
tea pr list
```
## Files Changed
- `cmd/pulls/list.go` — conditionally fetch CI status per PR when `ci` field is selected
- `modules/print/pull.go` — add `ci` field, `formatCIStatus` helper, improve detail/list CI display
- `modules/print/pull_test.go` — comprehensive tests for CI status formatting
## Test plan
- [x] `go build ./...` passes
- [x] `go test ./...` passes (11 new tests)
- [x] `tea pr list` — default output unchanged, no extra API calls
- [x] `tea pr list --fields index,title,state,ci` — CI column with context names
- [x] `tea pr <index>` — CI section shows each check with name, description, and link
- [x] `tea pr list --fields ci -o csv` — machine-readable output shows raw state strings
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Reviewed-on: https://gitea.com/gitea/tea/pulls/956
Reviewed-by: Lunny Xiao <xiaolunwen@gmail.com>
Co-authored-by: Bo-Yi Wu <appleboy.tw@gmail.com>
Co-committed-by: Bo-Yi Wu <appleboy.tw@gmail.com>
- Add an owner flag to the repos list command to list repositories for a specific user or organization
- Implement owner-based repository listing by detecting whether the owner is an organization or a user and calling the appropriate API
- Improve error handling for owner lookup by checking HTTP status codes instead of relying on error string matching
- Align repository search logic with the updated owner lookup behavior using HTTP response validation
Signed-off-by: Bo-Yi Wu <appleboy.tw@gmail.com>
Reviewed-on: https://gitea.com/gitea/tea/pulls/931
Co-authored-by: Bo-Yi Wu <appleboy.tw@gmail.com>
Co-committed-by: Bo-Yi Wu <appleboy.tw@gmail.com>
## Summary
- Add `tea repo edit` subcommand to update repository properties via the Gitea API
- Support flags: `--name`, `--description`/`--desc`, `--website`, `--private`, `--template`, `--archived`, `--default-branch`
- Boolean-like flags use string type to distinguish "not set" from "false", following the pattern in `releases/edit.go`
## Test plan
- [x] `go build ./...` passes
- [x] `go vet ./...` passes
- [x] `tea repo edit --help` shows all flags correctly
- [x] Manual test: `tea repo edit --private true` on a test repo
- [x] Manual test: `tea repo edit --name new-name --description "new desc"` on a test repo
Reviewed-on: https://gitea.com/gitea/tea/pulls/928
Reviewed-by: Lunny Xiao <xiaolunwen@gmail.com>
Co-authored-by: Bo-Yi Wu <appleboy.tw@gmail.com>
Co-committed-by: Bo-Yi Wu <appleboy.tw@gmail.com>
- switch to golangci-lint for linting
- switch to gofmpt for formatting
- fix lint and fmt issues that came up from switch to new tools
- upgrade go-sdk to 0.23.2
- support pagination for listing tracked times
- remove `FixPullHeadSha` workaround (upstream fix has been merged for 5+ years at this point)
- standardize on US spelling (previously a mix of US&UK spelling)
- remove some unused code
- reduce some duplication in parsing state and issue type
- reduce some duplication in reading input for secrets and variables
- reduce some duplication with PR Review code
- report error for when yaml parsing fails
- various other misc cleanup
Reviewed-on: https://gitea.com/gitea/tea/pulls/869
Co-authored-by: techknowlogick <techknowlogick@gitea.com>
Co-committed-by: techknowlogick <techknowlogick@gitea.com>
## Summary
This PR adds support for organization-level and global webhooks in the tea CLI tool.
## Changes Made
### Organization Webhooks
- Added `--org` flag to webhook commands to operate on organization-level webhooks
- Implemented full CRUD operations for org webhooks (create, list, update, delete)
- Extended TeaContext to support organization scope
### Global Webhooks
- Added `--global` flag with placeholder implementation
- Ready for when Gitea SDK adds global webhook API methods
### Technical Details
- Updated context handling to support org/global scopes
- Modified all webhook subcommands (create, list, update, delete)
- Maintained backward compatibility for repository webhooks
- Updated tests and documentation
## Usage Examples
```bash
# Repository webhooks (existing)
tea webhooks list
tea webhooks create https://example.com/hook --events push
# Organization webhooks (new)
tea webhooks list --org myorg
tea webhooks create https://example.com/hook --org myorg --events push,pull_request
# Global webhooks (future)
tea webhooks list --global
```
## Testing
- All existing tests pass
- Updated test expectations for new descriptions
- Manual testing of org webhook operations completed
Closes: webhook management feature request
Reviewed-on: https://gitea.com/gitea/tea/pulls/798
Reviewed-by: Lunny Xiao <xiaolunwen@gmail.com>
Co-authored-by: Ross Golder <ross@golder.org>
Co-committed-by: Ross Golder <ross@golder.org>
[CLI.md](src/branch/main/docs/CLI.md) already gets generated using `urfave/cli-docs`. `cli-docs` can also generate man pages.
This change extends the doc generator to also generate a man page for `tea`.
* Add a subcommand to the doc generator to print the generated man page to stdout
Closes#777.
Co-authored-by: Valentin Brandl <mail@vbrandl.net>
Reviewed-on: https://gitea.com/gitea/tea/pulls/811
Reviewed-by: Lunny Xiao <xiaolunwen@gmail.com>
Reviewed-by: TheFox0x7 <thefox0x7@noreply.gitea.com>
Co-authored-by: Valentin Brandl <vbrandl@noreply.gitea.com>
Co-committed-by: Valentin Brandl <vbrandl@noreply.gitea.com>
This PR adds validation for the `--object-format` flag in the `repo create` command. The flag now accepts only `sha1` or `sha256` as valid values, and returns an error for any other value.
Changes:
- Added validation in `runRepoCreate` to check for valid object format values
- Added unit tests to verify the validation logic
- Fixed the field name from `ObjectFormat` to `ObjectFormatName` to match the SDK
The changes ensure that users get clear error messages when using invalid object format values, improving the user experience.
Fix#727Fix#660Fix#767
Co-authored-by: techknowlogick <techknowlogick@noreply.gitea.com>
Reviewed-on: https://gitea.com/gitea/tea/pulls/741
Reviewed-by: TheFox0x7 <thefox0x7@noreply.gitea.com>
Expose the --labels option for the `tea repos migrate` command. This pull request fixes the issue reported in gitea/tea#698
```bash
> tea ( main ) % ./tea repos migrate --help
NAME:
tea repos migrate - Migrate a repository
USAGE:
tea repos migrate [command options]
DESCRIPTION:
Migrate a repository and or mirror it.
OPTIONS:
--name value Name of the repository
--owner value Owner of the repository
--clone-url value Clone URL of the repository
--service value Service to migrate from. Supported services are: git, gitea, gitlab, gogs
--mirror Mirror the repository (default: false)
--private Make the repository private (default: false)
--template Make the repository a template (default: false)
--wiki Copy the wiki (default: false)
--issues Copy the issues (default: false)
--labels Copy the lables (default: false)
--pull-requests Copy the pull requests (default: false)
--releases Copy the releases (default: false)
--milestones Copy the milestones (default: false)
--mirror-interval value Interval to mirror the repository.
--lfs Copy the LFS objects (default: false)
--lfs-endpoint value LFS endpoint to use
--auth-user value Username to use for authentication.
--auth-password value Password to use for authentication.
--auth-token value Token to use for authentication.
--login value, -l value Use a different Gitea Login. Optional
--output value, -o value Output format. (simple, table, csv, tsv, yaml, json)
--help, -h show help
```
Fix tested successfully on an own migration from gitlab to gitea
This PR closesgitea/tea#698
Co-authored-by: ebner <simon.ebner@psi.ch>
Reviewed-on: https://gitea.com/gitea/tea/pulls/699
Reviewed-by: Lunny Xiao <lunny@noreply.gitea.com>
Co-authored-by: simongregorebner <simongregorebner@noreply.gitea.com>
Co-committed-by: simongregorebner <simongregorebner@noreply.gitea.com>
Add release asset management. This includes a series of subcommands under `tea release assets`:
- `tea release assets create <release-tag> <asset> [<asset>...]`: Upload one or more release attachments
- `tea release assets delete <release tag> <attachment name> [<attachment name>...]`: Delete one or more release attachments
- `tea release assets list <release tag>`: List Release Attachments
Co-authored-by: Dane Bouchie <dbouchie@iradimed.com>
Reviewed-on: https://gitea.com/gitea/tea/pulls/619
Co-authored-by: danebou <danebou@noreply.gitea.com>
Co-committed-by: danebou <danebou@noreply.gitea.com>
Hello,
This is a proposal to support consulting / protecting / unprotecting branches for a specific repository.
I copied the existing code for "issues" report and adapted to branches. There is no change of legacy code so I do not expect any impact.
Supported commands are "list", "protect", "unprotect":
- "List" print the list of branches with some available fields from gitea.Branch type.
- "protect" creates a gitea.BranchProtection with some default parameters for some specific branches
- "unprotect" destroys gitea.BranchProtection for some specific branches
What is printed now could be enriched with additional information gitea datatypes already offer.
Could you please evaluate this proposal?
I would be happy to receive any comment or remark to take into account.
**tea branches unprotect** --login opsi --repo opensky main
**tea branches list** --login opsi --repo opensky --fields name,protected,user-can-merge,user-can-push,protection
[name protected user-can-merge user-can-push protection]
+--------+-----------+----------------+---------------+------------+
| NAME | PROTECTED | USER-CAN-MERGE | USER-CAN-PUSH | PROTECTION |
+--------+-----------+----------------+---------------+------------+
| b_test | false | true | true | <None> |
| main | false | true | true | <None> |
+--------+-----------+----------------+---------------+------------+
**tea branches protect** --login opsi --repo opensky main
**tea branches list** --login opsi --repo opensky --fields name,protected,user-can-merge,user-can-push,protection
[name protected user-can-merge user-can-push protection]
+--------+-----------+----------------+---------------+----------------------+
| NAME | PROTECTED | USER-CAN-MERGE | USER-CAN-PUSH | PROTECTION |
+--------+-----------+----------------+---------------+----------------------+
| b_test | false | true | true | <None> |
| main | true | true | false | - enable-push: false |
| | | | | - approving: - |
| | | | | merging: - pushing: |
| | | | | |
+--------+-----------+----------------+---------------+----------------------+
Following commands run OK:
> make test
> make fmt
> make lint
Co-authored-by: Leonard Vimond <leonard.vimond.e@thalesdigital.io>
Co-authored-by: techknowlogick <techknowlogick@noreply.gitea.com>
Reviewed-on: https://gitea.com/gitea/tea/pulls/645
Reviewed-by: techknowlogick <techknowlogick@noreply.gitea.com>
Co-authored-by: leonard.vimond <leonard.vimond@noreply.gitea.com>
Co-committed-by: leonard.vimond <leonard.vimond@noreply.gitea.com>