Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
---
id: 8qp1ai
title: t-0vy-empty-task-list-stats-footer
type: standard
tags: [task, ace-task, list-output]
created_at: "2026-03-26 00:51:40"
status: active
---

# t-0vy-empty-task-list-stats-footer

## What Went Well
- The target behavior was narrow and clearly specified, so implementation stayed limited to one formatter method and one test file.
- Existing `ace-idea` empty-list behavior provided a direct reference pattern, reducing ambiguity and rework.
- Verification stayed fast and reliable (`ace-test` focused + package profile run), and all tests passed on first run.

## What Could Be Improved
- The `ace-task plan` command took noticeable time with no immediate output, which can look like a stall during automation.
- Pre-commit review fallback (`ace-lint`) surfaced style warnings on pre-existing lines unrelated to this change; this adds noise to gate reports.

## Key Learnings
- For list-formatting changes, reusing existing stats formatter paths avoids divergence between empty and non-empty rendering.
- Empty-state UX still benefits from global context (`0 of N`, folder breakdown), especially for filtered views.
- In assignment subtrees, explicit scoped commands and per-step reports make recovery and auditability straightforward.

## Action Items
- Continue: Mirror behavior from sibling formatters (`ace-idea` / `ace-task`) before introducing new output logic.
- Start: Consider a small enhancement to `ace-task plan` user feedback for long-running plan generation.
- Stop: Treating style-only lint warnings as if they were release blockers when `pre_commit_review_block` is false.
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
---
id: 8qp27m
title: batch-t-0vy-stats-footer
type: standard
tags: []
created_at: "2026-03-26 01:28:28"
status: active
---

# batch-t-0vy-stats-footer

## What Went Well

- **Fork delegation worked smoothly**: The 8-step work-on-task subtree (010.01) completed autonomously without intervention — onboard through retro in one pass.
- **Review cycle efficiency**: Three review cycles (valid, fit, shine) executed in parallel fork subtrees. Valid cycle caught a real formatting issue (dangling space in empty stats), fit found only false positives, shine contributed two low-priority polish improvements.
- **Small, focused change**: The core fix was ~15 lines of production code. The ATOM architecture kept the change isolated to one molecule (TaskDisplayFormatter) with clear test boundaries.
- **Release automation**: Three patch releases (v0.31.1 → v0.31.3) were bumped automatically with proper CHANGELOG entries and lockfile updates.
- **Commit reorganization**: 12 interleaved commits were cleanly reorganized into 5 logical groups by ace-git-commit's scope detection.

## What Could Be Improved

- **Pre-existing test failure**: ace-docs has a failing test (`DocumentRegistryTest#test_discovers_frontmatter_free_readme_without_yaml`) unrelated to this work. This creates noise in suite verification and requires manual assessment each time.
- **Multiple patch releases**: Three successive patch bumps (0.31.1/0.31.2/0.31.3) within one PR is noisy. The valid review cycle found a real issue, so the second bump was justified, but the shine cycle's changes could have been folded into the same release.
- **ace-support-items side-effect**: The valid review cycle's fix touched ace-support-items (StatsLineFormatter), adding it to the release scope. Cross-package side-effects in review cycles should be flagged earlier.

## Key Learnings

### Review Cycle Analysis
- **Valid cycle**: 1 medium finding (real formatting bug) — high value, led to code change + test + release.
- **Fit cycle**: 1 finding marked invalid (false positive) — zero code changes, release correctly skipped as no-op.
- **Shine cycle**: 2 low-priority findings, both applied as quick wins — refactored shared return path, extended CLI test coverage.
- **False positive rate**: 1/4 total findings (25%) were false positives — reasonable for LLM review on a small change.

## Action Items

- **Continue**: Using fork delegation for review cycles — keeps driver clean and subtrees independent.
- **Start**: Tracking pre-existing test failures in a task so they don't create confusion during suite verification.
- **Consider**: Consolidating review-cycle releases when changes are minimal (e.g., shine-only changes could skip release if prior cycle already bumped).

Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
id: 8qp.t.0vy
status: in-progress
status: done
priority: medium
created_at: "2026-03-26 00:35:31"
estimate: TBD
Expand Down
16 changes: 16 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,22 @@ All notable changes to this project will be documented in this file.

## [Unreleased]

## [0.9.928] - 2026-03-26

### Fixed
- **ace-task v0.31.3**: Consolidated empty-list stats footer formatting into a single return path and added command-level coverage for zero-total footer output.

## [0.9.927] - 2026-03-26

### Fixed
- **ace-support-items v0.15.4**: corrected zero-status summary formatting in `StatsLineFormatter` so empty lists render `Tasks: • 0 total` without dangling spacing.
- **ace-task v0.31.2**: aligned empty-task list output with the formatter fix and added exact output regression coverage.

## [0.9.926] - 2026-03-26

### Fixed
- **ace-task v0.31.1**: `ace-task list` now shows the stats footer for empty results, including filtered `0 of N` summaries.

## [0.9.925] - 2026-03-23

### Fixed
Expand Down
4 changes: 2 additions & 2 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,7 @@ PATH
PATH
remote: ace-support-items
specs:
ace-support-items (0.15.3)
ace-support-items (0.15.4)
ace-b36ts (~> 0.7)
ace-support-core (~> 0.25)

Expand Down Expand Up @@ -323,7 +323,7 @@ PATH
PATH
remote: ace-task
specs:
ace-task (0.31.0)
ace-task (0.31.3)
ace-b36ts (~> 0.7)
ace-support-cli (~> 0.3)
ace-support-core (~> 0.25)
Expand Down
8 changes: 8 additions & 0 deletions ace-support-items/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

## [0.15.4] - 2026-03-26

### Fixed
- `StatsLineFormatter`: corrected empty-status output formatting to avoid the malformed `Tasks: • 0 total` footer when no status buckets are present.

### Technical
- Added regression coverage for zero-status summary formatting in `stats_line_formatter_test.rb`.

## [0.15.3] - 2026-03-22

### Technical
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,11 @@ def self.format(label:, stats:, status_order:, status_icons:, folder_stats: nil,
parts << "#{icon} #{count}"
end

line = "#{label}: #{parts.join(" | ")}"
line = if parts.empty?
"#{label}:"
else
"#{label}: #{parts.join(" | ")}"
end

shown = stats[:total]
total = total_count || shown
Expand Down
2 changes: 1 addition & 1 deletion ace-support-items/lib/ace/support/items/version.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
module Ace
module Support
module Items
VERSION = "0.15.3"
VERSION = "0.15.4"
end
end
end
13 changes: 13 additions & 0 deletions ace-support-items/test/atoms/stats_line_formatter_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,19 @@ def test_format_single_status
assert_equal "Tasks: ✓ 5 • 5 total", line
end

def test_format_with_no_status_parts
stats = {total: 0, by_field: {}}

line = Ace::Support::Items::Atoms::StatsLineFormatter.format(
label: "Tasks",
stats: stats,
status_order: %w[pending done],
status_icons: {"pending" => "○", "done" => "✓"}
)

assert_equal "Tasks: • 0 total", line
end

def test_format_includes_unknown_statuses
stats = {total: 5, by_field: {"pending" => 2, "draft" => 3}}

Expand Down
21 changes: 21 additions & 0 deletions ace-task/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,27 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

## [0.31.3] - 2026-03-26

### Fixed
- Simplified `TaskDisplayFormatter.format_list` by consolidating the shared stats footer return path for empty and non-empty output.

### Technical
- Strengthened `ace-task list` command coverage to assert empty-state stats footer output includes the zero-total summary.

## [0.31.2] - 2026-03-26

### Fixed
- Tightened empty-list stats rendering to match the corrected support formatter output (`Tasks: • 0 total`) for fully empty roots.

### Technical
- Strengthened task display formatter regression coverage with an exact empty-output assertion.

## [0.31.1] - 2026-03-26

### Fixed
- Updated `ace-task list` empty-result rendering to always append the stats footer, matching non-empty output and `ace-idea` behavior.

## [0.31.0] - 2026-03-24

### Fixed
Expand Down
15 changes: 12 additions & 3 deletions ace-task/lib/ace/task/molecules/task_display_formatter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -115,10 +115,19 @@ def self.format(task, show_content: false)
# @param global_folder_stats [Hash, nil] Folder name → count hash from full scan
# @return [String] Formatted list output
def self.format_list(tasks, total_count: nil, global_folder_stats: nil)
return "No tasks found." if tasks.empty?
stats_line = format_stats_line(
tasks,
total_count: total_count,
global_folder_stats: global_folder_stats
)

body = if tasks.empty?
"No tasks found."
else
tasks.map { |task| format_list_item(task) }.join("\n")
end

lines = tasks.map { |task| format_list_item(task) }.join("\n")
"#{lines}\n\n#{format_stats_line(tasks, total_count: total_count, global_folder_stats: global_folder_stats)}"
"#{body}\n\n#{stats_line}"
end

STATUS_ORDER = %w[draft pending in-progress done blocked skipped cancelled].freeze
Expand Down
2 changes: 1 addition & 1 deletion ace-task/lib/ace/task/version.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@

module Ace
module Task
VERSION = "0.31.0"
VERSION = "0.31.3"
end
end
1 change: 1 addition & 0 deletions ace-task/test/commands/list_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ def test_list_empty_shows_message
end.first

assert_match(/No tasks found/, output)
assert_match(/Tasks:.*0 total/, output)
end

def test_list_shows_stats_line
Expand Down
19 changes: 17 additions & 2 deletions ace-task/test/molecules/task_display_formatter_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -152,10 +152,25 @@ def test_format_list_shows_compact_items
assert_includes output, "Second task"
end

def test_format_list_returns_message_for_empty_list
def test_format_list_empty_returns_no_tasks_message_with_stats
output = Ace::Task::Molecules::TaskDisplayFormatter.format_list([])

assert_equal "No tasks found.", output
assert_equal "No tasks found.\n\nTasks: • 0 total", output
end

def test_format_list_empty_includes_folder_summary_when_totals_exist
output = Ace::Task::Molecules::TaskDisplayFormatter.format_list(
[],
total_count: 10,
global_folder_stats: {nil => 2, "_maybe" => 3, "_archive" => 5}
)

assert_includes output, "No tasks found."
assert_includes output, "Tasks:"
assert_includes output, "• 0 of 10"
assert_includes output, "next 2"
assert_includes output, "maybe 3"
assert_includes output, "archive 5"
end

def test_format_list_shows_tags_inline
Expand Down