Skip to content

Changelog

All notable changes to this project will be documented in this file.

The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.

[Unreleased]

[3.5.4] - 2026-11-14

Changed

  • deps: Bump the docs group with 4 updates
  • deps: Bump the npm group with 19 updates

[3.5.3] - 2026-11-13

Added

  • agents: Enable the model action-claim check by default

Fixed

  • database: Keep loading responsive and report timings
  • agents: Route automatic cancellations to a system actor

[3.5.2] - 2026-11-10

Added

  • db: Move selected reads to workers

Fixed

  • chat: Keep idle compaction pending until commit
  • chat: Wire thread ref into idle choice
  • chat: Keep idle choices one click
  • agents: Keep topics starting at the hot boundary
  • chat: Keep idle prompt from repeating after compaction
  • agents: Keep compaction when topic alignment fails
  • chat: Keep prompt closed when boundary is current
  • db: Fix stale test mock and defer async history-window read
  • db: Lazy-load the native sqlite3 read-pool addon
  • agents: Use model limits and report run failures
  • release: Remove stale, unpublished release-bump commits

Changed

  • chat: Keep idle prompt edge cases covered
  • agents: Fix hot boundary cooldown race
  • release: Bump to 3.5.2
  • release: Bump to 3.6.0

[3.5.1] - 2026-11-07

Fixed

  • db: Split the deferred migration into crypto and reshaping
  • agents: Verify claims cited via inline markdown links
  • agents: Fix retry-audit data leaks across bridges and retries
  • docker: Keep browser-extension/lib in the build context

Changed

  • contributing: Require addressing copilot review before merge
  • db: Split migrations into a versioned baseline runner
  • embeddings: Fix retry assertion against ambient background work
  • deps: Bump the npm group with 21 updates
  • deps: Bump zensical from 0.0.73 to 0.0.74 in the docs group

[3.5.0] - 2026-11-06

Added

  • chat: Wire idle and hot-history compaction
  • extension: Add form preference capture for agent memory
  • agents: Merge action and citation audits

Fixed

  • chat: Prevent duplicate steering retries
  • agents: Check action claims against tool evidence
  • tests: Keep chat layout fixture recent
  • e2e: Run isolated browser workers in parallel
  • e2e: Use canonical worker database paths

Added

  • agents: Request compaction when hot history reaches 50 message rows
  • chat: Prompt before compacting conversations idle for three hours

Changed

  • db: Record applied migrations and bound direct upgrade support to 3.0 and newer; older databases must first be opened and unlocked in 3.0.

Fixed

  • api: Make chat-steering retries idempotent and retain messages with uncertain delivery
  • agents: Check read/write claims against tool results and recent thread evidence before model-backed retries
  • agents: Combine model-backed action and citation audits in one call per answer; regex and off modes no longer run a separate citation model
  • ui: Clarify audit limitations, settings and provider data sharing

[3.4.0] - 2026-11-05

Added

  • agents: Align token budgets with model limits
  • ui: Stream active run status through app events
  • branding: Add branded builds for installed package

Fixed

  • stores: Clean staging directories with bounded retries
  • ui: Split liveness from runtime diagnostics
  • ui: Keep runtime status notice click-through
  • ui: Move notification prompt to navigation
  • ui: Keep routine runtime status out of banners
  • ui: Reserve docked sidebar space for status banners
  • package: Restore published build resources
  • package: Add release assets to packed builds
  • package: Verify production consumer builds
  • branding: Validate assets and resolve hoisted dependencies

Changed

  • hooks: Keep pre-commit tests focused
  • ui: Reuse top banner stack for runtime status
  • contributing: Add open and chained pull request sop

Added

  • ui: Share live run activity over the app event stream.
  • feat: Build a branded app from the installed Jarela npm dependency and config/assets.

Changed

  • agents: Scale usage-strategy context and output budgets to selected-model limits.
  • ui: Keep routine runtime-health details out of the top-banner area.
  • ui: Move system notification permission controls into navigation preferences.

Fixed

  • ui: Add fast server liveness, report active runs, and honor live agent streams.
  • release: Package runtime helpers and adoption data, and keep dev-only complexity lint out of builds.

[3.3.3] - 2026-11-03

Fixed

  • ui: Prevent premature server outage banner

[3.3.2] - 2026-11-02

Added

  • bridges: Add source timestamps to bridge messages.

Fixed

  • agents: Require explicit advertisement generation and avoid generation during inspection.
  • agents: Use choice controls for bounded decisions.
  • release: Prevent duplicate publication.
  • ui: Prevent overlapping health probes.

Changed

  • Document the stable architecture and correct broken documentation links.

[3.3.1] - 2026-11-01

Fixed

  • agents: Fix panel errors and keyboard access
  • agents: Fix advertisement scope and shared controls
  • ui: Fix avatar read errors and stale upload results
  • tools: Fix incomplete grep and result reference readback
  • agents: Fix output defaults and reuse context fallback
  • e2e: Keep prompt context for mock runs
  • memory: Fix encrypted revision history on updates
  • files: Add range guard for oversized reads
  • text: Reuse bounded utf-8 truncation

Changed

  • runtime: Remove duplicate shared operations
  • release: Keep runtime cleanup notes unreleased
  • tasks: Remove duplicate task and watcher detail rows
  • config: Reuse runtime config for tool result limits
  • approvals: Add lifecycle tests and enforce coverage
  • config: Reuse canonical usage strategy definitions
  • stores: Restore coverage gating for six stores
  • tools: Update search-first and bounded-read guidance
  • tools: Align file-read guidance assertions
  • memory: Reuse write contracts across form and api
  • whatsapp: Reuse media download and storage flow

Fixed

  • Preserve bounded revision history when updating encrypted structured memories, including legacy records. Fail before replacing an unreadable encrypted previous value instead of silently discarding it.
  • Report skipped oversized, binary and unreadable file_grep candidates so incomplete searches cannot be mistaken for confirmed no-match results.
  • Accept unambiguous legacy content hashes when reading text/JSON tool spills, clarify full reference names and async-list scope, and distinguish read failures from missing references.
  • Keep avatar uploads in the agent, profile and first-run editors consistent: report file-read errors, cancel superseded/unmounted reads and prevent late results from overwriting a newer selection or a removed icon.
  • Show agent-list and delete/duplicate failures in the Agents panel, retain retryable controls, and provide keyboard-accessible editing with separately labeled actions.

Changed

  • Gate approval-store coverage with the existing 80% thresholds and expand SQLite-backed lifecycle tests for single reservations, immutable outcomes, restart recovery, encrypted results and atomic signal-publication rollback. Production approval behavior is unchanged.
  • Reuse canonical usage-strategy choices, types and parsing in environment configuration. Preserve normalized process-env values and strict persisted and per-agent values without changing strategy defaults or profiles.
  • Expand deterministic store tests for configuration updates, watcher bookkeeping, document-source lifecycle, memory encryption/search and allowed-site cookies. Restore coverage gating for six previously excluded stores without changing production behavior or coverage thresholds.
  • Prioritize targeted file searches and explicit line-range reads in agent guidance, tool descriptions and spill hints. Discourage exhaustive file paging unless the task requires complete inspection; keep existing inline-result and file-read limits unchanged.
  • Require both line-range endpoints for files larger than the shared inline tool-result threshold. Unbounded calls return an explicit range-required error with navigation metadata, not whole-file content. Preserve small reads, explicit-range clipping and existing configuration defaults.
  • Reuse shared UTF-8 truncation for error reports, preserving complete emoji at the byte boundary. Find bounded prefixes by binary search instead of repeatedly rescanning oversized text; existing byte limits are unchanged.
  • Share memory write schemas between the editor and create/update endpoints, with contract tests for missing values, JSON null, identifier spelling, protected settings and save failures. Existing response shapes are unchanged.
  • Consolidate WhatsApp media extraction into one typed download/store loop, preserving per-kind filenames, MIME fallbacks, attachment order, captions and independent failure handling with inbound pipeline regressions.
  • Raise the default adaptive output floor for Balanced and High Reasoning to 8,192 tokens so short prompts have more room for large tool calls. Provider, model and context ceilings still apply; Fast and Cost-saving retain their 2,048-token baselines.
  • Route the existing tool-result inline-byte limit through the shared runtime configuration and expose it in advanced environment settings. Preserve its 16 KiB default, shared spill/readback behavior and operator-only control.
  • Share the scheduled-task and watcher detail-row layout without changing editor validation, controls, or in-flight state.
  • Manage advertisement generation policy once in the Agents panel and keep per-agent enable/regenerate controls in the editor. Refresh untouched global fields from saved settings while preserving unsaved edits.
  • Generate agent advertisements from exclusive permitted tools rather than the full tool catalog. Omit shared tools and omit all tool descriptions for a single saved agent; refresh selection on roster/permission changes without changing execution permissions or the bounded advertisement output.

  • Share stored attachment decoding between chat rendering and history assembly, best-effort context deadline handling, tolerant app-settings JSON reads and telemetry statistics defaults; unify nullable agent enum overrides while reusing canonical usage-strategy choices. Preserve zero-budget recall differences, strict policy validation and existing fallback behavior.

  • Reuse the lifecycle version reader in the update route, share tolerant stored-topic array parsing and preserve cause-aware error details through a common formatter for health probes and image generation.

[3.3.0] - 2026-10-31

Added

  • workflows: Add checked skill and durable execution
  • workflows: Add inert authoring and contribution builders
  • workflows: Add reviewed authoring lifecycles
  • agents: Add derived advertisements and bounded delegation

Fixed

  • runtime: Fix tool proxy and stream recovery

Changed

  • workflows: Fix contribution ownership harness portability
  • deps: Bump the docs group with 2 updates
  • deps: Bump actions/setup-node from 6 to 7 in the actions group
  • deps: Bump the npm group with 6 updates
  • agents: Document modular agent guidance
  • api: Align responses and local validation guardrails
  • core: Remove function exceptions and align contracts
  • api: Remove duplicate cache and response policies

Added

  • Add shared v1 API error construction and lint enforcement without changing response envelopes, statuses, retry headers, or domain probe results.
  • Add a 150-line production function-body ratchet with reviewed existing-debt exceptions, shared document-source serialization, and API contributor guidance.
  • Keep pre-commit unit tests focused for configuration, dependency, hook, deleted module, and large changes; run the full suite in CI or on explicit local opt-in.

  • Add opt-in, configured-model generation of bounded agent specialization advertisements after committed config saves, encrypted freshness/race handling, local inspection/regeneration/disable controls and an authorized delegate catalog with explicit overflow. Private instructions are no longer used as legacy catalog descriptions. Advertisements never grant permissions or prove expertise; human/live semantic-selection acceptance remains separate.

  • Add shared delegation call/deadline/pricing-estimate budgets, per-inference reservations, queued authority rechecks and bounded handoff/result contracts. Unknown pricing fails closed; delegated turns no longer automatically retry.

  • Start roadmap W3/W4 authoring and contribution with inert synthetic-service scaffolds, bounded local-only exact-diff review bundles and task-specific built-in skills. Separate execution, installation, commit, push and draft-PR gates remain mandatory; this slice does not execute, activate or publish code, verify caller-reported tests, or complete the roadmap release acceptance.

  • Add independently reviewed extension staging, owned fixture execution, exact-source installation, configuration, agent enablement, actual verification and explicit disable/removal/restoration. Retain user-owned inert source across restarts without recovering execution grants; expose local review controls in Skills and invalidate changed/expired approvals.
  • Add repository-inspected contribution tests and local review bundles with independent commit, topic-push and draft-PR gates, exact worktree/source/hook baselines, sensitive-content blockers and explicit missing-credential failures.

Fixed

  • Share list/value client-cache lifecycle and notification setters, model inline-secret preservation/redaction, and bridge-route/skill-repository response serializers; preserve cache races, copying, events and v1 contracts.
  • Use Node's built-in SQLite in document-search regression tests instead of an undeclared native dependency that failed clean CI installs.
  • Derive document-source mutation and statistics types from shared Zod schemas used at collection/item boundaries, preserving v1 payloads and validation.
  • Defer provider setup-guide content until its disclosure opens; retain the guide text and native keyboard-accessible disclosure behavior.
  • Batch document-source listing statistics into one SQLite query instead of three aggregate queries per source; preserve counts and response shapes.
  • Reject failed environment restart requests before health polling, cancel panel-owned requests and polling on unmount or scope changes, bound stalled health requests to 30 seconds, and retain drafts when settings reload fails.
  • Remove the remaining grandfathered function-size exceptions through typed lifecycle, stage, and view ownership boundaries; retain the 150-line guard.
  • Separate backend configuration normalization, migration schema data, bridge event/typing lifecycles, and contribution worktree staging; share dashboard attribution accumulation and currency response paths without changing their persistence, approval, or response contracts.
  • Split agent admission, preparation, streaming, retry, persistence, accounting, and delegation validation into typed stages while preserving assembled prompt bytes and existing queue and transcript behavior.
  • Separate UI lifecycle/mutation controllers from cohesive chat, configuration, approval, setup, package, and notification views, retaining existing public hook contracts and interaction behavior.
  • Consolidate document-search SQL, exclusion lookup, and substring fallback; preserve semantic thresholds, fail-closed topic filtering, and reindex repair.
  • Consolidate local document sweep upsert/backfill and per-file error handling, preserving unchanged chunks, forced rescans, embedding retries, and tick limits.
  • Separate credential editor modes, form state/actions, controls, and provider setup guides; keep the card free of credential API calls and remove its function-size exception. Preserve successful save and OAuth contracts while surfacing default-label/Clear failures and ignoring stale editor updates.
  • Extract credential-card OAuth lifecycle into a tested UI hook; prevent overlapping status polls and stale authorization responses after unmount, credential changes, timeout, or retry without changing API payloads.
  • Separate caller argument errors from suspected tool defects, exclude them from telemetry complaints, and require the configured escalation threshold for internal validation failures.
  • Let proxied tools own execution deadlines, background receipts, and streaming controls while preserving workspace, progress, cancellation, credentials, permissions, and coordinator settlement through invoke_tool.

[3.2.0] - 2026-10-30

Added

  • proposals: Add shared choices and artifact approvals
  • skills: Add bounded invocation and result validation
  • skills: Add inert in-memory artifact capture
  • skills: Add memory cleanup execution bundle contract
  • skills: Add bounded raw execution output capture
  • workflows: Add gated staged runner and durable coordinator

Fixed

  • proposals: Fix response delivery and outcome review
  • agents: Update chat and review interaction guidance
  • proposals: Add context for delayed user responses
  • proposals: Hide internal continuation messages from chat

Changed

  • proposals: Verify answered inputs remain hidden
  • prompts: Add structure and size verification guidance
  • cleanup: Remove confirmed unreachable code
  • acceptance: Add coverage for previously skipped checks
  • skills: Add policy http acceptance regressions

Added

  • Integrate explicit checked skill requests, exact-code approval review and platform-owned execution with durable encrypted workflow controls, typed answers, restart recovery, read-back reconciliation and conservative staging cleanup. Discovery remains inert; full-trust scripts are not sandboxed and unavailable ownership backends fail closed.

  • Add inactive run-owned skill staging, exact-consent runner orchestration and a bounded durable workflow coordinator with checked bindings, one retry budget, persisted choices, CAS ownership and uncertain-write reconciliation. Production activation and process-owner backends remain unavailable.

  • Add internal bounded raw skill stdout/stderr capture with strict streaming UTF-8 checks, terminal failures and shared result-schema validation; no process launch, execution authorization or cleanup guarantee is enabled.
  • Add an experimental Memory Organization execution manifest over the existing read-only planner, with bounded nullable/result schema alternatives and captured-byte CLI contract tests. Checked skill execution remains unavailable.
  • Add internal bounded skill invocation/result schema validation without enabling execution; share invocation parsing with exact-byte consent digests. Reject reserved manifest property names rather than silently dropping them.
  • Add opt-in, inert in-memory skill artifact capture with exact-byte content revisions, defensive copies, bounded assets and source-change detection. No executable staging, runner or authorization is enabled.

Added

  • Unified skill and scheduled-task/watcher prompt approvals under propose_config_change, with stale-content checks and verified application. Version adoption now queues real approval controls rather than chat-only confirmation requests.
  • Choice questions use the same proposal tool and review UI, with single/multiple selections, optional text responses, and validated persisted answers.

Fixed

  • Hide internal proposal-continuation instructions from chat, preserving their visibility metadata through queueing and retries without hiding user messages.
  • Keep delayed choice answers tied to their original questions and reconcile them with newer chat instructions rather than blindly resuming obsolete work.
  • Route agent interaction guidance through chat or the shared review UI, with explicit chat fallback, credential-only secret entry, and no duplicate confirmation for queued requests.
  • Resume chat after proposal responses without repeating approved operations; retain visible outcomes across polling, expose complete artifact previews, and return consistent decoded proposal payloads/results from API endpoints.

Changed

  • Remove unreachable task-editor and notification-test remnants, obsolete chat geometry helpers, unused credential-picker calculations, and stale tool-runtime imports without changing active workflows or registered tools.

[3.1.0] - 2026-10-29

Added

  • skills: Add inert execution manifest inspection
  • skills: Add run-scoped execution consent contract
  • skills: Add portable bundle metadata and resource reads
  • security: Add skill execution consent settings
  • security: Add persistent skill checksum approval records
  • skills: Add portable scripts for deterministic built-in steps

Fixed

  • navigation: Add missing tabs to deep-link parser
  • http: Align byte limits across response body paths
  • text: Avoid splitting surrogate pairs when truncating
  • limits: Configure more forgiving resource ceilings
  • agents: Add adaptive budgets and truncated tool call guards
  • skills: Update built-in workflow contracts
  • skills: Align built-in guidance and catalog e2e assertions
  • agents: Require code-first skill and workflow steps
  • agents: Fix adaptive thinking budget compatibility
  • providers: Fix incomplete tool argument dispatch

Changed

  • direction: Add post-3 extension-first roadmap
  • checkpoint: Use one parent config mapper
  • direction: Add minor-upgrade plan and w0 baseline
  • direction: Group related work into three milestones
  • skills: Add shared-bundle portability requirements

Added

  • skills: Back Personal Briefing validation and Memory Organization cleanup planning with portable dependency-free scripts, used by fixed read-only tools. Add plan_memory_cleanup for explicit-time expiry and exact duplicate candidates; it never scans or mutates memory. Include standalone JSON CLIs, copied-bundle/tool parity tests and cleanup fixtures. No general runner enabled.
  • skills: Add an internal, tested run-scoped consent contract binding one-use decisions to artifact/input/workspace/runtime identity and limits, with expiry, cancellation and stale-decision rejection. Record the selected non-resumable lifecycle in ADR-0112. This does not enable execution, capture snapshots or add a user-facing approval action.
  • skills: Add opt-in shared-bundle metadata diagnostics and a read-only read_skill_resource tool for bounded UTF-8 references, text assets and script source relative to the selected skill. Parse discovery metadata with YAML semantics, preserving original files and reporting unsupported host fields. This does not execute scripts or certify cross-host compatibility.
  • security: Add persistent skill execution consent policy in Privacy & security: block, ask each time, approve a workflow run, or trust exact revisions scoped to agent/workspace and limits. Safe mode remains authoritative; generic memory writes cannot change policy. Save server-issued approval records once per checksum scope, preserving their IDs/timestamps across restarts and allowing revocation in settings. This configures future consent requirements, not an enabled script runner or workflow approval engine.
  • skills: Add opt-in, inert read_skill inspection of experimental execution.json declarations, bounded schemas and declared file metadata. Invalid metadata produces explicit issues; prompt-only skills and default reads are unchanged. Inspection never executes code or grants approval and always reports execution unavailable.

Changed

  • skills: Modernize all seven packaged playbooks with discovery metadata, explicit input/output/validation contracts, bounded recovery and current configuration/source guidance. Include every built-in in prompt review; these remain prompt-only procedures, not an executable skill runtime. Discover optional bundle resources/inspection and Security approval features from installed schemas; distinguish checksum trust, execution and planned interaction panels. Prevent self-approval or memory-based trust workarounds.
  • agents: Make skills and workflows code-first for both execution and validation. Reuse authorized tools/code for codifiable steps; reserve model steps for intent, ambiguity, judgment and explanation, without bypassing unavailable execution support or consent.
  • agents: Allocate turn output tokens from the current user-text size estimate with 4x headroom and strategy/reasoning baselines, bounded by explicit model settings (or static model-limit fallbacks), and context allocation.

Fixed

  • tools: Prevent incomplete provider tool JSON from being silently repaired into missing write_skill/file_write content or empty invoke_tool arguments. Validate full streamed batches before dispatch, reject malformed non-streamed OpenAI-compatible arguments, and preserve otherwise-lost truncation reasons. Verify large direct and proxied bodies through the actual agent/tool path.
  • agents: Preserve explicit output-token limits over static catalog fallbacks and reject thinking budgets that cannot fit the effective output allocation before requesting a model response.
  • agents: Reject tool calls when the model reports output-token truncation, rather than executing potentially incomplete arguments.

[3.0.1] - 2026-10-28

Added

  • docs: Add generated interactive project history

Added

  • docs: Add an automatically generated interactive project-history chart with commit-type stacks, time and version grouping, accumulated net text lines, date and lockfile filters, and CSV export, without an editorial storyline.

Changed

  • tools: Raise default fetch, exec-output, file-read, and file-write ceilings; document indexing defaults now allow 10 MiB files and 20,000 files per source. Configured document-size limits are consistently honored by local sweeps, file watchers, and GitHub repository indexing. Artifact lifecycle settings now allow up to 10 years of retention and 100 GiB of storage.

[3.0.0] - 2026-10-27

Added

  • ui: Enrich desktop agent rows with profile, model configuration, selected-tool counts, and readable unread counts; add a selected-agent card with its icon and Markdown-rendered identity and instructions above the docked right menu, with quick model, usage-strategy, and voice controls, without changes to small-screen layouts. Agent-setting saves refresh chat controls immediately.

  • adoption: Publish the per-release changelog in the docs site and ask the adoption agent to prefer the schema-versioned JSON changeset feed when web access is permitted, retaining bundled changesets and offline operation.

  • mail: Add iCloud SMTP sending with mandatory STARTTLS, explicit execute-tool permissions, configured sender identity, and partial/uncertain-delivery errors.

  • documents: Align Gmail, Outlook, and iCloud indexing with Inbox, chosen folder/label, or whole-mailbox scopes, optional search and result limits, and automatic archive refresh.

  • documents: Add explicit indexing opt-in for supported connected integrations, nonlocal embedding warnings, global semantic topic exclusions, and document-level exclusions with a user-only search preview override.

  • tools: Add an opt-in DeepSeek Search & Fetch backend for web_search and web_fetch, using a separately encrypted credential and preserving existing backends by default.

  • models: Add source-backed model version and capability observations to catalog and badge metadata without changing saved models or enabling APIs.

Changed

  • agents: Focus local tool-history hints on task-matching allowed tool names, retrieve only bounded recent failure categories, and distinguish execution success from verified task completion without embeddings or extra model calls.

  • tools: Align iCloud mail trash and calendar deletion with Gmail/Outlook's write capability, preserve Mail/Calendar categories after package reload, and correct Gmail/Outlook send descriptions.

  • db: Reuse a bounded per-connection cache of prepared statements for repeated thread/history reads, without caching query results.

  • runtime: Drop Node 22 support; require Node 24.15.0+ on 24.x, or Node 26+. CLI and production launchers reject unsupported runtimes before loading the application. Upgrade Node before installing 3.0.0; bundled installers already include Node 24.

Fixed

  • release: Automatically recover untagged releases after content-identical base rebases, validating the exact release commit rather than later main.

  • dashboard: Show separate input/output spending across summaries and usage breakdowns, label model rates explicitly per million tokens, and retain unsplittable recorded costs as unattributed.

  • ui: Avoid stacked backdrop filters on touch surfaces to keep mobile interactions responsive.

[2.7.0] - 2026-10-25

Added

  • chat: Add docked navigation and full-width chat.

Fixed

  • redaction: Add provider-wide masking and broader detection.
  • ui: Update menu navigation and fix browser startup.
  • e2e: Fix panel selectors for docked navigation.

Changed

  • runtime: Build release archives and native packages with Node 24.15.0; use Node 24 for Docker and Node 24.15.0 for CI.
  • mcp: Include structured tool results as model-visible JSON alongside the original content, without exposing private MCP protocol metadata.
  • chat: Add sanitized SVG downloads and expandable, copyable source for Mermaid diagrams.
  • deps: Upgrade Anthropic SDK, MCP adapters, Mermaid, and jsdom major versions; retain the 2023 Anthropic Messages API version so existing sampling settings remain valid.
  • mcp: Preserve unprefixed tool names and disable elicitation prompts with MCP adapters v2.
  • runtime: Require Node 22.22.2+ on Node 22, 24.15.0+ on Node 24, or Node 26+. Users on older Node versions must upgrade Node before updating Jarela. The maintainer explicitly approved this narrower runtime support for a minor release as an exception to the usual major-release policy.
  • deps: Upgrade p-queue to 10 and update other runtime and development dependency patches; retain TypeScript 6.0.3.
  • docs: Migrate the documentation site toolchain to Zensical.

[2.6.1] - 2026-10-24

Fixed

  • release: Fix commit parsing for merged release recovery
  • release: Fix linux packages and duplicate release validation
  • tools: Normalize narrative field lengths
  • release: Add scoped release workflow approval

Changed

  • workflows: Pin linux runners to 26.04

[2.6.0] - 2026-10-24

Added

  • ci: Add nightly app release pipeline
  • chat: Render latest agent reply in menu
  • skills: Add code-validated personal briefing pilot
  • cli: Add a version command to verify upgrades
  • skills: Run representative fixtures against workflow check tools
  • agents: Add duplicate so tuned agents can be reused as templates
  • cli: Add a backup command that snapshots data without keys
  • workspace: Reuse recent workspace tree scans
  • integrations: Add declarative credential probes
  • agents: Add unified per-agent persona profiles
  • ui: Add animated agent switcher with unread indicators
  • release: Add on-demand copilot documentation gate

Fixed

  • deps: Update next 16.4.0 to 16.4.2 for security
  • setup: Fix first-run model selection and save recovery
  • agents: Keep async tool handoffs out of success evidence
  • credentials: Add retry for provider catalog failures
  • scheduler: Fix unhandled tick failures and recovery
  • documents: Skip queued reindex jobs for disabled sources
  • tools: Skip invalid stored location coordinates
  • tools: Keep watchers limited to read-only tools
  • tools: Keep provider status in image generation errors
  • tools: Skip inverted calendar event windows before sending invites
  • tools: Keep user-blocked agent workflow steps out of retries
  • tools: Keep scheduled tasks from firing empty or bogus schedules
  • privacy: Remove attachment files when their conversation is deleted
  • privacy: Keep files referenced by encrypted memory entries
  • release: Detect prerelease upgrades and explain update failures
  • release: Use full prerelease identifiers in update checks
  • tools: Drop finished delegate jobs after a retention window
  • tools: Drop expired delegate jobs on status reads too
  • tools: Keep terminal input behind the exec safety gate
  • terminal: Gate continued terminal input
  • skills: Keep frontmatter skill descriptions visible to agents
  • skills: Render block-scalar frontmatter descriptions
  • cli: Block backups that reach the data dir through links
  • workspace: Use the on-disk root as the tree scan cache key
  • agents: Render local date and time in the system prompt
  • agents: Normalize local offset signs in the time context
  • chat: Normalize metadata row spacing
  • chat: Normalize metadata width on narrow screens
  • chat: Prevent oversized photos from reaching the model
  • chat: Keep gif and svg photos by extension
  • ci: Use loopback for the e2e server inside the container
  • tests: Prevent tests from writing to the real data dir
  • pwa: Fix mobile safe areas and frosted chat overlays
  • release: Remove mandatory documentation review gates
  • release: Publish nightly dispatches by default
  • release: Fix unattended validation and publication
  • release: Fix existing release pr lookup

Changed

  • e2e: Pin runner to ubuntu 24.04
  • e2e: Run playwright in its container to stop install hangs
  • npm: Allow more registry retries to survive resets
  • deps: Enable weekly grouped github actions updates
  • hooks: Run only related unit tests before commit
  • deps: Bump the actions group with 5 updates
  • ui: Update persona browser checks for agent profiles

Added

  • Built-in and drop-in provider integrations can declare read-only HTTPS credential probes instead of hand-written probe code.

Fixed

  • Firecrawl Search credentials can be tested from the Credentials panel.

Security

  • Upgrade Next.js and its ESLint config to 16.4.2 and enable security-upgrade reminders.

Fixed

  • Large phone photos and HEIC images are downscaled to a 1568px JPEG before upload so they stay under provider image limits.

[2.5.3] - 2026-10-22

Fixed

  • Keep startup and agent-selection feedback accurate while agents and chat history load, with one current-action status on the boot screen.
  • Standardize interface transition timing, respect reduced-motion preferences, and keep dashboard chart animations restrained.
  • Keep token date labels below the plot so they do not overlap chart data.

[2.5.2] - 2026-10-20

Fixed

  • Preserve substantive chat answers during automatic correction and replace the draft only after a complete repair succeeds. Failed or empty repairs keep the draft and report the failure instead of erasing it.
  • Stop retry backoff promptly on cancellation, respect negative classifier verdicts without explanations, and do not treat failed or unresolved tools as confirmed successes. Keep duplicate-effect guards for uncertain writes.
  • Keep browser-extension field capture, context, replacement, and cleanup working across nested open shadow roots after the focused field loses focus.
  • Allow ordinary summary headings without triggering an action-fabrication retry.
  • Keep open navigation menus above error notifications so overlapping toasts do not block Settings or other menu controls.
  • Retry transient Windows file-lock failures while removing traced standalone artifacts during postbuild cleanup, without accepting incomplete bundles.
  • Keep Atlassian credentials on the configured tenant, route scoped tokens by product and Cloud ID, and follow documented Jira/Confluence pagination and endpoint contracts. Verify access to both products in the health probe.
  • Restrict authenticated GitHub, Google, and Microsoft Graph requests to their documented API origins, and align Microsoft Search scopes and Outlook setup guidance with the available tools.
  • Convert Outlook RFC3339 event instants to Microsoft Graph's offset-free dateTime/timeZone payload, map Windows time zones, and reject invalid dates or unknown time-zone identifiers.

Adoption

  • Outlook users must reconnect to grant the newly requested Files.Read.All and Sites.Read.All scopes for OneDrive and SharePoint Search. Review the Microsoft consent screen before granting access.

Changed

  • Separate thread retries, message content rendering, extension form editing, and Jira Agile tools into focused modules while preserving existing entry points.

[2.5.1] - 2026-10-19

Fixed

  • Show launch progress while waiting for the local server to respond.
  • Restore dashboard backgrounds, text, borders, chart colors, and selected controls in light and dark themes.

[2.5.0] - 2026-10-18

Added

  • Add appearance presets and accent-color choices, and reorganize configuration panels for a more consistent workspace.

Fixed

  • Let assistant replies use the available chat width and keep long tool names, status indicators, expanded tool details, and the composer within narrow screens.
  • Align configuration panel widths on desktop and mobile.
  • Refresh provider model catalogs and capability metadata.
  • Resolve optional tool packages from the workspace when their package entry point is unavailable.

Changed

  • Reuse short-lived startup reads between the agent picker and chat so the first agent load warms profile, configuration, and conversation data without duplicate requests. Writes and run submissions invalidate the handoff.
  • Speed up chat pagination, dashboard date windows, and thread lists with automatically created SQLite indexes. The first startup after upgrading a large database may take longer while indexes build.
  • Index latest usage, memory ordering, signal cleanup, background retention, and expired leases; find the next embedding wakeup with indexed lookups instead of scanning the active queue.
  • Reduce chat refresh work with metadata-only, visibility-aware polling and reuse historical message rows during streaming updates.
  • Reuse unchanged dashboard computations briefly, avoid loading snapshotted message bodies for token estimates, and skip rereading unchanged pricing snapshots. Database writes and pricing changes invalidate server-side metrics.

[2.4.0] - 2026-10-16

Added

  • Link answers back to the source: Gmail, Outlook mail and calendar, and Google Calendar results carry a web link and a ready-made cite_as markdown link, and WhatsApp 1:1 bridge messages carry a wa.me chat link, so agents can point you at the exact email, event or chat. Group chats and single WhatsApp messages have no public link. Replies delivered to WhatsApp use bare URLs.

Fixed

  • Stop bridge-heavy threads from showing "Compacting" and running an empty compaction on every turn, and stop topic detection from re-running every turn after a hot-turn-limit pass.
  • Always send localhost traffic (Ollama, the WhatsApp bridge, Jarela's own API) directly when an HTTP proxy is configured, accept IPv6 proxy hosts, and reject manual proxy hosts that include a scheme, port, path or credentials.
  • Replay each WhatsApp chat's offline backlog separately so one active chat no longer causes others to lose messages, and keep known chat names when a contact sends a blank name.
  • Keep tuned persona sliders when an approved proposal or tool edit updates an agent, apply hot_turn_limit from proposals, reject negative or fractional limits, and drop blank or duplicate tool names.
  • Save facts about non-Latin subjects under their own memory keys instead of colliding, and stop replacing a fact from deleting an unrelated one.
  • Keep distinct Outlook and Gmail links as separate citations, keep closing code fences and horizontal rules when deduplicating instruction lines, and fix fuzzy edits on CRLF files and paged reads that split multi-byte characters.

Adoption

  • If an agent's instructions or skills tell it not to include links or URLs in replies, decide whether it should now cite sources with the provided cite_as and chat links.
  • If you listed localhost or 127.0.0.1 in the proxy bypass list only to reach local services, you can remove them; loopback is always direct now.

[2.3.0] - 2026-10-16

Added

  • Compact earlier messages as validated topics: messages are grouped into topics, each topic gets a recap, and the recaps are merged in code. Every step's output is checked in code and retried once before falling back. Scheduled tasks, watchers and bridges are compacted with the same topic pipeline.
  • Agents save new facts to memory in the same turn with memory_upsert, check that the save succeeded, and cite the saved key, instead of waiting for background compaction.
  • Retry a single workflow step from the chat or the version-adoption checklist. Steps that fail validation retry automatically up to 3 times each.
  • Record a changeset of prompt and tool changes with every release, so version adoption can show what changed and adapt settings, task prompts, instructions and skills after an upgrade.
  • Show what a thread is doing (thinking, responding, preparing context, compacting) after switching agents or reloading, including turns started by a scheduled task, watcher, bridge or another device.

Fixed

  • Stop compaction after a time limit and allow only one compaction per thread at a time. The limit defaults to 10 minutes and is set with JARELA_COMPACTION_TIMEOUT_MS. /compact now says when a thread is already compacting or the attempt timed out.
  • Allow compacting agents whose only messages come from bridges, watchers or scheduled tasks, and show those recaps in the summary card instead of a summary that stays pending.
  • Report compaction results as toast notifications, and keep showing the compacting state after switching agents.
  • Show older summaries as collapsible topic rows instead of one long block.
  • Keep "locate boundary" and message deep links from snapping back to the bottom.
  • Install the current working tree, including uncommitted changes, from both make.ps1 and Makefile, and reinstall dependencies when package-lock.json changes.
  • Remove the unused @langchain/deepseek dependency; DeepSeek still runs through the OpenAI-compatible adapter.

Adoption

  • If an agent's instructions or skills tell it to leave fact capture to compaction or to avoid memory_upsert, remove that guidance, since agents now save facts during the turn.
  • If a scheduled task or watcher prompt asks the agent to write memory facts, keep that in the agent's own turn; automation channel summaries no longer extract facts.

[2.2.1] - 2026-10-15

Fixed

  • Let models be disabled temporarily so they drop out of model selection and default/router resolution without being deleted, and set the default model in one atomic step that no longer rewrites model params or silently clears the default on edits.
  • Show fresh agents, tasks, credentials, models, and other lists right after a save instead of a briefly stale browser-cached copy.
  • Stop treating a GITHUB_TOKEN environment PAT as a GitHub Copilot credential and report Copilot catalog configuration errors as 400 instead of 500.

[2.2.0] - 2026-10-15

Added

  • Download the Jarela Local embedding model (~135 MB) on first use instead of shipping it in every installer; set JARELA_BUNDLE_LOCAL_EMBEDDING=1 at build time to bundle it for offline installs, or JARELA_LOCAL_EMBEDDING_DOWNLOAD=0 to disable runtime downloads.

Fixed

  • Exclude other platforms' ONNX runtimes, WebAssembly runtimes, and traced git metadata from release bundles, cutting the standalone build from 785 MB to 270 MB together with the on-demand model.
  • Retry loading Jarela Local after a failed model load instead of failing until restart.

[2.1.0] - 2026-10-14

Added

  • Require verified workflow steps: every agent checklist item declares its input, output, and validation, and cannot be marked done without recorded validation evidence.
  • Show third-party pricing aggregator quotes as separate comparison signals alongside direct provider rates.
  • Group the earlier-messages summary by topic, with short recap previews that expand to the full recap and saved facts.

Fixed

  • Show pending state while a manual context compaction is running.
  • Treat legacy completed checklist entries without evidence as needing attention instead of silently passing.
  • Retry transient model-download failures and cache the verified embedding model so upstream outages no longer block releases.

[2.0.5] - 2026-10-13

The v2.0.5 release build failed before publishing; these fixes first ship in 2.1.0.

Fixed

  • Update Baileys' media metadata parser to address malformed-media denial-of-service advisories.
  • Decode gzip responses when upstreams omit Content-Encoding, fixing web fetch, Gmail, and pricing imports.
  • Retry provider streams that end without sending events instead of recording blank completed turns.
  • Report accurate DeepSeek probe statuses and avoid exposing malformed-response parser errors.

[2.0.4] - 2026-10-12

Fixed

  • The npm package loads ONNX runtimes from installed dependencies instead of bundling duplicate native runtimes.

[2.0.3] - 2026-10-11

Fixed

  • The npm publish lifecycle deterministically removes generated standalone source maps before packing.

[2.0.2] - 2026-10-11

Fixed

  • The npm publish lifecycle removes generated standalone source maps before packing.
  • The npm package resolves ONNX runtimes from installed dependencies instead of bundling duplicate native packages.

[2.0.1] - 2026-10-11

Fixed

  • The npm runtime package excludes browser-only and unused platform assets to stay below the registry upload limit.

[2.0.0] - 2026-10-11

Added

  • The dashboard can opt into weekly LLM pricing updates and recalculate current-rate cost estimates without rewriting recorded usage snapshots.
  • Context compaction now validates topic boundaries and summarizes prior topics within the warm budget. Hot-turn and near-budget triggers share the topic-aware coordinator; older transcript remains cold and embedding-retrievable.
  • Submitted chat prompts persist before context preparation, and warm-summary size is configurable per agent. The warm limit defaults to 50 messages; zero disables summaries while older chat remains available to embedding recall.
  • Agents can track complex tasks with visible workflow checklists. Built-in skills define when to use them; updates are verified snapshots, with approval blockers and secrets handled explicitly.

Fixed

  • Linux RPM packaging preserves bundled native addons for non-host architectures.
  • The dashboard vendor-pricing table now shows curated model-rate fallbacks when live pricing-page extraction returns no model rows.
  • The OAuth proxy release audit passes with patched proxy-addr and uuid dependencies.

Breaking Changes

  • Context-boundary cursors now use message sequence numbers. Timestamp-only pins are cleared during migration. API clients must send hot_since_seq for context-pin and run requests; timestamps are display metadata only.

[1.43.2] - 2026-10-09

Added

  • The Memory workspace brings document, memory, and chat search together, with document matches grouped by file.

Changed

  • Automatic recall now runs only with the High Reasoning strategy. Other strategies can still search memory and chats explicitly.

Removed

  • LinkedIn integrations The LinkedIn Personal and LinkedIn Enterprise integrations, their OAuth routes, health probes, and the two never-published @circuitwall/linkedin-*-langchain packages are removed. Previously stored LinkedIn credentials are ignored.

Fixed

  • The chat scroll control explains when auto-scroll is paused and resumes at the latest message.

[1.43.1] - 2026-10-08

Added

  • One embedding model for documents, memory, and chat. Choosing the bundled on-device model (Jarela Local, multilingual, no provider key needed) now applies to document chunks, memory entries, and chat messages, so none of that text reaches an embedding provider. Vectors from a previous model are rebuilt in the background, including swaps between models of the same dimension, with progress shown in Settings, Models. See ADR-0095.
  • One hybrid memory search. Proactive recall, memory_search, memory_list with a search term, and the Memory panel share one search that combines similarity with exact text matches, so keys, ids, and error codes are found even when similarity misses them. memory_search accepts include_chats to also search past conversations, including archived turns, and results label their source. Rows that never received an embedding are now embedded in the background.
  • Global and per-agent usage strategies pick cost-saving, balanced, or reasoning-oriented defaults, with provider retry ownership and durable completion signals.
  • Attachments carry canonical file references and interpretations, so file context stays retrievable across turns.
  • Tool definitions can be deferred under a bind budget, keeping prompts small when many tools are enabled.
  • Pruned chat messages stay recall-able through a chat archive, and a context compaction tool with an idle-gap hint keeps long threads usable.
  • Shared configuration UI. Panels, setting cards with drawers, dialogs, and the pinned save bar are now built from one set of components. Editors ask before discarding unsaved edits, Save and Discard stay visible while a form scrolls, tabs scroll without a scrollbar, and native confirm prompts are replaced by one in-app confirmation.

Changed

  • The embedding model setting moved to Settings, Models and now covers all recall, not only documents.
  • The Packages page groups sources into collapsible drawers and keeps the runtime settings and tool catalog collapsed until opened.

Fixed

  • Gmail search no longer crashes on binary responses.
  • File references stay retrievable, and usage strategy saves are atomic.
  • Stale reads and writes in CRUD stores are prevented.
  • Cost saving stays usable, and DeepSeek limits are refreshed.
  • Context compaction stays within the tool budget.
  • The warm summary cache tolerates near-miss matches.
  • The focus boundary keeps its anchor message on screen, and the tool trail stays visible until the stream refetches.

Security

  • Next.js and KaTeX are updated past published advisories, and vulnerable transitive packages and undici are bumped.

[1.42.3] - 2026-10-01

Fixed

  • Release dependency installs use a pinned npm version to avoid the npm 11.14 workspace lockfile regression that blocked the 1.42.2 security gate.
  • OAuth proxy dependencies use patched fast-uri, closing the remaining high severity advisory found by the tagged release gate.

[1.42.2] - 2026-10-01

Fixed

  • Attachment context no longer re-inlines prior-turn image and file references.
  • Thread embedding excludes serialized attachment blobs and embeds text only.

Security

  • Workspace package builds no longer use the vulnerable tsup/esbuild toolchain.

[1.42.1] - 2026-10-01

Fixed

  • Patch release metadata is synchronized with the package version. The project version and changelog now match for the 1.42.1 release train.

[1.42.0] - 2026-09-23

Added

  • File edits now provide resilient matching and diagnostics. file_edit and file_multi_edit report nearby matches and occurrence lines, tolerate CRLF/LF differences, and support opt-in trailing-whitespace and normalized-whitespace strategies. Batch failures also report how many leading edits were clean.
  • Delegated turns now render as structured conversation cards. Claude Code and Codex exchanges show the request, progress, and response as distinct turns instead of a flat tool transcript.

Changed

  • Claude Code and Codex delegation now grants full access under mostly_safe. The safe tier remains the blocking mode; callers that need the previous read-only behavior must explicitly select safe.

Fixed

  • Pinned context boundaries render when persisted summary metadata is absent. A saved boundary is now visible even when a thread response has no warm-summary fields.
  • Mobile E2E coverage stays focused on browser-specific behavior. Chromium retains the complete workflow suite while Mobile Safari covers viewport, composer, boot, and context-boundary contracts without duplicating desktop-only workflows.

  • Jira option-type custom fields accept plain strings. jira_update_issue and jira_create_issue now auto-wrap a plain string (or array of strings) as {value: "..."} for single/multi-select custom fields — Jira Cloud rejects a bare string for those with "Specify a valid 'id' or 'name'".

  • MCP and external tool schema errors include the field-level detail. A tool call that fails JSON-Schema validation now surfaces the underlying field path and expected/received type instead of a bare "did not match expected schema" message.
  • invoke_tool gives one consistent error when targeting itself. The schema-level and runtime rejections used to word the same mistake differently, driving pointless retries.
  • file_write / write_skill give an actionable error when content is omitted, instead of zod's generic "expected string, received undefined".
  • tool_result_get accepts the older flat {name, offset, limit} shape as shorthand for result_ref.name, with a deprecation warning.

Breaking Changes

  • Delegation safety defaults changed. claude_delegate and codex_delegate no longer default to read-only behavior under JARELA_TOOL_SAFETY=mostly_safe; use JARELA_TOOL_SAFETY=safe to block these tools.

[1.41.7] - 2026-09-21

Fixed

  • Jira option-type custom fields accept plain strings. jira_update_issue and jira_create_issue now auto-wrap a plain string (or array of strings) as {value: "..."} for single/multi-select custom fields.
  • MCP and external tool schema errors include field-level detail. Invalid calls now expose the underlying field path and expected/received type.
  • Tool reliability fixes improve actionable errors and compatibility. invoke_tool, file_write, write_skill, and tool_result_get now handle the reported self-target, missing-content, and legacy result-reference cases.
  • Markdown preview height matches the editor line height. Preview mode now uses rem-based sizing consistent with the editor.

[1.41.6] - 2026-09-11

Fixed

  • Transient web-search transport failures recover automatically. DuckDuckGo searches now retry temporary network, rate-limit, and upstream server errors while preserving immediate handling for non-retryable responses.

[1.41.5] - 2026-09-11

Fixed

  • Transient provider stream failures recover automatically. Provider connections that end before producing model output now use the shared retryable stream-error path, while partially streamed responses are not replayed blindly.

[1.41.4] - 2026-09-10

Fixed

  • Blocked tool failures retain their context and can trigger recurring alerts. Permission-denied tool calls now use a dedicated telemetry failure class with the original blocking context, and recurring tool failures can raise an actionable issue instead of remaining hidden in generic execution errors.
  • Optional package installs use peer dependencies by default. Package installation now keeps shared dependencies at the host application's level unless a package explicitly requires bundled dependencies, avoiding unnecessary duplicate installs.

[1.41.3] - 2026-09-10

Fixed

  • Markdown-aware text editors open in edit mode when empty. After 1.41.2, MarkdownTextarea defaulted to preview mode even for blank fields, which hid the input behind a "Nothing to preview" placeholder on fresh profiles and broke the Playwright locator for the "About me" textbox. The initial mode is now derived from the incoming value — preview when there is content to render, edit when the field is empty.
  • Consumer builds no longer choke on integration-only type imports. Package types that referenced integration-only modules leaked into the consumer build; the shared types are now scoped so downstream projects can compile against the published package again.
  • Jira Align telemetry uses endpoint-specific filter fields. The Jira Align integration sent the same generic filter payload to every endpoint, causing empty result sets on endpoints that expect their own field names. Each endpoint now maps to its documented filter shape.
  • Blocked tool calls surface as their own telemetry failure class. Tool invocations that were denied by permission rules previously registered as generic execution failures, hiding the underlying cause. Telemetry now classifies them as blocked so the reason is visible upstream.

[1.41.2] - 2026-09-09

Added

  • Mermaid diagrams and safe dialogs now render in chat. Mermaid content is displayed as diagrams, while potentially unsafe dialog content is rendered through the existing safe markdown path.

[1.41.1] - 2026-09-08

Fixed

  • E2E boot and panel checks are more reliable. The boot picker now keeps its primary tile above recent-agent entries, shared SQLite-backed tests run without worker races, and the Memory namespace assertion targets the correct control.

[1.41.0] - 2026-09-07

Added

  • Structured memory records now carry a recall summary, search aliases, and a soft-delete status. memory_upsert accepts optional summary and aliases fields to improve search recall, and status="archived" retires a record from recall without deleting it. Every update snapshots the prior record into a capped, dated history so revisions are never lost. Existing records are upgraded automatically the first time they are read; no database migration is required. See ADR-0084.

[1.40.0] - 2026-09-07

Added

  • Jarela agents can delegate coding work to Claude Code and OpenAI Codex. Delegation uses local CLI authentication and project configuration, keeps Jarela as the only user-facing agent, and shows an inspectable inline transcript of the delegated exchange. Codex supports the local ChatGPT sign-in, configured plugins, skills, MCP servers, trusted profiles, and extra writable directories. See ADR-0071.
  • Long-term memory is structured, proactive, and tunable. Agents can save versioned facts with searchable subject/tags, confidence, provenance, observed date, and expiry through memory_upsert. Recall uses those fields for semantic retrieval, excludes expired records, and remains compatible with existing free-form notes. The new Memory Organization skill documents consolidation and retrieval practice; the Memory panel offers Important only, Balanced, and Detailed proactive-memory policies. See ADR-0084.

Fixed

  • Silent bridge routes listen without treating every message as a reply. The bridge prompt now frames silent mode as observe-only context gathering: the agent may use allowed non-chat tools or internal state according to its instructions, but it must not draft or send chat text, and should emit NO_REPLY unless there is an important internal note for the paired user.
  • Per-agent chat filters no longer bounce back after switching agents. A delayed response from a previously selected agent can no longer overwrite the active agent's filter state, including the Bridge Listener's filters.

[1.39.3] - 2026-09-06

Fixed

  • Automatic model switches keep the current context. The router now measures how much hot conversation context the turn needs before choosing a model, then evaluates candidates through the same context-budget calculator used to build the prompt. A cheap or fast fallback can no longer win simply by ignoring that it would force the history window to drop the thread the user is continuing.
  • User-authored bridge replies are attributed to the user, not the contact. Bridge messages now carry an explicit sender JID through the adapter contract. WhatsApp fromMe replies in 1:1 chats are framed as coming from the paired account (You) instead of inheriting the chat/contact name, so the agent does not mistake the user's own reply for the other participant.

[1.39.2] - 2026-09-05

Added

  • The agent knows which page you are looking at. While the extension side panel is open it reports the focused tab's URL, title and host to Jarela, so "summarise this" resolves without pasting a link, and notes the agent wrote about a site surface again when you return to it. Page content is never sent — reading a page is still an explicit browser tool call. Closing the panel retracts the record immediately, automation runs never see it, and the whole thing is a global setting. See ADR-0082.

Fixed

  • Browser approvals stick, and stop interrupting work you can watch. Choosing "Always allow" used to be erased within seconds by a background reconcile against the cookie allow-list, and a risk classifier re-prompted on every command for any host matching mail, docs, drive, account or admin regardless of that choice. Approval is now asked only for work you cannot see — a background or pinned tab — because on the tab you are watching the overlay narrates the command and Stop is one click away. Approving a site for page control also no longer enrols it in cookie passthrough, which is a separate and much stronger grant. See ADR-0083.
  • The model no longer changes mid-conversation on a short follow-up. Route classification reads only the current message, so a terse follow-up inside a research thread scored as simple chat and flipped to a different model — discarding the provider prompt cache for the whole stable prompt prefix. Classification now escalates immediately but de-escalates only for a message long enough to read as a new topic.
  • A model config with a non-positive context window no longer empties the transcript. It was treated as an explicit setting, flooring the hot budget at zero so the model answered with no history at all. An empty hot window is now also logged loudly instead of looking like lost memory.

[1.39.1] - 2026-09-05

Fixed

  • An automatic context boundary no longer wipes the turn that triggers it. The boundary used to pin hot_since to now and summarise afterwards, so that turn saw neither the earlier messages nor a recap of them and the agent answered as if the thread were new. The pin is now prepared and applied together with its recap; a failed summary leaves the thread on its full history, and a manual drag during the summarise wins. The triggering turn also drops the history_window_hours bound, and the chat shows that earlier messages are being summarised while it happens.
  • The Docker image builds again. packages/linkedin-personal-langchain and packages/linkedin-enterprise-langchain were never copied into the builder stage, so next build could not resolve them and the 1.38.0 and 1.39.0 container builds failed. A lint check now walks packages/* and fails on any workspace missing from that copy list.

[1.39.0] - 2026-09-04

Added

  • The browser extension is now a first-class runtime surface. The agent can inventory and focus tabs, fill forms in batches, reuse cached snapshots, and extract pages in reduced or chunked form, and it reports progress phases while a browser command runs. New UI: Tools → Browser status, history, and retry; a popup tab switcher with focus and pin controls; side-panel adoption of the current tab; and Settings → Privacy & security artifact lifecycle controls. Sensitive actions raise a conservative approval prompt, allowed sites are persisted and synced, and every command lands in a sanitized ledger (metadata only — no page extracts, screenshots, cookies, tokens, or form values). See ADR-0081 and the built-in browser navigation skill.
  • A thinking indicator fills the gap before the first token. Between run start and the first delta the agent's slot showed nothing at all; it now shows three bouncing dots that vanish as soon as real content arrives and hold still under prefers-reduced-motion.

Fixed

  • The "Sending…" label now clears when the server accepts the run. The optimistic user bubble kept the label for the whole turn because it was tied to pending and nothing cleared it until the persisted row came back. A sent state sits between pending and confirmed, so the label goes while the bubble stays unconfirmed and reconciliation still promotes it in place.
  • The extension rebranding step is now reachable from the npm package. browser-extension/ and scripts/build-extension.mjs were missing from files, so an overlay consuming @circuitwall/jarela as a dependency could not run the packaging step ADR-0077 defines — it had to vendor the extension and hand-brand it, which is the fork the ADR set out to avoid. scripts/check-npm-package.mjs now asserts both are packed.

[1.38.0] - 2026-09-04

Added

  • In-progress agent turns now accept steering input. Messages submitted while a turn is running are routed into that turn and a queued steering request is continued after the active model call completes.
  • Chat run states have a unified visual language. Message lifecycle surfaces share a consistent treatment, including a blinking caret while text streams.

Fixed

  • Tool retry guards now use declared capabilities. Retries correctly use the tool's explicitly declared capability rather than inferred behavior.

[1.37.0] - 2026-09-04

Added

  • Added separate LinkedIn Personal and LinkedIn Enterprise integrations with OAuth connection flows, encrypted credential persistence, configurable scopes, organization access checks, and text-post tools.
  • Added connection probes and integration UI controls for both LinkedIn integrations.
  • Added a repository integration-development skill with an official LinkedIn credential acquisition guide and implementation checklist.

Fixed

  • invoke_tool dispatches now resolve to the tool that actually ran. Chat tool cards show the target's name, arguments, and unwrapped result instead of a generic invoke_tool entry, and the stall/loop retry heuristics no longer treat a proxied write as an unnamed read-only call.
  • Tool calls streamed without a chunk index are no longer dropped. Calls are recovered from invalid_tool_calls and raw tool_call_chunks, so turns from aggregator providers reach the transcript with their arguments intact.

[1.36.1] - 2026-09-03

Fixed

  • Large tool results no longer bloat the active agent turn. Oversized tool outputs are now stored as content-addressed file refs with a bounded preview, and tool_result_get can read the full result back in byte ranges. The same cap applies to direct tool calls and async_run results.
  • Spilled files now have reference-aware cleanup. The scheduler sweeps old unreferenced files while preserving files still referenced by messages, generated file links, image refs and tool-result refs.
  • Large tool-result previews render cleanly in chat. Tool cards show the stored byte count, item count, ref metadata and bounded preview instead of dumping the raw result-ref envelope.

[1.36.0] - 2026-09-02

Added

  • Agents reach tools they are permitted to use but that are not loaded. Only basic-category tools, the self-config tools, and the agent's own pinned tools are bound to the model each turn; everything else the agent may run is reached through the invoke_tool proxy and marked permission_reason="proxy_only". Per-agent permissions, category toggles and drop-in toggles all still hard-block, so this widens reach without widening authority.
  • Tools declare the integration that backs them. registerLangChainPackage takes an integrationId (defaulting to auth.integrationId), drop-in tools declare integration, and MCP tools declare it in annotations. See ADR-0078.
  • list_tools accepts exact names. names=["exact_name"] returns just those tools and ignores every other filter, so a skill can point at a tool and get its description and argument schema in one call — including tools the agent cannot currently execute.
  • Prompt verification tooling. npm run prompts:dump assembles every prompt for review, -- --changed narrows to the ones a change touches, and lib/agents/prompt-registry.ts is an inventory a new prompt must join or the build fails. Procedure in .github/skills/prompt-verification.

Changed

  • Unconfigured tools are hidden from agents but stay visible to you. A tool whose declared credentials are unresolved, or whose integration fails its cached probe, is denied to the agent with credentials_missing or integration_unconfigured instead of being offered and failing at call time. It still appears in the Tools panel so it can be set up. Probe results are cached in memory for five minutes; an unknown or transient result never hides a tool.
  • The full tool index is no longer embedded in the system prompt. Discovery goes through list_tools search instead. The prompt now carries an ordered six-step tool usage SOP, and every permission_reason the permission layer can emit is explained.

Fixed

  • Gemini could not pass arguments through the proxy. invoke_tool typed its arguments as a free-form object, which sanitizeGeminiSchema reduces to an object with no properties, leaving the model able to send only {}. Arguments now travel in args_json, a plain string every provider preserves.
  • The proxy could be switched off. list_tools and invoke_tool live in the Config category; disabling it left them executable but unbound, severing access to every non-basic tool. Both are now exempt from category toggles.
  • Contradictory tool counts. Tools reachable through the proxy were counted both as reachable and as "not enabled for this agent" in the same sentence.

Performance

  • Repeated embeddings are reused. prepareThreadRun embeds on the critical path of every turn, and auto-boundary detection re-embedded a barely-changing baseline each time at 200–800 ms per round-trip. Embeddings are now cached by model and text — a mapping that cannot go stale — and only cache misses are sent to the provider.
  • Skill and drop-in scans share one keyed cache. listSkills() re-read every SKILL.md on every turn (1.85 ms of a 2.93 ms prompt assembly). Writes invalidate immediately, so write_skill is still visible on the next turn.

Security

  • Dependencies refreshed to their latest in-range releases and six overrides that upstream had made redundant were removed. npm audit reports no production vulnerabilities.

[1.35.0] - 2026-09-02

Added

  • Official rebranding overlay contract. Forks and white-label deployments can rename the app, swap the logo/favicon/PWA icon set, and recolor the accent through NEXT_PUBLIC_APP_* env vars, with no source edits to rebase on each upstream release. The browser extension gains a matching packaging step, npm run build:extension -- --brand brand.json. Rebranded builds keep a "Powered by Jarela" credit linking upstream. See ADR-0077 and docs/EXTENDING.md → Branding the app. Note the env vars are inlined at build time, so a web-app overlay must run its own build; the prebuilt npm artifact cannot be rebranded by configuration alone.

Changed

  • public/manifest.json is now generated at /manifest.webmanifest. The PWA manifest follows the brand config. The static file is removed; the <link rel="manifest"> target changed accordingly.

Fixed

  • PWA manifest was falling behind proxy auth. The proxy matcher still exempted the removed manifest.json path, so the new manifest route required authentication and could break install prompts behind tailscale serve.

[1.34.2] - 2026-09-02

Fixed

  • Action button loading feedback and toast notifications. Added spinning Loader2 indicators and toast feedback to run, poll, pause, and delete buttons across Scheduled Tasks, Watchers, Documents, Memory, MCP, Bridges, and Skill Repos. Fixed non-awaited runNow handler in Scheduled Tasks.
  • Automatic model fallback and database cleanup. Orphaned model_config_name references are automatically reset to NULL on startup and on model deletion, allowing agents to cleanly fall back to the default model without warning toasts.

[1.34.1] - 2026-09-02

Fixed

  • Default model fallback when assigned model is missing. streamWithConfig and thread execution now fall back to the workspace default model if an agent's explicit model_config_name was deleted or is missing.
  • Model list state synchronization on update. Updating or changing the default model in the Models panel now re-fetches the full model list to keep default flags synchronized across all rows in client state without requiring a page reload.

[1.34.0] - 2026-09-02

Added

  • Web search can use Google Custom Search. web_search now supports a google provider between Tavily and DuckDuckGo, reusing the configured Google API key plus a JARELA_GOOGLE_SEARCH_ENGINE_ID / GOOGLE_CSE_ID Programmable Search Engine id.

[1.33.0] - 2026-09-01

Added

  • iCloud Calendar event recurrence, alerts, travel time, and metadata. icloud_calendar_create_event and icloud_calendar_update_event now support rrule recurrence rules, primary/secondary alerts (e.g. ['15m', '1h']), Apple travel time (X-APPLE-TRAVEL-DURATION), URL, status, and availability. Event summaries return these fields for inspectability.

[1.32.0] - 2026-09-01

Added

  • Background activity status in chat. Scheduled tasks, watchers, and bridge traffic run on non-preemptive foreground/background queue lanes with source-aware expiry, so silent/no-change automation outcomes are now visible as compact activity rows in the chat instead of being silently dropped. Conversation history is scoped per source so background automation traffic no longer blurs into direct-chat dialogue.

Fixed

  • Silent-reply sentinel detected after preamble text. The check for the NO_REPLY silent-mode sentinel now matches anywhere in the trimmed assistant reply instead of only at the very start, so compliant "preamble + NO_REPLY" replies from scheduled tasks, watchers, and bridges are correctly suppressed instead of being persisted and surfaced to the user.

Security

  • browserslist pinned to 4.28.7. Addresses a high-severity unbounded memory-growth advisory (GHSA-c83g-rgw3-j3cx) in the transitive dependency pulled in via autoprefixer/@serwist/Babel tooling.

[1.31.2] - 2026-09-01

Fixed

  • Windows native release packaging accepts the WiX v7 CI EULA flag. The MSI packaging step now passes WiX's documented noninteractive EULA acceptance option so tag releases can build Windows installers in GitHub Actions.

[1.31.1] - 2026-09-01

Changed

  • invoke_tool guidance discourages recursive proxy calls. The tool description and system prompt now explicitly explain the list_tools full catalog lookup plus invoke_tool proxy workflow, cache a compact full tool index in the prompt so agents can discover tool names before calling list_tools, tell agents not to call invoke_tool through itself, and remind them to call already-loaded tools directly.

Fixed

  • Confluence page fetches use valid body-format requests. confluence_get_page now fetches storage and rendered view bodies with separate single-format Confluence v2 requests instead of a comma-separated parameter that Cloud rejects.

[1.31.0] - 2026-09-01

Added

  • Releases now include native OS packages. Tag builds publish unsigned Windows .msi, macOS .pkg, Linux .deb, and Linux .rpm artifacts beside the existing portable archives. Native packages install the pre-built Jarela payload with a bundled Node runtime and expose a jarela launcher.

Changed

  • Anthropic prompt caching is more stable across tool-heavy turns. Per-turn tool permission state now stays after the dynamic cache split so request-scored provider-cap changes do not invalidate the static system-prompt prefix.

[1.30.4] - 2026-08-31

Added

  • Agents can invoke capped tools through a safe proxy. New invoke_tool executes permitted built-in, external, and MCP tools by name after list_tools discovery, without bypassing agent permissions or disabled tool state. list_tools can now include target input schemas for proxy planning.

[1.30.3] - 2026-08-31

Changed

  • Agents get clearer capped-tool recovery guidance. The stable tool prompt now keeps a compact cached catalog of Basic tools, tells agents to search list_tools by service/object/action keywords when a needed capability is missing or ambiguous, and distinguishes cached tool names from executable tools in the current turn.
  • Shell tools are combined for new agents. A new unified terminal tool handles one-shot shell commands plus persistent terminal open/exec/send/read/close/list actions. The legacy shell_exec alias was removed; use terminal with action='run' or local_exec for one-shot commands.
  • MCP permissions are grouped by server. MCP tools now carry their source server through the tool catalog and render in the agent editor as MCP -> server -> tools.

[1.30.2] - 2026-08-31

Fixed

  • Large MCP toolsets no longer disappear behind the provider tool cap. The provider tool payload limit is now configurable via the advanced JARELA_PROVIDER_TOOL_LIMIT setting, defaults to 512 tools, is clamped by provider hard limits such as OpenAI-compatible APIs' 128-tool maximum, and uses the current request to pick likely tool candidates instead of blindly sending the first tools in the list. The prompt only hints enabled tools, while list_tools can search either enabled tools or the full inventory with enabled/disabled flags so agents can suggest moving tools in/out when needed.
  • Git probe tests are safe under Git hooks. Git helper subprocesses now ignore inherited repository environment variables so hook-invoked tests operate on their requested working directory instead of the parent index.

[1.30.0] - 2026-08-31

Added

  • Change impact audits flag likely ripple effects. A new check:impact script compares staged changes or a git range and reports follow-up surfaces such as scheduler behavior, agent instructions, skills, persistence, API contracts, security-sensitive code, and release metadata.
  • Agent workflows can report structured checklist progress. A new Basic workflow_progress tool lets agents update reusable plan/action workflows, while chat tool cards can expand into live checklists with per-item status.
  • Version adoption status appears during agent startup. Jarela now tracks first-run and post-upgrade adoption state, identifies the default agent before showing adoption work, and renders a compact checklist in the existing recent agents slot without moving the logo or changing the breathing headline.

Changed

  • Version adoption uses a structured two-phase workflow. Adoption now starts with Fetch changes and Build todo list, automatically enters Phase 2 after the todo list is built, keeps progress on the agent picker, and shows a final summary with a follow-up hint when action is still needed.

[1.29.5] - 2026-08-30

Added

  • Agent workflow SOP skills are built in. New project skills document the standard workflow for tool telemetry complaints, code changes, information safety, issue replies, PR intent checks, branch cleanup, and focused commit amendments.

Changed

  • Adaptive persona guidance is more operational. Persona settings now emit explicit behavior profiles and operating-contract instructions so configured agents can shape organization and phrasing more consistently.
  • Tool telemetry complaints are less noisy. Automatic telemetry issue filing now gates on repeated failure patterns instead of surfacing one-off failures as systemic tool complaints.
  • Shell and file tool descriptions steer agents toward efficient built-ins. The tool catalog now nudges agents to use structured file/search/edit tools before shell commands, and clarifies when to choose one-shot shell execution versus persistent terminal sessions.
  • Workspace setup now points agents at repo instructions and skills. workspace_init discovers Copilot instruction files and repo skill files, adds instruction files to required reading, and returns recommended next steps that steer agents toward the right project guidance and tool workflow.

Fixed

  • iCloud Calendar updates no longer fail on LAST-MODIFIED timestamps. Event updates now patch LAST-MODIFIED as an iCalendar DATE-TIME value instead of a plain string.
  • Automatic retry no longer repeats state-changing tool calls. Stall and hallucination recovery now skips automatic retries after write-like tools have already run, avoiding duplicate external side effects such as repeated issue creation.

[1.29.4] - 2026-08-30

Added

  • Agents can see their full tool permission map. The agent runtime now builds a complete catalog of known tools, marks which ones are enabled, disabled, or unavailable for the current agent, and includes the durable permission map in the cacheable system-prompt prefix while still hard-limiting executable tool handles to permitted tools only.
  • Tool telemetry can file Jarela complaint issues. A new report_tool_telemetry_issue system tool summarizes success rates, usefulness scores, failure counts, and sanitized failure scenarios across one or more tools, then drafts or files an issue against CircuitWall/jarela. The scheduler can auto-file when GitHub auth is configured and skips duplicate telemetry fingerprints.

Changed

  • Basic tool permissions are enabled automatically. Memory, Documents, Files, Shell, Schedule, Config, Skills, and Web tools now sit under a Basic permission group and are dynamically available to all agents as new Basic tools are added.
  • Release CI now has a security gate. Tag-driven releases run dependency audits, npm signature checks, and the OAuth proxy audit before publishing artifacts.

Fixed

  • Semantic versioning guidance now treats existing-feature completion as a patch. The contribution docs reserve feat: / MINOR bumps for genuinely new capabilities and classify adding, fixing, or completing existing feature behavior as PATCH unless it is breaking.

[1.29.3] - 2026-08-29

Fixed

  • Gemini tool calls keep thought signatures. Native Gemini responses now preserve both thoughtSignature and thought_signature fields so follow-up tool turns replay the required signature instead of failing with Function call is missing a thought_signature.

[1.29.2] - 2026-08-29

Security

  • Corporate identifiers are scrubbed from the public branch. Current main no longer carries the targeted internal fixture/provider references, and CI now runs a dependency-free brand-term guard to catch future accidental leaks.

Fixed

  • Model config comments use neutral auth wording. The inline model params merge path now documents custom-provider auth generically instead of naming an internal provider pattern.

Changed

  • Dependency baseline refreshed. Next.js, React, LangChain packages, provider SDKs, workspace tooling, and related runtime/test dependencies have been updated within the current non-major compatibility band.

Documentation

  • Architecture audit notes added. The architecture docs now describe the attachment file-store boundary and record whole-repo audit findings for state ownership, route validation, extension capabilities, and secret surfaces.

[1.29.1] - 2026-08-28

Fixed

  • Large chat attachments no longer break run submission. Images and binary files now upload to the local file store first and enter chat runs as lightweight refs, avoiding oversized /threads/:id/run JSON bodies. HEIC and HEIF images are detected by filename when browsers omit their MIME type.
  • Fast scroll-to-latest controls remain reachable. The chat safe-area bottom token is now defined and chat toasts no longer cover bottom controls.
  • Automatic context boundaries respect each agent's history window. Idle topic-shift detection now uses the agent's configured history_window_hours instead of a hardcoded threshold.

[1.29.0] - 2026-08-28

Added

  • Mail tools can send explicit Gmail and Outlook messages. Adds gmail_send_email and outlook_send_email for user-requested immediate sends, keeps drafts as the default safer path, and lets Gmail drafts/sends emit HTML bodies via content_type: "html".
  • Skills get a Tools panel tab. A new "Skills" sub-tab (Tools → Skills) manages skill repos (add/enable/disable/pick-writable/remove) and lets you write, edit, and delete skills directly in the UI — no API calls required. Built-in skills show a "Clone" affordance that copies their content into your writable repo so you can customize them (same id overrides the built-in; a different id keeps both).

Changed

  • The Skills tool category can no longer be disabled. Every agent can already list/read/write skills regardless of its own tool selection (SELF_CONFIG_TOOLS); the Packages tab's per-category toggle for Skills is now locked to "always on" to match, instead of offering a switch that only partially worked.

Fixed

  • Idle + topic-shift context boundaries now behave like manual moves. The automatic boundary path now uses the same backend boundary transition as /new and manual focus moves, kicks a warm-summary refresh, and surfaces the pending boundary in chat while the summary catches up.
  • Fast scroll-to-latest button appears reliably again. The chat list now recomputes the button after content/layout changes and programmatic jumps, not only after a physical scroll event.
  • DELETE /api/v1/skills/[id] now returns { deleted: true } instead of a bare 204 No Content, matching every other delete endpoint — needed for the new UI's client to parse the response.
  • Skills panel no longer shows stale data right after a save. GET /api/v1/skills and GET /api/v1/skills/repos carry a short browser cache TTL meant for polling-style panels; the client now fetches them with cache: "no-store" so a save/delete followed immediately by a reload reflects the change instead of a cached pre-mutation response.

[1.28.2] - 2026-08-21

Changed

  • Skill repos are now DB-backed, like MCP servers and document sources. The old single-path JARELA_SKILLS_DIR env var is gone; skill repos are rows in a new skill_repos table managed via GET/POST /api/v1/skills/repos and .../repos/[id], each with a label, enabled toggle, and writable flag. Multiple repos can be configured — later-added repos override earlier ones (and built-ins) on skill id collision — and no restart is needed to add or remove one. See ADR-0074.

[1.28.1] - 2026-08-20

Fixed

  • Image previews now truly use the full viewport. Markdown images and attachments share the same edge-to-edge preview dialog, and the previewed image is no longer constrained by the original message bubble width.
  • Hot/warm focus masks now visibly fade out at the top. The mask now fades the entire overlay, including the backdrop filter, so the upper edge becomes fully transparent instead of staying subtly desaturated.
  • Image history no longer routes to text-only models. Turns with image attachments already present in hot history now prefer vision-capable models, and text-only fallbacks omit image blocks instead of sending unsupported image_url payloads to providers that reject them.

[1.28.0] - 2026-08-20

Added

  • Agents can learn from repeated workflows. Agents now detect repeated similar work from recall, ask before creating reusable skills, and can write scoped skills when the user agrees.
  • Long-lived agent sessions compact automatically. Oversized agent threads now compact through the same safe path as /compact, preserving warm summaries and pruning old rows before one-session-per-agent histories grow without bound.

Fixed

  • Tool reliability guidance now steers agents away from repeat failures. Tool stats now produce compact, aggregate-only reliability hints scoped to the tools available for the current run, including bounded failure categories for auth, validation, not-found, timeout, rate-limit, and size/context issues.
  • Tool failure telemetry stays bounded. Failure diagnostics are aggregated by tool and normalized reason, scrubbed/truncated, TTL-pruned, and never store raw tool arguments or per-call logs.
  • Tool catalog diagnostics are quieter by default. Raw call/success/error stats and failure categories are hidden inside collapsed advanced details, while problematic tools still show a compact health badge.
  • Document, calendar, mail, browser, Microsoft Graph, proposal, and file tools fail earlier with clearer recovery hints. High-failure tools now validate common bad inputs locally, cap oversized draft bodies and search patterns, add machine-readable truncation reasons, and guide agents toward source refreshes, snapshot refreshes, credential setup, or smaller work batches.
  • Context windows stay within model limits more reliably. Over-large saved context-window overrides are capped to known provider/model limits, and oversized hot messages are clipped even when warm-summary generation succeeds.
  • Agent credential overrides no longer dominate the editor. Per-tool credential overrides are tucked into collapsed advanced sections instead of rendering a long list by default.

[1.27.5] - 2026-08-20

Fixed

  • Image previews now use the full viewport. Clicking an image in chat opens an edge-to-edge preview dialog that uses the full viewport surface instead of a constrained modal width, while preserving explicit close controls and accessibility behavior.
  • Focus-boundary history mask now fades smoothly upward. The gray mask above the hot/warm line now transitions gradually and reaches full transparency toward the top for a cleaner visual boundary.
  • Pre-commit/unit test runs are more stable on loaded Windows environments. Vitest test and hook timeouts are raised from the default 5s to 15s to avoid spurious timeout failures during full-suite runs.

[1.27.4] - 2026-08-17

Fixed

  • Auto-routing no longer picks embedding/reranking/moderation models for a chat turn. The model router used a model's detected type only as a soft ranking hint, so a ModelConfig saved for embeddings/RAG could occasionally win a turn's routing decision and get called with a normal completion request, which the provider rejects. Non-generative model types are now excluded from the routing candidate pool entirely, including the fallback path used when no candidate matches the turn's vision/tool/file requirements.
  • update_agent_tools proposals can now add tools without wiping the rest. The apply step always replaced an agent's whole tool list, so proposing to add a single tool silently dropped every other tool the agent already had. It now takes an explicit mode: "add" | "replace" (defaulting to "add", which merges with the agent's existing tools).

[1.27.3] - 2026-08-16

Fixed

  • Conversation focus boundaries now reflect real summary state. Automatic internal hot/warm context splits no longer render an empty focus line in chat; the divider appears only for user-pinned or summarized context.
  • Moved focus boundaries show background refresh progress. After a user drags and confirms the focus line, Jarela renders it at the chosen location immediately and gives it a slow pulse until the warm summary refresh finishes.
  • Local file links in chat no longer become localhost links. Markdown links to local files now preview renderable text files inline and open other files with the operating system default app.

Changed

  • Source checkout service targets match the packaged CLI. make and make.ps1 now expose install-service, uninstall-service, start-service, stop-service, and restart-service, while preserving the old *-task aliases.

[1.27.2] - 2026-08-15

Fixed

  • Document search now falls back to substring matching. When semantic vector search finds no close matches, the document search now tries substring matching as a fallback, improving discoverability on sparse or short document sets.
  • Embedding dimension mismatches are auto-repaired. When embeddings from an old model are detected (dimension mismatch), the search immediately falls back to substring matching and queues the chunks for re-embedding on the next scheduler tick. This repairs the semantic index instead of permanently degrading it.
  • Chat turn metadata displays inline in message context. Turn timestamps, token counts, and provider info now appear alongside the message text instead of in a separate panel.
  • Agents can now expose environment configuration tools. The Jarela operating skills now include tools to list and describe environment variables and configuration options available to the agent.

Changed

  • Shared agent list hook reduces component duplication. AppShell and MenuPanel now reuse the useAgents hook instead of duplicating subscription and loading logic.

[1.27.1] - 2026-08-15

Fixed

  • Conversation focus boundary now only appears after the user pins it. Unpinned threads no longer show a misleading recent 0 · warm N divider.
  • Chat image attachments use the available viewport. Sent pictures expand to the available chat width while preserving the original pixel bounds and click-to-lightbox behavior.

[1.27.0] - 2026-08-15

Added

  • Built-in Jarela operating skills. Packaged skills now cover operating, configuring, and integrating Jarela, while user skills from JARELA_SKILLS_DIR can override or extend them.
  • Searchable tool catalog. /api/v1/tools?q=... and the list_tools agent tool can search by name, description, category, capability, source, and group.

Changed

  • Default harness instructions are leaner. Procedural setup guidance moved into built-in skills, leaving the always-on harness focused on safety, follow-through, and core capability facts.

[1.26.0] - 2026-08-14

Added

  • Live delegate tool progress in chat. claude_delegate can now stream progress updates into the tool timeline while a call is still running, and wallclock budgets reset on reported activity instead of total elapsed time.

Fixed

  • Credential groups are separated correctly. The Credentials panel and add dialog now group model provider credentials separately from tool credentials, matching how users choose and manage them.

[1.25.1] - 2026-08-14

Fixed

  • claude_delegate and every other spawned subprocess now see the user's full shell environment, not just the Anthropic-related allowlist. The claude CLI it delegates to often shells out to other CLI tools (gh, aws, jira, …) that read credentials straight from the environment; those only ever lived in the user's shell rc, never in Jarela's own process env when running as a background service. exec, terminal, and MCP stdio children pick this up too. See ADR-0072.

[1.25.0] - 2026-08-14

Added

  • Direct self-instruction update tools. Added read_agent_instruction and update_agent_instruction to the Config toolbelt so an agent can read and update its own persisted instruction text without waiting on a proposal approval flow.

Changed

  • Instruction editing is now deterministic. update_agent proposal payloads now accept instructions_edits for literal replace/remove and line/paragraph dedupe operations, reducing prompt-drift when tuning existing instructions.
  • Self-config guidance now prefers direct self-update. Harness guidance and propose tool docs now steer instruction-only self updates to update_agent_instruction, while proposal approvals remain for broader or cross-agent configuration changes.

  • Unified hook contracts expanded across core UI surfaces. useSSE, useUrlSync, useLocationSharing, and useEventNotifications now expose a canonical state + commands contract while preserving compatibility flat fields during migration.

  • Hook test naming and packaging standardized for DX. Hook contract tests now live under hooks/ with normalized use{Name}.test.ts filenames, with matching Vitest discovery updates.

  • Hook workflow docs and scripts added. Added docs/DEVELOPMENT.md, expanded docs/ui-hook-api.md with naming/packaging conventions, and added fast local commands (npm run test:hooks, npm run lint:hooks).

[1.24.3] - 2026-08-12

Fixed

  • Retry nudges now carry completed work forward. Stall and hallucination retries now include the assistant text so far, tools already used, and compact summaries of tool results. That gives the next pass enough context to continue the same task instead of redoing completed steps.

[1.24.2] - 2026-08-12

Fixed

  • Unread badge consumption and bucketing corrected. Notifications that arrive while the user is already on an agent chat now clear that chat's unread bucket immediately, preventing stale menu and per-agent badges.

  • System and malformed-agent notification buckets no longer stick. Notifications with missing/empty agent_id are normalized into the null bucket, and opening the menu now consumes that bucket so global alert badges do not remain latched.

[1.24.1] - 2026-08-10

Fixed

  • Boundary summary tap-open regression. Tapping the conversation-focus separator could open the floating summary on pointerup and then immediately close it again on the follow-up click, making the summary hard to open. The no-move release path now suppresses the synthetic click, and the drag-preview stats badge now matches the committed separator by rendering inline on the line.

  • Agent save 500 on older local databases. Saving an agent could crash with table agent_configs has no column named router_policy when the local DB had skipped the late router-column migration. The migration flow now always runs the router column ensure, and the agent payload mapper now preserves router_policy / router_enabled on create and update.

[1.24.0] - 2026-08-10

Added

  • Floating summary panel from boundary line. The inline warm-summary card is replaced with a click-to-open floating panel anchored below the context boundary line. The panel includes compact live status states (updating, ready, needs refresh, pending) and an animated indicator while the summary is refreshing.

  • Live boundary line stats while dragging. The context boundary now shows recent · warm counts on the separator and updates the same stats in real time on the drag guide.

Changed

  • Boundary visual polish and drag feedback. The separator removes center vertical handle marks, the gray history mask is anchored exactly at the boundary line and persists above it, and drag interaction now distinguishes click (open summary) from drag (move focus) to avoid accidental repins.

Test

  • Updated unit coverage for boundary interactions (confirm/cancel drag plus click-to-open floating summary), and refreshed boundary drag e2e assertions.

[1.23.0] - 2026-08-06

Added

  • Per-agent model router configuration — each agent can now independently override the global router behaviour: set Routing to "always route" (enables the heuristic router even when the global JARELA_MODEL_ROUTER_MODE is "off") or "never route" (bypasses it regardless of the global setting), and set Policy to cheap | fast | balanced | quality to override the global JARELA_MODEL_ROUTER_POLICY. Both choices are stored in the agent_configs table (router_enabled, router_policy columns) so they survive restarts and are preserved across exports. The Advanced Settings panel exposes the two dropdowns when no forced model is selected.

  • Drop-in tool metadata — external .cjs tools can now declare category, group, and credentials_required in their module exports; MCP tools surface the same fields via their tool annotations. These flow automatically to the agent config panel: unknown categories sort alphabetically between known ones and "MCP" (no code change required), and a 🔑 key-icon tooltip appears on any tool that declares required credentials. The jarela:tools-changed event is now dispatched from MCP server CRUD operations so the tool list refreshes in the agent editor without a page reload.

Changed

  • HTTP cache — list endpoints (/agents, /models, /tools, /tasks, /providers, /harnesses) gain stale-while-revalidate so back/forward navigation is instant while the browser refreshes data in the background. The /extensions endpoint switches from max-age=300 to no-store — credential state must never be served stale after a save.

  • Client-side tool list cache — api.tools.list() now uses a 30 s client-side cache (same pattern as agents/models). All tool-list mutations (mcp.create/update/delete, builtinTools.setEnabled, packages.reload, extensions.setDropinEnabled) route through a single invalidateToolListCache() helper that busts the cache and dispatches jarela:tools-changed.

Fixed

  • 8 security/correctness bugs fixed: JSON.parse crash on malformed SSE events, AbortController leak on component unmount, SHELL injection in subprocess PATH probe (now uses spawnSync with args array), symlink workspace escape via realpathSync fallback, TextDecoder trailing-byte loss in streaming and fetch tools, SQLite list() WHERE/args bind-count mismatch, and unbounded tokenCache growth in the GitHub Copilot provider.

[1.22.9] - 2026-08-06

Added

  • OpenAI zodResponseFormat re-exported from lib/providers/openai.ts so agent code can pass a Zod v4 schema as params.response_format without importing from openai/helpers/zod directly.
  • gpt-5.5 and gpt-5.6 context-window entries in lib/providers/known-context-windows.ts (1,050,000 context / 128,000 max output tokens each, sourced from OpenAI docs 2026-08).

Changed

  • @anthropic-ai/sdk bumped to ^0.115.0, enabling new Claude models (claude-opus-4-8, claude-mythos-5, claude-fable-5) and the middleware API without any code changes to the provider adapter.
  • Sub-package TypeScript configs add "ignoreDeprecations": "6.0" to silence the TS5101 baseUrl deprecation introduced by TypeScript 5.9.

[1.22.6] - 2026-08-05

Changed

  • Advanced settings panel collapsed by default in the agent editor; step index removed from the section header.
  • Settings nav renamed to "Advanced settings" (short label "Advanced") in the menu panel.
  • Temperature, context size, and model overrides moved into a collapsible "Advanced settings" section inside the model editor (collapsed by default).

Improved

  • All list panels (Agents, Models, Harnesses, MCP, Memory, Credentials, Scheduled Tasks, Setup wizard) replace per-row edit buttons with click-to-edit rows; only Delete (and where applicable, secondary action) buttons remain visible on hover/focus.

[1.22.5] - 2026-08-05

Fixed

  • Anthropic cache TTL ordering corrected. The last tool in a request was marked with the default 5-minute ephemeral breakpoint while the stable system-prompt prefix used a 1-hour TTL. Anthropic enforces non-increasing TTLs in the order tools → system → messages, so any request combining tools with a sentinel-split system prompt was rejected with "block must not come after a ttl='5m' cache_control block". The last-tool marker now uses the same 1-hour TTL, restoring a valid sequence (1h → 1h → 5m).

[1.22.4] - 2026-08-05

Fixed

  • Cross-turn conversation history caching corrected. withLastAssistantMessageCacheControl was marking only 1 assistant message per turn — net negative, because the Anthropic prefix cache only hits when the same breakpoint position appears in both the write turn and the read turn. With one marker, each turn wrote a new prefix that the next turn never read (paying 1.25–2× write cost, 0 reads). The function now marks up to 2 assistant messages per turn so the older breakpoint reappears in the next request and yields a cache read hit from turn 2 onwards. Capped at 1 during multi-step ReAct turns (tool_results present) to stay within Anthropic's 4-breakpoint-per-request budget.
  • Redundant body.temperature assignment removed from streamInvoke and buildAnthropicMessageBody; pickAnthropicOptions already handles it for both legacy and modern models.
  • CACHE_SPLIT_SENTINEL import direction corrected. The canonical definition moved from agents/prepare/system-prompt.ts to providers/anthropic.ts (where it is consumed); system-prompt.ts now imports it from there, resolving the inverted providers → agents dependency.
  • Bump to 1.22.4.

[1.22.3] - 2026-08-05

Fixed

  • Unit test assertion updated to reflect that cost_usd is now intentionally exposed in messageUsageToResponse (the previous assertion asserted it was absent, which broke coverage CI after #369).

[1.22.2] - 2026-08-05

Fixed

  • Prompt-cache hit rate dramatically improved. The system prompt was assembled as a single cache_control block whose content changed on every turn because buildTimeContext() (which embeds new Date().toISOString()) was placed mid-sequence among otherwise-static harness sections. The stable prefix (agent identity, instructions, harness bodies, integration/doc context) is now separated from the per-turn dynamic suffix (timestamp, recall hits, warm summaries, output budget) via a sentinel that withSystemCacheControl uses to emit two content blocks — only the stable block carries cache_control. The cache prefix is now consistent across consecutive turns, enabling the API's ephemeral cache to actually engage.
  • Auto-upgrade deprecated thinking parameter for modern Claude models. {type: "enabled", budget_tokens: N} was removed in Claude Opus 4.7 (400 on any request). Calls that carry the old shape targeting Opus 4.7 / Sonnet 5 / Haiku 4.5 or newer are now silently upgraded to {type: "adaptive"}.
  • Strip removed sampling params for Claude 4.7+ models. temperature, top_p, and top_k are rejected with a 400 on Opus 4.7 and later. pickAnthropicOptions now detects the model family and omits those keys when they would cause an error.
  • output_config.effort support. The effort key in a model config's params is now forwarded as output_config: { effort } in the Anthropic request body, enabling per-model reasoning-depth control without a separate code path.
  • Cache-sticky model routing. The model router's affinity bonus for a model that had a cache hit on the previous turn was raised from +10 to +30 (cache write: +15, no-cache continuity: +8). A prompt-cache switch always forces a cold re-write at 1.25× cost; the higher scores prevent gratuitous model switches when cost differences between tiers are minor.
  • Dynamic max_tokens from context budget. run-thread now forwards budget.outputReserveTokens through AgentRunConfig and llm.ts applies it as max_tokens when the model config does not set an explicit limit. Prevents silent output truncation on long complex turns (default 4096 is often too low) and avoids over-provisioning on short turns.
  • Warm-summary max_tokens capped at 1,024. Summarization calls (which produce 200-500 token outputs) no longer default to 4,096 output tokens, reducing per-summary token cost by ~75%.
  • Cross-turn conversation history cached via mid-conversation system messages. For Claude Opus 4.8 / Opus 5 / Fable 5 / Mythos 5, dynamic per-turn context (timestamp, recall, warm summary) is now injected as a {role:"system"} entry directly before the current user message rather than embedded in the top-level system block. This keeps the prefix from body.system through the entire prior conversation history byte-stable across turns so the 1-hour cache breakpoint on each assistant message can actually be read. Combined with withLastAssistantMessageCacheControl, the full conversation history is served at 0.1× on each subsequent turn; only the new user message is billed at full rate. Falls back to the legacy single-block system for unsupported models.

[1.22.1] - 2026-08-05

Fixed

  • Developer agent prefers interactive terminal tools. The stock Developer profile now nudges agents toward terminal_open + terminal_exec + terminal_read for shell work, while keeping shell_exec / local_exec as one-shot fallbacks. Existing installs backfill to the same tool set when they still match the legacy seed.
  • Subprocess PATH probing now honors the interactive shell. On macOS and Linux, shared subprocess env resolution probes the user's interactive shell so .zshrc / .bashrc PATH changes are reflected for exec and terminal tools.
  • Added regression coverage for the developer-seed backfill and the interactive-shell PATH probe.

[1.22.0] - 2026-08-05

Added

  • Interactive terminal sessions. Agents can now open persistent shell sessions (terminal_open) that retain state — working directory, shell variables, activated virtual environments — across multiple turns. terminal_exec runs commands in the session; terminal_send writes raw stdin for interactive programs (REPLs, prompts); terminal_read polls buffered output; terminal_close / terminal_list manage the lifecycle. Sessions are auto-evicted after JARELA_TERMINAL_IDLE_TTL_MS (default 10 min) and capped at JARELA_TERMINAL_MAX_SESSIONS (default 5).
  • local_exec / shell_exec now use the terminal infrastructure. Each call creates a throwaway session — same JSON output shape, no behaviour change for existing agents.
  • External skills directory. Set JARELA_SKILLS_DIR to a folder containing Claude-style */SKILL.md files or flat *.md files. Skills are loaded at startup, injected into the agent system prompt, and manageable via read_skill / write_skill / list_skills tools and the new REST API (GET/POST /api/v1/skills, GET/PUT/DELETE /api/v1/skills/:id).
  • Shared subprocess env resolver. Login-shell PATH probe and credential injection extracted to lib/tools/subprocess-env.ts and shared by exec and terminal tools.

Fixed

  • PowerShell 7 (pwsh) not recognised in terminal sentinel. The shell-detection logic now matches pwsh and pwsh.exe alongside powershell.exe.
  • PowerShell 5.1 piped output garbled with non-ASCII. Sessions now send a UTF-8 init line immediately after spawn.
  • Terminal sessions exposed PowerShell banner in stdout. PowerShell is now spawned with -NoLogo -NonInteractive.
  • Working directory not tracked across cd commands. The sentinel now embeds the current directory after every exec so cwd in tool responses reflects actual state.

[1.21.1] - 2026-08-03

Fixed

  • CVE patches in transitive prod deps. Updated undici (8.10.0), fast-uri (3.1.5), ip-address (10.4.0), @hono/node-server (2.0.12), and @modelcontextprotocol/sdk (1.30.0) to resolve high-severity advisories GHSA-8xcm-r25x-g524, GHSA-4cwx-7wf7-3272, GHSA-m8rv-5g2x-5cg5, GHSA-jr45-8vmc-qm54, GHSA-v3r7-h72x-cjcm, GHSA-7p8r-x3mc-p8w7, GHSA-mwp4-54f8-5fhr, GHSA-4xrf-jv44-h6hh, GHSA-22jq-vg5j-6vgg, and GHSA-frvp-7c67-39w9. Lockfile-only change; no API surface altered.

[1.21.0] - 2026-08-03

Added

  • Heuristic per-turn model routing. Jarela can now choose the execution model per turn from the saved model pool using task shape, tool requirements, attachment capabilities, pricing hints, cache affinity, and recent routing outcomes. The router remains deterministic by default and only changes model choice; agent identity, tools, and persistence stay unchanged.
  • Router controls in the Models panel. Settings for router mode and routing policy now live directly in the Models panel, so operators can turn automatic routing on or off and switch between cheap, fast, balanced, and quality behavior without editing env files manually.
  • Routing audit trail in chat. Assistant messages now persist and display model-selection metadata including source, route class, policy, latency, retries, and final outcome, making routing behavior visible in the chat UI instead of hiding it inside logs.

Changed

  • Agent setup is router-first by default. The main agent editor no longer treats per-agent model selection as the normal setup path. Automatic routing is now the default mental model, while explicit model pinning moved into Advanced settings as an override.

Fixed

  • Retry paths no longer duplicate the user's prompt in model context. Automatic transient retries and corrective stall retries now inject only explicit retry nudges into in-memory history when needed, rather than re-appending the already-persisted user prompt. This keeps retry turns semantically stable and prevents token bloat from accidental duplication.
  • Transient failures now retry with exponential backoff and policy escalation. Pre-output transient errors can be retried automatically with bounded exponential delay, and cheap/fast routing policies may escalate toward stronger models on retry without mutating the original persisted user turn.

[1.20.2] - 2026-08-03

Added

  • Running version on the boot picker. The full-screen agent picker now shows the running vX.Y.Z at the bottom, sourced from /api/v1/update so the number stays consistent with the "Update available" banner. Renders nothing until the fetch resolves, so it never causes a layout shift.

[1.20.1] - 2026-08-02

Fixed

  • Friendly message when a provider returns HTTP 429. The Anthropic / OpenAI SDKs throw an APIError whose message is a bare "429 status code (no body)". That string was passed through to the SSE error event and rendered in the chat toast, telling the user nothing about what to do. The chat runtime now recognises rate-limit errors (isRateLimitError in lib/agents/llm.ts) and emits a rate_limited code with a message that names the provider, explains the credential's quota is exhausted, quotes the retry-after hint from the SDK response headers when present, and points at Settings → Models for switching models or credentials.

[1.20.0] - 2026-08-01

Added

  • Image attachments as disk refs. Image content parts are now spilled to %LOCALAPPDATA%\Jarela\attachments\ (or ~/.jarela/attachments/) and referenced by image_ref markers in the persisted messages.content blob, replacing the base64 string previously stored inline. Reloading a thread with many screenshots no longer streams megabytes of encoded pixels per row, and the persistence path is one write per attachment instead of an O(N) balloon on every subsequent turn. See ADR-0065.
  • Image attachments shrunk at ingest. Uploaded / captured images are decoded via sharp, downscaled to 1600px on the longest edge, and re-encoded at JPEG q=85 (or PNG q=90 for images with an alpha channel) BEFORE hitting the disk-ref layer. Common phone screenshots drop from 4-8MB to 200-400KB with no visible quality loss, so the LLM's vision path pays for pixels it can actually resolve and the context window budget goes further. See ADR-0066.
  • Context window discovery + self-correcting overflow. On model save, Jarela probes the provider once for the effective context window and stores it on the model row; subsequent runs use it to size the history window instead of hardcoded defaults. When a run overflows anyway (provider bumped the limit down mid-window, or discovery was stale), the agent halves the fallback window and retries once — turning what used to be a hard 400 into a graceful degradation. See ADR-0067.
  • Provider auth-failure surface. Auth errors from Anthropic, OpenAI, Gemini, and Cohere are now classified at the provider layer and turned into a top-of-thread banner that deep-links straight to the failing credential in Settings, instead of surfacing as a raw stream error toast the user can't act on. See ADR-0068.
  • Persistent run_error marker rows. When a run crashes or is interrupted, a compact assistant-role row with category="run_error" is written to the thread so the failure survives a reload and the message list shows a discrete chip (with error code + credential deep-link) instead of a floating error toast that disappears on refresh. The row is filtered out of the LLM context so subsequent turns don't see phantom system output. See ADR-0069.
  • Refuse-to-save on credential auth failure. POST/PUT /api/v1/credentials now probe the provider immediately after save and roll the row back with a 400 if the vendor already returns auth_failed. Prevents a whole class of "I saved my key, why does chat still fail" reports. ?force=1 bypasses the probe when the operator is intentionally saving a credential they know the vendor can't yet validate (offline env, staging endpoint, etc.). See ADR-0070.

Fixed

  • Gemini thoughtSignature threaded through tool-call replay. Gemini 2.5+ models emit an opaque thoughtSignature on parts they produce once thinking is enabled, and every follow-up request must replay that signature on the corresponding functionCall part(s) or the API 400s with "Function call is missing a thought_signature in functionCall parts". The provider layer now captures the signature per part in both the streaming and non-streaming decoders, parks it on AIMessage.additional_kwargs.provider_tool_call_meta keyed by tool call id (LangChain merges these across chunks via recursive _mergeDicts), and reattaches it as a sibling thoughtSignature field when replaying the functionCall part on the next request. Also fixes a latent bug where tool_call_chunk was emitting index: 0 for every call in a multi-call turn — now uses a per-call counter and synthesises stable ids (gemini_fc_${index}) when Gemini omits them. See docs/adr/0065-gemini-thought-signature-passthrough.md (#358).
  • Steer / interrupt no longer reorders message bubbles. When the user stopped an in-flight reply and immediately sent another message, the client-side queue drained optimistically as soon as sse.streaming flipped false — BEFORE the server had persisted the interrupted assistant reply — so the follow-up user bubble landed above the interrupted reply in local state. appendUnique now sorts by created_at after reconciliation so the display order matches the server's chronological storage (#359).

Added

  • Agent list sorted by latest interaction. listAgentConfigs() now orders agents by MAX(threads.updated_at) DESC, falling back to the agent's own created_at for agents that have no thread yet. The agent you last talked to (either side) bubbles to the top, replacing the previous is_default DESC, created_at ASC ordering that pinned old / default agents even when the user hadn't touched them in months.

Security

  • Patched high-severity CVEs in prod deps. npm audit fix within semver ranges (body-parser, fast-uri, protobufjs, postcss, and other transitives) plus a top-level sharp: ^0.35.3 override so both baileys and next resolve past the libvips CVEs (GHSA-f88m-g3jw-g9cj: CVE-2026-33327, -33328, -35590, -35591). Brings npm audit --omit=dev from 10 vulnerabilities (1 low, 5 moderate, 4 high) down to 3 moderate, unblocking the security:ci gate. The remaining moderates are in @hono/node-server via @modelcontextprotocol/sdk and only fix via a breaking @langchain/mcp-adapters downgrade, so they stay queued behind an upstream release.

Fixed

  • Error notifications collapse and auto-clear. Toasts gained an optional dedupeKey; repeat pushes with the same key update the existing card in place instead of stacking another one to click away. pushErrorToast now defaults to error:${title} and a 30s auto-dismiss window (was sticky), so a persistent error keeps refreshing itself while a one-off error clears itself once it stops re-firing. health_alert events use health:${category}:${label} so a recovered event replaces the failing card (turning it green and auto-dismissing after 6s) instead of leaving two toasts to click through. Store-level dismiss timers are tracked in a Map so a dedupe refresh cleanly cancels + reschedules, and ToastCard resets its countdown + progress-bar animation when created_at changes so the refreshed ttl gets a fresh visual window.

[1.18.0] - 2026-07-19

Added

  • Per-bridge chat ignore list. New bridge_ignores table plus GET/POST /api/v1/bridges/:id/ignores and DELETE /api/v1/bridges/:id/ignores/:remote_jid. resolveRoute returns null for ignored remotes BEFORE any exact/catch-all lookup, so ignored chats never reach the agent — no thread history, no memory writes, no tool calls, no outbound replies. Different from silent_mode on a route, which still runs the agent and just gags the reply. The new Ignored chats section in BridgeEditor picks from synced chats or accepts a manual JID.
  • Abort and restart controls in Settings. Privacy & security now has a System control card with two buttons: Abort ongoing work (soft, calls new POST /api/v1/system/abort → abortAllRuns()) and Restart server (hard, supervisor relaunch via the existing /api/v1/system/restart). Both prompt for confirmation and surface the result inline. Escape hatch for stuck runs without paying the encrypted-master-key PIN re-entry cost of a full process kill.
  • Single-instance guard. New lib/lifecycle/pidfile.ts writes <dataDir>/jarela.pid at boot and checks any existing file for a live PID via process.kill(pid, 0) (POSIX + Windows). A second Jarela process on the same SQLite DB corrupts state via WAL-checkpoint races and half-open second binds; acquirePidLock() now blocks that with an actionable diagnostic pointing at the running instance. Stale files from crashed processes are clobbered on next boot. Set JARELA_SKIP_INSTANCE_LOCK=1 to bypass (registered in the environment schema under the lifecycle category, tier C, requires restart).
  • Provider-grouped tool views. Wide categories like Mail and Calendar now group tool pills inside per-provider mini-boxes with the vendor logo (Gmail, Outlook, iCloud, GitHub, Atlassian, Jira, Google, WhatsApp, …). Agent permissions (advanced mode) picks up the same grouping with a tri-state header checkbox per provider — flip all Outlook mail on or all Gmail off in one click. Unknown-brand tools fall into an Other bucket that always renders last. Single-provider categories (Memory, Files, …) stay flat.
  • list_scheduled_tasks and list_watchers are now cross-agent. Both tools return every row across every agent and tag each row with agent_id, agent_name, and owned_by_caller. Previously they scoped to the calling thread's agent while the Scheduled Tasks UI showed rows from every agent, which bit bridge-listener setups: the WhatsApp agent's tasks were invisible to the default agent asking what tasks do I have?. cancel_scheduled_task / cancel_watcher were already cross-agent; schedule_task / schedule_watcher still create rows under the calling agent's id.

Changed

  • iCloud tools folded into Mail / Calendar / Tasks categories. The dedicated iCloud tool category is gone. The single icloud default package is now three descriptors — icloud_mail (Mail), icloud_calendar (Calendar), icloud_tasks (Tasks) — all sharing the same Apple ID + app-specific-password auth bridge. Splitting by tool.name prefix keeps @circuitwall/icloud-langchain untouched. Existing agent configs are unaffected because tools are selected by name, not by category. migrateICloudPackageIds() transfers any disabled_packages.id="icloud" or builtin_tool_categories.category= "iCloud" intent to the three new package ids so tools stay hidden after upgrade.
  • ms_* tools render the Microsoft logo. brandSlugForToolName now aliases the short ms prefix to microsoft, so ms_graph_*, ms_search_*, ms_people_*, and ms_todo_* pick up the vendor logo in provider-grouped views. Added a PROVIDER_LABELS entry for groq and a drift-guard test asserting every KNOWN_BRAND_SLUGS entry has a matching label.

Fixed

  • WhatsApp LID DM contacts register in the chat picker. Baileys v7 delivers personal DM contacts from messaging-history.set and contacts.upsert with id in <n>@lid form; the phone-number JID is now only on Contact.phoneNumber. Our filter dropped every LID entry, so DMs vanished from the picker until a message arrived on that thread. New pickContactChatJid helper prefers Contact.phoneNumber when present (keeps entries aligned with PN-keyed routes), else accepts @lid, @s.whatsapp.net, or @g.us. listChats widened to include @lid — v7 accepts sendMessage to either LID or PN.
  • Category toggles accept iCloud, Microsoft, and Agent. PATCH /api/v1/builtin-tools validated category against a hardcoded set that had drifted from BuiltinCategory, so toggling any category added after the set was frozen returned 400 unknown category. Consolidated to a single source of truth: BUILTIN_CATEGORIES tuple in lib/tools/registry.ts (with a satisfies guard) drives the API route, the manifest schema in lib/tools/langchain-packages.ts, and the InstallPanel dropdown. A registry test guards the tuple contents.
  • Playwright promo-record script waits for BootScreen and force-clicks menu items. Three fixes: (1) openMenu now waits on the Dashboard tab button instead of a [role="radiogroup"] selector that no longer sits at the top of the menu; (2) pickSecondAgent uses force: true because inner SVG icons intercept pointer events; (3) on a fresh boot the BootScreen overlay (z-[70]) covers the viewport until an agent tile is picked, so we click the first Open tile and wait for the overlay to become pointer-events-none before proceeding. No-op when the overlay is absent.

[1.17.12] - 2026-07-16

Fixed

  • update_agent now accepts instructions_append to add standing rules without overwriting existing instructions. Previously agents had to read current instructions, concatenate, and write back the full string — a fetch-then-write that could race or accidentally drop content. instructions_append is mutually exclusive with instructions (full replace); passing both returns an error.

[1.17.11] - 2026-07-16

Fixed

  • Messages no longer disappear when a stream is interrupted. Two structural fixes: (1) the SSE error path now follows the same pattern as done and stop() — streaming content stays visible until finalizeRunFromServer replaces it with the persisted row; (2) the chat message state is now append-only: optimistic user bubbles carry a status: 'pending' marker and are promoted to confirmed in place when the server row arrives, never deleted and re-added. A "Sending…" indicator is shown on pending bubbles.

[1.17.10] - 2026-07-15

Fixed

  • Agents can propose their own standing instruction updates even when their tool allowlist is restricted. The self-configuration tools are now always available to the active agent during thread preparation and proposal checks, and the default harness explicitly tells agents to use update_agent when a user asks them to remember or enforce future behavior.

[1.17.9] - 2026-07-13

Fixed

  • Anti-stall detector now treats file edits as progress. Model-based stall classification short-circuits when the turn already invoked a write-class tool such as file_edit or file_multi_edit, so a completion that says it created or updated something via file editing is not retried as a false stall.

[1.17.8] - 2026-07-12

Fixed

  • Published package metadata is clean for downstream source rebuilds. Root workspace scripts now skip cleanly when the published tarball has no packages/* directory, so npm run build no longer fails with npm 11's No workspaces found error in consumers that rebuild Jarela from the npm package. The root manifest also declares the iCloud LangChain workspace dependency used by lib/tools/default-packages.ts, so downstream rebuilds do not need to inject @circuitwall/icloud-langchain before compiling.
  • Windows release bundles can install dependencies during prepare. The workspace-script helper now invokes npm through the current Node process when npm exposes its CLI entrypoint, avoiding a Windows command-shim spawn failure during release npm install.
  • Package self-test reports unexpected npm pack output clearly. The npm tarball verification script now accepts both known npm pack --json response shapes before reading the filename, and reports the actual npm output when the shape is unexpected.

[1.17.4] - 2026-06-23

Fixed

  • @circuitwall/jarela@1.17.0..1.17.3 failed to install with 404 Not Found - PUT https://registry.npmjs.org/@circuitwall%2ficloud-langchain during the boot preflight optimize step (and downstream mirrors such as vclaw's preflight). Two compounding bugs: the host-app integration in lib/tools/default-packages.ts imported @circuitwall/icloud-langchain without declaring it in root dependencies, while Next.js's standalone-build trace emitted it into .next/standalone/package.json at the workspace version (0.1.1) — which was never published to npm because the tag's publish job 404'd on a missing Trusted Publisher entry. Inline the workspace package via Next.js transpilePackages so its compiled output is bundled into jarela's webpack chunks rather than left as a runtime require(). The standalone manifest no longer references icloud-langchain, removing the registry roundtrip entirely and making jarela self-contained for this integration regardless of npm publish state.

[1.17.3] - 2026-06-21

Fixed

  • jarela update (and the boot-time update banner) crashed with ERR_MODULE_NOT_FOUND on globally-installed @circuitwall/jarela. scripts/jarela-bin.mjs dynamically imports ./update.mjs, but the file was missing from the files allowlist in package.json, so npm stripped it from the published tarball. Added scripts/update.mjs to files, and extended the npm tarball self-test (scripts/check-npm-package.mjs, run by the publish job before npm publish) to assert every script the bin imports — jarela-bin.mjs, update.mjs, service-install.mjs, first-run-prompt.mjs, start-prod.mjs — is present in the tarball. Prevents the same class of bug from shipping again.

[1.17.2] - 2026-06-21

Fixed

  • iCloud credential tile rendered the generic ic monogram instead of a recognisable Apple glyph. ProviderLogo didn't have an icloud entry in its brand-mark map, so the credentials panel, tool list rows, and bridge surfaces fell through to the two-letter initials fallback. Wires icloud to siApple from simple-icons (CC0) so the brand matches what the user actually authenticates against.

[1.17.1] - 2026-06-21

Fixed

  • iCloud Mail list returned iCloud IMAP error: Command failed whenever the agent asked for the most recent N messages without a filter. The underlying tool called IMAP SEARCH with an empty criteria object; per RFC 3501 §6.4.4 a SEARCH command requires at least one criterion, and iCloud's server replies NO Command failed for an empty list instead of treating it as ALL. icloud_mail_list_messages now substitutes { all: true } when the caller passed no unseen_only / query / since / before, matching the "give me the most recent N" use case the schema's limit parameter implies. Also short-circuits the subsequent client.fetch(uids, …) when the search returned zero UIDs so an empty mailbox returns { messages: [] } instead of another IMAP error. Bundled via @circuitwall/icloud-langchain@0.1.1.

[1.17.0] - 2026-06-21

Added

  • iCloud Mail + Calendar + Reminders integration. New first-class integration in the credentials panel under the Mail category, backed by the new @circuitwall/icloud-langchain@0.1.1 package. Connects via an Apple ID + app-specific password (16-character pattern with optional dashes, generated at https://appleid.apple.com/account/manage); 2FA on the Apple ID is a prerequisite. Ships 17 tools split into three permission tiers so agent policies can grant least privilege:
  • Read (8): icloud_mail_list_folders, icloud_mail_list_messages, icloud_mail_get_message, icloud_calendar_list_calendars, icloud_calendar_list_events, icloud_calendar_get_event, icloud_reminders_list_lists, icloud_reminders_list.
  • Write (7): icloud_mail_create_draft, icloud_mail_move_message, icloud_mail_flag_message, icloud_calendar_create_event, icloud_calendar_update_event, icloud_reminders_create, icloud_reminders_complete.
  • Execute (2): icloud_mail_delete_message, icloud_calendar_delete_event.
  • iCloud health probe. probeICloud issues a CalDAV PROPFIND against https://caldav.icloud.com/ with HTTP Basic auth to validate the credential live. 207 → ok, 401/403 → auth-failed (regenerate-app-password hint), 429 → transient. App-password input is normalised to strip the optional Apple-formatted dashes and zero-width characters before the basic-auth header is built.
  • Agent-facing iCloud setup manifest. lib/integrations/icloud/manifest.ts documents the 3-step setup (enable 2FA → generate app-specific password → save credentials with verify: { tool: "icloud_mail_list_folders" }) plus 3 troubleshooting entries, exposing the same flow to the in-app agent that other mail integrations already use.

Fixed

  • Docker multi-arch build skips the icloud-langchain workspace. v1.16.0's linux/arm64 and linux/amd64 images failed at npm ci because the Dockerfile only COPY'd four of the five workspace package.json files into the deps layer; npm then materialised an empty packages/icloud-langchain/ directory, so the later npm run build stage exited 127 (tsup: not found). Added the missing COPY packages/icloud-langchain/package.json line so the workspace resolves correctly during install.

[1.16.0] - 2026-06-21

Added

  • Bundled Jarela Google OAuth client + PKCE for Gmail/Calendar. End users can now connect Gmail and Google Calendar with a single click instead of standing up their own GCP project. A Jarela-owned Google Desktop OAuth client (client_id shipped in source, PKCE-protected per RFC 7636) drives the bundled flow; client_secret lives in Google Secret Manager and is injected by the hosted OAuth proxy at jarela-oauth-proxy-134669812881.europe-west1.run.app. The Advanced fields (client_id / client_secret / refresh_token) still work and override the bundle for forks, org-managed deployments, or users who prefer their own GCP project. JARELA_GMAIL_CLIENT_ID / JARELA_GOOGLE_TOKEN_PROXY env vars let downstream forks rebrand without code changes.
  • Advanced disclosure on the Gmail credentials card. The setup guide and three BYO fields now live inside a single collapsed <details> titled "Advanced — bring your own OAuth client", so the default flow is one click: Connect Gmail. Outlook layout unchanged (BYO is still required there until the same proxy treatment lands).

Fixed

  • Save no longer breaks the Gmail connection. probeGmail() was hitting oauth2.googleapis.com/token directly, which fails with client_secret is missing for the bundled client. After every Save the post-save probe re-run surfaced that as "Integration Gmail + Calendar is failing", so the connection looked broken. The probe now routes the refresh through the hosted OAuth proxy via the same selectTokenEndpoint() decision the runtime tools use, matching the pattern probeOutlook already followed for Microsoft.

Notes

  • The bundled OAuth flow drops client_id and client_secret from the required-on-save list for the Gmail integration. Existing rows are untouched; no migration required. Operators who want to keep using their own GCP project simply fill the Advanced fields as before.

[1.15.1] - 2026-06-20

Fixed

  • Accessible names stay stable across menu + sub-tab interactions. The primary navigation menu and the SubTabBar primitive were re-rendering with computed aria-label strings that flickered as the active state changed, causing assistive tech to re-announce the same element. Both surfaces now hold a stable accessible name.
  • /api/v1/files/[name] survives client aborts. The route used Readable.toWeb(fs.createReadStream(...)) which throws ERR_INVALID_STATE as an uncaughtException when the client cancels mid-stream (Node web-streams adapter race, nodejs/node#46540). Replaced with a hand-rolled ReadableStream that wraps every controller.enqueue / close / error call in try/catch and destroys the node stream on cancel(). Happy path (full read, range, conditional GET, 304/416) unchanged.
  • SubTabBar scrolls horizontally on iOS PWA. The sub-tab strip used touch-action: pan-y, which told iOS Safari to consume vertical pans on the strip and route horizontal pans to the page — the opposite of what a horizontally-scrolling strip needs. Switched to pan-x so the strip itself owns horizontal swipes and the page keeps scrolling vertically.
  • Brand marks for Gmail, Atlassian, and Jira credentials. The credentials panel rendered the generic monogram fallback for these three providers because they weren't registered with ProviderLogo. Added the corresponding simple-icons glyphs so every credential row shows the same visual weight.
  • WhatsApp bridges show the WhatsApp brand glyph. BridgesPanel dropped the generic MessageSquareText lucide icon in favour of <ProviderLogo name={bridge.kind} size={16} />, so bridges that map onto a known third-party brand (WhatsApp, Telegram, Discord, Signal, Messenger) render the brand mark inside the existing emerald avatar.
  • Tool-call rows in the chat transcript carry brand or per-family glyphs. ToolList now resolves the tool's brand prefix (gmail_*, github_*, jira_align_*, …) via brandSlugForToolName and renders the matching <ProviderLogo>, falls back to a per-family lucide glyph for internal tools (file, web, browser, memory, schedule, workspace, local exec, generate image / voice, …), and only shows the generic Wrench when the tool name is genuinely unknown.
  • Outlook credential renders a mail envelope. simple-icons removed the Outlook (and Microsoft / Office) brand marks at brand request, leaving the credentials list with a Ou two-letter monogram while every other email-shaped integration showed a real glyph. ProviderLogo now has a small LUCIDE_ICONS escape hatch for slugs with no simple-icons coverage but a sensible lucide stand-in; outlook maps to lucide's Mail envelope.

[1.15.0] - 2026-06-19

Added

  • Numeric-secret detection in the redaction layer (digit_run heuristic). Pure-digit secrets — credit cards, phone numbers, account numbers — have low Shannon entropy and were slipping past the alphanumeric heuristic. A new digit_run heuristic runs in parallel to high_entropy: it matches digit runs joined by space / hyphen / dot, requires at least 8 digits, and rejects matches that sit inside a recognised UUID / SHA / ULID / namespaced identifier by re-checking the surrounding token against the alphanumeric heuristic's exclude list. The first and last digit group must be ≥ 2 digits, so a stray 4 1234567 in prose doesn't get glued into a fake 8-digit secret. Slash is intentionally excluded from default separators so dates like 2026/06/19 stay unmatched. The high_entropy heuristic is split back out at min_length: 16 (entropy math means a 10-char string can't clear min_entropy: 4.0 and the threshold was nominal).
  • Secret-placeholder fingerprints. Redaction placeholders carry a short fingerprint so the agent can still reason about which secret it saw without seeing the secret itself. Format upgraded from «SECRET:<id>» to «SECRET:<id> type=<hint> len=<n> head=<h> tail=<t>», where head / tail expose floor(len * 0.1) characters (min 2). The placeholder regex stays tolerant so older bare placeholders still parse.

Changed

  • Onboarding wizard now reuses the production model and agent editors. Step 2 and Step 3 open the same <ModelEditor> / <AgentEditor> modals used elsewhere in the app, so what a user learns during setup matches the Settings panels they'll see later. The wizard becomes a checklist + sequencer: each step shows what's been created so far with an "Add another" button, and the final review screen reads back the actual saved rows instead of the wizard's local form state. First-time helper text on every step explains what a model / agent is and which fields matter. Net -123 LOC.
  • Credential-first model setup. In essential mode the model editor no longer shows the inline API-key field next to the credential dropdown. When no credential exists for the selected provider, an obvious "+ Add credential" call-to-action opens the credential dialog. The inline API-key field, base URL, temperature, max tokens, context window and extra headers are all gated behind Show advanced fields (or full-mode workspace).
  • Model editor field order. Reordered top-down to follow the way users think: provider → credential → API key (expert) → model ID → config name (auto-filled from model ID) → feature signals → advanced.
  • Provider brand marks throughout. Added a monochrome <ProviderLogo> component backed by CC0 brand-mark SVGs from simple-icons, rendered in model list rows, the credential group header, dashboard pricing groups, and the agent editor's "Using …" line. OpenAI and Cohere fall back to two-letter monograms because simple-icons no longer ships those marks per brand request.

Fixed

  • Setup wizard now triggers on fresh installs. Removed the seedModelConfigs migration that inserted three placeholder model rows on every boot — its presence made the listModelConfigs().length === 0 redirect guard in app/page.tsx always evaluate false, so brand-new installs skipped onboarding entirely. Existing installs are unaffected (the seed only ran when the table was empty).
  • Dev server hydrates over both localhost and 127.0.0.1. Added allowedDevOrigins: ["localhost", "127.0.0.1"] to next.config.ts so Next 16's strict origin check on /_next/static/* no longer 403s when contributors hit the dev server via one host while the listener is bound to the other. Dev-only; next start is unaffected.
  • Gmail / Outlook OAuth tolerates pasted invisible characters. The start endpoints and the credentials UI now strip whitespace and zero-width chars (U+200B…U+200D, U+FEFF) from client_id and client_secret before use, so a value copy-pasted from Google Cloud Console no longer fails with invalid_client because of a trailing ZWSP. When the provider rejects the exchange, the server logs a len=… head=… tail=… fingerprint of both fields (never the value) to make the mismatch debuggable without spilling secrets.
  • Model editor no longer crashes for providers without a credential manifest. Provider modules that don't declare a credential schema are now treated as "no credentials needed" instead of throwing while the dropdown renders, so DeepSeek-style providers load cleanly.

[1.14.1] - 2026-06-19

Added

  • One-click self-update with supervisor restart. The update-available banner now ships an "Update now" button alongside the dismiss X. Clicking it POSTs to /api/v1/update/apply, which spawns npm i -g @circuitwall/jarela@latest (or github:CircuitWall/jarela#main when JARELA_UPDATE_CHANNEL=main) in a detached child, streams its output into a 200-line ring buffer, and on success schedules process.exit(0) so the launcher (Task Scheduler / systemd / launchd / start-jarela.ps1) relaunches with the new bundle. The banner walks through preview → installing → restarting → waiting-for-server, polling /api/v1/health until the new process answers, then unregisters all service workers, clears every Cache Storage bucket, and reloads with a cache-busting query string. Source checkouts (.git present at cwd) refuse to self-update with a clear message.
  • OAuth setup in the credentials panel. The Gmail and Outlook integration cards now show the Connect button in the add-new and edit flows, not just on the default credential. The OAuth start / callback routes accept an optional credential_id so the refresh token is persisted onto the targeted credential row instead of the legacy default-integration slot, letting users wire multiple Google / Microsoft accounts to different agents.
  • Sync-from-env button in the credentials panel. Pulls OPENAI_API_KEY / ANTHROPIC_API_KEY / GOOGLE_API_KEY etc. from the running process environment into the credentials store on demand, so operators who set keys in ~/.jarela/env after first launch don't have to retype them in the UI.
  • Wizard credential safety. Re-saving a credential through the wizard now preserves any secrets the user didn't re-enter (masked fields fall back to the existing value), and the connection-test row fires automatically after a successful save so the user sees the green check without having to click test.

Changed

  • Shared UI primitives extracted. Six new headless components (Button, Dialog, TextInput / TextArea, StatusDot, Badge, CollapseChevron, SubTabBar) replace ad-hoc Tailwind clusters scattered across credentials, settings, models, agents, and chat panels. The migration covered ten primary buttons, every modal dialog site, all form text fields, and twelve side-panel sub-tab bars. The sub-tab refactor also fixes a mobile-PWA horizontal overflow on iOS Safari (the tab strip used to capture horizontal pan; it now delegates vertical pan to the page).
  • Settings sub-tabs reorganised. The Settings panel's sub-tabs are regrouped by domain (Profile, Models, Agents, Tools, Credentials, Logs, Memory, Updates, …) and each tab now surfaces a small attention badge when there's a configuration issue or unread item on that tab.
  • Frictionless first-run on npm install -g. Two small additions remove the "what do I do now?" beat between npm install -g and a running, autostarting service:
  • postinstall prints a brief hint listing the three subcommands most users want (jarela, jarela install-service, jarela --help) plus a link to the README. Silent in source checkouts, CI, local (non-global) installs, sudo, and when JARELA_QUIET_POSTINSTALL=1 is set. Wrapped in try/catch so it can never fail the install.
  • The first interactive jarela run detects when no autostart is registered for the current user and asks Install autostart now so it runs at login? [Y/n]. Accepting installs the OS-native unit and exits the foreground so the supervisor's instance takes the service port. Inert in non-TTY contexts (CI, pipes, Dockerfiles) and under sudo, opt-out with JARELA_NO_FIRST_RUN_PROMPT=1.
  • README: bleeding-edge install path. Documented how to pin to a specific commit, the tip of main, the next pre-release tag, and the andrewgewu/jarela:main Docker image for users who want to ride the trunk between stable npm releases.

Fixed

  • Claude routed through GitHub Copilot now uses prompt caching. Copilot exposes a native Anthropic-style /v1/messages endpoint at api.githubcopilot.com for Claude-family models. Until now we routed every Copilot request through chat.completions, which silently dropped the cache_control: ephemeral markers and forced Claude-via-Copilot to pay full input-token rates on every turn. Detect Claude-family model ids (canonical claude-* plus Github-Opus4.6 / copilot-claude-* aliases) and send them through the Anthropic SDK pointed at the Copilot baseURL with authToken Bearer auth. Non-Claude models keep the existing chat-completions path. The cache-control body builder and stream-event translator are now shared with the direct Anthropic adapter, so both paths apply the exact same three breakpoints (system, last tool, last tool_result) and emit the same cache_creation / cache_read token counts.
  • Boot failures now exit non-zero instead of half-starting. A thrown error during instrumentation-node.bootNode() used to propagate into Next.js, which logged it and then quietly brought the HTTP listener up anyway — leaving the server in a half-initialized state that responded with 5xx forever. The instrumentation.ts register() hook now wraps the boot chain in try/catch, prints the full stack to stderr, and schedules process.exit(1) after a 250 ms flush window so the launcher supervisor restarts cleanly.
  • Update install and Gemini fetches are bounded. npm i -g … spawned by the self-update endpoint is now killed after 15 minutes (SIGTERM then SIGKILL 5 s later), so a stalled registry or hung post-install script can't pin the update job in "running" forever. Gemini's four bare-fetch native endpoints (generateContent, streamGenerateContent for invoke + chat, batchEmbedContents) now carry a 10-minute AbortSignal.timeout(), matching the implicit ceilings the official OpenAI / Anthropic SDKs already enforce.
  • Credentials panel: Test button enabled for any saved credential. Previously the Test row only lit up for the default credential of each (type, provider) pair, so users couldn't validate the second GitHub PAT or the second Outlook account without first promoting it to default.
  • Gmail / Outlook OAuth Connect: invalid client_secret on re-auth. The credentials panel was masking saved secrets as "***" while the OAuth start route only recognised the legacy "********" sentinel, so clicking Connect on a saved Google/Microsoft credential sent the literal "***" to the token endpoint and Google rejected it with The provided client secret is invalid. The same mismatch let a Save-without-retype persist "***" into the encrypted credential blob, corrupting the stored secret until the user re-entered it. Introduced lib/utils/secret-mask.ts with a shared isMaskedSecret() recogniser that accepts both sentinel shapes; the credentials form, the stripMaskedSecrets() save filter, and both OAuth start routes now use it. The start routes also refuse to forward a placeholder secret to the provider and surface a clear "re-enter the real client secret" hint when corrupted data is detected.

[1.13.2] - 2026-06-19

Fixed

  • npm install @circuitwall/jarela failed with EUNSUPPORTEDPROTOCOL Unsupported URL Type "workspace:". The published 1.13.0 / 1.13.1 tarballs carried literal workspace:^ references for the four @circuitwall/*-langchain dependencies because npm only rewrites the workspace: protocol when publishing from inside a workspace sub-package, not when the root itself depends on workspaces. Added scripts/rewrite-workspace-deps.mjs and wired it as prepublishOnly so every npm publish resolves workspace:^ -> ^<actual-version> from the matching packages/*/package.json. scripts/check-npm-package.mjs now also asserts no workspace: strings remain in the packed manifest.

[1.13.1] - 2026-06-18

Fixed

  • Docker release build for ms-todo-langchain workspace. The builder stage now COPYs packages/ms-todo-langchain/package.json alongside the other three workspace manifests before npm ci, so the workspace:^ symlink can be materialised. Without it, npm ci failed with EUNSUPPORTEDPROTOCOL Unsupported URL Type "workspace:" on both linux/amd64 and linux/arm64, which blocked the v1.13.0 release artifacts. No image or package was published for v1.13.0; v1.13.1 is the first published build of the 1.13 series.

[1.13.0] - 2026-06-18

Added

  • Multi-instance named credentials. A credential row now carries a label and an is_default flag, so users can register more than one credential per (type, provider) pair and bind each agent's tools to a specific instance. Two Atlassian sites, two GitHub PATs, or two OpenAI keys can coexist in the same workspace and be wired to different tool instances. Agents gain a tool_credentials JSON column mapping each tool name to a credential id; the active credential is routed through an AsyncLocalStorage frame entered by a tool.invoke Proxy, so existing tool implementations need no changes. The first credential created for a pair is auto-labelled "Default"; deleting the default promotes the next survivor. POST/PUT/DELETE /api/v1/credentials accept label and is_default. CredentialsPanel now lists only configured providers, grouped by category, with per-row Add another / Edit / Delete affordances and a "default" badge. AgentEditor exposes a per-tool credential picker. 27 new unit/integration tests and a 9-test Playwright suite cover the API, agent round-trip, panel grouping, and empty state.

Changed

  • Side-panel sub-tabs share one clean underline pattern. CredentialsPanel, ToolsPanel and SettingsPanel previously rendered sub-tabs as a grid of bordered pills, which read as a card collection and made the active tab hard to spot. They are now a single horizontal row of plain labels with a 2px accent underline on the active tab; the row's bottom border forms a continuous baseline. Settings keeps its icons inline with the label. The strip is marked select-none touch-pan-y so iOS Safari PWA no longer captures horizontal drag on the tab row — touch only delegates vertical pan to the page, while tap still selects a tab. Twelve side panels also picked up no-scrollbar on their scrollable container for visual consistency with the rest of the app shell.

[1.12.0] - 2026-06-18

Added

  • Microsoft Graph core toolkit and search tools. Three new tools under the Microsoft category, all routed through the shared graphFetch helper: ms_graph_get (escape hatch for any v1.0 path with @odata.nextLink pagination), ms_search (cross-surface POST /search/query over mail, events, drive items, list items, people, Teams chats with slimmed hits), and ms_people_resolve (fuzzy /me/people lookup keyed on $search). graphFetch itself gained: 401 → access-token cache bust + one-shot retry, 429 / 503 honouring Retry-After (capped 30s) or exponential backoff, 403 path-prefix → required-scope hints, and a new graphPaged() helper that follows @odata.nextLink. Existing Outlook / Calendar / To Do callers benefit transparently. People.Read was added to MICROSOFT_SCOPES — operators who already connected need to reconnect Outlook to grant it (the 403 hint will say so).
  • Structural outline on file_read exploration calls. When the agent reads a file without start_line / end_line (i.e. it's exploring), the response now carries an outline of top-level functions / classes / consts / headings with their line numbers, per-language (TS/JS/JSX/TSX, Python, Markdown/MDX, JSON, YAML, TOML, Shell/PowerShell, Rust, Go, C/C++/Java/Kotlin/C#/Swift). The agent feeds the returned line straight back into start_line to zoom in deterministically — no follow-up file_grep, no guessing end lines, no re-reads. Targeted reads skip the outline entirely. Capped at 200 entries with outline_truncated: true. Binary files short-circuit via a denylist + NUL-byte sniff.
  • file_list depth and file_grep enclosing-symbol. file_list gained an optional depth parameter (default 1, max 4); depth>=2 walks the subtree in one call while skipping the standard noise dirs (node_modules, .git, dist, build, .next, out, coverage, .turbo, .cache, .venv, __pycache__, .idea, .vscode, target, vendor, …). file_grep now attaches enclosing: { kind, name, line } to each match, pointing at the surrounding function / class / heading, so the agent often skips the follow-up file_read entirely.

Fixed

  • Slow "Sending…" phase and stuck chat sessions on unpinned threads. buildHistoryWindow previously only checked the persisted warm summary when an explicit hot_since pin was set, and only persisted a freshly computed summary in that same case. Unpinned threads (the common case) paid a full summariser LLM round-trip on every turn. The cache is now keyed on a boundary string that falls back to the timestamp of the first hot message when no pin exists; subsequent turns whose hot/warm split is unchanged short-circuit the LLM call. The summariser itself is raced against JARELA_WARM_SUMMARY_BUDGET_MS (default 5000ms) so a hung provider can no longer permanently stall the chat.
  • Facts memory recall could indefinitely stall request preparation. buildHistoryWindow awaited recall() on every turn with no wall-clock budget — a hung embedding provider would block the whole turn. Bounded by the existing JARELA_RECALL_BUDGET_MS (default 1500ms); on timeout the facts tier falls through to the substring LIKE path on listMemory.
  • Operator-loaded LangChain tools couldn't see credentials stored via the UI. requiredEnv was checked against process.env only; secrets the user saved through the integrations store were invisible to the loader, so packages like Gemini failed to initialize even when a key was configured. The loader now also resolves requiredEnv entries from the integrations store and injects them into the subprocess env at load time.
  • tool_result events for operator-loaded tools were silently dropped on Windows. A stray @langchain/core install in the user's home directory (e.g. C:\Users\<u>\node_modules) caused operator packages to resolve a different module identity than Jarela's host. ToolMessage instanceof checks then returned false, the result chunk never reached the persistence layer, and the agent's tool call appeared to vanish without a response. The package loader now walks every subpath in Jarela's @langchain/core exports field and aliases the operator-side require.cache to Jarela's already-evaluated module records so there's exactly one constructor identity across host and operator code.

Documentation

  • README files-toolbelt row now lists file_glob, file_grep, file_multi_edit alongside the new file_list depth, file_grep enclosing-symbol, and file_read outline behaviour.

[1.11.0] - 2026-06-16

Added

  • Microsoft To Do tool category. New @circuitwall/ms-todo-langchain package ships 12 LangChain tools covering task lists, tasks, and checklist items (read + write). Wired into Jarela via the shared Microsoft OAuth client and surfaced under a new Tasks category in the built-in tool registry. Reuses the existing Outlook + Calendar connection (now relabelled Outlook + Calendar + To Do) after a one-time reconnect to grant Tasks.ReadWrite. dueDateTime / reminderDateTime inputs are normalized to Graph's "naive ISO
  • timeZone" envelope.

Fixed

  • Cost dashboard currency auto-detect ignored browser locale and manual currency change did not update the model pricing table. When no profile location was saved, the dashboard hard- defaulted to USD even on sv-SE / de-DE / etc. browsers; the manual dropdown also lacked SEK, NOK, DKK, CHF, NZD, SGD, HKD, KRW, ZAR, PLN, TRY and others. The auto path now derives an ISO-3166 country from navigator.language as a fallback (the /api/v1/dashboard/currency route grew a country query param alongside the existing lat/lng path), and the manual list was expanded to 27 common currencies. Separately, ModelPricingSection was not receiving currencyInfo and rendered $X.XX hardcoded — it now formats per-1M rates through formatMoney so picker changes propagate everywhere.

Security

  • hono <=4.12.24 (GHSA-wwfh-h76j-fc44, GHSA-j6c9-x7qj-28xf, GHSA-88fw-hqm2-52qc, GHSA-rv63-4mwf-qqc2, GHSA-wgpf-jwqj-8h8p) patched via root override to ^4.12.25. Pulled in transitively through @langchain/mcp-adapters → @modelcontextprotocol/sdk.

[1.10.6] - 2026-06-15

Fixed

  • SSE stream closed before queued runs started. Reattaching to a thread whose run had been queued (but not yet dispatched) used to synthesize an immediate done event and close the stream before the agent produced any output. The run registry now exposes waitForRun(thread_id, timeoutMs), and the GET /api/v1/threads/[thread_id]/run SSE handler awaits the queued run for up to 5 s before falling back to done. Drains waiters synchronously when startRun registers the run.
  • Chat tool list rendered raw LangChain serialized payloads. Tool messages arrived wrapped in {lc:1, type:"constructor", id:[...], kwargs:{content|args|tool_input}} envelopes and showed up as unreadable JSON. ToolList now unwraps the envelope (depth-6 cap), maps status:"error" to a structured {ok:false, error} result, renders args value-first with primary unkeyed and secondary fields as faint mono chips, and pretty-prints URLs, search-result lists, primitive arrays, and nested objects.

Security

  • form-data 4.0.0-4.0.5 (GHSA-hmw2-7cc7-3qxx) patched via transitive bump under cohere-ai / @langchain/cohere.
  • protobufjs <= 7.6.2 (GHSA-f38q-mgvj-vph7) patched via transitive bump.
  • @anthropic-ai/sdk bumped ^0.96.0 -> ^0.104.2.

Fixed

  • Picker ignored the popup's selected agent. Clicking "Pick element" with a non-default agent selected in the browser extension popup used to drop the captured element into the default agent's last-active thread. The picker's jarela-capture payload now goes through withSelectedAgent, and the /api/v1/page-capture endpoint accepts an optional agent_id and honours it (falling back to the default agent if the requested id is unknown).
  • Open Jarela ignored the popup's selected agent. The popup's side-panel opener, the options-page button, and the panel iframe all now forward the selected agent id via ?agent=<id>; useUrlSync consumes it on initial mount and on popstate so the app lands directly on the picked agent's chat.
  • Agent-control banner flickered between commands. During a multi-step agent run the overlay used to fade out at the end of every single command and back in at the start of the next, making it look like the agent kept losing control. The hide is now debounced by 5s — a new command in the chain cancels the pending hide so the banner stays put while the agent is actively driving the tab.
  • Pinning a tab while another was pinned required three clicks (Unpin → switch → Pin). The "Pin this tab" button now stays visible when the foreground differs from the pinned tab (labelled "Pin this tab instead") and atomically replaces the existing pin in one click.

[1.10.4] - 2026-06-14

Added

  • npm-installed manifests can be toggled enabled/disabled from the Tools → Packages list without uninstalling the package. The toggle persists in the new disabled_packages SQLite table; a missing row means enabled, so existing installs default to on. New POST /api/v1/packages/manifests/[name]/enabled endpoint and packages.setManifestEnabled() client method back the UI control.
  • Manifests can auto-discover every tool in a package by setting export: "*" (or leaving the Export field blank in the Install panel). The loader walks the module's exports, instantiates anything that looks like a LangChain StructuredTool, dedupes by tool name, and registers them all under one manifest handle. Removes the need to add one manifest per tool for multi-tool packages.

Fixed

  • Playwright chromium-desktop tests timed out clicking Settings sub-tabs. The NotificationStatus banner (absolute top-9 z-30) intercepted clicks on the tab strip underneath whenever headless Chromium reported Notification.permission === "denied". A new dismissOverlayBanners() helper pre-seeds both the crypto-fallback and notification dismiss flags in localStorage via addInitScript; every affected spec now uses it. Full chromium-desktop suite goes green in ~30 s instead of timing out at 30 s on the credentials/setup-reorg specs.

[1.10.3] - 2026-06-14

Fixed

  • Docker image build failed on every release. The root prepare script runs npm run packages:build (which calls tsup in each workspace), but the Dockerfile only copies each workspace's package.json before npm ci, not its src/ directory. tsup exits "No input files", taking the install step down with it. npm ci now runs with --ignore-scripts so the prepare hook is skipped; the actual workspace build still runs in the subsequent npm run build step, producing an identical image.

[1.10.2] - 2026-06-14

Fixed

  • Release workflow had been silently broken since v1.9.5. Every Bundle matrix job (Windows / Ubuntu / macOS) failed during next build page-data collection with ERR_SQLITE_ERROR: database is locked, so npm-publish was skipped for v1.9.5, v1.10.0, and v1.10.1 — the npm registry stayed pinned at v1.9.3 while three tags were promoted on GitHub. Root cause: both lib/tools/builtins.ts and lib/health/probes.ts call registerDefaultPackages() at module load, which transitively reaches getDb() + runMigrations(). Next 16 spawns three parallel page-data workers, all racing to open the same ~/.jarela/jarela.db; the second/third lose the migration lock. Both call sites are now gated behind a NEXT_PHASE !== "phase-production-build" check so registration is skipped during static analysis and still runs normally at runtime startup.

[1.10.1] - 2026-06-14

Fixed

  • Manifest loader silently kept stale cannot resolve package "…" errors after a successful install. When the operator saved a manifest from the curated catalog before the underlying npm package was installed (the natural "Save manifest" → "Install" UX flow), the loader cached the resolve failure. runInstall never invalidated that cache, so the InstallPanel kept surfacing the error as a "Load errors" entry even though the package was now on disk and require.resolve succeeded. The install pipeline now calls reloadLangChainPackages() after npm + introspection finish.
  • Cannot find module 'file:///…/wikipedia_query_run.cjs' when loading manifests under Next.js. Next.js's server bundler intercepts dynamic import() calls and cannot resolve file:// URLs to on-disk modules at runtime, so manifests targeting a package subpath (e.g. @langchain/community/tools/wikipedia_query_run) failed to load even though the file existed and require() against the same path worked. Both the manifest loader and the install-time introspector now load resolved modules via the anchor-scoped createRequire instance instead of import(pathToFileURL(…).href).

Tests

  • Added regression coverage for the v1.10.x install pipeline: assert runInstall invokes npm via cross-spawn with --legacy-peer-deps (Windows EINVAL + LangChain ERESOLVE), assert the post-install reload re-registers a pre-saved manifest, and assert searchUpstream clamps the caller limit to the upstream max of 100 (registry 422 fix). New tests in lib/tools/package-install.test.ts, lib/tools/langchain-packages.test.ts, and the new lib/mcp/upstream-registry.test.ts.

[1.10.0] - 2026-06-14

Added

  • Curated LangChain tool catalog in the Install panel. The Tools → Packages "Install" picker now ships with a hand-vetted catalog of 19 well-maintained LangChain integrations grouped by publisher (@langchain/*, langchain, plus selected community packages). One-click install no longer requires the operator to research package safety from scratch.

Changed

  • MCP picker defaults to a curated vendor allowlist. The MCP registry picker now defaults to the "Curated only (recommended)" view, restricting results to ~35 namespace prefixes of actively-maintained, vendor-published servers. Operators can still uncheck the toggle to browse the broader Official + Vendor registry. The allowlist is extensible via the JARELA_MCP_CURATED_PREFIXES env var.

Fixed

  • spawn EINVAL on Windows when installing npm packages. Node's fix for CVE-2024-27980 blocks child_process.spawn of .cmd / .bat shims without shell: true, which broke package installs on Windows where npm resolves to npm.cmd. The install flow now uses cross-spawn, which handles the Windows shim transparently. The InstallSchema validation was also tightened to allow only npm-spec / semver characters with explicit length caps.
  • ERESOLVE when installing @langchain/community and friends. The LangChain community package pulls in optional integrations (@getzep/zep-cloud and others) that pin @langchain/core <0.4.0, while the current @langchain/core is on the 1.x line. npm 7+ aborts the install rather than letting the operator decide. The install flow now passes --legacy-peer-deps — the LangChain-documented workaround — so community packages install cleanly. Scope is the ~/.jarela/packages sandbox only; the host Jarela process is unaffected.
  • MCP picker fails with HTTP 503 / upstream 422. The curated-only branch of the MCP registry search was sending limit=200, but the upstream MCP registry validates limit <= 100 and rejects larger values with HTTP 422. The page size is now clamped at the upstream maximum of 100; curated filtering and cursor-based pagination are unchanged.

[1.9.5] - 2026-06-14

Fixed

  • Health probes for additional LLM providers. /api/v1/health now consolidates the LLM provider probes and covers Cohere and GitHub Copilot in addition to the existing OpenAI / Anthropic / Google providers.

Changed

  • Internal refactors with no user-visible behaviour change: API route body validation standardized on zod, remaining process.env reads centralized through lib/env, the errorMessage helper restored and migrated to inline call sites, duplicate pricing helpers removed from lib/stores/dashboard-metrics, and additional unused exports pruned.

[1.9.4] - 2026-06-13

Changed

  • Tools tab consolidation. Built-in tools, default LangChain packages (Atlassian, GitHub, Jira Align), hot-loaded npm manifests, and drop-in .cjs tools all live under a single Tools → Packages sub-tab. MCP, Documents, Memory, and Bridges keep their own sub-tabs.
  • Default LangChain packages are now toggleable. Atlassian, GitHub, and Jira Align ship enabled but can be disabled via the new POST /api/v1/packages/defaults/{id} endpoint or directly from the Packages panel. Disabled defaults are unregistered live (no restart); state persists in the new disabled_packages SQLite table.
  • Custom provider plugins moved to Models. ~/.jarela/providers/*.cjs files now appear under the Models tab next to other provider listings instead of in the now-removed Browser-extension surface.
  • Network env vars moved to Settings → Networking. The bind host / port / HTTP timeout / retry editor that used to live at the bottom of User Profile is now a section inside Settings → Networking, alongside the proxy, allowed-sites, and env-alias controls.

Added

  • Auto-categorize tools by verb. Hot-loaded LangChain manifests no longer have to declare capability per tool. When omitted, the loader derives read / write / execute from the tool's verb using a Jira-style mental model (get_*/list_*/search_* → read, create_*/edit_*/delete_* → write, transition_*/exec_*/generate_* → execute). Operators can still pin a value when the verb is ambiguous. Helper: lib/tools/categorize-by-verb.ts.

Removed

  • Top-level Extensions menu entry. Drop-in tools moved to Tools → Packages; drop-in providers moved to Models. Legacy ?tab=extensions deep links resolve to Tools → Packages.
  • lib/tools/builtin-langchain-packages.ts (replaced by lib/tools/default-packages.ts).

[1.9.3] - 2026-06-13

Added

  • Settings tab. New top-level menu entry that consolidates Appearance, Networking, Credentials, Models, Harness, Logs, and Defaults as sub-tabs. The day-to-day menu grid is now just Chat, Dashboard, Agents, Tools, Tasks, Profile, Settings — every other configuration surface lives behind that single Settings entry.
  • Settings → Appearance hosts the theme picker (Light / Dark / System) that used to live in the MenuPanel footer, plus the Workspace mode toggle (Essential / Full) that used to sit above the menu grid.

Changed

  • MenuPanel slimmed: dropped the always-on theme picker from the footer and the workspace-mode toggle from the header — both moved into Settings → Appearance, so the menu surface is now just navigation.
  • Existing top-level Tab values (credentials, models, harness, logs, env) remain wired for backward compat — deep links and programmatic SET_TAB dispatches keep working — but they no longer appear as their own menu cards.

[1.9.2] - 2026-06-13

Changed

  • Credentials panel: one home for all auth. OAuth flows (Gmail, Outlook), API-key integrations (GitHub, Atlassian, Jira Align), and legacy model API keys now share a single grouped list under Credentials. Each known integration renders inline with Save / Test / Connect buttons and the same setup guides that previously only lived under "Built-in integrations" — no more flipping sub-tabs or clicking "Advanced" to reach the OAuth Connect button.
  • Credentials → Built-in integrations sub-tab renamed to Network & environment. The sub-tab now hosts only what isn't an auth surface: HTTP proxy, allowed sites, env-var aliases, and the "Sync from environment" button that pulls credential env vars into the unified Credentials list. Existing deep links (?tab=credentials&item=integrations) still resolve to this sub-tab for backward compat.
  • "Add credential" dialog now opens the same rich IntegrationCard editor used in the list, with inline OAuth Connect + Test instead of the old strip-down form that bounced to a sibling sub-tab.

[1.9.1] - 2026-06-13

Added

  • Settings → Tools → LangChain packages UI panel wrapping the /api/v1/packages/* endpoints. Operators can install vanilla LangChain tool packages from npm, approve/deny pending installs that fall outside the publisher allowlist, add/remove tool manifests, and trigger a hot-reload — all without leaving the browser. Mirrors the capability surface previously only reachable via curl.
  • Reusable usePackages() hook + api.packages.* namespace covering list / install / pending approval / manifest CRUD / reload.

Fixed

  • Docker image build for 1.9.0 release. The 1.9.0 tag's npm ci inside the Dockerfile failed because the root lockfile now resolves the @circuitwall/*-langchain entries through the workspace: protocol, but only package.json + package-lock.json were copied into the build context. The Dockerfile now copies each workspace package's package.json before npm ci so npm can materialize the symlinks. npm publish + GitHub Release for 1.9.0 were unaffected (those ran on the host directly).

[1.9.0] - 2026-06-13

Added

  • Hot-load vanilla LangChain tool packages from disk. Operators can drop a manifest under $JARELA_PACKAGES_DIR/manifests/*.json pointing at any installed npm package's StructuredToolInterface export, and the agent picks the tool up on the next turn — no rebuild, no restart. Manifests are zod-validated (package, export, category, capability, optional args + requiredEnv); missing required env vars cause the manifest to be skipped, not the loader to crash. Loaded packages live in the same registry as built-ins, so category toggles, deny-lists, and the /api/v1/tools endpoint all work transparently.
  • GET /api/v1/packages + POST /api/v1/packages/reload for introspection and hot-reload. The reload endpoint unregisters every currently-loaded package and rescans the manifests dir so a UI (or a curl from the operator) can pick up new packages or manifest edits without bouncing the process.
  • POST /api/v1/packages/install with publisher allowlist gate. Installs a package by npm spec into $JARELA_PACKAGES_DIR, introspects every StructuredToolInterface export it finds, and returns the result for the manifest-builder to pick from. Packages from a publisher in PACKAGE_PUBLISHER_ALLOWLIST (default @langchain/*, @circuitwall/*, langchain; extend via JARELA_PACKAGE_ALLOWLIST, same naming pattern as ENV_ALLOWLIST in lib/env/allowlist.ts) install immediately. Anything else returns 202 with a pending approval id; POST /api/v1/packages/install/:id approves, DELETE /api/v1/packages/install/:id denies, GET /api/v1/packages/install lists.
  • Manifest CRUD endpoints. GET|POST /api/v1/packages/manifests + GET|PUT|DELETE /api/v1/packages/manifests/:name let the operator (or a future UI) create, update, and remove manifests via HTTP. Every mutation triggers reloadLangChainPackages() so the tool becomes live (or disappears) on the agent's next turn — no hand-editing JSON, no restart. Names are slug-normalized for safe filesystem storage; duplicates return 409.
  • @circuitwall/jira-align-langchain v0.1.0 published to npm. Standalone release of the Jira Align (portfolio / SAFe) toolbelt extracted from lib/tools/jira-align.ts. 22 LangChain tools (work items, comments, hierarchy entities, dependencies).
  • @circuitwall/github-langchain v0.1.0 published to npm. Standalone release of the GitHub REST toolbelt extracted from lib/tools/github.ts. 22 LangChain tools (issues, PRs, repo content, code search) plus the pure helpers truncate and decodeContentsBlob.
  • @circuitwall/atlassian-langchain v0.1.0 published to npm. First standalone release of the Atlassian (Jira + Confluence) toolbelt extracted from lib/tools/atlassian.ts. External LangChain.js / LangGraph projects can now npm install @circuitwall/atlassian-langchain to consume the 64 tools (42 Jira + 22 Confluence) without running Jarela. README now advertises the package under a new "Reusable packages" section.

Changed

  • @circuitwall/{atlassian,github,jira-align}-langchain promoted to v1.0.0. The public surface of all three packages has been stable since the initial 0.1.0 release and is now consumed directly by Jarela's bootstrap path. The major bump signals API stability with no behaviour change.
  • In-tree adapters for the three @circuitwall/*-langchain packages removed. lib/tools/atlassian.ts, lib/tools/github.ts, and lib/tools/jira-align.ts (the thin wrappers that plugged the npm packages into the integrations store) have been deleted. Their wiring is now declared once in lib/tools/builtin-langchain-packages.ts, and cross-module callers (lib/health/probes.ts, lib/documents/remote/{github,jira,confluence}.ts) resolve auth via the new resolvePackageAuth<T>(integrationId) helper instead of importing per-adapter _resolveXxxAuth re-exports. Net -211 LOC. Integration ids (atlassian, github, jira_align) and stored field names (url, email, api_token, token) are unchanged, so existing credentials rows in the encrypted store resolve through the new path without any data migration.
  • All built-in tool registrations now go through registerLangChainPackage. The previous mix of direct registerTools(category, capability, [...]) and hand-rolled per-bucket loops collapses into one declarative form, matching what the hot-load path produces. No behaviour change for users.
  • Jira Align tools are now an extractable npm package. lib/tools/jira-align.ts was split into:
  • @circuitwall/jira-align-langchain (packages/jira-align-langchain/, v0.1.0) — the 22 LangChain tools, plus the low-level jiraAlignFetch escape hatch. Pluggable auth via setAuthResolver() with a default env-var resolver. Zero Jarela-specific code.
  • lib/tools/jira-align.ts (Jarela) — now a thin adapter that plugs Jarela's encrypted integrations store into the package via setAuthResolver() and re-exports every tool so existing internal callers (lib/health/probes.ts, lib/tools/jira-align.test.ts) keep working unchanged. (Subsequently deleted later in 1.9.0; see "In-tree adapters … removed" above.)
  • GitHub tools are now an extractable npm package. lib/tools/github.ts was split into:
  • @circuitwall/github-langchain (packages/github-langchain/, v0.1.0) — the 22 LangChain tools, the pure helpers (truncate, decodeContentsBlob), and the low-level githubFetch escape hatch (re-exported as _ghFetch for back-compat with the Jarela internal name).
  • lib/tools/github.ts (Jarela) — thin adapter mirroring the JA / Atlassian pattern; existing callers (lib/documents/remote/github.ts, lib/health/probes.ts, lib/tools/github.test.ts) keep working unchanged. (Subsequently deleted later in 1.9.0; see "In-tree adapters … removed" above.)
  • Release workflow now publishes all three packages by tag prefix. .github/workflows/release.yml switches on the pushed tag:
  • v* → publish @circuitwall/jarela (Jarela app) from the repo root.
  • atlassian-langchain-v* → publish from packages/atlassian-langchain.
  • jira-align-langchain-v* → publish from packages/jira-align-langchain.
  • github-langchain-v* → publish from packages/github-langchain.

No behavior change for Jarela users. All existing tests still pass. - Atlassian (Jira + Confluence) tools are now an extractable npm package. lib/tools/atlassian.ts was split into: - @circuitwall/atlassian-langchain (packages/atlassian-langchain/, v0.1.0) — the 64 LangChain tools, 5 pure helpers, and the low-level atlassianFetch escape hatch. Pluggable auth via setAuthResolver() with a default env-var resolver. Zero Jarela-specific code. - lib/tools/atlassian.ts (Jarela) — initially a thin adapter (later deleted in 1.9.0; see "In-tree adapters … removed" above). - Repo is now an npm workspaces monorepo. Added "workspaces": ["packages/*"] to the root package.json to host standalone @circuitwall/* packages extracted from lib/ alongside the Jarela app itself. The Jarela package (@circuitwall/jarela) builds, publishes, and runs unchanged. See packages/README.md for layout and conventions, and CONTRIBUTING.md for the release rules that apply to workspace packages. - Build now compiles workspace packages first. npm run build now runs npm run packages:build (a thin wrapper over npm run build --workspaces --if-present) before next build, and a root prepare script does the same after npm install so fresh clones don't need an extra step before npm run dev / npm test.

[1.8.1] - 2026-06-13

Fixed

  • Browser-control loop no longer stalls between long-poll iterations. MV3 terminates idle service workers after ~30s, and the existing chrome.alarms revival ticks (every 30s) could only restart the SW after it had already been killed — long enough for the server to time out the parked /poll request and for the user to perceive a hang on the next agent action. The extension now spawns a minimal offscreen document (offscreen.html) on install/startup that holds an open chrome.runtime.Port (jarela-keepalive) to the SW. As long as that port is connected the SW is kept alive; when Chrome hits its hard ~5 min SW lifetime and recycles the worker, the offscreen page detects the disconnect and reconnects within 500 ms, respawning the SW immediately. The chrome.alarms revival cadence stays in place as a fallback for the case where the offscreen doc itself is evicted. Adds the offscreen manifest permission.

[1.8.0] - 2026-06-12

Fixed

  • Agent overlay no longer crashes on re-injection after an extension reload. The overlay's IIFE used window.__jarelaAgentOverlayInstalled to guard against double-injection, but that flag lives in the isolated-world JS context — which is destroyed whenever the extension is reloaded or updated. The next injection found a fresh JS context but a leftover host element in the page DOM carrying a mode:"closed" shadow root that the new context couldn't read back, so the fallback hostEl.shadowRoot || hostEl.attachShadow(...) threw NotSupportedError: Shadow root cannot be created on a host which already hosts a shadow tree. The overlay now tears down any orphan host element on first run and rebuilds from scratch.
  • Pin auto-release now notifies the user. When the pinned tab is closed, or when the user manually navigates it to a page the agent can't drive (chrome://, about:blank, an extension page, etc.), the pin is cleared from storage and a system notification tells the user which tab was released and why. Previously the pin was cleared silently, so the popup card would update to "No active tab" with no explanation and the user could keep asking the agent to drive "this tab" without understanding why nothing was happening.
  • Browser-control commands fail fast when the extension is offline. Previously every command waited the full per-command timeout (30s default) before reporting failure, so the user saw a generic "the extension is timing out" message even when the SW had been killed for less than a second. The server now tracks the extension's last poll-arrival time and the count of currently parked long-pollers; if neither indicates the extension is alive within a 35s liveness window, enqueueCommand rejects immediately with a clear "extension is not connected — open Chrome and click the Jarela toolbar icon" message including how long ago the extension was last seen. A new loopback endpoint GET /api/v1/extension/browser/status returns the same state (connected, lastSeenMs, pendingCommands, pollerWaiting) for UI / diagnostics use. Extension-side: the SW revival alarm now fires every 30s (the MV3 minimum) instead of every 60s, and tab / window-focus events also resume the long-poll loop so the gap between SW wake and the next /poll request is seconds rather than up to a minute.

Added

  • browser_snapshot tool — structured page reads, no vision needed. Returns a compact JSON map of the active tab: URL, title, viewport, headings, ARIA landmarks, and a numbered list of every interactive control (links, buttons, inputs, selects, textareas, custom widgets) with role, accessible name, and a ready-to-use CSS selector the agent can pass straight to browser_click / browser_fill. Dramatically faster than the previous navigate → screenshot → vision → click loop: a snapshot is ~1–5 KB of text and skips the multi-second image upload + analysis round-trip on every step. The browser_navigate tool now points the agent at browser_snapshot by default; browser_screenshot stays for cases where the visual layout itself matters (charts, captchas, layout choices).
  • Foreground-tab auto-detection for the browser-control agent. The extension now tracks the last content tab the user actively focused (via chrome.tabs.onActivated, chrome.tabs.onUpdated, and chrome.windows.onFocusChanged) and stores it under jarelaForegroundTab. The dispatcher's tab resolver prefers this record over the live chrome.tabs.query — which was unreliable because the moment the user clicked the Jarela popup, side panel, or another window, the "current window" flipped and the agent silently retargeted the wrong tab. Pinning still works for the case where the user wants to lock to a specific non-foreground tab, but no pinning is required for the common case: the popup now shows "👁 " so the user can see at a glance which tab the agent will drive. Only http(s) tabs are tracked; chrome://, about:blank, and extension pages are skipped.
  • Tab pinning for the browser-control agent. The popup now has a Pin this tab button that locks the agent onto a specific browser tab by ID. Once pinned, every browser-control command runs against that tab regardless of which window has focus — fixes the failure mode where opening the popup or side panel made chrome.tabs.query({ active: true }) return the wrong (or no) tab mid-task. A pinned tab is auto-cleared when it's closed or navigated to a non-scriptable URL (chrome://, blank, extension page). When no pin is set the resolver falls back to the active http(s) tab in the last-focused window, skipping chrome:// / blank pages instead of silently failing.
  • Connection status indicator in the popup. A coloured dot on the target-tab card shows whether the SW is currently connected to the Jarela server (green = healthy, red = unreachable), so the user can tell at a glance whether the extension can deliver agent commands.
  • Agent-driven browser navigation via the extension. Six new tools register under the Web category and let an agent drive the user's active browser tab through the Jarela browser extension: browser_navigate, browser_click, browser_fill, browser_scroll, browser_screenshot, browser_extract. The agent enqueues commands on a server-side FIFO queue (POST /api/v1/extension/browser/poll long-poll, POST /api/v1/extension/browser/result submission); the extension service worker pulls them and executes them via chrome.scripting.executeScript in the active tab. Loopback-only auth on both endpoints. Screenshots are cropped to the element bounding rect via OffscreenCanvas and persisted under ~/.jarela/files/. Commands time out cleanly when the extension is not loaded — no headless browser process is spawned, preserving the single-process invariant. Every command runs behind a per-host approval prompt rendered inside the target tab (Approve once / Always allow / Deny), and a "Jarela agent is controlling this tab" banner with a Stop button stays mounted while a command is executing so the user is always aware when the agent has control.

Changed

  • Long-poll loop now backs off on consecutive errors. Previously the extension service worker tight-looped on /browser/poll when the Jarela server was unreachable. It now waits min(1s × 2^n, 30s) between retries, resetting on any successful response. The 1-minute poll-revival alarm still covers full SW death; this just makes network-blip behaviour graceful.

[1.7.0] - 2026-06-12

A feature drop on top of 1.6.0. Headline: outbound mask-and-rehydrate redaction. API keys, personnummer, IBANs, and high-entropy secrets in your messages and tool outputs are swapped for stable «SECRET:<id> type=<hint>» placeholders before they cross the provider boundary, then rehydrated to their real values before tool execution and before the UI renders. The model can compose with secrets it never sees ("put this key in the email body") while the provider only ever receives the placeholder. Disabled with one toggle; patterns are user-editable on disk.

Added

  • Outbound mask-and-rehydrate redaction with UI transparency (#244, ADR-0064). Implements the trust boundary described in docs/adr/0064-outbound-redaction-mask-and-rehydrate.md. Mechanics:
  • Outbound: every message and tool-event payload is scanned just before JarelaChatModel.toInvokeMessages. Each match becomes «SECRET:<id> type=<hint>» with a coarse type bucket (anthropic_api_key, personnummer, iban, unknown_long_string, …) so the model has enough context to decide what to do with the value without seeing it. Same source value gets the same id within a thread so the model can refer back to "the key from earlier."
  • Inbound — UI: streamed assistant deltas pass through a rehydrator that holds back partial placeholders across chunks, so the user sees the real values they already own and never a half-token.
  • Inbound — tool calls: every tool argument is rehydrated before the tool executes via a Proxy wrapper that preserves LangChain's prototype dispatch. The "use this secret in a tool call without seeing it" flow is the load-bearing piece.
  • Per-turn summary on every assistant row: redaction_summary metadata records coarse type counts (never the values). The chat bubble renders a green ShieldCheck affordance — "3 values held back from LLM" — that expands to per-type counts. Without the surface the feature would be invisible.
  • Settings panel under Profile → Security. Toggle (default on), pattern-file path with "Create default file" / "user-edited" affordance, collapsible list of active patterns (name, type_hint, validator), allowlisted JSON field names, and inline copy explaining the trust boundary.
  • User-editable patterns at ~/.jarela/redaction-patterns.json, hot-reloadable on file change. Defaults cover Anthropic / OpenAI / Cohere / Google API keys, Swedish personnummer, IBAN, and a high-entropy heuristic for unknown long strings. Allowlisted JSON field names (prompt, query, text, …) prevent the masker from eating tool inputs that legitimately look secret-shaped.
  • Persistence is unchanged: checkpoints continue to store the unmasked content, encrypted at rest by ADR-0005. Masking at rest would break thread resumption across processes (the rehydrate map is in memory) and gain little on top of existing encryption.
  • No behavior change when redaction is disabled — the chain reduces to a no-op MaskContext. All 1706 prior tests pass.

Fixed

  • PIN keypad backspace renders the ← glyph (#243). The setup-wizard PIN keypad was rendering the bare codepoint instead of the arrow on certain font stacks; switched to the explicit ← literal so the glyph is consistent across platforms.

[1.6.0] - 2026-06-12

A small feature drop on top of 1.5.0. Headline: agents can now use the sites you're logged into in your browser — approve a host once in Settings, and the Jarela browser extension transparently keeps the server-side cookie store fresh as cookies change so web_fetch can reach SSO-only intranets and personal-session endpoints without you ever pasting a token.

Added

  • Allowed-sites list with cookie passthrough for web_fetch (#241). New Settings section Sites the agent can use as you — adding a host approves cookie passthrough for that host (and, in a follow-up, browser-RPC navigation). The browser extension watches chrome.cookies.onChanged for approved hosts and pushes the latest cookie set to Jarela automatically; web_fetch then attaches them on outbound requests with per-redirect re-resolution so off-list redirects strip credentials. Cookies are envelope-encrypted at rest (same scheme as proxy passwords) and never appear in the UI. Per-host intranet toggle opts the host past the SSRF guard so an internal Confluence / Jira / dashboard behind the corporate VPN is reachable without flipping the global JARELA_ALLOW_PRIVATE_FETCH escape hatch. RFC 6265 path / Secure / expiry filtering happens server-side per request; suffix matching means approving example.com covers *.example.com automatically.

[1.5.0] - 2026-06-11

A feature drop on top of 1.4.1. Headlines: WhatsApp bridges no longer lose messages while the app is offline; the onboarding wizard is now a real step-by-step flow; the in-chat /compact command preserves the visible transcript and shows what it actually compressed; scheduled tasks that fire while the app is locked are no longer silently dropped; and large editor/panel components were split into focused sub-files for maintainability.

Added

  • Jira Align integration with write-side coverage (#238). Adds a manifest entry and a jira-align tool that covers the write side of the Jira Align REST API (create / update / link work items), so an agent can drive an Align portfolio backlog end-to-end alongside the existing read-only coverage.
  • WhatsApp bridge catches up missed messages on reconnect (#234). Baileys delivers offline-queued messages as messages.upsert type=append, not notify. The adapter previously ignored append batches — silently dropping every message received while the bridge was down. Now accepts both message types, watermarks per-route progress with a monotonic last_seen_ts, and dedupes against an LRU ring of the last ~2000 message IDs so a server restart no longer means lost messages.
  • Scheduled tasks deferred while the app is locked (#234). Cron-fired tasks that hit a locked vault are queued instead of erroring; on the next unlock the scheduler replays them in order. Surfaces the deferred list in the UI so the operator can see what is waiting.
  • Onboarding wizard is now a real step-by-step flow (#234). Replaces the scrollable cards with a fullscreen one-step-at-a-time wizard (Profile → Model → Agent → Review) so first-run users can't skip prerequisites. Each step is its own component under components/setup/wizard/.
  • Boot-time autostart in the installer (#232). install-startup.ps1 now accepts -Boot to register Jarela as a scheduled task that runs at machine startup (in addition to the existing logon trigger), so the launcher comes up before any user signs in.
  • Compaction stats on the context boundary chip (#234). The divider between the warm summary and hot context now reads N msgs · 18.2k → 1.4k (-92%) so you can see at a glance what the most recent compact actually saved.

Changed

  • Facts tier retrieves via semantic recall instead of substring LIKE (#239). buildFactsContext previously shortlisted facts with a SQLite LIKE %query% against each fact's key+value, requiring a literal substring overlap between the question and the stored fact. It now routes through the same recall() cosine path used by the recall context tier, filtered to namespace=facts, so semantically related facts surface even when no words overlap. Substring LIKE is retained as a fallback for workspaces with no embedding provider configured.
  • /compact (/new) preserves the transcript (#234). Compacting no longer wipes the visible chat. The hot/warm boundary moves to just after the last message and the summary lands behind the divider; the user can still scroll up through the prior turns. Long-term growth is still bounded — JARELA_MAX_THREAD_MESSAGES (default 1000) caps the retained transcript and JARELA_MAX_SESSION_ARCHIVES caps the per-agent session-summary archive.
  • Large editor/panel components split into focused pieces (#233). AgentEditor, ModelEditor, DocumentsPanel, ChatView, DashboardPanel and the long tool-callback files in lib/tools/ were broken into single-purpose sub-files and hooks. Mechanical extraction only — same props, same state — but each unit now fits on one screen and is independently testable.
  • Source-map and glob deprecation warnings remediated (#229). Bumps transitive deps and silences the noisy warnings emitted on next dev.

Fixed

  • Idle watchdog stays alive during silent tool-arg streaming (#240). Some providers stream long tool-call argument JSON without emitting any user-visible token deltas, which used to trip the idle watchdog and abort the turn mid-tool-call. The watchdog now treats tool-arg chunks as a heartbeat so a slow function-call stream no longer cancels itself.
  • Warm summary no longer restates user identity (#237). The summariser prompt was asking for "stable user facts," which made every /compact re-emit the user's name / email / location into the warm tier on top of the dedicated identity injection from user_profile. Tightened the prompt to explicitly skip identity fields so the warm summary stays focused on conversation content.
  • /compact extends the prior warm summary instead of resummarising every time (#235). Previously each /compact rebuilt the warm summary by passing every retained message back through the LLM. Two problems: (1) wasteful — long input every time and lossy summary-of-the-summary; (2) unsafe — once pruneThreadMessages had trimmed older rows past the retention cap, those rows were gone from the DB, so a from-scratch resummary silently dropped everything the previous summary used to cover. Now, when a non-empty warm summary already exists, the route only summarises the messages newer than warm_summary_before and folds the prior summary forward.
  • One PIN entry covers both decrypt and screen-unlock (#234). Server-side complement to #226: /api/v1/security/unlock also clears the screen-lock flag on success, and AppShell renders only the decrypt overlay when both flags are up. Decrypting proves human presence, which is exactly what the screen-lock check confirms — so requiring a second PIN immediately afterwards was pure friction.
  • /compact flushes the message queue when it finishes (#234). Messages typed while compaction was in flight previously stayed queued until the next user submit; they now drain automatically once the compact request resolves.
  • Drop the + N earlier affordance from the context boundary divider (#234). The link pointed at content already represented by the warm summary; the divider chip alone is enough.
  • Drop the redundant /compact succeeded toast (#235). The boundary chip already shows the same N msgs · before → after (-N%) numbers immediately above; the toast was duplicating the same information.
  • Surface session and stream errors as toasts (#230). 4xx/5xx responses from /api/v1/agents/.../session and stream-side aborts now produce an in-chat toast instead of failing silently.
  • Raise the recall budget for the agent boot path from 400 ms to 1500 ms (#231). Slow embedding models were timing out before recall could populate the warm context, which silently degraded answer quality on the very first turn.
  • README promo video renders with autoplay (#224). Re-encoded the source promo so GitHub serves it as video/mp4 instead of the audio-less webm (which the markdown sanitizer refused to render).

A reliability + UX polish patch on top of 1.4.0. The PIN keypad used at boot-time decrypt and screen-unlock has been collapsed into a single component with two modes, the API client treats both 423 lock states symmetrically (master-key-locked is no longer surfaced as a toast error), and several silent failure modes uncovered during last night's launcher diagnosis are now bounded and observable.

Changed

  • Unified PIN keypad (#226). UnlockScreen and ScreenLock were near-duplicate 6-digit keypads; collapsed into a single PinKeypad with mode: "decrypt" | "unlock". Both unlock paths converge on a shared landOnAgentPicker() so the user always lands on the agent selector. Boot-time decrypt now uses router.refresh() instead of a full window.location.reload(), so the transition to the AppShell is seamless. The API client handles 423 locked symmetrically with screen-locked — neither lock state is surfaced as a toast error any more; the matching overlay mounts instead.

Fixed

  • Bounded resource leaks and last-resort error handlers (#227). Installs process.on("uncaughtException") and process.on("unhandledRejection") in instrumentation-node.ts so stray async errors land in the in-memory log ring instead of going to raw stderr or killing the server. The thread-run SSE route's cancel() now tears down its 500 ms poll and event subscriber on client disconnect; the provider-probe route clears its timeout on the win-path; lib/tools/async-results exposes stopAsyncResults() and the shutdown drain calls it. Gmail and GitHub page-walkers switched from Promise.all to Promise.allSettled so one failed item no longer bins the whole page. AbortSignal.timeout() added to the dashboard currency lookups (Nominatim, restcountries, open.er-api) and the GitHub-Copilot provider fetches.
  • Installer captures node stdio and bounds task retries (#225). Replaces Start-Process -RedirectStandardOutput/Error (which silently dropped both streams under wscript -> powershell) with a raw [System.Diagnostics.Process] plus async BeginOutputReadLine / BeginErrorReadLine writing through autoflushed StreamWriter s, so server.out.log and server.err.log actually contain output. Logs node's exit code on every cycle. Tightens the in-launcher rate limiter from 5 to 3 restarts in 60 s. Reduces the scheduled-task retry policy from RestartCount=999, RestartInterval=1m to RestartCount=3, RestartInterval=5m — with an encrypted master key, every retry needs manual PIN re-entry, so 999 silent retries was strictly worse than failing loudly.
  • README promo video renders (#223). GitHub raw was serving the audio-less .webm as audio/webm (mime-sniffer mis-classifies); browsers refused to render it in a <video>. Re-encoded to h264 mp4 (faststart, video-only) which raw.githubusercontent.com tags as video/mp4, and switched the README to absolute raw URLs for src and poster since the markdown sanitizer doesn't rewrite relative paths inside <video>.

[1.4.0] - 2026-06-08

Added

  • Browser-extension element screenshot. The page-capture flow now ships a cropped PNG of the picked element alongside the text. The content script grabs the visible viewport via chrome.tabs.captureVisibleTab (loopback only, via the service worker) and crops it to the element's bounding rect through OffscreenCanvas at devicePixelRatio. The server validates the base64 payload (≤ 4 MB encoded), persists the user message as a multipart ContentPart[] of [text, image] so the bubble renders the picture inline, and forwards the image part to the silent observer turn so vision-capable agents see it on the immediate follow-up run. Falls back cleanly to text-only capture if the snapshot is denied. See docs/api.md for the updated request schema.
  • Promo video recorder. npm run promo:record (via scripts/promo-record.mjs) drives your real local install in a 9:16 vertical PWA viewport and records a dark-theme .webm of the tap-to-unlock intro, agent picker, a human-paced chat turn, and a tour of every side panel. First run saves auth state to promo/.storage.json and reuses it thereafter.

[1.3.0] - 2026-06-08

Two new agent capabilities and a hardening pass on tool wall-clocks. Bridge adapters (WhatsApp today) now spill large remote attachments to a local store instead of inlining them into the LLM context, and the agent picks them up by path through file_read. Long-running tool calls can now be fired asynchronously: the LLM gets a tracking key back immediately and pulls the result later via a new built-in.

Added

  • Bridge attachment spill store (#215). Inbound bridge messages no longer base64-inline every document, voice note, audio, or video into the next prompt. Buffers are persisted under <dataDir>/bridge-attachments/<bridge>/<YYYY-MM-DD>/<id>-<name> with sanitised paths, an SHA-256, and a future-facing pruneBridgeAttachments({ maxAgeMs }) helper; the prompt body carries a text pointer telling the agent to use file_read to inspect the contents. Images and stickers ≤ 1 MB still inline so vision works out of the box.
  • Async tool execution (async_run wrapper + tool_result_get) (#216). Every tool's schema now exposes an optional async_run: boolean. When set, the wrapper returns {ok, async, key, tool, started_at, deadline_ms, hint} immediately and runs the work detached; the LLM picks the result up via the new built-in tool_result_get(key, wait_ms?, consume?). tool_result_list returns summaries without dumping result bodies. In-process store with a 10-minute TTL and a 256-entry cap (oldest finished evicted first, then oldest pending with a warn).

Changed

  • Hard ceiling on tool deadline_ms (#216). The wall-clock budget the LLM can pick is now clamped to 30 minutes by default. Values above the ceiling are clamped and a one-line console.warn is emitted naming the tool, the requested value, and the ceiling. Operators can raise or lower the cap with the new JARELA_TOOL_MAX_DEADLINE_MS environment variable (integer milliseconds). Applies to both sync and async_run paths.

Fixed

  • E2E menu specs no longer race the boot agent picker (#217). Three Playwright specs (layout, credentials, setup-reorg) were intermittently failing because the BootScreen overlay intercepted clicks on the header menu button. A new waitForAppReady(page) helper picks the default agent tile and waits for the overlay to detach before the test drives the UI.

Configuration

  • JARELA_TOOL_MAX_DEADLINE_MS — overrides the per-tool wall-clock ceiling (default 1800000 ms / 30 min). Set to a smaller value to tighten the cap, or larger if a regulated workload genuinely needs long synchronous calls.

Two follow-up fixes on top of 1.2.0.

Fixed

  • Boot agent picker always shows after login (#213). The picker was being skipped in some session states; it now reliably appears so the user actively chooses an agent at boot instead of silently inheriting one.
  • Extension UX polish on one-shot turns (#212). Custom intent collapses by default, Enter submits, writes are queued, and one-shot turns drop the quality gates that didn't apply to them.

[1.2.0] - 2026-06-08

Security, runtime resilience, and a broad UI consolidation pass. The Setup surface gets a noticeable cleanup (capabilities all under one tab, MCP and connections folded in where they belong), runs now have proper watchdog coverage everywhere with an adaptive wall-clock that doesn't punish slow tools, and the on-disk keyfile can be PIN-protected with an auto-lock when the app idles.

Added

  • PIN-protected keyfile + idle screen lock (#200, ADR-0063). The local keyfile that wraps credentials and memory rows can now be protected by a user-set PIN, and the app auto-locks after an idle timeout so a left-open browser tab no longer exposes secrets at rest.
  • Per-turn output-token budget injected into the system prompt (#197). The agent now sees the per-turn output ceiling alongside the context window so it can plan its response length instead of getting truncated mid-thought.
  • Network env vars in the profile panel (#201). Proxy and bind-address knobs now live next to the rest of the user profile instead of buried in env panels.

Changed

  • Capability surfaces consolidated under the Tools tab (#208). Built-in tools, MCP servers, and connections each used to have their own top-level tab; they're now sub-tabs under one Tools surface.
  • MCP server management lives under Tools (#203). Setup step in the larger consolidation.
  • Connections folded back into Credentials (#204). Connections and credentials always referred to the same underlying rows; the split surface is gone.
  • Workspace mode as a segmented switch (#207). Replaces a single confusing toggle label with an explicit two-option switch.
  • Show-tools / show-thinking toggles and the test-notification button removed (#202). Dead UI dropped during the consolidation.
  • Model config, credentials, citations, icons, and chat perf polish (#194). Visual + interaction polish across the model picker, credential rows, in-message citations, lucide icons, and message-list re-render hot paths.

Fixed

  • Adaptive wall-clock watchdog with full entry-point parity (#209). The run-registry's idle and wall-clock watchdogs now wrap every agent run — not just HTTP chat, but triggers, watchers, bridges, the scheduler, the extension callback, and the delegate runner. The wall-clock now bounds agent + provider time only: time spent inside a tool call (exec, MCP, fetch) no longer counts against the agent's budget, so a slow tool can't force-stop a run that's otherwise making progress. Each tool already enforces its own per-call timeout.
  • Interrupted turns persist so the agent sees the cut (#206). Stopping a turn mid-stream now writes the partial assistant message with a clear interrupted marker, so the next turn doesn't replay the same prompt against a half-written history.
  • Scroll-to-latest button offset below glass header (#205). Button no longer hides behind the translucent app bar on tall threads.
  • Glass blur restored (#198). Reorders the backdrop-filter declarations so the blur layer paints in browsers that picked the wrong cascade order.
  • iOS standalone PWA viewport-height shim (#196). Patches the long-standing iOS Safari bug where 100vh in a home-screen app is taller than the actual visible viewport.
  • System theme: color-scheme: light dark (#195). Restores native form-control theming on macOS / iOS when the OS theme is set to follow the system.
  • Dependencies refreshed (#210). Lockfile-only npm update covering 99 in-range transitive bumps across @smithy/*, @aws-sdk/*, @langchain/*, and shared tooling.

Tests

  • fs-watch e2e spec skipped on non-macOS (#199). Removes a persistent CI flake on Linux runners where the watcher's wakeup latency exceeded the spec's budget.

[1.1.0] - 2026-06-07

Browser-extension UX is unified behind a single Alt+J action menu and two Gemini one-shot regressions are fixed.

Added

  • Unified Alt+J action menu in the browser extension (#192). Alt+J and the single context-menu entry now open a centered floating menu inside the page, so it works on hosts that hijack the native right-click (Outlook PWA, custom rich editors). The menu shows the captured selection preview plus rewrite preset chips (improve clarity, concise, formal, friendly, technical) when text is selected, and a collapsible custom-intent textarea. Selection inside a focused editable is rewritten in place via the same write path as fill; selection outside lands on the clipboard. Replaces the prior split Alt+J / Alt+Shift+J shortcuts and the rewrite-direction context submenu.

Fixed

  • Gemini one-shot turns (#192). The native Gemini adapter rejected fill / rewrite turns because the one-shot path emitted an empty messages array; it is now seeded with the system prompt.
  • Recall / facts leak into one-shot turns (#192). One-shot fill / rewrite turns no longer pull from the recall and facts memory stores, so prior fills cannot leak into later ones.
  • Selection capture across element-node containers (#192). Captures caret and range as text-offsets on a data-jarela-fill-target dataset attribute, measured via a synthetic range. Multi-paragraph selections in Gmail / Outlook now capture correctly instead of collapsing to zero, and the offsets survive framework reconciliation where a marker span would be stripped. Also removes an allFrames: true iframe-drilling race that caused the top frame to double-mark the iframe's editable.

Changed

  • Extension turn instruction cap raised from 2 000 to 16 000 chars (#192) so the unified fill prompt no longer trips a 400.
  • Tool capability re-classification. The Capability axis now reflects what a non-power user expects to see, not the HTTP method. Record edits (create / update / delete / add / move / upload / draft) are write regardless of whether they hit local SQLite or a remote API. execute is reserved for tools that perform an action beyond editing a record: arbitrary code (shell), server lifecycle (restart, env-var), generated artifacts (image, voice), agent delegation, workflow transitions (Jira / JA transitions), and PR merges. About fifty tools moved from execute to write across Atlassian, GitHub, Gmail, Outlook, Calendar, and Jira Align. ADR-0038 amended to drop the locality-based tie-breaker.

[1.0.0] - 2026-06-06

First stable release. The package surface is now formally locked, Anthropic prompt caching is enabled with cost-correct per-turn accounting, and agents can introspect their own toolbelt at runtime.

Breaking

  • ./* wildcard removed from package.json#exports. Consumers can now import only from the five paths in the explicit contract table (./lib/providers/types, ./lib/tools/types, ./lib/tools/registry, ./lib/mcp/registry, ./package.json). Anything else is internal and resolves to a Node ERR_PACKAGE_PATH_NOT_EXPORTED. ADR-0061 captured the planned lockdown; this is the cut. From this release forward, the deprecation policy in CONTRIBUTING.md applies: removing or breaking any public export bumps MAJOR.

Added

  • Anthropic prompt caching (#181). The Anthropic adapter now marks the system block, the tools block, and the most-recent tool result with cache_control: { type: "ephemeral" }. Cuts cost on multi-step ReAct turns where the same prefix repeats on every step. ADR-0062 documents the breakpoint placement.
  • Per-turn cost reflects Anthropic cache pricing (#183, #185). The message_usage table gained two nullable columns (cache_creation_input_tokens, cache_read_input_tokens). The agent loop reads them from the provider stream via LangChain's standard usage_metadata.input_token_details channel, persists them, and estimateCostUsd now prices them at 1.25× / 0.1× the input rate. The dashboard's totals are correct end-to-end.
  • Cache-hit indicator under each assistant turn (#187). The chat panel's per-turn usage bar shows a cache hit · Nk read · cache write · Mk chip when caching fires, with a Cache row in the expanded numeric details and full numbers in the bar tooltip.
  • MessageUsage.cache_creation_input_tokens / cache_read_input_tokens added to the wire contract type so external consumers of GET /api/v1/threads/<id> see the same shape the chat UI does.
  • Public API surface declared for the npm package (#182, ADR-0061). package.json#exports is the single source of truth for what's contractually public; the deprecation policy in CONTRIBUTING.md defines the change rules.
  • docs/EXTENDING.md — single integration guide covering all seven extension surfaces (built-in providers, external .cjs provider plugins, built-in tools, MCP servers, agent harnesses, integration manifests, brand overlays).
  • docs/api.md — HTTP API reference listing only the stable @public routes (health, threads, agents, tools, models, providers, events SSE, page-capture).
  • Four new agent-introspection tools (Config category, read capability): list_tools, list_providers + describe_provider, list_mcp_servers, describe_extension_surfaces. Lets an agent answer "what can I do" / "how do I add an X" without out-of-band docs.
  • Deprecation policy in CONTRIBUTING.md — public APIs get one minor version cycle of deprecation before removal; internals can change anytime.
  • JSDoc @public headers on the four contract type files (lib/providers/types.ts, lib/tools/types.ts, lib/tools/registry.ts, lib/mcp/registry.ts) and on the eleven public HTTP route files.

Changed

  • lib/tools/index.ts no longer snapshots the built-in tool list at module-load time. Replaces the ALL_BUILTINS / BUILTIN_TOOL_NAMES constants with live accessors so tool modules that import back from index (for getAllToolsAsync etc.) can register without falling out of the snapshot.
  • BUILTIN_TOOL_NAMES export replaced with getBuiltinToolNames() function. The two in-app callers (/api/v1/extensions routes) are updated.

Fixed

  • README "Extending" TOC link no longer points to a non-existent #extension-points anchor; it now links to docs/EXTENDING.md.
  • README "Add a built-in tool" walkthrough updated to the post-ADR-0038 three-arg registerTools(category, capability, [...]) signature (#184).

[0.14.0] - 2026-06-05

Mobile-focused polish release. iOS Safari PWA now correctly survives the on-screen keyboard after a research-backed simplification — see Francisco Moretti's writeup and the ios-pwa-keyboard-fix reference implementation — and the countdown ring animation is visible again.

Changed

  • iOS PWA viewport switched to 100dvh natively (#178). Replaces the useVisualViewportInsets JS hook, the --visual-vh / --kb-inset / --kb-scroll-offset CSS variables, and the body { position: fixed; inset: 0 } lock with the standard html, body { height: 100% } + h-[100dvh] pattern. The browser natively tracks the visible viewport including the OS keyboard on iOS 16.4+ and modern Chromium. Net -98 LOC.
  • interactiveWidget: "resizes-content" viewport meta (#174). Lets Chromium shrink the layout viewport when the OS keyboard appears, so 100dvh sits naturally above the keyboard.

Fixed

  • Countdown ring motion is obvious again (#172). The ring's motion was too subtle to register as a countdown.
  • Chat input visible when the iOS keyboard opens (#173, #175). Initial fix pinned the composer to the visual viewport; follow-up removed double- compensation that lifted the bar by 2× the keyboard height.
  • MessageList re-pins to the bottom on container resize (#176). When the on-screen keyboard shrinks AppShell via 100dvh without a React render, a ResizeObserver keeps the latest messages in view.
  • Shrink "chin" below the input bar on iPhone (#179). Bottom padding switched from calc(0.75rem + env(safe-area-inset-bottom)) to max(0.25rem, env(safe-area-inset-bottom)). Home-indicator and rounded-corner clearance preserved, ~12px of constant chin removed.

[0.13.0] - 2026-06-04

Follow-up release on top of 0.12.0 with anti-hallucination tooling, more direct send-bar controls, and watchdog/idle-loop fixes shaken out of real-world long-running tasks.

Added

  • Configurable anti-hallucination classifier. New per-agent classifier with off / report / enforce modes that catches fabricated tool results and assertion drift, surfaced via a model picker in the agent editor.
  • Explicit Steer / Queue / Interrupt actions on the send button (#165). Replaces the implicit "send during a turn = ???" behaviour with three unambiguous actions so a follow-up message can be steered into the running turn, queued for after it finishes, or used to interrupt.

Changed

  • Default timeouts and fetch byte cap raised for long-running tasks (#166). Operational defaults adjusted so a multi-step research / migration run no longer trips watchdogs or fetch caps that were sized for chat-shaped turns.

Fixed

  • Idle watchdog pauses while tool calls are in flight (#163, #164). A long exec/fetch no longer trips the "no progress" detector and cancels its own turn.
  • Wall-clock deadline on every built-in fs.* call. Read/write/ list operations now honour a hard deadline so a slow disk or a pathological glob cannot hang a turn indefinitely.
  • Stall detector catches mid-sentence "now" forms. Previously only matched sentence-final cues; now also flags I'll X ... now / I'm X ... now patterns that historically slipped through.
  • Watchdog timeouts surface as visible errors instead of silent hangs. Failed turns now emit an explicit error event so the UI can show what happened rather than appearing to stall.

[0.12.0] - 2026-06-04

This release line is rebuilt onto the v0.9.0 base via a selective replay of the v0.10.0 line, then layers in the user-facing parts of v0.11.x and a focused set of new features. The deeper 0.11.x agent-loop refactor (#129–#145, #151–#152, #157) is deliberately not included.

Added

  • Per-channel warm summary store (ADR-0044). New thread_channel_summaries table keyed by (thread_id, channel) so a thread shared across chat / scheduled_task / watcher / bridge channels stops blending automation history into interactive turns. Storage layer only — prompt-assembly wiring follows.
  • Live server-log panel (ADR-0058). In-app filterable scrollback over a 2000-entry ring with idempotent console patch + redaction of Authorization / api_key / sk-… / ghp_… tokens, exposed via /api/v1/logs SSE with replay. Mounts as an Advanced tab.
  • Runtime env overrides (ADR-0060). ~40 JARELA_* operational knobs centralised behind a single schema driving the typed config snapshot, per-deployment overrides at {dataDir}/env-overrides.json, REST surface, agent tools (set_env_var, restart_server), and a new EnvVarsPanel UI.
  • Anti-hallucination stall-retry detector. Catches three failure modes in one pass: same (tool, args) signature recurring ≥3× in a turn (ReAct loop), promised-write stalls (model called read-only tools then ended on writing X now / saving the file now), and the original zero-tool stall path. New _skip_persist_message + _inject_message_into_history flags keep the auto-retry nudge in front of the LLM but out of persisted history.
  • Model catalog browse accepts in-form credentials, allowlist removed. POST /providers/:p/models accepts { params } overrides so a freshly-typed api_key / base_url works before the user has clicked Save. Hardcoded CATALOG_PROVIDERS allowlist gone.

Changed

  • Per-model context-tier UI removed from ModelEditor. Per-agent override (ADR-0043) already supersedes the model-level value at run time, so the knob was duplicate UX. Payload-building lifted into lib/models/editor-payload.ts with 15 unit tests including a round-trip through upsertModelConfig.

Fixed

  • SSE connect timeout configurable. Replaces the hardcoded 8s with JARELA_SSE_CONNECT_TIMEOUT_MS (default 30s, surfaced via the runtime config layer to the browser). Plus plain-English wording for the user-facing toast (was Error: EventSource connect timeout, now Connection timed out — the server didn't respond within Ns.).
  • request() helper respects httpRequestTimeoutMs and httpMaxAttempts. Both knobs were defined in the runtime config schema with descriptions naming this code path but were never read.
  • OpenAI-compat adapters emit stream usage events. (0.11.0 backport.) Both lib/providers/openai.ts and lib/providers/github-copilot.ts send stream_options: { include_usage: true } and yield a usage chunk; ADR-0041 token accounting reflects real provider counts instead of content-length estimates.
  • Drop orphaned checkpoint rows on thread delete. (0.11.1 backport.) DELETE /api/v1/threads/{id} now calls getCheckpointer().deleteThread(id) so deleted threads' LangGraph rows are reclaimed instead of growing monotonically.
  • Pricing lookup handles aggregator-namespaced model ids. (0.11.2 backport.) Models exposed by aggregators (OpenRouter, LiteLLM) with a vendor/model prefix now resolve via the bare suffix; the github-copilot upstream-inference path strips the prefix too.
  • Hardcoded known-rates fallback for canonical model ids. (0.11.3 backport.) New lib/stores/known-rates.ts consulted as a 4th tier after the snapshot lookups so dashboard cost columns no longer go blank when the live extractor loses data. Snapshot still wins when present.

[0.10.0] - 2026-06-02

Added

  • Stacked per-tier token + cost breakdown in the dashboard chart (#119). The unified chart now stacks system / history / live / output segments and surfaces a data-quality chip so operators can spot tiers that fell back to estimation.
  • JARELA_TOOL_SAFETY tiers for exec + file ops (#121). Adds a capability-flagged safety ladder so risky tools (shell exec, file writes) can be gated independently per deployment.
  • Idle-progress watchdog in the run-registry (#123). Force- finishes runs that stop emitting progress for JARELA_RUN_IDLE_MS, complementing the existing wall-clock watchdog.
  • System prompt now nudges the agent about indexed documents (#125). When the workspace has documents indexed, the prompt mentions the documents_search tool so agents recall RAG before answering from parametric memory.
  • Trigger-originated chat messages now render as metadata cards (#127). Scheduled tasks (ADR-0032) and watchers (ADR-0027) get a Clock / Eye header, a tool-name pill, a silent pill when the firing was silent, and a collapsible "Change context" section for watcher diffs. Falls back to plain rendering if the prompt text doesn't parse cleanly.

Fixed

  • Collapse tool-permission categories by default in the agent editor (#118) so the panel doesn't open with a wall of toggles.
  • Clear stuck "reconnecting…" state when reattach returns 404 (#120).
  • Guarantee finishRun + add watchdog for leaked runs (#122) so abandoned runs can't keep the registry marked running forever.
  • Harden SSE run subscription against hung streaming gate (#124).
  • Stabilise two pre-existing e2e flakes (#126). The context-bar legend test now scopes its locator by [data-message-id] so parallel sibling tests can't cross-pollute, and the profile test uses page.goto("/?tab=profile") instead of page.reload() to deflake mobile-safari.

[0.9.3] - 2026-06-01

Changed

  • Threads GET serializer extracted into lib/api/serializers.ts. The per-message usage and context_window_tokens shaping that the ContextUsageBar consumes was inlined in the route, untestable, and prone to drift. The route now delegates to messageToResponse / messageUsageToResponse / resolveContextWindowTokens, each with unit coverage in lib/api/serializers.test.ts. No wire contract change.

Fixed

  • delegate_to_agent test signature updated for the new contextSnapshot argument added to persistAssistantMessage in #112 (lib/tools/delegate.test.ts).

[0.9.2] - 2026-06-01

Changed

  • iOS standalone PWA now follows the active theme in the status bar. Switched apple-mobile-web-app-status-bar-style to black-translucent and declared apple-mobile-web-app-capable, so the iOS status bar overlays the AppShell header (already padded with env(safe-area-inset-top) via --app-safe-top) and inherits the current light / dark surface color instead of forcing a static black or white bar. Safari ignores the manifest's theme_color once an app is installed to the home screen, so this is the only knob iOS actually respects (app/layout.tsx).

[0.9.1] - 2026-06-01

Fixed

  • Per-turn context-usage bar now actually persists. message_usage.cost_usd is NOT NULL in the schema, so snapshot-only inserts (provider didn't report token usage) were silently rejected and the bar never rendered. Default the fallback cost to 0 so the row lands (lib/agents/run-thread.ts, lib/stores/message-usage.ts).
  • Last assistant bubble no longer auto-collapses mid-read. The streaming bubble and the persisted bubble are two different React instances (key={msg.id} remounts when the stream finalises), so the streaming-aware “keep open” latch never carried over. MessageList now passes isLatest to the last visible message and CollapsibleLong treats it as defaultOpen (components/chat/MessageBubble.tsx, components/chat/MessageList.tsx).
  • dashboard-metrics snapshot gate no longer suppresses content-length cost estimates for rows whose snapshot has input_tokens = 0 (lib/stores/dashboard-metrics.ts).

Changed

  • Context-usage bar visuals. Bar is now a 3px strip flush along the assistant bubble’s bottom edge, clipped by the bubble’s rounded corners — no more floating pill below the message. Every segment (Hot / Warm / Facts / Overhead slots, reservation tail, footer) carries a native tooltip explaining how to read it (components/chat/ContextUsageBar.tsx, components/chat/MessageBubble.tsx).
  • Next 16 webpack tracing aliases instrumentation-node.ts to false for non-Node targets and adds libsignal to serverExternalPackages so the baileys / MCP / sharp graph stops leaking into edge and browser bundles (next.config.ts).

[0.9.0] - 2026-06-01

Added

  • Immutable per-message LLM usage telemetry (ADR-0041). Each assistant turn now snapshots its real provider-reported input / output tokens, the provider + model + agent + model-config name in effect, AND the pricing rates used to compute its $ cost into a new message_usage table. The dashboard prefers the snapshot when present, so reassigning an agent's model, renaming a model config, or refreshing the pricing snapshot no longer rewrites historical cost figures. Pre-existing messages without a snapshot keep using the content-length estimate as before (docs/adr/0041-immutable-message-usage.md, lib/stores/message-usage.ts, lib/stores/pricing.ts, lib/stores/dashboard-metrics.ts).
  • Clickable token-usage bars. Bars on the “Token usage over time” chart now filter the dashboard breakdown to that day, the same as the cost timeline. Click the same bar (or the cost-chart clear pill) to restore the window view (components/dashboard/DashboardPanel.tsx).

[0.8.2] - 2026-05-31

Added

  • Dashboard day drill-down. Click any day on the “Estimated cost over time” chart to narrow the agent / vendor / model breakdown pies, the headline metric cards, and the message-count details to that day only. Click the same point or the “clear” pill to restore the window view; changing the time window resets the selection. The selected point gets a larger dot, a pulsing halo and a vertical guide; the line and slice animations replay on selection change so the eye can re-anchor on the new context. Per-day breakdowns are computed server-side (breakdowns_by_day on DashboardMetrics) so the picker is instant (components/dashboard/DashboardPanel.tsx, lib/stores/dashboard-metrics.ts).

Fixed

  • Bridge counterpart replies now speak in the user’s voice. When an agent answers an inbound bridge message from the user’s counterpart (1:1 or group), the prompt now instructs the agent to respond on the user’s behalf in their voice, following the agent’s persona and instructions, instead of introducing itself as an assistant (lib/bridges/message-role.ts).

Changed

  • Silent-mode framing folded into the bridge prompt envelope. Silent / observer routes used to have a separate [SILENT_BRIDGE] directive appended after the per-role framing, which could contradict the role note (e.g. “respond on the user’s behalf” vs. “never write to the chat”). Silent is now a first-class flag on formatBridgePrompt; when set, the observer-mode note replaces the per-role note so the agent sees exactly one framing sentence (lib/bridges/message-role.ts, lib/bridges/dispatcher.ts).

[0.8.1] - 2026-05-31

Added

  • Live action text in app header. A small label next to the agent picker shows what the active agent is doing in real time — Sending… on submit, Thinking… on reasoning deltas, Using <tool>… while a tool runs, Responding… when text streams back — and clears on done/error/stop. Replaces the indeterminate top progress strip (components/ui/HeaderActivity.tsx, lib/ui/loading.ts, hooks/useSSE.ts).
  • Active agent identity in app header. The header now displays the active agent's icon and name next to the picker, falling back to the app mark when no agent is selected (components/layout/AppShell.tsx).
  • PWA title-bar theming. Desktop PWA window chrome and mobile browser address bars match the active color theme (app/layout.tsx).

Fixed

  • Playwright e2e specs aligned with the advanced-mode gating and menu reorganization introduced in 0.8.0.

[0.8.0] - 2026-05-31

Added

  • Usage & cost analytics dashboard. New top-level Dashboard panel (components/dashboard/DashboardPanel.tsx) with token/cost overtime charts, segmented sortable pricing and tool views, per-model and per-function breakdowns, an interactive donut chart for category share, and animated pie/timeline rerenders. Helpers live in lib/dashboard/ with full unit-test coverage.
  • Guided onboarding wizard (components/setup/OnboardingWizard.tsx) with an inline mode picker (Normal / Advanced) and per-provider capability guidance so first-time users land on a working setup quickly.
  • Normal vs. Advanced experience modes. Centralized mode toggle pill (components/layout/MenuPanel.tsx), default to Normal mode, mode-aware panel layouts, agent normal-mode permission buckets, and an expert toggle inside the model editor.
  • Live pricing extraction (lib/pricing/) with an LLM-based rate extractor, extraction policy + confidence metadata, Google-search fallback when provider pages fail, preference for provider-model rates in cost estimates, and a refreshable provider pricing snapshot (docs/journal/pricing-snapshot.json).
  • Currency-aware cost display. Dashboard converts costs to the user's local currency with an Auto/Manual override picker.
  • Humanized cron schedules on the Scheduled Tasks panel (lib/utils/cron.ts) — e.g. 0 9 * * 1-5 renders as "weekdays at 09:00" next to the raw expression.
  • Per-sub connection counts (e.g. "4/7") on the Connections panel.

Changed

  • Connections tab promoted to Common, Bridges deferred to Advanced; the Memory tab now lives behind the Advanced disclosure to reduce first-run cognitive load.
  • Centralized model feature-compatibility cues (components/models/CapBadges.tsx) with descriptive tooltips on every capability icon.
  • Centralized system feature-readiness indicators across surfaces so the same readiness signal renders identically in the model picker, agent editor, and onboarding wizard.
  • Dashboard panel polish: sticky controls bar pinned to the scrollport with a glass effect, mask on header, donut strokes use var(--border), cleaner pricing accents using var(--accent), and consistent control ergonomics across all dashboard surfaces.
  • Agent/model row actions fade in at 40% opacity by default and reach full opacity on hover/focus so they are discoverable on desktop without scanning the row first.

Fixed

  • Production boot regression (instrumentation.ts + instrumentation-node.ts). Node-only imports (lifecycle/shutdown, tools, triggers, scheduler, exposed-bind warning) are now loaded via dynamic await import() only when NEXT_RUNTIME === "nodejs", fixing a 500-at-boot regression where ESM require was undefined.
  • Dev-mode service worker no longer eager-bootstraps the server or serves stale chunks.
  • Setup wizard is now gated behind first-run and no longer reappears after profile completion.
  • Profile location display — collapsed double-encoded UTF-8 bytes (· / ±) back to proper · / ±.
  • Light-mode crypto fallback banner contrast restored.
  • Dashboard fixes: sticky controls glass effect, hover-induced control resizing, model attribution fallbacks, token chart input/output contrast, favorite-tools and model sort options rendering reliably, aliased models mapping to pricing rates, small-window cost visibility preserved, donut overlap removed.
  • Pricing parsers correctly detect DeepSeek unit-first token prices and Anthropic MTok rates.
  • Agent context handling: prefix-based permission mapping enforced; hot-context truncation on warm fallback miss.

Refactored

  • Pure dashboard helpers extracted into lib/dashboard/ with unit tests.
  • Mode-aware UI polish unified across panels; border noise reduced on inner elements.
  • New shared helpers consolidate widespread duplication: hooks/useEscapeKey.ts replaces the hand-rolled keydown listener in 5 modal editors; lib/api/sse.ts centralises Server-Sent Event response headers; six API routes adopt validateBody() / errorResponse() / notFoundResponse() from lib/api/responses.ts in place of inline req.json() + safeParse boilerplate.

[0.7.3] - 2026-05-30

Changed

  • Configuration UI copy clarity improved across bridge routes, watcher reactions, and scheduled-task reactions so option purpose and mode differences are visible inline without relying on hover-only hints.
  • README onboarding flow reorganized with Quick start moved to the top and a practical home/work configuration guide that includes tool-chain recipes for common goals.

[0.7.2] - 2026-05-30

Added

  • First-launch client chunk optimization preflight. Added scripts/optimize-client-chunks.mjs and integrated it into startup so npm-installed runs can ship scanner-friendly readable bundles while optimizing static client chunks locally once on first launch. Controlled by JARELA_PREFLIGHT_OPTIMIZE_CLIENT and JARELA_FORCE_PREFLIGHT_OPTIMIZE.

[0.7.1] - 2026-05-30

Changed

  • Release npm tarballs now ship readable browser chunks. next.config.ts adds an opt-in JARELA_DISABLE_CLIENT_MINIFICATION=1 mode and release workflow enables it for npm publish builds, reducing false-positive obfuscation/minified-code alerts from supply-chain scanners.
  • Runtime dependency surface reduced. Moved TypeScript and @types/* packages from runtime dependencies to devDependencies in package.json, trimming non-runtime packages from the published dependency graph.

[0.7.0] - 2026-05-30

Added

  • Post-turn output validator for safer agent responses (ADR-0037). Adds a policy-driven validation pass after each agent turn with configurable actions for block, warn, and transform paths, plus persistence-backed controls for validator behavior.

[0.6.5] - 2026-05-29

Added

  • Per-route reply trigger for bridges (respond_to). Bridge routes now carry an explicit respond_to setting ("counterpart" (default) or "user") controlling which inbound sender role unlocks an outbound reply. The agent always runs on every inbound message so it sees the full conversation context — only the reply is gated. silent_mode remains the master switch (hardwired in the WhatsApp adapter's own sendText / sendTyping) and overrides respond_to. Migration adds the column with a back-compat default that preserves existing behaviour.
  • Cross-adapter sender-role framing. New MessageRole type and lib/bridges/message-role.ts helper give the agent an explicit framing per inbound message (paired user / counterpart / group member / agent). The dispatcher prepends a one-line prose framing plus a [message_role:<role>] tag so the LLM no longer reads every inbound chunk as a direct command. Future adapters (Telegram, Slack, Discord, mail) just populate InboundMessage.role and inherit the behaviour.
  • Bridge editor reply-trigger control. New per-route select in components/bridges/BridgeEditor.tsx with chat-type-aware labels and explanatory subtext; greys out when silent_mode is on.

Fixed

  • Streamed thinking line stays visible after the turn finishes. The amber 'thinking…' panel was unmounting on stream done, yanking it out from under a user mid-read. hooks/useSSE.ts now keeps the buffered thinking content until the next start() / attach(), and components/chat/ChatView.tsx passes it to MessageList whenever non-empty rather than only while streaming.

[0.6.4] - 2026-05-29

Fixed

  • Release workflow build failure with optional Baileys fallback. lib/bridges/whatsapp.ts now resolves the legacy unscoped baileys fallback via runtime createRequire(...) instead of a literal dynamic import, so Next/TypeScript no longer attempt to resolve an uninstalled optional package during CI next build.

[0.6.3] - 2026-05-29

Changed

  • Lint output made actionable again. React-Compiler advisory warnings and stale eslint-disable directives were cleaned up, and components/integrations/NetworkSection.tsx was updated to satisfy hook dependency analysis.

Fixed

  • WhatsApp self-chat context forwarding improved without bot loops. lib/bridges/whatsapp.ts now forwards user-authored fromMe replies so agents get full local conversation context, while still suppressing bridge-authored echoes via sent-message ID tracking.

[0.6.2] - 2026-05-29

Changed

  • Baileys dependency hardened and compatibility-preserved. WhatsApp bridge dependency moved from unscoped baileys to @whiskeysockets/baileys in package.json, while lib/bridges/whatsapp.ts now prefers the scoped import with a fallback to the legacy package name for older installs.
  • Standalone external package allowlist updated. next.config.ts now externalizes both scoped and legacy Baileys package names to keep standalone tracing and runtime resolution stable during migration.
  • Build-only PWA dependencies moved out of production runtime deps. @serwist/next and serwist were moved to devDependencies, reducing production dependency surface for installs that consume the published bundle.

Fixed

  • Cross-platform file-list tests stabilized on Windows. lib/tools/files.test.ts now uses path.basename(...) instead of slash-splitting paths, making assertions robust across path separators.
  • fs-watch skip-dir filtering normalized across separators. lib/triggers/handlers/fs-watch.ts now splits event filenames on both / and \\, ensuring skip-dir and dot-dir filters work on Windows and POSIX-style watcher payloads.
  • Crypto tamper test made deterministic. lib/crypto/envelope.test.ts now mutates decoded bytes before re-encoding, avoiding base64url edge cases where string-level edits did not always alter authenticated payload bytes.

[0.6.1] - 2026-05-29

Changed

  • Supply-chain hardening for standalone server bundles. Server production minification is now disabled and server source maps are enabled in next.config.ts, reducing obfuscation-style scanner noise in generated route.js/chunk artifacts while preserving runtime behavior.
  • Standalone dependency externalization expanded. undici is now included in serverExternalPackages so Next's standalone output avoids rebundling a large minified HTTP client chunk family that previously triggered false-positive obfuscation alerts.
  • OpenAI-compatible and agent route internals refactored. Shared parsing and mapping logic was deduplicated across providers and API handlers to reduce drift risk and tighten maintenance on security-sensitive request/response code.

Added

  • link-preview-js version gate via scripts/check-link-preview-version.mjs and npm script security:link-preview, enforcing the patched CVE floor (>= 4.0.1) whenever the package appears in the lockfile.
  • Route bundle security attestation via scripts/check-route-bundles.mjs and npm script security:routes, checking generated standalone API route bundles for extreme line-length obfuscation signatures, dangerous invocation patterns, and missing source maps.
  • Shared tool test harness in lib/tools/test-helpers.ts, eliminating duplicate fetch/env scaffolding across Atlassian/Jira Align suites.

Fixed

  • WhatsApp bridge outbound SSRF risk surface reduced. Outbound message send calls in lib/bridges/whatsapp.ts now explicitly disable Baileys URL preview resolution (getUrlInfo: undefined), preventing link-preview fetch paths from executing during normal text sends.
  • Security CI ordering corrected. The pre-build security:ci gate now runs only checks that do not depend on build artifacts, while security:routes runs post-build in ci workflow, keeping the gate strict and deterministic in clean CI environments.

[0.6.0] - 2026-05-28

Changed

  • License switched from MIT to Apache-2.0. Aligns the project with the Apache-2.0 patent grant and contributor terms; users redistributing Jarela should review the new LICENSE and NOTICE requirements.
  • LangGraph checkpointer now uses node:sqlite instead of better-sqlite3 (ADR-0034). In-tree NodeSqliteSaver replaces @langchain/langgraph-checkpoint-sqlite. Schema is unchanged so existing ~/.jarela/checkpoints.db files keep working without migration. This drops the EOL prebuild-install transitive dependency and removes one native module from the standalone bundle.
  • Native-module dependencies trimmed. keytar was replaced by @napi-rs/keyring and react-syntax-highlighter by rehype-highlight, removing two more native build steps from the install path. p-timeout is now pinned to drop the unused p-finally transitive.
  • Chat scroll-to-latest button moved from the bottom-right corner to the top-center of the messages pane so it doesn't overlap the composer or follow-up suggestions on narrow viewports.
  • Optimistic user bubble is now dropped as soon as the persisted row arrives over the SSE stream, eliminating the brief duplicate that appeared on slow networks.

Added

  • Agent-driven harness edits via the approval flow (ADR-0036). Two new propose_config_change kinds — upsert_harness (create/edit a custom harness preset) and an extended update_agent that accepts harness_id — let the agent itself propose harness changes. Built-in harnesses (builtin:*) stay read-only and the global default pointer remains UI-only. Approval-time validation rejects unknown harness ids and built-in writes before they touch storage. The ApprovalsBanner toast now deep-links to ?tab=harness&item=<id> for the freshly created or edited row.
  • Configurable harness presets (ADR-0033). The five hard-coded harness modules (capabilities, plan_first, presentation, citation, self_config) wrapped around every agent turn are now first-class config: a global default pointer plus per-agent overrides, with built-in presets and user-authored custom presets surfaced in a new Harness settings tab. Existing agents keep the previous behaviour by inheriting the default builtin:default preset.
  • Comprehensive Atlassian + Jira Align coverage (ADR-0035). Adds full Jira Agile coverage (sprints: create / start / complete, move issues, rank backlog), worklogs read+add, attachment download and delete, issue history/changelog, project metadata (projects, versions, components, issue-types, priorities, statuses, version release lifecycle), Confluence v2 holes (label CRUD, content versions, ancestor walks), and broader Jira Align surface. Routes through the same proxy + custom CA bundle as the existing tools.
  • Script-backed reactions and silent muting (ADR-0030 / ADR-0031 / ADR-0032). Watchers now accept a user-defined reaction prompt per watcher (replacing the hardcoded "summarise what changed" directive), and both watchers and scheduled tasks can choose a script reaction kind that runs an in-process function with no LLM round-trip — useful for notify/log/append-to-memory reactions where the user already knows the action. A silent-mute flag suppresses the user-facing notification while still firing the reaction.
  • Mail as a configurable indexing source. Mail sources (Gmail / Outlook) are now configurable from the Documents panel like other remote sources, including watermark-based incremental sync.
  • Provider and chat UX expansion. Additional LLM/integration providers and chat controls land in the Connections + chat panes (model picker affordances, integration card refinements).
  • Inline source attribution is now mandated in the harness's citation section so the agent emits [ref:…] markers next to every factual claim, reducing hallucination and giving the UI a hook for future click-through.
  • Error-report toast. Browser errors that bubble up to the top-level handler now surface as an opt-in toast linking to the bug report URL (NEXT_PUBLIC_APP_ISSUE_URL), so forks see their own issue tracker and upstream users see CircuitWall's.
  • Confluence tool surface expanded with v2 + v1-fallback coverage for spaces, pages, comments, and labels.
  • Anthropic integration card + customizable env-sync allowlist (ADR-0034). The Integrations panel now has a Claude card so the Anthropic API key can live in the encrypted store like every other credential, and the Anthropic provider's fallback chain reads it before process.env.ANTHROPIC_API_KEY. Env-sync's default allowlist now includes ANTHROPIC_API_KEY. Users can also add per-(integration, field) env-var name aliases via a new "Aliases" editor in the panel (or PUT /api/v1/env-sync/allowlist) — useful when dotfiles use non-canonical names like MY_GH_PAT. Defaults always remain; overrides are additive.
  • Subprocess credential injection. local_exec shells and stdio MCP children now receive every env-sync-managed credential the encrypted store has, layered between process.env and the explicit per-call / per-server env override. Service-mode installs (launchd, systemd, brew services) where the launching environment was empty now expose the same ANTHROPIC_API_KEY / GITHUB_TOKEN / ATLASSIAN_* / GOOGLE_API_KEY to subprocesses that the agent itself uses. Per-call env (for exec) and per-server spec.env (for MCP) still win and can be set to empty string to unset.

  • Documents tooling parity for local sources: added documents_add_local_source(path, label?) so agents can create local folder sources directly (with path existence/directory validation), not only remote Jira/Confluence/GitHub sources. This closes the previous gap where local folders had to be added manually in the Documents UI.

  • Configurable app branding — three new NEXT_PUBLIC_* env vars let forks rebrand the user-visible name, description, and bug-report URL without patching source. Defaults preserve the upstream "Jarela" branding exactly:

  • NEXT_PUBLIC_APP_NAME (default Jarela) — browser tab title, sidebar header, app-shell logo title, welcome screen, and the agent's own system prompt (so the LLM stops echoing "Jarela" when running in a rebranded fork).
  • NEXT_PUBLIC_APP_DESCRIPTION (default "Jarela — local chat interface for LangGraph agents") — <meta name="description">.
  • NEXT_PUBLIC_APP_ISSUE_URL (default https://github.com/CircuitWall/jarela/issues/new) — the Report-a-bug toast target. Surfaced via a new lib/env/app-config.ts helper module (client-safe) and exposed on the cached getConfig() object as appName, appDescription, and issueUrl.
  • GitHub as a document-RAG source (ADR-0029): GitHub joins Jira and Confluence as a remote document source, so the same documents_search tool now retrieves across PRs, issues, and repo files. Two new source kinds, both surfaced in the Documents panel and the documents_add_remote_source tool:
  • github_pulls — index every PR of one repo (title + body + issue comments + review bodies) as one document per PR. Configurable state (open/closed/all) and recency_days. Watermark is max(updated_at) so re-runs are incremental.
  • github_repo — index text files on one branch of one repo via the Git Trees API. Filtered by the same extension allowlist + binary heuristic as the local-folder walker. Watermark is the tree SHA, so quiet repos cost a single API call per scheduler tick. documents_index_url now also recognises /pull/<n>, /issues/<n>, and /blob/<ref>/<path> URLs and stores the result under the same shared on-demand source as Jira/Confluence URL captures.
  • GitHub tools — full read/write surface: the GitHub integration grew from 7 tools to 19, so the agent no longer has to fall back to the gh CLI for the common write workflows (which is the whole reason these tools exist on locked-down corp laptops). New tools cover:
  • Issues: github_update_issue (close / reopen / edit / re-label), github_list_issue_comments.
  • Pull requests: github_create_pull, github_update_pull, github_merge_pull (merge / squash / rebase, optional sha guard against force-pushes), github_request_reviewers, github_create_review (approve / request changes / comment), github_list_pull_files (with truncated patches), github_list_pull_reviews.
  • Repo content: github_list_branches, github_get_file (UTF-8 decode
    • binary detection + 20 KB cap), github_search_code (with code snippets via text-match Accept header). All tools route through the same ghFetch wrapper as before, so the in-app HTTP proxy and custom CA bundle continue to apply.

[0.5.1] - 2026-05-27

Changed

  • Docs: refreshed the current-facing install and UI docs to match the shipped product. README / INSTALL / ARCHITECTURE now reflect the Connections tab rename, the split between Connections and Tools, Next.js 16, the platform-specific Windows data dir, and the scoped npm package name @circuitwall/jarela for install / update / uninstall commands.
  • npm distribution: the published package now includes a prebuilt .next/standalone bundle so npm install -g @circuitwall/jarela starts immediately instead of trying to compile inside node_modules.

Fixed

  • Windows task runner: make install now passes npm arguments reliably. The PowerShell helper no longer collides with the automatic $args variable, so Invoke-Npm actually runs npm install / npm run … instead of invoking bare npm with an empty argument list.
  • npm-installed startup: jarela start no longer attempts a Next build from a global node_modules path. If a packaged standalone bundle is missing, the CLI now fails fast with a clear packaging error instead of falling into an unrecoverable webpack parse failure.

[0.5.0] - 2026-05-26

Added

  • Documents — remote sources (Jira & Confluence): alongside local folders, the Documents tab now indexes Atlassian content directly. Pick a kind (Confluence space, Confluence CQL, Jira project, Jira JQL), supply the key/query, and the existing scheduler chunks + embeds the matching pages/issues into the same documents_search surface as local files. Auth reuses the Atlassian Connections entry — no second credential prompt. See ADR-0026.
  • Documents — folder picker: the local-folder source form now uses a native directory picker instead of a free-text path field, so the user no longer has to type /Users/… paths or remember escaping rules.
  • Documents — watcher-driven re-indexing: local sources now re-index in ~1 s after a file change instead of waiting for the 10-minute sweep, via fs.watch with a 500 ms debounce. Atlassian remote sources poll on a 60 s fast-sweep cadence. Built on a new scripted-trigger primitive (the trigger abstraction now fires either agent prompts or in-process scripts; deletions and missed events are still backstopped by the existing 10-min full sweep). See ADR-0027 and ADR-0028.
  • Watcher tasks: event-driven companion to scheduled tasks. A watcher polls a single built-in tool every N seconds and only invokes the agent when the tool's output changes since the previous poll — useful for "ping me when this PR list changes" without cron-style polling churn. Watcher firings are tagged category="watcher" so they're filterable in the chat-panel toolbar. See ADR-0027.
  • Chat filter — watcher channel: the chat-panel category toolbar now exposes a watcher chip alongside scheduled, bridge, and captures, so the operator can hide watcher-fired messages without affecting other automation.
  • Connections tab: a single home for every auth surface. The old "Credentials" tab is renamed to "Connections" and gains a sub-tab for MCP server credentials, which previously lived under Tools. Result: one mental model — Connections for "what accounts has this been given access to", Tools for "what can the agent do". Deep links update: ?tab=integrations becomes ?tab=connections (the in-app proposal banners are auto-rewritten; external bookmarks to the old slug stop resolving).
  • Built-in tool toggles: a new "Built-in" sub-tab under Tools lets the operator enable or disable whole categories of shipped tools (Memory, Files, Web, Shell, Mail, Calendar, …). Disabled categories disappear from the agent permission editor AND are blocked from invocation at runtime, so an older agent that still has them in its allow-list cannot reach them. Default-enabled semantics: existing installs see no change. First step of the Connections consolidation (see follow-up stages).
  • Documents: index any folder on disk for semantic recall. The new Documents tab lets the user point Jarela at one or more folders; text files (markdown, code, configs, plain text) are chunked, embedded with the configured model, and surfaced to agents via the documents_search tool. Reindex runs automatically every ~10 minutes from the scheduler; the panel offers per-source Reindex now, enable/disable, and a preview-search input. Embedding failures gracefully degrade to substring matching so installations without an embedding provider still get useful results. See ADR-0024.
  • External tools: encrypted secret slots. Tools loaded from ~/.jarela/tools/ may declare a secrets: [{ key, label?, required?, description? }] array; values are persisted in the tool-secrets memory namespace, AES-256-GCM enveloped at rest like the integrations store, and surfaced to the tool at run time via ctx.getSecret(key). The Extensions panel renders an "Edit" form per tool with the standard masked sentinel pattern (plaintext never reaches the client). See ADR-0023.

Changed

  • Trigger abstraction: scheduled tasks and the new watcher tasks now share a single TriggerHandler interface, and a generic change_tracker store records the "last seen" hash that watchers diff against. Pure refactor — no behavioural change for existing scheduled tasks. Lays the groundwork for additional trigger kinds (file-system, webhook, MQTT). See ADR-0025.

Fixed

  • E2E: the watcher e2e is now skipped on Linux runners — Node's recursive fs.watch is unsupported there and the spec relied on it. CI is green again on the GitHub-hosted Linux matrix; macOS / Windows still exercise the full watcher path.

Internal

  • Lint: ESLint now enforces the node: prefix on every Node builtin import (fs, path, crypto, …) and the codebase has been migrated. Required for Next.js's edge-runtime path resolution; the no-restricted-imports rule prevents regressions.

Breaking changes (#39, pre-1.0 → MINOR per CONTRIBUTING.md)

  • The ?tab=integrations deep link is removed in favour of ?tab=connections. In-app proposal banners are auto-rewritten; external bookmarks to the old slug stop resolving.
  • The tools category for MCP-server credentials moves under Connections → MCP. Any external tooling that screen-scraped the Tools tab for MCP credential UI will need to follow the new path.

[0.4.0] - 2026-05-25

Added

  • Browser extension: configurable Jarela endpoint. The extension options page now exposes the scheme (http/https), host, and port the popup launches into, so users running Jarela on a custom port (or behind a Tailscale-Serve hostname) no longer have to live with the hardcoded http://127.0.0.1:4312. Clicking the extension icon when Jarela isn't reachable opens the options page instead of silently failing. When the page is reachable, the extension prefers launching the installed PWA over a normal tab (#28).
  • Jira tool: jira_get_issue now accepts an include_comments flag so the agent can pull issue conversation history in one call without a follow-up jira_get_comments round trip (#32).
  • Profile: persona preset (Home / Work / Developer / Everything). The picker lives in the Profile editor and drives a new category filter on the Credentials panel so first-run users aren't faced with eight unrelated integration cards. Existing installs keep today's "show everything" behaviour until they pick a preset. Schema: user_profile.preset TEXT NULL (auto-migrated; NULL = no filter).
  • Tools: new top-level menu entry that bundles MCP servers and Browser extensions behind a single nav label with inline sub-tabs. Cuts the menu from 10 entries to 9 and clusters the two "extend what the agent can do" surfaces together.
  • Credentials: each integration definition now exposes a category (llm | mail | calendar | issue-tracker | chat | infrastructure | other) over the API. Already-configured credentials are never hidden by the persona filter even when their category is outside the active preset.
  • Memory panel: list items now render a typed, compact summary of each entry instead of a single-line JSON.stringify. Objects show the first few key: value chips with a "+N more" tail; arrays show their length and first elements; multi-line strings get a small scrollable <pre>. A chevron toggles a pretty-printed expansion of the full value. Token-shaped fields (*_token, *_secret, api_key, password, …) are masked at every nesting level, so glancing at the panel can't leak credentials.

Changed

  • Menu: the agent menu is now split into a top "common" row (Chat, Agents, Memory, Tasks, Bridges, Profile) and a collapsible "Advanced" section (Credentials, Models, Tools). The collapsed state is persisted in localStorage (jarela.menu.advanced) and auto-opens when navigating into an Advanced tab via deep-link.

Fixed

  • Chat (mobile): the "Play voice" button on assistant bubbles is now visible on touch devices. It was gated behind group-hover:opacity-100 with no fallback, so iOS Safari and the installed PWA rendered it invisibly. Same fix applied to the row- action toolbars in the MCP, Memory, Models, and Sidebar panels, plus the toast dismiss button (#33, #34).
  • Chat: stopping a streaming run now restores the input bar cleanly. Previously the Stop button could leave the UI in a half- streaming state where Send was disabled until the next refetch (#31).
  • Build: regenerated package-lock.json against the public npm registry. A previous lockfile regeneration was done on a machine with a private mirror configured, leaking 84 internal-only resolved URLs into the lockfile and breaking CI / Docker builds for anyone without access to that mirror (Cannot find module '../lightningcss.linux-x64-gnu.node' during next build) (#29).

Build

  • Project now ships a committed .npmrc that pins https://registry.npmjs.org/ so contributors with a private mirror in ~/.npmrc no longer leak internal URLs into the lockfile. The Dockerfile and CI workflow set --registry explicitly as belt- and-braces. CI also gained a sub-second tripwire that fails the build if package-lock.json ever contains a non-public resolved URL again (#30).

Security

  • web_fetch now refuses to call loopback, RFC1918, link-local, and cloud-metadata (169.254.169.254) addresses. A prompt-injected page could previously coax the agent into fetching http://127.0.0.1:4312/api/v1/..., which the auth middleware treats as the host's admin user (full unauthenticated access). Each redirect hop is re-checked against the same policy. Operators with a legitimate intranet target can opt back in with JARELA_ALLOW_PRIVATE_FETCH=1.
  • The file_* agent tools now refuse to touch credential trees (~/.ssh, ~/.gnupg, ~/.aws, ~/.config/gh, ~/.kube, ~/.docker, ~/.netrc, ~/.pgpass) and any path whose basename looks like a private key (id_rsa, *.pem, *.key, credentials). Writes/edits/moves/deletes into Jarela's own data dir (~/.jarela) are blocked too so prompt injection can't rewrite app state. Override with JARELA_ALLOW_SENSITIVE_FILES=1.
  • WhatsApp bridge now sanitises inbound media mimetype against a per-kind allowlist (image/audio/video/document) and rejects anything that doesn't match the type/subtype RFC 6838 shape, instead of trusting whatever the sender claimed.
  • The Next.js server now logs a prominent warning at boot if it is bound to a non-loopback interface outside a container, since the Tailscale-User-Login header it relies on for authentication is trivially forgeable on the LAN without a Tailscale-Serve (or equivalent) reverse proxy in front. Suppress with JARELA_ALLOW_NONLOOPBACK_BIND=1.

[0.3.0] - 2026-05-24

Added

  • Chat bubble now renders inbound bridge media inline: audio messages use an <audio controls> player and video messages use a <video controls> player, so voice notes and short clips from WhatsApp can be reviewed without downloading the attachment (#20).

Changed

  • Bridge notification titles now read Sender → Agent (with a (group) suffix for group chats) instead of just the chat name, so operators can see who is talking to which agent from the toast alone (#20).

[0.2.1] - 2026-05-24

Fixed

  • MCP registry picker no longer renders the same server multiple times. The upstream registry returns one row per published version, and the picker was only filtering by status == "active". It now filters by _meta.isLatest (treating a missing flag as latest so newly-published servers still surface) and dedupes by fully-qualified upstream name plus (id, transport) install identity (#14).
  • MCP registry picker no longer surfaces community entries labelled as "Vendor". The com.<vendor>/ namespace is now matched against an allowlist mirroring VENDOR_GITHUB_ORGS; any unrecognised domain-verified namespace falls back to Community and is filtered out by default (#14).

[0.2.0] - 2026-05-24

Added

  • WhatsApp bridge forwards inbound media (images, audio, video, documents) to vision-capable agents, and the bridge editor now surfaces a vision-capable hint per agent so operators can pick a compatible model (#11).
  • MCP picker shows only verified upstream servers and ranks them by popularity (#8).
  • Opt-in mock LLM provider (JARELA_ENABLE_MOCK_PROVIDER=1) for deterministic offline development and CI, plus a Playwright E2E suite driven entirely by the mock provider — no real LLM keys required (#5, #6).
  • Experimental main update channel and an in-app update notice with a jarela update CLI command for one-shot self-updates (#1, #4).
  • README hero video promoting the demo above the "what is Jarela" section (#9, #10).

Fixed

  • Chat filter toolbar no longer gets stranded by the iOS PWA bounce — it is now pinned to the top of the viewport (#2).
  • Menu tray pin behaviour on small viewports (#3).
  • Playwright chat-mock smoke test uses a unique marker per run and asserts on .last() so it no longer trips strict-mode locator resolution when the shared SQLite DB at JARELA_DB_DIR=/tmp/jarela-e2e accumulates messages across the chromium-desktop and mobile-safari projects (#7, #12).

[0.1.3] - 2026-05-24

Changed

  • Verify CI release path end-to-end via npm Trusted Publisher (OIDC). No functional code changes vs. 0.1.2; this version exists to confirm that tagged releases publish to npm with provenance attestations signed by GitHub Actions, without any long-lived NPM_TOKEN.

[0.1.2] - 2026-05-24

First public release.

Added

  • Docker support: multi-stage Dockerfile, docker-compose.yml, and a release-docker.mjs helper that builds and pushes multi-arch images (linux/amd64, linux/arm64) to Docker Hub as andrewgewu/jarela.
  • CI docker-publish job in .github/workflows/release.yml, gated by the JARELA_DOCKER_PUBLISH repo variable and DOCKERHUB_USERNAME / DOCKERHUB_TOKEN secrets.
  • LICENSE (MIT), CHANGELOG.md, and .nvmrc so the package is publishable to npm and the registry surfaces correct license metadata.
  • Published to npm under the @circuitwall org as @circuitwall/jarela.
  • package.json metadata: repository, author, keywords, homepage, and bugs.
  • Per-agent message-channel display filters (ADR-0022). Users can hide scheduled_task, bridge, synthetic, tool_use, and thinking messages on a per-agent basis; settings are persisted server-side.
  • never_reply flag on agent configs — agents can observe bridge/scheduled input without auto-responding until directly addressed.

Changed

  • Default Docker repo flipped from jarela/jarela to andrewgewu/jarela in the release script, the workflow's JARELA_DOCKER_REPO fallback, and the install docs.
  • Coder starter agent profile renamed to Developer, with tightened instructions (verify every edit via shell_exec build/lint/test) and an expanded toolset (shell_exec, local_exec, web_search, web_fetch, github_*, memory_*).

Fixed

  • Release workflow: INSTALL.md is now copied from docs/INSTALL.md; the previous v0.1.1 attempt failed because the file path was wrong.
  • Chat: category filter toolbar no longer disappears on the PWA. It was rendered inside a scroll container with a top/bottom transparency-fade mask that swallowed the ~26 px chip row.
  • UI: debounce health-check failures so long agent turns no longer flash an "offline" indicator mid-stream.

[0.1.1] - 2026-05-23

Internal beta. Docker image andrewgewu/jarela:0.1.1 was published, but the GitHub Release workflow failed (broken INSTALL.md path); superseded by 0.1.2.

[0.1.0] - 2026-05-23

Initial Docker Hub publication: andrewgewu/jarela:0.1.0 (multi-arch).