Skip to main content

Local-first HR app with BYOK AI agent loop and SQLite-backed modules.

Project description

Your HR App

A folder + DB-backed local HR app that runs entirely on the HR person's laptop. No servers to operate, no Docker, no cloud account to sign up for. One Python process, one SQLite file, one workspace folder, and you own all of it.

Pick the modules you actually need. A first-run wizard (or the Modules card on /settings) lets you enable or disable each HR feature independently — Departments, Employees and Roles are always on; everything else (Leave, Payroll, Recruitment, …) is opt-in. Disabled modules disappear from the top navigation, the CLI subcommands, and the AI assistant's tool list, so the app shows only what your team uses.

The app is white-label: you set its name with the APP_NAME env var or in /settings (default: HR Desk). Throughout this README we refer to it as ${APP_NAME} or simply "your HR app".

If APP_NAME=Acme HR, the browser title, top nav header, page titles, and CLI banner all read Acme HR. Replace any mention of ${APP_NAME} below with whatever you've named yours.


What it gives you

A complete HR desk for a small or mid-sized company, all running locally:

Module Covers
Employees Master record, codes, contact info, salary, manager chain, photo
Departments Org tree with heads and parent departments
Roles Job titles + levels per department
Documents Per-employee documents (ID proofs, contracts, certificates)
Leave Leave types, balances per year, requests + approvals
Attendance Daily check-in / check-out, hours, leave / holiday status
Payroll Periodic payroll runs and per-employee payslips
Performance Review cycles, rubric scoring, comments, status tracking
Onboarding Joiner checklist with tasks, owners, due dates
Exits Exit records, knowledge transfer, asset return, exit interview
Recruitment Kanban for candidates with AI-assisted scoring (the original board)

Each module gets its own page under /m/<module> and CRUD JSON API at /api/m/<module>. Same look across the app, same keyboard flow.


How it's built

  • Stack: Python 3.10+, SQLite, a tiny stdlib HTTP server, plain HTML/CSS/JS.
  • Single dependency: pydantic-ai-slim[openai] for the in-app AI agent loop. No Claude CLI, no anthropic SDK, no Node.
  • DB-primary: all module data lives in <workspace>/.getset/getset.db. Folders inside the workspace are demoted to attachment storage for things like resumes, signed contracts, and PDF payslips.
  • One unified shell: every page (home, modules, recruitment kanban, org chart, settings, activity) uses the same top navigation. No more split between the legacy hiring view and the HR desk view.
  • Module-level feature flags: enabled modules live in .getset/config.json mirrored to a settings table row, with ENABLED_MODULES env var as the override. Reads filter through every layer — UI nav, HTTP dispatcher, CLI subcommands, AI tool registry — so a disabled module is invisible everywhere.
  • Localhost-only HTTP: the server binds to 127.0.0.1 by default. You can opt into --host 0.0.0.0 for LAN access; there is no auth, so only do that on a trusted network.
  • No background workers, no message queues, no Redis. One process. Ctrl+C to stop.

Install

Three equivalent paths — pick whichever ecosystem you live in.

Channel Command When to use
PyPI pip install hrkit You have Python 3.10+ already; you want the smallest footprint
npm npx @thinqmesh/hrkit serve You're a Node user; the wrapper transparently runs pip install hrkit for you on first use
GitHub Release download wheel/sdist from v1.0.0 and pip install ./hrkit-*.whl Air-gapped machine, or you want a frozen version pinned to disk

From PyPI (recommended for Python users)

pip install hrkit

The package is published at https://pypi.org/project/hrkit/. After install, the hrkit CLI is on your $PATH.

From npm (recommended for non-Python users)

# Run with npx (no global install — auto-installs the Python package on first run)
npx @thinqmesh/hrkit serve

# Or install the wrapper globally
npm install -g @thinqmesh/hrkit
hrkit serve

The npm package @thinqmesh/hrkit is a tiny Node.js shim (under 200 lines) that detects Python ≥ 3.10 on your machine, pip installs the actual app from PyPI on first run, and forwards every command to the underlying Python CLI. You still need Python installed; the shim just hides pip from view.

From a GitHub Release (offline / pinned)

# Pick the asset URL from https://github.com/AnitChaudhry/HRKit/releases
pip install https://github.com/AnitChaudhry/HRKit/releases/download/v1.0.0/hrkit-1.0.0-py3-none-any.whl

Need more detail? docs/INSTALL.md covers prerequisites, upgrade paths, and troubleshooting. The whole docs tree is at docs/ — Quickstart, AI chat, integrations, recipes, releasing.

Five-step setup (the promise)

# 1. install (pick one of the install commands above)

# 2. initialise a workspace folder
hrkit init "D:\My-HR"                    # creates the folder + .getset/ + workspace marker

# 3. start the server (this also opens your browser automatically)
cd "D:\My-HR" && hrkit serve

# 4. on first run the browser opens a 5-step wizard:
#    - app name (white-label)
#    - AI provider + key (skippable)
#    - choose your modules (presets: Everything / Core only / Recruitment-focused / HR-focused)
#    - first department
#    - first employee
#    Every step except modules selection can be edited later in /settings.

# 5. start using it. Disabled modules can be re-enabled any time on
#    /settings → Modules.

That is the whole onboarding. Five steps, no .env files to learn, no docker-compose, no migrations to run by hand (the app runs them on first boot). Closing the terminal stops the server — there is no hosted SaaS version, every install runs on the user's own laptop on 127.0.0.1.

About http://127.0.0.1:8765/: that is the address your own laptop serves the app on after step 3. It is unreachable from anywhere else, and it stops working the moment you close the terminal. There is no hosted SaaS version of HR-Kit — running the app on your own machine is the entire product.

Footnote on the binary name. The console script installed by pip install is named hrkit (lowercase). The npm wrapper exposes the same name. The product brand "HR-Kit" appears only in marketing/docs — the UI label in the app itself is whatever you set with the APP_NAME env var.


Modules — pick what you actually use

Every install enables all 11 modules by default, but most teams turn off the ones they don't need. The module selector is on /settings and follows three rules:

  1. Always-on core: Departments, Employees, Roles. Every other HR table foreign-keys to employee.id, so these can't be turned off.
  2. HR modules: Documents, Leave, Attendance, Payroll, Performance, Onboarding, Exits. Each is independent — disable any combination.
  3. Hiring: Recruitment (candidate kanban + AI scoring + Gmail intake). Independent of everything else.

The setup wizard offers four presets to bootstrap quickly:

  • Everything — all 11 modules on (default)
  • Core only — Departments + Employees + Roles, nothing else
  • Recruitment-focused — core + Recruitment, no HR ops
  • HR-focused — everything except Recruitment

State lives in <workspace>/.getset/config.json (enabled_modules key) mirrored to the SQLite settings table. The env var ENABLED_MODULES=leave,payroll,... overrides both for one-shot testing.

When a module is disabled:

  • It disappears from the top navigation
  • /m/<slug>... URLs return 404
  • CLI subcommands (hrkit payroll-run, hrkit leave-request-add, …) refuse to run with a clear "module is disabled" message
  • The AI chat assistant's tool registry filters them out, so the LLM doesn't propose actions the app won't carry out

Re-enabling preserves data — disabling only hides routes and tools, it never deletes rows.

Org structure & reporting

Every employee has an optional manager_id field pointing at another employee. The reporting structure surfaces in three places:

  • The employee detail page shows Reports to (their manager, linked) and Direct reports (a table of everyone reporting to them)
  • An inline Reassign manager dropdown auto-excludes the employee themselves and all their descendants, so a cycle is unreachable from the UI. The API enforces the same rule (update_row raises if manager_id would create a loop)
  • /m/employee/tree renders the full org chart as nested collapsible cards, rooted at top-level managers (anyone whose manager_id IS NULL)

Roles use the standard HR ladder as suggestions in their level field: Intern → Junior → Senior → Team Lead → Assistant Manager → Manager → Senior Manager → Director → VP. Pick from the dropdown or type a custom value.

AI providers (BYOK, OpenAI-compatible only)

The app talks to any OpenAI-compatible chat completion endpoint. Two are pre-wired in the settings page:

Provider Base URL Notes
OpenRouter https://openrouter.ai/api/v1 Free tier available; many open-weight models
Upfyn https://ai.upfyn.com/v1 Drop-in OpenAI-compatible gateway

Switch providers from /settings. Default model is a free OpenRouter Llama-3.3-70B-Instruct entry; override per request from the UI or via the AI_MODEL env var.

You can also point at your own self-hosted OpenAI-compatible server by overriding AI_PROVIDER and the base URL in .getset/config.json.

Composio for app integrations

Composio is used as the integrations backbone (Gmail in particular, for the recruitment intake flow). Bring your own Composio API key, paste it into /settings, and connect Gmail from the Composio dashboard linked from the page.

If you don't paste a Composio key, the rest of the HR app still works - only the recruitment-from-email pipeline goes idle.


Configuration surface

Every setting can be supplied two ways: an environment variable or the in-app /settings page (which writes to .getset/config.json inside your workspace). Env vars win on conflict.

Env var Default Where it goes
APP_NAME HR Desk UI title, top-nav header, CLI banner
AI_PROVIDER openrouter openrouter or upfyn
AI_API_KEY (empty) OpenAI-compatible API key
AI_MODEL meta-llama/llama-3.3-70b-instruct:free Model identifier
COMPOSIO_API_KEY (empty) Composio API key
ENABLED_MODULES (all 11 enabled) Comma list or JSON, overrides config + DB
GETSET_ROOT (auto-detected) Workspace folder path

Where keys live

  • The /settings page writes to <workspace>/.getset/config.json.
  • That file lives only on the user's laptop. It is never uploaded.
  • Keys are masked when shown back in the UI (sk-***...last4).
  • Add .getset/ to your global .gitignore if you ever put a workspace in a git repo - the cache and config should not be committed.

Workspace layout

D:\My-HR\
|-- getset.md                    workspace marker (name, theme, port)
|-- .getset\
|   |-- getset.db                SQLite, all modules
|   `-- config.json              keys + per-workspace settings
|-- attachments\
|   |-- employees\<code>\        per-employee documents
|   |-- payslips\<period>\       generated PDFs
|   |-- resumes\<position>\      candidate resumes
|   `-- contracts\               signed contracts, NDAs
`-- ...departments and recruitment positions as folders...

The recruitment kanban still uses real folders (Department / Position / Candidate) for backwards compatibility with the original tool. On first boot the migrator copies anything it finds into the DB; from then on the DB is primary and the folder tree is just for human filing.


CLI cheat sheet

<app> init "D:\My-HR"                    # scaffold a new workspace
<app> serve                              # start the local server
<app> serve --port 9000 --no-browser     # custom port, headless
<app> scan                               # rebuild the cache from disk
<app> migrate                            # apply DB migrations
<app> migrate --dry-run                  # preview migrations
<app> status                             # workspace path, DB stats
<app> activity                           # last 20 activity rows
<app> --version

Each module also adds its own subcommands (e.g. employee-add, leave-grant, payroll-run). Run <app> --help for the full list on your install.


Security notes

  • The HTTP server binds to 127.0.0.1 by default. No authentication is enforced - it assumes the only thing on localhost:8765 is you.
  • Don't expose the port to the public internet. If you must reach it remotely, put it behind an SSH tunnel or a reverse proxy that does auth.
  • AI keys are stored as cleartext inside .getset/config.json on the user's machine. Encrypt the laptop disk; that is the boundary.
  • Composio handles its own OAuth tokens for connected apps - those are not stored locally; only your Composio API key is.
  • All data is local. There is no telemetry. There is no phoning home.

Roadmap

  • Multi-user mode (currently single-user-per-laptop)
  • Pluggable auth for the localhost UI
  • Importers for common HRMS exports (BambooHR, Zoho, Keka)
  • Native installers (.exe, .dmg, .AppImage) so no pip step

License

MIT. See pyproject.toml for the canonical license declaration. You may fork, rebrand, and redistribute under your own APP_NAME.


Credits

Built on the shoulders of the Python standard library, SQLite, and pydantic-ai. The original recruitment kanban (folder-native) lives on inside this app as the Recruitment module.

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

hrkit-1.0.0.tar.gz (226.2 kB view details)

Uploaded Source

Built Distribution

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

hrkit-1.0.0-py3-none-any.whl (221.3 kB view details)

Uploaded Python 3

File details

Details for the file hrkit-1.0.0.tar.gz.

File metadata

  • Download URL: hrkit-1.0.0.tar.gz
  • Upload date:
  • Size: 226.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.13

File hashes

Hashes for hrkit-1.0.0.tar.gz
Algorithm Hash digest
SHA256 c5b44fe03b4f754129808c5341213bb9cb4f9ecd7211688ecbf7229d41fe9b08
MD5 32d1eef5855e2e95db48494d829d8a01
BLAKE2b-256 184f16da09cbbd85071c5a7e38f4bd4a6e54aa7b8e85c248f328336f11271944

See more details on using hashes here.

File details

Details for the file hrkit-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: hrkit-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 221.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.13

File hashes

Hashes for hrkit-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 23f3e2cd2f312f87cdc84dd1a855bd54a164d4daf910942943dec50da553ef51
MD5 99d00249215b717dbac708af86e2954d
BLAKE2b-256 b9cbca04b56ed6c273fd0d3f5181de4eb104b3665b5d27f5ecab0d76b5eac92c

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