relaybay 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (126) hide show
  1. relaybay-0.1.0/.gitignore +34 -0
  2. relaybay-0.1.0/CHANGELOG.md +186 -0
  3. relaybay-0.1.0/LICENSE +21 -0
  4. relaybay-0.1.0/PKG-INFO +237 -0
  5. relaybay-0.1.0/README.md +207 -0
  6. relaybay-0.1.0/docs/PLAN.md +13 -0
  7. relaybay-0.1.0/docs/ROADMAP.md +90 -0
  8. relaybay-0.1.0/docs/SPEC.md +515 -0
  9. relaybay-0.1.0/docs/adr/0001-htmx-sse.md +38 -0
  10. relaybay-0.1.0/docs/architecture.md +169 -0
  11. relaybay-0.1.0/docs/changelog.md +5 -0
  12. relaybay-0.1.0/docs/connect-claude-code.md +149 -0
  13. relaybay-0.1.0/docs/design/0001-hooks-and-setup.md +62 -0
  14. relaybay-0.1.0/docs/design/0002-working-rules.md +57 -0
  15. relaybay-0.1.0/docs/design/0003-packaging-and-release.md +79 -0
  16. relaybay-0.1.0/docs/design/0004-navigation.md +55 -0
  17. relaybay-0.1.0/docs/design/0005-comments-to-agents.md +56 -0
  18. relaybay-0.1.0/docs/design/0006-environments-and-access.md +73 -0
  19. relaybay-0.1.0/docs/design/0007-review.md +101 -0
  20. relaybay-0.1.0/docs/design/0008-memory-and-context.md +162 -0
  21. relaybay-0.1.0/docs/design/0009-screenshot-annotations.md +51 -0
  22. relaybay-0.1.0/docs/design/0010-map-and-usage.md +50 -0
  23. relaybay-0.1.0/docs/design/0011-docs-in-database.md +43 -0
  24. relaybay-0.1.0/docs/design/0012-runner-and-embedded-terminal.md +65 -0
  25. relaybay-0.1.0/docs/design/index.md +22 -0
  26. relaybay-0.1.0/docs/getting-started/agent-install.md +121 -0
  27. relaybay-0.1.0/docs/getting-started/install.md +138 -0
  28. relaybay-0.1.0/docs/how-to/coordinator.md +8 -0
  29. relaybay-0.1.0/docs/how-to/lan-access.md +22 -0
  30. relaybay-0.1.0/docs/how-to/troubleshooting.md +57 -0
  31. relaybay-0.1.0/docs/how-to/uninstall.md +21 -0
  32. relaybay-0.1.0/docs/index.md +26 -0
  33. relaybay-0.1.0/docs/llms.txt +24 -0
  34. relaybay-0.1.0/docs/mcp-tools.md +228 -0
  35. relaybay-0.1.0/docs/reference/cli.md +92 -0
  36. relaybay-0.1.0/docs/reference/configuration.md +57 -0
  37. relaybay-0.1.0/docs/reference/mcp.md +227 -0
  38. relaybay-0.1.0/mkdocs.yml +92 -0
  39. relaybay-0.1.0/pyproject.toml +82 -0
  40. relaybay-0.1.0/scripts/changelog_notes.py +40 -0
  41. relaybay-0.1.0/scripts/check_dist.py +59 -0
  42. relaybay-0.1.0/scripts/gen_reference.py +278 -0
  43. relaybay-0.1.0/scripts/record_gif.md +40 -0
  44. relaybay-0.1.0/src/relaybay/__init__.py +8 -0
  45. relaybay-0.1.0/src/relaybay/__main__.py +3 -0
  46. relaybay-0.1.0/src/relaybay/app.py +68 -0
  47. relaybay-0.1.0/src/relaybay/cli.py +322 -0
  48. relaybay-0.1.0/src/relaybay/config.py +296 -0
  49. relaybay-0.1.0/src/relaybay/db/__init__.py +0 -0
  50. relaybay-0.1.0/src/relaybay/db/connection.py +46 -0
  51. relaybay-0.1.0/src/relaybay/db/migrations/0001_init.sql +94 -0
  52. relaybay-0.1.0/src/relaybay/db/migrations/0002_task_description_progress.sql +3 -0
  53. relaybay-0.1.0/src/relaybay/db/migrations/0003_tracker_and_session_alias.sql +15 -0
  54. relaybay-0.1.0/src/relaybay/db/migrations/0004_next_step_freshness.sql +5 -0
  55. relaybay-0.1.0/src/relaybay/db/migrations/0005_tracker_history.sql +18 -0
  56. relaybay-0.1.0/src/relaybay/db/migrations/0006_project_rules.sql +7 -0
  57. relaybay-0.1.0/src/relaybay/db/migrations/0007_hook_sessions.sql +8 -0
  58. relaybay-0.1.0/src/relaybay/db/repo.py +704 -0
  59. relaybay-0.1.0/src/relaybay/demo.py +220 -0
  60. relaybay-0.1.0/src/relaybay/doctor.py +146 -0
  61. relaybay-0.1.0/src/relaybay/domain/__init__.py +21 -0
  62. relaybay-0.1.0/src/relaybay/domain/errors.py +14 -0
  63. relaybay-0.1.0/src/relaybay/domain/hooks.py +88 -0
  64. relaybay-0.1.0/src/relaybay/domain/models.py +146 -0
  65. relaybay-0.1.0/src/relaybay/domain/reports.py +53 -0
  66. relaybay-0.1.0/src/relaybay/domain/rules.py +213 -0
  67. relaybay-0.1.0/src/relaybay/domain/sessions.py +22 -0
  68. relaybay-0.1.0/src/relaybay/domain/stages.py +24 -0
  69. relaybay-0.1.0/src/relaybay/domain/task_fields.py +92 -0
  70. relaybay-0.1.0/src/relaybay/domain/tasks.py +18 -0
  71. relaybay-0.1.0/src/relaybay/events.py +68 -0
  72. relaybay-0.1.0/src/relaybay/hook_client.py +49 -0
  73. relaybay-0.1.0/src/relaybay/logs.py +29 -0
  74. relaybay-0.1.0/src/relaybay/machine_setup.py +803 -0
  75. relaybay-0.1.0/src/relaybay/mcp_server/__init__.py +0 -0
  76. relaybay-0.1.0/src/relaybay/mcp_server/format.py +306 -0
  77. relaybay-0.1.0/src/relaybay/mcp_server/server.py +586 -0
  78. relaybay-0.1.0/src/relaybay/security.py +238 -0
  79. relaybay-0.1.0/src/relaybay/service.py +1351 -0
  80. relaybay-0.1.0/src/relaybay/web/__init__.py +0 -0
  81. relaybay-0.1.0/src/relaybay/web/hooks.py +56 -0
  82. relaybay-0.1.0/src/relaybay/web/markdown.py +10 -0
  83. relaybay-0.1.0/src/relaybay/web/routes.py +506 -0
  84. relaybay-0.1.0/src/relaybay/web/sse.py +59 -0
  85. relaybay-0.1.0/src/relaybay/web/static/app.css +690 -0
  86. relaybay-0.1.0/src/relaybay/web/static/app.js +357 -0
  87. relaybay-0.1.0/src/relaybay/web/static/htmx.min.js +1 -0
  88. relaybay-0.1.0/src/relaybay/web/static/sse.js +290 -0
  89. relaybay-0.1.0/src/relaybay/web/templates/_card.html +25 -0
  90. relaybay-0.1.0/src/relaybay/web/templates/_column.html +16 -0
  91. relaybay-0.1.0/src/relaybay/web/templates/_columns.html +3 -0
  92. relaybay-0.1.0/src/relaybay/web/templates/_integrations.html +101 -0
  93. relaybay-0.1.0/src/relaybay/web/templates/_projects.html +26 -0
  94. relaybay-0.1.0/src/relaybay/web/templates/_report_badges.html +6 -0
  95. relaybay-0.1.0/src/relaybay/web/templates/_session.html +11 -0
  96. relaybay-0.1.0/src/relaybay/web/templates/_task_dialog.html +14 -0
  97. relaybay-0.1.0/src/relaybay/web/templates/_task_form.html +72 -0
  98. relaybay-0.1.0/src/relaybay/web/templates/_task_view.html +119 -0
  99. relaybay-0.1.0/src/relaybay/web/templates/_tracker.html +16 -0
  100. relaybay-0.1.0/src/relaybay/web/templates/base.html +28 -0
  101. relaybay-0.1.0/src/relaybay/web/templates/board.html +31 -0
  102. relaybay-0.1.0/src/relaybay/web/templates/integrations.html +9 -0
  103. relaybay-0.1.0/src/relaybay/web/templates/login.html +21 -0
  104. relaybay-0.1.0/src/relaybay/web/templates/projects.html +9 -0
  105. relaybay-0.1.0/src/relaybay/web/templates/task.html +10 -0
  106. relaybay-0.1.0/tests/__init__.py +0 -0
  107. relaybay-0.1.0/tests/conftest.py +114 -0
  108. relaybay-0.1.0/tests/fixtures/claude_code_hooks.json +63 -0
  109. relaybay-0.1.0/tests/test_board.py +361 -0
  110. relaybay-0.1.0/tests/test_cli.py +46 -0
  111. relaybay-0.1.0/tests/test_config.py +100 -0
  112. relaybay-0.1.0/tests/test_demo.py +75 -0
  113. relaybay-0.1.0/tests/test_doctor.py +160 -0
  114. relaybay-0.1.0/tests/test_hooks.py +326 -0
  115. relaybay-0.1.0/tests/test_mcp.py +447 -0
  116. relaybay-0.1.0/tests/test_migrations.py +206 -0
  117. relaybay-0.1.0/tests/test_release.py +93 -0
  118. relaybay-0.1.0/tests/test_repo_hygiene.py +56 -0
  119. relaybay-0.1.0/tests/test_rules.py +374 -0
  120. relaybay-0.1.0/tests/test_security.py +194 -0
  121. relaybay-0.1.0/tests/test_service.py +319 -0
  122. relaybay-0.1.0/tests/test_sessions.py +235 -0
  123. relaybay-0.1.0/tests/test_setup.py +690 -0
  124. relaybay-0.1.0/tests/test_sse.py +132 -0
  125. relaybay-0.1.0/tests/test_tracker_archive.py +267 -0
  126. relaybay-0.1.0/tests/test_tracker_history.py +214 -0
@@ -0,0 +1,34 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ .venv/
5
+ .pytest_cache/
6
+ .ruff_cache/
7
+ .mypy_cache/
8
+ dist/
9
+ build/
10
+ site/
11
+ *.egg-info/
12
+
13
+ # Local data
14
+ .dev-data/
15
+ .demo-data/
16
+ gif-data/
17
+ *.sqlite
18
+ *.sqlite3
19
+ *.db
20
+ .env
21
+ .env.*
22
+ !.env.example
23
+
24
+ # Personal AI assistant settings (keep out of the public repo)
25
+ CLAUDE.md
26
+ CLAUDE.local.md
27
+ .claude/
28
+ .mcp.json
29
+
30
+ # OS / editors
31
+ .DS_Store
32
+ Thumbs.db
33
+ .idea/
34
+ .vscode/
@@ -0,0 +1,186 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project are documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project
6
+ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [Unreleased]
9
+
10
+ ## [0.1.0] - 2026-11-02
11
+
12
+ First public release: a local board and MCP server for many Claude Code sessions, installable with
13
+ one command (`uv tool install relaybay`, `uvx relaybay`, `pipx install relaybay` or the Docker
14
+ image), with Claude Code hooks for live session status, working rules served to every session,
15
+ `relaybay setup` and `relaybay doctor` for the machine setup, and a docs site.
16
+
17
+ ### Added
18
+
19
+ - Packaging and release: version `0.1.0` in `pyproject.toml` (the only place; `relaybay
20
+ --version` reads the installed metadata), wheel and sdist with the templates, static assets and
21
+ migrations, a `Dockerfile` (`python:3.12-slim`, non-root, `/data` volume) and a release workflow
22
+ on `v*` tags: build and check the artifacts, publish to PyPI by trusted publishing, push the
23
+ multi-arch image `ghcr.io/codenator81/relaybay:<version>` and `:latest`, create the GitHub
24
+ Release with this file's notes and deploy the docs.
25
+ - `relaybay doctor [--json]`: relaybay, Python and OS versions, data folder and token file, Claude
26
+ Code and its minimum supported version (2.0.0), the desktop app, the server with the same token,
27
+ MCP `initialize`, the hook endpoint, the rules hash against the running server, the hooks in the
28
+ user settings and the MCP registration. Read-only (it never creates the token); reports the
29
+ Claude Code files even when the server is down; the output has the shape of `setup --check
30
+ --json` and the exit code is 1 when an item fails.
31
+ - `relaybay demo --home <dir> [--force]`: seeds a neutral demo workspace (`acme-shop`, `demo-api`:
32
+ tasks in every stage with descriptions, progress and reports, tracker badges, a stale next step,
33
+ a decision, a desktop session shown as working). A folder that already holds a board is refused;
34
+ `--force` renames its database aside first.
35
+ - `/healthz` also returns `rules_hash`, the global rules the server started with.
36
+ - Docs: install on Windows, macOS and Linux (uv, uvx, pipx, Docker), "Install relaybay with your
37
+ coding agent" (an idempotent procedure and a copy-paste prompt), CLI, configuration and MCP
38
+ reference pages generated by `scripts/gen_reference.py` (CI fails when they drift).
39
+ - Community files: code of conduct (Contributor Covenant 2.1), security policy, governance note,
40
+ issue forms and a pull request template.
41
+ - Live session status from Claude Code hooks: `POST /hooks/claude-code` (Bearer token, same
42
+ Host/Origin rules as `/mcp`) maps `SessionStart` / `UserPromptSubmit` / `PreToolUse` to working
43
+ (with the tool name as activity), `Notification` to waiting, `Stop` to idle and `SessionEnd` to
44
+ ended, which also unbinds the session from its tasks (`task.session_unbound`, reason
45
+ `session_end`). Activity is coalesced to one `session.status_changed` event per session per 5 s.
46
+ Cards show a status dot on the "open in desktop" icon; the task dialog shows the status and the
47
+ last activity. Prompt text and tool input are never stored.
48
+ - Exact linking of hook sessions: the `SessionStart` answer tells the agent its hook session id,
49
+ and every write tool (and `task_bind_session`) accepts `hook_session`; the MCP instructions say
50
+ so. Without it, a hook session is linked by its working directory to the one desktop session bound
51
+ in that project; ambiguous cases stay unlinked and are listed on the Integrations page. Migration
52
+ `0007` adds `session.cc_session_id`, `activity_at` and `unlinked_reason`.
53
+ - `relaybay setup` (`--dry-run` default, `--apply`, `--remove`, `--check [--json]`, `--expect
54
+ <plan hash>`, `--mode command|http` with `command` as the default, `--claude-home`): detects
55
+ `claude` and its version and the desktop app, prints the exact diff of `~/.claude/settings.json`
56
+ and its plan hash, backs the file up before any write (through a symlink to its target), adds or
57
+ removes only relaybay's own hook entries (a command hook running `relaybay.hook_client` with
58
+ `--url …/hooks/claude-code`, or an http hook posting exactly to `/hooks/claude-code` on a
59
+ loopback or the configured host), never writes the token, refuses files that are not UTF-8 or
60
+ valid JSON, and prints the `claude mcp add` command instead of editing `~/.claude.json`.
61
+ `--check` also runs the hook's interpreter once. `relaybay hook` and
62
+ `python -m relaybay.hook_client`: a standard-library command hook that gives up after 0.3 s and
63
+ always exits 0.
64
+ - Board: **Integrations** page (header link) with detection, the plan, Apply / Remove / Run check
65
+ buttons (Apply and Remove write only the plan shown) and the unlinked hook sessions. Hook input
66
+ over 256 KB is dropped quietly (`204`). `relaybay serve --claude-home` / `RELAYBAY_CLAUDE_HOME`.
67
+ - Working rules: the MCP server instructions are a short working contract (snapshot first, pick or
68
+ create a task, keep next step / waiting on / progress current, `state · size · gist` reports,
69
+ `waiting_on` for decisions, `task_patch` for missing fields). Rules as structured data (report
70
+ format, stage requirements `report_since_stage_change` / `field_present`, description template,
71
+ guidance) with built-in defaults (a report before `test`, `progress` before `done`), a global
72
+ `[rules]` table in `config.toml` and per-project overrides in the new `project_rules` table
73
+ (migration `0006`); a config error stops the start, a broken project override is logged and
74
+ ignored (global rules apply, "project override ignored: …" is shown). Read through the tool `rules_get(project?)` and the
75
+ resources `relaybay://rules` and `relaybay://rules/{project}`; `project_snapshot` starts with
76
+ the rules hash. Stage moves that miss a rule succeed with a `Warning (rules)` line in the MCP
77
+ response, the board form and the event's `warnings` (`rules_mode = "warn"`, default), or are
78
+ refused (`rules_mode = "strict"`).
79
+ - `relaybay serve` (FastAPI + uvicorn, default `127.0.0.1:8765`) and `relaybay token [--rotate]`;
80
+ `python -m relaybay`; settings from `config.toml`, `RELAYBAY_*` environment variables and flags.
81
+ - SQLite storage (WAL, numbered migrations) for projects, tasks, reports, decisions, sessions and an
82
+ append-only event log; every write goes through one service layer and publishes an event.
83
+ - Token security: Bearer token on `/mcp` (and the reserved `/api` prefix), cookie login for the
84
+ board via `/login`, Host allow-list, Origin checks, CSRF protection for board edits,
85
+ `Content-Security-Policy`.
86
+ - MCP server (Streamable HTTP at `/mcp`) with the tools `project_list`, `project_upsert`,
87
+ `project_snapshot`, `task_list`, `task_get`, `task_create`, `task_update`, `task_set_stage`,
88
+ `task_bind_session`, `report_add`, `decision_add`, `events_since` and the resource
89
+ `relaybay://project/{slug}`.
90
+ - Board: projects list with per-stage counts, stage columns with cards, card editing, live updates
91
+ over Server-Sent Events with `Last-Event-ID` replay, a stage tab bar on narrow screens, light and
92
+ dark themes. htmx and its SSE extension are vendored.
93
+ - Configurable display labels for stages (`[stages.labels]`).
94
+ - Sign-in page: unauthenticated browser visits redirect to `/login`, which accepts the access
95
+ token in a form (CSRF-protected) and returns to the requested page.
96
+ - `relaybay serve` and `relaybay token` print their data folder; `/healthz` reports a public token
97
+ fingerprint (`token_id`) and `relaybay token` warns when the running server uses a different
98
+ token.
99
+ - Report state and size badges on cards and the task page (state coloured by meaning, size S/M/L,
100
+ both with tooltips); labels and tooltips configurable via `[reports.labels]` / `[reports.hints]`.
101
+ - Claude desktop app session links: write tools accept a desktop session id (`local_<uuid>`) and a
102
+ `session_title`; cards and the new task page (`/t/{key}`) show "Open in desktop" and a copy-link
103
+ button; the link template is configurable (`desktop_link_template`).
104
+ - Session binding history per task (`task_session`), shown on the task page and in `task_get`;
105
+ binding a session emits `task.session_bound`.
106
+ - Task `description` and `progress` (markdown, migration `0002` upgrades existing databases in
107
+ place): `task_create` and `task_update` accept both, `report_add` takes an optional `progress`
108
+ saved in the same transaction, `task_get` shows them in full and `project_snapshot` shortened.
109
+ - `task_unbind_session` MCP tool and an "Unbind session" button (with confirmation) on the board:
110
+ closes the binding, keeps the history and emits `task.session_unbound`; an optional `session`
111
+ refuses to unbind a session that took over meanwhile.
112
+ - Session aliases (migration `0003`): `task_bind_session` with a plain name on a task bound to a
113
+ desktop session keeps the desktop binding and records the name as that session's alias (event
114
+ `session.alias_added`); the name then resolves to the desktop session in writes, `task_list` and
115
+ `task_unbind_session`. Aliases are global; no alias is made for a name a plain session already
116
+ has (the call warns and changes nothing).
117
+ - Done column window and archive: the board's `done` column shows tasks closed within
118
+ `done_window_days` (default 7, `RELAYBAY_DONE_WINDOW_DAYS`); older ones are archived and shown
119
+ with "Show archived" (`?archived=1`). A search box filters cards by key or title (`?q=`) and also
120
+ searches the archive.
121
+ - External tracker mark (migration `0003`): task fields `tracker_ref`, `tracker_name`,
122
+ `tracker_url` (http/https only) and `tracker_logged`, accepted by `task_create` / `task_update`,
123
+ shown by `task_get` and `project_snapshot`, edited in the task dialog. Cards show the issue as a
124
+ badge (a link with a URL, ✓ when logged). Opt-in `require_tracker_log`
125
+ (`RELAYBAY_REQUIRE_TRACKER_LOG`, default false): done tasks without the mark show "not logged" and
126
+ are never archived.
127
+ - Next step freshness (migration `0004`, upgrades existing databases in place): `task_set_stage`
128
+ and `report_add` accept `next_step` and `waiting_on`, saved in the same transaction (`"-"`
129
+ clears them), and their descriptions ask sessions to keep both current. A next step set before
130
+ the task's last stage change shows muted with a "stale" marker on the card and in the task
131
+ dialog, and with `(stale)` in `task_get` / `project_snapshot`; writing it again over MCP (or editing it on the board) confirms it.
132
+ - Tracker history (migration `0005`, upgrades existing databases in place and backfills one entry
133
+ per task with an issue key): a new `tracker_ref` appends an entry and earlier ones stay; marking
134
+ the work log entered or not stamps `logged_at` / `unlogged_at` on the current entry. The task
135
+ dialog and `/t/<key>` show a "Tracker history" block and `task_get` a "Tracker history" section;
136
+ the card badge and `project_snapshot` keep showing only the current issue.
137
+ - Automatic unlog: when a logged task gets new work (a report, a changed `progress`, or a stage
138
+ move back out of `live` or `done` to an earlier stage), `tracker_logged` is cleared in the same
139
+ transaction with a `task.tracker_unlogged` event carrying the reason. Metadata edits (title,
140
+ branch, waiting on, next step, tracker fields) keep the mark; an explicit `tracker_logged` in
141
+ the same write wins. A new `tracker_ref` starts as not logged unless `tracker_logged` is passed
142
+ in the same write.
143
+ - `task_patch` MCP tool: changes any editable task fields given as one JSON object (`fields`),
144
+ with the same validation, clearing, stage-move and auto-unlog rules as `task_update` /
145
+ `task_set_stage` and optional `expected_version`; unknown names fail with the allowed list. The
146
+ editable fields come from one list that also drives write validation, the new resource
147
+ `relaybay://schema/task` and an "Editable fields: …" line at the end of `task_get`, so clients
148
+ that cached an older `task_update` schema can still set new fields. README and
149
+ `docs/mcp-tools.md` explain schema caching in long-running sessions.
150
+ - A test that keeps the repository English-only (no Cyrillic in `src/`, `docs/`, `tests/` and the
151
+ root markdown files).
152
+ - `"-"` clears a text field in `task_update` (and leaves it empty in `task_create`, clears
153
+ `progress` in `report_add`), since models cannot always send an empty string.
154
+
155
+ ### Changed
156
+
157
+ - Documentation restructured: `docs/SPEC.md` (shipped behaviour with stable `#spec-…` anchors),
158
+ `docs/ROADMAP.md` (versions 0.1.0 to 1.0 with status), `docs/architecture.md`, one design per
159
+ upcoming step in `docs/design/`, configuration and CLI reference pages, `docs/llms.txt`; the
160
+ former `docs/PLAN.md` is now a pointer to them. A MkDocs Material site (`mkdocs.yml`, optional
161
+ `docs` dependency group) is built with `mkdocs build --strict` on pull requests and deployed to
162
+ GitHub Pages from `main`.
163
+ - Docs and tests use English examples for custom stage and report labels; labels in any language
164
+ remain configurable, the defaults are English.
165
+
166
+ - Cards show only essentials: key, tracker badge (including "not logged") and an icon-only "open
167
+ in desktop" link in the top row, then title, "waiting on", branch and the next step (two lines).
168
+ Description, progress, the last report with its badges, the session name, "no session" and
169
+ "Copy link" moved off the card; the task dialog and `/t/<key>` still show all of them.
170
+ - Done cards no longer show "waiting on" and the next step; the task dialog shows them muted.
171
+ - The done column is no longer cut at 20 cards; it holds the window and is capped at 200 with a
172
+ note.
173
+ - Clicking a card opens the task in a dialog over the live board instead of an inline editor: the
174
+ full task (description, progress, reports, session history, desktop link, unbind) and its edit
175
+ form. The dialog has its own URL (`/p/<project>?task=<key>`), closes with Back, Esc or a click
176
+ outside, and is full screen on narrow screens. The task page `/t/<key>` shows the same details.
177
+
178
+ ### Fixed
179
+
180
+ - Clearing a field in the board's edit form (an empty input) now clears it; it used to keep the old
181
+ value.
182
+ - A long session title no longer widens a card past its column: the session badge shrinks with an
183
+ ellipsis and shows the full title on hover.
184
+
185
+ [Unreleased]: https://github.com/Codenator81/relaybay/compare/v0.1.0...HEAD
186
+ [0.1.0]: https://github.com/Codenator81/relaybay/releases/tag/v0.1.0
relaybay-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Aleksandrs Poltarjonoks
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.
@@ -0,0 +1,237 @@
1
+ Metadata-Version: 2.5
2
+ Name: relaybay
3
+ Version: 0.1.0
4
+ Summary: A live board and MCP server for coordinating many Claude Code sessions across projects.
5
+ Project-URL: Homepage, https://github.com/Codenator81/relaybay
6
+ Project-URL: Documentation, https://codenator81.github.io/relaybay/
7
+ Project-URL: Changelog, https://github.com/Codenator81/relaybay/blob/main/CHANGELOG.md
8
+ Project-URL: Issues, https://github.com/Codenator81/relaybay/issues
9
+ Author: Aleksandrs Poltarjonoks
10
+ License-Expression: MIT
11
+ License-File: LICENSE
12
+ Classifier: Development Status :: 3 - Alpha
13
+ Classifier: Environment :: Web Environment
14
+ Classifier: Framework :: FastAPI
15
+ Classifier: Operating System :: OS Independent
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Programming Language :: Python :: 3.13
19
+ Classifier: Topic :: Software Development
20
+ Requires-Python: >=3.12
21
+ Requires-Dist: aiosqlite>=0.20
22
+ Requires-Dist: fastapi>=0.115
23
+ Requires-Dist: jinja2>=3.1
24
+ Requires-Dist: markdown-it-py>=3.0
25
+ Requires-Dist: mcp<3,>=2
26
+ Requires-Dist: platformdirs>=4.2
27
+ Requires-Dist: python-multipart>=0.0.9
28
+ Requires-Dist: uvicorn>=0.30
29
+ Description-Content-Type: text/markdown
30
+
31
+ # relaybay
32
+
33
+ [![CI](https://github.com/Codenator81/relaybay/actions/workflows/ci.yml/badge.svg)](https://github.com/Codenator81/relaybay/actions/workflows/ci.yml)
34
+ [![PyPI](https://img.shields.io/pypi/v/relaybay)](https://pypi.org/project/relaybay/)
35
+ [![License: MIT](https://img.shields.io/badge/license-MIT-blue)](LICENSE)
36
+ [![Docs](https://github.com/Codenator81/relaybay/actions/workflows/docs.yml/badge.svg)](https://codenator81.github.io/relaybay/)
37
+
38
+ A live board and MCP server for people who run many Claude Code sessions across many repositories.
39
+ Sessions report their work through MCP tools; you watch **projects → tasks → stages → reports** update
40
+ in the browser, on the desktop or on your phone.
41
+
42
+ > **Status: early (0.1).** relaybay is built for my own workflow first and changes quickly. Expect
43
+ > rough edges; issues and ideas are welcome.
44
+
45
+ ![The relaybay board updating live while sessions report their work](https://raw.githubusercontent.com/Codenator81/relaybay/main/docs/assets/board.gif)
46
+
47
+ ## Quick start
48
+
49
+ ```bash
50
+ uv tool install relaybay # or: pipx install relaybay · or run it once: uvx relaybay
51
+ relaybay serve # prints the board's login link and the MCP URL
52
+ relaybay setup # shows how it connects Claude Code (then --apply --expect <hash>)
53
+ ```
54
+
55
+ Open the login link once; the browser keeps a cookie. `relaybay token` prints the token again with
56
+ the `claude mcp add …` command for Claude Code. Docker, Windows/macOS/Linux details and a procedure
57
+ your coding agent can follow for you:
58
+ [Install](https://codenator81.github.io/relaybay/getting-started/install/) ·
59
+ [Install with your coding agent](https://codenator81.github.io/relaybay/getting-started/agent-install/).
60
+ Something off? `relaybay doctor`.
61
+
62
+ **Documentation:** [codenator81.github.io/relaybay](https://codenator81.github.io/relaybay/) ·
63
+ [Specification](docs/SPEC.md) (how it behaves now) · [Roadmap](docs/ROADMAP.md) ·
64
+ [Architecture](docs/architecture.md)
65
+
66
+ ## Features
67
+
68
+ - **Board** — projects with per-stage counts; per project, columns `plan → dev → test → live → done`
69
+ with cards showing only the essentials: key, tracker badge, an "open in desktop" icon when a
70
+ desktop session works on the task, title, waiting-on person, branch and the next step. Click a
71
+ card to open the task in a dialog over the live board (its own URL,
72
+ `/p/<project>?task=<key>`, full screen on a phone): description and progress in full, reports,
73
+ session history, "Open in desktop", unbinding the session and editing the task. Each task also has
74
+ a page of its own (`/t/<key>`). Live updates over Server-Sent Events, catch-up after sleep or a
75
+ dropped connection, a stage tab bar on narrow screens.
76
+ - **Next step that keeps up** — sessions pass the next step and who acts next together with a
77
+ stage change or a report; a next step left over from before the last stage change shows muted
78
+ and marked "stale".
79
+ - **Done column and archive** — the `done` column shows tasks closed in the last
80
+ `done_window_days` (default 7); older ones are archived and come back with "Show archived" or a
81
+ search by key or title (`/p/<project>?archived=1`, `?q=…`). Done cards hide "waiting on" and the
82
+ next step.
83
+ - **External tracker mark** — a task can carry its issue in any tracker (tracker name, issue key,
84
+ optional link) and a "work log entered" mark. The card shows the issue as a badge at the top (a
85
+ link when a URL is set, ✓ once logged). With `require_tracker_log = true` a done task without
86
+ the mark shows "not logged" and stays out of the archive until it is marked. Every issue key a
87
+ task has had is kept in its tracker history (task dialog, `/t/<key>`, `task_get`), and new work
88
+ on a logged task (a report, a progress change, a move back from `live` or `done`) clears the
89
+ mark again, so it always means "the log covers everything done".
90
+ - **MCP server** — Streamable HTTP at `/mcp` in the same process: create and update tasks, change
91
+ stages, keep a task's description and progress summary current, add reports and decisions, bind
92
+ and unbind sessions, get a markdown snapshot of a project. A plain session name never replaces a
93
+ task's desktop session binding: it becomes that session's alias. `task_patch` takes any task
94
+ fields as one JSON object, so clients with an older tool schema can still set new fields.
95
+ - **Working rules** — the server tells every connected session how to work with the board (MCP
96
+ instructions: read the snapshot, pick a task, keep next step / waiting on / progress current,
97
+ report as `state · size · gist`) and serves the rules as data: report format, what a stage move
98
+ needs (by default a report before `test`, `progress` before `done`), a description template and
99
+ free-text guidance. Global rules come from `config.toml`, a project can override them; agents read
100
+ them through `rules_get` or `relaybay://rules/<project>`, and `project_snapshot` starts with the
101
+ rules hash. A stage move that misses a rule succeeds with a warning (or is refused with
102
+ `rules_mode = "strict"`), in MCP responses and on the board.
103
+ - **Local and private** — one process, SQLite, binds to `127.0.0.1`, token-protected, no telemetry,
104
+ no outbound calls, no CDN.
105
+
106
+ ## Try it with demo data
107
+
108
+ ```bash
109
+ relaybay demo --home ./relaybay-demo # acme-shop and demo-api, tasks in every stage
110
+ relaybay serve --home ./relaybay-demo --port 8766
111
+ ```
112
+
113
+ ## Connect Claude Code
114
+
115
+ ```bash
116
+ claude mcp add --transport http --scope user relaybay http://127.0.0.1:8765/mcp \
117
+ --header "Authorization: Bearer <token>"
118
+ ```
119
+
120
+ `user` scope adds relaybay once for all repositories. See
121
+ [docs/connect-claude-code.md](docs/connect-claude-code.md) for `.mcp.json` and a short instruction
122
+ snippet for your project's `CLAUDE.md` / `AGENTS.md` that tells the agent when to call the tools.
123
+
124
+ ### Live session status (hooks)
125
+
126
+ ```bash
127
+ relaybay setup # what it found, the exact diff and its hash
128
+ relaybay setup --apply --expect <hash> # adds relaybay's hooks to ~/.claude/settings.json
129
+ relaybay setup --check # end-to-end check, one ok/FAIL line per item
130
+ ```
131
+
132
+ The hooks let the board show whether each session is working, waiting for you, idle or gone, and
133
+ unbind a session from its task when it ends. Setup adds only its own entries (other hooks stay as
134
+ they are), never writes the token into the file, and `--remove` takes them out again. The same plan
135
+ and buttons are on the board under **Integrations**. Hooks stay silent when relaybay is not
136
+ running. Details: [docs/connect-claude-code.md](docs/connect-claude-code.md#3-live-session-status-hooks).
137
+
138
+ ### Schema changes and long-running sessions
139
+
140
+ A Claude Code session keeps the parameter schema of a tool it already loaded, even after relaybay
141
+ restarts and the client reconnects: new tools appear, but new parameters of an existing tool do
142
+ not. Use `task_patch(task, fields={...})` for fields your client does not know yet (the allowed
143
+ names are at the end of `task_get` and in `relaybay://schema/task`), or refresh the schemas by
144
+ reconnecting the server in the client (`/mcp` in the CLI) or starting a new session. See
145
+ [docs/mcp-tools.md](docs/mcp-tools.md#schema-changes-and-long-running-sessions).
146
+ The tool reference is in [docs/mcp-tools.md](docs/mcp-tools.md).
147
+
148
+ ## Configuration
149
+
150
+ Settings come from defaults, then `config.toml` in the data directory, then `RELAYBAY_*` environment
151
+ variables, then command-line flags.
152
+
153
+ | Setting | Default | Env | Flag |
154
+ |---|---|---|---|
155
+ | data directory | per-user data dir (`platformdirs`) | `RELAYBAY_HOME` | `--home` |
156
+ | bind address | `127.0.0.1` | `RELAYBAY_HOST` | `--host` |
157
+ | port | `8765` | `RELAYBAY_PORT` | `--port` |
158
+ | extra allowed Host names | none | `RELAYBAY_ALLOWED_HOSTS` (comma-separated) | — |
159
+ | desktop session link | `claude://claude.ai/epitaxy/{id}` | `RELAYBAY_DESKTOP_LINK_TEMPLATE` | — |
160
+ | days a done task stays in the done column | `7` | `RELAYBAY_DONE_WINDOW_DAYS` | — |
161
+ | keep done tasks without the tracker work log on the board | `false` | `RELAYBAY_REQUIRE_TRACKER_LOG` | — |
162
+ | what a stage move that misses a rule does: `warn` or `strict` | `warn` | `RELAYBAY_RULES_MODE` | — |
163
+ | folder with Claude Code's `.claude/` and `.claude.json` (setup, Integrations) | your home directory | `RELAYBAY_CLAUDE_HOME` | `--claude-home` |
164
+
165
+ The data directory holds `relaybay.sqlite`, the `token` file and the optional `config.toml`:
166
+
167
+ ```toml
168
+ port = 8765
169
+ allowed_hosts = ["my-laptop.lan"] # needed only when you bind to a LAN address
170
+ desktop_link_template = "claude://claude.ai/epitaxy/{id}" # {id} = desktop session id (local_…)
171
+ done_window_days = 7 # older done tasks are archived
172
+ require_tracker_log = false # true: done tasks without the tracker work log stay and show "not logged"
173
+ rules_mode = "warn" # "strict": a stage move that misses a rule is refused
174
+
175
+ [stages.labels] # display names; the stage keys stay plan/dev/test/live/done
176
+ dev = "in progress"
177
+ done = "shipped"
178
+
179
+ [reports.labels] # report badges: inspected/changed/verified/committed/pushed/blocked, S/M/L
180
+ verified = "checked"
181
+
182
+ [reports.hints] # badge tooltips
183
+ M = "medium change"
184
+
185
+ [rules] # global working rules, merged over the built-in defaults
186
+ guidance = "Ask the owner before anything goes live."
187
+ description_template = "Goal:\nWhy:\nDone when:"
188
+
189
+ [rules.report_format] # states/sizes: a subset of the built-in ones
190
+ sizes = ["S", "M", "L"]
191
+
192
+ [rules.stage_requirements] # per target stage; a list replaces the default, [] drops it
193
+ test = [{ kind = "report_since_stage_change" }]
194
+ done = [{ kind = "field_present", field = "progress" }]
195
+ ```
196
+
197
+ A rules error in `config.toml` (unknown key, stage, rule kind or field) stops `relaybay serve`
198
+ with a message that names the key. A broken project override never stops the server: it is
199
+ logged, the project falls back to the global rules, and `rules_get` and `project_snapshot` say
200
+ "project override ignored: <error>". Project overrides and the merge rules are described in
201
+ [docs/mcp-tools.md](docs/mcp-tools.md#working-rules).
202
+
203
+ `relaybay token --rotate` creates a new token; restart the server and update the Claude Code entry.
204
+
205
+ ### Troubleshooting: "token not valid"
206
+
207
+ Each data folder has its own token. `relaybay serve` prints the folder it uses (`Data folder: …`);
208
+ run `relaybay token` with the same `--home` (or `RELAYBAY_HOME`). `relaybay token` prints its folder
209
+ and warns when the server on the port uses a different token (another folder, or a rotation without
210
+ a restart). After `relaybay token --rotate`, restart the server. `relaybay doctor` checks this and
211
+ everything else in one command ([troubleshooting](https://codenator81.github.io/relaybay/how-to/troubleshooting/)).
212
+
213
+ ## Roadmap
214
+
215
+ - **0.1.0** — board, MCP tools, working rules, hooks and `relaybay setup`, packaging
216
+ (`uv tool install`, `uvx`, `pipx`, Docker), `relaybay doctor`, docs site, demo workspace.
217
+ - **0.2.0** — sidebar navigation and Inbox, comments to agents, project environments and access.
218
+ - **0.3.0** — review checklist with screenshots, memory and documents.
219
+ - **Later** — annotations, map and usage, rules versioning, intake, agents started from relaybay.
220
+
221
+ Details and status: [docs/ROADMAP.md](docs/ROADMAP.md). Designs of upcoming steps are in
222
+ [docs/design/](docs/design/index.md), decisions in [docs/adr/](docs/adr/). relaybay sends no
223
+ telemetry.
224
+
225
+ ## Contributing and feedback
226
+
227
+ - Questions, ideas, show and tell: [Discussions](https://github.com/Codenator81/relaybay/discussions).
228
+ - Bugs and feature requests: [issues](https://github.com/Codenator81/relaybay/issues/new/choose)
229
+ (include `relaybay doctor` output for bugs).
230
+ - Security problems: report privately, see [SECURITY.md](SECURITY.md).
231
+ - Code: [CONTRIBUTING.md](CONTRIBUTING.md); AI coding tools: [AGENTS.md](AGENTS.md). Everyone
232
+ follows the [Code of Conduct](CODE_OF_CONDUCT.md); how decisions are made:
233
+ [GOVERNANCE.md](GOVERNANCE.md).
234
+
235
+ ## License
236
+
237
+ [MIT](LICENSE)