[{"data":1,"prerenderedAt":554},["ShallowReactive",2],{"navigation_docs":3,"-platforms-artifacts":84,"-platforms-artifacts-surround":551},[4,56],{"title":5,"path":6,"stem":7,"children":8,"icon":55},"Guide","\u002Fguide","1.guide\u002F01.index",[9,11,15,19,23,27,31,35,39,43,47,51],{"title":10,"path":6,"stem":7},"Getting Started",{"title":12,"path":13,"stem":14},"Authentication","\u002Fguide\u002Fauth","1.guide\u002F02.auth",{"title":16,"path":17,"stem":18},"Repositories","\u002Fguide\u002Frepositories","1.guide\u002F03.repositories",{"title":20,"path":21,"stem":22},"Issues","\u002Fguide\u002Fissues","1.guide\u002F04.issues",{"title":24,"path":25,"stem":26},"Pull requests","\u002Fguide\u002Fpull-requests","1.guide\u002F05.pull-requests",{"title":28,"path":29,"stem":30},"Review threads","\u002Fguide\u002Fthreads","1.guide\u002F06.threads",{"title":32,"path":33,"stem":34},"Commits, CI and releases","\u002Fguide\u002Fcommits","1.guide\u002F07.commits",{"title":36,"path":37,"stem":38},"Contribution templates","\u002Fguide\u002Ftemplates","1.guide\u002F08.templates",{"title":40,"path":41,"stem":42},"Code search","\u002Fguide\u002Fcode-search","1.guide\u002F09.code-search",{"title":44,"path":45,"stem":46},"Agents","\u002Fguide\u002Fagents","1.guide\u002F10.agents",{"title":48,"path":49,"stem":50},"Custom providers","\u002Fguide\u002Fcustom","1.guide\u002F11.custom",{"title":52,"path":53,"stem":54},"Explorer","\u002Fguide\u002Fexplorer","1.guide\u002F12.explorer","i-lucide-book-open",{"title":57,"path":58,"stem":59,"children":60,"icon":83},"Platforms","\u002Fplatforms","2.platforms\u002F0.index",[61,63,67,71,75,79],{"title":62,"path":58,"stem":59},"Overview",{"title":64,"path":65,"stem":66},"GitHub","\u002Fplatforms\u002Fgithub","2.platforms\u002F01.github",{"title":68,"path":69,"stem":70},"GitLab","\u002Fplatforms\u002Fgitlab","2.platforms\u002F02.gitlab",{"title":72,"path":73,"stem":74},"Gitea","\u002Fplatforms\u002Fgitea","2.platforms\u002F03.gitea",{"title":76,"path":77,"stem":78},"GitBucket","\u002Fplatforms\u002Fgitbucket","2.platforms\u002F04.gitbucket",{"title":80,"path":81,"stem":82},"Artifacts","\u002Fplatforms\u002Fartifacts","2.platforms\u002F05.artifacts","i-lucide-library",{"id":85,"title":80,"body":86,"description":543,"extension":544,"links":545,"meta":546,"navigation":136,"path":81,"seo":548,"stem":82,"__hash__":550},"docs\u002F2.platforms\u002F05.artifacts.md",{"type":87,"value":88,"toc":533},"minimark",[89,93,98,253,261,266,295,298,305,309,316,376,379,385,389,455,459,502,506,509,516,520,529],[90,91],"platform-facts",{"platform":92},"artifacts",[94,95,97],"h2",{"id":96},"address-an-artifacts-namespace","Address an Artifacts namespace",[99,100,105],"pre",{"className":101,"code":102,"language":103,"meta":104,"style":104},"language-ts shiki shiki-themes forges forges forges","import { createProvider } from \"@agntn\u002Fforges\";\n\nconst artifacts = await createProvider(\"artifacts\", {\n  token: process.env.CLOUDFLARE_API_TOKEN,\n  accountId: process.env.CLOUDFLARE_ACCOUNT_ID,\n});\n\nconst repo = await artifacts.repos.get(\"default\", \"starter-repo\");\nconst readme = await artifacts.repos.readContents(\"default\", \"starter-repo\", \"README.md\");\n","ts","",[106,107,108,131,138,166,172,178,184,189,221],"code",{"__ignoreMap":104},[109,110,113,117,121,124,128],"span",{"class":111,"line":112},"line",1,[109,114,116],{"class":115},"skH_V","import",[109,118,120],{"class":119},"s38Sx"," { createProvider } ",[109,122,123],{"class":115},"from",[109,125,127],{"class":126},"shU9J"," \"@agntn\u002Fforges\"",[109,129,130],{"class":119},";\n",[109,132,134],{"class":111,"line":133},2,[109,135,137],{"emptyLinePlaceholder":136},true,"\n",[109,139,141,144,147,150,153,157,160,163],{"class":111,"line":140},3,[109,142,143],{"class":115},"const",[109,145,146],{"class":119}," artifacts ",[109,148,149],{"class":115},"=",[109,151,152],{"class":115}," await",[109,154,156],{"class":155},"sK71F"," createProvider",[109,158,159],{"class":119},"(",[109,161,162],{"class":126},"\"artifacts\"",[109,164,165],{"class":119},", {\n",[109,167,169],{"class":111,"line":168},4,[109,170,171],{"class":119},"  token: process.env.CLOUDFLARE_API_TOKEN,\n",[109,173,175],{"class":111,"line":174},5,[109,176,177],{"class":119},"  accountId: process.env.CLOUDFLARE_ACCOUNT_ID,\n",[109,179,181],{"class":111,"line":180},6,[109,182,183],{"class":119},"});\n",[109,185,187],{"class":111,"line":186},7,[109,188,137],{"emptyLinePlaceholder":136},[109,190,192,194,197,199,201,204,207,209,212,215,218],{"class":111,"line":191},8,[109,193,143],{"class":115},[109,195,196],{"class":119}," repo ",[109,198,149],{"class":115},[109,200,152],{"class":115},[109,202,203],{"class":119}," artifacts.repos.",[109,205,206],{"class":155},"get",[109,208,159],{"class":119},[109,210,211],{"class":126},"\"default\"",[109,213,214],{"class":119},", ",[109,216,217],{"class":126},"\"starter-repo\"",[109,219,220],{"class":119},");\n",[109,222,224,226,229,231,233,235,238,240,242,244,246,248,251],{"class":111,"line":223},9,[109,225,143],{"class":115},[109,227,228],{"class":119}," readme ",[109,230,149],{"class":115},[109,232,152],{"class":115},[109,234,203],{"class":119},[109,236,237],{"class":155},"readContents",[109,239,159],{"class":119},[109,241,211],{"class":126},[109,243,214],{"class":119},[109,245,217],{"class":126},[109,247,214],{"class":119},[109,249,250],{"class":126},"\"README.md\"",[109,252,220],{"class":119},[254,255,256,257,260],"p",{},"Artifacts is Git without the forge around it. An account holds namespaces, a namespace holds repositories, and that's the whole model. So ",[106,258,259],{},"owner"," is the namespace. Everything else lines up with the shapes you already know.",[262,263,265],"h3",{"id":264},"where-does-the-token-come-from","Where does the token come from?",[254,267,268,269,278,279,282,283,286,287,290,291,294],{},"Leave both fields out and ",[270,271,275],"a",{"href":272,"rel":273},"https:\u002F\u002Fgithub.com\u002Fagntn\u002Fcredentials",[274],"nofollow",[106,276,277],{},"@agntn\u002Fcredentials"," looks for you. The token comes from ",[106,280,281],{},"CLOUDFLARE_API_TOKEN",", then the session ",[106,284,285],{},"cf auth login"," left behind. The account comes from ",[106,288,289],{},"AGNTN_CLOUDFLARE_ACCOUNT_ID"," or ",[106,292,293],{},"CLOUDFLARE_ACCOUNT_ID",", or from that session when it reaches exactly one account. A token from the environment wants its account from there too.",[254,296,297],{},"That session token expires. So the provider asks the chain on every request, and a 401 on a session token gets one refresh and one retry. Your MCP server keeps reading after lunch. Nice.",[254,299,300,301,304],{},"There's no guest mode. ",[106,302,303],{},"{ token: \"\" }"," means go look, same as leaving it out.",[94,306,308],{"id":307},"what-it-reads","What it reads",[254,310,311,312,315],{},"Paths below hang off ",[106,313,314],{},"\u002Faccounts\u002F:account\u002Fartifacts",".",[317,318,319,332],"table",{},[320,321,322],"thead",{},[323,324,325,329],"tr",{},[326,327,328],"th",{},"Resource",[326,330,331],{},"Endpoint",[333,334,335,349,363],"tbody",{},[323,336,337,341],{},[338,339,340],"td",{},"repos",[338,342,343,214,346],{},[106,344,345],{},"GET \u002Fnamespaces\u002F:namespace\u002Frepos",[106,347,348],{},"…\u002Frepos\u002F:name",[323,350,351,354],{},[338,352,353],{},"repository contents",[338,355,356,214,359,362],{},[106,357,358],{},"GET …\u002Frepos\u002F:name\u002Ffile?ref=&path=",[106,360,361],{},"…\u002Ftree\u002F:hash",", after the ref resolves",[323,364,365,368],{},[338,366,367],{},"commits",[338,369,370,214,373],{},[106,371,372],{},"GET …\u002Frepos\u002F:name\u002Flog?ref=&offset=&limit=",[106,374,375],{},"…\u002Fcommit\u002F:hash",[254,377,378],{},"Repositories page by cursor, and a cursor can't jump. Page 3 reads pages 1 and 2 on the way, 200 rows a request at most, plus one row to tell if there's more. The log pages by offset like a sane API.",[254,380,381,382,384],{},"A full SHA goes straight to ",[106,383,375],{},". A branch or tag resolves through the log first. A file is one read at that commit. A directory walks the trees, one request per level.",[94,386,388],{"id":387},"what-comes-back","What comes back",[390,391,392,403,413,431,434,441],"ul",{},[393,394,395,398,399,402],"li",{},[106,396,397],{},"private"," is always ",[106,400,401],{},"true",". Every read needs a token.",[393,404,405,408,409,412],{},[106,406,407],{},"url"," is the REST address of the repository. ",[106,410,411],{},"cloneUrl"," is the Git remote.",[393,414,415,416,419,420,423,424,427,428,315],{},"Only a fork made inside Artifacts counts as one. A ",[106,417,418],{},"source"," of ",[106,421,422],{},"artifacts:\u003Cnamespace>\u002F\u003Crepo>"," sets ",[106,425,426],{},"isFork"," and ",[106,429,430],{},"parent",[393,432,433],{},"Commit dates arrive as Unix seconds and leave as ISO 8601.",[393,435,436,437,440],{},"Directory entries have ",[106,438,439],{},"size: null",". The tree doesn't send one.",[393,442,443,446,447,450,451,454],{},[106,444,445],{},"commits.get"," returns ",[106,448,449],{},"files: []"," with ",[106,452,453],{},"filesComplete: null",". There's no diff in the API, so the honest answer is \"don't know\", not \"nothing changed\".",[94,456,458],{"id":457},"gotchas","Gotchas",[390,460,461,472,479,499],{},[393,462,463,464,467,468,471],{},"The log reads ",[106,465,466],{},"ref=HEAD"," as a ref that doesn't exist and answers with an empty list. forges leaves ",[106,469,470],{},"HEAD"," out, so the default branch answers.",[393,473,474,475,478],{},"An unknown ref isn't a 404 there either. Just an empty log. forges turns it into ",[106,476,477],{},"NotFoundError",", so a typo doesn't pass for an empty repository.",[393,480,481,484,485,488,489,214,492,427,495,498],{},[106,482,483],{},"commits.list"," takes ",[106,486,487],{},"ref"," and nothing else. ",[106,490,491],{},"path",[106,493,494],{},"since",[106,496,497],{},"until"," are a 501 before any request goes out.",[393,500,501],{},"The file route answers 404 for a directory too. That's why a path that isn't a file gets the tree walk.",[94,503,505],{"id":504},"what-isnt-there","What isn't there",[254,507,508],{},"Issues, pull requests, comments, review threads, users, releases, CI, code search and templates. None of it. Just Git, no drama.",[254,510,511,512,515],{},"Why put storage without a forge into a forge library then? Because reading is the same job. An agent that reads a file on GitHub reads one here with the same call. Everything else is a ",[106,513,514],{},"ForgesError"," with status 501 and a sentence, so the agent stops instead of retrying.",[94,517,519],{"id":518},"where-it-lives","Where it lives",[254,521,522,525,526,315],{},[106,523,524],{},"src\u002Fproviders\u002Fartifacts.ts",", with the credentials from ",[106,527,528],{},"@agntn\u002Fcredentials\u002Fcloudflare",[530,531,532],"style",{},"html pre.shiki code .skH_V, html code.shiki .skH_V{--shiki-light:var(--shiki-token-keyword);--shiki-default:var(--shiki-token-keyword);--shiki-dark:var(--shiki-token-keyword)}html pre.shiki code .s38Sx, html code.shiki .s38Sx{--shiki-light:var(--ui-text-highlighted);--shiki-default:var(--ui-text-highlighted);--shiki-dark:var(--ui-text-highlighted)}html pre.shiki code .shU9J, html code.shiki .shU9J{--shiki-light:var(--shiki-token-string);--shiki-default:var(--shiki-token-string);--shiki-dark:var(--shiki-token-string)}html pre.shiki code .sK71F, html code.shiki .sK71F{--shiki-light:var(--shiki-token-function);--shiki-default:var(--shiki-token-function);--shiki-dark:var(--shiki-token-function)}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":104,"searchDepth":133,"depth":133,"links":534},[535,538,539,540,541,542],{"id":96,"depth":133,"text":97,"children":536},[537],{"id":264,"depth":140,"text":265},{"id":307,"depth":133,"text":308},{"id":387,"depth":133,"text":388},{"id":457,"depth":133,"text":458},{"id":504,"depth":133,"text":505},{"id":518,"depth":133,"text":519},"Git storage behind the Cloudflare API. Read repos and history like on any forge. The forge part answers 501.","md",null,{"icon":547},"i-simple-icons-cloudflare",{"title":549,"description":543},"Read Cloudflare Artifacts repositories with forges","SzQxjcJNknGuendzOyO9Y604xXetkXQ76iG9sg8_5ms",[552,545],{"title":76,"path":77,"stem":78,"description":553,"children":-1},"The GitHub provider pointed at a GitBucket \u002Fapi\u002Fv3. What GitBucket does not serve fails with a sentence, not a 404.",1791417714514]