Files
ar9av__obsidian-wiki/pyproject.toml
T
JaySon 0a9232f82d fix(deps): make uv lock/sync/run work, and declare pytest for tests (#214)
Every `uv lock`, `uv sync`, and `uv run` in this repo failed outright:

    No solution found when resolving dependencies for split
    (markers: python_full_version == '3.9.*')
    ... mcp>=2.0.0 depends on Python>=3.10 ...

uv resolves every Python version covered by `requires-python` (>=3.9), not
just the active interpreter, and the `server` extra pulled in `mcp>=2.0`,
which requires >=3.10. The 3.9 split therefore had no solution and the whole
lock was unusable.

Two changes:

- Mark mcp as 3.10+ inside the `server` extra:
  `"mcp>=2.0; python_version >= '3.10'"`. This states what is already true
  rather than adding a new constraint: the memory server is a 3.10+ surface
  (server.py imports mcp at module scope, and the Dockerfile ships
  python:3.12-slim). The pure-stdlib CLI keeps its 3.9 support, so the CI
  matrix is unchanged.

- Declare pytest in a `[dependency-groups] dev` group so the suite runs
  through uv with no extra flags (`uv sync && uv run pytest tests/ -q`).
  CI previously pip-installed pytest ad hoc.

uv.lock is regenerated. It predated the `server` extra entirely — no
fastapi/uvicorn/mcp entries — so uv re-resolved from scratch on every run.

Verified: `uv sync && uv run pytest tests/ -q` -> 701 passed, 5 skipped.
`uv sync --extra server` pulls mcp 2.2.0 / fastapi 0.141.1 / uvicorn 0.52.4,
and `import obsidian_wiki.server` yields `app = FastAPI`.
2026-09-11 00:01:01 -07:00

128 lines
5.2 KiB
TOML

[build-system]
requires = ["hatchling", "hatch-vcs"]
build-backend = "hatchling.build"
[project]
name = "obsidian-wiki"
dynamic = ["version"]
description = "A skill-based framework for building and maintaining an AI-maintained Obsidian knowledge base (Karpathy's LLM Wiki pattern) across any AI coding agent."
readme = "README.md"
requires-python = ">=3.9"
license = "MIT"
license-files = ["LICENSE"]
authors = [{ name = "Ar9av" }]
keywords = [
"obsidian",
"wiki",
"knowledge-base",
"llm",
"claude",
"agent-skills",
"second-brain",
]
classifiers = [
"Development Status :: 4 - Beta",
"Environment :: Console",
"Intended Audience :: Developers",
"Operating System :: OS Independent",
"Programming Language :: Python :: 3",
"Topic :: Documentation",
"Topic :: Text Processing :: Markup :: Markdown",
"Topic :: Utilities",
]
# Pure-stdlib CLI — installing skills needs no third-party runtime dependencies.
dependencies = []
[project.optional-dependencies]
# Higher-fidelity AST extraction (tree-sitter parses real ASTs; regex is the default fallback).
ast = ["tree-sitter>=0.21", "tree-sitter-languages>=1.10"]
# Higher-fidelity community detection (Leiden algorithm; greedy label propagation is the default fallback).
graph = ["leidenalg>=0.10", "igraph>=0.11"]
# HTTP + MCP memory server (obsidian_wiki/server.py). The core wheel stays dependency-free.
# mcp needs Python >=3.10; the marker keeps uv's cross-version resolver solvable.
server = [
"fastapi>=0.115",
"uvicorn[standard]>=0.30",
"mcp>=2.0; python_version >= '3.10'",
]
[project.urls]
Homepage = "https://github.com/Ar9av/obsidian-wiki"
Repository = "https://github.com/Ar9av/obsidian-wiki"
Issues = "https://github.com/Ar9av/obsidian-wiki/issues"
[project.scripts]
obsidian-wiki = "obsidian_wiki.cli:main"
# Test-only; `uv sync` installs it, so `uv run pytest tests/ -q` needs no extra flags.
[dependency-groups]
dev = ["pytest"]
# Version is derived from the git tag (CalVer, e.g. v2026.05.2 -> 2026.5.2),
# matching the repo's release tags. Tagging a release is the version bump.
[tool.hatch.version]
source = "vcs"
# ── Build configuration ──────────────────────────────────────────────────────
# The Python package is just the thin CLI in obsidian_wiki/. The actual product
# is the markdown skill content under .skills/ plus the agent bootstrap files.
# We force-include those into the wheel under obsidian_wiki/_data/ so the
# installed package is self-contained and the CLI can install skills without a
# cloned repo. Source paths stay at the repo root (single source of truth).
[tool.hatch.build.targets.wheel]
packages = ["obsidian_wiki"]
# force-include copies straight from the working tree, not a VCS-filtered
# view — without this, a local `scripts/__pycache__` picked up stray .pyc
# files into the published wheel.
exclude = [
"**/__pycache__",
"**/*.py[co]",
]
[tool.hatch.build.targets.wheel.force-include]
".skills" = "obsidian_wiki/_data/skills"
"scripts" = "obsidian_wiki/_data/scripts"
".claude/hooks/wiki-stop-capture.sh" = "obsidian_wiki/_data/hooks/wiki-stop-capture.sh"
".env.example" = "obsidian_wiki/_data/.env.example"
"AGENTS.md" = "obsidian_wiki/_data/bootstrap/AGENTS.md"
".cursor/rules/obsidian-wiki.mdc" = "obsidian_wiki/_data/bootstrap/cursor/rules/obsidian-wiki.mdc"
".windsurf/rules/obsidian-wiki.md" = "obsidian_wiki/_data/bootstrap/windsurf/rules/obsidian-wiki.md"
".kiro/steering/obsidian-wiki.md" = "obsidian_wiki/_data/bootstrap/kiro/steering/obsidian-wiki.md"
".agent/rules/obsidian-wiki.md" = "obsidian_wiki/_data/bootstrap/agent/rules/obsidian-wiki.md"
".agent/workflows/obsidian-wiki.md" = "obsidian_wiki/_data/bootstrap/agent/workflows/obsidian-wiki.md"
".github/copilot-instructions.md" = "obsidian_wiki/_data/bootstrap/github/copilot-instructions.md"
# The Chrome extension is loaded unpacked from a directory, so shipping it in
# the wheel gives pip users a path to point Chrome at. `obsidian-wiki info`
# prints it.
#
# NOTE: force-include ignores both .gitignore and the exclude lists above —
# every file in this directory ships. Keep nothing local-only or secret in it;
# the extension's private signing key lives at ~/.obsidian-wiki/, not here.
"extensions/brain" = "obsidian_wiki/_data/extension"
[tool.hatch.build.targets.sdist]
# Prune build noise and the committed agent symlink mirrors (the CLI
# regenerates those; left in, hatchling's VCS walker treats them as the
# canonical path for each skill and drops the real .skills/<name> files).
exclude = [
"/.claude",
"/.cursor/skills",
"/.windsurf/skills",
"/.agents/skills",
"/.pi/skills",
"/.kiro/skills",
"/dist",
"/build",
]
# Force the real .skills/ tree into the sdist regardless of the VCS walker, so
# the wheel (built from the sdist) can in turn force-include it under _data/.
# The Stop hook lives under /.claude (excluded above), so re-add just the one
# script the wiki-setup skill wires up — otherwise the wheel force-include has
# nothing to copy and the published package ships a dangling hook reference.
[tool.hatch.build.targets.sdist.force-include]
".skills" = ".skills"
"extensions/brain" = "extensions/brain"
".claude/hooks/wiki-stop-capture.sh" = ".claude/hooks/wiki-stop-capture.sh"