Add background-safe reads, split layouts, and media metadata#17
Conversation
Background-safe reads must fail cleanly instead of activating KakaoTalk, opening rooms, or leaking available chat titles. The read JSON now also carries media/link/attachment metadata so operations can queue image-bearing messages without storing raw image content. Constraint: AX-based Kakao reads can only inspect exposed UI safely without stealing focus Rejected: Frequent idle polling wrapper | still risks user disruption and lives outside the CLI contract Rejected: Raw image capture in read JSON | would expand private data exposure beyond message metadata Confidence: medium Scope-risk: moderate Directive: Do not make background-safe paths call activate, launch, login, search, resize, or close windows without revalidating operator impact Tested: swift build Tested: python3 -m unittest discover -s tests Tested: kmsg read __codex_no_such_chat__ --background-safe exits with BACKGROUND_SAFE_BLOCKED and hides window titles
Marketing operators need to keep KakaoTalk beside browsers and ad tools without the CLI resizing into a large operator-only window. The read command now supports split-left and split-right layouts, MCP accepts the same values, and the entrypoint follows the installed executable name so local operations can install the patched build as kangyu instead of replacing kmsg. Constraint: Local automation should not overwrite the existing kmsg command when the operator asks for a separate kangyu command Rejected: Symlink kangyu to a kmsg-named binary only | help and examples would still instruct users to run kmsg Confidence: high Scope-risk: narrow Directive: Keep background-safe behavior non-mutating; split layouts are for explicit layout requests only Tested: swift build Tested: python3 -m unittest discover -s tests Tested: /Users/yu/.local/bin/kangyu --help shows kangyu and read --layout split-left/split-right Tested: /Users/yu/.local/bin/kangyu read __codex_no_such_chat__ --background-safe --limit 1 --json exits with BACKGROUND_SAFE_BLOCKED
Madstamp runs the patched upstream kmsg build as a separate kangyu executable and a kmsg.kangyu MCP server ID until the upstream PR lands. Documenting the source-of-truth repo URLs prevents operators from replacing the canonical kmsg binary or guessing which fork owns the deployment patch.\n\nConstraint: Upstream official repository remains channprj/kmsg\nConstraint: Local Madstamp Hermes profile should not overwrite /Users/yu/.local/bin/kmsg\nRejected: Rename the upstream project to KangYu | would confuse upstream PR review and public package identity\nConfidence: high\nScope-risk: narrow\nDirective: Keep MCP server ID kmsg.kangyu for Madstamp profile while command points to /Users/yu/.local/bin/kangyu\nTested: python3 -m unittest discover -s tests\nTested: hermes --profile madstamp mcp list shows kmsg.kangyu enabled\nNot-tested: Upstream maintainer acceptance of the deployment naming note
The CLI supported --background-safe, but MCP clients could not request it, so Hermes would still have to choose between normal read and split layout behavior. Add a background_safe tool argument, pass it to read, and avoid automatic deep-recovery retry in that mode so a blocked background-safe read remains non-disruptive.\n\nConstraint: Background-safe MCP reads must not fall through into window-opening recovery behavior\nRejected: Rely on split-right default layout only | still permits operator-visible UI movement and misses the user's background-read requirement\nConfidence: high\nScope-risk: narrow\nDirective: Keep background_safe available on kmsg_read whenever --background-safe exists on the CLI\nTested: swift build\nTested: python3 -m unittest discover -s tests\nNot-tested: Live KakaoTalk MCP read of a real exposed chat window
MCP initialize was still running a Kakao status probe during startup, so an AX or app-state stall could block Hermes before tools/list was available. Startup now verifies the executable version and skips status by default, while retaining an opt-in KMSG_MCP_STARTUP_STATUS_CHECK gate for manual diagnostics.\n\nConstraint: MCP clients need initialize/tools-list to return even when KakaoTalk UI readiness is unstable\nRejected: Increase the status timeout | it preserves the blocking failure mode\nConfidence: high\nScope-risk: narrow\nDirective: Do not make MCP initialize depend on foreground KakaoTalk UI state by default\nTested: swift build\nTested: python3 -m unittest discover -s tests\nNot-tested: KMSG_MCP_STARTUP_STATUS_CHECK=true on a healthy live KakaoTalk session
44bafcb to
c43fa11
Compare
|
@MadKangYu Is it still in draft status? Please let me know if it is ready for review. Thank you. |
There was a problem hiding this comment.
Pull request overview
This PR adds a non-disruptive “background-safe” read path (CLI + MCP) for reading only already-exposed KakaoTalk chat windows, plus new split-window read layouts and richer per-message media/link metadata in JSON output. It fits the project’s accessibility-driven architecture by introducing an explicit interaction mode to prevent focus/activation/resizing paths when requested.
Changes:
- Add
read --background-safeand propagate the same behavior through MCP (background_safe), including skipping MCP startup status checks unless explicitly enabled. - Introduce
split-left/split-rightlayout modes in window resolution logic and expose them via CLI/MCP. - Emit message-level metadata fields in read JSON (
has_image,image_count,link_count,has_attachment,attachment_count) and add Python unittest contract coverage.
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/test_read_background_safe_contract.py | Adds contract tests asserting the presence of background-safe mode, split layouts, and media metadata surfaces. |
| Sources/kmsg/kmsg.swift | Uses invoked executable name for top-level CLI help/examples to support aliases (e.g. kangyu). |
| Sources/kmsg/Commands/ReadCommand.swift | Adds --background-safe, layout help updates, and hides window titles on background-safe failures. |
| Sources/kmsg/Commands/MCPServerCommand.swift | Adds background_safe argument, split layout enums, and skips status check by default via env flag. |
| Sources/kmsg/KakaoTalk/ChatWindowResolver.swift | Adds interaction mode guardrails and split-left/right frame calculation. |
| Sources/kmsg/KakaoTalk/MessageContextResolver.swift | Skips activation/focus fallback when in background-safe mode. |
| Sources/kmsg/KakaoTalk/TranscriptReader.swift | Adds per-message media/link/attachment metadata and passes interaction mode through transcript context resolution. |
| README.md | Documents new flags/layouts/JSON fields and the Madstamp/KangYu deployment convention. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| discussion: """ | ||
| Use either: | ||
| kmsg read <chat> | ||
| kmsg read --chat-id <chat-id> | ||
|
|
||
| Use --background-safe to read only already exposed chat windows without launching, | ||
| activating, logging in, searching, opening rows, resizing, or closing windows. | ||
|
|
| private func splitLayoutFrame(in usableFrame: CGRect) -> CGRect { | ||
| let halfWidth = floor(usableFrame.width / 2) | ||
| let width = min( | ||
| max(halfWidth, min(Self.minimumSplitWindowSize.width, usableFrame.width)), | ||
| usableFrame.width | ||
| ) | ||
| let height = min( | ||
| max(Self.minimumSplitWindowSize.height, usableFrame.height), | ||
| usableFrame.height | ||
| ) | ||
| let x = layoutMode.isRightAligned ? usableFrame.maxX - width : usableFrame.minX | ||
| return CGRect(origin: CGPoint(x: x, y: usableFrame.minY), size: CGSize(width: width, height: height)) | ||
| } |
| let imageCount: Int | ||
| let linkCount: Int | ||
| let attachmentCount: Int |
|
Thank you for your pr! I'll merge and fix some minor issues my own. |
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
Summary
read --background-safeto read only already exposed matching chat windows without launching, activating, logging in, searching, resizing, opening, or closing windowskmsg_read.background_safeKMSG_MCP_STARTUP_STATUS_CHECK=trueis explicitly sethas_image,image_count,link_count,has_attachment, andattachment_countfields in read JSONsplit-leftandsplit-rightread layouts for marketing operators who keep KakaoTalk beside browsers or ad toolskangyuinstead of replacingkmsghttps://github.com/channprj/kmsg; KangYu/Madstamp uses MCP server IDkmsg.kangyuwith command/Users/yu/.local/bin/kangyuuntil this patch lands upstreamDeployment identity
kmsg.kangyu/Users/yu/.local/bin/kangyusplit-rightVerification
swift buildswift build -c releasepython3 -m unittest discover -s tests/Users/yu/.local/bin/kangyu --helpshowskangyuin usage/examples/Users/yu/.local/bin/kangyu read --helplistssplit-leftandsplit-rightlayoutsinitialize+tools/listreturnskmsg_read.background_safe, startupstatus_check=skipped, and Hermes env layout defaultsplit-righthermes --profile madstamp mcp listshowskmsg.kangyuenabled with/Users/yu/.local/bin/kangyuNotes
split-left/split-rightare explicit layout requests.--background-safestill preserves existing window focus, size, and position.