Skip to content

[#91] Added a non-interactive informational note field.#117

Merged
AlexSkrypnyk merged 14 commits into
mainfrom
feature/91-note-field
Jul 24, 2026
Merged

[#91] Added a non-interactive informational note field.#117
AlexSkrypnyk merged 14 commits into
mainfrom
feature/91-note-field

Conversation

@AlexSkrypnyk

@AlexSkrypnyk AlexSkrypnyk commented Jul 23, 2026

Copy link
Copy Markdown
Member

Closes #91

Summary

Adds a note field type: a non-interactive, non-blocking informational card. It renders a title and body inline, is skipped by the selection cursor, and contributes nothing to the answers payload. A note is absent from headless collection and from both machine schemas, it honours ->when() like any other field, and it interpolates {{field}} tokens in its title and body so it can reflect earlier answers. ->border() frames it in the theme's box.

Changes

  • Extracted the {{field}} interpolation into a shared Strings::interpolate() helper, reused by Derive and the new note rendering, instead of duplicating the token-replacement logic.
  • Added the FieldType::Note case and an isPresentational() predicate that marks a field as display-only.
  • Added the note(id, title)->description(body)->border() builder API on PanelBuilder and FieldBuilder.
  • Excluded presentational fields from the engine and panel controller: a note never enters value resolution, the settled values or provenance maps, the active-answers payload, navigation, or fix-up targets.
  • Added the theme's renderNoteLines() card rendering, plus grid-preview and content-width measurement support for a note.
  • Excluded notes from AgentHelp, SchemaGenerator and SchemaValidator, so a note is never a prompt or a validated answer in the machine-readable schemas.
  • Fixed the action-button offset to count only navigable items rather than the raw field count, so a note placed in a modal no longer shifts which button is selected.
  • Added full test coverage across the builder, engine, panel controller, theme and schema layers, including TuiTester-driven interaction tests, and a new playground/02-widgets-note.php demo.
  • Generated the note widget's full SVG set (16 variants), added its docs/content/widgets/note.mdx page and sidebar entry, and regenerated the all-widgets montage so the gallery includes the note card. AGENTS.md now records that every widget must ship its full SVG set.

Before / After

Before                                   After
------------------------------------     ------------------------------------
┌ Order ───────────────────────────┐     ┌ Order ───────────────────────────┐
│ ❯ Item:  Pear                    │     │   Fresh produce order            │
│   Notes: ___________             │     │   This card is read-only.        │
└───────────────────────────────────┘     │ ❯ Item:  Pear                    │
                                          └───────────────────────────────────┘

Every field is navigable and                The note renders as a card, the
appears in the answers:                     cursor skips straight from the
                                             panel edge to "Item", and the
{                                            note is absent from the answers:
  "item": "Pear",
  "notes": ""                             {
}                                            "item": "Pear"
                                           }

Summary by CodeRabbit

  • New Features
    • Added a read-only Note widget/field with optional bordered/boxed styling and {{field}} template interpolation.
    • Note cards are displayed inline (including grid sizing previews) and can be included in widget galleries, playgrounds, and docs.
  • Bug Fixes
    • Notes are now consistently treated as presentational: excluded from collected answers, schema/required prompts, validation, agent help, and value/provenance/active answers.
    • Fixed cursor navigation and modal button offsets to skip notes correctly.
    • Prevented fix-ups/derives from using note values to affect value-carrying fields.

@AlexSkrypnyk AlexSkrypnyk added this to the 0.2.0 milestone Jul 23, 2026
@coderabbitai

coderabbitai Bot commented Jul 23, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Changes

Adds a non-interactive Note field type with optional borders and templated title/body rendering. Notes are excluded from answers, validation, schemas, provenance, cursor navigation, and editor creation while remaining conditionally visible in rendered forms.

Note field support

Layer / File(s) Summary
Note contracts and builders
src/Model/*, src/Builder/*, src/Utils/Strings.php, src/Derive/Derive.php, src/Widget/WidgetFactory.php, translations/en.php, tests/phpunit/Unit/{Builder,Model,Utils,Widget}/*
Defines the Note type, optional bordered state, fluent builder APIs, shared template interpolation, translation, and the absence of an editor widget.
Value and schema exclusion
src/Engine/Engine.php, src/Schema/*, tests/phpunit/Unit/{Engine,Schema}/*
Skips presentational fields during value resolution, transformations, validation, provenance, fix-ups, and schema generation while retaining conditional visibility.
Rendering and navigation
src/Render/PanelController.php, src/Theme/DefaultTheme.php, tests/phpunit/Unit/{Render,Theme}/*
Renders interpolated note cards and grid previews, supports bordered wrapping and sizing, and excludes notes from cursor, activation, help, and modal indexing.
Examples, documentation, and widget coverage
playground/*, .claude/demo_content_reference.md, AGENTS.md, docs/content/widgets/*, docs/sidebars.js, docs/util/render-widget-svgs.php, tests/phpunit/Fixtures/Form/*, tests/phpunit/Unit/Testing/*
Adds runnable examples, widget montage coverage, documentation, SVG-generation support, sidebar wiring, and widget maintenance guidance.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant PanelController
  participant DefaultTheme
  participant Engine
  User->>PanelController: navigate and edit interactive field
  PanelController->>DefaultTheme: render note card
  DefaultTheme->>Engine: read current answer values
  Engine-->>DefaultTheme: return interpolation values
  DefaultTheme-->>User: display note without cursor interaction
  PanelController->>Engine: resolve submitted inputs
  Engine-->>PanelController: return answers without note fields
Loading

Possibly related PRs

  • drevops/tui#52: Both PRs modify the widget SVG generation and static rendering pipeline.
  • drevops/tui#68: Both PRs modify the theme rendering flow in DefaultTheme.php.
  • drevops/tui#82: Both PRs modify the widget SVG rendering and static variant flow.

Suggested labels: A3

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 51.11% 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
Linked Issues check ✅ Passed The PR adds a note field that is inline, non-interactive, skipped in answers/headless collection, supports when/templating, and is covered by tests.
Out of Scope Changes check ✅ Passed The changes stay focused on the note field feature and its supporting rendering, schema, docs, and tests; no unrelated code changes stand out.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: adding a non-interactive informational note field.
✨ 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 feature/91-note-field

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

@github-actions

github-actions Bot commented Jul 23, 2026

Copy link
Copy Markdown

@github-actions

This comment has been minimized.

@codecov

codecov Bot commented Jul 23, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 99.05660% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 98.66%. Comparing base (9878aca) to head (430e707).
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
src/Render/PanelController.php 90.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #117      +/-   ##
==========================================
+ Coverage   98.21%   98.66%   +0.45%     
==========================================
  Files         100      100              
  Lines        3358     3450      +92     
==========================================
+ Hits         3298     3404     +106     
+ Misses         60       46      -14     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 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 `@src/Engine/Engine.php`:
- Around line 542-548: Update the fix-up processing near the existing target
check to also skip or reject any fix-up whose `from` field resolves to a
presentational field, before reading from `$values`. Preserve settled target
values when the source is presentational, and add a regression test covering a
fix-up that reads from a note.

In `@src/Theme/DefaultTheme.php`:
- Around line 1008-1018: Extract the shared note-title interpolation and
first-line normalization into a helper near the relevant rendering methods, then
reuse it from renderColumnBlock(), measureColumnBlock(), and renderNoteLines().
Preserve the existing empty-title handling and ensure the helper returns the
same first normalized line currently produced by Strings::interpolate(),
normalizeLines(), and explode().
🪄 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: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: bd27bc5e-700d-46e7-a79a-378378ecf2c0

📥 Commits

Reviewing files that changed from the base of the PR and between 4da0f18 and 810c698.

📒 Files selected for processing (31)
  • .claude/demo_content_reference.md
  • playground/02-widgets-all-widgets.php
  • playground/02-widgets-note.php
  • src/Builder/FieldBuilder.php
  • src/Builder/PanelBuilder.php
  • src/Derive/Derive.php
  • src/Engine/Engine.php
  • src/Model/Field.php
  • src/Model/FieldType.php
  • src/Render/PanelController.php
  • src/Schema/AgentHelp.php
  • src/Schema/SchemaGenerator.php
  • src/Schema/SchemaValidator.php
  • src/Theme/DefaultTheme.php
  • src/Utils/Strings.php
  • src/Widget/WidgetFactory.php
  • tests/phpunit/Fixtures/Form/AllWidgetsForm.php
  • tests/phpunit/Unit/Builder/FormTest.php
  • tests/phpunit/Unit/Engine/EngineConditionalTest.php
  • tests/phpunit/Unit/Engine/EngineNonInteractiveTest.php
  • tests/phpunit/Unit/Model/OptionTest.php
  • tests/phpunit/Unit/Render/PanelControllerTest.php
  • tests/phpunit/Unit/Schema/AgentHelpTest.php
  • tests/phpunit/Unit/Schema/SchemaGeneratorTest.php
  • tests/phpunit/Unit/Schema/SchemaValidatorTest.php
  • tests/phpunit/Unit/Testing/AllWidgetsFormTest.php
  • tests/phpunit/Unit/Theme/ThemeLayoutTest.php
  • tests/phpunit/Unit/Theme/ThemeRenderTest.php
  • tests/phpunit/Unit/Utils/StringsTest.php
  • tests/phpunit/Unit/Widget/WidgetFactoryTest.php
  • translations/en.php

Comment thread src/Engine/Engine.php Outdated
Comment thread src/Theme/DefaultTheme.php Outdated
@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@AlexSkrypnyk AlexSkrypnyk added the Needs review Pull request needs a review from assigned developers label Jul 23, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 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 `@docs/content/widgets/note.mdx`:
- Around line 22-25: Make the interpolation example around note() self-contained
by adding a preceding declaration or population of the item field before the
description uses {{item}}. Keep the existing note construction intact and ensure
readers can copy the snippet and observe resolved interpolation without relying
on prior form context.
🪄 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: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 6875935f-48bc-4e10-9d5e-cc0e66108039

📥 Commits

Reviewing files that changed from the base of the PR and between b59b62c and 90a7239.

⛔ Files ignored due to path filters (24)
  • docs/assets/widget-note-dark-animated-ascii-no-ansi.svg is excluded by !**/*.svg
  • docs/assets/widget-note-dark-animated-ascii.svg is excluded by !**/*.svg
  • docs/assets/widget-note-dark-animated-no-ansi.svg is excluded by !**/*.svg
  • docs/assets/widget-note-dark-animated.svg is excluded by !**/*.svg
  • docs/assets/widget-note-dark-static-ascii-no-ansi.svg is excluded by !**/*.svg
  • docs/assets/widget-note-dark-static-ascii.svg is excluded by !**/*.svg
  • docs/assets/widget-note-dark-static-no-ansi.svg is excluded by !**/*.svg
  • docs/assets/widget-note-dark-static.svg is excluded by !**/*.svg
  • docs/assets/widget-note-light-animated-ascii-no-ansi.svg is excluded by !**/*.svg
  • docs/assets/widget-note-light-animated-ascii.svg is excluded by !**/*.svg
  • docs/assets/widget-note-light-animated-no-ansi.svg is excluded by !**/*.svg
  • docs/assets/widget-note-light-animated.svg is excluded by !**/*.svg
  • docs/assets/widget-note-light-static-ascii-no-ansi.svg is excluded by !**/*.svg
  • docs/assets/widget-note-light-static-ascii.svg is excluded by !**/*.svg
  • docs/assets/widget-note-light-static-no-ansi.svg is excluded by !**/*.svg
  • docs/assets/widget-note-light-static.svg is excluded by !**/*.svg
  • docs/assets/widgets-dark-animated-ascii-no-ansi.svg is excluded by !**/*.svg
  • docs/assets/widgets-dark-animated-ascii.svg is excluded by !**/*.svg
  • docs/assets/widgets-dark-animated-no-ansi.svg is excluded by !**/*.svg
  • docs/assets/widgets-dark-animated.svg is excluded by !**/*.svg
  • docs/assets/widgets-light-animated-ascii-no-ansi.svg is excluded by !**/*.svg
  • docs/assets/widgets-light-animated-ascii.svg is excluded by !**/*.svg
  • docs/assets/widgets-light-animated-no-ansi.svg is excluded by !**/*.svg
  • docs/assets/widgets-light-animated.svg is excluded by !**/*.svg
📒 Files selected for processing (5)
  • AGENTS.md
  • docs/content/widgets/index.mdx
  • docs/content/widgets/note.mdx
  • docs/sidebars.js
  • docs/util/render-widget-svgs.php

Comment thread docs/content/widgets/note.mdx Outdated
The '{{field}}' token replacement lived privately in 'Derive'. Moved it to 'Strings::interpolate()' so the note field can reuse the same templating without duplicating the callback. 'Derive::compute()' now delegates to it, unchanged in behaviour.
A note renders a title and body inline as a read-only card. The selection cursor skips it, it contributes nothing to the answers payload, and it is absent from headless collection and both machine schemas. Its title and body take the same '{{field}}' templating derived values use, so a note can reflect earlier answers; '->border()' frames the card in the theme's box.

The card is presentational, keyed off a new 'FieldType::isPresentational()': the engine and panel controller exclude it from answers and navigation, while the theme renders it via 'renderNoteLines()'. Declared with 'note(id, title)->description(body)'.
The button selection offset read 'Panel::itemCount()', which counts presentational notes, while the cursor indexes only navigable items. In a modal (or any panel showing buttons) that held a note, the offset was one too high per note, so the highlighted button drifted or vanished. Both the hub and modal frames now derive the offset from 'itemCountFor()', matching the navigation.
A note now never enters the value or source maps: 'resolveAll()' skips it, so it cannot be resolved from a supplied input nor influence a later field's context, and 'ruleMap()' skips it, so it never carries a derive rule that would resolve against a missing source. The engine test proves a note with a validator and a throwing transformer, handed a malformed value, still contributes nothing and never runs either.
The title now splits on its own newlines like the body, so no rendered line carries an embedded newline that would break the box and scroll maths; the grid preview and its measurement take the title's first line, matching how field values already collapse in a one-row cell.
A fix-up sets a field's value, but a note has none. A rule mistakenly targeting a note is now skipped in 'applyFixups()' rather than writing a value into the settled state, so the no-value invariant holds even under a misconfigured form.
…ding.

The builder test asserts the field exists before reading its properties, dropping the nullsafe accesses. The all-widgets fixture note uses neutral, widget-focused wording, consistent with the rest of that fixture rather than the produce demo theme.
Split the combined early-continue guards into one condition each, switched a null assertion to 'assertNotInstanceOf()', and used a first-class callable in an 'array_map()' - the modernizations Rector enforces.
A fix-up whose 'from' field is presentational is now skipped as well as one whose 'set' target is: reading a note's absent value would write NULL over the target's settled value. The note-title interpolation and first-line extraction move into 'noteText()' and 'noteTitleFirstLine()', reused by 'renderNoteLines()', 'renderColumnBlock()' and 'measureColumnBlock()'.
Rendered the note widget's 16 SVG variants and added its 'docs/content/widgets/note.mdx' page, sidebar entry and widgets-index entry. Regenerated the all-widgets montage so the gallery includes the note card. Added a 'note' spec to the widget SVG renderer and documented in AGENTS.md that every widget must ship its full SVG set.
…voice.

The base docs switched to US spelling and 'kbd' key markup; 'note.mdx' now uses 'behavior'/'color' and Prettier's table formatting, and the note merges into the rewritten widgets index.
@AlexSkrypnyk
AlexSkrypnyk force-pushed the feature/91-note-field branch from 90a7239 to 678a3b6 Compare July 24, 2026 00:16
@github-actions

This comment has been minimized.

The '{{item}}' example now declares the 'item' text field it reflects, so the snippet demonstrates resolved interpolation when copied as-is.
@github-actions

Copy link
Copy Markdown
Code Coverage Report:
  2026-07-24 00:30:05

 Summary:
  Classes: 83.00% (83/100)
  Methods: 96.16% (776/807)
  Lines:   98.67% (3404/3450)

DrevOps\Tui\Answers\Answer
  Methods: 100.00% ( 1/ 1)   Lines: 100.00% (  1/  1)
DrevOps\Tui\Answers\Answers
  Methods: 100.00% ( 9/ 9)   Lines: 100.00% ( 20/ 20)
DrevOps\Tui\Answers\Provenance
  Methods: 100.00% ( 1/ 1)   Lines: 100.00% (  7/  7)
DrevOps\Tui\Answers\SummaryFormatter
  Methods: 100.00% ( 4/ 4)   Lines: 100.00% ( 20/ 20)
DrevOps\Tui\Answers\ValueFormatter
  Methods: 100.00% ( 2/ 2)   Lines: 100.00% (  6/  6)
DrevOps\Tui\Builder\FieldBuilder
  Methods: 100.00% (39/39)   Lines: 100.00% (141/141)
DrevOps\Tui\Builder\Form
  Methods:  92.31% (12/13)   Lines:  98.39% ( 61/ 62)
DrevOps\Tui\Builder\LayoutGuard
  Methods: 100.00% ( 1/ 1)   Lines: 100.00% (  7/  7)
DrevOps\Tui\Builder\PanelBuilder
  Methods: 100.00% (21/21)   Lines: 100.00% ( 38/ 38)
DrevOps\Tui\Condition\CompositeCondition
  Methods: 100.00% ( 4/ 4)   Lines: 100.00% ( 19/ 19)
DrevOps\Tui\Condition\Condition
  Methods: 100.00% (10/10)   Lines: 100.00% ( 38/ 38)
DrevOps\Tui\Derive\Derive
  Methods: 100.00% ( 3/ 3)   Lines: 100.00% ( 10/ 10)
DrevOps\Tui\Derive\Deriver
  Methods: 100.00% ( 1/ 1)   Lines: 100.00% ( 13/ 13)
DrevOps\Tui\Derive\Transform
  Methods: 100.00% ( 3/ 3)   Lines: 100.00% (  7/  7)
DrevOps\Tui\Discovery\AbstractDiscover
  Methods: 100.00% ( 1/ 1)   Lines: 100.00% (  1/  1)
DrevOps\Tui\Discovery\Dotenv
  Methods: 100.00% ( 3/ 3)   Lines: 100.00% ( 19/ 19)
DrevOps\Tui\Discovery\JsonValue
  Methods: 100.00% ( 4/ 4)   Lines: 100.00% ( 16/ 16)
DrevOps\Tui\Discovery\PathExists
  Methods: 100.00% ( 3/ 3)   Lines: 100.00% (  3/  3)
DrevOps\Tui\Discovery\Scan
  Methods: 100.00% ( 3/ 3)   Lines: 100.00% ( 20/ 20)
DrevOps\Tui\Engine\Engine
  Methods: 100.00% (18/18)   Lines: 100.00% (131/131)
DrevOps\Tui\Handler\HandlerRegistry
  Methods:  85.71% ( 6/ 7)   Lines:  95.45% ( 21/ 22)
DrevOps\Tui\Input\Binding
  Methods: 100.00% ( 1/ 1)   Lines: 100.00% (  1/  1)
DrevOps\Tui\Input\DefaultKeyMap
  Methods: 100.00% ( 1/ 1)   Lines: 100.00% ( 38/ 38)
DrevOps\Tui\Input\Hint
  Methods: 100.00% ( 1/ 1)   Lines: 100.00% (  2/  2)
DrevOps\Tui\Input\Key
  Methods:  87.50% ( 7/ 8)   Lines:  63.64% (  7/ 11)
DrevOps\Tui\Input\KeyMap
  Methods: 100.00% (11/11)   Lines: 100.00% ( 61/ 61)
DrevOps\Tui\Input\KeyMapManager
  Methods: 100.00% ( 2/ 2)   Lines: 100.00% (  8/  8)
DrevOps\Tui\Input\KeyParser
  Methods:  85.71% ( 6/ 7)   Lines:  98.95% ( 94/ 95)
DrevOps\Tui\Input\Scope
  Methods: 100.00% ( 7/ 7)   Lines: 100.00% ( 17/ 17)
DrevOps\Tui\Input\ScopedKeyMap
  Methods: 100.00% ( 4/ 4)   Lines: 100.00% (  4/  4)
DrevOps\Tui\Input\VimKeyMap
  Methods: 100.00% ( 1/ 1)   Lines: 100.00% ( 12/ 12)
DrevOps\Tui\Model\Buttons
  Methods: 100.00% ( 1/ 1)   Lines: 100.00% (  1/  1)
DrevOps\Tui\Model\DateBounds
  Methods: 100.00% ( 6/ 6)   Lines: 100.00% ( 28/ 28)
DrevOps\Tui\Model\Field
  Methods:  84.62% (11/13)   Lines:  89.33% ( 67/ 75)
DrevOps\Tui\Model\FieldType
  Methods: 100.00% ( 4/ 4)   Lines: 100.00% ( 24/ 24)
DrevOps\Tui\Model\FormDefinition
  Methods: 100.00% ( 4/ 4)   Lines: 100.00% ( 12/ 12)
DrevOps\Tui\Model\Modal
  Methods: 100.00% ( 1/ 1)   Lines: 100.00% (  2/  2)
DrevOps\Tui\Model\NumberBounds
  Methods:  83.33% ( 5/ 6)   Lines:  95.24% ( 20/ 21)
DrevOps\Tui\Model\Option
  Methods: 100.00% ( 4/ 4)   Lines: 100.00% ( 14/ 14)
DrevOps\Tui\Model\Panel
  Methods: 100.00% ( 3/ 3)   Lines: 100.00% (  3/  3)
DrevOps\Tui\Model\Weekday
  Methods: 100.00% ( 4/ 4)   Lines: 100.00% ( 15/ 15)
DrevOps\Tui\Render\Ansi
  Methods:  83.33% ( 5/ 6)   Lines:  76.47% ( 13/ 17)
DrevOps\Tui\Render\Box
  Methods: 100.00% ( 3/ 3)   Lines: 100.00% ( 15/ 15)
DrevOps\Tui\Render\ExternalEditor
  Methods: 100.00% ( 6/ 6)   Lines: 100.00% ( 27/ 27)
DrevOps\Tui\Render\HelpSection
  Methods: 100.00% ( 1/ 1)   Lines: 100.00% (  1/  1)
DrevOps\Tui\Render\Navigator
  Methods: 100.00% ( 7/ 7)   Lines: 100.00% ( 16/ 16)
DrevOps\Tui\Render\Overlay
  Methods: 100.00% ( 4/ 4)   Lines: 100.00% ( 24/ 24)
DrevOps\Tui\Render\PanelController
  Methods:  97.92% (47/48)   Lines:  99.68% (313/314)
DrevOps\Tui\Render\Scroller
  Methods: 100.00% ( 4/ 4)   Lines: 100.00% ( 14/ 14)
DrevOps\Tui\Render\Terminal
  Methods:  95.24% (20/21)   Lines:  96.88% ( 62/ 64)
DrevOps\Tui\Render\TerminalControl
  Methods: 100.00% ( 9/ 9)   Lines: 100.00% (  9/  9)
DrevOps\Tui\Render\Viewport
  Methods: 100.00% ( 1/ 1)   Lines: 100.00% (  1/  1)
DrevOps\Tui\Resolver\InputResolver
  Methods: 100.00% ( 6/ 6)   Lines: 100.00% ( 29/ 29)
DrevOps\Tui\Schema\AgentHelp
  Methods: 100.00% ( 4/ 4)   Lines: 100.00% ( 49/ 49)
DrevOps\Tui\Schema\SchemaGenerator
  Methods: 100.00% ( 3/ 3)   Lines: 100.00% ( 35/ 35)
DrevOps\Tui\Schema\SchemaValidator
  Methods: 100.00% ( 7/ 7)   Lines: 100.00% ( 34/ 34)
DrevOps\Tui\Testing\ArrayKeyStream
  Methods: 100.00% ( 3/ 3)   Lines: 100.00% ( 12/ 12)
DrevOps\Tui\Testing\BufferedTerminal
  Methods: 100.00% ( 7/ 7)   Lines: 100.00% ( 12/ 12)
DrevOps\Tui\Testing\KeyEncoder
  Methods: 100.00% ( 1/ 1)   Lines: 100.00% ( 22/ 22)
DrevOps\Tui\Testing\TuiTester
  Methods: 100.00% (13/13)   Lines: 100.00% ( 34/ 34)
DrevOps\Tui\Testing\WidgetRunner
  Methods: 100.00% ( 1/ 1)   Lines: 100.00% (  5/  5)
DrevOps\Tui\Theme\DefaultTheme
  Methods:  95.96% (95/99)   Lines:  98.81% (499/505)
DrevOps\Tui\Theme\DosTheme
  Methods:  80.00% (12/15)   Lines:  82.35% ( 14/ 17)
DrevOps\Tui\Theme\EmberTheme
  Methods:  66.67% ( 6/ 9)   Lines:  66.67% (  6/  9)
DrevOps\Tui\Theme\FrostTheme
  Methods:  66.67% ( 6/ 9)   Lines:  66.67% (  6/  9)
DrevOps\Tui\Theme\MidnightTheme
  Methods:  66.67% ( 6/ 9)   Lines:  66.67% (  6/  9)
DrevOps\Tui\Theme\MonoTheme
  Methods:  66.67% ( 6/ 9)   Lines:  66.67% (  6/  9)
DrevOps\Tui\Theme\Sgr
  Methods: 100.00% ( 1/ 1)   Lines: 100.00% (  1/  1)
DrevOps\Tui\Theme\ThemeManager
  Methods: 100.00% ( 2/ 2)   Lines: 100.00% (  8/  8)
DrevOps\Tui\Translation\Translator
  Methods: 100.00% (18/18)   Lines: 100.00% ( 87/ 87)
DrevOps\Tui\Tui
  Methods: 100.00% (23/23)   Lines: 100.00% ( 72/ 72)
DrevOps\Tui\Utils\Strings
  Methods: 100.00% ( 7/ 7)   Lines: 100.00% ( 13/ 13)
DrevOps\Tui\Widget\AbstractWidget
  Methods: 100.00% (18/18)   Lines: 100.00% ( 49/ 49)
DrevOps\Tui\Widget\CalendarWidget
  Methods: 100.00% (13/13)   Lines: 100.00% ( 52/ 52)
DrevOps\Tui\Widget\Capability\CompletionCapableTrait
  Methods: 100.00% ( 3/ 3)   Lines: 100.00% ( 14/ 14)
DrevOps\Tui\Widget\Capability\FilterCapableTrait
  Methods: 100.00% ( 4/ 4)   Lines: 100.00% ( 15/ 15)
DrevOps\Tui\Widget\Capability\OptionsCapableTrait
  Methods: 100.00% ( 9/ 9)   Lines: 100.00% ( 34/ 34)
DrevOps\Tui\Widget\Capability\PagingCapableTrait
  Methods: 100.00% ( 4/ 4)   Lines: 100.00% ( 16/ 16)
DrevOps\Tui\Widget\Capability\SearchCapableTrait
  Methods: 100.00% ( 3/ 3)   Lines: 100.00% (  3/  3)
DrevOps\Tui\Widget\Capability\SelectionCapableTrait
  Methods: 100.00% (13/13)   Lines: 100.00% ( 85/ 85)
DrevOps\Tui\Widget\Capability\TextEditCapableTrait
  Methods: 100.00% ( 9/ 9)   Lines: 100.00% ( 34/ 34)
DrevOps\Tui\Widget\ConfirmWidget
  Methods: 100.00% ( 7/ 7)   Lines: 100.00% ( 22/ 22)
DrevOps\Tui\Widget\FilePickerWidget
  Methods: 100.00% (31/31)   Lines: 100.00% (180/180)
DrevOps\Tui\Widget\MatchResult
  Methods: 100.00% ( 1/ 1)   Lines: 100.00% (  1/  1)
DrevOps\Tui\Widget\MatchTier
  Methods: 100.00% ( 1/ 1)   Lines: 100.00% (  6/  6)
DrevOps\Tui\Widget\Matcher
  Methods: 100.00% ( 9/ 9)   Lines: 100.00% ( 73/ 73)
DrevOps\Tui\Widget\NumberWidget
  Methods: 100.00% ( 9/ 9)   Lines: 100.00% ( 36/ 36)
DrevOps\Tui\Widget\PasswordDisplay
  Methods: 100.00% ( 1/ 1)   Lines: 100.00% (  5/  5)
DrevOps\Tui\Widget\PasswordWidget
  Methods: 100.00% ( 9/ 9)   Lines: 100.00% ( 45/ 45)
DrevOps\Tui\Widget\PauseWidget
  Methods: 100.00% ( 5/ 5)   Lines: 100.00% ( 11/ 11)
DrevOps\Tui\Widget\ReorderWidget
  Methods: 100.00% (10/10)   Lines: 100.00% ( 54/ 54)
DrevOps\Tui\Widget\SearchWidget
  Methods: 100.00% ( 4/ 4)   Lines: 100.00% ( 11/ 11)
DrevOps\Tui\Widget\SelectWidget
  Methods: 100.00% ( 5/ 5)   Lines: 100.00% (  7/  7)
DrevOps\Tui\Widget\SuggestWidget
  Methods: 100.00% (12/12)   Lines: 100.00% ( 45/ 45)
DrevOps\Tui\Widget\TextWidget
  Methods: 100.00% ( 5/ 5)   Lines: 100.00% ( 16/ 16)
DrevOps\Tui\Widget\TextareaWidget
  Methods: 100.00% ( 8/ 8)   Lines: 100.00% ( 49/ 49)
DrevOps\Tui\Widget\ToggleWidget
  Methods: 100.00% ( 8/ 8)   Lines: 100.00% ( 30/ 30)
DrevOps\Tui\Widget\WidgetFactory
  Methods: 100.00% ( 8/ 8)   Lines: 100.00% ( 37/ 37)

@AlexSkrypnyk
AlexSkrypnyk merged commit 18b4e33 into main Jul 24, 2026
12 checks passed
@AlexSkrypnyk
AlexSkrypnyk deleted the feature/91-note-field branch July 24, 2026 00:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Needs review Pull request needs a review from assigned developers

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add a non-interactive informational note field

1 participant