aboutsummaryrefslogtreecommitdiffstats
path: root/desktop/assistant/README.md
diff options
context:
space:
mode:
authorDanilo M. <danix@danix.xyz>2026-10-16 14:11:17 +0200
committerDanilo M. <danix@danix.xyz>2026-10-16 14:11:17 +0200
commitb7f33e54c93c5e3c764aa083c2f354fb8751e166 (patch)
tree6b9b66af1f0a5897137d13df66b19b504270da21 /desktop/assistant/README.md
parent72d3ff1f0c8c2cadf315214f31312895154cd20e (diff)
downloadquickshell-b7f33e54c93c5e3c764aa083c2f354fb8751e166.tar.gz
quickshell-b7f33e54c93c5e3c764aa083c2f354fb8751e166.zip
feat(assistant): the canvas, a view over the assistant daemon
The socket, the turn model and the window live in Assistant.qml, outside the window's loader, so closing the card loses nothing and a reply keeps streaming while it is closed. Tokens reach the model on a 50 ms tick rather than per token. Prose goes through Notify.sanitize, because model output can quote a search result and a remote image in it would be fetched on render. Code blocks get a copy button once their fence closes. The history panel lists conversations and searches them through the daemon's full-text index. Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Diffstat (limited to 'desktop/assistant/README.md')
-rw-r--r--desktop/assistant/README.md47
1 files changed, 47 insertions, 0 deletions
diff --git a/desktop/assistant/README.md b/desktop/assistant/README.md
new file mode 100644
index 0000000..0f80993
--- /dev/null
+++ b/desktop/assistant/README.md
@@ -0,0 +1,47 @@
+# assistant
+
+The assistant canvas: a centred card on DP-1, on SUPER+Home, for typed
+conversations with the local text assistant. It is only a view.
+desktop-assistant (the repo next to this one) is the daemon that owns the
+model, the tools and the history; this connects to its socket,
+`$XDG_RUNTIME_DIR/desktop-assistant.sock`, draws what it is told and sends
+what is typed. The protocol is specified in that repo,
+`docs/superpowers/specs/2026-10-16-text-daemon-design.md`.
+
+ qs -p ./desktop ipc call assistant toggle
+
+| File | Does |
+| --- | --- |
+| `Assistant.qml` | the socket, the turn model, the window |
+| `Card.qml` | header, transcript, input, the history panel's place |
+| `Message.qml` | one turn: question, thinking line, tool chips, reply |
+| `Segments.qml` | markdown with a copy button per code block |
+| `History.qml` | conversation list and full-text search |
+| `Md.js` | splits a message into prose and fenced code |
+
+Keys: Enter sends, Shift+Enter is a newline, Escape closes the history
+panel and then the card. Stop replaces Send while a reply streams.
+
+Notes:
+
+- **The state outlives the card.** The socket and the turn model live in
+ `Assistant.qml`, outside the window's loader, so closing the card loses
+ nothing, and a reply keeps streaming into it while it is closed.
+- **Tokens are batched.** They collect in a buffer and reach the model on a
+ 50 ms tick, so markdown is re-rendered twenty times a second at most
+ rather than per token.
+- **Prose goes through `Notify.sanitize`**, which blocks remote images.
+ Model output can quote a search result, and an image URL in it would be
+ fetched the moment it rendered.
+- **A code block's copy button appears once the fence closes.** A
+ half-streamed block is not the command the model meant.
+- **The daemon may be down.** The card says so and disables the input; the
+ socket retries every 2 s with a fresh `Socket` (see AGENTS.md), logging a
+ `ServerNotFoundError` warning each time.
+- **`tools` is a comma-joined string role.** A ListModel role holding an
+ array becomes a nested model, which `setProperty` cannot append to.
+- **Search snippets** mark matches with `**`, rendered as bold; backticks
+ are stripped first, since a match inside a code span would show the
+ markers literally.
+
+Test the splitter: `node desktop/assistant/test_md.js`.