Skip to content

fix: beads tracker closes tasks more consistently and in the correct database based on config.#108

Merged
subsy merged 4 commits intosubsy:mainfrom
jesse-merhi:fix/ralph-tui-ux-bugs
Jan 17, 2026
Merged

fix: beads tracker closes tasks more consistently and in the correct database based on config.#108
subsy merged 4 commits intosubsy:mainfrom
jesse-merhi:fix/ralph-tui-ux-bugs

Conversation

@jesse-merhi
Copy link
Copy Markdown
Contributor

@jesse-merhi jesse-merhi commented Jan 16, 2026

I found when using beads the agent would often just loop iteration after iteration trying to do the exact same task and constantly telling me that the task was finished and it was going to close the ticket.
After some investigation, I noticed a few things. The first of which was that bd update has no --reason flag.
I believe that meant the agent would try to close the issues, but the issue would error. Hence,

  • Use bd close instead of bd update --status=closed -> (supports --reason)

Apparently, Beads also doesn't like it when you attempt to close a child ticket before closing the parent epic when there are 'blocks' applied to the parent ticket. This was a bit frustrating as create-prd did so with a block for some reason. --force ensures that the task closes regardless.
I have considered perhaps if ralph was used on a PRD that was human made with blocks on purpose and we didnt do this - ralph would get stuck. My rebuttle is that if the user is running ralph on their ticket - they should expect it to close once its done.

  • Add --force flag to close tasks with open parent epics

Another thing I noticed is the LLM would use all of its bd commands in the cwd - this would mean the directory it worked in started being filled up with issues.jsonl.... In my case I had my beads in a different directory so I also added the following:

  • Add beadsDbPath template variable for agent bd commands
  • Update templates to use bd close --db {{beadsDbPath}} --reason

FInally I constantly found myself on the Stopped status - which really confused me before I realised that iterations are not for ONE issue - they are for them all! i.e. how many loops to complete all X tickets. SO I made s give you +1 iteration and continue execution. This probably could be improved but it felt at least more intuitive than hitting + and then start.

  • Fix 's' key to work when stopped/idle

Summary by CodeRabbit

  • New Features

    • Beads now close via a dedicated close command that supports force-closing and an explicit database path and reason.
    • Pressing "s" now resumes execution from paused/idle states and can add iterations when required.
  • Documentation

    • Templates and prompts updated to expose the beads database path and show the new close workflow.
  • Tests

    • Added tests covering beads close behaviour and template variable (beadsDbPath) resolution.

✏️ Tip: You can customize this high-level summary in your review settings.

- Use bd close instead of bd update --status=closed (supports --reason)
- Add --force flag to close tasks with open parent epics
- Add beadsDbPath template variable for agent bd commands
- Update templates to use bd close --db {{beadsDbPath}} --reason
- Fix 's' key to work when stopped/idle
@vercel
Copy link
Copy Markdown

vercel bot commented Jan 16, 2026

@jesse-merhi is attempting to deploy a commit to the plgeek Team on Vercel.

A member of the Team first needs to authorize it.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Jan 16, 2026

Walkthrough

Bead closure changed from an update-based flow to a dedicated bd close command (now invoked with --force and an explicit DB path). A beadsDbPath template variable was added and injected into template rendering. TUI 's' key handling was extended to resume and add iterations when needed.

Changes

Cohort / File(s) Summary
Beads tracker & templates
src/plugins/trackers/builtin/beads.ts, src/templates/builtin.ts, src/templates/prompts.ts, src/templates/defaults/beads.hbs, src/templates/defaults/beads-bv.hbs
Replaced bd update ... --status=closed --close_reason="..." with bd close [id] --db {{beadsDbPath}} --reason "..." in templates/prompts; beads.ts now spawns bd close <id> --force (includes --reason when provided). Public-type imports reordered/expanded in beads.ts.
Template engine & types
src/templates/engine.ts, src/templates/types.ts
Added beadsDbPath: string to TemplateVariables and implemented computeBeadsDbPath(config) (defaults to .beads/beads.db) to inject beadsDbPath into template context.
TUI run control
src/tui/components/RunApp.tsx
Expanded handling of 's' key: starts when ready; resumes via engine.continueExecution() when stopped/idle; if currentIteration >= maxIterations calls engine.addIterations(1) before continuing. Updated useCallback dependencies.
Tests
src/plugins/trackers/builtin/beads.test.ts, src/templates/engine.test.ts
Added tests for BeadsTrackerPlugin.completeTask (mocked child_process.spawn) verifying bd close invocation, --force and --reason handling, and success/failure cases; added tests for buildTemplateVariables and beadsDbPath resolution logic.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant User as User
  participant UI as RunApp (TUI)
  participant Engine as Engine
  participant IterMgr as IterationManager

  User->>UI: Press 's'
  alt status == ready
    UI->>UI: set status -> running
    UI->>Engine: onStart / startExecution()
  else status == stopped or idle
    UI->>Engine: continueExecution()
    alt currentIteration >= maxIterations
      UI->>Engine: addIterations(1)
      Engine->>IterMgr: add iteration
      IterMgr-->>Engine: added (ok)
      Engine-->>UI: success
      UI->>UI: set status -> running
      UI->>Engine: continueExecution()
    else
      Engine-->>UI: continued
      UI->>UI: set status -> running
    end
  end
  Engine-->>User: execution resumes / runs
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Poem

🐰 I hopped through lines of code at dawn,
Swapped updates for a close command drawn.
I tucked the DB path snug and neat,
And taught 's' to wake and add one beat.
Hop, hop — the tracker’s now complete! 🥕

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 66.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main changes: switching to bd close command and ensuring correct database targeting via beadsDbPath.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@jesse-merhi jesse-merhi changed the title fix: beads tracker closes tasks in correct database fix: beads tracker closes tasks more consistently and in the correct database based on config. Jan 16, 2026
@codecov
Copy link
Copy Markdown

codecov bot commented Jan 16, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 41.58%. Comparing base (91235aa) to head (5b713cb).
⚠️ Report is 5 commits behind head on main.

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main     #108      +/-   ##
==========================================
+ Coverage   40.36%   41.58%   +1.22%     
==========================================
  Files          57       57              
  Lines       12626    12600      -26     
==========================================
+ Hits         5096     5240     +144     
+ Misses       7530     7360     -170     
Files with missing lines Coverage Δ
src/plugins/trackers/builtin/beads.ts 60.18% <100.00%> (+23.70%) ⬆️
src/templates/builtin.ts 100.00% <ø> (ø)
src/templates/engine.ts 21.65% <100.00%> (+15.32%) ⬆️
src/templates/prompts.ts 100.00% <ø> (ø)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Fix all issues with AI agents
In `@src/templates/prompts.ts`:
- Around line 148-156: The examples in the "Closing a Bead" section use the `bd
close` command but omit the `--db` flag, causing inconsistency with other
builtin templates; update both example lines that show `bd close [bead-id]
--reason "..."` (the example for closing with a descriptive reason and the
specific `bd close devtuneai-001` example) to include the `--db <dbname>` flag
(e.g., `bd close [bead-id] --db <dbname> --reason "..."`) so they match the
other templates and clarify which database is targeted.
- Around line 135-138: Update the prompt examples that show the bd close command
to include the --db flag to match the built-in templates; specifically, modify
the prompt text in src/templates/prompts.ts where the example shows "bd close
[bead-id] --reason ..." so it becomes "bd close [bead-id] --db {{beadsDbPath}}
--reason ..." (to mirror the usage in src/templates/builtin.ts), or
alternatively add a brief clarifying sentence in the same prompt block
explaining when --db is required (e.g., when running from a different
directory); ensure the change references the example command string that
contains "bd close" so both prompt and builtin templates remain consistent.

In `@src/tui/components/RunApp.tsx`:
- Around line 840-856: The callback that performs continue logic (the function
using engine.continueExecution(), engine.addIterations(), setStatus and
referencing currentIteration and maxIterations) has stale closure risk because
currentIteration and maxIterations are not in its useCallback dependency list;
update the useCallback dependencies to include currentIteration and
maxIterations (in addition to engine and setStatus or other existing deps) so
the handler always sees up-to-date iteration values and behaves correctly when
deciding to add an iteration or continue.
🧹 Nitpick comments (2)
src/tui/components/RunApp.tsx (1)

840-840: Redundant engine check.

The && engine condition is unnecessary since engine is a required prop (not optional in RunAppProps). This is a minor nit but could be removed for clarity.

♻️ Suggested simplification
-          } else if ((status === 'stopped' || status === 'idle') && engine) {
+          } else if (status === 'stopped' || status === 'idle') {
src/templates/engine.ts (1)

260-269: Confirm beads.db is the correct filename for the beads database.

The codebase uses only beads.db as the database filename; no other variants exist in the TypeScript files. The file correctly begins with the required ABOUTME comment. The implementation properly chains fallbacks through tracker options, config, and process defaults.

Consider adding a brief inline comment explaining the fallback chain for maintainability:

const workingDir = (trackerOptions?.workingDir as string) 
  ?? config.cwd 
  ?? process.cwd(); // Falls back to tracker options, then config cwd, then process cwd
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a11c134 and c53d985.

📒 Files selected for processing (8)
  • src/plugins/trackers/builtin/beads.ts
  • src/templates/builtin.ts
  • src/templates/defaults/beads-bv.hbs
  • src/templates/defaults/beads.hbs
  • src/templates/engine.ts
  • src/templates/prompts.ts
  • src/templates/types.ts
  • src/tui/components/RunApp.tsx
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Start all code files with a file-level JSDoc comment section explaining the file's purpose, prefixed with 'ABOUTME: '

Files:

  • src/templates/types.ts
  • src/tui/components/RunApp.tsx
  • src/templates/engine.ts
  • src/templates/builtin.ts
  • src/templates/prompts.ts
  • src/plugins/trackers/builtin/beads.ts
**/*.{js,ts,tsx,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

Start all code files with a file-level JSDoc comment section explaining the file's purpose, prefixed with "ABOUTME: "

Files:

  • src/templates/types.ts
  • src/tui/components/RunApp.tsx
  • src/templates/engine.ts
  • src/templates/builtin.ts
  • src/templates/prompts.ts
  • src/plugins/trackers/builtin/beads.ts
🧠 Learnings (2)
📚 Learning: 2026-01-13T12:30:04.930Z
Learnt from: CR
Repo: subsy/ralph-tui PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-13T12:30:04.930Z
Learning: When ending a work session, complete all mandatory steps: file issues for remaining work, run quality gates, update issue status, push to remote with `git push`, clean up, and verify all changes are committed and pushed

Applied to files:

  • src/templates/defaults/beads.hbs
  • src/templates/builtin.ts
  • src/templates/prompts.ts
  • src/templates/defaults/beads-bv.hbs
📚 Learning: 2026-01-13T12:29:45.887Z
Learnt from: CR
Repo: subsy/ralph-tui PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-13T12:29:45.887Z
Learning: When ending a work session, complete all mandatory workflow steps: file issues, run quality gates, update issue status, push to remote, clean up, and verify

Applied to files:

  • src/templates/defaults/beads.hbs
  • src/templates/builtin.ts
  • src/templates/prompts.ts
  • src/templates/defaults/beads-bv.hbs
🧬 Code graph analysis (2)
src/tui/components/RunApp.tsx (1)
src/chat/engine.ts (1)
  • setStatus (113-122)
src/templates/engine.ts (1)
src/config/types.ts (1)
  • RalphConfig (194-233)
🔇 Additional comments (11)
src/plugins/trackers/builtin/beads.ts (2)

11-21: Import additions look correct.

The new imports align with the types used in this file. The reordering maintains alphabetical consistency.


431-436: Reconcile unconditional --force with documented usage.

Templates in the codebase show users closing beads with bd close [id] --reason "..." without the --force flag. However, this method unconditionally uses --force. Without tests or documentation explaining why --force is mandatory here, it's unclear whether this difference is intentional or if it masks legitimate error cases (e.g., tasks with incomplete dependencies).

Either document why --force is essential for this workflow, or test both code paths to ensure tasks fail appropriately when they shouldn't be closed.

src/templates/defaults/beads-bv.hbs (1)

13-13: Template updates align with the new bd close workflow.

The addition of {{beadsDbPath}} documentation and its usage in the close command instruction is consistent with the PR objectives. The template now correctly directs users to use bd close with --db and --reason flags.

Also applies to: 49-49

src/templates/defaults/beads.hbs (1)

13-13: Template updates are consistent with beads-bv.hbs.

The changes correctly add the {{beadsDbPath}} variable documentation and update the close instruction to use bd close with the database path and reason flags.

Also applies to: 39-39

src/templates/types.ts (1)

73-75: Type definition correctly extends TemplateVariables.

The new beadsDbPath property is properly typed as string with clear documentation. This enables type-safe usage in templates and the template engine.

src/templates/engine.ts (1)

256-256: LGTM!

Clean integration of the new beadsDbPath variable into the template context.

src/templates/builtin.ts (2)

72-72: LGTM!

The template correctly uses bd close with --db {{beadsDbPath}} and --reason, aligning with the PR objective to target the correct database directory.


117-117: LGTM!

Consistent with the BEADS_TEMPLATE change. Both beads templates now use the same bd close --db {{beadsDbPath}} --reason pattern.

src/templates/prompts.ts (3)

166-170: LGTM!

The browser testing example correctly shows the updated bd close syntax with --reason.


174-174: LGTM!

Stop condition correctly references the new bd close command.


193-193: Command reference updated correctly.

The command reference section now shows bd close [bead-id] --reason "...", which aligns with the new workflow. Consider whether to add the --db flag here as well for completeness.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

subsy and others added 2 commits January 16, 2026 21:55
- Fix stale closure bug: add currentIteration and maxIterations to
  useCallback dependency array in RunApp.tsx 's' key handler
- Add --db flag documentation to prompts.ts for consistency with
  builtin templates
- Correct misleading comment about --force flag (it's for pinned
  issues, not epic relationships)
- Remove redundant engine null check (engine is a required prop)
@subsy
Copy link
Copy Markdown
Owner

subsy commented Jan 16, 2026

Thanks for this contribution @jesse-merhi! The core changes here are solid - switching from bd update --status=closed to bd close is the right fix since bd update doesn't support the --reason flag.

I've pushed a follow-up commit (6200d47) addressing the code review feedback:

  1. Stale closure bug in RunApp.tsx - The 's' key handler was using currentIteration and maxIterations but these weren't in the useCallback dependency array. This would cause the handler to use stale values after iterations changed. Added both to the deps.

  2. Documentation consistency in prompts.ts - Added --db flag examples to match the builtin templates. This helps agents understand when to specify the database path explicitly.

  3. Accurate comment in beads.ts - The comment said --force was for "parent epic still open" but bd close --help shows it's actually for pinned issues:
    -f, --force Force close pinned issues
    Updated the comment to reflect this accurately.

  4. Removed redundant check - The && engine check was unnecessary since engine is a required prop in RunAppProps.

Note - The --force flag is retained as a defensive measure, but the real fix for the agent looping issue was switching to bd close (which supports --reason), not the --force flag. The flag prevents failures when issues are pinned, which is a reasonable safeguard for automated workflows.

- Add engine.test.ts with tests for buildTemplateVariables and
  beadsDbPath computation (5 test cases covering all fallback paths)
- Add beads.test.ts with tests for completeTask verifying --force flag
  and --reason handling (4 test cases)

These tests improve patch coverage for the PR changes.
@vercel
Copy link
Copy Markdown

vercel bot commented Jan 16, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Review Updated (UTC)
ralph-tui Ignored Ignored Jan 16, 2026 11:59pm

Request Review

@subsy subsy merged commit 8e08c1a into subsy:main Jan 17, 2026
9 checks passed
sakaman pushed a commit to sakaman/ralph-tui that referenced this pull request Feb 15, 2026
fix: beads tracker closes tasks more consistently and in the correct database based on config.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants