[{"data":1,"prerenderedAt":1992},["ShallowReactive",2],{"docs-sections":3,"docs-page-\u002Fdocs\u002Fquickstart":123},[4,9,13,17,22,26,30,34,38,42,46,50,55,59,63,67,72,76,80,85,89,93,97,102,106,110,114,119],{"path":5,"title":6,"description":7,"group":8},"\u002Fdocs","Introduction","What tunables is, the problem it solves, and the principles it holds to.","Get started",{"path":10,"title":11,"description":12,"group":8},"\u002Fdocs\u002Fquickstart","Quickstart","Take one group of settings from constants to a screen with a history, in a Nuxt app on Postgres.",{"path":14,"title":15,"description":16,"group":8},"\u002Fdocs\u002Fpatterns","What it is for","The kinds of value tunables keeps — live limits, plans, per-workspace and per-person values, model choices, values that bound each other, costly switches — and the feature that does each.",{"path":18,"title":19,"description":20,"group":21},"\u002Fdocs\u002Fsettings-and-groups","Settings and groups","Declare each setting once, in a group edited beside what it affects, and read it with types.","Concepts",{"path":23,"title":24,"description":25,"group":21},"\u002Fdocs\u002Fkinds-and-units","Kinds and units","The eight kinds of setting, the built-in units, your own units, and how values are checked and read.",{"path":27,"title":28,"description":29,"group":21},"\u002Fdocs\u002Fchecks-and-guards","Checks and guards","Rules across settings, guards for what your app keeps, within for presets, confirmations for costly changes, and notes.",{"path":31,"title":32,"description":33,"group":21},"\u002Fdocs\u002Fhistory-and-restore","History and restore","Every change is a revision with who, when, why and each value before and after; restoring one runs the same checks as any save.",{"path":35,"title":36,"description":37,"group":21},"\u002Fdocs\u002Fpresets","Presets","Named, reusable configurations with one default per slot, assigned by reference and bounded by the settings.",{"path":39,"title":40,"description":41,"group":21},"\u002Fdocs\u002Fscopes","Scopes","Values per workspace and per person, through layers — the system, a plan, the workspace, the person — each bounded by what it inherits.",{"path":43,"title":44,"description":45,"group":21},"\u002Fdocs\u002Fcatalogs","Catalogs","Lists of allowed choices, such as permitted models, whose entries are retired rather than deleted and cannot be retired while in use.",{"path":47,"title":48,"description":49,"group":21},"\u002Fdocs\u002Fdeployment-values","Deployment values","Values a deployment sets in its environment and nobody tunes while the app runs, declared once and listed in .env.example.",{"path":51,"title":52,"description":53,"group":54},"\u002Fdocs\u002Fstorage","Storage","Postgres through your own client, the four tables and how to create them, joining your transactions, and the storage contract behind it.","Integrate",{"path":56,"title":57,"description":58,"group":54},"\u002Fdocs\u002Fserver","Server and access","Mount tunables' API as a fetch handler in Nitro, Hono, Bun or Deno, as Express middleware or as an oRPC router, with access decided by your app.",{"path":60,"title":61,"description":62,"group":54},"\u002Fdocs\u002Faccess","Who can do what","End users bound by values they never see, staff who tune groups, owners and members who change only their own scope, and the terminal.",{"path":64,"title":65,"description":66,"group":54},"\u002Fdocs\u002Ftesting","Testing","Your app's tunables in memory for its own tests, with values set where a test needs them, and how to test rules, guards and confirmations.",{"path":68,"title":69,"description":70,"group":71},"\u002Fdocs\u002Fnuxt-layer","The Nuxt layer","Ready screens for a Nuxt UI app — a group's form, All settings, history, presets, assignments and catalogs — placed beside what they affect.","Screens",{"path":73,"title":74,"description":75,"group":71},"\u002Fdocs\u002Fvue-composables","Vue composables","Headless composables for building tunables' screens in any Vue app, on any design system.",{"path":77,"title":78,"description":79,"group":71},"\u002Fdocs\u002Ftheming","Theming","The screens bring no colors, fonts or CSS of their own; they take your Nuxt UI theme.",{"path":81,"title":82,"description":83,"group":84},"\u002Fdocs\u002Fcli","The CLI","The tunables command, tunables.config.ts, and which commands need a database.","CLI",{"path":86,"title":87,"description":88,"group":84},"\u002Fdocs\u002Fcli-check","Check and generate","The commands that need no database — checking definitions, writing .env.example, and keeping explanations and defaults in step with a pdd-kit Product Model.",{"path":90,"title":91,"description":92,"group":84},"\u002Fdocs\u002Fcli-values","Read and change values","The commands that read and change stored values, through the same checks and history as the screens.",{"path":94,"title":95,"description":96,"group":84},"\u002Fdocs\u002Fcli-skills","Install skills","Install tunables' agent skills for Claude Code, Codex CLI, Cursor, Gemini CLI and GitHub Copilot, and keep them current.",{"path":98,"title":99,"description":100,"group":101},"\u002Fdocs\u002Fskills","Agent skills","Three skills that let a coding agent adopt tunables, define settings the right way and verify that every value has one home.","Skills",{"path":103,"title":104,"description":105,"group":101},"\u002Fdocs\u002Fskill-adopt","tunables-adopt","Bring tunables into an app that has none yet, from an inventory of every value to a wired, synced app with the old homes removed.",{"path":107,"title":108,"description":109,"group":101},"\u002Fdocs\u002Fskill-define","tunables-define","Add, change, rename or remove one value in an app that uses tunables, with its home, its checks, its reads and what happens to stored values.",{"path":111,"title":112,"description":113,"group":101},"\u002Fdocs\u002Fskill-verify","tunables-verify","Audit an app's tunables against their rules, report every finding with where it is and the rule it breaks, and fix only the findings you choose.",{"path":115,"title":116,"description":117,"group":118},"\u002Fdocs\u002Fapi","API reference","Every export of the tunables package, by the subpath it is imported from.","Reference",{"path":120,"title":121,"description":122,"group":118},"\u002Fdocs\u002Ftasklane-example","Tasklane, the example app","A todo app with workspaces and people as tunables — two groups, plans as a layer, a catalog of models, scopes, a rule, a confirmation, and the playground that runs it.",{"id":124,"title":11,"body":125,"description":12,"extension":1987,"group":8,"meta":1988,"navigation":260,"order":257,"path":10,"seo":1989,"stem":1990,"__hash__":1991},"docs\u002Fdocs\u002Fquickstart.md",{"type":126,"value":127,"toc":1976},"minimark",[128,132,154,159,187,200,204,207,676,691,695,706,895,914,918,929,1121,1136,1144,1150,1154,1164,1279,1292,1296,1303,1671,1677,1681,1684,1760,1817,1820,1868,1874,1878,1881,1924,1930,1934,1972],[129,130,11],"h1",{"id":131},"quickstart",[133,134,135,136,140,141,145,146,149,150,153],"p",{},"This takes one group of settings from constants in your code to a screen in\nyour app, stored in your Postgres, with every change recorded. It assumes a\nNuxt 4 app with Nuxt UI and a Postgres database reached through ",[137,138,139],"code",{},"pg",". Other\nservers, drivers and UIs are covered in ",[142,143,57],"a",{"href":144},".\u002Fserver",",\n",[142,147,52],{"href":148},".\u002Fstorage"," and ",[142,151,74],{"href":152},".\u002Fvue-composables",".",[155,156,158],"h2",{"id":157},"_1-install","1. Install",[160,161,166],"pre",{"className":162,"code":163,"language":164,"meta":165,"style":165},"language-bash shiki shiki-themes tunables-panel-light tunables-panel-light tunables-panel-dark","npm install tunables pg\n","bash","",[137,167,168],{"__ignoreMap":165},[169,170,173,177,181,184],"span",{"class":171,"line":172},"line",1,[169,174,176],{"class":175},"sOThN","npm",[169,178,180],{"class":179},"sjCzm"," install",[169,182,183],{"class":179}," tunables",[169,185,186],{"class":179}," pg\n",[133,188,189,190,193,194,149,197,153],{},"tunables needs Node.js 22.12 or later. Its framework integrations are optional\npeer dependencies: install only the ones your app uses. A Nuxt app already has\n",[137,191,192],{},"nuxt",", ",[137,195,196],{},"@nuxt\u002Fui",[137,198,199],{},"vue",[155,201,203],{"id":202},"_2-declare-a-group","2. Declare a group",[133,205,206],{},"A group is a set of settings edited together, on one form, beside what they\naffect. Put your definitions in a module that imports nothing that connects,\nbecause both your app and the CLI load it.",[160,208,213],{"className":209,"code":210,"filename":211,"language":212,"meta":165,"style":165},"language-ts shiki shiki-themes tunables-panel-light tunables-panel-light tunables-panel-dark","import { defineGroup, number, toggle } from 'tunables'\n\nexport const limits = defineGroup({\n  id: 'limits',\n  title: 'Limits',\n  description: 'How much a workspace may hold and use.',\n  place: { label: 'Admin › Limits', href: '\u002Fadmin\u002Flimits' },\n  fields: {\n    maxProjects: number({\n      label: 'Projects',\n      help: 'The most projects a workspace may have open at once.',\n      unit: 'count',\n      default: 3,\n      section: 'What a workspace holds'\n    }),\n    attachmentMb: number({\n      label: 'Attachment size',\n      help: 'The largest file a task may carry.',\n      unit: 'megabytes',\n      default: 10,\n      section: 'What a workspace holds'\n    }),\n    aiSuggestions: toggle({\n      label: 'AI suggestions',\n      help: 'Whether people may ask for suggested tasks.',\n      default: true\n    })\n  }\n})\n\nexport const groups = [limits] as const\n","server\u002Fsettings.ts","ts",[137,214,215,255,262,282,301,318,335,374,385,397,414,431,448,461,476,482,494,510,526,542,554,567,572,585,601,617,627,633,639,645,650],{"__ignoreMap":165},[169,216,217,221,225,229,232,235,237,240,243,246,249,252],{"class":171,"line":172},[169,218,220],{"class":219},"sZ4mS","import",[169,222,224],{"class":223},"sp9ci"," {",[169,226,228],{"class":227},"sVz71"," defineGroup",[169,230,231],{"class":223},",",[169,233,234],{"class":227}," number",[169,236,231],{"class":223},[169,238,239],{"class":227}," toggle ",[169,241,242],{"class":223},"}",[169,244,245],{"class":219}," from",[169,247,248],{"class":223}," '",[169,250,251],{"class":179},"tunables",[169,253,254],{"class":223},"'\n",[169,256,258],{"class":171,"line":257},2,[169,259,261],{"emptyLinePlaceholder":260},true,"\n",[169,263,265,268,271,274,277,279],{"class":171,"line":264},3,[169,266,267],{"class":219},"export",[169,269,270],{"class":219}," const",[169,272,273],{"class":227}," limits ",[169,275,276],{"class":223},"=",[169,278,228],{"class":175},[169,280,281],{"class":223},"({\n",[169,283,285,288,291,293,296,299],{"class":171,"line":284},4,[169,286,287],{"class":227},"  id",[169,289,290],{"class":223},":",[169,292,248],{"class":223},[169,294,295],{"class":179},"limits",[169,297,298],{"class":223},"'",[169,300,145],{"class":223},[169,302,304,307,309,311,314,316],{"class":171,"line":303},5,[169,305,306],{"class":227},"  title",[169,308,290],{"class":223},[169,310,248],{"class":223},[169,312,313],{"class":179},"Limits",[169,315,298],{"class":223},[169,317,145],{"class":223},[169,319,321,324,326,328,331,333],{"class":171,"line":320},6,[169,322,323],{"class":227},"  description",[169,325,290],{"class":223},[169,327,248],{"class":223},[169,329,330],{"class":179},"How much a workspace may hold and use.",[169,332,298],{"class":223},[169,334,145],{"class":223},[169,336,338,341,343,345,348,350,352,355,357,359,362,364,366,369,371],{"class":171,"line":337},7,[169,339,340],{"class":227},"  place",[169,342,290],{"class":223},[169,344,224],{"class":223},[169,346,347],{"class":227}," label",[169,349,290],{"class":223},[169,351,248],{"class":223},[169,353,354],{"class":179},"Admin › Limits",[169,356,298],{"class":223},[169,358,231],{"class":223},[169,360,361],{"class":227}," href",[169,363,290],{"class":223},[169,365,248],{"class":223},[169,367,368],{"class":179},"\u002Fadmin\u002Flimits",[169,370,298],{"class":223},[169,372,373],{"class":223}," },\n",[169,375,377,380,382],{"class":171,"line":376},8,[169,378,379],{"class":227},"  fields",[169,381,290],{"class":223},[169,383,384],{"class":223}," {\n",[169,386,388,391,393,395],{"class":171,"line":387},9,[169,389,390],{"class":227},"    maxProjects",[169,392,290],{"class":223},[169,394,234],{"class":175},[169,396,281],{"class":223},[169,398,400,403,405,407,410,412],{"class":171,"line":399},10,[169,401,402],{"class":227},"      label",[169,404,290],{"class":223},[169,406,248],{"class":223},[169,408,409],{"class":179},"Projects",[169,411,298],{"class":223},[169,413,145],{"class":223},[169,415,417,420,422,424,427,429],{"class":171,"line":416},11,[169,418,419],{"class":227},"      help",[169,421,290],{"class":223},[169,423,248],{"class":223},[169,425,426],{"class":179},"The most projects a workspace may have open at once.",[169,428,298],{"class":223},[169,430,145],{"class":223},[169,432,434,437,439,441,444,446],{"class":171,"line":433},12,[169,435,436],{"class":227},"      unit",[169,438,290],{"class":223},[169,440,248],{"class":223},[169,442,443],{"class":179},"count",[169,445,298],{"class":223},[169,447,145],{"class":223},[169,449,451,454,456,459],{"class":171,"line":450},13,[169,452,453],{"class":227},"      default",[169,455,290],{"class":223},[169,457,458],{"class":179}," 3",[169,460,145],{"class":223},[169,462,464,467,469,471,474],{"class":171,"line":463},14,[169,465,466],{"class":227},"      section",[169,468,290],{"class":223},[169,470,248],{"class":223},[169,472,473],{"class":179},"What a workspace holds",[169,475,254],{"class":223},[169,477,479],{"class":171,"line":478},15,[169,480,481],{"class":223},"    }),\n",[169,483,485,488,490,492],{"class":171,"line":484},16,[169,486,487],{"class":227},"    attachmentMb",[169,489,290],{"class":223},[169,491,234],{"class":175},[169,493,281],{"class":223},[169,495,497,499,501,503,506,508],{"class":171,"line":496},17,[169,498,402],{"class":227},[169,500,290],{"class":223},[169,502,248],{"class":223},[169,504,505],{"class":179},"Attachment size",[169,507,298],{"class":223},[169,509,145],{"class":223},[169,511,513,515,517,519,522,524],{"class":171,"line":512},18,[169,514,419],{"class":227},[169,516,290],{"class":223},[169,518,248],{"class":223},[169,520,521],{"class":179},"The largest file a task may carry.",[169,523,298],{"class":223},[169,525,145],{"class":223},[169,527,529,531,533,535,538,540],{"class":171,"line":528},19,[169,530,436],{"class":227},[169,532,290],{"class":223},[169,534,248],{"class":223},[169,536,537],{"class":179},"megabytes",[169,539,298],{"class":223},[169,541,145],{"class":223},[169,543,545,547,549,552],{"class":171,"line":544},20,[169,546,453],{"class":227},[169,548,290],{"class":223},[169,550,551],{"class":179}," 10",[169,553,145],{"class":223},[169,555,557,559,561,563,565],{"class":171,"line":556},21,[169,558,466],{"class":227},[169,560,290],{"class":223},[169,562,248],{"class":223},[169,564,473],{"class":179},[169,566,254],{"class":223},[169,568,570],{"class":171,"line":569},22,[169,571,481],{"class":223},[169,573,575,578,580,583],{"class":171,"line":574},23,[169,576,577],{"class":227},"    aiSuggestions",[169,579,290],{"class":223},[169,581,582],{"class":175}," toggle",[169,584,281],{"class":223},[169,586,588,590,592,594,597,599],{"class":171,"line":587},24,[169,589,402],{"class":227},[169,591,290],{"class":223},[169,593,248],{"class":223},[169,595,596],{"class":179},"AI suggestions",[169,598,298],{"class":223},[169,600,145],{"class":223},[169,602,604,606,608,610,613,615],{"class":171,"line":603},25,[169,605,419],{"class":227},[169,607,290],{"class":223},[169,609,248],{"class":223},[169,611,612],{"class":179},"Whether people may ask for suggested tasks.",[169,614,298],{"class":223},[169,616,145],{"class":223},[169,618,620,622,624],{"class":171,"line":619},26,[169,621,453],{"class":227},[169,623,290],{"class":223},[169,625,626],{"class":219}," true\n",[169,628,630],{"class":171,"line":629},27,[169,631,632],{"class":223},"    })\n",[169,634,636],{"class":171,"line":635},28,[169,637,638],{"class":223},"  }\n",[169,640,642],{"class":171,"line":641},29,[169,643,644],{"class":223},"})\n",[169,646,648],{"class":171,"line":647},30,[169,649,261],{"emptyLinePlaceholder":260},[169,651,653,655,657,660,662,665,667,670,673],{"class":171,"line":652},31,[169,654,267],{"class":219},[169,656,270],{"class":219},[169,658,659],{"class":227}," groups ",[169,661,276],{"class":223},[169,663,664],{"class":223}," [",[169,666,295],{"class":227},[169,668,669],{"class":223},"]",[169,671,672],{"class":219}," as",[169,674,675],{"class":219}," const\n",[133,677,678,679,193,682,685,686,690],{},"Each field states its kind (",[137,680,681],{},"number",[137,683,684],{},"toggle",", and ",[142,687,689],{"href":688},".\u002Fkinds-and-units","six more","),\nits default and its explanation. The default lives here and nowhere else.",[155,692,694],{"id":693},"_3-store-it-in-your-postgres","3. Store it in your Postgres",[133,696,697,698,701,702,705],{},"Create the app's tunables over the client you already have. ",[137,699,700],{},"createTunables","\nchecks the definitions and never connects, and a ",[137,703,704],{},"pg.Pool"," opens its first\nconnection on its first query, so boot stays free of the database.",[160,707,710],{"className":209,"code":708,"filename":709,"language":212,"meta":165,"style":165},"import pg from 'pg'\nimport { createTunables } from 'tunables'\nimport { fromPg, postgresStore } from 'tunables\u002Fpostgres'\nimport { groups } from '.\u002Fsettings'\n\nexport const pool = new pg.Pool({ connectionString: process.env.DATABASE_URL })\n\nexport const tunables = createTunables({\n  store: postgresStore(fromPg(pool)),\n  groups\n})\n","server\u002Ftunables.ts",[137,711,712,728,747,772,791,795,842,846,862,886,891],{"__ignoreMap":165},[169,713,714,716,719,722,724,726],{"class":171,"line":172},[169,715,220],{"class":219},[169,717,718],{"class":227}," pg ",[169,720,721],{"class":219},"from",[169,723,248],{"class":223},[169,725,139],{"class":179},[169,727,254],{"class":223},[169,729,730,732,734,737,739,741,743,745],{"class":171,"line":257},[169,731,220],{"class":219},[169,733,224],{"class":223},[169,735,736],{"class":227}," createTunables ",[169,738,242],{"class":223},[169,740,245],{"class":219},[169,742,248],{"class":223},[169,744,251],{"class":179},[169,746,254],{"class":223},[169,748,749,751,753,756,758,761,763,765,767,770],{"class":171,"line":264},[169,750,220],{"class":219},[169,752,224],{"class":223},[169,754,755],{"class":227}," fromPg",[169,757,231],{"class":223},[169,759,760],{"class":227}," postgresStore ",[169,762,242],{"class":223},[169,764,245],{"class":219},[169,766,248],{"class":223},[169,768,769],{"class":179},"tunables\u002Fpostgres",[169,771,254],{"class":223},[169,773,774,776,778,780,782,784,786,789],{"class":171,"line":284},[169,775,220],{"class":219},[169,777,224],{"class":223},[169,779,659],{"class":227},[169,781,242],{"class":223},[169,783,245],{"class":219},[169,785,248],{"class":223},[169,787,788],{"class":179},".\u002Fsettings",[169,790,254],{"class":223},[169,792,793],{"class":171,"line":303},[169,794,261],{"emptyLinePlaceholder":260},[169,796,797,799,801,804,806,809,813,816,819,822,825,827,830,832,835,837,840],{"class":171,"line":320},[169,798,267],{"class":219},[169,800,270],{"class":219},[169,802,803],{"class":227}," pool ",[169,805,276],{"class":223},[169,807,808],{"class":219}," new",[169,810,812],{"class":811},"sq0K3"," pg",[169,814,153],{"class":815},"sBd0f",[169,817,818],{"class":175},"Pool",[169,820,821],{"class":223},"({",[169,823,824],{"class":227}," connectionString",[169,826,290],{"class":223},[169,828,829],{"class":227}," process",[169,831,153],{"class":223},[169,833,834],{"class":227},"env",[169,836,153],{"class":223},[169,838,839],{"class":227},"DATABASE_URL ",[169,841,644],{"class":223},[169,843,844],{"class":171,"line":337},[169,845,261],{"emptyLinePlaceholder":260},[169,847,848,850,852,855,857,860],{"class":171,"line":376},[169,849,267],{"class":219},[169,851,270],{"class":219},[169,853,854],{"class":227}," tunables ",[169,856,276],{"class":223},[169,858,859],{"class":175}," createTunables",[169,861,281],{"class":223},[169,863,864,867,869,872,875,878,880,883],{"class":171,"line":387},[169,865,866],{"class":227},"  store",[169,868,290],{"class":223},[169,870,871],{"class":175}," postgresStore",[169,873,874],{"class":223},"(",[169,876,877],{"class":175},"fromPg",[169,879,874],{"class":223},[169,881,882],{"class":227},"pool",[169,884,885],{"class":223},")),\n",[169,887,888],{"class":171,"line":399},[169,889,890],{"class":227},"  groups\n",[169,892,893],{"class":171,"line":416},[169,894,644],{"class":223},[133,896,897,898,900,901,904,905,908,909,913],{},"tunables keeps four tables in a schema called ",[137,899,251],{},". Create them in your\ndeploy step with ",[137,902,903],{},"migrate",", which is safe to run every time, or put\n",[137,906,907],{},"tunablesSql()"," or the ",[142,910,912],{"href":911},".\u002Fstorage#drizzle","Drizzle tables"," in your own\nmigrations.",[155,915,917],{"id":916},"_4-seed-the-values","4. Seed the values",[133,919,920,921,924,925,928],{},"The CLI reads ",[137,922,923],{},"tunables.config.ts",". Its ",[137,926,927],{},"connect"," hands the CLI your app's\ntunables; here it also creates the tables, so one command sets everything up.",[160,930,932],{"className":209,"code":931,"filename":923,"language":212,"meta":165,"style":165},"import { defineConfig } from 'tunables\u002Fconfig'\nimport { fromPg, migrate } from 'tunables\u002Fpostgres'\nimport { groups } from '.\u002Fserver\u002Fsettings'\nimport { pool, tunables } from '.\u002Fserver\u002Ftunables'\n\nexport default defineConfig({\n  groups,\n  async connect() {\n    await migrate(fromPg(pool))\n    return tunables\n  },\n  async disconnect() {\n    await pool.end()\n  }\n})\n",[137,933,934,954,977,996,1020,1024,1036,1043,1056,1075,1083,1088,1099,1113,1117],{"__ignoreMap":165},[169,935,936,938,940,943,945,947,949,952],{"class":171,"line":172},[169,937,220],{"class":219},[169,939,224],{"class":223},[169,941,942],{"class":227}," defineConfig ",[169,944,242],{"class":223},[169,946,245],{"class":219},[169,948,248],{"class":223},[169,950,951],{"class":179},"tunables\u002Fconfig",[169,953,254],{"class":223},[169,955,956,958,960,962,964,967,969,971,973,975],{"class":171,"line":257},[169,957,220],{"class":219},[169,959,224],{"class":223},[169,961,755],{"class":227},[169,963,231],{"class":223},[169,965,966],{"class":227}," migrate ",[169,968,242],{"class":223},[169,970,245],{"class":219},[169,972,248],{"class":223},[169,974,769],{"class":179},[169,976,254],{"class":223},[169,978,979,981,983,985,987,989,991,994],{"class":171,"line":264},[169,980,220],{"class":219},[169,982,224],{"class":223},[169,984,659],{"class":227},[169,986,242],{"class":223},[169,988,245],{"class":219},[169,990,248],{"class":223},[169,992,993],{"class":179},".\u002Fserver\u002Fsettings",[169,995,254],{"class":223},[169,997,998,1000,1002,1005,1007,1009,1011,1013,1015,1018],{"class":171,"line":284},[169,999,220],{"class":219},[169,1001,224],{"class":223},[169,1003,1004],{"class":227}," pool",[169,1006,231],{"class":223},[169,1008,854],{"class":227},[169,1010,242],{"class":223},[169,1012,245],{"class":219},[169,1014,248],{"class":223},[169,1016,1017],{"class":179},".\u002Fserver\u002Ftunables",[169,1019,254],{"class":223},[169,1021,1022],{"class":171,"line":303},[169,1023,261],{"emptyLinePlaceholder":260},[169,1025,1026,1028,1031,1034],{"class":171,"line":320},[169,1027,267],{"class":219},[169,1029,1030],{"class":219}," default",[169,1032,1033],{"class":175}," defineConfig",[169,1035,281],{"class":223},[169,1037,1038,1041],{"class":171,"line":337},[169,1039,1040],{"class":227},"  groups",[169,1042,145],{"class":223},[169,1044,1045,1048,1051,1054],{"class":171,"line":376},[169,1046,1047],{"class":219},"  async",[169,1049,1050],{"class":175}," connect",[169,1052,1053],{"class":223},"()",[169,1055,384],{"class":223},[169,1057,1058,1061,1064,1066,1068,1070,1072],{"class":171,"line":387},[169,1059,1060],{"class":219},"    await",[169,1062,1063],{"class":175}," migrate",[169,1065,874],{"class":223},[169,1067,877],{"class":175},[169,1069,874],{"class":223},[169,1071,882],{"class":227},[169,1073,1074],{"class":223},"))\n",[169,1076,1077,1080],{"class":171,"line":399},[169,1078,1079],{"class":219},"    return",[169,1081,1082],{"class":227}," tunables\n",[169,1084,1085],{"class":171,"line":416},[169,1086,1087],{"class":223},"  },\n",[169,1089,1090,1092,1095,1097],{"class":171,"line":433},[169,1091,1047],{"class":219},[169,1093,1094],{"class":175}," disconnect",[169,1096,1053],{"class":223},[169,1098,384],{"class":223},[169,1100,1101,1103,1105,1107,1110],{"class":171,"line":450},[169,1102,1060],{"class":219},[169,1104,1004],{"class":811},[169,1106,153],{"class":815},[169,1108,1109],{"class":175},"end",[169,1111,1112],{"class":223},"()\n",[169,1114,1115],{"class":171,"line":463},[169,1116,638],{"class":223},[169,1118,1119],{"class":171,"line":478},[169,1120,644],{"class":223},[160,1122,1124],{"className":162,"code":1123,"language":164,"meta":165,"style":165},"npx tunables sync\n",[137,1125,1126],{"__ignoreMap":165},[169,1127,1128,1131,1133],{"class":171,"line":172},[169,1129,1130],{"class":175},"npx",[169,1132,183],{"class":179},[169,1134,1135],{"class":179}," sync\n",[160,1137,1142],{"className":1138,"code":1140,"language":1141},[1139],"language-text","✓ seeded limits with its defaults\n","text",[137,1143,1140],{"__ignoreMap":165},[133,1145,1146,1149],{},[137,1147,1148],{},"sync"," stores each new group at its defaults, as a revision. Run it in every\ndeploy, after the tables exist and before the new code serves: a group that\nwas never synced cannot be read.",[155,1151,1153],{"id":1152},"_5-read-a-setting","5. Read a setting",[133,1155,1156,1157,1160,1161,1163],{},"Read at the point of use, every time. A read is one query and returns typed\nvalues: ",[137,1158,1159],{},"maxProjects"," is a ",[137,1162,681],{}," here.",[160,1165,1167],{"className":209,"code":1166,"language":212,"meta":165,"style":165},"const { maxProjects } = await tunables.get('limits')\nif (openProjects >= maxProjects) {\n  throw createError({ statusCode: 409, message: `A workspace may have ${maxProjects} open projects.` })\n}\n",[137,1168,1169,1205,1227,1274],{"__ignoreMap":165},[169,1170,1171,1174,1176,1179,1181,1184,1187,1189,1191,1194,1196,1198,1200,1202],{"class":171,"line":172},[169,1172,1173],{"class":219},"const",[169,1175,224],{"class":223},[169,1177,1178],{"class":227}," maxProjects ",[169,1180,242],{"class":223},[169,1182,1183],{"class":223}," =",[169,1185,1186],{"class":219}," await",[169,1188,183],{"class":811},[169,1190,153],{"class":815},[169,1192,1193],{"class":175},"get",[169,1195,874],{"class":223},[169,1197,298],{"class":223},[169,1199,295],{"class":179},[169,1201,298],{"class":223},[169,1203,1204],{"class":223},")\n",[169,1206,1207,1210,1213,1216,1219,1222,1225],{"class":171,"line":257},[169,1208,1209],{"class":219},"if",[169,1211,1212],{"class":223}," (",[169,1214,1215],{"class":227},"openProjects ",[169,1217,1218],{"class":223},">=",[169,1220,1221],{"class":227}," maxProjects",[169,1223,1224],{"class":223},")",[169,1226,384],{"class":223},[169,1228,1229,1232,1235,1237,1240,1242,1245,1247,1250,1252,1255,1258,1261,1263,1265,1268,1271],{"class":171,"line":264},[169,1230,1231],{"class":219},"  throw",[169,1233,1234],{"class":175}," createError",[169,1236,821],{"class":223},[169,1238,1239],{"class":227}," statusCode",[169,1241,290],{"class":223},[169,1243,1244],{"class":179}," 409",[169,1246,231],{"class":223},[169,1248,1249],{"class":227}," message",[169,1251,290],{"class":223},[169,1253,1254],{"class":223}," `",[169,1256,1257],{"class":179},"A workspace may have ",[169,1259,1260],{"class":223},"${",[169,1262,1159],{"class":227},[169,1264,242],{"class":223},[169,1266,1267],{"class":179}," open projects.",[169,1269,1270],{"class":223},"`",[169,1272,1273],{"class":223}," })\n",[169,1275,1276],{"class":171,"line":284},[169,1277,1278],{"class":223},"}\n",[133,1280,1281,1282,1284,1285,1288,1289,1291],{},"There is no fallback to write: ",[137,1283,1193],{}," returns every field, or throws\n",[137,1286,1287],{},"TunablesMissing"," when ",[137,1290,1148],{}," has not run.",[155,1293,1295],{"id":1294},"_6-mount-the-api","6. Mount the API",[133,1297,1298,1299,1302],{},"The screens talk to one handler. It answers paths under ",[137,1300,1301],{},"\u002Fapi\u002Ftunables"," and\nasks your app, on every request, who is asking and whether they may.",[160,1304,1307],{"className":209,"code":1305,"filename":1306,"language":212,"meta":165,"style":165},"import type { H3Event } from 'h3'\nimport { createHandler } from 'tunables\u002Fserver'\nimport { tunables } from '..\u002F..\u002F..\u002Ftunables'\n\nconst handle = createHandler\u003CH3Event>({\n  tunables,\n  \u002F\u002F Who is asking, from your own sign-in. Undefined when nobody is signed in.\n  actor: (event) => {\n    const user = event.context.user\n    return user ? { id: user.id, name: user.name } : undefined\n  },\n  \u002F\u002F Whether they may. Without it, nothing is allowed.\n  authorize: (event, { action }) =>\n    action === 'read' ? Boolean(event.context.user?.staff) : event.context.user?.role === 'admin'\n})\n\nexport default defineEventHandler(async event =>\n  (await handle(toWebRequest(event), event)) ?? createError({ statusCode: 404 }))\n","server\u002Froutes\u002Fapi\u002Ftunables\u002F[...].ts",[137,1308,1309,1332,1352,1371,1375,1396,1403,1409,1428,1451,1497,1501,1506,1530,1598,1602,1606,1626],{"__ignoreMap":165},[169,1310,1311,1313,1316,1318,1321,1323,1325,1327,1330],{"class":171,"line":172},[169,1312,220],{"class":219},[169,1314,1315],{"class":219}," type",[169,1317,224],{"class":223},[169,1319,1320],{"class":227}," H3Event ",[169,1322,242],{"class":223},[169,1324,245],{"class":219},[169,1326,248],{"class":223},[169,1328,1329],{"class":179},"h3",[169,1331,254],{"class":223},[169,1333,1334,1336,1338,1341,1343,1345,1347,1350],{"class":171,"line":257},[169,1335,220],{"class":219},[169,1337,224],{"class":223},[169,1339,1340],{"class":227}," createHandler ",[169,1342,242],{"class":223},[169,1344,245],{"class":219},[169,1346,248],{"class":223},[169,1348,1349],{"class":179},"tunables\u002Fserver",[169,1351,254],{"class":223},[169,1353,1354,1356,1358,1360,1362,1364,1366,1369],{"class":171,"line":264},[169,1355,220],{"class":219},[169,1357,224],{"class":223},[169,1359,854],{"class":227},[169,1361,242],{"class":223},[169,1363,245],{"class":219},[169,1365,248],{"class":223},[169,1367,1368],{"class":179},"..\u002F..\u002F..\u002Ftunables",[169,1370,254],{"class":223},[169,1372,1373],{"class":171,"line":284},[169,1374,261],{"emptyLinePlaceholder":260},[169,1376,1377,1379,1382,1384,1387,1390,1393],{"class":171,"line":303},[169,1378,1173],{"class":219},[169,1380,1381],{"class":227}," handle ",[169,1383,276],{"class":223},[169,1385,1386],{"class":175}," createHandler",[169,1388,1389],{"class":223},"\u003C",[169,1391,1392],{"class":175},"H3Event",[169,1394,1395],{"class":223},">({\n",[169,1397,1398,1401],{"class":171,"line":320},[169,1399,1400],{"class":227},"  tunables",[169,1402,145],{"class":223},[169,1404,1405],{"class":171,"line":337},[169,1406,1408],{"class":1407},"sKllz","  \u002F\u002F Who is asking, from your own sign-in. Undefined when nobody is signed in.\n",[169,1410,1411,1414,1416,1418,1421,1423,1426],{"class":171,"line":376},[169,1412,1413],{"class":175},"  actor",[169,1415,290],{"class":223},[169,1417,1212],{"class":223},[169,1419,1420],{"class":227},"event",[169,1422,1224],{"class":223},[169,1424,1425],{"class":219}," =>",[169,1427,384],{"class":223},[169,1429,1430,1433,1436,1438,1441,1443,1446,1448],{"class":171,"line":387},[169,1431,1432],{"class":219},"    const",[169,1434,1435],{"class":227}," user ",[169,1437,276],{"class":223},[169,1439,1440],{"class":227}," event",[169,1442,153],{"class":223},[169,1444,1445],{"class":227},"context",[169,1447,153],{"class":223},[169,1449,1450],{"class":227},"user\n",[169,1452,1453,1455,1457,1460,1462,1465,1467,1470,1472,1475,1477,1480,1482,1484,1486,1489,1491,1494],{"class":171,"line":399},[169,1454,1079],{"class":219},[169,1456,1435],{"class":227},[169,1458,1459],{"class":223},"?",[169,1461,224],{"class":223},[169,1463,1464],{"class":227}," id",[169,1466,290],{"class":223},[169,1468,1469],{"class":227}," user",[169,1471,153],{"class":223},[169,1473,1474],{"class":227},"id",[169,1476,231],{"class":223},[169,1478,1479],{"class":227}," name",[169,1481,290],{"class":223},[169,1483,1469],{"class":227},[169,1485,153],{"class":223},[169,1487,1488],{"class":227},"name ",[169,1490,242],{"class":223},[169,1492,1493],{"class":223}," :",[169,1495,1496],{"class":219}," undefined\n",[169,1498,1499],{"class":171,"line":416},[169,1500,1087],{"class":223},[169,1502,1503],{"class":171,"line":433},[169,1504,1505],{"class":1407},"  \u002F\u002F Whether they may. Without it, nothing is allowed.\n",[169,1507,1508,1511,1513,1515,1517,1519,1521,1524,1527],{"class":171,"line":450},[169,1509,1510],{"class":175},"  authorize",[169,1512,290],{"class":223},[169,1514,1212],{"class":223},[169,1516,1420],{"class":227},[169,1518,231],{"class":223},[169,1520,224],{"class":223},[169,1522,1523],{"class":227}," action ",[169,1525,1526],{"class":223},"})",[169,1528,1529],{"class":219}," =>\n",[169,1531,1532,1535,1538,1540,1543,1545,1548,1551,1553,1555,1557,1559,1561,1564,1567,1570,1572,1574,1576,1578,1580,1582,1584,1586,1589,1591,1593,1596],{"class":171,"line":463},[169,1533,1534],{"class":227},"    action ",[169,1536,1537],{"class":223},"===",[169,1539,248],{"class":223},[169,1541,1542],{"class":179},"read",[169,1544,298],{"class":223},[169,1546,1547],{"class":223}," ?",[169,1549,1550],{"class":175}," Boolean",[169,1552,874],{"class":223},[169,1554,1420],{"class":227},[169,1556,153],{"class":223},[169,1558,1445],{"class":227},[169,1560,153],{"class":223},[169,1562,1563],{"class":227},"user",[169,1565,1566],{"class":223},"?.",[169,1568,1569],{"class":227},"staff",[169,1571,1224],{"class":223},[169,1573,1493],{"class":223},[169,1575,1440],{"class":227},[169,1577,153],{"class":223},[169,1579,1445],{"class":227},[169,1581,153],{"class":223},[169,1583,1563],{"class":227},[169,1585,1566],{"class":223},[169,1587,1588],{"class":227},"role ",[169,1590,1537],{"class":223},[169,1592,248],{"class":223},[169,1594,1595],{"class":179},"admin",[169,1597,254],{"class":223},[169,1599,1600],{"class":171,"line":478},[169,1601,644],{"class":223},[169,1603,1604],{"class":171,"line":484},[169,1605,261],{"emptyLinePlaceholder":260},[169,1607,1608,1610,1612,1615,1617,1620,1623],{"class":171,"line":496},[169,1609,267],{"class":219},[169,1611,1030],{"class":219},[169,1613,1614],{"class":175}," defineEventHandler",[169,1616,874],{"class":223},[169,1618,1619],{"class":219},"async",[169,1621,1622],{"class":227}," event ",[169,1624,1625],{"class":219},"=>\n",[169,1627,1628,1631,1634,1637,1639,1642,1644,1646,1649,1651,1654,1657,1659,1661,1663,1665,1668],{"class":171,"line":512},[169,1629,1630],{"class":223},"  (",[169,1632,1633],{"class":219},"await",[169,1635,1636],{"class":175}," handle",[169,1638,874],{"class":223},[169,1640,1641],{"class":175},"toWebRequest",[169,1643,874],{"class":223},[169,1645,1420],{"class":227},[169,1647,1648],{"class":223},"),",[169,1650,1440],{"class":227},[169,1652,1653],{"class":223},"))",[169,1655,1656],{"class":223}," ??",[169,1658,1234],{"class":175},[169,1660,821],{"class":223},[169,1662,1239],{"class":227},[169,1664,290],{"class":223},[169,1666,1667],{"class":179}," 404",[169,1669,1670],{"class":223}," }))\n",[133,1672,1673,1676],{},[137,1674,1675],{},"event.context.user"," stands for whatever your auth sets; tunables has no users\nof its own. A refused request answers 404 by default, so an outsider cannot\ntell the administration exists.",[155,1678,1680],{"id":1679},"_7-embed-the-screens","7. Embed the screens",[133,1682,1683],{},"Extend the layer, and let Tailwind see its components:",[160,1685,1688],{"className":209,"code":1686,"filename":1687,"language":212,"meta":165,"style":165},"export default defineNuxtConfig({\n  extends: ['tunables\u002Fnuxt'],\n  modules: ['@nuxt\u002Fui'],\n  css: ['~\u002Fassets\u002Fcss\u002Fmain.css']\n})\n","nuxt.config.ts",[137,1689,1690,1701,1720,1737,1756],{"__ignoreMap":165},[169,1691,1692,1694,1696,1699],{"class":171,"line":172},[169,1693,267],{"class":219},[169,1695,1030],{"class":219},[169,1697,1698],{"class":175}," defineNuxtConfig",[169,1700,281],{"class":223},[169,1702,1703,1706,1708,1710,1712,1715,1717],{"class":171,"line":257},[169,1704,1705],{"class":227},"  extends",[169,1707,290],{"class":223},[169,1709,664],{"class":223},[169,1711,298],{"class":223},[169,1713,1714],{"class":179},"tunables\u002Fnuxt",[169,1716,298],{"class":223},[169,1718,1719],{"class":223},"],\n",[169,1721,1722,1725,1727,1729,1731,1733,1735],{"class":171,"line":264},[169,1723,1724],{"class":227},"  modules",[169,1726,290],{"class":223},[169,1728,664],{"class":223},[169,1730,298],{"class":223},[169,1732,196],{"class":179},[169,1734,298],{"class":223},[169,1736,1719],{"class":223},[169,1738,1739,1742,1744,1746,1748,1751,1753],{"class":171,"line":284},[169,1740,1741],{"class":227},"  css",[169,1743,290],{"class":223},[169,1745,664],{"class":223},[169,1747,298],{"class":223},[169,1749,1750],{"class":179},"~\u002Fassets\u002Fcss\u002Fmain.css",[169,1752,298],{"class":223},[169,1754,1755],{"class":223},"]\n",[169,1757,1758],{"class":171,"line":303},[169,1759,644],{"class":223},[160,1761,1766],{"className":1762,"code":1763,"filename":1764,"language":1765,"meta":165,"style":165},"language-css shiki shiki-themes tunables-panel-light tunables-panel-light tunables-panel-dark","@import \"tailwindcss\";\n@import \"@nuxt\u002Fui\";\n\n@source \"..\u002F..\u002F..\u002Fnode_modules\u002Ftunables\u002Flayers\u002Fnuxt\u002Ftunables\u002Fapp\";\n","app\u002Fassets\u002Fcss\u002Fmain.css","css",[137,1767,1768,1787,1801,1805],{"__ignoreMap":165},[169,1769,1770,1773,1775,1778,1781,1784],{"class":171,"line":172},[169,1771,1772],{"class":223},"@",[169,1774,220],{"class":219},[169,1776,1777],{"class":223}," \"",[169,1779,1780],{"class":179},"tailwindcss",[169,1782,1783],{"class":223},"\"",[169,1785,1786],{"class":223},";\n",[169,1788,1789,1791,1793,1795,1797,1799],{"class":171,"line":257},[169,1790,1772],{"class":223},[169,1792,220],{"class":219},[169,1794,1777],{"class":223},[169,1796,196],{"class":179},[169,1798,1783],{"class":223},[169,1800,1786],{"class":223},[169,1802,1803],{"class":171,"line":264},[169,1804,261],{"emptyLinePlaceholder":260},[169,1806,1807,1809,1812,1815],{"class":171,"line":284},[169,1808,1772],{"class":223},[169,1810,1811],{"class":219},"source",[169,1813,1814],{"class":227}," \"..\u002F..\u002F..\u002Fnode_modules\u002Ftunables\u002Flayers\u002Fnuxt\u002Ftunables\u002Fapp\"",[169,1816,1786],{"class":223},[133,1818,1819],{},"Then put the form on the page beside what it affects, behind your own admin\nroute guard:",[160,1821,1825],{"className":1822,"code":1823,"filename":1824,"language":199,"meta":165,"style":165},"language-vue shiki shiki-themes tunables-panel-light tunables-panel-light tunables-panel-dark","\u003Ctemplate>\n  \u003CTunablesGroupForm group=\"limits\" \u002F>\n\u003C\u002Ftemplate>\n","app\u002Fpages\u002Fadmin\u002Flimits.vue",[137,1826,1827,1837,1859],{"__ignoreMap":165},[169,1828,1829,1831,1834],{"class":171,"line":172},[169,1830,1389],{"class":223},[169,1832,1833],{"class":179},"template",[169,1835,1836],{"class":223},">\n",[169,1838,1839,1842,1845,1848,1850,1852,1854,1856],{"class":171,"line":257},[169,1840,1841],{"class":223},"  \u003C",[169,1843,1844],{"class":179},"TunablesGroupForm",[169,1846,1847],{"class":175}," group",[169,1849,276],{"class":223},[169,1851,1783],{"class":223},[169,1853,295],{"class":179},[169,1855,1783],{"class":223},[169,1857,1858],{"class":223}," \u002F>\n",[169,1860,1861,1864,1866],{"class":171,"line":264},[169,1862,1863],{"class":223},"\u003C\u002F",[169,1865,1833],{"class":179},[169,1867,1836],{"class":223},[133,1869,1870,1871,153],{},"The form shows each field by section with its explanation and default, saves\nthe whole group at once, shows each problem beside the field it is about, and\nlists the group's history with a way to restore. Add an All settings page with\n",[137,1872,1873],{},"\u003CTunablesOverview \u002F>",[155,1875,1877],{"id":1876},"_8-change-it-and-read-the-history","8. Change it, and read the history",[133,1879,1880],{},"Change a value on the screen, or from a terminal:",[160,1882,1884],{"className":162,"code":1883,"language":164,"meta":165,"style":165},"npx tunables set limits maxProjects=5 --reason \"More room on the free tier\"\nnpx tunables history limits\n",[137,1885,1886,1912],{"__ignoreMap":165},[169,1887,1888,1890,1892,1895,1898,1901,1904,1906,1909],{"class":171,"line":172},[169,1889,1130],{"class":175},[169,1891,183],{"class":179},[169,1893,1894],{"class":179}," set",[169,1896,1897],{"class":179}," limits",[169,1899,1900],{"class":179}," maxProjects=5",[169,1902,1903],{"class":179}," --reason",[169,1905,1777],{"class":223},[169,1907,1908],{"class":179},"More room on the free tier",[169,1910,1911],{"class":223},"\"\n",[169,1913,1914,1916,1918,1921],{"class":171,"line":257},[169,1915,1130],{"class":175},[169,1917,183],{"class":179},[169,1919,1920],{"class":179}," history",[169,1922,1923],{"class":179}," limits\n",[160,1925,1928],{"className":1926,"code":1927,"language":1141},[1139],"Saved as revision 2.\n#2  2026-10-23T09:12:44.021Z  ada (terminal)  “More room on the free tier”\n    maxProjects: 3 → 5\n#1  2026-10-23T09:02:10.518Z  ada (terminal)  “Seeded with the defaults.”\n    maxProjects: null → 3; attachmentMb: null → 10; aiSuggestions: null → true\n",[137,1929,1927],{"__ignoreMap":165},[155,1931,1933],{"id":1932},"next","Next",[1935,1936,1937,1948,1956,1964],"ul",{},[1938,1939,1940,1941,685,1944,1947],"li",{},"Let each workspace, or each person, set its own value within what it\ninherits: see ",[142,1942,40],{"href":1943},".\u002Fscopes",[142,1945,61],{"href":1946},".\u002Faccess"," for\nletting them reach their own screen.",[1938,1949,1950,1951,1955],{},"Add ",[142,1952,1954],{"href":1953},".\u002Fchecks-and-guards","rules, guards and confirmations"," so a change\ncannot break what depends on it.",[1938,1957,1958,1959,1963],{},"Move environment variables that are really deployment values into\n",[142,1960,1962],{"href":1961},".\u002Fdeployment-values","deployment values",", and the rest into groups.",[1938,1965,1966,1967,1971],{},"Install the ",[142,1968,1970],{"href":1969},".\u002Fskills","agent skills"," and let your coding agent adopt the\nrest of your app's settings.",[1973,1974,1975],"style",{},"html pre.shiki code .sOThN, html code.shiki .sOThN{--shiki-light:#2A3439;--shiki-light-font-weight:bold;--shiki-default:#2A3439;--shiki-default-font-weight:bold;--shiki-dark:#F6F8F8;--shiki-dark-font-weight:bold}html pre.shiki code .sjCzm, html code.shiki .sjCzm{--shiki-light:#92400E;--shiki-default:#92400E;--shiki-dark:#FCD34D}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 .sZ4mS, html code.shiki .sZ4mS{--shiki-light:#115E59;--shiki-default:#115E59;--shiki-dark:#5EEAD4}html pre.shiki code .sp9ci, html code.shiki .sp9ci{--shiki-light:#4F5D63;--shiki-default:#4F5D63;--shiki-dark:#A3AFB4}html pre.shiki code .sVz71, html code.shiki .sVz71{--shiki-light:#182025;--shiki-default:#182025;--shiki-dark:#E6EBEC}html pre.shiki code .sq0K3, html code.shiki .sq0K3{--shiki-light:#182025;--shiki-light-font-weight:bold;--shiki-default:#182025;--shiki-default-font-weight:bold;--shiki-dark:#E6EBEC;--shiki-dark-font-weight:bold}html pre.shiki code .sBd0f, html code.shiki .sBd0f{--shiki-light:#4F5D63;--shiki-light-font-weight:bold;--shiki-default:#4F5D63;--shiki-default-font-weight:bold;--shiki-dark:#A3AFB4;--shiki-dark-font-weight:bold}html pre.shiki code .sKllz, html code.shiki .sKllz{--shiki-light:#4F5D63;--shiki-light-font-style:italic;--shiki-default:#4F5D63;--shiki-default-font-style:italic;--shiki-dark:#A3AFB4;--shiki-dark-font-style:italic}",{"title":165,"searchDepth":257,"depth":257,"links":1977},[1978,1979,1980,1981,1982,1983,1984,1985,1986],{"id":157,"depth":257,"text":158},{"id":202,"depth":257,"text":203},{"id":693,"depth":257,"text":694},{"id":916,"depth":257,"text":917},{"id":1152,"depth":257,"text":1153},{"id":1294,"depth":257,"text":1295},{"id":1679,"depth":257,"text":1680},{"id":1876,"depth":257,"text":1877},{"id":1932,"depth":257,"text":1933},"md",{},{"title":11,"description":12},"docs\u002Fquickstart","dtf2x_rLfQbhRsS7ceZ0FmgBAJapc2NbWURABVZ03Ms",1792845117971]