<feed xmlns='http://www.w3.org/2005/Atom'>
<title>ollama-translations.git/src/options/options.js, branch main</title>
<subtitle>Unnamed repository; edit this file 'description' to name the repository.
</subtitle>
<id>https://git.takashi-2521.com/ollama-translations.git/atom?h=main</id>
<link rel='self' href='https://git.takashi-2521.com/ollama-translations.git/atom?h=main'/>
<link rel='alternate' type='text/html' href='https://git.takashi-2521.com/ollama-translations.git/'/>
<updated>2026-09-01T12:17:29+00:00</updated>
<entry>
<title>style: align advanced settings rows</title>
<updated>2026-09-01T12:17:29+00:00</updated>
<author>
<name>tanaka takashi</name>
<email>isazaka@gmail.com</email>
</author>
<published>2026-09-01T12:17:29+00:00</published>
<link rel='alternate' type='text/html' href='https://git.takashi-2521.com/ollama-translations.git/commit/?id=f5439335e1d18ee577e2b7c1e67f7844f9f235ac'/>
<id>urn:sha1:f5439335e1d18ee577e2b7c1e67f7844f9f235ac</id>
<content type='text'>
The advanced settings labels (num_keep, num_predict, top_k, ...) had
variable widths, so each numeric input started at a different x
position. Give the labels a fixed 150px width in the #advanced-fields
rows so all inputs line up in a single column.

Verified in a live DOM: after the rule applies, all 10 labels share the
same width (150px) and all 10 inputs start at the same x position.
Results: 73 passed, 0 failed. dist rebuilt.
</content>
</entry>
<entry>
<title>fix: model select showed a value that was never saved</title>
<updated>2026-09-01T11:57:29+00:00</updated>
<author>
<name>tanaka takashi</name>
<email>isazaka@gmail.com</email>
</author>
<published>2026-09-01T11:57:29+00:00</published>
<link rel='alternate' type='text/html' href='https://git.takashi-2521.com/ollama-translations.git/commit/?id=5ba53d7b64b181134b9c594fd9881ec626eae791'/>
<id>urn:sha1:5ba53d7b64b181134b9c594fd9881ec626eae791</id>
<content type='text'>
Root cause of "設定値が不正です (モデルが設定されていません)" despite the
settings UI showing a selected model:
- fillModels(models, selected="") never set option.selected when no model
  was saved yet. The browser then auto-selects the first option visually,
  so the UI displayed e.g. "glm-5.3:cloud" while storage.model remained
  empty. Translation therefore failed with the no-model error until the
  user pressed Save, which materialized the UI value into storage.

Fixes
- popup.js/options.js fillModels: when no model is saved and the list is
  non-empty, explicitly select the first model so the UI value always
  matches what will be used
- popup.js: after the model list loads, persist the auto-selected model
  if storage still has none
- options.js loadSettings: same sync after loadModels, so opening the
  options page also heals the empty-model state

Results: 73 passed, 0 failed. dist rebuilt.
</content>
</entry>
<entry>
<title>fix: options page never ran due to missing export; unify settings handling</title>
<updated>2026-09-01T11:38:17+00:00</updated>
<author>
<name>tanaka takashi</name>
<email>isazaka@gmail.com</email>
</author>
<published>2026-09-01T11:38:17+00:00</published>
<link rel='alternate' type='text/html' href='https://git.takashi-2521.com/ollama-translations.git/commit/?id=bb06e0e58dcb90eceede6f0b05743fdccc8f51af'/>
<id>urn:sha1:bb06e0e58dcb90eceede6f0b05743fdccc8f51af</id>
<content type='text'>
Root cause of the broken options page (audit finding):
- options.js imported CONTEXT_PRESETS from settings-schema.js, but that
  module never exported it. A named-import mismatch in ES modules is a
  SyntaxError, so the entire options page script silently never executed.
  This is why the settings page rendered its static HTML but was dead:
  no language options, no model list, no save handler.

Fixes
- options.js: import CONTEXT_PRESETS from shared/constants.js (where it
  is defined) instead of settings-schema.js
- options.js: save flow now merges the validated form over the stored
  settings (sanitize again) so fields saved by the popup in the meantime
  are preserved instead of being dropped
- popup.js: populate language options inside loadSettings and sanitize
  settings before every save, matching the options page behavior
- settings-schema.js: add normalizeOllamaHost() and use it in
  sanitizeSettings so trailing-slash variants are stored identically
- content.js: consolidate popover state - remove the duplicate outer
  lastSourceText and keep regenerate source inside the popover module;
  regenerate now calls portClient.translate directly

Test hardening (would have caught the original bug)
- tests/ui-smoke-tests.js: new smoke tests that install a fake browser
  API, run the real popup.js / options.js page scripts as ES modules
  against representative markup, and assert that language options are
  populated, the model select is filled from the mocked model list, and
  the stored host is reflected. The runner result elements are preserved
  across the sandboxed DOM swap
- test.html: include the smoke test module

Results: 73 passed, 0 failed (71 existing + 2 smoke). dist rebuilt.
</content>
</entry>
<entry>
<title>feat: Firefox selection translation extension with local Ollama (initial version)</title>
<updated>2026-09-01T11:10:20+00:00</updated>
<author>
<name>tanaka takashi</name>
<email>isazaka@gmail.com</email>
</author>
<published>2026-09-01T11:10:20+00:00</published>
<link rel='alternate' type='text/html' href='https://git.takashi-2521.com/ollama-translations.git/commit/?id=55e581bab9b600e7c070ec596d3109fc897d2d86'/>
<id>urn:sha1:55e581bab9b600e7c070ec596d3109fc897d2d86</id>
<content type='text'>
Implement the complete initial version of a Firefox WebExtension (Manifest V3)
that translates selected text on web pages using a local Ollama LLM and shows
the result in a small popover near the selection.

Specification alignment (Phase 0)
- Unified Specifications.md / Design.md / Security.md on the same approach:
  Ollama REST API + Fetch API + NDJSON streaming (no ollama-js SDK dependency)
- Fixed host_permissions to http://localhost/* and http://127.0.0.1/* because
  Firefox match patterns do not support port numbers (bug 1362809/1468162);
  the actual connection target is restricted to localhost/127.0.0.1 + any port
  by application-side validation (defense in depth, OLL-09)
- Clipboard: use navigator.clipboard.writeText() only inside the copy button
  click (user activation); no deprecated execCommand fallback

Implementation (zero dependencies, vanilla JS, no npm/Node required)
- manifest.json: MV3, background.scripts + type:module (event page, no
  service_worker), action popup, options_ui, content_scripts for http/https,
  permissions: storage + localhost host permissions only
- src/shared: constants (ports, limits, presets, error codes), message
  validation, settings schema (defaults / merge / sanitize / buildOptions /
  toApiThinking), system prompt builder (fixed prompt first + user prompt)
- src/background: message-router (runtime.Port streaming + runtime.onMessage
  for model list), translation-session (single active request, abort previous
  on new request, stale chunk suppression), ollama-client (fetch against
  /api/tags and /api/chat with buffering NDJSON line parser tolerant to chunk
  boundaries inside JSON objects, AbortController, host re-validation before
  every request, HTTP status to error-code mapping), settings-service
  (storage.local load/save with validation and fallback to defaults)
- src/content/content.js: single classic script (Firefox does not support ES
  modules in content scripts) with selection detection (selectionchange +
  mouseup + keyup, debounced), Shadow DOM action button, Shadow DOM popover
  with HIDDEN/LOADING/STREAMING/COMPLETED/ERROR state machine, port client
  with requestId-based stale chunk filtering, enabled-state sync via
  storage.onChanged; all dynamic text rendered via textContent only
- src/popup + src/options: full settings UI (enable toggle, Ollama host,
  model list from Ollama with saved-model warning, target language, thinking
  mode, temperature slider 0.0-2.0 step 0.1, context length presets
  4k/8k/16k/32k/128k/256k, seed random/fixed with integer value, user system
  prompt, advanced numeric options with steppers, stop sequences textarea)
- icons generated by tools/make-icons.ps1 (System.Drawing, no external tools)
- build.ps1 packages manifest.json + icons/ + src/ into dist zip, excluding
  tests/, doc/, ollama-js/ and tools/

Tests (71 passed, 0 failed)
- In-browser test runner (tests/test.html) with custom describe/it/assert
  framework; no npm, no Node.js
- Unit: constants sync between content mirror and shared module, Ollama host
  validation (localhost/127.0.0.1 + any port only; rejects external hosts,
  LAN IPs, https, credentials, paths), settings schema defaults and fallback,
  temperature 0.1-step validation, context length presets, seed modes,
  advanced option types, buildOptions omission of unset values and absence of
  tfs_z/mirostat fields, system prompt composition order, message validation
  with selection length boundary values
- Integration: NDJSON streaming across awkward byte boundaries, thinking
  chunk forwarding, malformed line tolerance, error payload mapping, think/
  options inclusion rules, model list, TranslationSession abort semantics,
  settings round-trip with storage.onChanged cache refresh, full port flow
  (started/chunk/completed), newer request aborts older with stale chunk
  discard, malformed message rejection, OLLAMA_UNAVAILABLE and
  INVALID_SETTINGS error paths, untrusted sender rejection

Security audit (Design.md section 24 checklist: all pass)
- No innerHTML/outerHTML/document.write/eval/new Function/localStorage
- No remote JS/CSS/fonts/CDN resources; no inline scripts in extension pages
- Ollama access limited to background; content scripts never fetch Ollama
- Background validates message type/length/requestId; single concurrent
  translation enforced
- Clipboard API only (no execCommand fallback)
- Minimal permissions: storage + localhost host permissions

Docs
- README.md with build/load/usage instructions, API list, permission rationale
- doc/Testing-Results.md with automated test results, security audit results,
  and a 14-item manual Firefox verification checklist (to be executed on a
  real Firefox + Ollama environment)
</content>
</entry>
</feed>
