Repository navigation
[SDK-776] One set of words, and a way to read them - #25
Merged
Merged
Conversation
The terminal wizard carried its own wording for every moment the chat path already had a screen for. The sign-in step said "I never see your password — gcloud opens your browser and handles it" in a terminal and "You run it, your browser handles it" in a chat; neither was the other's source, and nothing noticed, because the test suite pinned which screens exist and never which words they use. So "look in bin/questions.sh to change what a developer reads" was false for half the people reading it. Two functions, in questions.sh where the screens are rather than in config.sh which the gates also source: q_render prints a question's words, and ask_question feeds its option labels to the menu and reports which came back. Split in two so that "the terminal prints what the chat is handed" can be asserted offline — tied to the menu it needs a pty, and a test that needs a pty to check a sentence is a test that ends up skipped, which is how this drifted. The wizard now renders the sign-in and remembered-target screens outright, and the device step takes its words from the screen while drawing its own menu: a chat picker is capped at four options with free text for the rest, and copying that cap into a terminal would have made a fourth device unreachable. q_sign_in's first option is relabelled "Sign in with gcloud". "Show me the command to run" was true in a chat and wrong in the terminal that hosts the command; what differs between the front ends moved into the option description, which a chat shows and a menu does not. Five moments still word themselves, each because the two paths reach them differently — the project and app menus draw from a discovered.json the wizard does not write, and bin/agent has no verb that deletes the local key, so a shared "delete it?" screen would have nothing behind its yes. The count is asserted, so a sixth has to be either a screen or a reason. Found while testing: ask_question set its output variables after question_for, so an unknown kind returned 2 with them unset and set -u killed the caller. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
"Where are the texts coming from?" had no answer you could act on. The words are in bin/questions.sh, but they are JSON assembled by shell functions with state in them, so seeing what a developer is actually shown meant running the agent and answering your way to each screen. `make screens` prints all seventeen of them, each headed by the file and line its words live on. Read it, change the line it names, run it again. Nothing is stored. A committed dump would be a second copy of the words to keep true, and once behind it is worse than no dump at all: it shows you text without telling you where to type. Same reason the list of screens is read out of question_for's own dispatch rather than written down here again. The fixtures are a stub toolchain, a sample discovery cache of five projects (five because at four the pickers start saying "N more not shown", which is one of the sentences worth reading), and a stub emulator, so the same command prints the same text to two people reading it together. tests/screens-resolve.sh guards the pointer rather than the prose — the wording is already checked against the JSON in agent-questions.sh. What it catches is the addresses going quiet: a screen the tool cannot place, a function dropped because its definition was reformatted, a dispatch the list can no longer read, and the fixtures breaking so it renders nothing at all. All four were checked by breaking them. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Answers the question this set of changes started from — "where are the texts for the prompts coming from?" — in the file a maintainer already reads, rather than in a new document. Four places hold nearly all of it, `make screens` prints the questions with their addresses, and a rewording is a one-place edit because both front ends now render the same objects. Two limits get written down because the text itself cannot tell you about them: a gate name is printed into a 34-column field, so a longer one shoves that row's verdict out of line while every other row stays put; and nothing printed may tell somebody to run a bare `bin/…` path, which does not resolve from the project the tool actually runs in. The first of those had nothing checking it, so the suite that checks the addresses now checks it too — renamed text-surface.sh, since it is no longer only about tools/screens. Both halves negative-tested: a name one character over fails, and so does a ladder declared some other way, which would otherwise pass by finding no names at all. Explicitly not a second contract. INTENDED-FLOW.md says what the path is; this says what the words currently are, and says so where a reader will see it — two documents claiming the flow is how the sixteen-versus-eighteen-gates disagreement got started. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
bin/wizard and bin/questions.sh both changed, and a host skips an update when the version string matches what it already has. 26.9.12-beta is what is on main, so without this the terminal front end would keep reading its old, separate set of words on every machine that already has the plugin. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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.
Summary
Makes onboarding language a reviewable surface with one shared set of questions for the
terminal wizard and coding-agent conversation.
Shared questions
q_renderandask_questioninbin/questions.shrender the same question objects thatthe coding-agent path receives. The wizard uses those objects for shared steps instead of
maintaining a second version of their wording.
Option labels and descriptions are presentation. Commands, consent records, option effects,
and state transitions remain behavior owned by the shell program.
Some terminal interactions still have their own presentation where the terminal and chat
have different data or capabilities.
tests/agent-questions.shcounts those exceptions soadding another requires an explicit decision.
Writer-facing Markdown
This PR introduces
copy/screens/and moves the opening screen intocopy/screens/opening.md.bin/screen-copy.shreads and validates the constrained Markdown format. Stable option IDsconnect labels, descriptions, and ordering in Markdown to commands and state changes in
bin/questions.sh; changing the words cannot silently attach an option to differentbehavior.
Only the opening screen has moved so far. Unmigrated question copy remains in
bin/questions.shand can move one screen at a time.Reviewing the copy
From the repository root:
make screens-help make screens make screens KIND=opening make screens KIND=pick_device make screens KIND="iterable_step 3"make screens-helplists every supported scenario and its source.make screensrendersthe shared onboarding questions as a developer sees them, with sample Firebase projects and
devices and a source location above each question.
The preview requires Node.js, but no network access, credentials, Firebase or Iterable
project, or connected device. It renders live from the Markdown and shell sources and does
not store a second generated copy.
make screenscovers shared questions and options, not every user-facing string. The sourcemap in
CONTRIBUTING.mdalso identifies gate verdicts, summaries, Iterable dashboardinstructions, and terminal- or agent-specific text.
Documentation structure
README.mdis now focused on installation, supported workflows, requirements, securityboundaries, limitations, and updates for installed users.
CONTRIBUTING.mdis the entry point for Docs and engineering contributors reviewinghuman-facing or model-facing content.
bin/README.mdis an engineering reference for the onboarding program's invariants,components, protocol, consent, gates, workspace, and tests.
INTENDED-FLOW.mdremains the authoritative contract for the onboarding sequence.The security language now describes what this repository controls without making guarantees
about a coding-assistant provider or claiming that authenticated API requests never leave
the machine.
Validation
Coverage includes:
tests/agent-questions.shfor parity between chat and terminal questions.tests/text-surface.shfor scenario discovery, source locations, Markdown structure,stable option IDs, placeholders, and gate-name display limits.
tests/no-bare-commands.shfor commands that resolve from an installed user's project.tests/plugin-manifests.shfor synchronized plugin delivery versions.Local result:
GitHub's
shellandvalidatechecks pass.Delivery
The Claude and Cursor manifests are synchronized at
26.10.0-beta. The plugin versionchanges because installed clients skip an update when their installed version matches the
manifest, and this PR changes files delivered with the plugin.