Commit Graph
3429 Commits
Author SHA1 Message Date
Serhii DziupinandSerhii Dziupin 6183ca6629 fix(chat): clamp text selection menu Y position to the viewport (#2257)
Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>
2026-08-06 19:46:21 +00:00
Chiamandchiamsun 2c331e2f8b fix(ui): cascade-remove extracted document attachments when parent is removed (#2432)
When a document (PPTX, DOCX, XLSX, ODP, ODT, ODS) is attached,
extracted slide images were left orphaned after removing the
parent text entry. This adds a sourceDocumentId field to
AttachedFile that links all entries from the same document
extraction, and cascades removal of all entries in the group
when any one is removed.

Fixes #2426

Co-authored-by: chiamsun <chiamsun@users.noreply.github.com>
2026-08-06 22:38:34 +03:00
Serhii Dziupin fe331c093b fix(ui): never auto-send the message queue into a streaming turn (#2642)
The queue auto-send gate treated a missing session status entry as idle,
but the server's /session/status map only lists busy/retry sessions — a
missed busy event leaves no entry while a turn is still streaming. On a
client that missed the busy event (e.g. mobile reconnect window), queued
follow-ups were dispatched into the running turn; OpenCode then merged
both prompts into one model response instead of serializing them.

Extract resolveQueuedSessionStatusType and mirror useSessionActivity's
fallback: a trailing in-flight assistant message means the session is
still busy, so the queue waits for the real idle edge. Subscribe the
effect to messages so the queue drains as soon as the turn completes
even when status events were missed.
2026-08-06 22:19:50 +03:00
TPOB 4bb89bf6a6 fix(vscode): open notebook links in notebook editor (#2373) 2026-08-06 21:37:41 +03:00
Aman Tahiliani bcc64f7586 fix(settings): preserve notification template edits (#2300) 2026-08-06 21:17:16 +03:00
Sérgio Pedro fa63866cbb fix(ui): make overlay scrollbar persistent on desktop shells (#2581)
PR #2520 fixed #2475 in the wrong layer (overflow classes on
SettingsView.tsx wrapper divs that aren't the actual scroll containers),
so the "no scrollbar in Settings" bug shipped in v1.17.2 unchanged, and
the sessions feed has the same underlying issue (#2402).

The actual scroll containers render through ScrollableOverlay ->
OverlayScrollbar, which hides the native scrollbar and draws its own
JS thumb that auto-hides ~1s after scroll activity stops, with a
second CSS rule fully hiding that thumb inside Settings specifically.

Fix both at the shared component/CSS layer so every consumer (Settings,
sessions feed, git panels, chat, etc.) gets a persistent scrollbar on
desktop shells (Electron + VS Code webview) in one change:

- OverlayScrollbar.tsx: skip the auto-hide timer and show the thumb
  immediately on mount when content overflows, on desktop runtimes.
  userIntentOnly consumers (chat auto-follow scroll, reasoning blocks)
  keep today's intent-gated behavior unchanged.
- index.css: scope the Settings-specific hide rule to non-desktop, so
  mobile/web keep existing behavior and desktop gets the thumb back.
2026-08-06 21:10:22 +03:00
Pascal André 3f5a453d31 fix(desktop): preserve native taskbar minimize (#2494) 2026-08-06 21:06:54 +03:00
Pascal André 7d9af7aa3a fix(chat): expand shell output by default (#2492) 2026-08-06 20:58:49 +03:00
Serhii Dziupin 9368d44b99 Merge pull request #2685 from makeittech/fix/gh-2558-ios-shift-enter
fix(composer): restore Shift+Enter newline on iOS
2026-08-06 18:13:29 +03:00
Serhii Dziupin 7a9e5099d7 Merge pull request #2256 from bashrusakh/fix/issue-2244-todo-event-resilience
fix(sync): route directory-less todo updates
2026-08-06 18:09:24 +03:00
Serhii Dziupin 43f03608ec Merge pull request #2682 from makeittech/feat/gh-2634-pending-question
feat(sessions): show a pending-question indicator on sessions
2026-08-06 13:06:24 +03:00
Serhii Dziupin 99a6dcd052 Merge branch 'main' into feat/gh-2634-pending-question 2026-08-06 13:04:16 +03:00
Serhii Dziupin 319e58686b Merge pull request #2663 from makeittech/fix/ope-236-question-tool-stuck
fix(sync): route question/permission replies by the request's own session directory
2026-08-06 11:39:53 +03:00
Serhii Dziupin f36bfee0d5 Merge pull request #2660 from makeittech/fix/ope-216-ui-password-daemon
fix(cli): generate a UI password for bare --ui-password in daemon/serve mode
2026-08-06 10:34:19 +03:00
Serhii Dziupin c9f39f7604 Merge pull request #2695 from makeittech/fix/gh-2638-chat-ui-freeze
fix(server): rebind message-stream upstreams after a managed OpenCode restart (#2638)
2026-08-06 10:15:51 +03:00
Serhii Dziupin aa5f37a25a Merge pull request #2661 from makeittech/feat/ope-231-opencode-hostname
feat(server): validate OPENCHAMBER_OPENCODE_HOSTNAME bind hostname
2026-08-06 10:10:10 +03:00
Serhii Dziupin e2fb4f8f21 Merge pull request #2665 from makeittech/fix/ope-178-yaml-frontmatter
fix(web): parse agent frontmatter as leniently as OpenCode
2026-08-06 10:07:17 +03:00
Serhii Dziupin 5964a7d8ba Merge pull request #2698 from makeittech/feat/gh-2583-markdown-loops
feat(tasks): support markdown scheduled-task loops in .agents/loops
2026-08-06 09:57:49 +03:00
makeittech 0a4fd7c5fb docs(tasks): add loops quick-start to the scheduled-tasks page
User-facing onboarding for markdown loop tasks: where .agents/loops
files live (project + user scope), a copy-paste sample file, the
frontmatter field table, and the behavior contract (file authoritative,
off by default, rename/malformed semantics, run-now still available).
Also lists the cron schedule type in the UI task creation steps, which
the page previously omitted.
2026-08-06 09:56:11 +03:00
makeittech 9b6b90504c fix(tasks): cover syncProject wiring and allow deleting orphans after file removal
Review follow-up:

- runtime.test.js: add syncProject wiring tests with a real temp-dir
  project and real project-config runtime — asserts reconcileLoopTasks is
  driven with the discovered loops when the project path is known (task
  created, nextRunAt computed) and that plain listing is used when the
  path cannot be resolved (reconcile not called).
- service.js: DELETE on a loop-owned task is rejected with a 400 only
  while its loop file still exists on disk; once the file is gone the
  orphan task can be deleted directly instead of waiting for the next
  reconcile. Tests use real temp files for both branches.
- DOCUMENTATION.md: delete semantics updated accordingly.
- PR description refreshed for the final HEAD (test counts, reconciliation
  contract, evidence wording).
2026-08-06 09:49:31 +03:00
makeittech 59a6c1b70d fix(tasks): guard loop name length and surface loop ownership in the UI
Review follow-up:

- Reject loop files whose frontmatter name exceeds MAX_TASK_NAME_LENGTH
  (80): task names are clamped at storage time, so a raw name longer than
  the limit could never match the stored task identity. The file is treated
  as malformed (definition: null) instead of creating an unreachable
  definition; MAX_TASK_NAME_LENGTH is now exported from project-config.js
  and shared with loops.js.
- Surface loop-sourced tasks in the scheduled-tasks dialog: tasks carrying
  loopFile show a 'Managed by loop file <path>' note, and the enable
  toggle / edit / delete actions are disabled with an explanatory tooltip,
  since the file remains authoritative and would revert any such change.
  run-now stays available. New locale keys added to all 11 message files
  (i18n parity test enforces exact key sets).
- ScheduledTask type gains an optional loopFile field (additive, unknown
  to older clients).
2026-08-06 09:38:18 +03:00
makeittech 359225d363 fix(tasks): harden loop reconciliation against renames and malformed files
Review fixes for the markdown loop feature:

- Loop-owned tasks now adopt by loop file path, not task name, so renaming
  a loop (frontmatter name or UI rename) renames the task in place instead
  of leaving a stale duplicate that keeps running the old definition;
  orphan duplicates of the same file are unscheduled.
- Unparseable loop files are reported to the scheduler as
  definition:null entries: a task whose file still exists is kept with its
  last good definition, and only a genuinely removed file unschedules it.
  Transiently malformed files (mid-edit, bad merge) no longer delete tasks
  or their runtime state.
- Adoption preserves UI-only execution fields (goalEnabled, goalTokenBudget,
  permissionAutoAccept, variant) that the portable format does not define.
- DELETE on a loop-sourced task now returns 400 with guidance to remove the
  loop file, instead of being silently undone by the next reconcile.
- Loops default to enabled: false; discovery of repository content never
  auto-executes scheduled sessions unless the file explicitly enables them.

Regression tests for each fix; DOCUMENTATION.md updated.
2026-08-06 09:28:31 +03:00
ChangeHow 23253b9481 fix(ui): refine contextual shortcut interactions 2026-08-06 14:18:15 +08:00
ChangeHow 45a792d657 feat(ui): show platform-specific shortcut labels 2026-08-06 14:18:15 +08:00
ChangeHow 8d968f3d71 fix(ui): enforce shortcut conflict rules 2026-08-06 14:18:15 +08:00
ChangeHow 669f1603d4 fix(ui): handle IME prefixes and select shortcut conflicts 2026-08-06 14:18:15 +08:00
ChangeHow 6420460dfc fix(ui): refine shortcut and recent session interactions 2026-08-06 14:18:15 +08:00
ChangeHow aba10476c6 refactor(ui): enforce shortcut registration IDs 2026-08-06 14:18:15 +08:00
ChangeHow a5d5d07d3e feat(ui): add session list shortcut 2026-08-06 14:18:15 +08:00
ChangeHow 51fd947de8 refactor(ui): separate shortcut configuration 2026-08-06 14:18:15 +08:00
ChangeHow bb25b68657 refactor(ui): centralize shortcut schema 2026-08-06 14:18:15 +08:00
ChangeHow 4c5421a7af feat(ui): redesign shortcut settings 2026-08-06 14:18:15 +08:00
ChangeHow 1b9da5f9fa feat(ui): add draft target shortcut sequences 2026-08-06 14:18:14 +08:00
ChangeHow ab3ccf395d refactor(ui): register application shortcuts centrally 2026-08-06 14:18:14 +08:00
ChangeHow 82f099be0a feat(ui): add shortcut registry and sequence dispatcher 2026-08-06 14:18:14 +08:00
Serhii Dziupin 352cd2e1e2 Merge pull request #2699 from makeittech/fix/gh-2577-stale-running-ui
fix(sync): finalize tool parts orphaned by an interrupted turn after settlement (#2577)
2026-08-06 09:00:54 +03:00
Serhii Dziupin 4fa753773e Merge pull request #2707 from openchamber/feat/file-tree-depth-limit-497d
fix(fs): keep file-tree list paths through symlinks (#2627)
2026-08-06 08:33:05 +03:00
Serhii DziupinandSerhii Dziupin ee57088dfe fix(fs): keep list paths in requested space through symlinks
Closes openchamber/openchamber#2627

Listing a directory through a workspace symlink was returning realpath
entry paths. The file tree then rejected nested expand toggles because
those paths fall outside the workspace root.

Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>
2026-08-05 17:40:01 +00:00
Serhii Dziupin 22766fe0ac Merge pull request #2706 from openchamber/feat/terminal-escape-key-behavior-ba7f
fix(ui): Escape in terminal reaches PTY instead of closing panel
2026-08-05 20:21:09 +03:00
Cursor AgentandSerhii Dziupin 938e58868f fix(ui): let Escape reach the terminal PTY from the context panel
The desktop ContextPanel captured Escape on the panel aside and closed
the whole pane before ghostty-web's bubble-phase listener could forward
the key. Skip closing when the event target is inside the terminal so
apps like Vim can leave insert mode.

Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>
2026-08-05 17:11:41 +00:00
Serhii Dziupin 23a677b45e Merge pull request #2679 from makeittech/feat/gh-2364-git-changes-count
feat(ui): show the changed-files count badge on the Git rail surface
2026-08-05 17:06:24 +03:00
Serhii Dziupin a0436b3aa8 Merge pull request #2678 from makeittech/feat/gh-2447-focus-after-context
feat(chat): refocus composer after adding message to context
2026-08-05 16:40:32 +03:00
Serhii Dziupin f7157d3137 Merge pull request #2487 from pascalandr/fix/2405-settings-persistence
fix(settings): persist collapsed message preference
2026-08-05 16:39:05 +03:00
Serhii DziupinandSerhii Dziupin 341b4b45c8 fix(ui): stop painting git activity dots on non-git rail surfaces
The badge PR inverted showActivityDot to !== 'git', so editor/terminal/diff
picked up the blue activity dot whenever git had changes. Git already shows
a numeric badge; other surfaces should stay quiet. Also split the count
aria/tooltip strings into singular/plural keys.

Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>
2026-08-05 13:26:46 +00:00
Serhii Dziupin 856ab452dc docs(server): document onOpenCodeRestarted lifecycle dependency 2026-08-05 14:16:18 +03:00
Serhii Dziupin e3202df037 fix(sync): finalize tool parts orphaned by an interrupted turn after settlement
When a managed OpenCode process dies mid-turn (crash, health-check
restart), the persisted turn never settles: the trailing assistant
message has no time.completed and its tool parts stay pending/running
forever — the server never finalizes them (anomalyco/opencode#19023).
The existing settle-triggered tail refresh refetches the same stale
records, so the UI kept running tool timers and working styling
indefinitely (#2577).

Now, when a session is authoritatively settled (session.idle/
session.error event, or an authoritative status snapshot lowering a
previously busy session) and the trailing assistant message is still
unfinished with active tool parts and no pending question/permission,
the orphaned parts are finalized locally as error/"Interrupted" with
an end time — the same shape OpenCode itself writes for cancelled
tools. The mark is gated on an explicit idle status (absent status is
"unknown", never judged), never applies while busy (including
question/permission waits), and a later terminal event or refresh
supersedes it while a stale running refresh cannot regress it (the
reducer and materializer already preserve final statuses).

Fixes #2577
2026-08-05 14:15:03 +03:00
Serhii Dziupin 2fcfe511a5 feat(tasks): support markdown scheduled-task loops in .agents/loops
Adds markdown-based scheduled-task definitions ("loops") discovered from
.agents/loops/*.md (project scope, ancestor directories up to the
worktree root) and ~/.agents/loops/*.md (user scope), mirroring the
skills discovery pattern.

File format: YAML frontmatter (name, schedule cron, enabled, model as
provider/model, optional agent/timezone) plus the markdown body as the
execution prompt. Discovery and parsing live in
scheduled-tasks/loops.js; project-config gains reconcileLoopTasks which
runs inside the project write lock on every syncProject:
- identity by task name; a loop takes over a matching task, preserving
  its id and runtime state (markdown wins on conflict with JSON)
- tasks whose loopFile is gone are unscheduled; JSON tasks are never
  removed
- new loops are created under deterministic loop:<scope>:<name> ids
- project scope shadows user scope on name collisions
- malformed files are skipped with a warning and never block valid ones

Runtime state stays in the project config/state store; it is never
written to the markdown files. Module documentation updated with the
file format and reconciliation rules.

Fixes #2583
2026-08-05 14:11:28 +03:00
Serhii Dziupin 17d5b90d83 fix(ui): add in-document search to the Markdown file preview
The rendered Markdown preview had no way to search: the Electron desktop
shell implements no find-in-page at all, and CodeMirror's search panel only
exists in edit mode, so Ctrl/Cmd+F in the preview was a dead shortcut (web
browsers happen to find plain-DOM text natively, but desktop does not).

Adds a compact find bar for the rendered preview (Ctrl/Cmd+F or the search
button): case-insensitive match highlighting with a live count, Enter /
Shift+Enter and arrow buttons to navigate matches, Esc to close. Matches
are wrapped in <mark> elements and re-applied via MutationObserver when the
markdown renderer re-morphs the container (theme/content changes); svg
(mermaid) and script/style text is skipped. The pure match-range logic is
unit-tested.

Fixes #2401
2026-08-05 14:05:12 +03:00
Serhii Dziupin 13f6a0280d fix(server): rebind message-stream upstreams after a managed OpenCode restart
When the managed OpenCode process exits but a server survives on the old
port (Windows: killProcessOnPort is a no-op, so the orphaned process tree
keeps the port), restartOpenCode() times out waiting for the port and
spawns a fresh server on a NEW port. HTTP/proxy traffic follows the new
port, but the global message-stream hub's upstream SSE reader stays pinned
to the old server's /global/event stream — that connection never closes —
so new events never reach the UI and the chat stops updating until the
app is restarted (#2638).

Lifecycle now fires an optional onOpenCodeRestarted hook after a
successful managed restart; index.js wires it to the new
messageStreamRuntime.rebindUpstream(), which restarts the shared hub
(its reader re-dials buildOpenCodeUrl → the current port) and closes
directory-scoped sockets so their per-connection readers rebuild against
the new port. External servers are untouched (their port cannot change).

Fixes #2638
2026-08-05 13:59:17 +03:00
Serhii Dziupin 264fc16f2c fix(ui): keep the selected model when switching agent modes
Switching between Build and Plan modes reset the model selector to the
settings default because setAgent fell through to the settings-default
fallback whenever the target agent had no saved override, and the
explicit-switch path in ModelControls force-applied the agent's default
model, overwriting any per-agent override.

setAgent now keeps the current model selection when the user has a live
manual selection and the target agent configures no model of its own,
and the explicit-switch handler no longer clobbers saved per-agent
overrides with the agent default. Startup and pin behavior are
unchanged: the settings-default and agent-pin cascade still applies
when no manual selection exists yet.

Fixes #2531
2026-08-05 13:50:23 +03:00