Skip to main content

Job application tracker CLI for Applika.dev

Project description

applika-cli

Command-line interface for Applika.dev — a structured job application tracker designed for active job seekers who want full control over their data without relying on a browser.

Track every application you send, filter and review your pipeline from the terminal, and keep your AI coding assistant (Claude Code, Gemini, Codex) aware of the CLI through a bundled skill file.

Requirements

  • Python 3.10+
  • uv (recommended) or pip

Installation

# Using uv (recommended)
uv tool install applika-cli

# Using pipx
pipx install applika-cli

This installs the applika binary globally. Verify:

applika --help

To install from a local source checkout (useful during development):

uv tool install --force .

Authentication

The CLI authenticates via GitHub OAuth. On applika login, your browser opens to GitHub's authorization page. Once you authorize, the callback is captured locally on a loopback port and the session (access + refresh tokens) is saved to ~/.config/applika/session.json. The session refreshes automatically on expiry — you only need to log in once per device.

# Open browser and complete GitHub OAuth
applika login

# Verify the active session without making any other API call
applika whoami
# → Logged in as: username=luissoares  name=Luis Soares  email=luis@example.com

# Revoke the session server-side and clear local storage
applika logout

applika whoami is the recommended pre-flight check. Run it before any other command, especially in scripts or AI-assisted workflows, to confirm a valid session exists before hitting the API.


Commands

applika applications list

Lists all job applications in the current cycle, sorted by date descending. Supports rich filtering and both human-readable table output and machine-readable JSON.

# Default: all applications as a table
applika applications list

# Narrow down by any combination of filters
applika applications list \
  --search "stripe" \
  --mode active \
  --status active \
  --platform LinkedIn \
  --from 2026-01-01 \
  --to 2026-06-30

# JSON output — useful for piping into jq or scripts
applika applications list --output-format json

# Scope to a specific job-search cycle by UUID
applika applications list --cycle-id <uuid>

Filter reference:

Flag Values Default Description
--search TEXT any string Case-insensitive substring match on company name or role title
--mode active · passive · all all active = you applied; passive = recruiter reached out
--status active · finalized · all all finalized applications have a recorded outcome
--platform TEXT e.g. LinkedIn Exact match on platform name
--from YYYY-MM-DD date Include applications from this date (inclusive)
--to YYYY-MM-DD date Include applications up to this date (inclusive)
--output-format table · json table json returns the raw API response as a formatted array
--cycle-id TEXT UUID Filter to a specific job-search cycle

applika applications new

Records a new job application. The CLI validates the payload locally with Pydantic before calling the API, so you get clear field-level error messages without a round-trip.

# Minimal — required fields only
applika applications new \
  --company "Stripe" \
  --role "Backend Engineer" \
  --platform "LinkedIn" \
  --mode active \
  --date 2026-05-10

# With salary info (currency and period are always required together with any salary field)
applika applications new \
  --company "Cloudflare" \
  --role "Systems Engineer" \
  --platform "Email" \
  --mode passive \
  --date 2026-05-10 \
  --observation "Recruiter cold-messaged. Interesting stack." \
  --country "Brazil" \
  --work-mode remote \
  --salary-min 18000 \
  --salary-max 24000 \
  --currency BRL \
  --salary-period monthly

Required flags:

Flag Description
--company TEXT Company name. Matched against known companies; a new record is created if not found.
--role TEXT Job title or role description
--platform TEXT Platform where you found or were contacted about the role (e.g. LinkedIn, Indeed, Email)
--mode active — you applied proactively · passive — inbound from a recruiter
--date YYYY-MM-DD Date the application was submitted or the first contact occurred

Optional flags:

Flag Description
--company-url URL Company website
--job-url URL Direct link to the job posting
--observation TEXT Free-form notes about the role, process, or company
--country TEXT Country where the role is based
--work-mode remote · hybrid · on_site
--experience-level intern · junior · mid_level · senior · staff · lead · principal · specialist
--expected-salary FLOAT The salary you expect or asked for
--salary-min FLOAT Lower bound of a posted salary range
--salary-max FLOAT Upper bound of a posted salary range
--currency USD · BRL · EUR · GBP · CAD · AUD · JPY · CHF · INR
--salary-period hourly · monthly · annual

Salary rule: if any salary amount is provided (--expected-salary, --salary-min, or --salary-max), both --currency and --salary-period become required. The CLI enforces this before making any API call.


applika applications edit <id>

Updates an existing application. Only the flags you pass are changed — everything else keeps its current value. This makes partial updates safe: you can update just the role name or add salary info without touching anything else.

# Update the role title
applika applications edit 42 --role "Staff Engineer"

# Add salary info that wasn't captured at application time
applika applications edit 42 \
  --expected-salary 180000 \
  --currency USD \
  --salary-period annual

# Clear fields you no longer want to track
applika applications edit 42 \
  --clear-job-url \
  --clear-observation \
  --clear-country \
  --clear-salary

Find the application id with:

applika applications list --search "company name" --output-format json

Clear flags — set a field back to null without affecting others:

Flag Clears
--clear-job-url Job posting URL
--clear-observation Notes
--clear-country Country
--clear-salary All salary fields (expected_salary, salary_min, salary_max, currency, salary_period)

Finalized applications (those with a recorded outcome) are read-only and cannot be edited. The CLI checks this before sending the request.


applika skill

Installs the bundled AI skill into your assistant's skills directory. The skill teaches Claude Code, Gemini, or Codex how to use this CLI — what commands exist, how authentication works, required vs optional flags, and common workflows.

The skill file is shipped inside the installed package (applika/skills/applika-cli/SKILL.md) so it stays in sync with the CLI version you have installed. By default the command creates a symlink so updates are reflected automatically; it falls back to a file copy if symlink creation fails (e.g. Windows without Developer Mode enabled).

# Interactive — choose which tool(s) to install for
applika skill
# →  1. Claude   (~/.claude/skills/applika-cli)
# →  2. Gemini   (~/.gemini/skills/applika-cli)
# →  3. Codex    (~/.codex/skills/applika-cli)
# →  4. All of the above

# Install to the current project's .claude/skills/ (file copy, no prompt)
# Useful when you want the skill scoped to a single repo
applika skill --local

# Install to any arbitrary directory (file copy, no prompt)
applika skill --dir /path/to/skills

# Preview what would be installed without touching the filesystem
applika skill --dry-run

# Overwrite an existing installation
applika skill --force

Once installed, the AI assistant automatically loads the skill context in every session and knows how to:

  • check authentication with applika whoami before running commands
  • construct valid new and edit payloads
  • apply the correct filters on list
  • recover from auth errors by prompting for applika login

Global options

These flags apply to every command and are passed before the subcommand name:

applika --api-base-url https://staging.applika.dev/api applications list
Flag Default Env variable
--api-base-url TEXT https://applika.dev/api APPLIKA_API_BASE_URL

Package structure

cli/
├── pyproject.toml               # Build config, dependencies, entry point
├── Makefile                     # Shortcuts: test, lint, format
├── README.md
├── CLAUDE.md                    # Guidance for AI assistants working in this repo
└── src/
    └── applika/                 # Importable package (entry: applika.main:main)
        ├── main.py              # Entry point — calls app()
        ├── app.py               # Root Typer app, --api-base-url callback, AppConfig wiring
        ├── config.py            # AppConfig dataclass + resolve_api_base_url()
        │
        ├── skills/
        │   └── applika-cli/
        │       └── SKILL.md     # Bundled AI skill — installed via `applika skill`
        │
        ├── schemas/             # Vendored Pydantic models (no backend import)
        │   ├── enums.py         # StrEnum types: Currency, SalaryPeriod, WorkMode, etc.
        │   └── application.py   # ApplicationCreate, ApplicationUpdate with validators
        │
        ├── lib/                 # Infrastructure — no Typer dependency
        │   ├── api.py           # ApiClient (httpx + cookie auth), ApiError, AuthError
        │   ├── session.py       # SessionData, SessionStore (~/.config/applika/session.json)
        │   └── loopback.py      # LoopbackLoginServer for OAuth browser callback
        │
        ├── utils/               # Pure helpers — no httpx, no Typer
        │   ├── dates.py         # parse_date, ensure_date_string
        │   └── output.py        # render_application_table, print_application_summary
        │
        └── commands/
            ├── auth.py          # login, logout, whoami commands
            ├── skill.py         # skill command — installs the AI skill
            └── applications/
                ├── __init__.py  # applications_app Typer sub-app, default-to-list callback
                ├── commands.py  # list_applications, new_application, edit_application
                ├── filter.py    # filter_applications, resolve_platform_id
                └── payloads.py  # ApplicationArgs dataclass, build_application_payload()

Layer rules:

  • lib/ — HTTP and session logic only. No Typer, no output formatting.
  • utils/ — Pure functions. No side effects, no I/O beyond what the function signature implies.
  • schemas/ — Vendored copies of backend DTOs. Keep in sync manually with backend/app/application/dto/application.py and backend/app/core/enums.py when the backend changes.
  • commands/ — Typer command functions only. Delegates to lib/ and utils/.

Development

# Install project + dev dependencies into a local virtualenv
uv sync

# Run the test suite
make test

# Auto-fix lint issues
make lint

# Apply code formatter
make format

# Build a wheel for distribution
uv build

# Install the locally built CLI globally for manual testing
uv tool install --force .

Tests live in tests/ and use typer.testing.CliRunner with fake ApiClient and SessionStore implementations defined in tests/conftest.py. No real network calls are made.


License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

applika_cli-0.1.2.tar.gz (41.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

applika_cli-0.1.2-py3-none-any.whl (24.8 kB view details)

Uploaded Python 3

File details

Details for the file applika_cli-0.1.2.tar.gz.

File metadata

  • Download URL: applika_cli-0.1.2.tar.gz
  • Upload date:
  • Size: 41.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.26 {"installer":{"name":"uv","version":"0.9.26","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for applika_cli-0.1.2.tar.gz
Algorithm Hash digest
SHA256 4b0dbd0f81c70fff2451e9399c535c67cec981ec93bec71b78e83203222742b4
MD5 470c9f9288f0a8f3e80e7021eeb5da6f
BLAKE2b-256 8b97a298be67c7a924426c95ce992da24aaf55934ac39cf8082e23f6992087b9

See more details on using hashes here.

File details

Details for the file applika_cli-0.1.2-py3-none-any.whl.

File metadata

  • Download URL: applika_cli-0.1.2-py3-none-any.whl
  • Upload date:
  • Size: 24.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.26 {"installer":{"name":"uv","version":"0.9.26","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for applika_cli-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 fd27416eaa15329c6b61dc83c88b08b0a274e637698e1b7b621233b12dc5d8d6
MD5 c0df0e9475611d57357b962134736d61
BLAKE2b-256 df06345c23cfb34b60ac56ed1c25b785e870f098a19d6089ab230f7a48236e10

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page