sleev 0.0.12 → 0.0.13

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.
Files changed (143) hide show
  1. package/README.md +19 -39
  2. package/dist/auth/browser.d.ts +12 -0
  3. package/dist/auth/browser.js +33 -24
  4. package/dist/auth/browser.js.map +1 -0
  5. package/dist/auth/firebase-tokens.d.ts +39 -0
  6. package/dist/auth/firebase-tokens.js +173 -0
  7. package/dist/auth/firebase-tokens.js.map +1 -0
  8. package/dist/auth/firebase.d.ts +17 -0
  9. package/dist/auth/firebase.js +55 -0
  10. package/dist/auth/firebase.js.map +1 -0
  11. package/dist/auth/login.d.ts +22 -0
  12. package/dist/auth/login.js +31 -28
  13. package/dist/auth/login.js.map +1 -0
  14. package/dist/auth/loopback.d.ts +19 -0
  15. package/dist/auth/loopback.js +114 -44
  16. package/dist/auth/loopback.js.map +1 -0
  17. package/dist/auth/schema.d.ts +26 -0
  18. package/dist/auth/schema.js +59 -17
  19. package/dist/auth/schema.js.map +1 -0
  20. package/dist/auth/token.d.ts +19 -0
  21. package/dist/auth/token.js +53 -0
  22. package/dist/auth/token.js.map +1 -0
  23. package/dist/auth/verify.d.ts +6 -0
  24. package/dist/auth/verify.js +22 -0
  25. package/dist/auth/verify.js.map +1 -0
  26. package/dist/cli.d.ts +8 -0
  27. package/dist/cli.js +245 -59
  28. package/dist/cli.js.map +1 -0
  29. package/dist/config/paths.d.ts +12 -0
  30. package/dist/config/paths.js +34 -0
  31. package/dist/config/paths.js.map +1 -0
  32. package/dist/config/store.d.ts +63 -0
  33. package/dist/config/store.js +270 -0
  34. package/dist/config/store.js.map +1 -0
  35. package/dist/control/local-installations.d.ts +13 -0
  36. package/dist/control/local-installations.js +37 -0
  37. package/dist/control/local-installations.js.map +1 -0
  38. package/dist/daemon/config.d.ts +10 -0
  39. package/dist/daemon/config.js +52 -0
  40. package/dist/daemon/config.js.map +1 -0
  41. package/dist/daemon/controller.d.ts +29 -0
  42. package/dist/daemon/controller.js +34 -0
  43. package/dist/daemon/controller.js.map +1 -0
  44. package/dist/daemon/health.d.ts +8 -0
  45. package/dist/daemon/health.js +47 -0
  46. package/dist/daemon/health.js.map +1 -0
  47. package/dist/daemon/start.d.ts +5 -0
  48. package/dist/daemon/start.js +24 -0
  49. package/dist/daemon/start.js.map +1 -0
  50. package/dist/daemon/systemd.d.ts +35 -0
  51. package/dist/daemon/systemd.js +181 -0
  52. package/dist/daemon/systemd.js.map +1 -0
  53. package/dist/gateway/acquire.d.ts +14 -0
  54. package/dist/gateway/acquire.js +112 -0
  55. package/dist/gateway/acquire.js.map +1 -0
  56. package/dist/gateway/manifest.d.ts +26 -0
  57. package/dist/gateway/manifest.js +98 -0
  58. package/dist/gateway/manifest.js.map +1 -0
  59. package/dist/gateway/platform.d.ts +5 -0
  60. package/dist/gateway/platform.js +27 -0
  61. package/dist/gateway/platform.js.map +1 -0
  62. package/dist/harness/claude.d.ts +8 -0
  63. package/dist/{apps → harness}/claude.js +28 -28
  64. package/dist/harness/claude.js.map +1 -0
  65. package/dist/harness/codex.d.ts +10 -0
  66. package/dist/{apps → harness}/codex.js +50 -45
  67. package/dist/harness/codex.js.map +1 -0
  68. package/dist/harness/index.d.ts +13 -0
  69. package/dist/harness/index.js +63 -0
  70. package/dist/harness/index.js.map +1 -0
  71. package/dist/harness/opencode-config.d.ts +8 -0
  72. package/dist/{apps → harness}/opencode-config.js +116 -83
  73. package/dist/harness/opencode-config.js.map +1 -0
  74. package/dist/harness/opencode.d.ts +14 -0
  75. package/dist/harness/opencode.js +50 -0
  76. package/dist/harness/opencode.js.map +1 -0
  77. package/dist/harness/providers.d.ts +8 -0
  78. package/dist/harness/providers.js +30 -0
  79. package/dist/harness/providers.js.map +1 -0
  80. package/dist/harness/types.d.ts +14 -0
  81. package/dist/harness/types.js +2 -0
  82. package/dist/harness/types.js.map +1 -0
  83. package/dist/product.d.ts +12 -0
  84. package/dist/product.js +53 -10
  85. package/dist/product.js.map +1 -0
  86. package/dist/tui/clipboard.d.ts +1 -0
  87. package/dist/tui/clipboard.js +48 -0
  88. package/dist/tui/clipboard.js.map +1 -0
  89. package/dist/tui/openTuiApp.d.ts +1 -0
  90. package/dist/tui/openTuiApp.js +1436 -0
  91. package/dist/tui/openTuiApp.js.map +1 -0
  92. package/dist/tui/pages/flow-screen.d.ts +50 -0
  93. package/dist/tui/pages/flow-screen.js +435 -0
  94. package/dist/tui/pages/flow-screen.js.map +1 -0
  95. package/dist/tui/pages/footer.d.ts +7 -0
  96. package/dist/tui/pages/footer.js +14 -0
  97. package/dist/tui/pages/footer.js.map +1 -0
  98. package/dist/tui/pages/home-screen.d.ts +19 -0
  99. package/dist/tui/pages/home-screen.js +89 -0
  100. package/dist/tui/pages/home-screen.js.map +1 -0
  101. package/dist/tui/pages/index.d.ts +17 -0
  102. package/dist/tui/pages/index.js +11 -0
  103. package/dist/tui/pages/index.js.map +1 -0
  104. package/dist/tui/pages/local-setup-screen.d.ts +23 -0
  105. package/dist/tui/pages/local-setup-screen.js +134 -0
  106. package/dist/tui/pages/local-setup-screen.js.map +1 -0
  107. package/dist/tui/pages/location-card.d.ts +19 -0
  108. package/dist/tui/pages/location-card.js +116 -0
  109. package/dist/tui/pages/location-card.js.map +1 -0
  110. package/dist/tui/pages/menu-screen.d.ts +24 -0
  111. package/dist/tui/pages/menu-screen.js +117 -0
  112. package/dist/tui/pages/menu-screen.js.map +1 -0
  113. package/dist/tui/pages/session-grid.d.ts +23 -0
  114. package/dist/tui/pages/session-grid.js +552 -0
  115. package/dist/tui/pages/session-grid.js.map +1 -0
  116. package/dist/tui/pages/setup-screen.d.ts +15 -0
  117. package/dist/tui/pages/setup-screen.js +80 -0
  118. package/dist/tui/pages/setup-screen.js.map +1 -0
  119. package/dist/tui/pages/terminal-log.d.ts +14 -0
  120. package/dist/tui/pages/terminal-log.js +104 -0
  121. package/dist/tui/pages/terminal-log.js.map +1 -0
  122. package/dist/tui/pages/welcome-screen.d.ts +16 -0
  123. package/dist/tui/pages/welcome-screen.js +80 -0
  124. package/dist/tui/pages/welcome-screen.js.map +1 -0
  125. package/dist/tui/saved-tokens.d.ts +10 -0
  126. package/dist/tui/saved-tokens.js +104 -0
  127. package/dist/tui/saved-tokens.js.map +1 -0
  128. package/dist/tui/theme.d.ts +25 -0
  129. package/dist/tui/theme.js +27 -0
  130. package/dist/tui/theme.js.map +1 -0
  131. package/package.json +55 -38
  132. package/dist/apps/opencode.js +0 -158
  133. package/dist/apps.js +0 -148
  134. package/dist/auth/command.js +0 -109
  135. package/dist/auth/index.js +0 -2
  136. package/dist/auth/validation.js +0 -27
  137. package/dist/credentials/index.js +0 -3
  138. package/dist/credentials/schema.js +0 -63
  139. package/dist/credentials/store.js +0 -52
  140. package/dist/harnesses.js +0 -66
  141. package/dist/index.js +0 -3
  142. package/dist/providers.js +0 -30
  143. package/dist/terminal.js +0 -55
@@ -0,0 +1,89 @@
1
+ // Owns the local/cloud service location page composition.
2
+ import { Footer } from "./footer.js";
3
+ import { LocationCard, locationCardMaxHeight, } from "./location-card.js";
4
+ import { TerminalLog, terminalLogHeight } from "./terminal-log.js";
5
+ import { theme } from "../theme.js";
6
+ export function HomeScreen(core, props) {
7
+ const layout = homeLayout(props.columns, props.rows);
8
+ const chooser = core.Box({
9
+ width: layout.contentWidth,
10
+ height: layout.chooserHeight,
11
+ flexDirection: "column",
12
+ alignItems: "center",
13
+ gap: layout.sectionGap,
14
+ }, core.Box({
15
+ flexDirection: "column",
16
+ alignItems: "center",
17
+ }, core.Text({
18
+ content: "choose service location",
19
+ fg: theme.color.quiet,
20
+ attributes: core.TextAttributes.BOLD,
21
+ })), LocationCard(core, {
22
+ selectedIndex: props.selectedIndex,
23
+ width: layout.cardWidth,
24
+ onHover: props.onHover,
25
+ onChoose: props.onChoose,
26
+ }));
27
+ return core.Box({
28
+ backgroundColor: theme.color.app,
29
+ width: "100%",
30
+ height: "100%",
31
+ flexDirection: "column",
32
+ }, core.Box({
33
+ width: "100%",
34
+ flexGrow: 1,
35
+ flexDirection: "column",
36
+ }, core.Box({
37
+ flexGrow: 1,
38
+ flexDirection: "column",
39
+ alignItems: "center",
40
+ justifyContent: "center",
41
+ paddingLeft: layout.pad,
42
+ paddingRight: layout.pad,
43
+ }, chooser)), TerminalLog(core, {
44
+ lines: props.logs,
45
+ width: layout.logWidth,
46
+ height: layout.logHeight,
47
+ offset: props.logOffset,
48
+ notice: props.logNotice,
49
+ onScroll: props.onLogScroll,
50
+ onLinkClick: props.onLogLink,
51
+ }), Footer(core, {
52
+ pad: layout.pad,
53
+ }));
54
+ }
55
+ function homeLayout(columns, rows) {
56
+ const pad = sidePad(columns);
57
+ const usable = Math.max(1, columns - pad * 2);
58
+ const compact = rows < 34;
59
+ const cardWidth = clamp(usable, 22, theme.size.locationCardWidth);
60
+ const contentWidth = cardWidth;
61
+ const sectionGap = compact ? 1 : 2;
62
+ const chooserHeight = 1 + sectionGap + locationCardMaxHeight(cardWidth);
63
+ const logWidth = columns;
64
+ const logHeight = terminalLogHeight(rows);
65
+ return {
66
+ pad,
67
+ cardWidth,
68
+ contentWidth,
69
+ sectionGap,
70
+ chooserHeight,
71
+ logWidth,
72
+ logHeight,
73
+ };
74
+ }
75
+ function sidePad(columns) {
76
+ if (columns >= 120)
77
+ return 8;
78
+ if (columns >= 96)
79
+ return 6;
80
+ if (columns >= 70)
81
+ return 4;
82
+ if (columns >= 48)
83
+ return 3;
84
+ return 2;
85
+ }
86
+ function clamp(value, min, max) {
87
+ return Math.min(Math.max(value, min), max);
88
+ }
89
+ //# sourceMappingURL=home-screen.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"home-screen.js","sourceRoot":"","sources":["../../../src/tui/pages/home-screen.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ export { FlowScreen } from "./flow-screen.js";
2
+ export type { FlowPage, FlowScreenProps, HarnessCard } from "./flow-screen.js";
3
+ export { HomeScreen } from "./home-screen.js";
4
+ export type { HomeAction, HomeScreenProps } from "./home-screen.js";
5
+ export { LOCATION_CARDS as HOME_CARDS, LocationCard } from "./location-card.js";
6
+ export type { LocationAction, LocationCardProps } from "./location-card.js";
7
+ export { LocalSetupScreen } from "./local-setup-screen.js";
8
+ export type { LocalSetupScreenProps, LocalSetupState, LocalSetupStep, LocalSetupStepStatus, } from "./local-setup-screen.js";
9
+ export { MenuScreen } from "./menu-screen.js";
10
+ export type { MenuAction, MenuItem, MenuScreenProps } from "./menu-screen.js";
11
+ export { SetupScreen } from "./setup-screen.js";
12
+ export type { SetupScreenProps } from "./setup-screen.js";
13
+ export { TerminalLog, terminalLogHeight } from "./terminal-log.js";
14
+ export type { TerminalLogProps } from "./terminal-log.js";
15
+ export { WelcomeScreen } from "./welcome-screen.js";
16
+ export type { WelcomeScreenProps } from "./welcome-screen.js";
17
+ export { createSessionGridAnimation } from "./session-grid.js";
@@ -0,0 +1,11 @@
1
+ // Public page exports for the OpenTUI app.
2
+ export { FlowScreen } from "./flow-screen.js";
3
+ export { HomeScreen } from "./home-screen.js";
4
+ export { LOCATION_CARDS as HOME_CARDS, LocationCard } from "./location-card.js";
5
+ export { LocalSetupScreen } from "./local-setup-screen.js";
6
+ export { MenuScreen } from "./menu-screen.js";
7
+ export { SetupScreen } from "./setup-screen.js";
8
+ export { TerminalLog, terminalLogHeight } from "./terminal-log.js";
9
+ export { WelcomeScreen } from "./welcome-screen.js";
10
+ export { createSessionGridAnimation } from "./session-grid.js";
11
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/tui/pages/index.ts"],"names":[],"mappings":"AAAA,2CAA2C;AAC3C,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE9C,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE9C,OAAO,EAAE,cAAc,IAAI,UAAU,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEhF,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAO3D,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE9C,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEhD,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAEnE,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEpD,OAAO,EAAE,0BAA0B,EAAE,MAAM,mBAAmB,CAAC"}
@@ -0,0 +1,23 @@
1
+ type OpenTuiCore = typeof import("@opentui/core");
2
+ type LocalSetupCore = Pick<OpenTuiCore, "Box" | "Text" | "TextAttributes">;
3
+ export type LocalSetupStepStatus = "pending" | "active" | "done" | "skipped" | "error";
4
+ export type LocalSetupStep = {
5
+ label: string;
6
+ status: LocalSetupStepStatus;
7
+ };
8
+ export type LocalSetupState = "running" | "done" | "error";
9
+ export type LocalSetupScreenProps = {
10
+ steps: LocalSetupStep[];
11
+ note: string | null;
12
+ state: LocalSetupState;
13
+ spinner: string;
14
+ columns: number;
15
+ rows: number;
16
+ logs: string[];
17
+ logOffset: number;
18
+ logNotice: string | null;
19
+ onLogScroll: (delta: number) => void;
20
+ onLogLink: (url: string) => void;
21
+ };
22
+ export declare function LocalSetupScreen(core: LocalSetupCore, props: LocalSetupScreenProps): import("@opentui/core").ProxiedVNode<typeof import("@opentui/core").BoxRenderable>;
23
+ export {};
@@ -0,0 +1,134 @@
1
+ // Live progress view for the "Setup local installation" menu action. It
2
+ // narrates each phase (register → mode → install → config → daemon) so the
3
+ // action is legible instead of a silent pause with only log spew.
4
+ import { theme } from "../theme.js";
5
+ import { Footer } from "./footer.js";
6
+ import { TerminalLog, terminalLogHeight } from "./terminal-log.js";
7
+ function marker(status, spinner) {
8
+ switch (status) {
9
+ case "done":
10
+ return "✓";
11
+ case "active":
12
+ return spinner;
13
+ case "skipped":
14
+ return "–";
15
+ case "error":
16
+ return "✗";
17
+ default:
18
+ return "·";
19
+ }
20
+ }
21
+ function stepColor(status) {
22
+ switch (status) {
23
+ case "done":
24
+ return theme.color.accent;
25
+ case "active":
26
+ return theme.color.text;
27
+ case "error":
28
+ return theme.color.text;
29
+ case "skipped":
30
+ return theme.color.quiet;
31
+ default:
32
+ return theme.color.quiet;
33
+ }
34
+ }
35
+ function statusLine(state) {
36
+ switch (state) {
37
+ case "done":
38
+ return "Done — local gateway installed and running. Press Esc to return.";
39
+ case "error":
40
+ return "Setup failed — see the log below. Press Esc to return.";
41
+ default:
42
+ return "Working… please wait.";
43
+ }
44
+ }
45
+ export function LocalSetupScreen(core, props) {
46
+ const layout = setupLayout(props.columns, props.rows);
47
+ const stepNodes = props.steps.map((step) => core.Box({
48
+ width: layout.bodyWidth,
49
+ flexDirection: "row",
50
+ paddingLeft: 1,
51
+ }, core.Text({
52
+ content: `${marker(step.status, props.spinner)} `,
53
+ fg: stepColor(step.status),
54
+ attributes: step.status === "active"
55
+ ? core.TextAttributes.BOLD
56
+ : undefined,
57
+ }), core.Text({
58
+ content: step.label,
59
+ fg: stepColor(step.status),
60
+ attributes: step.status === "active"
61
+ ? core.TextAttributes.BOLD
62
+ : undefined,
63
+ })));
64
+ return core.Box({
65
+ backgroundColor: theme.color.app,
66
+ width: "100%",
67
+ height: "100%",
68
+ flexDirection: "column",
69
+ }, core.Box({
70
+ width: "100%",
71
+ flexGrow: 1,
72
+ flexDirection: "column",
73
+ alignItems: "center",
74
+ justifyContent: "center",
75
+ paddingLeft: layout.pad,
76
+ paddingRight: layout.pad,
77
+ }, core.Box({
78
+ width: layout.bodyWidth,
79
+ flexDirection: "column",
80
+ }, core.Text({
81
+ content: "Local installation setup",
82
+ fg: theme.color.text,
83
+ attributes: core.TextAttributes.BOLD,
84
+ }), core.Box({ width: layout.bodyWidth, height: 1 }), ...stepNodes, core.Box({ width: layout.bodyWidth, height: 1 }), core.Text({
85
+ content: props.note ?? " ",
86
+ fg: theme.color.muted,
87
+ }), core.Box({ width: layout.bodyWidth, height: 1 }), core.Text({
88
+ content: statusLine(props.state),
89
+ fg: props.state === "running"
90
+ ? theme.color.accent
91
+ : theme.color.text,
92
+ attributes: props.state === "running"
93
+ ? undefined
94
+ : core.TextAttributes.BOLD,
95
+ }))), TerminalLog(core, {
96
+ lines: props.logs,
97
+ width: layout.logWidth,
98
+ height: layout.logHeight,
99
+ offset: props.logOffset,
100
+ notice: props.logNotice,
101
+ onScroll: props.onLogScroll,
102
+ onLinkClick: props.onLogLink,
103
+ }), Footer(core, {
104
+ pad: layout.pad,
105
+ }));
106
+ }
107
+ function setupLayout(columns, rows) {
108
+ const pad = sidePad(columns);
109
+ const usable = Math.max(1, columns - pad * 2);
110
+ const bodyWidth = clamp(usable, 24, 64);
111
+ const logWidth = columns;
112
+ const logHeight = terminalLogHeight(rows);
113
+ return {
114
+ pad,
115
+ bodyWidth,
116
+ logWidth,
117
+ logHeight,
118
+ };
119
+ }
120
+ function sidePad(columns) {
121
+ if (columns >= 120)
122
+ return 8;
123
+ if (columns >= 96)
124
+ return 6;
125
+ if (columns >= 70)
126
+ return 4;
127
+ if (columns >= 48)
128
+ return 3;
129
+ return 2;
130
+ }
131
+ function clamp(value, min, max) {
132
+ return Math.min(Math.max(value, min), max);
133
+ }
134
+ //# sourceMappingURL=local-setup-screen.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local-setup-screen.js","sourceRoot":"","sources":["../../../src/tui/pages/local-setup-screen.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ type OpenTuiCore = typeof import("@opentui/core");
2
+ type LocationCore = Pick<OpenTuiCore, "Box" | "Text" | "TextAttributes">;
3
+ export type LocationAction = "local" | "cloud";
4
+ type Location = {
5
+ action: LocationAction;
6
+ icon: string;
7
+ label: string;
8
+ description: string;
9
+ };
10
+ export type LocationCardProps = {
11
+ selectedIndex: number;
12
+ width: number;
13
+ onHover: (index: number) => void;
14
+ onChoose: (index: number) => void;
15
+ };
16
+ export declare const LOCATION_CARDS: Location[];
17
+ export declare function locationCardMaxHeight(width: number): number;
18
+ export declare function LocationCard(core: LocationCore, props: LocationCardProps): import("@opentui/core").ProxiedVNode<typeof import("@opentui/core").BoxRenderable>;
19
+ export {};
@@ -0,0 +1,116 @@
1
+ // Owns the local/cloud location chooser card used by the TUI home screen.
2
+ import { theme } from "../theme.js";
3
+ const bodyPad = 3;
4
+ const cardGap = 1;
5
+ export const LOCATION_CARDS = [
6
+ {
7
+ action: "local",
8
+ icon: "◐",
9
+ label: "LOCAL",
10
+ description: "When running locally, none of your personal data hits our servers. Enjoy the benefits of using Sleev, privately.",
11
+ },
12
+ {
13
+ action: "cloud",
14
+ icon: "🌐",
15
+ label: "CLOUD",
16
+ description: "Use sleev cloud if you do not wish to install our local gateway. Parts of your conversations will be temporarily stored on our servers.",
17
+ },
18
+ ];
19
+ export function locationCardMaxHeight(width) {
20
+ const innerWidth = Math.max(1, width - 2);
21
+ const bodyWidth = Math.max(1, innerWidth - bodyPad * 2);
22
+ const bodyHeight = Math.max(...LOCATION_CARDS.map((card) => wrap(card.description, bodyWidth).length + 2));
23
+ return theme.size.tabHeight + cardGap + bodyHeight;
24
+ }
25
+ export function LocationCard(core, props) {
26
+ const active = LOCATION_CARDS[props.selectedIndex] ?? LOCATION_CARDS[0];
27
+ const innerWidth = Math.max(1, props.width - 2);
28
+ const bodyWidth = Math.max(1, innerWidth - bodyPad * 2);
29
+ const lines = wrap(active.description, bodyWidth);
30
+ const bodyHeight = lines.length + 2;
31
+ return core.Box({
32
+ width: props.width,
33
+ flexDirection: "column",
34
+ backgroundColor: "transparent",
35
+ gap: cardGap,
36
+ }, BorderCard(core, props.width, {
37
+ height: theme.size.tabHeight,
38
+ flexDirection: "row",
39
+ }, ...LOCATION_CARDS.map((card, index) => {
40
+ const selected = index === props.selectedIndex;
41
+ const background = selected
42
+ ? theme.color.card
43
+ : theme.color.footer;
44
+ return core.Box({
45
+ backgroundColor: background,
46
+ flexDirection: "column",
47
+ width: tabWidth(innerWidth, index),
48
+ height: theme.size.tabHeight,
49
+ onMouseOver: (event) => {
50
+ event.stopPropagation();
51
+ props.onHover(index);
52
+ },
53
+ onMouseDown: (event) => {
54
+ event.preventDefault();
55
+ event.stopPropagation();
56
+ props.onChoose(index);
57
+ },
58
+ }, core.Box({
59
+ flexGrow: 1,
60
+ alignItems: "center",
61
+ justifyContent: "center",
62
+ paddingTop: 1,
63
+ }, core.Text({
64
+ content: `${card.icon} ${card.label}`,
65
+ fg: selected ? theme.color.text : theme.color.muted,
66
+ attributes: core.TextAttributes.BOLD,
67
+ })), core.Box({
68
+ backgroundColor: background,
69
+ width: "100%",
70
+ height: 1,
71
+ }, core.Text({
72
+ content: "▀".repeat(tabWidth(innerWidth, index)),
73
+ fg: background,
74
+ bg: selected ? theme.color.accent : background,
75
+ })));
76
+ })), BorderCard(core, props.width, {
77
+ height: bodyHeight,
78
+ paddingLeft: bodyPad,
79
+ paddingRight: bodyPad,
80
+ paddingTop: 1,
81
+ paddingBottom: 1,
82
+ flexDirection: "column",
83
+ backgroundColor: theme.color.card,
84
+ }, ...lines.map((line) => core.Text({
85
+ content: line,
86
+ fg: theme.color.muted,
87
+ }))));
88
+ }
89
+ function BorderCard(core, width, props, ...children) {
90
+ const inner = Math.max(1, width - 2);
91
+ return core.Box({
92
+ width,
93
+ flexDirection: "row",
94
+ }, core.Box({ width: 1, backgroundColor: theme.color.shadow }), core.Box({
95
+ ...props,
96
+ width: inner,
97
+ }, ...children), core.Box({ width: 1, backgroundColor: theme.color.shadow }));
98
+ }
99
+ function tabWidth(width, index) {
100
+ const half = Math.floor(width / LOCATION_CARDS.length);
101
+ if (index === LOCATION_CARDS.length - 1)
102
+ return width - half * index;
103
+ return half;
104
+ }
105
+ function wrap(text, width) {
106
+ return text.split(" ").reduce((lines, word) => {
107
+ const last = lines.at(-1);
108
+ if (!last)
109
+ return [word];
110
+ if (`${last} ${word}`.length <= width) {
111
+ return [...lines.slice(0, -1), `${last} ${word}`];
112
+ }
113
+ return [...lines, word];
114
+ }, []);
115
+ }
116
+ //# sourceMappingURL=location-card.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"location-card.js","sourceRoot":"","sources":["../../../src/tui/pages/location-card.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAC1E,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAgBpC,MAAM,OAAO,GAAG,CAAC,CAAC;AAClB,MAAM,OAAO,GAAG,CAAC,CAAC;AASlB,MAAM,CAAC,MAAM,cAAc,GAAe;IACtC;QACI,MAAM,EAAE,OAAO;QACf,IAAI,EAAE,GAAG;QACT,KAAK,EAAE,OAAO;QACd,WAAW,EACP,kHAAkH;KACzH;IACD;QACI,MAAM,EAAE,OAAO;QACf,IAAI,EAAE,IAAI;QACV,KAAK,EAAE,OAAO;QACd,WAAW,EACP,yIAAyI;KAChJ;CACJ,CAAC;AAEF,MAAM,UAAU,qBAAqB,CAAC,KAAa;IAC/C,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC;IAC1C,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,UAAU,GAAG,OAAO,GAAG,CAAC,CAAC,CAAC;IACxD,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CACvB,GAAG,cAAc,CAAC,GAAG,CACjB,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC,MAAM,GAAG,CAAC,CACzD,CACJ,CAAC;IACF,OAAO,KAAK,CAAC,IAAI,CAAC,SAAS,GAAG,OAAO,GAAG,UAAU,CAAC;AACvD,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,IAAkB,EAAE,KAAwB;IACrE,MAAM,MAAM,GAAG,cAAc,CAAC,KAAK,CAAC,aAAa,CAAC,IAAI,cAAc,CAAC,CAAC,CAAC,CAAC;IACxE,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;IAChD,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,UAAU,GAAG,OAAO,GAAG,CAAC,CAAC,CAAC;IACxD,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;IAClD,MAAM,UAAU,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;IAEpC,OAAO,IAAI,CAAC,GAAG,CACX;QACI,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,aAAa,EAAE,QAAQ;QACvB,eAAe,EAAE,aAAa;QAC9B,GAAG,EAAE,OAAO;KACf,EACD,UAAU,CACN,IAAI,EACJ,KAAK,CAAC,KAAK,EACX;QACI,MAAM,EAAE,KAAK,CAAC,IAAI,CAAC,SAAS;QAC5B,aAAa,EAAE,KAAK;KACvB,EACD,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;QAClC,MAAM,QAAQ,GAAG,KAAK,KAAK,KAAK,CAAC,aAAa,CAAC;QAC/C,MAAM,UAAU,GAAG,QAAQ;YACvB,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI;YAClB,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC;QAEzB,OAAO,IAAI,CAAC,GAAG,CACX;YACI,eAAe,EAAE,UAAU;YAC3B,aAAa,EAAE,QAAQ;YACvB,KAAK,EAAE,QAAQ,CAAC,UAAU,EAAE,KAAK,CAAC;YAClC,MAAM,EAAE,KAAK,CAAC,IAAI,CAAC,SAAS;YAC5B,WAAW,EAAE,CAAC,KAAiB,EAAE,EAAE;gBAC/B,KAAK,CAAC,eAAe,EAAE,CAAC;gBACxB,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;YACzB,CAAC;YACD,WAAW,EAAE,CAAC,KAAiB,EAAE,EAAE;gBAC/B,KAAK,CAAC,cAAc,EAAE,CAAC;gBACvB,KAAK,CAAC,eAAe,EAAE,CAAC;gBACxB,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;YAC1B,CAAC;SACJ,EACD,IAAI,CAAC,GAAG,CACJ;YACI,QAAQ,EAAE,CAAC;YACX,UAAU,EAAE,QAAQ;YACpB,cAAc,EAAE,QAAQ;YACxB,UAAU,EAAE,CAAC;SAChB,EACD,IAAI,CAAC,IAAI,CAAC;YACN,OAAO,EAAE,GAAG,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,KAAK,EAAE;YACrC,EAAE,EAAE,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK;YACnD,UAAU,EAAE,IAAI,CAAC,cAAc,CAAC,IAAI;SACvC,CAAC,CACL,EACD,IAAI,CAAC,GAAG,CACJ;YACI,eAAe,EAAE,UAAU;YAC3B,KAAK,EAAE,MAAM;YACb,MAAM,EAAE,CAAC;SACZ,EACD,IAAI,CAAC,IAAI,CAAC;YACN,OAAO,EAAE,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;YAChD,EAAE,EAAE,UAAU;YACd,EAAE,EAAE,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,UAAU;SACjD,CAAC,CACL,CACJ,CAAC;IACN,CAAC,CAAC,CACL,EACD,UAAU,CACN,IAAI,EACJ,KAAK,CAAC,KAAK,EACX;QACI,MAAM,EAAE,UAAU;QAClB,WAAW,EAAE,OAAO;QACpB,YAAY,EAAE,OAAO;QACrB,UAAU,EAAE,CAAC;QACb,aAAa,EAAE,CAAC;QAChB,aAAa,EAAE,QAAQ;QACvB,eAAe,EAAE,KAAK,CAAC,KAAK,CAAC,IAAI;KACpC,EACD,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAClB,IAAI,CAAC,IAAI,CAAC;QACN,OAAO,EAAE,IAAI;QACb,EAAE,EAAE,KAAK,CAAC,KAAK,CAAC,KAAK;KACxB,CAAC,CACL,CACJ,CACJ,CAAC;AACN,CAAC;AAED,SAAS,UAAU,CACf,IAAkB,EAClB,KAAa,EACb,KAAyC,EACzC,GAAG,QAAiB;IAEpB,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC;IAErC,OAAO,IAAI,CAAC,GAAG,CACX;QACI,KAAK;QACL,aAAa,EAAE,KAAK;KACvB,EACD,IAAI,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,eAAe,EAAE,KAAK,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,EAC3D,IAAI,CAAC,GAAG,CACJ;QACI,GAAG,KAAK;QACR,KAAK,EAAE,KAAK;KACf,EACD,GAAG,QAAQ,CACd,EACD,IAAI,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,eAAe,EAAE,KAAK,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAC9D,CAAC;AACN,CAAC;AAED,SAAS,QAAQ,CAAC,KAAa,EAAE,KAAa;IAC1C,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC;IACvD,IAAI,KAAK,KAAK,cAAc,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,KAAK,GAAG,IAAI,GAAG,KAAK,CAAC;IACrE,OAAO,IAAI,CAAC;AAChB,CAAC;AAED,SAAS,IAAI,CAAC,IAAY,EAAE,KAAa;IACrC,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAW,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;QACpD,MAAM,IAAI,GAAG,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QAC1B,IAAI,CAAC,IAAI;YAAE,OAAO,CAAC,IAAI,CAAC,CAAC;QACzB,IAAI,GAAG,IAAI,IAAI,IAAI,EAAE,CAAC,MAAM,IAAI,KAAK,EAAE,CAAC;YACpC,OAAO,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,IAAI,IAAI,IAAI,EAAE,CAAC,CAAC;QACtD,CAAC;QACD,OAAO,CAAC,GAAG,KAAK,EAAE,IAAI,CAAC,CAAC;IAC5B,CAAC,EAAE,EAAE,CAAC,CAAC;AACX,CAAC"}
@@ -0,0 +1,24 @@
1
+ type OpenTuiCore = typeof import("@opentui/core");
2
+ type MenuCore = Pick<OpenTuiCore, "Box" | "Text" | "TextAttributes">;
3
+ export type MenuAction = "local-setup" | "wizard" | "auth" | "location" | "tokens" | "harnesses";
4
+ export type MenuItem = {
5
+ action: MenuAction;
6
+ label: string;
7
+ detail: string;
8
+ enabled: boolean;
9
+ };
10
+ export type MenuScreenProps = {
11
+ items: MenuItem[];
12
+ selectedIndex: number;
13
+ columns: number;
14
+ rows: number;
15
+ logs: string[];
16
+ logOffset: number;
17
+ logNotice: string | null;
18
+ onHover: (index: number) => void;
19
+ onChoose: (index: number) => void;
20
+ onLogScroll: (delta: number) => void;
21
+ onLogLink: (url: string) => void;
22
+ };
23
+ export declare function MenuScreen(core: MenuCore, props: MenuScreenProps): import("@opentui/core").ProxiedVNode<typeof import("@opentui/core").BoxRenderable>;
24
+ export {};
@@ -0,0 +1,117 @@
1
+ // Owns the top-level TUI navigation menu.
2
+ import { theme } from "../theme.js";
3
+ import { TerminalLog, terminalLogHeight } from "./terminal-log.js";
4
+ export function MenuScreen(core, props) {
5
+ const layout = menuLayout(props.columns, props.rows);
6
+ return core.Box({
7
+ backgroundColor: "transparent",
8
+ width: "100%",
9
+ height: "100%",
10
+ flexDirection: "column",
11
+ }, core.Box({
12
+ width: "100%",
13
+ flexGrow: 1,
14
+ alignItems: "center",
15
+ justifyContent: "center",
16
+ paddingLeft: layout.pad,
17
+ paddingRight: layout.pad,
18
+ }, core.Box({
19
+ width: layout.width,
20
+ flexDirection: "column",
21
+ backgroundColor: theme.color.card,
22
+ paddingLeft: 3,
23
+ paddingRight: 3,
24
+ paddingTop: 2,
25
+ paddingBottom: 2,
26
+ gap: 1,
27
+ }, core.Text({
28
+ content: "Menu",
29
+ fg: theme.color.text,
30
+ attributes: core.TextAttributes.BOLD,
31
+ }), core.Text({
32
+ content: "Open any setup step or account action.",
33
+ fg: theme.color.muted,
34
+ }), core.Box({
35
+ flexDirection: "column",
36
+ gap: 1,
37
+ paddingTop: 1,
38
+ }, ...props.items.map((item, index) => MenuRow(core, {
39
+ item,
40
+ index,
41
+ selected: index === props.selectedIndex,
42
+ width: Math.max(20, layout.width - 6),
43
+ onHover: props.onHover,
44
+ onChoose: props.onChoose,
45
+ }))))), TerminalLog(core, {
46
+ lines: props.logs,
47
+ width: props.columns,
48
+ height: layout.logHeight,
49
+ offset: props.logOffset,
50
+ notice: props.logNotice,
51
+ onScroll: props.onLogScroll,
52
+ onLinkClick: props.onLogLink,
53
+ }));
54
+ }
55
+ function MenuRow(core, props) {
56
+ const background = props.selected
57
+ ? theme.color.accentDim
58
+ : theme.color.footer;
59
+ const titleColor = props.item.enabled
60
+ ? theme.color.text
61
+ : theme.color.quiet;
62
+ const detailColor = props.item.enabled
63
+ ? theme.color.muted
64
+ : theme.color.quiet;
65
+ return core.Box({
66
+ width: props.width,
67
+ flexDirection: "column",
68
+ backgroundColor: background,
69
+ paddingLeft: 2,
70
+ paddingRight: 2,
71
+ paddingTop: 1,
72
+ paddingBottom: 1,
73
+ onMouseOver: (event) => {
74
+ event.stopPropagation();
75
+ props.onHover(props.index);
76
+ },
77
+ onMouseDown: (event) => {
78
+ event.preventDefault();
79
+ event.stopPropagation();
80
+ if (props.item.enabled)
81
+ props.onChoose(props.index);
82
+ },
83
+ }, core.Text({
84
+ content: props.item.label,
85
+ fg: titleColor,
86
+ attributes: core.TextAttributes.BOLD,
87
+ }), core.Text({
88
+ content: props.item.detail,
89
+ fg: detailColor,
90
+ }));
91
+ }
92
+ function menuLayout(columns, rows) {
93
+ const pad = sidePad(columns);
94
+ const usable = Math.max(1, columns - pad * 2);
95
+ const width = clamp(usable, 34, 62);
96
+ const logHeight = terminalLogHeight(rows);
97
+ return {
98
+ pad,
99
+ width,
100
+ logHeight,
101
+ };
102
+ }
103
+ function sidePad(columns) {
104
+ if (columns >= 120)
105
+ return 8;
106
+ if (columns >= 96)
107
+ return 6;
108
+ if (columns >= 70)
109
+ return 4;
110
+ if (columns >= 48)
111
+ return 3;
112
+ return 2;
113
+ }
114
+ function clamp(value, min, max) {
115
+ return Math.min(Math.max(value, min), max);
116
+ }
117
+ //# sourceMappingURL=menu-screen.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"menu-screen.js","sourceRoot":"","sources":["../../../src/tui/pages/menu-screen.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ type OpenTuiCore = typeof import("@opentui/core");
2
+ type GridCore = Pick<OpenTuiCore, "Box" | "Text" | "TextAttributes">;
3
+ export type SessionGridSnapshot = {
4
+ dots: Array<{
5
+ x: number;
6
+ y: number;
7
+ opacity: number;
8
+ }>;
9
+ rows: number;
10
+ rawWidth: number;
11
+ currentWidth: number;
12
+ currentTokens: number;
13
+ savedTokens: number;
14
+ };
15
+ export type SessionGridAnimation = {
16
+ snapshot: (now?: number) => SessionGridSnapshot;
17
+ };
18
+ export declare const SESSION_GRID_WIDTH: number;
19
+ export declare const SESSION_GRID_MAX_HEIGHT: number;
20
+ export declare function createSessionGridAnimation(start?: number): SessionGridAnimation;
21
+ export declare function SessionGrid(core: GridCore, snapshot: SessionGridSnapshot): import("@opentui/core").ProxiedVNode<typeof import("@opentui/core").BoxRenderable>;
22
+ export declare function sessionGridHeight(snapshot: SessionGridSnapshot): number;
23
+ export {};