[{"data":1,"prerenderedAt":1016},["ShallowReactive",2],{"docs-\u002Fdocs\u002Fv2\u002Ftui\u002Fapi\u002Fcomponents":3},{"id":4,"title":5,"body":6,"description":1009,"extension":1010,"meta":1011,"navigation":97,"path":1012,"seo":1013,"stem":1014,"__hash__":1015},"docs\u002Fdocs\u002Fv2\u002Ftui\u002Fapi\u002Fcomponents.md","components",{"type":7,"value":8,"toc":1000},"minimark",[9,12,22,261,266,339,352,359,362,366,444,450,454,457,548,570,577,581,628,634,640,674,684,691,740,744,809,812,816,954,968,974,978,984,996],[10,11,5],"h1",{"id":5},[13,14,15,16,21],"p",{},"The live values a ",[17,18,20],"a",{"href":19},"\u002Fdocs\u002Fv2\u002Ftui\u002Fapi\u002Flines","line"," shows. A component is a name,\nwhat changes it, and what it says.",[23,24,29],"pre",{"className":25,"code":26,"language":27,"meta":28,"style":28},"language-ts shiki shiki-themes dark-plus","interface ComponentsApi {\n    \u002F\u002F Register a component. Throws if the name is taken.\n    create(name: string, component: LineComponent): Disposer\n\n    \u002F\u002F Every registered name, built-ins included.\n    list(): readonly string[]\n}\n\ntype LineComponent = {\n    on?: readonly TuiHookName[]   \u002F\u002F hook events that change this value\n    every?: number                \u002F\u002F or a tick, in ms — for values time changes\n    icon?: IconName | (string & {})\n    click?: () => void | Promise\u003Cvoid>\n    render: () => string | number | null | undefined\n}\n","ts","",[30,31,32,48,55,92,99,105,123,129,134,146,166,180,199,229,256],"code",{"__ignoreMap":28},[33,34,36,40,44],"span",{"class":20,"line":35},1,[33,37,39],{"class":38},"scz_3","interface",[33,41,43],{"class":42},"sNl3T"," ComponentsApi",[33,45,47],{"class":46},"sTNBD"," {\n",[33,49,51],{"class":20,"line":50},2,[33,52,54],{"class":53},"sOLPB","    \u002F\u002F Register a component. Throws if the name is taken.\n",[33,56,58,62,65,69,72,75,78,81,83,86,89],{"class":20,"line":57},3,[33,59,61],{"class":60},"sCudf","    create",[33,63,64],{"class":46},"(",[33,66,68],{"class":67},"s3F5K","name",[33,70,71],{"class":46},": ",[33,73,74],{"class":42},"string",[33,76,77],{"class":46},", ",[33,79,80],{"class":67},"component",[33,82,71],{"class":46},[33,84,85],{"class":42},"LineComponent",[33,87,88],{"class":46},"): ",[33,90,91],{"class":42},"Disposer\n",[33,93,95],{"class":20,"line":94},4,[33,96,98],{"emptyLinePlaceholder":97},true,"\n",[33,100,102],{"class":20,"line":101},5,[33,103,104],{"class":53},"    \u002F\u002F Every registered name, built-ins included.\n",[33,106,108,111,114,117,120],{"class":20,"line":107},6,[33,109,110],{"class":60},"    list",[33,112,113],{"class":46},"(): ",[33,115,116],{"class":38},"readonly",[33,118,119],{"class":42}," string",[33,121,122],{"class":46},"[]\n",[33,124,126],{"class":20,"line":125},7,[33,127,128],{"class":46},"}\n",[33,130,132],{"class":20,"line":131},8,[33,133,98],{"emptyLinePlaceholder":97},[33,135,137,140,143],{"class":20,"line":136},9,[33,138,139],{"class":38},"type",[33,141,142],{"class":42}," LineComponent",[33,144,145],{"class":46}," = {\n",[33,147,149,152,155,157,160,163],{"class":20,"line":148},10,[33,150,151],{"class":67},"    on",[33,153,154],{"class":46},"?: ",[33,156,116],{"class":38},[33,158,159],{"class":42}," TuiHookName",[33,161,162],{"class":46},"[]   ",[33,164,165],{"class":53},"\u002F\u002F hook events that change this value\n",[33,167,169,172,174,177],{"class":20,"line":168},11,[33,170,171],{"class":67},"    every",[33,173,154],{"class":46},[33,175,176],{"class":42},"number",[33,178,179],{"class":53},"                \u002F\u002F or a tick, in ms — for values time changes\n",[33,181,183,186,188,191,194,196],{"class":20,"line":182},12,[33,184,185],{"class":67},"    icon",[33,187,154],{"class":46},[33,189,190],{"class":42},"IconName",[33,192,193],{"class":46}," | (",[33,195,74],{"class":42},[33,197,198],{"class":46}," & {})\n",[33,200,202,205,208,211,214,217,220,223,226],{"class":20,"line":201},13,[33,203,204],{"class":60},"    click",[33,206,207],{"class":46},"?: () ",[33,209,210],{"class":38},"=>",[33,212,213],{"class":42}," void",[33,215,216],{"class":46}," | ",[33,218,219],{"class":42},"Promise",[33,221,222],{"class":46},"\u003C",[33,224,225],{"class":42},"void",[33,227,228],{"class":46},">\n",[33,230,232,235,238,240,242,244,246,248,251,253],{"class":20,"line":231},14,[33,233,234],{"class":60},"    render",[33,236,237],{"class":46},": () ",[33,239,210],{"class":38},[33,241,119],{"class":42},[33,243,216],{"class":46},[33,245,176],{"class":42},[33,247,216],{"class":46},[33,249,250],{"class":42},"null",[33,252,216],{"class":46},[33,254,255],{"class":42},"undefined\n",[33,257,259],{"class":20,"line":258},15,[33,260,128],{"class":46},[262,263,265],"h2",{"id":264},"declaring-when-it-changes","Declaring when it changes",[23,267,269],{"className":25,"code":268,"language":27,"meta":28,"style":28},"components.create(\"me:sent\", {\n    on: [\"message:sent\"],\n    render: () => `${sent} sent`,\n})\n",[30,270,271,290,304,334],{"__ignoreMap":28},[33,272,273,275,278,281,283,287],{"class":20,"line":35},[33,274,5],{"class":67},[33,276,277],{"class":46},".",[33,279,280],{"class":60},"create",[33,282,64],{"class":46},[33,284,286],{"class":285},"sKc5r","\"me:sent\"",[33,288,289],{"class":46},", {\n",[33,291,292,295,298,301],{"class":20,"line":50},[33,293,294],{"class":67},"    on:",[33,296,297],{"class":46}," [",[33,299,300],{"class":285},"\"message:sent\"",[33,302,303],{"class":46},"],\n",[33,305,306,308,311,314,316,319,322,325,328,331],{"class":20,"line":57},[33,307,234],{"class":60},[33,309,310],{"class":67},":",[33,312,313],{"class":46}," () ",[33,315,210],{"class":38},[33,317,318],{"class":285}," `",[33,320,321],{"class":38},"${",[33,323,324],{"class":67},"sent",[33,326,327],{"class":38},"}",[33,329,330],{"class":285}," sent`",[33,332,333],{"class":46},",\n",[33,335,336],{"class":20,"line":94},[33,337,338],{"class":46},"})\n",[13,340,341,344,345,351],{},[30,342,343],{},"on"," takes the same names ",[17,346,348],{"href":347},"\u002Fdocs\u002Fv2\u002Ftui\u002Fapi\u002Ftui#hooks",[30,349,350],{},"tui.hook"," does — the\nterminal already emits a precise event for everything it does, so you pick from\na list you have learned rather than inventing a subscription.",[13,353,354,358],{},[355,356,357],"strong",{},"The trigger is declared, and that is the whole design."," A bare function\nleaves the terminal with no idea when to call it: re-running every component on\nevery frame lets one slow value stall the paint, and asking users to wire their\nown reactivity is the raw-power design this avoids. So a component says what\nwakes it, and the renderer evaluates it then and never otherwise.",[13,360,361],{},"A component with no trigger renders once and stays — the right shape for\nsomething static, and free.",[262,363,365],{"id":364},"values-that-change-with-time","Values that change with time",[23,367,369],{"className":25,"code":368,"language":27,"meta":28,"style":28},"components.create(\"me:uptime\", {\n    every: 1000,\n    render: () => `up ${Math.floor(process.uptime())}s`,\n})\n",[30,370,371,386,397,440],{"__ignoreMap":28},[33,372,373,375,377,379,381,384],{"class":20,"line":35},[33,374,5],{"class":67},[33,376,277],{"class":46},[33,378,280],{"class":60},[33,380,64],{"class":46},[33,382,383],{"class":285},"\"me:uptime\"",[33,385,289],{"class":46},[33,387,388,391,395],{"class":20,"line":50},[33,389,390],{"class":67},"    every:",[33,392,394],{"class":393},"sDGX8"," 1000",[33,396,333],{"class":46},[33,398,399,401,403,405,407,410,412,415,417,420,422,425,427,430,433,435,438],{"class":20,"line":57},[33,400,234],{"class":60},[33,402,310],{"class":67},[33,404,313],{"class":46},[33,406,210],{"class":38},[33,408,409],{"class":285}," `up ",[33,411,321],{"class":38},[33,413,414],{"class":67},"Math",[33,416,277],{"class":46},[33,418,419],{"class":60},"floor",[33,421,64],{"class":46},[33,423,424],{"class":67},"process",[33,426,277],{"class":46},[33,428,429],{"class":60},"uptime",[33,431,432],{"class":46},"())",[33,434,327],{"class":38},[33,436,437],{"class":285},"s`",[33,439,333],{"class":46},[33,441,442],{"class":20,"line":94},[33,443,338],{"class":46},[13,445,446,449],{},[30,447,448],{},"every"," is for values nothing in the terminal marks the passing of. Taken as\nwritten, with no floor — painting a string is cheap, and a component doing heavy\nwork on a fast interval is your call.",[262,451,453],{"id":452},"render-is-synchronous","render is synchronous",[13,455,456],{},"A frame cannot await. A component that needs real work does it in its trigger\nand returns the cached value:",[23,458,460],{"className":25,"code":459,"language":27,"meta":28,"style":28},"let branch = \"\"\n\ncomponents.create(\"me:branch\", {\n    every: 5000,\n    render: () => {\n        void refresh()   \u002F\u002F fills `branch`, does not block\n        return branch\n    },\n})\n",[30,461,462,476,480,495,504,516,530,539,544],{"__ignoreMap":28},[33,463,464,467,470,473],{"class":20,"line":35},[33,465,466],{"class":38},"let",[33,468,469],{"class":67}," branch",[33,471,472],{"class":46}," = ",[33,474,475],{"class":285},"\"\"\n",[33,477,478],{"class":20,"line":50},[33,479,98],{"emptyLinePlaceholder":97},[33,481,482,484,486,488,490,493],{"class":20,"line":57},[33,483,5],{"class":67},[33,485,277],{"class":46},[33,487,280],{"class":60},[33,489,64],{"class":46},[33,491,492],{"class":285},"\"me:branch\"",[33,494,289],{"class":46},[33,496,497,499,502],{"class":20,"line":94},[33,498,390],{"class":67},[33,500,501],{"class":393}," 5000",[33,503,333],{"class":46},[33,505,506,508,510,512,514],{"class":20,"line":101},[33,507,234],{"class":60},[33,509,310],{"class":67},[33,511,313],{"class":46},[33,513,210],{"class":38},[33,515,47],{"class":46},[33,517,518,521,524,527],{"class":20,"line":107},[33,519,520],{"class":38},"        void",[33,522,523],{"class":60}," refresh",[33,525,526],{"class":46},"()   ",[33,528,529],{"class":53},"\u002F\u002F fills `branch`, does not block\n",[33,531,532,536],{"class":20,"line":125},[33,533,535],{"class":534},"sYbnZ","        return",[33,537,538],{"class":67}," branch\n",[33,540,541],{"class":20,"line":131},[33,542,543],{"class":46},"    },\n",[33,545,546],{"class":20,"line":136},[33,547,338],{"class":46},[13,549,550,551,553,554,557,558,561,562,565,566,569],{},"Returns a string, a number, or ",[30,552,250],{},"\u002F",[30,555,556],{},"undefined"," for \"nothing right now\" — which\nrenders as no columns rather than the text \"null\". Primitives only: an object\nwould render as ",[30,559,560],{},"[object Object]",", and a stray ",[30,563,564],{},"async"," as ",[30,567,568],{},"[object Promise]",",\nsilently.",[13,571,572,573,576],{},"A ",[30,574,575],{},"render"," that throws costs that component and nothing else. It renders empty,\nthe fault is reported, and the line around it is unaffected.",[262,578,580],{"id":579},"icons","Icons",[23,582,584],{"className":25,"code":583,"language":27,"meta":28,"style":28},"components.create(\"me:branch\", {\n    icon: \"branch\",\n    render: () => branch,\n})\n",[30,585,586,600,610,624],{"__ignoreMap":28},[33,587,588,590,592,594,596,598],{"class":20,"line":35},[33,589,5],{"class":67},[33,591,277],{"class":46},[33,593,280],{"class":60},[33,595,64],{"class":46},[33,597,492],{"class":285},[33,599,289],{"class":46},[33,601,602,605,608],{"class":20,"line":50},[33,603,604],{"class":67},"    icon:",[33,606,607],{"class":285}," \"branch\"",[33,609,333],{"class":46},[33,611,612,614,616,618,620,622],{"class":20,"line":57},[33,613,234],{"class":60},[33,615,310],{"class":67},[33,617,313],{"class":46},[33,619,210],{"class":38},[33,621,469],{"class":67},[33,623,333],{"class":46},[33,625,626],{"class":20,"line":94},[33,627,338],{"class":46},[13,629,630,631,633],{},"An icon is a ",[355,632,68],{}," from the catalogue, resolved through the active set — so\none setting swaps every icon at once, which is what lets a shared component work\non a machine without a patched font.",[13,635,636,637,310],{},"Set it in ",[30,638,639],{},"profile.config.ts",[23,641,643],{"className":25,"code":642,"language":27,"meta":28,"style":28},"settings: {\n    icons: \"auto\",   \u002F\u002F \"auto\" | \"nerd\" | \"unicode\" | \"none\"\n}\n",[30,644,645,654,670],{"__ignoreMap":28},[33,646,647,651],{"class":20,"line":35},[33,648,650],{"class":649},"sqDPy","settings",[33,652,653],{"class":46},": {\n",[33,655,656,659,661,664,667],{"class":20,"line":50},[33,657,658],{"class":649},"    icons",[33,660,71],{"class":46},[33,662,663],{"class":285},"\"auto\"",[33,665,666],{"class":46},",   ",[33,668,669],{"class":53},"\u002F\u002F \"auto\" | \"nerd\" | \"unicode\" | \"none\"\n",[33,671,672],{"class":20,"line":57},[33,673,128],{"class":46},[13,675,676,679,680,683],{},[30,677,678],{},"auto"," guesses from the environment and errs toward ",[30,681,682],{},"unicode",", because the two\nfailure modes are not symmetrical: guessing low costs you a plainer bar, which\none setting fixes. Guessing high fills the row with boxes — and tofu does not\nlook like a font problem, it looks like the tool is broken.",[13,685,686,687,690],{},"A literal glyph (",[30,688,689],{},"icon: \"▸\"",") passes through untouched and ignores the setting.",[13,692,693,694,697,698,697,701,697,704,697,707,697,710,697,713,716,697,719,697,722,697,725,697,728,697,731,697,734,697,737],{},"Names: ",[30,695,696],{},"agent"," ",[30,699,700],{},"model",[30,702,703],{},"modules",[30,705,706],{},"session",[30,708,709],{},"tokens",[30,711,712],{},"messages",[30,714,715],{},"branch",[30,717,718],{},"changes",[30,720,721],{},"ahead",[30,723,724],{},"behind",[30,726,727],{},"folder",[30,729,730],{},"clock",[30,732,733],{},"user",[30,735,736],{},"warning",[30,738,739],{},"error",[262,741,743],{"id":742},"clickable","Clickable",[23,745,747],{"className":25,"code":746,"language":27,"meta":28,"style":28},"components.create(\"nav:zeno\", {\n    render: () => \"zeno\",\n    click: () => tui.nav(\"zeno\"),\n})\n",[30,748,749,764,779,805],{"__ignoreMap":28},[33,750,751,753,755,757,759,762],{"class":20,"line":35},[33,752,5],{"class":67},[33,754,277],{"class":46},[33,756,280],{"class":60},[33,758,64],{"class":46},[33,760,761],{"class":285},"\"nav:zeno\"",[33,763,289],{"class":46},[33,765,766,768,770,772,774,777],{"class":20,"line":50},[33,767,234],{"class":60},[33,769,310],{"class":67},[33,771,313],{"class":46},[33,773,210],{"class":38},[33,775,776],{"class":285}," \"zeno\"",[33,778,333],{"class":46},[33,780,781,783,785,787,789,792,794,797,799,802],{"class":20,"line":57},[33,782,204],{"class":60},[33,784,310],{"class":67},[33,786,313],{"class":46},[33,788,210],{"class":38},[33,790,791],{"class":67}," tui",[33,793,277],{"class":46},[33,795,796],{"class":60},"nav",[33,798,64],{"class":46},[33,800,801],{"class":285},"\"zeno\"",[33,803,804],{"class":46},"),\n",[33,806,807],{"class":20,"line":94},[33,808,338],{"class":46},[13,810,811],{},"What turns a status line into a control surface — a row of agent names becomes a\nnav bar. Unawaited, so a handler that takes a second does not hold the frame, and\na failure is reported rather than surfacing as a click that silently did nothing.",[262,813,815],{"id":814},"what-ships","What ships",[817,818,819,832],"table",{},[820,821,822],"thead",{},[823,824,825,829],"tr",{},[826,827,828],"th",{},"Group",[826,830,831],{},"Components",[833,834,835,858,871,890,909,925,941],"tbody",{},[823,836,837,841],{},[838,839,840],"td",{},"the focused agent",[838,842,843,697,846,697,849,697,852,697,855],{},[30,844,845],{},"axon:agent\u002Fname",[30,847,848],{},"axon:agent\u002Fmodel",[30,850,851],{},"axon:agent\u002Fmodules",[30,853,854],{},"axon:agent\u002Fstatus",[30,856,857],{},"axon:agent\u002Ferror",[823,859,860,863],{},[838,861,862],{},"every agent",[838,864,865,697,868],{},[30,866,867],{},"axon:agents\u002Factive",[30,869,870],{},"axon:agents\u002Ftotal",[823,872,873,876],{},[838,874,875],{},"the conversation",[838,877,878,697,881,697,884,697,887],{},[30,879,880],{},"axon:session\u002Fname",[30,882,883],{},"axon:session\u002Fid",[30,885,886],{},"axon:session\u002Ftokens",[30,888,889],{},"axon:session\u002Fmessages",[823,891,892,895],{},[838,893,894],{},"git",[838,896,897,697,900,697,903,697,906],{},[30,898,899],{},"axon:git\u002Fbranch",[30,901,902],{},"axon:git\u002Fdirty",[30,904,905],{},"axon:git\u002Fahead",[30,907,908],{},"axon:git\u002Fbehind",[823,910,911,914],{},[838,912,913],{},"the machine",[838,915,916,697,919,697,922],{},[30,917,918],{},"axon:process\u002Fcwd",[30,920,921],{},"axon:process\u002Fpid",[30,923,924],{},"axon:profile\u002Femail",[823,926,927,930],{},[838,928,929],{},"the terminal",[838,931,932,697,935,697,938],{},[30,933,934],{},"axon:mode",[30,936,937],{},"axon:keys",[30,939,940],{},"axon:clock",[823,942,943,946],{},[838,944,945],{},"your config",[838,947,948,697,951],{},[30,949,950],{},"axon:ext\u002Floaded",[30,952,953],{},"axon:ext\u002Fdegraded",[13,955,956,959,960,963,964,967],{},[30,957,958],{},"agent\u002F"," is the focused one, ",[30,961,962],{},"agents\u002F"," is all of them, ",[30,965,966],{},"session\u002F"," is the\nconversation — genuinely different nouns, which is why an agent's name and a\nsession's name are two components rather than one.",[13,969,970,971,973],{},"The git ones read a local cache filled by ",[30,972,894],{}," plumbing commands. No auth, no\nnetwork. Outside a repository they render empty rather than complaining.",[262,975,977],{"id":976},"names","Names",[13,979,980,983],{},[30,981,982],{},"provider:name",", not a package specifier. A package ships many things; a\ncomponent comes from one provider, and naming it after a package would make\nevery component read like an import path. Prefix yours with something of your\nown.",[13,985,986,987,991,992,995],{},"Every registered name is ",[17,988,990],{"href":989},"\u002Fdocs\u002Fv2\u002Ftui\u002Fstructure","generated into your types",", so\n",[30,993,994],{},"lines.create"," completes them and a typo is a compile error rather than a fault\nyou find at runtime.",[997,998,999],"style",{},"html pre.shiki code .scz_3, html code.shiki .scz_3{--shiki-default:#569CD6}html pre.shiki code .sNl3T, html code.shiki .sNl3T{--shiki-default:#4EC9B0}html pre.shiki code .sTNBD, html code.shiki .sTNBD{--shiki-default:#D4D4D4}html pre.shiki code .sOLPB, html code.shiki .sOLPB{--shiki-default:#6A9955}html pre.shiki code .sCudf, html code.shiki .sCudf{--shiki-default:#DCDCAA}html pre.shiki code .s3F5K, html code.shiki .s3F5K{--shiki-default:#9CDCFE}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 pre.shiki code .sKc5r, html code.shiki .sKc5r{--shiki-default:#CE9178}html pre.shiki code .sDGX8, html code.shiki .sDGX8{--shiki-default:#B5CEA8}html pre.shiki code .sYbnZ, html code.shiki .sYbnZ{--shiki-default:#C586C0}html pre.shiki code .sqDPy, html code.shiki .sqDPy{--shiki-default:#C8C8C8}",{"title":28,"searchDepth":50,"depth":50,"links":1001},[1002,1003,1004,1005,1006,1007,1008],{"id":264,"depth":50,"text":265},{"id":364,"depth":50,"text":365},{"id":452,"depth":50,"text":453},{"id":579,"depth":50,"text":580},{"id":742,"depth":50,"text":743},{"id":814,"depth":50,"text":815},{"id":976,"depth":50,"text":977},"The live values a line shows. A component is a name,\nwhat changes it, and what it says.","md",{},"\u002Fdocs\u002Fv2\u002Ftui\u002Fapi\u002Fcomponents",{"title":5,"description":1009},"docs\u002Fv2\u002Ftui\u002Fapi\u002Fcomponents","v-awabgTWMO7sq3PK1NzEFikQDGgcRtprOVDoGem7So",1786881117855]