Skip to content

Releases: DuckTapeKiller/dive

5.0.6

Choose a tag to compare

@DuckTapeKiller DuckTapeKiller released this 03 Aug 00:32

Dive 5.0.6

A release about trust. Dive now tells you when it drops something, stops when you tell it to stop, and comes with documentation that matches what the code actually does.

Highlights

Deep research is now an evidence pipeline, not a bigger web search. Orientation, multiple research angles, candidate ranking, page-quality validation, deduplication, domain-diverse selection, and a structured dossier. It rejects CAPTCHA and bot-protection pages, raw HTML, paywalls, error payloads and syndicated duplicates instead of passing them off as evidence — and it no longer pads an answer with weak sources to reach a count.

Four new encyclopedic sources. Larousse (French), Scholarpedia (specialist science), Store norske leksikon (Norwegian), alongside Wikipedia and Britannica. Answers stay in your language even when the evidence is not.

Skills from the composer. Enable any of 17 skills to appear as a button above the input. Clicking inserts its slash command. Per mode, and never in Pi.

Source pills everywhere. One renderer for every mode and skill. Deep research reads only its own verified manifest, so links inside fetched article text can never become sources.

Archive recovery. Unreachable pages are retried through the Wayback Machine and archive.ph, labelled with the service, archived URL, original URL and capture date, and treated as historical rather than current.

Fixes

Stop actually stops. Pressing Stop tore down the browser's connection while the model kept generating. Every mode now tears down the upstream connection — for Cloud, that is billed tokens you cancelled. Pi additionally sends real abort_bash, abort_retry and abort commands, in that order, so sub-activities stop before the agent does.

Quitting is instant. Shutdown always took five seconds and exited with an error, because the app-event stream was never closed and the server waited on it. Now 0.02 seconds and a clean exit.

No more placeholder bubbles. The pulsing drum icon that appeared before the model had said anything is gone. A turn that only runs a tool creates no answer bubble at all — the activity panel carries it, naming the tool as it runs. A related bug meant such turns came back as an empty bordered box when you reopened the conversation; the live path and the reload path now share one rule.

Attachments no longer vanish silently. Attach ten images and only eight reached the model, while your own message showed all ten. Anything dropped — past the eight-image limit, unreadable, or malformed — is now reported, and the turn still runs.

Malformed tool arguments are refused. They used to be logged where you would never see them and the skill run with no arguments, so it either failed for an unrelated reason or answered a question nobody asked. Skills that legitimately take no arguments are unaffected, and valid arguments that omit a field keep each skill's own defaults.

Pi reports failed library lookups. The streaming route said so; the non-streaming route swallowed it and returned an ordinary answer that was not grounded in your database and could not be told apart from one that was. An explicit /db request that cannot reach the library now fails instead of answering anyway.

Look-alike domains cannot borrow authority. Trusted domains were matched as substrings, so nih.gov.evil-mirror.com scored exactly the same as nih.gov, and cheap-university-essays.biz inherited institutional authority. Since authority decides what gets read and cited, a registered look-alike could walk into your research. Now matched by domain suffix.

Disambiguation buttons are precise. When research finds several possible people, only the exact name is clickable — the description stays as ordinary text. Previously an entire bullet or heading could become one button.

The skill launcher stays in its own mode. Buttons enabled in llama.cpp remained visible after switching to Pi. The composer is repainted on every mode change.

Grokipedia is blocked by host label on every fetch path, so subdomains and mirrors cannot slip through.

Also: a deep_etymology crash on a missing language, the Pi sandbox indicator reading the wrong file and reporting a sandbox that was not in force, and a Pi command path that silently blanked itself on restart when installed via a symlink.

Under the hood

  • One mode registry. Adding or changing a mode is a single-file edit.
  • Per-mode state accessors. Stale aliases that had to be re-pointed on every mode change are gone — they were the cause of skills and settings showing the wrong mode's data.
  • skills.js split from 4,679 lines into six focused modules.
  • Injectable data directory via DIVE_DATA_DIR, so tests never touch your real data.
  • Whole-program frontend lint catching cross-file reference errors that per-file linting cannot see.
  • 406 tests, up from 52. Every one verified by breaking the code it covers and confirming it fails.

Documentation

Thirteen documents in [docs/](https://claude.ai/epitaxy/docs/README.md) covering architecture, modes, the HTTP API, all 27 skills, slash commands, Pi, the library, MCP, plugins, security, the data directory, development and testing. Written from the code, with every limit and default checked against its source.

Notes for existing users

  • No migration needed. Your ~/dive directory is unchanged.
  • Cloud API keys are never sent back to the client.
  • If a fix appears missing after updating, rebuild — the packaged app copies its files to a runtime directory on launch, and a stale build faithfully reproduces stale behaviour.

5.0.5

Choose a tag to compare

@DuckTapeKiller DuckTapeKiller released this 01 Aug 11:57

Dive 5.0.5

  • Restored Pi-mode sandbox permission prompts in RPC sessions.
  • Added RPC compatibility for the current pi-sandbox permission flow.
  • Preserved fail-closed permission handling and existing sandbox semantics.
  • Updated security documentation for the active npm:pi-sandbox configuration.
  • Added regression tests for the Pi RPC permission bridge.
  • Updated the application version to 5.0.5.
  • Verified with 212 passing tests.

5.0.4

Choose a tag to compare

@DuckTapeKiller DuckTapeKiller released this 01 Aug 02:40

Dive 5.0.4

Highlights

  • Added selectable media previews for BBC, RTVE, playlists, series, feeds, and generic media pages.
  • Added metadata-rich previews with dates, durations, descriptions, availability, stable URLs, and episode details.
  • Added asynchronous selected media and gallery downloads.
  • Added concise side-panel download status with subtle animated accent indicators.
  • Added safe handling for invalid, expired, empty, and cancelled selections.
  • Added configurable media discovery rules for unsupported collection pages.
  • Added explicit BBC audio/video clarification for ambiguous programme URLs.
  • Improved FFmpeg and FFprobe discovery for yt-dlp downloads.
  • Preserved standard confirmation before downloads.
  • Added regression coverage for media previews, background jobs, and status UI.

Validation

  • 209 tests passing.
  • ESLint passing.
  • Prettier passing.
  • ARM64 macOS build verified.

5.0.3

Choose a tag to compare

@DuckTapeKiller DuckTapeKiller released this 30 Jul 23:13

Dive 5.0.3 — model and port selection stays in step

Which model is loaded, and on which port, was stored in three config files and cached again in the browser. Every write path updated only the copy it happened to own, so the same defect kept surfacing in a new place. One module now owns those copies and all writes go through it.

Fixed

  • Deleting a model left the startup choice and the model dropdown still naming it. The next message asked the server for a model that no longer existed, and autostart tried to load it again on the next launch.
  • Changing SERVER PORT moved neither derived address. The chat URL righted itself on the next model load; the library's embedding URL never did, so database search silently kept calling the old port.
  • Loading a model from the MODELS tab left both dropdowns naming the model it replaced. Because a message sends that name explicitly, the next message loaded the old model back over the one just loaded.
  • The dropdown in settings did not update when the one in the side panel changed, and the side panel could sit on "Automatic" at startup while a model was actually selected.
  • Changing CONTEXT unloaded the model and never loaded it again. Applying a new context requires restarting the model server, and what came back was empty. Whatever was loaded is now put back afterwards.
  • Deleting or downloading a model also unloaded whatever else was running, for the same reason. Fixed by the same change.
  • Changing CONTEXT, GPU layers, threads, batch size, flash attention, mlock, cache type or the embedding flag did nothing at all when Dive runs its own model server — the value was saved but the running process kept its old settings, while the token counter reported the new one. The model is now reloaded so the change takes effect.

Changed

  • Loading an embedding model no longer silently does nothing to database search. Dive adopts the new model only when it can confirm the server is serving it, and never when doing so would invalidate an existing index — it tells you to re-index instead. This protects your existing embeddings from being discarded without warning.

5.0.2

Choose a tag to compare

@DuckTapeKiller DuckTapeKiller released this 30 Jul 20:06

Dive 5.0.2

llama.cpp router support now works without configuration

Preset sync previously had to be enabled by hand, with two .ini paths and two LaunchAgent labels typed into settings. All four defaulted to empty, so on a fresh install the feature did nothing.

Dive now reads the preset file and models directory from the running llama-server process, and restarts it by signal — launchd's KeepAlive brings it back. The five settings fields are gone; the MODELS tab reports the routers it detected instead. If no router is running, Dive manages its own servers as before and none of this applies.

Downloading a model now writes it into the router's preset and restarts the router, so it is usable immediately. Deleting one removes its entry the same way.

Fixed

  • The CONTEXT slider was ignored for any model served by a router, which loaded at its trained maximum instead. On a small model with a very long context window this could request more memory than the machine had. The chosen context is now written into the preset, capped at the model's trained maximum.
  • The token counter now follows the slider rather than lagging a reload behind it.
  • Embedding models could not be loaded or unloaded from the MODELS tab when their preset section was named for something other than the file. Loading failed outright; unloading reported success while leaving the model resident. Models are now matched by file path rather than by name.
  • Tool calling failed on models whose preset lacked a Jinja chat template. jinja is now written into generated sections, and the fallback that drops native tools correctly recognises llama.cpp's error.
  • Dive could take the router's port during a restart, leaving the router unable to rebind and serving one model where the preset served several. Loads now wait for the restart to finish.

Added

  • MERGE SYSTEM PROMPTS, a per-model option under ADVANCED, off by default. Dive normally sends the assistant policy, database context and skills policy as separate system messages. Some chat templates reject any system message after the first and fail the request; enable this for those models only.

Changed

  • New models start at 20480 context instead of 4096. Existing models keep their saved value.

Upgrading

Nothing to do. Any preset paths and LaunchAgent labels previously saved are ignored and removed from the config on next save. Preset files are backed up before first modification.

5.0.1

Choose a tag to compare

@DuckTapeKiller DuckTapeKiller released this 29 Jul 07:43

5.0.1
Fix: new models are now registered and usable without editing the .ini by hand

Downloading a model and trying to load it failed with "is not registered in the external llama-server", and the only way out was to add it to the preset manually — the exact thing preset sync exists to prevent.

Two causes, both fixed:

Every chat model now gets a preset section. Sync had been skipping plain chat models on the assumption that --models-dir would find them. It doesn't — a router scans that folder once, at startup, so anything downloaded later is invisible to it. Worse, since no section was written the preset never changed, so the restart that would have picked the model up never ran either. Vision models only worked by accident, because their mmproj line happened to change the file.
A plist filename is now accepted as the LaunchAgent label. launchd wants the Label (com.user.llamacpp-router), but the field invited pasting the filename (com.user.llamacpp-router.plist). The mismatch silently failed the restart. A trailing .plist is stripped, and a full path is reduced to its basename.

5.0.0

Choose a tag to compare

@DuckTapeKiller DuckTapeKiller released this 28 Jul 20:25

5.0.0
Markdown rendering in notes

Notes were written in Markdown but displayed as raw source. A new PREVIEW / EDIT toggle in the notes header renders the current note properly — headings, emphasis, lists, tables, blockquotes, links, and syntax-highlighted code blocks.

Uses the same renderer and sanitizer as chat messages
The editor stays the single source of truth; the preview is read-only and never written back, so rendering can't alter a saved note
Links open outside the app window
If the renderer ever fails, it falls back to raw text rather than a blank pane
Fix: app icon looked wrong in Finder

Broken since 4.0.8, when a dependency update swapped electron-builder's native icon converter for a WASM one. That converter writes oversized images into two .icns slots (128x128@2x and 256x256@2x), and macOS scales by the declared size — so those rendered at double scale, cropped and aliased. The Dock reads a different, correct slot, which is why only Finder looked wrong.

Dive now ships a pre-built icon.icns, verified slot by slot. electron-builder copies a supplied .icns verbatim, so this can't regress on a future dependency bump. The icon artwork itself was never at fault.

Testing

Fixed a gap where the DOM test harness never loaded the Markdown and sanitizer libraries, leaving every Markdown path in the app effectively untested.

4.0.9

Choose a tag to compare

@DuckTapeKiller DuckTapeKiller released this 27 Jul 23:44

4.0.9

Queue messages while a response is streaming

Typing a follow-up mid-answer used to kill the reply — Enter was wired straight to Stop. Now text in the box means "send it next": Enter queues the message and it goes out when the run finishes. Works in every mode, including Pi runs that continue on the event channel after the stream closes.

  • Queued messages show as pills above the composer, each removable
  • An empty box still means Stop, so that gesture is unchanged
  • Stop discards the queue
  • The queue stays with the mode and conversation it was typed in — it will never fire into a transcript you've left
  • Attachments go with their message; the composer is free immediately

llama.cpp router preset sync (optional, off by default)

For setups running llama-server in router mode from a LaunchAgent, Dive keeps --models-preset .ini files in step with the models folder: embedding models get their section on download and lose it on delete, and vision models are paired with their mmproj projector.

  • Writes only to paths you enter, and only between its own markers — your comments, [*] globals and hand-written sections are untouched
  • Won't re-create a section that already exists, so an embedding alias keeps the name your vector index is keyed to
  • .dive-backup on first write; atomic replace
  • Deletion rewrites the preset before removing the file
  • Restarts only the embedding router, never mid-index, never the chat router

Fix: embedding server URL reverting to the chat port

In Database settings, correcting the embedding port and saving appeared to do nothing — the field snapped back. It was rebuilt on every render from a routed value using llama.cpp's chat port instead of the embedding port (chat + 1), and the stale value was written back to disk on the next save. Saved URLs now survive; auto-routing only replaces the untouched default.

4.0.8

Choose a tag to compare

@DuckTapeKiller DuckTapeKiller released this 26 Jul 10:29

Dive 4.0.8

Permission prompts always appear. A tool that needed your approval could be denied without ever asking you: the prompt stayed hidden while its timer ran out, and outside Pi mode there was no button to reveal it either. The dialog now opens by itself in every mode — llama.cpp, LM Studio, Ollama, Cloud and Pi.

  • The PERMISSION button in the top bar now shows up wherever a request is pending, restyled to match the rest of the bar. It reopens the prompt if you close it.
  • The prompt shows a countdown, so an answer applied on your behalf is never a surprise.
  • A prompt that expires is no longer reported to the model as "the user denied this" — it's told the request timed out and to ask you again.
  • The Auto-open permission dialogs setting is gone. A prompt that could be hidden while its clock ran was the bug.

Security update. DOMPurify updated to 3.4.12 ([GHSA-c2j3-45gr-mqc4](GHSA-c2j3-45gr-mqc4)); tar and electron-builder updated too. Message rendering is unchanged — output was compared across both versions over markdown, code, tables, images and XSS payloads with identical results.

4.0.7

Choose a tag to compare

@DuckTapeKiller DuckTapeKiller released this 25 Jul 11:35

Dive 4.0.7

Image attachments now stay with the conversation. An attached image used to exist only for the one request it was sent with — the model lost sight of it on the next turn, so asking a follow-up meant attaching it again, and reopening the conversation showed the turn with its thumbnail gone. Images are now stored once, kept in history, and re-sent to the model automatically.

Fixed along with it:

  • A tool call mid-turn no longer drops the image before the answer.
  • REGEN re-sends the image instead of regenerating blind.
  • Sending a message the instant a file is dropped waits for the upload; the composer shows an "Uploading…" pill.
  • Vision models are told explicitly that attached images are visible to them, so they stop replying "please provide the image".

New: export a conversation as Markdown. A download button beside the attach control saves the whole session to your Downloads folder — every turn with its attachments, the model's reasoning, the tools it ran and the library passages it was given.