BareGit
# Doctor Boring

Doctor Boring is an evolution of Emacs' `M-x doctor`, backed by an
LLM. It is intended to be a fun side activity rather than a serious
assistant or medical tool.

## User experience

- Doctor Boring provides a new interactive command, `M-x doctor-boring`.
- The command switches to a buffer named `*doctor-boring*`.
- If that buffer already exists, the command switches to it without
  resetting the conversation. Users start a new conversation by
  killing the buffer and invoking the command again.
- When first created, the buffer displays a fixed greeting. The
  greeting is included as the first assistant message in conversation
  history.
- The buffer behaves like the original Doctor:
  - The user types a message and presses `RET` twice to submit it.
  - `C-j` submits the current message immediately.
  - Empty or whitespace-only messages are ignored.
  - Auto Fill is enabled.
- Leading and trailing whitespace is removed from user messages and
  model responses. Whitespace within a message is preserved.
- Submission is available only from the current input area at the end
  of the buffer. When editing earlier messages, `RET` inserts a newline
  normally.
- Earlier user and assistant messages remain editable. The history for
  each request is reconstructed from the current buffer, so edits affect
  future requests.
- Invisible buffer metadata distinguishes user messages, assistant
  messages, local errors, and the current input without changing the
  visible Doctor-style presentation.
- If `markdown-mode` is available when the conversation buffer is
  created, it is used automatically. Otherwise, the buffer falls back
  to `text-mode`. Model output is inserted without additional
  processing in either mode.

## Request behavior

- Requests use an OpenAI-compatible Chat Completions API.
- The configured endpoint is a base URL ending at the API version, such
  as `https://example.com/v1`. Doctor Boring appends
  `/chat/completions`, handling a trailing slash in the configured URL.
- The complete conversation history is sent with every request,
  preceded by the configured system prompt.
- Requests are asynchronous and must not block Emacs.
- Streaming responses are out of scope for the initial version.
- Only one request may be active at a time. While a request is active,
  the conversation buffer is read-only and no messages can be queued.
- A response arriving while the user is viewing another buffer updates
  `*doctor-boring*` without changing the selected buffer or window.
- Requests have a configurable timeout that defaults to 300 seconds.
- Killing the conversation buffer while a request is active cancels or
  safely abandons that request.

## Error behavior

- An empty endpoint is detected locally when the user submits a
  message. An empty API key or model is allowed.
- Network, timeout, HTTP, and malformed-response failures insert a
  concise local error above the failed user input.
- Detailed error information is written to `*Messages*`.
- Local error text is excluded from conversation history.
- After a failure, Doctor Boring rolls back the submission: the failed
  user text is restored as the current input, point is placed at its
  end, and the buffer is writable. The user can retry by submitting it
  again.

## Configuration

The following options are exposed as `defcustom` variables:

- API endpoint, empty by default
- API key, empty by default; when empty, the `Authorization` header is
  omitted
- Model, empty by default
- Temperature, defaulting to `1.0`
- System prompt, with a sensible default that makes Doctor Boring
  brief, curious, mildly repetitive, playful, and inclined to respond
  in plain prose
- Initial greeting, with a sensible fixed default
- Request timeout, defaulting to 300 seconds

No arbitrary additional request fields are required in the initial
version.

## Implementation constraints

- The implementation is pure Emacs Lisp.
- It may use libraries bundled with the latest Emacs release.
- It must not require third-party Emacs packages or external
  executables. `markdown-mode` support is optional and must degrade
  gracefully when it is absent.
- The initial implementation consists of one installable package file,
  `doctor-boring.el`, and an ERT test file,
  `doctor-boring-test.el`.
- Tests must not contact a real API. They should mock networking and
  cover at least request construction, buffer-to-history conversion,
  submission behavior, asynchronous state, and failure rollback.

## Package metadata

- Version: `0.1.0`
- Author: `MetroWind <chris.corsair@gmail.com>`
- License: WTFPL