diff --git a/.beads/beads.jsonl b/.beads/beads.jsonl index f50ba721..6c35340e 100644 --- a/.beads/beads.jsonl +++ b/.beads/beads.jsonl @@ -22,6 +22,7 @@ {"id":"bd-29c128e8","content_hash":"b93b210ddad4f38c993d184e2f7c897eb00cb2f9c8183224e27ff54e129bb1f7","title":"Update AGENTS.md with event-driven mode","description":"Document BEADS_DAEMON_MODE env var. Explain opt-in during Phase 1. Add troubleshooting for watcher failures.","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-28T16:20:02.433145-07:00","updated_at":"2025-10-30T17:05:26.040499-07:00","closed_at":"2025-10-29T15:53:24.019613-07:00"} {"id":"bd-2a01ad","content_hash":"3dcb5f171ea773fe3368f791a2ef71fbdda047bd8cc03356bde21b74b2b5ba86","title":"Sort JSONL by ID to reduce git merge conflicts","description":"With hash-based IDs, JSONL order is meaningless. By sorting issues alphabetically by ID during export, we can drastically reduce merge conflicts when multiple clones add issues simultaneously.\n\nCurrent behavior:\n- Issues appended to end of JSONL\n- Every multi-clone create causes merge conflict at EOF\n- Conflicts are trivial but annoying\n\nProposed solution:\n- Sort issues by ID before writing JSONL\n- Clone A adds test-a1b2c3 (early in file)\n- Clone B adds test-z9y8x7 (late in file) \n- Git merges cleanly - no conflict\n\nBenefits:\n- Much lower conflict rate (only when IDs alphabetically adjacent)\n- Deterministic and reproducible\n- Human-readable sorted order\n- Works with existing git merge\n\nImplementation:\n- Update export logic to sort by ID\n- Update import to handle sorted order\n- Update tests\n\nRelated: bd-165 (hash IDs), current multi-clone test failures","status":"closed","priority":1,"issue_type":"feature","created_at":"2025-10-30T19:53:09.61787-07:00","updated_at":"2025-10-30T19:57:04.307134-07:00","closed_at":"2025-10-30T19:57:04.307134-07:00"} {"id":"bd-2a491483","content_hash":"d1ffe0d966939abf9449b6157cf9fcf42342b3056bfa65aeffbfa913ff722928","title":"Child test","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-30T15:46:47.841563-07:00","updated_at":"2025-10-30T17:05:26.031068-07:00","closed_at":"2025-10-30T15:46:59.618715-07:00"} +{"id":"bd-2a70","content_hash":"928f6b71fa0fe60d5c6332f248a0e7c856df89b1f7186d9cc973958353ea1f49","title":"Remove remaining sequential ID test files and obsolete renumber command","description":"","status":"open","priority":2,"issue_type":"chore","created_at":"2025-10-30T21:51:25.156123-07:00","updated_at":"2025-10-30T21:51:25.156123-07:00","dependencies":[{"issue_id":"bd-2a70","depends_on_id":"bd-aa744b","type":"discovered-from","created_at":"2025-10-30T21:51:25.157562-07:00","created_by":"stevey"}]} {"id":"bd-2f388ca7","content_hash":"27498c808874010ee62da58e12434a6ae7c73f4659b2233aaf8dcd59566a907d","title":"Fix TestTwoCloneCollision timeout","description":"","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-10-28T14:11:25.219607-07:00","updated_at":"2025-10-30T17:05:26.03067-07:00","closed_at":"2025-10-28T16:12:26.286611-07:00"} {"id":"bd-317ddbbf","content_hash":"81a74ccf29037e5a780b12540a4059bab98b9a790a5a043a68118fc00a083cda","title":"Add BEADS_DAEMON_MODE flag handling","description":"Add environment variable BEADS_DAEMON_MODE (values: poll, events). Default to 'poll' for Phase 1. Wire into daemon startup to select runEventLoop vs runEventDrivenLoop.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-28T16:20:02.433638-07:00","updated_at":"2025-10-30T17:05:26.041122-07:00","closed_at":"2025-10-28T12:31:47.819136-07:00"} {"id":"bd-31aab707","title":"Unit tests for FileWatcher","description":"Test watcher detects JSONL changes. Test git ref changes trigger import. Test debounce integration. Test watcher recovery from file removal/rename.","status":"open","priority":1,"issue_type":"task","created_at":"2025-10-29T11:30:59.842317-07:00","updated_at":"2025-10-30T17:05:25.993816-07:00"} @@ -123,7 +124,7 @@ {"id":"bd-a5e2bd80.9","content_hash":"cf15dbd5b7dbc10b54ea8d0d173899983bcdc0775b799e77c9334ec3f9fcba14","title":"Update MCP server for hash IDs","description":"Update beads-mcp server to support hash IDs and aliases.\n\n## Changes Needed\n\n### 1. MCP Function Signatures (No Change)\nFunctions already use issue IDs as strings, so they work with hash IDs:\n\n```python\n# These already work!\nbeads_show(issue_id: str) # Accepts bd-af78e9a2 or #42\nbeads_update(issue_id: str, ...) # Accepts both formats\nbeads_close(issue_ids: List[str]) # Accepts both formats\n```\n\n### 2. Add Alias Resolution Helper\nFile: integrations/beads-mcp/src/beads_mcp/server.py\n\n```python\ndef resolve_issue_id(issue_id: str) -\u003e str:\n \"\"\"Resolve alias to hash ID if needed.\"\"\"\n # Hash ID: pass through\n if issue_id.startswith('bd-') and len(issue_id) == 11:\n return issue_id\n \n # Alias: #42 or 42\n alias_str = issue_id.lstrip('#')\n try:\n alias = int(alias_str)\n # Call bd to resolve\n result = subprocess.run(\n ['bd', 'alias', 'find', f'bd-{alias}'],\n capture_output=True, text=True\n )\n if result.returncode == 0:\n return result.stdout.strip()\n except ValueError:\n pass\n \n # Invalid format\n raise ValueError(f\"Invalid issue ID: {issue_id}\")\n```\n\n### 3. Update Response Formatting\nShow aliases in responses:\n\n```python\n@server.call_tool()\nasync def beads_show(issue_id: str) -\u003e List[TextContent]:\n resolved_id = resolve_issue_id(issue_id)\n \n result = subprocess.run(['bd', 'show', resolved_id], ...)\n \n # Parse response and add alias info\n # Format: \"bd-af78e9a2 (alias: #42)\"\n ...\n```\n\n### 4. Add beads_alias_* Functions\n\n```python\n@server.call_tool()\nasync def beads_alias_list() -\u003e List[TextContent]:\n \"\"\"List all alias mappings.\"\"\"\n result = subprocess.run(['bd', 'alias', 'list'], ...)\n return [TextContent(type=\"text\", text=result.stdout)]\n\n@server.call_tool()\nasync def beads_alias_set(alias: int, issue_id: str) -\u003e List[TextContent]:\n \"\"\"Manually assign alias to issue.\"\"\"\n result = subprocess.run(['bd', 'alias', 'set', str(alias), issue_id], ...)\n return [TextContent(type=\"text\", text=result.stdout)]\n\n@server.call_tool()\nasync def beads_alias_compact() -\u003e List[TextContent]:\n \"\"\"Compact aliases to fill gaps.\"\"\"\n result = subprocess.run(['bd', 'alias', 'compact'], ...)\n return [TextContent(type=\"text\", text=result.stdout)]\n```\n\n### 5. Update Documentation\nFile: integrations/beads-mcp/README.md\n\n```markdown\n## Issue IDs (v2.0+)\n\nThe MCP server accepts both hash IDs and aliases:\n\n```python\n# Using hash IDs\nawait beads_show(issue_id=\"bd-af78e9a2\")\n\n# Using aliases\nawait beads_show(issue_id=\"#42\")\nawait beads_show(issue_id=\"42\") # Shorthand\n```\n\n## Alias Management\n\nNew functions for alias control:\n\n- `beads_alias_list()` - List all alias mappings\n- `beads_alias_set(alias, issue_id)` - Manually assign alias\n- `beads_alias_compact()` - Compact aliases to fill gaps\n\n## Migration\n\nAfter migrating to hash IDs:\n1. Update beads-mcp: `pip install --upgrade beads-mcp`\n2. Restart MCP server\n3. All existing workflows continue to work\n```\n\n### 6. Version Compatibility\nDetect and handle both v1.x and v2.0 formats:\n\n```python\ndef detect_beads_version() -\u003e str:\n \"\"\"Detect if beads is using sequential or hash IDs.\"\"\"\n result = subprocess.run(['bd', 'list', '-n', '1'], ...)\n first_id = parse_first_issue_id(result.stdout)\n \n if first_id.startswith('bd-') and len(first_id) \u003e 11:\n return '2.0' # Hash ID\n else:\n return '1.x' # Sequential ID\n\n# On startup\nbeads_version = detect_beads_version()\nlogger.info(f\"Detected beads version: {beads_version}\")\n```\n\n## Testing\n\n### Unit Tests\nFile: integrations/beads-mcp/tests/test_hash_ids.py\n\n```python\ndef test_resolve_hash_id():\n \"\"\"Hash IDs pass through unchanged.\"\"\"\n assert resolve_issue_id(\"bd-af78e9a2\") == \"bd-af78e9a2\"\n\ndef test_resolve_alias():\n \"\"\"Aliases resolve to hash IDs.\"\"\"\n # Mock bd alias find command\n assert resolve_issue_id(\"#42\") == \"bd-af78e9a2\"\n assert resolve_issue_id(\"42\") == \"bd-af78e9a2\"\n\ndef test_invalid_id():\n \"\"\"Invalid IDs raise ValueError.\"\"\"\n with pytest.raises(ValueError):\n resolve_issue_id(\"invalid\")\n```\n\n### Integration Tests\n```python\nasync def test_show_with_hash_id(mcp_server):\n result = await mcp_server.beads_show(issue_id=\"bd-af78e9a2\")\n assert \"bd-af78e9a2\" in result[0].text\n\nasync def test_show_with_alias(mcp_server):\n result = await mcp_server.beads_show(issue_id=\"#42\")\n assert \"bd-af78e9a2\" in result[0].text # Resolved\n```\n\n## Backward Compatibility\nThe MCP server should work with both:\n- Beads v1.x (sequential IDs)\n- Beads v2.0+ (hash IDs)\n\nDetection happens at runtime based on issue ID format.\n\n## Files to Modify\n- integrations/beads-mcp/src/beads_mcp/server.py\n- integrations/beads-mcp/README.md\n- integrations/beads-mcp/tests/test_hash_ids.py (new)\n- integrations/beads-mcp/pyproject.toml (bump version)\n\n## Deployment\n```bash\ncd integrations/beads-mcp\n# Bump version to 2.0.0\npoetry version 2.0.0\n# Publish to PyPI\npoetry publish --build\n```","status":"open","priority":1,"issue_type":"task","created_at":"2025-10-29T21:28:45.256074-07:00","updated_at":"2025-10-30T17:05:26.015489-07:00","dependencies":[{"issue_id":"bd-a5e2bd80.9","depends_on_id":"bd-a5e2bd80","type":"parent-child","created_at":"2025-10-29T21:28:45.257315-07:00","created_by":"stevey"},{"issue_id":"bd-a5e2bd80.9","depends_on_id":"bd-67335f92","type":"blocks","created_at":"2025-10-29T21:28:45.258057-07:00","created_by":"stevey"},{"issue_id":"bd-a5e2bd80.9","depends_on_id":"bd-a5e2bd80.3","type":"blocks","created_at":"2025-10-30T17:00:11.092331-07:00","created_by":"import-remap"}]} {"id":"bd-a6abe1c7","content_hash":"2a102864134b5192b5ee4e2a773cb4860b4330c9f3242b094ce8e92b01d20d80","title":"Implement hierarchical child ID generation","description":"Implement sequential child ID generation within parent contexts.\n\n## Function Signature\n```go\nfunc (s *SQLiteStorage) getNextChildID(ctx context.Context, parentID string) (string, error)\n```\n\n## Logic\n1. Insert or update child_counters for parent_id\n2. Return incremented counter\n3. Format as parentID.{counter}\n4. Works at any depth (bd-a3f8e9.1 → bd-a3f8e9.1.5)\n\n## Collision Handling\n- In single-player mode: No collisions (sequential)\n- In multi-player mode (future): Rare collisions, manual resolution needed\n- Epic ownership makes collisions naturally rare\n\n## Integration\n- Called from CreateIssue when --parent flag is used\n- Validates parent exists and depth \u003c= 3","status":"open","priority":1,"issue_type":"task","created_at":"2025-10-30T17:00:11.081086-07:00","updated_at":"2025-10-30T17:05:26.010798-07:00"} {"id":"bd-a9699011","content_hash":"87d969cf57e247ebfac4f052a9ecbd1254bc55070b87b5ffb78a2b6ee2afddb6","title":"GH#146: No color showing in terminal for some users","description":"User reports color not working in macOS (Taho 26.0.1) with iTerm 3.6.4 and Terminal.app, despite color working elsewhere in terminal. Python rich and printf escape codes work.\n\nNeed to investigate:\n- Is NO_COLOR env var set?\n- Terminal type detection?\n- fatih/color library configuration\n- Does bd list show colors? bd ready? bd init?\n- What's the output of: echo $TERM, echo $NO_COLOR","status":"open","priority":2,"issue_type":"bug","created_at":"2025-10-24T22:26:36.22163-07:00","updated_at":"2025-10-30T17:05:26.026247-07:00","external_ref":"github:146"} -{"id":"bd-aa744b","content_hash":"dcced7668c97199985e802ca9bdae0db24d26a31be59b2e540e8263ac60bcb4f","title":"Remove sequential ID code path and simplify to hash-only","description":"Now that we have adaptive hash IDs with 4-char starting length, sequential IDs are obsolete.\n\n**Remove:**\n- Sequential ID generation logic (nextSequentialID, issue_counters table)\n- id_mode config (always use hash)\n- Migration complexity for sequential→hash\n- Tests for sequential IDs\n\n**Simplify:**\n- ID generation code (just adaptive hash)\n- Database schema (no counters table)\n- Documentation (remove sequential references)\n- Init command (no --id-mode flag needed)\n\n**Benefits:**\n- Less code to maintain\n- Simpler mental model\n- No migration path needed\n- Hash IDs are superior in every way with adaptive length\n\n**Discovered from:** bd-ea2a13 (adaptive ID length implementation showed sequential IDs are no longer needed)","status":"open","priority":2,"issue_type":"chore","created_at":"2025-10-30T21:40:41.288338-07:00","updated_at":"2025-10-30T21:40:41.288338-07:00"} +{"id":"bd-aa744b","content_hash":"1f97fdaededb45b8a97ab609b7ef4905ccb837d2c6fd1839b111dfc45b5285a6","title":"Remove sequential ID code path and simplify to hash-only","description":"Now that we have adaptive hash IDs with 4-char starting length, sequential IDs are obsolete.\n\n**Remove:**\n- Sequential ID generation logic (nextSequentialID, issue_counters table)\n- id_mode config (always use hash)\n- Migration complexity for sequential→hash\n- Tests for sequential IDs\n\n**Simplify:**\n- ID generation code (just adaptive hash)\n- Database schema (no counters table)\n- Documentation (remove sequential references)\n- Init command (no --id-mode flag needed)\n\n**Benefits:**\n- Less code to maintain\n- Simpler mental model\n- No migration path needed\n- Hash IDs are superior in every way with adaptive length\n\n**Discovered from:** bd-ea2a13 (adaptive ID length implementation showed sequential IDs are no longer needed)","status":"closed","priority":2,"issue_type":"chore","created_at":"2025-10-30T21:40:41.288338-07:00","updated_at":"2025-10-30T21:51:29.836941-07:00","closed_at":"2025-10-30T21:51:29.836941-07:00"} {"id":"bd-aafbe2ef","content_hash":"fc18ef649aec7da9df51f2f5a37e06583f818eaa56b4f47fe6304278ea0bd988","title":"bd list should output exactly one line per issue (no header/footer)","description":"Another agent ran into confusion: `bd list --status all | wc -l` output 509 lines, but there are only 165 issues. The extra lines are headers/footers.\n\nAgents expect `bd list` to output exactly one line per issue for easy piping/counting. Current output includes decorative headers and footers that break this expectation.\n\nSolution: Either remove headers/footers entirely, or add a `--no-header` flag that suppresses them for agent-friendly output.","status":"open","priority":2,"issue_type":"bug","created_at":"2025-10-29T23:46:15.512567-07:00","updated_at":"2025-10-30T17:05:26.017887-07:00"} {"id":"bd-acb971c7","content_hash":"70f8197b1981ef8031f0c436b2916d706b94ea280d6eeeeb4a10837f8ec26b7e","title":"bd daemons list hangs indefinitely","description":"The 'bd daemons list' command appears to hang and never complete. Needs investigation into why it's blocking and add timeout or fix the underlying issue.","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-10-30T17:47:18.852905-07:00","updated_at":"2025-10-30T18:37:03.874524-07:00","closed_at":"2025-10-30T18:37:03.874524-07:00"} {"id":"bd-aec5439f","content_hash":"9ad0242285e9ef9b326468b9be34f533f27cbbaa0c698607cca0cd6228016d2c","title":"Update LINTING.md with current baseline","description":"After cleanup, document the remaining acceptable baseline in LINTING.md so we can track regression.","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-27T18:53:10.38679-07:00","updated_at":"2025-10-30T17:05:26.003254-07:00"}