Merge upstream v1.37.3 - #1
Merged
Merged
Conversation
Reduce npm notice output and stream release logs so package listings do not obscure failures. Print saved npm errors after failed releases to recover diagnostics lost to truncated output. Quote release inputs so custom names retain spaces and literal characters.
…oon#1265) The OpenCode provider authenticated any credentials file entry, so a subscriber who connected OpenCode Go (`opencode-go` in auth.json) counted as logged in - but the curated catalog had no `opencode-go/*` entries at all. The connected-provider filter then found no Go options, fell back to the full catalog, and left Go users staring at a list of models their CLI rejects while every model they pay for was missing. See siteboon#840, which was closed without a fix while the bug persists on main. Add the 27 `opencode-go/<model-id>` entries `opencode models --verbose` reports, with the reasoning-variant values from the same output wired as effort metadata so the existing effort picker resolves them through `--variant`. Labels follow the catalog's existing style; the CLI's marketing suffixes ("(2x usage)", "(New)") are dropped. `DEFAULT` stays on the Zen default - the filter already relocates it for Go-only installs. The docs also list `minimax-m2.5`, but the CLI does not report it, so it is deliberately left out; the catalog mirrors CLI output.
…on#1249) Question/answer cards split a multi-select answer on ", " unconditionally, so a single option whose own label contains ", " ("Yes, always") rendered as two chips, neither matching an option, both marked (custom). Match one exact option first and split only when no option matches, which leaves genuine multi-select answers unchanged.
…eboon#1238) * feat(chat): recall sent messages with arrow keys in the composer ArrowUp in an empty composer recalls messages previously sent in the open chat, newest first; ArrowDown walks forward and finally restores the draft. History is kept per chat scope (the same session-or-project key drafts use) in localStorage, capped per scope and across scopes, and recorded on send, queue, and slash-command execution. The arrows keep their normal meaning while editing text or navigating the command/mention menus. Signed-off-by: Matthew McClintock <matthew@mcclintock.net> * fix(chat): walk a stable history snapshot during recall An append from another tab mid-recall shifted what ArrowDown landed on and could displace the draft restore. Navigation now snapshots the entries when recall starts and walks that array until recall ends. Signed-off-by: Matthew McClintock <matthew@mcclintock.net> * fix(chat): record queued messages before the session-switch return Switching sessions while a queued message's attachments uploaded hit the early return after persistence, so the message dispatched later without ever entering input history. Record it right after persistence, under the session it was queued for. Signed-off-by: Matthew McClintock <matthew@mcclintock.net> --------- Signed-off-by: Matthew McClintock <matthew@mcclintock.net> Co-authored-by: blackmammoth <118998054+blackmammoth@users.noreply.github.com>
* feat: collapsible branches in the model picker
The picker lists every model of every installed provider in one flat
run - an OpenCode installation alone contributes ninety - so reaching
the provider below means scrolling past all of them.
Each branch now collapses by its heading, with the model count beside
it, and the state is remembered in localStorage. A search opens every
branch for as long as it runs, because a hit inside a collapsed one
would be invisible. A collapsed branch keeps one row ("N hidden - click
to show"): cmdk drops a group whose items are all gone, and a heading
that is no longer rendered cannot be clicked open again.
The rendering moved into its own component rather than growing the
440-line empty state further.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: persist the collapsed branches from an effect
React may run a state updater more than once or discard its result, so a
`localStorage` write inside one is not tied to committed state. The
updater only computes the next set now; an effect on it does the write.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: clear the model search when the picker closes
The search box is controlled, and closing the dialog only flipped `dialogOpen`.
A query stayed behind and came back the next time the picker opened - with
every provider branch expanded, because searching expands them. That undoes
the collapsing this picker exists for.
Closing now clears the query, through one function the four call sites share.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
…oon#1223) Node's explicit module extensions fell through to the default arm of the language switch, so a .mts or .cts file opened in the editor with no highlighting at all. The existing `ext.includes('ts')` check already picks TypeScript for the two new TS extensions and JavaScript for the other two, so the four cases are all that is missing. Co-authored-by: Malte Buttjer <claude@buttjer.net> Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
…eboon#1220) * fix(sessions): keep an archived session archived across a rescan createSession resets isArchived on every re-index, without checking whether anything was written. The full rescan runs on each project-list fetch and selects transcripts by birthtime, so it re-indexes every session created since the last fetch -- and each of those loses its archive flag. Archiving a session started since the sidebar was last loaded therefore never sticks, which covers every session a user archives right after finishing it. Reset only when the caller reports newer activity: an explicit timestamp that is newer than the stored one, or no timestamp at all, which the statement already treats as "now" when it writes updated_at. julianday() parses both the column-default and ISO forms that occur in the column. * fix(sessions): treat an omitted timestamp as activity on the upsert path too Review catch: the ON CONFLICT branch compared excluded.updated_at, which is already COALESCE(?, CURRENT_TIMESTAMP), so a call that passes no timestamp was compared as "now" -- and CURRENT_TIMESTAMP resolves to whole seconds, so it is not newer than a row written in the same second. An archived app-created row, indexed for the first time without timestamps, therefore stayed archived while its own updated_at said it was live. Same reasoning as the UPDATE branch, same `? IS NULL` arm. Two tests, one per direction, both checked against the unpatched query first: the omitted-timestamp one fails without this change, and the stale-transcript one pins that an older transcript is still not activity. --------- Co-authored-by: Malte Buttjer <claude@buttjer.net> Co-authored-by: blackmammoth <118998054+blackmammoth@users.noreply.github.com>
…iteboon#1192) * feat(i18n): connect remaining hardcoded UI strings to translations Wire user-facing strings that never went through i18n so they respond to the language setting. Adds a new git namespace for the source control panel and extends the settings, auth, chat and common namespaces for skills, browser use, onboarding, the command palette, MCP server views, the setup form, the version upgrade modal, the folder browser and a few smaller screens. Template strings become interpolated t() calls, plural counts use i18next _one/_other forms, labels stored in constant files are resolved through t() at render time, and commit dates in the history view follow the active locale instead of hard-coded en-US. English keys cover every namespace touched here; other languages fall back to English through the existing fallbackLng setting until their translations are added. * fix(i18n): address CodeRabbit full-review findings - AuthContext: use the auth namespace with stable errors.* keys for session/status/login/registration/network messages - CommandResultModal: translate the modal footer hint and Close button - MergeWorktreeModal: refresh the untouched default message when the locale changes (tracked per worktree) - gitPanelUtils: FILE_STATUS_LABELS now returns git:status.* translation keys, matching FileChangeItem's t() rendering - BrowserUseSettingsTab: always show localized operation-failure messages instead of raw API error text; render the translated runtime-required fallback instead of the server's English status message * feat(browser-use): error-code contract for browserUse API Server now replies with the structured AppError envelope { success:false, error:{ code, message, details } } on every browser-use endpoint (status, settings get/save, runtime install, sessions list/stop/delete). Stable BROWSER_USE_* codes let clients map errors to localized copy instead of rendering raw English API text. - readApiJson throws ApiRequestError carrying code/details/status and accepts both legacy string and structured error envelopes - BrowserUseSettingsTab and BrowserUsePanel translate failures through code->i18n-key tables with localized per-operation fallbacks - add en browserUse.installFailed key used by the panel mapping * fix(api): preserve legacy top-level details in readApiJson Legacy envelopes ({ success:false, error:'msg', details }) lost their top-level details because payload was empty for string errors. Fall back to data.details and cover structured, legacy and bare envelopes with tests. * chore: align package-lock.json and package.json with upstream main The PR carries no package-lock.json changes (reviewer request): the lockfile now matches origin/main exactly. --------- Co-authored-by: blackmammoth <118998054+blackmammoth@users.noreply.github.com>
…eboon#1162) The project and session delete dialogs in `SidebarModals.tsx` render five translation keys that exist in none of the locale catalogs: - deleteConfirmation.archiveProject - deleteConfirmation.archiveSession - deleteConfirmation.archiveSessionNotice - deleteConfirmation.archivedSessionNotice - deleteConfirmation.deleteSessionPermanently Each call site passes an inline English default, so the keys never surface as missing at runtime — they silently render English in all 11 languages. The effect is worst where it matters most. Both dialogs offer a safe action and a destructive one side by side. The destructive button uses `deleteConfirmation.deleteAllData`, which *is* translated everywhere, while the safe "Archive" button falls back to English. A non-English user reading the project dialog sees a localized "Delete all data permanently" next to an English "Archive project", which is precisely the choice the dialog exists to make clear. Adds the five keys to all 11 locales, following the pattern of siteboon#896. Note: `removeFromSidebar`, `allConversationsDeleted` and `cannotUndo` are translated in every catalog but no longer referenced by any component — they appear to be the pre-refactor names of these same strings. Left untouched here to keep this change additive; happy to remove them in a follow-up.
…oon#1274) listPluginSkills read a plugin's commands/ or its skills/, whichever it found first: the existence of a commands folder ended that plugin's turn, so a plugin shipping both contributed only its commands. The commands reader also takes .md only, so a plugin whose commands are in another agent's format lost both halves at once -- nothing matched, and the `continue` walked past the skills sitting beside them. The CLI offers both halves for the same plugin, so those skills work in the terminal and are absent from the slash menu, with nothing to say why. Read both folders. The skills branch already skips a plugin with no skills/, and the menu dedupes by command, so a name present in both places is still listed once. Fixes siteboon#1273 Signed-off-by: Liran Funaro <liran.funaro@gmail.com>
…on#1159) `getProviderModels` resolves to a `ProviderModelsDefinition` - `OPTIONS` and `DEFAULT` - but the agent route read `.models` off it, so both catalog handles came back undefined. A codex or opencode run that named no model then died on `codexModels.DEFAULT` with a TypeError before the provider was ever started, and the route reported it as a 500. The route's own test mock encoded the same imaginary wrapper, which is why nothing caught it. The mock now returns the real shape, and a new test drives the codex path with no model and asserts the catalog default reaches the runtime.
…ion model (siteboon#1207) * fix(claude): ignore <synthetic> model placeholder when resolving session model Claude Code stamps locally-synthesized rows in session JSONL files (API-error placeholders and similar) with model: "<synthetic>". The session-model scan in readClaudeSessionModelFromJsonl walks the JSONL backwards and takes the first event carrying a model field, so when the last row happens to be such a placeholder, "<synthetic>" is surfaced as the session's active model. The UI then adopts it, sends it back as the model for the next turn, and the SDK issues a real API request with model "<synthetic>", which the upstream API rejects with 404 model_not_found. Treat angle-bracketed values as placeholders and skip them, falling back to earlier events or the provider default. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(claude): skip placeholder hits inside content-part scan Move the placeholder filter into extractClaudeModelFromMessageContent so a placeholder in an earlier content part no longer stops the scan before a later part carrying the real model tag. Add regression tests. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(claude): filter placeholders per candidate inside text extraction A placeholder "set model to <synthetic>" stdout hit no longer shadows a real <model> tag later in the same text. Filtering now lives at each candidate site in extractClaudeModelFromTextContent, so the content-part scan needs no extra checks. Regression tests cover both content shapes. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
…wn (siteboon#1157) A Conversations row was a link and a chevron: you could open the session and nothing else. Renaming it, copying its provider session id, forking it or archiving it meant finding it again under its project. This gives that list the controls the Projects list already has, from one component rather than a second copy of the markup. Re-ported onto the layout siteboon#1206 landed, which moved src/components/sidebar to src/modules/sidebar and flattened view/subcomponents. Nothing of the previous version survived as a diff, so this is that change rewritten against the new tree, with two differences worth naming: - fork is included. It did not exist when this was first written, and it is the third action the Conversations row was missing. The fork path reads only a session's id, provider and owning project, which is exactly what a recents row knows, so no session object is invented. - PROVIDER_LABELS moves to utils/sidebarProjectFormatting, beside the other row formatting, rather than being exported from a component. The shape is unchanged from the version that was reviewed down to ~116 net lines: the mechanism is extracted, not duplicated. SessionOptions the options menu and the inline rename that replaces it, with the outside-click dismissal that belongs to it useProviderSessionIdCopy the id behind "copy id": fetched when the menu opens rather than per row, dropped when it closes, sequenced so a late reply is discarded SessionRowActions the nine members a row needs, named once; SidebarProjectListProps composes it rather than restating it, and the call site passes one prop SidebarSessionItem is 208 lines lighter for giving those up; the Conversations row spends 103 to gain all four actions and two states. Callers keep only what is genuinely theirs. The Conversations row shows the amber attention dot and the processing spinner, but not the green "touched recently" dot — in a list ordered by recency it would be on nearly every row and say nothing. A row whose project is unknown gets no rename, since a rename is keyed by project; it is withheld rather than guessed. Also fixes a bug the second list exposed: nothing refetched the recents feed after a rename or a delete, so the row you had just acted on kept its old title or stayed in the list. Both now patch in place, which also preserves the pages loaded past the first that refetching page zero would discard. Build, both typechecks and lint are clean; 380 client tests and 394 server tests pass, including six new ones asserting what the Conversations row resolves for the shared controls. Signed-off-by: Liran Funaro <liran.funaro@gmail.com> Co-authored-by: blackmammoth <118998054+blackmammoth@users.noreply.github.com>
* feat(codex): expose GPT-6 Astra model * chore(codex): upgrade runtime for GPT-6 Astra
* feat(codex): expose GPT-6 Astra model * chore(codex): upgrade runtime for GPT-6 Astra * fix(codex): replace unsupported default approval policy Use on-request to prevent startup failures while preserving workspace sandboxing. Update permission descriptions and test both new and resumed Codex sessions. --------- Co-authored-by: Simos Mikelatos <simosmik@gmail.com>
Release 1.37.3 # Conflicts: # README.md # docs/README.md # docs/README.upstream.md # package-lock.json # package.json # server/modules/database/repositories/sessions.db.ts # server/modules/providers/list/codex/codex-runtime.provider.ts # src/modules/auth/AuthLoadingScreen.tsx # src/modules/chat/hooks/useChatComposerState.ts # src/modules/chat/modals/CommandResultModal.tsx # src/modules/chat/modals/ModelLibraryPanel.tsx # src/modules/chat/tools/BashCommandDisplay.tsx # src/modules/chat/transcript/ProviderSelectionEmptyState.tsx # src/modules/i18n/locales/de/settings.json # src/modules/i18n/locales/en/chat.json # src/modules/i18n/locales/en/settings.json # src/modules/i18n/locales/es/settings.json # src/modules/i18n/locales/fr/settings.json # src/modules/i18n/locales/it/settings.json # src/modules/i18n/locales/ja/settings.json # src/modules/i18n/locales/ko/settings.json # src/modules/i18n/locales/ru/settings.json # src/modules/i18n/locales/tr/settings.json # src/modules/i18n/locales/zh-CN/settings.json # src/modules/i18n/locales/zh-TW/settings.json # src/modules/plugins/PluginTabContent.tsx # src/modules/sidebar/SidebarSessionItem.tsx # src/modules/task-master/NextTaskBanner.tsx
- README.md: strip unresolved conflict markers (fork Chinese README kept; upstream body already mirrored in docs/README.upstream.md) - NextTaskBanner: restore upstream i18n (t() for priority titles, start task, view details/all, complete/no-pending labels) lost to fork-side conflict resolution; drop now-unused setup-block leftovers - SidebarSessionItem: remove dead PROVIDER_LABELS import - PluginTabContent: merge duplicate useTranslation calls
…8n completions - i18n: restore 148 missing settings keys in en/settings.json; complete tasks:banner and priorities translations in zh-CN/tasks.json; internationalize review button - api: drop dead src/utils/api.js (449 lines) and extractResponseError; adopt readApiJson in PluginsContext with non-JSON fallback protection - providers: consolidate resolveModelEffort across claude/codex/opencode; direct ws.send in codex runtime - db: fix sessions upsert unarchiving for legacy NULL timestamps with integration tests - chat: unify composer programmatic input updates via updateInput - sidebar: eliminate duplicate PROVIDER_LABELS via getProviderDisplayName - tests: relocate NextTaskBanner test under task-master/tests with I18nextProvider
- Guard keyboard offset by active editable element: when no input/textarea is focused, force --keyboard-height to 0 to eliminate initial load glitches - Add focusin, visibilitychange, and pageshow listeners to clear stale offset when returning from background apps or restoring tabs - Schedule two-stage focusout cleanup (50ms and 350ms) to ensure keyboard height drops to 0 and resets lingering window scroll
New sessions now read the provider's configured permission mode from the user preference store instead of a separate permissionMode-last-* key, removing the dual-channel drift between the settings page and composer. Unsent choices stay in an in-memory draft map until the session id is established, then persist under the session-scoped key.
…ge rows Codex engine 0.153.4 (brought in by 5ad4b31) stopped writing legacy event_msg/user_message rows; the typed prompt now arrives as an event_msg/item_completed whose item is a UserMessage. The history reader only matched the legacy shape, so every codex session opened after the upgrade lost its user messages from history and exports (assistant rows were unaffected: response_item parsing unchanged). Parse the new UserMessage items with the same turn-anchoring discipline as the legacy branch (first prompt of a turn anchors it, so edit/fork cuts stay addressable). Injected context (AGENTS.md, plugin lists) rides unnamed response_item user messages and stays excluded, same as before. UserMessage items only appear as item_completed (never item_started), so there is no double-count risk. Regression test mirrors a real 0.153.4 rollout turn sequence; verified against the production rollout file: 3 user prompts + 11 assistant rows recovered, no injected-context leakage.
Claude's permissions tab now shows the same permission-mode radio cards the other agents have, covering all five modes from the capability catalog (default, auto, acceptEdits, bypassPermissions, plan). The mode persists in the claudePermissions preference, which the composer already reads as the new-session default, so claude chats no longer always start in 'default'. - ClaudePermissionsState gains a permissionMode field, normalized on load and written on save by the settings controller - In-chat permission grants keep the stored mode instead of wiping it - Mode card copy added to en/zh-CN; other locales fall back to en - Drop the unused duplicate settings/types/types.ts
…mission descriptions
The composer permission menu reuses codex.descriptions.* copy for every
provider, and the default/acceptEdits texts described codex's sandbox
semantics ("commands run automatically inside the workspace sandbox"),
which is wrong for claude, whose default mode asks for approval. Rewrite
them in en/zh-CN/zh-TW as provider-neutral wording that stays true for
every provider. Also translate the auto mode label and description into
zh-CN, which had been left in English.
…r of the mode card The checkbox and the bypassPermissions mode card converged on the same runtime state (both ended up as the SDK's bypassPermissions), and the checkbox's hard override silently defeated per-session mode choices — only plan mode took precedence. The mode card is now the single entry point; existing stored flags are deliberately left inert rather than migrated. - ClaudePermissionsState/ClaudeSettings drop skipPermissions; the legacy claude-settings hydrate no longer copies it - chat.send no longer sends skipPermissions for claude, so a stale stored flag can never override the mode again (server untouched) - toClaudePermissionMode moves to chatStorage so the storage reader and the settings controller share one normalization - The in-app terminal's bypass toggle seeds from the stored default permission mode instead of the removed flag - Cursor keeps its checkbox; its settings surface is unchanged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
概要
合并上游 siteboon/claudecodeui v1.37.3 到本 fork 的 main 分支。
主要变更
<synthetic>模型占位符(fix(claude): ignore <synthetic> model placeholder when resolving session model siteboon/claudecodeui#1207)、.mts/.cts/.mjs/.cjs 语法高亮(fix(editor): syntax highlighting for .mts, .cts, .mjs and .cjs siteboon/claudecodeui#1223)、发布流程修复(fix(release): expose npm publish failures siteboon/claudecodeui#1271)规模
19 个提交,129 个文件,+4269 / -1107。
测试计划
npm run build)🤖 Generated with Claude Code