[{"data":1,"prerenderedAt":1756},["ShallowReactive",2],{"navigation_docs":3,"-reference-configuration-repos-detectors":504,"-reference-configuration-repos-detectors-surround":1751},[4,28,51,187,214,469],{"title":5,"path":6,"stem":7,"children":8},"Get started","\u002Fget-started","1.get-started",[9,12,16,20,24],{"title":10,"path":6,"stem":11},"Overview","1.get-started\u002Findex",{"title":13,"path":14,"stem":15},"Why Kraft","\u002Fget-started\u002Fwhy-kraft","1.get-started\u002F0.why-kraft",{"title":17,"path":18,"stem":19},"Install","\u002Fget-started\u002Finstall","1.get-started\u002F1.install",{"title":21,"path":22,"stem":23},"Your first work item","\u002Fget-started\u002Ffirst-work-item","1.get-started\u002F2.first-work-item",{"title":25,"path":26,"stem":27},"FAQ","\u002Fget-started\u002Ffaq","1.get-started\u002F3.faq",{"title":29,"path":30,"stem":31,"children":32},"Concepts","\u002Fconcepts","2.concepts",[33,35,39,43,47],{"title":10,"path":30,"stem":34},"2.concepts\u002Findex",{"title":36,"path":37,"stem":38},"How a work item runs","\u002Fconcepts\u002Fhow-a-work-item-runs","2.concepts\u002F1.how-a-work-item-runs",{"title":40,"path":41,"stem":42},"Caps and budgets","\u002Fconcepts\u002Fcaps-and-budgets","2.concepts\u002F2.caps-and-budgets",{"title":44,"path":45,"stem":46},"Why a permission gate","\u002Fconcepts\u002Fpermission-gate","2.concepts\u002F3.permission-gate",{"title":48,"path":49,"stem":50},"Vocabulary","\u002Fconcepts\u002Fvocabulary","2.concepts\u002F4.vocabulary",{"title":52,"path":53,"stem":54,"children":55},"Guides","\u002Fguides","3.guides",[56,58,96,113,134,183],{"title":10,"path":53,"stem":57},"3.guides\u002Findex",{"title":59,"path":60,"stem":61,"children":62,"page":95},"Day to day","\u002Fguides\u002Fday-to-day","3.guides\u002F1.day-to-day",[63,67,71,75,79,83,87,91],{"title":64,"path":65,"stem":66},"The setup wizard on first start","\u002Fguides\u002Fday-to-day\u002Ffirst-run","3.guides\u002F1.day-to-day\u002F2.first-run",{"title":68,"path":69,"stem":70},"File a work item","\u002Fguides\u002Fday-to-day\u002Ffile-a-work-item","3.guides\u002F1.day-to-day\u002F3.file-a-work-item",{"title":72,"path":73,"stem":74},"Use Kraft from your agent","\u002Fguides\u002Fday-to-day\u002Fagent-integration","3.guides\u002F1.day-to-day\u002F4.agent-integration",{"title":76,"path":77,"stem":78},"Reviewing a change","\u002Fguides\u002Fday-to-day\u002Freview-a-change","3.guides\u002F1.day-to-day\u002F5.review-a-change",{"title":80,"path":81,"stem":82},"Raise a cap on a stopped item","\u002Fguides\u002Fday-to-day\u002Fraise-a-cap","3.guides\u002F1.day-to-day\u002F6.raise-a-cap",{"title":84,"path":85,"stem":86},"Kraft for VS Code","\u002Fguides\u002Fday-to-day\u002Fvscode","3.guides\u002F1.day-to-day\u002F7.vscode",{"title":88,"path":89,"stem":90},"Kraft on a phone","\u002Fguides\u002Fday-to-day\u002Fkraft-on-a-phone","3.guides\u002F1.day-to-day\u002F8.kraft-on-a-phone",{"title":92,"path":93,"stem":94},"Get notified when an item needs you","\u002Fguides\u002Fday-to-day\u002Fnotifications","3.guides\u002F1.day-to-day\u002F9.notifications",false,{"title":97,"path":98,"stem":99,"children":100,"page":95},"Customize and automate","\u002Fguides\u002Fcustomize","3.guides\u002F2.customize",[101,105,109],{"title":102,"path":103,"stem":104},"Write your own chain","\u002Fguides\u002Fcustomize\u002Fwrite-your-own-chain","3.guides\u002F2.customize\u002F1.write-your-own-chain",{"title":106,"path":107,"stem":108},"Add a security review or a gate reviewer","\u002Fguides\u002Fcustomize\u002Fadd-review-agents","3.guides\u002F2.customize\u002F2.add-review-agents",{"title":110,"path":111,"stem":112},"Schedule or webhook work","\u002Fguides\u002Fcustomize\u002Fschedule-and-webhook-work","3.guides\u002F2.customize\u002F3.schedule-and-webhook-work",{"title":114,"path":115,"stem":116,"children":117,"page":95},"Agents and harnesses","\u002Fguides\u002Fharnesses","3.guides\u002F3.harnesses",[118,122,126,130],{"title":119,"path":120,"stem":121},"Switch a task to another harness","\u002Fguides\u002Fharnesses\u002Fswitch-harness","3.guides\u002F3.harnesses\u002F1.switch-harness",{"title":123,"path":124,"stem":125},"Add or override a harness","\u002Fguides\u002Fharnesses\u002Fadding-a-harness","3.guides\u002F3.harnesses\u002F2.adding-a-harness",{"title":127,"path":128,"stem":129},"Build a worker Kit","\u002Fguides\u002Fharnesses\u002Fworker-kit","3.guides\u002F3.harnesses\u002F3.worker-kit",{"title":131,"path":132,"stem":133},"Give a worker its login","\u002Fguides\u002Fharnesses\u002Fgive-a-worker-its-login","3.guides\u002F3.harnesses\u002F4.give-a-worker-its-login",{"title":135,"path":136,"stem":137,"children":138,"page":95},"Run the server","\u002Fguides\u002Frun","3.guides\u002F4.run",[139,143,147,151,155,159,163,167,171,175,179],{"title":140,"path":141,"stem":142},"Remote access","\u002Fguides\u002Frun\u002Fremote-access","3.guides\u002F4.run\u002F01.remote-access",{"title":144,"path":145,"stem":146},"Put a proxy in front of Kraft","\u002Fguides\u002Frun\u002Fput-a-proxy-in-front-of-kraft","3.guides\u002F4.run\u002F02.put-a-proxy-in-front-of-kraft",{"title":148,"path":149,"stem":150},"Restart Kraft without ending running agents","\u002Fguides\u002Frun\u002Frestart-kraft","3.guides\u002F4.run\u002F03.restart-kraft",{"title":152,"path":153,"stem":154},"Back up and restore the database","\u002Fguides\u002Frun\u002Fback-up-and-restore","3.guides\u002F4.run\u002F04.back-up-and-restore",{"title":156,"path":157,"stem":158},"Logs and disk space","\u002Fguides\u002Frun\u002Flogs-and-disk-space","3.guides\u002F4.run\u002F05.logs-and-disk-space",{"title":160,"path":161,"stem":162},"Run Kraft as a service","\u002Fguides\u002Frun\u002Frun-as-a-service","3.guides\u002F4.run\u002F06.run-as-a-service",{"title":164,"path":165,"stem":166},"Upgrade Kraft","\u002Fguides\u002Frun\u002Fupgrade-kraft","3.guides\u002F4.run\u002F07.upgrade-kraft",{"title":168,"path":169,"stem":170},"Upgrade your configuration","\u002Fguides\u002Frun\u002Fupgrade-your-configuration","3.guides\u002F4.run\u002F08.upgrade-your-configuration",{"title":172,"path":173,"stem":174},"Upgrade from 1.4","\u002Fguides\u002Frun\u002Fupgrade-from-1-4","3.guides\u002F4.run\u002F09.upgrade-from-1-4",{"title":176,"path":177,"stem":178},"Upgrade from 0.x or a release candidate","\u002Fguides\u002Frun\u002Fupgrade-from-0-x-or-a-release-candidate","3.guides\u002F4.run\u002F10.upgrade-from-0-x-or-a-release-candidate",{"title":180,"path":181,"stem":182},"Roll back to 1.4","\u002Fguides\u002Frun\u002Froll-back","3.guides\u002F4.run\u002F11.roll-back",{"title":184,"path":185,"stem":186},"Kraft Lite","\u002Fguides\u002Fkraft-lite","3.guides\u002F5.kraft-lite",{"title":188,"path":189,"stem":190,"children":191},"Troubleshooting","\u002Ftroubleshooting","4.troubleshooting",[192,194,198,202,206,210],{"title":10,"path":189,"stem":193},"4.troubleshooting\u002Findex",{"title":195,"path":196,"stem":197},"Why did my item stop?","\u002Ftroubleshooting\u002Fwhy-did-my-item-stop","4.troubleshooting\u002F1.why-did-my-item-stop",{"title":199,"path":200,"stem":201},"Stop reasons in detail","\u002Ftroubleshooting\u002Fstop-reasons-in-detail","4.troubleshooting\u002F2.stop-reasons-in-detail",{"title":203,"path":204,"stem":205},"Starting and reaching Kraft","\u002Ftroubleshooting\u002Fstarting-and-reaching-kraft","4.troubleshooting\u002F3.starting-and-reaching-kraft",{"title":207,"path":208,"stem":209},"Doctor failures","\u002Ftroubleshooting\u002Fdoctor-failures","4.troubleshooting\u002F4.doctor-failures",{"title":211,"path":212,"stem":213},"Sandbox and Kit stops","\u002Ftroubleshooting\u002Fsandbox-and-kit-stops","4.troubleshooting\u002F5.sandbox-and-kit-stops",{"title":215,"path":216,"stem":217,"children":218},"Reference","\u002Freference","5.reference",[219,221,259,281,285,375,393,419,423,427,461,465],{"title":10,"path":216,"stem":220},"5.reference\u002Findex",{"title":222,"path":223,"stem":224,"children":225},"Web UI","\u002Freference\u002Fweb-ui","5.reference\u002F00.web-ui\u002Findex",[226,227,231,235,239,243,247,251,255],{"title":10,"path":223,"stem":224},{"title":228,"path":229,"stem":230},"Sidebar, search, and keyboard","\u002Freference\u002Fweb-ui\u002Fsidebar-search-and-keyboard","5.reference\u002F00.web-ui\u002F0.sidebar-search-and-keyboard",{"title":232,"path":233,"stem":234},"The board","\u002Freference\u002Fweb-ui\u002Fboard","5.reference\u002F00.web-ui\u002F1.board",{"title":236,"path":237,"stem":238},"An item's page","\u002Freference\u002Fweb-ui\u002Fitem-page","5.reference\u002F00.web-ui\u002F2.item-page",{"title":240,"path":241,"stem":242},"Fix loops and test scopes","\u002Freference\u002Fweb-ui\u002Ffix-loops-and-test-scopes","5.reference\u002F00.web-ui\u002F3.fix-loops-and-test-scopes",{"title":244,"path":245,"stem":246},"Config before an item starts","\u002Freference\u002Fweb-ui\u002Fconfig-before-start","5.reference\u002F00.web-ui\u002F4.config-before-start",{"title":248,"path":249,"stem":250},"The review page","\u002Freference\u002Fweb-ui\u002Freview-page","5.reference\u002F00.web-ui\u002F5.review-page",{"title":252,"path":253,"stem":254},"Templates and Settings","\u002Freference\u002Fweb-ui\u002Ftemplates-and-settings","5.reference\u002F00.web-ui\u002F6.templates-and-settings",{"title":256,"path":257,"stem":258},"Analytics","\u002Freference\u002Fweb-ui\u002Fanalytics","5.reference\u002F00.web-ui\u002F7.analytics",{"title":260,"path":261,"stem":262,"children":263},"CLI","\u002Freference\u002Fcli","5.reference\u002F01.cli\u002Findex",[264,265,269,273,277],{"title":10,"path":261,"stem":262},{"title":266,"path":267,"stem":268},"Item verbs","\u002Freference\u002Fcli\u002Fitem","5.reference\u002F01.cli\u002F2.item",{"title":270,"path":271,"stem":272},"View verbs","\u002Freference\u002Fcli\u002Fview","5.reference\u002F01.cli\u002F3.view",{"title":274,"path":275,"stem":276},"Repo verbs","\u002Freference\u002Fcli\u002Frepo","5.reference\u002F01.cli\u002F4.repo",{"title":278,"path":279,"stem":280},"Admin verbs","\u002Freference\u002Fcli\u002Fadmin","5.reference\u002F01.cli\u002F5.admin",{"title":282,"path":283,"stem":284},"Work item statuses","\u002Freference\u002Fstatuses","5.reference\u002F02.statuses",{"title":286,"path":287,"stem":288,"children":289},"Configuration","\u002Freference\u002Fconfiguration","5.reference\u002F03.configuration\u002Findex",[290,291,309,313,317,321,325,329,333,337,371],{"title":10,"path":287,"stem":288},{"title":292,"path":293,"stem":294,"children":295},"repos.yaml","\u002Freference\u002Fconfiguration\u002Frepos","5.reference\u002F03.configuration\u002F02.repos\u002Findex",[296,297,301,305],{"title":10,"path":293,"stem":294},{"title":298,"path":299,"stem":300},"How connect proposes commands","\u002Freference\u002Fconfiguration\u002Frepos\u002Fconnect-proposals","5.reference\u002F03.configuration\u002F02.repos\u002F1.connect-proposals",{"title":302,"path":303,"stem":304},"detectors.yaml","\u002Freference\u002Fconfiguration\u002Frepos\u002Fdetectors","5.reference\u002F03.configuration\u002F02.repos\u002F2.detectors",{"title":306,"path":307,"stem":308},"Workspaces","\u002Freference\u002Fconfiguration\u002Frepos\u002Fworkspaces","5.reference\u002F03.configuration\u002F02.repos\u002F3.workspaces",{"title":310,"path":311,"stem":312},"policy.yaml","\u002Freference\u002Fconfiguration\u002Fpolicy","5.reference\u002F03.configuration\u002F03.policy",{"title":314,"path":315,"stem":316},"Library and chains","\u002Freference\u002Fconfiguration\u002Flibrary-and-chains","5.reference\u002F03.configuration\u002F04.library-and-chains",{"title":318,"path":319,"stem":320},"harnesses.yaml","\u002Freference\u002Fconfiguration\u002Fharnesses-file","5.reference\u002F03.configuration\u002F05.harnesses-file",{"title":322,"path":323,"stem":324},"access.yaml","\u002Freference\u002Fconfiguration\u002Faccess","5.reference\u002F03.configuration\u002F06.access",{"title":326,"path":327,"stem":328},"intake.yaml","\u002Freference\u002Fconfiguration\u002Fintake","5.reference\u002F03.configuration\u002F07.intake",{"title":330,"path":331,"stem":332},"notify.yaml","\u002Freference\u002Fconfiguration\u002Fnotify","5.reference\u002F03.configuration\u002F08.notify",{"title":334,"path":335,"stem":336},"theme.yaml","\u002Freference\u002Fconfiguration\u002Ftheme","5.reference\u002F03.configuration\u002F09.theme",{"title":338,"path":339,"stem":340,"children":341},"Sandboxed workers","\u002Freference\u002Fconfiguration\u002Fsandbox","5.reference\u002F03.configuration\u002F10.sandbox\u002Findex",[342,343,347,351,355,359,363,367],{"title":10,"path":339,"stem":340},{"title":344,"path":345,"stem":346},"Resource limits","\u002Freference\u002Fconfiguration\u002Fsandbox\u002Fresource-limits","5.reference\u002F03.configuration\u002F10.sandbox\u002F1.resource-limits",{"title":348,"path":349,"stem":350},"Callbacks from a sandbox","\u002Freference\u002Fconfiguration\u002Fsandbox\u002Fcallbacks","5.reference\u002F03.configuration\u002F10.sandbox\u002F2.callbacks",{"title":352,"path":353,"stem":354},"Network policy","\u002Freference\u002Fconfiguration\u002Fsandbox\u002Fnetwork-policy","5.reference\u002F03.configuration\u002F10.sandbox\u002F3.network-policy",{"title":356,"path":357,"stem":358},"Credentials","\u002Freference\u002Fconfiguration\u002Fsandbox\u002Fcredentials","5.reference\u002F03.configuration\u002F10.sandbox\u002F4.credentials",{"title":360,"path":361,"stem":362},"Kits","\u002Freference\u002Fconfiguration\u002Fsandbox\u002Fkits","5.reference\u002F03.configuration\u002F10.sandbox\u002F5.kits",{"title":364,"path":365,"stem":366},"sandbox.yaml","\u002Freference\u002Fconfiguration\u002Fsandbox\u002Fsandbox-yaml","5.reference\u002F03.configuration\u002F10.sandbox\u002F6.sandbox-yaml",{"title":368,"path":369,"stem":370},"Git in a sandbox","\u002Freference\u002Fconfiguration\u002Fsandbox\u002Fgit-in-a-sandbox","5.reference\u002F03.configuration\u002F10.sandbox\u002F7.git-in-a-sandbox",{"title":372,"path":373,"stem":374},"Environment variables","\u002Freference\u002Fconfiguration\u002Fenvironment-variables","5.reference\u002F03.configuration\u002F11.environment-variables",{"title":376,"path":377,"stem":378,"children":379},"Chain file keys","\u002Freference\u002Fchain-nodes","5.reference\u002F04.chain-nodes\u002Findex",[380,381,385,389],{"title":10,"path":377,"stem":378},{"title":382,"path":383,"stem":384},"Subprocess tasks","\u002Freference\u002Fchain-nodes\u002Fsubprocess-tasks","5.reference\u002F04.chain-nodes\u002F2.subprocess-tasks",{"title":386,"path":387,"stem":388},"Fix loop and judge","\u002Freference\u002Fchain-nodes\u002Ffix-loop","5.reference\u002F04.chain-nodes\u002F3.fix-loop",{"title":390,"path":391,"stem":392},"Result file","\u002Freference\u002Fchain-nodes\u002Fresult-file","5.reference\u002F04.chain-nodes\u002F4.result-file",{"title":394,"path":395,"stem":396,"children":397},"Agent harnesses","\u002Freference\u002Fharnesses","5.reference\u002F05.harnesses\u002Findex",[398,399,403,407,411,415],{"title":10,"path":395,"stem":396},{"title":400,"path":401,"stem":402},"Unattended runs","\u002Freference\u002Fharnesses\u002Funattended-runs","5.reference\u002F05.harnesses\u002F2.unattended-runs",{"title":404,"path":405,"stem":406},"Agent profiles","\u002Freference\u002Fharnesses\u002Fagent-profiles","5.reference\u002F05.harnesses\u002F3.agent-profiles",{"title":408,"path":409,"stem":410},"Harness definition files","\u002Freference\u002Fharnesses\u002Fharness-files","5.reference\u002F05.harnesses\u002F4.harness-files",{"title":412,"path":413,"stem":414},"Fallback and escalation","\u002Freference\u002Fharnesses\u002Ffallback-and-escalation","5.reference\u002F05.harnesses\u002F5.fallback-and-escalation",{"title":416,"path":417,"stem":418},"Cost reporting","\u002Freference\u002Fharnesses\u002Fcost-reporting","5.reference\u002F05.harnesses\u002F6.cost-reporting",{"title":420,"path":421,"stem":422},"Permission gate","\u002Freference\u002Fpermissions","5.reference\u002F06.permissions",{"title":424,"path":425,"stem":426},"Inbound triggers","\u002Freference\u002Ftriggers","5.reference\u002F07.triggers",{"title":428,"path":429,"stem":430,"children":431},"HTTP API","\u002Freference\u002Fhttp-api","5.reference\u002F08.http-api\u002Findex",[432,433,437,441,445,449,453,457],{"title":10,"path":429,"stem":430},{"title":434,"path":435,"stem":436},"Filing, reading and changing work items","\u002Freference\u002Fhttp-api\u002Fwork-items","5.reference\u002F08.http-api\u002F2.work-items",{"title":438,"path":439,"stem":440},"Gates, run control, ending and retry","\u002Freference\u002Fhttp-api\u002Fgates-run-control-and-ending","5.reference\u002F08.http-api\u002F3.gates-run-control-and-ending",{"title":442,"path":443,"stem":444},"The work item object","\u002Freference\u002Fhttp-api\u002Fwork-item-object","5.reference\u002F08.http-api\u002F4.work-item-object",{"title":446,"path":447,"stem":448},"Budget, events, diff and documents","\u002Freference\u002Fhttp-api\u002Fbudget-and-events","5.reference\u002F08.http-api\u002F5.budget-and-events",{"title":450,"path":451,"stem":452},"Repos, chains, harnesses and the server","\u002Freference\u002Fhttp-api\u002Frepos-chains-harnesses-and-server","5.reference\u002F08.http-api\u002F6.repos-chains-harnesses-and-server",{"title":454,"path":455,"stem":456},"Drafts","\u002Freference\u002Fhttp-api\u002Fdrafts","5.reference\u002F08.http-api\u002F7.drafts",{"title":458,"path":459,"stem":460},"Ops for each draft area","\u002Freference\u002Fhttp-api\u002Fdraft-ops","5.reference\u002F08.http-api\u002F8.draft-ops",{"title":462,"path":463,"stem":464},"MCP tools","\u002Freference\u002Fmcp-tools","5.reference\u002F09.mcp-tools",{"title":466,"path":467,"stem":468},"Events","\u002Freference\u002Fevents","5.reference\u002F10.events",{"title":470,"path":471,"stem":472,"children":473},"Security and project","\u002Fproject","6.project",[474,476,480,484,488,492,496,500],{"title":10,"path":471,"stem":475},"6.project\u002Findex",{"title":477,"path":478,"stem":479},"Security","\u002Fproject\u002Fsecurity","6.project\u002F1.security",{"title":481,"path":482,"stem":483},"Data and privacy","\u002Fproject\u002Fdata-and-privacy","6.project\u002F2.data-and-privacy",{"title":485,"path":486,"stem":487},"What's new in 2.0","\u002Fproject\u002Fwhats-new","6.project\u002F3.whats-new",{"title":489,"path":490,"stem":491},"Status and support","\u002Fproject\u002Fstatus-and-support","6.project\u002F4.status-and-support",{"title":493,"path":494,"stem":495},"Architecture","\u002Fproject\u002Farchitecture","6.project\u002F5.architecture",{"title":497,"path":498,"stem":499},"Source map","\u002Fproject\u002Fsource-map","6.project\u002F6.source-map",{"title":501,"path":502,"stem":503},"Contributing","\u002Fproject\u002Fcontributing","6.project\u002F7.contributing",{"id":505,"title":302,"body":506,"description":1744,"extension":1745,"links":1746,"meta":1747,"navigation":1748,"path":303,"seo":1749,"stem":304,"__hash__":1750},"docs\u002F5.reference\u002F03.configuration\u002F02.repos\u002F2.detectors.md",{"type":507,"value":508,"toc":1734},"minimark",[509,525,536,768,775,778,908,924,929,1023,1027,1422,1434,1441,1444,1510,1513,1521,1544,1564,1568,1571,1689,1693,1730],[510,511,512,513,516,517,520,521,524],"p",{},"This page lists the keys of ",[514,515,302],"code",{},", where you teach ",[514,518,519],{},"kraft repo connect"," your own conventions, and the toolchains Kraft ships. ",[522,523,298],"a",{"href":299}," says how a proposal is made from them.",[510,526,527,528,531,532,535],{},"The shipped table is data. Kraft ships it with each release, and you can layer your own on top of it in ",[514,529,530],{},"$KRAFT_HOME\u002Fconfig\u002Fdetectors.yaml"," (default ",[514,533,534],{},"~\u002F.kraft\u002Fconfig\u002F","). This file is optional and is not seeded, so a newer Kraft's detectors still reach you after you write one.",[537,538,544],"pre",{"className":539,"code":540,"filename":541,"language":542,"meta":543,"style":543},"language-yaml shiki shiki-themes github-light-high-contrast github-light-high-contrast github-dark-high-contrast","max_depth: 3                 # how far below the root a scope can be (default 2, at most 4)\nignore_dirs: [playground]    # added to the shipped list\ndisable: [tox]               # shipped detectors to switch off, by id\ndetectors:\n  # A detector of your own: tried before the shipped ones.\n  - id: earthly\n    tier: runner\n    files: [Earthfile]\n    test:\n      - run: \"earthly +test\"\n  # The same id as a shipped detector replaces it, in its place.\n  - id: go\n    tier: toolchain\n    family: go\n    files: [go.mod]\n    test:\n      - run: \"gotestsum .\u002F...\"\n    setup:\n      - run: \"go mod download\"\n","~\u002F.kraft\u002Fconfig\u002Fdetectors.yaml","yaml","",[514,545,546,567,586,603,612,618,632,643,657,665,679,685,697,707,717,729,736,748,756],{"__ignoreMap":543},[547,548,551,555,559,563],"span",{"class":549,"line":550},"line",1,[547,552,554],{"class":553},"sb7M8","max_depth",[547,556,558],{"class":557},"s7iLA",": ",[547,560,562],{"class":561},"ssYy9","3",[547,564,566],{"class":565},"sq92B","                 # how far below the root a scope can be (default 2, at most 4)\n",[547,568,570,573,576,580,583],{"class":549,"line":569},2,[547,571,572],{"class":553},"ignore_dirs",[547,574,575],{"class":557},": [",[547,577,579],{"class":578},"semJd","playground",[547,581,582],{"class":557},"]    ",[547,584,585],{"class":565},"# added to the shipped list\n",[547,587,589,592,594,597,600],{"class":549,"line":588},3,[547,590,591],{"class":553},"disable",[547,593,575],{"class":557},[547,595,596],{"class":578},"tox",[547,598,599],{"class":557},"]               ",[547,601,602],{"class":565},"# shipped detectors to switch off, by id\n",[547,604,606,609],{"class":549,"line":605},4,[547,607,608],{"class":553},"detectors",[547,610,611],{"class":557},":\n",[547,613,615],{"class":549,"line":614},5,[547,616,617],{"class":565},"  # A detector of your own: tried before the shipped ones.\n",[547,619,621,624,627,629],{"class":549,"line":620},6,[547,622,623],{"class":557},"  - ",[547,625,626],{"class":553},"id",[547,628,558],{"class":557},[547,630,631],{"class":578},"earthly\n",[547,633,635,638,640],{"class":549,"line":634},7,[547,636,637],{"class":553},"    tier",[547,639,558],{"class":557},[547,641,642],{"class":578},"runner\n",[547,644,646,649,651,654],{"class":549,"line":645},8,[547,647,648],{"class":553},"    files",[547,650,575],{"class":557},[547,652,653],{"class":578},"Earthfile",[547,655,656],{"class":557},"]\n",[547,658,660,663],{"class":549,"line":659},9,[547,661,662],{"class":553},"    test",[547,664,611],{"class":557},[547,666,668,671,674,676],{"class":549,"line":667},10,[547,669,670],{"class":557},"      - ",[547,672,673],{"class":553},"run",[547,675,558],{"class":557},[547,677,678],{"class":578},"\"earthly +test\"\n",[547,680,682],{"class":549,"line":681},11,[547,683,684],{"class":565},"  # The same id as a shipped detector replaces it, in its place.\n",[547,686,688,690,692,694],{"class":549,"line":687},12,[547,689,623],{"class":557},[547,691,626],{"class":553},[547,693,558],{"class":557},[547,695,696],{"class":578},"go\n",[547,698,700,702,704],{"class":549,"line":699},13,[547,701,637],{"class":553},[547,703,558],{"class":557},[547,705,706],{"class":578},"toolchain\n",[547,708,710,713,715],{"class":549,"line":709},14,[547,711,712],{"class":553},"    family",[547,714,558],{"class":557},[547,716,696],{"class":578},[547,718,720,722,724,727],{"class":549,"line":719},15,[547,721,648],{"class":553},[547,723,575],{"class":557},[547,725,726],{"class":578},"go.mod",[547,728,656],{"class":557},[547,730,732,734],{"class":549,"line":731},16,[547,733,662],{"class":553},[547,735,611],{"class":557},[547,737,739,741,743,745],{"class":549,"line":738},17,[547,740,670],{"class":557},[547,742,673],{"class":553},[547,744,558],{"class":557},[547,746,747],{"class":578},"\"gotestsum .\u002F...\"\n",[547,749,751,754],{"class":549,"line":750},18,[547,752,753],{"class":553},"    setup",[547,755,611],{"class":557},[547,757,759,761,763,765],{"class":549,"line":758},19,[547,760,670],{"class":557},[547,762,673],{"class":553},[547,764,558],{"class":557},[547,766,767],{"class":578},"\"go mod download\"\n",[510,769,770,771,774],{},"The file is read on every probe, with no restart. A file that does not parse fails the probe, naming the file, and ",[514,772,773],{},"kraft admin doctor"," reports it. Connecting a repo that is already connected reads it only for what the entry left undecided.",[510,776,777],{},"A detector for a task runner names the tasks to look for, and a condition for a command that depends on what else is in the directory:",[537,779,781],{"className":539,"code":780,"filename":541,"language":542,"meta":543,"style":543},"detectors:\n  - id: bin-tools\n    tier: runner\n    files: [bin\u002Fcheck]\n    unless: [bin\u002Frails]\n    tasks: script\n    test:\n      - {tasks: [bin\u002Fcheck], run: \".\u002F{task}\"}\n    setup:\n      - {when: [{files: [package.json]}], run: \"npm ci\"}\n",[514,782,783,789,800,808,819,831,841,847,872,878],{"__ignoreMap":543},[547,784,785,787],{"class":549,"line":550},[547,786,608],{"class":553},[547,788,611],{"class":557},[547,790,791,793,795,797],{"class":549,"line":569},[547,792,623],{"class":557},[547,794,626],{"class":553},[547,796,558],{"class":557},[547,798,799],{"class":578},"bin-tools\n",[547,801,802,804,806],{"class":549,"line":588},[547,803,637],{"class":553},[547,805,558],{"class":557},[547,807,642],{"class":578},[547,809,810,812,814,817],{"class":549,"line":605},[547,811,648],{"class":553},[547,813,575],{"class":557},[547,815,816],{"class":578},"bin\u002Fcheck",[547,818,656],{"class":557},[547,820,821,824,826,829],{"class":549,"line":614},[547,822,823],{"class":553},"    unless",[547,825,575],{"class":557},[547,827,828],{"class":578},"bin\u002Frails",[547,830,656],{"class":557},[547,832,833,836,838],{"class":549,"line":620},[547,834,835],{"class":553},"    tasks",[547,837,558],{"class":557},[547,839,840],{"class":578},"script\n",[547,842,843,845],{"class":549,"line":634},[547,844,662],{"class":553},[547,846,611],{"class":557},[547,848,849,852,855,857,859,862,864,866,869],{"class":549,"line":645},[547,850,851],{"class":557},"      - {",[547,853,854],{"class":553},"tasks",[547,856,575],{"class":557},[547,858,816],{"class":578},[547,860,861],{"class":557},"], ",[547,863,673],{"class":553},[547,865,558],{"class":557},[547,867,868],{"class":578},"\".\u002F{task}\"",[547,870,871],{"class":557},"}\n",[547,873,874,876],{"class":549,"line":659},[547,875,753],{"class":553},[547,877,611],{"class":557},[547,879,880,882,885,888,891,893,896,899,901,903,906],{"class":549,"line":667},[547,881,851],{"class":557},[547,883,884],{"class":553},"when",[547,886,887],{"class":557},": [{",[547,889,890],{"class":553},"files",[547,892,575],{"class":557},[547,894,895],{"class":578},"package.json",[547,897,898],{"class":557},"]}], ",[547,900,673],{"class":553},[547,902,558],{"class":557},[547,904,905],{"class":578},"\"npm ci\"",[547,907,871],{"class":557},[510,909,910,911,914,915,923],{},"The VS Code extension validates your file against ",[514,912,913],{},"detectors.schema.json",". The shipped table, with a comment on each choice, is ",[522,916,920],{"href":917,"rel":918},"https:\u002F\u002Fgithub.com\u002FitsOmidKarami\u002Fkraft\u002Fblob\u002Fmain\u002Fsrc\u002Fkraft\u002Fdetectors.yaml",[919],"nofollow",[514,921,922],{},"src\u002Fkraft\u002Fdetectors.yaml",".",[925,926,928],"h2",{"id":927},"top-level-keys","Top-level keys",[930,931,932,951],"table",{},[933,934,935],"thead",{},[936,937,938,942,945,948],"tr",{},[939,940,941],"th",{},"Key",[939,943,944],{},"Type",[939,946,947],{},"Default",[939,949,950],{},"Meaning",[952,953,954,972,989,1007],"tbody",{},[936,955,956,961,964,969],{},[957,958,959],"td",{},[514,960,554],{},[957,962,963],{},"integer, 0 to 4",[957,965,966],{},[514,967,968],{},"2",[957,970,971],{},"How far below the root a scope can be.",[936,973,974,978,981,986],{},[957,975,976],{},[514,977,572],{},[957,979,980],{},"list of strings",[957,982,983],{},[514,984,985],{},"[]",[957,987,988],{},"Directory names added to the shipped list of non-project names.",[936,990,991,995,997,1001],{},[957,992,993],{},[514,994,591],{},[957,996,980],{},[957,998,999],{},[514,1000,985],{},[957,1002,1003,1004,1006],{},"Shipped detectors to switch off, by ",[514,1005,626],{},". An id the shipped table does not have is refused.",[936,1008,1009,1013,1016,1020],{},[957,1010,1011],{},[514,1012,608],{},[957,1014,1015],{},"list of detectors",[957,1017,1018],{},[514,1019,985],{},[957,1021,1022],{},"Your own detectors, tried before the shipped ones.",[925,1024,1026],{"id":1025},"detector-fields","Detector fields",[930,1028,1029,1042],{},[933,1030,1031],{},[936,1032,1033,1036,1038,1040],{},[939,1034,1035],{},"Field",[939,1037,944],{},[939,1039,947],{},[939,1041,950],{},[952,1043,1044,1068,1093,1113,1129,1147,1210,1238,1264,1288,1309,1335,1353,1389],{},[936,1045,1046,1050,1056,1062],{},[957,1047,1048],{},[514,1049,626],{},[957,1051,1052,1053],{},"string, ",[514,1054,1055],{},"[a-z][a-z0-9_-]*",[957,1057,1058],{},[1059,1060,1061],"em",{},"(required)",[957,1063,1064,1065,1067],{},"Once per file. Shown as where a proposal came from, and what ",[514,1066,591],{}," names.",[936,1069,1070,1075,1084,1088],{},[957,1071,1072],{},[514,1073,1074],{},"tier",[957,1076,1077,1080,1081],{},[514,1078,1079],{},"runner"," or ",[514,1082,1083],{},"toolchain",[957,1085,1086],{},[1059,1087,1061],{},[957,1089,1090,1092],{},[514,1091,1079],{}," outranks a toolchain. Both outrank CI.",[936,1094,1095,1099,1102,1106],{},[957,1096,1097],{},[514,1098,890],{},[957,1100,1101],{},"list of globs",[957,1103,1104],{},[1059,1105,1061],{},[957,1107,1108,1109,1112],{},"At least one, relative to the directory. The detector applies when any matches. A glob without ",[514,1110,1111],{},"\u002F"," matches only the directory's own files.",[936,1114,1115,1120,1122,1126],{},[957,1116,1117],{},[514,1118,1119],{},"unless",[957,1121,1101],{},[957,1123,1124],{},[514,1125,985],{},[957,1127,1128],{},"The detector does not apply when any of them matches.",[936,1130,1131,1136,1139,1144],{},[957,1132,1133],{},[514,1134,1135],{},"contains",[957,1137,1138],{},"mapping of glob to regex",[957,1140,1141],{},[514,1142,1143],{},"{}",[957,1145,1146],{},"Each regex must match some file its glob names.",[936,1148,1149,1153,1156,1161],{},[957,1150,1151],{},[514,1152,854],{},[957,1154,1155],{},"string",[957,1157,1158],{},[514,1159,1160],{},"null",[957,1162,1163,1164,1167,1168,1167,1171,1167,1174,1167,1177,1180,1181,1167,1184,1167,1187,1167,1190,1167,1193,1080,1196,1199,1200,1167,1203,1167,1206,1209],{},"Which reader lists the runner's tasks: ",[514,1165,1166],{},"just",", ",[514,1169,1170],{},"make",[514,1172,1173],{},"taskfile",[514,1175,1176],{},"mise",[514,1178,1179],{},"npm"," (package.json scripts), ",[514,1182,1183],{},"composer",[514,1185,1186],{},"deno",[514,1188,1189],{},"rake",[514,1191,1192],{},"pdm",[514,1194,1195],{},"poe",[514,1197,1198],{},"script"," (executables under ",[514,1201,1202],{},"script\u002F",[514,1204,1205],{},"scripts\u002F",[514,1207,1208],{},"bin\u002F",").",[936,1211,1212,1220,1223,1227],{},[957,1213,1214,1167,1217],{},[514,1215,1216],{},"test",[514,1218,1219],{},"setup",[957,1221,1222],{},"list of commands",[957,1224,1225],{},[514,1226,985],{},[957,1228,1229,1230,923],{},"Tried in order. The first one that holds is the proposal. See ",[522,1231,1233,1235,1236],{"href":1232},"#test-and-setup",[514,1234,1216],{}," and ",[514,1237,1219],{},[936,1239,1240,1245,1247,1251],{},[957,1241,1242],{},[514,1243,1244],{},"family",[957,1246,1155],{},[957,1248,1249],{},[514,1250,1160],{},[957,1252,1253,1254,1167,1257,1080,1260,1263],{},"The ecosystem, such as ",[514,1255,1256],{},"js",[514,1258,1259],{},"python",[514,1261,1262],{},"jvm",". A workspace root covers members of its own family.",[936,1265,1266,1271,1274,1279],{},[957,1267,1268],{},[514,1269,1270],{},"lockfile",[957,1272,1273],{},"boolean",[957,1275,1276],{},[514,1277,1278],{},"false",[957,1280,1281,1284,1285,1287],{},[514,1282,1283],{},"true"," when ",[514,1286,890],{}," are lockfiles: a workspace member this detector matches installs on its own, and its install still stands in a stopped directory.",[936,1289,1290,1295,1298,1302],{},[957,1291,1292],{},[514,1293,1294],{},"workspace",[957,1296,1297],{},"list of conditions",[957,1299,1300],{},[514,1301,985],{},[957,1303,1304,1305,923],{},"When any one holds, the directory is a workspace root. See ",[522,1306,1308],{"href":1307},"#conditions","Conditions",[936,1310,1311,1316,1318,1322],{},[957,1312,1313],{},[514,1314,1315],{},"stop",[957,1317,1273],{},[957,1319,1320],{},[514,1321,1278],{},[957,1323,1324,1326,1327,1330,1331,923],{},[514,1325,1283],{}," marks a project Kraft has no safe command for, as the shipped ",[514,1328,1329],{},"pyproject"," detector does. Where it matches and no other detector of its family does, the directory is stopped as in ",[522,1332,1334],{"href":1333},"\u002Freference\u002Fconfiguration\u002Frepos\u002Fconnect-proposals#a-python-project-with-no-lockfile","A Python project with no lockfile",[936,1336,1337,1342,1344,1348],{},[957,1338,1339],{},[514,1340,1341],{},"reason",[957,1343,1155],{},[957,1345,1346],{},[514,1347,1160],{},[957,1349,1350,1351,923],{},"What connect says about a stopped directory. Required with ",[514,1352,1315],{},[936,1354,1355,1360,1366,1370],{},[957,1356,1357],{},[514,1358,1359],{},"wrap",[957,1361,1362,1363],{},"string with ",[514,1364,1365],{},"{command}",[957,1367,1368],{},[514,1369,1160],{},[957,1371,1372,1373,1376,1377,1379,1380,1167,1383,1080,1385,1388],{},"How a command runs in this toolchain's environment: ",[514,1374,1375],{},"uv run {command}",". A runner's ",[514,1378,1216],{}," task in the same directory that runs ",[514,1381,1382],{},"pytest",[514,1384,1259],{},[514,1386,1387],{},"coverage"," bare is proposed through it.",[936,1390,1391,1396,1399,1403],{},[957,1392,1393],{},[514,1394,1395],{},"venv",[957,1397,1398],{},"string, a relative path",[957,1400,1401],{},[514,1402,1160],{},[957,1404,1405,1406,1409,1410,1413,1414,1417,1418,1421],{},"The virtualenv this detector's setup makes, relative to the directory: ",[514,1407,1408],{},".venv",". A test command another detector proposes beside it (",[514,1411,1412],{},"make test",", CI's ",[514,1415,1416],{},"python -m unittest",") runs with it active, so it imports the project's dependencies, not a worker's ",[514,1419,1420],{},"PATH"," Python.",[510,1423,1424,1425,1427,1428,1430,1431,1433],{},"A detector applies to a directory when any ",[514,1426,890],{}," glob matches, no ",[514,1429,1119],{}," glob does, and every ",[514,1432,1135],{}," regex matches a file its glob names.",[925,1435,1437,1235,1439],{"id":1436},"test-and-setup",[514,1438,1216],{},[514,1440,1219],{},[510,1442,1443],{},"Each command in the list has these keys:",[930,1445,1446,1456],{},[933,1447,1448],{},[936,1449,1450,1452,1454],{},[939,1451,941],{},[939,1453,944],{},[939,1455,950],{},[952,1457,1458,1473,1484,1495],{},[936,1459,1460,1464,1466],{},[957,1461,1462],{},[514,1463,673],{},[957,1465,1155],{},[957,1467,1468,1469,1472],{},"Required. The command, with ",[514,1470,1471],{},"{task}"," replaced by the task found.",[936,1474,1475,1479,1481],{},[957,1476,1477],{},[514,1478,854],{},[957,1480,980],{},[957,1482,1483],{},"Names to look for, first present wins.",[936,1485,1486,1490,1492],{},[957,1487,1488],{},[514,1489,884],{},[957,1491,1297],{},[957,1493,1494],{},"Any one of them must hold.",[936,1496,1497,1502,1504],{},[957,1498,1499],{},[514,1500,1501],{},"reads",[957,1503,980],{},[957,1505,1506,1507,1509],{},"The files the command reads, shown as where the proposal came from. Left out, it is the first of the detector's ",[514,1508,890],{}," that is there.",[925,1511,1308],{"id":1512},"conditions",[510,1514,1515,1516,1080,1518,1520],{},"A condition, in ",[514,1517,884],{},[514,1519,1294],{},", holds when all of what it gives holds:",[1522,1523,1524,1530,1535],"ul",{},[1525,1526,1527,1529],"li",{},[514,1528,890],{},": any glob matches.",[1525,1531,1532,1534],{},[514,1533,1135],{},": each glob names a file its regex matches.",[1525,1536,1537,558,1540,1543],{},[514,1538,1539],{},"toml",[514,1541,1542],{},"{glob: {dotted.key: regex}}","; the value at that key of a TOML file, as JSON, matches.",[510,1545,1546,1548,1549,1552,1553,1555,1556,1559,1560,1563],{},[514,1547,1539],{}," reads one table, such as ",[514,1550,1551],{},"project.optional-dependencies",", where a regex over the whole file would run on into the tables after it. Keep a ",[514,1554,1135],{}," regex to one line (",[514,1557,1558],{},"[ \\t]"," rather than ",[514,1561,1562],{},"\\s","): one that backtracks across a large file runs the probe into its time limit.",[925,1565,1567],{"id":1566},"toolchains-in-the-shipped-table","Toolchains in the shipped table",[510,1569,1570],{},"The shipped table covers:",[1522,1572,1573,1649,1655,1665,1671],{},[1525,1574,1575,1579,1580,1583,1584,1587,1588,1591,1592,1595,1596,1080,1599,1602,1603,1606],{},[1576,1577,1578],"strong",{},"Python:"," uv, Poetry, PDM, Pipenv, Hatch (a ",[514,1581,1582],{},"[tool.hatch.envs]"," table or a ",[514,1585,1586],{},"hatch.toml","), ",[514,1589,1590],{},"requirements.txt",", tox (its ",[514,1593,1594],{},"py"," environment, also beside a ",[514,1597,1598],{},"pyproject.toml",[514,1600,1601],{},"setup.py"," with no lockfile); Django's ",[514,1604,1605],{},"manage.py test",[1522,1607,1608],{},[1525,1609,1610,1611,1613,1614,1616,1617,1620,1621,1624,1625,1628,1629,1167,1632,1635,1636,1639,1640,1642,1643,1646,1647,923],{},"A ",[514,1612,1590],{}," is set up in a ",[514,1615,1408],{},", which ignores itself (a ",[514,1618,1619],{},".gitignore"," of ",[514,1622,1623],{},"*"," inside it), so no work item commits it. A ",[514,1626,1627],{},"requirements-dev.txt"," (or ",[514,1630,1631],{},"requirements_dev.txt",[514,1633,1634],{},"dev-requirements.txt",") beside it is installed too, after the base file unless it includes it with ",[514,1637,1638],{},"-r",". A task runner's or CI's test command there runs inside that venv: a ",[514,1641,1259],{}," line as ",[514,1644,1645],{},".venv\u002Fbin\u002Fpython",", anything else with the venv first on ",[514,1648,1420],{},[1525,1650,1651,1654],{},[1576,1652,1653],{},"JavaScript and TypeScript:"," npm, pnpm, Yarn classic and Berry, Bun, Deno; Nx and Turborepo; npm, pnpm, Yarn and Deno workspaces",[1525,1656,1657,1660,1661,1664],{},[1576,1658,1659],{},"JVM:"," Gradle (Android included), Maven (a multi-module build's setup installs its modules, ",[514,1662,1663],{},"-DskipTests install","), sbt",[1525,1666,1667,1670],{},[1576,1668,1669],{},"Ruby:"," Rails, RSpec, Rake",[1525,1672,1673,1676,1677,1680,1681,1684,1685,1688],{},[1576,1674,1675],{},"Others:"," Cargo (workspaces included), Go, .NET, Composer (its install only beside a ",[514,1678,1679],{},"composer.lock",", which it would otherwise write), Mix (umbrellas included), Swift, Flutter and Dart, Zig, Stack and Cabal, Julia, Bazel, CMake (a ",[514,1682,1683],{},"CMakeLists.txt"," with a ",[514,1686,1687],{},"project("," of its own), Meson",[925,1690,1692],{"id":1691},"related","Related",[1522,1694,1695,1700,1715,1722],{},[1525,1696,1697,1699],{},[522,1698,298],{"href":299},": what connect reads, and how it ranks what it finds.",[1525,1701,1702,1704,1705,1167,1708,1235,1711,1714],{},[522,1703,292],{"href":293},": the ",[514,1706,1707],{},"setup_command",[514,1709,1710],{},"test_command",[514,1712,1713],{},"test_scopes"," fields a proposal fills in.",[1525,1716,1717,1704,1719,1721],{},[522,1718,274],{"href":275},[514,1720,519],{}," flags.",[1525,1723,1724,1726,1727,1729],{},[522,1725,207],{"href":208},": the fix when your ",[514,1728,302],{}," does not load.",[1731,1732,1733],"style",{},"html pre.shiki code .sb7M8, html code.shiki .sb7M8{--shiki-light:#024C1A;--shiki-default:#024C1A;--shiki-dark:#72F088}html pre.shiki code .s7iLA, html code.shiki .s7iLA{--shiki-light:#0E1116;--shiki-default:#0E1116;--shiki-dark:#F0F3F6}html pre.shiki code .ssYy9, html code.shiki .ssYy9{--shiki-light:#023B95;--shiki-default:#023B95;--shiki-dark:#91CBFF}html pre.shiki code .sq92B, html code.shiki .sq92B{--shiki-light:#66707B;--shiki-default:#66707B;--shiki-dark:#BDC4CC}html pre.shiki code .semJd, html code.shiki .semJd{--shiki-light:#032563;--shiki-default:#032563;--shiki-dark:#ADDCFF}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":543,"searchDepth":569,"depth":569,"links":1735},[1736,1738,1739,1741,1742,1743],{"id":927,"depth":569,"text":1737},"Top-​level keys",{"id":1025,"depth":569,"text":1026},{"id":1436,"depth":569,"text":1740},"test and setup",{"id":1512,"depth":569,"text":1308},{"id":1566,"depth":569,"text":1567},{"id":1691,"depth":569,"text":1692},"The keys of detectors.yaml, the file that teaches kraft repo connect your own setup and test conventions, and the toolchains Kraft ships.","md",null,{},true,{"title":302,"description":1744},"3n6aihlf7PvhOABPnUOnXIOWsjLhWKzq1gpfMdolvFs",[1752,1754],{"title":298,"path":299,"stem":300,"description":1753,"children":-1},"What kraft repo connect reads in a repo, where each proposed setup and test command comes from, and what it does when it finds none.",{"title":306,"path":307,"stem":308,"description":1755,"children":-1},"Declare a root repository with member submodules in repos.yaml, and what it means for sandboxing and publication.",1791801261703]