[{"data":1,"prerenderedAt":2583},["ShallowReactive",2],{"navigation_docs":3,"-integrations-cli":277,"-integrations-cli-surround":2578},[4,10,57,83,236,262],{"title":5,"path":6,"stem":7,"icon":8,"exact":9},"Introduction","\u002F","0.index","i-lucide-book-open",true,{"title":11,"icon":12,"modifiedAt":13,"path":14,"stem":15,"children":16,"page":12},"Getting Started",false,"2026-04-30T19:15:33.000Z","\u002Fgetting-started","1.getting-started",[17,22,27,32,37,42,47,52],{"title":18,"path":19,"stem":20,"icon":21},"Quickstart","\u002Fgetting-started\u002Fquickstart","1.getting-started\u002F1.quickstart","i-lucide-fast-forward",{"title":23,"path":24,"stem":25,"icon":26},"Core Concepts","\u002Fgetting-started\u002Fcore-concepts","1.getting-started\u002F2.core-concepts","i-lucide-workflow",{"title":28,"path":29,"stem":30,"icon":31},"Configs Anatomy","\u002Fgetting-started\u002Fconfigs","1.getting-started\u002F3.configs","i-lucide-file-cog",{"title":33,"path":34,"stem":35,"icon":36},"Architecture","\u002Fgetting-started\u002Farchitecture","1.getting-started\u002F4.architecture","i-lucide-layers",{"title":38,"path":39,"stem":40,"icon":41},"JSON Schema Validation","\u002Fgetting-started\u002Fjson-schema-validation","1.getting-started\u002F5.json-schema-validation","i-lucide-braces",{"title":43,"path":44,"stem":45,"icon":46},"Testing Rules","\u002Fgetting-started\u002Ftesting-targeting-rules","1.getting-started\u002F6.testing-targeting-rules","i-lucide-flask-conical",{"title":48,"path":49,"stem":50,"icon":51},"Segments","\u002Fgetting-started\u002Fsegments","1.getting-started\u002F7.segments","i-lucide-squares-intersect",{"title":53,"path":54,"stem":55,"icon":56},"Pricing & Billing","\u002Fgetting-started\u002Fpricing-and-billing","1.getting-started\u002F8.pricing-and-billing","i-lucide-credit-card",{"title":58,"modifiedAt":59,"defaultOpen":9,"path":60,"stem":61,"children":62,"page":12},"Monitoring","2026-09-24T23:33:20.000Z","\u002Fmonitoring","2.monitoring",[63,68,73,78],{"title":64,"path":65,"stem":66,"icon":67},"Activity","\u002Fmonitoring\u002Factivity","2.monitoring\u002F1.activity","i-lucide-activity",{"title":69,"path":70,"stem":71,"icon":72},"Lifecycle","\u002Fmonitoring\u002Flifecycle","2.monitoring\u002F2.lifecycle","i-lucide-recycle",{"title":74,"path":75,"stem":76,"icon":77},"Alerts","\u002Fmonitoring\u002Falerts","2.monitoring\u002F3.alerts","i-lucide-bell",{"title":79,"path":80,"stem":81,"icon":82},"Dynamic Detection","\u002Fmonitoring\u002Fdynamic-detection","2.monitoring\u002F4.dynamic-detection","i-lucide-hat-glasses",{"title":84,"modifiedAt":59,"defaultOpen":9,"path":85,"stem":86,"children":87,"page":12},"SDKs","\u002Fsdks","3.sdks",[88,93,114,139,155,186,231],{"title":89,"path":90,"stem":91,"icon":92},"Available SDKs","\u002Fsdks\u002Favailable-sdks","3.sdks\u002F1.available-sdks","i-lucide-list",{"title":94,"modifiedAt":59,"icon":95,"defaultOpen":12,"path":96,"stem":97,"children":98,"page":12},"Browser SDKs","i-lucide-monitor","\u002Fsdks\u002Fbrowser","3.sdks\u002F2.browser",[99,104,109],{"title":100,"path":101,"stem":102,"icon":103},"Javascript","\u002Fsdks\u002Fbrowser\u002Fjavascript","3.sdks\u002F2.browser\u002F1.javascript","cd-logos-javascript",{"title":105,"path":106,"stem":107,"icon":108},"React","\u002Fsdks\u002Fbrowser\u002Freact","3.sdks\u002F2.browser\u002F2.react","cd-logos-react-light",{"title":110,"path":111,"stem":112,"icon":113},"Vue","\u002Fsdks\u002Fbrowser\u002Fvue","3.sdks\u002F2.browser\u002F3.vue","cd-logos-vue",{"title":115,"modifiedAt":59,"icon":116,"defaultOpen":12,"path":117,"stem":118,"children":119,"page":12},"Mobile SDKs","i-lucide-smartphone","\u002Fsdks\u002Fmobile","3.sdks\u002F3.mobile",[120,124,129,134],{"title":121,"path":122,"stem":123,"icon":108},"React Native","\u002Fsdks\u002Fmobile\u002Freact-native","3.sdks\u002F3.mobile\u002F1.react-native",{"title":125,"path":126,"stem":127,"icon":128},"Flutter","\u002Fsdks\u002Fmobile\u002Fflutter","3.sdks\u002F3.mobile\u002F2.flutter","cd-logos-flutter",{"title":130,"path":131,"stem":132,"icon":133},"Swift","\u002Fsdks\u002Fmobile\u002Fswift","3.sdks\u002F3.mobile\u002F3.swift","cd-logos-swift",{"title":135,"path":136,"stem":137,"icon":138},"Android","\u002Fsdks\u002Fmobile\u002Fandroid","3.sdks\u002F3.mobile\u002F4.android","cd-logos-android",{"title":140,"modifiedAt":59,"icon":141,"defaultOpen":12,"path":142,"stem":143,"children":144,"page":12},"Meta-framework SDKs","i-lucide-monitor-smartphone","\u002Fsdks\u002Fmeta","3.sdks\u002F4.meta",[145,150],{"title":146,"path":147,"stem":148,"icon":149},"Next.js","\u002Fsdks\u002Fmeta\u002Fnextjs","3.sdks\u002F4.meta\u002F1.nextjs","cd-logos-nextjs",{"title":151,"path":152,"stem":153,"icon":154},"Nuxt","\u002Fsdks\u002Fmeta\u002Fnuxt","3.sdks\u002F4.meta\u002F2.nuxt","cd-logos-nuxt",{"title":156,"modifiedAt":59,"icon":157,"defaultOpen":12,"path":158,"stem":159,"children":160,"page":12},"Server SDKs","i-lucide-server","\u002Fsdks\u002Fserver","3.sdks\u002F5.server",[161,166,171,176,181],{"title":162,"path":163,"stem":164,"icon":165},"Node.js","\u002Fsdks\u002Fserver\u002Fnode-js","3.sdks\u002F5.server\u002F1.node-js","cd-logos-nodejs",{"title":167,"path":168,"stem":169,"icon":170},"Python","\u002Fsdks\u002Fserver\u002Fpython","3.sdks\u002F5.server\u002F2.python","cd-logos-python",{"title":172,"path":173,"stem":174,"icon":175},"Java","\u002Fsdks\u002Fserver\u002Fjava","3.sdks\u002F5.server\u002F3.java","cd-logos-java",{"title":177,"path":178,"stem":179,"icon":180},".NET","\u002Fsdks\u002Fserver\u002Fdotnet","3.sdks\u002F5.server\u002F4.dotnet","cd-logos-dotnet",{"title":182,"path":183,"stem":184,"icon":185},"Go","\u002Fsdks\u002Fserver\u002Fgo","3.sdks\u002F5.server\u002F5.go","cd-logos-go",{"title":187,"modifiedAt":59,"icon":188,"defaultOpen":12,"path":189,"stem":190,"children":191},"OpenFeature Providers","cd-logos-openfeature","\u002Fsdks\u002Fopenfeature","3.sdks\u002F6.openfeature\u002Findex",[192,194,199,203,207,211,215,219,223,227],{"title":193,"path":189,"stem":190,"icon":188},"Overview",{"title":195,"path":196,"stem":197,"icon":188,"icons":198},"Web","\u002Fsdks\u002Fopenfeature\u002Fweb","3.sdks\u002F6.openfeature\u002F1.web",[188,103],{"title":130,"path":200,"stem":201,"icon":188,"icons":202},"\u002Fsdks\u002Fopenfeature\u002Fswift","3.sdks\u002F6.openfeature\u002F2.swift",[188,133],{"title":135,"path":204,"stem":205,"icon":188,"icons":206},"\u002Fsdks\u002Fopenfeature\u002Fandroid","3.sdks\u002F6.openfeature\u002F3.android",[188,138],{"title":125,"path":208,"stem":209,"icon":188,"icons":210},"\u002Fsdks\u002Fopenfeature\u002Fflutter","3.sdks\u002F6.openfeature\u002F4.flutter",[188,128],{"title":162,"path":212,"stem":213,"icon":188,"icons":214},"\u002Fsdks\u002Fopenfeature\u002Fnode-js","3.sdks\u002F6.openfeature\u002F5.node-js",[188,165],{"title":167,"path":216,"stem":217,"icon":188,"icons":218},"\u002Fsdks\u002Fopenfeature\u002Fpython","3.sdks\u002F6.openfeature\u002F6.python",[188,170],{"title":172,"path":220,"stem":221,"icon":188,"icons":222},"\u002Fsdks\u002Fopenfeature\u002Fjava","3.sdks\u002F6.openfeature\u002F7.java",[188,175],{"title":177,"path":224,"stem":225,"icon":188,"icons":226},"\u002Fsdks\u002Fopenfeature\u002Fdotnet","3.sdks\u002F6.openfeature\u002F8.dotnet",[188,180],{"title":182,"path":228,"stem":229,"icon":188,"icons":230},"\u002Fsdks\u002Fopenfeature\u002Fgo","3.sdks\u002F6.openfeature\u002F9.go",[188,185],{"title":232,"path":233,"stem":234,"icon":235},"Maven Repository","\u002Fsdks\u002Fmaven-repository","3.sdks\u002F7.maven-repository","i-lucide-package",{"title":237,"modifiedAt":59,"defaultOpen":9,"path":238,"stem":239,"children":240,"page":12},"Integrations","\u002Fintegrations","4.integrations",[241,246,251,257],{"title":242,"path":243,"stem":244,"icon":245},"Terraform","\u002Fintegrations\u002Fterraform","4.integrations\u002F1.terraform","cd-logos-terraform",{"title":247,"path":248,"stem":249,"icon":250},"MCP","\u002Fintegrations\u002Fmcp","4.integrations\u002F2.mcp","cd-logos-mcp",{"title":252,"path":253,"stem":254,"icon":255,"badge":256},"CLI","\u002Fintegrations\u002Fcli","4.integrations\u002F3.cli","cd-logos-cli","Beta",{"title":258,"path":259,"stem":260,"icon":261},"Admin API","\u002Fintegrations\u002Fadmin-api","4.integrations\u002F4.admin-api","i-lucide-blocks",{"title":263,"modifiedAt":264,"defaultOpen":9,"path":265,"stem":266,"children":267,"page":12},"Migration Guides","2026-10-16T17:57:49.000Z","\u002Fmigration-guides","5.migration-guides",[268,273],{"title":269,"path":270,"stem":271,"icon":272},"From LaunchDarkly","\u002Fmigration-guides\u002Flaunchdarkly","5.migration-guides\u002F1.launchdarkly","i-lucide-baggage-claim",{"title":274,"path":275,"stem":276,"icon":272},"From Firebase Remote Config","\u002Fmigration-guides\u002Ffirebase-remote-config","5.migration-guides\u002F2.firebase-remote-config",{"id":278,"title":252,"body":279,"description":2570,"extension":2571,"links":2572,"meta":2573,"navigation":2575,"path":253,"seo":2576,"stem":254,"__hash__":2577},"docs\u002F4.integrations\u002F3.cli.md",{"type":280,"value":281,"toc":2552},"minimark",[282,286,291,295,308,316,332,335,354,358,361,397,412,427,437,441,447,472,479,483,488,500,506,556,574,594,598,609,627,642,761,836,840,849,939,946,949,961,966,1042,1045,1079,1097,1107,1111,1118,1149,1152,1189,1192,1204,1209,1292,1390,1397,1400,1404,1452,1455,1459,1470,1477,1645,1660,1696,1714,1717,1726,1760,1770,2430,2454,2539,2548],[283,284],"div",{"hidden":9,"dataTitleIcon":285},"cli",[287,288],"external-badges",{"package-url":289,"registry":290,"repo":285},"https:\u002F\u002Fwww.npmjs.com\u002Fpackage\u002F@configdirector\u002Fcli","npm",[292,293,5],"h2",{"id":294},"introduction",[296,297,298,299,307],"note",{},"The CLI is in beta. Commands and their output may change before 1.0, and the ",[300,301,306],"a",{"href":302,"rel":303,"target":305},"https:\u002F\u002Fgithub.com\u002FConfigDirector\u002Fcli\u002Fblob\u002Fmain\u002FCHANGELOG.md",[304],"noopener","_blank","changelog"," lists every change.",[309,310,311,315],"p",{},[312,313,314],"code",{},"configdirector"," checks your code against your ConfigDirector project, on your machine or as a CI step. The beta has two commands for a repository:",[317,318,319,326],"ul",{},[320,321,322,325],"li",{},[312,323,324],{},"configdirector scan"," lists every place your code reads a config key through a ConfigDirector SDK or OpenFeature provider, with the file and line.",[320,327,328,331],{},[312,329,330],{},"configdirector validate"," checks those keys against the project's configs, and fails the build when the code reads a key no config has, the old key of a renamed config, a config as the wrong type, a config that is not served to that kind of SDK, or an enum value the config does not allow.",[309,333,334],{},"Both commands only read from ConfigDirector. They never change a config.",[309,336,337,338,341,342,345,346,349,350,353],{},"If you have used LaunchDarkly's ",[312,339,340],{},"ld-find-code-refs"," or ConfigCat's ",[312,343,344],{},"configcat scan",": those tools search your code for the keys your flags already have. ",[312,347,348],{},"scan"," also lists the SDK calls whose key no config has, which is how ",[312,351,352],{},"validate"," catches a misspelled key before it ships. A key held in a constant is found too, with nothing to configure.",[292,355,357],{"id":356},"install","Install",[309,359,360],{},"The CLI needs Node.js 20 or later. Install it globally:",[362,363,368],"pre",{"className":364,"code":365,"language":366,"meta":367,"style":367},"language-bash shiki shiki-themes material-theme-lighter github-light github-dark","npm install -g @configdirector\u002Fcli@beta\nconfigdirector --version\n","bash","",[312,369,370,389],{"__ignoreMap":367},[371,372,375,378,382,386],"span",{"class":373,"line":374},"line",1,[371,376,290],{"class":377},"sbgvK",[371,379,381],{"class":380},"s_sjI"," install",[371,383,385],{"class":384},"stzsN"," -g",[371,387,388],{"class":380}," @configdirector\u002Fcli@beta\n",[371,390,392,394],{"class":373,"line":391},2,[371,393,314],{"class":377},[371,395,396],{"class":384}," --version\n",[309,398,399,400,403,404,406,407,411],{},"Or run it without installing by writing ",[312,401,402],{},"npx @configdirector\u002Fcli@beta"," in place of ",[312,405,314],{},", as the ",[300,408,410],{"href":409},"#run-it-in-ci","CI examples"," do:",[362,413,415],{"className":364,"code":414,"language":366,"meta":367,"style":367},"npx @configdirector\u002Fcli@beta --version\n",[312,416,417],{"__ignoreMap":367},[371,418,419,422,425],{"class":373,"line":374},[371,420,421],{"class":377},"npx",[371,423,424],{"class":380}," @configdirector\u002Fcli@beta",[371,426,396],{"class":384},[309,428,429,432,433,436],{},[312,430,431],{},"@beta"," gets the newest beta. To upgrade on your own schedule, replace ",[312,434,435],{},"beta"," with a version number from the changelog.",[292,438,440],{"id":439},"create-an-api-token","Create an API token",[309,442,443,444,446],{},"The CLI reads your projects and configs through the ",[300,445,258],{"href":259},", with an API token.",[448,449,450,458,469],"ol",{},[320,451,452,453,457],{},"In the ConfigDirector dashboard, open ",[454,455,456],"strong",{},"API tokens"," and create a token.",[320,459,460,461,464,465,468],{},"Choose ",[312,462,463],{},"Projects: Read"," and ",[312,466,467],{},"Configs: Read",". They are all the CLI needs, and a token with only these permissions cannot change anything.",[320,470,471],{},"Set an expiration on a token you keep on your workstation, and do not commit a token into source control.",[309,473,474,475,478],{},"A token belongs to the member who created it, and it stops working when that member leaves the organization. For CI, create a token used only by CI rather than reusing the one on your workstation, so you can replace or revoke it without affecting anything else. If its creator leaves, CI fails with ",[312,476,477],{},"API_TOKEN_OWNER_REMOVED"," until another member creates a new one.",[292,480,482],{"id":481},"configure","Configure",[484,485,487],"h3",{"id":486},"sign-in-on-your-machine","Sign in on your machine",[362,489,491],{"className":364,"code":490,"language":366,"meta":367,"style":367},"configdirector login\n",[312,492,493],{"__ignoreMap":367},[371,494,495,497],{"class":373,"line":374},[371,496,314],{"class":377},[371,498,499],{"class":380}," login\n",[309,501,502,505],{},[312,503,504],{},"login"," asks you to paste the token and hides it while you do. It checks that the token can list your projects, then saves it where only your user can read it:",[507,508,509,522],"table",{},[510,511,512],"thead",{},[513,514,515,519],"tr",{},[516,517,518],"th",{},"System",[516,520,521],{},"Saved in",[523,524,525,536,546],"tbody",{},[513,526,527,531],{},[528,529,530],"td",{},"macOS",[528,532,533],{},[312,534,535],{},"~\u002FLibrary\u002FApplication Support\u002Fconfigdirector\u002Fconfig.json",[513,537,538,541],{},[528,539,540],{},"Linux",[528,542,543],{},[312,544,545],{},"~\u002F.config\u002Fconfigdirector\u002Fconfig.json",[513,547,548,551],{},[528,549,550],{},"Windows",[528,552,553],{},[312,554,555],{},"%APPDATA%\\configdirector\\config.json",[309,557,558,559,562,563,566,567,570,571,573],{},"When ",[312,560,561],{},"XDG_CONFIG_HOME"," is set, the token is saved in ",[312,564,565],{},"$XDG_CONFIG_HOME\u002Fconfigdirector\u002Fconfig.json"," instead. ",[312,568,569],{},"configdirector login --token \u003Ctoken>"," saves a token without asking, and running ",[312,572,504],{}," again replaces the saved token.",[309,575,576,577,579,580,583,584,587,588,590,591,593],{},"In CI, skip ",[312,578,504],{}," and set ",[312,581,582],{},"CONFIGDIRECTOR_TOKEN",". The CLI uses ",[312,585,586],{},"--token"," first, then ",[312,589,582],{},", then the token ",[312,592,504],{}," saved.",[484,595,597],{"id":596},"link-the-repository-to-a-project","Link the repository to a project",[309,599,600,601,604,605,608],{},"From the repository root, with your project's slug, shown as ",[454,602,603],{},"Project slug"," on the project's ",[454,606,607],{},"Project details"," page:",[362,610,612],{"className":364,"code":611,"language":366,"meta":367,"style":367},"configdirector init --project web-app\n",[312,613,614],{"__ignoreMap":367},[371,615,616,618,621,624],{"class":373,"line":374},[371,617,314],{"class":377},[371,619,620],{"class":380}," init",[371,622,623],{"class":384}," --project",[371,625,626],{"class":380}," web-app\n",[309,628,629,632,633,636,637,464,639,641],{},[312,630,631],{},"init"," checks that the project exists and writes ",[312,634,635],{},"configdirector.json"," in the current directory. It never overwrites an existing file. Commit the file, so every run and every CI job uses the same project, and run ",[312,638,348],{},[312,640,352],{}," from the directory that holds it.",[362,643,647],{"className":644,"code":645,"filename":635,"language":646,"meta":367,"style":367},"language-json shiki shiki-themes material-theme-lighter github-light github-dark","{\n  \"project\": \"web-app\",\n  \"include\": [\"src\u002F**\"],\n  \"exclude\": [\"src\u002Fgenerated\u002F**\"],\n  \"ignoreKeys\": [\"billing-flag-from-other-project\"]\n}\n","json",[312,648,649,655,683,708,731,755],{"__ignoreMap":367},[371,650,651],{"class":373,"line":374},[371,652,654],{"class":653},"sP7_E","{\n",[371,656,657,661,665,668,671,675,678,680],{"class":373,"line":391},[371,658,660],{"class":659},"s39Yj","  \"",[371,662,664],{"class":663},"sseR_","project",[371,666,667],{"class":659},"\"",[371,669,670],{"class":653},":",[371,672,674],{"class":673},"sjJ54"," \"",[371,676,677],{"class":380},"web-app",[371,679,667],{"class":673},[371,681,682],{"class":653},",\n",[371,684,686,688,691,693,695,698,700,703,705],{"class":373,"line":685},3,[371,687,660],{"class":659},[371,689,690],{"class":663},"include",[371,692,667],{"class":659},[371,694,670],{"class":653},[371,696,697],{"class":653}," [",[371,699,667],{"class":673},[371,701,702],{"class":380},"src\u002F**",[371,704,667],{"class":673},[371,706,707],{"class":653},"],\n",[371,709,711,713,716,718,720,722,724,727,729],{"class":373,"line":710},4,[371,712,660],{"class":659},[371,714,715],{"class":663},"exclude",[371,717,667],{"class":659},[371,719,670],{"class":653},[371,721,697],{"class":653},[371,723,667],{"class":673},[371,725,726],{"class":380},"src\u002Fgenerated\u002F**",[371,728,667],{"class":673},[371,730,707],{"class":653},[371,732,734,736,739,741,743,745,747,750,752],{"class":373,"line":733},5,[371,735,660],{"class":659},[371,737,738],{"class":663},"ignoreKeys",[371,740,667],{"class":659},[371,742,670],{"class":653},[371,744,697],{"class":653},[371,746,667],{"class":673},[371,748,749],{"class":380},"billing-flag-from-other-project",[371,751,667],{"class":673},[371,753,754],{"class":653},"]\n",[371,756,758],{"class":373,"line":757},6,[371,759,760],{"class":653},"}\n",[507,762,763,773],{},[510,764,765],{},[513,766,767,770],{},[516,768,769],{},"Field",[516,771,772],{},"Meaning",[523,774,775,791,810,824],{},[513,776,777,781],{},[528,778,779],{},[312,780,664],{},[528,782,783,784,464,787,790],{},"The project's slug. ",[312,785,786],{},"--project",[312,788,789],{},"CONFIGDIRECTOR_PROJECT"," take precedence over it.",[513,792,793,797],{},[528,794,795],{},[312,796,690],{},[528,798,799,800,802,803,805,806,809],{},"Globs of the files to scan, relative to ",[312,801,635],{},". ",[312,804,631],{}," writes ",[312,807,808],{},"[\"**\"]",", every file.",[513,811,812,816],{},[528,813,814],{},[312,815,715],{},[528,817,818,819,823],{},"Globs of the files to skip, on top of the files ",[300,820,822],{"href":821},"#what-the-scan-reads","the scan always skips",".",[513,825,826,830],{},[528,827,828],{},[312,829,738],{},[528,831,832,833,835],{},"Keys that ",[312,834,352],{}," never reports, such as the key of a config another project serves.",[484,837,839],{"id":838},"options-and-environment-variables","Options and environment variables",[309,841,842,843,464,846,670],{},"Every command takes these options, as well as ",[312,844,845],{},"--help",[312,847,848],{},"--version",[507,850,851,863],{},[510,852,853],{},[513,854,855,858,861],{},[516,856,857],{},"Option",[516,859,860],{},"Environment variable",[516,862,772],{},[523,864,865,881,905,923],{},[513,866,867,872,876],{},[528,868,869],{},[312,870,871],{},"--token \u003Ctoken>",[528,873,874],{},[312,875,582],{},[528,877,878,879,823],{},"The API token. Without either, the token saved by ",[312,880,504],{},[513,882,883,888,892],{},[528,884,885],{},[312,886,887],{},"--project \u003Cslug>",[528,889,890],{},[312,891,789],{},[528,893,894,895,464,897,899,900,902,903,823],{},"The project's slug. Without either, ",[312,896,348],{},[312,898,352],{}," use the ",[312,901,664],{}," in ",[312,904,635],{},[513,906,907,912,917],{},[528,908,909],{},[312,910,911],{},"--base-url \u003Curl>",[528,913,914],{},[312,915,916],{},"CONFIGDIRECTOR_BASE_URL",[528,918,919,920,823],{},"The Admin API host. Defaults to ",[312,921,922],{},"https:\u002F\u002Fapi.configdirector.com",[513,924,925,930,932],{},[528,926,927],{},[312,928,929],{},"--json",[528,931],{},[528,933,934,935,823],{},"Print JSON instead of text. See ",[300,936,938],{"href":937},"#output","Output",[309,940,941,942,945],{},"An option takes precedence over its environment variable. An empty variable counts as unset, so a CI job whose token secret is missing stops with ",[312,943,944],{},"No API token found"," rather than sending an empty token.",[292,947,948],{"id":348},"Scan",[362,950,952],{"className":364,"code":951,"language":366,"meta":367,"style":367},"configdirector scan\n",[312,953,954],{"__ignoreMap":367},[371,955,956,958],{"class":373,"line":374},[371,957,314],{"class":377},[371,959,960],{"class":380}," scan\n",[309,962,963,965],{},[312,964,348],{}," lists every place your code reads a config key, grouped by key, with the file, the line, the SDK call and the SDK:",[362,967,971],{"className":968,"code":969,"language":970,"meta":367,"style":367},"language-txt shiki shiki-themes material-theme-lighter github-light github-dark","max-cart-items\n  src\u002Fadmin\u002Ffeature-list.ts:1 (indirect)\n  src\u002Fcheckout.ts:6 getValue (js-server)\n\nnew-checkout\n  src\u002Fadmin\u002Ffeature-list.ts:1 (indirect)\n  src\u002Fcheckout.ts:5 getValue(NEW_CHECKOUT) (js-server)\n  test\u002Fcheckout.test.ts:3 createTestClient (js-server, test)\n\nDynamic references (calls whose key is not a string literal)\n  src\u002Fsettings.ts:3 getValue(setting.key) (js-server)\n\n3 direct, 2 indirect and 1 dynamic references in 5 scanned files.\n","txt",[312,972,973,978,983,988,993,998,1002,1008,1014,1019,1025,1031,1036],{"__ignoreMap":367},[371,974,975],{"class":373,"line":374},[371,976,977],{},"max-cart-items\n",[371,979,980],{"class":373,"line":391},[371,981,982],{},"  src\u002Fadmin\u002Ffeature-list.ts:1 (indirect)\n",[371,984,985],{"class":373,"line":685},[371,986,987],{},"  src\u002Fcheckout.ts:6 getValue (js-server)\n",[371,989,990],{"class":373,"line":710},[371,991,992],{"emptyLinePlaceholder":9},"\n",[371,994,995],{"class":373,"line":733},[371,996,997],{},"new-checkout\n",[371,999,1000],{"class":373,"line":757},[371,1001,982],{},[371,1003,1005],{"class":373,"line":1004},7,[371,1006,1007],{},"  src\u002Fcheckout.ts:5 getValue(NEW_CHECKOUT) (js-server)\n",[371,1009,1011],{"class":373,"line":1010},8,[371,1012,1013],{},"  test\u002Fcheckout.test.ts:3 createTestClient (js-server, test)\n",[371,1015,1017],{"class":373,"line":1016},9,[371,1018,992],{"emptyLinePlaceholder":9},[371,1020,1022],{"class":373,"line":1021},10,[371,1023,1024],{},"Dynamic references (calls whose key is not a string literal)\n",[371,1026,1028],{"class":373,"line":1027},11,[371,1029,1030],{},"  src\u002Fsettings.ts:3 getValue(setting.key) (js-server)\n",[371,1032,1034],{"class":373,"line":1033},12,[371,1035,992],{"emptyLinePlaceholder":9},[371,1037,1039],{"class":373,"line":1038},13,[371,1040,1041],{},"3 direct, 2 indirect and 1 dynamic references in 5 scanned files.\n",[309,1043,1044],{},"Each place is one of three kinds of code reference:",[317,1046,1047,1064,1073],{},[320,1048,1049,1052,1053,1056,1057,1060,1061,1063],{},[454,1050,1051],{},"Direct",": an SDK call whose key is known, either a string such as ",[312,1054,1055],{},"getValue(\"max-cart-items\", 20)"," or a constant that holds one, shown after the call as ",[312,1058,1059],{},"getValue(NEW_CHECKOUT)",". These are the references ",[312,1062,352],{}," checks.",[320,1065,1066,1069,1070,1072],{},[454,1067,1068],{},"Indirect",": one of the project's keys written as a quoted string anywhere else, such as a list of keys, the argument of your own wrapper function, or a test fixture. The key is used there, but not through a call ",[312,1071,352],{}," can check, so look at these before you rename or archive the config.",[320,1074,1075,1078],{},[454,1076,1077],{},"Dynamic",": an SDK call whose key cannot be known from the code, such as a variable, a key built at runtime, or a constant assigned a different string in two places. These are listed so you know they exist. They are never checked, so they never fail the build; to have one checked, pass the key as a string or a constant.",[309,1080,1081,1082,1085,1086,1089,1090,1093,1094,823],{},"A reference is marked ",[312,1083,1084],{},"test"," when it is a call to an SDK test client, such as ",[312,1087,1088],{},"createTestClient"," or ",[312,1091,1092],{},"setValue",", or an indirect reference in a test directory or a test file such as ",[312,1095,1096],{},"checkout.test.ts",[309,1098,1099,1100,1103,1104,823],{},"The scan exits with 0 whenever it ran, whether it found references or not. ",[312,1101,1102],{},"configdirector scan src"," scans only ",[312,1105,1106],{},"src",[484,1108,1110],{"id":1109},"what-the-scan-reads","What the scan reads",[309,1112,1113,1114,1117],{},"A call is found when its file imports a ConfigDirector SDK or the OpenFeature SDK. In JavaScript, TypeScript, Python, Dart and Go, it is also found when the file imports one of your own files that does, such as the setup module the SDK pages create. In Swift and Go, it is enough for another file of the same target or package to import the SDK, and Nuxt's auto-imported composables need no import. A ",[312,1115,1116],{},"getValue"," from another library in a file that imports none of these is not reported.",[309,1119,1120,1121,1124,1125,1128,1129,1128,1132,1128,1135,464,1138,1141,1142,464,1144,902,1146,1148],{},"The scan skips the files ",[312,1122,1123],{},".gitignore"," ignores, the ",[312,1126,1127],{},"node_modules",", ",[312,1130,1131],{},"vendor",[312,1133,1134],{},"build",[312,1136,1137],{},"dist",[312,1139,1140],{},"target"," directories, binary files, and files over 1 MB. ",[312,1143,690],{},[312,1145,715],{},[312,1147,635],{}," narrow it further.",[309,1150,1151],{},"If a call you expected is missing, the file most likely reaches the SDK client in one of these ways:",[317,1153,1154,1160,1176,1182],{},[320,1155,1156,1157,823],{},"Through two of your own files, such as a module that imports the setup module and passes the client on. Import the setup module directly, or have the module in between re-export the client with ",[312,1158,1159],{},"export { client } from \".\u002Fsetup\"",[320,1161,1162,1163,902,1166,1169,1170,902,1173,823],{},"Through a path alias that only your bundler knows, such as ",[312,1164,1165],{},"resolve.alias",[312,1167,1168],{},"vite.config.ts",". Add the alias to ",[312,1171,1172],{},"compilerOptions.paths",[312,1174,1175],{},"tsconfig.json",[320,1177,1178,1179,823],{},"Through a CommonJS re-export, such as ",[312,1180,1181],{},"module.exports = require(\".\u002Fsetup\")",[320,1183,1184,1185,1188],{},"In Kotlin, Java or C#, through a class of your own, in a file that never names the SDK. Declare the client with its SDK type, such as a ",[312,1186,1187],{},"ConfigDirectorClient"," parameter or property, so the file names the SDK.",[292,1190,1191],{"id":352},"Validate",[362,1193,1195],{"className":364,"code":1194,"language":366,"meta":367,"style":367},"configdirector validate\n",[312,1196,1197],{"__ignoreMap":367},[371,1198,1199,1201],{"class":373,"line":374},[371,1200,314],{"class":377},[371,1202,1203],{"class":380}," validate\n",[309,1205,1206,1208],{},[312,1207,352],{}," runs the same scan, then checks every direct reference against the project's configs. It lists the problems it found by kind, and exits with 1 when there is at least one:",[362,1210,1212],{"className":968,"code":1211,"language":970,"meta":367,"style":367},"Unknown keys\n  src\u002Fcheckout.ts:9 free-shiping: no config in web-app has this key.\n\nDeprecated keys\n  src\u002Fcheckout.ts:6 checkout-v2: the config was renamed to new-checkout.\n\nType mismatches\n  src\u002Fcheckout.ts:8 checkout-timeout: read as string, but the config's type is timespan, served as a float.\n\nAvailability mismatches\n  src\u002Ftheme.tsx:4 fraud-threshold: read from a client SDK (react), but the config is server-only.\n\nEnum values not allowed\n  src\u002Ftheme.tsx:3 theme: \"system\" is not one of the allowed values: light, dark.\n\nChecked 7 direct references in 4 scanned files and found 5 problems. 1 dynamic reference was not checked.\n",[312,1213,1214,1219,1224,1228,1233,1238,1242,1247,1252,1256,1261,1266,1270,1275,1281,1286],{"__ignoreMap":367},[371,1215,1216],{"class":373,"line":374},[371,1217,1218],{},"Unknown keys\n",[371,1220,1221],{"class":373,"line":391},[371,1222,1223],{},"  src\u002Fcheckout.ts:9 free-shiping: no config in web-app has this key.\n",[371,1225,1226],{"class":373,"line":685},[371,1227,992],{"emptyLinePlaceholder":9},[371,1229,1230],{"class":373,"line":710},[371,1231,1232],{},"Deprecated keys\n",[371,1234,1235],{"class":373,"line":733},[371,1236,1237],{},"  src\u002Fcheckout.ts:6 checkout-v2: the config was renamed to new-checkout.\n",[371,1239,1240],{"class":373,"line":757},[371,1241,992],{"emptyLinePlaceholder":9},[371,1243,1244],{"class":373,"line":1004},[371,1245,1246],{},"Type mismatches\n",[371,1248,1249],{"class":373,"line":1010},[371,1250,1251],{},"  src\u002Fcheckout.ts:8 checkout-timeout: read as string, but the config's type is timespan, served as a float.\n",[371,1253,1254],{"class":373,"line":1016},[371,1255,992],{"emptyLinePlaceholder":9},[371,1257,1258],{"class":373,"line":1021},[371,1259,1260],{},"Availability mismatches\n",[371,1262,1263],{"class":373,"line":1027},[371,1264,1265],{},"  src\u002Ftheme.tsx:4 fraud-threshold: read from a client SDK (react), but the config is server-only.\n",[371,1267,1268],{"class":373,"line":1033},[371,1269,992],{"emptyLinePlaceholder":9},[371,1271,1272],{"class":373,"line":1038},[371,1273,1274],{},"Enum values not allowed\n",[371,1276,1278],{"class":373,"line":1277},14,[371,1279,1280],{},"  src\u002Ftheme.tsx:3 theme: \"system\" is not one of the allowed values: light, dark.\n",[371,1282,1284],{"class":373,"line":1283},15,[371,1285,992],{"emptyLinePlaceholder":9},[371,1287,1289],{"class":373,"line":1288},16,[371,1290,1291],{},"Checked 7 direct references in 4 scanned files and found 5 problems. 1 dynamic reference was not checked.\n",[507,1293,1294,1307],{},[510,1295,1296],{},[513,1297,1298,1301,1304],{},[516,1299,1300],{},"Problem",[516,1302,1303],{},"What it means for your app",[516,1305,1306],{},"What to do",[523,1308,1309,1324,1342,1359,1377],{},[513,1310,1311,1316,1319],{},[528,1312,1313],{},[454,1314,1315],{},"Unknown keys",[528,1317,1318],{},"No config in the project has this key, as its current key or an old one, so the SDK returns the in-code default value every time. The key of an archived config is unknown too.",[528,1320,1321,1322,823],{},"Correct the key, or create the config. If another project serves the key, add it to ",[312,1323,738],{},[513,1325,1326,1331,1339],{},[528,1327,1328],{},[454,1329,1330],{},"Deprecated keys",[528,1332,1333,1334,1338],{},"The config was renamed, and the code still reads an old key. The old key works until ConfigDirector removes it once it is no longer used, as ",[300,1335,1337],{"href":1336},"\u002Fgetting-started\u002Fconfigs#key","Key"," explains.",[528,1340,1341],{},"Replace it with the current key, which the output names.",[513,1343,1344,1349,1356],{},[528,1345,1346],{},[454,1347,1348],{},"Type mismatches",[528,1350,1351,1352,1355],{},"The in-code default value, or a getter whose name sets the type such as ",[312,1353,1354],{},"getBoolean",", reads the config as a type the SDKs do not serve it as, so the SDK can return the in-code default value instead of the config's value.",[528,1357,1358],{},"Read the config as the type the output names.",[513,1360,1361,1366,1369],{},[528,1362,1363],{},[454,1364,1365],{},"Availability mismatches",[528,1367,1368],{},"A client SDK reads a server-only config, or a server SDK reads a client-only one. That SDK never receives the config, so it returns the in-code default value every time.",[528,1370,1371,1372,1376],{},"Change the config's ",[300,1373,1375],{"href":1374},"\u002Fgetting-started\u002Fconfigs#sdk-availability","SDK availability",", or read the config where it is served.",[513,1378,1379,1384,1387],{},[528,1380,1381],{},[454,1382,1383],{},"Enum values not allowed",[528,1385,1386],{},"The in-code default value is not one of the enum's allowed values.",[528,1388,1389],{},"Use an allowed value as the in-code default value, or add the value to the enum.",[309,1391,1392,1393,1396],{},"The SDKs serve a timespan as a number in its unit and a URL as a string. So an in-code default value, or a getter whose name sets the type, reads a config of these types: a boolean reads a boolean config; an integer reads an integer, float or timespan config; a decimal number reads a float or timespan config; a string reads a string, enum or URL config; and an object or array reads a JSON config. Read a timespan with a number, not a string such as ",[312,1394,1395],{},"\"30s\"",". An enum whose values are numbers can also be read with a number.",[309,1398,1399],{},"A test client call is checked for unknown and deprecated keys only, since ConfigDirector never serves a test client. Indirect and dynamic references are never checked, and a config's lifecycle state is never a problem.",[484,1401,1403],{"id":1402},"exit-codes","Exit codes",[507,1405,1406,1415],{},[510,1407,1408],{},[513,1409,1410,1413],{},[516,1411,1412],{},"Code",[516,1414,772],{},[523,1416,1417,1430,1442],{},[513,1418,1419,1424],{},[528,1420,1421],{},[312,1422,1423],{},"0",[528,1425,1426,1427,1429],{},"The command succeeded. For ",[312,1428,352],{},", it found no problem.",[513,1431,1432,1437],{},[528,1433,1434],{},[312,1435,1436],{},"1",[528,1438,1439,1441],{},[312,1440,352],{}," found at least one problem.",[513,1443,1444,1449],{},[528,1445,1446],{},[312,1447,1448],{},"2",[528,1450,1451],{},"The command could not run: a mistake in the command, no token or a rejected one, a missing permission, a suspended service, or an unreachable API. The message says which.",[309,1453,1454],{},"A CI job can therefore tell a wrong config key from an outage.",[484,1456,1458],{"id":1457},"run-it-in-ci","Run it in CI",[309,1460,1461,1462,1464,1465,1467,1468,823],{},"Add the token as a secret named ",[312,1463,582],{},", then run ",[312,1466,352],{}," with ",[312,1469,421],{},[309,1471,1472,1473,1476],{},"On GitHub, add the secret under the repository's ",[454,1474,1475],{},"Settings → Secrets and variables → Actions",", and add this workflow, or its last step to an existing job:",[362,1478,1483],{"className":1479,"code":1480,"filename":1481,"language":1482,"meta":367,"style":367},"language-yaml shiki shiki-themes material-theme-lighter github-light github-dark","name: ConfigDirector\n\non:\n  pull_request:\n  push:\n    branches: [main]\n\njobs:\n  validate:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions\u002Fcheckout@v5\n      - uses: actions\u002Fsetup-node@v6\n        with:\n          node-version: 24\n      - run: npx --yes @configdirector\u002Fcli@beta validate\n        env:\n          CONFIGDIRECTOR_TOKEN: ${{ secrets.CONFIGDIRECTOR_TOKEN }}\n",".github\u002Fworkflows\u002Fconfigdirector.yml","yaml",[312,1484,1485,1496,1500,1509,1516,1523,1537,1541,1548,1555,1565,1572,1585,1596,1603,1614,1626,1634],{"__ignoreMap":367},[371,1486,1487,1491,1493],{"class":373,"line":374},[371,1488,1490],{"class":1489},"sQzsp","name",[371,1492,670],{"class":653},[371,1494,1495],{"class":380}," ConfigDirector\n",[371,1497,1498],{"class":373,"line":391},[371,1499,992],{"emptyLinePlaceholder":9},[371,1501,1502,1506],{"class":373,"line":685},[371,1503,1505],{"class":1504},"syTEX","on",[371,1507,1508],{"class":653},":\n",[371,1510,1511,1514],{"class":373,"line":710},[371,1512,1513],{"class":1489},"  pull_request",[371,1515,1508],{"class":653},[371,1517,1518,1521],{"class":373,"line":733},[371,1519,1520],{"class":1489},"  push",[371,1522,1508],{"class":653},[371,1524,1525,1528,1530,1532,1535],{"class":373,"line":757},[371,1526,1527],{"class":1489},"    branches",[371,1529,670],{"class":653},[371,1531,697],{"class":653},[371,1533,1534],{"class":380},"main",[371,1536,754],{"class":653},[371,1538,1539],{"class":373,"line":1004},[371,1540,992],{"emptyLinePlaceholder":9},[371,1542,1543,1546],{"class":373,"line":1010},[371,1544,1545],{"class":1489},"jobs",[371,1547,1508],{"class":653},[371,1549,1550,1553],{"class":373,"line":1016},[371,1551,1552],{"class":1489},"  validate",[371,1554,1508],{"class":653},[371,1556,1557,1560,1562],{"class":373,"line":1021},[371,1558,1559],{"class":1489},"    runs-on",[371,1561,670],{"class":653},[371,1563,1564],{"class":380}," ubuntu-latest\n",[371,1566,1567,1570],{"class":373,"line":1027},[371,1568,1569],{"class":1489},"    steps",[371,1571,1508],{"class":653},[371,1573,1574,1577,1580,1582],{"class":373,"line":1033},[371,1575,1576],{"class":653},"      -",[371,1578,1579],{"class":1489}," uses",[371,1581,670],{"class":653},[371,1583,1584],{"class":380}," actions\u002Fcheckout@v5\n",[371,1586,1587,1589,1591,1593],{"class":373,"line":1038},[371,1588,1576],{"class":653},[371,1590,1579],{"class":1489},[371,1592,670],{"class":653},[371,1594,1595],{"class":380}," actions\u002Fsetup-node@v6\n",[371,1597,1598,1601],{"class":373,"line":1277},[371,1599,1600],{"class":1489},"        with",[371,1602,1508],{"class":653},[371,1604,1605,1608,1610],{"class":373,"line":1283},[371,1606,1607],{"class":1489},"          node-version",[371,1609,670],{"class":653},[371,1611,1613],{"class":1612},"srdBf"," 24\n",[371,1615,1616,1618,1621,1623],{"class":373,"line":1288},[371,1617,1576],{"class":653},[371,1619,1620],{"class":1489}," run",[371,1622,670],{"class":653},[371,1624,1625],{"class":380}," npx --yes @configdirector\u002Fcli@beta validate\n",[371,1627,1629,1632],{"class":373,"line":1628},17,[371,1630,1631],{"class":1489},"        env",[371,1633,1508],{"class":653},[371,1635,1637,1640,1642],{"class":373,"line":1636},18,[371,1638,1639],{"class":1489},"          CONFIGDIRECTOR_TOKEN",[371,1641,670],{"class":653},[371,1643,1644],{"class":380}," ${{ secrets.CONFIGDIRECTOR_TOKEN }}\n",[309,1646,1647,1648,1651,1652,1655,1656,1659],{},"On GitLab, add the token as a masked variable under the project's ",[454,1649,1650],{},"Settings → CI\u002FCD → Variables",", which GitLab passes to every job as an environment variable, and add this job to ",[312,1653,1654],{},".gitlab-ci.yml",". A variable marked ",[454,1657,1658],{},"Protect variable"," reaches only pipelines of protected branches and tags, so leave it unmarked for the check to run on merge requests.",[362,1661,1663],{"className":1479,"code":1662,"filename":1654,"language":1482,"meta":367,"style":367},"configdirector-validate:\n  image: node:24\n  script:\n    - npx --yes @configdirector\u002Fcli@beta validate\n",[312,1664,1665,1672,1682,1689],{"__ignoreMap":367},[371,1666,1667,1670],{"class":373,"line":374},[371,1668,1669],{"class":1489},"configdirector-validate",[371,1671,1508],{"class":653},[371,1673,1674,1677,1679],{"class":373,"line":391},[371,1675,1676],{"class":1489},"  image",[371,1678,670],{"class":653},[371,1680,1681],{"class":380}," node:24\n",[371,1683,1684,1687],{"class":373,"line":685},[371,1685,1686],{"class":1489},"  script",[371,1688,1508],{"class":653},[371,1690,1691,1694],{"class":373,"line":710},[371,1692,1693],{"class":653},"    -",[371,1695,1625],{"class":380},[309,1697,1698,1699,1089,1701,1703,1704,464,1706,1708,1709,1713],{},"Each ",[312,1700,348],{},[312,1702,352],{}," run makes two Admin API requests, and ",[312,1705,504],{},[312,1707,631],{}," make one each. They count toward your organization's monthly ",[300,1710,1712],{"href":1711},"\u002Fgetting-started\u002Fpricing-and-billing#the-free-allowance","free allowance"," like any other Admin API request.",[292,1715,938],{"id":1716},"output",[309,1718,1719,1720,1722,1723,1725],{},"Every command prints text for people by default. With ",[312,1721,929],{},", it prints JSON instead, for scripts and CI. Errors and the token prompt go to stderr, so with ",[312,1724,929],{}," the JSON is all that reaches stdout:",[362,1727,1729],{"className":364,"code":1728,"language":366,"meta":367,"style":367},"configdirector scan --json | jq -r '.references[] | select(.key == \"new-checkout\") | \"\\(.file):\\(.line)\"'\n",[312,1730,1731],{"__ignoreMap":367},[371,1732,1733,1735,1738,1741,1745,1748,1751,1754,1757],{"class":373,"line":374},[371,1734,314],{"class":377},[371,1736,1737],{"class":380}," scan",[371,1739,1740],{"class":384}," --json",[371,1742,1744],{"class":1743},"smGrS"," |",[371,1746,1747],{"class":377}," jq",[371,1749,1750],{"class":384}," -r",[371,1752,1753],{"class":673}," '",[371,1755,1756],{"class":380},".references[] | select(.key == \"new-checkout\") | \"\\(.file):\\(.line)\"",[371,1758,1759],{"class":673},"'\n",[309,1761,1762,1765,1766,1769],{},[312,1763,1764],{},"validate --json"," prints the scan's JSON with a ",[312,1767,1768],{},"findings"," array, and still exits with 1 when the array is not empty. Shortened to one reference of each kind and one finding:",[362,1771,1773],{"className":644,"code":1772,"language":646,"meta":367,"style":367},"{\n  \"project\": \"web-app\",\n  \"filesScanned\": 4,\n  \"references\": [\n    {\n      \"key\": \"new-checkout\",\n      \"file\": \"src\u002Fcheckout.ts\",\n      \"line\": 5,\n      \"kind\": \"direct\",\n      \"sdk\": \"js-server\",\n      \"call\": \"getValue\",\n      \"argument\": \"NEW_CHECKOUT\",\n      \"default\": { \"type\": \"boolean\", \"value\": false },\n      \"test\": false\n    },\n    {\n      \"key\": \"new-checkout\",\n      \"file\": \"src\u002Fflags.ts\",\n      \"line\": 1,\n      \"kind\": \"indirect\",\n      \"test\": false\n    }\n  ],\n  \"dynamicReferences\": [\n    {\n      \"file\": \"src\u002Ftheme.tsx\",\n      \"line\": 5,\n      \"sdk\": \"react\",\n      \"call\": \"useConfigValue\",\n      \"argument\": \"setting.key\"\n    }\n  ],\n  \"findings\": [\n    {\n      \"kind\": \"availability-mismatch\",\n      \"key\": \"fraud-threshold\",\n      \"file\": \"src\u002Ftheme.tsx\",\n      \"line\": 4,\n      \"sdk\": \"react\",\n      \"sdkType\": \"client\",\n      \"configAvailableTo\": [\"server\"]\n    }\n  ]\n}\n",[312,1774,1775,1779,1797,1813,1827,1832,1854,1874,1889,1909,1929,1948,1968,2016,2029,2034,2038,2056,2075,2091,2111,2124,2130,2136,2150,2155,2175,2190,2210,2230,2249,2254,2259,2272,2277,2297,2317,2336,2351,2370,2391,2414,2419,2425],{"__ignoreMap":367},[371,1776,1777],{"class":373,"line":374},[371,1778,654],{"class":653},[371,1780,1781,1783,1785,1787,1789,1791,1793,1795],{"class":373,"line":391},[371,1782,660],{"class":659},[371,1784,664],{"class":663},[371,1786,667],{"class":659},[371,1788,670],{"class":653},[371,1790,674],{"class":673},[371,1792,677],{"class":380},[371,1794,667],{"class":673},[371,1796,682],{"class":653},[371,1798,1799,1801,1804,1806,1808,1811],{"class":373,"line":685},[371,1800,660],{"class":659},[371,1802,1803],{"class":663},"filesScanned",[371,1805,667],{"class":659},[371,1807,670],{"class":653},[371,1809,1810],{"class":1612}," 4",[371,1812,682],{"class":653},[371,1814,1815,1817,1820,1822,1824],{"class":373,"line":710},[371,1816,660],{"class":659},[371,1818,1819],{"class":663},"references",[371,1821,667],{"class":659},[371,1823,670],{"class":653},[371,1825,1826],{"class":653}," [\n",[371,1828,1829],{"class":373,"line":733},[371,1830,1831],{"class":653},"    {\n",[371,1833,1834,1837,1841,1843,1845,1847,1850,1852],{"class":373,"line":757},[371,1835,1836],{"class":659},"      \"",[371,1838,1840],{"class":1839},"sZMiF","key",[371,1842,667],{"class":659},[371,1844,670],{"class":653},[371,1846,674],{"class":673},[371,1848,1849],{"class":380},"new-checkout",[371,1851,667],{"class":673},[371,1853,682],{"class":653},[371,1855,1856,1858,1861,1863,1865,1867,1870,1872],{"class":373,"line":1004},[371,1857,1836],{"class":659},[371,1859,1860],{"class":1839},"file",[371,1862,667],{"class":659},[371,1864,670],{"class":653},[371,1866,674],{"class":673},[371,1868,1869],{"class":380},"src\u002Fcheckout.ts",[371,1871,667],{"class":673},[371,1873,682],{"class":653},[371,1875,1876,1878,1880,1882,1884,1887],{"class":373,"line":1010},[371,1877,1836],{"class":659},[371,1879,373],{"class":1839},[371,1881,667],{"class":659},[371,1883,670],{"class":653},[371,1885,1886],{"class":1612}," 5",[371,1888,682],{"class":653},[371,1890,1891,1893,1896,1898,1900,1902,1905,1907],{"class":373,"line":1016},[371,1892,1836],{"class":659},[371,1894,1895],{"class":1839},"kind",[371,1897,667],{"class":659},[371,1899,670],{"class":653},[371,1901,674],{"class":673},[371,1903,1904],{"class":380},"direct",[371,1906,667],{"class":673},[371,1908,682],{"class":653},[371,1910,1911,1913,1916,1918,1920,1922,1925,1927],{"class":373,"line":1021},[371,1912,1836],{"class":659},[371,1914,1915],{"class":1839},"sdk",[371,1917,667],{"class":659},[371,1919,670],{"class":653},[371,1921,674],{"class":673},[371,1923,1924],{"class":380},"js-server",[371,1926,667],{"class":673},[371,1928,682],{"class":653},[371,1930,1931,1933,1936,1938,1940,1942,1944,1946],{"class":373,"line":1027},[371,1932,1836],{"class":659},[371,1934,1935],{"class":1839},"call",[371,1937,667],{"class":659},[371,1939,670],{"class":653},[371,1941,674],{"class":673},[371,1943,1116],{"class":380},[371,1945,667],{"class":673},[371,1947,682],{"class":653},[371,1949,1950,1952,1955,1957,1959,1961,1964,1966],{"class":373,"line":1033},[371,1951,1836],{"class":659},[371,1953,1954],{"class":1839},"argument",[371,1956,667],{"class":659},[371,1958,670],{"class":653},[371,1960,674],{"class":673},[371,1962,1963],{"class":380},"NEW_CHECKOUT",[371,1965,667],{"class":673},[371,1967,682],{"class":653},[371,1969,1970,1972,1975,1977,1979,1982,1984,1987,1989,1991,1993,1996,1998,2001,2003,2006,2008,2010,2013],{"class":373,"line":1038},[371,1971,1836],{"class":659},[371,1973,1974],{"class":1839},"default",[371,1976,667],{"class":659},[371,1978,670],{"class":653},[371,1980,1981],{"class":653}," {",[371,1983,674],{"class":659},[371,1985,1986],{"class":1612},"type",[371,1988,667],{"class":659},[371,1990,670],{"class":653},[371,1992,674],{"class":673},[371,1994,1995],{"class":380},"boolean",[371,1997,667],{"class":673},[371,1999,2000],{"class":653},",",[371,2002,674],{"class":659},[371,2004,2005],{"class":1612},"value",[371,2007,667],{"class":659},[371,2009,670],{"class":653},[371,2011,2012],{"class":659}," false",[371,2014,2015],{"class":653}," },\n",[371,2017,2018,2020,2022,2024,2026],{"class":373,"line":1277},[371,2019,1836],{"class":659},[371,2021,1084],{"class":1839},[371,2023,667],{"class":659},[371,2025,670],{"class":653},[371,2027,2028],{"class":659}," false\n",[371,2030,2031],{"class":373,"line":1283},[371,2032,2033],{"class":653},"    },\n",[371,2035,2036],{"class":373,"line":1288},[371,2037,1831],{"class":653},[371,2039,2040,2042,2044,2046,2048,2050,2052,2054],{"class":373,"line":1628},[371,2041,1836],{"class":659},[371,2043,1840],{"class":1839},[371,2045,667],{"class":659},[371,2047,670],{"class":653},[371,2049,674],{"class":673},[371,2051,1849],{"class":380},[371,2053,667],{"class":673},[371,2055,682],{"class":653},[371,2057,2058,2060,2062,2064,2066,2068,2071,2073],{"class":373,"line":1636},[371,2059,1836],{"class":659},[371,2061,1860],{"class":1839},[371,2063,667],{"class":659},[371,2065,670],{"class":653},[371,2067,674],{"class":673},[371,2069,2070],{"class":380},"src\u002Fflags.ts",[371,2072,667],{"class":673},[371,2074,682],{"class":653},[371,2076,2078,2080,2082,2084,2086,2089],{"class":373,"line":2077},19,[371,2079,1836],{"class":659},[371,2081,373],{"class":1839},[371,2083,667],{"class":659},[371,2085,670],{"class":653},[371,2087,2088],{"class":1612}," 1",[371,2090,682],{"class":653},[371,2092,2094,2096,2098,2100,2102,2104,2107,2109],{"class":373,"line":2093},20,[371,2095,1836],{"class":659},[371,2097,1895],{"class":1839},[371,2099,667],{"class":659},[371,2101,670],{"class":653},[371,2103,674],{"class":673},[371,2105,2106],{"class":380},"indirect",[371,2108,667],{"class":673},[371,2110,682],{"class":653},[371,2112,2114,2116,2118,2120,2122],{"class":373,"line":2113},21,[371,2115,1836],{"class":659},[371,2117,1084],{"class":1839},[371,2119,667],{"class":659},[371,2121,670],{"class":653},[371,2123,2028],{"class":659},[371,2125,2127],{"class":373,"line":2126},22,[371,2128,2129],{"class":653},"    }\n",[371,2131,2133],{"class":373,"line":2132},23,[371,2134,2135],{"class":653},"  ],\n",[371,2137,2139,2141,2144,2146,2148],{"class":373,"line":2138},24,[371,2140,660],{"class":659},[371,2142,2143],{"class":663},"dynamicReferences",[371,2145,667],{"class":659},[371,2147,670],{"class":653},[371,2149,1826],{"class":653},[371,2151,2153],{"class":373,"line":2152},25,[371,2154,1831],{"class":653},[371,2156,2158,2160,2162,2164,2166,2168,2171,2173],{"class":373,"line":2157},26,[371,2159,1836],{"class":659},[371,2161,1860],{"class":1839},[371,2163,667],{"class":659},[371,2165,670],{"class":653},[371,2167,674],{"class":673},[371,2169,2170],{"class":380},"src\u002Ftheme.tsx",[371,2172,667],{"class":673},[371,2174,682],{"class":653},[371,2176,2178,2180,2182,2184,2186,2188],{"class":373,"line":2177},27,[371,2179,1836],{"class":659},[371,2181,373],{"class":1839},[371,2183,667],{"class":659},[371,2185,670],{"class":653},[371,2187,1886],{"class":1612},[371,2189,682],{"class":653},[371,2191,2193,2195,2197,2199,2201,2203,2206,2208],{"class":373,"line":2192},28,[371,2194,1836],{"class":659},[371,2196,1915],{"class":1839},[371,2198,667],{"class":659},[371,2200,670],{"class":653},[371,2202,674],{"class":673},[371,2204,2205],{"class":380},"react",[371,2207,667],{"class":673},[371,2209,682],{"class":653},[371,2211,2213,2215,2217,2219,2221,2223,2226,2228],{"class":373,"line":2212},29,[371,2214,1836],{"class":659},[371,2216,1935],{"class":1839},[371,2218,667],{"class":659},[371,2220,670],{"class":653},[371,2222,674],{"class":673},[371,2224,2225],{"class":380},"useConfigValue",[371,2227,667],{"class":673},[371,2229,682],{"class":653},[371,2231,2233,2235,2237,2239,2241,2243,2246],{"class":373,"line":2232},30,[371,2234,1836],{"class":659},[371,2236,1954],{"class":1839},[371,2238,667],{"class":659},[371,2240,670],{"class":653},[371,2242,674],{"class":673},[371,2244,2245],{"class":380},"setting.key",[371,2247,2248],{"class":673},"\"\n",[371,2250,2252],{"class":373,"line":2251},31,[371,2253,2129],{"class":653},[371,2255,2257],{"class":373,"line":2256},32,[371,2258,2135],{"class":653},[371,2260,2262,2264,2266,2268,2270],{"class":373,"line":2261},33,[371,2263,660],{"class":659},[371,2265,1768],{"class":663},[371,2267,667],{"class":659},[371,2269,670],{"class":653},[371,2271,1826],{"class":653},[371,2273,2275],{"class":373,"line":2274},34,[371,2276,1831],{"class":653},[371,2278,2280,2282,2284,2286,2288,2290,2293,2295],{"class":373,"line":2279},35,[371,2281,1836],{"class":659},[371,2283,1895],{"class":1839},[371,2285,667],{"class":659},[371,2287,670],{"class":653},[371,2289,674],{"class":673},[371,2291,2292],{"class":380},"availability-mismatch",[371,2294,667],{"class":673},[371,2296,682],{"class":653},[371,2298,2300,2302,2304,2306,2308,2310,2313,2315],{"class":373,"line":2299},36,[371,2301,1836],{"class":659},[371,2303,1840],{"class":1839},[371,2305,667],{"class":659},[371,2307,670],{"class":653},[371,2309,674],{"class":673},[371,2311,2312],{"class":380},"fraud-threshold",[371,2314,667],{"class":673},[371,2316,682],{"class":653},[371,2318,2320,2322,2324,2326,2328,2330,2332,2334],{"class":373,"line":2319},37,[371,2321,1836],{"class":659},[371,2323,1860],{"class":1839},[371,2325,667],{"class":659},[371,2327,670],{"class":653},[371,2329,674],{"class":673},[371,2331,2170],{"class":380},[371,2333,667],{"class":673},[371,2335,682],{"class":653},[371,2337,2339,2341,2343,2345,2347,2349],{"class":373,"line":2338},38,[371,2340,1836],{"class":659},[371,2342,373],{"class":1839},[371,2344,667],{"class":659},[371,2346,670],{"class":653},[371,2348,1810],{"class":1612},[371,2350,682],{"class":653},[371,2352,2354,2356,2358,2360,2362,2364,2366,2368],{"class":373,"line":2353},39,[371,2355,1836],{"class":659},[371,2357,1915],{"class":1839},[371,2359,667],{"class":659},[371,2361,670],{"class":653},[371,2363,674],{"class":673},[371,2365,2205],{"class":380},[371,2367,667],{"class":673},[371,2369,682],{"class":653},[371,2371,2373,2375,2378,2380,2382,2384,2387,2389],{"class":373,"line":2372},40,[371,2374,1836],{"class":659},[371,2376,2377],{"class":1839},"sdkType",[371,2379,667],{"class":659},[371,2381,670],{"class":653},[371,2383,674],{"class":673},[371,2385,2386],{"class":380},"client",[371,2388,667],{"class":673},[371,2390,682],{"class":653},[371,2392,2394,2396,2399,2401,2403,2405,2407,2410,2412],{"class":373,"line":2393},41,[371,2395,1836],{"class":659},[371,2397,2398],{"class":1839},"configAvailableTo",[371,2400,667],{"class":659},[371,2402,670],{"class":653},[371,2404,697],{"class":653},[371,2406,667],{"class":673},[371,2408,2409],{"class":380},"server",[371,2411,667],{"class":673},[371,2413,754],{"class":653},[371,2415,2417],{"class":373,"line":2416},42,[371,2418,2129],{"class":653},[371,2420,2422],{"class":373,"line":2421},43,[371,2423,2424],{"class":653},"  ]\n",[371,2426,2428],{"class":373,"line":2427},44,[371,2429,760],{"class":653},[309,2431,2432,2433,2435,2436,2438,2439,2442,2443,2445,2446,2445,2448,2450,2451,2453],{},"A direct reference has ",[312,2434,1954],{}," when its key came from a constant, ",[312,2437,1974],{}," when the call passes an in-code default value, and ",[312,2440,2441],{},"getterType"," when the getter's name sets the type. Each finding has a ",[312,2444,1895],{},", the ",[312,2447,1840],{},[312,2449,1860],{}," and the ",[312,2452,373],{},", and the config facts it was checked against:",[507,2455,2456,2467],{},[510,2457,2458],{},[513,2459,2460,2464],{},[516,2461,2462],{},[312,2463,1895],{},[516,2465,2466],{},"Also has",[523,2468,2469,2478,2490,2511,2525],{},[513,2470,2471,2476],{},[528,2472,2473],{},[312,2474,2475],{},"unknown-key",[528,2477],{},[513,2479,2480,2485],{},[528,2481,2482],{},[312,2483,2484],{},"deprecated-key",[528,2486,2487],{},[312,2488,2489],{},"currentKey",[513,2491,2492,2497],{},[528,2493,2494],{},[312,2495,2496],{},"type-mismatch",[528,2498,2499,1128,2502,2505,2506,1128,2508,2510],{},[312,2500,2501],{},"configType",[312,2503,2504],{},"servedAs",", and ",[312,2507,1974],{},[312,2509,2441],{}," or both",[513,2512,2513,2517],{},[528,2514,2515],{},[312,2516,2292],{},[528,2518,2519,1128,2521,1128,2523],{},[312,2520,1915],{},[312,2522,2377],{},[312,2524,2398],{},[513,2526,2527,2532],{},[528,2528,2529],{},[312,2530,2531],{},"enum-value-not-allowed",[528,2533,2534,1128,2536],{},[312,2535,1974],{},[312,2537,2538],{},"allowedValues",[309,2540,2541,2542,2547],{},"The ",[300,2543,2546],{"href":2544,"rel":2545,"target":305},"https:\u002F\u002Fgithub.com\u002FConfigDirector\u002Fcli\u002Fblob\u002Fmain\u002Fschema\u002Fscan-output.schema.json",[304],"JSON Schema"," in the package describes every field.",[2549,2550,2551],"style",{},"html pre.shiki code .sbgvK, html code.shiki .sbgvK{--shiki-light:#E2931D;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .s_sjI, html code.shiki .s_sjI{--shiki-light:#91B859;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .stzsN, html code.shiki .stzsN{--shiki-light:#91B859;--shiki-default:#005CC5;--shiki-dark:#79B8FF}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 .sP7_E, html code.shiki .sP7_E{--shiki-light:#39ADB5;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .s39Yj, html code.shiki .s39Yj{--shiki-light:#39ADB5;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sseR_, html code.shiki .sseR_{--shiki-light:#9C3EDA;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sjJ54, html code.shiki .sjJ54{--shiki-light:#39ADB5;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sQzsp, html code.shiki .sQzsp{--shiki-light:#E53935;--shiki-default:#22863A;--shiki-dark:#85E89D}html pre.shiki code .syTEX, html code.shiki .syTEX{--shiki-light:#FF5370;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .srdBf, html code.shiki .srdBf{--shiki-light:#F76D47;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .smGrS, html code.shiki .smGrS{--shiki-light:#39ADB5;--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sZMiF, html code.shiki .sZMiF{--shiki-light:#E2931D;--shiki-default:#005CC5;--shiki-dark:#79B8FF}",{"title":367,"searchDepth":391,"depth":391,"links":2553},[2554,2555,2556,2557,2562,2565,2569],{"id":294,"depth":391,"text":5},{"id":356,"depth":391,"text":357},{"id":439,"depth":391,"text":440},{"id":481,"depth":391,"text":482,"children":2558},[2559,2560,2561],{"id":486,"depth":685,"text":487},{"id":596,"depth":685,"text":597},{"id":838,"depth":685,"text":839},{"id":348,"depth":391,"text":948,"children":2563},[2564],{"id":1109,"depth":685,"text":1110},{"id":352,"depth":391,"text":1191,"children":2566},[2567,2568],{"id":1402,"depth":685,"text":1403},{"id":1457,"depth":685,"text":1458},{"id":1716,"depth":391,"text":938},"Find where your code reads each config, and fail the build when it reads a key that does not exist, was renamed, or has the wrong type, with the configdirector command line tool","md",null,{"modifiedAt":2574},"2026-10-17T05:30:24.000Z",{"title":252,"icon":255,"badge":256},{"title":252,"description":2570},"nX5MMM2nykPoOXOc2BmNJsT9bB_trd490M8HJxb4d5k",[2579,2581],{"title":247,"path":248,"stem":249,"description":2580,"icon":250,"children":-1},"Manage projects, configs, targeting rules, and segments from AI coding tools through the Model Context Protocol",{"title":258,"path":259,"stem":260,"description":2582,"icon":261,"children":-1},"Manage projects, environments, configs, targeting rules, segments, and tags over HTTPS with an API token. The base URL, authentication, permissions, error responses, usage counting, the endpoints, and the OpenAPI document.",1792216093851]