[{"data":1,"prerenderedAt":402},["ShallowReactive",2],{"navigation_docs":3,"-guide-diagnostics":227,"-guide-diagnostics-surround":397},[4,26,100,109,206],{"title":5,"icon":6,"path":7,"stem":8,"children":9,"page":25},"Getting started","i-lucide-rocket","\u002Fgetting-started","1.getting-started",[10,15,20],{"title":11,"path":12,"stem":13,"icon":14},"Installation","\u002Fgetting-started\u002Finstallation","1.getting-started\u002F1.installation","i-lucide-download",{"title":16,"path":17,"stem":18,"icon":19},"The first app","\u002Fgetting-started\u002Ffirst-app","1.getting-started\u002F2.first-app","i-lucide-play",{"title":21,"path":22,"stem":23,"icon":24},"The first test","\u002Fgetting-started\u002Ffirst-test","1.getting-started\u002F3.first-test","i-lucide-flask-conical",false,{"title":27,"icon":28,"path":29,"stem":30,"children":31,"page":25},"Guide","i-lucide-book-open","\u002Fguide","2.guide",[32,37,42,47,52,57,62,67,72,77,81,86,91,96],{"title":33,"path":34,"stem":35,"icon":36},"Components","\u002Fguide\u002Fcomponents","2.guide\u002F01.components","i-lucide-component",{"title":38,"path":39,"stem":40,"icon":41},"Inputs and forms","\u002Fguide\u002Finputs-and-forms","2.guide\u002F02.inputs-and-forms","i-lucide-text-cursor-input",{"title":43,"path":44,"stem":45,"icon":46},"Scrolling and viewports","\u002Fguide\u002Fscrolling","2.guide\u002F03.scrolling","i-lucide-scroll-text",{"title":48,"path":49,"stem":50,"icon":51},"Overlays and layers","\u002Fguide\u002Foverlays","2.guide\u002F04.overlays","i-lucide-layers",{"title":53,"path":54,"stem":55,"icon":56},"Styles and theme","\u002Fguide\u002Fstyles","2.guide\u002F05.styles","i-lucide-palette",{"title":58,"path":59,"stem":60,"icon":61},"Composables","\u002Fguide\u002Fcomposables","2.guide\u002F06.composables","i-lucide-puzzle",{"title":63,"path":64,"stem":65,"icon":66},"Widgets","\u002Fguide\u002Fwidgets","2.guide\u002F07.widgets","i-lucide-blocks",{"title":68,"path":69,"stem":70,"icon":71},"The assistant","\u002Fguide\u002Fassistant","2.guide\u002F08.assistant","i-lucide-message-square",{"title":73,"path":74,"stem":75,"icon":76},"The same app on the web","\u002Fguide\u002Fweb","2.guide\u002F09.web","i-lucide-globe",{"title":78,"path":79,"stem":80,"icon":24},"Testing","\u002Fguide\u002Ftesting","2.guide\u002F10.testing",{"title":82,"path":83,"stem":84,"icon":85},"Running and packaging","\u002Fguide\u002Fpackaging","2.guide\u002F11.packaging","i-lucide-package",{"title":87,"path":88,"stem":89,"icon":90},"The terminal contract","\u002Fguide\u002Fterminal","2.guide\u002F12.terminal","i-lucide-square-terminal",{"title":92,"path":93,"stem":94,"icon":95},"Benchmarks","\u002Fguide\u002Fbenchmarks","2.guide\u002F13.benchmarks","i-lucide-gauge",{"title":97,"path":98,"stem":99},"Diagnose input latency","\u002Fguide\u002Fdiagnostics","2.guide\u002F14.diagnostics",{"title":101,"icon":102,"path":103,"stem":104,"children":105,"page":25},"AI and agents","i-lucide-bot","\u002Fai","3.ai",[106],{"title":101,"path":107,"stem":108,"icon":102},"\u002Fai\u002Fagents","3.ai\u002F1.agents",{"title":110,"icon":111,"path":112,"stem":113,"children":114},"Decisions","i-lucide-scale","\u002Fdecisions","4.decisions",[115,118,122,126,130,134,138,142,146,150,154,158,162,166,170,174,178,182,186,190,194,198,202],{"title":116,"path":112,"stem":117,"icon":46},"All decisions","4.decisions\u002Findex",{"title":119,"path":120,"stem":121},"0001. kyo-ui is the DSL","\u002Fdecisions\u002F0001-kyo-ui-is-the-dsl","4.decisions\u002F0001-kyo-ui-is-the-dsl",{"title":123,"path":124,"stem":125},"0002. jatatui renders the cells","\u002Fdecisions\u002F0002-jatatui-renders-the-cells","4.decisions\u002F0002-jatatui-renders-the-cells",{"title":127,"path":128,"stem":129},"0003. Pin Kyo 1.0.0-RC7 and JDK 25","\u002Fdecisions\u002F0003-pin-kyo-rc7-and-jdk-25","4.decisions\u002F0003-pin-kyo-rc7-and-jdk-25",{"title":131,"path":132,"stem":133},"0004. Public Kyo APIs only","\u002Fdecisions\u002F0004-public-kyo-apis-only","4.decisions\u002F0004-public-kyo-apis-only",{"title":135,"path":136,"stem":137},"0005. A SOFT frame contract and an own watcher loop","\u002Fdecisions\u002F0005-soft-frame-contract-and-own-watcher-loop","4.decisions\u002F0005-soft-frame-contract-and-own-watcher-loop",{"title":139,"path":140,"stem":141},"0006. Purity: edge files, lint and a pure painter","\u002Fdecisions\u002F0006-purity-edge-files-and-lint","4.decisions\u002F0006-purity-edge-files-and-lint",{"title":143,"path":144,"stem":145},"0007. Compiler flags from sbt-tpolecat","\u002Fdecisions\u002F0007-compiler-flags-from-sbt-tpolecat","4.decisions\u002F0007-compiler-flags-from-sbt-tpolecat",{"title":147,"path":148,"stem":149},"0008. The artifact split: runner, app, testkit and core","\u002Fdecisions\u002F0008-artifact-split-runner-app-testkit-core","4.decisions\u002F0008-artifact-split-runner-app-testkit-core",{"title":151,"path":152,"stem":153},"0009. tui4s-use and tui4s-widgets, cross-built","\u002Fdecisions\u002F0009-use-and-widgets-cross-built","4.decisions\u002F0009-use-and-widgets-cross-built",{"title":155,"path":156,"stem":157},"0010. The flagship assistant is the blueprint of a real app","\u002Fdecisions\u002F0010-the-flagship-assistant-as-blueprint","4.decisions\u002F0010-the-flagship-assistant-as-blueprint",{"title":159,"path":160,"stem":161},"0011. The web target: a standalone Scala.js app and one theme","\u002Fdecisions\u002F0011-web-target-standalone-scalajs-and-one-theme","4.decisions\u002F0011-web-target-standalone-scalajs-and-one-theme",{"title":163,"path":164,"stem":165},"0012. The documentation is example-first","\u002Fdecisions\u002F0012-documentation-is-example-first","4.decisions\u002F0012-documentation-is-example-first",{"title":167,"path":168,"stem":169},"0013. Benchmarks in the repository, with their own build","\u002Fdecisions\u002F0013-benchmarks-in-repo-with-own-build","4.decisions\u002F0013-benchmarks-in-repo-with-own-build",{"title":171,"path":172,"stem":173},"0014. Release per module, by tag, as 0.1.0-RC1","\u002Fdecisions\u002F0014-release-per-module-tags-and-rc1","4.decisions\u002F0014-release-per-module-tags-and-rc1",{"title":175,"path":176,"stem":177},"0015. Packaging: the AOT cache in the start scripts, native-image as an option","\u002Fdecisions\u002F0015-packaging-aot-cache-and-native-image","4.decisions\u002F0015-packaging-aot-cache-and-native-image",{"title":179,"path":180,"stem":181},"0016. Process: lean mode and agent roles","\u002Fdecisions\u002F0016-process-lean-mode-and-agent-roles","4.decisions\u002F0016-process-lean-mode-and-agent-roles",{"title":183,"path":184,"stem":185},"0017. Deferred: templates, mouse, the kitty keyboard protocol and Windows","\u002Fdecisions\u002F0017-deferred-templates-mouse-and-kitty","4.decisions\u002F0017-deferred-templates-mouse-and-kitty",{"title":187,"path":188,"stem":189},"0018. pini4s is a vendored Git submodule","\u002Fdecisions\u002F0018-pini4s-as-a-vendored-submodule","4.decisions\u002F0018-pini4s-as-a-vendored-submodule",{"title":191,"path":192,"stem":193},"0019. Upstream issues are drafts that the user posts","\u002Fdecisions\u002F0019-upstream-kyo-issues-as-drafts","4.decisions\u002F0019-upstream-kyo-issues-as-drafts",{"title":195,"path":196,"stem":197},"0020. Release from the Actions form","\u002Fdecisions\u002F0020-release-from-the-actions-form","4.decisions\u002F0020-release-from-the-actions-form",{"title":199,"path":200,"stem":201},"0021. The rulebook is CONTRIBUTING.md","\u002Fdecisions\u002F0021-the-rulebook-is-contributing-md","4.decisions\u002F0021-the-rulebook-is-contributing-md",{"title":203,"path":204,"stem":205},"0022. The logo is text","\u002Fdecisions\u002F0022-the-logo-is-text","4.decisions\u002F0022-the-logo-is-text",{"title":207,"icon":208,"path":209,"stem":210,"children":211,"page":25},"Project","i-lucide-compass","\u002Fproject","5.project",[212,217,222],{"title":213,"path":214,"stem":215,"icon":216},"Roadmap","\u002Fproject\u002Froadmap","5.project\u002F1.roadmap","i-lucide-map",{"title":218,"path":219,"stem":220,"icon":221},"Contributing","\u002Fproject\u002Fcontributing","5.project\u002F2.contributing","i-lucide-git-pull-request",{"title":223,"path":224,"stem":225,"icon":226},"Security","\u002Fproject\u002Fsecurity","5.project\u002F3.security","i-lucide-shield",{"id":228,"title":97,"body":229,"description":390,"extension":391,"links":392,"meta":393,"navigation":394,"path":98,"seo":395,"stem":99,"__hash__":396},"docs\u002F2.guide\u002F14.diagnostics.md",{"type":230,"value":231,"toc":385},"minimark",[232,236,240,251,254,257,262,265,276,287,290,293,297,300,303,307,310,331,334,361,364,367,370,381],[233,234,97],"h1",{"id":235},"diagnose-input-latency",[237,238,239],"p",{},"Add this option to the JVM that runs your app:",[241,242,248],"pre",{"className":243,"code":245,"language":246,"meta":247},[244],"language-text","-Dtui4s.diagnostics.file=\u002Ftmp\u002Ftui4s-diagnostics.json\n","text","",[249,250,245],"code",{"__ignoreMap":247},[237,252,253],{},"Type while the workload runs. Copy the JSON file during the delay, or after\nyou quit. Give each app process a different file path. The parent directory\nmust exist and be writable. Remove the JVM option to turn diagnostics off.",[237,255,256],{},"This release adds measurements. It does not change the settlement rules.\nBackground scheduler work can still delay a frame. Continuous notifications\ncan still extend settlement past its configured maximum.",[258,259,261],"h2",{"id":260},"what-the-report-measures","What the report measures",[237,263,264],{},"The input clock starts when tui4s receives an event from the terminal\nreader. It includes the wait before dispatch and the wait in the runner's\nbacklog. A completed input sample ends when its runner frame pass completes,\nbefore warning logs or frame-stat delivery. A pass can finish without\npainting. It is not proof that the expected text appeared. The external\nscreen check described below measures that separate condition.",[237,266,267,268,271,272,275],{},"The report includes the current runner phase and its age. It also includes\npending input, backlog size, notification counts, settlement observations,\ntimeouts, and recent completed input timings. A frame need not finish for\nthe report to update. Check pending input and phase age when completed\nsamples are absent. ",[249,269,270],{},"observationAgeNanos"," measures the last hook observation;\na small value does not prove useful progress. ",[249,273,274],{},"framePasses"," counts runner\npasses, including passes with no screen output.",[237,277,278,279,282,283,286],{},"Check that ",[249,280,281],{},"elapsedNanos"," advances while the app runs. A missing or stale\nfile is not evidence that input is healthy. The exporter retries write\nfailures; ",[249,284,285],{},"writeFailures"," shows their count if a later write succeeds.",[237,288,289],{},"The terminal reader offers input in batches. A batch acceptance time means\nthat the whole batch was accepted. An earlier event can already have run.\nDo not subtract that batch time from each event's dispatch time and call the\nresult its queue delay.",[237,291,292],{},"The recorder keeps at most 1,024 pending input timings and 64 recent completed\nsamples. It counts inputs that it cannot track. Recent samples do not form\na complete latency distribution. A small recent average cannot establish\nthat all input completed. Compare received and completed counts, pending\nages, and untracked counts too.",[258,294,296],{"id":295},"cost-and-contents","Cost and contents",[237,298,299],{},"Diagnostics are off by default. When enabled, one daemon thread outside the\nKyo scheduler exports a snapshot every 250 ms. File output runs on that\nthread. The latest snapshot replaces the previous snapshot; the file does\nnot grow with the duration of the run. Session cleanup requests a final\nsnapshot and waits at most 200 ms for the exporter. Slow file output can\noutlast that wait on the daemon thread. Measurement has a cost: compare\nruns with it enabled and disabled.",[237,301,302],{},"The report contains durations, sequence numbers, phases and counts. It does\nnot record key characters, pasted text, chat content, signal values or\napplication logs. The output stays in the file that you selected.",[258,304,306],{"id":305},"reproduce-locally","Reproduce locally",[237,308,309],{},"Build the example launchers with JDK 25:",[241,311,315],{"className":312,"code":313,"language":314,"meta":247,"style":247},"language-sh shiki shiki-themes github-light github-light github-dark-default","sbt examples\u002Flaunchers\nmkdir -p work\n","sh",[249,316,317,325],{"__ignoreMap":247},[318,319,322],"span",{"class":320,"line":321},"line",1,[318,323,324],{},"sbt examples\u002Flaunchers\n",[318,326,328],{"class":320,"line":327},2,[318,329,330],{},"mkdir -p work\n",[237,332,333],{},"The PTY kit sends keys on a schedule and observes the correct input text.\nIt sends the next key without waiting for the previous frame. Start with a\nquiet run, then add unrelated runnable work or notification traffic:",[241,335,337],{"className":312,"code":336,"language":314,"meta":247,"style":247},"python3 examples\u002Fptycheck\u002Flatency.py --rate 10 --keys 60 --deadline-ms 100 --output work\u002Fquiet.json --command examples\u002Ftarget\u002Fbin\u002Fsettlement\npython3 examples\u002Fptycheck\u002Flatency.py --rate 10 --keys 60 --deadline-ms 100 --require-load-running --output work\u002Fbusy.json --command examples\u002Ftarget\u002Fbin\u002Fsettlement --busy --duration=15\npython3 examples\u002Fptycheck\u002Flatency.py --rate 10 --keys 60 --deadline-ms 100 --require-updates --require-load-running --output work\u002Fupdates.json --command examples\u002Ftarget\u002Fbin\u002Fsettlement --updates=1000 --duration=15\npython3 examples\u002Fptycheck\u002Flatency.py --rate 10 --keys 60 --deadline-ms 100 --require-updates --require-load-running --output work\u002Fcombined.json --command examples\u002Ftarget\u002Fbin\u002Fsettlement --busy --updates=1000 --duration=15\n",[249,338,339,344,349,355],{"__ignoreMap":247},[318,340,341],{"class":320,"line":321},[318,342,343],{},"python3 examples\u002Fptycheck\u002Flatency.py --rate 10 --keys 60 --deadline-ms 100 --output work\u002Fquiet.json --command examples\u002Ftarget\u002Fbin\u002Fsettlement\n",[318,345,346],{"class":320,"line":327},[318,347,348],{},"python3 examples\u002Fptycheck\u002Flatency.py --rate 10 --keys 60 --deadline-ms 100 --require-load-running --output work\u002Fbusy.json --command examples\u002Ftarget\u002Fbin\u002Fsettlement --busy --duration=15\n",[318,350,352],{"class":320,"line":351},3,[318,353,354],{},"python3 examples\u002Fptycheck\u002Flatency.py --rate 10 --keys 60 --deadline-ms 100 --require-updates --require-load-running --output work\u002Fupdates.json --command examples\u002Ftarget\u002Fbin\u002Fsettlement --updates=1000 --duration=15\n",[318,356,358],{"class":320,"line":357},4,[318,359,360],{},"python3 examples\u002Fptycheck\u002Flatency.py --rate 10 --keys 60 --deadline-ms 100 --require-updates --require-load-running --output work\u002Fcombined.json --command examples\u002Ftarget\u002Fbin\u002Fsettlement --busy --updates=1000 --duration=15\n",[237,362,363],{},"The update rate is a requested maximum. The screen counter shows actual\nupdates. The finite load starts before the first frame, so startup consumes\npart of its duration. Keep the run shorter than the load. The fixture's\ninput is 100 columns wide; keep the sent text below 100 characters.",[237,365,366],{},"The load checks require visible running markers and advancing update counts.\nA screen marker can be stale during a stall. The example's lifecycle tests\nalso check the producer state directly, during input and after shutdown.",[237,368,369],{},"The command exits with a failure when input is missing, incorrect, or late.\nThe loaded runs can fail on this release: they expose the settlement issue.\nKeep their reports as the baseline for a fix. The 100 ms value above is an\nexplicit test deadline, not a claim about supported performance.",[237,371,372,373,376,377,380],{},"The PTY report separates actual send-to-screen time from planned\nsend-to-screen time. The deadline uses planned send time, so a late sender\ncannot hide a delay. The endpoint is the decoded terminal screen with the\nexpected input. It includes transport and queueing. It does not measure a\nphysical terminal's painting. Report sender delay, missing input and the\nmaximum delay beside percentiles. Do not use\n",[249,374,375],{},"FrameStats.nanos"," or the layout-only ",[249,378,379],{},"PerfProbe"," as a substitute.",[382,383,384],"style",{},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":247,"searchDepth":327,"depth":327,"links":386},[387,388,389],{"id":260,"depth":327,"text":261},{"id":295,"depth":327,"text":296},{"id":305,"depth":327,"text":306},"Record input and settlement timings without application contents.","md",null,{},true,{"title":97,"description":390},"tdCxmHQPZIwzKObsTj17MxB9DIF0lgsCDB2aiWpP2LM",[398,400],{"title":92,"path":93,"stem":94,"description":399,"icon":95,"children":-1},"The frame-path probe of tui4s, and the bench of tui4s against seven other terminal UI stacks.",{"title":101,"path":107,"stem":108,"description":401,"icon":102,"children":-1},"How an AI agent reads this documentation and works on the tui4s repository.",1792716337007]