Skip to content
44 changes: 44 additions & 0 deletions .github/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,26 @@ itself rather than reconstructing it at tag time.
Purely local setups (`npx opendia`, Claude Desktop over stdio, the browser
extension) are unaffected and need no token. (#55)

- **The `prompts/*` workflow surface is gone.** `prompts/list`, `prompts/get` and
the six workflow prompts (`post_to_social`, `post_selected_quote`,
`research_workflow`, `analyze_browsing_session`, `organize_tabs`, `fill_form`)
have been removed. They were unreachable in practice: the server never declared
a `prompts` capability during `initialize`, and `prompts/get` replied with
`{ content: [...] }` where the spec requires `{ messages: [...] }`, so
spec-compliant clients never called them. Tools are unaffected.

### Security

- **`--token=` with an empty value disabled authentication entirely.** The flag was
matched with `startsWith('--token=')`, so a bare `--token=` produced an empty
token, and the request guard treated an empty token as "no auth configured" and
waved every request through. The startup banner was gated the same way, so
nothing was printed — `--tunnel --token=` published an unauthenticated
browser-control endpoint with no visible sign, defeating the boundary added in
#55. `--http-host=` had the same bug and bound all interfaces. Empty flag values
are now a startup error, and invalid `--port` values fail with a readable message
instead of an unhandled rejection.

- Bind the extension control channel to loopback and gate its handshake. The
WebSocket server listened on all interfaces, and because the connection handler
hands the extension slot to whoever connects last, any reachable peer could evict
Expand All @@ -44,6 +62,32 @@ itself rather than reconstructing it at tag time.
stopgap — removal is tracked in #58. (#56)
- Bump `node-forge` to 1.4.0 and `brace-expansion` to 1.1.15. (#43)

### Fixed

- **Tools no longer report failures to the model as success.** `get_history`
rendered a browser API failure as "No history items found", `get_selected_text`
rendered four distinct failures as "No text selected", `page_navigate` claimed
success when its wait condition had timed out, and the research workflow claimed
it had bookmarked a page after the bookmark call failed. Each now surfaces the
real error. The genuine empty cases still report normally.
- **A dropped connection no longer executes tools anyway.** The extension's
connection helper resolved without waiting for the socket to open and swallowed
connection failures, so a tool call proceeded even when the server was
unreachable — `tab_close` and `element_click` ran against the browser while the
reply was written to a socket that was still connecting and discarded. The model
saw only a generic "Tool call timeout" and would reasonably retry a side effect.
Connections now resolve on open and fail loudly, and Chrome reuses a live socket
instead of replacing the one the request arrived on.

### Removed

- The enhanced-pattern matching tier in the content script. It had never executed:
its guard referenced an identifier declared nowhere in the codebase, so it threw
on every call and the failure was swallowed, silently degrading `page_analyze` to
a viewport scan. The legacy single-phase analysis engine went with it — reaching
it required a `phase` value that both tool schemas forbid. `page_analyze` output
is unchanged, because none of the removed code could run.

### Maintenance

- Dependency bumps: `ws` (#52), `web-ext` (#48), `actions/checkout` 4 → 7 (#46),
Expand Down
9 changes: 5 additions & 4 deletions opendia-extension/build.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,6 @@ async function buildForBrowser(browser) {
if (await fs.pathExists('logo.mp4')) {
await fs.copy('logo.mp4', path.join(buildDir, 'logo.mp4'));
}
if (await fs.pathExists('logo.webm')) {
await fs.copy('logo.webm', path.join(buildDir, 'logo.webm'));
}

// Copy browser-specific manifest
await fs.copy(
Expand Down Expand Up @@ -180,7 +177,11 @@ if (require.main === module) {
buildForBrowser('firefox');
break;
case 'validate':
validateAllBuilds();
// Exit non-zero on failure, or the CI "Validate builds" step passes
// whatever validateAllBuilds() reports.
validateAllBuilds().then((ok) => {
if (!ok) process.exit(1);
});
break;
case 'package':
buildAll().then(() => createPackages());
Expand Down
Loading