Commit Graph
8 Commits
Author SHA1 Message Date
LatteandClaude Opus 4.8 61837d4783 Multi-character support across accounts
CI / lint (pull_request) Successful in 49s
CI / test (pull_request) Successful in 56s
CI / lint (push) Successful in 50s
CI / publish (pull_request) Has been skipped
CI / test (push) Successful in 55s
CI / publish (push) Successful in 50s
Rework the token store to hold many characters keyed by character_id,
migrating the previous single-character file transparently. `familiar login`
now adds a character; `familiar status` lists all; `familiar logout [name|id]`
removes one or all.

Every account tool gains an optional `character` (name or id): omitted means
all logged-in characters, given means just that one. Results are uniform
{"characters": [...]}. get_auth refreshes per character.

58 tests, coverage 89%. Closes #9

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-27 18:47:34 +02:00
LatteandClaude Opus 4.8 eb6440db40 Phase 2: EVE SSO auth + read-only account tools
CI / lint (pull_request) Successful in 51s
CI / lint (push) Successful in 50s
CI / test (pull_request) Successful in 57s
CI / publish (pull_request) Has been skipped
CI / test (push) Successful in 57s
CI / publish (push) Successful in 50s
Add PKCE OAuth2 login against EVE SSO with an encrypted, auto-refreshing
token store, driven by `familiar login` / `status` / `logout` CLI commands.
The MCP server gains authenticated account tools:

- account_status, get_wallet, get_skills, get_skill_queue
- get_location, get_clones, get_assets (paginated)

ESI client extended with Bearer auth and X-Pages pagination. 51 tests
(auth + account mocked), coverage 88%. Client id/callback/scopes are
env-overridable; refresh token Fernet-encrypted on disk.

Closes #7

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-27 18:32:47 +02:00
LatteandClaude Opus 4.8 edf2298e20 ci: authenticate twine with REGISTRY_TOKEN secret
CI / lint (pull_request) Successful in 51s
CI / test (pull_request) Successful in 59s
CI / lint (push) Successful in 53s
CI / publish (pull_request) Has been skipped
CI / test (push) Successful in 1m0s
CI / publish (push) Successful in 51s
The repo already has a REGISTRY_TOKEN secret (Gitea access token with
package scope); the workflow referenced a non-existent PACKAGE_REGISTRY_TOKEN
and fell back to the auto GITHUB_TOKEN, which is not granted package-write,
so every upload was rejected. Point twine at REGISTRY_TOKEN.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-27 18:01:22 +02:00
LatteandClaude Opus 4.8 d76c8f87a8 ci: drop unsupported --skip-existing from twine upload
CI / lint (pull_request) Successful in 51s
CI / test (pull_request) Successful in 59s
CI / lint (push) Successful in 52s
CI / publish (pull_request) Has been skipped
CI / test (push) Successful in 58s
CI / publish (push) Failing after 30s
Gitea's PyPI registry rejects twine's --skip-existing flag
(UnsupportedConfiguration), which failed every publish run. Remove it and
instead tolerate an "already exists" conflict in the shell, so dev (unique
.devN versions) always publishes and a main re-run of an existing release
is treated as success rather than a hard failure.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-27 17:57:50 +02:00
LatteandClaude Opus 4.8 a136853126 ci: grant contents:read so publish can checkout private repo
CI / lint (pull_request) Successful in 52s
CI / test (pull_request) Successful in 58s
CI / publish (pull_request) Has been skipped
CI / lint (push) Successful in 51s
CI / test (push) Successful in 56s
CI / publish (push) Failing after 29s
Setting `permissions: packages: write` alone dropped every other scope to
none, so actions/checkout could not clone the private repo and the publish
job failed before building. Add contents:read, and use github.actor (more
reliably populated than gitea.actor) as the twine username.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-27 17:52:14 +02:00
LatteandClaude Opus 4.8 4223141cf7 Phase 1: public market + universe lookups via ESI
CI / test (pull_request) Successful in 56s
CI / publish (pull_request) Has been skipped
CI / lint (push) Successful in 52s
CI / test (push) Successful in 56s
CI / publish (push) Failing after 34s
CI / lint (pull_request) Successful in 52s
Add a thin async ESI client (httpx, descriptive User-Agent, uniform errors,
mockable transport) plus name<->id resolution. New read-only tools:

- universe: resolve_names, get_item, get_system, get_station, get_region, get_route
- market:   list_hubs, get_market_price, get_market_orders, compare_hubs

Trade-hub IDs (Jita/Amarr/Dodixie/Rens/Hek) are hardcoded constants. Market
aggregation (best buy/sell, spread, order book) lives in pure helpers. 30 unit
tests with mocked ESI; coverage 99%. SDE bulk-load deferred to a later phase.

Closes #2

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-27 17:49:40 +02:00
LatteandClaude Opus 4.8 585acc766c ci: add Gitea Actions workflow (lint, test, publish)
CI / lint (pull_request) Successful in 53s
CI / test (pull_request) Successful in 1m0s
CI / publish (pull_request) Has been skipped
CI / lint (push) Successful in 53s
CI / test (push) Successful in 59s
CI / publish (push) Failing after 39s
Lint (ruff) and test (pytest, fail under 80% coverage) on every PR and
push to main/dev. On a merge to main/dev, build the sdist+wheel and
publish to the Gitea PyPI registry — main as a clean release, dev as a
unique .devN pre-release. No Docker; runs on uv.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-27 17:34:59 +02:00
LatteandClaude Opus 4.8 ef27cd85f6 Phase 0: FastMCP scaffold with ping tool
Set up the familiar package (src layout, uv/hatchling) with a FastMCP
server exposing a read-only ping health tool. Add pytest smoke tests with
80% coverage gate. Flesh out the README with the project vision and roadmap.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-27 17:34:51 +02:00