Skip to content

Commit b340698

Browse files
committed
Add release infrastructure, README, and LICENSE
- GitHub Actions workflow for tag-triggered releases - Taskfile release/bump targets - MIT license - README with usage docs - Remove PAPERCUTS.md
1 parent c8086ce commit b340698

8 files changed

Lines changed: 186 additions & 102 deletions

File tree

.github/workflows/release.yml

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
name: Release
2+
3+
on:
4+
push:
5+
tags:
6+
- 'v*'
7+
8+
permissions:
9+
contents: write
10+
11+
jobs:
12+
release:
13+
runs-on: ubuntu-latest
14+
steps:
15+
- uses: actions/checkout@v4
16+
17+
# TODO: install pact here
18+
19+
- name: Build binaries
20+
run: |
21+
mkdir -p dist
22+
pact build src/main.pact --release -T linux -o dist/br-linux-amd64
23+
pact build src/main.pact --release -T linux-arm64 -o dist/br-linux-arm64
24+
pact build src/main.pact --release -T macos -o dist/br-darwin-amd64
25+
pact build src/main.pact --release -T macos-arm64 -o dist/br-darwin-arm64
26+
27+
- name: Checksums
28+
run: |
29+
cd dist
30+
sha256sum br-* > checksums.txt
31+
32+
- uses: softprops/action-gh-release@v2
33+
with:
34+
files: |
35+
dist/br-*
36+
dist/checksums.txt

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
build/
2+
dist/
23
.tmp/
34
.pact/
45
.task/

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2025 Nick Humrich
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

PAPERCUTS.md

Lines changed: 0 additions & 86 deletions
This file was deleted.

README.md

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
# Bridge
2+
3+
A local-only task list that persists across repos and AI sessions.
4+
5+
Bridge is a dependency-aware task manager that persists globally across repos and sessions. It gives AI coding agents (and you) a shared view of what needs to be done, what's blocked, and what's ready to work on. It is designed only for local, and as such, has no concept of git or remote syncing.
6+
7+
8+
## Why
9+
10+
Dev workflows often live across multiple AI coding sessions. It can be helpful to have a place to manage them. Keeping track of a project in a single file means all sub-agents have to read the whole file. Sometimes and agent doesn't need the whole picture, but a peice. This is a task manager similar to beads that allows you to manage tasks for usage across sessions. This means sessions can either:
11+
a) assign work to eachother
12+
b) store "future work" of stuff to be done without effecting current session
13+
c) pick up "work to be done" without you have to copy/paste or reference a file.
14+
15+
16+
## Features
17+
18+
- **Global task list**: tasks aren't scoped to a repo, they follow you everywhere
19+
- **Dependencies**: tasks can have dependencies, so you can mark things to NOT be worked on until other work is completed
20+
- **Priority + tags** — organize however you want with tags. Set priorities.
21+
- **Agent integration** — optional Claude Code plugin with slash commands (`/br:next`, `/br:plan`, `/br:add`)
22+
- **Fast CLI** — single binary, no runtime dependencies, prefix-matching IDs
23+
24+
## Install
25+
26+
Download the latest binary from [Releases](https://github.com/nhumrich/bridge/releases):
27+
28+
```sh
29+
# Linux (amd64)
30+
curl -L https://github.com/nhumrich/bridge/releases/latest/download/br-linux-amd64 -o ~/.local/bin/br
31+
chmod +x ~/.local/bin/br
32+
```
33+
34+
I also recommend you add something to your CLAUDE/AGENTS.md so it knows to use `br`, such as:
35+
36+
```markdown
37+
## Task Management
38+
We track work in Bridge (`br`) — a global task manager. Run `br --help` to see commands.
39+
40+
### br Workflow
41+
1. Check what's ready: `br ready`
42+
2. Add tasks: `br add "task description" -p 0` (0=highest priority)
43+
3. Add dependencies: `br dep <parent-id> <child-id>` (child blocks parent)
44+
4. Start work: `br start <id>`
45+
5. Complete work: `br close <id>`
46+
47+
### br Best Practices
48+
- Break down complex tasks into multiple issues with dependencies
49+
- Use `br ready` to see unblocked work before starting
50+
- Tags use `namespace:value` convention (e.g., `repo:bridge`, `feature`, `bug`)
51+
- Use `-t tag` to filter by tag
52+
- Use `br show <id>` for task details
53+
```
54+
55+
### Agent integration (optional)
56+
57+
```sh
58+
br install # installs Claude Code slash commands
59+
br uninstall # removes them
60+
```
61+
62+
## Usage
63+
64+
```
65+
br add "my task" -p 0 # add task (priority 0 = highest)
66+
br add "fix bug" -t repo:bridge # add with tag
67+
br ready # show unblocked tasks
68+
br start <id> # start working
69+
br close <id> # complete task
70+
br dep add <blocker> <blocked> # add dependency
71+
br blocked # show what's stuck
72+
br ls # list open tasks
73+
br stats # overview
74+
```
75+
76+
Run `br --help` for all commands.
77+
78+
# Tags
79+
Bridge supports tags. Tags are a very loosely opinionated system that lets you break down work however you want. You can tag things simply such as `[feature] [projecta]` or, you can use `:` notation for categories such as `repo:backend`, `repo:frontend`, `type:epic`, `project:foobar`, whatever you want. Just update your AI commands and workflows to tell it how you want to organize, and it does a good job.
80+
Also, putting `[]` around labels seems to work pretty well. For example:
81+
`create a task on br [feature repo:other]`
82+
83+
AI will figure out `[featue repo:other]` means add those two tags.
84+
85+
# Tricks
86+
I like to run `/br:plan` after a plan mode _instead of hitting accept plan_. It breaks the plan down into smaller steps. I then use `/clear` and `/br:next` and then the agent will pick up the work, and run the different tasks in parallel, each one only having the context of what it needs.
87+
88+
I also sometimes like to keep adding tasks this way in a loop, while a different session picks up tasks from the "backlog" in a loop.
89+
90+
## Build from source
91+
92+
Requires [Pact](https://github.com/nhumrich/pact).
93+
```sh
94+
pact build src/main.pact
95+
cp build/main ~/.local/bin/br
96+
```
97+
98+
## License
99+
100+
MIT
101+
102+
## Etymology
103+
104+
The bridge of a spaceship. It also bridges context between sessions.

Taskfile.yml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,3 +49,22 @@ tasks:
4949
deps: [build]
5050
cmds:
5151
- "{{.BIN}} {{.CLI_ARGS}}"
52+
53+
release:
54+
desc: Cross-compile release binaries to dist/
55+
cmds:
56+
- mkdir -p dist
57+
- pact build {{.SRC}} --release -T linux -o dist/br-linux-amd64
58+
- pact build {{.SRC}} --release -T linux-arm64 -o dist/br-linux-arm64
59+
- pact build {{.SRC}} --release -T macos -o dist/br-darwin-amd64
60+
- pact build {{.SRC}} --release -T macos-arm64 -o dist/br-darwin-arm64
61+
- cd dist && sha256sum br-* > checksums.txt
62+
- echo "Release binaries in dist/"
63+
64+
bump:
65+
desc: "Bump version (usage: task bump -- 0.2.0)"
66+
cmds:
67+
- sed -i 's/^version = ".*"/version = "{{.CLI_ARGS}}"/' pact.toml
68+
- sed -i 's/set_version(p, ".*")/set_version(p, "{{.CLI_ARGS}}")/' src/main.pact
69+
- 'sed -i ''s/"version": ".*"/"version": "{{.CLI_ARGS}}"/'' .claude-plugin/plugin.json'
70+
- echo "Bumped to v{{.CLI_ARGS}}"

src/commands.pact

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -513,7 +513,7 @@ pub fn cmd_install() {
513513

514514
fn install_hook(home: Str) {
515515
let settings_path = "{home}/.claude/settings.json"
516-
let hook_cmd = "bash -c 'read input; sid=$(echo \"$input\" | sed -n '\\''s/.*\"session_id\":\"\\([^\"]*\\)\".*/\\1/p'\\''); [ -n \"$CLAUDE_ENV_FILE\" ] && [ -n \"$sid\" ] && echo \"export BR_SESSION_ID=$sid\" >> \"$CLAUDE_ENV_FILE\"'"
516+
let hook_cmd = #"bash -c 'read input; sid=$(echo "$input" | sed -n '"'"'s/.*"session_id":"\([^"]*\)".*/\1/p'"'"'); [ -n "$CLAUDE_ENV_FILE" ] && [ -n "$sid" ] && echo "export BR_SESSION_ID=$sid" >> "$CLAUDE_ENV_FILE"'"#
517517

518518
json_clear()
519519
let mut root = -1

src/main.pact

Lines changed: 4 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@ fn args_positionals_from(a: Args, start: Int) -> List[Str] {
1414

1515
fn build_parser() -> ArgParser {
1616
let mut p = argparser_new("br", "Bridge Task Manager")
17+
p = set_version(p, "0.1.0")
1718

1819
p = add_flag(p, "--json", "-j", "JSON output")
19-
p = add_flag(p, "--version", "-V", "Print version")
2020

2121
p = add_command(p, "add", "Add a new task")
2222
p = command_add_positional(p, "add", "title", "Task title")
@@ -96,8 +96,6 @@ fn build_parser() -> ArgParser {
9696
p = command_add_option(p, "stats", "-t", "", "Filter by tag")
9797
p = add_command(p, "install", "Install Claude Code commands")
9898
p = add_command(p, "uninstall", "Remove Claude Code commands")
99-
p = add_command(p, "version", "Print version")
100-
10199
p
102100
}
103101

@@ -107,7 +105,7 @@ fn main() {
107105
let p = build_parser()
108106
let a = argparse(p)
109107
let err = args_error(a)
110-
if err == "help" { exit(0) }
108+
if err == "help" || err == "version" { exit(0) }
111109
if err != "" {
112110
io.eprintln(err)
113111
exit(1)
@@ -116,11 +114,6 @@ fn main() {
116114
let cmd = args_command(a)
117115
let json_mode = args_has(a, "json")
118116

119-
if args_has(a, "version") {
120-
io.println("br 0.1.0")
121-
exit(0)
122-
}
123-
124117
if cmd == "" {
125118
io.println(generate_help(p))
126119
exit(0)
@@ -206,16 +199,14 @@ fn main() {
206199
}
207200
cmd_rm(id)
208201
} else if cmd == "dep add" {
209-
let blocker = args_positional(a, 0)
210-
let blocked = args_positional(a, 1)
202+
let (blocker, blocked) = (args_positional(a, 0), args_positional(a, 1))
211203
if blocker == "" || blocked == "" {
212204
io.eprintln("Usage: br dep add <blocker> <blocked>")
213205
exit(1)
214206
}
215207
cmd_dep_add(blocker, blocked)
216208
} else if cmd == "dep rm" {
217-
let blocker = args_positional(a, 0)
218-
let blocked = args_positional(a, 1)
209+
let (blocker, blocked) = (args_positional(a, 0), args_positional(a, 1))
219210
if blocker == "" || blocked == "" {
220211
io.eprintln("Usage: br dep rm <blocker> <blocked>")
221212
exit(1)
@@ -251,8 +242,6 @@ fn main() {
251242
cmd_install()
252243
} else if cmd == "uninstall" {
253244
cmd_uninstall()
254-
} else if cmd == "version" {
255-
io.println("br 0.1.0")
256245
} else {
257246
io.eprintln("Unknown command: {cmd}")
258247
io.eprintln("Run 'br --help' for usage")

0 commit comments

Comments
 (0)