[{"data":1,"prerenderedAt":2947},["ShallowReactive",2],{"navigation":3,"page:\u002Fconcepts\u002Fprograms-and-versions":1019,"surround:\u002Fconcepts\u002Fprograms-and-versions":2939},[4,21,82,133,154,1010],[5,6,7,8],"Getting started","\u002Fgetting-started","i-lucide-rocket",[9,12,15,18],[10,6,11,11],"What Kaabist is",0,[13,14,11,11],"API keys and modes","keys-and-modes",[16,17,11,11],"Your first job","first-job",[19,20,11,11],"Understanding the envelope","envelope",[22,23,24,25],"Concepts","\u002Fconcepts","i-lucide-book-open",[26,28,31,34,37,40,43,46,49,52,55,58,61,64,67,70,73,76,79],[27,23,11,11],"Overview",[29,30,11,11],"Programs and versions","programs-and-versions",[32,33,11,11],"Tiers and escalation","tiers-and-escalation",[35,36,11,11],"The http tier","http-tier",[38,39,11,11],"The browser tier","browser-tier",[41,42,11,11],"Sessions","sessions",[44,45,11,11],"Human in the loop","human-in-the-loop",[47,48,11,11],"How healing works","self-healing",[50,51,11,11],"Obstacles and captchas","obstacles",[53,54,11,11],"Validation and warnings","validation-and-warnings",[56,57,11,11],"Credits and billing","credits-and-billing",[59,60,11,11],"Limits","limits",[62,63,11,11],"Locators","locators",[65,66,11,11],"Snapshots","snapshots",[68,69,11,11],"Egress and proxies","egress-and-proxies",[71,72,11,11],"Queueing and fairness","queueing",[74,75,11,11],"Accounts, organisations and roles","accounts-and-roles",[77,78,11,11],"Data retention","data-retention",[80,81,11,11],"Documents and PDFs","documents-and-pdfs",[83,84,85,86],"Guides","\u002Fguides","i-lucide-map",[87,88,91,94,97,100,103,106,109,112,115,118,121,124,127,130],[27,84,11,11],[89,90,11,11],"Authenticated flows","authenticated-flows",[92,93,11,11],"Hosted resolve pages","hosted-resolve",[95,96,11,11],"Lists and pagination","lists-and-pagination",[98,99,11,11],"JSON and network locators","json-and-network-locators",[101,102,11,11],"Schedules and change detection","schedules-and-change-detection",[104,105,11,11],"Webhooks","webhooks",[107,108,11,11],"Bring your own providers","byo-providers",[110,111,11,11],"Testing: replay, dry-run and test mode","testing",[113,114,11,11],"Side-effect safety","side-effect-safety",[116,117,11,11],"Security & data handling","security-and-data",[119,120,11,11],"Migrating from other tools","migrating",[122,123,11,11],"Drift detection and canaries","drift-and-canaries",[125,126,11,11],"SDKs","sdks",[128,129,11,11],"The kaab CLI","cli",[131,132,11,11],"Coding agents (MCP)","mcp",[134,135,136,137],"Panel","\u002Fpanel","i-lucide-layout-dashboard",[138,139,142,145,148,151],[27,135,11,11],[140,141,11,11],"The program builder","builder",[143,144,11,11],"Picking and recording","picking-and-recording",[146,147,11,11],"Taking over a job","takeover",[149,150,11,11],"Getting help","support",[152,153,11,11],"Referrals","referrals",[155,156,157,158],"Reference","\u002Freference","i-lucide-library",[159,160,520,834,837,840,1006,1007],[27,156,11,11],[161,162,11,163],"API","api",[164,166,169,212,222,274,297,316,347,376,389,396,403,410,426,447,454],[27,165,11,11],"\u002Freference\u002Fapi",[167,168,11,11],"Interactive reference","explorer",[170,171,11,172],"Jobs","jobs",[173,176,179,182,185,188,191,194,197,200,203,206,209],[174,175,11,11],"Create job","create-job",[177,178,11,11],"List jobs","list-jobs",[180,181,11,11],"Create job batch","create-job-batch",[183,184,11,11],"Estimate job","estimate-job",[186,187,11,11],"Get job","get-job",[189,190,11,11],"List job steps","list-job-steps",[192,193,11,11],"Get job snapshot","get-job-snapshot",[195,196,11,11],"Get job screenshot","get-job-screenshot",[198,199,11,11],"Get job artifact","get-job-artifact",[201,202,11,11],"Submit job input","submit-job-input",[204,205,11,11],"Resume job","resume-job",[207,208,11,11],"Takeover job","takeover-job",[210,211,11,11],"Cancel job","cancel-job",[213,214,11,215],"Batches","batches",[216,219],[217,218,11,11],"Get batch","get-batch",[220,221,11,11],"List batch jobs","list-batch-jobs",[223,224,11,225],"Programs","programs",[226,229,232,235,238,241,244,247,250,253,256,259,262,265,268,271],[227,228,11,11],"Create program","create-program",[230,231,11,11],"List programs","list-programs",[233,234,11,11],"Lint program","lint-program",[236,237,11,11],"Get program","get-program",[239,240,11,11],"Update program","update-program",[242,243,11,11],"Delete program","delete-program",[245,246,11,11],"List program versions","list-program-versions",[248,249,11,11],"Create program version","create-program-version",[251,252,11,11],"Update program version","update-program-version",[254,255,11,11],"Delete program version","delete-program-version",[257,258,11,11],"Get program version","get-program-version",[260,261,11,11],"Publish program version","publish-program-version",[263,264,11,11],"Diff program version","diff-program-version",[266,267,11,11],"Replay program version","replay-program-version",[269,270,11,11],"Set program alias","set-program-alias",[272,273,11,11],"Delete program alias","delete-program-alias",[41,42,11,275],[276,279,282,285,288,291,294],[277,278,11,11],"Create session","create-session",[280,281,11,11],"List sessions","list-sessions",[283,284,11,11],"Get session","get-session",[286,287,11,11],"Update session","update-session",[289,290,11,11],"Delete session","delete-session",[292,293,11,11],"Verify session","verify-session",[295,296,11,11],"Refresh session","refresh-session",[298,299,11,300],"Proposals","proposals",[301,304,307,310,313],[302,303,11,11],"List proposals","list-proposals",[305,306,11,11],"Get proposal","get-proposal",[308,309,11,11],"Approve proposal","approve-proposal",[311,312,11,11],"Reject proposal","reject-proposal",[314,315,11,11],"Edit proposal","edit-proposal",[317,318,11,319],"Schedules","schedules",[320,323,326,329,332,335,338,341,344],[321,322,11,11],"Create schedule","create-schedule",[324,325,11,11],"List schedules","list-schedules",[327,328,11,11],"Get schedule","get-schedule",[330,331,11,11],"Update schedule","update-schedule",[333,334,11,11],"Delete schedule","delete-schedule",[336,337,11,11],"Pause schedule","pause-schedule",[339,340,11,11],"Resume schedule","resume-schedule",[342,343,11,11],"List schedule runs","list-schedule-runs",[345,346,11,11],"Get schedule run diff","get-schedule-run-diff",[104,105,11,348],[349,352,355,358,361,364,367,370,373],[350,351,11,11],"Create webhook","create-webhook",[353,354,11,11],"List webhooks","list-webhooks",[356,357,11,11],"Get webhook","get-webhook",[359,360,11,11],"Update webhook","update-webhook",[362,363,11,11],"Delete webhook","delete-webhook",[365,366,11,11],"Rotate webhook secret","rotate-webhook-secret",[368,369,11,11],"List webhook deliveries","list-webhook-deliveries",[371,372,11,11],"Resend webhook delivery","resend-webhook-delivery",[374,375,11,11],"Test webhook","test-webhook",[377,378,11,379],"Organisation","org",[380,383,386],[381,382,11,11],"Rotate org webhook secret","rotate-org-webhook-secret",[384,385,11,11],"Get org","get-org",[387,388,11,11],"Request data deletion","request-data-deletion",[390,391,11,392],"Credits","credits",[393],[394,395,11,11],"Get credits","get-credits",[397,398,11,399],"Ledger","ledger",[400],[401,402,11,11],"List ledger entries","list-ledger-entries",[404,405,11,406],"Usage","usage",[407],[408,409,11,11],"Get usage","get-usage",[411,412,11,413],"API keys","api-keys",[414,417,420,423],[415,416,11,11],"List API keys","list-api-keys",[418,419,11,11],"Create API key","create-api-key",[421,422,11,11],"Rotate API key","rotate-api-key",[424,425,11,11],"Revoke API key","revoke-api-key",[427,108,11,428],"BYO providers",[429,432,435,438,441,444],[430,431,11,11],"List BYO providers","list-byo-providers",[433,434,11,11],"Create BYO provider","create-byo-provider",[436,437,11,11],"Get BYO provider","get-byo-provider",[439,440,11,11],"Update BYO provider","update-byo-provider",[442,443,11,11],"Delete BYO provider","delete-byo-provider",[445,446,11,11],"Test BYO provider","test-byo-provider",[448,449,11,450],"Sites","sites",[451],[452,453,11,11],"Get site profile","get-site-profile",[455,456,11,457],"Objects","schemas",[458,460,463,466,469,470,473,476,479,482,485,487,490,493,496,499,502,505,508,511,514,517],[27,459,11,11],"\u002Freference\u002Fapi\u002Fschemas",[461,462,11,11],"ApiKey","api-key",[464,465,11,11],"Batch","batch",[467,468,11,11],"ByoProvider","byo-provider",[390,391,11,11],[471,472,11,11],"ErrorResponse","error-response",[474,475,11,11],"ExtractSchema","extract-schema",[477,478,11,11],"Job","job",[480,481,11,11],"LedgerEntry","ledger-entry",[483,484,11,11],"LintResult","lint-result",[486,378,11,11],"Org",[488,489,11,11],"Program","program",[491,492,11,11],"ProgramDefinition","program-definition",[494,495,11,11],"ProgramVersion","program-version",[497,498,11,11],"Proposal","proposal",[500,501,11,11],"Schedule","schedule",[503,504,11,11],"Session","session",[506,507,11,11],"SiteProfile","site-profile",[509,510,11,11],"StepRecord","step-record",[512,513,11,11],"Webhook","webhook",[515,516,11,11],"WebhookDelivery","webhook-delivery",[518,519,11,11],"WebhookEvent","webhook-event",[521,522,11,523],"DSL","dsl",[524,526,529,532,535,538,603,637,640,751,754,756],[27,525,11,11],"\u002Freference\u002Fdsl",[527,528,11,11],"Inputs","inputs",[530,531,11,11],"Options","options",[533,534,11,11],"Policies","policies",[536,537,11,11],"Steps","steps",[539,540,11,541],"Actions","actions",[542,544,546,548,550,552,554,556,558,560,562,565,568,570,573,575,577,579,582,585,587,589,591,594,596,598,600],[27,543,11,11],"\u002Freference\u002Fdsl\u002Factions",[545,545,11,11],"fill",[547,547,11,11],"click",[549,549,11,11],"press",[551,551,11,11],"hover",[553,553,11,11],"select",[555,555,11,11],"check",[557,557,11,11],"uncheck",[559,559,11,11],"upload",[561,561,11,11],"scroll",[563,564,11,11],"wait_for","wait-for",[566,567,11,11],"set_session","set-session",[569,569,11,11],"extract",[571,572,11,11],"capture_response","capture-response",[574,574,11,11],"evaluate",[576,576,11,11],"paginate",[578,578,11,11],"download",[580,581,11,11],"read_pdf","read-pdf",[583,584,11,11],"set_vars","set-vars",[586,586,11,11],"sleep",[588,588,11,11],"reload",[590,590,11,11],"goto",[592,593,11,11],"await_input","await-input",[595,595,11,11],"checkpoint",[597,597,11,11],"screenshot",[599,599,11,11],"when",[601,602,11,11],"loop_until","loop-until",[604,605,11,606],"Conditions","conditions",[607,609,611,613,615,617,619,621,623,625,627,629,631,633,635],[27,608,11,11],"\u002Freference\u002Fdsl\u002Fconditions",[610,610,11,11],"url",[612,612,11,11],"title",[614,614,11,11],"visible",[616,616,11,11],"hidden",[618,618,11,11],"exists",[620,620,11,11],"absent",[622,622,11,11],"text",[624,624,11,11],"count",[626,626,11,11],"network",[628,628,11,11],"var",[630,630,11,11],"landmark",[632,632,11,11],"all",[634,634,11,11],"any",[636,636,11,11],"not",[638,639,11,11],"Targets","targets",[641,642,11,643],"Fields","fields",[644,646,649,651,654,656,659,661,663,666,668,671,672,674,677,679,681,683,685,687,690,693,695,698,701,703,704,707,709,712,714,716,718,720,722,724,726,728,731,733,734,736,738,740,743,745,747,749],[27,645,11,11],"\u002Freference\u002Fdsl\u002Ffields",[647,648,11,11],"allow_suffix","allow-suffix",[650,650,11,11],"attr",[652,653,11,11],"base_url","base-url",[655,655,11,11],"candidates",[657,658,11,11],"case_insensitive","case-insensitive",[660,660,11,11],"country",[662,662,11,11],"currency",[664,665,11,11],"date_format","date-format",[667,667,11,11],"decimal",[669,670,11,11],"false_values","false-values",[642,642,11,11],[673,673,11,11],"flags",[675,676,11,11],"follow_redirects","follow-redirects",[678,678,11,11],"frame",[680,680,11,11],"json",[682,682,11,11],"locale",[684,684,11,11],"many",[686,686,11,11],"max",[688,689,11,11],"max_items","max-items",[691,692,11,11],"max_length","max-length",[694,694,11,11],"min",[696,697,11,11],"min_items","min-items",[699,700,11,11],"min_length","min-length",[702,702,11,11],"name",[626,626,11,11],[705,706,11,11],"null_markers","null-markers",[708,708,11,11],"nullable",[710,711,11,11],"on_invalid","on-invalid",[713,713,11,11],"pattern",[715,715,11,11],"presence",[717,717,11,11],"regex",[719,719,11,11],"required",[721,721,11,11],"role",[723,723,11,11],"sample",[725,725,11,11],"selector",[727,727,11,11],"source",[729,730,11,11],"strip_fragment","strip-fragment",[732,732,11,11],"testid",[622,622,11,11],[735,735,11,11],"thousands",[737,737,11,11],"timezone",[739,739,11,11],"transforms",[741,742,11,11],"true_values","true-values",[744,744,11,11],"type",[746,746,11,11],"unique",[748,748,11,11],"values",[750,750,11,11],"xpath",[752,753,11,11],"Assertions","assertions",[755,739,11,11],"Transforms",[757,758,11,759],"Lint codes","lint",[760,762,765,768,771,774,777,780,783,786,789,792,795,798,801,804,807,810,813,816,819,822,825,828,831],[27,761,11,11],"\u002Freference\u002Fdsl\u002Flint",[763,764,11,11],"E001","e001",[766,767,11,11],"E002","e002",[769,770,11,11],"E003","e003",[772,773,11,11],"E004","e004",[775,776,11,11],"E005","e005",[778,779,11,11],"E006","e006",[781,782,11,11],"E007","e007",[784,785,11,11],"E008","e008",[787,788,11,11],"E009","e009",[790,791,11,11],"E010","e010",[793,794,11,11],"E011","e011",[796,797,11,11],"E012","e012",[799,800,11,11],"E013","e013",[802,803,11,11],"E014","e014",[805,806,11,11],"W001","w001",[808,809,11,11],"W002","w002",[811,812,11,11],"W003","w003",[814,815,11,11],"W004","w004",[817,818,11,11],"W005","w005",[820,821,11,11],"W006","w006",[823,824,11,11],"W007","w007",[826,827,11,11],"W008","w008",[829,830,11,11],"W009","w009",[832,833,11,11],"W010","w010",[835,836,11,11],"Codes","codes",[838,839,11,11],"Events","events",[841,129,11,842],"CLI",[843,845,847,850,853,856,859,862,865,868,871,874,877,880,883,886,889,892,895,898,901,904,907,910,913,916,919,922,925,928,931,934,937,940,943,946,949,952,955,958,961,964,967,970,973,976,979,982,985,988,991,994,997,1000,1003],[27,844,11,11],"\u002Freference\u002Fcli",[846,846,11,11],"kaab",[848,849,11,11],"kaab auth","kaab-auth",[851,852,11,11],"kaab auth login","kaab-auth-login",[854,855,11,11],"kaab auth logout","kaab-auth-logout",[857,858,11,11],"kaab auth status","kaab-auth-status",[860,861,11,11],"kaab completion","kaab-completion",[863,864,11,11],"kaab completion bash","kaab-completion-bash",[866,867,11,11],"kaab completion fish","kaab-completion-fish",[869,870,11,11],"kaab completion powershell","kaab-completion-powershell",[872,873,11,11],"kaab completion zsh","kaab-completion-zsh",[875,876,11,11],"kaab credits","kaab-credits",[878,879,11,11],"kaab jobs","kaab-jobs",[881,882,11,11],"kaab jobs cancel","kaab-jobs-cancel",[884,885,11,11],"kaab jobs get","kaab-jobs-get",[887,888,11,11],"kaab jobs input","kaab-jobs-input",[890,891,11,11],"kaab jobs list","kaab-jobs-list",[893,894,11,11],"kaab jobs resume","kaab-jobs-resume",[896,897,11,11],"kaab jobs run","kaab-jobs-run",[899,900,11,11],"kaab jobs snapshot","kaab-jobs-snapshot",[902,903,11,11],"kaab jobs steps","kaab-jobs-steps",[905,906,11,11],"kaab jobs takeover","kaab-jobs-takeover",[908,909,11,11],"kaab open","kaab-open",[911,912,11,11],"kaab open job","kaab-open-job",[914,915,11,11],"kaab programs","kaab-programs",[917,918,11,11],"kaab programs alias","kaab-programs-alias",[920,921,11,11],"kaab programs alias set","kaab-programs-alias-set",[923,924,11,11],"kaab programs diff","kaab-programs-diff",[926,927,11,11],"kaab programs lint","kaab-programs-lint",[929,930,11,11],"kaab programs list","kaab-programs-list",[932,933,11,11],"kaab programs pull","kaab-programs-pull",[935,936,11,11],"kaab programs push","kaab-programs-push",[938,939,11,11],"kaab proposals","kaab-proposals",[941,942,11,11],"kaab proposals approve","kaab-proposals-approve",[944,945,11,11],"kaab proposals list","kaab-proposals-list",[947,948,11,11],"kaab proposals reject","kaab-proposals-reject",[950,951,11,11],"kaab proposals show","kaab-proposals-show",[953,954,11,11],"kaab schedules","kaab-schedules",[956,957,11,11],"kaab schedules create","kaab-schedules-create",[959,960,11,11],"kaab schedules list","kaab-schedules-list",[962,963,11,11],"kaab schedules pause","kaab-schedules-pause",[965,966,11,11],"kaab schedules resume","kaab-schedules-resume",[968,969,11,11],"kaab schedules runs","kaab-schedules-runs",[971,972,11,11],"kaab sessions","kaab-sessions",[974,975,11,11],"kaab sessions create","kaab-sessions-create",[977,978,11,11],"kaab sessions delete","kaab-sessions-delete",[980,981,11,11],"kaab sessions list","kaab-sessions-list",[983,984,11,11],"kaab sessions verify","kaab-sessions-verify",[986,987,11,11],"kaab usage","kaab-usage",[989,990,11,11],"kaab version","kaab-version",[992,993,11,11],"kaab webhooks","kaab-webhooks",[995,996,11,11],"kaab webhooks create","kaab-webhooks-create",[998,999,11,11],"kaab webhooks deliveries","kaab-webhooks-deliveries",[1001,1002,11,11],"kaab webhooks list","kaab-webhooks-list",[1004,1005,11,11],"kaab webhooks test","kaab-webhooks-test",[125,126,11,11],[1008,1009,11,11],"Plans and pricing","plans",[1011,1012,1013,1014],"Changelog","\u002Fchangelog","i-lucide-history",[1015,1016],[27,1012,11,11],[1017,1018,11,11],"Deprecations","deprecations",{"id":1020,"title":29,"body":1021,"breaking":2930,"date":2931,"description":2932,"extension":2933,"generated":2930,"meta":2934,"navigation":2227,"path":2935,"seo":2936,"stem":2937,"version":2931,"__hash__":2938},"docs\u002F2.concepts\u002F01.programs-and-versions.md",{"type":1022,"value":1023,"toc":2915},"minimark",[1024,1028,1033,1043,1047,1280,1306,1311,1322,1326,1404,1408,1430,1440,1465,1468,1472,1478,1550,1576,1582,1585,1600,1625,1631,1697,1703,1707,1713,1719,1740,1755,1759,1773,1777,1780,2164,2170,2442,2448,2539,2555,2769,2780,2784,2846,2849,2911],[1025,1026,1027],"p",{},"A program is a named, versioned JSON definition of what to do on a website and what data to return, and every job runs one exact version of one. Because a published version never changes, a job that ran last month is reproducible, and you decide when production moves to new behaviour.",[1029,1030,1032],"h2",{"id":1031},"when-to-use-it","When to use it",[1025,1034,1035,1036,1039,1040,1042],{},"Store a program as soon as a job is more than a one-off: when it signs in, clicks, runs on a schedule, or other people depend on its output. A stored program gets versions, aliases, diffs, healing proposals and the review queue. For a single public page read once, the ",[1037,1038,610],"code",{}," + ",[1037,1041,569],{}," shorthand is enough, and it compiles to the same kind of program.",[1029,1044,1046],{"id":1045},"what-a-program-is","What a program is",[1048,1049,1053],"pre",{"className":1050,"code":1051,"language":680,"meta":1052,"style":1052},"language-json shiki shiki-themes kaab-code kaab-code kaab-code","{\n  \"kaab\": \"1\",\n  \"name\": \"shop-product\",\n  \"inputs\": { \"product_id\": { \"type\": \"string\", \"default\": \"1\", \"pattern\": \"^[0-9]+$\" } },\n  \"options\": { \"max_tier\": \"http\" },\n  \"steps\": [\n    { \"goto\": \"https:\u002F\u002Fshop.example.com\u002Fp\u002F{{inputs.product_id}}\" },\n    { \"extract\": { \"title\": \"h1\", \"price\": { \"selector\": \".price\", \"type\": \"money\", \"locale\": \"tr\", \"currency\": \"TRY\" } } }\n  ]\n}\n","",[1037,1054,1055,1064,1082,1095,1146,1169,1180,1198,1268,1274],{"__ignoreMap":1052},[1056,1057,1060],"span",{"class":1058,"line":1059},"line",1,[1056,1061,1063],{"class":1062},"sTzsn","{\n",[1056,1065,1067,1071,1075,1079],{"class":1058,"line":1066},2,[1056,1068,1070],{"class":1069},"sqn18","  \"kaab\"",[1056,1072,1074],{"class":1073},"sQm2-",":",[1056,1076,1078],{"class":1077},"suOy4"," \"1\"",[1056,1080,1081],{"class":1073},",\n",[1056,1083,1085,1088,1090,1093],{"class":1058,"line":1084},3,[1056,1086,1087],{"class":1069},"  \"name\"",[1056,1089,1074],{"class":1073},[1056,1091,1092],{"class":1077}," \"shop-product\"",[1056,1094,1081],{"class":1073},[1056,1096,1098,1101,1103,1106,1109,1111,1113,1116,1118,1121,1124,1127,1129,1131,1133,1136,1138,1141,1144],{"class":1058,"line":1097},4,[1056,1099,1100],{"class":1069},"  \"inputs\"",[1056,1102,1074],{"class":1073},[1056,1104,1105],{"class":1062}," { ",[1056,1107,1108],{"class":1069},"\"product_id\"",[1056,1110,1074],{"class":1073},[1056,1112,1105],{"class":1062},[1056,1114,1115],{"class":1069},"\"type\"",[1056,1117,1074],{"class":1073},[1056,1119,1120],{"class":1077}," \"string\"",[1056,1122,1123],{"class":1073},",",[1056,1125,1126],{"class":1069}," \"default\"",[1056,1128,1074],{"class":1073},[1056,1130,1078],{"class":1077},[1056,1132,1123],{"class":1073},[1056,1134,1135],{"class":1069}," \"pattern\"",[1056,1137,1074],{"class":1073},[1056,1139,1140],{"class":1077}," \"^[0-9]+$\"",[1056,1142,1143],{"class":1062}," } }",[1056,1145,1081],{"class":1073},[1056,1147,1149,1152,1154,1156,1159,1161,1164,1167],{"class":1058,"line":1148},5,[1056,1150,1151],{"class":1069},"  \"options\"",[1056,1153,1074],{"class":1073},[1056,1155,1105],{"class":1062},[1056,1157,1158],{"class":1069},"\"max_tier\"",[1056,1160,1074],{"class":1073},[1056,1162,1163],{"class":1077}," \"http\"",[1056,1165,1166],{"class":1062}," }",[1056,1168,1081],{"class":1073},[1056,1170,1172,1175,1177],{"class":1058,"line":1171},6,[1056,1173,1174],{"class":1069},"  \"steps\"",[1056,1176,1074],{"class":1073},[1056,1178,1179],{"class":1062}," [\n",[1056,1181,1183,1186,1189,1191,1194,1196],{"class":1058,"line":1182},7,[1056,1184,1185],{"class":1062},"    { ",[1056,1187,1188],{"class":1069},"\"goto\"",[1056,1190,1074],{"class":1073},[1056,1192,1193],{"class":1077}," \"https:\u002F\u002Fshop.example.com\u002Fp\u002F{{inputs.product_id}}\"",[1056,1195,1166],{"class":1062},[1056,1197,1081],{"class":1073},[1056,1199,1201,1203,1206,1208,1210,1213,1215,1218,1220,1223,1225,1227,1230,1232,1235,1237,1240,1242,1245,1247,1250,1252,1255,1257,1260,1262,1265],{"class":1058,"line":1200},8,[1056,1202,1185],{"class":1062},[1056,1204,1205],{"class":1069},"\"extract\"",[1056,1207,1074],{"class":1073},[1056,1209,1105],{"class":1062},[1056,1211,1212],{"class":1069},"\"title\"",[1056,1214,1074],{"class":1073},[1056,1216,1217],{"class":1077}," \"h1\"",[1056,1219,1123],{"class":1073},[1056,1221,1222],{"class":1069}," \"price\"",[1056,1224,1074],{"class":1073},[1056,1226,1105],{"class":1062},[1056,1228,1229],{"class":1069},"\"selector\"",[1056,1231,1074],{"class":1073},[1056,1233,1234],{"class":1077}," \".price\"",[1056,1236,1123],{"class":1073},[1056,1238,1239],{"class":1069}," \"type\"",[1056,1241,1074],{"class":1073},[1056,1243,1244],{"class":1077}," \"money\"",[1056,1246,1123],{"class":1073},[1056,1248,1249],{"class":1069}," \"locale\"",[1056,1251,1074],{"class":1073},[1056,1253,1254],{"class":1077}," \"tr\"",[1056,1256,1123],{"class":1073},[1056,1258,1259],{"class":1069}," \"currency\"",[1056,1261,1074],{"class":1073},[1056,1263,1264],{"class":1077}," \"TRY\"",[1056,1266,1267],{"class":1062}," } } }\n",[1056,1269,1271],{"class":1058,"line":1270},9,[1056,1272,1273],{"class":1062},"  ]\n",[1056,1275,1277],{"class":1058,"line":1276},10,[1056,1278,1279],{"class":1062},"}\n",[1025,1281,1282,1284,1285,1288,1289,1291,1292,1294,1295,1297,1298,1300,1301,1305],{},[1037,1283,846],{}," is the DSL version (",[1037,1286,1287],{},"\"1\"","), ",[1037,1290,702],{}," identifies the program in your organisation, ",[1037,1293,528],{}," are typed values each job supplies, ",[1037,1296,531],{}," set the tier, session, region and budgets, and ",[1037,1299,537],{}," run in order. The ",[1302,1303,1304],"a",{"href":525},"DSL reference"," lists every key.",[1307,1308,1310],"h3",{"id":1309},"the-one-step-shorthand","The one-step shorthand",[1025,1312,1313,1314,1317,1318,1321],{},"A job body ",[1037,1315,1316],{},"{ \"url\": U, \"extract\": S, \"options\": O }"," compiles at request time to ",[1037,1319,1320],{},"{ \"kaab\": \"1\", \"options\": O, \"steps\": [ { \"goto\": U }, { \"extract\": S } ] }",". There is no second, simpler engine: the shorthand is linted, run and billed exactly like a program you typed out, so moving from a shorthand job to a stored program changes nothing about how it runs.",[1307,1323,1325],{"id":1324},"three-forms-of-the-same-program","Three forms of the same program",[1327,1328,1329,1345],"table",{},[1330,1331,1332],"thead",{},[1333,1334,1335,1339,1342],"tr",{},[1336,1337,1338],"th",{},"Form",[1336,1340,1341],{},"Where you see it",[1336,1343,1344],{},"What it looks like",[1346,1347,1348,1367,1391],"tbody",{},[1333,1349,1350,1357,1360],{},[1351,1352,1353],"td",{},[1354,1355,1356],"strong",{},"Authored",[1351,1358,1359],{},"what you send, and what the API stores",[1351,1361,1362,1363,1366],{},"what the DSL reference describes: shorthands allowed, ",[1037,1364,1365],{},"id"," optional, defaults implied",[1333,1368,1369,1374,1377],{},[1351,1370,1371],{},[1354,1372,1373],{},"Expanded",[1351,1375,1376],{},"exports and version diffs",[1351,1378,1379,1380,1383,1384,1387,1388,1390],{},"the same document with shorthands written out (",[1037,1381,1382],{},"\"h1\""," becomes ",[1037,1385,1386],{},"{ \"selector\": \"h1\", \"type\": \"string\" }","), every step given an ",[1037,1389,1365],{},", and the defaults filled in; still a program you could send back",[1333,1392,1393,1398,1401],{},[1351,1394,1395],{},[1354,1396,1397],{},"Canonical",[1351,1399,1400],{},"inside Kaabist",[1351,1402,1403],{},"one shape per step, durations in milliseconds; never shown to you, it is what the engine runs",[1029,1405,1407],{"id":1406},"versions","Versions",[1025,1409,1410,1413,1414,1417,1418,1421,1422,1425,1426,1429],{},[1037,1411,1412],{},"POST \u002Fv1\u002Fprograms"," creates the program and its version 1, published unless you pass ",[1037,1415,1416],{},"publish: false",". Every later change is ",[1037,1419,1420],{},"POST \u002Fv1\u002Fprograms\u002F{id}\u002Fversions"," with a new ",[1037,1423,1424],{},"definition"," and optional ",[1037,1427,1428],{},"notes",". There is no endpoint that edits a published version, because a version is what a job's result is attributable to.",[1025,1431,1432,1433,1436,1437,1074],{},"A version is either a ",[1354,1434,1435],{},"draft"," or ",[1354,1438,1439],{},"published",[1441,1442,1443,1459],"ul",{},[1444,1445,1446,1447,1450,1451,1454,1455,1458],"li",{},"A draft can be replaced in place (",[1037,1448,1449],{},"PUT \u002Fv1\u002Fprograms\u002F{id}\u002Fversions\u002F{n}",") and discarded (",[1037,1452,1453],{},"DELETE","), and is what the panel's builder autosaves into. It can be run by its ",[1037,1456,1457],{},"pv_…"," id but is never what a bare name resolves to.",[1444,1460,1461,1464],{},[1037,1462,1463],{},"POST \u002Fv1\u002Fprograms\u002F{id}\u002Fversions\u002F{n}\u002Fpublish"," publishes a draft. From then on the version is immutable, and jobs, schedules and aliases may point at it.",[1025,1466,1467],{},"A version's identity is a hash of its canonical form. Two documents that differ only in shorthand, in the order of their keys, or in which defaults they wrote down are the same version.",[1029,1469,1471],{"id":1470},"aliases-and-references","Aliases and references",[1025,1473,1474,1475,1477],{},"The ",[1037,1476,489],{}," field of a job or a schedule accepts five spellings:",[1327,1479,1480,1489],{},[1330,1481,1482],{},[1333,1483,1484,1486],{},[1336,1485,155],{},[1336,1487,1488],{},"Resolves to",[1346,1490,1491,1505,1515,1529,1541],{},[1333,1492,1493,1498],{},[1351,1494,1495],{},[1037,1496,1497],{},"shop-product",[1351,1499,1500,1501,1504],{},"the ",[1037,1502,1503],{},"latest"," alias",[1333,1506,1507,1512],{},[1351,1508,1509],{},[1037,1510,1511],{},"shop-product@3",[1351,1513,1514],{},"version 3",[1333,1516,1517,1522],{},[1351,1518,1519],{},[1037,1520,1521],{},"shop-product@production",[1351,1523,1524,1525,1528],{},"whatever ",[1037,1526,1527],{},"production"," points at",[1333,1530,1531,1536],{},[1351,1532,1533],{},[1037,1534,1535],{},"prg_…",[1351,1537,1538,1539],{},"the program, at ",[1037,1540,1503],{},[1333,1542,1543,1547],{},[1351,1544,1545],{},[1037,1546,1457],{},[1351,1548,1549],{},"that exact version, published or draft",[1025,1551,1552,1554,1555,1558,1559,1562,1563,1565,1566,1569,1570,1572,1573,1575],{},[1037,1553,1503],{}," is moved by publishing and by nothing else, so a bare name never resolves to a draft. Every other alias is yours: ",[1037,1556,1557],{},"PUT \u002Fv1\u002Fprograms\u002F{id}\u002Faliases\u002Fproduction"," with ",[1037,1560,1561],{},"{ \"version\": 2 }"," creates or moves it, and ",[1037,1564,1453],{}," removes it. Alias names are lowercase letters, digits and hyphens, up to 32 characters, starting with a letter. Approving a healing proposal with ",[1037,1567,1568],{},"promote: true"," publishes a new version and moves ",[1037,1571,1503],{},", and deliberately leaves ",[1037,1574,1527],{}," where it is.",[1025,1577,1578,1579,1581],{},"A schedule stores the reference, not the version, and resolves it at every run: a schedule on ",[1037,1580,1521],{}," follows the alias when you move it.",[1029,1583,1584],{"id":758},"Lint",[1025,1586,1587,1588,1591,1592,1595,1596,1599],{},"Every program is linted when it is saved and when it is published. Errors block the write (",[1037,1589,1590],{},"422 program_invalid",", with the findings in ",[1037,1593,1594],{},"details.errors[]","); warnings are returned and do not block. ",[1037,1597,1598],{},"POST \u002Fv1\u002Fprograms\u002Flint"," returns both, plus the normalized document, without storing anything.",[1025,1601,1602,1605,1606,1608,1609,1611,1612,1614,1615,1618,1619,1621,1622,1624],{},[1354,1603,1604],{},"Errors"," are things that cannot work: an unknown key or wrong type, a loop or pagination with no bound, ",[1037,1607,574],{}," without its limits, a target with no locator or with two, a duplicate step ",[1037,1610,1365],{},", a template naming an input or variable that does not exist, an invalid field name, a regular expression, glob or JSONPath that does not compile, ",[1037,1613,576],{}," over a schema with no list, a side-effect step that asks to be retried or skipped, more than 200 steps or nesting deeper than three, a ",[1037,1616,1617],{},"secret"," input used inside ",[1037,1620,569],{}," or rendered into a URL, and a ",[1037,1623,578],{}," name that can produce no file name.",[1025,1626,1627,1630],{},[1354,1628,1629],{},"Warnings"," are about programs that work today and will break later:",[1441,1632,1633,1645,1648,1654,1660,1676,1682,1687],{},[1444,1634,1635,1636,1436,1638,1640,1641,1644],{},"a ",[1037,1637,590],{},[1037,1639,547],{}," with no ",[1037,1642,1643],{},"expect",", the step that fails silently;",[1444,1646,1647],{},"a locator with nothing but a structural path behind it, which the next redesign breaks;",[1444,1649,1650,1651,1653],{},"a fixed ",[1037,1652,586],{}," where a condition would do;",[1444,1655,1656,1657,1659],{},"a side-effect step not followed by a ",[1037,1658,595],{}," before the next side effect;",[1444,1661,1662,1663,1666,1667,1669,1670,1672,1673,1675],{},"a number or money field whose sample contains both ",[1037,1664,1665],{},"."," and ",[1037,1668,1123],{}," with neither ",[1037,1671,682],{}," nor ",[1037,1674,667],{}," set;",[1444,1677,1678,1679,1681],{},"an ",[1037,1680,574],{},", which the healer cannot see through;",[1444,1683,1678,1684,1686],{},[1037,1685,592],{}," collected on a hosted page with nobody notified;",[1444,1688,1635,1689,1692,1693,1696],{},[1037,1690,1691],{},"{{vars.x}}"," read after a block that sets ",[1037,1694,1695],{},"x"," on only one branch, which renders an empty string.",[1025,1698,1699,1700,1665],{},"Each code has its own page under ",[1302,1701,1702],{"href":761},"lint codes",[1029,1704,1706],{"id":1705},"diff-and-replay","Diff and replay",[1025,1708,1709,1712],{},[1037,1710,1711],{},"GET \u002Fv1\u002Fprograms\u002F{id}\u002Fversions\u002F{n}\u002Fdiff?against=m"," returns a JSON Patch (RFC 6902) between two definitions, taken over the expanded form, so a change reads the way you wrote it. A healing proposal that relocates one field produces a diff with one operation in it.",[1025,1714,1715,1718],{},[1037,1716,1717],{},"POST \u002Fv1\u002Fprograms\u002F{id}\u002Fversions\u002F{n}\u002Freplay"," runs a version's extraction against a page Kaabist already fetched, with no network:",[1048,1720,1722],{"className":1050,"code":1721,"language":680,"meta":1052,"style":1052},"{ \"snapshot\": \"job_01J…:steps[1]\" }\n",[1037,1723,1724],{"__ignoreMap":1052},[1056,1725,1726,1729,1732,1734,1737],{"class":1058,"line":1059},[1056,1727,1728],{"class":1062},"{ ",[1056,1730,1731],{"class":1069},"\"snapshot\"",[1056,1733,1074],{"class":1073},[1056,1735,1736],{"class":1077}," \"job_01J…:steps[1]\"",[1056,1738,1739],{"class":1062}," }\n",[1025,1741,1742,1743,1746,1747,1750,1751,1754],{},"or ",[1037,1744,1745],{},"{ \"snapshot\": \"ground_truth\" }"," for the page the version's fields were confirmed against. It answers ",[1037,1748,1749],{},"{ data, raw, warnings }"," and costs ",[1354,1752,1753],{},"no credits",", which makes it the loop to use while you get a locator right. A version whose steps need a live page cannot be replayed, and says so.",[1029,1756,1758],{"id":1757},"deleting","Deleting",[1025,1760,1761,1764,1765,1768,1769,1772],{},[1037,1762,1763],{},"DELETE \u002Fv1\u002Fprograms\u002F{id}"," (an ",[1037,1766,1767],{},"admin"," key) is a soft delete. A program that still has schedules, active or paused, answers ",[1037,1770,1771],{},"409 program_has_schedules",": delete them first, so nothing is left pointing at a program that no longer resolves.",[1029,1774,1776],{"id":1775},"worked-example","Worked example",[1025,1778,1779],{},"This walks a shop's product page from a lint to a job that runs by alias. First, lint the definition shown above:",[1781,1782,1783],"code-group",{},[1048,1784,1789],{"className":1785,"code":1786,"filename":1787,"language":1788,"meta":1052,"style":1052},"language-ts shiki shiki-themes kaab-code kaab-code kaab-code","const definition = {\n  kaab: \"1\",\n  name,\n  inputs: { product_id: { type: \"string\", default: \"1\", pattern: \"^[0-9]+$\" } },\n  options: { max_tier: \"http\" },\n  steps: [\n    { goto: `${site}\u002Fp\u002F{{inputs.product_id}}` },\n    {\n      extract: {\n        title: \"h1\",\n        price: { selector: \".price\", type: \"money\", locale: \"tr\", currency: \"TRY\" },\n      },\n    },\n  ],\n};\nconst lint = await kaab.programs.lint({ definition });\nif (lint.errors.length > 0) throw new Error(`lint: ${JSON.stringify(lint.errors)}`);\nconsole.log(`lint: ${lint.errors.length} errors, ${lint.warnings.length} warnings`);\n","TypeScript","ts",[1037,1790,1791,1806,1817,1824,1865,1883,1892,1918,1923,1932,1943,1989,1997,2005,2013,2019,2046,2114],{"__ignoreMap":1052},[1056,1792,1793,1796,1800,1803],{"class":1058,"line":1059},[1056,1794,1795],{"class":1069},"const",[1056,1797,1799],{"class":1798},"sHJIl"," definition",[1056,1801,1802],{"class":1069}," =",[1056,1804,1805],{"class":1062}," {\n",[1056,1807,1808,1811,1813,1815],{"class":1058,"line":1066},[1056,1809,1810],{"class":1062},"  kaab",[1056,1812,1074],{"class":1069},[1056,1814,1078],{"class":1077},[1056,1816,1081],{"class":1073},[1056,1818,1819,1822],{"class":1058,"line":1084},[1056,1820,1821],{"class":1062},"  name",[1056,1823,1081],{"class":1073},[1056,1825,1826,1829,1831,1834,1836,1839,1841,1843,1845,1848,1850,1852,1854,1857,1859,1861,1863],{"class":1058,"line":1097},[1056,1827,1828],{"class":1062},"  inputs",[1056,1830,1074],{"class":1069},[1056,1832,1833],{"class":1062}," { product_id",[1056,1835,1074],{"class":1069},[1056,1837,1838],{"class":1062}," { type",[1056,1840,1074],{"class":1069},[1056,1842,1120],{"class":1077},[1056,1844,1123],{"class":1073},[1056,1846,1847],{"class":1062}," default",[1056,1849,1074],{"class":1069},[1056,1851,1078],{"class":1077},[1056,1853,1123],{"class":1073},[1056,1855,1856],{"class":1062}," pattern",[1056,1858,1074],{"class":1069},[1056,1860,1140],{"class":1077},[1056,1862,1143],{"class":1062},[1056,1864,1081],{"class":1073},[1056,1866,1867,1870,1872,1875,1877,1879,1881],{"class":1058,"line":1148},[1056,1868,1869],{"class":1062},"  options",[1056,1871,1074],{"class":1069},[1056,1873,1874],{"class":1062}," { max_tier",[1056,1876,1074],{"class":1069},[1056,1878,1163],{"class":1077},[1056,1880,1166],{"class":1062},[1056,1882,1081],{"class":1073},[1056,1884,1885,1888,1890],{"class":1058,"line":1171},[1056,1886,1887],{"class":1062},"  steps",[1056,1889,1074],{"class":1069},[1056,1891,1179],{"class":1062},[1056,1893,1894,1897,1899,1902,1905,1908,1911,1914,1916],{"class":1058,"line":1182},[1056,1895,1896],{"class":1062},"    { goto",[1056,1898,1074],{"class":1069},[1056,1900,1901],{"class":1077}," `",[1056,1903,1904],{"class":1069},"${",[1056,1906,1907],{"class":1062},"site",[1056,1909,1910],{"class":1069},"}",[1056,1912,1913],{"class":1077},"\u002Fp\u002F{{inputs.product_id}}`",[1056,1915,1166],{"class":1062},[1056,1917,1081],{"class":1073},[1056,1919,1920],{"class":1058,"line":1200},[1056,1921,1922],{"class":1062},"    {\n",[1056,1924,1925,1928,1930],{"class":1058,"line":1270},[1056,1926,1927],{"class":1062},"      extract",[1056,1929,1074],{"class":1069},[1056,1931,1805],{"class":1062},[1056,1933,1934,1937,1939,1941],{"class":1058,"line":1276},[1056,1935,1936],{"class":1062},"        title",[1056,1938,1074],{"class":1069},[1056,1940,1217],{"class":1077},[1056,1942,1081],{"class":1073},[1056,1944,1946,1949,1951,1954,1956,1958,1960,1963,1965,1967,1969,1972,1974,1976,1978,1981,1983,1985,1987],{"class":1058,"line":1945},11,[1056,1947,1948],{"class":1062},"        price",[1056,1950,1074],{"class":1069},[1056,1952,1953],{"class":1062}," { selector",[1056,1955,1074],{"class":1069},[1056,1957,1234],{"class":1077},[1056,1959,1123],{"class":1073},[1056,1961,1962],{"class":1062}," type",[1056,1964,1074],{"class":1069},[1056,1966,1244],{"class":1077},[1056,1968,1123],{"class":1073},[1056,1970,1971],{"class":1062}," locale",[1056,1973,1074],{"class":1069},[1056,1975,1254],{"class":1077},[1056,1977,1123],{"class":1073},[1056,1979,1980],{"class":1062}," currency",[1056,1982,1074],{"class":1069},[1056,1984,1264],{"class":1077},[1056,1986,1166],{"class":1062},[1056,1988,1081],{"class":1073},[1056,1990,1992,1995],{"class":1058,"line":1991},12,[1056,1993,1994],{"class":1062},"      }",[1056,1996,1081],{"class":1073},[1056,1998,2000,2003],{"class":1058,"line":1999},13,[1056,2001,2002],{"class":1062},"    }",[1056,2004,1081],{"class":1073},[1056,2006,2008,2011],{"class":1058,"line":2007},14,[1056,2009,2010],{"class":1062},"  ]",[1056,2012,1081],{"class":1073},[1056,2014,2016],{"class":1058,"line":2015},15,[1056,2017,2018],{"class":1062},"};\n",[1056,2020,2022,2024,2027,2029,2032,2035,2038,2040,2043],{"class":1058,"line":2021},16,[1056,2023,1795],{"class":1069},[1056,2025,2026],{"class":1798}," lint",[1056,2028,1802],{"class":1069},[1056,2030,2031],{"class":1069}," await",[1056,2033,2034],{"class":1798}," kaab",[1056,2036,1665],{"class":2037},"sJugJ",[1056,2039,224],{"class":1798},[1056,2041,2042],{"class":2037},".lint",[1056,2044,2045],{"class":1062},"({ definition });\n",[1056,2047,2049,2052,2055,2057,2059,2062,2064,2067,2070,2073,2076,2079,2082,2085,2088,2091,2093,2096,2099,2101,2103,2106,2108,2111],{"class":1058,"line":2048},17,[1056,2050,2051],{"class":1069},"if",[1056,2053,2054],{"class":1062}," (",[1056,2056,758],{"class":1798},[1056,2058,1665],{"class":1062},[1056,2060,2061],{"class":1798},"errors",[1056,2063,1665],{"class":1062},[1056,2065,2066],{"class":1798},"length",[1056,2068,2069],{"class":1069}," >",[1056,2071,2072],{"class":1798}," 0",[1056,2074,2075],{"class":1062},") ",[1056,2077,2078],{"class":1069},"throw",[1056,2080,2081],{"class":1069}," new",[1056,2083,2084],{"class":2037}," Error",[1056,2086,2087],{"class":1062},"(",[1056,2089,2090],{"class":1077},"`lint: ",[1056,2092,1904],{"class":1069},[1056,2094,2095],{"class":1798},"JSON",[1056,2097,2098],{"class":2037},".stringify",[1056,2100,2087],{"class":1062},[1056,2102,758],{"class":1798},[1056,2104,2105],{"class":1062},".errors)",[1056,2107,1910],{"class":1069},[1056,2109,2110],{"class":1077},"`",[1056,2112,2113],{"class":1062},");\n",[1056,2115,2117,2120,2123,2125,2127,2129,2131,2133,2135,2137,2139,2141,2144,2146,2148,2150,2153,2155,2157,2159,2162],{"class":1058,"line":2116},18,[1056,2118,2119],{"class":1798},"console",[1056,2121,2122],{"class":2037},".log",[1056,2124,2087],{"class":1062},[1056,2126,2090],{"class":1077},[1056,2128,1904],{"class":1069},[1056,2130,758],{"class":1798},[1056,2132,1665],{"class":1062},[1056,2134,2061],{"class":1798},[1056,2136,1665],{"class":1062},[1056,2138,2066],{"class":1798},[1056,2140,1910],{"class":1069},[1056,2142,2143],{"class":1077}," errors, ",[1056,2145,1904],{"class":1069},[1056,2147,758],{"class":1798},[1056,2149,1665],{"class":1062},[1056,2151,2152],{"class":1798},"warnings",[1056,2154,1665],{"class":1062},[1056,2156,2066],{"class":1798},[1056,2158,1910],{"class":1069},[1056,2160,2161],{"class":1077}," warnings`",[1056,2163,2113],{"class":1062},[1025,2165,2166,2167,2169],{},"It has no errors, so create the program with version 1 published, then add version 2, which also reads the SKU, and publish it. ",[1037,2168,1503],{}," now points at 2:",[1781,2171,2172],{},[1048,2173,2175],{"className":1785,"code":2174,"filename":1787,"language":1788,"meta":1052,"style":1052},"\u002F\u002F Version 1, published: alias `latest` points at it.\nconst program = await kaab.programs.create({ name, definition, publish: true });\n\n\u002F\u002F Version 2 adds a field; publishing it moves `latest` to 2.\nconst v2 = await kaab.programs.versions.create(program.id, {\n  definition: {\n    ...definition,\n    steps: [\n      definition.steps[0],\n      { extract: { ...definition.steps[1]?.extract, sku: { selector: \".sku\" } } },\n    ],\n  },\n  notes: \"read the SKU too\",\n  publish: true,\n});\nconsole.log(`${program.name}: v${v2.version} is ${v2.status}`);\n",[1037,2176,2177,2183,2223,2229,2234,2268,2277,2286,2295,2311,2352,2359,2366,2378,2389,2394],{"__ignoreMap":1052},[1056,2178,2179],{"class":1058,"line":1059},[1056,2180,2182],{"class":2181},"sKog0","\u002F\u002F Version 1, published: alias `latest` points at it.\n",[1056,2184,2185,2187,2190,2192,2194,2196,2198,2200,2203,2206,2208,2210,2212,2215,2217,2220],{"class":1058,"line":1066},[1056,2186,1795],{"class":1069},[1056,2188,2189],{"class":1798}," program",[1056,2191,1802],{"class":1069},[1056,2193,2031],{"class":1069},[1056,2195,2034],{"class":1798},[1056,2197,1665],{"class":2037},[1056,2199,224],{"class":1798},[1056,2201,2202],{"class":2037},".create",[1056,2204,2205],{"class":1062},"({ name",[1056,2207,1123],{"class":1073},[1056,2209,1799],{"class":1062},[1056,2211,1123],{"class":1073},[1056,2213,2214],{"class":1062}," publish",[1056,2216,1074],{"class":1069},[1056,2218,2219],{"class":1798}," true",[1056,2221,2222],{"class":1062}," });\n",[1056,2224,2225],{"class":1058,"line":1084},[1056,2226,2228],{"emptyLinePlaceholder":2227},true,"\n",[1056,2230,2231],{"class":1058,"line":1097},[1056,2232,2233],{"class":2181},"\u002F\u002F Version 2 adds a field; publishing it moves `latest` to 2.\n",[1056,2235,2236,2238,2241,2243,2245,2247,2249,2251,2253,2255,2257,2259,2261,2264,2266],{"class":1058,"line":1148},[1056,2237,1795],{"class":1069},[1056,2239,2240],{"class":1798}," v2",[1056,2242,1802],{"class":1069},[1056,2244,2031],{"class":1069},[1056,2246,2034],{"class":1798},[1056,2248,1665],{"class":2037},[1056,2250,224],{"class":1798},[1056,2252,1665],{"class":2037},[1056,2254,1406],{"class":1798},[1056,2256,2202],{"class":2037},[1056,2258,2087],{"class":1062},[1056,2260,489],{"class":1798},[1056,2262,2263],{"class":1062},".id",[1056,2265,1123],{"class":1073},[1056,2267,1805],{"class":1062},[1056,2269,2270,2273,2275],{"class":1058,"line":1171},[1056,2271,2272],{"class":1062},"  definition",[1056,2274,1074],{"class":1069},[1056,2276,1805],{"class":1062},[1056,2278,2279,2282,2284],{"class":1058,"line":1182},[1056,2280,2281],{"class":1069},"    ...",[1056,2283,1424],{"class":1062},[1056,2285,1081],{"class":1073},[1056,2287,2288,2291,2293],{"class":1058,"line":1200},[1056,2289,2290],{"class":1062},"    steps",[1056,2292,1074],{"class":1069},[1056,2294,1179],{"class":1062},[1056,2296,2297,2300,2303,2306,2309],{"class":1058,"line":1270},[1056,2298,2299],{"class":1798},"      definition",[1056,2301,2302],{"class":1062},".steps[",[1056,2304,2305],{"class":1798},"0",[1056,2307,2308],{"class":1062},"]",[1056,2310,1081],{"class":1073},[1056,2312,2313,2316,2318,2320,2323,2325,2327,2330,2333,2335,2338,2340,2342,2344,2347,2350],{"class":1058,"line":1276},[1056,2314,2315],{"class":1062},"      { extract",[1056,2317,1074],{"class":1069},[1056,2319,1105],{"class":1062},[1056,2321,2322],{"class":1069},"...",[1056,2324,1424],{"class":1798},[1056,2326,2302],{"class":1062},[1056,2328,2329],{"class":1798},"1",[1056,2331,2332],{"class":1062},"]?.extract",[1056,2334,1123],{"class":1073},[1056,2336,2337],{"class":1062}," sku",[1056,2339,1074],{"class":1069},[1056,2341,1953],{"class":1062},[1056,2343,1074],{"class":1069},[1056,2345,2346],{"class":1077}," \".sku\"",[1056,2348,2349],{"class":1062}," } } }",[1056,2351,1081],{"class":1073},[1056,2353,2354,2357],{"class":1058,"line":1945},[1056,2355,2356],{"class":1062},"    ]",[1056,2358,1081],{"class":1073},[1056,2360,2361,2364],{"class":1058,"line":1991},[1056,2362,2363],{"class":1062},"  }",[1056,2365,1081],{"class":1073},[1056,2367,2368,2371,2373,2376],{"class":1058,"line":1999},[1056,2369,2370],{"class":1062},"  notes",[1056,2372,1074],{"class":1069},[1056,2374,2375],{"class":1077}," \"read the SKU too\"",[1056,2377,1081],{"class":1073},[1056,2379,2380,2383,2385,2387],{"class":1058,"line":2007},[1056,2381,2382],{"class":1062},"  publish",[1056,2384,1074],{"class":1069},[1056,2386,2219],{"class":1798},[1056,2388,1081],{"class":1073},[1056,2390,2391],{"class":1058,"line":2015},[1056,2392,2393],{"class":1062},"});\n",[1056,2395,2396,2398,2400,2402,2404,2406,2408,2411,2413,2416,2418,2421,2424,2426,2429,2431,2433,2436,2438,2440],{"class":1058,"line":2021},[1056,2397,2119],{"class":1798},[1056,2399,2122],{"class":2037},[1056,2401,2087],{"class":1062},[1056,2403,2110],{"class":1077},[1056,2405,1904],{"class":1069},[1056,2407,489],{"class":1798},[1056,2409,2410],{"class":1062},".name",[1056,2412,1910],{"class":1069},[1056,2414,2415],{"class":1077},": v",[1056,2417,1904],{"class":1069},[1056,2419,2420],{"class":1798},"v2",[1056,2422,2423],{"class":1062},".version",[1056,2425,1910],{"class":1069},[1056,2427,2428],{"class":1077}," is ",[1056,2430,1904],{"class":1069},[1056,2432,2420],{"class":1798},[1056,2434,2435],{"class":1062},".status",[1056,2437,1910],{"class":1069},[1056,2439,2110],{"class":1077},[1056,2441,2113],{"class":1062},[1025,2443,2444,2445,2447],{},"Point ",[1037,2446,1527],{}," at version 1. It stays there until you move it, whatever you publish:",[1781,2449,2450],{},[1048,2451,2453],{"className":1785,"code":2452,"filename":1787,"language":1788,"meta":1052,"style":1052},"\u002F\u002F `production` moves only when you say so: here it stays on version 1.\nconst aliased = await kaab.programs.aliases.set(program.id, \"production\", { version: 1 });\nconsole.log(`aliases: ${JSON.stringify(aliased.aliases)}`);\n",[1037,2454,2455,2460,2508],{"__ignoreMap":1052},[1056,2456,2457],{"class":1058,"line":1059},[1056,2458,2459],{"class":2181},"\u002F\u002F `production` moves only when you say so: here it stays on version 1.\n",[1056,2461,2462,2464,2467,2469,2471,2473,2475,2477,2479,2482,2485,2487,2489,2491,2493,2496,2498,2501,2503,2506],{"class":1058,"line":1066},[1056,2463,1795],{"class":1069},[1056,2465,2466],{"class":1798}," aliased",[1056,2468,1802],{"class":1069},[1056,2470,2031],{"class":1069},[1056,2472,2034],{"class":1798},[1056,2474,1665],{"class":2037},[1056,2476,224],{"class":1798},[1056,2478,1665],{"class":2037},[1056,2480,2481],{"class":1798},"aliases",[1056,2483,2484],{"class":2037},".set",[1056,2486,2087],{"class":1062},[1056,2488,489],{"class":1798},[1056,2490,2263],{"class":1062},[1056,2492,1123],{"class":1073},[1056,2494,2495],{"class":1077}," \"production\"",[1056,2497,1123],{"class":1073},[1056,2499,2500],{"class":1062}," { version",[1056,2502,1074],{"class":1069},[1056,2504,2505],{"class":1798}," 1",[1056,2507,2222],{"class":1062},[1056,2509,2510,2512,2514,2516,2519,2521,2523,2525,2527,2530,2533,2535,2537],{"class":1058,"line":1084},[1056,2511,2119],{"class":1798},[1056,2513,2122],{"class":2037},[1056,2515,2087],{"class":1062},[1056,2517,2518],{"class":1077},"`aliases: ",[1056,2520,1904],{"class":1069},[1056,2522,2095],{"class":1798},[1056,2524,2098],{"class":2037},[1056,2526,2087],{"class":1062},[1056,2528,2529],{"class":1798},"aliased",[1056,2531,2532],{"class":1062},".aliases)",[1056,2534,1910],{"class":1069},[1056,2536,2110],{"class":1077},[1056,2538,2113],{"class":1062},[1025,2540,2541,2542,2428,2545,2547,2548,2550,2551,2554],{},"Run a job by alias. The envelope's ",[1037,2543,2544],{},"program.version",[1037,2546,2329],{},", because ",[1037,2549,1527],{}," resolved to it, and ",[1037,2552,2553],{},"data"," has a title and a price but no SKU:",[1781,2556,2557],{},[1048,2558,2560],{"className":1785,"code":2559,"filename":1787,"language":1788,"meta":1052,"style":1052},"const job = await kaab.jobs.create({\n  program: `${name}@production`,\n  inputs: { product_id: \"2\" },\n  wait: 30,\n});\nif (job.status !== \"succeeded\") throw new Error(`job ${job.id} is ${job.status}`);\nconsole.log(\n  `${job.id} ran ${job.program?.name}@${job.program?.version}: ${JSON.stringify(job.data)}`,\n);\n",[1037,2561,2562,2584,2604,2621,2633,2637,2689,2698,2765],{"__ignoreMap":1052},[1056,2563,2564,2566,2569,2571,2573,2575,2577,2579,2581],{"class":1058,"line":1059},[1056,2565,1795],{"class":1069},[1056,2567,2568],{"class":1798}," job",[1056,2570,1802],{"class":1069},[1056,2572,2031],{"class":1069},[1056,2574,2034],{"class":1798},[1056,2576,1665],{"class":2037},[1056,2578,171],{"class":1798},[1056,2580,2202],{"class":2037},[1056,2582,2583],{"class":1062},"({\n",[1056,2585,2586,2589,2591,2593,2595,2597,2599,2602],{"class":1058,"line":1066},[1056,2587,2588],{"class":1062},"  program",[1056,2590,1074],{"class":1069},[1056,2592,1901],{"class":1077},[1056,2594,1904],{"class":1069},[1056,2596,702],{"class":1062},[1056,2598,1910],{"class":1069},[1056,2600,2601],{"class":1077},"@production`",[1056,2603,1081],{"class":1073},[1056,2605,2606,2608,2610,2612,2614,2617,2619],{"class":1058,"line":1084},[1056,2607,1828],{"class":1062},[1056,2609,1074],{"class":1069},[1056,2611,1833],{"class":1062},[1056,2613,1074],{"class":1069},[1056,2615,2616],{"class":1077}," \"2\"",[1056,2618,1166],{"class":1062},[1056,2620,1081],{"class":1073},[1056,2622,2623,2626,2628,2631],{"class":1058,"line":1097},[1056,2624,2625],{"class":1062},"  wait",[1056,2627,1074],{"class":1069},[1056,2629,2630],{"class":1798}," 30",[1056,2632,1081],{"class":1073},[1056,2634,2635],{"class":1058,"line":1148},[1056,2636,2393],{"class":1062},[1056,2638,2639,2641,2643,2645,2648,2651,2654,2656,2658,2660,2662,2664,2667,2669,2671,2673,2675,2677,2679,2681,2683,2685,2687],{"class":1058,"line":1171},[1056,2640,2051],{"class":1069},[1056,2642,2054],{"class":1062},[1056,2644,478],{"class":1798},[1056,2646,2647],{"class":1062},".status ",[1056,2649,2650],{"class":1069},"!==",[1056,2652,2653],{"class":1077}," \"succeeded\"",[1056,2655,2075],{"class":1062},[1056,2657,2078],{"class":1069},[1056,2659,2081],{"class":1069},[1056,2661,2084],{"class":2037},[1056,2663,2087],{"class":1062},[1056,2665,2666],{"class":1077},"`job ",[1056,2668,1904],{"class":1069},[1056,2670,478],{"class":1798},[1056,2672,2263],{"class":1062},[1056,2674,1910],{"class":1069},[1056,2676,2428],{"class":1077},[1056,2678,1904],{"class":1069},[1056,2680,478],{"class":1798},[1056,2682,2435],{"class":1062},[1056,2684,1910],{"class":1069},[1056,2686,2110],{"class":1077},[1056,2688,2113],{"class":1062},[1056,2690,2691,2693,2695],{"class":1058,"line":1182},[1056,2692,2119],{"class":1798},[1056,2694,2122],{"class":2037},[1056,2696,2697],{"class":1062},"(\n",[1056,2699,2700,2703,2705,2707,2709,2711,2714,2716,2718,2720,2722,2725,2727,2730,2732,2734,2736,2738,2741,2743,2746,2748,2750,2752,2754,2756,2759,2761,2763],{"class":1058,"line":1200},[1056,2701,2702],{"class":1077},"  `",[1056,2704,1904],{"class":1069},[1056,2706,478],{"class":1798},[1056,2708,2263],{"class":1062},[1056,2710,1910],{"class":1069},[1056,2712,2713],{"class":1077}," ran ",[1056,2715,1904],{"class":1069},[1056,2717,478],{"class":1798},[1056,2719,1665],{"class":1062},[1056,2721,489],{"class":1798},[1056,2723,2724],{"class":1062},"?.name",[1056,2726,1910],{"class":1069},[1056,2728,2729],{"class":1077},"@",[1056,2731,1904],{"class":1069},[1056,2733,478],{"class":1798},[1056,2735,1665],{"class":1062},[1056,2737,489],{"class":1798},[1056,2739,2740],{"class":1062},"?.version",[1056,2742,1910],{"class":1069},[1056,2744,2745],{"class":1077},": ",[1056,2747,1904],{"class":1069},[1056,2749,2095],{"class":1798},[1056,2751,2098],{"class":2037},[1056,2753,2087],{"class":1062},[1056,2755,478],{"class":1798},[1056,2757,2758],{"class":1062},".data)",[1056,2760,1910],{"class":1069},[1056,2762,2110],{"class":1077},[1056,2764,1081],{"class":1073},[1056,2766,2767],{"class":1058,"line":1270},[1056,2768,2113],{"class":1062},[1025,2770,2771,2772,2775,2776,2779],{},"To see what changed between the two versions, ask for the diff of version 2 against 1: a single ",[1037,2773,2774],{},"add"," operation for the ",[1037,2777,2778],{},"sku"," field of the second step's extract. To move production, set the alias to 2; jobs created after that run version 2, and jobs created before it keep the version they pinned.",[1029,2781,2783],{"id":2782},"pitfalls","Pitfalls",[1441,2785,2786,2801,2816,2831],{},[1444,2787,2788,2794,2795,2797,2798,1665],{},[1354,2789,2790,2791,2793],{},"Expecting ",[1037,2792,1503],{}," to be what production runs."," ",[1037,2796,1503],{}," moves on every publish, including a healed version you approved. Run production jobs and schedules by an alias you control, such as ",[1037,2799,2800],{},"@production",[1444,2802,2803,2806,2807,2809,2810,2813,2814,1665],{},[1354,2804,2805],{},"Editing instead of versioning."," A published version cannot change. Create a new version, test it by its ",[1037,2808,1457],{}," id or a ",[1037,2811,2812],{},"staging"," alias, then move ",[1037,2815,1527],{},[1444,2817,2818,2821,2822,2824,2825,2827,2828,2830],{},[1354,2819,2820],{},"Ignoring warnings."," They do not block publishing, but ",[1037,2823,805],{}," (no ",[1037,2826,1643],{},") and ",[1037,2829,808],{}," (structural-only locators) are the usual cause of a program that returns nothing after a site redesign.",[1444,2832,2833,2836,2837,2839,2840,2842,2843,2845],{},[1354,2834,2835],{},"Putting a secret in a URL."," Lint refuses a ",[1037,2838,1617],{}," input rendered into a ",[1037,2841,590],{}," URL or used in ",[1037,2844,569],{},", because each of those writes it somewhere Kaabist keeps.",[1029,2847,155],{"id":2848},"reference",[1441,2850,2851,2866,2880,2889,2904],{},[1444,2852,2853,2857,2858,2857,2862],{},[1302,2854,2856],{"href":2855},"\u002Freference\u002Fapi\u002Fprograms\u002Fcreate-program","Create a program",", ",[1302,2859,2861],{"href":2860},"\u002Freference\u002Fapi\u002Fprograms\u002Fcreate-program-version","create a version",[1302,2863,2865],{"href":2864},"\u002Freference\u002Fapi\u002Fprograms\u002Fpublish-program-version","publish a version",[1444,2867,2868,2857,2872,2857,2876],{},[1302,2869,2871],{"href":2870},"\u002Freference\u002Fapi\u002Fprograms\u002Fset-program-alias","Set an alias",[1302,2873,2875],{"href":2874},"\u002Freference\u002Fapi\u002Fprograms\u002Fdiff-program-version","diff two versions",[1302,2877,2879],{"href":2878},"\u002Freference\u002Fapi\u002Fprograms\u002Freplay-program-version","replay a version",[1444,2881,2882,2886,2887],{},[1302,2883,2885],{"href":2884},"\u002Freference\u002Fapi\u002Fprograms\u002Flint-program","Lint a program"," and the ",[1302,2888,1702],{"href":761},[1444,2890,2891,2857,2895,1666,2899,2903],{},[1302,2892,2894],{"href":2893},"\u002Freference\u002Fapi\u002Fschemas\u002Fprogram","The program",[1302,2896,2898],{"href":2897},"\u002Freference\u002Fapi\u002Fschemas\u002Fprogram-version","program version",[1302,2900,2902],{"href":2901},"\u002Freference\u002Fapi\u002Fschemas\u002Fprogram-definition","program definition"," objects",[1444,2905,2906],{},[1302,2907,2909],{"href":2908},"\u002Freference\u002Fcli\u002Fkaab-programs-push",[1037,2910,935],{},[2912,2913,2914],"style",{},"html pre.shiki code .sTzsn, html code.shiki .sTzsn{--shiki-light:var(--kaab-code-foreground);--shiki-default:var(--kaab-code-foreground);--shiki-dark:var(--kaab-code-foreground)}html pre.shiki code .sqn18, html code.shiki .sqn18{--shiki-light:var(--kaab-code-token-keyword);--shiki-default:var(--kaab-code-token-keyword);--shiki-dark:var(--kaab-code-token-keyword)}html pre.shiki code .sQm2-, html code.shiki .sQm2-{--shiki-light:var(--kaab-code-token-punctuation);--shiki-default:var(--kaab-code-token-punctuation);--shiki-dark:var(--kaab-code-token-punctuation)}html pre.shiki code .suOy4, html code.shiki .suOy4{--shiki-light:var(--kaab-code-token-string-expression);--shiki-default:var(--kaab-code-token-string-expression);--shiki-dark:var(--kaab-code-token-string-expression)}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 .sHJIl, html code.shiki .sHJIl{--shiki-light:var(--kaab-code-token-constant);--shiki-default:var(--kaab-code-token-constant);--shiki-dark:var(--kaab-code-token-constant)}html pre.shiki code .sJugJ, html code.shiki .sJugJ{--shiki-light:var(--kaab-code-token-function);--shiki-default:var(--kaab-code-token-function);--shiki-dark:var(--kaab-code-token-function)}html pre.shiki code .sKog0, html code.shiki .sKog0{--shiki-light:var(--kaab-code-token-comment);--shiki-default:var(--kaab-code-token-comment);--shiki-dark:var(--kaab-code-token-comment)}",{"title":1052,"searchDepth":1084,"depth":1084,"links":2916},[2917,2918,2922,2923,2924,2925,2926,2927,2928,2929],{"id":1031,"depth":1066,"text":1032},{"id":1045,"depth":1066,"text":1046,"children":2919},[2920,2921],{"id":1309,"depth":1084,"text":1310},{"id":1324,"depth":1084,"text":1325},{"id":1406,"depth":1066,"text":1407},{"id":1470,"depth":1066,"text":1471},{"id":758,"depth":1066,"text":1584},{"id":1705,"depth":1066,"text":1706},{"id":1757,"depth":1066,"text":1758},{"id":1775,"depth":1066,"text":1776},{"id":2782,"depth":1066,"text":2783},{"id":2848,"depth":1066,"text":155},false,null,"Programs are versioned JSON: immutable versions, the latest and production aliases, the one-step shorthand, lint, publishing, diffs and replay.","md",{},"\u002Fconcepts\u002Fprograms-and-versions",{"title":29,"description":2932},"2.concepts\u002F01.programs-and-versions","_WcQltVuwP4tNv1XhwDxN179TIJIKWmUZRKBCVaWAl4",[2940,2943],{"title":27,"path":23,"stem":2941,"description":2942,"children":-1},"2.concepts\u002Findex","The ideas behind Kaabist, one page each: programs, tiers, sessions, parking, healing, obstacles, validation, credits, limits and data.",{"title":32,"path":2944,"stem":2945,"description":2946,"children":-1},"\u002Fconcepts\u002Ftiers-and-escalation","2.concepts\u002F02.tiers-and-escalation","Which tier a job starts at and why it moves up, what Kaabist learns about each site, when a discovered API makes a job cheaper, and the shared cache.",1793593409300]