Skip to content

feat(dogfood): polish block-authored docs surfaces#115

Merged
flyingrobots merged 17 commits into
mainfrom
cycle/df-070-dogfood-block-polish
May 24, 2026
Merged

feat(dogfood): polish block-authored docs surfaces#115
flyingrobots merged 17 commits into
mainfrom
cycle/df-070-dogfood-block-polish

Conversation

@flyingrobots
Copy link
Copy Markdown
Owner

@flyingrobots flyingrobots commented May 24, 2026

Summary

Completes DF-070 as a 10-slice DOGFOOD product-polish stack. This branch moves visible DOGFOOD documentation surfaces closer to the block-authored product direction without adding provider runtime, subscriptions, command dispatch, or broad AppShell rendering scope.

What changed:

  • Adds the DF-070 design cycle and BEARING/legend links.
  • Adds word-aware proseSurface() in @flyingrobots/bijou-tui and routes DOGFOOD prose through it.
  • Routes DOGFOOD article, navigation, guide inspector, and settings data through their corresponding DOGFOOD block contracts.
  • Persists selected DOGFOOD locale through the injected locale port and Node host adapter.
  • Expands guide-info localization coverage and ratchets i18n debt from 2219 to 1993 raw strings.
  • Polishes Blocks preview posture so block names are the primary card titles and lower-mode output appears as a compact lowering summary.

Non-goals

  • No provider subscriptions.
  • No active runtime traversal.
  • No command dispatch implementation.
  • No full AppShell rewrite.
  • No full DOGFOOD-as-Blocks migration.
  • No broad standard block catalog expansion.

Validation

  • git diff --check
  • npm run docs:inventory
  • npm run dogfood:i18n:check
  • npm run dogfood:i18n:debt
  • npm test -- --run packages/bijou-tui/src/surface-layout.test.ts scripts/docs-preview.test.ts tests/cycles/DF-068/dogfood-block-preview-regressions.test.ts tests/cycles/DF-070/dogfood-block-product-polish.test.ts tests/cycles/DX-031/dogfood-blocks-section.test.ts tests/cycles/LX-011/dogfood-locale-ratchet.test.ts tests/cycles/LX-012/dogfood-i18n-debt-inventory.test.ts
  • npm run typecheck:test
  • npm run lint
  • npm test (312 files, 3513 tests)
  • npm run verify:interactive-examples
  • Pre-push reran npm run typecheck:test, npm test, and npm run verify:interactive-examples.

Summary by CodeRabbit

  • New Features

    • Added proseSurface (word-aware paragraph wrapping) and exported it for use across UIs
    • Persisted preferred locale via localization port; improved locale resolution behavior
    • Richer block-rendered outputs for docs, navigation, settings, and guide inspector
  • Documentation

    • Added DF-070 design doc and updated changelog, guides, and package README with proseSurface guidance
    • Expanded i18n message entries across multiple language catalogs
  • Tests

    • Added/updated tests for proseSurface, block rendering, and locale persistence behavior

Review Change Stack

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 24, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: d2ea8077-c485-4364-96a1-a2fc9a287dfc

📥 Commits

Reviewing files that changed from the base of the PR and between 0a729d1 and 4c778a3.

📒 Files selected for processing (9)
  • docs/CHANGELOG.md
  • examples/docs/app.ts
  • examples/docs/dogfood-blocks.ts
  • examples/docs/node-locale.ts
  • packages/bijou-tui/src/surface-layout.test.ts
  • packages/bijou-tui/src/surface-layout.ts
  • tests/cycles/DF-070/dogfood-block-product-polish.test.ts
  • tests/cycles/DX-031/dogfood-blocks-section.test.ts
  • tests/cycles/LX-011/dogfood-locale-ratchet.test.ts
💤 Files with no reviewable changes (1)
  • tests/cycles/DX-031/dogfood-blocks-section.test.ts
✅ Files skipped from review due to trivial changes (1)
  • docs/CHANGELOG.md

📝 Walkthrough

Walkthrough

This PR implements DF-070, making DOGFOOD feel like a block-authored terminal product. It introduces prose-wrapped text rendering to bijou-tui, extends DOGFOOD block contracts, adds locale persistence, routes documentation panes through block renderers, expands i18n coverage, and provides comprehensive test coverage validating the new behavior.

Changes

DF-070 DOGFOOD Block Product Polish

Layer / File(s) Summary
Prose Surface Foundation
packages/bijou-tui/src/surface-layout.ts, packages/bijou-tui/src/surface-layout.test.ts, packages/bijou-tui/src/index.ts, packages/bijou-tui/README.md, packages/bijou-tui/GUIDE.md, examples/_shared/example-surfaces.ts
New proseSurface(content, options) utility wraps text at word boundaries using wrapToWidth, converts to Surface via parseAnsiToSurface, exported from the bijou-tui barrel with docs and example wrapper.
DOGFOOD Block Contract Extensions
examples/docs/dogfood-blocks.ts
NavigationListBlockConfig gains activeItemId and items array with per-item id/label/depth; DocumentationArticleBlockConfig adds body; SettingsMenuBlockConfig and GuideInspectorBlockConfig expand to support sections. Renderers conditionally format multi-section output and emit state facts (itemCount,headingCount).
Storybook Documentation with Prose
examples/docs/storybook-app.ts
Story docs panel now wraps rendered markdown via proseSurface at computed width instead of contentSurface.
Locale Persistence Infrastructure
examples/docs/locale.ts, examples/docs/node-locale.ts
DogfoodLocalePort gains optional savePreferredLocale(locale) method. Node implementation adds storage/options interfaces, filesystem-backed preference reads/writes, and preference-path resolution (XDG/HOME).
DOGFOOD UI Pane Integration
examples/docs/app.ts
activateDogfoodLocale calls optional localePort.savePreferredLocale in try/catch (best-effort). Guide nav routes through navigationListBlock.render with prose output in lowered modes; guide reader uses documentationArticleBlock.render with heading counts and displays via proseSurface; guide info pane uses guideInspectorBlock.render with section-based rendering. Adds countMarkdownHeadings.
Localization Data
examples/docs/i18n-debt.ts, examples/docs/i18n/catalogs/en/de/es/fr/bijou.dogfood.json
Debt baseline adjusted (2219 → 1993). English: loweringFacts"{count} facts", modeLoweringTitle"lowering summary", pageTitle"{blockName}". Added guide.info.* entries across catalogs with partial translations.
DF-070 Behavior Tests
tests/cycles/DF-070/*, tests/cycles/LX-011/*
New DF-070 suite verifies block renderers output expected formatted text and avoid leaking debug facts. LX-011 extended with locale persistence read/write tests, i18n key coverage, and interactive cycling tests that assert savePreferredLocale calls (including failure path).
Test Assertion Updates
tests/cycles/DF-068/*, tests/cycles/DX-031/*
Updated regressions and block-section tests: replaced "mode lowering" with "lowering summary" and simplified page title assertions to use block name.
Design & Documentation
docs/design/DF-070-dogfood-block-product-polish.md, docs/BEARING.md, docs/CHANGELOG.md, docs/legends/DF-dogfood-field-guide.md
New DF-070 design doc; BEARING.md updated to target DF-070 and rewritten expected sequence; CHANGELOG lists features; field guide links DF-070.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Poem

🐰 Prose snugged to wordly bounds,

Blocks arrange the guide’s small towns,
Locale whispers saved to disk,
Tests hop through every risk,
DF-070 polishes the app with tiny, jaunty bounds.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 6.45% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat(dogfood): polish block-authored docs surfaces' is concise and clearly describes the main change—polishing DOGFOOD documentation surfaces to use block-authored rendering patterns, which is the primary objective of the DF-070 cycle.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch cycle/df-070-dogfood-block-polish

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint skipped: no ESLint configuration detected in root package.json. To enable, add eslint to devDependencies.


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.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 798185b782

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread examples/docs/app.ts Outdated
Copy link
Copy Markdown

@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: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
examples/docs/dogfood-blocks.ts (1)

1144-1152: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Preserve headingCount facts when body is absent.

DocumentationArticleBlockConfig.body is optional now, but this fallback only returns the entity fact. Callers that provide title + headingCount without body will silently lose dogfood.documentation.headingCount, so the block’s fact surface changes based on config shape instead of content.

💡 Suggested fix
   return {
     output: [
       'DocumentationArticleBlock',
       `title: ${title}`,
       `headings: ${headingCount}`,
       'Intents: select heading; open reference',
     ].join('\n'),
-    facts: [{ kind: 'entity', key: 'dogfood.block', value: 'DocumentationArticleBlock' }],
+    facts: [
+      { kind: 'entity', key: 'dogfood.block', value: 'DocumentationArticleBlock' },
+      { kind: 'state', key: 'dogfood.documentation.headingCount', value: String(headingCount) },
+    ],
   };
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@examples/docs/dogfood-blocks.ts` around lines 1144 - 1152, The current return
value for DocumentationArticleBlock drops the headingCount fact when body is
absent; update the return so that if headingCount (from
DocumentationArticleBlockConfig) is present you include a facts entry with key
'dogfood.documentation.headingCount' and its numeric/value (in addition to the
existing 'dogfood.block' entity) so callers providing title + headingCount still
receive that fact; locate the return in the function that builds the block
output (where output and facts are constructed) and append or conditionally push
the headingCount fact into the facts array when headingCount is defined.
🧹 Nitpick comments (1)
tests/cycles/DX-031/dogfood-blocks-section.test.ts (1)

320-321: 💤 Low value

Remove redundant assertion.

Lines 320 and 321 assert the identical condition—the template literal on line 320 produces the same string as the direct variable reference on line 321.

♻️ Proposed fix
-      expect(text).toContain(`${block.metadata.blockName}`);
       expect(text).toContain(block.metadata.blockName);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/cycles/DX-031/dogfood-blocks-section.test.ts` around lines 320 - 321,
Remove the redundant assertion that checks the same string twice: keep a single
expect on the rendered text containing the block name. Specifically, delete one
of the two lines asserting expect(text).toContain(`${block.metadata.blockName}`)
/ expect(text).toContain(block.metadata.blockName) and retain the simpler
expect(text).toContain(block.metadata.blockName) in the
dogfood-blocks-section.test.ts test so the test still validates presence of
block.metadata.blockName once.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@examples/docs/app.ts`:
- Around line 3147-3159: The nav marker uses model.selectedGuideId for
activeItemId even in pipe/accessible modes, but keyboard nav updates
model.guideState.focusIndex; update the navigationListBlock.render call so that
when ctx.mode is 'pipe' or 'accessible' it derives activeItemId from
model.guideState.items[model.guideState.focusIndex].value (fallback to
model.selectedGuideId or undefined if out of range), otherwise keep using
model.selectedGuideId; change the activeItemId assignment in the config passed
to navigationListBlock.render to implement this conditional selection so the
marker follows focus during guide-next/guide-prev.

In `@examples/docs/dogfood-blocks.ts`:
- Around line 1165-1175: The sectioned-output branch that builds the
pipe/accessible string (inside the if sections.length > 0) only concatenates
section.title plus row.label and row.valueLabel, dropping row.description;
update the construction for sections.flatMap(...) (and mirror the same change in
the other section render path around lines referencing sections and rows) to
include row.description when present (e.g., append it after the valueLabel or on
a new line) so both the pipe/accessible and non-pipe section renderings expand
rows to include row.description as well as label and valueLabel.

In `@examples/docs/node-locale.ts`:
- Around line 36-44: The readText implementation in NodeDogfoodLocaleStorage
currently rethrows any fs error other than ENOENT; change readText to treat all
read errors as best-effort fallbacks by returning undefined (not throwing) for
non-ENOENT errors so locale resolution can continue; likewise update
savePreferredLocale to wrap the call to storage.writeText(...) in a try/catch
and swallow/log errors (do not allow them to propagate) so an unwritable
preference file does not abort locale switching. Ensure you modify the
NodeDogfoodLocaleStorage.readText function and the savePreferredLocale path that
calls storage.writeText to implement these best-effort behaviors.

In `@packages/bijou-tui/src/surface-layout.ts`:
- Around line 35-36: The width computed in proseSurface is not guarded against
non-finite values (NaN/Infinity) before calling
wrapToWidth/parseAnsiToSurface/createSurface; change the width calculation in
proseSurface to first coerce and validate options.width (e.g. use
Number.isFinite) and fall back to a safe default before Math.floor/Math.max so
wrapToWidth always receives a finite positive integer; ensure the check
references proseSurface and wrapToWidth (and indirectly
parseAnsiToSurface/createSurface) so the sanitized finite width is propagated to
those functions.

---

Outside diff comments:
In `@examples/docs/dogfood-blocks.ts`:
- Around line 1144-1152: The current return value for DocumentationArticleBlock
drops the headingCount fact when body is absent; update the return so that if
headingCount (from DocumentationArticleBlockConfig) is present you include a
facts entry with key 'dogfood.documentation.headingCount' and its numeric/value
(in addition to the existing 'dogfood.block' entity) so callers providing title
+ headingCount still receive that fact; locate the return in the function that
builds the block output (where output and facts are constructed) and append or
conditionally push the headingCount fact into the facts array when headingCount
is defined.

---

Nitpick comments:
In `@tests/cycles/DX-031/dogfood-blocks-section.test.ts`:
- Around line 320-321: Remove the redundant assertion that checks the same
string twice: keep a single expect on the rendered text containing the block
name. Specifically, delete one of the two lines asserting
expect(text).toContain(`${block.metadata.blockName}`) /
expect(text).toContain(block.metadata.blockName) and retain the simpler
expect(text).toContain(block.metadata.blockName) in the
dogfood-blocks-section.test.ts test so the test still validates presence of
block.metadata.blockName once.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 72bb3947-7cf4-4650-a89e-acc35a9c5758

📥 Commits

Reviewing files that changed from the base of the PR and between d9c9b8a and 0a729d1.

⛔ Files ignored due to path filters (1)
  • examples/docs/i18n/source/dogfood-strings.csv is excluded by !**/*.csv
📒 Files selected for processing (24)
  • docs/BEARING.md
  • docs/CHANGELOG.md
  • docs/design/DF-070-dogfood-block-product-polish.md
  • docs/legends/DF-dogfood-field-guide.md
  • examples/_shared/example-surfaces.ts
  • examples/docs/app.ts
  • examples/docs/dogfood-blocks.ts
  • examples/docs/i18n-debt.ts
  • examples/docs/i18n/catalogs/de/bijou.dogfood.json
  • examples/docs/i18n/catalogs/en/bijou.dogfood.json
  • examples/docs/i18n/catalogs/es/bijou.dogfood.json
  • examples/docs/i18n/catalogs/fr/bijou.dogfood.json
  • examples/docs/locale.ts
  • examples/docs/node-locale.ts
  • examples/docs/storybook-app.ts
  • packages/bijou-tui/GUIDE.md
  • packages/bijou-tui/README.md
  • packages/bijou-tui/src/index.ts
  • packages/bijou-tui/src/surface-layout.test.ts
  • packages/bijou-tui/src/surface-layout.ts
  • tests/cycles/DF-068/dogfood-block-preview-regressions.test.ts
  • tests/cycles/DF-070/dogfood-block-product-polish.test.ts
  • tests/cycles/DX-031/dogfood-blocks-section.test.ts
  • tests/cycles/LX-011/dogfood-locale-ratchet.test.ts

Comment thread examples/docs/app.ts
Comment thread examples/docs/dogfood-blocks.ts
Comment thread examples/docs/node-locale.ts
Comment thread packages/bijou-tui/src/surface-layout.ts Outdated
@flyingrobots
Copy link
Copy Markdown
Owner Author

@codex Addressed the latest CodeRabbit/Codex feedback in follow-up commits:

Issue Commit
Lowered DOGFOOD nav now marks focused row before selection 31a0283
Settings rows preserve descriptions and article fallback keeps heading facts 056a2fa
Node DOGFOOD locale storage read/write failures are best-effort 571f90a
proseSurface guards non-finite widths before wrapping c5a0936
Removed duplicate block-name assertion 712f8a7
Kept the new nav regression type-safe under test typecheck 4c778a3

Validation: focused regression suites, docs inventory, git diff --check, typecheck:test, lint, and pre-push full test suite + interactive examples all passed.

@chatgpt-codex-connector
Copy link
Copy Markdown

Summary

  • I reviewed the PR trigger and current branch state, and no additional code changes are needed: the latest requested CodeRabbit/Codex feedback appears already addressed by the follow-up commits listed in the trigger (056a2fa, 571f90a, c5a0936, 712f8a7, 4c778a3).
  • The working tree is clean, so there was nothing to commit and therefore no new follow-up PR to create.

Testing / Checks

  • cd /workspace/bijou && git status --short && git log -n 5 --oneline (clean working tree; latest 5 commits match the feedback-addressing sequence)

View task →

@flyingrobots flyingrobots merged commit 3b9d719 into main May 24, 2026
7 checks passed
@flyingrobots flyingrobots deleted the cycle/df-070-dogfood-block-polish branch May 24, 2026 20:51
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.

1 participant