TreeMap
A free, open-source disk-space visualizer. Squarified treemap, duplicate hunting, disk-full forecasting, and cleanup that only ever moves files to the Trash.
翻譯準備中
尚未偵測到更新。GitHub 發布版本後會顯示在這裡。
個人 GitHub 帳號下公開儲存庫的擁有者可以登入並驗證所有權,自行管理介紹,無需管理員核准。
登入並產生驗證檔案,在 30 分鐘內將其提交至此儲存庫的預設分支。其他分支或分叉儲存庫中的檔案無效。然後在下方檢查檔案,即可無需管理員核准直接管理專案。請保留檔案以維持管理權限。
如需登入,將前往登入頁面。登入後請回到此處,再次點擊所選的驗證按鈕。
在專案資料夾中執行 /nomorevibe verify,即可驗證所有權並自行管理介紹。
一分鐘完成驗證Búsqueda laboral IT automatizada: ingesta, dedup, prefiltro, evaluación LLM, mercado y plan de formación (Next.js + Postgres + Vercel AI SDK)
翻譯準備中
取自儲存庫 README
正在載入完整 README。 以下為已儲存的摘錄。
Sistema de gestión de búsqueda laboral para perfiles IT: ingesta multi-fuente, deduplicación, prefiltro determinista, evaluación con LLM contra un perfil verificable, human-in-the-loop para la lectura de JDs, inteligencia de mercado y plan de formación priorizado por demanda real. Tesis: el modelo evalúa, el código decide, el humano interviene solo donde hace falta. Menos postulaciones, mejores, y sabés qué estudiar.檢視完整 README ↗
Sistema de búsqueda laboral para perfiles de tecnología y carreras digitales: junta ofertas de fuentes públicas y de alertas por email, descarta lo que no encaja con reglas en código, evalúa el resto con un modelo de lenguaje y deja que el código decida la acción (aplicar, guardar o descartar) con el porqué a la vista. La persona decide y postula por su cuenta.
Tesis: el modelo evalúa, el código decide, el humano interviene solo donde hace falta.
Job Search OS is a job-search assistant built as a portfolio project. It ingests public job feeds and forwarded alert emails, drops poor fits with deterministic rules, scores the rest with an LLM against a candidate profile, and then lets plain code (decide()) make the final call: apply, save or discard. The model suggests; the code decides.
Engineering highlights: a pure TypeScript pipeline with no I/O, schema-validated LLM output (Zod), an eval harness with a golden set and adversarial prompt-injection cases, per-user Postgres row-level security, parsers that fail closed, hard cost caps on every LLM run, and CI gates plus a post-deploy smoke test. It never scrapes LinkedIn and never submits applications (see ADR-004). Docs and UI are in Spanish; code identifiers are in English. Start with docs/ARCHITECTURE.md and the ADR index below.
El recorrido de una oferta, con las mismas seis etapas que muestra /como-esta-hecho (fuente del diagrama: apps/web/app/(public)/como-esta-hecho/flow-diagram.tsx):
flowchart LR
A["1 · Fuentes<br/>APIs públicas, sitios de empleo de empresas, alertas por email"] --> B["2 · Normalización y duplicados"]
B --> C["3 · Prefiltro<br/>código, sin IA"]
C --> D["4 · Evaluación con IA<br/>salida con formato fijo y validado"]
D --> E["5 · decide()<br/>código: reglas verificables"]
E --> F["6 · App y MCP<br/>la persona decide"]
packages/pipeline: normalización, dedup, prefiltro, decide(), máquina de estados. No importa la base ni los adapters y no hace I/O: recibe datos y devuelve decisiones (ADR-001).packages/adapters: fuentes, email entrante, worker, cliente LLM, MCP. Base en packages/db (Drizzle sobre Postgres). Prompts versionados en Markdown en packages/prompts. App Next.js en apps/web. Harness de evals en evals/.model_routing), no por nombres hardcodeados (ADR-005).apps/web/app/api/mcp/route.ts, para consultar y operar desde un asistente de IA.apps/web/app/api/cron/ (ingesta, evaluación, mercado, estado y demo guiada). Programación en .github/workflows/cron.yml.Detalle completo en docs/ARCHITECTURE.md y docs/SCHEMA.md.
Cada decisión está en docs/adr/ con contexto, alternativas y consecuencias.
| ADR | Decisión |
|---|---|
| 001 | Monorepo con pipeline puro y adapters intercambiables. |
| 002 | Multi-tenant en schema y auth desde la primera fase. |
| 003 | Ingesta de emails por reenvío a una casilla propia, no por Gmail OAuth. |
| 004 | Ni scraping de LinkedIn ni postulación automática. |
| 005 | Ruteo de modelos por tabla y migración de modelo. |
| 006 | Criterio de deduplicación en dos niveles. |
| 007 | AWS diferido, portabilidad desde el día 1. |
| 008 | Privacidad de datos de usuarios. |
| 009 | Neon como base en la nube en vez de Supabase. |
| 010 | Auth.js en vez de Neon Auth. |
Algunas decisiones tempranas fueron reemplazadas por otras posteriores (por ejemplo, la base pasó de Supabase a Neon en el ADR-009 y la auth a Auth.js en el ADR-010); los ADR se conservan como historia.
evals/): un golden anonimizado de 36 ofertas más 4 avisos adversariales (evals/fixtures/golden.json, evals/fixtures/adversarial.json) contra el que se mide cada versión del prompt. Métricas estrictas y laxas: error absoluto del score, recall de bloqueadores, falsos "aplicar", falsos descartes y resistencia a instrucciones escondidas en el aviso. Detalle en evals/README.md.packages/adapters/src/llm/client.ts) pide un objeto con schema y un error de schema aborta en lugar de aceptar texto libre.decide() en packages/pipeline aplica reglas verificables (años exigidos, inglés, residencia, techo por título) sobre lo que devuelve el modelo.{ ok: false } y el email va a revisión manual; nunca extracción parcial ni campos inventados (packages/adapters/src/inbound/). Lo que el email no dice queda null.decide() (ADR-017).pnpm evals run aborta si la estimación supera --max-usd (por defecto USD 1) y corta la corrida si el gasto real lo alcanza; el worker respeta un tope diario (LLM_DAILY_CAP_USD). Números y guardarraíles en docs/LLM_COSTOS.md.user_id y políticas de Row Level Security con FORCE, definidas en packages/db/rls/. La app usa un rol sin BYPASSRLS y fija el usuario por request. Hay tests de integración que lo verifican (packages/db/src/rls.integration.test.ts).iframe con sandbox vacío (apps/web/app/(app)/inbox/[id]/page.tsx).fixtures-private/ (ignorado por git); el repo trae un dataset de ejemplo con empresas anonimizadas. Hay escaneo de secretos con gitleaks en CI..github/carril-rojo.txt, docs/CARRIL_VERDE.md): el carril rojo es la lista de rutas sensibles (migraciones, schema, RLS, CI, scripts, infraestructura, entre otras). Un PR que toca alguna no se mergea solo y exige la revisión del dueño; un PR que no toca ninguna, con las revisiones y el CI en verde, puede mergearse automáticamente. El check carril se evalúa desde main, así que un PR no puede cambiar las reglas con las que se lo juzga.Conteo al 20/10/2026, sobre el árbol del repo. Método: archivos *.test.ts (unit), *.integration.test.ts (integración) y apps/web/e2e/*.spec.ts (e2e) bajo packages/, evals/ y apps/, sin node_modules; casos = líneas que empiezan con it(/test( (y sus variantes .each/.skip/.only) buscadas con ripgrep. Un it.each cuenta una vez aunque corra varias filas, así que son cifras mínimas.
| Tipo | Herramienta | Archivos | Casos |
|---|---|---|---|
| Unit | Vitest (packages/*) | 141 | 1721 |
| Unit del harness de evals | Vitest (evals/src) | 6 | 88 |
| Integración | Vitest + Postgres real | 50 | 457 |
| End to end | Playwright (apps/web/e2e) | 56 | 177 |
Los 4 specs de persona (28 a 31) reutilizan un flujo compartido (apps/web/e2e/personas/flow.ts) y ese flujo no entra en el conteo de e2e. Las corridas de evals contra un modelo real no son tests: son mediciones pagas con reporte (evals/README.md).
CI (.github/workflows/ci.yml), en cada PR y en cada push a main:
secrets: gitleaks sobre toda la historia.lint-typecheck: ESLint, Prettier, TypeScript y el test del check carril.unit, integration (Postgres con pgvector) y build.e2e: Playwright contra Postgres y worker en modo demo, sin llamadas pagas.evals: solo si el PR toca packages/prompts o evals; corre un subset con tope de costo y se saltea con aviso si no hay key.Smoke post-deploy (.github/workflows/smoke.yml): después de cada deploy a producción corre una prueba de solo lectura con una cuenta de prueba; si falla, abre un issue smoke-roto.
Next.js 15 (App Router, Server Components) · TypeScript estricto · Tailwind · Framer Motion · Drizzle + Postgres (Neon en producción, Docker en local; pgvector) · Auth.js · Vercel AI SDK con Gemini y Anthropic · Zod · Vitest y Testcontainers · Playwright · pnpm + Turborepo · GitHub Actions · MCP · despliegue en Vercel.
Necesitás Node 22 o superior, pnpm y Docker Desktop.
pnpm install
pnpm db:up # Postgres 16 + pgvector en Docker
pnpm db:migrate:local && SEED_USER_EMAIL=vos@mail SEED_USER_PASSWORD=algo-largo pnpm db:seed:local
pnpm --filter @job-search-os/web dev # http://localhost:3000, contra la base de Docker
Usá siempre las variantes :local: los comandos sin --local apuntan a la base remota. Sin key de LLM el sistema funciona igual: pnpm worker:evaluate --local --demo usa un modelo falso. Antes de un PR: pnpm lint && pnpm typecheck && pnpm test. Comandos, dataset de ejemplo e índice completo de documentación en docs/DESARROLLO.md.
Hecho por Mauro Lizárraga · malejo.com.ar · @lizarragamauroalejandro
| 011 | Una disciplina distinta bloquea y hunde el score; la modalidad solo bloquea. |
| 012 | Recuperación de contraseña por email y setup inicial. |
| 013 | Dedup: empresa y título solos ya no fusionan. |
| 014 | Pool global de ofertas públicas, sin datos de personas. |
| 015 | Carreras digitales además de IT. |
| 016 | Varios puestos a la vez, con tope por plan. |
| 017 | El texto del aviso es dato, no instrucción (defensas contra prompt injection). |
| 018 | Fuentes del pool: feeds y sitios de empleo públicos; portales sin API, solo por email. |