Skip to content

Latest commit

 

History

616 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

workflow

CI CodeQL Scorecard Docs site Release OpenSSF Scorecard Latest release Go reference Go Bubble Tea License Docs Conventional Commits Code of Conduct Security policy

A terminal UI for the loop a developer actually runs all day: pick up a Jira issue, start a branch for it, open the pull or merge request, and tell the team in Slack, Teams or Discord — without leaving the keyboard or reconstructing the same context in three browser tabs.

Status

The whole loop works, and is new: expect rough edges, and a configuration format that may still change before 1.0.

  • workflow opens the TUI. Pick up an assigned Jira issue, comment on it or change its status, branch for it, stage and commit through the repository's own hooks — opening a failure at its line in $EDITOR — push, open the pull or merge request from the repository's template, follow its CI, and announce it to your team. ? lists the keys.
  • workflow --dry-run does all of that with every write held back, saying what it would have done.
  • workflow --web serves the same loop in a browser, on 127.0.0.1 alone — issues, branch, commit, push, the pull request and its announcement, your review queue and the settings — pushed live as the repository changes.
  • With no Jira configured, the Issues pane lists the issues assigned to you on your forge (GitHub or GitLab) instead — pick one up, branch for it, and the pull request closes it on merge.
  • A repository with hooks in .git/hooks and no lefthook configuration is offered a lefthook.yml that runs them.
  • workflow doctor reports the repository, tooling and configuration in effect; workflow doctor --online asks Jira, your messaging service and your forge whether each credential actually works.
  • workflow config init writes a starting configuration file, and workflow config show prints the one in effect, credentials masked.
  • workflow standup drafts what you did — your recent commits, the issues you touched and the open pull requests on your branches — for you to edit and, optionally, post to your team.
  • workflow reviews lists the pull requests on your forge that are waiting on your review — the longest-waiting first, with the author, how CI stands and how long each has waited.

Install

With Go:

go install github.com/jacob-delgado/workflow/cmd/workflow@latest

The binary lands in $(go env GOPATH)/bin, which needs to be on your PATH. For a reproducible install, name the version instead: @v0.0.5. Note that @latest resolves to the newest release tag, and until the first tag exists, to the most recent commit on main.

From a release — binaries are published for macOS (arm64), Linux (amd64) and Windows (amd64), each with a checksum and a build provenance attestation:

sha256sum -c SHA256SUMS --ignore-missing
gh attestation verify workflow_darwin_arm64 --repo jacob-delgado/workflow

From source, using mise for the pinned toolchain and go-task as the runner:

git clone https://github.com/jacob-delgado/workflow.git
cd workflow
mise trust && mise install
task build            # builds bin/workflow

There is also a devcontainer (VS Code, GoLand, Codespaces, or the devcontainer CLI), and a build container for running the same checks without installing anything: task container:check.

Configure

workflow config init      # writes .workflow.json here, readable only by you
workflow doctor           # says what is still missing

.workflow.json looks like this:

{
  "jira": {
    "base_url": "https://jira.example.com",
    "token": "",
    "user": ""
  },
  "messaging": {
    "kind": "slack",
    "token": "",
    "webhook_url": "",
    "channel": "#dev-workflow"
  },
  "forge": {
    "kind": "",
    "host": "",
    "token": ""
  },
  "ui": {
    "mouse": true,
    "ascii": false
  }
}

workflow reads .workflow.json from the current directory, and falls back to your home directory. A file in the current directory replaces the one in your home directory — they are never merged, so a repository-local configuration is always the whole story.

workflow keeps a little state between sessions in an on-disk store — the commit scope you last used, which pull requests you have announced, and the last issue list it saw — under your platform's data directory, and never a secret. It is on by default; set "store": { "disabled": true } to keep nothing on disk. See Configuration for where it lives and how it is keyed.

Jira token (on-premises / Data Center)

  1. Sign in to your Jira instance in a browser.
  2. Open your avatar menu → Profile → Personal Access Tokens.
  3. Create a token and copy the value into jira.token, with your instance's URL in jira.base_url.

Leave jira.user empty to authenticate with that token as a bearer token, which is what Data Center expects. Set jira.user only if your instance requires HTTP Basic authentication, in which case the token is used as the password.

Behind single sign-on (Azure AD / Office 365)? SSO usually guards only the web UI, so a personal access token still reaches the REST API directly — no special handling needed. When a gateway sits in front of the API too, the configuration guide shows how to tell (a one-line curl), and how to carry the gateway's own token or headers with jira.token_command and jira.headers.

Messaging: Slack, Teams, Discord or a plain webhook

messaging.kind picks the service — slack (the default when empty), teams, discord or webhook. Slack posts over a bot token or an incoming webhook; the others post over an incoming webhook, rendered in that service's own markup.

Slack, either transport. Set a webhook or a bot token; if you set both, the bot token wins.

Incoming webhook, the two-minute option: create an app at https://api.slack.com/apps, turn on Incoming Webhooks, add one to the workspace, pick its channel, and put the URL in messaging.webhook_url. It is bound to that channel, so messaging.channel does not apply. Treat the URL as a password.

Bot token, to choose the channel at runtime:

  1. Create an app at https://api.slack.com/apps in your workspace.
  2. Under OAuth & Permissions, add the chat:write bot token scope.
  3. Install the app to the workspace and copy the Bot User OAuth Token — it starts with xoxb- — into messaging.token.
  4. Set messaging.channel to the channel to post in, and invite the bot to it.

Teams, Discord or a plain webhook: create an incoming webhook in the service, set messaging.kind accordingly, and put the URL in messaging.webhook_url.

A configuration written before this block was renamed still names it slack; rename the key to messaging and add "kind": "slack". workflow --help repeats all of this at the terminal.

Reaching a forge behind SSO

If a bare token cannot reach your forge — an SSO gateway in front of it, say — set forge.cli to true. workflow then routes its GitHub or GitLab API calls through gh or glab, reusing the login those tools already hold, and falls back to HTTP when the tool is not installed.

Keeping the tokens safe

.workflow.json holds live credentials. config init writes it at mode 0600, doctor fails while anyone else can read it, it is listed in .gitignore, and config show masks every credential — including messaging.webhook_url, which is a password that happens to look like an address. Nothing in this repo will print a credential in full.

Use

Run workflow in a repository. Six panes run down the left — Issues, Branch, Commits, Review and your messaging service, named for it, in the order the work goes, then Reviews, the pull requests waiting on your review — and the one in focus fills the right. The bottom row shows only the keys that do something right now.

Key Where Does
tab / 1–6 anywhere Move between panes
t / c / b Issues Change status, comment, branch for the issue
space / a / c Commits Stage a file, stage all, commit
h Commits Run the pre-commit hook
P Branch Push
n Review Open the pull or merge request
p messaging Preview the announcement; announce now or once CI passes
? anywhere Every key

Comments, commit bodies, pull request descriptions and announcements are written in $EDITOR and previewed before they send. workflow --dry-run holds every write back. The usage guide has the whole loop.

workflow --web serves the loop in a browser instead, at http://127.0.0.1:7000: six sections — Issues, Branch, Review, your messaging service, Reviews and Settings — kept live by the server, in a light or a dark theme. --web --dry-run makes it read-only. Re-running CI, merging, finishing a branch and most issue writes stay in the terminal for now; the web page says which.

Development

task --list        # every task, with a description
task run           # run the TUI from source
task test          # tests with the race detector
task cover:branch  # condition coverage: which conditions went only one way
task check         # the full gate: lint, tests, coverage floors, vuln, secrets

task check is what CI runs. See ARCHITECTURE.md for how the system fits together — the surfaces, the seams, and the two kinds of local state — CONTRIBUTING.md for the setup and conventions, and CLAUDE.md for the code standards this project holds itself to.

Documentation

Full documentation is at jacob-delgado.github.io/workflow — install, usage, the web interface, configuration, and a command reference generated from the code. The source is in docs/; task docs:serve previews it locally.

Releases

Versioning is automated from the commit history with release-please: merging its release pull request tags the version and publishes binaries for macOS (arm64), Linux (amd64) and Windows (amd64), each with a SHA256 checksum and a build provenance attestation. There are no releases yet.

Security

Found a vulnerability? Please report it privately through a security advisory rather than opening an issue — see SECURITY.md for what to include and what to expect.

.workflow.json holds live credentials. It is written 0600, gitignored, and every path that surfaces a token masks it first.

License

Apache License 2.0. Contributions are accepted under the same terms; see CONTRIBUTING.md and the Code of Conduct.

About

A terminal UI that ties Jira, Slack, and GitHub or GitLab into one developer workflow.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages