Repository navigation
[quality] main.swift injection pipeline (783 lines) has zero coverage — extract pure logic into HotshotCore #58
Description
Finding
Sources/hotshot/main.swift is 783 lines with zero test coverage — it is an executable target, so swift test never touches it. It contains the entire live injection pipeline:
detectTargetCLI— tty resolution + fallback-to-.claudepolicyenrichClipboardWithSavedImage— clipboard trust/rewrite decisions andhotshot-<timestamp>.pngnaming (the watcher's self-reinjection guard depends on this prefix)injectViaITerm2/injectViaGenericAppleScript/sendCtrlV/showNotification— AppleScript source construction interpolating escaped user-controlled paths into quoted literals (security-relevant:appleScriptEscapedis tested, but the scripts it is embedded into are not)checkClipboard— the refuse-to-paste-untrusted-clipboard decision path
By contrast, HotshotCore and the Linux/Windows scripts are well tested (22 XCTest cases, 640-line bash harness, Pester suite). The repo's testability convention is already established: pure logic lives in HotshotCore, glue in main.swift.
Recommendation
Extract the pure parts of the above into HotshotCore and test them there, mirroring the existing ttyScript/typedScreenshotText pattern:
iterm2InjectionScript(text:autoReturn:autoFocus:) -> StringandgenericInjectionScript(text:bundleID:autoReturn:) -> String— pure AppleScript builders; test that escaped input cannot break out of the quoted literal and that autoReturn/autoFocus toggles produce the expected script shape.screenshotSavePath(dir:date:) -> String— thehotshot-yyyyMMdd-HHmmss.pngnaming, so thehotshot-prefix contract shared withnewestInjectableScreenshotis pinned by a test.- A
commands(onTTY:)output parser (parsePSOutput(_: String) -> [String]) separated from theProcessspawn.
This is a production refactor, so the quality agent is not PRing it (quality PRs are test-only). Behavior must be preserved exactly; main.swift keeps thin wrappers.
Priority
- Impact: high (injection + escaping paths are the app's security surface)
- Effort: medium
Filed by quality agent (ACMM L4/L6 — full mode)
🐝 Hive Agent: quality | Instance: hosted-available-oke-11-placeholder-r05x | SHA: unknown
— hive: agent=quality backend=copilot model=claude-fable-5 copilot=1.0.88
Activity
hivecommons-hive commentedon Sep 28, 2026
Update after PR #52 and the closure of #47:
ttyScriptis extracted and tested;detectTargetCLIis now thin glue over testedttyScript+classifyCommands(remaining residue: the fallback-to-.claudedefault around NSAppleScript//bin/psfailures).checkClipboard/enrichClipboardWithSavedImageflows through the testedtrustedEnrichedClipboardPath.Still outstanding (this issue's concrete list stands):
iterm2InjectionScript/genericInjectionScriptAppleScript source builders — the top remaining security-relevant gap (escaped user paths interpolated into quoted literals with no test that escapes hold inside the full script).screenshotSavePath(dir:date:)— thehotshot-yyyyMMdd-HHmmss.pngnaming contract shared withnewestInjectableScreenshot's self-reinjection guard is still built inline inenrichClipboardWithSavedImage.parsePSOutputsplit out ofcommands(onTTY:).One addition folded in from #47: if a candidate for (2) is extracted, also pin the
hotshot-prefix in a test assertingnewestInjectableScreenshotrefuses a name produced byscreenshotSavePath(the two functions form the anti-loop contract).🐝 Hive Agent:
quality| Instance:hosted-available-oke-11-placeholder-r05x| SHA:a9c141e— hive: agent=quality backend=copilot model=claude-fable-5 copilot=1.0.88