feat(web): new task opens straight into chat, context rail waits for content, frosted windows
Some checks failed
ci / build-test (push) Has been cancelled
ci / docker-build (push) Has been cancelled
ci / web (push) Has been cancelled
Desktop App / Build Linux (amd64) (push) Has been cancelled
Desktop App / Attach to Release (push) Has been cancelled

New Task now opens directly as an empty ChatThread (NewTaskChat) instead of
a separate compose screen, sized like a real task window. The Scope/Activity
context rail in a task window no longer renders until there's actually
something to show (touched entities, activity, or an open question),
avoiding an empty-placeholder sidebar on every new task. Also fixes the
chat input defaulting to several lines tall on window open, centers the
empty-chat greeting vertically, and gives floating windows the same
frosted-glass look as the desktop's task launcher card.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-21 09:50:47 +02:00
parent ce34cfeac7
commit 6b6bfe1fd8
7 changed files with 107 additions and 23 deletions

View File

@@ -0,0 +1,29 @@
<script lang="ts">
// Content for the "new-task" window slot (windows.ts openNewTaskWindow) —
// a real ChatThread in its empty state rather than a separate compose
// screen, so starting a task looks and feels exactly like the task chat
// it becomes. Submitting the first message starts the task via
// startTask() and hands off to the real session window (see windows.ts's
// openTaskWindow) the moment the backend assigns an id.
import { startTask } from '$lib/stores/chat'
import { openTaskWindow, wm, NEW_TASK_WINDOW_ID } from '$lib/stores/windows'
import { truncateMiddle } from '$lib/utils'
import ChatThread from '$lib/components/ChatThread.svelte'
function onSend(text: string) {
startTask(text, (sessionId) => {
openTaskWindow(sessionId, truncateMiddle(text, 60))
wm.close(NEW_TASK_WINDOW_ID)
})
}
</script>
<ChatThread
messages={[]}
streaming={false}
connectionState="connected"
onSend={onSend}
onCancel={() => {}}
onReconnect={() => {}}
onDismissError={() => {}}
/>

View File

@@ -7,13 +7,13 @@
// wmPersist in windows.ts) need no extra bookkeeping to know what to render:
// app:<id> -> registry component (windows.ts openAppWindow)
// session:<id> -> SessionChatWindow (windows.ts openTaskWindow)
// new-task -> TaskLauncher (windows.ts openNewTaskWindow)
// new-task -> NewTaskChat (windows.ts openNewTaskWindow)
// anything else -> entity slug -> EntityDetailContent
import { wm, dk, wmState, openEntityWindow, NEW_TASK_WINDOW_ID } from '$lib/stores/windows'
import { appById, appIdFromWindowId } from '$lib/apps'
import EntityDetailContent from '../EntityDetailContent.svelte'
import SessionChatWindow from '../SessionChatWindow.svelte'
import TaskLauncher from './TaskLauncher.svelte'
import NewTaskChat from './NewTaskChat.svelte'
import XIcon from '@lucide/svelte/icons/x'
import MinusIcon from '@lucide/svelte/icons/minus'
import Maximize2Icon from '@lucide/svelte/icons/maximize-2'
@@ -73,9 +73,7 @@
{#if id.startsWith(SESSION_PREFIX)}
<SessionChatWindow sessionId={id.slice(SESSION_PREFIX.length)} />
{:else if id === NEW_TASK_WINDOW_ID}
<div class="flex h-full items-center justify-center p-6">
<TaskLauncher onStarted={() => wm.close(NEW_TASK_WINDOW_ID)} />
</div>
<NewTaskChat />
{:else if app}
<app.component />
{:else}