brooklet 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 (69) hide show
  1. brooklet-0.1.0/.beads/.gitignore +49 -0
  2. brooklet-0.1.0/.beads/README.md +81 -0
  3. brooklet-0.1.0/.beads/backup/backup_state.json +13 -0
  4. brooklet-0.1.0/.beads/backup/comments.jsonl +0 -0
  5. brooklet-0.1.0/.beads/backup/config.jsonl +11 -0
  6. brooklet-0.1.0/.beads/backup/dependencies.jsonl +5 -0
  7. brooklet-0.1.0/.beads/backup/events.jsonl +12 -0
  8. brooklet-0.1.0/.beads/backup/issues.jsonl +8 -0
  9. brooklet-0.1.0/.beads/backup/labels.jsonl +0 -0
  10. brooklet-0.1.0/.beads/config.yaml +55 -0
  11. brooklet-0.1.0/.beads/dolt-monitor.pid +1 -0
  12. brooklet-0.1.0/.beads/dolt-server.activity +1 -0
  13. brooklet-0.1.0/.beads/dolt-server.port +1 -0
  14. brooklet-0.1.0/.beads/hooks/post-checkout +9 -0
  15. brooklet-0.1.0/.beads/hooks/post-merge +9 -0
  16. brooklet-0.1.0/.beads/hooks/pre-commit +9 -0
  17. brooklet-0.1.0/.beads/hooks/pre-push +9 -0
  18. brooklet-0.1.0/.beads/hooks/prepare-commit-msg +9 -0
  19. brooklet-0.1.0/.beads/interactions.jsonl +0 -0
  20. brooklet-0.1.0/.beads/metadata.json +6 -0
  21. brooklet-0.1.0/.github/workflows/publish.yml +24 -0
  22. brooklet-0.1.0/.github/workflows/test.yml +39 -0
  23. brooklet-0.1.0/.gitignore +17 -0
  24. brooklet-0.1.0/.python-version +1 -0
  25. brooklet-0.1.0/CLAUDE.md +78 -0
  26. brooklet-0.1.0/LICENSE +21 -0
  27. brooklet-0.1.0/PKG-INFO +191 -0
  28. brooklet-0.1.0/README.md +171 -0
  29. brooklet-0.1.0/docs/superpowers/plans/2026-03-22-pytest-adapter.md +1444 -0
  30. brooklet-0.1.0/docs/superpowers/specs/2026-03-22-pytest-adapter-design.md +192 -0
  31. brooklet-0.1.0/examples/ci_health_check.py +91 -0
  32. brooklet-0.1.0/pyproject.toml +102 -0
  33. brooklet-0.1.0/src/brooklet/__init__.py +23 -0
  34. brooklet-0.1.0/src/brooklet/consumer.py +382 -0
  35. brooklet-0.1.0/src/brooklet/contrib/__init__.py +2 -0
  36. brooklet-0.1.0/src/brooklet/contrib/claude_analytics.py +665 -0
  37. brooklet-0.1.0/src/brooklet/contrib/pytest_analytics.py +368 -0
  38. brooklet-0.1.0/src/brooklet/envelope.py +72 -0
  39. brooklet-0.1.0/src/brooklet/offsets.py +90 -0
  40. brooklet-0.1.0/src/brooklet/registry.py +123 -0
  41. brooklet-0.1.0/src/brooklet/stream.py +118 -0
  42. brooklet-0.1.0/src/brooklet/types.py +64 -0
  43. brooklet-0.1.0/tests/__init__.py +0 -0
  44. brooklet-0.1.0/tests/bdd/__init__.py +0 -0
  45. brooklet-0.1.0/tests/bdd/conftest.py +33 -0
  46. brooklet-0.1.0/tests/bdd/features/glob_follow.feature +41 -0
  47. brooklet-0.1.0/tests/bdd/features/produce.feature +83 -0
  48. brooklet-0.1.0/tests/bdd/features/pytest_adapter.feature +50 -0
  49. brooklet-0.1.0/tests/bdd/features/scout.feature +100 -0
  50. brooklet-0.1.0/tests/bdd/steps/__init__.py +0 -0
  51. brooklet-0.1.0/tests/bdd/steps/test_glob_follow.py +265 -0
  52. brooklet-0.1.0/tests/bdd/steps/test_produce.py +253 -0
  53. brooklet-0.1.0/tests/bdd/steps/test_pytest_adapter.py +229 -0
  54. brooklet-0.1.0/tests/bdd/steps/test_scout.py +402 -0
  55. brooklet-0.1.0/tests/conftest.py +135 -0
  56. brooklet-0.1.0/tests/pytest_fixtures.py +188 -0
  57. brooklet-0.1.0/tests/scout_helpers.py +38 -0
  58. brooklet-0.1.0/tests/test_consumer.py +504 -0
  59. brooklet-0.1.0/tests/test_consumer_follow.py +397 -0
  60. brooklet-0.1.0/tests/test_envelope.py +69 -0
  61. brooklet-0.1.0/tests/test_integration.py +98 -0
  62. brooklet-0.1.0/tests/test_offsets.py +90 -0
  63. brooklet-0.1.0/tests/test_produce.py +217 -0
  64. brooklet-0.1.0/tests/test_pytest_analytics.py +396 -0
  65. brooklet-0.1.0/tests/test_registry.py +84 -0
  66. brooklet-0.1.0/tests/test_scout.py +567 -0
  67. brooklet-0.1.0/tests/test_stream.py +94 -0
  68. brooklet-0.1.0/tests/test_types.py +64 -0
  69. brooklet-0.1.0/uv.lock +437 -0
@@ -0,0 +1,49 @@
1
+ # Dolt database (managed by Dolt, not git)
2
+ dolt/
3
+ dolt-access.lock
4
+
5
+ # Runtime files
6
+ bd.sock
7
+ bd.sock.startlock
8
+ sync-state.json
9
+ last-touched
10
+
11
+ # Local version tracking (prevents upgrade notification spam after git ops)
12
+ .local_version
13
+
14
+ # Worktree redirect file (contains relative path to main repo's .beads/)
15
+ # Must not be committed as paths would be wrong in other clones
16
+ redirect
17
+
18
+ # Sync state (local-only, per-machine)
19
+ # These files are machine-specific and should not be shared across clones
20
+ .sync.lock
21
+ export-state/
22
+
23
+ # Ephemeral store (SQLite - wisps/molecules, intentionally not versioned)
24
+ ephemeral.sqlite3
25
+ ephemeral.sqlite3-journal
26
+ ephemeral.sqlite3-wal
27
+ ephemeral.sqlite3-shm
28
+
29
+ # Dolt server management (auto-started by bd)
30
+ dolt-server.pid
31
+ dolt-server.log
32
+ dolt-server.lock
33
+
34
+ # Legacy files (from pre-Dolt versions)
35
+ *.db
36
+ *.db?*
37
+ *.db-journal
38
+ *.db-wal
39
+ *.db-shm
40
+ db.sqlite
41
+ bd.db
42
+ daemon.lock
43
+ daemon.log
44
+ daemon-*.log.gz
45
+ daemon.pid
46
+ # NOTE: Do NOT add negation patterns here.
47
+ # They would override fork protection in .git/info/exclude.
48
+ # Config files (metadata.json, config.yaml) are tracked by git by default
49
+ # since no pattern above ignores them.
@@ -0,0 +1,81 @@
1
+ # Beads - AI-Native Issue Tracking
2
+
3
+ Welcome to Beads! This repository uses **Beads** for issue tracking - a modern, AI-native tool designed to live directly in your codebase alongside your code.
4
+
5
+ ## What is Beads?
6
+
7
+ Beads is issue tracking that lives in your repo, making it perfect for AI coding agents and developers who want their issues close to their code. No web UI required - everything works through the CLI and integrates seamlessly with git.
8
+
9
+ **Learn more:** [github.com/steveyegge/beads](https://github.com/steveyegge/beads)
10
+
11
+ ## Quick Start
12
+
13
+ ### Essential Commands
14
+
15
+ ```bash
16
+ # Create new issues
17
+ bd create "Add user authentication"
18
+
19
+ # View all issues
20
+ bd list
21
+
22
+ # View issue details
23
+ bd show <issue-id>
24
+
25
+ # Update issue status
26
+ bd update <issue-id> --claim
27
+ bd update <issue-id> --status done
28
+
29
+ # Sync with Dolt remote
30
+ bd dolt push
31
+ ```
32
+
33
+ ### Working with Issues
34
+
35
+ Issues in Beads are:
36
+ - **Git-native**: Stored in `.beads/issues.jsonl` and synced like code
37
+ - **AI-friendly**: CLI-first design works perfectly with AI coding agents
38
+ - **Branch-aware**: Issues can follow your branch workflow
39
+ - **Always in sync**: Auto-syncs with your commits
40
+
41
+ ## Why Beads?
42
+
43
+ ✨ **AI-Native Design**
44
+ - Built specifically for AI-assisted development workflows
45
+ - CLI-first interface works seamlessly with AI coding agents
46
+ - No context switching to web UIs
47
+
48
+ 🚀 **Developer Focused**
49
+ - Issues live in your repo, right next to your code
50
+ - Works offline, syncs when you push
51
+ - Fast, lightweight, and stays out of your way
52
+
53
+ 🔧 **Git Integration**
54
+ - Automatic sync with git commits
55
+ - Branch-aware issue tracking
56
+ - Intelligent JSONL merge resolution
57
+
58
+ ## Get Started with Beads
59
+
60
+ Try Beads in your own projects:
61
+
62
+ ```bash
63
+ # Install Beads
64
+ curl -sSL https://raw.githubusercontent.com/steveyegge/beads/main/scripts/install.sh | bash
65
+
66
+ # Initialize in your repo
67
+ bd init
68
+
69
+ # Create your first issue
70
+ bd create "Try out Beads"
71
+ ```
72
+
73
+ ## Learn More
74
+
75
+ - **Documentation**: [github.com/steveyegge/beads/docs](https://github.com/steveyegge/beads/tree/main/docs)
76
+ - **Quick Start Guide**: Run `bd quickstart`
77
+ - **Examples**: [github.com/steveyegge/beads/examples](https://github.com/steveyegge/beads/tree/main/examples)
78
+
79
+ ---
80
+
81
+ *Beads: Issue tracking that moves at the speed of thought* ⚡
@@ -0,0 +1,13 @@
1
+ {
2
+ "last_dolt_commit": "v15tq1j1hfei89ikmihtn40r162pl7c9",
3
+ "last_event_id": 0,
4
+ "timestamp": "2026-03-22T23:50:18.895382Z",
5
+ "counts": {
6
+ "issues": 8,
7
+ "events": 12,
8
+ "comments": 0,
9
+ "dependencies": 5,
10
+ "labels": 0,
11
+ "config": 11
12
+ }
13
+ }
File without changes
@@ -0,0 +1,11 @@
1
+ {"key":"auto_compact_enabled","value":"false"}
2
+ {"key":"compact_batch_size","value":"50"}
3
+ {"key":"compact_parallel_workers","value":"5"}
4
+ {"key":"compact_tier1_days","value":"30"}
5
+ {"key":"compact_tier1_dep_levels","value":"2"}
6
+ {"key":"compact_tier2_commits","value":"100"}
7
+ {"key":"compact_tier2_days","value":"90"}
8
+ {"key":"compact_tier2_dep_levels","value":"5"}
9
+ {"key":"compaction_enabled","value":"false"}
10
+ {"key":"issue_prefix","value":"brooklet"}
11
+ {"key":"schema_version","value":"6"}
@@ -0,0 +1,5 @@
1
+ {"created_at":"2026-03-22T14:05:02Z","created_by":"Joshua Oliphant","depends_on_id":"brooklet-cnu","issue_id":"brooklet-0gb","type":"blocks"}
2
+ {"created_at":"2026-03-22T14:05:02Z","created_by":"Joshua Oliphant","depends_on_id":"brooklet-cnu","issue_id":"brooklet-cfq","type":"blocks"}
3
+ {"created_at":"2026-03-22T14:05:02Z","created_by":"Joshua Oliphant","depends_on_id":"brooklet-d23","issue_id":"brooklet-cnu","type":"blocks"}
4
+ {"created_at":"2026-03-22T14:05:02Z","created_by":"Joshua Oliphant","depends_on_id":"brooklet-cnu","issue_id":"brooklet-cs0","type":"blocks"}
5
+ {"created_at":"2026-03-22T14:05:02Z","created_by":"Joshua Oliphant","depends_on_id":"brooklet-d23","issue_id":"brooklet-yh5","type":"blocks"}
@@ -0,0 +1,12 @@
1
+ {"actor":"Joshua Oliphant","comment":null,"created_at":"2026-03-15T07:13:12Z","event_type":"created","id":1,"issue_id":"brooklet-a3m","new_value":"","old_value":""}
2
+ {"actor":"Joshua Oliphant","comment":null,"created_at":"2026-03-15T07:13:15Z","event_type":"created","id":2,"issue_id":"brooklet-1mw","new_value":"","old_value":""}
3
+ {"actor":"Joshua Oliphant","comment":null,"created_at":"2026-03-22T14:04:49Z","event_type":"created","id":3,"issue_id":"brooklet-d23","new_value":"","old_value":""}
4
+ {"actor":"Joshua Oliphant","comment":null,"created_at":"2026-03-22T14:04:51Z","event_type":"created","id":4,"issue_id":"brooklet-cnu","new_value":"","old_value":""}
5
+ {"actor":"Joshua Oliphant","comment":null,"created_at":"2026-03-22T14:04:52Z","event_type":"created","id":5,"issue_id":"brooklet-cs0","new_value":"","old_value":""}
6
+ {"actor":"Joshua Oliphant","comment":null,"created_at":"2026-03-22T14:04:53Z","event_type":"created","id":6,"issue_id":"brooklet-cfq","new_value":"","old_value":""}
7
+ {"actor":"Joshua Oliphant","comment":null,"created_at":"2026-03-22T14:04:55Z","event_type":"created","id":7,"issue_id":"brooklet-0gb","new_value":"","old_value":""}
8
+ {"actor":"Joshua Oliphant","comment":null,"created_at":"2026-03-22T14:04:57Z","event_type":"created","id":8,"issue_id":"brooklet-yh5","new_value":"","old_value":""}
9
+ {"actor":"Joshua Oliphant","comment":null,"created_at":"2026-03-22T15:14:28Z","event_type":"closed","id":9,"issue_id":"brooklet-a3m","new_value":"Fixed and merged to main","old_value":""}
10
+ {"actor":"Joshua Oliphant","comment":null,"created_at":"2026-03-22T15:14:28Z","event_type":"closed","id":10,"issue_id":"brooklet-1mw","new_value":"Fixed and merged to main","old_value":""}
11
+ {"actor":"Joshua Oliphant","comment":null,"created_at":"2026-03-22T15:29:36Z","event_type":"closed","id":11,"issue_id":"brooklet-d23","new_value":"Closed","old_value":""}
12
+ {"actor":"Joshua Oliphant","comment":null,"created_at":"2026-03-22T15:29:36Z","event_type":"closed","id":12,"issue_id":"brooklet-cnu","new_value":"Closed","old_value":""}
@@ -0,0 +1,8 @@
1
+ {"acceptance_criteria":"","actor":"","agent_state":"","assignee":null,"await_id":"","await_type":"","close_reason":"","closed_at":null,"closed_by_session":"","compacted_at":null,"compacted_at_commit":null,"compaction_level":0,"content_hash":"a4706606998f7122c072f4a9c85307daa848c5a01418ccb59bc06e4d22218255","created_at":"2026-03-22T21:04:56Z","created_by":"Joshua Oliphant","crystallizes":0,"defer_until":null,"description":"Aggregation consumer that reads from multiple project pytest topics and produces a combined pytest/portfolio topic with health metrics per project.","design":"","due_at":null,"ephemeral":0,"estimated_minutes":null,"event_kind":"","external_ref":null,"hook_bead":"","id":"brooklet-0gb","is_template":0,"issue_type":"feature","last_activity":null,"metadata":"{}","mol_type":"","notes":"","original_size":null,"owner":"joshua.oliphant@hey.com","payload":"","pinned":0,"priority":4,"quality_score":null,"rig":"","role_bead":"","role_type":"","sender":"","source_repo":"","source_system":"","spec_id":"","status":"open","target":"","timeout_ns":0,"title":"pytest adapter: cross-project aggregation (AC-9)","updated_at":"2026-03-22T21:04:56Z","waiters":"","wisp_type":"","work_type":""}
2
+ {"acceptance_criteria":"","actor":"","agent_state":"","assignee":null,"await_id":"","await_type":"","close_reason":"Fixed and merged to main","closed_at":"2026-03-22T22:14:29Z","closed_by_session":"","compacted_at":null,"compacted_at_commit":null,"compaction_level":0,"content_hash":"9197d082668987cf50556be198a23f5b568b44c7f6c055afe43c1ba0951296f7","created_at":"2026-03-15T14:13:15Z","created_by":"Joshua Oliphant","crystallizes":0,"defer_until":null,"description":"observer.join() in _iterate_glob_follow(), _iterate_follow(), and close() has no timeout. If the watchdog thread hangs, the application hangs on shutdown with no indication. Add a 5s timeout and log a warning if exceeded.","design":"","due_at":null,"ephemeral":0,"estimated_minutes":null,"event_kind":"","external_ref":null,"hook_bead":"","id":"brooklet-1mw","is_template":0,"issue_type":"bug","last_activity":null,"metadata":"{}","mol_type":"","notes":"","original_size":null,"owner":"joshua.oliphant@hey.com","payload":"","pinned":0,"priority":3,"quality_score":null,"rig":"","role_bead":"","role_type":"","sender":"","source_repo":"","source_system":"","spec_id":"","status":"closed","target":"","timeout_ns":0,"title":"Add timeout to observer.join() calls to prevent hang on shutdown","updated_at":"2026-03-22T22:14:29Z","waiters":"","wisp_type":"","work_type":""}
3
+ {"acceptance_criteria":"","actor":"","agent_state":"","assignee":null,"await_id":"","await_type":"","close_reason":"Fixed and merged to main","closed_at":"2026-03-22T22:14:29Z","closed_by_session":"","compacted_at":null,"compacted_at_commit":null,"compaction_level":0,"content_hash":"e0c235b2a2f41623c5d3c22f25129b5c05dfc50b394236a205e004fa5a058471","created_at":"2026-03-15T14:13:12Z","created_by":"Joshua Oliphant","crystallizes":0,"defer_until":null,"description":"The offset stores an integer index into a sorted file list. If files are added or removed between sessions, the index points to the wrong file — causing silent re-processing, skipped events, or IndexError. Needs a design decision (DEC-013) about switching to filename-based offset tracking. As a short-term mitigation, add a bounds check with warning log in _catch_up_glob().","design":"","due_at":null,"ephemeral":0,"estimated_minutes":null,"event_kind":"","external_ref":null,"hook_bead":"","id":"brooklet-a3m","is_template":0,"issue_type":"bug","last_activity":null,"metadata":"{}","mol_type":"","notes":"","original_size":null,"owner":"joshua.oliphant@hey.com","payload":"","pinned":0,"priority":2,"quality_score":null,"rig":"","role_bead":"","role_type":"","sender":"","source_repo":"","source_system":"","spec_id":"","status":"closed","target":"","timeout_ns":0,"title":"GlobOffset file_index is unstable across sessions with file adds/removes","updated_at":"2026-03-22T22:14:29Z","waiters":"","wisp_type":"","work_type":""}
4
+ {"acceptance_criteria":"","actor":"","agent_state":"","assignee":null,"await_id":"","await_type":"","close_reason":"","closed_at":null,"closed_by_session":"","compacted_at":null,"compacted_at_commit":null,"compaction_level":0,"content_hash":"d9c19b6de578b58e0f71a66a11bb3aa197bbdc1e5e2b9267c7b7240b0c42a338","created_at":"2026-03-22T21:04:54Z","created_by":"Joshua Oliphant","crystallizes":0,"defer_until":null,"description":"Cross-run analytics consumer that tracks per-test duration over time. Flags tests with \u003e50% duration increase vs baseline (first 3 runs average). Produces pytest/slow-trends topic.","design":"","due_at":null,"ephemeral":0,"estimated_minutes":null,"event_kind":"","external_ref":null,"hook_bead":"","id":"brooklet-cfq","is_template":0,"issue_type":"feature","last_activity":null,"metadata":"{}","mol_type":"","notes":"","original_size":null,"owner":"joshua.oliphant@hey.com","payload":"","pinned":0,"priority":3,"quality_score":null,"rig":"","role_bead":"","role_type":"","sender":"","source_repo":"","source_system":"","spec_id":"","status":"open","target":"","timeout_ns":0,"title":"pytest adapter: duration trend detection (AC-8)","updated_at":"2026-03-22T21:04:54Z","waiters":"","wisp_type":"","work_type":""}
5
+ {"acceptance_criteria":"","actor":"","agent_state":"","assignee":null,"await_id":"","await_type":"","close_reason":"Closed","closed_at":"2026-03-22T22:29:37Z","closed_by_session":"","compacted_at":null,"compacted_at_commit":null,"compaction_level":0,"content_hash":"c2cd4470eabe50d44cc39e4ebde4a044ae1d95e5559d8564432726c88760cda2","created_at":"2026-03-22T21:04:52Z","created_by":"Joshua Oliphant","crystallizes":0,"defer_until":null,"description":"First analytics consumer for the pytest adapter. Process a test run and produce a summary event to a derived topic: total/passed/failed/skipped/errored, duration, slowest 5 tests, failure details. Follows the scout 3-layer pattern (parse, consume, render).","design":"","due_at":null,"ephemeral":0,"estimated_minutes":null,"event_kind":"","external_ref":null,"hook_bead":"","id":"brooklet-cnu","is_template":0,"issue_type":"feature","last_activity":null,"metadata":"{}","mol_type":"","notes":"","original_size":null,"owner":"joshua.oliphant@hey.com","payload":"","pinned":0,"priority":2,"quality_score":null,"rig":"","role_bead":"","role_type":"","sender":"","source_repo":"","source_system":"","spec_id":"","status":"closed","target":"","timeout_ns":0,"title":"pytest adapter: summary stats consumer (AC-6)","updated_at":"2026-03-22T22:29:37Z","waiters":"","wisp_type":"","work_type":""}
6
+ {"acceptance_criteria":"","actor":"","agent_state":"","assignee":null,"await_id":"","await_type":"","close_reason":"","closed_at":null,"closed_by_session":"","compacted_at":null,"compacted_at_commit":null,"compaction_level":0,"content_hash":"0243f9827d4ca5d2937c615845b013df03167161748f072460c4167d8a982476","created_at":"2026-03-22T21:04:52Z","created_by":"Joshua Oliphant","crystallizes":0,"defer_until":null,"description":"Cross-run analytics consumer that identifies tests alternating between passed/failed. Reports flake rate and produces pytest/flaky topic. Simple heuristic: outcomes_differing_from_majority / total_runs.","design":"","due_at":null,"ephemeral":0,"estimated_minutes":null,"event_kind":"","external_ref":null,"hook_bead":"","id":"brooklet-cs0","is_template":0,"issue_type":"feature","last_activity":null,"metadata":"{}","mol_type":"","notes":"","original_size":null,"owner":"joshua.oliphant@hey.com","payload":"","pinned":0,"priority":3,"quality_score":null,"rig":"","role_bead":"","role_type":"","sender":"","source_repo":"","source_system":"","spec_id":"","status":"open","target":"","timeout_ns":0,"title":"pytest adapter: flaky test detection (AC-7)","updated_at":"2026-03-22T21:04:52Z","waiters":"","wisp_type":"","work_type":""}
7
+ {"acceptance_criteria":"","actor":"","agent_state":"","assignee":null,"await_id":"","await_type":"","close_reason":"Closed","closed_at":"2026-03-22T22:29:37Z","closed_by_session":"","compacted_at":null,"compacted_at_commit":null,"compaction_level":0,"content_hash":"3f1b1bce949867624447eda096ac6c00b29d62e322892481acc4df2aa11c05cc","created_at":"2026-03-22T21:04:50Z","created_by":"Joshua Oliphant","crystallizes":0,"defer_until":null,"description":"Part 1 of the pytest adapter. Register pytest-reportlog JSONL as brooklet topics (single-file and glob), filter to test outcomes, incremental consumption, and follow mode. Validates brooklet's three-layer architecture with a non-Claude-Code source.","design":"","due_at":null,"ephemeral":0,"estimated_minutes":null,"event_kind":"","external_ref":null,"hook_bead":"","id":"brooklet-d23","is_template":0,"issue_type":"feature","last_activity":null,"metadata":"{}","mol_type":"","notes":"","original_size":null,"owner":"joshua.oliphant@hey.com","payload":"","pinned":0,"priority":2,"quality_score":null,"rig":"","role_bead":"","role_type":"","sender":"","source_repo":"","source_system":"","spec_id":"","status":"closed","target":"","timeout_ns":0,"title":"pytest adapter: registration \u0026 consumption (AC-1 through AC-5)","updated_at":"2026-03-22T22:29:37Z","waiters":"","wisp_type":"","work_type":""}
8
+ {"acceptance_criteria":"","actor":"","agent_state":"","assignee":null,"await_id":"","await_type":"","close_reason":"","closed_at":null,"closed_by_session":"","compacted_at":null,"compacted_at_commit":null,"compaction_level":0,"content_hash":"de82f28a7cb1eb35a8f442ca7eb53aa8593762ffad4ad50e424d45e3f167beee","created_at":"2026-03-22T21:04:57Z","created_by":"Joshua Oliphant","crystallizes":0,"defer_until":null,"description":"Rich live terminal dashboard showing real-time test progress (pass/fail/skip counts, current test, progress bar) and historical run comparison view. Follows the scout render_rich pattern.","design":"","due_at":null,"ephemeral":0,"estimated_minutes":null,"event_kind":"","external_ref":null,"hook_bead":"","id":"brooklet-yh5","is_template":0,"issue_type":"feature","last_activity":null,"metadata":"{}","mol_type":"","notes":"","original_size":null,"owner":"joshua.oliphant@hey.com","payload":"","pinned":0,"priority":4,"quality_score":null,"rig":"","role_bead":"","role_type":"","sender":"","source_repo":"","source_system":"","spec_id":"","status":"open","target":"","timeout_ns":0,"title":"pytest adapter: live dashboard (AC-10, AC-11)","updated_at":"2026-03-22T21:04:57Z","waiters":"","wisp_type":"","work_type":""}
File without changes
@@ -0,0 +1,55 @@
1
+ # Beads Configuration File
2
+ # This file configures default behavior for all bd commands in this repository
3
+ # All settings can also be set via environment variables (BD_* prefix)
4
+ # or overridden with command-line flags
5
+
6
+ # Issue prefix for this repository (used by bd init)
7
+ # If not set, bd init will auto-detect from directory name
8
+ # Example: issue-prefix: "myproject" creates issues like "myproject-1", "myproject-2", etc.
9
+ # issue-prefix: ""
10
+
11
+ # Use no-db mode: load from JSONL, write back after each command
12
+ # When true, bd will use .beads/issues.jsonl as the source of truth
13
+ # instead of the Dolt database
14
+ # no-db: false
15
+
16
+ # Enable JSON output by default
17
+ # json: false
18
+
19
+ # Feedback title formatting for mutating commands (create/update/close/dep/edit)
20
+ # 0 = hide titles, N > 0 = truncate to N characters
21
+ # output:
22
+ # title-length: 255
23
+
24
+ # Default actor for audit trails (overridden by BD_ACTOR or --actor)
25
+ # actor: ""
26
+
27
+ # Export events (audit trail) to .beads/events.jsonl on each flush/sync
28
+ # When enabled, new events are appended incrementally using a high-water mark.
29
+ # Use 'bd export --events' to trigger manually regardless of this setting.
30
+ # events-export: false
31
+
32
+ # Multi-repo configuration (experimental - bd-307)
33
+ # Allows hydrating from multiple repositories and routing writes to the correct JSONL
34
+ # repos:
35
+ # primary: "." # Primary repo (where this database lives)
36
+ # additional: # Additional repos to hydrate from (read-only)
37
+ # - ~/beads-planning # Personal planning repo
38
+ # - ~/work-planning # Work planning repo
39
+
40
+ # JSONL backup (periodic export for off-machine recovery)
41
+ # Auto-enabled when a git remote exists. Override explicitly:
42
+ # backup:
43
+ # enabled: false # Disable auto-backup entirely
44
+ # interval: 15m # Minimum time between auto-exports
45
+ # git-push: false # Disable git push (export locally only)
46
+ # git-repo: "" # Separate git repo for backups (default: project repo)
47
+
48
+ # Integration settings (access with 'bd config get/set')
49
+ # These are stored in the database, not in this file:
50
+ # - jira.url
51
+ # - jira.project
52
+ # - linear.url
53
+ # - linear.api-key
54
+ # - github.org
55
+ # - github.repo
@@ -0,0 +1 @@
1
+ 93692
@@ -0,0 +1 @@
1
+ 1774217668
@@ -0,0 +1 @@
1
+ 14299
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env sh
2
+ # --- BEGIN BEADS INTEGRATION v0.57.0 ---
3
+ # This section is managed by beads. Do not remove these markers.
4
+ if command -v bd >/dev/null 2>&1; then
5
+ export BD_GIT_HOOK=1
6
+ bd hooks run post-checkout "$@"
7
+ _bd_exit=$?; if [ $_bd_exit -ne 0 ]; then exit $_bd_exit; fi
8
+ fi
9
+ # --- END BEADS INTEGRATION ---
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env sh
2
+ # --- BEGIN BEADS INTEGRATION v0.57.0 ---
3
+ # This section is managed by beads. Do not remove these markers.
4
+ if command -v bd >/dev/null 2>&1; then
5
+ export BD_GIT_HOOK=1
6
+ bd hooks run post-merge "$@"
7
+ _bd_exit=$?; if [ $_bd_exit -ne 0 ]; then exit $_bd_exit; fi
8
+ fi
9
+ # --- END BEADS INTEGRATION ---
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env sh
2
+ # --- BEGIN BEADS INTEGRATION v0.57.0 ---
3
+ # This section is managed by beads. Do not remove these markers.
4
+ if command -v bd >/dev/null 2>&1; then
5
+ export BD_GIT_HOOK=1
6
+ bd hooks run pre-commit "$@"
7
+ _bd_exit=$?; if [ $_bd_exit -ne 0 ]; then exit $_bd_exit; fi
8
+ fi
9
+ # --- END BEADS INTEGRATION ---
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env sh
2
+ # --- BEGIN BEADS INTEGRATION v0.57.0 ---
3
+ # This section is managed by beads. Do not remove these markers.
4
+ if command -v bd >/dev/null 2>&1; then
5
+ export BD_GIT_HOOK=1
6
+ bd hooks run pre-push "$@"
7
+ _bd_exit=$?; if [ $_bd_exit -ne 0 ]; then exit $_bd_exit; fi
8
+ fi
9
+ # --- END BEADS INTEGRATION ---
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env sh
2
+ # --- BEGIN BEADS INTEGRATION v0.57.0 ---
3
+ # This section is managed by beads. Do not remove these markers.
4
+ if command -v bd >/dev/null 2>&1; then
5
+ export BD_GIT_HOOK=1
6
+ bd hooks run prepare-commit-msg "$@"
7
+ _bd_exit=$?; if [ $_bd_exit -ne 0 ]; then exit $_bd_exit; fi
8
+ fi
9
+ # --- END BEADS INTEGRATION ---
File without changes
@@ -0,0 +1,6 @@
1
+ {
2
+ "database": "dolt",
3
+ "backend": "dolt",
4
+ "dolt_mode": "server",
5
+ "dolt_database": "brooklet"
6
+ }
@@ -0,0 +1,24 @@
1
+ name: publish
2
+ on:
3
+ release:
4
+ types: [published]
5
+
6
+ permissions:
7
+ id-token: write
8
+
9
+ jobs:
10
+ publish:
11
+ runs-on: ubuntu-latest
12
+ environment: pypi
13
+ steps:
14
+ - uses: actions/checkout@v4
15
+
16
+ - uses: astral-sh/setup-uv@v5
17
+
18
+ - run: uv python install 3.12
19
+
20
+ - name: Build package
21
+ run: uv build
22
+
23
+ - name: Publish to PyPI
24
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,39 @@
1
+ name: tests
2
+ on:
3
+ push:
4
+ branches: [main]
5
+ pull_request:
6
+ branches: [main]
7
+
8
+ jobs:
9
+ test:
10
+ runs-on: ubuntu-latest
11
+ strategy:
12
+ matrix:
13
+ python-version: ["3.12", "3.13"]
14
+
15
+ steps:
16
+ - uses: actions/checkout@v4
17
+
18
+ - uses: astral-sh/setup-uv@v5
19
+ with:
20
+ enable-cache: true
21
+
22
+ - run: uv python install ${{ matrix.python-version }}
23
+
24
+ - name: Install dependencies
25
+ run: uv sync --locked
26
+
27
+ - name: Lint
28
+ run: uv run ruff check .
29
+
30
+ - name: Run tests with report logging
31
+ run: uv run pytest -v --report-log=reports/test-results.jsonl
32
+
33
+ - name: Analyze test results with brooklet-pytest
34
+ run: uv run brooklet-pytest reports/test-results.jsonl
35
+
36
+ - name: Produce summaries and run CI health check
37
+ run: |
38
+ uv run brooklet-pytest reports/test-results.jsonl --output pytest/summaries
39
+ uv run python examples/ci_health_check.py reports/
@@ -0,0 +1,17 @@
1
+ # Python-generated files
2
+ __pycache__/
3
+ *.py[oc]
4
+ build/
5
+ dist/
6
+ wheels/
7
+ *.egg-info
8
+
9
+ # Virtual environments
10
+ .venv
11
+
12
+ # Dolt database files (added by bd init)
13
+ .dolt/
14
+ *.db
15
+
16
+ # Runtime logs
17
+ logs/
@@ -0,0 +1 @@
1
+ 3.12
@@ -0,0 +1,78 @@
1
+ # Brooklet — The SQLite of Event Streaming
2
+
3
+ Lightweight JSONL-based event streaming library. Adds consumer coordination (offsets, tailing, topic discovery) on top of append-only JSONL files that other tools already produce.
4
+
5
+ ## Architecture
6
+
7
+ Brooklet is a **consumer coordination layer**, not a message broker. External tools write JSONL; brooklet reads it with offset tracking.
8
+
9
+ ### Core Modules
10
+ - `envelope.py` — Metadata injection (_ts, _seq, _src): `wrap()` on read, `serialize()` on write
11
+ - `offsets.py` — Byte offset persistence per consumer group
12
+ - `registry.py` — Maps topic names to sources; supports external (registered) and local (produced)
13
+ - `consumer.py` — Batch and follow-mode iterators over JSONL files
14
+ - `stream.py` — Orchestrator: `register()`, `produce()`, `consume()`, `topics()`
15
+ - `__init__.py` — Public API: `brooklet.open(path)`
16
+
17
+ ### Contrib Adapters (3-layer pattern: parsing → consumer integration → CLI)
18
+ - `contrib/claude_analytics.py` — Claude Code session analytics (`brooklet-scout`)
19
+ - `contrib/pytest_analytics.py` — pytest-reportlog test run analytics (`brooklet-pytest`)
20
+
21
+ ### Key Decisions
22
+ - `produce()` is in core — consumers that transform and re-emit need a clean write path (DEC-011)
23
+ - Unified topic namespace with auto-registration — `produce()` auto-registers local topics (DEC-012)
24
+ - Source registration maps arbitrary external JSONL paths to topic names (DEC-007)
25
+ - Thin envelope with `_ts`, `_seq`, `_src` auto-injected on both read and write (DEC-004)
26
+ - watchdog for filesystem watching in follow mode (DEC-008)
27
+ - Python 3.12+ minimum (DEC-009)
28
+ - Path-style topic names (`scout/stats`) create nested directories
29
+ - Full design docs at `second_brain/projects/_active/brooklet/`
30
+
31
+ ### Data Layout
32
+ ```
33
+ <stream_dir>/
34
+ ├── <topic>/
35
+ │ └── data.jsonl # Produced events (local topics)
36
+ ├── <parent>/<child>/
37
+ │ └── data.jsonl # Path-style nested topics
38
+ └── .brooklet/
39
+ ├── sources.json # Registry (external + local sources)
40
+ └── offsets/
41
+ └── <group>-<topic>.json # Byte offset per consumer group
42
+ ```
43
+
44
+ ## Dev Commands
45
+
46
+ ```bash
47
+ uv run pytest -v # Run tests
48
+ uv run pytest -v --tb=short # Run tests with short traceback
49
+ uv run ruff check . # Lint
50
+ uv run ruff format . # Format
51
+ ```
52
+
53
+ ## Conventions
54
+ - All `.py` files start with 2-line `ABOUTME:` comment
55
+ - TDD: tests first, then minimal implementation
56
+ - Simple over clever — readability is the priority
57
+
58
+ ## Non-Interactive Shell Commands
59
+
60
+ **ALWAYS use non-interactive flags** with file operations to avoid hanging on confirmation prompts.
61
+
62
+ ```bash
63
+ cp -f source dest # NOT: cp source dest
64
+ mv -f source dest # NOT: mv source dest
65
+ rm -f file # NOT: rm file
66
+ rm -rf directory # NOT: rm -r directory
67
+ ```
68
+
69
+ Other commands: `apt-get -y`, `HOMEBREW_NO_AUTO_UPDATE=1 brew`, `scp -o BatchMode=yes`.
70
+
71
+ ## Session Completion
72
+
73
+ When ending a work session, complete ALL steps:
74
+
75
+ 1. Run quality gates (tests, linters) if code changed
76
+ 2. Commit all changes
77
+ 3. Push to remote — work is NOT complete until `git push` succeeds
78
+ 4. Provide context for next session
brooklet-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Joshua Oliphant
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.