fix: v0.2.9 — review welle 1 (C-1, C-2, M-3)
C-1: __version__ now derived from package metadata via importlib.metadata.version() so pyproject.toml is the single source of truth. Previously stuck at "0.1.0" since the initial release. C-2: Backfill CHANGELOG entries for 0.2.7 and 0.2.8 (both releases had shipped without changelog updates) and add a 0.2.9 entry covering this welle. M-3: Reject project names containing path separators or other unsafe characters before they reach _find_compose_path. Previously a name like "../../etc" could traverse out of compose_base_path when the project was not yet registered with Container Manager. Adds _validate_project_name (regex ^[a-zA-Z0-9_-]+$, applied in read_compose, update_compose, update_image_tag, update_env_var) plus parametrized tests for valid and unsafe names and one rejection test per tool. 236 tests pass. Also: ruff format autofix on three pre-existing files (cli.py, config.py, test_config.py) — cosmetic only. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -2,6 +2,93 @@
|
||||
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
## [0.2.9] - 2026-05-18
|
||||
|
||||
### Fixed
|
||||
|
||||
- `__version__` is now derived from package metadata via
|
||||
`importlib.metadata.version()`, eliminating the drift between
|
||||
`pyproject.toml` and `src/mcp_synology_container/__init__.py` (was stuck
|
||||
at `0.1.0` since the initial release).
|
||||
- `compose.py`: reject project names that contain path separators or other
|
||||
unsafe characters before they reach `_find_compose_path`. Previously a
|
||||
name like `"../../etc"` could traverse out of `compose_base_path` when
|
||||
the project was not yet registered with Container Manager. The new
|
||||
`_validate_project_name` helper enforces `^[a-zA-Z0-9_-]+$` and is
|
||||
applied to `read_compose`, `update_compose`, `update_image_tag`, and
|
||||
`update_env_var`. Addresses M-3 from the v0.2.8 review.
|
||||
|
||||
### Docs
|
||||
|
||||
- `CHANGELOG.md` backfilled for releases 0.2.7 and 0.2.8 (entries had been
|
||||
missed during those releases).
|
||||
|
||||
## [0.2.8] - 2026-04-21
|
||||
|
||||
### Added
|
||||
|
||||
- `tests/test_dsm_client.py` — comprehensive offline test suite for
|
||||
`DsmClient`:
|
||||
- `_scrub_url` and `_error_message` pure helpers.
|
||||
- `request()` happy-path, API-not-cached, `_sid` scrubbing in
|
||||
`HTTPStatusError`, sensitive-param log masking.
|
||||
- Session re-auth retry: single-retry semantics, auth-manager-absent
|
||||
path, re-auth failure path, thundering-herd (login called once under
|
||||
concurrent 106 responses).
|
||||
- `trigger_build_stream`: SSE fire-and-forget, JSON error detection,
|
||||
`ReadTimeout` swallowing, HTTP-error scrubbing.
|
||||
- `upload_text` and `download_text` happy-path + error-response branches.
|
||||
- `_ensure_initialized` double-checked locking and negative-cache
|
||||
cooldown behavior.
|
||||
|
||||
### Fixed
|
||||
|
||||
- `DsmClient._ensure_initialized`: cache failed init outcomes for 60 s so
|
||||
that repeated tool calls during a credential outage (wrong password,
|
||||
IP-blocked 407, DNS failure) do not keep hammering DSM. Each caller
|
||||
receives the cached exception until the cooldown window expires, after
|
||||
which a fresh attempt is made. Adds `INIT_ERROR_COOLDOWN` module
|
||||
constant and `_init_error` / `_init_error_until` state. Addresses M4
|
||||
from the 0.2.7 review.
|
||||
|
||||
## [0.2.7] - 2026-04-21
|
||||
|
||||
### Fixed
|
||||
|
||||
- `DsmClient`: scrub `_sid` query-parameter values from URLs embedded in
|
||||
`httpx.HTTPStatusError` messages so the raw DSM session ID never reaches
|
||||
log output or MCP tool responses (C1).
|
||||
- `DsmClient`: re-auth lock now snapshots `_sid` before entering the lock
|
||||
and skips the redundant login if another task has already refreshed the
|
||||
session, eliminating duplicate logins on concurrent 106/107/119
|
||||
responses (M3).
|
||||
- `DsmClient.trigger_build_stream`: re-instates immediate JSON-error
|
||||
detection (regression from 0.2.6). Inspects the `Content-Type` header
|
||||
and reads a small capped prefix of the body for `application/json`
|
||||
responses to surface DSM error codes without forcing the caller into a
|
||||
multi-minute polling timeout. SSE responses remain fire-and-forget
|
||||
(C2/M8).
|
||||
- `compose.update_env_var`: parenthesise the apply-branch match condition
|
||||
so `(isinstance AND startswith) OR (entry == var_name)` no longer
|
||||
evaluates the equality branch for non-string entries — aligns the apply
|
||||
side with the preview-side detection logic (M1).
|
||||
|
||||
### Changed
|
||||
|
||||
- All 23 `@mcp.tool()` functions: strip `-> str` return annotations and
|
||||
trim docstrings to a single line (≤100 chars). FastMCP generates an
|
||||
`outputSchema` entry for every annotated tool, which roughly doubles
|
||||
the `tools/list` payload size; multi-line docstrings with
|
||||
`Args:`/`Returns:` sections add further bulk that Claude Desktop must
|
||||
parse on every connection.
|
||||
|
||||
### Chore
|
||||
|
||||
- `uv.lock` resynced (was stale at `0.2.2`).
|
||||
- `.gitignore`: exclude `.claude/` per-user Claude Code settings.
|
||||
- Mechanical `ruff check --fix` + `ruff format` cleanup (import sorting,
|
||||
unused-import removal). No functional change.
|
||||
|
||||
## [0.2.6] - 2026-04-21
|
||||
|
||||
### Fixed
|
||||
|
||||
Reference in New Issue
Block a user