release v1.22.0
This commit is contained in:
@@ -4,6 +4,8 @@ All notable changes to this project will be documented in this file.
|
|||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
|
## [1.22.0] - 2026-08-30
|
||||||
|
|
||||||
- **Linear integration:** connect a workspace in Settings → Integrations, browse and filter issues, and start a session or worktree from an issue. OpenChamber reports session progress back to Linear and can attach an issue to the next chat message (thanks to @AlexKutas).
|
- **Linear integration:** connect a workspace in Settings → Integrations, browse and filter issues, and start a session or worktree from an issue. OpenChamber reports session progress back to Linear and can attach an issue to the next chat message (thanks to @AlexKutas).
|
||||||
- **Voice:** local text-to-speech and macOS say now choose a voice that matches the reply's language. Additional local models download on first use, and the voice picker lists voices from every installed model.
|
- **Voice:** local text-to-speech and macOS say now choose a voice that matches the reply's language. Additional local models download on first use, and the voice picker lists voices from every installed model.
|
||||||
- **Git:** projects containing several repositories can now switch between them from the Git tab. Diff, pull request, walkthrough, mobile Changes, and work status follow the selected repository (thanks to @jaygupta17).
|
- **Git:** projects containing several repositories can now switch between them from the Git tab. Diff, pull request, walkthrough, mobile Changes, and work status follow the selected repository (thanks to @jaygupta17).
|
||||||
|
|||||||
@@ -97,7 +97,7 @@
|
|||||||
},
|
},
|
||||||
"packages/electron": {
|
"packages/electron": {
|
||||||
"name": "@openchamber/electron",
|
"name": "@openchamber/electron",
|
||||||
"version": "1.21.0",
|
"version": "1.22.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@openchamber/web": "workspace:*",
|
"@openchamber/web": "workspace:*",
|
||||||
"electron-context-menu": "^4.1.2",
|
"electron-context-menu": "^4.1.2",
|
||||||
@@ -134,7 +134,7 @@
|
|||||||
},
|
},
|
||||||
"packages/ui": {
|
"packages/ui": {
|
||||||
"name": "@openchamber/ui",
|
"name": "@openchamber/ui",
|
||||||
"version": "1.21.0",
|
"version": "1.22.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@aparajita/capacitor-secure-storage": "^8.0.0",
|
"@aparajita/capacitor-secure-storage": "^8.0.0",
|
||||||
"@base-ui/react": "^1.4.0",
|
"@base-ui/react": "^1.4.0",
|
||||||
@@ -241,7 +241,7 @@
|
|||||||
},
|
},
|
||||||
"packages/vscode": {
|
"packages/vscode": {
|
||||||
"name": "openchamber",
|
"name": "openchamber",
|
||||||
"version": "1.21.0",
|
"version": "1.22.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@openchamber/ui": "workspace:*",
|
"@openchamber/ui": "workspace:*",
|
||||||
"@opencode-ai/sdk": "1.18.25",
|
"@opencode-ai/sdk": "1.18.25",
|
||||||
@@ -264,7 +264,7 @@
|
|||||||
},
|
},
|
||||||
"packages/web": {
|
"packages/web": {
|
||||||
"name": "@openchamber/web",
|
"name": "@openchamber/web",
|
||||||
"version": "1.21.0",
|
"version": "1.22.0",
|
||||||
"bin": {
|
"bin": {
|
||||||
"openchamber": "./bin/cli.js",
|
"openchamber": "./bin/cli.js",
|
||||||
},
|
},
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "openchamber-monorepo",
|
"name": "openchamber-monorepo",
|
||||||
"version": "1.21.1",
|
"version": "1.22.0",
|
||||||
"description": "OpenChamber monorepo workspace for web, ui, and desktop runtimes",
|
"description": "OpenChamber monorepo workspace for web, ui, and desktop runtimes",
|
||||||
"private": true,
|
"private": true,
|
||||||
"type": "module",
|
"type": "module",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@openchamber/electron",
|
"name": "@openchamber/electron",
|
||||||
"version": "1.21.1",
|
"version": "1.22.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"description": "Electron desktop runtime for OpenChamber",
|
"description": "Electron desktop runtime for OpenChamber",
|
||||||
"author": "OpenChamber",
|
"author": "OpenChamber",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@openchamber/ui",
|
"name": "@openchamber/ui",
|
||||||
"version": "1.21.1",
|
"version": "1.22.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "src/main.tsx",
|
"main": "src/main.tsx",
|
||||||
|
|||||||
@@ -748,7 +748,11 @@ export const ChatContainer: React.FC<ChatContainerProps> = ({
|
|||||||
// One gate per opened session; the scroll hook holds it until the
|
// One gate per opened session; the scroll hook holds it until the
|
||||||
// viewport is pinned to the end so the first visible frame is already
|
// viewport is pinned to the end so the first visible frame is already
|
||||||
// at the bottom.
|
// at the bottom.
|
||||||
const revealGate = React.useMemo(() => createTimelineRevealGate(), [currentSessionKey]);
|
const revealGateRef = React.useRef<{ key: string | null; gate: TimelineRevealGate } | null>(null);
|
||||||
|
if (revealGateRef.current?.key !== currentSessionKey) {
|
||||||
|
revealGateRef.current = { key: currentSessionKey, gate: createTimelineRevealGate() };
|
||||||
|
}
|
||||||
|
const revealGate = revealGateRef.current.gate;
|
||||||
const chatColumnSession = React.useMemo<ChatColumnSession>(
|
const chatColumnSession = React.useMemo<ChatColumnSession>(
|
||||||
() => ({ sessionId: currentSessionId ?? null, directory: currentSessionId ? effectiveSessionDirectory ?? null : null }),
|
() => ({ sessionId: currentSessionId ?? null, directory: currentSessionId ? effectiveSessionDirectory ?? null : null }),
|
||||||
[currentSessionId, effectiveSessionDirectory],
|
[currentSessionId, effectiveSessionDirectory],
|
||||||
|
|||||||
@@ -962,7 +962,7 @@ const useMorphdomMarkdown = ({
|
|||||||
// or re-decorating ordinary blocks.
|
// or re-decorating ordinary blocks.
|
||||||
refreshMermaidViewers();
|
refreshMermaidViewers();
|
||||||
}
|
}
|
||||||
}, [containerRef, text, streaming, imageMode, ctx, refreshMermaidViewers]);
|
}, [containerRef, text, streaming, imageMode, ctx, refreshMermaidViewers, revealGate]);
|
||||||
|
|
||||||
React.useEffect(() => () => {
|
React.useEffect(() => () => {
|
||||||
mermaidViewerRef.current?.cleanup();
|
mermaidViewerRef.current?.cleanup();
|
||||||
|
|||||||
@@ -29,7 +29,6 @@ import { useGlobalSessionsStore } from '@/stores/useGlobalSessionsStore';
|
|||||||
import { streamPerfCount } from '@/stores/utils/streamDebug';
|
import { streamPerfCount } from '@/stores/utils/streamDebug';
|
||||||
import { useFeatureFlagsStore } from '@/stores/useFeatureFlagsStore';
|
import { useFeatureFlagsStore } from '@/stores/useFeatureFlagsStore';
|
||||||
|
|
||||||
import { useRuntimeAPIs } from '@/hooks/useRuntimeAPIs';
|
|
||||||
import { useDesktopWindowControlsLayout } from '@/hooks/useDesktopWindowControlsLayout';
|
import { useDesktopWindowControlsLayout } from '@/hooks/useDesktopWindowControlsLayout';
|
||||||
import { ContextUsageDisplay } from '@/components/ui/ContextUsageDisplay';
|
import { ContextUsageDisplay } from '@/components/ui/ContextUsageDisplay';
|
||||||
import { WindowsWindowControls } from '@/components/desktop/WindowsWindowControls';
|
import { WindowsWindowControls } from '@/components/desktop/WindowsWindowControls';
|
||||||
|
|||||||
@@ -49,11 +49,11 @@ export function LinearProjectMapping({
|
|||||||
console.error('Failed to load Linear mapping:', error);
|
console.error('Failed to load Linear mapping:', error);
|
||||||
setLoadFailed(true);
|
setLoadFailed(true);
|
||||||
}
|
}
|
||||||
}, [connected, linear, organizationId]);
|
}, [connected, linear]);
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
void loadMapping();
|
void loadMapping();
|
||||||
}, [loadMapping]);
|
}, [loadMapping, organizationId]);
|
||||||
|
|
||||||
const saveMapping = React.useCallback(async (next: LinearMappingResult) => {
|
const saveMapping = React.useCallback(async (next: LinearMappingResult) => {
|
||||||
const teamProjectPaths: { [teamId: string]: string } = {};
|
const teamProjectPaths: { [teamId: string]: string } = {};
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
## [Unreleased]
|
## [1.22.0] - 2026-08-30
|
||||||
|
|
||||||
- Switching sessions is now visually stable, without conversation jumps or partial rendering.
|
- Switching sessions is now visually stable, without conversation jumps or partial rendering.
|
||||||
- Chat: a turn that OpenCode stopped no longer ends with nothing on screen — what OpenCode reported shows under the last message, and a message an idle session has left unanswered is named as such. The status report (Ctrl/Cmd+Shift+L) now lists the last session errors and rejected sends.
|
- Chat: a turn that OpenCode stopped no longer ends with nothing on screen — what OpenCode reported shows under the last message, and a message an idle session has left unanswered is named as such. The status report (Ctrl/Cmd+Shift+L) now lists the last session errors and rejected sends.
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
"name": "openchamber",
|
"name": "openchamber",
|
||||||
"displayName": "OpenChamber",
|
"displayName": "OpenChamber",
|
||||||
"description": "%extension.description%",
|
"description": "%extension.description%",
|
||||||
"version": "1.21.1",
|
"version": "1.22.0",
|
||||||
"publisher": "fedaykindev",
|
"publisher": "fedaykindev",
|
||||||
"private": true,
|
"private": true,
|
||||||
"repository": {
|
"repository": {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@openchamber/web",
|
"name": "@openchamber/web",
|
||||||
"version": "1.21.1",
|
"version": "1.22.0",
|
||||||
"private": false,
|
"private": false,
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "./server/index.js",
|
"main": "./server/index.js",
|
||||||
|
|||||||
Reference in New Issue
Block a user