feat: v0.6.0 — read build_stream log instead of dropping it (#2)

DSM emits a readable plaintext build log over the build_stream HTTP
body (one short status line per step) and closes the connection when
the build is done. The 0.2.5 implementation sent the request and
dropped the body unread, leaving users with nothing more than a
BUILD_FAILED polling status and no actionable diagnostic.

DsmClient.trigger_build_stream now consumes the body line-by-line and
returns the collected log as a string. Wall-clock budget of 210 s
(under the Claude Desktop ~4 min ceiling); on timeout the partial log
is returned with a "[build_stream: timeout — stream still open
server-side]" marker so callers know the build continues server-side.
Per-chunk ReadTimeout is treated the same way. JSON error envelope,
transport-error mapping (M-4), and SID-scrubbed HTTP-error formatting
are unchanged.

redeploy_project and create_project now parse the returned log via
_parse_build_stream_log (any line containing "Error response from
daemon:" or ending in " Error" counts as a failure). On a failed log
the tools abort immediately, surface the daemon line(s) in the result
(e.g. "Error response from daemon: manifest for nginx:9.9.9 not
found: manifest unknown"), and skip the polling step. The BUILD_FAILED
polling guard (M-5) stays as a second safety net for late failures
where the stream was clean but the container exited after start.

No new MCP tool: the build log is a live stream and cannot be
re-fetched after the build ends, so it is surfaced during
redeploy_project / create_project rather than exposed as a standalone
get_project_build_log call.

Minor version bump because redeploy_project and create_project return
materially different strings on a failed build and exit earlier in
the failure path. Signatures unchanged.

Tests: streamed-log collection, daemon-error log, header ReadTimeout
marker, per-chunk ReadTimeout partial log, wall-clock budget
truncation, _parse_build_stream_log unit tests, redeploy/create end-
to-end behavior with a failing log.

Closes #2

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-05-18 13:58:55 +02:00
parent 18fe063691
commit 036429e9bf
8 changed files with 441 additions and 54 deletions
+42
View File
@@ -2,6 +2,48 @@
All notable changes to this project will be documented in this file.
## [0.6.0] - 2026-05-18
### Changed
**`build_stream` is no longer fire-and-forget (#2).** A live stream
capture confirmed that DSM emits a readable plaintext build log over
the HTTP body — one short status line per step — and closes the
connection when the build is done. The 0.2.5 implementation sent the
request and dropped the body unread, which meant a failed image pull
left users with nothing more than a `BUILD_FAILED` polling status and
no actionable diagnostic.
- `DsmClient.trigger_build_stream` now consumes the body line by line
and returns the collected log as a string instead of `None`. A wall-
clock budget of 210 s (`BUILD_STREAM_BUDGET`, kept under the Claude
Desktop ~4 min tool-call ceiling) caps the read; on timeout the
partial log is returned with a `[build_stream: timeout — stream
still open server-side]` marker appended so the caller knows the
build is still going server-side. Per-chunk `ReadTimeout` is treated
the same way — return what we have plus the marker.
- `redeploy_project` and `create_project` now parse the returned log
via `_parse_build_stream_log`, which classifies any line containing
`Error response from daemon:` or ending in ` Error` as a failure.
When the log contains errors the tools abort immediately, surface
the daemon line(s) in the result (e.g. `Error response from daemon:
manifest for nginx:9.9.9-nonexistent not found: manifest unknown`),
and skip the polling step entirely — DSM has already told us the
build is dead. The existing `BUILD_FAILED` / `ERROR` polling guard
(M-5) stays as a second safety net for late failures where the
stream log was clean but the container exited after start.
- No new MCP tool: the build log is a live stream and cannot be
re-fetched after the build ends, so it is surfaced during
`redeploy_project` / `create_project` rather than exposed as a
standalone `get_project_build_log` call.
JSON error envelope handling, transport-error mapping (M-4), and the
SID-scrubbed HTTP-error formatting are unchanged. Closes #2.
Minor version bump because `redeploy_project` and `create_project`
return materially different strings on a failed build and exit
earlier in the failure path; signatures unchanged.
## [0.5.1] - 2026-05-18
### Fixed