Sign in
Join now
scn-chat
sharedcomputer.network
/
Star
Starred
Star
4
Something went wrong. Try again.
Fork
0
Eye filled
Watch
Watching
Watch
ATProto-based AI Assistant Chat interface.
Star
Starred
Star
4
Something went wrong. Try again.
Fork
0
Eye filled
Watch
Watching
Watch
Overview
Overview
Issues
Issues
1
1
Pulls
Pulls
Pipelines
Pipelines
Version history of
apps/web/src/features/models/components/
ModelSelect.tsx
October 2026
pouriade.com
ed6a8acb
Copied
Failed
Copy SHA
Give Select a loading
state
state
Copy SHA
Browse repository
committed
2w ago
pouriade.com
9490edb3
Copied
Failed
Copy SHA
Layer colors into scales, roles, and
components
components
Copy SHA
Browse repository
committed
2w ago
pouriade.com
a154eb4e
Copied
Failed
Copy SHA
Move the composer's model and effort under the
card
card
Copy SHA
Browse repository
committed
3w ago
pouriade.com
ae9caba7
Copied
Failed
Copy SHA
A chat keeps the model last used on its branch, the nearest reply's or the one a message asked for, even when that reply failed or was stopped, so the app never switches models on its
own.
own.
Copy SHA
Browse repository
committed
3w ago
pouriade.com
d6a00140
Copied
Failed
Copy SHA
A Select given searchLabel opens a list of eight options or more, about as many as it shows before scrolling, with a search box named by it, and the model select gives "Search models", which finds a model by its name, its ID, or its provider through the options' new keywords. The box takes the focus as the list opens, except on a touch screen, where it waits for a tap so its keyboard doesn't cover the list. Typing narrows the options to those holding every word typed, in any case, moves to the first that matches, and says "No matches" through a status that is there from the start, so screen readers hear it. The arrow keys, Page Up, Page Down, and Enter work from the box while Home, End, and Space stay the field's, Escape closes the list and Tab moves on, each from the button, which takes the focus back as after a pick, and a letter typed on the closed button opens the list searching for it. An option's id comes from its place among every option, so the active id changes with each move and screen readers and the scroll into view follow it. The list's heading and search box sit over the options, which alone scroll, and usePlacement measures the room the reader can see, following the visual viewport as an on-screen keyboard comes and goes. touchOnly is shared with the composer from shared/touch.ts. The styling and web UI specs describe it, with tests and an acceptance criterion.
Copy SHA
Browse repository
committed
1mo ago
pouriade.com
bf28924b
Copied
Failed
Copy SHA
The composer's thinking effort is its own quiet select beside the model select, between it and Send, showing the chosen level's pie and name, rather than a submenu at the end of the model list. It shows only for a model that reasons, as before. With nothing else using it, the Select loses its submenu and usePlacement its useSidePlacement. The Select also scrolls the active option into view only when it changes, since the list re-rendered on its own scroll and jumped back to the active option, so a long model list couldn't be scrolled to its end.
Copy SHA
Browse repository
committed
1mo ago
pouriade.com
75c56c9b
Copied
Failed
Copy SHA
Content on its way shows a skeleton in its own shape, pulsing gently on a new --color-skeleton, in place of every "Loading…" and every empty space that filled in later. Loading reads its shapes out once and fades them in after the quiet wait, while a route's pending page shows at once, since the router now holds it back 400ms and keeps it at least 300ms. The chat frame has the sidebar's logo and toggle over New chat, the chats, and the account card; the chat list keeps its rows until the local copy answers or, with no chats yet, until the index first syncs; a search shows rows until it first answers rather than saying nothing matched; the account card holds its avatar and name; a conversation holds its title and first turn, so a titled chat never flashes New chat; the model selects hold a line for the name, so a chosen model no longer flashes as unavailable; and settings and admin pages, the users list, the Sync page's switch, the Share panel, and the shared page each have theirs. The store hooks report loading as React Query's isLoading, or the store still opening in this tab, so no component checks the handover. The shared page's loader fetches the chat for a signed-in viewer and the page reads it with useSuspenseQuery, under the route's skeleton and a centered error page with Retry. A busy button keeps its label with a turning spinner before it, a little stronger than a disabled one, for Save, every submit, Load models, Rebuild, Sign in's Continue, and the rest.
Copy SHA
Browse repository
committed
1mo ago
pouriade.com
fbbfd82a
Copied
Failed
Copy SHA
Port the composer from design-reference. It is one card stuck to the panel's foot over a fade, with quotes and attachment chips at its top, a box that grows with its text and clears from its corner, and a toolbar of Attach, one quiet select for the model and its thinking effort in a submenu with timer pies, and Send, which Stop replaces while a reply runs. Files paste or drop anywhere on the conversation, Enter doesn't send on touch or while an input method composes, editing shows a banner, More quotes a reply into it, and a button above it jumps to the latest message. New chat goes to /, an empty conversation with starters whose first message creates the chat, reusing it when a send is tried again. The last effort is kept on the device, and ModelSelect and EffortSelect move onto the app's Select.
Copy SHA
Browse repository
committed
1mo ago
pouriade.com
992d10f4
Copied
Failed
Copy SHA
Split the web app's leaf components into smaller ones that return early. MessageView keeps the message's layout, and drawing parts moves to src/parts, as the extending spec lays out: markdown.tsx holds the renderer with its exported plugin lists and components, each part kind has a view taking { part, record, blobUrl }, and partViews in parts/index.ts maps kinds to them, matching only its own keys. Reasoning is one component, shared with the streamed reply, and SiblingPicker, Status, and StreamingReply have their own files. Source links are keyed like other parts, so two with the same URL no longer share a key. SchemaFields renders a SchemaField per property, with inputKind picking the control, and shares splitLines with RoleAdmin. SearchResults returns early from ResultList and ResultLabel in place of nested ternaries. SectionNav renders the admin and settings section links, ViewerSignOut moves from the login route to features/auth, and ModelSelect's props extend the select's directly. SchemaFields and RolePicker return a fragment rather than an array, since React Compiler silently skips a component that returns an array.
Copy SHA
Browse repository
committed
1mo ago
hadsie.com
e427e122
Copied
Failed
Copy SHA
Merge pull request #7 from
Z-Space-Society/merge-web-rebuild
Z-Space-Society/merge-web-rebuild
Copy SHA
Browse repository
committed
1mo ago
hadsie.com
e52c57c4
Copied
Failed
Copy SHA
Merge web-rebuild: the web app on TanStack Start. Port main's no-models composer block, role and model summary pages, API keys and Cron pages into its feature folders
Copy SHA
Browse repository
committed
1mo ago
pouriade.com
f764916e
Copied
Failed
Copy SHA
Have React components take props: Props, declared as an interface, and read props.example rather than destructuring props in the signature. A component destructures only the values it builds other variables from, such as ModelSelect and EffortSelect passing the rest of their props to the select. Inline prop types became named interfaces, and CLAUDE.md states the
rule.
rule.
Copy SHA
Browse repository
committed
1mo ago
pouriade.com
c8b86cd1
Copied
Failed
Copy SHA
Group the web app's code by feature. Each folder in src/features (auth, chat-list, conversation, sharing, models, settings, admin) holds that feature's pages, layouts included, components, hooks, lib, and queries, and the routes stay thin, rendering a feature's page. Page files are named after the component they export. The query factories split from src/queries.ts into each feature's queries.ts, leaving staleTime in src/shared, which also holds the API client, errors, search params, and the schema forms that admin and settings share. inheritedModel moves from the models module to the conversation's branch module, so models no longer depends on the conversation. Tests mirror the new tree, and the specs, the architecture doc, and CLAUDE.md name the new
paths.
paths.
Copy SHA
Browse repository
committed
1mo ago