@cueloop/client 0.1.0-alpha.66 → 0.1.0-alpha.68
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 +6 -5
- package/src/App.autoclose.test.tsx +2 -2
- package/src/App.diff.test.tsx +71 -39
- package/src/App.plan-review.test.tsx +20 -21
- package/src/App.readonly.test.tsx +7 -3
- package/src/App.test.tsx +73 -14
- package/src/App.tsx +375 -129
- package/src/App.walk.test.tsx +14 -15
- package/src/App.workbench.test.tsx +390 -0
- package/src/__snapshots__/view-plan.regression.test.ts.snap +1 -1
- package/src/annotation-palette.ts +61 -0
- package/src/app-screens.tsx +176 -45
- package/src/app-view-model.ts +7 -65
- package/src/components/AnnotationCard.tsx +1 -1
- package/src/components/AnnotationCards.stories.tsx +87 -0
- package/src/components/AnnotationCards.tsx +303 -0
- package/src/components/AppHeader.stories.tsx +50 -0
- package/src/components/AppHeader.tsx +83 -0
- package/src/components/AppShell.stories.tsx +47 -42
- package/src/components/AppShell.tsx +212 -100
- package/src/components/AppShell.zoom.test.tsx +94 -0
- package/src/components/ChangesColumn.tsx +49 -26
- package/src/components/DiffSheet.scroll.test.tsx +38 -55
- package/src/components/DiffSheet.split.test.tsx +140 -0
- package/src/components/DiffSheet.stories.tsx +55 -53
- package/src/components/DiffSheet.syntax.test.tsx +24 -7
- package/src/components/DiffSheet.tsx +607 -276
- package/src/components/DiscussionMarkerRail.stories.tsx +54 -0
- package/src/components/DiscussionMarkerRail.tsx +181 -0
- package/src/components/EditorGrid.stories.tsx +59 -0
- package/src/components/EditorGrid.tabs.test.tsx +105 -0
- package/src/components/EditorGrid.tsx +338 -0
- package/src/components/EditorGrid.zoom.test.tsx +68 -0
- package/src/components/FileContentsView.stories.tsx +16 -0
- package/src/components/FileContentsView.test.tsx +29 -0
- package/src/components/FileContentsView.tsx +78 -0
- package/src/components/InboxList.tsx +159 -30
- package/src/components/PaneGrid.stories.tsx +84 -0
- package/src/components/PaneGrid.tsx +128 -0
- package/src/components/PanelColumn.stories.tsx +25 -0
- package/src/components/PanelColumn.tsx +95 -0
- package/src/components/ProjectTreeView.stories.tsx +25 -0
- package/src/components/ProjectTreeView.test.tsx +32 -0
- package/src/components/ProjectTreeView.tsx +82 -0
- package/src/components/PromptDialog.tsx +8 -1
- package/src/components/RootOverlay.stories.tsx +44 -0
- package/src/components/RootOverlay.tsx +35 -0
- package/src/components/SettingsDialog.tsx +2 -1
- package/src/components/SurfaceScrollbar.stories.tsx +34 -0
- package/src/components/SurfaceScrollbar.test.tsx +111 -0
- package/src/components/SurfaceScrollbar.tsx +93 -0
- package/src/components/ThreadFooter.stories.tsx +2 -2
- package/src/components/ThreadFooter.test.tsx +31 -0
- package/src/components/ThreadFooter.tsx +12 -7
- package/src/components/ThreadView.tsx +62 -1440
- package/src/components/ThreadsSidebar.tsx +14 -1
- package/src/components/Tooltip.stories.tsx +26 -0
- package/src/components/Tooltip.tsx +72 -0
- package/src/components/WelcomeSurface.stories.tsx +12 -0
- package/src/components/WelcomeSurface.tsx +52 -0
- package/src/components/__snapshots__/stories.test.tsx.snap +509 -559
- package/src/components/diff-sheet-layout.test.ts +125 -55
- package/src/components/diff-sheet-layout.ts +3 -103
- package/src/components/editor-grid.test.ts +86 -0
- package/src/components/editor-grid.ts +138 -0
- package/src/components/fade-title.test.ts +49 -0
- package/src/components/fade-title.ts +61 -0
- package/src/components/file-tree.test.ts +15 -0
- package/src/components/file-tree.ts +59 -4
- package/src/components/pages/Workspace.stories.tsx +2 -2
- package/src/components/primitives/IconButton.tsx +21 -2
- package/src/components/primitives/Tree.tsx +13 -4
- package/src/components/primitives/icons.ts +27 -4
- package/src/components/session-tree.test.ts +20 -0
- package/src/components/session-tree.ts +16 -2
- package/src/components/stories-app.tsx +2 -2
- package/src/config.test.ts +20 -49
- package/src/config.ts +26 -28
- package/src/diff-fold.test.ts +78 -0
- package/src/diff-fold.ts +126 -0
- package/src/diff-syntax.test.ts +16 -0
- package/src/diff-syntax.ts +6 -3
- package/src/discussions.ts +79 -0
- package/src/ghostty-terminal.test.ts +2 -1
- package/src/ghostty-terminal.ts +27 -4
- package/src/intent-dispatch.test.ts +31 -11
- package/src/intent-dispatch.ts +93 -48
- package/src/key-bindings.test.ts +1 -1
- package/src/keymap.test.ts +3 -25
- package/src/keymap.ts +17 -18
- package/src/mark-runs.ts +120 -0
- package/src/pty.ts +10 -2
- package/src/run.ts +17 -7
- package/src/serve.test.ts +4 -8
- package/src/session-controller.curate.test.ts +75 -0
- package/src/session-controller.share.test.ts +1 -0
- package/src/session-controller.tree.test.ts +26 -0
- package/src/session-controller.ts +153 -29
- package/src/slash-palette.ts +83 -0
- package/src/split-diff.test.ts +110 -0
- package/src/split-diff.ts +149 -0
- package/src/test-support.test.ts +15 -3
- package/src/test-support.ts +66 -15
- package/src/thread-chords.test.ts +25 -9
- package/src/thread-chords.ts +33 -8
- package/src/use-annotation-surface.tsx +837 -0
- package/src/use-changes-workbench.ts +151 -0
- package/src/use-frame-measure.ts +38 -0
- package/src/use-settings-dialog.tsx +14 -24
- package/src/use-terminal-virtualizer.ts +233 -0
- package/src/view-diff.ts +114 -0
- package/src/components/ReviewPanel.stories.tsx +0 -100
- package/src/components/ReviewPanel.tsx +0 -103
- package/src/components/ReviewRail.stories.tsx +0 -232
- package/src/components/ReviewRail.tsx +0 -327
- package/src/review-panel.test.ts +0 -113
- package/src/review-panel.ts +0 -83
|
@@ -13,9 +13,15 @@ export interface ThreadsSidebarProps {
|
|
|
13
13
|
cursor: number;
|
|
14
14
|
/** The open thread's id, highlighted in the list. */
|
|
15
15
|
activeId?: string;
|
|
16
|
+
/** Ids of pinned threads. */
|
|
17
|
+
pinnedIds?: ReadonlySet<string>;
|
|
16
18
|
onSelect: (sessionId: string) => void;
|
|
17
|
-
/** Ask to delete a thread (the
|
|
19
|
+
/** Ask to delete a thread (the row menu's Delete, wired to the confirm dialog). */
|
|
18
20
|
onRequestDelete?: (id: string, title: string) => void;
|
|
21
|
+
/** Toggle a thread's pinned state (the row menu's Pin/Unpin). */
|
|
22
|
+
onPin?: (id: string) => void;
|
|
23
|
+
/** Rename a thread's title (the row menu's Rename). */
|
|
24
|
+
onRename?: (id: string, title: string) => void;
|
|
19
25
|
width?: number;
|
|
20
26
|
theme?: Theme;
|
|
21
27
|
}
|
|
@@ -25,8 +31,11 @@ export function ThreadsSidebar({
|
|
|
25
31
|
rows,
|
|
26
32
|
cursor,
|
|
27
33
|
activeId,
|
|
34
|
+
pinnedIds,
|
|
28
35
|
onSelect,
|
|
29
36
|
onRequestDelete,
|
|
37
|
+
onPin,
|
|
38
|
+
onRename,
|
|
30
39
|
width = 30,
|
|
31
40
|
theme,
|
|
32
41
|
}: ThreadsSidebarProps): React.ReactNode {
|
|
@@ -47,8 +56,12 @@ export function ThreadsSidebar({
|
|
|
47
56
|
rows={rows}
|
|
48
57
|
cursor={cursor}
|
|
49
58
|
activeId={activeId}
|
|
59
|
+
pinnedIds={pinnedIds}
|
|
60
|
+
width={width}
|
|
50
61
|
onSelect={onSelect}
|
|
51
62
|
onRequestDelete={onRequestDelete}
|
|
63
|
+
onPin={onPin}
|
|
64
|
+
onRename={onRename}
|
|
52
65
|
theme={theme}
|
|
53
66
|
/>
|
|
54
67
|
</scrollbox>
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { DARK } from "../theme";
|
|
3
|
+
import type { Story, StoryMeta } from "./story";
|
|
4
|
+
import { TooltipProvider } from "./Tooltip";
|
|
5
|
+
import { IconButton } from "./primitives/IconButton";
|
|
6
|
+
import { NERD } from "./primitives/icons";
|
|
7
|
+
|
|
8
|
+
export const meta: StoryMeta = { title: "Layout/Tooltip" };
|
|
9
|
+
|
|
10
|
+
// The tooltip surfaces only on hover, so a static story shows the provider wrapping a labelled control.
|
|
11
|
+
export const HoverControl: Story = {
|
|
12
|
+
render: () => (
|
|
13
|
+
<TooltipProvider theme={DARK}>
|
|
14
|
+
<box style={{ flexDirection: "row", padding: 1, backgroundColor: DARK.panel }}>
|
|
15
|
+
<IconButton
|
|
16
|
+
glyph={NERD.sidebarRight}
|
|
17
|
+
tip="Toggle Right Sidebar"
|
|
18
|
+
onPress={() => {}}
|
|
19
|
+
theme={DARK}
|
|
20
|
+
/>
|
|
21
|
+
</box>
|
|
22
|
+
</TooltipProvider>
|
|
23
|
+
),
|
|
24
|
+
expectedColors: [DARK.textMuted],
|
|
25
|
+
size: { width: 40, height: 4 },
|
|
26
|
+
};
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
// Hover tooltips for the header controls. A tiny header cell clips its own children, so the label is
|
|
2
|
+
// surfaced at the screen root instead: controls report the hovered label and cursor cell, and this layer
|
|
3
|
+
// paints it one row below, nudged left when it would run past the right edge.
|
|
4
|
+
|
|
5
|
+
import React, { createContext, useContext, useMemo, useState } from "react";
|
|
6
|
+
import { useTerminalDimensions } from "@opentui/react";
|
|
7
|
+
import { DARK, type Theme } from "../theme";
|
|
8
|
+
|
|
9
|
+
interface TooltipTarget {
|
|
10
|
+
label: string;
|
|
11
|
+
x: number;
|
|
12
|
+
y: number;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
interface TooltipApi {
|
|
16
|
+
showTooltip: (label: string, x: number, y: number) => void;
|
|
17
|
+
hideTooltip: () => void;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const TooltipContext = createContext<TooltipApi>({
|
|
21
|
+
showTooltip: () => {},
|
|
22
|
+
hideTooltip: () => {},
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
/** Report or clear the hovered control's tooltip; a no-op outside a TooltipProvider. */
|
|
26
|
+
export function useTooltip(): TooltipApi {
|
|
27
|
+
return useContext(TooltipContext);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/** Wrap a shell so its header controls can surface hover tooltips at the screen root. */
|
|
31
|
+
export function TooltipProvider({
|
|
32
|
+
theme,
|
|
33
|
+
children,
|
|
34
|
+
}: {
|
|
35
|
+
theme?: Theme;
|
|
36
|
+
children: React.ReactNode;
|
|
37
|
+
}): React.ReactNode {
|
|
38
|
+
const tokens = theme ?? DARK;
|
|
39
|
+
const { width, height } = useTerminalDimensions();
|
|
40
|
+
const [target, setTarget] = useState<TooltipTarget | null>(null);
|
|
41
|
+
const api = useMemo<TooltipApi>(
|
|
42
|
+
() => ({
|
|
43
|
+
showTooltip: (label, x, y) => setTarget({ label, x, y }),
|
|
44
|
+
hideTooltip: () => setTarget(null),
|
|
45
|
+
}),
|
|
46
|
+
[],
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
const boxWidth = target ? target.label.length + 2 : 0;
|
|
50
|
+
const left = target ? Math.max(0, Math.min(target.x, width - boxWidth)) : 0;
|
|
51
|
+
const top = target ? (target.y + 1 <= height - 1 ? target.y + 1 : Math.max(0, target.y - 1)) : 0;
|
|
52
|
+
|
|
53
|
+
return (
|
|
54
|
+
<TooltipContext.Provider value={api}>
|
|
55
|
+
{children}
|
|
56
|
+
{target ? (
|
|
57
|
+
<box
|
|
58
|
+
style={{
|
|
59
|
+
position: "absolute",
|
|
60
|
+
left,
|
|
61
|
+
top,
|
|
62
|
+
paddingLeft: 1,
|
|
63
|
+
paddingRight: 1,
|
|
64
|
+
backgroundColor: tokens.elevated,
|
|
65
|
+
}}
|
|
66
|
+
>
|
|
67
|
+
<text fg={tokens.text}>{target.label}</text>
|
|
68
|
+
</box>
|
|
69
|
+
) : null}
|
|
70
|
+
</TooltipContext.Provider>
|
|
71
|
+
);
|
|
72
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { DARK } from "../theme";
|
|
3
|
+
import type { Story, StoryMeta } from "./story";
|
|
4
|
+
import { WelcomeSurface } from "./WelcomeSurface";
|
|
5
|
+
|
|
6
|
+
export const meta: StoryMeta = { title: "Surfaces/WelcomeSurface" };
|
|
7
|
+
|
|
8
|
+
export const Welcome: Story = {
|
|
9
|
+
render: () => <WelcomeSurface version="0.1.0-alpha.66" theme={DARK} />,
|
|
10
|
+
expectedColors: [DARK.accent],
|
|
11
|
+
size: { width: 60, height: 16 },
|
|
12
|
+
};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
// The Welcome body: the disposable default tab's contents in the Changes panel,
|
|
2
|
+
// shown when nothing else is open. Points at where to start, the docs, and what
|
|
3
|
+
// shipped in this build. The tab chrome (label + close) lives in the panel header.
|
|
4
|
+
|
|
5
|
+
import React from "react";
|
|
6
|
+
import type { Theme } from "../theme";
|
|
7
|
+
|
|
8
|
+
const DOCS_URL = "www.cueloop.dev";
|
|
9
|
+
|
|
10
|
+
export interface WelcomeSurfaceProps {
|
|
11
|
+
version: string;
|
|
12
|
+
theme?: Theme;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function Section({
|
|
16
|
+
title,
|
|
17
|
+
children,
|
|
18
|
+
theme,
|
|
19
|
+
}: {
|
|
20
|
+
title: string;
|
|
21
|
+
children: React.ReactNode;
|
|
22
|
+
theme?: Theme;
|
|
23
|
+
}): React.ReactNode {
|
|
24
|
+
return (
|
|
25
|
+
<box style={{ flexDirection: "column", flexShrink: 0, marginTop: 1 }}>
|
|
26
|
+
<text fg={theme?.text}>{title}</text>
|
|
27
|
+
{children}
|
|
28
|
+
</box>
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export function WelcomeSurface({ version, theme }: WelcomeSurfaceProps): React.ReactNode {
|
|
33
|
+
return (
|
|
34
|
+
<box
|
|
35
|
+
style={{ flexDirection: "column", flexGrow: 1, flexShrink: 0, paddingLeft: 2, paddingTop: 1 }}
|
|
36
|
+
>
|
|
37
|
+
<text fg={theme?.accent}>Welcome to cueloop</text>
|
|
38
|
+
<text fg={theme?.textDim}>a review loop for coding agents</text>
|
|
39
|
+
<Section title="Start" theme={theme}>
|
|
40
|
+
<text fg={theme?.textDim}>· select a thread on the left</text>
|
|
41
|
+
<text fg={theme?.textDim}>· or run cueloop plan / cueloop diff from a repo</text>
|
|
42
|
+
</Section>
|
|
43
|
+
<Section title="Learn" theme={theme}>
|
|
44
|
+
<text fg={theme?.textDim}>{`· docs ${DOCS_URL}`}</text>
|
|
45
|
+
<text fg={theme?.textDim}>{`· changelog ${DOCS_URL}/changelog`}</text>
|
|
46
|
+
</Section>
|
|
47
|
+
<Section title="What's new" theme={theme}>
|
|
48
|
+
<text fg={theme?.textDim}>{`· cueloop v${version}`}</text>
|
|
49
|
+
</Section>
|
|
50
|
+
</box>
|
|
51
|
+
);
|
|
52
|
+
}
|