Files

Input Pipeline Overview

The input side of ResumeCustomizer prepares job-specific Markdown resumes by stitching together the base resume, a job-description Markdown file, and the shared instruction prompt, then invoking the Codex CLI inside a containerized watcher.

Workflow Recap

  1. Ensure input/resume/ contains exactly one Markdown resume.
  2. Drop a single job-description file (plain text or Markdown) into input/ForCustomizing/inbox/.
  3. Start the watcher stack (input/Docker/run-input-processor.sh up -d).
  4. The watcher normalizes the messy job description via Codex (using the baked-in normalizer prompt), stripping recruiter chatter while preserving every job-related detail, then combines the cleaned Markdown, the base resume, and the resolved customization prompt into a second Codex run that writes the generated resume to ForCustomizing/outbox/YYYY/MM/DD/HHMM/<company>-<jobtitle>.md.
  5. Successful runs archive the job description under ForCustomizing/processed/, copy both the prompt and the cleaned job description into the same outbox folder, and leave the Codex output for human review. Failures move the job description into ForCustomizing/failed/.

The human operator reviews the Codex output Markdown, makes any edits, and then manually hands it off to the output pipeline for document rendering.

Container Stack

The watcher lives in input/Docker/:

  • Dockerfile builds a Node/Python base image, installs the Codex CLI, and prepares a non-root codex user.
  • watch_and_customize.py polls the inbox, validates preconditions, resolves both templates (normalizer and customization), cleans the job description, builds prompts, runs Codex twice, and routes files.
  • entrypoint.sh maps the container user to the callers UID/GID and ensures shared directories exist.
  • run-input-processor.sh wrapper around docker compose that resolves your Codex config directory (${HOST_CODEX_DIR:-${HOME}/.codex}) and forwards CLI arguments.
  • docker-compose.yml defines the container, volumes (including machine-id bindings required by the Codex CLI), environment variables, and restart policy (no so fatal errors halt the stack).

Templates

  • baked normalizer prompt (input/Docker/JobDescriptionNormalizerPrompt.md) ships with the container; customize by editing the image.
  • templates/ResumeCustomizerPrompt.md.example ships with default resume-customization instructions. Copy it to ResumeCustomizerPrompt.md to override.
  • The .gitignore in templates/ keeps local overrides out of version control.

Codex CLI

  • The container image installs the official Codex CLI and expects credentials/configuration from the mounted ~/.codex directory on the host.
  • The watcher pipes prompts directly to codex exec - --output-last-message <path> --skip-git-repo-check --sandbox read-only, so no additional command-line customization is required from operators.

Key Environment Variables

  • POLL_INTERVAL_SECONDS watch loop delay (defaults to 5).
  • CODEX_TIMEOUT_SECONDS wall-clock timeout for each Codex call (defaults to 600).
  • HOST_CODEX_DIR host path that mounts into /home/codex/.codex (defaults to ${HOME}/.codex via the wrapper).

Prerequisites

  • Docker Engine with the Compose plugin (docker compose) or the standalone docker-compose binary.
  • A working Codex CLI and credentials in ~/.codex. The Docker build attempts npm install --location=global codex-cli; override or update as needed if packages change.

Failure Modes

  • Multiple resumes or job descriptions watcher exits immediately with a fatal configuration error. Fix the files and restart.
  • Codex CLI missing or failing job description moves to ForCustomizing/failed/; inspect container logs, resolve, and requeue.
  • Timeouts treat as failures; adjust CODEX_TIMEOUT_SECONDS if Codex regularly needs more time.

For day-to-day operating guidelines, see input/AGENTS.md.