Onboarding language and flow fixes from first user-onboarding feedback - #771
Conversation
The prompt promised "last N days" from the retention window, but each client keeps far less on disk (Claude prunes after ~30 days), so a 90-day team install read as a promise the import could not keep. Say "already on this machine (up to N days)" instead.
The org-config converge after login can block a full minute and the backfill import runs multi-second with no output; both showed a static line that read as a hang (first onboarding feedback, 8/12). On a TTY the announce line now animates in place with elapsed seconds and clears when the wait settles; off a TTY (and under HYP_NO_TUI=1) output is byte-identical to before.
A detected needs_setup row seeded the defaults, so the express gate and pick gate said "record all of these" with Claude Desktop in the list - and the configure phase then asked again with a consent screen defaulting to no, the wizard contradicting itself (first onboarding feedback, 8/12). Detection still labels the row detected; checking it is now the deliberate opt-in its consent gate expects. Config- and selection-seeded rows are a user's recorded answer and still check.
The closing sequence said "to send it sooner, run hyp sync..." and then immediately asked "send now or wait?" with a row carrying the same command and the same asks-first promise - two blocks saying one thing, in the stretch of setup that already reads as a wall of text (first onboarding feedback, 8/12). The narration now drops that sentence exactly when the offer follows; aborts, dry runs, and a close that cannot prompt keep it, with the cannot-prompt skip stating it as a line instead of a question.
…ater A config that already composes Claude Desktop re-seeds it on every reconfigure, so the gate said "record and sync all of these" over a row whose configure phase then asks its own consent question with a default of no. The gate keeps the row (it is a recorded answer) but now says "needs extra setup" on it, so the later screen is announced rather than a contradiction. Locked rows keep the fleet suffix alone.
The confirm lands at the end of an attended run, after every question was answered, and a bare enter aborted the whole walk with exit 1 - the happy path's last keystroke threw its answers away. Enter now completes the run; only an explicit no declines. Safe as a yes because the file is backed up before the rewrite either way.
The install opened with two paragraphs of credential-helper mechanism and a y/N defaulting to "leave Claude Desktop alone" - jarring right after the user chose to record it. The explanation now leads with the decision (Claude Desktop needs extra setup, here is why and what will change), and the single question after it defaults to yes: the picker row is never pre-checked, so a user at this prompt chose to be here, and the plist write still cannot happen without the sudo password. The question survives (an earlier cut removed it) because a yes on a signed-out machine immediately launches the Claude OAuth flow in a browser, and that launch must never be a surprise: the prompt names it when that is what enter does next. Non-answers still decline with the --yes / --print-commands hint and EOF cannot hang. Asked for a new pick only: the wizard's configure phase skips a needs_setup row the existing config already composed, so reconfiguring an unrelated setting never re-opens Desktop setup. The standalone command stays the finish and repair path. LLP 0139 amended in place.
The question's sign-in clause was sharpened by running `claude-account status` as a predicate. Sub-commands share the dispatcher's stdout, so that probe printed `mode: subscription` and `signed in: no (run 'hyp claude-account login')` between the disclosure and the question - a diagnostic in the middle of a consent screen, telling the user to run a command the flow was about to run for them. Tests could not see it: the fixture's `commands.run` writes nothing. The clause is now conditioned on the reader's state rather than probed, and true either way; `org_key` mode still drops it, being the one case config alone settles. Two assertions pin it: the status probe belongs to the login step and is called once, and a decline runs nothing at all. Also in the same screen: the undo instruction pointed at the credential helper, which is not what attaches Claude Desktop. Removing the helper leaves Desktop pointed at the local gateway with nothing to answer it. It names the managed plist now. Two claims that were not true: `hyp status` has no line for an incomplete `needs_setup` row, so the configure-phase skip has no standing pointer at its repair path (recorded as a known gap, in the comment and the doc, rather than asserted as covered); and the sync offer's "same polarity as the overwrite confirm" no longer holds, since that confirm flipped to yes in this branch. Finally, the amended `#default-no` block opened its blockquote after an inline anchor on the same line, so it did not render as one. Co-Authored-By: Claude <noreply@anthropic.com>
|
Verdict: findings. Seven actionable items; six fixed and pushed as Fixed (commit
|
…h it The privacy narration now drops its `hyp sync` sentence whenever the closing sync offer is about to render, on the reasoning that the offer's "Send now" row states the same command. But that offer is a TUI select with `clearOnResolve`, so its frame is erased the moment it resolves - and waiting is the default answer, reached by a bare enter or an esc. On the ordinary attended enrolled close the run therefore ended with the release verb nowhere on screen: the narration had dropped it and the only other sighting had been wiped. The wait now writes the same still-held line the sync-declined and spawn-failed paths already write, which names the deadline and `hyp sync`. Dropping the sentence upstream stays right; it is only safe because the wait restates it after the choice instead of before it. Also: LLP 0139's new amendment claimed "only a real enter is a yes", which the prompt it describes does not do - anything that is not `n` or `no` takes the default. Says what the code does instead. Co-Authored-By: Claude <noreply@anthropic.com>
|
Verdict: findings. Round 2 of 2. One new actionable item, found and fixed ( New this round1. A declined first sync ends the run with
|
|
neutral triage: stuck. The review fix-loop hit its 2-round cap with findings still open. Triage re-verified both rounds and finds one of the two residuals is a hole this PR itself widens, so the triage marker is withheld and the PR is parked for a maintainer decision. What neutral was doingTriage of PR #771 at head Blocker: a declined or failed Desktop setup is now permanently stranded, and this PR is what makes it permanent
The decisive fact, determined from git history rather than taken from the review records:
Net effect at this head: tick Claude Desktop in Triage did not fix it for the same reason both review rounds did not: every remedy widens a contract (wizard/picker or core status) that is yours to change, not neutral's. Decision needed, with optionsAny one of these unblocks the PR:
Also open, not a blocker: LLP 0139 amended in place
Verified resolved at e1ad58e, no action needed
How to unstickReply on this PR with the option you pick, or push to the branch. neutral monitors the thread and re-engages next tick. Options 1 and 2 can be neutral-implemented once authorized; option 3 needs only your reply. |
…orrected and pinned The review flagged two leftovers. First, the branch amended Accepted LLP 0139 in place with bare dated blocks, against the corpus rule that change mints a new numbered doc: LLP 0224 now carries the decisions (deliberate tick, decision-led disclosure, one question defaulting to yes, ask once per pick, and the repair surface), and 0139's blocks are Amended-by/Superseded-by pointers to it. Second, the recorded claim that no core surface points at an incomplete Desktop setup was overstated: hyp status already warns via client_attach_missing, whose repair names the row's configure_command (0139 #repair-must-be-runnable) - the string is assembled in the daemon collector, which is why grepping core missed it. The configure phase comment now states the surface instead of a gap, and a new status-collector test pins the diagnostic and its repair string so the claim the skip rests on cannot silently rot. Known follow-up recorded in 0224: claude-desktop has no attach probe, so the warning clears via the reconciler rather than by observing the plist.
|
Thanks for the pass, the consent-screen stdout leak especially. Both leftovers are handled in 2d3ad70: LLP process. Minted LLP 0224 (desktop setup second pass: deliberate tick, decision-led disclosure, one question defaulting to yes, ask once per pick, repair surface). 0139's two dated blocks are now standard The incomplete-setup hole. Pushing back on finding 3: the surface exists. One real residue, recorded in 0224 rather than fixed here: claude-desktop declares no attach probe, so its client reports unattached unconditionally and the warning clears via the reconciler's attach action, not by observing the plist. A plist-reading attach probe is the named follow-up. |
|
Re-engaging with your guidance - taking the The stuck label is removed. Neutral re-runs the review rung at the current head ( |
|
neutral triage: pass at The previous blocker call was wrong, and platypii's pushback was rightThe stuck report claimed no core surface points at an incomplete Desktop setup, evidenced by a tree-wide grep for the literal string What triage independently verified at this head
Deferred to #772, not blockingThe residue platypii recorded in 0224 is real but acceptable: claude-desktop declares no attach probe, so the client reports unattached unconditionally. That makes the warning correct for the declined state and a standing false positive on a machine whose setup finished. Triage confirmed this facet is pre-existing master behaviour, unchanged by this PR, and documented with the fix named (a plist-reading attach probe). One clarification for the record: with no probe, the collector cannot observe attachment at all, so nothing clears the warning by observation today; the probe follow-up is what makes it clearable. Tracked in #772 along with two minor pre-existing notes from the review rounds. |
Conflict: src/core/cli/walkthrough.js, defaultOverwriteConfirmFactory's return expression. #771 flipped the confirm's default to yes ("only an explicit no declines"); this branch routes the prompt through queuedLineAsker so EOF settles as `null` instead of hanging. Both intents compose: the null is coalesced to the empty line and read by #771's parse, so a spent stdin takes the yes the printed [Y/n] promises and the config is regenerated over the backup the caller already takes. The EOF regression test's two overwrite cases follow the default they assert: EOF now returns true and the prompt reads [Y/n]. Its third case now scripts an explicit `n` rather than a `y`, since after the flip only the decline distinguishes an answered prompt from a defaulted one.
Fixes from the 8/12 onboarding session (first outside user walking
hyp initon a screen share), plus follow-ups from re-running the flow on a configured machine.What changed
needs_setuprow seeded the defaults, so "record all of these" opted users into a setup flow that then re-negotiated. Detection still labels the row; checking it is the deliberate opt-in.needs_setuprow ("· needs extra setup") when a config already composes it, so the later setup step is announced rather than a contradiction.hyp syncsentence.needs_setuprow the existing config already composed, so reconfiguring an unrelated setting never re-opens Desktop setup. LLP 0139 amended in place.Testing
Full suite (4039) and typecheck clean on every commit.