add-api-route
Add a new JobPilot API route or module the standard way - contracts schema, controller, service, response schema, optional web hook. Use for "add an endpoint",…
Solve a CAPTCHA on the current browser tab - free checkbox/text paths first, then a configured token service for image challenges. Returns solved or unsolved for the caller to fall back.
$ npx -y skills add suxrobGM/jobpilot --skill solve-captcha --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/solve-captchaContext preview
The summary Claude sees to decide when to auto-load this skill.
Solve a CAPTCHA on the current browser tab - free checkbox/text paths first, then a configured token service for image challenges. Returns solved or unsolved for the caller to fall back.
name: solve-captcha description: Solve a CAPTCHA on the current browser tab - free checkbox/text paths first, then a configured token service for image challenges. Returns solved or unsolved for the caller to fall back. argument-hint: "[url | ref_or_description] (optional; a URL → navigate there first; omit → auto-detect)"
Clear a CAPTCHA on the **current browser tab**. Return **solved** or **unsolved** (the caller falls back). Authorized use only - the user's own applications. `$JOBPILOT_API` / `$JOBPILOT_API_TOKEN` are injected by the terminal host.
If the argument is a URL → `browser_navigate` there first. `browser_resize` to a tall viewport (`1280×1400`) so the widget is fully on-screen, then `browser_snapshot` + `browser_take_screenshot` the captcha and classify:
`browser_click` the control by `ref`, `browser_wait_for`, re-snapshot. Verified → **solved**. An image grid opened instead → escalate to §4. **Never hand-click tiles** - automated clicks get flagged and fail.
`browser_take_screenshot`, read the characters, `browser_type` the answer, submit. Verified → **solved**.
Read the sitekey (`browser_evaluate`, read-only):
() => {
const el = document.querySelector(".g-recaptcha, [data-sitekey]");
let key = el?.getAttribute("data-sitekey");
if (!key) {
const f = [...document.querySelectorAll('iframe[src*="recaptcha"]')]
.map((f) => f.src)
.find((s) => /[?&]k=/.test(s));
key = f && new URL(f).searchParams.get("k");
}
return { sitekey: key, pageurl: location.href };
};hCaptcha: `iframe[src*="hcaptcha"]` → `type:"hcaptcha"`. Turnstile: `.cf-turnstile[data-sitekey]` → `type:"turnstile"`.
Solve it server-side (the endpoint resolves the configured key + polls the provider; the skill never sees the key):
RESP=$(curl -fsS -H "authorization: Bearer $JOBPILOT_API_TOKEN" -X POST "$JOBPILOT_API/api/captcha/solve" -H 'content-type: application/json' \
-d "$(jq -n --arg s "$SITEKEY" --arg u "$PAGEURL" '{type:"recaptcha", sitekey:$s, pageurl:$u}')") || true
TOKEN=$(echo "$RESP" | jq -r '.token // empty')Empty `TOKEN` (no key configured, or solver failure) → **unsolved**.
Inject the token (sanctioned `browser_evaluate` - a real solved token, not a faked click), then `browser_click` the form's submit `ref`:
(t) => {
document
.querySelectorAll('textarea[name="g-recaptcha-response"], #g-recaptcha-response')
.forEach((el) => {
el.value = t;
el.style.display = "";
});
try {
for (const c of Object.values(window.___grecaptcha_cfg?.clients ?? {}))
for (const o of Object.values(c))
for (const m of Object.values(o ?? {}))
if (typeof m?.callback === "function") m.callback(t);
} catch {}
};hCaptcha uses `h-captcha-response`; Turnstile uses `cf-turnstile-response`. `browser_wait_for`, verify → **solved**.
An AI agent that applies to jobs for you, on the Claude or Codex subscription you already have.
Repo: suxrobGM/jobpilot
Add a new JobPilot API route or module the standard way - contracts schema, controller, service, response schema, optional web hook. Use for "add an endpoint",…
Review and clean up the given file(s)/folder(s)/module(s): rate organization, find dead code, duplication, coupling, over-engineering, deep nesting, structural…
Create and apply a Prisma migration safely against the remote (tunneled) PostgreSQL. Use for schema changes - "create a migration", "apply migrations", "add a…
Add knip to a TypeScript project and use it to remove dead exports, collapse pass-through barrels, and narrow every export to what another file actually…
Bump the unified JobPilot version (host + plugin), update the changelog, commit, and tag a new release
Rebuild the .NET terminal host, restart it, and wait for /healthz. Use after any C# change under apps/terminal, or when asked to "restart the terminal host".