Repository navigation
Act by instance id; render Dashboard cards in place (#128) - #133
Merged
Merged
Conversation
SpawnClient's mutating methods (stop/start/hibernate/terminate/extend/ signalComplete) take an instance id and reject a Name. Name lookups that remain (get, the terminal commands) resolve as Go's resolveInstance: spawn-managed live instances only, case-insensitive, a single running match wins, otherwise AmbiguousNameError with the candidate ids. The Dashboard keeps one card per instance id and updates it in place: text only when it changes, buttons only when the offered set changes and never mid-action, so a slow press survives the monitor's renders. signalComplete is mock-only and hidden on real backends. Fixes #128
This was referenced Nov 11, 2026
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.
Fixes #128
1. Every action takes an instance id
SpawnClient.stop / start / hibernate / terminate / extend / signalCompletenow takeinstanceId: stringand reject anything that isn'ti-followed by 8 or 17 hex digits. The error says why ("an instance's Name is not unique…"). Before this, the Dashboard passedi.name, andEC2Provider.get(name)returned the first DescribeInstances match. In the audit that was a terminatedtest, so terminate on the live card "succeeded" on the dead one.Name lookups that remain are
client.get(nameOrId)(read-only) and the in-browser terminal's Go-parity commands (stop test). Both now resolve exactly as Go'sresolveInstancedoes (spawn/cmd/utils.go:186) via the newcore/resolve.ts:EqualFold).AmbiguousNameErrorlisting the candidate ids. The terminal prints it.get(id)returns the instance in any state, so a terminated instance shows as terminated. It returns null forInvalidInstanceID.NotFoundand for an instance that isn't spawn-managed (Go: "must be spawn-managed").The terminal keeps name-or-id on purpose, because Go's CLI accepts a Name with exactly these rules. Only the library's action API is id-only.
2. Cards render in place, keyed by id
renderInstancesreplaced every card on eachinstancesevent, which fired about every 125 ms, so a 180 ms press lost its click. Now:data-instance-id);3.
signalCompleteis mock-onlyIt throws on any non-simulated provider. On EC2, spored runs on-complete when the completion file appears. The Dashboard hides the button when
backend.isReal.Tests
testand a livetest. Extend, stop, start, hibernate, start and terminate on the live card all hit the live id (provider spied), and the dead one is untouched.stepplusrefresh(the TTL meter changes), then mouseup: it is the same button node, still connected, and the click opens the confirm.start.signalCompleteis hidden and refused on a real-flagged provider.EC2Provider.getcovers: by id, terminated by id, unmanaged by id,NotFoundversus other errors, a Name skipping a terminated namesake, case-insensitivity, a single running match beating stopped ones, and an ambiguous Name throwing with both ids.Breaking for existing consumers
Yes, noted in the CHANGELOG: passing a Name to those six methods now rejects. Pass
instance.instanceId. The in-repo demos already pass ids.Relationship to the other PRs