Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,8 @@ State lives at `~/.lavish-axi/state.json` (`LAVISH_AXI_STATE_DIR`), shared acros
Detection is **passive**: that route updates the warning inbox and emits an SSE `layout-warnings` event, and it deliberately never emits `feedback`, so a diagnostic pass can never make `lavish-axi poll` return or wake an agent. The gate reveals on the first completed pass whatever it found (detection and user-facing behavior: README's Layout issues inbox, Layout issue lifecycle, and Open-time layout gate bullets).
Cosmetic, intentional, transient, tiny, warning-severity, and uncertain observations fail open and never enter the inbox.
The narrow **fatal** path is separate and still immediate: `/api/:key/artifact-failures` records only `artifact-unavailable` (the chrome's probe of the artifact route failed) or `artifact-asset-unavailable` (the SDK saw a same-origin subresource `error`), marks the session `feedback`, and `takeFeedback` returns them as `artifact_failures`. Ordinary layout findings must never be relabelled fatal to regain auto-repair.
6. User actions in the iframe `postMessage` to the chrome. Queued prompts live in tab `sessionStorage`; unsent prompts sharing the SDK-internal `_lavishQueueKey` replace each other, that field is stripped before POSTing collected prompts to `/api/:key/prompts`, and sent prompts are removed only after a successful response.
6. User actions in the iframe `postMessage` to the chrome. Queued prompts live in tab `sessionStorage`; unsent prompts sharing the SDK-internal `_lavishQueueKey` replace each other, every SDK-internal `_lavish*` field is stripped before POSTing collected prompts to `/api/:key/prompts`, and sent prompts are removed only after a successful response.
The other internal field, `_lavishQuestionKey`, lets the chrome mirror queued question scopes back into the iframe over `lavish:setQueuedQuestionKeys` - re-sent on every iframe load, since the chrome owns queue state and the sandboxed document cannot read it - so a queued `data-lavish-question` scope keeps its Queued marker; README's Feedback controls bullet owns that marker's user-facing behavior.
Text selection prompts use `tag: "text"` with a `target` of `type: "text-range"` (selected text, `commonAncestorSelector`, start/end boundary anchors).
Mermaid diagram-node prompts for rendered SVGs outside `.mermaid` containers use `tag: "mermaid-node"` with a `target` carrying `diagramId`, `nodeId`, the rendered `label`, and a `selector`, so the annotation anchors to node identity and survives a re-render that reshuffles the SVG.
Composer and annotation-card keyboard conventions, button layout, and the conversation panel are user-facing behavior owned by README's Feedback controls and Keyboard shortcuts bullets.
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,8 @@ pnpm link
- **Live reload** - Lavish watches the HTML artifact file by default and preserves review context across reloads: the artifact iframe scroll position, an open annotation card's unsent text, and answers to `data-lavish-question` controls (application-owned form state is left alone). While a queued layout-issue batch is outstanding, closely spaced saves coalesce so one batch of fixes costs one refresh. To also reload on sibling asset changes, add `data-lavish-live-reload-root` to the root element or `<meta name="lavish-live-reload" content="root">`.
- **Feedback controls** - Native controls (radios, checkboxes, inputs, selects, buttons, labels, disclosure summaries, contenteditable) are interactive automatically, so they do not need `data-lavish-action`.
For reversible choices, let option clicks update local state, then queue exactly one final answer from a per-question submit or Queue answer button with `window.lavish.queuePrompt()`.
Question wrappers with a non-empty `data-lavish-question` value show a visible **Queued** state while that question's answer is waiting to be sent; replacing the answer keeps one marker, and removing or sending it clears the marker.
Queueing with an explicit empty `queueKey` (`window.lavish.queuePrompt(text, { queueKey: "" })`) opts out of both replacement and that marker, which is how free-form annotation previews stay separate from a question's answer.
Mark only custom (non-native) clickable elements with `data-lavish-action` so Lavish does not annotate them, and use `data-lavish-question` or `queueKey` when pre-send updates for the same question should replace each other.
Queued annotation preview pills and chat history share a scrollable Conversation panel above a sticky composer, so long feedback queues do not push the text box or send controls off screen.
The browser chrome keeps editing actions in the overflow menu (copy path, reload artifact, copy DOM snapshot, export standalone HTML, publish link, end session), while the composer exposes **Send & End** beside **Send to Agent** to submit queued prompts and user-ended attribution together.
Expand Down
Loading
Loading