Commit Graph
3306 Commits
Author SHA1 Message Date
Serhii Dziupin fc0ae0f445 Merge upstream/main into feat/shiki-re-highlighting-performance-dd3a
Conflict: packages/ui/src/components/chat/markdown/markdownCore.ts

main added per-image-mode markdown parsers (`imageMode` threaded through
`parseBlock` and into the block cache key); this branch replaced the
identity-keyed block cache with a content-addressed LRU. Resolution keeps the
content-addressed cache and folds `imageMode` into the content key, so the
`inline` and `label` renderings of the same source cannot answer for each other.
2026-08-17 16:44:05 +03:00
Serhii Dziupin 07f8264e72 merge: resolve changelog conflicts with main
Keep main's reordered Unreleased lists and add the config-wipe fix bullet
at the top of both changelogs.
2026-08-17 16:29:08 +03:00
Serhii DziupinandBohdan Triapitsyn 1c76dbefe4 fix(chat): defer composer value writeback during IME composition (Fixes #2527) (#2691)
* fix(chat): defer composer value writeback during IME composition

The controlled-writeback effect compared the value prop against the
CodeMirror document and, on mismatch, dispatched a wholesale replacement
with the caret forced to the end. While the browser composes (pinyin,
kana, hangul) the uncommitted text lives in the DOM, not in the document,
so the mismatch is expected and the dispatch interrupted the IME session
and jumped the cursor. Skip the writeback while the view is composing,
using CodeMirror's public compositionStarted getter; the composition
commits through its own pipeline and reports via onChange.

Fixes #2527

* fix(chat): preserve external composer writes during IME

* fix(chat): restore composition-wide writeback guard

---------

Co-authored-by: Bohdan Triapitsyn <artmore@protonmail.com>
2026-08-17 14:24:39 +03:00
Jakub Syty 917f85212b Merge branch 'openchamber:main' into github-usage-rework 2026-08-17 13:00:01 +02:00
bot-hermes 5481e19069 test(ui): include gitProvidersConnected in settings search fixture 2026-08-17 10:08:31 +00:00
bot-hermes 45437a4221 feat(web,ui): per-project forced git provider and settings gating
Adds a per-project forced provider (github|gitlab|gitea) on top of the
per-project API base URL overrides: stored under gitProviders.provider in
projects/<projectId>.json, sanitized server-side, and winning over remote-host
detection both in useGitProvider and in server repo resolution
(parseGitLabRemoteUrl/parseGiteaRemoteUrl accept any host when the provider
is forced). The Projects settings page replaces the three always-visible URL
fields with a provider selector (auto-detect + the three forges) and one URL
override for the active provider. Global provider override fields on the
GitHub/GitLab/Gitea settings tabs now render only once an account is
connected, and Settings search availability matches that gating.

Also fixes the useConfigStore/useDirectoryStore circular-import TDZ in the
bundled chunk via the window-registered store handle and defers the directory
subscription to a microtask; fixes the Gitea PR merge payload (Do carries the
merge-style string enum, not a boolean + MergeMethod); and adds a documented
Gitea client live-test harness (scripts/gitea-live-test.ts + client.d.ts).
2026-08-17 09:57:54 +00:00
bot-hermes 66edc74fac feat(web,ui): per-project git provider API base URL overrides
Per provider (github|gitlab|gitea) a project override stored in
~/.config/openchamber/projects/<projectId>.json under gitProviders wins
over the global settings.json value (precedence: project override > global
> built-in default). Server forge routes resolve the override per request
directory (worktree-aware via git-common-dir + containment + path fallback,
60s TTL cache); the override host is also accepted for remote parsing and
client detection. New GET/PUT /api/projects/:projectId/git-providers route;
client openchamberConfig preserves the server-owned gitProviders key;
Projects page gains a Git provider API base URLs section; detection store
hydrates per-project overrides (memory-only, server-authoritative).
2026-08-17 09:57:54 +00:00
bot-hermes 697925ee0d feat(web,ui): built-in codeberg.org gitea host and provider detectUrls 2026-08-17 09:56:59 +00:00
bot-hermes a30c7bce0a feat(ui): tabbed git provider settings with search auto-reveal 2026-08-17 09:56:59 +00:00
bot-hermes 0fc857959e feat(web,ui): per-provider git forge API base URL and detection URLs
Configure a default API base URL per git provider (github/gitlab/gitea)
in settings.json gitProviders, with GitHub Enterprise support (Octokit
baseUrl + device-flow web origin derived from the API base), and replace
the client-side custom-domains list with server-persisted detection URL
chips (SSH/HTTPS forms normalized to hosts). The configured API base host
auto-counts as a detection host. Settings round-trip through the existing
/api/config/settings sanitizer; the UI store hydrates from server settings
with a one-time localStorage migration.
2026-08-17 09:55:11 +00:00
herjarsa 39bb71a62b fix(ui): bound OpenCode read requests so half-open sockets cannot freeze bootstrap (#2470)
The SDK client fetch wrapper now applies a 30s timeout to non-streaming
reads. Without it, a socket that neither resolves nor rejects keeps the
directory bootstrap concurrency slot busy forever and the UI stays on
"loading sessions". Long-lived streams (POST prompts, the /event SSE)
are explicitly excluded so they are not cut off mid-flight.

The normalized "request timed out" error is added to the retry
allowlist alongside undici's "terminated" (the exact failure observed
in #2470 when undici tears down a half-open upstream connection); both
are transient while the managed OpenCode process restarts. Caller-
initiated aborts keep their original error shape so a user-cancelled
request is not retried.

Tests cover: GET timeout fires after the bound, POST is not timed out,
/event SSE is not timed out, caller abort wins, AbortError is not
retried, and the SDK normalized error is retried 3x.
2026-08-17 11:37:20 +02:00
bot-hermes a87b3fd228 fix(ui): render forge lookup dropdowns in a portal
The assignee/label/milestone combobox and @-mention list were inline
absolute-positioned inside the ContextPanel rail (overflow-hidden) and the
PR-view scroll container, so the panels were clipped and invisible. Render
both via createPortal to document.body with fixed positioning computed from
the trigger's viewport rect (viewport-edge clamping, flip to the other side
when there is no room), close on outside pointerdown/scroll/resize while
still allowing interaction inside the panel, and keep the panel inside the
outside-click check.

Also show the loading spinner until the first lookup completes instead of a
brief 'No matches' flash (useForgeLookup now reports 'initialized').
2026-08-16 16:29:25 +00:00
bot-hermes 66adb65377 test(web): gitea issue creation — wire api coverage, module docs, section comment
The Gitea create-issue path (server route, client, wire api, facade, UI
button/dialog) landed with the forge user-lookup work; close the remaining
verification/documentation gaps:

- wire: gitea.test.ts covers issueCreate (POST /api/gitea/issues/create,
  full/optional body, error throw)
- docs: DOCUMENTATION.md lists createIssue client method and the
  POST /repos/{owner}/{repo}/issues endpoint (labels as names)
- ui: fix stale 'read-only by design' JSDoc in GiteaIssuesSection — creation
  is offered here and the detail view provides edit/close/reopen
2026-08-16 16:29:25 +00:00
bot-hermes 3b3799f79e fix(web): optional fs stat outside workspace returns exists:false
Graceful probe: an optional stat of a config/backup path outside the active
workspace now reports exists:false instead of 400, so boot-time probes don't
surface console errors for a check that was never mandatory.
2026-08-16 16:29:25 +00:00
bot-hermes 3800c84948 feat(ui): forge user lookup — assignee combobox, @-mentions, repo-scoped user search
Repo-scoped assignable-user search for GitHub, GitLab, and Gitea, surfaced as
an assignee combobox in the metadata editor and @-mention autocomplete in
forge comment/reply/review surfaces.

- server: GET /api/{provider}/users/search (assignees / project members),
  query + directory/override repo resolution, 429 -> 503, connected:false
  degradation; GitLab assignee writes resolve login -> ID server-side
- wire: searchUsers (+ searchLabels/milestones/branches/tags) on the three
  API clients with tests
- facade: userSearch capability (all three), searchUsers adapters,
  mapGithubAssignee/mapGitlabMember/mapGiteaAssignee -> ForgeUser
- ui: ForgeLookupCombobox (keyboard nav, debounced 30s-TTL cache,
  connected-only caching), ForgeMentionTextarea (@ token parsing, caret
  restore), free-text fallback when lookup is unavailable; i18n in 12 locales
- extras sharing the same infrastructure: GitLab create-issue dialog and
  label/milestone/branch/tag lookups in the metadata editor
2026-08-16 16:29:25 +00:00
bot-hermes 1f28b61c5a feat(ui): chat-entity linking — live linked-entity cards, manual link/unlink, session cross-listing
- linkedIssues: provider/repo/host fields (backward-compatible), gitea id generation fix, parseLinkedIssueRef/parseForgeEntityUrl
- work-status panel: live state cards (TTL-cached), link-by-URL dialog, per-row unlink
- forge entity view: 'Chats working on this' section derived from the session store
2026-08-16 16:29:25 +00:00
bot-hermes 8f5cfdcd62 feat(ui): forge write operations — comments, replies, close/reopen, edit, reviews, draft, metadata
- server: write routes for all three providers (issue/PR comments, inline review-comment replies, issue/MR updates w/ labels-assignees-milestone, review submit, draft toggle)
- ui: ForgeProvider gains six write ops; shared action components (composer, thread reply, state/review/draft/metadata/edit) wired into ForgeEntityDetailView and GitHub PR Overview
2026-08-16 16:29:24 +00:00
bot-hermes 92f0eced34 feat(ui): rich forge entity views — commits, files/diff, timeline, checks, metadata chips
- server: new read routes for PR/MR commits, timeline, reviews, commit-statuses across github/gitlab/gitea; enrich PR/issue summaries with labels/assignees/milestone/commentsCount
- ui: forge facade gains getCommits/getTimeline/getChecks; shared ForgeEntityDetailView + section components; mounted into PR/MR views and issue sections
2026-08-16 16:29:24 +00:00
bot-hermes f02c33700b feat(ui): forge facade foundation — normalized types, capability flags, three adapters 2026-08-16 16:27:50 +00:00
bot-hermes bb46866879 feat(ui): add Gitea brand icon and use it for detected Gitea providers
Add the Gitea teapot mark (Simple Icons, 24x24) to the icon sprite as a
custom icon, and swap the gitea fallback icons for it wherever the
provider brand is shown: context rail PR surface, context panel PR tab,
GitHeader PR chip, and the work-status Gitea PR row.
2026-08-16 16:27:50 +00:00
bot-hermes b772f5dad9 fix(ui): support bare scp and IPv6 host forms in git provider detection
Extract a single shared parseGitHost (packages/ui/src/lib/gitHost.ts) used
by both the custom-domain registry (normalizeProviderDomain) and remote
detection (gitProvider). Previously both parsers required a user@ prefix,
rejecting valid bare scp remotes like codeberg.org:owner/repo.git, and
mangled IPv6 hosts. Now scp forms with or without a user, ssh:// URLs with
ports, git+ssh scheme, and bracketed/unbracketed IPv6 all normalize to a
bare hostname; Windows-path-like input is rejected.
2026-08-16 16:27:50 +00:00
bot-hermes ca91fd7e2d feat(gitea): add Gitea/Forgejo as a git provider
Full parity with the existing GitLab provider:
- Server module packages/web/server/lib/gitea (auth/client/repo/routes + docs + tests)
  with Gitea REST v1 API, PAT + base URL auth, multi-account storage
- Shared GiteaAPI types and web API client
- Provider detection generalized with user-configurable custom domains
  per provider (github/gitlab/gitea), additive with built-in defaults
  (github.com, gitlab.com) and connected-account hosts; precedence
  github -> gitlab -> gitea
- Gitea PR view, issues section, pickers, integration dialog, branch
  PR status helper, settings UI (PAT + base URL + custom domains)
- Magic prompts (gitea.pr.review, gitea.issue.review) and full 11-locale
  i18n parity
2026-08-16 16:27:49 +00:00
bot-hermes be13272eb1 feat(ui): issues tabs in GitLab MR and GitHub PR views
Add an Issues tab alongside the merge-request / pull-request content in the
context panel's PR surface for both providers. The tab lists open issues
lazily and expands a selected issue into an inline detail view (body, labels,
assignees, comments) with a back action. Read-only: no issue create, update,
or close actions. Adds 15 i18n keys across all 11 locales.
2026-08-16 16:27:49 +00:00
bot-hermes 7c8c2bba3f feat(ui): head branch selector in the GitHub pull request create form 2026-08-16 16:27:49 +00:00
bot-hermes d5dea0c004 feat(ui): branch selectors in the GitLab merge request create form 2026-08-16 16:27:48 +00:00
bot-hermes c25e16d093 feat(ui): GitLab brand icons in GitLab surfaces 2026-08-16 16:27:48 +00:00
bot-hermes 51ffe54788 fix(ui): provider-aware context tab icon 2026-08-16 16:26:02 +00:00
bot-hermes 7bf07f0dd9 fix(ui): provider-aware context rail branding for GitLab 2026-08-16 16:24:40 +00:00
bot-hermes 06a5dd63bb fix(ui): label GitLab merge requests as MR in the composer 2026-08-16 16:23:40 +00:00
bot-hermes 324dca9057 feat(ui): create, update and merge GitLab merge requests from the MR view 2026-08-16 16:23:39 +00:00
bot-hermes 28d992ac78 feat(web): create, update and merge GitLab merge requests 2026-08-16 16:23:39 +00:00
bot-hermes b8a0aa0242 feat(web): resolve walkthrough diffs for GitLab merge requests 2026-08-16 16:23:38 +00:00
bot-hermes 89db325168 feat(ui): show GitLab merge request status in walkthrough, git view and work status 2026-08-16 16:23:38 +00:00
bot-hermes 2c4ba78ae5 feat(ui): GitLab merge request view in the context panel 2026-08-16 16:23:37 +00:00
bot-hermes 454b3591e5 feat(ui): attach GitLab issues and merge requests to sessions 2026-08-16 16:23:36 +00:00
bot-hermes 267db3fb9d feat(web): filter GitLab merge requests by source branch 2026-08-16 16:23:36 +00:00
bot-hermes 6868a58359 fix(ui): hide GitHub surfaces in non-GitHub repositories 2026-08-16 16:23:36 +00:00
Bohdan Triapitsyn 7ef6441bf3 Reduce anti-slop findings in Persistence (#2953)
* chore(ui): reduce persistence anti-slop findings

* test(ui): cover fallback settings response

* fix(ui): preserve usage model group contract
2026-08-16 19:21:35 +03:00
bot-hermes e83bd2bc08 fix(ui): refresh GitLab auth status on worktree dialog mount 2026-08-16 15:42:26 +00:00
bot-hermes a05056a871 feat(ui): start worktree sessions from GitLab issues and merge requests 2026-08-16 15:42:26 +00:00
bot-hermes a42eec5c9c feat(ui): add GitLab connect settings 2026-08-16 15:42:26 +00:00
bot-hermes d798b3f479 feat(web): add GitLab issues/MRs server module
Add a server-side GitLab integration mirroring the GitHub module:
- auth.js: PAT auth storage with multi-account support and configurable
  base URL (gitlab.com default, self-hosted instances supported)
- client.js: raw-fetch GitLab REST v4 client with per-request timeout,
  ETag conditional-GET cache, own rate-limit cooldown, pagination, and
  single-follow redirect handling
- repo.js: GitLab remote URL parser + directory resolution
- routes.js: read-only /api/gitlab/* routes (auth, issues, MRs, branches)
- index.js + DOCUMENTATION.md + unit tests for auth, client, repo, routes
- Wire registerGitLabRoutes into feature-routes-runtime
2026-08-16 15:42:26 +00:00
bot-hermes b5ddb6f3a1 feat(web): add GitLab API client wrapper and types 2026-08-16 15:42:26 +00:00
bot-hermes f16a5bab6b docs: add GitLab issues/MRs page 2026-08-16 15:42:26 +00:00
Bohdan Triapitsyn bfa0f9ee2a docs: require PR template and complete-file batches in maintenance flows
Maintenance task commands now fill .github/PULL_REQUEST_TEMPLATE.md section by
section instead of inventing their own headings, and follow-up tasks keep the
description true for the final HEAD while preserving hand-added content.

Raise the anti-slop batch window to 60-120 findings and require each selected
file to be finished: remaining findings need an individual specific reason,
shared root causes count once, and difficulty alone no longer justifies a skip.
A half-fixed file otherwise returns as a second pull request over the same code.

Add the maintenance-review command, which reviews every open anti-slop and
react-doctor pull request and fixes the findings directly rather than
commenting, without merging or approving.
2026-08-16 18:34:02 +03:00
Bohdan Triapitsyn 80150aaf0d chore: increase default max active claims to 20 2026-08-16 17:31:55 +03:00
Bohdan Triapitsyn 58c190f0b1 fix(web): use Vitest timers in PR status tests 2026-08-16 17:30:45 +03:00
Bohdan Triapitsyn b178f75eff docs: add maintenance review workflow 2026-08-16 17:10:31 +03:00
Bohdan Triapitsyn 97691fc4ac chore(scripts): raise default active batch limit to 10 2026-08-16 16:34:05 +03:00
Bohdan Triapitsyn 21152ec120 chore(vscode): update changelog for integrations settings page 2026-08-16 15:55:49 +03:00