You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maka.apache.org by as...@apache.org on 2026/08/23 07:41:31 UTC
(maka) branch main updated: feat(desktop): improve active goal status bar (#3535)
This is an automated email from the ASF dual-hosted git repository.
Astro-Han pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/maka.git
The following commit(s) were added to refs/heads/main by this push:
new b2785b479 feat(desktop): improve active goal status bar (#3535)
b2785b479 is described below
commit b2785b4797def7dbb12dde71bed5ae2454775e54
Author: yum <ya...@chihum.dev>
AuthorDate: Sun Aug 23 15:41:27 2026 +0800
feat(desktop): improve active goal status bar (#3535)
Generated-by: Codex
---
apps/desktop/src/renderer/styles/chat-header.css | 27 ++++++++++++++++++++++
docs/astryx-surface-file-inventory.md | 2 +-
.../__tests__/session-context-layer-goal.test.tsx | 3 +++
packages/ui/src/session-context-layer.tsx | 12 +++++++++-
4 files changed, 42 insertions(+), 2 deletions(-)
diff --git a/apps/desktop/src/renderer/styles/chat-header.css b/apps/desktop/src/renderer/styles/chat-header.css
index 13416f06e..a26249d76 100644
--- a/apps/desktop/src/renderer/styles/chat-header.css
+++ b/apps/desktop/src/renderer/styles/chat-header.css
@@ -84,6 +84,16 @@
-webkit-app-region: no-drag;
}
+/* A live Goal can keep creating Turns after the user stops typing, so its
+ identity and kill switches stay reachable while the transcript scrolls.
+ Ordinary lineage/revision context remains in-flow when no Goal is present. */
+.maka-session-context[data-has-goal="true"] {
+ position: sticky;
+ top: 0;
+ z-index: var(--z-sticky);
+ box-shadow: 0 var(--border-width-hairline) 0 var(--border-soft);
+}
+
.maka-session-context__inner {
min-width: 0;
/* Control rhythm 36 (lg) — band holds sm/md controls without off-ladder 40. */
@@ -124,6 +134,23 @@
white-space: nowrap;
}
+.maka-session-context__goal-description {
+ display: block;
+ min-width: 0;
+ overflow: hidden;
+ padding-left: var(--space-1);
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
+
+/* Goal rows are intentionally single-line, but Astryx tooltip layers inherit
+ typography from their trigger subtree even after entering the top layer.
+ Restore the Tooltip contract here so long Goal copy wraps inside its 300px
+ content measure instead of being clipped as one unbreakable line. */
+.maka-session-context [role="tooltip"] {
+ white-space: normal;
+}
+
.maka-session-context__cluster {
width: min(100%, 560px);
justify-self: end;
diff --git a/docs/astryx-surface-file-inventory.md b/docs/astryx-surface-file-inventory.md
index 780b9c273..9119fcd6a 100644
--- a/docs/astryx-surface-file-inventory.md
+++ b/docs/astryx-surface-file-inventory.md
@@ -208,7 +208,7 @@ Wiki bar: Design Conventions · API Use-the-System · Theming · Container Paddi
| `packages/ui/src/scheduled-task-inspector.tsx` | module-hub | Button, Divider, HStack, Heading, List, ListItem, MetadataList, MetadataListItem, Switch, Text, VStack | aligned — uses Astryx (Button, Divider, HStack, Heading, List, ListItem, MetadataList, MetadataListItem) | aligned |
| `packages/ui/src/scheduled-task-panel.tsx` | module-hub | Button, Divider, EmptyState, List, ListItem, SegmentedControl, SegmentedControlItem, Selector, Text, TextInput, Toolbar | aligned — uses Astryx (Button, Divider, EmptyState, List, ListItem, SegmentedControl, SegmentedControlItem, Selector) | aligned |
| `packages/ui/src/search-modal.tsx` | dialog-overlay | none | aligned — no raw controls; no Astryx JSX usage | aligned |
-| `packages/ui/src/session-context-layer.tsx` | shell-chrome-or-panel | BreadcrumbItem, Breadcrumbs, IconButton, LayoutHeader, Text, Token | aligned — uses Astryx (BreadcrumbItem, Breadcrumbs, IconButton, LayoutHeader, Text, Token) | aligned |
+| `packages/ui/src/session-context-layer.tsx` | shell-chrome-or-panel | BreadcrumbItem, Breadcrumbs, IconButton, LayoutHeader, Text, Token, Tooltip | aligned — uses Astryx (BreadcrumbItem, Breadcrumbs, IconButton, LayoutHeader, Text, Token, Tooltip) | aligned |
| `packages/ui/src/session-history-list.tsx` | shell-chrome-or-panel | Badge, VStack | aligned — uses Astryx (Badge, VStack) | aligned |
| `packages/ui/src/session-list-panel.tsx` | shell-chrome-or-panel | SegmentedControl, SegmentedControlItem, SideNav | aligned — uses Astryx (SegmentedControl, SegmentedControlItem, SideNav) | aligned |
| `packages/ui/src/session-rename-dialog.tsx` | dialog-overlay | Button, Dialog, DialogHeader, HStack, Layout, LayoutContent, TextInput | aligned — uses Astryx (Button, Dialog, DialogHeader, HStack, Layout, LayoutContent, TextInput) | aligned |
diff --git a/packages/ui/src/__tests__/session-context-layer-goal.test.tsx b/packages/ui/src/__tests__/session-context-layer-goal.test.tsx
index ee3ac1463..2466d8b71 100644
--- a/packages/ui/src/__tests__/session-context-layer-goal.test.tsx
+++ b/packages/ui/src/__tests__/session-context-layer-goal.test.tsx
@@ -50,6 +50,8 @@ test('a running goal reads as running and offers pause, with elapsed and tokens'
onClear: () => undefined,
});
assert.ok(markup.includes('Goal 3 of 50'));
+ assert.ok(markup.includes('Ship the feature'));
+ assert.ok(markup.includes('role="tooltip"'));
assert.ok(markup.includes('12m'));
assert.ok(markup.includes('12k / 100k'));
assert.ok(markup.includes('Autonomous goal running'));
@@ -58,6 +60,7 @@ test('a running goal reads as running and offers pause, with elapsed and tokens'
assert.ok(!markup.includes('Resume autonomous goal'));
// The clear kill switch stays.
assert.ok(markup.includes('Clear autonomous goal after 3/50 iterations'));
+ assert.ok(markup.includes('data-has-goal="true"'));
});
test('a paused goal reads as paused and offers resume, not pause', () => {
diff --git a/packages/ui/src/session-context-layer.tsx b/packages/ui/src/session-context-layer.tsx
index ec881657b..ddc9b62e2 100644
--- a/packages/ui/src/session-context-layer.tsx
+++ b/packages/ui/src/session-context-layer.tsx
@@ -30,6 +30,7 @@ import {
StatusDot,
Text,
Token,
+ Tooltip,
type DropdownMenuOption,
} from '@astryxdesign/core';
import { getConversationCopy } from './conversation-copy.js';
@@ -348,6 +349,7 @@ export function SessionContextLayer(props: {
label={copy.sessionContextAriaLabel}
className="maka-session-context"
data-session-context-layer="true"
+ data-has-goal={props.goal ? 'true' : undefined}
>
<div className="maka-session-context__inner">
{/* Lineage only. The session's own name moved to the window titlebar
@@ -356,7 +358,15 @@ export function SessionContextLayer(props: {
twice. What stays is what the titlebar cannot answer: which session
this one branched FROM. */}
<div className="maka-session-context__lineage">
- {props.branch ? (
+ {props.goal ? (
+ <Tooltip content={props.goal.condition}>
+ <div className="maka-session-context__goal-description">
+ <Text type="supporting" maxLines={1}>
+ {props.goal.condition}
+ </Text>
+ </div>
+ </Tooltip>
+ ) : props.branch ? (
<Breadcrumbs
label={copy.sessionLineageAriaLabel}
variant="supporting"
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@maka.apache.org
For additional commands, e-mail: commits-help@maka.apache.org