-
Notifications
You must be signed in to change notification settings - Fork 320
feat: Interactive shell streaming with live output #562
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,187 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import * as React from "react"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import {cx} from "class-variance-authority"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Banner as PrimitiveBanner, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Button as PrimitiveButton, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| FilterButton as PrimitiveFilterButton, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| NumberStepper as PrimitiveNumberStepper, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } from "@spacedrive/primitives"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| export * from "@spacedrive/primitives"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| type LegacyButtonVariant = "ghost" | "secondary" | "destructive"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| type PrimitiveButtonVariant = NonNullable< | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| React.ComponentProps<typeof PrimitiveButton>["variant"] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| >; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| type PrimitiveButtonSize = React.ComponentProps<typeof PrimitiveButton>["size"]; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| type PrimitiveButtonRounding = | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| React.ComponentProps<typeof PrimitiveButton>["rounding"]; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| type ButtonVariant = PrimitiveButtonVariant | LegacyButtonVariant; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| type CompatButtonBaseProps = { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| children?: React.ReactNode; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| className?: string; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| loading?: boolean; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| rounding?: PrimitiveButtonRounding; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| size?: PrimitiveButtonSize; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| variant?: ButtonVariant; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| type CompatActionButtonProps = CompatButtonBaseProps & | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, "children"> & { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| href?: undefined; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| type CompatLinkButtonProps = CompatButtonBaseProps & | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Omit<React.AnchorHTMLAttributes<HTMLAnchorElement>, "children"> & { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| href: string; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| type CompatButtonProps = CompatActionButtonProps | CompatLinkButtonProps; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| function hasHref( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| props: CompatButtonProps, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ): props is CompatLinkButtonProps { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return "href" in props && props.href !== undefined; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| function mapButtonVariant( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| variant: ButtonVariant | undefined, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ): PrimitiveButtonVariant | undefined { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| switch (variant) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| case "ghost": | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return "subtle"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| case "secondary": | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return "gray"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| case "destructive": | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return "outline"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| default: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return variant; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| function legacyButtonClassName(variant: ButtonVariant | undefined) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (variant === "destructive") { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return "border-red-500/40 text-red-300 hover:border-red-500/60 hover:bg-red-500/10"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return undefined; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| function LoadingSpinner() { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <span | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| aria-hidden="true" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| className="inline-block size-3 shrink-0 animate-spin rounded-full border border-current border-t-transparent" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| export const Button = React.forwardRef< | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| React.ElementRef<typeof PrimitiveButton>, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| CompatButtonProps | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| >(({variant, loading = false, className, children, ...props}, ref) => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const buttonClassName = cx(legacyButtonClassName(variant), className); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const buttonVariant = mapButtonVariant(variant); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const content = ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| {loading ? <LoadingSpinner /> : null} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| {children} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (hasHref(props)) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <PrimitiveButton | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| {...props} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ref={ref} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| variant={buttonVariant} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| className={buttonClassName} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| > | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| {content} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </PrimitiveButton> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+89
to
+99
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Apply the loading guard in the This branch renders the spinner, but unlike the action-button path it never marks the control busy/disabled or blocks activation. A loading link can still be focused and clicked, which makes the wrapper look disabled while remaining interactive. Suggested patch if (hasHref(props)) {
+ const {onClick, tabIndex, ...linkProps} = props;
return (
<PrimitiveButton
- {...props}
+ {...linkProps}
ref={ref}
+ aria-busy={loading || undefined}
+ aria-disabled={loading || undefined}
+ tabIndex={loading ? -1 : tabIndex}
+ onClick={(event) => {
+ if (loading) {
+ event.preventDefault();
+ event.stopPropagation();
+ return;
+ }
+ onClick?.(event);
+ }}
variant={buttonVariant}
- className={buttonClassName}
+ className={cx(buttonClassName, loading && "pointer-events-none")}
>
{content}
</PrimitiveButton>
);
}📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const actionProps = props as CompatActionButtonProps; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <PrimitiveButton | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| {...actionProps} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ref={ref} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| disabled={loading || actionProps.disabled} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| aria-busy={loading || undefined} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| variant={buttonVariant} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| className={buttonClassName} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| > | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| {content} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </PrimitiveButton> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Button.displayName = "Button"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| type BannerDotMode = "pulse" | "static"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| type CompatBannerProps = React.ComponentProps<typeof PrimitiveBanner> & { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| dot?: BannerDotMode; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| export const Banner = React.forwardRef< | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| React.ElementRef<typeof PrimitiveBanner>, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| CompatBannerProps | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| >(({dot, showDot, className, ...props}, ref) => ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <PrimitiveBanner | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| {...props} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ref={ref} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| showDot={showDot ?? dot !== undefined} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| className={cx( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| dot === "pulse" && "[&>span:first-child]:animate-pulse", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| className, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| )} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| )); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Banner.displayName = "Banner"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| type CompatFilterButtonProps = React.ComponentProps< | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| typeof PrimitiveFilterButton | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| > & { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| colorClass?: string; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| export const FilterButton = React.forwardRef< | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| React.ElementRef<typeof PrimitiveFilterButton>, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| CompatFilterButtonProps | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| >(({colorClass, active, className, ...props}, ref) => ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <PrimitiveFilterButton | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| {...props} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ref={ref} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| active={active} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| className={cx(active && colorClass, className)} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| )); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| FilterButton.displayName = "FilterButton"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| type CompatNumberStepperProps = React.ComponentProps< | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| typeof PrimitiveNumberStepper | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| > & { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| type?: "float" | "int"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| variant?: string; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| export const NumberStepper = React.forwardRef< | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| React.ElementRef<typeof PrimitiveNumberStepper>, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| CompatNumberStepperProps | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| >(({type, variant: _variant, allowFloat, ...props}, ref) => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Only pass allowFloat when explicitly provided or when type === "float" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // so PrimitiveNumberStepper can use its own default when neither is set. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const resolvedAllowFloat = allowFloat !== undefined | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ? allowFloat | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| : (type === "float" ? true : undefined); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <PrimitiveNumberStepper | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| {...props} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ref={ref} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| allowFloat={resolvedAllowFloat} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| NumberStepper.displayName = "NumberStepper"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't use placeholder
tool_resultsteps as the completion signal.interface/src/hooks/useLiveContext.tsx:239-275now creates a temporarytool_resultwithtext: ""just to carrylive_outputwhile the tool is still running. Line 91'sresult ? ... : "running"heuristic treats that placeholder as a real completion, so the card flips out of the running state on the first streamed line and the live-output branch below becomes effectively dead. It also leaves no way to represent the newwaiting_for_inputshell outcome distinctly from a hard error. Please carry an explicit pending/final status instead of deriving it from the presence of atool_resultrecord.Also applies to: 82-93
🤖 Prompt for AI Agents