nighthawk-python 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (101) hide show
  1. nighthawk_python-0.1.0/.claude/rules/coding.md +14 -0
  2. nighthawk_python-0.1.0/.claude/rules/docs.md +104 -0
  3. nighthawk_python-0.1.0/.claude/unset_envs.sh +3 -0
  4. nighthawk_python-0.1.0/.devcontainer/Dockerfile.devcontainer +3 -0
  5. nighthawk_python-0.1.0/.devcontainer/Dockerfile.litellm +11 -0
  6. nighthawk_python-0.1.0/.devcontainer/devcontainer.json +24 -0
  7. nighthawk_python-0.1.0/.devcontainer/docker-compose.yaml +19 -0
  8. nighthawk_python-0.1.0/.devcontainer/litellm-config.yaml +37 -0
  9. nighthawk_python-0.1.0/.github/dependabot.yml +16 -0
  10. nighthawk_python-0.1.0/.github/workflows/ci.yml +83 -0
  11. nighthawk_python-0.1.0/.github/workflows/docs.yml +49 -0
  12. nighthawk_python-0.1.0/.github/workflows/publish.yml +33 -0
  13. nighthawk_python-0.1.0/.gitignore +221 -0
  14. nighthawk_python-0.1.0/.python-version +1 -0
  15. nighthawk_python-0.1.0/AGENTS.md +63 -0
  16. nighthawk_python-0.1.0/CLAUDE.md +1 -0
  17. nighthawk_python-0.1.0/CONTRIBUTING.md +152 -0
  18. nighthawk_python-0.1.0/LICENSE +21 -0
  19. nighthawk_python-0.1.0/PKG-INFO +111 -0
  20. nighthawk_python-0.1.0/README.md +78 -0
  21. nighthawk_python-0.1.0/docs/api.md +90 -0
  22. nighthawk_python-0.1.0/docs/assets/nighthawk_logo-128x128.png +0 -0
  23. nighthawk_python-0.1.0/docs/coding-agent-backends.md +250 -0
  24. nighthawk_python-0.1.0/docs/design.md +632 -0
  25. nighthawk_python-0.1.0/docs/for-coding-agents.md +373 -0
  26. nighthawk_python-0.1.0/docs/index.md +146 -0
  27. nighthawk_python-0.1.0/docs/providers.md +118 -0
  28. nighthawk_python-0.1.0/docs/quickstart.md +116 -0
  29. nighthawk_python-0.1.0/docs/roadmap.md +73 -0
  30. nighthawk_python-0.1.0/docs/tutorial.md +831 -0
  31. nighthawk_python-0.1.0/mkdocs.yml +67 -0
  32. nighthawk_python-0.1.0/pyproject.toml +77 -0
  33. nighthawk_python-0.1.0/pyrightconfig.json +10 -0
  34. nighthawk_python-0.1.0/src/nighthawk/__init__.py +48 -0
  35. nighthawk_python-0.1.0/src/nighthawk/backends/__init__.py +0 -0
  36. nighthawk_python-0.1.0/src/nighthawk/backends/base.py +95 -0
  37. nighthawk_python-0.1.0/src/nighthawk/backends/claude_code_cli.py +342 -0
  38. nighthawk_python-0.1.0/src/nighthawk/backends/claude_code_sdk.py +325 -0
  39. nighthawk_python-0.1.0/src/nighthawk/backends/codex.py +352 -0
  40. nighthawk_python-0.1.0/src/nighthawk/backends/mcp_boundary.py +129 -0
  41. nighthawk_python-0.1.0/src/nighthawk/backends/mcp_server.py +226 -0
  42. nighthawk_python-0.1.0/src/nighthawk/backends/tool_bridge.py +240 -0
  43. nighthawk_python-0.1.0/src/nighthawk/configuration.py +193 -0
  44. nighthawk_python-0.1.0/src/nighthawk/errors.py +25 -0
  45. nighthawk_python-0.1.0/src/nighthawk/identifier_path.py +35 -0
  46. nighthawk_python-0.1.0/src/nighthawk/json_renderer.py +216 -0
  47. nighthawk_python-0.1.0/src/nighthawk/natural/__init__.py +0 -0
  48. nighthawk_python-0.1.0/src/nighthawk/natural/blocks.py +279 -0
  49. nighthawk_python-0.1.0/src/nighthawk/natural/decorator.py +302 -0
  50. nighthawk_python-0.1.0/src/nighthawk/natural/transform.py +346 -0
  51. nighthawk_python-0.1.0/src/nighthawk/runtime/__init__.py +0 -0
  52. nighthawk_python-0.1.0/src/nighthawk/runtime/async_bridge.py +50 -0
  53. nighthawk_python-0.1.0/src/nighthawk/runtime/prompt.py +344 -0
  54. nighthawk_python-0.1.0/src/nighthawk/runtime/runner.py +462 -0
  55. nighthawk_python-0.1.0/src/nighthawk/runtime/scoping.py +288 -0
  56. nighthawk_python-0.1.0/src/nighthawk/runtime/step_context.py +171 -0
  57. nighthawk_python-0.1.0/src/nighthawk/runtime/step_contract.py +231 -0
  58. nighthawk_python-0.1.0/src/nighthawk/runtime/step_executor.py +360 -0
  59. nighthawk_python-0.1.0/src/nighthawk/runtime/tool_calls.py +99 -0
  60. nighthawk_python-0.1.0/src/nighthawk/tools/__init__.py +0 -0
  61. nighthawk_python-0.1.0/src/nighthawk/tools/assignment.py +246 -0
  62. nighthawk_python-0.1.0/src/nighthawk/tools/contracts.py +72 -0
  63. nighthawk_python-0.1.0/src/nighthawk/tools/execution.py +83 -0
  64. nighthawk_python-0.1.0/src/nighthawk/tools/provided.py +80 -0
  65. nighthawk_python-0.1.0/src/nighthawk/tools/registry.py +212 -0
  66. nighthawk_python-0.1.0/tests/__init__.py +0 -0
  67. nighthawk_python-0.1.0/tests/backends/__init__.py +0 -0
  68. nighthawk_python-0.1.0/tests/backends/test_claude_code_cli.py +142 -0
  69. nighthawk_python-0.1.0/tests/backends/test_claude_code_sdk.py +33 -0
  70. nighthawk_python-0.1.0/tests/backends/test_codex.py +338 -0
  71. nighthawk_python-0.1.0/tests/conftest.py +45 -0
  72. nighthawk_python-0.1.0/tests/docs/__init__.py +0 -0
  73. nighthawk_python-0.1.0/tests/docs/test_prompt_examples.py +118 -0
  74. nighthawk_python-0.1.0/tests/execution/__init__.py +0 -0
  75. nighthawk_python-0.1.0/tests/execution/prompt_test_helpers.py +53 -0
  76. nighthawk_python-0.1.0/tests/execution/stub_executor.py +69 -0
  77. nighthawk_python-0.1.0/tests/execution/test_execution_outcome_prompt_fragment.py +59 -0
  78. nighthawk_python-0.1.0/tests/execution/test_globals_prompt.py +227 -0
  79. nighthawk_python-0.1.0/tests/execution/test_natural_block_ordering.py +155 -0
  80. nighthawk_python-0.1.0/tests/execution/test_natural_traceback.py +163 -0
  81. nighthawk_python-0.1.0/tests/execution/test_runtime.py +639 -0
  82. nighthawk_python-0.1.0/tests/execution/test_variables_prompt.py +317 -0
  83. nighthawk_python-0.1.0/tests/integration/__init__.py +0 -0
  84. nighthawk_python-0.1.0/tests/integration/skip_helpers.py +47 -0
  85. nighthawk_python-0.1.0/tests/integration/test_carry_pattern.py +136 -0
  86. nighthawk_python-0.1.0/tests/integration/test_claude_code_cli_integration.py +149 -0
  87. nighthawk_python-0.1.0/tests/integration/test_claude_code_sdk_integration.py +181 -0
  88. nighthawk_python-0.1.0/tests/integration/test_codex_integration.py +152 -0
  89. nighthawk_python-0.1.0/tests/integration/test_llm_integration.py +289 -0
  90. nighthawk_python-0.1.0/tests/natural/__init__.py +0 -0
  91. nighthawk_python-0.1.0/tests/natural/test_blocks.py +135 -0
  92. nighthawk_python-0.1.0/tests/public/__init__.py +0 -0
  93. nighthawk_python-0.1.0/tests/public/test_public_api.py +133 -0
  94. nighthawk_python-0.1.0/tests/public/test_readme_example.py +18 -0
  95. nighthawk_python-0.1.0/tests/test_renderer.py +97 -0
  96. nighthawk_python-0.1.0/tests/tools/__init__.py +0 -0
  97. nighthawk_python-0.1.0/tests/tools/test_assignment_async.py +101 -0
  98. nighthawk_python-0.1.0/tests/tools/test_contracts.py +106 -0
  99. nighthawk_python-0.1.0/tests/tools/test_registry.py +150 -0
  100. nighthawk_python-0.1.0/tests/tools/test_tool_boundary.py +217 -0
  101. nighthawk_python-0.1.0/uv.lock +1596 -0
@@ -0,0 +1,14 @@
1
+ ---
2
+ paths:
3
+ - "src/**/*.py"
4
+ - "tests/**/*.py"
5
+ ---
6
+
7
+ # Coding standards
8
+
9
+ - Avoid premature abstraction: new abstractions must be used by code in `src/` or `tests/` in the same change. Docs examples do not count.
10
+ - Keep identifiers module-private (leading underscore) until clearly used from outside in non-test code. Export intentionally via `__all__`.
11
+ - Pydantic-first: depend on Pydantic and Pydantic AI as required (non-optional) dependencies. Use `pydantic.BaseModel` and built-in features aggressively. Do not reimplement what either library provides (validation, coercion, parsing, schema, agent/tool abstractions).
12
+ - Observability: `opentelemetry.trace` for spans at run/scope/step/tool boundaries. `logging` (logger `"nighthawk"`) for diagnostics. No `logfire` imports in `src/`; it is dev-only.
13
+ - Type aliases: PEP 695 `type` statements for new type aliases.
14
+ - No unnecessary subdirectories under `src/`. Do not add folders with only `__init__.py` + a single class without maintainer buy-in.
@@ -0,0 +1,104 @@
1
+ ---
2
+ paths:
3
+ - "docs/**/*.md"
4
+ ---
5
+
6
+ # Documentation rules
7
+
8
+ ## File roles and boundaries
9
+
10
+ Each file has a distinct audience and scope. Content belongs in exactly one file; cross-reference rather than duplicate. Exception: `for-coding-agents.md` is standalone and condenses (distills) content from other files into actionable rules. This is distillation, not duplication.
11
+
12
+ | File | Audience | Role | Scope boundary |
13
+ |---|---|---|---|
14
+ | `index.md` | First-time visitors | Project overview, motivation, workflow styles | What Nighthawk is and why. No API details, no how-to. |
15
+ | `quickstart.md` | New users | Shortest path to running a Natural block | Setup, first example, backends table, credentials, troubleshooting. No deep explanations. |
16
+ | `tutorial.md` | Users learning the system | Build understanding from first principles | Bindings, tools, control flow, composition, configuration, guidelines. Assumes quickstart is done. |
17
+ | `design.md` | Implementors and advanced users | Canonical specification (target behavior) | Full technical detail: syntax rules, state layers, prompt rendering, tool contracts, outcome schema, frontmatter. |
18
+ | `providers.md` | Users choosing and configuring models | Provider selection, Pydantic AI setup, custom backends | Provider categories, capability matrix, model identifiers, Pydantic AI model settings, step executor protocols. No coding-agent-backend-specific content. |
19
+ | `coding-agent-backends.md` | Users of Claude Code or Codex backends | Coding agent backend configuration and features | Backend-specific settings, skills, MCP tool exposure, working directory, project-scoped files. |
20
+ | `for-coding-agents.md` | Coding agents (LLMs) working on Nighthawk projects | Condensed development knowledge base | Nighthawk mental model, Natural block writing, binding function design, control flow, composition, testing, common mistakes. Not a human tutorial; an LLM reference. |
21
+ | `api.md` | Developers using the library | Auto-generated API reference (mkdocstrings) | Public API surface only. Content comes from source docstrings; do not hand-edit. |
22
+ | `roadmap.md` | Contributors and planners | Future directions | Ideas and desired directions only. Must not restate what is already implemented. |
23
+
24
+ ## What goes where (decision guide)
25
+
26
+ - **Syntax rule or runtime contract?** -> `design.md`
27
+ - **How to use a feature with examples?** -> `tutorial.md`
28
+ - **Provider selection, Pydantic AI settings, or custom step executor?** -> `providers.md`
29
+ - **Coding agent backend settings, skills, MCP, or working directory?** -> `coding-agent-backends.md`
30
+ - **Backend-agnostic concept that applies across all providers?** -> `tutorial.md` (or `design.md` for strict contracts)
31
+ - **First-time setup or "just make it work"?** -> `quickstart.md`
32
+ - **Credential or authentication setup?** -> `quickstart.md` (Pydantic AI providers), `coding-agent-backends.md` (coding agent backends)
33
+ - **Error types or exception hierarchy?** -> `design.md` (specification), `tutorial.md` (practical usage with examples)
34
+ - **Not yet implemented?** -> `roadmap.md`
35
+ - **Public API signature or docstring?** -> `api.md` (edit the source docstring, not api.md)
36
+ - **Knowledge a coding agent needs to develop Nighthawk code?** -> `for-coding-agents.md`
37
+
38
+ ## Writing guidelines for docs/
39
+
40
+ ### General
41
+
42
+ - Cross-reference with relative links (e.g., `[Section 5](tutorial.md#5-cross-block-composition)`) instead of duplicating content. Exception: `for-coding-agents.md` uses absolute URLs based on `site_url` from `mkdocs.yml` (see [for-coding-agents.md specifics](#for-coding-agentsmd-specifics)).
43
+ - When tutorial.md and design.md cover the same concept, tutorial.md shows the "what and how" with examples; design.md specifies the "exact rules and edge cases".
44
+ - Keep code examples self-contained: a reader should understand the example without reading surrounding prose.
45
+ - Built-in tool names (`nh_eval`, `nh_exec`, `nh_assign`) are implementation details. Only `design.md` may expose them. All other files describe behavior instead (e.g., "the LLM can set a new value" rather than "use `nh_assign`").
46
+
47
+ ### index.md specifics
48
+
49
+ - The documentation links list must stay in sync with the `nav` entries in `mkdocs.yml`.
50
+
51
+ ### quickstart.md specifics
52
+
53
+ - Optimize for copy-paste. A new user should be able to run the first example within minutes.
54
+ - Keep troubleshooting entries to common first-run errors only.
55
+
56
+ ### tutorial.md specifics
57
+
58
+ - Assumes the reader has completed quickstart.md. Do not re-explain setup beyond a brief reminder.
59
+ - Every section should teach one concept. Combine related ideas only when they share an example.
60
+ - `<!-- prompt-example:name -->` markers are test anchors verified by `tests/docs/test_prompt_examples.py`. Never modify the content between a marker pair without updating the corresponding test.
61
+ - Keep tutorial content backend-agnostic. Do not document backend-specific file layouts, provider credentials, or backend initialization variants here.
62
+ - If a concept needs backend-specific setup, add a short pointer to `providers.md` or `coding-agent-backends.md` instead of duplicating configuration details.
63
+
64
+ ### design.md specifics
65
+
66
+ - This is the specification. Implementation should match this document; if they diverge, prefer changing the implementation (see Section 0.1 alignment policy).
67
+ - Use precise, unambiguous language. Avoid hedging ("usually", "typically") for specified behavior.
68
+ - Structure: numbered sections, decision notes, implementation notes. Keep the hierarchy stable; other docs link to specific section anchors.
69
+
70
+ ### providers.md specifics
71
+
72
+ - The capability matrix must clearly show which features require a coding agent backend.
73
+ - Prefer concise, runnable setup snippets over conceptual narrative; link to `tutorial.md` for concept-first explanations.
74
+ - For custom backends, show the recommended path (`AgentStepExecutor.from_agent`) first, then the direct protocol implementation as an alternative.
75
+ - Credential details are not placed here. Pydantic AI provider credentials are delegated to the Pydantic AI documentation via external links.
76
+
77
+ ### coding-agent-backends.md specifics
78
+
79
+ - Document shared capabilities (skills, MCP, working directory) once in a shared section, then keep per-backend sections focused on differences.
80
+ - For external CLI integrations, separate:
81
+ - what Nighthawk configures and guarantees, and
82
+ - what is delegated to backend CLI rules.
83
+ - Include a settings field table for each backend with type, default, and description columns.
84
+
85
+ ### for-coding-agents.md specifics
86
+
87
+ - The reader is a coding agent (LLM), not a human. Write for immediate applicability, not progressive learning.
88
+ - Condense principles from tutorial.md, design.md, and writing guidelines into actionable rules. Do not duplicate prose; distill into decision rules and patterns.
89
+ - Include runnable code templates the agent can adapt directly.
90
+ - Keep the "common mistakes" table current; add entries when recurring issues are observed.
91
+ - This file should be self-contained: a coding agent reading only this file should be able to write correct Nighthawk code without consulting other docs.
92
+ - This file is consumed standalone (`@docs/for-coding-agents.md` in CLAUDE.md/AGENTS.md, GitHub raw URL, etc.). Do not assume sibling files exist at relative paths.
93
+ - All external references to other docs use absolute URLs based on `site_url` from `mkdocs.yml` (currently `https://kurusugawa-computer.github.io/nighthawk-python/`). If `site_url` changes, update the URLs in this file.
94
+
95
+ ### api.md specifics
96
+
97
+ - Content comes from source docstrings. Edit the source code, not api.md directly.
98
+ - Hand-editing is limited to `:::` directive structure (adding/removing sections, adjusting member filters).
99
+ - When the same module appears in multiple sections, use `members` filters in `:::` directives to partition members and avoid duplicate rendering.
100
+
101
+ ### roadmap.md specifics
102
+
103
+ - Future-facing only. Remove items once they are implemented.
104
+ - Avoid implementation details; describe intent and motivation.
@@ -0,0 +1,3 @@
1
+ unset ANTHROPIC_API_KEY
2
+ unset ANTHROPIC_AUTH_TOKEN
3
+ unset ANTHROPIC_BASE_URL
@@ -0,0 +1,3 @@
1
+ FROM mcr.microsoft.com/devcontainers/python:2-3.13-bookworm
2
+ RUN curl -fsSL https://dl.yarnpkg.com/debian/pubkey.gpg \
3
+ | sudo gpg --batch --yes --dearmor -o /usr/share/keyrings/yarn-archive-keyring.gpg
@@ -0,0 +1,11 @@
1
+ FROM python:3.13-slim
2
+ ENV PYTHONDONTWRITEBYTECODE=1 \
3
+ PYTHONUNBUFFERED=1
4
+ RUN pip install --no-cache-dir 'litellm[proxy]'
5
+ EXPOSE 4000
6
+ ENTRYPOINT [ \
7
+ "litellm", \
8
+ "--config", "/litellm-config.yaml", \
9
+ "--host", "0.0.0.0", \
10
+ "--port", "4000" \
11
+ ]
@@ -0,0 +1,24 @@
1
+ {
2
+ "name": "Python 3.13 with Claude Code CLI",
3
+ "dockerComposeFile": "docker-compose.yaml",
4
+ "service": "devcontainer",
5
+ "workspaceFolder": "/workspace",
6
+ "shutdownAction": "stopCompose",
7
+ "features": {
8
+ "ghcr.io/devcontainers/features/docker-in-docker:2": {},
9
+ "ghcr.io/devcontainers/features/node:1": {}
10
+ },
11
+ "postCreateCommand": "npm install -g pyright @openai/codex && pip install --no-cache-dir uv && curl -fsSL https://claude.ai/install.sh | bash",
12
+ "remoteEnv": {
13
+ "ANTHROPIC_BASE_URL": "http://litellm:4000",
14
+ "ANTHROPIC_AUTH_TOKEN": "sk-dummy"
15
+ },
16
+ "customizations": {
17
+ "vscode": {
18
+ "extensions": [
19
+ "charliermarsh.ruff",
20
+ "Anthropic.claude-code"
21
+ ]
22
+ }
23
+ }
24
+ }
@@ -0,0 +1,19 @@
1
+ services:
2
+ devcontainer:
3
+ container_name: nighthawk-devcontainer
4
+ build:
5
+ context: .
6
+ dockerfile: Dockerfile.devcontainer
7
+ volumes:
8
+ - ..:/workspace:cached
9
+ command: sleep infinity
10
+
11
+ litellm:
12
+ container_name: nighthawk-litellm
13
+ build:
14
+ context: .
15
+ dockerfile: Dockerfile.litellm
16
+ env_file:
17
+ - ../.env
18
+ volumes:
19
+ - ./litellm-config.yaml:/litellm-config.yaml:ro
@@ -0,0 +1,37 @@
1
+ model_list:
2
+ - model_name: gpt-5.4
3
+ litellm_params:
4
+ model: openai/gpt-5.4
5
+ api_key: os.environ/OPENAI_API_KEY
6
+ reasoning_effort: "high"
7
+ additional_drop_params: ["context_management", "output_config"]
8
+ - model_name: gpt-5.4-codex
9
+ litellm_params:
10
+ model: openai/gpt-5.4-codex
11
+ api_key: os.environ/OPENAI_API_KEY
12
+ reasoning_effort: "high"
13
+ additional_drop_params: ["context_management", "output_config"]
14
+ - model_name: gpt-5.3-codex
15
+ litellm_params:
16
+ model: openai/gpt-5.3-codex
17
+ api_key: os.environ/OPENAI_API_KEY
18
+ reasoning_effort: "high"
19
+ additional_drop_params: ["context_management", "output_config"]
20
+ - model_name: claude-opus-*
21
+ litellm_params:
22
+ model: openai/gpt-5.3-codex
23
+ api_key: os.environ/OPENAI_API_KEY
24
+ reasoning_effort: "high"
25
+ additional_drop_params: ["context_management", "output_config"]
26
+ - model_name: claude-sonnet-*
27
+ litellm_params:
28
+ model: openai/gpt-5.3-codex
29
+ api_key: os.environ/OPENAI_API_KEY
30
+ additional_drop_params: ["context_management", "output_config"]
31
+ - model_name: claude-haiku-*
32
+ litellm_params:
33
+ model: openai/gpt-5-mini
34
+ api_key: os.environ/OPENAI_API_KEY
35
+ additional_drop_params: ["context_management", "output_config"]
36
+ litellm_settings:
37
+ drop_params: true
@@ -0,0 +1,16 @@
1
+ # To get started with Dependabot version updates, you'll need to specify which
2
+ # package ecosystems to update and where the package manifests are located.
3
+ # Please see the documentation for more information:
4
+ # https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
5
+ # https://containers.dev/guide/dependabot
6
+
7
+ version: 2
8
+ updates:
9
+ - package-ecosystem: "devcontainers"
10
+ directory: "/"
11
+ schedule:
12
+ interval: weekly
13
+ - package-ecosystem: "github-actions"
14
+ directory: "/"
15
+ schedule:
16
+ interval: weekly
@@ -0,0 +1,83 @@
1
+ name: CI
2
+
3
+ on:
4
+ workflow_call:
5
+ push:
6
+ branches: [main]
7
+ pull_request:
8
+ branches: [main]
9
+
10
+ concurrency:
11
+ group: ci-${{ github.ref }}
12
+ cancel-in-progress: true
13
+
14
+ permissions:
15
+ contents: read
16
+
17
+ jobs:
18
+ lint:
19
+ name: Lint and type check
20
+ runs-on: ubuntu-latest
21
+ steps:
22
+ - uses: actions/checkout@v6
23
+ with:
24
+ persist-credentials: false
25
+
26
+ - uses: astral-sh/setup-uv@v6
27
+ with:
28
+ python-version: "3.13"
29
+
30
+ - name: Install dependencies
31
+ run: uv sync --all-extras --all-groups
32
+
33
+ - name: Format check
34
+ run: uv run ruff format --check .
35
+
36
+ - name: Lint
37
+ run: uv run ruff check .
38
+
39
+ - name: Type check
40
+ run: uv run pyright
41
+
42
+ test:
43
+ name: Test (Python ${{ matrix.python-version }})
44
+ runs-on: ubuntu-latest
45
+ strategy:
46
+ fail-fast: false
47
+ matrix:
48
+ python-version: ["3.13", "3.14"]
49
+ continue-on-error: ${{ matrix.python-version != '3.13' }}
50
+ steps:
51
+ - uses: actions/checkout@v6
52
+ with:
53
+ persist-credentials: false
54
+
55
+ - uses: astral-sh/setup-uv@v6
56
+ with:
57
+ python-version: ${{ matrix.python-version }}
58
+
59
+ - name: Install dependencies
60
+ run: uv sync --all-extras --all-groups
61
+
62
+ - name: Run tests
63
+ run: uv run pytest -q
64
+
65
+ build:
66
+ name: Build distribution
67
+ needs: [lint, test]
68
+ runs-on: ubuntu-latest
69
+ steps:
70
+ - uses: actions/checkout@v6
71
+ with:
72
+ persist-credentials: false
73
+
74
+ - uses: astral-sh/setup-uv@v6
75
+
76
+ - name: Build sdist and wheel
77
+ run: uv build
78
+
79
+ - name: Upload distribution artifacts
80
+ uses: actions/upload-artifact@v6
81
+ with:
82
+ name: python-package-distributions
83
+ path: dist/
@@ -0,0 +1,49 @@
1
+ name: Deploy docs to GitHub Pages
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ paths:
7
+ - "docs/**"
8
+ - "src/nighthawk/**"
9
+ - "mkdocs.yml"
10
+ - "pyproject.toml"
11
+ - ".github/workflows/docs.yml"
12
+ workflow_dispatch:
13
+
14
+ permissions:
15
+ contents: read
16
+ pages: write
17
+ id-token: write
18
+
19
+ concurrency:
20
+ group: pages
21
+ cancel-in-progress: false
22
+
23
+ jobs:
24
+ build:
25
+ runs-on: ubuntu-latest
26
+ steps:
27
+ - uses: actions/checkout@v6
28
+
29
+ - uses: astral-sh/setup-uv@v6
30
+
31
+ - name: Install dependencies
32
+ run: uv sync --group docs
33
+
34
+ - name: Build docs
35
+ run: uv run mkdocs build --strict
36
+
37
+ - uses: actions/upload-pages-artifact@v4
38
+ with:
39
+ path: site
40
+
41
+ deploy:
42
+ needs: build
43
+ runs-on: ubuntu-latest
44
+ environment:
45
+ name: github-pages
46
+ url: ${{ steps.deployment.outputs.page_url }}
47
+ steps:
48
+ - id: deployment
49
+ uses: actions/deploy-pages@v4
@@ -0,0 +1,33 @@
1
+ name: Publish to PyPI
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - "v[0-9]+.[0-9]+.[0-9]+"
7
+
8
+ permissions:
9
+ contents: read
10
+
11
+ jobs:
12
+ ci:
13
+ name: CI
14
+ uses: ./.github/workflows/ci.yml
15
+
16
+ publish:
17
+ name: Publish to PyPI
18
+ needs: ci
19
+ runs-on: ubuntu-latest
20
+ environment:
21
+ name: pypi
22
+ url: https://pypi.org/p/nighthawk-python
23
+ permissions:
24
+ id-token: write
25
+ steps:
26
+ - name: Download distribution artifacts
27
+ uses: actions/download-artifact@v6
28
+ with:
29
+ name: python-package-distributions
30
+ path: dist/
31
+
32
+ - name: Publish to PyPI
33
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,221 @@
1
+ .agents/
2
+ .claude/docs/
3
+ *.local.json
4
+ .vscode/
5
+
6
+ # Byte-compiled / optimized / DLL files
7
+ __pycache__/
8
+ *.py[codz]
9
+ *$py.class
10
+
11
+ # C extensions
12
+ *.so
13
+
14
+ # Distribution / packaging
15
+ .Python
16
+ build/
17
+ develop-eggs/
18
+ dist/
19
+ downloads/
20
+ eggs/
21
+ .eggs/
22
+ lib/
23
+ lib64/
24
+ parts/
25
+ sdist/
26
+ var/
27
+ wheels/
28
+ share/python-wheels/
29
+ *.egg-info/
30
+ .installed.cfg
31
+ *.egg
32
+ MANIFEST
33
+
34
+ # PyInstaller
35
+ # Usually these files are written by a python script from a template
36
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
37
+ *.manifest
38
+ *.spec
39
+
40
+ # Installer logs
41
+ pip-log.txt
42
+ pip-delete-this-directory.txt
43
+
44
+ # Unit test / coverage reports
45
+ htmlcov/
46
+ .tox/
47
+ .nox/
48
+ .coverage
49
+ .coverage.*
50
+ .cache
51
+ nosetests.xml
52
+ coverage.xml
53
+ *.cover
54
+ *.py.cover
55
+ .hypothesis/
56
+ .pytest_cache/
57
+ cover/
58
+
59
+ # Translations
60
+ *.mo
61
+ *.pot
62
+
63
+ # Django stuff:
64
+ *.log
65
+ local_settings.py
66
+ db.sqlite3
67
+ db.sqlite3-journal
68
+
69
+ # Flask stuff:
70
+ instance/
71
+ .webassets-cache
72
+
73
+ # Scrapy stuff:
74
+ .scrapy
75
+
76
+ # Sphinx documentation
77
+ docs/_build/
78
+
79
+ # PyBuilder
80
+ .pybuilder/
81
+ target/
82
+
83
+ # Jupyter Notebook
84
+ .ipynb_checkpoints
85
+
86
+ # IPython
87
+ profile_default/
88
+ ipython_config.py
89
+
90
+ # pyenv
91
+ # For a library or package, you might want to ignore these files since the code is
92
+ # intended to run in multiple environments; otherwise, check them in:
93
+ # .python-version
94
+
95
+ # pipenv
96
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
97
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
98
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
99
+ # install all needed dependencies.
100
+ # Pipfile.lock
101
+
102
+ # UV
103
+ # Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
104
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
105
+ # commonly ignored for libraries.
106
+ # uv.lock
107
+
108
+ # poetry
109
+ # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
110
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
111
+ # commonly ignored for libraries.
112
+ # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
113
+ # poetry.lock
114
+ # poetry.toml
115
+
116
+ # pdm
117
+ # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
118
+ # pdm recommends including project-wide configuration in pdm.toml, but excluding .pdm-python.
119
+ # https://pdm-project.org/en/latest/usage/project/#working-with-version-control
120
+ # pdm.lock
121
+ # pdm.toml
122
+ .pdm-python
123
+ .pdm-build/
124
+
125
+ # pixi
126
+ # Similar to Pipfile.lock, it is generally recommended to include pixi.lock in version control.
127
+ # pixi.lock
128
+ # Pixi creates a virtual environment in the .pixi directory, just like venv module creates one
129
+ # in the .venv directory. It is recommended not to include this directory in version control.
130
+ .pixi
131
+
132
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
133
+ __pypackages__/
134
+
135
+ # Celery stuff
136
+ celerybeat-schedule
137
+ celerybeat.pid
138
+
139
+ # Redis
140
+ *.rdb
141
+ *.aof
142
+ *.pid
143
+
144
+ # RabbitMQ
145
+ mnesia/
146
+ rabbitmq/
147
+ rabbitmq-data/
148
+
149
+ # ActiveMQ
150
+ activemq-data/
151
+
152
+ # SageMath parsed files
153
+ *.sage.py
154
+
155
+ # Environments
156
+ .env
157
+ .envrc
158
+ .venv
159
+ env/
160
+ venv/
161
+ ENV/
162
+ env.bak/
163
+ venv.bak/
164
+
165
+ # Spyder project settings
166
+ .spyderproject
167
+ .spyproject
168
+
169
+ # Rope project settings
170
+ .ropeproject
171
+
172
+ # mkdocs documentation
173
+ /site
174
+
175
+ # mypy
176
+ .mypy_cache/
177
+ .dmypy.json
178
+ dmypy.json
179
+
180
+ # Pyre type checker
181
+ .pyre/
182
+
183
+ # pytype static type analyzer
184
+ .pytype/
185
+
186
+ # Cython debug symbols
187
+ cython_debug/
188
+
189
+ # PyCharm
190
+ # JetBrains specific template is maintained in a separate JetBrains.gitignore that can
191
+ # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
192
+ # and can be added to the global gitignore or merged into this file. For a more nuclear
193
+ # option (not recommended) you can uncomment the following to ignore the entire idea folder.
194
+ # .idea/
195
+
196
+ # Abstra
197
+ # Abstra is an AI-powered process automation framework.
198
+ # Ignore directories containing user credentials, local state, and settings.
199
+ # Learn more at https://abstra.io/docs
200
+ .abstra/
201
+
202
+ # Visual Studio Code
203
+ # Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore
204
+ # that can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore
205
+ # and can be added to the global gitignore or merged into this file. However, if you prefer,
206
+ # you could uncomment the following to ignore the entire vscode folder
207
+ # .vscode/
208
+
209
+ # Ruff stuff:
210
+ .ruff_cache/
211
+
212
+ # PyPI configuration file
213
+ .pypirc
214
+
215
+ # Marimo
216
+ marimo/_static/
217
+ marimo/_lsp/
218
+ __marimo__/
219
+
220
+ # Streamlit
221
+ .streamlit/secrets.toml
@@ -0,0 +1 @@
1
+ 3.13