ua-fallback
Retrieval fallback için bir Claude Code Mod'u: bir curl ya da wget çağrısı bir automated-client filtresi tarafından reddedildiğinde mod modele bir kere browser User-Agent ile tekrar denemesini söyler ve bunu yapmaması gereken iki durumu belirtir.
Ne yapar
Mod Bash tool'unu hook'lar. Bir
curlya dawgetçağrısından sonra komutun kendi çıktısını, iki stream'i de, bir automated-client filtresinin verdiği bir status için okur:403ya da429, bu komutların yazdığı her biçimde (HTTP/2 403,403 Forbidden,curl: (22) ... error: 403,429 Too Many Requests,Rate limit).Zaten bir User-Agent ayarlayan bir komut (
-A,--user-agent,-U, birUser-Agentheader'ı) dokunulmadan bırakılır: tavsiye harcanmıştır.Model bu notu tool'un sonucundan sonra okur:
ua-fallback: example.com answered 403, which is an automated-client filter, not a broken URL. Retry the same request once with a browser User-Agent: -A 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36'. If that is refused too, one of OpenAI File Downloader, XaiImageApiFetch/1.0, Claude-User may pass. Do not do this while testing an application, an API, an auth flow or a client of your own: a changed User-Agent hides the access-control or compatibility problem you are measuring. A reply you get with another User-Agent is not proof the resource works for ordinary clients, and it is never a way around authentication or a permission.Son iki cümle her notta yer alır, çünkü tekrar deneme yalnız public içerik içindir. Bir uygulamanın kendi davranışını ölçmek için gönderilen bir request gerçek client'ını korumak zorundadır ve başka bir User-Agent altındaki bir başarı sıradan client'lar hakkında hiçbir şey söylemez.
Aynı anda transcript'e bir satır yazılır, yalnız bulgu, talimat olmadan:
ua-fallback: example.com answered 403; a browser User-Agent may passsidebar açıkken bu bulgu oraya gider, ilk satırda host ve status ve altında soluk
not while testing your own app, auth flow or clientile, stream'inde bir entry halinde, ve transcript temiz kalır. Sidebar kapalıyken ya da o mod kurulu değilken transcript satırı yukarıdaki gibi yazılır.Bir host session başına bir kere konuşur. Aynı host'tan gelen ikinci reddedilen request sessizdir, yani bir tekrar deneme döngüsü context'i doldurmaz.
Komut
/ua-fallback on ya da off, ve bu session'ın reddedildiği host'lar
/ua-fallback on | off varsayılan on
Kurulum
claude plugin marketplace add KilimcininKorOglu/claude-code-mods
claude plugin install ua-fallback@kilimcininkoroglu-mods
Function hook'lar early access. Flag olmadan hiçbir şey yüklenmez. Flag'i kalıcı yapmak için ~/.claude/settings.json dosyasına ekleyin:
{ "env": { "CLAUDE_CODE_ENABLE_FUNCTION_HOOKS": "1" } }
Kurulumdan sonra
- Claude Code'u yeniden başlatın.
Nereye uzanır
Claude Code 2.1.278 üzerinde claude plugin validate ile doğrulandı:
❯ ./register.ts hooks: session.start, command.run{command=ua-fallback}, tool.call{tool=Bash}
❯ ./register.ts calls: $.command.register, $.sidebar.set (via toPerson), $.store.get, $.store.set (via runCommand), $.ui.log (via toPerson)
Reach L1, session'ı okur.
1. Okur: her Bash komutunun metnini ve iki çıktı stream'ini, bir URL ve bir status için
2. Çalıştırır: hiçbir şey; kendi request'ini göndermez, yani server iki değil bir request görür
3. Gönderir: tool'un sonucundan sonra modele bir not ve transcript'e bir satır; makineden hiçbir şey çıkmaz
4. Saklar: $.store içinde on/off ayarını
5. Düşman girdi: çıktı sabit status pattern'leriyle eşleştirilir ve ondan hiçbir şey nota kopyalanmaz; yalnız URL'nin host'u kopyalanır ve User-Agent string'leri mod içinde sabittir
Sınırlar
- Status, komutun yazdığından okunur. Status metni olmadan yalnız bir body yazan sessiz bir
curl -snot almaz. - Kendi düz metninde "403" yazan bir sayfa filtrelenmiş bir request olarak okunur. Not bir tavsiyedir, response kodunun bir ölçümü değil.
- Mod komutu yeniden yazmaz ve kendi request'ini göndermez, yani çıktıda göremediği bir filtre bildirilmeden kalır.
- Başarısız bir çağrı (
curl --failbir 403'te verdiği gibi sıfır olmayan bir exit) kişiye bildirilir ama modele bildirilmez, böylece modelin kendi hata metni olduğu gibi kalır. - Browser User-Agent'ı
hooks/fetch.tsiçinde bir sabittir ve eskir. Güncel bir sürümü kontrol eden bir site onu reddedebilir.
Geliştirme
make install # eslint, typescript-eslint, typescript
make lint # complexity limiti 10, üstünde build'i düşürür
make typecheck # /plugin-types ile üretilen .claude/types/ gerekir
make validate
make test # claude plugin test
ua-fallback
A Claude Code Mod for the retrieval fallback: when a curl or wget is refused by an automated-client filter, the mod tells the model to retry once with a browser User-Agent, and states the two cases where it must not.
What it does
The mod hooks the Bash tool. After a
curlorwgetcall it reads the command's own output, both streams, for a status an automated-client filter answers with:403or429, in any of the forms those commands print (HTTP/2 403,403 Forbidden,curl: (22) ... error: 403,429 Too Many Requests,Rate limit).A command that already sets a User-Agent (
-A,--user-agent,-U, aUser-Agentheader) is left alone: the advice is spent.The model reads this note after the tool's result:
ua-fallback: example.com answered 403, which is an automated-client filter, not a broken URL. Retry the same request once with a browser User-Agent: -A 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36'. If that is refused too, one of OpenAI File Downloader, XaiImageApiFetch/1.0, Claude-User may pass. Do not do this while testing an application, an API, an auth flow or a client of your own: a changed User-Agent hides the access-control or compatibility problem you are measuring. A reply you get with another User-Agent is not proof the resource works for ordinary clients, and it is never a way around authentication or a permission.The last two sentences ride in every note, because the retry is only for public content. A request sent to measure an application's own behaviour must keep its real client, and a success under another User-Agent says nothing about ordinary clients.
The same moment writes one line to the transcript, the finding alone, without the instruction:
ua-fallback: example.com answered 403; a browser User-Agent may passWhile the sidebar is open, that finding goes there instead, the host and status on the first line and
not while testing your own app, auth flow or clientfaint under it, as an entry in its stream, and the transcript stays clean. With the sidebar closed, or without that mod installed, the transcript line is written as above.One host speaks once per session. The second refused request from the same host is quiet, so a loop of retries does not fill the context.
Command
/ua-fallback on or off, and the hosts this session was refused by
/ua-fallback on | off on by default
Install
claude plugin marketplace add KilimcininKorOglu/claude-code-mods
claude plugin install ua-fallback@kilimcininkoroglu-mods
Function hooks are early access. Nothing loads without the flag. To keep it on, add this to ~/.claude/settings.json:
{ "env": { "CLAUDE_CODE_ENABLE_FUNCTION_HOOKS": "1" } }
After installing
- Restart Claude Code.
What it can reach
Validated with claude plugin validate on Claude Code 2.1.278:
❯ ./register.ts hooks: session.start, command.run{command=ua-fallback}, tool.call{tool=Bash}
❯ ./register.ts calls: $.command.register, $.sidebar.set (via toPerson), $.store.get, $.store.set (via runCommand), $.ui.log (via toPerson)
Reach L1, reads the session.
1. Reads: each Bash command's text and its two output streams, for a URL and a status
2. Runs: nothing; it sends no request of its own, so the server sees one request, not two
3. Sends: a note to the model after the tool's result, and one line to the transcript; nothing leaves the machine
4. Persists: in $.store, the on/off setting
5. Hostile input: the output is matched against fixed status patterns and nothing from it is copied into the note; only the URL's host is, and the User-Agent strings are constants in the mod
Limits
- The status is read from what the command printed. A silent
curl -sthat prints only a body with no status text gets no note. - A page that says "403" in its own prose reads as a filtered request. The note is advice, not a measurement of the response code.
- The mod does not rewrite the command and sends no request of its own, so a filter it cannot see in the output stays unreported.
- A failed call (a non-zero exit, as
curl --failgives on a 403) is reported to the person but not to the model, so the model's own error text stays as it is. - The browser User-Agent is a constant in
hooks/fetch.tsand ages. A site that checks a current version may refuse it.
Development
make install # eslint, typescript-eslint, typescript
make lint # complexity limit 10, fails the build above it
make typecheck # needs .claude/types/ from /plugin-types
make validate
make test # claude plugin test