kirox 1.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 (54) hide show
  1. kirox-1.1.0/.github/workflows/ci.yml +118 -0
  2. kirox-1.1.0/.github/workflows/release.yml +61 -0
  3. kirox-1.1.0/.gitignore +73 -0
  4. kirox-1.1.0/CHANGELOG.md +63 -0
  5. kirox-1.1.0/CONTRIBUTING.md +82 -0
  6. kirox-1.1.0/LICENSE +21 -0
  7. kirox-1.1.0/PKG-INFO +188 -0
  8. kirox-1.1.0/README.md +148 -0
  9. kirox-1.1.0/docs/api-reference.md +223 -0
  10. kirox-1.1.0/docs/configuration.md +122 -0
  11. kirox-1.1.0/docs/installation.md +98 -0
  12. kirox-1.1.0/pyproject.toml +101 -0
  13. kirox-1.1.0/scripts/verify_distribution.py +145 -0
  14. kirox-1.1.0/src/kirox/__init__.py +20 -0
  15. kirox-1.1.0/src/kirox/_version.py +3 -0
  16. kirox-1.1.0/src/kirox/cli/__init__.py +387 -0
  17. kirox-1.1.0/src/kirox/core/__init__.py +1 -0
  18. kirox-1.1.0/src/kirox/core/auth.py +358 -0
  19. kirox-1.1.0/src/kirox/core/client.py +262 -0
  20. kirox-1.1.0/src/kirox/core/errors.py +27 -0
  21. kirox-1.1.0/src/kirox/core/eventstream.py +254 -0
  22. kirox-1.1.0/src/kirox/core/models.py +163 -0
  23. kirox-1.1.0/src/kirox/mcp/__init__.py +1 -0
  24. kirox-1.1.0/src/kirox/mcp/server.py +172 -0
  25. kirox-1.1.0/src/kirox/py.typed +0 -0
  26. kirox-1.1.0/src/kirox/service/__init__.py +1 -0
  27. kirox-1.1.0/src/kirox/service/_http_adapter.py +170 -0
  28. kirox-1.1.0/src/kirox/service/daemon.py +234 -0
  29. kirox-1.1.0/src/kirox/service/process_identity.py +299 -0
  30. kirox-1.1.0/src/kirox/service/scheduler.py +136 -0
  31. kirox-1.1.0/src/kirox/service/server.py +639 -0
  32. kirox-1.1.0/src/kirox/service/state.py +194 -0
  33. kirox-1.1.0/src/kirox/service/tray.py +113 -0
  34. kirox-1.1.0/src/kirox/utils/__init__.py +6 -0
  35. kirox-1.1.0/src/kirox/utils/config.py +52 -0
  36. kirox-1.1.0/src/kirox/utils/logging.py +30 -0
  37. kirox-1.1.0/tests/conftest.py +18 -0
  38. kirox-1.1.0/tests/test_auth.py +270 -0
  39. kirox-1.1.0/tests/test_cli.py +163 -0
  40. kirox-1.1.0/tests/test_cli_commands.py +421 -0
  41. kirox-1.1.0/tests/test_client.py +513 -0
  42. kirox-1.1.0/tests/test_config.py +22 -0
  43. kirox-1.1.0/tests/test_e2e.py +66 -0
  44. kirox-1.1.0/tests/test_eventstream.py +140 -0
  45. kirox-1.1.0/tests/test_logging.py +12 -0
  46. kirox-1.1.0/tests/test_mcp.py +227 -0
  47. kirox-1.1.0/tests/test_models.py +148 -0
  48. kirox-1.1.0/tests/test_performance.py +47 -0
  49. kirox-1.1.0/tests/test_process_identity.py +298 -0
  50. kirox-1.1.0/tests/test_scheduler.py +160 -0
  51. kirox-1.1.0/tests/test_server.py +711 -0
  52. kirox-1.1.0/tests/test_service_lifecycle.py +154 -0
  53. kirox-1.1.0/tests/test_state.py +90 -0
  54. kirox-1.1.0/tests/test_tray.py +121 -0
@@ -0,0 +1,118 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ branches: [main]
8
+
9
+ permissions:
10
+ contents: read
11
+
12
+ jobs:
13
+ quality:
14
+ name: ${{ matrix.os }} / Python ${{ matrix.python-version }}
15
+ runs-on: ${{ matrix.os }}
16
+ strategy:
17
+ fail-fast: false
18
+ matrix:
19
+ os: [ubuntu-latest, windows-latest]
20
+ python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"]
21
+
22
+ steps:
23
+ - uses: actions/checkout@v7
24
+ - uses: actions/setup-python@v7
25
+ with:
26
+ python-version: ${{ matrix.python-version }}
27
+ cache: pip
28
+
29
+ - name: Install development and MCP dependencies
30
+ run: |
31
+ python -m pip install --upgrade pip
32
+ python -m pip install -e ".[dev,mcp]"
33
+
34
+ - name: Ruff format check
35
+ run: python -m ruff format --check .
36
+
37
+ - name: Ruff lint
38
+ run: python -m ruff check .
39
+
40
+ - name: Mypy
41
+ run: python -m mypy src tests scripts
42
+
43
+ - name: Pyrefly
44
+ run: python -m pyrefly check
45
+
46
+ - name: Test with branch coverage
47
+ run: python -m pytest tests -q --cov=kirox --cov-branch --cov-report=term-missing
48
+
49
+ - name: Build wheel and source distribution
50
+ run: python -m build
51
+
52
+ - name: Inspect wheel and run clean-install smoke test
53
+ run: python scripts/verify_distribution.py
54
+
55
+ - uses: actions/upload-artifact@v7
56
+ with:
57
+ name: kirox-${{ matrix.os }}-py${{ matrix.python-version }}
58
+ path: dist/*
59
+ if-no-files-found: error
60
+
61
+
62
+ service-extra:
63
+ name: Optional service extra / ${{ matrix.os }}
64
+ runs-on: ${{ matrix.os }}
65
+ strategy:
66
+ fail-fast: false
67
+ matrix:
68
+ os: [ubuntu-latest, windows-latest]
69
+
70
+ steps:
71
+ - uses: actions/checkout@v7
72
+ - uses: actions/setup-python@v7
73
+ with:
74
+ python-version: "3.13"
75
+ cache: pip
76
+
77
+ - name: Build wheel
78
+ run: |
79
+ python -m pip install --upgrade pip
80
+ python -m pip install build==1.5.0
81
+ python -m build --wheel
82
+
83
+ - name: Install wheel with the service extra
84
+ shell: bash
85
+ run: python -m pip install "$(ls dist/*.whl)[service]"
86
+
87
+ - name: Verify dependency resolution
88
+ run: python -m pip check
89
+
90
+ - name: Headless tray import smoke test
91
+ shell: bash
92
+ run: |
93
+ python - <<'PY'
94
+ import importlib.util
95
+ import os
96
+ import sys
97
+
98
+ import kirox.service.tray as tray
99
+ from kirox.service.daemon import KiroxService
100
+
101
+ # Prove the optional dependencies are installed without importing
102
+ # pystray, which probes a display backend at import time.
103
+ for name in ("pystray", "PIL"):
104
+ assert importlib.util.find_spec(name) is not None, f"{name} is not installed"
105
+
106
+ assert tray.KiroTray is not None
107
+ assert KiroxService is not None
108
+
109
+ if sys.platform.startswith("linux") and not os.environ.get("DISPLAY"):
110
+ assert tray.HAS_PYSTRAY is False, "tray must degrade without a display"
111
+ assert tray.create_icon_image() is None
112
+ assert tray.KiroTray().start() is False, "start() must refuse headless"
113
+
114
+ print("tray import ok, HAS_PYSTRAY =", tray.HAS_PYSTRAY)
115
+ PY
116
+
117
+ - name: Console script smoke test
118
+ run: kirox --help
@@ -0,0 +1,61 @@
1
+ name: Release
2
+
3
+ on:
4
+ push:
5
+ tags: ["v*"]
6
+
7
+ permissions:
8
+ contents: read
9
+
10
+ jobs:
11
+ publish:
12
+ name: Publish to PyPI
13
+ runs-on: ubuntu-latest
14
+ environment:
15
+ name: pypi
16
+ url: https://pypi.org/p/kirox
17
+ permissions:
18
+ # Required for PyPI trusted publishing. No API token is used.
19
+ id-token: write
20
+
21
+ steps:
22
+ - uses: actions/checkout@v7
23
+ - uses: actions/setup-python@v7
24
+ with:
25
+ python-version: "3.13"
26
+ cache: pip
27
+
28
+ - name: Verify the tag matches the packaged version
29
+ shell: bash
30
+ run: |
31
+ python - <<'PY'
32
+ import importlib.util
33
+ import os
34
+ import sys
35
+
36
+ # Load _version.py on its own. Importing kirox._version would execute
37
+ # kirox/__init__.py, which needs runtime dependencies that are not
38
+ # installed yet at this point in the job.
39
+ spec = importlib.util.spec_from_file_location("_kirox_version", "src/kirox/_version.py")
40
+ assert spec is not None and spec.loader is not None
41
+ module = importlib.util.module_from_spec(spec)
42
+ spec.loader.exec_module(module)
43
+
44
+ ref = os.environ["GITHUB_REF_NAME"]
45
+ tag = ref.removeprefix("v")
46
+ if tag != module.__version__:
47
+ sys.exit(f"tag {ref} does not match src/kirox/_version.py ({module.__version__})")
48
+ print(f"tag {ref} matches packaged version {module.__version__}")
49
+ PY
50
+
51
+ - name: Build wheel and source distribution
52
+ run: |
53
+ python -m pip install --upgrade pip
54
+ python -m pip install build==1.5.0
55
+ python -m build
56
+
57
+ - name: Inspect wheel and run clean-install smoke test
58
+ run: python scripts/verify_distribution.py
59
+
60
+ - name: Publish to PyPI
61
+ uses: pypa/gh-action-pypi-publish@v1.14.2
kirox-1.1.0/.gitignore ADDED
@@ -0,0 +1,73 @@
1
+ __pycache__/
2
+ *.py[cod]
3
+ *$py.class
4
+ *.so
5
+ .Python
6
+ build/
7
+ develop-eggs/
8
+ dist/
9
+ downloads/
10
+ eggs/
11
+ .eggs/
12
+ lib/
13
+ lib64/
14
+ parts/
15
+ sdist/
16
+ var/
17
+ wheels/
18
+ *.egg-info/
19
+ .installed.cfg
20
+ *.egg
21
+ MANIFEST
22
+ .venv/
23
+ venv/
24
+ ENV/
25
+ env/
26
+ .vscode/
27
+ .idea/
28
+ *.swp
29
+ *.swo
30
+ *~
31
+ .pytest_cache/
32
+ .coverage
33
+ .coverage.*
34
+ coverage.xml
35
+ htmlcov/
36
+ .tox/
37
+ .nox/
38
+ .mypy_cache/
39
+ .pyre/
40
+ .pytype/
41
+ .ruff_cache/
42
+ .ipynb_checkpoints/
43
+ .DS_Store
44
+ Thumbs.db
45
+ Desktop.ini
46
+ *.log
47
+ *.tmp
48
+ *.temp
49
+ .env
50
+ .env.*
51
+ !.env.example
52
+ .kiro/
53
+ *.mitm
54
+
55
+ # Compiled extensions on Windows (companion to *.so above)
56
+ *.pyd
57
+
58
+ # Type checker daemons and caches not covered above
59
+ .dmypy.json
60
+ dmypy.json
61
+ .pyrefly_cache/
62
+
63
+ # Local interpreter pins and build metadata
64
+ .python-version
65
+ pip-wheel-metadata/
66
+
67
+ # Merge, patch, and backup leftovers
68
+ *.orig
69
+ *.rej
70
+ *.bak
71
+
72
+ # Created by mistyped PowerShell redirection on Windows
73
+ nul
@@ -0,0 +1,63 @@
1
+ # Changelog
2
+
3
+ All notable changes to Kirox are documented in this file. The format follows [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) and [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
4
+
5
+ ## [1.1.0] - 2026-07-31
6
+
7
+ ### Added
8
+
9
+ - Strict incremental AWS EventStream decoder with CRC, size, header-type, UTF-8, and truncation validation.
10
+ - Deterministic credential resolution with explicit/config/KIROX/ASSISTANT/database precedence and fixed database discovery locations.
11
+ - Managed service state, authenticated loopback shutdown, startup rollback, socket/thread ownership, and idempotent client cleanup.
12
+ - Text-only OpenAI chat-completions and Anthropic messages adapters with canonical history, field-addressed validation, incremental SSE, disconnect cleanup, and sanitized errors.
13
+ - Operational `kirox-mcp` stdio entry point with lazy optional imports, strict tool input, worker-thread bridging, one client, and lifecycle cleanup.
14
+ - PEP 561 `py.typed` marker and wheel/clean-install distribution verifier.
15
+ - Windows and Ubuntu CI matrix for Python 3.10–3.14 covering Ruff, mypy, Pyrefly, branch coverage, wheel/sdist build, metadata inspection, and install smoke tests, plus a dedicated job that installs the built wheel with the optional `service` extra and runs a headless tray-import and `pip check` smoke test.
16
+ - Pyrefly as a second required type checker, with an explicit `[tool.pyrefly]` section so it does not fall back to the permissive `basic` preset, and warnings promoted to failures.
17
+ - Loopback `Host` header validation and a 1 MiB request-body limit on every bridge route, returning HTTP 400 and provider-shaped HTTP 413 responses before validation or upstream work.
18
+ - Kernel-derived process identity in service state, with identity-bound `kirox stop --force` termination on Linux and Windows that fails closed on PID reuse, missing identity, or unsupported platforms.
19
+
20
+ ### Changed
21
+
22
+ - The token scheduler now treats HTTP 401 and 403 from its authentication check as credential failures, re-resolves credentials, and retries the check once instead of relying on error-message text.
23
+ - `AssistantClient.list_tools()` now validates the upstream envelope strictly and raises `APIError` for a missing `result`, a missing or non-array `tools` member, or entries without a non-empty `name` and an `inputSchema` object.
24
+ - Package version now has one source in `src/kirox/_version.py`; CLI, health responses, root metadata, and built distributions report 1.1.0.
25
+ - HTTP service binding is explicitly loopback-only.
26
+ - The service token scheduler now uses an interruptible standard-library worker, removing the unused APScheduler dependency.
27
+ - CLI, tray, scheduler, and server lifecycle paths now close owned resources deterministically.
28
+ - Quality configuration now checks formatting, imports, common bugs, repository typing with two checkers, and a minimum 80% branch-aware coverage threshold.
29
+ - Development tooling is pinned to exact versions, and runtime dependencies now carry both a tested floor and a major upper bound. The optional MCP extra stays on `mcp>=1.28.1,<2`: the v2 SDK moved the low-level `Server` handlers from decorators to constructor parameters, so the current stdio server would not run against it.
30
+ - Installation, configuration, API, contribution, and lifecycle documentation now match actual behavior and text-only limitations.
31
+
32
+ ### Fixed
33
+
34
+ - EventStream parsing no longer assumes complete HTTP chunks or accepts bad checksums, impossible lengths, unsupported header encodings, or trailing partial frames.
35
+ - Streaming provider responses no longer prebuffer the upstream iterator, leak it on disconnect/error, duplicate terminal events, expose exception details, or fabricate usage values.
36
+ - MCP import no longer exits the host process when the optional dependency is absent.
37
+ - CLI stop no longer targets a PID until persisted state and service ownership have been validated, and force stop now additionally proves process identity so a reused PID is never signalled.
38
+ - `ModelInfo.from_api()` no longer stores `None` in fields declared `str`, `int`, or `float` when upstream sends an explicit null, and no longer raises `AttributeError` for a null `tokenLimits`; an unusable `modelId` now raises `ValueError` instead of producing a mistyped model.
39
+ - `AssistantClient.list_models()` now validates the response envelope and reports malformed payloads as `APIError` rather than letting `KeyError` or `ValueError` escape the SDK.
40
+ - Importing `kirox.service.tray` no longer crashes on a host with no usable display. `pystray` probes a display backend while importing, so a headless Linux server raised `Xlib.error.DisplayNameError`, which the previous `except ImportError` guard did not catch. The tray now degrades to unavailable and reports a message that names the missing display as a possible cause.
41
+
42
+ ## [1.0.0] - 2026-07-30
43
+
44
+ ### Added
45
+
46
+ - Initial core API client with streaming and multi-model support.
47
+ - CLI with interactive chat and update checks.
48
+ - Background HTTP service and optional system tray.
49
+ - Token refresh scheduler and configuration management.
50
+ - OpenAI- and Anthropic-compatible bridge endpoints.
51
+ - MCP integration and unit, integration, end-to-end, and performance tests.
52
+
53
+ ## [0.2.0] - 2026-07-30
54
+
55
+ ### Added
56
+
57
+ - Background service module, system tray support, token scheduler, HTTP API server, and associated tests.
58
+
59
+ ## [0.1.0] - 2026-07-30
60
+
61
+ ### Added
62
+
63
+ - Initial project structure, API client, EventStream parser, CLI interface, and basic tests.
@@ -0,0 +1,82 @@
1
+ # Contributing to Kirox
2
+
3
+ ## Development setup
4
+
5
+ Kirox supports Python 3.10–3.14 on Windows and Linux CI.
6
+
7
+ ```bash
8
+ git clone https://github.com/your-username/kirox.git
9
+ cd kirox
10
+ python -m venv .venv
11
+ ```
12
+
13
+ Activate the environment with `.venv\Scripts\Activate.ps1` on Windows PowerShell or `source .venv/bin/activate` in a POSIX shell, then install all development dependencies used by the test suite:
14
+
15
+ ```bash
16
+ python -m pip install -e ".[dev,mcp]"
17
+ ```
18
+
19
+ The tray extra is not required for tests; tray behavior is exercised with fakes so CI does not need a desktop session.
20
+
21
+ ## Required quality gates
22
+
23
+ Run every command from the repository root before opening a pull request:
24
+
25
+ ```bash
26
+ python -m ruff format --check .
27
+ python -m ruff check .
28
+ python -m mypy src tests scripts
29
+ python -m pyrefly check
30
+ python -m pytest tests -q --cov=kirox --cov-branch --cov-report=term-missing
31
+ python -m build
32
+ python scripts/verify_distribution.py
33
+ ```
34
+
35
+ Branch coverage must remain at least 80%. Both type checkers are required: they disagree often enough that each one catches errors the other misses. Pyrefly reads its `[tool.pyrefly]` section in `pyproject.toml`; without that section it would fall back to the `basic` preset and silence most type errors. The distribution verifier checks the wheel version, `kirox/py.typed`, `kirox` and `kirox-mcp` entry points, then performs a clean temporary-environment install/import/CLI/missing-extra smoke test and `pip check`.
36
+
37
+ CI runs the same gates on Windows and Ubuntu with Python 3.10, 3.11, 3.12, 3.13, and 3.14. A separate job installs the built wheel with the optional `service` extra and runs a headless tray-import and `pip check` smoke test, so the tray dependencies are exercised without requiring a desktop session in the main matrix. A local Python version outside that matrix is useful but does not replace supported-version CI.
38
+
39
+ ## Code style and typing
40
+
41
+ - Use Ruff as the formatter and linter; do not hand-format around it.
42
+ - Type public APIs and keep `mypy src tests scripts` and `pyrefly check` clean.
43
+ - Preserve existing public imports and call signatures unless a compatibility plan is documented.
44
+ - Keep optional features lazy: importing the base package must not require MCP or tray dependencies.
45
+ - Do not add runtime dependencies when the standard library or an existing dependency is sufficient.
46
+ - `_version.py` is the single version source. Do not duplicate the package version in `pyproject.toml` or service responses.
47
+
48
+ To apply formatting during development:
49
+
50
+ ```bash
51
+ python -m ruff format .
52
+ python -m ruff check .
53
+ ```
54
+
55
+ ## Tests
56
+
57
+ Add behavior-focused tests for every change. Tests must not use live credentials, external AI services, or arbitrary user databases.
58
+
59
+ For relevant areas, cover:
60
+
61
+ - Success, validation, and resource-cleanup paths
62
+ - Incremental streaming and malformed/truncated input
63
+ - Authentication precedence without exposing secret values
64
+ - Service startup rollback, idempotent shutdown, socket/thread cleanup, and state ownership
65
+ - Optional dependency present and absent behavior
66
+ - Provider adapter text-only rejection rather than silent semantic loss
67
+
68
+ Use `httpx.MockTransport`, Flask's test client, temporary paths, and injected fakes. Avoid assertions that only repeat implementation constants without exercising a contract.
69
+
70
+ ## Documentation and changelog
71
+
72
+ Update README and focused docs whenever configuration, compatibility limitations, entry points, lifecycle behavior, or API envelopes change. Do not publish a static test-count claim; it becomes stale immediately. Add user-visible changes to `CHANGELOG.md` using semantic-versioning categories.
73
+
74
+ ## Pull requests
75
+
76
+ 1. Create a focused branch and make the smallest compatible change.
77
+ 2. Add meaningful tests and documentation.
78
+ 3. Run the full quality and distribution gates above.
79
+ 4. Include supported-OS/Python limitations and any unverified behavior in the pull-request description.
80
+ 5. Submit the pull request without generated temporary virtual environments or distribution-check directories.
81
+
82
+ Be respectful and do not include credentials, database contents, or user prompts in issues, fixtures, logs, or screenshots.
kirox-1.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Kirox Contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
kirox-1.1.0/PKG-INFO ADDED
@@ -0,0 +1,188 @@
1
+ Metadata-Version: 2.4
2
+ Name: kirox
3
+ Version: 1.1.0
4
+ Summary: Production-ready SDK for AI coding assistants with background service and system tray
5
+ Project-URL: Homepage, https://github.com/idugeni/kirox
6
+ Project-URL: Documentation, https://github.com/idugeni/kirox#readme
7
+ Project-URL: Repository, https://github.com/idugeni/kirox
8
+ Project-URL: Issues, https://github.com/idugeni/kirox/issues
9
+ Author: Kirox Contributors
10
+ License-Expression: MIT
11
+ License-File: LICENSE
12
+ Keywords: ai,background-service,claude,coding-assistant,gpt,kiro,llm,sdk
13
+ Classifier: Development Status :: 5 - Production/Stable
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: License :: OSI Approved :: MIT License
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Programming Language :: Python :: 3.13
21
+ Classifier: Programming Language :: Python :: 3.14
22
+ Classifier: Topic :: Software Development :: Libraries
23
+ Classifier: Typing :: Typed
24
+ Requires-Python: >=3.10
25
+ Requires-Dist: flask<4,>=3.1.3
26
+ Requires-Dist: httpx<0.29,>=0.28.1
27
+ Provides-Extra: dev
28
+ Requires-Dist: build==1.5.0; extra == 'dev'
29
+ Requires-Dist: mypy==2.3.0; extra == 'dev'
30
+ Requires-Dist: pyrefly==1.2.0; extra == 'dev'
31
+ Requires-Dist: pytest-cov==7.1.0; extra == 'dev'
32
+ Requires-Dist: pytest==9.1.1; extra == 'dev'
33
+ Requires-Dist: ruff==0.16.1; extra == 'dev'
34
+ Provides-Extra: mcp
35
+ Requires-Dist: mcp<2,>=1.28.1; extra == 'mcp'
36
+ Provides-Extra: service
37
+ Requires-Dist: pillow<13,>=12.3.0; extra == 'service'
38
+ Requires-Dist: pystray<0.20,>=0.19.5; extra == 'service'
39
+ Description-Content-Type: text/markdown
40
+
41
+ # Kirox
42
+
43
+ Kirox is a typed Python SDK and local HTTP bridge for AI coding-assistant workflows. It provides incremental AWS EventStream decoding, a synchronous client, managed local service and tray lifecycle, text-only OpenAI/Anthropic-compatible endpoints, and an optional MCP stdio server.
44
+
45
+ Kirox deliberately binds its HTTP service to loopback addresses only. It is not a network-facing gateway and rejects `0.0.0.0` or other non-loopback hosts.
46
+
47
+ ## Requirements
48
+
49
+ - Python 3.10 or newer; tested on 3.10–3.14
50
+ - A Kiro-compatible bearer token or an authenticated supported CLI database
51
+ - Windows, macOS, or Linux; tray support depends on the desktop environment
52
+
53
+ ## Installation
54
+
55
+ ```bash
56
+ python -m pip install kirox # SDK, CLI, and local HTTP bridge
57
+ python -m pip install "kirox[service]" # Add pystray and Pillow
58
+ python -m pip install "kirox[mcp]" # Add the MCP SDK
59
+ python -m pip install "kirox[service,mcp]" # All optional features
60
+ ```
61
+
62
+ The MCP dependency is optional and imported only by MCP operations. Running `kirox-mcp` without it exits with an instruction to install `kirox[mcp]`; importing `kirox.mcp.server` remains safe.
63
+
64
+ ## Authentication
65
+
66
+ `AuthManager.resolve()` uses a deterministic precedence order:
67
+
68
+ 1. Explicit `token` / `profile_arn` arguments
69
+ 2. Configuration values
70
+ 3. `KIROX_TOKEN` / `KIROX_PROFILE_ARN`
71
+ 4. Backward-compatible `ASSISTANT_TOKEN` / `ASSISTANT_PROFILE_ARN` aliases
72
+ 5. An explicitly configured database, then fixed supported CLI database locations
73
+
74
+ `KIROX_DB_PATH` and `ASSISTANT_DB_PATH` can select a database. Kirox does not scan arbitrary files or treat unrelated keys such as `OPENAI_API_KEY` as upstream credentials.
75
+
76
+ ## CLI and managed lifecycle
77
+
78
+ ```bash
79
+ kirox # Same as `kirox run`
80
+ kirox run --no-tray # Service only
81
+ kirox run --no-update # Disable the background PyPI update check
82
+ kirox status
83
+ kirox stop # Authenticated graceful shutdown
84
+ kirox stop --force # Identity-verified PID fallback for unchanged state
85
+ kirox models
86
+ kirox chat --model auto
87
+ kirox ask --model auto "Hello"
88
+ kirox update
89
+ ```
90
+
91
+ The service owns one client, refresh scheduler, HTTP server, state file, and optional tray. Startup rolls back partial resources; normal stop closes threads, sockets, state, and the client idempotently. Runtime control data is stored in `~/.kirox/service.json` with a per-process token and is accepted only over loopback. State also records a kernel-derived process identity, so `stop --force` terminates only a process that still matches the recorded owner and fails closed on mismatch, on missing identity, or where the platform cannot supply one.
92
+
93
+ ## Python API
94
+
95
+ ```python
96
+ from kirox import AssistantClient
97
+
98
+ with AssistantClient.auto() as client:
99
+ for event in client.chat("Explain this function", model_id="auto"):
100
+ if event.content:
101
+ print(event.content, end="", flush=True)
102
+ ```
103
+
104
+ `AssistantClient.chat()` validates and decodes upstream EventStream frames incrementally, including both CRCs and frame/header bounds. Closing the generator early closes the HTTP response.
105
+
106
+ ## Local HTTP bridge
107
+
108
+ Start the service and use `http://127.0.0.1:8420` (or the configured loopback port):
109
+
110
+ ```bash
111
+ kirox run --no-tray
112
+
113
+ curl http://127.0.0.1:8420/v1/chat/completions \
114
+ -H "Content-Type: application/json" \
115
+ -d '{"model":"auto","messages":[{"role":"user","content":"Hello"}],"stream":true}'
116
+ ```
117
+
118
+ Available routes include:
119
+
120
+ - Native: `/health`, `/`, `/api/models`, `/api/chat`, `/api/token/status`
121
+ - OpenAI-compatible: `/v1/models`, `/v1/chat/completions`
122
+ - Anthropic-compatible: `/v1/messages`
123
+
124
+ The provider adapters are intentionally **text-only**. They accept text strings or arrays of text blocks, preserve system/user/assistant history in a canonical transcript, require the final message to be from the user, and reject unsupported fields instead of silently ignoring them. Tools, tool calls, images, audio, metadata, sampling parameters, and other multimodal semantics are not supported. `max_tokens` is validated for compatibility but not enforced; responses carry an HTTP `Warning` and do not fabricate token usage.
125
+
126
+ Streaming is incremental SSE. OpenAI streams terminate once with `[DONE]`; Anthropic streams use ordered message/content events and a single terminal event. Upstream and internal exception details are sanitized from HTTP responses.
127
+
128
+ Requests must carry a loopback `Host` header, so a browser page on another origin cannot reach the bridge through DNS rebinding, and bodies larger than 1 MiB are rejected with HTTP 413 before validation or upstream work.
129
+
130
+ See [API Reference](docs/api-reference.md) for the complete request contract.
131
+
132
+ ## MCP
133
+
134
+ After installing the extra, configure an MCP client to launch the stdio command:
135
+
136
+ ```json
137
+ {
138
+ "mcpServers": {
139
+ "kirox": {"command": "kirox-mcp"}
140
+ }
141
+ }
142
+ ```
143
+
144
+ The server exposes one `kirox_chat` tool with required non-empty `message` and optional non-empty `model` (default `auto`). Unknown tools, unknown arguments, and invalid values return errors. Synchronous client work runs in a worker thread so the MCP event loop stays responsive, and the owned client closes when the stdio session ends.
145
+
146
+ ## Configuration
147
+
148
+ The default file is `~/.kirox/config.json`:
149
+
150
+ ```json
151
+ {
152
+ "region": "us-east-1",
153
+ "server_host": "127.0.0.1",
154
+ "server_port": 8420,
155
+ "auto_refresh": true,
156
+ "refresh_interval": 3000,
157
+ "log_level": "INFO"
158
+ }
159
+ ```
160
+
161
+ Only loopback values are accepted for `server_host`. See [Configuration](docs/configuration.md) for all fields and environment aliases.
162
+
163
+ ## Development and release gates
164
+
165
+ ```bash
166
+ python -m pip install -e ".[dev,mcp]"
167
+ python -m ruff format --check .
168
+ python -m ruff check .
169
+ python -m mypy src tests scripts
170
+ python -m pyrefly check
171
+ python -m pytest tests -q --cov=kirox --cov-branch --cov-report=term-missing
172
+ python -m build
173
+ python scripts/verify_distribution.py
174
+ ```
175
+
176
+ Coverage is branch-aware and must remain at least 80%. Both type checkers run because they catch different classes of error; Pyrefly is configured explicitly in `pyproject.toml` so it does not silently fall back to its permissive `basic` preset. The distribution verifier checks `py.typed`, version metadata, both console scripts, then installs the wheel into a temporary clean virtual environment for import, CLI, missing-MCP, and `pip check` smoke tests.
177
+
178
+ ## Documentation
179
+
180
+ - [Installation](docs/installation.md)
181
+ - [Configuration](docs/configuration.md)
182
+ - [API Reference](docs/api-reference.md)
183
+ - [Contributing](CONTRIBUTING.md)
184
+ - [Changelog](CHANGELOG.md)
185
+
186
+ ## License
187
+
188
+ MIT License. See [LICENSE](LICENSE).