feat(bin): add fm-relaunch.sh for on-demand session resume#894
Open
imemdev wants to merge 3 commits into
Open
Conversation
…trigger Registers a launchd LaunchAgent with no RunAtLoad/StartInterval/ StartCalendarInterval/watch-path key, so the job can only fire via an explicit launchctl call, never on its own. install/status/uninstall/run manage the job; run kickstarts it, which opens claude in a terminal and drives the trust-dialog and first-message handshake needed to actually trigger session-start. Supersedes the ad hoc dev.firstmate.relaunch prototype on the captain's machine by reusing its label.
…id AppleScript quoting injection
imemdev
force-pushed
the
fm/fm-relaunch-tool
branch
from
July 23, 2026 10:48
16e7c0f to
a573c1e
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Intent
Developer (acting as an autonomous crewmate managed by "firstmate") tasked the agent with converting a hand-built prototype (a launchd LaunchAgent plist plus a payload script that opens Terminal running
claude) into a proper, tracked repo tool:bin/fm-relaunch.shwith install/run/status/uninstall subcommands. The core requirement was safety: the generated launchd job must never self-trigger (no RunAtLoad, StartInterval, StartCalendarInterval, or watch-path keys) and can only fire via explicitlaunchctl kickstart/start, since the captain explicitly did not want an unattended auto-starting session. Requirements included idempotent install, macOS-only support with clear failure elsewhere, a colocated test file mocking system commands (launchctl/osascript/uname/id) that specifically asserts the forbidden auto-trigger keys are absent, documentation indocs/relaunch-tool.mdper the "one-owner rule" (avoiding duplicating narrative in the script header or AGENTS.md), and cleanly superseding the existing same-named LaunchAgent without leaving conflicting duplicate jobs. The developer also required the work go through theno-mistakesvalidation pipeline (review, test, lint, document, push, PR) before completion, explicitly avoiding--yesso ask-user decisions remain with the human, and directed the agent to escalate rather than fix infrastructure blockers (spend limits, push permission errors) itself. A real security finding (AppleScript injection via unescaped$quoted_cdin the osascript call) was caught and fixed during the pipeline's review step. The developer (captain) ultimately resolved a GitHub push-permission blocker by forking and pushing manually, opening PR #894.What Changed
bin/fm-relaunch.shwith install/run/status/uninstall subcommands, generating a launchd LaunchAgent that opens Terminal runningclaude— the plist deliberately omits RunAtLoad, StartInterval, StartCalendarInterval, and watch-path keys so the job only fires via explicitlaunchctl kickstart/start, macOS-only with a clear failure message elsewhere.FM_HOMEtoosascriptas an argv parameter instead of interpolating it into the quoted script string.tests/fm-relaunch.test.sh, mockinglaunchctl/osascript/uname/idto cover install idempotency, safety-key absence, and subcommand behavior.docs/relaunch-tool.mdand add a row for it indocs/scripts.md.Risk Assessment
✅ Low: Small self-contained script+tests+docs; core safety invariant (no launchd auto-trigger keys) verified present and tested; prior AppleScript injection already fixed via argv passing.
Testing
Ran the colocated mocked test suite (all 13 assertions pass, including the no-auto-trigger-key assertion) and additionally did a real, non-mocked install/status/uninstall cycle against actual launchctl/launchd on this macOS machine to confirm the generated LaunchAgent plist truly has no RunAtLoad/StartInterval/StartCalendarInterval/WatchPaths/QueueDirectories/KeepAlive keys and cleanly unloads; did not fire cmd_fire for real since that opens a live Terminal window/osascript trust dialog, which the mocked test already exercises safely.
Evidence: manual install output
Evidence: manual status output
Evidence: generated plist (real launchd install)
Evidence: manual uninstall output
Pipeline
Updates from git push no-mistakes
✅ **intent** - passed
✅ No issues found.
✅ **Rebase** - passed
✅ No issues found.
✅ **Review** - passed
✅ No issues found.
✅ **Test** - passed
✅ No issues found.
bash tests/fm-relaunch.test.sh (13 mocked subcommand/safety tests, all ok)manual: FM_ROOT_OVERRIDE=<tmp> bin/fm-relaunch.sh install/status/uninstall against real launchctl on this Mac, inspected generated plist in ~/Library/LaunchAgents for absence of auto-trigger keys✅ **Document** - passed
✅ No issues found.
✅ **Lint** - passed
✅ No issues found.
✅ **Push** - passed
✅ No issues found.