[{"data":1,"prerenderedAt":834},["ShallowReactive",2],{"navigation_docs":3,"-guide-web":223,"-guide-web-surround":829},[4,26,96,105,202],{"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],{"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,"icon":98,"path":99,"stem":100,"children":101,"page":25},"AI and agents","i-lucide-bot","\u002Fai","3.ai",[102],{"title":97,"path":103,"stem":104,"icon":98},"\u002Fai\u002Fagents","3.ai\u002F1.agents",{"title":106,"icon":107,"path":108,"stem":109,"children":110},"Decisions","i-lucide-scale","\u002Fdecisions","4.decisions",[111,114,118,122,126,130,134,138,142,146,150,154,158,162,166,170,174,178,182,186,190,194,198],{"title":112,"path":108,"stem":113,"icon":46},"All decisions","4.decisions\u002Findex",{"title":115,"path":116,"stem":117},"0001. kyo-ui is the DSL","\u002Fdecisions\u002F0001-kyo-ui-is-the-dsl","4.decisions\u002F0001-kyo-ui-is-the-dsl",{"title":119,"path":120,"stem":121},"0002. jatatui renders the cells","\u002Fdecisions\u002F0002-jatatui-renders-the-cells","4.decisions\u002F0002-jatatui-renders-the-cells",{"title":123,"path":124,"stem":125},"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":127,"path":128,"stem":129},"0004. Public Kyo APIs only","\u002Fdecisions\u002F0004-public-kyo-apis-only","4.decisions\u002F0004-public-kyo-apis-only",{"title":131,"path":132,"stem":133},"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":135,"path":136,"stem":137},"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":139,"path":140,"stem":141},"0007. Compiler flags from sbt-tpolecat","\u002Fdecisions\u002F0007-compiler-flags-from-sbt-tpolecat","4.decisions\u002F0007-compiler-flags-from-sbt-tpolecat",{"title":143,"path":144,"stem":145},"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":147,"path":148,"stem":149},"0009. tui4s-use and tui4s-widgets, cross-built","\u002Fdecisions\u002F0009-use-and-widgets-cross-built","4.decisions\u002F0009-use-and-widgets-cross-built",{"title":151,"path":152,"stem":153},"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":155,"path":156,"stem":157},"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":159,"path":160,"stem":161},"0012. The documentation is example-first","\u002Fdecisions\u002F0012-documentation-is-example-first","4.decisions\u002F0012-documentation-is-example-first",{"title":163,"path":164,"stem":165},"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":167,"path":168,"stem":169},"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":171,"path":172,"stem":173},"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":175,"path":176,"stem":177},"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":179,"path":180,"stem":181},"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":183,"path":184,"stem":185},"0018. pini4s is a vendored Git submodule","\u002Fdecisions\u002F0018-pini4s-as-a-vendored-submodule","4.decisions\u002F0018-pini4s-as-a-vendored-submodule",{"title":187,"path":188,"stem":189},"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":191,"path":192,"stem":193},"0020. Release from the Actions form","\u002Fdecisions\u002F0020-release-from-the-actions-form","4.decisions\u002F0020-release-from-the-actions-form",{"title":195,"path":196,"stem":197},"0021. The rulebook is CONTRIBUTING.md","\u002Fdecisions\u002F0021-the-rulebook-is-contributing-md","4.decisions\u002F0021-the-rulebook-is-contributing-md",{"title":199,"path":200,"stem":201},"0022. The logo is text","\u002Fdecisions\u002F0022-the-logo-is-text","4.decisions\u002F0022-the-logo-is-text",{"title":203,"icon":204,"path":205,"stem":206,"children":207,"page":25},"Project","i-lucide-compass","\u002Fproject","5.project",[208,213,218],{"title":209,"path":210,"stem":211,"icon":212},"Roadmap","\u002Fproject\u002Froadmap","5.project\u002F1.roadmap","i-lucide-map",{"title":214,"path":215,"stem":216,"icon":217},"Contributing","\u002Fproject\u002Fcontributing","5.project\u002F2.contributing","i-lucide-git-pull-request",{"title":219,"path":220,"stem":221,"icon":222},"Security","\u002Fproject\u002Fsecurity","5.project\u002F3.security","i-lucide-shield",{"id":224,"title":73,"body":225,"description":822,"extension":823,"links":824,"meta":825,"navigation":826,"path":74,"seo":827,"stem":75,"__hash__":828},"docs\u002F2.guide\u002F09.web.md",{"type":226,"value":227,"toc":815},"minimark",[228,237,563,568,572,579,583,605,632,636,642,764,782,786,804,808,811],[229,230,231,232,236],"p",{},"The web main gives the layers of the browser and mounts the shared UI with kyo-ui's ",[233,234,235],"code",{},"UI.runMount",":",[238,239,245],"pre",{"className":240,"code":241,"filename":242,"language":243,"meta":244,"style":244},"language-scala shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","    run {\n      val screen =\n        UIWindow.size.map((w, h) => Surface.cells(w, h, Theme.web.font.size))\n      for\n          mode    \u003C- AssistantWeb.mode\n          storage \u003C- AssistantWeb.storage(mode)\n          keys     = AssistantWeb.keys(storage)\n          _       \u003C- UI.runStylesheet(Look.stylesheet(Look.Web))\n          ui      \u003C- Memo.run(\n                       Env.runLayer(\n                         Layer(storage),\n                         Layer(keys: Secrets),\n                         Wiring.conversations,\n                         AssistantWeb.log,\n                         Wiring.providers(\n                           AssistantWeb.live,\n                           FakeProvider.make(),\n                           mode,\n                         ),\n                         AssistantWeb.surface(keys),\n                       )(AssistantUi.run(mode, Kyo.unit, screen)),\n                     )\n          _       \u003C- UI.runMount(ui, \"#app\")\n      yield ()\n      end for\n    }\n","AssistantWebApp.scala","scala","",[233,246,247,260,272,297,304,319,332,346,377,391,400,409,430,439,448,456,465,474,480,486,494,512,518,542,551,557],{"__ignoreMap":244},[248,249,252,256],"span",{"class":250,"line":251},"line",1,[248,253,255],{"class":254},"sTEyZ","    run ",[248,257,259],{"class":258},"sMK4o","{\n",[248,261,263,266,269],{"class":250,"line":262},2,[248,264,265],{"class":258},"      val",[248,267,268],{"class":254}," screen ",[248,270,271],{"class":258},"=\n",[248,273,275,279,282,285,288,291,294],{"class":250,"line":274},3,[248,276,278],{"class":277},"sBMFI","        UIWindow",[248,280,281],{"class":254},".size.map((w, h) ",[248,283,284],{"class":258},"=>",[248,286,287],{"class":277}," Surface",[248,289,290],{"class":254},".cells(w, h, ",[248,292,293],{"class":277},"Theme",[248,295,296],{"class":254},".web.font.size))\n",[248,298,300],{"class":250,"line":299},4,[248,301,303],{"class":302},"s7zQu","      for\n",[248,305,307,310,313,316],{"class":250,"line":306},5,[248,308,309],{"class":254},"          mode    ",[248,311,312],{"class":258},"\u003C-",[248,314,315],{"class":277}," AssistantWeb",[248,317,318],{"class":254},".mode\n",[248,320,322,325,327,329],{"class":250,"line":321},6,[248,323,324],{"class":254},"          storage ",[248,326,312],{"class":258},[248,328,315],{"class":277},[248,330,331],{"class":254},".storage(mode)\n",[248,333,335,338,341,343],{"class":250,"line":334},7,[248,336,337],{"class":254},"          keys     ",[248,339,340],{"class":258},"=",[248,342,315],{"class":277},[248,344,345],{"class":254},".keys(storage)\n",[248,347,349,352,354,357,360,363,366,368,371,374],{"class":250,"line":348},8,[248,350,351],{"class":254},"          _       ",[248,353,312],{"class":258},[248,355,356],{"class":277}," UI",[248,358,359],{"class":254},".runStylesheet(",[248,361,362],{"class":277},"Look",[248,364,365],{"class":254},".stylesheet(",[248,367,362],{"class":277},[248,369,370],{"class":254},".",[248,372,373],{"class":277},"Web",[248,375,376],{"class":254},"))\n",[248,378,380,383,385,388],{"class":250,"line":379},9,[248,381,382],{"class":254},"          ui      ",[248,384,312],{"class":258},[248,386,387],{"class":277}," Memo",[248,389,390],{"class":254},".run(\n",[248,392,394,397],{"class":250,"line":393},10,[248,395,396],{"class":277},"                       Env",[248,398,399],{"class":254},".runLayer(\n",[248,401,403,406],{"class":250,"line":402},11,[248,404,405],{"class":277},"                         Layer",[248,407,408],{"class":254},"(storage),\n",[248,410,412,414,417,421,424,427],{"class":250,"line":411},12,[248,413,405],{"class":277},[248,415,416],{"class":254},"(",[248,418,420],{"class":419},"sHdIc","keys",[248,422,423],{"class":254},": ",[248,425,426],{"class":277},"Secrets",[248,428,429],{"class":254},"),\n",[248,431,433,436],{"class":250,"line":432},13,[248,434,435],{"class":277},"                         Wiring",[248,437,438],{"class":254},".conversations,\n",[248,440,442,445],{"class":250,"line":441},14,[248,443,444],{"class":277},"                         AssistantWeb",[248,446,447],{"class":254},".log,\n",[248,449,451,453],{"class":250,"line":450},15,[248,452,435],{"class":277},[248,454,455],{"class":254},".providers(\n",[248,457,459,462],{"class":250,"line":458},16,[248,460,461],{"class":277},"                           AssistantWeb",[248,463,464],{"class":254},".live,\n",[248,466,468,471],{"class":250,"line":467},17,[248,469,470],{"class":277},"                           FakeProvider",[248,472,473],{"class":254},".make(),\n",[248,475,477],{"class":250,"line":476},18,[248,478,479],{"class":254},"                           mode,\n",[248,481,483],{"class":250,"line":482},19,[248,484,485],{"class":254},"                         ),\n",[248,487,489,491],{"class":250,"line":488},20,[248,490,444],{"class":277},[248,492,493],{"class":254},".surface(keys),\n",[248,495,497,500,503,506,509],{"class":250,"line":496},21,[248,498,499],{"class":254},"                       )(",[248,501,502],{"class":277},"AssistantUi",[248,504,505],{"class":254},".run(mode, ",[248,507,508],{"class":277},"Kyo",[248,510,511],{"class":254},".unit, screen)),\n",[248,513,515],{"class":250,"line":514},22,[248,516,517],{"class":254},"                     )\n",[248,519,521,523,525,527,530,533,537,539],{"class":250,"line":520},23,[248,522,351],{"class":254},[248,524,312],{"class":258},[248,526,356],{"class":277},[248,528,529],{"class":254},".runMount(ui, ",[248,531,532],{"class":258},"\"",[248,534,536],{"class":535},"sfazB","#app",[248,538,532],{"class":258},[248,540,541],{"class":254},")\n",[248,543,545,548],{"class":250,"line":544},24,[248,546,547],{"class":302},"      yield",[248,549,550],{"class":254}," ()\n",[248,552,554],{"class":250,"line":553},25,[248,555,556],{"class":302},"      end for\n",[248,558,560],{"class":250,"line":559},26,[248,561,562],{"class":258},"    }\n",[564,565,567],"h2",{"id":566},"try-it","Try it",[569,570],"demo",{"src":571},"\u002Fdemo\u002Fassistant\u002Findex.html?demo",[229,573,574,575,578],{},"The demo opens the app with ",[233,576,577],{},"?demo",": it reads no key, it uses only the fake provider (no network), and it keeps its storage in memory, so each load starts again. It runs in a sandboxed frame, apart from the storage of this site. Do not type a real key into it.",[564,580,582],{"id":581},"build-it","Build it",[238,584,588],{"className":585,"code":586,"language":587,"meta":244,"style":244},"language-sh shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","bash scripts\u002Fweb-build.sh                         # dist\u002Fassistant: index.html and main.js\npython3 -m http.server -d dist\u002Fassistant 8000     # a static server for your own use\nnode scripts\u002Fweb-smoke.mjs                        # the smoke test (Playwright and Chromium)\n","sh",[233,589,590,595,600],{"__ignoreMap":244},[248,591,592],{"class":250,"line":251},[248,593,594],{},"bash scripts\u002Fweb-build.sh                         # dist\u002Fassistant: index.html and main.js\n",[248,596,597],{"class":250,"line":262},[248,598,599],{},"python3 -m http.server -d dist\u002Fassistant 8000     # a static server for your own use\n",[248,601,602],{"class":250,"line":274},[248,603,604],{},"node scripts\u002Fweb-smoke.mjs                        # the smoke test (Playwright and Chromium)\n",[229,606,607,608,611,612,615,616,619,620,623,624,627,628,631],{},"The web app is static files: one page and one script. There is no server of tui4s and no link to the terminal app. ",[233,609,610],{},"modules\u002Fassistant\u002Fjs"," has the interpreters of the browser: ",[233,613,614],{},"FetchHttp"," (the HTTP seam on ",[233,617,618],{},"fetch","), ",[233,621,622],{},"BrowserKeys"," (the keys in ",[233,625,626],{},"localStorage",") and ",[233,629,630],{},"AssistantWeb"," (the layers).",[564,633,635],{"id":634},"one-look-for-both-platforms","One look for both platforms",[229,637,638,639,236],{},"The settings of the assistant switch the look on both platforms. Each look is a block for ",[233,640,641],{},"[data-theme=\"\u003Cname>\"]",[238,643,646],{"className":240,"code":644,"filename":645,"language":243,"meta":244,"style":244},"    \u002F** The colours of all the looks for a terminal (`TuiApp.stylesheet`): the\n      * root of the app selects one with its `data-theme`.\n      *\u002F\n    val palette: Stylesheet = Theme.palette(Terminal.theme, Web.theme)\n\n    \u002F** All of all the looks for the web (`UI.runStylesheet`); `first` is the\n      * look of the page outside the app.\n      *\u002F\n    def stylesheet(first: Look): Stylesheet =\n      Theme.stylesheet(first.theme, values.filterNot(_ == first).map(_.theme)*)\n","Settings.scala",[233,647,648,654,659,664,697,703,708,713,717,745],{"__ignoreMap":244},[248,649,650],{"class":250,"line":251},[248,651,653],{"class":652},"sHwdD","    \u002F** The colours of all the looks for a terminal (`TuiApp.stylesheet`): the\n",[248,655,656],{"class":250,"line":262},[248,657,658],{"class":652},"      * root of the app selects one with its `data-theme`.\n",[248,660,661],{"class":250,"line":274},[248,662,663],{"class":652},"      *\u002F\n",[248,665,666,669,672,674,677,680,683,686,689,692,694],{"class":250,"line":299},[248,667,668],{"class":258},"    val",[248,670,671],{"class":254}," palette",[248,673,236],{"class":258},[248,675,676],{"class":277}," Stylesheet",[248,678,679],{"class":258}," =",[248,681,682],{"class":277}," Theme",[248,684,685],{"class":254},".palette(",[248,687,688],{"class":277},"Terminal",[248,690,691],{"class":254},".theme, ",[248,693,373],{"class":277},[248,695,696],{"class":254},".theme)\n",[248,698,699],{"class":250,"line":306},[248,700,702],{"emptyLinePlaceholder":701},true,"\n",[248,704,705],{"class":250,"line":321},[248,706,707],{"class":652},"    \u002F** All of all the looks for the web (`UI.runStylesheet`); `first` is the\n",[248,709,710],{"class":250,"line":334},[248,711,712],{"class":652},"      * look of the page outside the app.\n",[248,714,715],{"class":250,"line":348},[248,716,663],{"class":652},[248,718,719,722,726,728,731,733,735,738,740,742],{"class":250,"line":379},[248,720,721],{"class":258},"    def",[248,723,725],{"class":724},"s2Zo4"," stylesheet",[248,727,416],{"class":254},[248,729,730],{"class":419},"first",[248,732,423],{"class":254},[248,734,362],{"class":277},[248,736,737],{"class":254},")",[248,739,236],{"class":258},[248,741,676],{"class":277},[248,743,744],{"class":258}," =\n",[248,746,747,750,753,756,759,762],{"class":250,"line":393},[248,748,749],{"class":277},"      Theme",[248,751,752],{"class":254},".stylesheet(first.theme, values.filterNot(_ ",[248,754,755],{"class":258},"==",[248,757,758],{"class":254}," first).map(_.theme)",[248,760,761],{"class":258},"*",[248,763,541],{"class":254},[229,765,766,767,770,771,774,775,778,779,781],{},"The sizes of the shared UI are in cells in a terminal, and tui4s reads one em as one cell. A browser reads one em as the size of the font. So the UI takes its sizes from ",[233,768,769],{},"Surface",", a platform service: ",[233,772,773],{},"surface.rows(n)"," is ",[233,776,777],{},"n"," cells in a terminal and ",[233,780,777],{}," lines of text in a browser.",[564,783,785],{"id":784},"your-key","Your key",[229,787,788,792,793,795,796,799,800,803],{},[789,790,791],"strong",{},"Your key stays in this browser. Extensions and anyone with this profile\ncan read it."," The page keeps the key in ",[233,794,626],{}," (one entry for each\nprovider) and sends it only to the host of its provider (the page policy\nlets it call no other host). The page never shows the key, never writes it\ninto the page (the key field is not bound to a value), and never logs it.\nFor Anthropic, the page sends the header\n",[233,797,798],{},"anthropic-dangerous-direct-browser-access",": a browser call to the API needs\nit, and its risk is the one above (a script or an extension in the page can\nread the key). Use a key with a low spend limit, and push Forget when you\nare done. The key belongs to the origin that serves the page (for example\n",[233,801,802],{},"localhost:8000","): each page of that origin can read it. Use that origin\nonly for this app, or push Forget before you serve another page there.",[564,805,807],{"id":806},"the-keys-of-the-web","The keys of the web",[229,809,810],{},"A browser acts on most Ctrl chords on Windows and Linux, and kyo-ui cannot stop that. So each command has an Alt chord: Alt-P (the commands), Alt-N (a new chat), Alt-, (the settings), Alt-? (the help). Enter sends. Shift-Enter starts a new line. Esc stops a reply and closes the settings, the help and the command palette.",[812,813,814],"style",{},"html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sHdIc, html code.shiki .sHdIc{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}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);}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}",{"title":244,"searchDepth":262,"depth":262,"links":816},[817,818,819,820,821],{"id":566,"depth":262,"text":567},{"id":581,"depth":262,"text":582},{"id":634,"depth":262,"text":635},{"id":784,"depth":262,"text":785},{"id":806,"depth":262,"text":807},"The assistant in a browser, from the same shared code, as static files.","md",null,{},{"icon":76},{"title":73,"description":822},"qd-3VXewvCsFmEB5HshIaShhpIytsEV7d8_mvWCJFgA",[830,832],{"title":68,"path":69,"stem":70,"description":831,"icon":71,"children":-1},"The flagship example, a chat with a language model, and the shape of a real app.",{"title":78,"path":79,"stem":80,"description":833,"icon":24,"children":-1},"Test an app on the headless test kit, and check the real terminal with the PTY kit.",1792528752826]