@cueloop/client 0.1.0-alpha.31 → 0.1.0-alpha.33
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +5 -5
- package/src/App.autoclose.test.tsx +4 -3
- package/src/App.diff.test.tsx +5 -2
- package/src/App.export.test.tsx +5 -7
- package/src/App.plan-review.test.tsx +14 -17
- package/src/App.readonly.test.tsx +9 -7
- package/src/App.rendering.test.tsx +6 -2
- package/src/App.review-panel.test.tsx +19 -14
- package/src/App.submit-confirm.test.tsx +6 -7
- package/src/App.test.tsx +8 -5
- package/src/App.toast.test.tsx +68 -0
- package/src/App.tsx +154 -50
- package/src/App.walk.test.tsx +7 -4
- package/src/components/AnnotationCard.stories.tsx +1 -1
- package/src/components/AnnotationCard.tsx +18 -13
- package/src/components/CompletionOverlay.tsx +1 -1
- package/src/components/ConfirmCard.tsx +1 -0
- package/src/components/ConfirmDialog.stories.tsx +1 -1
- package/src/components/ConfirmDialog.tsx +1 -1
- package/src/components/DiffSheet.stories.tsx +21 -3
- package/src/components/DiffSheet.tsx +45 -19
- package/src/components/InboxList.stories.tsx +1 -1
- package/src/components/InboxList.tsx +3 -3
- package/src/components/KeybindsDialog.stories.tsx +31 -0
- package/src/components/KeybindsDialog.tsx +42 -0
- package/src/components/MenuBar.stories.tsx +33 -0
- package/src/components/MenuBar.tsx +58 -0
- package/src/components/PlanSheet.stories.tsx +2 -2
- package/src/components/PlanSheet.tsx +26 -75
- package/src/components/PromptDialog.stories.tsx +2 -2
- package/src/components/PromptDialog.tsx +1 -1
- package/src/components/ReviewPanel.stories.tsx +5 -17
- package/src/components/ReviewPanel.tsx +10 -29
- package/src/components/ReviewRail.stories.tsx +39 -0
- package/src/components/ReviewRail.tsx +62 -57
- package/src/components/SettingsDialog.stories.tsx +1 -1
- package/src/components/SettingsDialog.tsx +4 -3
- package/src/components/SettingsRows.stories.tsx +1 -1
- package/src/components/SettingsRows.tsx +1 -1
- package/src/components/Toast.stories.tsx +12 -0
- package/src/components/Toast.tsx +29 -0
- package/src/components/WalkWizard.stories.tsx +1 -1
- package/src/components/WalkWizard.tsx +1 -1
- package/src/components/__snapshots__/stories.test.tsx.snap +598 -566
- package/src/components/primitives/Button.stories.tsx +2 -2
- package/src/components/primitives/Dialog.stories.tsx +1 -1
- package/src/components/primitives/Dialog.tsx +7 -5
- package/src/components/primitives/Tabs.tsx +19 -38
- package/src/components/stories-app.tsx +1 -1
- package/src/components/stories.test.tsx +2 -0
- package/src/key-bindings.test.ts +4 -4
- package/src/key-bindings.ts +41 -2
- package/src/serve.test.ts +2 -2
- package/src/session-controller.share.test.ts +13 -0
- package/src/session-controller.ts +19 -1
- package/src/test-support.test.ts +55 -0
- package/src/test-support.ts +113 -23
- package/src/theme.ts +16 -16
- package/src/version.ts +5 -0
- package/src/components/ComposeBar.stories.tsx +0 -18
- package/src/components/ComposeBar.tsx +0 -54
|
@@ -14,16 +14,12 @@ import type { Annotation } from "@cueloop/schema";
|
|
|
14
14
|
import type { Theme } from "../theme";
|
|
15
15
|
import { useComponentTheme } from "./theme-context";
|
|
16
16
|
import { ReviewRail, type ReviewRailHandle, type ReviewRailProps } from "./ReviewRail";
|
|
17
|
-
import { REVIEW_COMPACT_WIDTH,
|
|
17
|
+
import { REVIEW_COMPACT_WIDTH, type ReviewPanelMode } from "../review-panel";
|
|
18
18
|
|
|
19
19
|
export interface ReviewPanelProps {
|
|
20
20
|
mode: ReviewPanelMode;
|
|
21
21
|
/** Expanded-rail width in columns (already clamped by the app). */
|
|
22
22
|
width: number;
|
|
23
|
-
/** Rows for the divider glyph column - the height of the plan/rail row. */
|
|
24
|
-
height: number;
|
|
25
|
-
/** Accent the divider while a drag is live. */
|
|
26
|
-
dragging: boolean;
|
|
27
23
|
/** Arm a divider drag; the app tracks the drag itself on the container. */
|
|
28
24
|
onDividerGrab: () => void;
|
|
29
25
|
/** Chevron click: expanded <-> compact (never hidden). */
|
|
@@ -34,28 +30,15 @@ export interface ReviewPanelProps {
|
|
|
34
30
|
theme?: Theme;
|
|
35
31
|
}
|
|
36
32
|
|
|
37
|
-
/**
|
|
38
|
-
function ReviewDivider({
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
onGrab
|
|
42
|
-
theme,
|
|
43
|
-
}: {
|
|
44
|
-
dragging: boolean;
|
|
45
|
-
rows: number;
|
|
46
|
-
onGrab: () => void;
|
|
47
|
-
theme?: Theme;
|
|
48
|
-
}): React.ReactNode {
|
|
49
|
-
const tokens = useComponentTheme(theme);
|
|
50
|
-
return (
|
|
51
|
-
<box style={{ width: 1 }} onMouseDown={onGrab}>
|
|
52
|
-
<text fg={dragging ? tokens.accent : tokens.border}>{reviewRowsToDivider(rows)}</text>
|
|
53
|
-
</box>
|
|
54
|
-
);
|
|
33
|
+
/** An invisible, full-height grab column: the plan's right border is the seam. */
|
|
34
|
+
function ReviewDivider({ onGrab }: { onGrab: () => void }): React.ReactNode {
|
|
35
|
+
// childless: it stretches to the row height like the plan and rail beside it,
|
|
36
|
+
// so the three columns share one bottom edge. Invisible, but full-height grab.
|
|
37
|
+
return <box style={{ width: 1 }} onMouseDown={onGrab} />;
|
|
55
38
|
}
|
|
56
39
|
|
|
57
40
|
/** The compact strip: the card count, one kind-colored dot per card, and the
|
|
58
|
-
*
|
|
41
|
+
* `<` expand chevron, bottom-padded to sit at the same row as the expanded `>`. */
|
|
59
42
|
function CompactRail({
|
|
60
43
|
annotations,
|
|
61
44
|
onExpand,
|
|
@@ -70,7 +53,7 @@ function CompactRail({
|
|
|
70
53
|
annotation.kind === "suggestion" ? tokens.green : tokens.accent;
|
|
71
54
|
return (
|
|
72
55
|
<box
|
|
73
|
-
style={{ width: REVIEW_COMPACT_WIDTH, backgroundColor: tokens.panel, flexDirection: "column", paddingTop: 1 }}
|
|
56
|
+
style={{ width: REVIEW_COMPACT_WIDTH, backgroundColor: tokens.panel, flexDirection: "column", paddingTop: 1, paddingBottom: 1 }}
|
|
74
57
|
>
|
|
75
58
|
<box style={{ alignItems: "center" }}>
|
|
76
59
|
<text fg={tokens.accent}>{String(annotations.length)}</text>
|
|
@@ -85,7 +68,7 @@ function CompactRail({
|
|
|
85
68
|
</box>
|
|
86
69
|
<box style={{ flexGrow: 1 }} />
|
|
87
70
|
<box style={{ paddingLeft: 1 }} onMouseUp={onExpand}>
|
|
88
|
-
<text fg={tokens.textDim}
|
|
71
|
+
<text fg={tokens.textDim}>{"<"}</text>
|
|
89
72
|
</box>
|
|
90
73
|
</box>
|
|
91
74
|
);
|
|
@@ -94,8 +77,6 @@ function CompactRail({
|
|
|
94
77
|
export function ReviewPanel({
|
|
95
78
|
mode,
|
|
96
79
|
width,
|
|
97
|
-
height,
|
|
98
|
-
dragging,
|
|
99
80
|
onDividerGrab,
|
|
100
81
|
onToggle,
|
|
101
82
|
rail,
|
|
@@ -105,7 +86,7 @@ export function ReviewPanel({
|
|
|
105
86
|
if (mode === "hidden") return null;
|
|
106
87
|
return (
|
|
107
88
|
<>
|
|
108
|
-
<ReviewDivider
|
|
89
|
+
<ReviewDivider onGrab={onDividerGrab} />
|
|
109
90
|
{mode === "expanded" ? (
|
|
110
91
|
<ReviewRail ref={railRef} {...rail} width={width} onCollapse={onToggle} theme={theme} />
|
|
111
92
|
) : (
|
|
@@ -38,6 +38,45 @@ export const AnnotationStack: Story = {
|
|
|
38
38
|
size: { width: 40, height: 24 },
|
|
39
39
|
};
|
|
40
40
|
|
|
41
|
+
export const MixedOwnershipStack: Story = {
|
|
42
|
+
render: () => (
|
|
43
|
+
<RailFrame>
|
|
44
|
+
<ReviewRail
|
|
45
|
+
session={fixturePlanSession({
|
|
46
|
+
participants: [{ id: "SHA256:collab1", provider: "ssh", name: "Priya" }],
|
|
47
|
+
annotations: [
|
|
48
|
+
{
|
|
49
|
+
id: "own_note",
|
|
50
|
+
kind: "comment",
|
|
51
|
+
anchor: { quote: "persists sessions", prefix: "The daemon ", suffix: " to disk" },
|
|
52
|
+
body: "Which daemon owns this?",
|
|
53
|
+
createdAt: "2026-01-01T00:00:00Z",
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
id: "collab_note",
|
|
57
|
+
kind: "suggestion",
|
|
58
|
+
anchor: { quote: "move the store", prefix: "", suffix: "" },
|
|
59
|
+
body: "move it behind one interface",
|
|
60
|
+
author: "SHA256:collab1",
|
|
61
|
+
createdAt: "2026-01-01T00:00:01Z",
|
|
62
|
+
},
|
|
63
|
+
],
|
|
64
|
+
})}
|
|
65
|
+
authorNames={{}}
|
|
66
|
+
selectedId="own_note"
|
|
67
|
+
resolvedIds={new Set(["own_note", "collab_note"])}
|
|
68
|
+
railTab="review"
|
|
69
|
+
pendingCount={2}
|
|
70
|
+
cardEdit={null}
|
|
71
|
+
submitConfirm={null}
|
|
72
|
+
{...callbacks}
|
|
73
|
+
/>
|
|
74
|
+
</RailFrame>
|
|
75
|
+
),
|
|
76
|
+
expectedColors: [DARK.accent, DARK.blue],
|
|
77
|
+
size: { width: 40, height: 24 },
|
|
78
|
+
};
|
|
79
|
+
|
|
41
80
|
export const AgentTab: Story = {
|
|
42
81
|
render: () => (
|
|
43
82
|
<RailFrame>
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
import React, { forwardRef, useImperativeHandle, useRef } from "react";
|
|
10
10
|
import type { ScrollBoxRenderable } from "@opentui/core";
|
|
11
|
-
import { isAddressed, type Annotation, type ReviewSession } from "@cueloop/schema";
|
|
11
|
+
import { isAddressed, isAgentNote, type Annotation, type ReviewSession } from "@cueloop/schema";
|
|
12
12
|
import type { Theme } from "../theme";
|
|
13
13
|
import { useComponentTheme } from "./theme-context";
|
|
14
14
|
import { Tabs, Tab, TabList } from "./primitives/Tabs";
|
|
@@ -46,7 +46,7 @@ export interface ReviewRailProps {
|
|
|
46
46
|
/** Rail column width; the app derives it from the persisted review layout. */
|
|
47
47
|
width?: number;
|
|
48
48
|
/**
|
|
49
|
-
* When set, renders the muted
|
|
49
|
+
* When set, renders the muted `>` chevron pinned at the rail's bottom-left,
|
|
50
50
|
* one column from the divider. Clicking it collapses the panel to compact.
|
|
51
51
|
*/
|
|
52
52
|
onCollapse?: () => void;
|
|
@@ -83,6 +83,7 @@ export const ReviewRail = forwardRef<ReviewRailHandle, ReviewRailProps>(function
|
|
|
83
83
|
// addressed annotations leave the card list; a dim count keeps them honest
|
|
84
84
|
const openAnnotations = session.annotations.filter((annotation) => !isAddressed(annotation));
|
|
85
85
|
const addressedCount = session.annotations.length - openAnnotations.length;
|
|
86
|
+
const collaboratorsPresent = session.annotations.some((annotation) => annotation.author);
|
|
86
87
|
|
|
87
88
|
useImperativeHandle(handleRef, () => ({
|
|
88
89
|
revealCard: (annotationId: string): void => {
|
|
@@ -95,74 +96,78 @@ export const ReviewRail = forwardRef<ReviewRailHandle, ReviewRailProps>(function
|
|
|
95
96
|
}));
|
|
96
97
|
|
|
97
98
|
return (
|
|
98
|
-
<box style={{ width, backgroundColor: tokens.panel, flexDirection: "column", paddingLeft: 1,
|
|
99
|
+
<box style={{ width, backgroundColor: tokens.panel, flexDirection: "column", paddingLeft: 1, paddingBottom: 1 }}>
|
|
99
100
|
<Tabs selectedKey={railTab} onSelectionChange={(key) => onTabChange(key as RailTab)} theme={theme}>
|
|
100
101
|
<TabList>
|
|
101
|
-
<Tab id="review">
|
|
102
|
+
<Tab id="review">Review</Tab>
|
|
102
103
|
<Tab id="agent">Agent</Tab>
|
|
103
104
|
</TabList>
|
|
104
105
|
</Tabs>
|
|
105
|
-
<text> </text>
|
|
106
106
|
{railTab === "agent" ? (
|
|
107
|
-
<
|
|
107
|
+
<box style={{ flexGrow: 1, flexDirection: "column", paddingLeft: 2 }}>
|
|
108
|
+
<text> </text>
|
|
109
|
+
<AgentTab session={session} theme={theme} />
|
|
110
|
+
</box>
|
|
111
|
+
) : openAnnotations.length === 0 ? (
|
|
112
|
+
<box style={{ flexGrow: 1, alignItems: "center", justifyContent: "center" }}>
|
|
113
|
+
<text fg={tokens.textDim}>{session.annotations.length === 0 ? "no annotations yet" : "all annotations addressed"}</text>
|
|
114
|
+
</box>
|
|
108
115
|
) : (
|
|
109
|
-
|
|
116
|
+
<box style={{ flexGrow: 1, flexDirection: "column" }}>
|
|
110
117
|
{session.workingCopy !== undefined ? <text fg={tokens.textDim}>± plan edits → one diff</text> : null}
|
|
111
118
|
{addressedCount > 0 ? <text fg={tokens.textDim}>✓ {addressedCount} addressed by revision</text> : null}
|
|
112
|
-
{
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
119
|
+
<scrollbox ref={scrollRef} style={{ flexGrow: 1 }} focused={false}>
|
|
120
|
+
{openAnnotations.map((annotation) => (
|
|
121
|
+
<AnnotationCard
|
|
122
|
+
key={annotation.id}
|
|
123
|
+
id={`annotation-card-${annotation.id}`}
|
|
124
|
+
kind={annotation.kind}
|
|
125
|
+
quote={annotation.anchor.quote}
|
|
126
|
+
theme={theme}
|
|
127
|
+
saved={{
|
|
128
|
+
body: annotation.body,
|
|
129
|
+
isSelected: annotation.id === selectedId,
|
|
130
|
+
isOrphan: resolvedIds !== null && !resolvedIds.has(annotation.id),
|
|
131
|
+
isBlocking: annotationBlocking(annotation),
|
|
132
|
+
authorLabel: annotation.author ? resolveDisplayName(annotation.author, session.participants, authorNames) : undefined,
|
|
133
|
+
selfLabel: !annotation.author && !isAgentNote(annotation) && collaboratorsPresent ? "me" : undefined,
|
|
134
|
+
editing:
|
|
135
|
+
cardEdit && cardEdit.id === annotation.id
|
|
136
|
+
? {
|
|
137
|
+
text: cardEdit.text,
|
|
138
|
+
onInput: cardEdit.onInput,
|
|
139
|
+
onSave: cardEdit.onSave,
|
|
140
|
+
onCancel: cardEdit.onCancel,
|
|
141
|
+
}
|
|
142
|
+
: null,
|
|
143
|
+
onPress: () =>
|
|
144
|
+
annotation.id === selectedId ? onActivateCard(annotation.id) : onSelectCard(annotation.id),
|
|
145
|
+
}}
|
|
146
|
+
/>
|
|
147
|
+
))}
|
|
148
|
+
</scrollbox>
|
|
149
|
+
</box>
|
|
150
|
+
)}
|
|
151
|
+
{/* the confirm card keeps full width, above the footer row */}
|
|
152
|
+
{railTab !== "agent" && submitConfirm ? <ConfirmCard {...submitConfirm} theme={theme} /> : null}
|
|
153
|
+
{/* footer row: collapse chevron left-bound, the submit affordance inline
|
|
154
|
+
beside it, both on the rail's last row (the plan's bottom-border height) */}
|
|
155
|
+
<box style={{ flexDirection: "row", alignItems: "center", justifyContent: "space-between" }}>
|
|
156
|
+
{onCollapse ? (
|
|
157
|
+
<box onMouseUp={onCollapse}>
|
|
158
|
+
<text fg={tokens.textDim}>{">"}</text>
|
|
159
|
+
</box>
|
|
160
|
+
) : null}
|
|
161
|
+
{railTab !== "agent" && !submitConfirm ? (
|
|
162
|
+
session.status === "resolved" ? (
|
|
149
163
|
<text fg={tokens.green}>resolved: {session.verdict!.kind.replace("_", " ")}</text>
|
|
150
|
-
) : submitConfirm ? (
|
|
151
|
-
<ConfirmCard {...submitConfirm} theme={theme} />
|
|
152
164
|
) : (
|
|
153
165
|
<Button variant="accent-text" onPress={onSubmitRequest} theme={theme}>
|
|
154
|
-
|
|
166
|
+
Submit review
|
|
155
167
|
</Button>
|
|
156
|
-
)
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
{/* the collapse chevron: muted, left-bound, one column from the divider.
|
|
160
|
-
» points right - it hands the width back toward the plan */}
|
|
161
|
-
{onCollapse ? (
|
|
162
|
-
<box style={{ flexDirection: "row" }} onMouseUp={onCollapse}>
|
|
163
|
-
<text fg={tokens.textDim}>»</text>
|
|
164
|
-
</box>
|
|
165
|
-
) : null}
|
|
168
|
+
)
|
|
169
|
+
) : null}
|
|
170
|
+
</box>
|
|
166
171
|
</box>
|
|
167
172
|
);
|
|
168
173
|
});
|
|
@@ -57,6 +57,7 @@ export function SettingsDialog({
|
|
|
57
57
|
title=" Settings "
|
|
58
58
|
width={Math.min(76, terminalWidth - 6)}
|
|
59
59
|
height={Math.min(22, terminalHeight - 4)}
|
|
60
|
+
background={tokens.elevated}
|
|
60
61
|
theme={theme}
|
|
61
62
|
>
|
|
62
63
|
<box style={{ flexDirection: "row", flexGrow: 1 }}>
|
|
@@ -67,7 +68,7 @@ export function SettingsDialog({
|
|
|
67
68
|
return (
|
|
68
69
|
<box
|
|
69
70
|
key={candidate.id}
|
|
70
|
-
style={{ backgroundColor: isActive && activeZone === "nav" ? tokens.
|
|
71
|
+
style={{ backgroundColor: isActive && activeZone === "nav" ? tokens.border : undefined }}
|
|
71
72
|
onMouseUp={() => onCategorySelect(candidate.id)}
|
|
72
73
|
>
|
|
73
74
|
<text fg={isActive ? tokens.accent : tokens.textMuted}>{`${isActive ? "› " : " "}${candidate.name}`}</text>
|
|
@@ -120,10 +121,10 @@ export function SettingsDialog({
|
|
|
120
121
|
})}
|
|
121
122
|
</box>
|
|
122
123
|
</box>
|
|
123
|
-
<box style={{ flexDirection: "row", height: 1,
|
|
124
|
+
<box style={{ flexDirection: "row", height: 1, paddingLeft: 1 }}>
|
|
124
125
|
<text fg={tokens.textDim}>
|
|
125
126
|
{activeZone === "nav"
|
|
126
|
-
? "j/k category · l
|
|
127
|
+
? "j/k category · l/enter into settings · esc close"
|
|
127
128
|
: "j/k row · l/space change · h back · esc close"}
|
|
128
129
|
</text>
|
|
129
130
|
</box>
|
|
@@ -14,5 +14,5 @@ export const AllKinds: Story = {
|
|
|
14
14
|
<TextRow label="Vault path" value="~/vaults/notes" isActive={false} onPress={() => {}} />
|
|
15
15
|
</box>
|
|
16
16
|
),
|
|
17
|
-
expectedColors: [DARK.green, DARK.accent, DARK.
|
|
17
|
+
expectedColors: [DARK.green, DARK.accent, DARK.border],
|
|
18
18
|
};
|
|
@@ -29,7 +29,7 @@ function RowShell({ label, isActive, onPress, theme, children }: RowShellProps):
|
|
|
29
29
|
const tokens = useComponentTheme(theme);
|
|
30
30
|
return (
|
|
31
31
|
<box
|
|
32
|
-
style={{ flexDirection: "row", height: 1, backgroundColor: isActive ? tokens.
|
|
32
|
+
style={{ flexDirection: "row", height: 1, backgroundColor: isActive ? tokens.border : undefined }}
|
|
33
33
|
onMouseUp={onPress}
|
|
34
34
|
>
|
|
35
35
|
<box style={{ width: 26, paddingLeft: 1 }}>
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { DARK } from "../theme";
|
|
3
|
+
import type { Story, StoryMeta } from "./story";
|
|
4
|
+
import { Toast } from "./Toast";
|
|
5
|
+
|
|
6
|
+
export const meta: StoryMeta = { title: "Toast" };
|
|
7
|
+
|
|
8
|
+
export const ShareLink: Story = {
|
|
9
|
+
render: () => <Toast title="share link copied" body="ssh review-4f2a@cueloop.dev" />,
|
|
10
|
+
expectedColors: [DARK.accent],
|
|
11
|
+
size: { width: 60, height: 12 },
|
|
12
|
+
};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { useTerminalDimensions } from "@opentui/react";
|
|
3
|
+
import type { Theme } from "../theme";
|
|
4
|
+
import { useComponentTheme } from "./theme-context";
|
|
5
|
+
import { Dialog } from "./primitives/Dialog";
|
|
6
|
+
|
|
7
|
+
export interface ToastProps {
|
|
8
|
+
title?: string;
|
|
9
|
+
body: string;
|
|
10
|
+
theme?: Theme;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function Toast({ title, body, theme }: ToastProps): React.ReactNode {
|
|
14
|
+
const tokens = useComponentTheme(theme);
|
|
15
|
+
const { width: terminalWidth } = useTerminalDimensions();
|
|
16
|
+
const width = Math.min(terminalWidth - 6, Math.max(28, body.length + 4));
|
|
17
|
+
return (
|
|
18
|
+
<Dialog isOpen title={title ? ` ${title} ` : undefined} width={width} height={6} theme={theme}>
|
|
19
|
+
<box style={{ flexDirection: "column", flexGrow: 1, paddingLeft: 1, paddingRight: 1, paddingTop: 1 }}>
|
|
20
|
+
<text fg={tokens.text}>{body}</text>
|
|
21
|
+
<box style={{ flexGrow: 1 }} />
|
|
22
|
+
<box style={{ flexDirection: "row" }}>
|
|
23
|
+
<box style={{ flexGrow: 1 }} />
|
|
24
|
+
<text fg={tokens.textDim}>[esc]</text>
|
|
25
|
+
</box>
|
|
26
|
+
</box>
|
|
27
|
+
</Dialog>
|
|
28
|
+
);
|
|
29
|
+
}
|
|
@@ -40,7 +40,7 @@ export const FirstFile: Story = {
|
|
|
40
40
|
/>
|
|
41
41
|
),
|
|
42
42
|
// the main card wears the accent border; stats carry the +/- colors
|
|
43
|
-
expectedColors: [DARK.accent, DARK.green, DARK.red, DARK.
|
|
43
|
+
expectedColors: [DARK.accent, DARK.green, DARK.red, DARK.insertedForeground, DARK.deletedForeground],
|
|
44
44
|
};
|
|
45
45
|
|
|
46
46
|
export const WithAgentNote: Story = {
|
|
@@ -118,7 +118,7 @@ export function WalkWizard({
|
|
|
118
118
|
<text
|
|
119
119
|
key={previewIndex}
|
|
120
120
|
style={{ wrapMode: "none" }}
|
|
121
|
-
fg={previewLine.sign === "+" ? tokens.
|
|
121
|
+
fg={previewLine.sign === "+" ? tokens.insertedForeground : tokens.deletedForeground}
|
|
122
122
|
>
|
|
123
123
|
{previewLine.sign + previewLine.text}
|
|
124
124
|
</text>
|