[{"data":1,"prerenderedAt":1273},["ShallowReactive",2],{"docs-nav":3,"cli-commands":159,"docs-\u002Fdocs\u002Fguides\u002Fpro-license":668},[4],{"title":5,"path":6,"stem":7,"children":8},"Docs","\u002Fdocs","docs",[9,22,47,80,101,142,146],{"title":10,"path":11,"stem":12,"children":13},"Getting Started","\u002Fdocs\u002Fgetting-started","docs\u002F1.getting-started\u002Findex",[14,18],{"title":15,"path":16,"stem":17},"Installation","\u002Fdocs\u002Fgetting-started\u002Finstallation","docs\u002F1.getting-started\u002F1.installation",{"title":19,"path":20,"stem":21},"Quick start","\u002Fdocs\u002Fgetting-started\u002Fquick-start","docs\u002F1.getting-started\u002F2.quick-start",{"title":23,"path":24,"stem":25,"children":26},"Concepts","\u002Fdocs\u002Fconcepts","docs\u002F2.concepts\u002Findex",[27,31,35,39,43],{"title":28,"path":29,"stem":30},"Files-first","\u002Fdocs\u002Fconcepts\u002Ffiles-first","docs\u002F2.concepts\u002F1.files-first",{"title":32,"path":33,"stem":34},"The hierarchy","\u002Fdocs\u002Fconcepts\u002Fhierarchy","docs\u002F2.concepts\u002F2.hierarchy",{"title":36,"path":37,"stem":38},"OpenAPI as the source of truth","\u002Fdocs\u002Fconcepts\u002Fopenapi-source-of-truth","docs\u002F2.concepts\u002F3.openapi-source-of-truth",{"title":40,"path":41,"stem":42},"Instance visibility","\u002Fdocs\u002Fconcepts\u002Finstance-visibility","docs\u002F2.concepts\u002F4.instance-visibility",{"title":44,"path":45,"stem":46},"Environments","\u002Fdocs\u002Fconcepts\u002Fenvironments","docs\u002F2.concepts\u002F5.environments",{"title":48,"path":49,"stem":50,"children":51},"Guides","\u002Fdocs\u002Fguides","docs\u002F3.guides\u002Findex",[52,56,60,64,68,72,76],{"title":53,"path":54,"stem":55},"Importing a spec","\u002Fdocs\u002Fguides\u002Fimporting-a-spec","docs\u002F3.guides\u002F1.importing-a-spec",{"title":57,"path":58,"stem":59},"Request instances","\u002Fdocs\u002Fguides\u002Frequest-instances","docs\u002F3.guides\u002F2.request-instances",{"title":61,"path":62,"stem":63},"Auth & middlewares","\u002Fdocs\u002Fguides\u002Fauth-and-middlewares","docs\u002F3.guides\u002F3.auth-and-middlewares",{"title":65,"path":66,"stem":67},"Writing workflows","\u002Fdocs\u002Fguides\u002Fwriting-workflows","docs\u002F3.guides\u002F4.writing-workflows",{"title":69,"path":70,"stem":71},"CI\u002FCD","\u002Fdocs\u002Fguides\u002Fci-cd","docs\u002F3.guides\u002F5.ci-cd",{"title":73,"path":74,"stem":75},"Documenting an API","\u002Fdocs\u002Fguides\u002Fdocumenting-an-api","docs\u002F3.guides\u002F6.documenting-an-api",{"title":77,"path":78,"stem":79},"Pro license","\u002Fdocs\u002Fguides\u002Fpro-license","docs\u002F3.guides\u002F7.pro-license",{"title":81,"path":82,"stem":83,"children":84},"Interface","\u002Fdocs\u002Finterface","docs\u002F4.interface\u002Findex",[85,89,93,97],{"title":86,"path":87,"stem":88},"Navigation","\u002Fdocs\u002Finterface\u002Fnavigation","docs\u002F4.interface\u002F1.navigation",{"title":90,"path":91,"stem":92},"History","\u002Fdocs\u002Finterface\u002Fhistory","docs\u002F4.interface\u002F2.history",{"title":94,"path":95,"stem":96},"Command palette","\u002Fdocs\u002Finterface\u002Fcommand-palette","docs\u002F4.interface\u002F3.command-palette",{"title":98,"path":99,"stem":100},"Keyboard shortcuts","\u002Fdocs\u002Finterface\u002Fkeyboard-shortcuts","docs\u002F4.interface\u002F4.keyboard-shortcuts",{"title":102,"path":103,"stem":104,"children":105},"Reference","\u002Fdocs\u002Freference","docs\u002F5.reference\u002Findex",[106],{"title":107,"path":108,"stem":109,"children":110},"File formats","\u002Fdocs\u002Freference\u002Ffile-formats","docs\u002F5.reference\u002F1.file-formats\u002Findex",[111,115,119,123,126,130,134,138],{"title":112,"path":113,"stem":114},"config.json","\u002Fdocs\u002Freference\u002Ffile-formats\u002Fconfig-json","docs\u002F5.reference\u002F1.file-formats\u002F1.config-json",{"title":116,"path":117,"stem":118},"api.json","\u002Fdocs\u002Freference\u002Ffile-formats\u002Fapi-json","docs\u002F5.reference\u002F1.file-formats\u002F2.api-json",{"title":120,"path":121,"stem":122},"_resource.json","\u002Fdocs\u002Freference\u002Ffile-formats\u002Fresource-json","docs\u002F5.reference\u002F1.file-formats\u002F3.resource-json",{"title":57,"path":124,"stem":125},"\u002Fdocs\u002Freference\u002Ffile-formats\u002Frequest-instance","docs\u002F5.reference\u002F1.file-formats\u002F4.request-instance",{"title":127,"path":128,"stem":129},"Environment files","\u002Fdocs\u002Freference\u002Ffile-formats\u002Fenvironment-schema","docs\u002F5.reference\u002F1.file-formats\u002F5.environment-schema",{"title":131,"path":132,"stem":133},"schema.rules.json","\u002Fdocs\u002Freference\u002Ffile-formats\u002Fschema-rules","docs\u002F5.reference\u002F1.file-formats\u002F6.schema-rules",{"title":135,"path":136,"stem":137},"Documentation files","\u002Fdocs\u002Freference\u002Ffile-formats\u002Fdocumentation","docs\u002F5.reference\u002F1.file-formats\u002F7.documentation",{"title":139,"path":140,"stem":141},"Workflow files","\u002Fdocs\u002Freference\u002Ffile-formats\u002Fworkflow","docs\u002F5.reference\u002F1.file-formats\u002F8.workflow",{"title":143,"path":144,"stem":145},"CLI reference","\u002Fdocs\u002Fcli","docs\u002F6.cli\u002Findex",{"title":147,"path":148,"stem":149,"children":150},"Plugins","\u002Fdocs\u002Fplugins","docs\u002F7.plugins\u002Findex",[151,155],{"title":152,"path":153,"stem":154},"Using plugins","\u002Fdocs\u002Fplugins\u002Fusing-plugins","docs\u002F7.plugins\u002F1.using-plugins",{"title":156,"path":157,"stem":158},"Writing a plugin","\u002Fdocs\u002Fplugins\u002Fwriting-a-plugin","docs\u002F7.plugins\u002F2.writing-a-plugin",{"id":160,"extension":161,"meta":162,"namespaces":163,"stem":665,"version":666,"__hash__":667},"cliCommands\u002Fdata\u002Fcli-commands.json","json",{},[164,201,277,406,422,501,537,608,640],{"namespace":165,"description":166,"commands":167,"seeAlso":198},"project","Create and validate an API Craft project.",[168,178,183,192],{"name":169,"usage":170,"description":171,"flags":172,"examples":176},"init","craftr project init \u003Cname> [--private]","Initialize an API Craft project in the current directory.",[173],{"name":174,"description":175},"--private","Mark the project as private (gitignore the apis directory and .api-craft).",[177],"craftr project init \"Petstore Project\"",{"name":179,"usage":180,"description":181,"flags":182},"validate","craftr project validate","Validate the project structure and report problems.",[],{"name":184,"usage":185,"description":186,"examples":187,"seeAlso":188},"trust","craftr project trust","Approve this project so its scripts (middlewares, custom auth, workflow scripts) can run. Persists until untrusted.",[185],[189],{"label":190,"to":191},"Auth & middlewares: middlewares","\u002Fdocs\u002Fguides\u002Fauth-and-middlewares#middlewares",{"name":193,"usage":194,"description":195,"seeAlso":196},"untrust","craftr project untrust","Refuse this project, blocking its scripts until it is trusted again.",[197],{"label":190,"to":191},[199,200],{"label":28,"to":29},{"label":19,"to":20},{"namespace":202,"description":203,"commands":204,"seeAlso":273},"api","Manage APIs and their default auth and overrides.",[205,210,223,229,242,261,267],{"name":206,"usage":207,"description":208,"flags":209},"list","craftr api list","List the APIs in the project.",[],{"name":211,"usage":212,"description":213,"flags":214,"examples":220},"create","craftr api create --api \u003Capi>","Create a new API.",[215],{"name":216,"short":217,"description":218,"takesValue":219,"required":219},"--api","-a","API slug.",true,[221,222],"craftr api create --api petstore-api","craftr api create -a petstore-api",{"name":224,"usage":225,"description":226,"flags":227},"delete","craftr api delete --api \u003Capi>","Delete an API.",[228],{"name":216,"short":217,"description":218,"takesValue":219,"required":219},{"name":230,"usage":231,"description":232,"flags":233,"examples":238,"seeAlso":240},"set auth bearer","craftr api set auth bearer --token \u003Ctoken> [--api \u003Capi>]","Set the API default auth to a bearer token. Supports {{variables}}.",[234,237],{"name":235,"description":236,"takesValue":219,"required":219},"--token","Bearer token value. Supports {{variables}}.",{"name":216,"short":217,"description":218,"takesValue":219},[239],"craftr api set auth bearer --token \"{{apiKey}}\" --api petstore-api",[241],{"label":61,"to":62},{"name":243,"usage":244,"description":245,"flags":246,"examples":257,"seeAlso":259},"set auth api-key","craftr api set auth api-key --in \u003Cheader|query> --name \u003Cname> --value \u003Cvalue> [--api \u003Capi>]","Set the API default auth to an API key sent as a header or query parameter.",[247,250,253,256],{"name":248,"description":249,"takesValue":219,"required":219},"--in","Where to send the key: header or query.",{"name":251,"description":252,"takesValue":219,"required":219},"--name","Header or query parameter name.",{"name":254,"description":255,"takesValue":219,"required":219},"--value","API key value. Supports {{variables}}.",{"name":216,"short":217,"description":218,"takesValue":219},[258],"craftr api set auth api-key --in header --name api_key --value \"{{apiKey}}\" -a petstore-api",[260],{"label":61,"to":62},{"name":262,"usage":263,"description":264,"flags":265},"unset auth","craftr api unset auth [--api \u003Capi>]","Clear the API default auth.",[266],{"name":216,"short":217,"description":218,"takesValue":219},{"name":268,"usage":269,"description":270,"flags":271},"overrides","craftr api overrides [--api \u003Capi>]","List all overrides for an API, grouped by kind (api, resource, operation, parameter).",[272],{"name":216,"short":217,"description":218,"takesValue":219},[274,275],{"label":61,"to":62},{"label":276,"to":117},"api.json format",{"namespace":278,"description":279,"commands":280,"seeAlso":403},"schema","Import an OpenAPI spec and manage the resource\u002Foperation mapping.",[281,302,308,314,320,326,334,349,355,361,370,376,382,397],{"name":282,"usage":283,"description":284,"flags":285,"examples":297,"seeAlso":300},"import","craftr schema import [source] [--api \u003Capi>] [--yes] [--no-persist-source] [--no-auto-clear-caught-up]","Import an OpenAPI spec: preview the diff, resolve conflicts, write, and remap. Source may be a file path or URL; omit to use the saved source or piped stdin.",[286,287,291,294],{"name":216,"short":217,"description":218,"takesValue":219},{"name":288,"short":289,"description":290},"--yes","-y","Skip the apply confirmation (required for non-interactive use).",{"name":292,"description":293},"--no-persist-source","Do not persist the spec source in api.json when a path or URL is given. Ignored for stdin and for a saved source.",{"name":295,"description":296},"--no-auto-clear-caught-up","Keep overrides whose value already matches the new source.",[298,299],"craftr schema import .\u002Fopenapi.json -a petstore-api","craftr schema import https:\u002F\u002Fpetstore3.swagger.io\u002Fapi\u002Fv3\u002Fopenapi.json -a petstore-api --yes",[301],{"label":53,"to":54},{"name":303,"usage":304,"description":305,"flags":306},"diff","craftr schema diff [source] [--api \u003Capi>]","Preview the diff between the current schema and a candidate spec. Uses the persisted source if no path is given.",[307],{"name":216,"short":217,"description":218,"takesValue":219},{"name":309,"usage":310,"description":311,"flags":312},"read","craftr schema read [--api \u003Capi>]","Read the effective schema (resources, unmapped, ignored, orphan rules).",[313],{"name":216,"short":217,"description":218,"takesValue":219},{"name":315,"usage":316,"description":317,"flags":318},"unmapped","craftr schema unmapped [--api \u003Capi>]","List operations that are not mapped to any resource.",[319],{"name":216,"short":217,"description":218,"takesValue":219},{"name":321,"usage":322,"description":323,"flags":324},"ignored","craftr schema ignored [--api \u003Capi>]","List ignored operations with their rule ids.",[325],{"name":216,"short":217,"description":218,"takesValue":219},{"name":327,"usage":328,"description":329,"flags":330,"examples":332},"map","craftr schema map \u003Coperation-id> \u003Cresource> \u003Coperation> [--api \u003Capi>]","Map an unmapped operation to a resource and operation name.",[331],{"name":216,"short":217,"description":218,"takesValue":219},[333],"craftr schema map updatePetWithForm Pet updateWithForm -a petstore-api",{"name":335,"usage":336,"description":337,"flags":338},"map-all","craftr schema map-all (--from \u003Cfile> | --default | --skip-all) [--api \u003Capi>]","Bulk-map every unmapped operation. Choose exactly one mode.",[339,342,345,348],{"name":340,"description":341,"takesValue":219},"--from","Path to a JSON array of {operationId, resource, operation, skip?}. Use \"-\" for stdin.",{"name":343,"description":344},"--default","Apply heuristic defaults to every unmapped operation.",{"name":346,"description":347},"--skip-all","Add an ignore rule for every unmapped operation.",{"name":216,"short":217,"description":218,"takesValue":219},{"name":350,"usage":351,"description":352,"flags":353},"rename operation","craftr schema rename operation \u003Cresource> \u003Coperation-name> \u003Cnew-name> [--api \u003Capi>]","Rename a single operation within a resource.",[354],{"name":216,"short":217,"description":218,"takesValue":219},{"name":356,"usage":357,"description":358,"flags":359},"rename resource","craftr schema rename resource \u003Cold-slug> \u003Cnew-slug> [--api \u003Capi>]","Rename a resource.",[360],{"name":216,"short":217,"description":218,"takesValue":219},{"name":362,"usage":363,"description":364,"flags":365},"set-parent","craftr schema set-parent \u003Cresource> [parent] [--clear] [--api \u003Capi>]","Set or clear the parent of a resource. Provide a parent or pass --clear, not both.",[366,369],{"name":367,"description":368},"--clear","Clear the parent instead of setting it.",{"name":216,"short":217,"description":218,"takesValue":219},{"name":371,"usage":372,"description":373,"flags":374},"ignore","craftr schema ignore \u003Coperation-id> [--api \u003Capi>]","Ignore an operation. It is removed from the effective schema.",[375],{"name":216,"short":217,"description":218,"takesValue":219},{"name":377,"usage":378,"description":379,"flags":380},"unignore","craftr schema unignore \u003Coperation-id> [--api \u003Capi>]","Remove an ignore rule by operationId.",[381],{"name":216,"short":217,"description":218,"takesValue":219},{"name":383,"usage":384,"description":385,"flags":386},"define","craftr schema define \u003Cresource> \u003Cname> --method \u003Cmethod> --path \u003Cpath> --operation-id \u003Cid> [--api \u003Capi>]","Define a local operation that does not exist in the source spec. Creates the resource if new.",[387,390,393,396],{"name":388,"description":389,"takesValue":219,"required":219},"--method","HTTP method (GET, POST, …).",{"name":391,"description":392,"takesValue":219,"required":219},"--path","OpenAPI path, e.g. \u002Fpet\u002F{petId}\u002Fvaccinations.",{"name":394,"description":395,"takesValue":219,"required":219},"--operation-id","Unique operationId.",{"name":216,"short":217,"description":218,"takesValue":219},{"name":398,"usage":399,"description":400,"flags":401},"undefine","craftr schema undefine \u003Cresource> \u003Cname> [--api \u003Capi>]","Delete a locally-defined operation.",[402],{"name":216,"short":217,"description":218,"takesValue":219},[404,405],{"label":53,"to":54},{"label":36,"to":37},{"namespace":407,"description":408,"commands":409,"seeAlso":420},"spec","Read the OpenAPI spec.",[410],{"name":309,"usage":411,"description":412,"flags":413,"examples":418},"craftr spec read [--api \u003Capi>] [--imported]","Print the effective OpenAPI spec, or the raw imported spec with --imported.",[414,415],{"name":216,"short":217,"description":218,"takesValue":219},{"name":416,"description":417},"--imported","Print the raw imported spec (spec.imported.json) instead of the projected one.",[419],"craftr spec read -a petstore-api | jq '.paths | keys'",[421],{"label":36,"to":37},{"namespace":423,"description":424,"commands":425,"seeAlso":497},"req","List, run, and manage request instances.",[426,439,474,480,486],{"name":206,"usage":427,"description":428,"flags":429},"craftr req list [--resource \u003Cresource>] [--filter \u003Ctext>] [--api \u003Capi>]","List request instances, optionally filtered.",[430,434,438],{"name":431,"short":432,"description":433,"takesValue":219},"--resource","-r","Resource slug to list. Omit to list every request.",{"name":435,"short":436,"description":437,"takesValue":219},"--filter","-f","Case-insensitive substring matched against resource and request name.",{"name":216,"short":217,"description":218,"takesValue":219},{"name":440,"usage":441,"description":442,"flags":443,"examples":465,"seeAlso":469},"run","craftr req run \u003Cresource\u002Fname> --env \u003Cenv> [--api \u003Capi>] [--var \u003Ck=v>…] [--set \u003Cns.k=v>…] [--full] [--trust] [--verbose]","Execute a request instance against an environment. Prints the response body by default.",[444,448,449,452,455,458,461],{"name":445,"short":446,"description":447,"takesValue":219,"required":219},"--env","-e","Environment name.",{"name":216,"short":217,"description":218,"takesValue":219},{"name":450,"description":451,"takesValue":219,"repeatable":219},"--var","Override an environment variable: key=value. The variable must be declared in the environment schema.",{"name":453,"description":454,"takesValue":219,"repeatable":219},"--set","Override a request parameter: \u003Cpath|query|header|body>.key=value. Body keys support dot-notation.",{"name":456,"description":457},"--full","Print the full execution result instead of just the response body.",{"name":459,"description":460},"--trust","Allow this project's scripts to run for this invocation only. Never saved.",{"name":462,"short":463,"description":464},"--verbose","-v","Print the trace to stderr. -v is info, -vv adds debug.",[466,467,468],"craftr req run Pet\u002Fget-pet -e dev","craftr req run Pet\u002Fget-pet -e dev --set path.petId=3 | jq '.name'","craftr req run Pet\u002Fget-pet -e dev --var apiKey=sk-test --full",[470,473],{"label":471,"to":472},"Request instances: running","\u002Fdocs\u002Fguides\u002Frequest-instances#running",{"label":69,"to":70},{"name":475,"usage":476,"description":477,"flags":478},"duplicate","craftr req duplicate \u003Cresource\u002Fname> \u003Cnew-name> [--api \u003Capi>]","Duplicate a request instance. The copy is created as private.",[479],{"name":216,"short":217,"description":218,"takesValue":219},{"name":481,"usage":482,"description":483,"flags":484},"rename","craftr req rename \u003Cresource\u002Fname> \u003Cnew-name> [--api \u003Capi>]","Rename a request instance.",[485],{"name":216,"short":217,"description":218,"takesValue":219},{"name":487,"usage":488,"description":489,"flags":490,"seeAlso":495},"set-visibility","craftr req set-visibility \u003Cresource\u002Fname> \u003Cpublic|private> [--new-name \u003Cname>] [--api \u003Capi>]","Change a request instance's visibility (public or private).",[491,494],{"name":492,"description":493,"takesValue":219},"--new-name","Rename the request as it changes visibility.",{"name":216,"short":217,"description":218,"takesValue":219},[496],{"label":40,"to":41},[498,499],{"label":57,"to":58},{"label":500,"to":124},"Request instance format",{"namespace":502,"description":503,"commands":504,"seeAlso":533},"env","Manage environments and their values.",[505,510,515,523,528],{"name":206,"usage":506,"description":507,"flags":508},"craftr env list [--api \u003Capi>]","List environments.",[509],{"name":216,"short":217,"description":218,"takesValue":219},{"name":309,"usage":511,"description":512,"flags":513},"craftr env read \u003Cenv> [--api \u003Capi>]","Read an environment's values, with the extends chain resolved.",[514],{"name":216,"short":217,"description":218,"takesValue":219},{"name":516,"usage":517,"description":518,"flags":519,"examples":521},"write","craftr env write \u003Cenv> \u003Ckey> \u003Cvalue> [--api \u003Capi>]","Write a single environment variable. The value is JSON-parsed if it is a valid scalar, otherwise stored as a string.",[520],{"name":216,"short":217,"description":218,"takesValue":219},[522],"craftr env write dev baseUrl https:\u002F\u002Fpetstore3.swagger.io\u002Fapi\u002Fv3",{"name":224,"usage":524,"description":525,"flags":526},"craftr env delete \u003Cenv> [--api \u003Capi>]","Delete an environment.",[527],{"name":216,"short":217,"description":218,"takesValue":219},{"name":481,"usage":529,"description":530,"flags":531},"craftr env rename \u003Cold-name> \u003Cnew-name> [--api \u003Capi>]","Rename an environment.",[532],{"name":216,"short":217,"description":218,"takesValue":219},[534,535],{"label":44,"to":45},{"label":536,"to":128},"Environment schema format",{"namespace":538,"description":539,"commands":540,"seeAlso":604},"workflow","Run project-scoped workflows.",[541,574,578,584,595,598,601],{"name":440,"usage":542,"description":543,"flags":544,"examples":565,"seeAlso":569},"craftr workflow run [\u003Cworkflow>...] [--all] --env \u003Capi>=\u003Cenv> [--input ...] [--concurrency \u003Cn>] [--on-failure halt|continue] [--full-output \u003Cfile>] [--trust]","Run one or more workflows (or every workflow with --all) and aggregate the results. Prints a JSON summary report on stdout, a human summary on stderr, and exits 1 if any workflow failed (130 if cancelled).",[545,548,550,553,556,559,561,564],{"name":546,"description":547},"--all","Run every workflow in the project. Mutually exclusive with named workflows.",{"name":445,"short":446,"description":549,"takesValue":219,"required":219,"repeatable":219},"Bind an environment to an API: \u003Capi>=\u003Cenv>. Repeat once per API the run touches (the union across a batch).",{"name":551,"description":552,"takesValue":219,"repeatable":219},"--input","Workflow input: [\u003Cworkflow>:]\u003Ckey>=\u003Cvalue>. Without a workflow prefix it applies to every workflow in the batch.",{"name":554,"description":555,"takesValue":219},"--concurrency","Workflows in flight at once (default 4). 1 runs them sequentially.",{"name":557,"description":558,"takesValue":219},"--on-failure","halt stops starting new workflows after a failure; continue (default) runs them all. Separate from a workflow file's own onFailure, which governs blocks within a run.",{"name":462,"short":463,"description":560},"Progress and traces to stderr: -v workflow level, -vv block logs, -vvv debug.",{"name":562,"description":563,"takesValue":219},"--full-output","Write the complete run result (every block and response) to this file. Omitted, that detail is discarded.",{"name":459,"description":460},[566,567,568],"craftr workflow run pet-lifecycle --env petstore-api=prod","craftr workflow run publish-and-verify -e petstore-api=prod -e catalog=staging","craftr workflow run --all -e petstore-api=prod -e catalog=staging",[570,573],{"label":571,"to":572},"Writing workflows: from the CLI","\u002Fdocs\u002Fguides\u002Fwriting-workflows#from-the-cli",{"label":69,"to":70},{"name":206,"usage":575,"description":576,"examples":577},"craftr workflow list","List every workflow in the project.",[575],{"name":179,"usage":579,"description":580,"examples":581},"craftr workflow validate [\u003Cworkflow>...]","Check that a workflow's references resolve (api, resource, operation, instance, scripts) and refresh the generated script typings. Omit the name to check every workflow. Sends no request, so it is cheap to run in CI before a run.",[582,583],"craftr workflow validate","craftr workflow validate pet-lifecycle",{"name":585,"usage":586,"description":587,"flags":588,"examples":592},"history","craftr workflow history [\u003Crun-id>] [--limit \u003Cn>]","List past workflow runs newest first, or read one run in full by id. Run ids are the ISO timestamp of the run with \":\" replaced by \"-\".",[589],{"name":590,"description":591,"takesValue":219},"--limit","Keep only the first N summaries. Ignored when an id is given.",[593,594],"craftr workflow history --limit 5","craftr workflow history 2026-08-23T10-14-02.981Z",{"name":481,"usage":596,"description":597},"craftr workflow rename \u003Cold-name> \u003Cnew-name>","Rename a workflow, its scripts directory included.",{"name":475,"usage":599,"description":600},"craftr workflow duplicate \u003Csource-name> \u003Cnew-name>","Duplicate a workflow, its scripts directory included.",{"name":224,"usage":602,"description":603},"craftr workflow delete \u003Cworkflow-name>","Delete a workflow and its scripts directory.",[605,606],{"label":65,"to":66},{"label":607,"to":140},"Workflow file format",{"namespace":609,"description":610,"commands":611,"seeAlso":635},"license","Install, inspect or remove the Pro license. Per user, not per project, so these work from any directory.",[612,623,629],{"name":613,"usage":614,"description":615,"flags":616,"examples":620},"install","craftr license install [--file \u003Cpath>]","Install a license from a file or from stdin. Verifies the signature first; on failure the current license, if any, is left in place.",[617],{"name":618,"description":619,"takesValue":219},"--file","Path to the license file. Reads stdin when omitted.",[621,622],"craftr license install --file=license.key","cat license.key | craftr license install",{"name":624,"usage":625,"description":626,"flags":627,"examples":628},"get","craftr license get","Print the active license state as JSON: status, tier, who it is issued to, expiry, features and limits. A limit of -1 means unlimited.",[],[625],{"name":630,"usage":631,"description":632,"flags":633,"examples":634},"remove","craftr license remove","Delete the installed license and fall back to the Free plan. Prints the resulting state.",[],[631],[636,637],{"label":77,"to":78},{"label":638,"to":639},"Pricing","\u002Fpricing",{"namespace":641,"description":642,"commands":643,"seeAlso":662},"completion","Shell tab-completion management.",[644,654],{"name":613,"usage":645,"description":646,"flags":647,"examples":651},"craftr completion install [--shell \u003Cbash|zsh|fish>]","Install shell tab-completion. Writes the completion script and, for bash and zsh, adds a marked block to the shell rc file that sources it.",[648],{"name":649,"description":650,"takesValue":219},"--shell","bash, zsh or fish. Defaults to the shell named by $SHELL.",[652,653],"craftr completion install","craftr completion install --shell fish",{"name":655,"usage":656,"description":657,"flags":658,"examples":660},"uninstall","craftr completion uninstall [--shell \u003Cbash|zsh|fish>]","Remove the completion script and the block it added to the shell rc file.",[659],{"name":649,"description":650,"takesValue":219},[661],"craftr completion uninstall",[663],{"label":15,"to":664},"\u002Fdocs\u002Fgetting-started\u002Finstallation#tab-completion","data\u002Fcli-commands",1,"wkEyqz4vOf0W24NAkAJY-4EyLZpK5NBQO7YE9JmKeUw",{"id":669,"title":77,"body":670,"description":1267,"extension":1268,"meta":1269,"navigation":1270,"path":78,"seo":1271,"stem":79,"__hash__":1272},"docs\u002Fdocs\u002F3.guides\u002F7.pro-license.md",{"type":671,"value":672,"toc":1254},"minimark",[673,677,681,686,694,702,706,711,727,732,735,739,742,770,773,798,801,805,808,816,827,831,836,999,1008,1012,1015,1094,1105,1108,1112,1115,1122,1128,1132,1139,1153,1156,1160,1242,1250],[674,675,77],"h1",{"id":676},"pro-license",[678,679,680],"p",{},"A Pro license is a single signed file. Nothing phones home, nothing is bound to a machine: the\napp verifies the signature locally against a public key it ships with, and that is the whole\ncheck. Install the file once per user and every project on that machine is Pro.",[682,683,685],"h2",{"id":684},"what-you-receive","What you receive",[678,687,688,689,693],{},"Within 24 hours of ",[690,691,692],"a",{"href":639},"buying Pro"," you get an email with the license attached as a\none-line text file. It carries who it was issued to, the tier, the issue and expiry dates, and\nthe limits, all signed, so nothing in it can be edited.",[678,695,696,697,701],{},"The license is per ",[698,699,700],"strong",{},"person",", not per machine or per project. Install the same file on every\ncomputer you use.",[682,703,705],{"id":704},"install-it","Install it",[707,708,710],"h3",{"id":709},"from-the-app","From the app",[678,712,713,714,717,718,722,723,726],{},"Open ",[698,715,716],{},"Settings"," (the gear in the header, or ",[719,720,721],"code",{},"Ctrl+Alt+S",") and pick the ",[698,724,725],{},"License"," tab.\nDrop the file on the drop zone, or click it to browse.",[728,729],"screenshot",{"alt":730,"src":731},"The License tab in Settings, with the drop zone and the details of an installed license","\u002Fimages\u002Fguides\u002Flicense-settings.png",[678,733,734],{},"The panel switches to the license's details as soon as the signature checks out: status,\nplan, who it is licensed to, and the expiry date. Nothing to restart: the daemon picks the\nfile up the moment it is written.",[707,736,738],{"id":737},"from-the-cli","From the CLI",[678,740,741],{},"Same result, useful on a headless machine or in a dotfiles script:",[743,744,749],"pre",{"className":745,"code":746,"language":747,"meta":748,"style":748},"language-bash shiki shiki-themes github-light github-dark","craftr license install --file=license.key\n","bash","",[719,750,751],{"__ignoreMap":748},[752,753,755,759,763,766],"span",{"class":754,"line":666},"line",[752,756,758],{"class":757},"sScJk","craftr",[752,760,762],{"class":761},"sZZnC"," license",[752,764,765],{"class":761}," install",[752,767,769],{"class":768},"sj4cs"," --file=license.key\n",[678,771,772],{},"Or pipe it in:",[743,774,776],{"className":745,"code":775,"language":747,"meta":748,"style":748},"cat license.key | craftr license install\n",[719,777,778],{"__ignoreMap":748},[752,779,780,783,786,790,793,795],{"class":754,"line":666},[752,781,782],{"class":757},"cat",[752,784,785],{"class":761}," license.key",[752,787,789],{"class":788},"szBVR"," |",[752,791,792],{"class":757}," craftr",[752,794,762],{"class":761},[752,796,797],{"class":761}," install\n",[678,799,800],{},"Both work outside a project directory. On success the command prints the resulting license\nstate as JSON; on failure it says why and leaves whatever license was already installed\nuntouched.",[707,802,804],{"id":803},"by-hand","By hand",[678,806,807],{},"The app and the CLI both just write the file to:",[743,809,814],{"className":810,"code":812,"language":813},[811],"language-text","~\u002F.config\u002Fapi-craft\u002Flicense.key\n","text",[719,815,812],{"__ignoreMap":748},[678,817,818,819,822,823,826],{},"(or ",[719,820,821],{},"$XDG_CONFIG_HOME\u002Fapi-craft\u002Flicense.key"," if you set ",[719,824,825],{},"XDG_CONFIG_HOME","). Copying the file\nthere yourself is equivalent.",[682,828,830],{"id":829},"check-its-status","Check its status",[678,832,833,835],{},[719,834,625],{}," prints the active state:",[743,837,840],{"className":838,"code":839,"language":161,"meta":748,"style":748},"language-json shiki shiki-themes github-light github-dark","{\n  \"status\": \"active\",\n  \"tier\": \"pro\",\n  \"issuedTo\": { \"name\": \"Ada Lovelace\", \"email\": \"ada@example.com\" },\n  \"issuedAt\": \"2026-09-10T00:00:00.000Z\",\n  \"expiresAt\": \"2027-09-10T00:00:00.000Z\",\n  \"daysUntilExpiry\": 365,\n  \"limits\": { \"maxApis\": -1, \"maxEnvironments\": -1, \"maxWorkflows\": -1, \"maxHistoryPerApi\": 100 }\n}\n",[719,841,842,848,863,876,907,920,933,946,993],{"__ignoreMap":748},[752,843,844],{"class":754,"line":666},[752,845,847],{"class":846},"sVt8B","{\n",[752,849,851,854,857,860],{"class":754,"line":850},2,[752,852,853],{"class":768},"  \"status\"",[752,855,856],{"class":846},": ",[752,858,859],{"class":761},"\"active\"",[752,861,862],{"class":846},",\n",[752,864,866,869,871,874],{"class":754,"line":865},3,[752,867,868],{"class":768},"  \"tier\"",[752,870,856],{"class":846},[752,872,873],{"class":761},"\"pro\"",[752,875,862],{"class":846},[752,877,879,882,885,888,890,893,896,899,901,904],{"class":754,"line":878},4,[752,880,881],{"class":768},"  \"issuedTo\"",[752,883,884],{"class":846},": { ",[752,886,887],{"class":768},"\"name\"",[752,889,856],{"class":846},[752,891,892],{"class":761},"\"Ada Lovelace\"",[752,894,895],{"class":846},", ",[752,897,898],{"class":768},"\"email\"",[752,900,856],{"class":846},[752,902,903],{"class":761},"\"ada@example.com\"",[752,905,906],{"class":846}," },\n",[752,908,910,913,915,918],{"class":754,"line":909},5,[752,911,912],{"class":768},"  \"issuedAt\"",[752,914,856],{"class":846},[752,916,917],{"class":761},"\"2026-09-10T00:00:00.000Z\"",[752,919,862],{"class":846},[752,921,923,926,928,931],{"class":754,"line":922},6,[752,924,925],{"class":768},"  \"expiresAt\"",[752,927,856],{"class":846},[752,929,930],{"class":761},"\"2027-09-10T00:00:00.000Z\"",[752,932,862],{"class":846},[752,934,936,939,941,944],{"class":754,"line":935},7,[752,937,938],{"class":768},"  \"daysUntilExpiry\"",[752,940,856],{"class":846},[752,942,943],{"class":768},"365",[752,945,862],{"class":846},[752,947,949,952,954,957,959,962,964,967,969,971,973,976,978,980,982,985,987,990],{"class":754,"line":948},8,[752,950,951],{"class":768},"  \"limits\"",[752,953,884],{"class":846},[752,955,956],{"class":768},"\"maxApis\"",[752,958,856],{"class":846},[752,960,961],{"class":768},"-1",[752,963,895],{"class":846},[752,965,966],{"class":768},"\"maxEnvironments\"",[752,968,856],{"class":846},[752,970,961],{"class":768},[752,972,895],{"class":846},[752,974,975],{"class":768},"\"maxWorkflows\"",[752,977,856],{"class":846},[752,979,961],{"class":768},[752,981,895],{"class":846},[752,983,984],{"class":768},"\"maxHistoryPerApi\"",[752,986,856],{"class":846},[752,988,989],{"class":768},"100",[752,991,992],{"class":846}," }\n",[752,994,996],{"class":754,"line":995},9,[752,997,998],{"class":846},"}\n",[678,1000,1001,1003,1004,1007],{},[719,1002,961],{}," in a limit means unlimited. In the app, the header shows a ",[698,1005,1006],{},"Pro"," badge next to the\nname on the license.",[682,1009,1011],{"id":1010},"when-it-expires","When it expires",[678,1013,1014],{},"A license is valid for one year from issue. It does not renew on its own: there is no\nsubscription and nothing is charged again. The app walks you through the end of the term:",[1016,1017,1018,1034],"table",{},[1019,1020,1021],"thead",{},[1022,1023,1024,1028,1031],"tr",{},[1025,1026,1027],"th",{},"Status",[1025,1029,1030],{},"When",[1025,1032,1033],{},"What you see",[1035,1036,1037,1051,1068,1081],"tbody",{},[1022,1038,1039,1045,1048],{},[1040,1041,1042],"td",{},[719,1043,1044],{},"active",[1040,1046,1047],{},"More than 30 days left",[1040,1049,1050],{},"Nothing.",[1022,1052,1053,1058,1061],{},[1040,1054,1055],{},[719,1056,1057],{},"expiring",[1040,1059,1060],{},"Last 30 days",[1040,1062,1063,1064,1067],{},"A banner with the expiry date and a ",[698,1065,1066],{},"Renew"," button pointing at the pricing page. Pro limits still apply.",[1022,1069,1070,1075,1078],{},[1040,1071,1072],{},[719,1073,1074],{},"grace",[1040,1076,1077],{},"Up to 14 days past expiry",[1040,1079,1080],{},"A banner asking you to renew before the grace period ends. Pro limits still apply, nothing locks.",[1022,1082,1083,1088,1091],{},[1040,1084,1085],{},[719,1086,1087],{},"expired",[1040,1089,1090],{},"Past the grace period",[1040,1092,1093],{},"A permanent banner. The app runs on Free limits.",[678,1095,1096,1097,1100,1101,1104],{},"Every banner also offers ",[698,1098,1099],{},"Import a license",", which opens the Settings tab, and ",[698,1102,1103],{},"I haven't\nreceived it",", which opens a mail to support.",[678,1106,1107],{},"Renewing means buying another year and installing the new file over the old one.",[682,1109,1111],{"id":1110},"what-free-mode-means","What Free mode means",[678,1113,1114],{},"When a license expires, or when you have none, Free limits apply, but nothing on disk\nchanges. Your files are plain JSON in your repository and stay exactly as they were.",[678,1116,1117,1118,1121],{},"The limits are counted against what already exists. If a project has more of something than\nFree allows, the app ",[698,1119,1120],{},"locks its use of the extras"," rather than deleting anything: sorted by\nname, everything past the limit can no longer be edited or run. The app shows a panel\nexplaining why, the CLI refuses with an error. Delete an item to free the next one, or install\na license and everything opens again.",[1123,1124,1125],"note",{},[678,1126,1127],{},"The lock is in the app, not on the files. A locked API is still in your repository, still\ncommitted, still readable by anything else. API Craft just declines to work on it until you\nare back under the limit.",[682,1129,1131],{"id":1130},"remove-a-license","Remove a license",[678,1133,1134,1135,1138],{},"Settings → License → ",[698,1136,1137],{},"Remove license",", or:",[743,1140,1142],{"className":745,"code":1141,"language":747,"meta":748,"style":748},"craftr license remove\n",[719,1143,1144],{"__ignoreMap":748},[752,1145,1146,1148,1150],{"class":754,"line":666},[752,1147,758],{"class":757},[752,1149,762],{"class":761},[752,1151,1152],{"class":761}," remove\n",[678,1154,1155],{},"The app returns to the Free plan immediately. Your projects are not touched, and the same\nfile can be installed again at any time.",[682,1157,1159],{"id":1158},"if-something-goes-wrong","If something goes wrong",[1016,1161,1162,1175],{},[1019,1163,1164],{},[1022,1165,1166,1169,1172],{},[1025,1167,1168],{},"Message",[1025,1170,1171],{},"Cause",[1025,1173,1174],{},"What to do",[1035,1176,1177,1191,1204,1217,1229],{},[1022,1178,1179,1185,1188],{},[1040,1180,1181],{},[1182,1183,1184],"em",{},"This file is not a valid license.",[1040,1186,1187],{},"Wrong file, or the text was altered; a stray line break from a mail client is enough.",[1040,1189,1190],{},"Save the attachment again without opening it in an editor.",[1022,1192,1193,1198,1201],{},[1040,1194,1195],{},[1182,1196,1197],{},"This license signature is invalid.",[1040,1199,1200],{},"The content no longer matches its signature.",[1040,1202,1203],{},"Same as above. If it persists, ask support for a reissue.",[1022,1205,1206,1211,1214],{},[1040,1207,1208],{},[1182,1209,1210],{},"This license was signed with an unknown key.",[1040,1212,1213],{},"Your app is older than the key that signed the license.",[1040,1215,1216],{},"Update API Craft.",[1022,1218,1219,1224,1227],{},[1040,1220,1221],{},[1182,1222,1223],{},"This license was issued for a newer version of API Craft.",[1040,1225,1226],{},"Same, at the file-format level.",[1040,1228,1216],{},[1022,1230,1231,1236,1239],{},[1040,1232,1233],{},[1182,1234,1235],{},"This license has already expired.",[1040,1237,1238],{},"The file you are installing is past its grace period.",[1040,1240,1241],{},"Nothing is overwritten. Buy a new one, or install the current file instead.",[678,1243,1244,1245,1249],{},"Nothing after 24 hours from purchase? Check spam, then write to\n",[690,1246,1248],{"href":1247},"mailto:support@api-craft.dev","support@api-craft.dev"," with the order number from your Paddle\nreceipt.",[1251,1252,1253],"style",{},"html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}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 .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}",{"title":748,"searchDepth":850,"depth":850,"links":1255},[1256,1257,1262,1263,1264,1265,1266],{"id":684,"depth":850,"text":685},{"id":704,"depth":850,"text":705,"children":1258},[1259,1260,1261],{"id":709,"depth":865,"text":710},{"id":737,"depth":865,"text":738},{"id":803,"depth":865,"text":804},{"id":829,"depth":850,"text":830},{"id":1010,"depth":850,"text":1011},{"id":1110,"depth":850,"text":1111},{"id":1130,"depth":850,"text":1131},{"id":1158,"depth":850,"text":1159},"Install the license file you receive after buying Pro, check its status, and know what happens when it expires.","md",{},null,{"title":77,"description":1267},"8iRwDxVrGJ9oiqw0OuIKYREDzMvjnmuLm0r1VNq-Ess",1789469405691]