Skip to content

Latest commit

 

History

History
78 lines (54 loc) · 3.75 KB

File metadata and controls

78 lines (54 loc) · 3.75 KB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Commands

make build        # Build CLI binary → bin/it-pracuj-pl
make build-mcp    # Build MCP server → bin/it-pracuj-pp-mcp
make build-all    # Build both binaries
make test         # go test ./...
make lint         # golangci-lint run
make install      # go install ./cmd/it-pracuj-pl
make clean        # Remove bin/

Run a single test:

go test ./internal/cli/... -run TestFunctionName
go test ./internal/store/... -run TestSchemaVersion -v

Build without Make:

go build -o bin/it-pracuj-pl ./cmd/it-pracuj-pl
go build -o bin/it-pracuj-pp-mcp ./cmd/it-pracuj-pp-mcp

Architecture

Two binaries share all logic in internal/:

  • cmd/it-pracuj-pl/ — calls cli.Execute()
  • cmd/it-pracuj-pp-mcp/ — creates an MCP server, calls mcp.RegisterTools(), then cobratree.RegisterAll() to mirror the Cobra tree, then server.ServeStdio()

Package responsibilities

Package Role
internal/cli/ All Cobra commands. root.go defines rootFlags and RootCmd(). Each file = one command or group.
internal/client/ HTTP client wrapping enetx/surf for browser-compatible headers, response caching, and rate limiting.
internal/cliutil/ AdaptiveLimiter (rate limiter), FanoutRun (concurrent parallel requests), text and probe helpers.
internal/scraper/ Extracts __NEXT_DATA__ JSON from it.pracuj.pl SSR HTML; maps 270+ IT technology names to API IDs.
internal/store/ SQLite persistence (pure-Go modernc.org/sqlite). FTS5 full-text search, WAL mode, schema version 2.
internal/mcp/ Registers typed MCP tools for the 6 primary API endpoints.
internal/mcp/cobratree/ Reflects the live Cobra command tree into MCP tools at runtime — every CLI command becomes an MCP tool automatically without manual registration.
internal/config/ Loads ~/.config/it-pracuj-pl/config.toml (TOML, optional static headers).
internal/cache/ SHA256-keyed file cache at ~/.cache/it-pracuj-pl/http/.

Command flow

Every command receives a *rootFlags pointer from the root. The rootFlags.newClient() method builds an *client.Client from config. Commands call resolveRead() (in data_source.go) which handles --data-source auto/live/local routing — either hitting the live API through the client or querying the local SQLite store.

Generated vs hand-written files

Files with // Generated by CLI Printing Press ... DO NOT EDIT. at the top are generated. Do not modify them manually — they will be overwritten on the next printing-press run. Hand-written files (no header): compare.go, filters.go, job_offers_list_offers.go, scraper/nextdata.go, scraper/tech_lookup.go, and the new cmd/it-pracuj-pp-mcp/main.go.

Error handling

Errors in command RunE handlers are wrapped with typed helpers from helpers.go:

  • usageErr(err) → exit code 2
  • notFoundErr(err) → exit code 3
  • apiErr(err) → exit code 5
  • rateLimitErr(err) → exit code 7
  • configErr(err) → exit code 10

ExitCode(err) in root.go extracts the code; main.go passes it to os.Exit.

Agent mode

--agent expands to --json --compact --no-input --no-color --yes. Output envelope for JSON responses: {"meta": {...}, "results": <data>}. The --compact flag filters response fields to a minimal set.

API surface

The live API base is https://massachusetts.pracuj.pl (internal pracuj.pl hostname). The list-offers command scrapes https://it.pracuj.pl directly (SSR HTML, no JSON endpoint exists). spec.yaml defines all known endpoints. docs/filters.md is the authoritative reference for filter codes and the 343 technology IDs.