5 Commits

Author SHA1 Message Date
HAL9000 38fd9cc839 fix(tests): align output-rendering tests with spec §26936 progress-omission and renamed TerminalCapabilities fields
Four CI failures fixed:

1. JSON/YAML progress scenarios (features/output_rendering.feature:588 and :1584):
   The conflict resolver had preserved master's test assertions expecting
   ProgressIndicator elements in JSON/YAML data arrays, but the PR's
   _snapshot_to_dict correctly omits them per spec §26936 ("progress is
   omitted from JSON output"). Removed the assertions that contradict the
   spec-compliant implementation.

2. ColumnDef all-fields scenario (:1885):
   Test checked for "col_type" in raw JSON output, but _column_def_to_dict
   serialises the field under the key "type" (via Pydantic alias). Changed
   assertion to "width_hint" which IS a serialised key in the ColumnDef dict.

3. Rich-with-cursor scenario (:2154):
   Step constructed TerminalCapabilities(supports_cursor=True, term=...) using
   the old field names — now backward-compat properties, not Pydantic fields.
   Pydantic silently ignores unknown kwargs, leaving supports_cursor_movement=False
   and causing select_materializer("rich") to return TableMaterializer. Updated
   to supports_cursor_movement=True and term_program="xterm-256color".

4. Robot json-all / yaml-all helpers:
   Same conflict-resolution issue as #1: helper expected all 10 element types
   including "progress" in JSON/YAML data arrays. Removed "progress" from both
   expected lists to match the spec-compliant implementation.
2026-06-02 16:48:22 -04:00
freemo afe6b849fe feat(cli): implement missing output element types and handles
CI / benchmark-publish (pull_request) Has been skipped
CI / build (pull_request) Successful in 19s
CI / helm (pull_request) Successful in 21s
CI / lint (pull_request) Successful in 3m19s
CI / quality (pull_request) Successful in 3m52s
CI / typecheck (pull_request) Successful in 3m56s
CI / security (pull_request) Successful in 4m5s
CI / integration_tests (pull_request) Successful in 7m2s
CI / unit_tests (pull_request) Successful in 11m51s
CI / docker (pull_request) Successful in 1m31s
CI / coverage (pull_request) Successful in 11m50s
CI / e2e_tests (pull_request) Successful in 16m31s
CI / status-check (pull_request) Successful in 1s
CI / build (push) Successful in 17s
CI / helm (push) Successful in 21s
CI / lint (push) Successful in 24s
CI / quality (push) Successful in 3m41s
CI / integration_tests (push) Successful in 3m46s
CI / typecheck (push) Successful in 3m55s
CI / security (push) Successful in 4m6s
CI / unit_tests (push) Successful in 7m14s
CI / docker (push) Successful in 1m32s
CI / benchmark-regression (push) Has been skipped
CI / coverage (push) Successful in 11m46s
CI / e2e_tests (push) Successful in 18m1s
CI / status-check (push) Successful in 1s
CI / benchmark-publish (push) Successful in 28m19s
CI / benchmark-regression (pull_request) Successful in 54m43s
Implement LiveMaterializationStrategy as the third materialization
strategy type (alongside sequential_buffer and accumulate) per spec
§26456-26492.  The live strategy renders element updates in-place at
~15 fps by tracking a dirty-element set and coalescing updates into
frame redraws.

RichMaterializer now extends LiveMaterializationStrategy instead of
_BaseBufferStrategy, enabling supports_incremental_updates=True.
Element rendering still delegates to the colour renderer for visual
formatting, maintaining backward compatibility.

Changes:
- Add _LiveMaterializationStrategy class with frame-rate throttling,
  dirty-element tracking, and per-frame composition in declaration
  order
- Update RichMaterializer to extend _LiveMaterializationStrategy
- Export LiveMaterializationStrategy from materializers.py and
  __init__.py
- Update SD-2 and SD-7 documentation in __init__.py
- Add vulture whitelist entry for LiveMaterializationStrategy
- Add 5 Behave scenarios covering live strategy rendering, incremental
  update support, dirty-element coalescing, all-element-type rendering,
  and frame rate validation
- Add step definitions for the new scenarios

ISSUES CLOSED: #903
2026-03-30 19:52:51 +00:00
hurui200320 2434253c1a feat(cli): implement full output rendering framework (#812)
CI / build (push) Successful in 16s
CI / lint (push) Successful in 18s
CI / quality (push) Successful in 28s
CI / typecheck (push) Successful in 1m0s
CI / security (push) Successful in 1m0s
CI / benchmark-regression (push) Has been skipped
CI / unit_tests (push) Successful in 3m14s
CI / integration_tests (push) Successful in 3m38s
CI / docker (push) Successful in 55s
CI / e2e_tests (push) Successful in 5m15s
CI / coverage (push) Successful in 7m8s
CI / benchmark-publish (push) Successful in 20m34s
## Summary

Implement the 6 missing element handle types (Tree, Text, Code, Diff, Separator, ActionHint) and ensure all 6 materialization strategies (rich, color, table, plain, json, yaml) support all 10 element types. This completes the output rendering framework per the specification (§25417-27276).

Closes #550

## Changes

### Source (restructured into smaller modules)

#### `handles/` package (was `handles.py` — 1062 lines → 5 files, all ≤500 lines)
- **`_models.py`**: All Pydantic data models, constants (MAX_TREE_DEPTH, MAX_ELEMENTS_PER_SESSION, MAX_TABLE_ROWS), exceptions (ElementClosedError), event classes, ElementSnapshot union. P2-1: `DiffLine.type` renamed to `line_type` with backward-compatible alias.
- **`_base.py`**: Generic `ElementHandle[E]` base class with thread-safe `element_copy()` (lock-protected).
- **`_panel_table.py`**: PanelHandle, TableHandle, StatusHandle.
- **`_concrete.py`**: ProgressHandle (P1-1: validates `total` non-negative), TreeHandle, TextHandle (P3-2: close() delegates to super()), CodeHandle, DiffHandle, SeparatorHandle, ActionHintHandle. P3-8: `increment(delta=0)` now rejected.
- **`__init__.py`**: Re-exports all public symbols.

#### `_renderers.py` — plain renderers, sanitization, and shared helpers
- Plain render functions for all 10 element types.
- Terminal escape sanitization (`strip_terminal_escapes`).
- P2-3: `_sort_table_rows` now consults `ColumnDef.col_type` for numeric sorting.
- P2-6: `compute_column_widths()` shared helper extracted (DRY fix).

#### `_color_renderers.py` — ANSI colour renderers
- Colour-coded render functions for all 10 element types.
- P2-2: TextBlock now gets color treatment (`_render_text_color`) instead of falling through to plain.

#### `_boxdraw.py` — box-drawing renderers
- P2-5: Upgraded from ASCII `+-|` to Unicode box-drawing `╭─╮│╰╯` with rounded corners per spec §26821.

#### `_ids.py` — ID generation helpers
- P3-1: Session and handle IDs now use separate counters, making IDs monotonic within their namespace.

#### `materializers.py` — strategy protocol and 6 concrete strategies
- P1-2: `_snapshot_to_dict` now includes `timing` field in JSON/YAML output per spec §27022.
- P2-4: `_column_def_to_dict` always includes all fields unconditionally for stable JSON schemas.

#### `selection.py` — materializer selection with fallback
- P1-4: `NO_COLOR` environment variable now respected (https://no-color.org/). When set, all visual formats fall back to plain. Precedence: explicit flag > NO_COLOR > terminal capability fallback.

#### `session.py`
- P1-1: `session.progress()` factory validates `total >= 0`.
- P1-2: `snapshot()` includes `timing` when available.

#### `__init__.py` — package docstring
- P1-3: SD-29 corrected to reflect actual Table → Color → Plain fallback chain.
- SD-14 marked as implemented (NO_COLOR support added).

### Spec Deviations (Documented)
28 deliberate deviations documented in `__init__.py` module docstring (SD-1 through SD-29, with SD-14 now implemented). SD-29 corrected.

### Tests (updated)
- **+23 new BDD scenarios** covering: P1-1 total validation, P1-4 NO_COLOR, P2-1 DiffLine.line_type alias, P2-2 text color, P2-3 numeric sorting, P2-4 ColumnDef serialization, P2-5 Unicode box-drawing, P3-3 add_rows limit, P3-5 10-thread stress test, P3-6 summary truncation, P3-7 explicit format for color/table, P3-8 zero delta.
- **Robot tests**: Updated box-drawing assertion for Unicode chars.

## Verification

| Check | Result |
|-------|--------|
| Pyright | 0 errors, 1 pre-existing warning |
| Ruff lint | All passed |
| Unit tests | 393 features, 11,344 scenarios, 0 failures |
| Integration tests | All passed |
| E2E tests | All passed |
| Coverage | 97% overall (threshold: 97%) |

## Review Fixes Applied (Luis Review #2412)

| ID | Severity | Fix |
|----|----------|-----|
| P1-1 | High | `set_progress()` and `session.progress()` validate `total >= 0` |
| P1-2 | High | `_snapshot_to_dict` includes `timing` field |
| P1-3 | High | SD-29 documentation corrected |
| P1-4 | High | `NO_COLOR` env var respected |
| P2-1 | Medium | `DiffLine.type` → `line_type` with alias |
| P2-2 | Medium | TextBlock gets color treatment |
| P2-3 | Medium | Numeric column sorting |
| P2-4 | Medium | ColumnDef always serializes all fields |
| P2-5 | Medium | Unicode box-drawing characters |
| P2-6 | Medium | Shared `compute_column_widths()` helper |
| P3-1 | Low | Separate ID counters |
| P3-2 | Low | TextHandle.close() delegates to super() |
| P3-3 | Low | add_rows batch limit test |
| P3-5 | Low | 10-thread stress test |
| P3-6 | Low | Summary truncation test |
| P3-7 | Low | Explicit format tests for color/table |
| P3-8 | Low | Zero delta rejected |

### Deferred Items
| ID | Reason |
|----|--------|
| P3-9 | snapshot() lock scope — acceptable correctness trade-off |
| P3-10 | CLEVERAGENTS_FORMAT env var — documented as SD-15, requires CLI framework changes |

Reviewed-on: #812
Reviewed-by: Jeffrey Phillips Freeman <jeffrey.freeman@cleverthis.com>
Co-authored-by: Rui Hu <rui.hu@cleverthis.com>
Co-committed-by: Rui Hu <rui.hu@cleverthis.com>
2026-03-19 08:46:46 +00:00
freemo 2980b14e7b test: boost combined branch coverage to 97% with additional behave scenarios
Add ~60 new behave scenarios across output rendering, tool router, file ops,
and skill search features targeting uncovered lines and branches. Key additions:
- ElementHandle validation guards (empty id, type, negative index, None args)
- Handle close/context-manager edge cases
- Table list-row and batch-row coverage
- Color/box-draw/JSON/YAML materializer edge cases
- Format selection paths (detect capabilities, explicit flag, empty format)
- Session ColumnDef, double-close guard, force-close open handles
- Tool router schema export and provider format scenarios
- File ops edge cases and search stat-failure/glob-include tests

All nox checks pass: lint, typecheck (0 errors), unit_tests (4730 scenarios),
coverage_report (97.0% >= 97% threshold).
2026-02-21 10:23:33 -05:00
freemo 1df21e6a64 feat(cli): add output rendering framework with materialization strategies 2026-02-21 10:19:45 -05:00