diff --git a/.github/workflows/indexnow.yml b/.github/workflows/indexnow.yml index a1b14e80..6e928431 100644 --- a/.github/workflows/indexnow.yml +++ b/.github/workflows/indexnow.yml @@ -123,6 +123,11 @@ jobs: for extra in ( 'https://career-ops.org/llms.txt', 'https://career-ops.org/llms-full.txt', + # The category guide's old URLs, which 301 to /ai-job-search. They + # left the sitemap, and IndexNow asks to be told about redirects + # too. Drop these once Bing has absorbed the move (search-ops). + 'https://career-ops.org/blog/the-complete-ai-job-search-guide', + 'https://career-ops.org/blog/the-complete-guide-to-ai-powered-job-search-in-2026', ): if extra not in urls: urls.append(extra) diff --git a/content/blog/ai-job-search.es.mdx b/content/blog/ai-job-search.es.mdx new file mode 100644 index 00000000..a9c2d2d2 --- /dev/null +++ b/content/blog/ai-job-search.es.mdx @@ -0,0 +1,127 @@ +--- +title: "Cómo elegir un agente de IA para buscar trabajo" +description: "Un agente de IA para buscar trabajo lee vacantes, las puntúa según tu CV y redacta candidaturas. Siete preguntas antes de elegir uno, desde quién envía la candidatura hasta adónde va tu CV." +date: "2026-10-31" +lastModified: "2026-10-31" +tags: [ai-job-search, guide, ai-job-search-agent, methodology] +summary: "Un agente de IA para buscar trabajo lee vacantes, las puntúa según tu CV y redacta candidaturas. Siete preguntas antes de elegir uno, desde quién envía la candidatura hasta adónde va tu CV." +translationHash: 7a64132aaffe9d22 +localized: true +translatedFrom: /ai-job-search +faq: + - q: "¿Cuál es la mejor herramienta de IA para buscar trabajo?" + a: "No hay una única mejor herramienta de IA para buscar trabajo; la mejor es la que supera tus propias comprobaciones. Pregunta quién envía la candidatura, adónde va tu CV, si evalúa las vacantes antes de aplicar, cuánto cuesta, si puedes leerla y cambiarla, si encaja con las herramientas que ya usas y cómo se mantiene al día con las nuevas fuentes de empleo." + - q: "¿Qué es un agente de IA para buscar trabajo?" + a: "Un agente de IA para buscar trabajo es un software que encuentra vacantes, puntúa cada una según tu CV y redacta el material de la candidatura, para que dediques tu tiempo a los puestos que merecen la pena. Se diferencia de un chatbot en que sigue un proceso repetible y lleva el registro de lo que ha hecho." + - q: "¿Puede un agente de IA gestionar toda mi búsqueda de empleo?" + a: "Un agente de IA puede encargarse de las partes repetitivas: revisar fuentes de empleo, puntuar vacantes, adaptar tu CV y hacer el seguimiento de las candidaturas. Las decisiones siguen siendo tuyas: qué puestos quieres, si una vacante merece una candidatura y qué envías." + - q: "¿Hay algún agente de IA que aplique a empleos automáticamente?" + a: "Algunas herramientas lo anuncian. career-ops no aplica por ti; prepara, y tú envías. Redacta y rellena; nunca envía. Tú pulsas Enviar." + - q: "¿Existe un agente de IA gratuito y open source para buscar trabajo?" + a: "Sí. career-ops es un agente de IA open source para buscar trabajo con licencia MIT, gratis para el candidato y sin planes de pago. Solo pagas a tu proveedor de IA, si es que pagas, porque también funciona con modelos gratuitos y locales." + - q: "¿Cómo puntúa un agente de IA una vacante según mi CV?" + a: "Lee la vacante junto con tu CV y tus objetivos, y da una puntuación con su razonamiento. career-ops puntúa cada vacante de 1 a 5 en cinco dimensiones: encaje con tu CV, alineación con tus puestos objetivo, compensación, señales culturales y señales de alerta. Por debajo de 4,0, recomienda no aplicar salvo que tengas un motivo concreto." +--- + +{/* Las preguntas frecuentes de abajo están duplicadas en el `faq` del frontmatter (JSON-LD FAQPage): edita ambos a la vez. El control de paridad de schema en CI compara cada pregunta y cada respuesta literalmente. */} + +Un agente de IA para buscar trabajo es un software que encuentra vacantes, puntúa cada una según tu CV y redacta el material de la candidatura, para que dediques tu tiempo a los puestos que merecen la pena. Para elegir uno, hazte siete preguntas: quién envía la candidatura, adónde va tu CV, si evalúa antes de aplicar, cuánto cuesta, si puedes leerlo y cambiarlo, si encaja con las herramientas que ya usas y cómo se mantiene al día con las nuevas fuentes de empleo. + +Cada pregunta viene con la respuesta de una herramienta, [career-ops, un agente de IA open source para buscar trabajo](/es), para que veas cómo es una respuesta concreta. Hazle las mismas preguntas a cualquier herramienta que estés valorando. + +**En esta página:** [¿Quién envía la candidatura?](#quien-envia-la-candidatura) · [¿Adónde va tu CV?](#adonde-va-tu-cv) · [¿Evalúa antes de aplicar?](#evalua-antes-de-aplicar) · [¿Cuánto cuesta?](#cuanto-cuesta) · [¿Puedes leerlo y cambiarlo?](#puedes-leerlo-y-cambiarlo) · [¿Encaja con tus herramientas?](#encaja-con-las-herramientas-que-ya-usas) · [¿Cómo se mantiene al día?](#como-se-mantiene-al-dia-con-las-nuevas-fuentes-de-empleo) · [Una búsqueda, paso a paso](#como-es-una-busqueda-paso-a-paso) · [Límites](#los-limites-que-debes-comprobar-antes-de-decidirte) · [Preguntas frecuentes](#preguntas-frecuentes) + +## ¿Quién envía la candidatura? [#quien-envia-la-candidatura] + +Empieza por aquí, porque esta respuesta decide quién asume el riesgo. Una candidatura sale con tu nombre. Si un agente envía por su cuenta, una respuesta equivocada en un formulario o un puesto que nunca aceptarías pasan a ser tu problema, y te enteras después. + +career-ops pone el límite en un solo sitio: redacta y rellena; nunca envía. Tú pulsas Enviar. No manda ninguna candidatura a un portal de empleo ni ningún correo. Redacta a partir de tu CV, y tú revisas cada línea antes de enviarla. + +## ¿Adónde va tu CV? [#adonde-va-tu-cv] + +Un CV contiene tu historial laboral, tus datos de contacto y, durante una búsqueda, lo que ganas y lo que quieres ganar. Pregunta adónde va todo eso, quién lo guarda y si puedes recuperarlo. + +Sin backend nuestro. Tu CV va de tu máquina al proveedor de IA que elegiste, y a ningún otro sitio. career-ops guarda tu CV, tu perfil, tu pipeline y tus informes como archivos de texto en tu equipo. Con un modelo local, tu CV no sale de tu equipo. La [política de privacidad](/privacy) cubre el sitio web. + +## ¿Evalúa antes de aplicar? [#evalua-antes-de-aplicar] + +Una herramienta pensada para el volumen te ayuda a enviar más candidaturas. Una pensada como filtro te ayuda a enviar menos y mejores. Fíjate en qué hace cuando un puesto encaja mal: ¿te lo dice y te enseña por qué? + +career-ops [puntúa cada vacante según tu CV](/es/docs/introduction/guides/is-this-job-worth-applying-to) de 1 a 5, con su razonamiento, en cinco dimensiones: encaje con tu CV, alineación con tus puestos objetivo, compensación, señales culturales y señales de alerta. Por debajo de 4,0, recomienda no aplicar salvo que tengas un motivo concreto. Tú decides. + + + La candidata y el puesto son inventados. Esto no es una evaluación real. Solo muestra cómo se lee el razonamiento. + + +Maya, ingeniera de backend, quiere trabajo de producto en un equipo pequeño. Pega una vacante de Senior Platform Engineer. Su CV encaja con el núcleo del puesto, pero un requisito crítico solo encaja en parte, el puesto se inclina hacia la infraestructura y la vacante describe una organización grande. **Puntuación (ficticia): 3,6/5.** El informe recomienda no aplicar y nombra cada carencia. Maya sabe algo que el informe no puede ver, una amiga en el equipo, así que aplica de todos modos. La decisión es suya. + +## ¿Cuánto cuesta? [#cuanto-cuesta] + +Pregunta qué pagas por el software, qué pagas por el modelo de IA que hay detrás y qué pasa cuando termina la prueba. + +career-ops es gratis para el candidato, para siempre, con licencia MIT: sin planes de pago, sin niveles, sin pruebas. Solo pagas a tu proveedor de IA, si es que pagas, porque también [funciona con modelos gratuitos y locales](/es/docs/free-ai-engine). El escáner por defecto no consume tokens de IA. + +## ¿Puedes leerlo y cambiarlo? [#puedes-leerlo-y-cambiarlo] + +Si un agente puntúa tu búsqueda de empleo, deberías poder ver cómo lo hace. Con el open source, puedes leer las reglas, comprobar lo que afirma y cambiar lo que no te sirva. + +career-ops es [open source en GitHub](https://github.com/career-ops-hq/career-ops) y lo mejoran sus propios usuarios. Su [metodología está publicada](/methodology). Las instrucciones que sigue son texto plano en el repositorio, y lo adaptas diciéndole en el chat lo que quieres y lo que rechazas. + +## ¿Encaja con las herramientas que ya usas? [#encaja-con-las-herramientas-que-ya-usas] + +Un agente que te obliga a reorganizar tu día es un agente que dejas de usar. Pregunta dónde se ejecuta y con qué modelos de IA funciona. + +career-ops se ejecuta dentro del CLI de IA para programar que elijas, como Claude Code, Codex, Cursor, OpenCode y [los demás CLIs compatibles](/es/docs/supported-clis). No necesitas programar. Necesitas sentirte cómodo ejecutando un comando en una terminal; después, la configuración y el uso diario son una conversación en lenguaje natural. + +## ¿Cómo se mantiene al día con las nuevas fuentes de empleo? [#como-se-mantiene-al-dia-con-las-nuevas-fuentes-de-empleo] + +Los portales de empleo aparecen y cambian, así que una herramienta de búsqueda necesita mantenimiento, y alguien tiene que hacerlo. Pregunta esto: ¿las nuevas fuentes te llegan con una actualización que no toca tus datos, o mantienes tu propia copia y pasas los cambios a mano? + +career-ops lee [más de 100 fuentes de empleo](https://github.com/career-ops-hq/career-ops/blob/main/docs/SUPPORTED_JOB_BOARDS.md), y las nuevas llegan con las actualizaciones. Los plugins de la comunidad se revisan y se fijan a un commit. `/career-ops update` te enseña una vista previa de los cambios antes de tocar nada, y su [Data Contract](https://github.com/career-ops-hq/career-ops/blob/main/DATA_CONTRACT.md) deja fuera tu CV, tu perfil y tus informes. + +## Cómo es una búsqueda, paso a paso [#como-es-una-busqueda-paso-a-paso] + +Sea cual sea la herramienta, una búsqueda estructurada tiene los mismos cinco pasos. Así funcionan en career-ops: + +1. **Buscar.** [Lee las fuentes de empleo que elegiste](/es/docs/introduction/guides/scan-job-portals) para encontrar vacantes que encajen con tus puestos objetivo. +2. **Evaluar.** [Puntúa cada vacante](/es/docs/introduction/guides/is-this-job-worth-applying-to) según tu CV, o [un lote entero](/es/docs/introduction/guides/batch-evaluate-offers) de una vez. +3. **Adaptar.** [Redacta el CV y las respuestas](/es/docs/introduction/guides/apply-for-a-job) para los puestos que superan tu listón. +4. **Revisar.** Lee cada línea, corrige lo que esté mal y pulsa Enviar tú. +5. **Hacer seguimiento.** [Guarda cada candidatura y su estado](/es/docs/reference/modes/tracker) en un solo sitio, para ver qué toca después. + +## Los límites que debes comprobar antes de decidirte [#los-limites-que-debes-comprobar-antes-de-decidirte] + +Toda herramienta honesta tiene límites, y conviene oírlos antes de decidirte. Estos son los de career-ops: + +- **No puede decirte quién va a contestar.** Una puntuación te dice cuánto encaja un puesto con tu CV y con lo que quieres. No predice el resultado. +- **Las primeras evaluaciones son toscas.** Todavía no te conoce. Mejoran cuando le dices tus puestos objetivo y corriges lo que falló. +- **Necesita una terminal para empezar.** Ejecutas un comando, y necesitas Node.js. Si no usas un CLI de programación, [apúntate a la lista de espera de la versión web](/es/waitlist?ref=guide-es). +- **No lee todos los sitios.** El escáner no lee LinkedIn, Indeed ni Naukri directamente, pero puedes pegar cualquier vacante de ellos y la evalúa. + +Su autor, Santiago Fernández de Valderrama Aparicio, creó career-ops para su propia búsqueda de empleo y publica un solo embudo: 740 vacantes evaluadas → 68 candidaturas → 12 entrevistas → 1 oferta. Es la búsqueda de una persona, no una promesa. + +## Preguntas frecuentes [#preguntas-frecuentes] + +### ¿Cuál es la mejor herramienta de IA para buscar trabajo? + +No hay una única mejor herramienta de IA para buscar trabajo; la mejor es la que supera tus propias comprobaciones. Pregunta quién envía la candidatura, adónde va tu CV, si evalúa las vacantes antes de aplicar, cuánto cuesta, si puedes leerla y cambiarla, si encaja con las herramientas que ya usas y cómo se mantiene al día con las nuevas fuentes de empleo. + +### ¿Qué es un agente de IA para buscar trabajo? + +Un agente de IA para buscar trabajo es un software que encuentra vacantes, puntúa cada una según tu CV y redacta el material de la candidatura, para que dediques tu tiempo a los puestos que merecen la pena. Se diferencia de un chatbot en que sigue un proceso repetible y lleva el registro de lo que ha hecho. + +### ¿Puede un agente de IA gestionar toda mi búsqueda de empleo? + +Un agente de IA puede encargarse de las partes repetitivas: revisar fuentes de empleo, puntuar vacantes, adaptar tu CV y hacer el seguimiento de las candidaturas. Las decisiones siguen siendo tuyas: qué puestos quieres, si una vacante merece una candidatura y qué envías. + +### ¿Hay algún agente de IA que aplique a empleos automáticamente? + +Algunas herramientas lo anuncian. career-ops no aplica por ti; prepara, y tú envías. Redacta y rellena; nunca envía. Tú pulsas Enviar. + +### ¿Existe un agente de IA gratuito y open source para buscar trabajo? + +Sí. career-ops es un agente de IA open source para buscar trabajo con licencia MIT, gratis para el candidato y sin planes de pago. Solo pagas a tu proveedor de IA, si es que pagas, porque también funciona con modelos gratuitos y locales. + +### ¿Cómo puntúa un agente de IA una vacante según mi CV? + +Lee la vacante junto con tu CV y tus objetivos, y da una puntuación con su razonamiento. career-ops puntúa cada vacante de 1 a 5 en cinco dimensiones: encaje con tu CV, alineación con tus puestos objetivo, compensación, señales culturales y señales de alerta. Por debajo de 4,0, recomienda no aplicar salvo que tengas un motivo concreto. diff --git a/content/blog/ai-job-search.mdx b/content/blog/ai-job-search.mdx new file mode 100644 index 00000000..2f4a35e7 --- /dev/null +++ b/content/blog/ai-job-search.mdx @@ -0,0 +1,128 @@ +--- +title: "How to choose an AI job search agent" +description: "AI job search agents read job listings, score them against your CV and draft applications. Seven questions to ask before you pick one, from who sends the application to where your CV goes." +date: "2026-05-18" +lastModified: "2026-10-31" +tags: [ai-job-search, guide, ai-job-search-agent, methodology] +summary: "AI job search agents read job listings, score them against your CV and draft applications. Seven questions to ask before you pick one, from who sends the application to where your CV goes." +faq: + - q: "What is the best AI job search tool?" + a: "There is no single best AI job search tool; the best one is the one that passes your own checks. Ask who sends the application, where your CV goes, whether it evaluates listings before it applies, what it costs, whether you can read and change it, whether it fits the tools you already use, and how it keeps up with new job sources." + - q: "What is an AI job search agent?" + a: "An AI job search agent is software that finds job listings, scores each one against your CV and drafts the application material, so you spend your time on the roles worth applying to. The difference from a chatbot is that it follows a repeatable process and keeps track of what it did." + - q: "Can an AI agent manage my whole job search?" + a: "An AI agent can run the repetitive parts: scanning job sources, scoring listings, tailoring your CV and tracking applications. The decisions stay with you: which roles you want, whether a listing is worth an application, and what you send." + - q: "Is there an AI agent that applies to jobs automatically?" + a: "Some tools advertise it. career-ops does not apply for you; it prepares, you send. It drafts and fills; it never submits. You press Submit." + - q: "Is there a free, open-source AI job search agent?" + a: "Yes. career-ops is an open-source AI job search agent under the MIT license, free for candidates, with no paid plans. You only pay your AI provider, if at all, because it also runs on free and local models." + - q: "How does an AI agent score a job against my resume?" + a: "It reads the job posting against your CV and your targets, then gives a score with its reasoning. career-ops scores each posting from 1 to 5 across five dimensions: match with your CV, alignment with your target roles, comp, cultural signals and red flags. Below 4.0, it recommends against applying unless you have a specific reason." +--- + +{/* The FAQ below is duplicated in the frontmatter `faq` (FAQPage JSON-LD): edit both together. The CI schema parity guard compares every question and answer literally. */} + +An AI job search agent is software that finds job listings, scores each one against your CV (resume) and drafts the application material, so you spend your time on the roles worth applying to. To choose one, ask seven questions: who sends the application, where your CV goes, whether it evaluates before it applies, what it costs, whether you can read and change it, whether it fits the tools you already use, and how it keeps up with new job sources. + +Each question below comes with the answer of one tool, [career-ops, an open-source AI job search agent](/), so you can see what a concrete answer looks like. Ask any tool you are considering the same questions. + +**On this page:** [Who sends the application?](#who-sends-the-application) · [Where does your CV go?](#where-does-your-cv-go) · [Does it evaluate before it applies?](#does-it-evaluate-before-it-applies) · [What does it cost?](#what-does-it-cost) · [Can you read it and change it?](#can-you-read-it-and-change-it) · [Does it fit your tools?](#does-it-fit-the-tools-you-already-use) · [How does it keep up?](#how-does-it-keep-up-with-new-job-sources) · [A search, step by step](#what-a-search-looks-like-step-by-step) · [Limits](#the-limits-to-check-before-you-commit) · [FAQ](#frequently-asked-questions) + +## Who sends the application? [#who-sends-the-application] + +Start here, because this answer decides who carries the risk. An application goes out under your name. If an agent submits on its own, a wrong answer on a form or a role you would never take becomes your problem, and you find out afterwards. + +career-ops draws the line in one place: it drafts and fills; it never submits. You press Submit. It sends no application to a job portal and no email. It writes its drafts from your CV, and you review every line before you send it. + +## Where does your CV go? [#where-does-your-cv-go] + +A CV holds your employment history, your contact details and, in a search, what you earn and what you want to earn. Ask where that goes, who stores it and whether you can get it back. + +No backend of ours. Your CV goes from your machine to the AI provider you chose, and nowhere else. career-ops keeps your CV, profile, pipeline and reports as plain files on your computer. With a local model, your CV stays on your computer. The [privacy policy](/privacy) covers the website itself. + +## Does it evaluate before it applies? [#does-it-evaluate-before-it-applies] + +A tool built for volume helps you send more applications. A tool built as a filter helps you send fewer and better ones. Look at what it does when a job is a poor fit: does it say so, and does it show why? + +career-ops [scores each job posting against your resume](/docs/introduction/guides/is-this-job-worth-applying-to) from 1 to 5, with its reasoning, across five dimensions: match with your CV, alignment with your target roles, comp, cultural signals and red flags. Below 4.0, it recommends against applying unless you have a specific reason. You decide. + + + The candidate and the role here are invented. This is not a real evaluation. It only shows how the reasoning reads. + + +Maya, a backend engineer, wants product work on a small team. She pastes a Senior Platform Engineer posting. Her CV matches the core of the job, but one critical requirement is only a partial match, the role leans toward infrastructure, and the posting describes a large organization. **Score (fictional): 3.6/5.** The report recommends against applying and names each gap. Maya knows something the report cannot see, a friend on the team, so she applies anyway. The call is hers. + +## What does it cost? [#what-does-it-cost] + +Ask what you pay for the software, what you pay for the AI model behind it, and what happens when a trial ends. + +career-ops is free for candidates, forever, and MIT-licensed: no paid plans, no tiers, no trials. You only pay your AI provider, if at all, because it also [runs on free and local models](/docs/free-ai-engine). The default scanner uses no AI tokens. + +## Can you read it and change it? [#can-you-read-it-and-change-it] + +If an agent scores your job search, you should be able to see how. With open source, you can read the rules, check a claim and change what does not suit you. + +career-ops is [open source on GitHub](https://github.com/career-ops-hq/career-ops), and its own users improve it. Its [methodology is published](/methodology). The instructions it follows are plain text in the repository, and you adapt it by telling it in chat what you want and what you refuse. + +## Does it fit the tools you already use? [#does-it-fit-the-tools-you-already-use] + +An agent you have to build your day around is one you stop using. Ask where it runs and which AI models it works with. + +career-ops runs inside the AI coding CLI you choose, including Claude Code, Codex, Cursor, OpenCode and [the other supported CLIs](/docs/supported-clis). You don't need to code. You need to be comfortable running one command in a terminal; after that, setup and daily use are a conversation in plain language. + +## How does it keep up with new job sources? [#how-does-it-keep-up-with-new-job-sources] + +Job boards appear and change, so a job search tool needs upkeep, and someone has to do it. Ask this: do new job sources reach you through an update that leaves your data alone, or do you maintain your own copy and move changes across by hand? + +career-ops reads [more than 100 job sources](https://github.com/career-ops-hq/career-ops/blob/main/docs/SUPPORTED_JOB_BOARDS.md), and new ones arrive with updates. Community plugins are reviewed and pinned to a commit. `/career-ops update` shows you a diff preview before it changes anything, and its [Data Contract](https://github.com/career-ops-hq/career-ops/blob/main/DATA_CONTRACT.md) keeps your CV, profile and reports out of it. + +## What a search looks like, step by step [#what-a-search-looks-like-step-by-step] + +Whichever tool you choose, a structured search has the same five steps. Here is how they run in career-ops: + +1. **Scan.** [Read the job sources you picked](/docs/introduction/guides/scan-job-portals) for listings that match your target roles. +2. **Evaluate.** [Score each listing](/docs/introduction/guides/is-this-job-worth-applying-to) against your CV, or [a whole batch](/docs/introduction/guides/batch-evaluate-offers) at once. +3. **Tailor.** [Draft the CV and the answers](/docs/introduction/guides/apply-for-a-job) for the roles that clear your bar. +4. **Review.** Read every line, fix what is wrong, and press Submit yourself. +5. **Track.** [Keep every application and its status](/docs/reference/modes/tracker) in one place, so you can see what to do next. + +## The limits to check before you commit [#the-limits-to-check-before-you-commit] + +Any honest tool has limits, and you should hear them before you commit. These are career-ops's: + +- **It cannot tell you who will reply.** A score tells you how well a role fits your CV and what you want. It does not predict the result. +- **The first evaluations are rough.** It does not know you yet. They improve once you tell it your target roles and correct what it got wrong. +- **It needs a terminal to start.** You run one command, and you need Node.js. If you don't use a coding CLI, [join the waitlist for a web version](/waitlist?ref=guide-en). +- **It does not scan every site.** The scanner does not read LinkedIn, Indeed or Naukri directly, but you can paste any listing from them and it evaluates it. + +Its author, Santiago Fernández de Valderrama Aparicio, built career-ops for his own job search and publishes one funnel: 740 listings evaluated → 68 applications → 12 interviews → 1 offer. That is one person's search, not a promise. + +## Frequently asked questions [#frequently-asked-questions] + +### What is the best AI job search tool? + +There is no single best AI job search tool; the best one is the one that passes your own checks. Ask who sends the application, where your CV goes, whether it evaluates listings before it applies, what it costs, whether you can read and change it, whether it fits the tools you already use, and how it keeps up with new job sources. + +### What is an AI job search agent? + +An AI job search agent is software that finds job listings, scores each one against your CV and drafts the application material, so you spend your time on the roles worth applying to. The difference from a chatbot is that it follows a repeatable process and keeps track of what it did. + +### Can an AI agent manage my whole job search? + +An AI agent can run the repetitive parts: scanning job sources, scoring listings, tailoring your CV and tracking applications. The decisions stay with you: which roles you want, whether a listing is worth an application, and what you send. + +### Is there an AI agent that applies to jobs automatically? + +Some tools advertise it. career-ops does not apply for you; it prepares, you send. It drafts and fills; it never submits. You press Submit. + +### Is there a free, open-source AI job search agent? + +Yes. career-ops is an open-source AI job search agent under the MIT license, free for candidates, with no paid plans. You only pay your AI provider, if at all, because it also runs on free and local models. + +### How does an AI agent score a job against my resume? + +It reads the job posting against your CV and your targets, then gives a score with its reasoning. career-ops scores each posting from 1 to 5 across five dimensions: match with your CV, alignment with your target roles, comp, cultural signals and red flags. Below 4.0, it recommends against applying unless you have a specific reason. + +## Keep reading [#keep-reading] + +For a longer answer on running the whole search with an agent, read [Can an AI agent run your job search?](/blog/can-an-ai-agent-run-your-job-search) diff --git a/content/blog/the-complete-ai-job-search-guide.mdx b/content/blog/the-complete-ai-job-search-guide.mdx deleted file mode 100644 index f32521c7..00000000 --- a/content/blog/the-complete-ai-job-search-guide.mdx +++ /dev/null @@ -1,106 +0,0 @@ ---- -title: "AI job search in 2026: a practical guide" -description: An honest, current guide to using AI for job search in 2026 — what works, what is wasted effort, and which tools fit which audiences. Written by someone who used the approach to land a Head of AI role. -date: "2026-05-18" -lastModified: "2026-10-11" -tags: [ai-job-search, guide, claude-code, methodology] -summary: A practical 2026 guide to AI-powered job search. Covers the asymmetry between recruiter-side and candidate-side AI, the four phases of a structured search, which tools fit which user profile, and where to spend time vs where not to. ---- - -Most "AI job search guides" online are either marketing copy for a single tool or a list of generic tips that ignore how the field has actually shifted in the last twelve months. This is the honest version, written by someone who used the approach to evaluate 740 listings, apply to 68 roles, and land one Head of AI offer — then open-sourced the system. - -The guide is opinionated. Three foundational claims drive everything that follows. - -**One.** The hiring market in 2026 is asymmetric. Companies have used AI to filter candidates for nearly a decade — applicant tracking systems, automated screening, AI-assisted interviewer notes. Candidates, until very recently, had nothing equivalent. Large language models inverted that asymmetry in the last eighteen months. The candidate side now has access to better reasoning than the ATS doing the filtering. - -**Two.** Volume is the wrong objective. Spray-and-pray was always a bad strategy, but in a post-LLM world where everyone can spray faster, it is actively self-destructive. Recruiters drowning in AI-generated mass applications now filter more aggressively, which means the cost of a low-quality application is higher than it was in 2023. Fewer applications, more tailored, beat the inverse. - -**Three.** The tool you choose matters less than the workflow you adopt. Jobscan, Teal, Huntr, career-ops, your own GPT prompts — all of these can produce a competent tailored application. What separates effective searches from ineffective ones is the structure: scanning systematically, filtering against an explicit rubric, tailoring per listing, and tracking with discipline. The tool is a force multiplier on the workflow, not a substitute for it. - -## The four phases of a structured AI job search - -Every AI-powered job search worth running has the same four phases. Different tools handle each phase with different polish, but the phases themselves are non-negotiable. - -### Phase 1 — Scan - -Define your target archetypes before you start scanning. An archetype is a specific shape of role you would take: "Staff Software Engineer at a Series B–D AI company, full remote or hybrid in EU, comp band $250K–$400K." If you cannot write the archetype in one sentence, you do not have one yet — and scanning without an archetype just produces noise. - -With archetypes defined, scanning means hitting the public APIs of the major applicant tracking systems used by your target companies. Greenhouse, Ashby, and Lever each publish public job-board APIs that anyone can query without authentication. Workday and SmartRecruiters require more careful handling. LinkedIn is the largest source but the ToS explicitly forbids scraping and the workarounds expose you to account suspension; most serious AI job search tools (including career-ops) deliberately stay off LinkedIn for that reason. - -The output of Phase 1 is a flat list of listings — title, company, location, JD text — that matched your archetype keywords. Realistically you will end the day with a hundred listings if you ran a broad scan, or twenty if you scanned only your top-tier companies. - -### Phase 2 — Evaluate - -This is where the wheat-from-chaff happens. Every listing gets scored against an explicit rubric. The rubric matters because without one, you fall back on gut response, and gut response in a job search trends toward applying to everything because rejection is uncomfortable and applying feels productive. - -A useful rubric covers at minimum five dimensions, plus one overall score: match (does your background actually fit the role), north-star alignment (does the role move you toward your stated career direction), comp (is the comp band realistic and in your acceptable range), cultural signals (culture, growth stage, stability, remote policy), and red flags (legal, ethical, or operational blockers). The global score is not a sixth dimension — it is the model's holistic judgement across those five, weighing everything together into a single number. - -Score on 1-5. Set a threshold — career-ops uses 4.0 — and reject everything below it. In practice, on a scan of 100 listings, roughly 8–12 will clear a 4.0 threshold against a well-defined archetype. The rest are off-archetype, under-leveled, mispriced, or carry flags severe enough that applying is wasted time. - -The cost of this step before LLMs was thirty minutes of careful reading per listing, which meant most people skipped the step. With LLMs, the cost per evaluation is under a minute and a few cents of tokens. The economics shifted; the discipline did not. - -### Phase 3 — Tailor - -Every listing that clears the threshold gets a tailored CV and a tailored application. Tailoring used to be the bottleneck: thirty minutes per listing to rewrite bullets, surface relevant experience, integrate JD keywords, and format for ATS parsers. Most people tailored a third of their applications because that was the cost ceiling they could pay. - -LLMs collapsed this. An LLM with your CV and the JD can produce a tailored variant in under a minute, integrating the JD's priority keywords naturally (when they accurately describe what you have done) and reordering sections to surface the most relevant experience first. - -The work shifted from "writing the tailored variant" to "reviewing the tailored variant." Five minutes of human review per listing is sustainable. Thirty minutes of human writing is not. The math inverted. - -Tailoring well is also the highest-ROI moment in the entire search. I do not quote a multiplier here: I have not found one with a source good enough to repeat. - -### Phase 4 — Track - -Every application you send becomes a future thing you need to manage: when did you apply, what stage is it in, who responded, what is the next action, when is the followup due. A search with even thirty active applications becomes psychologically rough without explicit tracking. - -The minimum useful tracker has: company, role, date applied, score, stage, last contact date, next action, next action due date. That is enough structure to surface what to do next on any given morning. Beyond the minimum, the marginal value of more fields drops quickly. - -The tool that handles this varies wildly by preference. A Notion database works. A Google Sheet works. Huntr's Kanban board works. Teal's web dashboard works. career-ops's Go TUI dashboard works. The shape of the tool matters less than the discipline of keeping it current. - -## Which tool fits which user - -Five archetypes cover most active job searchers in 2026. Each maps to a different tool choice. - -**The polished SaaS user.** You want a web app with a Chrome extension, a polished UI, and a one-click "save this job" workflow. You will pay $30–60 a month for the convenience. Your data lives on a vendor's servers; that is a trade-off you accept. - -→ **[Teal](/compare/career-ops-vs-teal)** (full-pipeline ATS-friendly resume builder + Kanban tracker + Chrome extension) or **[Huntr](/compare/career-ops-vs-huntr)** (Kanban-first with a popular Chrome extension). - -**The ATS-anxious applicant.** You believe — correctly — that ATS keyword alignment matters for your applications. You want a tool that scans your resume against a JD and tells you what is missing. You will iterate manually on the edits. - -→ **[Jobscan](/compare/career-ops-vs-jobscan)** is the polished answer here. It costs $50/month for the full toolset, and it does one thing well: keyword gap analysis. - -**The technical user who wants ownership.** You write code, you live in a terminal, and the SaaS pattern annoys you because your career data ends up on someone else's servers and the matching algorithm is a black box. - -→ **career-ops** (MIT-licensed, runs locally through your AI CLI, full pipeline from scan to evaluation to tailoring to tracking). Setup takes fifteen minutes if you already have Node 22.13+ (23.4+ on Node 23); if you do not, the other tools are friendlier. - -**The senior operator with one shot at a role.** You are not in active search. You have one specific role you want, possibly through a warm intro. You do not need an entire pipeline; you need to nail this single application. - -→ Run ChatGPT or Claude manually with the JD and your CV. The single-shot quality of a focused conversation beats any structured pipeline for a single application. Tools become valuable when applications multiply. - -**The recruiter or hiring manager curious about the candidate side.** You want to understand what is happening on the other end of the funnel. - -→ Read [career-ops's published methodology](/methodology). It is the most transparent rubric and pipeline anyone has published in this space. You will see exactly what a structured candidate process looks like. - -## Where to spend time and where not to - -**Spend time on:** - -- **Archetype definition.** One hour writing your archetypes saves a hundred hours of scanning the wrong listings. -- **Reviewing tailored variants.** The LLM does the first draft; you do the final pass. Five minutes per application makes the difference between a generic tailored response and a credible one. -- **Followups.** A one-line followup at the right cadence moves the response rate more than any algorithm tweak. Most candidates skip this. - -**Do not spend time on:** - -- **Tweaking your master CV constantly.** Master once thoroughly, then let the tailoring step produce variants. Most CV rewriting energy is wasted at the source level. -- **Cover letter templates.** Per-listing cover letters generated against the JD outperform any reusable template by a wide margin. Skip the template-building. -- **LinkedIn optimization theater.** A clean headline, a current role, and a working "open to" signal cover 95% of LinkedIn's value to most candidates. The remaining 5% rarely justifies the hours. - -## A final note on ethics - -The mass auto-application pattern — point an AI agent at a job board, click "auto-apply" on everything — is a defection from the equilibrium that benefited everyone, candidates included. Recruiters' pipelines are visibly degraded by it. Response rates dropped industry-wide. Quality candidates lose because the noise floor rose. - -Structured AI-augmented search is the cooperative move. Filter against a real rubric, apply only to listings you actually fit, draft each application well, retain the submit decision. That is the pattern career-ops and similar tools were built around. It produces better outcomes for the candidate using the tool, and it does not poison the well for everyone else. - -If you want to see what a complete implementation of this pattern looks like, [the repo is here](https://github.com/career-ops-hq/career-ops). If you want comparisons against the polished SaaS alternatives, [those are here](/compare). If you want to read the rubric and the canonical evaluation prompt, [the methodology is published in full](/methodology). - -Pick a tool, define your archetypes, run the four phases with discipline. The candidate side of the table is finally on level footing with the recruiter side. The question is what you do with it. diff --git a/content/docs/free-ai-engine.mdx b/content/docs/free-ai-engine.mdx index 9d7ac3c9..ae4b75d5 100644 --- a/content/docs/free-ai-engine.mdx +++ b/content/docs/free-ai-engine.mdx @@ -93,3 +93,5 @@ The core career-ops repo's **[Running on a Budget](https://github.com/career-ops ## You're ready Once your engine is set up, continue to the **[Quick Start](/docs)** — you'll clone career-ops, add your CV, and run your first free scan. + +Still choosing a tool? Read [how to choose an AI job search agent](/ai-job-search). diff --git a/content/docs/index.mdx b/content/docs/index.mdx index 7d53d86d..4560fe0e 100644 --- a/content/docs/index.mdx +++ b/content/docs/index.mdx @@ -7,6 +7,8 @@ icon: Rocket This guide takes you from zero to your first evaluated job in about fifteen minutes the first time. You will set up the workspace, open your AI coding assistant, and paste a job posting. The agent completes any needed onboarding, then gives you a full report, a score, and a tailored PDF resume. +Still comparing tools? Read [how to choose an AI job search agent](/ai-job-search) first. + ## What you need You do not need to know how to code. You only need to be comfortable opening a terminal and running a command. diff --git a/content/docs/introduction/guides/is-this-job-worth-applying-to.mdx b/content/docs/introduction/guides/is-this-job-worth-applying-to.mdx index bba1a9df..2b4bfb0b 100644 --- a/content/docs/introduction/guides/is-this-job-worth-applying-to.mdx +++ b/content/docs/introduction/guides/is-this-job-worth-applying-to.mdx @@ -17,7 +17,7 @@ career-ops is built around one decision: whether a posting deserves an applicati career-ops is designed for quality, not quantity. It steers you toward fewer, better applications, and it says so plainly when a posting falls short. A result that says *do not apply* is the product doing its job. -Fewer, better applications is also a matter of dignity on both sides of the table. Recruiters' time deserves respect. So does yours. +Fewer, better applications is also a matter of dignity on both sides of the table. Recruiters' time deserves respect. So does yours. If you are still choosing a tool, read [how to choose an AI job search agent](/ai-job-search). > I built career-ops for my own 2026 job search. My funnel: 740 evaluated → 68 applied → 12 interviews → 1 offer. — Santiago Fernández de Valderrama Aparicio diff --git a/content/docs/introduction/what-is-career-ops.es.mdx b/content/docs/introduction/what-is-career-ops.es.mdx index 8fde1787..f2854ba9 100644 --- a/content/docs/introduction/what-is-career-ops.es.mdx +++ b/content/docs/introduction/what-is-career-ops.es.mdx @@ -3,7 +3,7 @@ title: Qué es career-ops description: "career-ops es un sistema de búsqueda de empleo con IA, gratis y open source, que se ejecuta en local dentro del CLI de IA que ya usas: puntúa ofertas, adapta tu CV y hace seguimiento de tus candidaturas." seoTitle: "¿Qué es career-ops? El sistema de búsqueda de empleo con IA, open source y local-first" icon: CircleQuestionMark -translationHash: 34992fc9b6bc843b +translationHash: f1c9c1ccb82cd32c localized: true translatedFrom: /docs/introduction/what-is-career-ops --- @@ -26,7 +26,7 @@ career-ops no incluye su propio modelo de IA. Funciona como un conjunto de slash ## Cuándo usar career-ops -career-ops es la herramienta adecuada cuando haces una búsqueda de empleo activa y estructurada, no cuando echas un vistazo casual. Funciona mejor para candidatos que ya tienen un CV con el que están contentos y quieren adaptarlo a cada candidatura sin reescribirlo a mano cada vez, que gestionan varias candidaturas y quieren una única fuente de verdad en lugar de una hoja de cálculo desbordada, que quieren postular solo a puestos que de verdad encajan en vez de a todo lo vagamente relacionado, y que se manejan con comandos en una terminal aunque no programen profesionalmente. career-ops probablemente no es lo que necesitas si vas a enviar una o dos candidaturas y ya está. La configuración — clonar el repo, configurar tu perfil, añadir tu CV — lleva unos quince minutos, una inversión que solo compensa cuando evalúas más de un puñado de puestos. +career-ops es la herramienta adecuada cuando haces una búsqueda de empleo activa y estructurada, no cuando echas un vistazo casual. Funciona mejor para candidatos que ya tienen un CV con el que están contentos y quieren adaptarlo a cada candidatura sin reescribirlo a mano cada vez, que gestionan varias candidaturas y quieren una única fuente de verdad en lugar de una hoja de cálculo desbordada, que quieren postular solo a puestos que de verdad encajan en vez de a todo lo vagamente relacionado, y que se manejan con comandos en una terminal aunque no programen profesionalmente. career-ops probablemente no es lo que necesitas si vas a enviar una o dos candidaturas y ya está. La configuración — clonar el repo, configurar tu perfil, añadir tu CV — lleva unos quince minutos, una inversión que solo compensa cuando evalúas más de un puñado de puestos. Para comparar opciones antes, lee [cómo elegir un agente de IA para buscar trabajo](/es/ai-job-search). ## Lo que no es diff --git a/content/docs/introduction/what-is-career-ops.mdx b/content/docs/introduction/what-is-career-ops.mdx index 9ad02e4d..8dc63c4c 100644 --- a/content/docs/introduction/what-is-career-ops.mdx +++ b/content/docs/introduction/what-is-career-ops.mdx @@ -25,7 +25,7 @@ career-ops does not ship its own AI model. It runs as a set of slash commands an ## When to use career-ops -career-ops is the right tool when you are running an active, structured job search — not casually browsing. It works best for candidates who have a CV they are happy with and want to tailor per application without rewriting it manually each time, who are tracking multiple applications and want a single source of truth instead of a sprawling spreadsheet, who want to apply only to roles that actually fit rather than everything vaguely relevant, and who are comfortable running commands in a terminal even if they do not write code professionally. career-ops is probably not what you need if you are sending one or two applications and are done. The setup — cloning the repo, configuring your profile, adding your CV — takes about fifteen minutes, an investment that only pays off once you are evaluating more than a handful of roles. +career-ops is the right tool when you are running an active, structured job search — not casually browsing. It works best for candidates who have a CV they are happy with and want to tailor per application without rewriting it manually each time, who are tracking multiple applications and want a single source of truth instead of a sprawling spreadsheet, who want to apply only to roles that actually fit rather than everything vaguely relevant, and who are comfortable running commands in a terminal even if they do not write code professionally. career-ops is probably not what you need if you are sending one or two applications and are done. The setup — cloning the repo, configuring your profile, adding your CV — takes about fifteen minutes, an investment that only pays off once you are evaluating more than a handful of roles. To compare your options first, read [how to choose an AI job search agent](/ai-job-search). ## What it is not diff --git a/next.config.mjs b/next.config.mjs index 20305525..a39bc273 100644 --- a/next.config.mjs +++ b/next.config.mjs @@ -167,6 +167,19 @@ const config = { missing: [{ type: 'header', key: 'accept', value: '.*text/html.*' }], destination: '/es/manifesto.md', }, + // Same for the category guide and its literal twins. + { + source: '/ai-job-search', + has: [{ type: 'header', key: 'accept', value: '.*text/markdown.*' }], + missing: [{ type: 'header', key: 'accept', value: '.*text/html.*' }], + destination: '/ai-job-search.md', + }, + { + source: '/es/ai-job-search', + has: [{ type: 'header', key: 'accept', value: '.*text/markdown.*' }], + missing: [{ type: 'header', key: 'accept', value: '.*text/html.*' }], + destination: '/es/ai-job-search.md', + }, ], }; }, diff --git a/scripts/verify-agent-layer.mjs b/scripts/verify-agent-layer.mjs index 313579ae..a2b27fd1 100644 --- a/scripts/verify-agent-layer.mjs +++ b/scripts/verify-agent-layer.mjs @@ -304,6 +304,26 @@ async function main() { } } + // 6. The category guide: top-level, so the docs rewrite and the proxy do not + // cover it. Literal .md twins, Accept on the human URL, an llms.txt line. + { + const { body: llms } = await get('/llms.txt'); + if (!llms.includes('https://career-ops.org/ai-job-search')) + fail('/llms.txt lost the /ai-job-search line'); + for (const url of ['/ai-job-search', '/es/ai-job-search']) { + const md = await get(`${url}.md`); + if (md.res.status !== 200) fail(`${url}.md status ${md.res.status} (want 200)`); + if (!md.ct.includes('text/markdown')) fail(`${url}.md content-type "${md.ct}"`); + if ((md.res.headers.get('x-robots-tag') || '') !== 'noindex') + fail(`${url}.md missing X-Robots-Tag: noindex`); + if (!(md.res.headers.get('link') || '').includes(`https://career-ops.org${url}>; rel="canonical"`)) + fail(`${url}.md missing its Link canonical`); + if (/\[#[a-z0-9-]+\]$/m.test(md.body)) fail(`${url}.md leaks heading anchors`); + const acc = await get(url, { Accept: 'text/markdown' }); + if (!acc.ct.includes('text/markdown')) fail(`${url} with Accept:markdown returned "${acc.ct}"`); + } + } + if (failures.length) { console.error(`\n✗ Agent-layer guard: ${failures.length} regression(s)\n`); for (const f of failures) console.error(` - ${f}`); diff --git a/scripts/verify-i18n-seo.mjs b/scripts/verify-i18n-seo.mjs index 73c4cb21..19e68d88 100644 --- a/scripts/verify-i18n-seo.mjs +++ b/scripts/verify-i18n-seo.mjs @@ -70,7 +70,10 @@ const tagOf = (locale) => LANG_TAG[locale] ?? locale; const HTML_VARY_MODE = 'warn'; // English URLs removed on purpose (each with its 308 in next.config.mjs). -const ALLOWED_EN_REMOVALS = []; +const ALLOWED_EN_REMOVALS = [ + // The category guide moved to /ai-job-search with a 301 (search-ops, 26-oct). + 'https://career-ops.org/blog/the-complete-ai-job-search-guide', +]; // Public image URLs that must keep working: the EN home's share card under its // pre-October-2026 name, and a signatory's wide card at its stable path. Both diff --git a/src/app/(en)/ai-job-search/layout.tsx b/src/app/(en)/ai-job-search/layout.tsx new file mode 100644 index 00000000..5b52000f --- /dev/null +++ b/src/app/(en)/ai-job-search/layout.tsx @@ -0,0 +1,6 @@ +import { HomeLayout } from 'fumadocs-ui/layouts/home'; +import { baseOptions } from '@/lib/layout.shared'; + +export default function Layout({ children }: LayoutProps<'/ai-job-search'>) { + return {children}; +} diff --git a/src/app/(en)/ai-job-search/page.tsx b/src/app/(en)/ai-job-search/page.tsx new file mode 100644 index 00000000..4af73734 --- /dev/null +++ b/src/app/(en)/ai-job-search/page.tsx @@ -0,0 +1,35 @@ +import { DEFAULT_OG_IMAGE } from '@/lib/shared'; +import type { Metadata } from 'next'; +import { aiJobSearchGuide } from '@/lib/blog-source'; +import { BlogPostView, type BlogFrontmatter } from '@/components/blog-post-view'; + +// The category guide (F4, search-ops). Its text is content/blog/ai-job-search.mdx. +const en = aiJobSearchGuide('en'); +const es = aiJobSearchGuide('es'); +const data = en.data as unknown as BlogFrontmatter; +const url = `https://career-ops.org${en.url}`; + +export const metadata: Metadata = { + title: `${data.title} · career-ops`, + description: data.description, + alternates: { + canonical: url, + languages: { en: url, es: `https://career-ops.org${es.url}`, 'x-default': url }, + }, + openGraph: { + images: [DEFAULT_OG_IMAGE], + type: 'article', + url, + siteName: 'career-ops', + title: data.title, + description: data.description, + publishedTime: data.date, + modifiedTime: data.lastModified || data.date, + }, + twitter: { images: [DEFAULT_OG_IMAGE.url], card: 'summary_large_image' }, + robots: { index: true, follow: true }, +}; + +export default function AiJobSearchPage() { + return ; +} diff --git a/src/app/(en)/blog/[slug]/page.tsx b/src/app/(en)/blog/[slug]/page.tsx index d9db6188..0a6de1b7 100644 --- a/src/app/(en)/blog/[slug]/page.tsx +++ b/src/app/(en)/blog/[slug]/page.tsx @@ -1,14 +1,17 @@ import { DEFAULT_OG_IMAGE } from '@/lib/shared'; import type { Metadata } from 'next'; import { notFound } from 'next/navigation'; -import { blogSource, blogTwin } from '@/lib/blog-source'; +import { blogRoutePages, blogSource, blogTwin } from '@/lib/blog-source'; import { BlogPostView, type BlogFrontmatter } from '@/components/blog-post-view'; +// Only the listed posts exist here; the category guide lives at /ai-job-search. +export const dynamicParams = false; + export async function generateStaticParams() { // /blog/[slug] is a single-segment route, so we flatten the slugs // array Fumadocs returns to a string. Posts must live at // content/blog/.mdx (no nested directories) for this to hold. - return blogSource.getPages('en').map((page) => ({ slug: page.slugs[0] })); + return blogRoutePages('en').map((page) => ({ slug: page.slugs[0] })); } export async function generateMetadata( diff --git a/src/app/(en)/compare/page.tsx b/src/app/(en)/compare/page.tsx index 54ce7b2a..cd09a1cd 100644 --- a/src/app/(en)/compare/page.tsx +++ b/src/app/(en)/compare/page.tsx @@ -32,7 +32,11 @@ export default function CompareIndexPage() {

Open source local vs SaaS cloud. MIT vs proprietary. Free vs $50–200 a month. The matrix is honest, the verdicts are blunt, and neither - product wins every row. + product wins every row. Not sure what to compare? Start with{' '} + + how to choose an AI job search agent + + .

diff --git a/src/app/(en)/manifesto/page.tsx b/src/app/(en)/manifesto/page.tsx index 11cba61c..a0c2adc5 100644 --- a/src/app/(en)/manifesto/page.tsx +++ b/src/app/(en)/manifesto/page.tsx @@ -338,6 +338,19 @@ export default async function ManifestoPage() { {AI_JOB_SEARCH_IN_THE_MANIFESTO}

+ {/* Below the block, not inside it: the block is one literal version on + every surface (page, schema FAQ, llms.txt, MANIFESTO.md) and links + to no career-ops page (venture-ops, 24-oct). */} +

+ For the practical side, read{' '} + + How to choose an AI job search agent + + . +


diff --git a/src/app/_home/home-content.tsx b/src/app/_home/home-content.tsx index 619fdc01..85446c70 100644 --- a/src/app/_home/home-content.tsx +++ b/src/app/_home/home-content.tsx @@ -268,6 +268,13 @@ export async function HomeContent({ dict }: { dict: HomeDict }) {

)} + {dict.aiJobSearchGuideLabel && dict.aiJobSearchGuideHref && ( +

+ + {dict.aiJobSearchGuideLabel} + +

+ )}

{'//'}{' '} {formatK(stats.stars)}{dict.statsComment} diff --git a/src/app/_home/home-dict.tsx b/src/app/_home/home-dict.tsx index b88810ce..47d4c9a2 100644 --- a/src/app/_home/home-dict.tsx +++ b/src/app/_home/home-dict.tsx @@ -54,6 +54,10 @@ export type HomeDict = { // arrow. Optional: only EN and ES have the definition block. aiJobSearchLabel?: string; aiJobSearchHref?: string; + // Link to the AI job search guide (24-oct, search-ops: Bing counted one + // internal anchor to it). EN and ES: the guide has no other twins. + aiJobSearchGuideLabel?: string; + aiJobSearchGuideHref?: string; authorTagline: string; // Official localized rendering of the signature thesis, shown BELOW the // literal-English blockquote (which stays verbatim on every locale, it is the diff --git a/src/app/_home/home-en.tsx b/src/app/_home/home-en.tsx index 32609b57..678b5c1d 100644 --- a/src/app/_home/home-en.tsx +++ b/src/app/_home/home-en.tsx @@ -32,6 +32,8 @@ export const homeEn: HomeDict = { worthApplyingHref: '/docs/introduction/guides/is-this-job-worth-applying-to', aiJobSearchLabel: 'What is AI job search?', aiJobSearchHref: '/manifesto#what-is-ai-job-search', + aiJobSearchGuideLabel: 'How to choose an AI job search agent', + aiJobSearchGuideHref: '/ai-job-search', authorTagline: ', 16-year operator and creator of career-ops', nowSignedManifesto: <>Now a signed manifesto ·, readIt: 'Read it →', diff --git a/src/app/_home/home-es.tsx b/src/app/_home/home-es.tsx index 2d795c27..a9b82b78 100644 --- a/src/app/_home/home-es.tsx +++ b/src/app/_home/home-es.tsx @@ -31,6 +31,8 @@ export const homeEs: HomeDict = { worthApplyingLabel: 'Cómo saber si una oferta merece tu candidatura →', worthApplyingHref: '/es/docs/introduction/guides/is-this-job-worth-applying-to', aiJobSearchLabel: '¿Qué es la búsqueda de empleo con IA?', + aiJobSearchGuideLabel: 'Cómo elegir un agente de IA para buscar trabajo', + aiJobSearchGuideHref: '/es/ai-job-search', aiJobSearchHref: '/es/manifesto#what-is-ai-job-search', authorTagline: ', operador durante 16 años y creador de career-ops', // Versión «yo» oficial del README.es (superficie personal = home). El diff --git a/src/app/ai-job-search.md/route.ts b/src/app/ai-job-search.md/route.ts new file mode 100644 index 00000000..933c24ea --- /dev/null +++ b/src/app/ai-job-search.md/route.ts @@ -0,0 +1,5 @@ +import { aiJobSearchMarkdown } from '@/lib/ai-job-search-md'; + +export async function GET() { + return aiJobSearchMarkdown('en'); +} diff --git a/src/app/es/ai-job-search.md/route.ts b/src/app/es/ai-job-search.md/route.ts new file mode 100644 index 00000000..79a40e6f --- /dev/null +++ b/src/app/es/ai-job-search.md/route.ts @@ -0,0 +1,5 @@ +import { aiJobSearchMarkdown } from '@/lib/ai-job-search-md'; + +export async function GET() { + return aiJobSearchMarkdown('es'); +} diff --git a/src/app/es/ai-job-search/layout.tsx b/src/app/es/ai-job-search/layout.tsx new file mode 100644 index 00000000..773957a0 --- /dev/null +++ b/src/app/es/ai-job-search/layout.tsx @@ -0,0 +1,7 @@ +import type { ReactNode } from 'react'; +import { HomeLayout } from 'fumadocs-ui/layouts/home'; +import { baseOptions } from '@/lib/layout.shared'; + +export default function Layout({ children }: { children: ReactNode }) { + return {children}; +} diff --git a/src/app/es/ai-job-search/page.tsx b/src/app/es/ai-job-search/page.tsx new file mode 100644 index 00000000..3c6d74b2 --- /dev/null +++ b/src/app/es/ai-job-search/page.tsx @@ -0,0 +1,37 @@ +import { OG_IMAGE_BY_LOCALE } from '@/lib/shared'; +import type { Metadata } from 'next'; +import { aiJobSearchGuide } from '@/lib/blog-source'; +import { BlogPostView, type BlogFrontmatter } from '@/components/blog-post-view'; + +// Spanish twin of the category guide. Its text is content/blog/ai-job-search.es.mdx. +const en = aiJobSearchGuide('en'); +const es = aiJobSearchGuide('es'); +const data = es.data as unknown as BlogFrontmatter; +const url = `https://career-ops.org${es.url}`; +const enUrl = `https://career-ops.org${en.url}`; + +export const metadata: Metadata = { + title: `${data.title} · career-ops`, + description: data.description, + alternates: { + canonical: url, + languages: { en: enUrl, es: url, 'x-default': enUrl }, + }, + openGraph: { + images: [OG_IMAGE_BY_LOCALE.es], + type: 'article', + url, + siteName: 'career-ops', + locale: 'es_ES', + title: data.title, + description: data.description, + publishedTime: data.date, + modifiedTime: data.lastModified || data.date, + }, + twitter: { images: [OG_IMAGE_BY_LOCALE.es.url], card: 'summary_large_image' }, + robots: { index: true, follow: true }, +}; + +export default function SpanishAiJobSearchPage() { + return ; +} diff --git a/src/app/es/blog/[slug]/page.tsx b/src/app/es/blog/[slug]/page.tsx index 61d4cf39..4f60fd1b 100644 --- a/src/app/es/blog/[slug]/page.tsx +++ b/src/app/es/blog/[slug]/page.tsx @@ -1,14 +1,14 @@ import { OG_IMAGE_BY_LOCALE } from '@/lib/shared'; import type { Metadata } from 'next'; import { notFound } from 'next/navigation'; -import { blogSource, blogTwin } from '@/lib/blog-source'; +import { blogRoutePages, blogSource, blogTwin } from '@/lib/blog-source'; import { BlogPostView, type BlogFrontmatter } from '@/components/blog-post-view'; // Only posts with a Spanish twin exist here; any other /es/blog/* path 404s. export const dynamicParams = false; export async function generateStaticParams() { - return blogSource.getPages('es').map((page) => ({ slug: page.slugs[0] })); + return blogRoutePages('es').map((page) => ({ slug: page.slugs[0] })); } type Props = { params: Promise<{ slug: string }> }; diff --git a/src/components/language-bar.tsx b/src/components/language-bar.tsx index a593ccbb..881152cb 100644 --- a/src/components/language-bar.tsx +++ b/src/components/language-bar.tsx @@ -187,6 +187,7 @@ function localeUrl(base: string, target: Code): string { return MANIFESTO_LOCALES.includes(target) ? `/${target}/manifesto` : `/${target}`; } if (base === '/waitlist') return `/${target}/waitlist`; + if (target === 'es' && base === '/ai-job-search') return '/es/ai-job-search'; if (target === 'es' && base.startsWith('/blog/') && BLOG_ES_TWINS.includes(base.slice(6))) { return `/es${base}`; // a blog post with a Spanish twin (same slug) } diff --git a/src/components/root-shell.tsx b/src/components/root-shell.tsx index 9a7a46fa..73040981 100644 --- a/src/components/root-shell.tsx +++ b/src/components/root-shell.tsx @@ -156,6 +156,13 @@ export async function RootShell({ locale, children }: { locale: SiteLocale; chil Blog + {/* EN and ES only: the guide has no other twins (24-oct, search-ops: Bing + counted one internal anchor to it). */} + {(locale === 'en' || locale === 'es') && ( + + AI job search guide + + )} Changelog diff --git a/src/lib/ai-job-search-md.ts b/src/lib/ai-job-search-md.ts new file mode 100644 index 00000000..dd3956a5 --- /dev/null +++ b/src/lib/ai-job-search-md.ts @@ -0,0 +1,27 @@ +import { aiJobSearchGuide } from '@/lib/blog-source'; +import { normalizeAgentMarkdown } from '@/lib/source'; + +// Markdown twin of the category guide, for AI assistants. A literal route, like +// /manifesto.md and /changelog.md: extension paths route reliably only as literal +// segments, and the proxy does not cover this page. Top-level pages need this +// route, an llms.txt line and a guard invariant (scripts/verify-agent-layer.mjs). +export async function aiJobSearchMarkdown(locale: 'en' | 'es'): Promise { + const page = aiJobSearchGuide(locale); + const url = `https://career-ops.org${page.url}`; + // Drop the explicit [#id] anchors: they are page markup, not text for a reader. + const body = normalizeAgentMarkdown(await page.data.getText('processed')).replace( + /^(#{1,6} .*?) \[#[^\]]+\]$/gm, + '$1', + ); + return new Response(`# ${page.data.title} (${url})\n\n${body}\n`, { + headers: { + 'Content-Type': 'text/markdown; charset=utf-8', + Link: `<${url}>; rel="canonical"`, + // Alternate form of the HTML page, never competing with it in the index. + 'X-Robots-Tag': 'noindex', + // Same URL, HTML or markdown depending on Accept. Next.js drops the Vary + // set in next.config for these responses (search-ops D3, 30-sep). + Vary: 'Accept', + }, + }); +} diff --git a/src/lib/blog-source.ts b/src/lib/blog-source.ts index 537888ff..43759a60 100644 --- a/src/lib/blog-source.ts +++ b/src/lib/blog-source.ts @@ -1,5 +1,5 @@ import { blog } from 'collections/server'; -import { type InferPageType, loader } from 'fumadocs-core/source'; +import { createGetUrl, type InferPageType, loader } from 'fumadocs-core/source'; import { lucideIconsPlugin } from 'fumadocs-core/source/lucide-icons'; import { i18n } from '@/lib/i18n'; import { BLOG_ES_TWINS } from '@/lib/blog-twins'; @@ -9,9 +9,24 @@ import { BLOG_ES_TWINS } from '@/lib/blog-twins'; // has a Spanish twin iff content/blog/.es.mdx exists, and the twin keeps // the English slug (/es/blog/). EN surfaces (index, sitemap, llms-full) // must ask for getPages('en'): with i18n on, getPages() returns every locale. +// +// One post lives outside /blog: the category guide, at /ai-job-search and +// /es/ai-job-search (Santiago, 26-oct: Bing weighs the phrase in the URL). +// Keeping it in this collection means the blog index, the sitemap and llms-full +// follow it through page.url. The /blog routes must not serve it: they list +// blogRoutePages(). +const AI_JOB_SEARCH_SLUG = 'ai-job-search'; +const blogUrl = createGetUrl('/blog', i18n); + export const blogSource = loader({ i18n, baseUrl: '/blog', + url: (slugs, locale) => + slugs[0] === AI_JOB_SEARCH_SLUG + ? locale === 'es' + ? '/es/ai-job-search' + : '/ai-job-search' + : blogUrl(slugs, locale), source: blog.toFumadocsSource(), plugins: [lucideIconsPlugin()], }); @@ -23,6 +38,18 @@ export function blogTwin(page: BlogPage, locale: 'en' | 'es'): BlogPage | undefi return blogSource.getPage(page.slugs, locale); } +/** The posts served under /blog (or /es/blog), so everything but the guide. */ +export function blogRoutePages(locale: 'en' | 'es'): BlogPage[] { + return blogSource.getPages(locale).filter((p) => p.slugs[0] !== AI_JOB_SEARCH_SLUG); +} + +/** The category guide in `locale`. It exists on disk, so a miss is a broken build. */ +export function aiJobSearchGuide(locale: 'en' | 'es'): BlogPage { + const page = blogSource.getPage([AI_JOB_SEARCH_SLUG], locale); + if (!page) throw new Error(`blog: the ${locale} category guide is missing`); + return page; +} + // Build-time invariants. A Spanish post without an English twin, a French // post (no /fr/blog route exists), or a twin list that disagrees with the // files would each publish something broken without any error. diff --git a/src/lib/blog-twins.ts b/src/lib/blog-twins.ts index ae5304cd..f1589f92 100644 --- a/src/lib/blog-twins.ts +++ b/src/lib/blog-twins.ts @@ -3,4 +3,4 @@ // a client component and cannot read the content loader, so it reads this // list; src/lib/blog-source.ts fails the build if it ever disagrees with the // files on disk. -export const BLOG_ES_TWINS: readonly string[] = ['why-am-i-not-getting-interviews']; +export const BLOG_ES_TWINS: readonly string[] = ['why-am-i-not-getting-interviews', 'ai-job-search']; diff --git a/src/lib/llms-index.ts b/src/lib/llms-index.ts index e4154441..130b6232 100644 --- a/src/lib/llms-index.ts +++ b/src/lib/llms-index.ts @@ -121,7 +121,7 @@ ${comparisonsData.comparisons ## Long-form (blog) - https://career-ops.org/blog/why-career-ops — the thesis behind the project, what it deliberately is not, and the asymmetry it addresses -- https://career-ops.org/blog/the-complete-ai-job-search-guide — opinionated guide to AI-powered job search in 2026, four-phase pipeline, tool selection by user archetype +- https://career-ops.org/ai-job-search — how to choose an AI job search agent: seven questions, from who sends the application to where your CV goes - https://career-ops.org/blog/job-search-data-from-740-listings — real data from one real search: threshold ratios, tailoring delta, reject-pile patterns - https://career-ops.org/blog/why-am-i-not-getting-interviews — why applications go unanswered: what the US hiring data says, and what you control (where you apply, who you write to, your own funnel). diff --git a/vercel.json b/vercel.json index 387536ca..368a893e 100644 --- a/vercel.json +++ b/vercel.json @@ -80,10 +80,15 @@ "destination": "/blog/open-source-job-application-tracker", "permanent": true }, + { + "source": "/blog/the-complete-ai-job-search-guide", + "destination": "/ai-job-search", + "statusCode": 301 + }, { "source": "/blog/the-complete-guide-to-ai-powered-job-search-in-2026", - "destination": "/blog/the-complete-ai-job-search-guide", - "permanent": true + "destination": "/ai-job-search", + "statusCode": 301 }, { "source": "/community", @@ -137,8 +142,8 @@ }, { "source": "/ai-job-search-tool", - "destination": "/blog/the-complete-ai-job-search-guide", - "permanent": true + "destination": "/ai-job-search", + "statusCode": 301 }, { "source": "/job-application-tracker",