okf-tui 1.0.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/.okf/capabilities/index.md +13 -0
  3. data/.okf/capabilities/okf-surface.md +48 -0
  4. data/.okf/capabilities/views.md +48 -0
  5. data/.okf/decisions/invents-no-analysis.md +8 -7
  6. data/.okf/decisions/no-version-ceilings.md +8 -9
  7. data/.okf/decisions/okf-capability-drift.md +16 -18
  8. data/.okf/decisions/one-door-the-plugin-seam.md +15 -14
  9. data/.okf/decisions/registry-write-boundary.md +15 -14
  10. data/.okf/decisions/ruby-floor.md +11 -9
  11. data/.okf/decisions/search-facade-coupling.md +22 -24
  12. data/.okf/decisions/undeclared-width-dependency.md +12 -10
  13. data/.okf/index.md +13 -5
  14. data/.okf/interaction/cross-bundle-scope.md +8 -8
  15. data/.okf/interaction/deferred-search.md +8 -6
  16. data/.okf/interaction/esc-peels-one-layer.md +10 -9
  17. data/.okf/interaction/filter-escalates-to-search.md +12 -11
  18. data/.okf/interaction/following-links.md +10 -8
  19. data/.okf/interaction/key-routing.md +6 -5
  20. data/.okf/interaction/which-registry.md +14 -15
  21. data/.okf/log.md +22 -0
  22. data/.okf/rendering/ansi-aware-width.md +8 -7
  23. data/.okf/rendering/fit-or-say-so.md +34 -0
  24. data/.okf/rendering/index.md +1 -0
  25. data/.okf/rendering/markdown-rendering-trap.md +8 -7
  26. data/.okf/rendering/status-vocabulary.md +6 -5
  27. data/.okf/rendering/whole-frame-painting.md +8 -6
  28. data/.okf/structure/doors.md +61 -0
  29. data/.okf/structure/index.md +16 -0
  30. data/.okf/structure/rendering.md +58 -0
  31. data/.okf/structure/the-app.md +55 -0
  32. data/.okf/structure/the-workspace.md +69 -0
  33. data/.okf/testing/adding-a-view.md +58 -0
  34. data/.okf/testing/ci-matrix.md +8 -6
  35. data/.okf/testing/headless-frames.md +6 -6
  36. data/.okf/testing/index.md +2 -0
  37. data/.okf/testing/pty-test.md +6 -5
  38. data/.okf/testing/the-suite.md +120 -0
  39. data/CHANGELOG.md +57 -1
  40. data/README.md +7 -2
  41. data/lib/okf/tui/version.rb +1 -1
  42. metadata +18 -7
@@ -3,7 +3,12 @@ type: Runbook
3
3
  title: The One Test That Opens a Terminal
4
4
  description: A single pty test boots `okf tui` in a real process and walks every view, and the three timing traps that made it flake on the Ruby floor.
5
5
  tags: [testing, terminal, scar-tissue]
6
- timestamp: 2026-07-18
6
+ generated:
7
+ by: human:maintainer
8
+ at: 2026-07-18
9
+ sources:
10
+ - title: "`test/integration/terminal_test.rb` — `SCRIPT`, `settle`, `reap`."
11
+ resource: https://github.com/serradura/okf/blob/main/gems/okf-tui/test/integration/terminal_test.rb
7
12
  ---
8
13
 
9
14
  # Why it exists
@@ -67,7 +72,3 @@ the escape sequences before it do not.
67
72
  `"\t\r"` in a single write can reach the reader as a *single* keypress. Split
68
73
  control keys into separate steps — a race the test loses only sometimes is worse
69
74
  than one it loses always.
70
-
71
- # Citations
72
-
73
- [1] `test/integration/terminal_test.rb` — `SCRIPT`, `settle`, `reap`.
@@ -0,0 +1,120 @@
1
+ ---
2
+ type: Component
3
+ title: The Suite — Its Layers, and the Two Fixtures That Exist to Bite
4
+ description: "What each test file proves, why `nested` and `provenance` were built when twelve fixtures already existed, and the two gaps between this suite and the okf a user actually resolves."
5
+ tags: [testing, fixtures, structure]
6
+ generated:
7
+ by: human:maintainer
8
+ at: 2026-08-19
9
+ ---
10
+
11
+ # Integration first
12
+
13
+ `test/integration/` is the critical layer: it drives the app the way a user does
14
+ — real keys, real frames, real exit codes. A unit test proves a method behaves;
15
+ an integration test proves the *product* behaves.
16
+
17
+ ```
18
+ test/
19
+ test_helper.rb OKF::TUI::TestCase: app_for, render, with_registry,
20
+ with_local_registry
21
+ fixtures/ bundles chosen for their standing, not their size
22
+ nested/ the only one whose directories nest — see below
23
+ provenance/ the only v0.2 one, §5 declared and withheld — below
24
+ integration/
25
+ geometry_test.rb every row is exactly the terminal width
26
+ browse_test.rb reading order, rendering, find-in-body
27
+ search_test.rb deferred search, focus, escalation, the held corpus
28
+ graph_test.rb facets, and following a concept out
29
+ dirs_test.rb okf's directory set, and the dir facet
30
+ structure_test.rb hubs and dir traffic, against okf's own numbers,
31
+ and health's two panes
32
+ groups_test.rb registry groups, and scoping a search to one
33
+ refs_test.rb @slug / @group, and which registry resolves them
34
+ provenance_test.rb §5 on screen, and what a v0.1 bundle is spared
35
+ signals_test.rb health colours, the tab flag, the filters
36
+ cli_test.rb argv, streams, exit codes — CLI.run driven straight
37
+ plugin_test.rb `okf tui` through okf's registry, and that the
38
+ dispatcher adds nothing but the streams
39
+ terminal_test.rb `okf tui` in a real process, through a real pty —
40
+ the only test that walks process boot + discovery
41
+ unit/
42
+ gemspec_test.rb the declared okf floor tracks the kernel next door
43
+ packaging_test.rb LICENSE.txt and NOTICE ship, real files, unchanged
44
+ bundle_catalog_test.rb this bundle against the code it describes
45
+ ```
46
+
47
+ The three unit tests are there because their claims are about the *package* and
48
+ the *documentation*, not the app — no integration test can reach them.
49
+
50
+ # The two fixtures built to reach a branch nothing else could
51
+
52
+ **`fixtures/nested` exists because every other fixture is one level deep**, and
53
+ at one level `dir` and `top_dir` are the same string — so an assertion against
54
+ them passes whichever field the code reads, which is exactly how the `area`
55
+ break survived. It carries a real tree, an intermediate directory holding no
56
+ concepts of its own (`platform/`), and a directory whose only file is a `log.md`
57
+ (`history/`) — the two shapes okf 1.13.0 had to fix its own directory set for.
58
+ Six directories against three top-level ones: reach for it for anything about
59
+ `dir`, depth, or traffic.
60
+
61
+ **`fixtures/provenance` is the only v0.2 bundle**, and it carries a concept that
62
+ declares no §5 family (`untouched.md`) beside four that do — deliberately, so
63
+ the suppression rule is a property of the *concept* rather than of the fixture,
64
+ and one test can assert both halves against one bundle. Its numbers are chosen
65
+ to bite: three of its four `unverified` concepts are claimable, so a trust facet
66
+ counting the whole tally would say 4 and narrow to 3. Reach for it for anything
67
+ about trust, status, `generated`, `stale_after` or `sources`; reach for a v0.1
68
+ fixture to prove the same surface stays *absent*.
69
+
70
+ Keep both conformant and lint-clean, so they stay usable by the health tests.
71
+ Provenance's one `info` is the legacy `timestamp:` on `untouched.md`, which is
72
+ the §13.1 lift under test.
73
+
74
+ # Run with colour on, not just off
75
+
76
+ Pastel disables colour when stdout is not a terminal, so a piped test exercises
77
+ none of the ANSI-aware width, clipping and wrapping code — the paths most likely
78
+ to be wrong are exactly the ones a naive capture cannot see. `geometry_test` runs
79
+ both modes; `browse_test` forces colour for the render sweep.
80
+
81
+ That is not thoroughness for its own sake: the `IndexError` in
82
+ [markdown-rendering-trap](/rendering/markdown-rendering-trap.md) rendered
83
+ perfectly in every uncoloured test.
84
+
85
+ # No suite here runs the okf a user gets
86
+
87
+ The `Gemfile` resolves okf from `../okf`, and in the monorepo that checkout is
88
+ always there — so the local run, CI, and the 2.4 container all exercise
89
+ *unreleased* okf. That is the right default: it lets a kernel change be driven
90
+ from the UI without a release. It also leaves a checkout-versus-RubyGems gap.
91
+
92
+ Two things stand in that gap, covering different halves.
93
+ `test/unit/gemspec_test.rb` is the standing one: it fails the moment okf bumps
94
+ and the gemspec floor does not follow. And a run against the *published* okf
95
+ catches the rest — a released kernel resolves different analysis output, which
96
+ is a difference no floor expresses.
97
+
98
+ The disagreement it catches is silent: okf's lint findings on
99
+ `fixtures/okf-docs` have changed between releases before, which is enough to
100
+ change how many rows the health view has. **A test whose premise depends on
101
+ okf's analysis output can pass here and fail there** — the health scroll tests
102
+ did exactly that, proving a pane overflowed by leaning on a lint count. Prove a
103
+ rendering property from geometry (a terminal too short to fit) and let the
104
+ agreement tests be the place okf's numbers are asserted.
105
+
106
+ # Two assertion traps this suite has already hit
107
+
108
+ * **A check that crashes tells you less than one that fails.** When an
109
+ assertion's subject can be nil because the thing under test broke, report that
110
+ and skip the dependents rather than raising `NoMethodError` from the middle.
111
+ * **Judge a rendered offset against the window the view actually used.** An
112
+ earlier version compared a scroll against a different window size and reported
113
+ a failure that was not one.
114
+
115
+ And one naming rule: **name things, do not count them.** The browse list holds
116
+ reserved files as well as concepts, so `<down><down><down>` is a guess about
117
+ ordering. `open_concept("overview")` is a statement about which concept is open.
118
+
119
+ For the 2.4 container, **read its output, not its exit status** — piping it
120
+ through `tail` returns `tail`'s status, which is zero however the run went.
data/CHANGELOG.md CHANGED
@@ -5,6 +5,61 @@ All notable changes to this project are documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [1.0.1] - 2026-08-20
9
+
10
+ ### Fixed
11
+
12
+ - **The package metadata follows the `gems/` move and the repository rename.**
13
+ Two URLs on the package page were about to be wrong at once. `changelog_uri`
14
+ named `blob/main/okf-tui/CHANGELOG.md`, a path that stopped existing when the
15
+ four gems moved under `gems/`; `homepage` named `serradura/okf-gem`, and the
16
+ repository is now **`serradura/okf`** — the name the command has had all
17
+ along. rubygems.org serves whatever the last release published, so neither
18
+ corrects itself: only a release republishes metadata, and this is that
19
+ release. Both land in one round rather than two, which is the whole reason
20
+ the rename waited for the paths to stop moving.
21
+
22
+ `homepage_uri`, `source_code_uri` and `changelog_uri` are all derived from
23
+ `homepage`, so one line moves four pieces of this gem's metadata. GitHub
24
+ redirects the old URLs permanently, so anything already published keeps
25
+ resolving.
26
+
27
+ ### Changed
28
+
29
+ - **The gem's own bundle is now OKF v0.2.** It was the last one in the tree on
30
+ v0.1. Its 30 concepts moved `timestamp:` under `generated: { by, at }`, and
31
+ the 22 carrying a body `# Citations` list moved that provenance into
32
+ `sources:` — every entry keeping its text, with a GitHub URL where it named a
33
+ real file. The three concepts using positional `[1]` markers were rekeyed to
34
+ `[^1]` footnotes, which is what §5.1 asks for. `okf validate` and `okf lint`
35
+ are both clean on it.
36
+
37
+ ### Added
38
+
39
+ - **The bundle carries the structure and the catalogue, and a test pins them.**
40
+ `.okf/structure/` names every file under `lib/`, grouped by the layer that
41
+ owns it; `.okf/capabilities/` is the catalogue of the six views and the kernel
42
+ surface behind them; `.okf/testing/the-suite.md` is what each test file proves
43
+ and why the two special fixtures exist; `.okf/testing/adding-a-view.md` is the
44
+ walk a new screen owes. `test/unit/bundle_catalog_test.rb` fails when a file
45
+ under `lib/` is named by no concept, when a concept names a file that is gone,
46
+ or when the view catalogue and `App::TABS` disagree. `AGENTS.md` kept the
47
+ contracts and the commands and now routes here for the rest — its
48
+ hand-maintained Map of `lib/**` was the thing nothing checked.
49
+
50
+ ### Fixed
51
+
52
+ - **Three `AGENTS.md` paths pointed at directories that no longer exist** —
53
+ `cd /build/okf-tui`, `cd okf-tui`, and `working-directory: okf-tui`, all from
54
+ before the gems moved under `gems/`.
55
+
56
+ ### Changed
57
+
58
+ - **The okf floor moves to `>= 2.1.1, < 3`** — the kernel this gem develops
59
+ against released 2.1.1, and the floor tracks what the suite proves against
60
+ (the gemspec drill enforces equality as the normal state). Nothing here calls
61
+ a 2.1-only surface; the ceiling is unchanged.
62
+
8
63
  ## [1.0.0] - 2026-08-15
9
64
 
10
65
  First release.
@@ -236,4 +291,5 @@ First release.
236
291
  turns the next one into a resolution failure a maintainer sees instead of a
237
292
  wrong number a reader believes.
238
293
 
239
- [1.0.0]: https://github.com/serradura/okf-gem/releases/tag/okf-tui/v1.0.0
294
+ [1.0.1]: https://github.com/serradura/okf/compare/okf-tui/v1.0.0...okf-tui/v1.0.1
295
+ [1.0.0]: https://github.com/serradura/okf/releases/tag/okf-tui/v1.0.0
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # okf-tui
2
2
 
3
- A full-screen terminal UI for [Open Knowledge Format](https://github.com/serradura/okf-gem)
3
+ A full-screen terminal UI for [Open Knowledge Format](https://github.com/serradura/okf)
4
4
  bundles: read one, switch between many, configure the registry, and search
5
5
  across all of them at once. Built on the [TTY toolkit](https://ttytoolkit.org/components/).
6
6
 
@@ -21,7 +21,7 @@ This gem ships **no executable of its own** — deliberately. A second binary th
21
21
  only aliased `okf tui` would be one more name to install, document and keep
22
22
  working, and two front ends is two argument grammars waiting to drift. `okf`
23
23
  finds this gem because it ships `okf/plugin.rb`, the convention any gem can use
24
- to add a verb — see [extension points](https://github.com/serradura/okf-gem/blob/main/.okf/design/extension-points.md).
24
+ to add a verb — see [extension points](https://github.com/serradura/okf/blob/main/.okf/design/extension-points.md).
25
25
 
26
26
  The argument shape mirrors `okf server` exactly, because it is the same grammar:
27
27
  `@slug` names a registered bundle, bare `@` the registry default, `@group` fans out
@@ -189,6 +189,11 @@ silently rather than loudly.
189
189
  the verb resolves the same way it does for a user. See [AGENTS.md](AGENTS.md)
190
190
  for the contracts a change has to keep.
191
191
 
192
+ This gem ships its own knowledge bundle at `.okf/`, and it is the gem's own
193
+ documentation rather than a sample: what every file under `lib/` does, what each
194
+ of the six views answers, and why the interaction model is what it is. `okf tui
195
+ .okf` reads it in this program, which is the shortest honest demo there is.
196
+
192
197
  ## License
193
198
 
194
199
  Apache-2.0.
@@ -2,6 +2,6 @@
2
2
 
3
3
  module OKF
4
4
  module TUI
5
- VERSION = "1.0.0"
5
+ VERSION = "1.0.1"
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: okf-tui
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rodrigo Serradura
@@ -15,7 +15,7 @@ dependencies:
15
15
  requirements:
16
16
  - - ">="
17
17
  - !ruby/object:Gem::Version
18
- version: '2.0'
18
+ version: 2.1.1
19
19
  - - "<"
20
20
  - !ruby/object:Gem::Version
21
21
  version: '3'
@@ -25,7 +25,7 @@ dependencies:
25
25
  requirements:
26
26
  - - ">="
27
27
  - !ruby/object:Gem::Version
28
- version: '2.0'
28
+ version: 2.1.1
29
29
  - - "<"
30
30
  - !ruby/object:Gem::Version
31
31
  version: '3'
@@ -157,6 +157,9 @@ executables: []
157
157
  extensions: []
158
158
  extra_rdoc_files: []
159
159
  files:
160
+ - ".okf/capabilities/index.md"
161
+ - ".okf/capabilities/okf-surface.md"
162
+ - ".okf/capabilities/views.md"
160
163
  - ".okf/decisions/index.md"
161
164
  - ".okf/decisions/invents-no-analysis.md"
162
165
  - ".okf/decisions/no-version-ceilings.md"
@@ -177,14 +180,22 @@ files:
177
180
  - ".okf/interaction/which-registry.md"
178
181
  - ".okf/log.md"
179
182
  - ".okf/rendering/ansi-aware-width.md"
183
+ - ".okf/rendering/fit-or-say-so.md"
180
184
  - ".okf/rendering/index.md"
181
185
  - ".okf/rendering/markdown-rendering-trap.md"
182
186
  - ".okf/rendering/status-vocabulary.md"
183
187
  - ".okf/rendering/whole-frame-painting.md"
188
+ - ".okf/structure/doors.md"
189
+ - ".okf/structure/index.md"
190
+ - ".okf/structure/rendering.md"
191
+ - ".okf/structure/the-app.md"
192
+ - ".okf/structure/the-workspace.md"
193
+ - ".okf/testing/adding-a-view.md"
184
194
  - ".okf/testing/ci-matrix.md"
185
195
  - ".okf/testing/headless-frames.md"
186
196
  - ".okf/testing/index.md"
187
197
  - ".okf/testing/pty-test.md"
198
+ - ".okf/testing/the-suite.md"
188
199
  - CHANGELOG.md
189
200
  - LICENSE.txt
190
201
  - NOTICE
@@ -199,14 +210,14 @@ files:
199
210
  - lib/okf/tui/version.rb
200
211
  - lib/okf/tui/views.rb
201
212
  - lib/okf/tui/workspace.rb
202
- homepage: https://github.com/serradura/okf-gem
213
+ homepage: https://github.com/serradura/okf
203
214
  licenses:
204
215
  - Apache-2.0
205
216
  metadata:
206
217
  allowed_push_host: https://rubygems.org
207
- homepage_uri: https://github.com/serradura/okf-gem
208
- source_code_uri: https://github.com/serradura/okf-gem
209
- changelog_uri: https://github.com/serradura/okf-gem/blob/main/okf-tui/CHANGELOG.md
218
+ homepage_uri: https://github.com/serradura/okf
219
+ source_code_uri: https://github.com/serradura/okf
220
+ changelog_uri: https://github.com/serradura/okf/blob/main/gems/okf-tui/CHANGELOG.md
210
221
  rubygems_mfa_required: 'true'
211
222
  rdoc_options: []
212
223
  require_paths: