Skip to content

[quality] main.swift injection pipeline (783 lines) has zero coverage — extract pure logic into HotshotCore #58

Closed

Description

@hivecommons-hive

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-.claude policy
  • enrichClipboardWithSavedImage — clipboard trust/rewrite decisions and hotshot-<timestamp>.png naming (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: appleScriptEscaped is 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:

  1. iterm2InjectionScript(text:autoReturn:autoFocus:) -> String and genericInjectionScript(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.
  2. screenshotSavePath(dir:date:) -> String — the hotshot-yyyyMMdd-HHmmss.png naming, so the hotshot- prefix contract shared with newestInjectableScreenshot is pinned by a test.
  3. A commands(onTTY:) output parser (parsePSOutput(_: String) -> [String]) separated from the Process spawn.

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

  1. added
    help wantedDenotes an issue that needs help from a contributor. Must meet "help wanted" guidelines.
    on Sep 28, 2026
  2. hivecommons-hive commented on Sep 28, 2026

    @hivecommons-hive
    ContributorAuthor

    Update after PR #52 and the closure of #47:

    • ttyScript is extracted and tested; detectTargetCLI is now thin glue over tested ttyScript + classifyCommands (remaining residue: the fallback-to-.claude default around NSAppleScript//bin/ps failures).
    • The trust decision in checkClipboard/enrichClipboardWithSavedImage flows through the tested trustedEnrichedClipboardPath.

    Still outstanding (this issue's concrete list stands):

    1. iterm2InjectionScript/genericInjectionScript AppleScript 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).
    2. screenshotSavePath(dir:date:) — the hotshot-yyyyMMdd-HHmmss.png naming contract shared with newestInjectableScreenshot's self-reinjection guard is still built inline in enrichClipboardWithSavedImage.
    3. parsePSOutput split out of commands(onTTY:).

    One addition folded in from #47: if a candidate for (2) is extracted, also pin the hotshot- prefix in a test asserting newestInjectableScreenshot refuses a name produced by screenshotSavePath (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

  3. added
    🐝 covered by PRHive verified that an open PR references or claims this issue; still actionable until confirmed
    on Sep 29, 2026
  4. added
    hive/likely-doneHive verified that a merged PR references or claims this issue; pending confirmation
    and removed
    🐝 covered by PRHive verified that an open PR references or claims this issue; still actionable until confirmed
    on Sep 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    agent/qualityCreated by Hive for agent-filed issue provenancehelp wantedDenotes an issue that needs help from a contributor. Must meet "help wanted" guidelines.hive/likely-doneHive verified that a merged PR references or claims this issue; pending confirmationqualityCreated by Hive for agent-filed issue provenancetestingCreated by Hive for agent-filed issue provenance

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions