Skip to main content

redi

PyPI

redi is a Redmine CLI/TUI tool that wraps the Redmine REST API.

Demo

TUI demo

Quickstart

redi init                # interactive: select language, then enter Redmine URL and API key
redi --tui               # launch the TUI
redi issue               # or list issues

redi init verifies the credentials and writes a profile to ~/.config/redi/config.toml. See Usage (examples) for the full command reference.

Install

I recommend installation via uv.

uv tool install redtile  # name on PyPI is redtile, NOT redi

Plugin (Agent Skill + Hook)

redmine-redi makes coding agents (Claude Code, Codex) use redi for Redmine work. It bundles an Agent Skill and a PreToolUse hook that denies direct reads of the config file. See Plugin for skill-only installation.

Install

# Claude Code
claude plugin marketplace add kawagh/redi
claude plugin install redmine-redi@redi

# Codex
codex plugin marketplace add kawagh/redi
codex plugin add redmine-redi@redi

Update

Refresh the marketplace first, then update the plugin. Claude Code needs a restart to apply.

# Claude Code
claude plugin marketplace update redi
claude plugin update redmine-redi@redi

# Codex
codex plugin marketplace upgrade redi
codex plugin add redmine-redi@redi

Documentation

https://kawagh.github.io/redi/ (also available in Japanese(日本語))

Usage (examples)

Most commands follow the form:

redi <resource> <action> [<resource_id>] [options]
  • <resource> — issue, project, time_entry, ... (almost every resource has a short alias such as i / p / te; init / me / relation have no alias)
  • <action> — list / view / create / update / delete / comment (also has aliases: v / c / u / d / co)
    • redi <resource> alone is shorthand for redi <resource> list
  • <resource_id> — required for actions that target a specific item (view, update, delete, comment)
# init
redi init # interactive: select language, then Redmine URL / API key / projects

# run TUI
redi --tui

# config (alias: c)
redi config # list profiles (same as `redi config list`)
redi config view # show the profile in use
redi config create # interactive: profile name / Redmine URL / API key / projects
redi config create <profile_name> --url <url> --api_key <key> # create new profile
redi config create <profile_name> --url <url> --api_key <key> --set_default
redi config update # interactive: Enter to switch profile, u to update fields of the profile
redi config update --default_profile <profile_name> # switch profile
redi config update <profile_name> --editor nvim # update profile
redi config update --language ja # switch language ("en" or "ja")
redi config update --text_formatting textile # text formatting of the Redmine server ("markdown" or "textile")
redi config delete # interactive: select profile to delete
redi config delete <profile_name> --yes # delete profile without confirmation
redi --profile <profile_name> issue # temporarily switch profile for this command

# project (alias: p)
redi project # list projects
redi project list # same as above (`redi project l` / `redi p list` / `redi p l` / `redi p` also work)
redi project view <project_id> # view project
redi project view <project_id> --include trackers,issue_categories
redi project list --limit 10 --offset 10 # `list` returns Redmine's default 25 unless limited
redi project create # (interactive)
redi project create <name> <identifier>
redi project create <name> <identifier> -d "description" --is_public true
redi project create <name> <identifier> --homepage https://example.com --inherit_members true
redi project create <name> <identifier> --enabled_module_names issue_tracking,wiki --issue_custom_field_ids 1,2
redi project update <project_id> # (interactive)
redi project update <project_id> --name renamed_project
redi project update <project_id> --enabled_module_names issue_tracking,time_tracking,wiki
redi project update <project_id> --default_assigned_to_id 3 --default_version_id 5
redi project update <project_id> --default_assigned_to_id "" # unset

# issue (alias: i)
redi issue # list issues
redi issue -p <project_id> -a me -s open
redi issue -q <query_id>
redi issue view <issue_id>
redi issue view <issue_id> --web # view issue with web browser
redi issue view <issue_id> --include children,watchers # relations, attachments and journals are shown by default
redi issue create # (interactive)
redi issue create "subject" -p <project_id> -t <tracker_id> -a <user_id> -d "description"
redi issue create "subject" -p <project_id> --full # output created issue as full JSON
redi issue update <issue_id> # (interactive)
redi issue update <issue_id> --status_id <status_id> -n "notes"
redi issue update <issue_id> --start_date 2026-04-26 --due_date 2026-05-31 --estimated_hours 1.5
redi issue update <issue_id> --done_ratio 70
redi issue update <issue_id> --assigned_to_id <user_id>
redi issue update <issue_id> --assigned_to_id "" # unset assignee
redi issue update <issue_id> --project_id <project_id> # move issue to another project
redi issue update <issue_id> --relate relates --to <other_issue_id>
redi issue update <issue_id> --attach ./foo.png --attach ./bar.log
redi issue comment <issue_id> "hello~"
redi issue delete <issue_id> # (confirm before delete)
redi issue delete <issue_id> -y # skip confirmation

# version (alias: v)
redi version # list versions(fixed_versions)
redi version -p <project_id>
redi version view <version_id>
redi version create <name> -p <project_id> --due_date 2026-12-31 --status open
redi version update <version_id> --status closed

# wiki (alias: w)
redi wiki
redi wiki -p <project_id>
redi wiki view <page_title>
redi wiki create # (interactive, fails if the page already exists)
redi wiki update # (interactive)

# file (alias: f, project files)
redi file -p <project_id> # list
redi file create ./foo.zip -p <project_id> -d "description"

# attachment (alias: a)
redi attachment view <attachment_id>
redi attachment download <attachment_id> # alias: dl, save with the original filename
redi attachment download <attachment_id> -o ./dir_or_path # confirm before overwrite (-y to skip)
redi attachment update <attachment_id> -f new_name.png -d "desc"
redi attachment delete <attachment_id> # confirm before delete (-y to skip)

# relation (issue relation details)
redi relation view <relation_id>

# issue_journal (alias: ij, requires Redmine 5.0+)
redi issue_journal update <journal_id> "updated note"
redi issue_journal update <journal_id> "" # updating with an empty note is equivalent to delete
redi issue_journal delete <journal_id> # confirm before delete (-y to skip)

# time_entry (alias: te)
redi time_entry -p <project_id> -u me
redi time_entry --from 2026-01-01 --to 2026-01-31 # filter by date range
redi time_entry --limit 50 --offset 100 # pagination
redi time_entry create 1.5 -i <issue_id> -a <activity_id> -c "comment"
redi time_entry update <time_entry_id> --hours 2.0
redi time_entry delete <time_entry_id> # confirm before delete (-y to skip)

# me (own account)
redi me
redi me update -f <firstname> -l <lastname> -m <mail>

# membership (alias: m)
redi membership -p <project_id>
redi membership list --limit 10 --offset 10
redi membership view <membership_id>

# news (alias: n)
redi news -p <project_id>
redi news list --limit 10 --offset 10
redi news view <news_id>
redi news view <news_id> --web # open in browser
redi news create -p <project_id> # interactive: title, summary (optional), then the description in an editor
redi news create "title" -p <project_id> # opens editor for the description
redi news create "title" -d "description" --summary "summary" -p <project_id>
redi news update # interactive: pick the news, then the items to update
redi news update <news_id> # interactive: pick the items to update
redi news update <news_id> --title "new title" -d "new description"
redi news update <news_id> -d # opens editor with the current description
redi news delete # interactive: pick the news to delete
redi news delete <news_id>

# issue_category (alias: ic)
redi issue_category -p <project_id>
redi issue_category create "category" -p <project_id>

# issue_template (alias: it)
# This command requires redmine_issue_templates plugin ( https://www.redmine.org/plugins/redmine_issue_templates )
redi issue_template # list issue_templates
redi issue_template -t <tracker_id> # list issue_templates for the tracker

# search (alias: s)
redi search "keyword" # search all projects
redi search "keyword" -p <project_id> # search within a project
redi search "keyword" --type issues # limit object types
redi search "keyword" --type issues,wiki_pages # comma separated (issues, news, documents, changesets, wiki_pages, messages, projects)
redi search "keyword" --scope my_projects # all, my_projects, bookmarks (cannot be combined with -p)
redi search "keyword" -p <project_id> --scope subprojects # search the project and its subprojects (-p is required)
redi search "keyword" --titles_only --open_issues
redi search "keyword" --no_all_words # match any word (default: all words)
redi search "keyword" --attachments only # 0: description only, 1: description and attachments, only: attachments only
redi search "keyword" --limit 10 --offset 10
redi search "keyword" --full # output full JSON

# user (alias: u, admin required)
redi user # list users
redi user list --status locked # active / registered / locked (default: active only)
redi user list --name kawagh # partial match on login / firstname / lastname / mail
redi user list --group_id <group_id> # members of the group
redi user --status locked list # filters can be placed before the subcommand too
redi user list --limit 10 --offset 10 # `list` returns Redmine's default 25 unless limited
redi user list --full # output full JSON
redi user list --format tsv # header row + tab-separated columns (list only; header names are fixed in English)
redi user list -f tsv # -f is short for --format

# others
redi tracker # list trackers (alias: t)
redi tracker list # 同上 (以下の一覧専用リソースも `list` / `l` を受け付ける)
redi issue_status # list issue statuses (alias: is)
redi issue_priority # list priorities (alias: ip)
redi time_entry_activity # list activities (alias: tea)
redi document_category # list document categories (alias: dc)
redi role # list roles (alias: r)
redi group # list groups (alias: g)
redi custom_field # list custom fields (alias: cf)
redi query # list custom queries (alias: q)
redi --version

Redmine version

redi is developed against Redmine 6.1, 7.0.

Development

install

uv tool install -e .

task

Common tasks (managed by task runner Task):

task check       # format → lint → typecheck → test (run before opening a PR)
task format      # uv run ruff format
task lint        # uv run ruff check
task typecheck   # uv run ty check
task test        # uv run pytest -v
task test:e2e    # E2E tests against every target Redmine version
task test:e2e:7.0 # E2E tests against Redmine 7.0 only (also: task test:e2e:6.1)

Debug

redi --debug <command> # log request URLs and response status codes to ~/.config/redi/redi-debug.log
redi --debug-tui   # dump rendered TUI screens as YAML to log

Metadata

Release files for redtile 0.0.82

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for redtile 0.0.82
File Size Uploaded
redtile-0.0.82.tar.gz 190.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for redtile 0.0.82
File Interpreter ABI Platform
redtile-0.0.82-py3-none-any.whl Python 3 none any Details

Total release size: 463.1 kB

Release files / redtile-0.0.82.tar.gz

Download URL redtile-0.0.82.tar.gz
Size 190.0 kB
Tags Source
SHA-256 checksum
How to use checksums
08722469b09c3ac16f825ca3e00bdab51b37a030cdef1855ac1d92f559e9eeff
BLAKE2b-256 checksum
How to use checksums
cd9b862a8e82e7beb5054dfc637d0deb75c130ab8f83077991cd355161d6f278
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 13, 2026.

Transparency log

Release files / redtile-0.0.82-py3-none-any.whl

Download URL redtile-0.0.82-py3-none-any.whl
Size 273.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
377c499bdae2e8ed84f82df1371f8c3efb18fe8a6e0b90c3c3f743962efd3df9
BLAKE2b-256 checksum
How to use checksums
ae38f3bb96522899e32f91f3a35ef47ef584ce7dee00f9f959723fe3300cb8ad
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 13, 2026.

Transparency log

Release history Release notifications | RSS feed

0.0.86

2 release files

0.0.84

2 release files

0.0.83

2 release files

This release

0.0.82 This release

2 release files

0.0.81

2 release files

0.0.80

2 release files

0.0.74

2 release files

0.0.73

2 release files

0.0.72

2 release files

0.0.71

2 release files

0.0.70

2 release files

0.0.69

2 release files

0.0.68

2 release files

0.0.67

2 release files

0.0.66

2 release files

0.0.65

2 release files

0.0.64

2 release files

0.0.63

2 release files

0.0.62

2 release files

0.0.61

2 release files

0.0.60

2 release files

0.0.59

2 release files

0.0.58

2 release files

0.0.57

2 release files

0.0.56

2 release files

0.0.55

2 release files

0.0.54

2 release files

0.0.53

2 release files

0.0.52

2 release files

0.0.51

2 release files

0.0.46

2 release files

0.0.45

2 release files

0.0.44

2 release files

0.0.43

2 release files

0.0.40

2 release files

0.0.39

2 release files

0.0.38

2 release files

0.0.37

2 release files

0.0.36

2 release files

0.0.35

2 release files

0.0.34

2 release files

0.0.33

2 release files

0.0.32

2 release files

0.0.25

2 release files

0.0.24

2 release files

0.0.23

2 release files

0.0.22

2 release files

0.0.21

2 release files

0.0.20

2 release files

0.0.19

2 release files

0.0.18

2 release files

0.0.17

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page