Commit graph

234 commits

Author SHA1 Message Date
Luis Novo
23b51faf9f
docs: development docs match the codebase; add-a-provider playbook (#1458)
* docs: development docs match the codebase; add-a-provider playbook

- architecture.md: rewritten as a ~110-line map verified against the code
  (processes, layout, data model from the migrations, graphs, model calls,
  background jobs); links the accurate topic pages
- testing.md, api-reference.md, code-standards.md: rewritten from the real
  suite, the /api prefix and Bearer auth, and the actual error-handling
  pattern (no longer contradicts AGENTS.md)
- change-playbooks.md: new "Add an AI provider" playbook (registry + the four
  hand-maintained copies + tests + docs, checked against #1443/#1444); fixes
  async nodes, command registration, polling paths, locale steps
  (LanguageToggle, satisfies TranslationShape), colocated frontend tests
- development-setup.md is the single setup page (deps, .env with localhost
  SURREAL_URL, DB -> API -> worker -> frontend, real log lines, /health);
  quick-start.md and README.dev.md point to it
- contributing.md: Conventional Commits, CHANGELOG rule, pre-PR checks that
  match CI; PR template gains ruff format and frontend checks
- AGENTS files agree with the docs (provider edits, routers vs services,
  async nodes, checkpoint path, ADR-013, stop_on); api/AGENTS.md is a plain
  link instead of a Claude-only @ import
- ADR index explains ADR-010 (reserved for #1332) and number-at-merge;
  GitHub-compatible encryption anchor; small credentials/security fixes

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* docs: address review (CI commands, async source creation, paths, ADR-010, language toggle)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 23:06:36 -03:00
Luis Novo
37217b01de
fix: error hints, Italian in the language menu and dev fallbacks (docs review) (#1457)
* fix: error hints, Italian menu entry and dev fallbacks found by the docs review

- error_classifier: read timeouts get their own message naming
  ESPERANTO_LLM_TIMEOUT; connect failures keep "Could not connect".
  Auth hint points to Manage -> Models; provision's "Please go to
  Manage" message is recognized again.
- Podcast voice hint and the empty-episodes text point to real screens.
- LanguageToggle renders the registered languages list, so it-IT shows
  up (and future locales can't be missed); it-IT date locale added.
  The per-language common.* labels it used are removed.
- make start-all uses the shipped compose file.
- Legacy SURREAL_ADDRESS/SURREAL_PORT fallback builds ws://host:port/rpc.
- .env.example uses the real OPEN_NOTEBOOK_CHUNK_* names.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix: address review (IPv6 legacy address, connection-timed-out wording, stronger tests)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* test: assert exception class for OS connection timeouts

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 22:51:31 -03:00
Luis Novo
60e3c2161e
fix(podcasts): unconfigured speaker profiles no longer break generation (#1454)
generate_podcast_command hands every speaker profile to podcast-creator,
whose SpeakerProfile requires tts_provider/tts_model. Profiles without a
voice model (the seeded business_panel / solo_expert ship that way) were
kept without those fields, so SpeakerConfig validation failed for every
podcast, even when generating with a complete profile.

Speaker profiles without a voice model are now removed from the config with
a warning, like unresolvable episode profiles. The selected profile is never
removed: it is validated earlier and still fails with a clear error. The
test validates the resulting config with podcast-creator's SpeakerConfig.

Closes #1450

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 09:44:51 -03:00
dependabot[bot]
be03e57d5c
chore(deps): bump the all-npm group in /frontend with 38 updates (#1417)
* chore(deps): bump the all-npm group in /frontend with 38 updates

Bumps the all-npm group in /frontend with 38 updates:

| Package | From | To |
| --- | --- | --- |
| [@hookform/resolvers](https://github.com/react-hook-form/resolvers) | `5.1.1` | `5.9.1` |
| [@radix-ui/react-accordion](https://github.com/radix-ui/primitives/tree/HEAD/packages/react/accordion) | `1.2.12` | `1.2.20` |
| [@radix-ui/react-alert-dialog](https://github.com/radix-ui/primitives/tree/HEAD/packages/react/alert-dialog) | `1.1.14` | `1.1.23` |
| [@radix-ui/react-checkbox](https://github.com/radix-ui/primitives/tree/HEAD/packages/react/checkbox) | `1.3.2` | `1.3.11` |
| [@radix-ui/react-collapsible](https://github.com/radix-ui/primitives/tree/HEAD/packages/react/collapsible) | `1.1.12` | `1.1.20` |
| [@radix-ui/react-dialog](https://github.com/radix-ui/primitives/tree/HEAD/packages/react/dialog) | `1.1.15` | `1.1.23` |
| [@radix-ui/react-dropdown-menu](https://github.com/radix-ui/primitives/tree/HEAD/packages/react/dropdown-menu) | `2.1.15` | `2.1.24` |
| [@radix-ui/react-label](https://github.com/radix-ui/primitives/tree/HEAD/packages/react/label) | `2.1.7` | `2.1.15` |
| [@radix-ui/react-popover](https://github.com/radix-ui/primitives/tree/HEAD/packages/react/popover) | `1.1.15` | `1.1.23` |
| [@radix-ui/react-progress](https://github.com/radix-ui/primitives/tree/HEAD/packages/react/progress) | `1.1.7` | `1.1.16` |
| [@radix-ui/react-radio-group](https://github.com/radix-ui/primitives/tree/HEAD/packages/react/radio-group) | `1.3.8` | `1.4.7` |
| [@radix-ui/react-scroll-area](https://github.com/radix-ui/primitives/tree/HEAD/packages/react/scroll-area) | `1.2.9` | `1.2.18` |
| [@radix-ui/react-select](https://github.com/radix-ui/primitives/tree/HEAD/packages/react/select) | `2.2.5` | `2.3.7` |
| [@radix-ui/react-separator](https://github.com/radix-ui/primitives/tree/HEAD/packages/react/separator) | `1.1.7` | `1.1.15` |
| [@radix-ui/react-slot](https://github.com/radix-ui/primitives/tree/HEAD/packages/react/slot) | `1.2.3` | `1.3.3` |
| [@radix-ui/react-tabs](https://github.com/radix-ui/primitives/tree/HEAD/packages/react/tabs) | `1.1.12` | `1.1.21` |
| [@radix-ui/react-tooltip](https://github.com/radix-ui/primitives/tree/HEAD/packages/react/tooltip) | `1.2.7` | `1.2.16` |
| [@tailwindcss/typography](https://github.com/tailwindlabs/tailwindcss-typography) | `0.5.16` | `0.5.20` |
| [@tanstack/react-query](https://github.com/TanStack/query/tree/HEAD/packages/react-query) | `5.83.0` | `5.103.3` |
| [@uiw/react-md-editor](https://github.com/uiwjs/react-md-editor) | `4.0.8` | `4.1.2` |
| [date-fns](https://github.com/date-fns/date-fns) | `4.1.0` | `4.4.0` |
| [i18next-browser-languagedetector](https://github.com/i18next/i18next-browser-languageDetector) | `8.2.0` | `8.2.1` |
| [katex](https://github.com/KaTeX/KaTeX) | `0.16.47` | `0.18.9` |
| [react](https://github.com/react/react/tree/HEAD/packages/react) | `19.2.3` | `19.3.0` |
| [@types/react](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/react) | `19.1.8` | `19.3.0` |
| [react-dom](https://github.com/react/react/tree/HEAD/packages/react-dom) | `19.2.3` | `19.3.0` |
| [@types/react-dom](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/react-dom) | `19.1.6` | `19.3.0` |
| [react-hook-form](https://github.com/react-hook-form/react-hook-form) | `7.60.0` | `7.89.0` |
| [sonner](https://github.com/emilkowalski/sonner) | `2.0.6` | `2.0.8` |
| [tailwind-merge](https://github.com/dcastil/tailwind-merge/tree/HEAD/packages/tailwind-merge) | `3.3.1` | `3.7.0` |
| [use-debounce](https://github.com/xnimorz/use-debounce) | `10.0.6` | `10.1.1` |
| [zod](https://github.com/colinhacks/zod) | `4.0.5` | `4.6.5` |
| [zustand](https://github.com/pmndrs/zustand) | `5.0.6` | `5.0.15` |
| [@eslint/eslintrc](https://github.com/eslint/eslintrc) | `3.3.1` | `3.3.7` |
| [@tailwindcss/postcss](https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/@tailwindcss-postcss) | `4.1.11` | `4.3.3` |
| [@testing-library/react](https://github.com/testing-library/react-testing-library) | `16.3.1` | `16.3.3` |
| [tailwindcss](https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/tailwindcss) | `4.1.11` | `4.3.3` |
| [tw-animate-css](https://github.com/Wombosvideo/tw-animate-css) | `1.3.5` | `1.4.0` |


Updates `@hookform/resolvers` from 5.1.1 to 5.9.1
- [Release notes](https://github.com/react-hook-form/resolvers/releases)
- [Commits](https://github.com/react-hook-form/resolvers/compare/v5.1.1...v5.9.1)

Updates `@radix-ui/react-accordion` from 1.2.12 to 1.2.20
- [Changelog](https://github.com/radix-ui/primitives/blob/main/packages/react/accordion/CHANGELOG.md)
- [Commits](https://github.com/radix-ui/primitives/commits/HEAD/packages/react/accordion)

Updates `@radix-ui/react-alert-dialog` from 1.1.14 to 1.1.23
- [Changelog](https://github.com/radix-ui/primitives/blob/main/packages/react/alert-dialog/CHANGELOG.md)
- [Commits](https://github.com/radix-ui/primitives/commits/HEAD/packages/react/alert-dialog)

Updates `@radix-ui/react-checkbox` from 1.3.2 to 1.3.11
- [Changelog](https://github.com/radix-ui/primitives/blob/main/packages/react/checkbox/CHANGELOG.md)
- [Commits](https://github.com/radix-ui/primitives/commits/HEAD/packages/react/checkbox)

Updates `@radix-ui/react-collapsible` from 1.1.12 to 1.1.20
- [Changelog](https://github.com/radix-ui/primitives/blob/main/packages/react/collapsible/CHANGELOG.md)
- [Commits](https://github.com/radix-ui/primitives/commits/HEAD/packages/react/collapsible)

Updates `@radix-ui/react-dialog` from 1.1.15 to 1.1.23
- [Changelog](https://github.com/radix-ui/primitives/blob/main/packages/react/dialog/CHANGELOG.md)
- [Commits](https://github.com/radix-ui/primitives/commits/HEAD/packages/react/dialog)

Updates `@radix-ui/react-dropdown-menu` from 2.1.15 to 2.1.24
- [Changelog](https://github.com/radix-ui/primitives/blob/main/packages/react/dropdown-menu/CHANGELOG.md)
- [Commits](https://github.com/radix-ui/primitives/commits/HEAD/packages/react/dropdown-menu)

Updates `@radix-ui/react-label` from 2.1.7 to 2.1.15
- [Changelog](https://github.com/radix-ui/primitives/blob/main/packages/react/label/CHANGELOG.md)
- [Commits](https://github.com/radix-ui/primitives/commits/HEAD/packages/react/label)

Updates `@radix-ui/react-popover` from 1.1.15 to 1.1.23
- [Changelog](https://github.com/radix-ui/primitives/blob/main/packages/react/popover/CHANGELOG.md)
- [Commits](https://github.com/radix-ui/primitives/commits/HEAD/packages/react/popover)

Updates `@radix-ui/react-progress` from 1.1.7 to 1.1.16
- [Changelog](https://github.com/radix-ui/primitives/blob/main/packages/react/progress/CHANGELOG.md)
- [Commits](https://github.com/radix-ui/primitives/commits/HEAD/packages/react/progress)

Updates `@radix-ui/react-radio-group` from 1.3.8 to 1.4.7
- [Changelog](https://github.com/radix-ui/primitives/blob/main/packages/react/radio-group/CHANGELOG.md)
- [Commits](https://github.com/radix-ui/primitives/commits/HEAD/packages/react/radio-group)

Updates `@radix-ui/react-scroll-area` from 1.2.9 to 1.2.18
- [Changelog](https://github.com/radix-ui/primitives/blob/main/packages/react/scroll-area/CHANGELOG.md)
- [Commits](https://github.com/radix-ui/primitives/commits/HEAD/packages/react/scroll-area)

Updates `@radix-ui/react-select` from 2.2.5 to 2.3.7
- [Changelog](https://github.com/radix-ui/primitives/blob/main/packages/react/select/CHANGELOG.md)
- [Commits](https://github.com/radix-ui/primitives/commits/HEAD/packages/react/select)

Updates `@radix-ui/react-separator` from 1.1.7 to 1.1.15
- [Changelog](https://github.com/radix-ui/primitives/blob/main/packages/react/separator/CHANGELOG.md)
- [Commits](https://github.com/radix-ui/primitives/commits/HEAD/packages/react/separator)

Updates `@radix-ui/react-slot` from 1.2.3 to 1.3.3
- [Changelog](https://github.com/radix-ui/primitives/blob/main/packages/react/slot/CHANGELOG.md)
- [Commits](https://github.com/radix-ui/primitives/commits/HEAD/packages/react/slot)

Updates `@radix-ui/react-tabs` from 1.1.12 to 1.1.21
- [Changelog](https://github.com/radix-ui/primitives/blob/main/packages/react/tabs/CHANGELOG.md)
- [Commits](https://github.com/radix-ui/primitives/commits/HEAD/packages/react/tabs)

Updates `@radix-ui/react-tooltip` from 1.2.7 to 1.2.16
- [Changelog](https://github.com/radix-ui/primitives/blob/main/packages/react/tooltip/CHANGELOG.md)
- [Commits](https://github.com/radix-ui/primitives/commits/HEAD/packages/react/tooltip)

Updates `@tailwindcss/typography` from 0.5.16 to 0.5.20
- [Release notes](https://github.com/tailwindlabs/tailwindcss-typography/releases)
- [Changelog](https://github.com/tailwindlabs/tailwindcss-typography/blob/main/CHANGELOG.md)
- [Commits](https://github.com/tailwindlabs/tailwindcss-typography/compare/v0.5.16...v0.5.20)

Updates `@tanstack/react-query` from 5.83.0 to 5.103.3
- [Release notes](https://github.com/TanStack/query/releases)
- [Changelog](https://github.com/TanStack/query/blob/main/packages/react-query/CHANGELOG.md)
- [Commits](https://github.com/TanStack/query/commits/@tanstack/react-query@5.103.3/packages/react-query)

Updates `@uiw/react-md-editor` from 4.0.8 to 4.1.2
- [Release notes](https://github.com/uiwjs/react-md-editor/releases)
- [Commits](https://github.com/uiwjs/react-md-editor/compare/v4.0.8...v4.1.2)

Updates `date-fns` from 4.1.0 to 4.4.0
- [Release notes](https://github.com/date-fns/date-fns/releases)
- [Commits](https://github.com/date-fns/date-fns/compare/v4.1.0...v4.4.0)

Updates `i18next-browser-languagedetector` from 8.2.0 to 8.2.1
- [Changelog](https://github.com/i18next/i18next-browser-languageDetector/blob/master/CHANGELOG.md)
- [Commits](https://github.com/i18next/i18next-browser-languageDetector/compare/v8.2.0...v8.2.1)

Updates `katex` from 0.16.47 to 0.18.9
- [Release notes](https://github.com/KaTeX/KaTeX/releases)
- [Changelog](https://github.com/KaTeX/KaTeX/blob/main/CHANGELOG.md)
- [Commits](https://github.com/KaTeX/KaTeX/compare/v0.16.47...v0.18.9)

Updates `react` from 19.2.3 to 19.3.0
- [Release notes](https://github.com/react/react/releases)
- [Changelog](https://github.com/react/react/blob/main/CHANGELOG.md)
- [Commits](https://github.com/react/react/commits/v19.3.0/packages/react)

Updates `@types/react` from 19.1.8 to 19.3.0
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react)

Updates `react-dom` from 19.2.3 to 19.3.0
- [Release notes](https://github.com/react/react/releases)
- [Changelog](https://github.com/react/react/blob/main/CHANGELOG.md)
- [Commits](https://github.com/react/react/commits/v19.3.0/packages/react-dom)

Updates `@types/react-dom` from 19.1.6 to 19.3.0
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react-dom)

Updates `react-hook-form` from 7.60.0 to 7.89.0
- [Release notes](https://github.com/react-hook-form/react-hook-form/releases)
- [Changelog](https://github.com/react-hook-form/react-hook-form/blob/master/CHANGELOG.md)
- [Commits](https://github.com/react-hook-form/react-hook-form/compare/v7.60.0...v7.89.0)

Updates `sonner` from 2.0.6 to 2.0.8
- [Release notes](https://github.com/emilkowalski/sonner/releases)
- [Commits](https://github.com/emilkowalski/sonner/compare/v2.0.6...v2.0.8)

Updates `tailwind-merge` from 3.3.1 to 3.7.0
- [Release notes](https://github.com/dcastil/tailwind-merge/releases)
- [Commits](https://github.com/dcastil/tailwind-merge/commits/tailwind-merge@3.7.0/packages/tailwind-merge)

Updates `use-debounce` from 10.0.6 to 10.1.1
- [Release notes](https://github.com/xnimorz/use-debounce/releases)
- [Changelog](https://github.com/xnimorz/use-debounce/blob/master/CHANGELOG.md)
- [Commits](https://github.com/xnimorz/use-debounce/commits)

Updates `zod` from 4.0.5 to 4.6.5
- [Release notes](https://github.com/colinhacks/zod/releases)
- [Commits](https://github.com/colinhacks/zod/compare/v4.0.5...v4.6.5)

Updates `zustand` from 5.0.6 to 5.0.15
- [Release notes](https://github.com/pmndrs/zustand/releases)
- [Commits](https://github.com/pmndrs/zustand/compare/v5.0.6...v5.0.15)

Updates `@eslint/eslintrc` from 3.3.1 to 3.3.7
- [Release notes](https://github.com/eslint/eslintrc/releases)
- [Changelog](https://github.com/eslint/eslintrc/blob/main/CHANGELOG.md)
- [Commits](https://github.com/eslint/eslintrc/compare/v3.3.1...eslintrc-v3.3.7)

Updates `@tailwindcss/postcss` from 4.1.11 to 4.3.3
- [Release notes](https://github.com/tailwindlabs/tailwindcss/releases)
- [Changelog](https://github.com/tailwindlabs/tailwindcss/blob/main/CHANGELOG.md)
- [Commits](https://github.com/tailwindlabs/tailwindcss/commits/v4.3.3/packages/@tailwindcss-postcss)

Updates `@testing-library/react` from 16.3.1 to 16.3.3
- [Release notes](https://github.com/testing-library/react-testing-library/releases)
- [Changelog](https://github.com/testing-library/react-testing-library/blob/main/CHANGELOG.md)
- [Commits](https://github.com/testing-library/react-testing-library/compare/v16.3.1...v16.3.3)

Updates `@types/react` from 19.1.8 to 19.3.0
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react)

Updates `@types/react-dom` from 19.1.6 to 19.3.0
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react-dom)

Updates `tailwindcss` from 4.1.11 to 4.3.3
- [Release notes](https://github.com/tailwindlabs/tailwindcss/releases)
- [Changelog](https://github.com/tailwindlabs/tailwindcss/blob/main/CHANGELOG.md)
- [Commits](https://github.com/tailwindlabs/tailwindcss/commits/v4.3.3/packages/tailwindcss)

Updates `tw-animate-css` from 1.3.5 to 1.4.0
- [Release notes](https://github.com/Wombosvideo/tw-animate-css/releases)
- [Commits](https://github.com/Wombosvideo/tw-animate-css/compare/v1.3.5...v1.4.0)

---
updated-dependencies:
- dependency-name: "@hookform/resolvers"
  dependency-version: 5.9.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: all-npm
- dependency-name: "@radix-ui/react-accordion"
  dependency-version: 1.2.20
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: all-npm
- dependency-name: "@radix-ui/react-alert-dialog"
  dependency-version: 1.1.23
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: all-npm
- dependency-name: "@radix-ui/react-checkbox"
  dependency-version: 1.3.11
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: all-npm
- dependency-name: "@radix-ui/react-collapsible"
  dependency-version: 1.1.20
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: all-npm
- dependency-name: "@radix-ui/react-dialog"
  dependency-version: 1.1.23
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: all-npm
- dependency-name: "@radix-ui/react-dropdown-menu"
  dependency-version: 2.1.24
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: all-npm
- dependency-name: "@radix-ui/react-label"
  dependency-version: 2.1.15
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: all-npm
- dependency-name: "@radix-ui/react-popover"
  dependency-version: 1.1.23
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: all-npm
- dependency-name: "@radix-ui/react-progress"
  dependency-version: 1.1.16
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: all-npm
- dependency-name: "@radix-ui/react-radio-group"
  dependency-version: 1.4.7
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: all-npm
- dependency-name: "@radix-ui/react-scroll-area"
  dependency-version: 1.2.18
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: all-npm
- dependency-name: "@radix-ui/react-select"
  dependency-version: 2.3.7
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: all-npm
- dependency-name: "@radix-ui/react-separator"
  dependency-version: 1.1.15
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: all-npm
- dependency-name: "@radix-ui/react-slot"
  dependency-version: 1.3.3
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: all-npm
- dependency-name: "@radix-ui/react-tabs"
  dependency-version: 1.1.21
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: all-npm
- dependency-name: "@radix-ui/react-tooltip"
  dependency-version: 1.2.16
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: all-npm
- dependency-name: "@tailwindcss/typography"
  dependency-version: 0.5.20
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: all-npm
- dependency-name: "@tanstack/react-query"
  dependency-version: 5.103.3
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: all-npm
- dependency-name: "@uiw/react-md-editor"
  dependency-version: 4.1.2
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: all-npm
- dependency-name: date-fns
  dependency-version: 4.4.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: all-npm
- dependency-name: i18next-browser-languagedetector
  dependency-version: 8.2.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: all-npm
- dependency-name: katex
  dependency-version: 0.18.9
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: all-npm
- dependency-name: react
  dependency-version: 19.3.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: all-npm
- dependency-name: "@types/react"
  dependency-version: 19.3.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: all-npm
- dependency-name: react-dom
  dependency-version: 19.3.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: all-npm
- dependency-name: "@types/react-dom"
  dependency-version: 19.3.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: all-npm
- dependency-name: react-hook-form
  dependency-version: 7.89.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: all-npm
- dependency-name: sonner
  dependency-version: 2.0.8
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: all-npm
- dependency-name: tailwind-merge
  dependency-version: 3.7.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: all-npm
- dependency-name: use-debounce
  dependency-version: 10.1.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: all-npm
- dependency-name: zod
  dependency-version: 4.6.5
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: all-npm
- dependency-name: zustand
  dependency-version: 5.0.15
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: all-npm
- dependency-name: "@eslint/eslintrc"
  dependency-version: 3.3.7
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: all-npm
- dependency-name: "@tailwindcss/postcss"
  dependency-version: 4.3.3
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: all-npm
- dependency-name: "@testing-library/react"
  dependency-version: 16.3.3
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: all-npm
- dependency-name: "@types/react"
  dependency-version: 19.3.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: all-npm
- dependency-name: "@types/react-dom"
  dependency-version: 19.3.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: all-npm
- dependency-name: tailwindcss
  dependency-version: 4.3.3
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: all-npm
- dependency-name: tw-animate-css
  dependency-version: 1.4.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: all-npm
...

Signed-off-by: dependabot[bot] <support@github.com>

* fix(deps): keep katex on 0.16 to match rehype-katex

The group bumped the direct katex dependency (which only provides
katex.min.css) to 0.18.9 while rehype-katex keeps rendering with its own
katex 0.16.47, so the stylesheet and the generated markup would come from
different versions. Keep katex on ^0.16.47 (deduped with rehype-katex) and
tell dependabot to skip katex >= 0.17 until rehype-katex moves.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GBYpxzSS62Y3TZkgB9NUZy

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Luis Novo <lfnovo@gmail.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 05:33:00 -03:00
Luis Novo
2c620647ea
feat(podcasts): adopt podcast-creator 0.13.1 (#1446)
Some checks are pending
Development Build / extract-version (push) Waiting to run
Development Build / changes (push) Waiting to run
Development Build / build-regular (push) Blocked by required conditions
Development Build / build-single (push) Blocked by required conditions
Development Build / summary (push) Blocked by required conditions
Tests / Backend Tests (push) Waiting to run
Tests / Backend Lint (push) Waiting to run
Tests / Backend Typecheck (push) Waiting to run
Tests / Frontend Tests (push) Waiting to run
Tests / Frontend Lint (push) Waiting to run
Tests / Frontend Build (push) Waiting to run
* feat(podcasts): adopt podcast-creator 0.13.1

podcast-creator 0.13 requests schema-validated JSON for outlines and
transcripts, raises the default output budget to 8192 tokens for both, and
adds a ~400 ms pause between turns; 0.13.1 falls back to plain JSON when an
endpoint rejects json_schema (lfnovo/podcast-creator#51).

- Floor raised to podcast-creator>=0.13.1.
- The episode profile's Max output tokens help no longer claims 3000/5000
  defaults (all 14 locales); docs cover the 8192 default, when to lower it,
  the turn pause and the JSON fallback.
- Tests render our shadowed prompts/podcast templates with the variables
  0.13 passes, and check they are ours (not the bundled ones).

Closes #1435

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GBYpxzSS62Y3TZkgB9NUZy

* fix(i18n): translate the full max tokens guidance in every locale

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GBYpxzSS62Y3TZkgB9NUZy

* fix(i18n): use Gesprächsrunde for 'turn' in the German max tokens help

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GBYpxzSS62Y3TZkgB9NUZy

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 23:19:53 -03:00
Luis Novo
4aadf88710
feat(sources): OpenDocument uploads and content-core 2.2 settings docs (#1445)
* feat(sources): OpenDocument uploads and content-core 2.2 settings docs

- Upload accepts .odt, .ods, .odp (content-core 2.2 office route) and .htm;
  the multi-file hint lists the OpenDocument formats in every locale.
- Docs: OpenDocument in the supported file types; CCORE_YOUTUBE_PROXY,
  CCORE_YOUTUBE_COOKIES_FILE and CCORE_AUDIO_SEGMENT_MINUTES in the
  environment reference (set on the worker; Compose example for cookies);
  a YouTube "blocked" note pointing at them.

Closes #1439

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GBYpxzSS62Y3TZkgB9NUZy

* fix(sources): close the cookies code block; list HTML/HTM in the upload hint

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GBYpxzSS62Y3TZkgB9NUZy

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 22:46:45 -03:00
Luis Novo
5f021c5405
fix(transformations): refuse to run on sources with no text (#1425)
Some checks are pending
Development Build / extract-version (push) Waiting to run
Tests / Backend Lint (push) Waiting to run
Tests / Backend Typecheck (push) Waiting to run
Development Build / changes (push) Waiting to run
Development Build / build-regular (push) Blocked by required conditions
Development Build / build-single (push) Blocked by required conditions
Development Build / summary (push) Blocked by required conditions
Tests / Frontend Lint (push) Waiting to run
Tests / Frontend Build (push) Waiting to run
Tests / Backend Tests (push) Waiting to run
Tests / Frontend Tests (push) Waiting to run
* fix(transformations): refuse to run on sources with no text

create_source_insight now returns 400 when the source's full_text is empty
or whitespace, so no job is queued, and run_transformation raises
InvalidInputError before calling the model as defence in depth. The source
detail view shows the server's reason instead of a generic error toast.

Closes #1394

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GBYpxzSS62Y3TZkgB9NUZy

* fix(transformations): raise InvalidInputError for empty sources

Uses the registered typed-exception handler instead of a bare HTTPException.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GBYpxzSS62Y3TZkgB9NUZy

* fix(transformations): address review on empty-source guard

- Worker: InvalidInputError is a permanent failure for run_transformation
  (stop_on + re-raise), so an empty source is not retried five times.
- Graph message is neutral ("There is no text content to transform"); it
  also guards the direct /transformations/execute path.
- UI: the empty-source error is mapped to a translated apiErrors key in all
  locales, and a network error without a server detail keeps the localized
  generic message.
- Tests assert the exact queued command and the worker's permanent failure.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GBYpxzSS62Y3TZkgB9NUZy

* fix(transformations): skip whitespace-only text in source processing

- transform_content (source graph) skips whitespace-only text like empty
  text, so process_source never hits the transformation graph's guard.
- The graph's message maps to the same translated key, and the polled
  command failure toast goes through getApiErrorMessage.
- Rename the worker test to what it checks (permanent-failure handling).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GBYpxzSS62Y3TZkgB9NUZy

* docs(changelog): move entry to avoid merge conflicts

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GBYpxzSS62Y3TZkgB9NUZy

* test(frontend): cover the empty-source error mapping

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GBYpxzSS62Y3TZkgB9NUZy

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 23:20:23 -03:00
Luis Novo
6b4c1f99b5
fix(notebooks,transformations): persist a cleared description (#1426)
* fix(notebooks,transformations): persist a cleared description

NotebookHeader and TransformationEditorDialog sent `description || undefined`,
so an empty description was dropped from the update. They now send it as-is
(a cleared transformation title falls back to the name, as on create). The
update endpoints use model_fields_set: an explicit "" or null clears the
field, an absent one leaves it untouched.

Closes #1396

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GBYpxzSS62Y3TZkgB9NUZy

* fix(transformations): leave title handling unchanged; test notebook clear

The form schema already requires a title, so the empty-title fallback was
unreachable; the title is sent as before. Adds a NotebookHeader test that
clearing the description sends `description: ""`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GBYpxzSS62Y3TZkgB9NUZy

* test(transformations): clearing the description sends an empty string

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GBYpxzSS62Y3TZkgB9NUZy

* docs(changelog): move entry to avoid merge conflicts

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GBYpxzSS62Y3TZkgB9NUZy

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 23:19:46 -03:00
Luis Novo
2aa58722f2
fix(source-chat): stream only the new answer; restore context badge on load (#1423)
* fix(source-chat): stream only the new answer; restore context badge on load

The SSE generator emitted an ai_message for every AI message in the
checkpointed history, and the hook concatenated them into one bubble. Only
the last message is emitted now. The session-load effect also sets the
context indicators returned by GET session, so the badge survives refresh.

Closes #1393

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GBYpxzSS62Y3TZkgB9NUZy

* fix(source-chat): clear context badge when the session goes away

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GBYpxzSS62Y3TZkgB9NUZy

* style: drop unrelated formatting changes

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GBYpxzSS62Y3TZkgB9NUZy

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 23:10:59 -03:00
Luis Novo
1b4443bf81
docs: design-system ADR, contributor styling rule, refreshed README brand (#1223)
* docs: design-system decision record, contributor styling rule, refreshed brand assets

- ADR-008: visual identity as a token contract in globals.css, reviewed
  through /dev/design (laws, dark-mode resolution constraint, hex
  rationale, alternatives)
- frontend/AGENTS.md: hard rule — styling via semantic tokens only, no
  raw palette classes or hand-written dark: twins
- README: new Quiet Green hero mark and a current workspace screenshot
  replacing the pre-redesign UI; drop a dead image reference

* docs: renumber design-token record to ADR-009 and index it

ADR-008 was taken by the notebook-scoped-search record (#1331) after this
branch was opened. Renames the file, updates the frontend/AGENTS.md link
and adds the missing index row.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NnMHW3qrSc8Nhi7xTPfZuv

* docs: renumber the design-token ADR to 011 and index ADR-009

ADR-009 was taken by the PBKDF2 credential record (#1360), which also
never got its row in decisions/README.md; ADR-010 is reserved for the
source-chat checkpointer bridge (#1332). Update the frontend/AGENTS.md
link accordingly.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ScFn54FhBq3cvVbcbQJjBZ

---------

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-03 01:39:19 +00:00
Cory Potter
cc5af65473
fix(frontend): silence noisy KaTeX warning on Unicode symbols in math spans (#1208)
* fix(frontend): silence noisy KaTeX warning on Unicode symbols

AI-generated content often contains Unicode punctuation (en/em dashes,
smart quotes) inside single-dollar math spans, e.g. a price range like
"$5 – $10". Models legitimately emit inline math as $...$ per this
project's own prompts ("MATH FORMATTING" sections), so remark-math
correctly reads it as math - but KaTeX's default strict mode then logs
a console warning for every character outside its symbol table.

The warning is harmless (KaTeX still renders a best-effort glyph) but
noisy: 66+ occurrences in a few days of normal use on one deployment.

Fix: pass KaTeX's own `strict` option as a function that ignores only
the `unknownSymbol` error code, leaving every other strict check (e.g.
deprecated commands) at its default. All three markdown-rendering call
sites (chat/insight/source rendering, the note editor live preview,
and the transformation playground) now share one KATEX_OPTIONS
constant instead of duplicating the same override three times.

Verified: 140/140 frontend tests pass (including the existing test
that asserts single-dollar inline math still renders via KaTeX),
tsc --noEmit clean, eslint clean (0 errors), production build clean.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

* address review: lock down unknownSymbol suppression with tests

Per cubic's review on this PR:
- Add a regression test asserting the em/en-dash-in-price-range
  pattern that motivated this fix produces no [unknownSymbol] warning,
  and a second test asserting a different strict violation
  ([commentAtEnd]) is still warned on - proving the ignore is scoped
  to exactly one error code, not silently widened.
- Reword the KATEX_OPTIONS comment: suppressing unknownSymbol isn't
  purely cosmetic. KaTeX's own parser falls back unrecognized
  codepoints to mode: 'text' rather than proper math-mode metrics, so
  an ignored symbol can render with approximated spacing rather than a
  real glyph. Acceptable for stray punctuation, not a blanket license
  to route arbitrary Unicode through math mode.

Verified: 142/142 frontend tests pass (up from 140 - the two new
tests), tsc --noEmit clean, eslint clean (0 errors).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
Co-authored-by: Luis Novo <lfnovo@gmail.com>
2026-10-03 01:19:46 +00:00
Luis Novo
30b8be9566
chore(deps): security update for frontend and Python dependencies (#1404)
Frontend: next 16.3.8 (critical next/og ImageResponse RCE advisory; the
app does not use next/og), axios 1.20.0, and the postcss (8.5.23) and
brace-expansion (1.1.21) npm overrides.

Python (uv.lock): anyio 4.14.2, pyjwt 2.15.1, tornado 6.5.10,
urllib3 2.8.0, virtualenv 21.14.5 (filelock 4.0.9 follows).

Dependabot now ignores odd-numbered (non-LTS) Node majors for the
image base. vitest stays at 4.1.9: the bump trips an npm 10 tree bug
and only clears moderate test-runner findings.


Claude-Session: https://claude.ai/code/session_01ScFn54FhBq3cvVbcbQJjBZ

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 01:07:22 +00:00
Aditya Raj Singh
4e390a792d
fix: show insights after long-running generation (#1346)
* fix: keep insight polling active until completion

* fix: harden insight polling lifecycle

* fix: handle terminal insight edge cases

---------

Co-authored-by: Luis Novo <lfnovo@gmail.com>
2026-10-01 01:51:09 +00:00
Aditya Raj Singh
ae7b96d376
fix(search): open matched records and deduplicate sources (#1345)
Some checks failed
Development Build / extract-version (push) Has been cancelled
Development Build / changes (push) Has been cancelled
Tests / Backend Tests (push) Has been cancelled
Tests / Backend Lint (push) Has been cancelled
Tests / Backend Typecheck (push) Has been cancelled
Tests / Frontend Tests (push) Has been cancelled
Tests / Frontend Lint (push) Has been cancelled
Tests / Frontend Build (push) Has been cancelled
Development Build / build-regular (push) Has been cancelled
Development Build / build-single (push) Has been cancelled
Development Build / summary (push) Has been cancelled
2026-09-11 01:24:00 +00:00
Matt Van Horn
a96f114dac
fix: open the note editor from Write Note (#1286) 2026-09-11 00:14:59 +00:00
dependabot[bot]
fce66d4435
chore(deps): bump sharp (#1319)
Bumps the npm-security group with 1 update in the /frontend directory: [sharp](https://github.com/lovell/sharp).


Updates `sharp` from 0.34.5 to 0.35.4
- [Release notes](https://github.com/lovell/sharp/releases)
- [Commits](https://github.com/lovell/sharp/compare/v0.34.5...v0.35.4)

---
updated-dependencies:
- dependency-name: sharp
  dependency-version: 0.35.4
  dependency-type: indirect
  dependency-group: npm-security
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Luis Novo <lfnovo@gmail.com>
2026-09-05 16:52:41 -03:00
Luis Novo
7d674bd53a
feat(search): scope Search and Ask to selected notebooks (#1331)
* feat(search): scope Search and Ask to selected notebooks

Search and Ask always ran against the whole knowledge base; `notebook_id`
was accepted by POST /api/search and silently ignored because the request
model never declared it. Both endpoints now take an optional notebook
scope and the Search/Ask page gets a shared notebook selector.

- Migration 24: fn::text_search / fn::vector_search gain an optional
  trailing `$notebook_ids: option<array<record<notebook>>>` parameter.
  NONE/empty keeps the unfiltered path; otherwise sources are limited via
  the `reference` edge and notes via the `artifact` edge (chunks and
  insights follow their parent source). The 4-/5-arg call shapes still
  work, so existing callers are unaffected; `24_down` restores the
  previous definitions.
- API: SearchRequest / AskRequest accept `notebook_ids` (list) and
  `notebook_id` (single, the shape clients already send); ids are
  validated (400 for non-notebook ids, 404 for unknown notebooks) before
  reaching the query so a typo never masquerades as "no matches".
- Domain: text_search / vector_search take `notebook_ids`; the highlight
  overflow fallback preserves the scope.
- Ask graph: scope travels in the thread state and reaches every fan-out
  vector search.
- Frontend: NotebookScopeSelector (collapsible checkbox list, "All
  notebooks" by default, Clear action) shared by the Ask and Search tabs;
  strings in all 14 locales.
- Docs: user guide section on scoping; API reference note.

Closes #574
Closes #87

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01U53d3BNjGghLsf6tufRTKX

* fix(search): harden notebook scope validation after review

- Raise typed InvalidInputError / NotFoundError instead of bare
  HTTPException, per the API error convention.
- Check notebook existence with a single query for the whole scope; a
  database failure now surfaces as 500 instead of a misleading 404.
- Bound notebook_ids to 50 entries; keep empty ids so they are rejected
  (400) rather than silently widening the scope to everything.
- Replace the pluralized "N notebooks selected" string with a neutral
  "N selected" form: the locale parity test forbids per-language extra
  keys, so _few/_many forms for ru/pl were not an option.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01U53d3BNjGghLsf6tufRTKX

* refactor(search): move scope resolution to the domain, add ADR-008

- resolve_notebook_scope() now lives in open_notebook/domain/notebook.py
  next to text_search / vector_search; the router only calls it.
- Reject malformed ids such as "notebook:" (empty key) and anything
  RecordID.parse cannot handle with InvalidInputError instead of letting
  them surface as 500.
- ADR-008 records the notebook-scope semantics, the compatibility choice
  (notebook_id + notebook_ids, optional trailing SurrealQL parameter) and
  how it relates to the #1315 retrieval contract.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01U53d3BNjGghLsf6tufRTKX

* test(search): cover migration 24, validate Ask scope before model lookups

- Ask endpoints resolve the notebook scope first, so a malformed or
  unknown scope returns 400/404 before any model or embedding lookup.
- Registration and content tests for 24.surrealql / 24_down.surrealql,
  following the existing migration test pattern.
- ADR-008 context trimmed to the template's sentence budget.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01U53d3BNjGghLsf6tufRTKX

* fix(search): surface a typed error when scope resolution hits the database

resolve_notebook_scope() now logs the raw driver error and raises
DatabaseOperationError with a fixed message, matching text_search /
vector_search, so connection details never reach the 500 response body.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01U53d3BNjGghLsf6tufRTKX

* fix(search): compare notebook scope ids as strings

The driver returns `id` as RecordID objects, which are unhashable and
never equal to the request strings, so every real scoped request raised
TypeError before reaching the search. Normalize to str before comparing
and add a regression test that mocks RecordID rows.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014kRBoPiBD1NKeKHCo6EyrE

---------

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-05 16:09:04 -03:00
Augusto Sandim
bbc7d110f6
refactor: rename "API Keys" settings page to "Models" (#1313)
* refactor: rename "API Keys" settings page to "Models" (#1199)

Rename the provider credentials settings area from "API Keys" to "Models":

- Route: /settings/api-keys -> /settings/models with a permanent redirect
- UI copy: page title, description, and learn-more now use "Models" wording
- i18n: updated display values across all 14 locales (key names unchanged)
- Internal links: sidebar, setup banner, and command palette point to /settings/models
- Docs: "Settings → API Keys" references updated to "Settings → Models"

* docs(quick-start): update model settings navigation to Manage → Models

* fix(frontend): highlight only the active sidebar item on nested routes

Use longest-prefix matching so parent items like Settings don't also
highlight when viewing a child page such as Models. Add test coverage
for the Models page active state.

---------

Co-authored-by: Luis Novo <lfnovo@gmail.com>
2026-09-05 13:20:20 -03:00
Matt Van Horn
97e5504d82
fix: clarify OpenAI-compatible base URL requirements (#1251)
Fixes #1242

Co-authored-by: Matt Van Horn <455140+mvanhorn@users.noreply.github.com>
Co-authored-by: Luis Novo <lfnovo@gmail.com>
2026-09-05 10:22:24 -03:00
zivkidd
a160247ca3
fix(frontend): Ask spinner never stops under React Strict Mode (#1235)
* fix(frontend): keep Ask loading state clearable under React Strict Mode

The mountedRef effect only declared a cleanup function and never set the
ref back to true on mount. React Strict Mode mounts, unmounts and remounts
in development, so the first cleanup left mountedRef.current false forever
and every guard depending on it became dead code.

That silently disabled all five paths that end the loading state:
stopStreaming on final_answer and complete, the normal end-of-stream call,
the error handler, and the idle watchdog added in #777. The Ask spinner ran
forever and the answer was never rendered, even when the stream completed
successfully.

* test(frontend): cover Ask loading state across StrictMode remount

Renders useAsk inside StrictMode so the mount → unmount → remount sequence
runs, then drives a mocked SSE stream to completion and to an in-band error
event. Both assertions fail on the pre-fix hook with `expected true to be
false`, because mountedRef.current stays false and every setState becomes a
no-op — the existing suite could not catch this since nothing exercised a
remount.

---------

Co-authored-by: Luis Novo <lfnovo@gmail.com>
2026-09-05 09:37:38 -03:00
Luis Novo
8297bb22e2
chore(deps): bump pyasn1 to 0.6.4 and brace-expansion to 1.1.16 (#1222)
Some checks are pending
Development Build / extract-version (push) Waiting to run
Development Build / changes (push) Waiting to run
Development Build / build-regular (push) Blocked by required conditions
Development Build / build-single (push) Blocked by required conditions
Development Build / summary (push) Blocked by required conditions
Tests / Backend Tests (push) Waiting to run
Tests / Backend Lint (push) Waiting to run
Tests / Backend Typecheck (push) Waiting to run
Tests / Frontend Tests (push) Waiting to run
Tests / Frontend Lint (push) Waiting to run
Tests / Frontend Build (push) Waiting to run
Resolves the three open high-severity Dependabot alerts (two pyasn1
entries in uv.lock, one brace-expansion in the frontend lockfile pinned
via overrides).
2026-09-04 07:20:05 -03:00
Augusto Sandim
3c44dc63d7
docs(search): document content coverage for text and vector search (#1295)
* docs(search): document content coverage for text and vector search

- Add 'Content searched'sections to the user guide explaining
  which source/note fields are matched by text and vector search.
- Surface a short coverage hint below the search input in the UI.
- Add  translations across all supported locales.
Fixes #1267

* feat(search): make coverage hint reflect selected search type

- Show vector-specific coverage hint when vector search is selected.
- Split searchCoverage locale key into searchCoverageText and searchCoverageVector across all supported locales.

---------

Co-authored-by: Luis Novo <lfnovo@gmail.com>
2026-09-03 23:55:10 -03:00
αI
bef53688b3
fix(frontend): follow app theme in markdown editor (#1294)
* fix(frontend): sync markdown editor theme

* fix(frontend): wait for theme hydration

* fix(frontend): recover from theme storage errors

* test: assert theme fallback after hydration failure

---------

Co-authored-by: Alphaxiaoteng <230277249+Alphaxiaoteng@users.noreply.github.com>
Co-authored-by: Luis Novo <lfnovo@gmail.com>
2026-09-03 23:47:29 -03:00
αI
cdb7992612
fix(ui): restore markdown preview list markers (#1300)
* fix: restore markdown preview list markers

* test: cover markdown preview list markers

---------

Co-authored-by: αI <230277249+Alphaxiaoteng@users.noreply.github.com>
Co-authored-by: Luis Novo <lfnovo@gmail.com>
2026-09-03 23:40:23 -03:00
Sure
43a07fe28e
fix: align sidebar footer actions (#1288)
* fix: align sidebar footer actions

* test: cover sidebar footer spacing

* test: guard theme icon sizing

---------

Co-authored-by: Luis Novo <lfnovo@gmail.com>
2026-09-03 23:30:41 -03:00
Manish Singh Parihar
eeb2e67820
fix(frontend): stop long voice-model badge overflowing profile card (#1259)
Let the speaker-profile row wrap and constrain the voice-model badge
(min-w-0, max-w-full, truncate with a title tooltip) so long
provider/model names no longer clip past the card edge.

Fixes #1196

Co-authored-by: Luis Novo <lfnovo@gmail.com>
2026-09-03 23:23:35 -03:00
Paco Cartones
91f70f4d20
Fix SSE stream parsing in source chat: buffer partial lines and stream-decode (#1289)
The SSE consumer in useSourceChat decoded and split each network chunk in
isolation (decoder.decode(value) with no { stream: true }, and text.split('\n')
with no carry-over). A data: line split across two reads was dropped (first half
fails JSON.parse, second half fails the 'data: ' guard) and a multibyte char
straddling a chunk boundary decoded to U+FFFD.

Carry the incomplete trailing line across reads and use a streaming decoder,
mirroring the sibling hook useAsk in use-ask.ts.

Co-authored-by: pacocartones <pacocartones@users.noreply.github.com>
Co-authored-by: Luis Novo <lfnovo@gmail.com>
2026-09-03 23:13:55 -03:00
dependabot[bot]
f9a6539ad1
chore(deps-dev): bump tar from 7.5.16 to 7.5.22 in /frontend (#1227)
Bumps [tar](https://github.com/isaacs/node-tar) from 7.5.16 to 7.5.22.
- [Release notes](https://github.com/isaacs/node-tar/releases)
- [Changelog](https://github.com/isaacs/node-tar/blob/main/CHANGELOG.md)
- [Commits](https://github.com/isaacs/node-tar/compare/v7.5.16...v7.5.22)

---
updated-dependencies:
- dependency-name: tar
  dependency-version: 7.5.22
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Luis Novo <lfnovo@gmail.com>
2026-09-03 22:46:40 -03:00
dependabot[bot]
346089cd38
chore(deps): bump next from 16.2.6 to 16.2.11 in /frontend (#1228)
Bumps [next](https://github.com/vercel/next.js) from 16.2.6 to 16.2.11.
- [Release notes](https://github.com/vercel/next.js/releases)
- [Commits](https://github.com/vercel/next.js/compare/v16.2.6...v16.2.11)

---
updated-dependencies:
- dependency-name: next
  dependency-version: 16.2.11
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Luis Novo <lfnovo@gmail.com>
2026-09-03 22:38:05 -03:00
dependabot[bot]
6bd768b435
build(deps): bump nanoid from 3.3.11 to 3.3.18 in /frontend (#1256)
Bumps [nanoid](https://github.com/ai/nanoid) from 3.3.11 to 3.3.18.
- [Release notes](https://github.com/ai/nanoid/releases)
- [Changelog](https://github.com/ai/nanoid/blob/3.3.18/CHANGELOG.md)
- [Commits](https://github.com/ai/nanoid/compare/3.3.11...3.3.18)

---
updated-dependencies:
- dependency-name: nanoid
  dependency-version: 3.3.18
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Luis Novo <lfnovo@gmail.com>
2026-09-03 22:05:06 -03:00
dependabot[bot]
c52c51a354
build(deps-dev): bump js-yaml from 4.2.0 to 4.3.2 in /frontend (#1258)
Bumps [js-yaml](https://github.com/nodeca/js-yaml) from 4.2.0 to 4.3.2.
- [Changelog](https://github.com/nodeca/js-yaml/blob/4.3.2/CHANGELOG.md)
- [Commits](https://github.com/nodeca/js-yaml/compare/4.2.0...4.3.2)

---
updated-dependencies:
- dependency-name: js-yaml
  dependency-version: 4.3.1
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Luis Novo <lfnovo@gmail.com>
2026-09-03 21:59:05 -03:00
dependabot[bot]
08294a8f85
build(deps-dev): bump browserslist from 4.28.2 to 4.28.8 in /frontend (#1298)
Bumps [browserslist](https://github.com/browserslist/browserslist) from 4.28.2 to 4.28.8.
- [Release notes](https://github.com/browserslist/browserslist/releases)
- [Changelog](https://github.com/browserslist/browserslist/blob/main/CHANGELOG.md)
- [Commits](https://github.com/browserslist/browserslist/compare/4.28.2...4.28.8)

---
updated-dependencies:
- dependency-name: browserslist
  dependency-version: 4.28.8
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Luis Novo <lfnovo@gmail.com>
2026-09-03 21:35:26 -03:00
dependabot[bot]
9ec847003c
build(deps-dev): bump @humanfs/node from 0.16.6 to 0.16.8 in /frontend (#1302)
Bumps [@humanfs/node](https://github.com/humanwhocodes/humanfs/tree/HEAD/packages/node) from 0.16.6 to 0.16.8.
- [Release notes](https://github.com/humanwhocodes/humanfs/releases)
- [Changelog](https://github.com/humanwhocodes/humanfs/blob/main/packages/node/CHANGELOG.md)
- [Commits](https://github.com/humanwhocodes/humanfs/commits/node-v0.16.8/packages/node)

---
updated-dependencies:
- dependency-name: "@humanfs/node"
  dependency-version: 0.16.8
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-03 21:26:35 -03:00
Luis Novo
62b071b917
feat(frontend): Quiet Green screen-by-screen reskin — shell, workspace, home, modals, remaining screens (#1220)
Some checks failed
Tests / Backend Tests (push) Has been cancelled
Tests / Backend Lint (push) Has been cancelled
Tests / Backend Typecheck (push) Has been cancelled
Tests / Frontend Tests (push) Has been cancelled
Tests / Frontend Lint (push) Has been cancelled
Tests / Frontend Build (push) Has been cancelled
Development Build / extract-version (push) Has been cancelled
Development Build / changes (push) Has been cancelled
Development Build / build-regular (push) Has been cancelled
Development Build / build-single (push) Has been cancelled
Development Build / summary (push) Has been cancelled
* feat(frontend): reskin app shell — pebble wordmark, fern nav spine, hued destination icons

* feat(frontend): reskin screens — workspace, home, sources, modals, settings, podcasts, search

Visual-only pass per screen: panel headers with hue ticks, one-line
source card metadata with top-right overflow, de-washed chat bubbles
(AI speaks teal), library treatment on the sources table (type pebbles,
quiet embedded pills), flattened dialog internals with uniform breathing
room, badge diet on models/settings, quiet podcast player containers,
mono for data everywhere. No behavior, columns or i18n changes.

* docs: changelog entry for the screen-by-screen reskin
2026-07-24 17:59:08 -03:00
Luis Novo
b3e8328e38
feat(frontend): Quiet Green design foundation — tokens, fonts, primitives, /dev/design (#1218)
* feat(frontend): design foundation — Quiet Green tokens, fonts, primitives, /dev/design

- Port the ratified design token system into globals.css: core palette,
  semantic surfaces/ink/hairlines, content-type hues, evidence classes,
  context states, squared 4-6px radii, shadow scale (popovers own the
  only real shadow)
- Swap Inter for Bricolage Grotesque (display) + Instrument Sans (UI) +
  Spline Sans Mono (data) via next/font
- Restyle shadcn primitives to the foundation laws: fern primary button,
  red reserved for destructive, hairline cards without default shadow,
  underline tabs, quiet neutral badges, teal focus ring, single-shadow
  overlays
- Add /dev/design living styleguide (dev-only, 404 in production)
  rendering all tokens and primitives with a theme toggle

* refactor(frontend): sweep hard-coded palette colors into design tokens

Replace raw Tailwind palette classes (red/amber/green/blue/emerald/sky/
purple…) across 38 components with the semantic token utilities:
errors -> destructive, warnings -> warn (clay), success -> fern,
system/info -> teal, context states -> ctx-* tokens, model-type chips
redistributed over the owned palette. Light/dark duplicates collapse
into single token classes since tokens re-resolve per theme.

* docs: changelog entry for the Quiet Green design foundation
2026-07-24 17:53:21 -03:00
Thomas Pockrandt
ee0ea5ebaa
feat(frontend): add "New Source" button to sources empty state (#1165)
Some checks are pending
Development Build / extract-version (push) Waiting to run
Development Build / changes (push) Waiting to run
Development Build / build-regular (push) Blocked by required conditions
Development Build / build-single (push) Blocked by required conditions
Development Build / summary (push) Blocked by required conditions
Tests / Backend Tests (push) Waiting to run
Tests / Backend Lint (push) Waiting to run
Tests / Backend Typecheck (push) Waiting to run
Tests / Frontend Tests (push) Waiting to run
Tests / Frontend Lint (push) Waiting to run
Tests / Frontend Build (push) Waiting to run
* feat: add 'add source' button to sources page

* feat(i18n): add sources.newSource translation to all locales

* refactor(frontend): deduplicate AddSourceDialog in sources page

* i18n(de-DE): add missing sources.newSource key

The new sources.newSource key was added to the other 13 locales but not
de-DE, so the locale parity test (src/lib/locales/index.test.ts) failed
and de-DE users would fall back to the raw key. Add the German string.

---------

Co-authored-by: Luis Novo <lfnovo@gmail.com>
2026-07-21 11:14:51 -03:00
dyzur
9f75748c4d
fix: prevent Ask streaming loading from getting stuck on dangling connections (#777) (#1146)
* fix: prevent Ask streaming loading from getting stuck on dangling connections

Adds a safety-net timeout (5 min) to useAsk that forces the loading
state to end even when the SSE stream's 'done' signal doesn't reach
the browser — which happens in Docker/standalone deployments where
the Next.js proxy connection is left open without proper termination.

Changes:
- use-ask.ts: AbortController per request, mountedRef for cleanup,
  STREAM_TIMEOUT_MS that resets isStreaming, stopStreaming() helper
  that centralizes cleanup + clears the timeout
- search.ts: pass AbortSignal through to fetch() so the timeout can
  actually cancel the HTTP request

The complete event now also carries final_answer content as a
backup path in case the final_answer event is missed.

Co-Authored-By: Claude <noreply@anthropic.com>

* chore: reduce stream timeout from 5 min to 75s

* fix(ask): make stream watchdog idle-based and abort dangling connections

The Ask stream safety timeout was a fixed 75s wall-clock cap measured from
stream start and never reset by incoming SSE events. A legitimately slow but
healthy Ask (slow local models — Ollama, LM Studio) would have its loading
state killed mid-stream, showing a partial/empty answer while the backend was
still producing — the exact slow-hardware scenario in #777.

- Re-arm the timeout on every received chunk so it fires only when the
  connection goes genuinely silent (idle timeout, not wall-clock).
- Align the idle window to the API client budget (NEXT_PUBLIC_API_TIMEOUT_MS,
  default 10 min; 0 disables) so slow local models aren't cut off. Export
  API_TIMEOUT_MS from the client for this.
- On fire, abort the in-flight request so a truly dangling connection frees the
  socket/reader instead of leaking it (the catch already swallows AbortError).

---------

Co-authored-by: dyzur <dyzur@users.noreply.github.com>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Luis Novo <lfnovo@gmail.com>
2026-07-21 11:11:02 -03:00
Yu Feng
1b46de7b76
fix: prevent source dialog action overlap (#1195)
Some checks are pending
Development Build / extract-version (push) Waiting to run
Development Build / changes (push) Waiting to run
Development Build / build-regular (push) Blocked by required conditions
Development Build / build-single (push) Blocked by required conditions
Development Build / summary (push) Blocked by required conditions
Tests / Backend Typecheck (push) Waiting to run
Tests / Frontend Tests (push) Waiting to run
Tests / Frontend Lint (push) Waiting to run
Tests / Frontend Build (push) Waiting to run
Tests / Backend Lint (push) Waiting to run
Tests / Backend Tests (push) Waiting to run
* fix: prevent source dialog action overlap

* fix(sources): pad only the right of the detail header to clear close button

px-12 cleared the overlap but also indented the header's left edge 40px
past the tab content below (which stays px-2), misaligning the title. Keep
px-2 and add pr-12 so the header left-aligns with the body while the actions
menu still clears the dialog close button on the right.

---------

Co-authored-by: Luis Novo <lfnovo@gmail.com>
2026-07-21 09:28:16 -03:00
Cory Potter
fa352c151e
fix(frontend): support allowedDevOrigins via env var (#1190)
* fix(frontend): support allowedDevOrigins via env var

Accessing the Next.js dev server from a LAN IP fails all HMR/dev
resource requests: Next.js blocks cross-origin dev requests (including
the webpack-hmr websocket) from any host not in an explicit allowlist,
as a DNS-rebinding guard. Server log:

  Blocked cross-origin request to Next.js dev resource
  /_next/webpack-hmr from "<lan-ip>".

Add NEXT_ALLOWED_DEV_ORIGINS (comma-separated hostnames) to populate
Next's allowedDevOrigins config, so LAN/custom-hostname dev access can
be enabled per-deployment without hardcoding a host into next.config.ts.

* fix(frontend): treat whitespace-only NEXT_ALLOWED_DEV_ORIGINS as unset

A whitespace-only or comma-only value parsed to an empty array, which is
truthy and still spread allowedDevOrigins: [] into the config, overriding
Next's default dev-origin behavior. Only set the key when at least one
origin survives trimming.

---------

Co-authored-by: Luis Novo <lfnovo@gmail.com>
2026-07-21 09:23:52 -03:00
Luis Novo
30c7e2a63e
fix(podcasts): clarify episode max_tokens field and fix empty-state error (#1197)
Some checks are pending
Development Build / extract-version (push) Waiting to run
Development Build / changes (push) Waiting to run
Development Build / build-regular (push) Blocked by required conditions
Development Build / build-single (push) Blocked by required conditions
Development Build / summary (push) Blocked by required conditions
Tests / Frontend Tests (push) Waiting to run
Tests / Frontend Lint (push) Waiting to run
Tests / Frontend Build (push) Waiting to run
Tests / Backend Tests (push) Waiting to run
Tests / Backend Lint (push) Waiting to run
Tests / Backend Typecheck (push) Waiting to run
The episode profile "Max output tokens" field (#991) confused users:
nothing explained what it controls, and whether it was a
per-conversation, per-turn, or per-call limit. An empty field also
showed "Must be a positive integer" — a scary error on an optional
field — because a transient/empty number-input state produced NaN,
which slipped past the nullable() guard into the positive() rule.

- Add help text (all 14 locales) stating it caps output tokens per
  generation step — the outline and the full transcript, not a per-turn
  or conversation limit — and that blank uses the built-in defaults
  (3000 outline / 5000 transcript, from podcast-creator).
- Add a placeholder ("Leave blank for defaults") so the empty field
  reads as intentionally optional rather than unfilled.
- Map empty and NaN inputs to null in setValueAs, so an empty or
  half-typed value reads as "unset" and never trips the positive-integer
  rule. Genuinely invalid entries (0, negatives, decimals) still error.

Field stays an optional override — no behavior change to generation.
Verified in the browser: help renders, placeholder shows, empty field
has no error, zero console errors. Frontend lint/test/build green.
2026-07-20 22:10:50 -03:00
Luis Novo
8a39589d58
chore(deps): resolve open Dependabot security alerts (#1191)
Bump two dependencies flagged by Dependabot ahead of the v1.14.0 release:

- mcp 1.25.0 -> 1.28.1 (3 high alerts). Transitive via content-core ->
  fastmcp; the advisories cover MCP *server* transports (missing
  Host/Origin validation on the WebSocket transport, HTTP transports
  serving session requests without verifying the authenticated
  principal, and experimental task handlers exposing other clients'
  tasks). Open Notebook does not serve MCP, so none of them are
  reachable here, but fastmcp accepts the newer release and the bump
  resolves cleanly with no other dependency churn.
- axios 1.16.0 -> 1.18.1 (medium alert). Prototype pollution allowing
  Basic auth injection through auth subfields. Direct frontend
  dependency; pulls nested agent-base/https-proxy-agent, which newer
  axios uses for proxy handling.

Verified: uv sync + content-core/fastmcp import clean, frontend
npm ci + npm run build green, npm audit reports 0 vulnerabilities.
2026-07-20 17:40:16 -03:00
Luis Novo
3bfa6d728e
feat(settings): expose Docling formula & vision enrichment toggles (#1187)
Some checks are pending
Development Build / summary (push) Blocked by required conditions
Development Build / extract-version (push) Waiting to run
Development Build / changes (push) Waiting to run
Development Build / build-regular (push) Blocked by required conditions
Development Build / build-single (push) Blocked by required conditions
Tests / Backend Tests (push) Waiting to run
Tests / Backend Lint (push) Waiting to run
Tests / Backend Typecheck (push) Waiting to run
Tests / Frontend Tests (push) Waiting to run
Tests / Frontend Lint (push) Waiting to run
Tests / Frontend Build (push) Waiting to run
Surface content-core 2.x's docling_formulas (formula extraction) and
docling_vision (image/chart vision) enrichment flags in Settings →
Content Processing, mirroring the existing OCR toggle. Both default off
and are gated on Docling availability in the UI. The settings persist
via GET/PUT /api/settings and are threaded into content-core extraction
alongside docling_ocr. Migration 23 backfills the new fields on the
existing content_settings record. Labels and help are translated across
all 14 locales.

Closes #1131
2026-07-19 18:15:40 -03:00
Luis Novo
b83f1d61e6
fix(models): stop auto-assign from re-filling cleared optional defaults (#1186)
* fix(models): stop auto-assign from re-filling cleared optional defaults

Auto-assign treated every empty default slot as "missing" and filled it,
so an optional slot a user deliberately cleared (to fall back to the chat
model) got silently re-populated on the next run, undoing the intent.

- Auto-assign now fills only the required slots (chat, embedding); the
  optional slots (transformation, tools, large context, TTS, STT) are
  left untouched.
- get_default_model("large_context") now falls back to the chat model
  when unset, matching transformation/tools (TTS/STT still return None).
- Settings UI shows an inline hint on each empty optional slot: the text
  slots show "using chat model (<name>)"; TTS/STT show a not-configured
  hint. Required slots remain non-clearable. New i18n keys across all 14
  locales.

Closes #1098

* test: guard await_args against None for mypy
2026-07-19 18:06:17 -03:00
Luis Novo
ccd81a67ed
test(i18n): validate interpolation placeholder parity across locales (#1184)
The locale parity test and TranslationShape type only compared keys, not
the interpolation placeholders inside values. This let single-brace drift
(a stray {count} instead of i18next's {{count}}) slip through unnoticed.

Extend the parity suite to, for every leaf string, compare the set of
{{...}} placeholders against en-US and flag any stray single-brace token
that maps to a real en-US placeholder. Aligns zh-CN/zh-TW
podcasts.generationStartedDesc, which referenced a {{name}} placeholder
absent from the en-US reference.
2026-07-19 17:59:31 -03:00
Gautam Diwan
ef9bc43b9a
feat: add first-class oMLX provider via Esperanto profile (#1164)
Expose Esperanto's built-in omlx OpenAICompatibleProfile in Settings with
Ollama-style UX (default http://localhost:11435/v1, optional API key,
language+embedding discovery). No openai-compatible remapping or
OPENAI_COMPATIBLE_* env mirroring.

Fixes #1048

Co-authored-by: Luis Novo <lfnovo@gmail.com>
2026-07-19 15:02:14 -03:00
Luis Novo
22d1ae7780
perf(chat): isolate composer state to fix IME lag in long conversations (#1174)
* perf(chat): isolate composer state to fix IME lag in long chats

Move the chat composer input state into a dedicated ChatComposer child so
keystrokes (including IME composition) no longer re-render the whole message
history. Memoize each message row with React.memo and make the reference-click
handler stable with useCallback so historical messages don't re-render on
composer input. Send behavior and the Ctrl/Cmd+Enter shortcut are preserved.

Closes #1147

* fix(chat): stabilize modal callbacks and use realistic shortcut tests

Memoize openModal/closeModal in useModalManager with useCallback so their
identities stay stable across renders. This keeps handleReferenceClick (which
depends on openModal) stable, so the memoized ChatMessage rows no longer
re-render on every ChatPanel render — completing the IME-lag fix.

Split the Ctrl/Cmd+Enter test into two realistic paths (Mac metaKey, non-Mac
ctrlKey) driven by a mocked userAgent, instead of an impossible combined
ctrlKey+metaKey event.
2026-07-19 12:42:09 -03:00
okaken
df106fabe6
fix(i18n): improve Japanese (ja-JP) translation quality (#998)
Some checks failed
Development Build / extract-version (push) Has been cancelled
Tests / Backend Tests (push) Has been cancelled
Tests / Backend Lint (push) Has been cancelled
Tests / Backend Typecheck (push) Has been cancelled
Tests / Frontend Tests (push) Has been cancelled
Tests / Frontend Lint (push) Has been cancelled
Tests / Frontend Build (push) Has been cancelled
Development Build / changes (push) Has been cancelled
Development Build / build-regular (push) Has been cancelled
Development Build / build-single (push) Has been cancelled
Development Build / summary (push) Has been cancelled
* fix(i18n): improve Japanese translation quality

- Replace 'トランスフォーメーション' with natural '変換'
- Improve various phrasing for natural Japanese
- Add spacing in duration format
- Refine accessibility labels and error messages

* fix(i18n): remove redundant 含める in ja-JP includeAllInsights

---------

Co-authored-by: Lovin <lovin@example.com>
Co-authored-by: Luis Novo <lfnovo@gmail.com>
2026-07-17 12:57:01 -03:00
Matt Van Horn
f7d9f0fb1e
feat(frontend): expose episode profile max_tokens in the UI (#992)
Adds an optional "Max output tokens" number input to the episode profile form, mirroring num_segments handling: zod validation (positive integer, clearable to null), form defaults/reset, and submit payload. Shows the value in episode card details and adds max_tokens to the episode profile types.

Includes maxTokens/maxTokensInteger/maxTokensPositive translation keys in all 14 locales (the locale parity test requires new keys everywhere).

Closes #991

Co-authored-by: Matt Van Horn <455140+mvanhorn@users.noreply.github.com>
2026-07-14 09:22:53 -03:00
Luis Novo
906ad1698a
feat(sources): opt-in Docling + Crawl4AI runtimes installed at startup (#1122) (#1123)
Docling and local Crawl4AI are now opt-in, installed on first container startup
via OPEN_NOTEBOOK_ENABLE_DOCLING / OPEN_NOTEBOOK_ENABLE_CRAWL4AI, keeping the
default image lean (Crawl4AI un-bundled). Downloads cache on the /app/data
volume; installs are blocking with loud logs and degrade-don't-die on failure.
A GET /api/capabilities probe reports actual availability and the Settings UI
gates the Docling/Crawl4AI engines and OCR toggle (with env-var hints) until the
runtime is present. Docs folded from #1121 and rewritten to opt-in; ADR-007 added.

Closes #1122. Closes #1105.
2026-07-13 08:26:20 -03:00
Luis Novo
7dfe8aa0a7
feat(sources): add Docling OCR toggle to content processing settings (#1104) (#1120)
Some checks are pending
Development Build / summary (push) Blocked by required conditions
Development Build / extract-version (push) Waiting to run
Development Build / build-regular (push) Blocked by required conditions
Development Build / build-single (push) Blocked by required conditions
Tests / Backend Tests (push) Waiting to run
Tests / Backend Lint (push) Waiting to run
Tests / Backend Typecheck (push) Waiting to run
Tests / Frontend Tests (push) Waiting to run
Tests / Frontend Lint (push) Waiting to run
Tests / Frontend Build (push) Waiting to run
Expose content-core's docling_ocr flag as a user setting. OCR runs on
scanned PDFs and images when the Docling engine handles them; it's on by
default (matching content-core) and can be turned off for faster
processing of text-native documents.

- New `docling_ocr` boolean on ContentSettings (default True), plumbed
  through the settings API and into ContentCoreConfig in the source graph.
- "Enable OCR" checkbox in the Content Processing settings card, with
  label + help translated across all 14 locales.

Part of #939. Stacked on #432.
2026-07-12 20:16:15 -03:00