nairon-local-agent-browser-qa
Use when testing the Nairon website locally with the agent-browser CLI, especially careers applications and admin review flows.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Use when testing the Nairon website locally with the agent-browser CLI, especially careers applications and admin review flows.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
General-purpose grilling for plans, writing, strategy, life decisions, or early ideas when there is no useful repo/domain documentation to update. Do not prefer for coding work in an existing codebase; use grill-with-docs instead. Use when user wants to stress-test a non-code plan, get grilled on an idea, or mentions "grill me" without a repo-specific task.
Default grilling skill for coding work in an existing repo/codebase. Challenges the plan against code, sharpens shared domain language, and updates CONTEXT.md/ADRs inline. Prefer over grill-me whenever durable repo context, domain terms, implementation behavior, or architectural decisions matter.
Run a premortem on any plan, launch, product, hire, strategy, novel feature idea, or decision. First grills vague novel ideas until they are concrete enough to fail-test, then assumes the plan failed 6 months from now and works backward to find every reason why. Produces a revised plan with blind spots exposed. MANDATORY TRIGGERS: 'premortem this', 'premortem my', 'run a premortem', 'what could kill this', 'future-proof this', 'stress test this plan', 'what am i missing here', 'find the blind spots'. STRONG TRIGGERS: 'what could go wrong', 'am i missing anything', 'poke holes in this', 'where will this break', 'devil's advocate this'. Do NOT trigger on simple feedback requests, factual questions, or LLM Council requests. DO trigger when someone has a plan or commitment where the cost of being wrong is high.
Map a codebase feature-by-feature into a human-readable system tour grounded in real code. Use when the user wants to understand the whole system, onboard quickly into an unfamiliar repo, enumerate major product areas, or create/update high-level architecture, journey, provider, and glossary docs.
Build and leverage online communities to drive product growth and brand loyalty. Use when the user wants to create a community strategy, grow a Discord or Slack community, manage a forum or subreddit, build brand advocates, increase word-of-mouth, drive community-led growth, engage users post-signup, or turn customers into evangelists. Trigger phrases: 'build a community,' 'community strategy,' 'Discord community,' 'Slack community,' 'community-led growth,' 'brand advocates,' 'user community,' 'forum strategy,' 'community engagement,' 'grow our community,' 'ambassador program,' 'community flywheel.'
Principle-grounded review of code changes, PRs, or plans. Use when asked to review, critique, or assess quality of work - "review", "review this", "code review", "check this".
| name | nairon-local-agent-browser-qa |
| description | Use when testing the Nairon website locally with the agent-browser CLI, especially careers applications and admin review flows. |
Use this skill to run the Nairon website locally, exercise it with agent-browser, and leave reproducible evidence in .context/qa-runs.
cd /Users/obaid/conductor/workspaces/nairon-website/louisville-v2
export PATH="/Users/obaid/.bun/bin:$PATH"
QA_DIR=".context/qa-runs/$(date +%Y%m%d-%H%M%S)-local-agent-browser"
mkdir -p "$QA_DIR"
printf "%s\n" "$QA_DIR" > .context/latest-qa-dir
For careers admin tests, CAREERS_ADMIN_TOKEN must be available in the web server process. The ignored .context/CAREERS_ADMIN_TOKEN.txt file is the local source of truth when present.
TOKEN="$(cat .context/CAREERS_ADMIN_TOKEN.txt)"
export CAREERS_ADMIN_TOKEN="$TOKEN"
The web app reads Convex URLs from the repo root .env.local and syncs them into apps/web/.env.local before Vite starts. If the files are missing, pull Vercel env first or start Convex using the repo instructions.
PORT=3001 VITE_DISABLE_REACT_GRAB=true CAREERS_ADMIN_TOKEN="$CAREERS_ADMIN_TOKEN" bun run dev:web
Use lsof -ti tcp:3001 | xargs -r kill if a stale server is already using the port.
Do not rely on bun run dev:server in a fresh workspace unless Convex is already configured; Convex may prompt interactively. For noninteractive QA, use the configured Convex deployment URL from local env and state that the local web app is backed by that deployment.
Load the built-in CLI guidance when needed:
agent-browser skills get core --full
Use isolated sessions and save artifacts under QA_DIR:
export AGENT_BROWSER_SESSION_NAME=nairon-local-qa
agent-browser open http://localhost:3001/careers/founding-engineer
agent-browser snapshot -i > "$QA_DIR/careers-snapshot.txt"
agent-browser screenshot "$QA_DIR/careers.png"
agent-browser open http://localhost:3001/careers/founding-engineer
type="text" with inputMode="url".agent-browser eval "JSON.stringify(Array.from(document.querySelectorAll('#apply input[inputmode=url]')).map(el => ({ name: el.name, type: el.type, inputMode: el.inputMode, valid: el.checkValidity() })), null, 2)" > "$QA_DIR/url-inputs.json"
fill command does not mutate every controlled React input. This page can be affected by smooth scrolling and overlay tooling in local dev.EMAIL="agent.browser+$(date +%s)@example.com"
printf "%s\n" "$EMAIL" > "$QA_DIR/application-email.txt"
agent-browser eval "const values={name:'Agent Browser QA',email:'$EMAIL',phone:'+971501234567',portfolio:'github.com/naironai/local-qa',traces:'traces.com/share/local-agent-browser-qa',aiStack:'Codex, agent-browser CLI, Convex, TanStack Start.',projects:'Built local automated QA for Nairon careers.',note:'Testing the application flow.'}; const setValue=(el,value)=>{ const proto=el instanceof HTMLTextAreaElement ? HTMLTextAreaElement.prototype : HTMLInputElement.prototype; Object.getOwnPropertyDescriptor(proto,'value').set.call(el,value); el.dispatchEvent(new Event('input',{bubbles:true})); el.dispatchEvent(new Event('change',{bubbles:true})); }; const form=document.querySelector('#apply form'); for (const [name,value] of Object.entries(values)) setValue(form.querySelector('[name='+CSS.escape(name)+']'), value); JSON.stringify({valid:form.checkValidity(), formData:Object.fromEntries(new FormData(form).entries())}, null, 2)" > "$QA_DIR/application-before-submit.json"
The browser UI should be checked, but the authoritative local E2E assertion is that the application is saved and can be read through the admin API.
agent-browser eval "document.querySelector('#apply form').requestSubmit(); 'submitted'"
sleep 5
agent-browser snapshot -i > "$QA_DIR/application-after-submit.txt"
bun -e 'const email=process.argv[1]; const token=process.argv[2]; const res=await fetch("http://localhost:3001/api/career-applications",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({adminEmail:"obaid@naironai.com",adminToken:token})}); const json=await res.json(); const found=json.applications?.find(a=>a.email===email); console.log(JSON.stringify({status:res.status, found: found && {name:found.name,email:found.email,portfolioUrl:found.portfolioUrl,roleTitle:found.roleTitle,applicationFieldsJson:found.applicationFieldsJson}}, null, 2));' "$EMAIL" "$CAREERS_ADMIN_TOKEN" > "$QA_DIR/admin-api-verify.json"
Expected:
status is 200.found.email equals the submitted email.https://....applicationFieldsJson includes every role-specific answer.agent-browser open http://localhost:3001/admin/careers
agent-browser eval "const token='$CAREERS_ADMIN_TOKEN'; const setValue=(el,value)=>{ const setter=Object.getOwnPropertyDescriptor(HTMLInputElement.prototype,'value').set; setter.call(el,value); el.dispatchEvent(new Event('input',{bubbles:true})); el.dispatchEvent(new Event('change',{bubbles:true})); }; const form=document.querySelector('form'); setValue(form.querySelector('input[name=adminEmail]'),'obaid@naironai.com'); setValue(form.querySelector('input[name=adminToken]'),token); form.requestSubmit(); 'submitted';"
sleep 4
agent-browser eval "document.body.innerText" > "$QA_DIR/admin-positive.txt"
agent-browser screenshot "$QA_DIR/admin-positive.png"
agent-browser open http://localhost:3001/admin/careers
agent-browser eval "const token='$CAREERS_ADMIN_TOKEN'; const setValue=(el,value)=>{ const setter=Object.getOwnPropertyDescriptor(HTMLInputElement.prototype,'value').set; setter.call(el,value); el.dispatchEvent(new Event('input',{bubbles:true})); el.dispatchEvent(new Event('change',{bubbles:true})); }; const form=document.querySelector('form'); setValue(form.querySelector('input[name=adminEmail]'),'bad@example.com'); setValue(form.querySelector('input[name=adminToken]'),token); form.requestSubmit(); 'submitted';"
sleep 2
agent-browser eval "document.body.innerText" > "$QA_DIR/admin-negative.txt"
Expected negative text includes This email is not authorized for careers admin.
Before finishing code changes:
bun run check-types
bun run build
If apps/web/public/sitemap.xml changes only because the build refreshed <lastmod>, restore the unrelated date churn before committing.
Include:
agent-browser fill not mutating every controlled input on the careers form.