@cueloop/client 0.1.0-alpha.42 → 0.1.0-alpha.44

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.
@@ -849,17 +849,17 @@ exports[`stories catalog ReviewPanel/Compact renders, snapshots, and carries its
849
849
  `;
850
850
 
851
851
  exports[`stories catalog ReviewPanel/ExpandedNarrow renders, snapshots, and carries its colors: ReviewPanel/ExpandedNarrow 1`] = `
852
- " The plan takes the width the panel hands back. ╭─────────────────────╮
853
- │ Review Agent │
854
- ╰─────────────────────╯
855
- ╭─ COMMENT · me ──────╮
856
- │ Whichidaemonsownss" │
857
- │ this? │
858
- ╰─────────────────────╯
859
- ╭─ COMMENT · me ──────╮
860
- │ moveetheestoree" │
861
- │ behind o… │
862
- ╰─────────────────────╯
852
+ " The plan takes the width the panel hands back. ╭──────────────────────╮
853
+ │ Review Agent │
854
+ ╰──────────────────────╯
855
+ ╭─ COMMENT · me ───────╮
856
+ │ Whichidaemonsownss" │
857
+ │ this? │
858
+ ╰──────────────────────╯
859
+ ╭─ COMMENT · me ───────╮
860
+ │ moveetheestoree" │
861
+ │ behind o… │
862
+ ╰──────────────────────╯
863
863
 
864
864
 
865
865
 
@@ -871,23 +871,23 @@ exports[`stories catalog ReviewPanel/ExpandedNarrow renders, snapshots, and carr
871
871
 
872
872
 
873
873
 
874
- > Submit review
874
+ > Submit review
875
875
 
876
876
  "
877
877
  `;
878
878
 
879
879
  exports[`stories catalog ReviewPanel/ExpandedWide renders, snapshots, and carries its colors: ReviewPanel/ExpandedWide 1`] = `
880
- " The plan takes the width the panel ╭───────────────────────────────────────────────╮
881
- hands back. │ Review Agent │
882
- ╰───────────────────────────────────────────────╯
883
- ╭─ COMMENT · me ────────────────────────────────╮
884
- │ "persists sessions" │
885
- │ Which daemon owns this? │
886
- ╰───────────────────────────────────────────────╯
887
- ╭─ COMMENT · me ────────────────────────────────╮
888
- │ "move the store" │
889
- │ move the store behind o… │
890
- ╰───────────────────────────────────────────────╯
880
+ " The plan takes the width the panel ╭────────────────────────────────────────────────╮
881
+ hands back. │ Review Agent │
882
+ ╰────────────────────────────────────────────────╯
883
+ ╭─ COMMENT · me ─────────────────────────────────╮
884
+ │ "persists sessions" │
885
+ │ Which daemon owns this? │
886
+ ╰────────────────────────────────────────────────╯
887
+ ╭─ COMMENT · me ─────────────────────────────────╮
888
+ │ "move the store" │
889
+ │ move the store behind o… │
890
+ ╰────────────────────────────────────────────────╯
891
891
 
892
892
 
893
893
 
@@ -899,7 +899,7 @@ exports[`stories catalog ReviewPanel/ExpandedWide renders, snapshots, and carrie
899
899
 
900
900
 
901
901
 
902
- > Submit review
902
+ > Submit review
903
903
 
904
904
  "
905
905
  `;
@@ -933,45 +933,45 @@ exports[`stories catalog ReviewPanel/Hidden renders, snapshots, and carries its
933
933
  `;
934
934
 
935
935
  exports[`stories catalog ReviewRail/AgentTab renders, snapshots, and carries its colors: ReviewRail/AgentTab 1`] = `
936
- " ╭───────────────────────────────╮
937
- │ Review Agent │
938
- ╰───────────────────────────────╯
936
+ "╭────────────────────────────────╮
937
+ │ Review Agent │
938
+ ╰────────────────────────────────╯
939
+ ╭────────────────────────────────╮
940
+ │ Claude Code │
941
+ ╰────────────────────────────────╯
942
+ ╭────────────────────────────────╮
943
+ │ Pi │
944
+ ╰────────────────────────────────╯
945
+ ╭────────────────────────────────╮
946
+ │ OpenAI Codex │
947
+ ╰────────────────────────────────╯
948
+ plan context: seed the plan
949
+
950
+
951
+
952
+
953
+
954
+
955
+
939
956
 
940
- Ask an agent about this plan
941
- ╭─────────────────────────────╮
942
- │ ▛████▜ claude code │
943
- │ ▜██████▛ launch in rail ▸ │
944
- │ ▝▝ ▝▝ │
945
- ╰─────────────────────────────╯
946
957
 
947
- ╭─────────────────────────────╮
948
- │ ███ pi │
949
- │ █ █ launch in rail ▸ │
950
- │ ██ █ │
951
- │ █ █ │
952
- ╰─────────────────────────────╯
953
958
 
954
- ╭─────────────────────────────╮
955
- │ ┌───┐ codex │
956
- │ │>_ │ launch in rail ▸ │
957
- │ └───┘ │
958
- ╰─────────────────────────────╯
959
959
 
960
960
  "
961
961
  `;
962
962
 
963
963
  exports[`stories catalog ReviewRail/AnnotationStack renders, snapshots, and carries its colors: ReviewRail/AnnotationStack 1`] = `
964
- " ╭───────────────────────────────╮
965
- │ Review Agent │
966
- ╰───────────────────────────────╯
967
- ╭─ COMMENT · me ────────────────╮
968
- │ "persists sessions" │
969
- │ Which daemon owns this? │
970
- ╰───────────────────────────────╯
971
- ╭─ COMMENT · me ────────────────╮
972
- │ "move the store" │
973
- │ move the store behind o… │
974
- ╰───────────────────────────────╯
964
+ "╭────────────────────────────────╮
965
+ │ Review Agent │
966
+ ╰────────────────────────────────╯
967
+ ╭─ COMMENT · me ─────────────────╮
968
+ │ "persists sessions" │
969
+ │ Which daemon owns this? │
970
+ ╰────────────────────────────────╯
971
+ ╭─ COMMENT · me ─────────────────╮
972
+ │ "move the store" │
973
+ │ move the store behind o… │
974
+ ╰────────────────────────────────╯
975
975
 
976
976
 
977
977
 
@@ -983,26 +983,26 @@ exports[`stories catalog ReviewRail/AnnotationStack renders, snapshots, and carr
983
983
 
984
984
 
985
985
 
986
- Submit review
986
+ Submit review
987
987
 
988
988
  "
989
989
  `;
990
990
 
991
991
  exports[`stories catalog ReviewRail/InterleavedStack renders, snapshots, and carries its colors: ReviewRail/InterleavedStack 1`] = `
992
- " ╭───────────────────────────────╮
993
- │ Review Agent │
994
- ╰───────────────────────────────╯
995
- ╭─ CUT · me ────────────────────╮
996
- │ - add recovery │
997
- ╰───────────────────────────────╯
998
- ╭─ COMMENT · me ────────────────╮
999
- │ "persists sessions" │
1000
- │ Which daemon owns this? │
1001
- ╰───────────────────────────────╯
1002
- ╭─ COMMENT · me ────────────────╮
1003
- │ "move the store" │
1004
- │ move the store behind o… │
1005
- ╰───────────────────────────────╯
992
+ "╭────────────────────────────────╮
993
+ │ Review Agent │
994
+ ╰────────────────────────────────╯
995
+ ╭─ CUT · me ─────────────────────╮
996
+ │ - add recovery │
997
+ ╰────────────────────────────────╯
998
+ ╭─ COMMENT · me ─────────────────╮
999
+ │ "persists sessions" │
1000
+ │ Which daemon owns this? │
1001
+ ╰────────────────────────────────╯
1002
+ ╭─ COMMENT · me ─────────────────╮
1003
+ │ "move the store" │
1004
+ │ move the store behind o… │
1005
+ ╰────────────────────────────────╯
1006
1006
 
1007
1007
 
1008
1008
 
@@ -1011,23 +1011,23 @@ exports[`stories catalog ReviewRail/InterleavedStack renders, snapshots, and car
1011
1011
 
1012
1012
 
1013
1013
 
1014
- Submit review
1014
+ Submit review
1015
1015
 
1016
1016
  "
1017
1017
  `;
1018
1018
 
1019
1019
  exports[`stories catalog ReviewRail/MixedOwnershipStack renders, snapshots, and carries its colors: ReviewRail/MixedOwnershipStack 1`] = `
1020
- " ╭───────────────────────────────╮
1021
- │ Review Agent │
1022
- ╰───────────────────────────────╯
1023
- ╭─ COMMENT · me ────────────────╮
1024
- │ "persists sessions" │
1025
- │ Which daemon owns this? │
1026
- ╰───────────────────────────────╯
1027
- ╭─ COMMENT · Priya ─────────────╮
1028
- │ "move the store" │
1029
- │ move it behind one inte… │
1030
- ╰───────────────────────────────╯
1020
+ "╭────────────────────────────────╮
1021
+ │ Review Agent │
1022
+ ╰────────────────────────────────╯
1023
+ ╭─ COMMENT · me ─────────────────╮
1024
+ │ "persists sessions" │
1025
+ │ Which daemon owns this? │
1026
+ ╰────────────────────────────────╯
1027
+ ╭─ COMMENT · Priya ──────────────╮
1028
+ │ "move the store" │
1029
+ │ move it behind one inte… │
1030
+ ╰────────────────────────────────╯
1031
1031
 
1032
1032
 
1033
1033
 
@@ -1039,25 +1039,25 @@ exports[`stories catalog ReviewRail/MixedOwnershipStack renders, snapshots, and
1039
1039
 
1040
1040
 
1041
1041
 
1042
- Submit review
1042
+ Submit review
1043
1043
 
1044
1044
  "
1045
1045
  `;
1046
1046
 
1047
1047
  exports[`stories catalog ReviewRail/Removals renders, snapshots, and carries its colors: ReviewRail/Removals 1`] = `
1048
- " ╭───────────────────────────────╮
1049
- │ Review Agent │
1050
- ╰───────────────────────────────╯
1051
- ╭─ REJECT · me ─────────────────╮
1052
- │ - private items = []; │
1053
- │ + private items = new… │
1054
- │ undo │
1055
- ╰───────────────────────────────╯
1056
- ╭─ REJECT · me ─────────────────╮
1057
- │ - return null; │
1058
- │ + return fallback(); │
1059
- │ + log(fallback); │
1060
- ╰───────────────────────────────╯
1048
+ "╭────────────────────────────────╮
1049
+ │ Review Agent │
1050
+ ╰────────────────────────────────╯
1051
+ ╭─ REJECT · me ──────────────────╮
1052
+ │ - private items = []; │
1053
+ │ + private items = new… │
1054
+ │ undo │
1055
+ ╰────────────────────────────────╯
1056
+ ╭─ REJECT · me ──────────────────╮
1057
+ │ - return null; │
1058
+ │ + return fallback(); │
1059
+ │ + log(fallback); │
1060
+ ╰────────────────────────────────╯
1061
1061
 
1062
1062
 
1063
1063
 
@@ -1067,23 +1067,23 @@ exports[`stories catalog ReviewRail/Removals renders, snapshots, and carries its
1067
1067
 
1068
1068
 
1069
1069
 
1070
- Submit review
1070
+ Submit review
1071
1071
 
1072
1072
  "
1073
1073
  `;
1074
1074
 
1075
1075
  exports[`stories catalog ReviewRail/Resolved renders, snapshots, and carries its colors: ReviewRail/Resolved 1`] = `
1076
- " ╭───────────────────────────────╮
1077
- │ Review Agent │
1078
- ╰───────────────────────────────╯
1079
- ╭─ COMMENT · me · ORPHANED ─────╮
1080
- │ "persists sessions" │
1081
- │ Which daemon owns this? │
1082
- ╰───────────────────────────────╯
1083
- ╭─ COMMENT · me · ORPHANED ─────╮
1084
- │ "move the store" │
1085
- │ move the store behind o… │
1086
- ╰───────────────────────────────╯
1076
+ "╭────────────────────────────────╮
1077
+ │ Review Agent │
1078
+ ╰────────────────────────────────╯
1079
+ ╭─ COMMENT · me · ORPHANED ──────╮
1080
+ │ "persists sessions" │
1081
+ │ Which daemon owns this? │
1082
+ ╰────────────────────────────────╯
1083
+ ╭─ COMMENT · me · ORPHANED ──────╮
1084
+ │ "move the store" │
1085
+ │ move the store behind o… │
1086
+ ╰────────────────────────────────╯
1087
1087
 
1088
1088
 
1089
1089
 
@@ -1095,23 +1095,23 @@ exports[`stories catalog ReviewRail/Resolved renders, snapshots, and carries its
1095
1095
 
1096
1096
 
1097
1097
 
1098
- resolved: approve
1098
+ resolved: approve
1099
1099
 
1100
1100
  "
1101
1101
  `;
1102
1102
 
1103
1103
  exports[`stories catalog ReviewRail/SubmitConfirmOpen renders, snapshots, and carries its colors: ReviewRail/SubmitConfirmOpen 1`] = `
1104
- " ╭───────────────────────────────╮
1105
- │ Review Agent │
1106
- ╰───────────────────────────────╯
1107
- ╭─ COMMENT · me · ORPHANED ─────╮
1108
- │ "persists sessions" │
1109
- │ Which daemon owns this? │
1110
- ╰───────────────────────────────╯
1111
- ╭─ COMMENT · me · ORPHANED ─────╮
1112
- │ "move the store" │
1113
- │ move the store behind o… │
1114
- ╰───────────────────────────────╯
1104
+ "╭────────────────────────────────╮
1105
+ │ Review Agent │
1106
+ ╰────────────────────────────────╯
1107
+ ╭─ COMMENT · me · ORPHANED ──────╮
1108
+ │ "persists sessions" │
1109
+ │ Which daemon owns this? │
1110
+ ╰────────────────────────────────╯
1111
+ ╭─ COMMENT · me · ORPHANED ──────╮
1112
+ │ "move the store" │
1113
+ │ move the store behind o… │
1114
+ ╰────────────────────────────────╯
1115
1115
 
1116
1116
 
1117
1117
 
@@ -1121,15 +1121,15 @@ exports[`stories catalog ReviewRail/SubmitConfirmOpen renders, snapshots, and ca
1121
1121
 
1122
1122
 
1123
1123
 
1124
- ╭─ submit review ──────────────╮
1125
- │ 2 annotations · 0 blocking │
1126
- │ │
1127
- │ Comment Approve [Changes] │
1128
- │ │
1129
- │ summary for the agent (option│
1130
- │ │
1131
- │ Submit Cancel │
1132
- ╰──────────────────────────────╯
1124
+ ╭─ submit review ───────────────╮
1125
+ │ 2 annotations · 0 blocking │
1126
+ │ │
1127
+ │ Comment Approve [Changes] │
1128
+ │ │
1129
+ │ summary for the agent (optiona│
1130
+ │ │
1131
+ │ Submit Cancel │
1132
+ ╰───────────────────────────────╯
1133
1133
 
1134
1134
  "
1135
1135
  `;
@@ -1393,30 +1393,30 @@ exports[`stories catalog WalkWizard/WithAgentNote renders, snapshots, and carrie
1393
1393
  `;
1394
1394
 
1395
1395
  exports[`stories catalog AgentLauncher/Launcher renders, snapshots, and carries its colors: AgentLauncher/Launcher 1`] = `
1396
- " Ask an agent about this plan
1397
-
1398
- ╭────────────────────────────────────╮
1399
- │ ▛████▜ claude code │
1400
- │ ▜██████▛ launch in rail ▸ │
1401
- │ ▝▝ ▝▝ │
1396
+ " ╭────────────────────────────────────╮
1397
+ │ Claude Code │
1402
1398
  ╰────────────────────────────────────╯
1403
-
1404
1399
  ╭────────────────────────────────────╮
1405
- │ ███ pi │
1406
- │ █ █ launch in rail ▸ │
1407
- │ ██ █ │
1408
- │ █ █ │
1400
+ │ Pi │
1409
1401
  ╰────────────────────────────────────╯
1410
-
1411
1402
  ╭────────────────────────────────────╮
1412
- │ ┌───┐ codex │
1413
- │ │>_ │ launch in rail ▸ │
1414
- │ └───┘ │
1403
+ │ OpenAI Codex │
1415
1404
  ╰────────────────────────────────────╯
1405
+ plan context: seed the plan
1406
+
1407
+
1408
+
1409
+
1410
+
1411
+
1412
+
1413
+
1414
+
1415
+
1416
+
1417
+
1416
1418
 
1417
- plan context: seed the plan ▸
1418
1419
 
1419
- agent/worker-3 · pending · rev 1
1420
1420
  "
1421
1421
  `;
1422
1422
 
@@ -21,6 +21,6 @@ export const Launcher: Story = {
21
21
  <AgentLauncher session={fixturePlanSession()} onLaunchHarness={() => {}} theme={DARK} />
22
22
  </RailFrame>
23
23
  ),
24
- expectedColors: [DARK.accent, "#cc785c"],
24
+ expectedColors: [DARK.accent],
25
25
  size: { width: 40, height: 24 },
26
26
  };
@@ -1,5 +1,10 @@
1
1
  import { describe, expect, test } from "bun:test";
2
- import { HARNESS_LAUNCHERS, planHandoffBriefing } from "./agent-launcher";
2
+ import React from "react";
3
+ import { testRender } from "@opentui/react/test-utils";
4
+ import { DARK } from "../theme";
5
+ import { fixturePlanSession } from "./story-fixtures";
6
+ import { waitForText } from "../test-support";
7
+ import { AgentLauncher, HARNESS_LAUNCHERS, planHandoffBriefing } from "./agent-launcher";
3
8
 
4
9
  describe("planHandoffBriefing", () => {
5
10
  test("references the session by id and directs the agent to read then annotate, not rewrite", () => {
@@ -14,8 +19,31 @@ describe("planHandoffBriefing", () => {
14
19
  });
15
20
 
16
21
  describe("HARNESS_LAUNCHERS", () => {
17
- test("carries the three branded harnesses with their launch commands", () => {
18
- // Assert
19
- expect(HARNESS_LAUNCHERS.map((harness) => harness.command)).toEqual(["cc", "pi", "codex"]);
22
+ test("carries the three harnesses with real binary commands (never the `cc` alias)", () => {
23
+ // Assert - `cc` resolves to the system C compiler when spawned on a PTY, so
24
+ // the Claude harness must run `claude`, the real binary, not the shell alias
25
+ expect(HARNESS_LAUNCHERS.map((harness) => harness.command)).toEqual(["claude", "pi", "codex"]);
26
+ });
27
+ });
28
+
29
+ describe("AgentLauncher", () => {
30
+ test("renders a button for every harness, in order", async () => {
31
+ // Arrange
32
+ const setup = await testRender(
33
+ <box style={{ width: 44, height: 20, flexDirection: "column" }}>
34
+ <AgentLauncher session={fixturePlanSession()} onLaunchHarness={() => {}} theme={DARK} />
35
+ </box>,
36
+ { width: 44, height: 20 },
37
+ );
38
+
39
+ // Act
40
+ await waitForText(setup, "Claude Code");
41
+ const frame = setup.captureCharFrame();
42
+
43
+ // Assert - all three launcher names present, in launch order
44
+ const names = HARNESS_LAUNCHERS.map((harness) => harness.name);
45
+ const positions = names.map((name) => frame.indexOf(name));
46
+ expect(positions.every((position) => position >= 0)).toBe(true);
47
+ expect(positions).toEqual(positions.toSorted((left, right) => left - right));
20
48
  });
21
49
  });
@@ -24,38 +24,24 @@ export interface AgentTerminalHandle {
24
24
  detach: () => void;
25
25
  }
26
26
 
27
- /** One launchable harness: its rail command and the real logo, rendered as colored rows. */
27
+ /** One launchable harness: its display name and the rail command. */
28
28
  export interface HarnessLauncher {
29
29
  id: string;
30
30
  name: string;
31
31
  /** The shell command that starts the harness, run in the split. */
32
32
  command: string;
33
- /** Brand color for the mark. */
34
- color: string;
35
- /** Multi-row mark rendered from the real logo. */
36
- logo: string[];
37
33
  }
38
34
 
39
- /** Claude Code's brand coral - not a theme token, the mark keeps its own color. */
40
- const CLAUDE_CORAL = "#CC785C";
35
+ /** Off-white for the running-terminal header, shared by every harness. */
36
+ const HARNESS_HEADER_COLOR = "#e4e6ec";
41
37
 
42
- /** The bring-your-own harnesses, with their real marks (finalized in the prototype). */
38
+ /** The bring-your-own harnesses, in launch order. The command is the real binary
39
+ * name spawned on a PTY (not a shell alias, so `claude` - never `cc`, which is
40
+ * the system C compiler). */
43
41
  export const HARNESS_LAUNCHERS: HarnessLauncher[] = [
44
- {
45
- id: "claude",
46
- name: "claude code",
47
- command: "cc",
48
- color: CLAUDE_CORAL,
49
- logo: [" ▛████▜", "▜██████▛", " ▝▝ ▝▝"],
50
- },
51
- { id: "pi", name: "pi", command: "pi", color: "#e4e6ec", logo: ["███ ", "█ █ ", "██ █", "█ █"] },
52
- {
53
- id: "codex",
54
- name: "codex",
55
- command: "codex",
56
- color: "#e4e6ec",
57
- logo: ["┌───┐", "│>_ │", "└───┘"],
58
- },
42
+ { id: "claude", name: "Claude Code", command: "claude" },
43
+ { id: "pi", name: "Pi", command: "pi" },
44
+ { id: "codex", name: "OpenAI Codex", command: "codex" },
59
45
  ];
60
46
 
61
47
  /** The briefing typed into a launched harness when the plan-context toggle is on. */
@@ -63,18 +49,6 @@ export function planHandoffBriefing(sessionId: string): string {
63
49
  return `Review this cueloop plan: read it with 'cueloop session get ${sessionId}', then comment with 'cueloop session annotate ${sessionId} --author me --quote "<exact span>" --body "<comment>"'. Do not rewrite the plan.`;
64
50
  }
65
51
 
66
- function LogoMark({ harness }: { harness: HarnessLauncher }): React.ReactNode {
67
- return (
68
- <box style={{ width: 9, flexShrink: 0, flexDirection: "column", alignItems: "flex-start" }}>
69
- {harness.logo.map((row) => (
70
- <text key={row} fg={harness.color}>
71
- {row}
72
- </text>
73
- ))}
74
- </box>
75
- );
76
- }
77
-
78
52
  /** Props for the Agent tab body: the session under review plus the launch callbacks. */
79
53
  export interface AgentLauncherProps {
80
54
  session: ReviewSession;
@@ -110,7 +84,12 @@ export function AgentLauncher({
110
84
  if (embeddedTerminalAvailable()) setRunning({ harness, seed });
111
85
  else onLaunchHarness(harness.command, seed);
112
86
  };
113
- const detach = (): void => setRunning(null);
87
+ const detach = (): void => {
88
+ // The reconciler's removeChild detaches the pane without destroying it, so
89
+ // kill the child + free the VT here or they leak. shutdown() is idempotent.
90
+ paneRef.current?.shutdown();
91
+ setRunning(null);
92
+ };
114
93
 
115
94
  useEffect(() => {
116
95
  if (!running) return onAgentTerminal?.(null);
@@ -123,9 +102,9 @@ export function AgentLauncher({
123
102
  return (
124
103
  <box style={{ flexDirection: "column", flexGrow: 1 }}>
125
104
  <box style={{ flexDirection: "row" }} onMouseUp={detach}>
126
- <text fg={running.harness.color}>{running.harness.name}</text>
105
+ <text fg={HARNESS_HEADER_COLOR}>{running.harness.name}</text>
127
106
  <box style={{ flexGrow: 1 }} />
128
- <text fg={tokens.textDim}>✕ detach (⌃])</text>
107
+ <text fg={tokens.textDim}>✕ detach</text>
129
108
  </box>
130
109
  {React.createElement("terminalPane", {
131
110
  ref: paneRef,
@@ -141,40 +120,28 @@ export function AgentLauncher({
141
120
 
142
121
  return (
143
122
  <box style={{ flexDirection: "column", flexGrow: 1 }}>
144
- <text fg={tokens.text}>Ask an agent about this plan</text>
145
- <box style={{ height: 1 }} />
146
123
  {HARNESS_LAUNCHERS.map((harness) => (
147
124
  <box
148
125
  key={harness.id}
149
126
  style={{
150
127
  flexDirection: "row",
151
- height: harness.logo.length + 2,
128
+ height: 3,
152
129
  border: true,
153
130
  borderStyle: FRAME_BORDER_STYLE,
154
131
  backgroundColor: "transparent",
155
- borderColor: tokens.border,
156
- marginBottom: 1,
132
+ borderColor: tokens.text,
157
133
  paddingLeft: 1,
158
134
  paddingRight: 1,
159
135
  }}
160
136
  onMouseUp={() => launch(harness)}
161
137
  >
162
- <LogoMark harness={harness} />
163
- <box style={{ flexDirection: "column", flexGrow: 1, paddingLeft: 1 }}>
164
- <text fg={tokens.textMuted}>{harness.name}</text>
165
- <text fg={tokens.textDim}>launch in rail ▸</text>
166
- </box>
138
+ <text fg={tokens.textMuted}>{harness.name}</text>
167
139
  </box>
168
140
  ))}
169
141
  <box style={{ flexDirection: "row" }} onMouseUp={() => setSeedContext((on) => !on)}>
170
142
  <text fg={tokens.textDim}>plan context: </text>
171
- <text fg={tokens.accent}>{seedContext ? "seed the plan ▸" : "none ▸"}</text>
143
+ <text fg={tokens.accent}>{seedContext ? "seed the plan" : "none"}</text>
172
144
  </box>
173
- <box style={{ flexGrow: 1 }} />
174
- <text fg={tokens.textDim}>
175
- {session.artifact.meta.agent ?? "unknown"} · {session.status} · rev{" "}
176
- {session.revisions.length}
177
- </text>
178
145
  </box>
179
146
  );
180
147
  }
@@ -5,6 +5,7 @@
5
5
  */
6
6
 
7
7
  import React from "react";
8
+ import type { MouseEvent } from "@opentui/core";
8
9
  import type { Theme } from "../../theme";
9
10
  import { useComponentTheme } from "../theme-context";
10
11
 
@@ -38,7 +39,9 @@ export function Button({
38
39
  return (
39
40
  <box
40
41
  style={{ backgroundColor, marginRight }}
41
- onMouseUp={() => {
42
+ onMouseUp={(event: MouseEvent) => {
43
+ // Consume the press so it never bubbles to an ancestor's onMouseUp (e.g. a card).
44
+ event.stopPropagation();
42
45
  if (!isDisabled) onPress();
43
46
  }}
44
47
  >