aboutsummaryrefslogtreecommitdiffstats
path: root/docs
diff options
context:
space:
mode:
Diffstat (limited to 'docs')
-rw-r--r--docs/superpowers/specs/2026-09-26-overlay-design.md4
-rw-r--r--docs/superpowers/specs/2026-10-16-text-daemon-design.md16
2 files changed, 12 insertions, 8 deletions
diff --git a/docs/superpowers/specs/2026-09-26-overlay-design.md b/docs/superpowers/specs/2026-09-26-overlay-design.md
index e45819f..3c4aef3 100644
--- a/docs/superpowers/specs/2026-09-26-overlay-design.md
+++ b/docs/superpowers/specs/2026-09-26-overlay-design.md
@@ -1,6 +1,8 @@
# Assistant overlay: design
-Date: 2026-09-26. Status: approved in brainstorming, not implemented.
+Date: 2026-09-26. Status: **superseded** by
+`2026-10-16-text-daemon-design.md`; the overlay and the voice pipeline it
+drew were removed (tag `voice-v1`).
## Goal
diff --git a/docs/superpowers/specs/2026-10-16-text-daemon-design.md b/docs/superpowers/specs/2026-10-16-text-daemon-design.md
index 30f202b..40a73c8 100644
--- a/docs/superpowers/specs/2026-10-16-text-daemon-design.md
+++ b/docs/superpowers/specs/2026-10-16-text-daemon-design.md
@@ -54,7 +54,7 @@ merging, `--test`, `assistant.sh`.
- **Thinking.** `chat_template_kwargs.enable_thinking` becomes true.
`delta.reasoning_content` is streamed as its own `think` event, so the
canvas can collapse it. Reasoning is not stored and not sent back to the
- model.
+ model. It is the config key `thinking` (default true): measured live, reasoning added about 21 s before the first token of a two-line answer.
- **System prompt.** The default is rewritten for text: markdown is
allowed, there is no instruction to answer in short spoken sentences.
- **Input.** The mic loop is replaced by a reader thread per client. Each
@@ -71,6 +71,7 @@ merging, `--test`, `assistant.sh`.
JSON lines both ways on the existing socket. Every connected client sees
every outbound event, so a canvas reopened mid-reply catches up.
+A client stalled for 2 s on a send is dropped.
Inbound:
@@ -84,6 +85,8 @@ Inbound:
| `{"type":"search","q":"..."}` | answers `results` |
| `{"type":"delete","id":N}` | deletes N, answers `conversations`; deleting the current one acts as `new` |
+Ids in `open` and `delete` must be integers; a bad id, a non-string `text` or `q`, or a command that raises answers `error` (`bad id`, `bad text`, `bad query`, `<type> failed`) and leaves the conversation untouched.
+
An `ask` while a reply is streaming stops the old reply first. An unknown
or malformed line is logged and answered with `error`; it never closes the
connection.
@@ -92,21 +95,20 @@ Outbound:
| Event | Fields |
| --- | --- |
-| `hello` | `state`, `model`, `ctx_used`, `ctx_max`, `id`, `turns` (the current conversation) |
+| `hello` | `state`, `model`, `ctx_used`, `ctx_max`, `id`, `turns` (the current conversation), `pending` (`{user, reply, think, tools}` of a reply in flight, or null) |
| `state` | `state`: `idle`, `thinking`, `tool` (with `tool`) |
| `user` | `text`: the question, echoed so every client draws it |
| `think` | `delta` |
| `token` | `delta` |
| `tool` | `name`, `done` (false when it starts, true when it returns) |
-| `done` | `id`: the conversation the turn was saved in |
+| `done` | `id`: the conversation the turn was saved in; `stopped`: true for a reply that was stopped |
| `error` | `message` |
| `ctx` | `used`, `max` |
| `conversations` | `items`: `[{id, title, updated}]`, newest first |
| `conversation` | `id`, `turns`: `[{user, reply, tools}]` |
| `results` | `items`: `[{id, title, snippet}]`, best first |
-`hello` is sent on connect. A reply that was stopped emits `done` with
-whatever text it had, and that partial turn is not saved.
+`hello` is sent on connect. A stopped reply gets a `done` with `stopped: true` from whatever stopped it, and that partial turn is not saved.
## Storage
@@ -142,12 +144,12 @@ delete trigger cleans the index.
- `open` loads the last 10 turns' `messages` as the model history and all
turns' `user`, `reply`, `tools` for the canvas. Tool results come back as
the stored placeholder.
-- `search` wraps the user's text as an FTS5 phrase (double quotes doubled
- inside), so FTS syntax in the query cannot break or widen it. Results are
+- `search` wraps the user's text as an FTS5 phrase (double quotes doubled inside) with a prefix star, so FTS syntax in the query cannot break or widen it and a half-typed word still matches. Snippets mark matches with `**`. Results are
ranked by `bm25` and grouped to one row per conversation, with
`snippet()` from its best turn.
- One connection guarded by a lock: the reply threads and the client
reader threads all go through it. Only the daemon touches the file.
+- An index on `turns(conv, seq)`; `db_open` chmods the directory and file even when they already exist.
## assistant.sh