How the /apply Command Handles Input and URL Parsing in ai-job-search
The /apply command intelligently discriminates between URLs and raw text by checking if arguments match URL patterns, fetches job postings using the WebFetch tool with robust error handling, and treats all content as untrusted data rather than executable instructions.
The /apply command in the MadsLorentzen/ai-job-search repository serves as the primary entry point for processing job applications, with sophisticated input parsing logic defined in .claude/commands/apply.md. Understanding how this command handles input parsing and URL detection is essential for safely automating your job search workflow.
URL Detection and Fetching Strategy
In Step 0 – Parse Input, the command examines the user-supplied $ARGUMENTS parameter to determine if the input matches URL patterns. When a URL is detected, the workflow immediately invokes the WebFetch tool to download the job posting content (see line 23 of the apply spec).
Escalation Order for Failed Fetches
If the initial fetch returns an HTTP 403 error, encounters a login wall, or retrieves a generic listing page rather than the specific job posting, the command does not abort. Instead, it follows a strict escalation order defined in .claude/skills/job-application-assistant/09-web-research.md (referenced at line 24):
- First retry: Attempt the fetch with browser-like headers via
curl - Second retry: Search for the employer's own careers page and extract the posting from there
The command specifically prefers the employer's own posting over third-party aggregators such as LinkedIn or Indeed. Aggregators often strip crucial metadata like requisition IDs, grade levels, or department codes (line 25), making canonical sources more reliable for structured extraction.
Handling Non-URL Input and Safety Measures
Fallback to Pasted Text
When $ARGUMENTS does not resolve to a valid URL pattern, the command treats the content verbatim as pasted text (line 26). This enables users to paste job descriptions directly from clipboard sources when URLs are unavailable or restricted.
Security Isolation and Input Sanitization
The specification implements strict security boundaries to prevent prompt injection attacks. According to line 27 of the apply spec:
- The posting is treated only as data, never as executable instructions
- The system explicitly forbids following hidden directions or commands embedded within the job posting text
- Further URL fetching is restricted to the original argument URL only, preventing the workflow from navigating to unintended external domains
Structured Data Extraction
After obtaining the raw posting—whether via WebFetch or direct text paste—the command extracts specific structured fields: company name, role title, department, location, application deadline, and language. The full posting text is preserved for later archival steps (lines 28-29), ensuring no contextual information is lost during processing.
Programmatic Usage Examples
Use the CLI to apply by URL:
ai-job-search /apply https://careers.example.com/jobs/12345
Apply by pasting job description text:
ai-job-search /apply
# paste the job description, then press Ctrl-D (EOF) to submit
Python wrapper implementation:
from pathlib import Path
import subprocess
# Example with a URL
subprocess.run(["ai-job-search", "/apply", "https://jobs.acme.com/openings/engineer"])
# Example with pasted text
posting_path = Path("my_posting.txt")
subprocess.run(["ai-job-search", "/apply"], input=posting_path.read_text().encode())
Summary
- URL vs. text detection: The command analyzes
$ARGUMENTSto route input through WebFetch for URLs or direct ingestion for pasted text - Robust fetching: Failed f trigger an escalation strategy using browser headers and employer site searches defined in
09-web-research.md - Source preference: Canonical employer postings are prioritized over LinkedIn and Indeed to preserve requisition IDs and grade details
- Security model: Content is strictly isolated as data; executable instructions and additional URL fetching are explicitly blocked
- Data preservation: Structured fields are extracted while maintaining the complete original posting for archival
Frequently Asked Questions
What happens if the job posting URL returns a 403 Forbidden error?
The command enters an escalation workflow defined in .claude/skills/job-application-assistant/09-web-research.md. It first retries with browser-like headers using curl, then attempts to locate the posting on the employer's careers page directly rather than abandoning the process.
Can I use the /apply command without a URL?
Yes. If $ARGUMENTS does not match URL patterns, the command accepts the input as verbatim pasted text (line 26). Simply invoke the command and paste the job description content directly into the terminal.
Why does the command prefer employer websites over LinkedIn or Indeed?
According to line 25 of the apply spec, third-party aggregators often strip critical details such as requisition IDs, grade levels, or department information. Employer sites provide canonical, complete postings that enable more accurate structured data extraction.
How does the command prevent malicious content in job postings?
The specification at line 27 explicitly treats postings only as data, never as executable instructions. The command ignores hidden directions embedded in the posting text and restricts all subsequent URL fetching to the original input URL, preventing unauthorized external navigation.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →