---
status: in-force
summary: "Set up like last time" — the machine's last install roams as state on the toolkit root's own config host; a fresh bootstrap offers it, and applies it unasked only when the root's Always Set Up Like Last Time toggle says so.
since: unreleased 2026-08-22 (landed with the first-run welcome; root host now ships in the bootstrap)
---
What it is. When a project saves, the toolkit root's config host
(canonical FNS) writes one extra state entry into the roaming config:
"FNS": { "state": { "last_install": {
"packages": ["AutoRes", "FNS_Toolbar", "..."],
"project": "MyShow.toe",
"when": "2026-08-22T21:10:03",
"bind": "embedded"
}}}Dropping the bootstrap into a new project then opens the first-run
welcome with a first card, Set up like last time — "12 tools, as in
MyShow.toe on 2026-08-22" — first and lit as the primary choice. Since
2026-09-13 that one click plans and installs: the list is the user's own,
from a project they saved, so the click is the confirmation and the
review dialog is not asked for (the other cards still land on
Review install… → Install). The settings half of "my setup" needs no
work at all: the moment those tools register, the roaming config
re-applies their sections, exactly as docs/ConfiguratorDistribution.md
promises ("install decides WHAT is in the project; the config layer always
re-applies on top").
- Derived, never hand-maintained. The record is computed on every
SaveAllfrom the rails'installedtable (written per package as it lands —InstallerExt.RecordInstalled). There is no fourth record to keep honest besideinstalled, the store manifest andPkgversion; the table is the truth and the record is a view of it. A root with no table (never installed through the rails: the dev master, a hand-built root) returns the previous value rather than{}, becauseSaveAllreplaces a tool's section wholesale and a root with nothing to say must not erase what another project recorded. - State on the root host, not a sidecar file.
docs/ConfigScope.mdrefuses palette sidecars, anddocs/FirstRunNudgePlan.mdalready fixed where machine-global first-run state lives: "a state entry on the rootFNShost … fires once per machine, not per project, and roams correctly." Last-writer-wins across projects is the config's documented semantics — "last time" means the project you saved last, which is the mental model the card's label sets. - Scope comes for free. Under
Configscope = projectthe snapshot runs but the file is never written, the read-back is skipped, and the installer's reader refuses too — so no offer appears, and none would half-work (the settings would not re-apply there either). Same ruling as the nudge plan: acceptable, do not special-case it. - Offered, not applied unasked. "An update pass is not an install pass"
(
docs/PackagingScheme.md); a download into someone's project because a different project once held those tools is exactly the surprise a live-show toolkit must not pull. The card pre-selects; the plan step still surfaces stale caches, missing artifacts andSourceLockrefusals. - Only on a root with no tools. The card lives inside the served
picker's
FNS_FIRSTRUNbranch. "No tools" is measured against the manifest since 2026-09-12: no manifest tool (packages minus core) as a child of the root or in its install record. Before that the test counted every COMP but the three rails, and the root's ownFNS_ConfigHost(shipped in the bootstrap since 2026-08-22, and also a catalogued package name) made every root look installed-into, so the card had never fired. Core does not count either: the paste rail installs core before anything can open, and a root with core and no tools is still the user's first look at the picker. Everywhere else served mode pre-checks what this project has (unchecking reads as removal), and a remembered list leaking in there would read as "install these" over a live project.
The owner asked for the opposite of the offer as an explicit opt-in: a
toggle on the toolkit root, Always Set Up Like Last Time
(Setuplikelast, on the FNSTools page beside the pulses, default off).
With it on, a fresh drop installs the last recorded setup with nothing
to click: no picker, no window, progress as Textport lines. The user
turned it on themselves, on this machine, so the surprise the bullet
above guards against is not one.
- It roams as an ordinary root par. The root's host snapshots the
root's pars (only
Configscopeis excluded), so the toggle travels in the same file as the record it acts on, and every new project on the machine sets itself up the same way. - The welcome reads it from the file, not only the par. The host that
restores the root's pars may not have run when the welcome fires (90
frames after the drop), so
InstallerExt.AutoSetupWantedreads the live par first and then the root'sparssection of the roaming file directly, the wayLastInstallreads the record. Same scope rule: never under project scope, and never without a record. - The rail is the picker's card, without the page.
InstallerExt.InstallLastSetup(confirm=True)writes the selection the card would post (record names the release still has, over core, in the recorded bind mode; Patreon names held aside and named), then walks manifest → artifacts → install, each download waited for by a frame-scheduled tick, bounded at ten minutes. It never removes. Any stop prints why and points at Pick Tools; anything short of a started install makes the welcome fall through to the picker as before. Withoutconfirmit is a dry run that reports what would land. - The flag still moves to
shownbefore the rail starts, so a project load never fires it, and the paste rail (flagpaste) is untouched.
The bootstrap now carries the root's config host (FNS_ConfigHost in
BOOTSTRAP_KEEP, severed from the dev checkout like every stamped host:
externaltox cut, pi_suspect stripped, Regstatus blank). Before this
the shipped root had no section in a user's config — packaging/README
claimed the root "keeps roaming its own settings" and it did not. The
callbacks DAT (config_callbacks) is generated by EnsureRootEntryPoints
alongside the pulse forwarder and the welcome DAT, and the host's
Callback par is pointed at it there.
- The reader (
InstallerExt.LastInstall) opens the registry's default path directly — a bare root has no registry to ask and cannot know a master'sConfigfileoverride. Users who relocate the config get no offer; they still get Recommended / Everything / Pick my own. - Names are filtered against the current manifest and dropped silently (every package name changed once already, with no migration path); the card says how many fell away.
bind(thePackage Filesmode) rides along and is applied to the installer only when this card is chosen; an ordinary selection leaves the par alone.- Core is never part of the record's offer: the list is tools only, and core is implied by the plan as always.