[PR #7058] [MERGED] fix(cli): format arrays of empty objects without keys as JSON #7612

Closed
opened 2026-11-03 13:39:06 +00:00 by bsakaguchi · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/morluto/rea/pull/7058
Author: @viniciusdsandrade
Created: 10/25/2026
Status: ✅ Merged
Merged: 10/25/2026
Merged by: @morluto

Base: main ← Head: fix/7057-cli-markdown-empty-objects


📝 Commits (1)

  • 25c04e6 fix(cli): format arrays of empty objects without keys as JSON

📊 Changes

3 files changed (+21 additions, -1 deletions)

View changed files

📝 src/cli/cliOutputFormatter.ts (+4 -1)
📝 tests/boundary/cli/cliOutput.test.ts (+8 -0)
📝 tests/boundary/cli/filteredArrayOutput.test.ts (+9 -0)

📄 Description

Summary

Fixes #7057. When formatting an array of objects that have no own enumerable keys (such as [{}] or [{}, {}]) as Markdown via --format md, formatObjectTable derived an empty header list (headers = []) and called renderTable([], rows), emitting malformed Markdown table syntax (| |\n||\n| |). This change requires at least one object with own keys in isObjectArray and falls back to JSON serialization when headers are empty.

Problem and expected behavior

Trigger: Format an array of empty objects as Markdown, e.g. formatCliOutput([{}], "md") or renderCliDocument([{}], "md", false).
Observed: isObjectArray evaluated to true because every element was a non-null object, but no element had own enumerable keys. renderTable produced an empty header row | |, an invalid delimiter row || with zero column separators, and rows | |. Under GitHub Flavored Markdown (GFM), a table requires at least one column with a valid delimiter row containing hyphens (|---|).
Expected: Arrays without column keys are formatted as JSON text ([{}] or [{},{}]), consistent with how non-tabular arrays and scalar values are rendered in Markdown.

Change and scope

  • src/cli/cliOutputFormatter.ts:
    • isObjectArray: added value.some((item) => Object.keys(item).length > 0) so arrays of empty objects are not classified as tabular object arrays.
    • formatObjectTable: added if (headers.length === 0) return markdownCell(items); as defensive fallback when no headers exist.
    • renderTable: added if (headers.length === 0) return ""; to ensure a table with 0 columns is never emitted.
  • tests/boundary/cli/cliOutput.test.ts: added regression test verifying renderCliDocument([{}], "md", false) produces "[{}]\n", [{}, {}] produces "[{},{}]\n", and { empty: [{}] } produces "## empty\n\n[{}]\n".
  • tests/boundary/cli/filteredArrayOutput.test.ts: added test verifying runFilteredCli([{}, {}], "md") outputs "[{},{}]\n".

Follow the contribution scope: ordinary bug fix within existing CLI output boundaries; maintainer scope decision is not applicable.

Contract and boundary impact

  • Semantic owner and earliest changed stage: CLI output formatting (src/cli/cliOutputFormatter.ts).
  • Contribution scope fit and linked maintainer decision: not applicable; routine fix for CLI output formatting.
  • CLI and MCP/tool-catalog contract: unchanged.
  • Provider, bridge, target-format, or platform compatibility: all platforms.
  • Evidence, artifact, provenance, or reconstruction contract: unchanged.
  • Target selection, authority, upstream behavior, and cleanup details: not applicable.
  • Generated metadata: none.

Expected effects:

  • Read existing files or captured data.
  • Launch or attach to a process.
  • Inject instrumentation or run scripts/code.
  • Change process memory, registers, files, or configuration.
  • Contact network services.
  • Recover protected code or work around protections.
  • Documentation or usability only; no target interaction.
  • Not sure yet; investigation or maintainer guidance needed.

Evidence and regression coverage

  • Tests added or updated:
    • tests/boundary/cli/cliOutput.test.ts: formats arrays of empty objects without column keys as JSON in Markdown.
    • tests/boundary/cli/filteredArrayOutput.test.ts: formats arrays of empty objects without columns as JSON in Markdown.
  • Base reproduction or other evidence: source-derived analysis showing renderTable([], [[]]) outputs invalid markdown table syntax | |\n||\n| |.
  • User-visible CLI/MCP output: formatCliOutput([{}], "md") returns "[{}]" instead of malformed table markup.
  • Remaining proof gaps: full CI execution on GitHub Actions.

Validation performed

  • Source review of touched files against project style and lint conventions.
  • Local verification commands were intentionally omitted; verification relies on PR CI.

Compatibility, safety, and release

  • Breaking changes or migration steps: none.
  • Real Hopper/Ghidra, browser, or OS coverage: platform-independent formatting logic.
  • Package or release metadata impact: none.
  • Security, privacy, process, or containment review: pure formatting change, no process or filesystem effects.

Author readiness

Human owner: @viniciusdsandrade

  • I reviewed the final diff and relevant existing code, understand the change and its edge cases, and take responsibility for the complete PR, including AI-assisted work.
  • I checked the evidence above, confirmed it supports the current change, and recorded meaningful validation gaps.
  • I declare this PR ready for initial maintainer review.

Before merge

  • This PR addresses a concrete problem or an agreed enhancement.
  • Material scope and authority questions are resolved, and any required maintainer scope decision covers the final diff.
  • The PR has one focused outcome and the title follows type(scope): outcome.
  • Related issue is linked, or the reason for not linking one is stated above.
  • Tests cover changed observable behavior and meaningful failure paths.
  • Owning docs, contracts, and generated metadata are updated where needed.
  • User-visible CLI/MCP changes include representative output.
  • I checked the final diff for secrets, unrelated cleanup, and unsupported claims.

🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/morluto/rea/pull/7058 **Author:** [@viniciusdsandrade](https://github.com/viniciusdsandrade) **Created:** 10/25/2026 **Status:** ✅ Merged **Merged:** 10/25/2026 **Merged by:** [@morluto](https://github.com/morluto) **Base:** `main` ← **Head:** `fix/7057-cli-markdown-empty-objects` --- ### 📝 Commits (1) - [`25c04e6`](https://github.com/morluto/rea/commit/25c04e696a9e34365811b16b368070a1fb1b6006) fix(cli): format arrays of empty objects without keys as JSON ### 📊 Changes **3 files changed** (+21 additions, -1 deletions) <details> <summary>View changed files</summary> 📝 `src/cli/cliOutputFormatter.ts` (+4 -1) 📝 `tests/boundary/cli/cliOutput.test.ts` (+8 -0) 📝 `tests/boundary/cli/filteredArrayOutput.test.ts` (+9 -0) </details> ### 📄 Description ## Summary Fixes #7057. When formatting an array of objects that have no own enumerable keys (such as `[{}]` or `[{}, {}]`) as Markdown via `--format md`, `formatObjectTable` derived an empty header list (`headers = []`) and called `renderTable([], rows)`, emitting malformed Markdown table syntax (`| |\n||\n| |`). This change requires at least one object with own keys in `isObjectArray` and falls back to JSON serialization when headers are empty. ## Problem and expected behavior Trigger: Format an array of empty objects as Markdown, e.g. `formatCliOutput([{}], "md")` or `renderCliDocument([{}], "md", false)`. Observed: `isObjectArray` evaluated to `true` because every element was a non-null object, but no element had own enumerable keys. `renderTable` produced an empty header row `| |`, an invalid delimiter row `||` with zero column separators, and rows `| |`. Under GitHub Flavored Markdown (GFM), a table requires at least one column with a valid delimiter row containing hyphens (`|---|`). Expected: Arrays without column keys are formatted as JSON text (`[{}]` or `[{},{}]`), consistent with how non-tabular arrays and scalar values are rendered in Markdown. ## Change and scope - `src/cli/cliOutputFormatter.ts`: - `isObjectArray`: added `value.some((item) => Object.keys(item).length > 0)` so arrays of empty objects are not classified as tabular object arrays. - `formatObjectTable`: added `if (headers.length === 0) return markdownCell(items);` as defensive fallback when no headers exist. - `renderTable`: added `if (headers.length === 0) return "";` to ensure a table with 0 columns is never emitted. - `tests/boundary/cli/cliOutput.test.ts`: added regression test verifying `renderCliDocument([{}], "md", false)` produces `"[{}]\n"`, `[{}, {}]` produces `"[{},{}]\n"`, and `{ empty: [{}] }` produces `"## empty\n\n[{}]\n"`. - `tests/boundary/cli/filteredArrayOutput.test.ts`: added test verifying `runFilteredCli([{}, {}], "md")` outputs `"[{},{}]\n"`. Follow the contribution scope: ordinary bug fix within existing CLI output boundaries; maintainer scope decision is not applicable. ## Contract and boundary impact - Semantic owner and earliest changed stage: CLI output formatting (`src/cli/cliOutputFormatter.ts`). - Contribution scope fit and linked maintainer decision: not applicable; routine fix for CLI output formatting. - CLI and MCP/tool-catalog contract: unchanged. - Provider, bridge, target-format, or platform compatibility: all platforms. - Evidence, artifact, provenance, or reconstruction contract: unchanged. - Target selection, authority, upstream behavior, and cleanup details: not applicable. - Generated metadata: none. Expected effects: - [ ] Read existing files or captured data. - [ ] Launch or attach to a process. - [ ] Inject instrumentation or run scripts/code. - [ ] Change process memory, registers, files, or configuration. - [ ] Contact network services. - [ ] Recover protected code or work around protections. - [x] Documentation or usability only; no target interaction. - [ ] Not sure yet; investigation or maintainer guidance needed. ## Evidence and regression coverage - Tests added or updated: - `tests/boundary/cli/cliOutput.test.ts`: formats arrays of empty objects without column keys as JSON in Markdown. - `tests/boundary/cli/filteredArrayOutput.test.ts`: formats arrays of empty objects without columns as JSON in Markdown. - Base reproduction or other evidence: source-derived analysis showing `renderTable([], [[]])` outputs invalid markdown table syntax `| |\n||\n| |`. - User-visible CLI/MCP output: `formatCliOutput([{}], "md")` returns `"[{}]"` instead of malformed table markup. - Remaining proof gaps: full CI execution on GitHub Actions. ## Validation performed - Source review of touched files against project style and lint conventions. - Local verification commands were intentionally omitted; verification relies on PR CI. ## Compatibility, safety, and release - Breaking changes or migration steps: none. - Real Hopper/Ghidra, browser, or OS coverage: platform-independent formatting logic. - Package or release metadata impact: none. - Security, privacy, process, or containment review: pure formatting change, no process or filesystem effects. ## Author readiness Human owner: @viniciusdsandrade - [x] I reviewed the final diff and relevant existing code, understand the change and its edge cases, and take responsibility for the complete PR, including AI-assisted work. - [x] I checked the evidence above, confirmed it supports the current change, and recorded meaningful validation gaps. - [x] I declare this PR ready for initial maintainer review. ## Before merge - [x] This PR addresses a concrete problem or an agreed enhancement. - [x] Material scope and authority questions are resolved, and any required maintainer scope decision covers the final diff. - [x] The PR has one focused outcome and the title follows `type(scope): outcome`. - [x] Related issue is linked, or the reason for not linking one is stated above. - [x] Tests cover changed observable behavior and meaningful failure paths. - [x] Owning docs, contracts, and generated metadata are updated where needed. - [x] User-visible CLI/MCP changes include representative output. - [x] I checked the final diff for secrets, unrelated cleanup, and unsupported claims. --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
bsakaguchi 2026-11-03 13:39:06 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
morluto/rea#7612
No description provided.