Skip to content

Offer Setup on the first Run from a terminal - #162

Merged
JacobStephens2 merged 3 commits into
mainfrom
issue-131
Sep 30, 2026
Merged

JacobStephens2 merged 3 commits into
mainfrom
issue-131

Conversation

@JacobStephens2

Copy link
Copy Markdown
Owner

Summary

The first Run from a terminal with no User config offers Setup before any work.

 main
   args::parse                      # bad command → exit 2, no offer
+  config::offer_setup              # terminal (stdin + stderr) and no User config only
+    "No User config at <path>. Set your defaults now? [Y/n]"   (stderr)
+    yes → Setup questions → write answers (test email, if asked)
+    no  → write the all-defaults User config, say `thirdshift setup` changes it
+    write fails → `warning:` line, carry on with the defaults
+    Ctrl-C → SIGINT kills it before interrupt::install: no file, no work, no Run notification
   UserConfig::load                 # picks up what was just written
   flags (--no-merge, --email, --no-email) still win over the config
   interrupt::install, Run notification, run::run …

setup and the offer share answered (ask + apply) and write_new. help, version, update, email-test and setup return before the offer. The README's User config section describes the offer and the no-terminal behavior, and says update, version and help never offer Setup.

Evidence

  • Before: cargo test --test setup_offer → 7 of 10 failed (the terminal never showed "Set your defaults now? [Y/n]").
    After: all 11 pass, and so does the full cargo test (23 test binaries).

New PTY tests in tests/setup_offer.rs:

first Run from a terminal          → offer on stderr before the first progress line
accept, merge.always = y           → that Run is a Merge run (PR MERGED)
accept + --no-merge                → ready for review, file still says always = true
accept notifications + --no-email  → no Run notification sent
decline                            → file == `thirdshift setup </dev/null`; a second Run doesn't offer
bad command                        → exit 2, no offer, no file
no terminal                        → no offer, no file, today's outcome
~/.thirdshift read-only            → `thirdshift: warning: …`, Run completes on the defaults
Ctrl-C at the offer (with --email) → no file, no claude/gh calls, no email
Ctrl-C in the questions            → no file, no work
help / version / update / email-test → never offer

Merge Danger

Door: two-way

Revert and it's gone. The only thing left behind is a User config written by a user who answered the offer, and that's the same file thirdshift setup writes.

Blast Radius: interactive-runs

This only changes Runs started from a terminal on a machine with no ~/.thirdshift/config.toml, where it adds one question. Unattended Runs (cron, CI, agents' shells) are unchanged. Stdout still holds only the PR URL.

Unaddressed findings

Standards

  • Duplicated tail in setup and offer_setup (the "wrote the User config" message, test email after write): the two handle errors oppositely (setup fails, the offer only warns). A shared helper would need an error-policy parameter, which costs more than the few lines it would save.
  • offer_setup prints instead of returning its message (codebase-design "return results"): the offer prints mid-Run and then the Run carries on. There's no single outcome for main to print, as there is for setup.
  • questions::offer is a Middle Man over yes_or_no: it's kept on purpose so all prompt wording lives in questions, and yes_or_no stays private.

Spec

  • README also says email-test never offers Setup: that's accurate and Setup: the first Run offers Setup #131 lists it. The spec's wording didn't include it.
  • A failed test email during the offer is a warning:, not an error: the spec says Setup can't stop a Run, so the offer applies the same rule it uses for a failed write.
  • Answers are dropped, not applied in memory, when the User config can't be written: this follows the spec ("the Run carries on with the defaults"), and the warning says so.
  • With HOME unset, the error now comes from offer_setup rather than UserConfig::load: the message and exit code 1 are the same, and it still happens before any work.
  • A failed write can leave an empty ~/.thirdshift: this is cosmetic. The offer checks for the file, so it comes back next time.

Closes #131

🤖 Generated with Claude Code

JacobStephens2 and others added 3 commits September 30, 2026 00:12
Closes #131

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… Ctrl-C with --email

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@JacobStephens2
JacobStephens2 merged commit d0fcb23 into main Sep 30, 2026
13 checks passed
@JacobStephens2
JacobStephens2 deleted the issue-131 branch September 30, 2026 00:33
@JacobStephens2 JacobStephens2 mentioned this pull request Sep 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Setup: the first Run offers Setup

1 participant