Repository navigation
1.19: the Prompt builder, a fourth tab where an Ollama LLM asks questions and writes the prompt - #41
Merged
Merged
Conversation
…nt, connection routes) The first piece of DESIGN.md section 37, built so that nothing yet needs a language model to be running: - Settings for the Ollama server (STUDIO_OLLAMA_*, STUDIO_BUILDER_*), checked at start-up. A bad address is refused without echoing it; the address is kept out of repr, logs, capabilities and every message. - A stdlib-only Ollama client: streamed chat with thinking, keep-alive and context settings, silence time-out versus an overall cap, Stop from another thread, redirects refused, errors reduced to fixed sentences with a hint. - BuilderService: status (cached a few seconds), Test connection (always fresh), Unload from memory, and a cached view for the capabilities that never waits on the network. - GET /api/builder/status, POST /api/builder/test, POST /api/builder/unload; capabilities.builder and limits.builder. - compose.yaml and .env.example carry the settings, and extra_hosts so a container can reach an Ollama on the Spark itself. - A fake Ollama server for the tests; tests check that compose, the example file and the parser agree. No schema change yet and no page; the Prompt builder tab comes in later slices. Co-Authored-By: Claude Sonnet 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_011NDCKtu1QcLwawbdzwmFA1
DESIGN.md section 37.4, criterion 251: - Seven new tables (prompts, prompt_versions, prompt_tags, chats, chat_messages, chat_attachments, preferences) and an FTS5 word index over a prompt's title, newest text and tags; where SQLite has no FTS5 the studio opens and keeps prompts without the index. - runs gains prompt_id and prompt_version as its last two columns, plain and not foreign keys, so a migrated table equals a new one and deleting a prompt for good leaves them. A schema 8 database is copied to studio.sqlite.before-schema-9 first; an older studio refuses a schema 9 one. - BuilderStore: chats and numbered messages, prompts with version 1 and tags, the index kept in step, the bin (bin, restore, delete forever, the clean-up, Empty bin), and the counts for the tab and its filters. The column for "For" is for_kind (for is an SQL keyword); the API will say for. - Deleting a project deletes no prompt or chat and turns its preferences off while keeping them in it; the projects list counts prompts and chats that are on show. - The app builds the store and rebuilds the index at start-up if it is behind. - The schema-number tripwires move to 9; exact project counts gain prompts and chats; the 1.17 migration test no longer pins the number. Still no routes for prompts or chats, and no page. Co-Authored-By: Claude Sonnet 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_011NDCKtu1QcLwawbdzwmFA1
Hand-picked mutants of BuilderStore showed four real gaps, now covered: versions are listed oldest first (checked with three versions), a chat in the bin and in no project is counted only under deleted, an index with a row too many or a row for a prompt that is gone is rebuilt (by count and by a full rebuild from nothing), and the store's refusal says what is wrong. Stored message content is checked to be written one way. Co-Authored-By: Claude Sonnet 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_011NDCKtu1QcLwawbdzwmFA1
… schema) Hand-picked mutants of the schema showed that nothing tested the tables refusing a bad value, a version or message number below 1, a second message with the same number in one chat, or the defaults (a new preference is on, a new prompt is not a favourite). Every value of each allowed set is now accepted and one outside it refused, straight in SQL; the sets are pinned to the spec's; and the accent test no longer compares two empty searches. Co-Authored-By: Claude Sonnet 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_011NDCKtu1QcLwawbdzwmFA1
…med replies, pictures)
DESIGN.md section 37.3 rules 6-11 and 13, 18, and section 37.5:
- Five instruction files (common, images, vector, music, edit), FIRST DRAFTS
for the owner's review; the studio fills in its own numbers and a typo in
a {{word}} is an error rather than text sent to the model.
- answer.py: the JSON schema sent as Ollama's format (reply first) and a
validator that keeps only what is valid by the same rules as a run
(shapes, guidance, steps, palette less white, sizes, lengths, three
questions, three to five chips); what breaks a rule is dropped and the
reply says so in words. An unreadable answer is asked again once with
thinking off whatever the setting, then shown as plain text.
- context.py: earlier turns are sent as what they said (no draft, no
reasoning); the oldest are dropped first when the window is full, never
the instruction, preferences, examples, draft or the newest turn.
- engine.py: the person's message is saved first, so a failed reply never
loses it; the reasoning streams but is never stored; Stop keeps what was
written, marked; closing the connection keeps none of it.
- chat_routes.py: chats (list, create, read, rename, file, bin, restore,
delete), the streamed message route, Stop, one reply at a time with
waiting and busy-making-an-image events, and pictures attached to a chat
(copied in, shrunk to 1536 px, checked as an edit's upload is, removed
with the chat).
- A scripted model for STUDIO_BUILDER_LLM=fake that can be told to
misbehave, so every failure path is reachable without a real model.
- Tests run a real server for Stop and a closed page, since TestClient
delivers a streamed reply only when it is over.
Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_011NDCKtu1QcLwawbdzwmFA1
…ences) and runs from a prompt
DESIGN.md section 37.3 rules 1-5 and 7, section 37.4; criteria 229, 230, 236-238, 245-247:
- Library: versions are only ever added; saving what is already the newest
makes none and says "Nothing changed." (settings compared in one canonical
form, so 4 and 4.0 are the same); Make this the current one copies an old
version as the newest; tags, star, project and kind; search over title,
newest text and tags (each word starts a word; plain match where SQLite has
no FTS5); filters and sorts; the pictures made from each version.
- Compare: the words that changed (removed and added runs), the negative
prompt and each setting, computed on the server so it is tested once.
- Preferences: add, edit, switch, delete; no duplicates; at most 50; a note
of a project that is gone stays off until it is given a place.
- Routes under /api/builder: prompts, versions, compare, bin, restore,
delete, file-runs ("Also file its pictures' runs": nothing moves until
asked), preferences, counts, and Empty bin for the builder's own bin.
- POST /api/runs takes prompt_ref {prompt_id, version} for every kind. The
prompt must exist (404) and not be in the bin (409) and have that version
(422). A run from a prompt in a project is filed there and kept; a quick
try (a draft) is linked but neither. The run's payload says where it came
from, whether that prompt is deleted, and whether the words differ
("edited"); GET /api/runs?prompt= lists the runs made from one.
- Prompts and chats in the bin are deleted for good by the daily clean-up on
the same clock as pictures, and with no bin (STUDIO_BIN_DAYS=0) Delete is
for good at once; chat folders go with their chats.
- The Vector contract and the page's Run type gain prompt_ref.
Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_011NDCKtu1QcLwawbdzwmFA1
… rules The foundation of the Prompt builder's tab, with no component yet: - builderTypes.ts: the shapes the server sends (status, chats, messages and what a reply contains, prompts and versions, preferences, counts, the events of a reply), and capabilities.builder / limits.builder. - sse.ts: a parser for server-sent events that hands over nothing until an event is complete, and a reader for a streamed POST (EventSource cannot POST); an error status becomes the studio's own error, a drop in the middle says the server can't be reached. - builderApi.ts: every call of the builder, through the studio's request helper, with the X-Studio-Client header on each change. - builder.ts: what a reply is doing; choosing chips (tap, tap again, Surprise me, Skip); reading a chat (open questions, newest draft); the words that changed; the length meter; how a prompt's settings are laid over the Images options and the exact words of the Undo toast; the request for Generate now and a quick try; where a run came from. - prompt_ref is a wrapper type, not a field of the create bodies, which the Vector contract pins key for key. Co-Authored-By: Claude Sonnet 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_011NDCKtu1QcLwawbdzwmFA1
… saving The fourth tab (DESIGN.md section 37.2, criteria 221-229, 244, 248, 250, 253, 255-256): - A tab after Vector, remembered like the others, with a dot while a reply is being written; the panel stays mounted so a reply carries on while another tab is open. The tab is wider than the rest (list, chat, prompt); on a phone it is one column with a Chat | Prompt | Library switch. - Connection: not set up says how, in the spec's words; an unreachable Ollama or a missing model says which, with its hint; Test connection shows the version, the models, whether yours is there and whether it can see pictures; Unload from memory only asks. The page never has the address. - Chat: the person's words appear at once; the reply streams; thinking shows the seconds and a fold, and is dropped when the reply ends; chips toggle on a tap, Surprise me and Skip replace them; Stop keeps what was written, marked; a failed reply keeps the message and offers Retry; a lost connection reloads the chat; the model's text is only ever text. - The prompt so far: editable (the next message starts from it), a length meter against the limit, the words the last reply changed marked with strike-through and underline, the settings that fit as switches. - Save as prompt / Save as new version, with the title and tags the builder suggested, the project and what it is for; Nothing changed. when it is. - Pictures: attach, drop or paste into a chat (a paste on this tab goes to the chat), shown numbered, taken back, refused in the server's words, off with the reason when the model cannot see. - Server, for the page: the status says which way Think starts; a chat can be linked to a prompt through PATCH; a reply can be asked again without a saved prompt that was left out (retry with redo). Co-Authored-By: Claude Sonnet 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_011NDCKtu1QcLwawbdzwmFA1
The Prompt builder tab now has its library (DESIGN.md §37.2, criteria 229-233, 245-247): - Chats, Prompts and Preferences at the left; Chats and prompts can be looked at as they are or as they are in Deleted (restore, delete for good, Empty bin, each asked first). - Prompts: search (title, words, tags) once the typing pauses, Show All / starred / Deleted and Project / Tag / Sort, each with its count; star without opening. - A prompt opened: title, star, For, Project, Tags; every version newest first with its pictures; Make this the current one (a copy as the newest); Compare two versions with the changed words and settings marked in text; Flesh out; Delete / Restore / Delete forever; a prompt's chats; the offer to file earlier pictures' runs. - Preferences: add, switch, edit, delete, where each applies; notes of a deleted project listed apart. - A chat's name and project, from the chat header. Two faults found while testing it, both fixed here: a list that was read fine wiped the words about another list that was not (one shared error); and a fresh copy of an open prompt from the server replaced the title or tags the person was half-way through typing. 1000 Vitest tests pass (34 new); tsc and the production build are clean. Co-Authored-By: Claude Sonnet 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_011NDCKtu1QcLwawbdzwmFA1
Use in …, Generate now and Quick try (DESIGN.md §37.2, §37.3 rule 3; criteria 235, 236, 239, 242): - Use in Images / Edit fills the prompt box, sets only the settings left on, switches to Generate (or Edit), says what it set and offers Undo, and shows the "From Prompt builder: "title" vN" chip. Generate carries the chip's prompt as prompt_ref; ✕ removes it; Reuse of a run made from a prompt brings it back, and Reuse of any other run takes it away. - Use in Vector / Music asks the panel to fill its form (idea or description, kind, colours, inks, size; fields, lyrics, length), keeping to each form's own rules: what the form cannot take is left out and named in the toast, and Undo puts the form back. - Generate now queues a run at once from the tab's own options with the prompt's settings over them, without touching the form; for Vector and Music it uses the saved form. Quick try makes a Draft and stays in the builder. A prompt that is not saved carries no reference. - The builder re-reads an open prompt when a run made from a prompt appears or finishes, so a quick try's picture shows on its version. - Help me write this (Edit) is on the prompt bar, off with its reason when it cannot open. The rules are pure functions (promptUse.ts); the behaviour is a hook (usePromptUse.ts) tested with a fake API: 1041 Vitest tests pass; tsc and the production build are clean. Co-Authored-By: Claude Sonnet 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_011NDCKtu1QcLwawbdzwmFA1
…where a run came from DESIGN.md §37.2, §37.3 rule 3; criteria 237, 241, 243, 244: - Every run made from a saved prompt says so on its card: From "title" vN, with edited and deleted when they apply, opening the prompt in the Prompt builder. A prompt deleted for good is named as such and cannot be opened. - Refine in Prompt builder, on an Images card, in the picture viewer, and on a picture in a prompt's detail: a new chat linked to the prompt (when it still exists) and its project, holding the run's words in the prompt box and, when the model can look at pictures, the picture. The next message is sent as a refinement of that run (the server tells the model the run's settings and seed). A picture not made from a prompt opens an unlinked chat and saves nothing. - Help me write this (Edit): the builder opens For Edit with the tray's pictures attached in order, in one chat, even when the model cannot look at them (it then works from their count). - Pick from my history and Describe as a prompt in the chat. - The page asks the builder for these things through one command channel (a new seq each time). Fixed on the way: attaching several pictures to a chat that did not exist yet made a chat for each, because the loop held the chat as it was when the first was chosen; the hook now tracks the open chat as it is now. And a test of mine that asserted on an effect's call too early. 1074 Vitest tests pass; tsc and the production build are clean. Co-Authored-By: Claude Sonnet 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_011NDCKtu1QcLwawbdzwmFA1
…tray for Edit
DESIGN.md §37.2, §37.3 rule 5, §37.4; criteria 243, 247, 249:
- The Manage projects list counts prompts and chats beside the runs ("Logo: 4 pictures,
1 track, 3 prompts, 2 chats"), and the question before deleting a project says that its
prompts and chats stay too, no longer in a project. A count the server did not send is not
said as 0.
- When the Prompt builder is set up, the advice that goes with "Not enough free memory"
(on a run, on loading a model, on the worker's state) also says to press Unload from memory
on the builder's tab. Without the builder the advice is exactly what it was.
- Use in Images for a prompt made For Edit puts the chat's pictures in the tray, in the order
the prompt numbers them, but only into an empty tray: a tray with pictures in it is the
person's, so it is left as it is and they are told why.
1080 Vitest tests and 2322 backend tests pass (3 skipped, as before); tsc and the production
build are clean.
Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_011NDCKtu1QcLwawbdzwmFA1
…, backups - frontend/e2e/builder.spec.ts: 14 browser tests of the Prompt builder against the real server with the scripted model (STUBBED nothing else): the tab, an idea to a finished prompt, saving, versions and Compare, Use in Images with Undo, Generate now and the run's line, Quick try, filing in a project (and the offer to file earlier runs), Refine, Help me write this, preferences, the bin, a failed reply and Stop, text shown as text, a 360 px phone. playwright.config.ts starts the server with STUDIO_BUILDER_LLM=fake. - A Stop pressed in the moment between Send and the server listing the reply was answered "no reply" and lost, so the reply ran on. It is now tried again for about a second while the reply is being waited for (found by the browser test). - The toast after filing a prompt in a project said "1 earlier picture's run is where they were"; it now says "it was" for one. - Version 1.19. The backup and restore scripts say they hold prompts and chats too, and their test now proves a chat's picture (data/builder) is in the backup and comes back. 1081 Vitest tests pass; 303 script checks pass. Co-Authored-By: Claude Sonnet 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_011NDCKtu1QcLwawbdzwmFA1
…a phone, the Spark test
The whole browser suite (295 tests) was run on the tree: 291 passed, 4 did not, and
this commit deals with them:
- Two tests of the tab bar still said Vector is the last tab; the Prompt builder is
(music.spec.ts, vector.spec.ts). They now say what is true, and that the bar wraps round.
- On a 360 px phone the viewer's row of buttons wrapped once more because of Refine in
Prompt builder, and pushed the picture 35 px off the screen (studio.spec.ts caught it).
In the viewer the button now reads "Refine" and keeps its whole name for a screen reader
and the tooltip.
- music.spec.ts "Add lyrics shows Voice…" fails as DESIGN.md 36.9 records for this machine's
Chromium ("oh oh" is typed as "h oho"), in code 1.19 does not touch. Not changed here.
Mutation checks of the page's new pure logic found tests missing at the limits (colours, sides,
a field, lyrics, description and length exactly at their limit), for "1 ink", for naming the
tempo, and for "nothing was left out"; and of the server's comparison, a long text (where
the matcher must not give up on common words) and an object whose keys come in another order.
They are added.
Also: README describes the Prompt builder and says backups hold prompts and chats;
docs/SPARK_TEST.md section 30 is how to load 1.19 on the Spark (the branch, .env, Ollama)
and what to check there.
Note on the previous commit (6530080): its message has a stray phrase ("STUBBED nothing
else") and says 1081 Vitest tests; there were 1085.
1090 Vitest tests pass.
Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_011NDCKtu1QcLwawbdzwmFA1
…d a word when Stop keeps nothing Mutation checks of usePromptUse.ts (68 mutants, 9 survivors) and of answer.py (156 mutants, 51 survivors, 36 of them in docstrings) showed what the tests did not pin down. Added: - the hook does nothing until the page has its capabilities and options; Generate now for Edit when the pipeline cannot edit; an edit's own size is checked; the queue-full message is shown as the server wrote it; a picture with no type gets one; the tray message in the singular. - the answer: the limits cannot be changed by what reads them; a bare Answer is not done and has no draft; the stored message carries the draft exactly; a plain-text reply is cut only past the limit; the object is found when it is the first thing and something follows it; the two "not an answer" messages; questions without ids are numbered from 1; both notices about inks; lyrics exactly at the limit; and the streaming reply's decoder at every edge of an escape and of a surrogate pair. Also: when Stop is pressed before anything has been written the server keeps nothing and sends no message, and the page said nothing at all. The chat now says "Stopped before anything was written, so nothing was kept. Your message is still there." Frontend: 1100 Vitest tests pass. Co-Authored-By: Claude Sonnet 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_011NDCKtu1QcLwawbdzwmFA1
…d DESIGN brought up to date The mutation rounds on the server (answer, context, library, diff, prompt routes, chat routes, the engine) and on the page (builder.ts, useLibrary.ts) left survivors; most were in code the tests did not pin down, and those are now pinned: - the server: both limits of every field (a prompt of exactly the most characters, exactly the most tags), a PATCH that names only some fields, values that only look like the right type, the four things a button can ask for (flesh out, refine, describe, help write) reaching the model, what a Refine tells the model about the run, deleting a chat for good with and without a bin, the most pictures a message may carry (only the waiting ones count), a picture exactly as large as the limit, which draft the model is given (the person's edit, the last it wrote, the one a retry carries), asking again for three wordings, a reply that cannot be read twice, the name a chat gets, a stopped reply being neither finished nor plain text, how a job is stopped and who decides whether what was written is kept, the whole of a long text when it is compared. - the page: the words that changed, held to a plain longest-common-subsequence over three hundred random pairs; the settings at exactly the studio's limits; an Edit request with no pictures; the words for a Vector and a Music prompt's settings; the search box's pause (a word typed in two goes), one ask when the list opens, and the words of an error. Not changed, because the mutants are equivalent or the behaviour is not a rule: the spelling `for_kind` accepted as well as `for`; request types with nothing that could be coerced; defaults that the routes always override; a defensive fallback in the preferences count. DESIGN.md: the header, the 1.19 row, section 37's heading and section 9a now say 1.18 and 1.19 are built. Co-Authored-By: Claude Sonnet 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_011NDCKtu1QcLwawbdzwmFA1
…ked for The last page and server rounds left survivors that were real; the tests that kill them: - the hook that holds a chat: that it is testing, unloading, opening and attaching only while those are on their way; what a message looks like before the server has answered (the answers with their questions, the edited draft, whether it was to think), the server's number for it and the chat the reply leaves; a redo showing the old reply gone and a plain retry not; the difference between a page closing and a network failing; a stream that ends with no ending; a Stop that the server refuses for a reason of its own not being asked again; the choices of a chat that does not exist yet; and the note that Stop kept nothing going when another chat starts. - the library: that an error with the prompts stays when the chats, being slower, are read well after it; that the search box waits for the typing to pause; that the list is asked for once when it opens; and that nothing says "no prompts" while it is still looking. - the server: that a quick try is called a draft in what Refine tells the model, that answers still count after a message that got no reply, that a delta says whether the model thought first, and what a chat is called when the model gives no title and when the first message is a picture alone. Co-Authored-By: Claude Sonnet 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_011NDCKtu1QcLwawbdzwmFA1
… (DESIGN section 37.11) Section 37.11 says what is where, what the checks found (all fixed), what has not been tried (everything that needs your Ollama, the instruction files, a real phone) and the small choices made while building, with the figures of a run on this tree: - backend 2361 passed, 3 skipped; front end 1123; browser 295 (294 pass; the one that does not is the Music "Add lyrics" test that fails on this machine on earlier trees too); script checks 303. - mutation checks: 932 mutants of the 1.19 code in two passes; 902 killed; 30 left, each judged one a test cannot tell apart, and listed by kind. The test of Try 3 wordings now names criterion 240, the one criterion no test file cited. Co-Authored-By: Claude Sonnet 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_011NDCKtu1QcLwawbdzwmFA1
Co-Authored-By: Claude Sonnet 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_011NDCKtu1QcLwawbdzwmFA1
The two places in section 30 that said `./scripts/backup.sh` would only have printed its usage and stopped: the script takes the folder to write into. They now say `scripts/backup.sh --no-model ~/backups` (the data, the image and the settings, without the models, which an update of the studio's own code does not touch). Co-Authored-By: Claude Sonnet 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_011NDCKtu1QcLwawbdzwmFA1
NoSQLKnowHow
added a commit
that referenced
this pull request
Nov 9, 2026
Spec 1.20: Speech, text read aloud (DESIGN §38; stacked on #41)
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.
What this is
Version 1.19, built to
docs/DESIGN.md§37 (criteria 221 to 257; specified in #39 and decided with you on 2026-10-28).A fourth tab, Prompt builder. You type a rough idea; an LLM hosted in your Ollama (
STUDIO_OLLAMA_URL,STUDIO_OLLAMA_MODELin.env) asks up to three questions at a time (tap a chip to answer) until it has written a prompt. You see it think, you can Stop it, and nothing it writes is run: only a button you press queues anything.Back up first
The first start of 1.19 upgrades the database to schema 9 (new tables for prompts, versions, chats, messages, attachments and preferences;
runs.prompt_idandruns.prompt_versionas the last two columns so an upgraded database equals a new one). A copy is made first (data/studio.sqlite.before-schema-9); every run and project is kept.docs/SPARK_TEST.mdsection 30 is how to load it on the Spark (the branch,.env, Ollama) and what to check, and starts with./scripts/backup.sh. The backup and restore scripts already cover prompts and chats (they live in./data); their test now proves a chat's picture comes back.How it was built
Server in
backend/studio/builder/(a stdlib Ollama client that never shows the address; a validator that drops anything the studio's own rules refuse and says so in words; one reply at a time; server-sent events;prompt_refonPOST /api/runs). Page:BuilderPaneland its parts, the rules as pure functions (builder.ts,promptUse.ts), the hooksuseBuilder/useLibrary/usePromptUse. What was built, what the checks found and the small choices I made are inDESIGN.md§37.11.Evidence (all local; the repo has no CI)
Run on the final tree (commit
9b98544, after merging main, which changed no file):e2e/builder.spec.ts): 294 pass and one does not, see below. Backup/restore script checks 303. Type check and production build clean.music.spec.tsAdd lyrics shows Voice and the lyrics box… ("oh oh"is typed as"h oho"). DESIGN §36.9 records it for this machine's Chromium on earlier trees; it is in Music code 1.19 does not touch.Not checked
qwen3.8:27b: its speed, how long it thinks, whether it keeps to the structure (the studio asks again once with thinking off, then shows plain text, but I do not know how often that happens), whetherthinkand the structured answer mix well in your Ollama version, whetherhost.docker.internalreaches it from the container, whether it reports it can look at pictures, and whether a 32768-token window fits next to Qwen-Image.SPARK_TEST.mdsection 30 measures each.backend/studio/builder/instructions/*.md) are my first draft and nobody has read them with a model. They decide how good the questions are; please read them and tell me what to change. They are plain text.Small choices made while building
All fourteen are in
DESIGN.md§37.11. The ones most worth a look: (8) words used from The prompt so far are not a saved prompt, so Use in and Generate now from there carry no prompt reference and show no chip; (9) Use in for an Edit prompt puts the chat's pictures in the tray only if the tray is empty; (6) search looks at the title, the newest version's text and the tags, not older versions' words.Known limits
One reply is written at a time (
STUDIO_BUILDER_AT_ONCE, 1); a prompt's older versions are not searched; every picture attached to a chat is sent again with each later reply as far as the window holds them; nothing is exported (§37.10).Notes
Version bumped to 1.19 (
__init__.py,package.json, lock file, test data). Two commit messages on this branch are wrong in small ways that I could not fix because rewriting a pushed branch was blocked:6530080has a stray phrase ("STUBBED nothing else") and says 1081 Vitest tests where there were 1085;316db4csays 1100 where there were 1097. The figures above are from the final run.Generated by Claude Code