@vibesdotdev/terminal-client 0.0.0-stage → 1.0.0-rc.2

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 (195) hide show
  1. package/LICENSE +18 -0
  2. package/README.md +102 -2
  3. package/dist/ansi/index.d.ts +11 -0
  4. package/dist/ansi/index.d.ts.map +1 -0
  5. package/dist/ansi/index.js +11 -0
  6. package/dist/ansi/index.js.map +1 -0
  7. package/dist/ansi/keymap.d.ts +77 -0
  8. package/dist/ansi/keymap.d.ts.map +1 -0
  9. package/dist/ansi/keymap.js +257 -0
  10. package/dist/ansi/keymap.js.map +1 -0
  11. package/dist/api-client-plugin.d.ts +4 -0
  12. package/dist/api-client-plugin.d.ts.map +1 -0
  13. package/dist/api-client-plugin.js +16 -0
  14. package/dist/api-client-plugin.js.map +1 -0
  15. package/dist/client/http-session.d.ts +44 -0
  16. package/dist/client/http-session.d.ts.map +1 -0
  17. package/dist/client/http-session.js +457 -0
  18. package/dist/client/http-session.js.map +1 -0
  19. package/dist/client/index.d.ts +8 -0
  20. package/dist/client/index.d.ts.map +1 -0
  21. package/dist/client/index.js +8 -0
  22. package/dist/client/index.js.map +1 -0
  23. package/dist/client.d.ts +56 -0
  24. package/dist/client.d.ts.map +1 -0
  25. package/dist/client.js +169 -0
  26. package/dist/client.js.map +1 -0
  27. package/dist/index.d.ts +14 -0
  28. package/dist/index.d.ts.map +1 -0
  29. package/dist/index.js +14 -0
  30. package/dist/index.js.map +1 -0
  31. package/dist/pty-bridge/index.d.ts +15 -0
  32. package/dist/pty-bridge/index.d.ts.map +1 -0
  33. package/dist/pty-bridge/index.js +15 -0
  34. package/dist/pty-bridge/index.js.map +1 -0
  35. package/dist/pty-bridge/protocol.d.ts +6 -0
  36. package/dist/pty-bridge/protocol.d.ts.map +1 -0
  37. package/dist/pty-bridge/protocol.js +6 -0
  38. package/dist/pty-bridge/protocol.js.map +1 -0
  39. package/dist/pty-bridge/server.d.ts +7 -0
  40. package/dist/pty-bridge/server.d.ts.map +1 -0
  41. package/dist/pty-bridge/server.js +9 -0
  42. package/dist/pty-bridge/server.js.map +1 -0
  43. package/dist/remote-session.d.ts +51 -0
  44. package/dist/remote-session.d.ts.map +1 -0
  45. package/dist/remote-session.js +326 -0
  46. package/dist/remote-session.js.map +1 -0
  47. package/dist/schemas/http.d.ts +61 -0
  48. package/dist/schemas/http.d.ts.map +1 -0
  49. package/dist/schemas/http.js +45 -0
  50. package/dist/schemas/http.js.map +1 -0
  51. package/dist/schemas/remote.d.ts +25 -0
  52. package/dist/schemas/remote.d.ts.map +1 -0
  53. package/dist/schemas/remote.js +23 -0
  54. package/dist/schemas/remote.js.map +1 -0
  55. package/dist/schemas/session.d.ts +26 -0
  56. package/dist/schemas/session.d.ts.map +1 -0
  57. package/dist/schemas/session.js +17 -0
  58. package/dist/schemas/session.js.map +1 -0
  59. package/dist/schemas/store.d.ts +29 -0
  60. package/dist/schemas/store.d.ts.map +1 -0
  61. package/dist/schemas/store.js +22 -0
  62. package/dist/schemas/store.js.map +1 -0
  63. package/dist/schemas/terminal.d.ts +296 -0
  64. package/dist/schemas/terminal.d.ts.map +1 -0
  65. package/dist/schemas/terminal.js +243 -0
  66. package/dist/schemas/terminal.js.map +1 -0
  67. package/dist/server/index.d.ts +9 -0
  68. package/dist/server/index.d.ts.map +1 -0
  69. package/dist/server/index.js +9 -0
  70. package/dist/server/index.js.map +1 -0
  71. package/dist/server/session-store.d.ts +176 -0
  72. package/dist/server/session-store.d.ts.map +1 -0
  73. package/dist/server/session-store.js +462 -0
  74. package/dist/server/session-store.js.map +1 -0
  75. package/dist/server/sse-stream.d.ts +32 -0
  76. package/dist/server/sse-stream.d.ts.map +1 -0
  77. package/dist/server/sse-stream.js +87 -0
  78. package/dist/server/sse-stream.js.map +1 -0
  79. package/dist/svelte/HostPicker.svelte +256 -0
  80. package/dist/svelte/HostPicker.svelte.d.ts +30 -0
  81. package/dist/svelte/HostPicker.svelte.d.ts.map +1 -0
  82. package/dist/svelte/README.md +52 -0
  83. package/dist/svelte/ReconnectBanner.svelte +88 -0
  84. package/dist/svelte/ReconnectBanner.svelte.d.ts +16 -0
  85. package/dist/svelte/ReconnectBanner.svelte.d.ts.map +1 -0
  86. package/dist/svelte/SessionTabs.svelte +192 -0
  87. package/dist/svelte/SessionTabs.svelte.d.ts +17 -0
  88. package/dist/svelte/SessionTabs.svelte.d.ts.map +1 -0
  89. package/dist/svelte/Terminal.svelte +567 -0
  90. package/dist/svelte/Terminal.svelte.d.ts +25 -0
  91. package/dist/svelte/Terminal.svelte.d.ts.map +1 -0
  92. package/dist/svelte/TerminalMobileToolbar.svelte +56 -0
  93. package/dist/svelte/TerminalMobileToolbar.svelte.d.ts +14 -0
  94. package/dist/svelte/TerminalMobileToolbar.svelte.d.ts.map +1 -0
  95. package/dist/svelte/TerminalWorkspace.svelte +562 -0
  96. package/dist/svelte/TerminalWorkspace.svelte.d.ts +25 -0
  97. package/dist/svelte/TerminalWorkspace.svelte.d.ts.map +1 -0
  98. package/dist/svelte/ambient.d.ts +9 -0
  99. package/dist/svelte/docs/terminal-svelte.docs.descriptor.d.ts +4 -0
  100. package/dist/svelte/docs/terminal-svelte.docs.descriptor.d.ts.map +1 -0
  101. package/dist/svelte/docs/terminal-svelte.docs.descriptor.js +74 -0
  102. package/dist/svelte/index.d.ts +27 -0
  103. package/dist/svelte/index.d.ts.map +1 -0
  104. package/dist/svelte/index.js +26 -0
  105. package/dist/svelte/styles.css +8 -0
  106. package/dist/svelte/terminal-session-authority.d.ts +17 -0
  107. package/dist/svelte/terminal-session-authority.d.ts.map +1 -0
  108. package/dist/svelte/terminal-session-authority.js +25 -0
  109. package/dist/svelte/terminal-svelte.plugin.d.ts +19 -0
  110. package/dist/svelte/terminal-svelte.plugin.d.ts.map +1 -0
  111. package/dist/svelte/terminal-svelte.plugin.js +42 -0
  112. package/dist/svelte/terminal-theme.d.ts +11 -0
  113. package/dist/svelte/terminal-theme.d.ts.map +1 -0
  114. package/dist/svelte/terminal-theme.js +116 -0
  115. package/dist/svelte/tool-widgets/TerminalToolCard.svelte +65 -0
  116. package/dist/svelte/tool-widgets/TerminalToolCard.svelte.d.ts +5 -0
  117. package/dist/svelte/tool-widgets/TerminalToolCard.svelte.d.ts.map +1 -0
  118. package/dist/svelte/tool-widgets/terminal-tool-card.d.ts +25 -0
  119. package/dist/svelte/tool-widgets/terminal-tool-card.d.ts.map +1 -0
  120. package/dist/svelte/tool-widgets/terminal-tool-card.js +116 -0
  121. package/dist/svelte/types.d.ts +160 -0
  122. package/dist/svelte/types.d.ts.map +1 -0
  123. package/dist/svelte/types.js +51 -0
  124. package/dist/svelte/workspace.d.ts +3 -0
  125. package/dist/svelte/workspace.d.ts.map +1 -0
  126. package/dist/svelte/workspace.js +2 -0
  127. package/dist/terminal-client.plugin.d.ts +3 -0
  128. package/dist/terminal-client.plugin.d.ts.map +1 -0
  129. package/dist/terminal-client.plugin.js +3 -0
  130. package/dist/terminal-client.plugin.js.map +1 -0
  131. package/dist/terminal-runtime.d.ts +30 -0
  132. package/dist/terminal-runtime.d.ts.map +1 -0
  133. package/dist/terminal-runtime.js +673 -0
  134. package/dist/terminal-runtime.js.map +1 -0
  135. package/dist/terminal.consumer.plugin.d.ts +14 -0
  136. package/dist/terminal.consumer.plugin.d.ts.map +1 -0
  137. package/dist/terminal.consumer.plugin.js +31 -0
  138. package/dist/terminal.consumer.plugin.js.map +1 -0
  139. package/dist/tools/terminal.impl.consumer.d.ts +11 -0
  140. package/dist/tools/terminal.impl.consumer.d.ts.map +1 -0
  141. package/dist/tools/terminal.impl.consumer.js +20 -0
  142. package/dist/tools/terminal.impl.consumer.js.map +1 -0
  143. package/dist/tools/terminal.schemas.d.ts +3 -0
  144. package/dist/tools/terminal.schemas.d.ts.map +1 -0
  145. package/dist/tools/terminal.schemas.js +3 -0
  146. package/dist/tools/terminal.schemas.js.map +1 -0
  147. package/dist/tools/terminal.unified.descriptor.d.ts +218 -0
  148. package/dist/tools/terminal.unified.descriptor.d.ts.map +1 -0
  149. package/dist/tools/terminal.unified.descriptor.js +36 -0
  150. package/dist/tools/terminal.unified.descriptor.js.map +1 -0
  151. package/dist/tui/index.d.ts +9 -0
  152. package/dist/tui/index.d.ts.map +1 -0
  153. package/dist/tui/index.js +8 -0
  154. package/dist/tui/index.js.map +1 -0
  155. package/dist/tui/terminal-open.descriptor.d.ts +9 -0
  156. package/dist/tui/terminal-open.descriptor.d.ts.map +1 -0
  157. package/dist/tui/terminal-open.descriptor.js +18 -0
  158. package/dist/tui/terminal-open.descriptor.js.map +1 -0
  159. package/dist/tui/terminal-open.impl.consumer.d.ts +9 -0
  160. package/dist/tui/terminal-open.impl.consumer.d.ts.map +1 -0
  161. package/dist/tui/terminal-open.impl.consumer.js +13 -0
  162. package/dist/tui/terminal-open.impl.consumer.js.map +1 -0
  163. package/dist/tui/terminal-registry.descriptor.d.ts +11 -0
  164. package/dist/tui/terminal-registry.descriptor.d.ts.map +1 -0
  165. package/dist/tui/terminal-registry.descriptor.js +17 -0
  166. package/dist/tui/terminal-registry.descriptor.js.map +1 -0
  167. package/dist/tui/terminal-registry.impl.consumer.d.ts +71 -0
  168. package/dist/tui/terminal-registry.impl.consumer.d.ts.map +1 -0
  169. package/dist/tui/terminal-registry.impl.consumer.js +190 -0
  170. package/dist/tui/terminal-registry.impl.consumer.js.map +1 -0
  171. package/dist/tui/terminal-tui.plugin.d.ts +10 -0
  172. package/dist/tui/terminal-tui.plugin.d.ts.map +1 -0
  173. package/dist/tui/terminal-tui.plugin.js +32 -0
  174. package/dist/tui/terminal-tui.plugin.js.map +1 -0
  175. package/dist/tui/terminal.descriptor.d.ts +10 -0
  176. package/dist/tui/terminal.descriptor.d.ts.map +1 -0
  177. package/dist/tui/terminal.descriptor.js +25 -0
  178. package/dist/tui/terminal.descriptor.js.map +1 -0
  179. package/dist/tui/terminal.impl.consumer.d.ts +14 -0
  180. package/dist/tui/terminal.impl.consumer.d.ts.map +1 -0
  181. package/dist/tui/terminal.impl.consumer.js +189 -0
  182. package/dist/tui/terminal.impl.consumer.js.map +1 -0
  183. package/dist/tui/terminal.state-key.d.ts +30 -0
  184. package/dist/tui/terminal.state-key.d.ts.map +1 -0
  185. package/dist/tui/terminal.state-key.js +9 -0
  186. package/dist/tui/terminal.state-key.js.map +1 -0
  187. package/dist/tui/terminal.state.d.ts +152 -0
  188. package/dist/tui/terminal.state.d.ts.map +1 -0
  189. package/dist/tui/terminal.state.js +149 -0
  190. package/dist/tui/terminal.state.js.map +1 -0
  191. package/dist/workspace.d.ts +155 -0
  192. package/dist/workspace.d.ts.map +1 -0
  193. package/dist/workspace.js +292 -0
  194. package/dist/workspace.js.map +1 -0
  195. package/package.json +228 -4
@@ -0,0 +1,192 @@
1
+ <script lang="ts">
2
+ /**
3
+ * <SessionTabs> — tab strip for multiple concurrent terminal sessions.
4
+ *
5
+ * Each tab shows: command label (truncated) + host suffix, active/detached
6
+ * indicator, and a close button. Clicking a tab makes it active; clicking a
7
+ * close button kills the session (with confirmation when still running). The
8
+ * "+" button opens the picker for a new session.
9
+ *
10
+ * Keyboard: Left/Right arrow keys navigate tabs; Delete/Backspace on a tab
11
+ * opens the kill confirmation.
12
+ *
13
+ * Detached sessions are shown with a dimmed indicator — the PTY is running
14
+ * but no browser client is watching. Clicking them re-attaches.
15
+ */
16
+
17
+ import { Button } from '@vibesdotdev/kit/components/ui/button';
18
+ import { cn } from '@vibesdotdev/kit/utils';
19
+ import type { TabSession } from './types.js';
20
+
21
+ interface Props {
22
+ /** Ordered list of tabs to render. */
23
+ tabs: TabSession[];
24
+ /** The id of the currently visible (active) tab. */
25
+ activeId: string;
26
+ /** Called when a tab is clicked to activate it. */
27
+ onSelect: (id: string) => void;
28
+ /** Called when the user confirms closing (killing) a session. */
29
+ onClose: (id: string) => void;
30
+ /** Called when the + button is pressed to open the picker for a new session. */
31
+ onNewTab: () => void;
32
+ }
33
+
34
+ let { tabs, activeId, onSelect, onClose, onNewTab }: Props = $props();
35
+
36
+ /** Tab whose close button was clicked, pending user confirmation. */
37
+ let confirmingCloseId = $state<string | null>(null);
38
+
39
+ const confirmingTab = $derived(
40
+ confirmingCloseId !== null ? tabs.find((t) => t.id === confirmingCloseId) : null
41
+ );
42
+
43
+ function handleTabKeydown(e: KeyboardEvent, tabId: string, idx: number) {
44
+ if (e.key === 'ArrowRight') {
45
+ e.preventDefault();
46
+ const next = tabs[idx + 1];
47
+ if (next) onSelect(next.id);
48
+ } else if (e.key === 'ArrowLeft') {
49
+ e.preventDefault();
50
+ const prev = tabs[idx - 1];
51
+ if (prev) onSelect(prev.id);
52
+ } else if (e.key === 'Delete' || e.key === 'Backspace') {
53
+ e.preventDefault();
54
+ confirmingCloseId = tabId;
55
+ }
56
+ }
57
+
58
+ function requestClose(id: string) {
59
+ const tab = tabs.find((t) => t.id === id);
60
+ if (!tab) return;
61
+ // If process has exited there's nothing running — close without confirm.
62
+ if (tab.exited) {
63
+ onClose(id);
64
+ } else {
65
+ confirmingCloseId = id;
66
+ }
67
+ }
68
+
69
+ function confirmClose() {
70
+ if (confirmingCloseId) {
71
+ onClose(confirmingCloseId);
72
+ confirmingCloseId = null;
73
+ }
74
+ }
75
+
76
+ function cancelClose() {
77
+ confirmingCloseId = null;
78
+ }
79
+
80
+ /** Reference to the cancel button so we can focus it when the dialog mounts. */
81
+ let cancelBtnEl = $state<HTMLButtonElement | null>(null);
82
+
83
+ $effect(() => {
84
+ if (confirmingCloseId && cancelBtnEl) {
85
+ cancelBtnEl.focus();
86
+ }
87
+ });
88
+
89
+ function shortLabel(tab: TabSession): string {
90
+ const cmd = tab.command.split('/').pop() ?? tab.command;
91
+ const host = tab.hostLabel ? ` — ${tab.hostLabel}` : '';
92
+ return cmd + host;
93
+ }
94
+
95
+ function tabClass(tab: TabSession): string {
96
+ return cn(
97
+ 'group relative flex min-w-20 max-w-44 cursor-pointer select-none items-center gap-1.5 border-r border-border px-2.5 text-xs text-muted-foreground outline-none transition-colors hover:bg-card hover:text-foreground focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-ring',
98
+ tab.id === activeId && 'border-b-2 border-b-primary bg-card text-foreground',
99
+ tab.detached && !tab.exited && 'opacity-70',
100
+ tab.exited && 'opacity-50'
101
+ );
102
+ }
103
+
104
+ function indicatorClass(tab: TabSession): string {
105
+ return cn(
106
+ 'size-2 shrink-0 rounded-full bg-muted-foreground',
107
+ !tab.detached && !tab.exited && 'bg-success',
108
+ tab.detached && !tab.exited && 'bg-warning'
109
+ );
110
+ }
111
+ </script>
112
+
113
+ <div
114
+ class="flex min-h-9 shrink-0 items-stretch overflow-x-auto border-b border-border bg-background"
115
+ role="tablist"
116
+ aria-label="Terminal sessions"
117
+ >
118
+ {#each tabs as tab, idx (tab.id)}
119
+ <div
120
+ class={tabClass(tab)}
121
+ role="tab"
122
+ aria-selected={tab.id === activeId}
123
+ aria-label="{shortLabel(tab)}{tab.detached && !tab.exited ? ' (detached — running)' : ''}{tab.exited ? ' (ended)' : ''}"
124
+ tabindex={tab.id === activeId ? 0 : -1}
125
+ onclick={() => onSelect(tab.id)}
126
+ onkeydown={(e) => handleTabKeydown(e, tab.id, idx)}
127
+ >
128
+ <span
129
+ class={indicatorClass(tab)}
130
+ title={tab.detached && !tab.exited ? 'Running — not connected' : tab.exited ? 'Session ended' : 'Live'}
131
+ ></span>
132
+ <span class="min-w-0 flex-1 truncate font-mono">{shortLabel(tab)}</span>
133
+ <button
134
+ class={cn(
135
+ 'flex size-4 shrink-0 items-center justify-center rounded-sm text-sm leading-none text-muted-foreground/60 opacity-0 transition-opacity hover:bg-accent hover:text-foreground focus-visible:opacity-100 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring',
136
+ tab.id === activeId && 'opacity-100',
137
+ 'group-hover:opacity-100'
138
+ )}
139
+ type="button"
140
+ aria-label="Close {shortLabel(tab)}"
141
+ onclick={(e) => {
142
+ e.stopPropagation();
143
+ requestClose(tab.id);
144
+ }}
145
+ tabindex={-1}
146
+ >×</button>
147
+ </div>
148
+ {/each}
149
+
150
+ <Button
151
+ variant="ghost"
152
+ size="icon-sm"
153
+ class="h-9 min-w-9 rounded-none border-r border-border text-muted-foreground hover:text-foreground"
154
+ aria-label="Open a new terminal tab"
155
+ title="New tab"
156
+ onclick={onNewTab}
157
+ >+</Button>
158
+ </div>
159
+
160
+ {#if confirmingTab}
161
+ <!-- Kill confirmation overlay -->
162
+ <div
163
+ class="fixed inset-0 z-50 flex items-center justify-center bg-background/80 px-4"
164
+ role="dialog"
165
+ aria-modal="true"
166
+ aria-label="Close session"
167
+ >
168
+ <div class="w-full max-w-80 rounded-md border border-border bg-card px-6 py-5">
169
+ <p class="mb-4 mt-0 text-sm leading-normal text-card-foreground">
170
+ {#if confirmingTab.exited}
171
+ Remove this tab?
172
+ {:else}
173
+ Close "<strong>{shortLabel(confirmingTab)}</strong>"?
174
+ The running process will be stopped.
175
+ {/if}
176
+ </p>
177
+ <div class="flex justify-end gap-2">
178
+ <Button
179
+ variant="outline"
180
+ size="sm"
181
+ onclick={cancelClose}
182
+ bind:ref={cancelBtnEl}
183
+ >Keep running</Button>
184
+ <Button
185
+ variant="destructive"
186
+ size="sm"
187
+ onclick={confirmClose}
188
+ >{confirmingTab.exited ? 'Remove' : 'Stop and close'}</Button>
189
+ </div>
190
+ </div>
191
+ </div>
192
+ {/if}
@@ -0,0 +1,17 @@
1
+ import type { TabSession } from './types.ts';
2
+ interface Props {
3
+ /** Ordered list of tabs to render. */
4
+ tabs: TabSession[];
5
+ /** The id of the currently visible (active) tab. */
6
+ activeId: string;
7
+ /** Called when a tab is clicked to activate it. */
8
+ onSelect: (id: string) => void;
9
+ /** Called when the user confirms closing (killing) a session. */
10
+ onClose: (id: string) => void;
11
+ /** Called when the + button is pressed to open the picker for a new session. */
12
+ onNewTab: () => void;
13
+ }
14
+ declare const SessionTabs: import("svelte").Component<Props, {}, "">;
15
+ type SessionTabs = ReturnType<typeof SessionTabs>;
16
+ export default SessionTabs;
17
+ //# sourceMappingURL=SessionTabs.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SessionTabs.svelte.d.ts","sourceRoot":"","sources":["../../src/svelte/SessionTabs.svelte.ts"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAG5C,UAAU,KAAK;IACd,sCAAsC;IACtC,IAAI,EAAE,UAAU,EAAE,CAAC;IACnB,oDAAoD;IACpD,QAAQ,EAAE,MAAM,CAAC;IACjB,mDAAmD;IACnD,QAAQ,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/B,iEAAiE;IACjE,OAAO,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9B,gFAAgF;IAChF,QAAQ,EAAE,MAAM,IAAI,CAAC;CACrB;AA6HF,QAAA,MAAM,WAAW,2CAAwC,CAAC;AAC1D,KAAK,WAAW,GAAG,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC;AAClD,eAAe,WAAW,CAAC"}