fix(session-inbox-monitor): UTF-8 OutputEncoding forward-guard in SessionStart hook (v0.2.2)

Closes session-inbox-monitor-encoding-guard-followup (finding from -review
structural audit item E, CONCERN).

inbox-monitor.ps1 emitted ConvertTo-Json (incl. the interpolated inbox path)
to a redirected pipe under WinPS 5.1 without setting [Console]::OutputEncoding
— the same context that mojibaked stop-dispatcher. ASCII-safe today, but the
inbox path is user-data, so a non-ASCII path/content would mangle the inject.

- Add [Console]::OutputEncoding + $OutputEncoding = UTF8 after the $ProjectDir
  gate (mirror of stop-dispatcher.ps1). Comment text kept pure ASCII.
- Regression under WinPS 5.1: parse 0 errors; ran hook against a Cyrillic-path
  project, read raw stdout bytes as no-BOM UTF-8 -> JSON valid, Cyrillic path
  round-trips intact.
- Re-deployed to ~/.claude/hooks/inbox-monitor.ps1, SHA256 byte-identical.
- SKILL.md Mojibake failure-mode extended; version 0.2.1 -> 0.2.2 (PATCH).

install/hermes/dist not rebuilt — PATCH needs only reload-plugins; the runtime
hook is deployed.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-17 12:05:15 +03:00
parent c5f983a2a2
commit 8205f5d758
3 changed files with 21 additions and 8 deletions

View File

@@ -1,6 +1,6 @@
---
name: session-inbox-monitor
version: 0.2.1
version: 0.2.2
description: >
Raises a persistent Monitor (Monitor tool, NOT background Bash) on the
project's `.claude-inbox/` at the start of an interactive session, so
@@ -113,7 +113,11 @@ for free on session end. Headless sessions skip it and rely on the pull-model
`[IO.File]::WriteAllText($p,$t,[Text.UTF8Encoding]::new($false))`, NOT
`Set-Content`/`Out-File -Encoding utf8` (which adds a BOM under 5.1). Same
WinPS-5.1 encoding class as the hook-source em-dash gotcha. Fixed + in-situ
verified 2026-06-17.
verified 2026-06-17. The SessionStart injector (`inbox-monitor.ps1`) carries
the **same `[Console]::OutputEncoding` UTF-8 guard** as a forward-protection
(v0.2.2): it interpolates the inbox path into the injected JSON, so a non-ASCII
path or `additionalContext` would otherwise mangle the same way — the guard is
preventive (today's `$ctx` is ASCII) but cheaper than an "ASCII-only" invariant.
## Side effects

View File

@@ -30,6 +30,14 @@ param(
if (-not $ProjectDir) { exit 0 }
# UTF-8 stdout guard. This hook emits JSON (additionalContext) to a redirected
# pipe under WinPS 5.1 - the same context that mojibaked stop-dispatcher output
# (see session-inbox-monitor-stophook-utf8-fix). $ctx is ASCII today, but the
# inbox path ($inboxFwd) is user-data interpolated into stdout, so set UTF-8 as a
# forward-guard: a non-ASCII path or content never mangles the inject. Idempotent.
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
$OutputEncoding = [System.Text.Encoding]::UTF8
$inbox = Join-Path $ProjectDir '.claude-inbox'
$claudeMd = Join-Path $ProjectDir 'CLAUDE.md'