@vibesdotdev/code-sessions 0.0.0-stage → 1.0.0-rc.0

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 (217) hide show
  1. package/LICENSE +18 -0
  2. package/README.md +165 -2
  3. package/dist/agent/coordinator.agent.descriptor.d.ts +69 -0
  4. package/dist/agent/coordinator.agent.descriptor.d.ts.map +1 -0
  5. package/dist/agent/coordinator.agent.descriptor.js +60 -0
  6. package/dist/agent/coordinator.agent.descriptor.js.map +1 -0
  7. package/dist/agent/coordinator.prompt.descriptor.d.ts +135 -0
  8. package/dist/agent/coordinator.prompt.descriptor.d.ts.map +1 -0
  9. package/dist/agent/coordinator.prompt.descriptor.js +29 -0
  10. package/dist/agent/coordinator.prompt.descriptor.js.map +1 -0
  11. package/dist/agent/coordinator.system-prompt.d.ts +3 -0
  12. package/dist/agent/coordinator.system-prompt.d.ts.map +1 -0
  13. package/dist/agent/coordinator.system-prompt.js +18 -0
  14. package/dist/agent/coordinator.system-prompt.js.map +1 -0
  15. package/dist/agent/developer.agent.descriptor.d.ts +74 -0
  16. package/dist/agent/developer.agent.descriptor.d.ts.map +1 -0
  17. package/dist/agent/developer.agent.descriptor.js +138 -0
  18. package/dist/agent/developer.agent.descriptor.js.map +1 -0
  19. package/dist/agent/developer.prompt.descriptor.d.ts +137 -0
  20. package/dist/agent/developer.prompt.descriptor.d.ts.map +1 -0
  21. package/dist/agent/developer.prompt.descriptor.js +29 -0
  22. package/dist/agent/developer.prompt.descriptor.js.map +1 -0
  23. package/dist/agent/reviewer.agent.descriptor.d.ts +69 -0
  24. package/dist/agent/reviewer.agent.descriptor.d.ts.map +1 -0
  25. package/dist/agent/reviewer.agent.descriptor.js +60 -0
  26. package/dist/agent/reviewer.agent.descriptor.js.map +1 -0
  27. package/dist/agent/reviewer.prompt.descriptor.d.ts +135 -0
  28. package/dist/agent/reviewer.prompt.descriptor.d.ts.map +1 -0
  29. package/dist/agent/reviewer.prompt.descriptor.js +29 -0
  30. package/dist/agent/reviewer.prompt.descriptor.js.map +1 -0
  31. package/dist/agent/reviewer.system-prompt.d.ts +3 -0
  32. package/dist/agent/reviewer.system-prompt.d.ts.map +1 -0
  33. package/dist/agent/reviewer.system-prompt.js +17 -0
  34. package/dist/agent/reviewer.system-prompt.js.map +1 -0
  35. package/dist/agent/system-prompt.d.ts +12 -0
  36. package/dist/agent/system-prompt.d.ts.map +1 -0
  37. package/dist/agent/system-prompt.js +28 -0
  38. package/dist/agent/system-prompt.js.map +1 -0
  39. package/dist/api/code-sessions.api-client.descriptor.d.ts +25 -0
  40. package/dist/api/code-sessions.api-client.descriptor.d.ts.map +1 -0
  41. package/dist/api/code-sessions.api-client.descriptor.js +26 -0
  42. package/dist/api/code-sessions.api-client.descriptor.js.map +1 -0
  43. package/dist/api/code-sessions.api-client.impl.d.ts +156 -0
  44. package/dist/api/code-sessions.api-client.impl.d.ts.map +1 -0
  45. package/dist/api/code-sessions.api-client.impl.js +852 -0
  46. package/dist/api/code-sessions.api-client.impl.js.map +1 -0
  47. package/dist/api/code-sessions.api-client.schemas.d.ts +2 -0
  48. package/dist/api/code-sessions.api-client.schemas.d.ts.map +1 -0
  49. package/dist/api/code-sessions.api-client.schemas.js +2 -0
  50. package/dist/api/code-sessions.api-client.schemas.js.map +1 -0
  51. package/dist/api/code-sessions.api-client.types.d.ts +252 -0
  52. package/dist/api/code-sessions.api-client.types.d.ts.map +1 -0
  53. package/dist/api/code-sessions.api-client.types.js +77 -0
  54. package/dist/api/code-sessions.api-client.types.js.map +1 -0
  55. package/dist/api/index.d.ts +13 -0
  56. package/dist/api/index.d.ts.map +1 -0
  57. package/dist/api/index.js +20 -0
  58. package/dist/api/index.js.map +1 -0
  59. package/dist/capability.d.ts +9 -0
  60. package/dist/capability.d.ts.map +1 -0
  61. package/dist/capability.js +9 -0
  62. package/dist/capability.js.map +1 -0
  63. package/dist/catalog/index.d.ts +2 -0
  64. package/dist/catalog/index.d.ts.map +1 -0
  65. package/dist/catalog/index.js +2 -0
  66. package/dist/catalog/index.js.map +1 -0
  67. package/dist/catalog/session-catalog.d.ts +131 -0
  68. package/dist/catalog/session-catalog.d.ts.map +1 -0
  69. package/dist/catalog/session-catalog.impl.consumer.worker.d.ts +113 -0
  70. package/dist/catalog/session-catalog.impl.consumer.worker.d.ts.map +1 -0
  71. package/dist/catalog/session-catalog.impl.consumer.worker.js +32 -0
  72. package/dist/catalog/session-catalog.impl.consumer.worker.js.map +1 -0
  73. package/dist/catalog/session-catalog.js +126 -0
  74. package/dist/catalog/session-catalog.js.map +1 -0
  75. package/dist/clock/clock.client.d.ts +18 -0
  76. package/dist/clock/clock.client.d.ts.map +1 -0
  77. package/dist/clock/clock.client.js +43 -0
  78. package/dist/clock/clock.client.js.map +1 -0
  79. package/dist/code-sessions.consumer.plugin.d.ts +4 -0
  80. package/dist/code-sessions.consumer.plugin.d.ts.map +1 -0
  81. package/dist/code-sessions.consumer.plugin.js +16 -0
  82. package/dist/code-sessions.consumer.plugin.js.map +1 -0
  83. package/dist/code-sessions.plugin.d.ts +15 -0
  84. package/dist/code-sessions.plugin.d.ts.map +1 -0
  85. package/dist/code-sessions.plugin.js +65 -0
  86. package/dist/code-sessions.plugin.js.map +1 -0
  87. package/dist/config/index.d.ts +9 -0
  88. package/dist/config/index.d.ts.map +1 -0
  89. package/dist/config/index.js +9 -0
  90. package/dist/config/index.js.map +1 -0
  91. package/dist/config/preparation.d.ts +2 -0
  92. package/dist/config/preparation.d.ts.map +1 -0
  93. package/dist/config/preparation.js +2 -0
  94. package/dist/config/preparation.js.map +1 -0
  95. package/dist/docs/code-sessions.docs.descriptor.d.ts +4 -0
  96. package/dist/docs/code-sessions.docs.descriptor.d.ts.map +1 -0
  97. package/dist/docs/code-sessions.docs.descriptor.js +241 -0
  98. package/dist/docs/code-sessions.docs.descriptor.js.map +1 -0
  99. package/dist/index.d.ts +26 -0
  100. package/dist/index.d.ts.map +1 -0
  101. package/dist/index.js +28 -0
  102. package/dist/index.js.map +1 -0
  103. package/dist/pull-request-plan.d.ts +68 -0
  104. package/dist/pull-request-plan.d.ts.map +1 -0
  105. package/dist/pull-request-plan.js +94 -0
  106. package/dist/pull-request-plan.js.map +1 -0
  107. package/dist/schemas/preparation.d.ts +51 -0
  108. package/dist/schemas/preparation.d.ts.map +1 -0
  109. package/dist/schemas/preparation.js +20 -0
  110. package/dist/schemas/preparation.js.map +1 -0
  111. package/dist/schemas/requests.d.ts +411 -0
  112. package/dist/schemas/requests.d.ts.map +1 -0
  113. package/dist/schemas/requests.js +87 -0
  114. package/dist/schemas/requests.js.map +1 -0
  115. package/dist/schemas/responses.d.ts +275 -0
  116. package/dist/schemas/responses.d.ts.map +1 -0
  117. package/dist/schemas/responses.js +90 -0
  118. package/dist/schemas/responses.js.map +1 -0
  119. package/dist/svelte/actions.d.ts +70 -0
  120. package/dist/svelte/actions.d.ts.map +1 -0
  121. package/dist/svelte/actions.js +280 -0
  122. package/dist/svelte/clock.svelte.d.ts +6 -0
  123. package/dist/svelte/clock.svelte.d.ts.map +1 -0
  124. package/dist/svelte/clock.svelte.js +33 -0
  125. package/dist/svelte/components/CreateSessionDialog.svelte +470 -0
  126. package/dist/svelte/components/CreateSessionDialog.svelte.d.ts +57 -0
  127. package/dist/svelte/components/CreateSessionDialog.svelte.d.ts.map +1 -0
  128. package/dist/svelte/components/SessionCard.svelte +216 -0
  129. package/dist/svelte/components/SessionCard.svelte.d.ts +27 -0
  130. package/dist/svelte/components/SessionCard.svelte.d.ts.map +1 -0
  131. package/dist/svelte/components/SessionList.svelte +86 -0
  132. package/dist/svelte/components/SessionList.svelte.d.ts +23 -0
  133. package/dist/svelte/components/SessionList.svelte.d.ts.map +1 -0
  134. package/dist/svelte/components/SessionSeed.svelte +60 -0
  135. package/dist/svelte/components/SessionSeed.svelte.d.ts +9 -0
  136. package/dist/svelte/components/SessionSeed.svelte.d.ts.map +1 -0
  137. package/dist/svelte/components/TranscriptView.svelte +360 -0
  138. package/dist/svelte/components/TranscriptView.svelte.d.ts +26 -0
  139. package/dist/svelte/components/TranscriptView.svelte.d.ts.map +1 -0
  140. package/dist/svelte/create-session-form.d.ts +84 -0
  141. package/dist/svelte/create-session-form.d.ts.map +1 -0
  142. package/dist/svelte/create-session-form.js +107 -0
  143. package/dist/svelte/index.d.ts +20 -0
  144. package/dist/svelte/index.d.ts.map +1 -0
  145. package/dist/svelte/index.js +18 -0
  146. package/dist/svelte/live-session.d.ts +156 -0
  147. package/dist/svelte/live-session.d.ts.map +1 -0
  148. package/dist/svelte/live-session.js +152 -0
  149. package/dist/svelte/loaders.d.ts +74 -0
  150. package/dist/svelte/loaders.d.ts.map +1 -0
  151. package/dist/svelte/loaders.js +124 -0
  152. package/dist/svelte/outcome.d.ts +46 -0
  153. package/dist/svelte/outcome.d.ts.map +1 -0
  154. package/dist/svelte/outcome.js +49 -0
  155. package/dist/svelte/relative-time.d.ts +32 -0
  156. package/dist/svelte/relative-time.d.ts.map +1 -0
  157. package/dist/svelte/relative-time.js +51 -0
  158. package/dist/svelte/session-list-item.d.ts +23 -0
  159. package/dist/svelte/session-list-item.d.ts.map +1 -0
  160. package/dist/svelte/session-list-item.js +1 -0
  161. package/dist/svelte/styles.css +8 -0
  162. package/dist/svelte/transcript-input.d.ts +45 -0
  163. package/dist/svelte/transcript-input.d.ts.map +1 -0
  164. package/dist/svelte/transcript-input.js +188 -0
  165. package/dist/tui/code-sessions-tui.plugin.d.ts +10 -0
  166. package/dist/tui/code-sessions-tui.plugin.d.ts.map +1 -0
  167. package/dist/tui/code-sessions-tui.plugin.js +29 -0
  168. package/dist/tui/code-sessions-tui.plugin.js.map +1 -0
  169. package/dist/tui/code-sessions.tui-app.descriptor.d.ts +7 -0
  170. package/dist/tui/code-sessions.tui-app.descriptor.d.ts.map +1 -0
  171. package/dist/tui/code-sessions.tui-app.descriptor.js +30 -0
  172. package/dist/tui/code-sessions.tui-app.descriptor.js.map +1 -0
  173. package/dist/tui/code-sessions.tui-app.impl.consumer.d.ts +14 -0
  174. package/dist/tui/code-sessions.tui-app.impl.consumer.d.ts.map +1 -0
  175. package/dist/tui/code-sessions.tui-app.impl.consumer.js +453 -0
  176. package/dist/tui/code-sessions.tui-app.impl.consumer.js.map +1 -0
  177. package/dist/tui/code-sessions.tui-client.d.ts +22 -0
  178. package/dist/tui/code-sessions.tui-client.d.ts.map +1 -0
  179. package/dist/tui/code-sessions.tui-client.js +95 -0
  180. package/dist/tui/code-sessions.tui-client.js.map +1 -0
  181. package/dist/tui/code-sessions.tui-open.descriptor.d.ts +7 -0
  182. package/dist/tui/code-sessions.tui-open.descriptor.d.ts.map +1 -0
  183. package/dist/tui/code-sessions.tui-open.descriptor.js +16 -0
  184. package/dist/tui/code-sessions.tui-open.descriptor.js.map +1 -0
  185. package/dist/tui/code-sessions.tui-open.impl.consumer.d.ts +7 -0
  186. package/dist/tui/code-sessions.tui-open.impl.consumer.d.ts.map +1 -0
  187. package/dist/tui/code-sessions.tui-open.impl.consumer.js +11 -0
  188. package/dist/tui/code-sessions.tui-open.impl.consumer.js.map +1 -0
  189. package/dist/tui/code-sessions.tui-state.descriptor.d.ts +16 -0
  190. package/dist/tui/code-sessions.tui-state.descriptor.d.ts.map +1 -0
  191. package/dist/tui/code-sessions.tui-state.descriptor.js +50 -0
  192. package/dist/tui/code-sessions.tui-state.descriptor.js.map +1 -0
  193. package/dist/tui/code-sessions.tui-state.impl.consumer.d.ts +30 -0
  194. package/dist/tui/code-sessions.tui-state.impl.consumer.d.ts.map +1 -0
  195. package/dist/tui/code-sessions.tui-state.impl.consumer.js +533 -0
  196. package/dist/tui/code-sessions.tui-state.impl.consumer.js.map +1 -0
  197. package/dist/tui/code-sessions.tui-state.key.d.ts +322 -0
  198. package/dist/tui/code-sessions.tui-state.key.d.ts.map +1 -0
  199. package/dist/tui/code-sessions.tui-state.key.js +104 -0
  200. package/dist/tui/code-sessions.tui-state.key.js.map +1 -0
  201. package/dist/tui/index.d.ts +9 -0
  202. package/dist/tui/index.d.ts.map +1 -0
  203. package/dist/tui/index.js +8 -0
  204. package/dist/tui/index.js.map +1 -0
  205. package/dist/workspace/index.d.ts +2 -0
  206. package/dist/workspace/index.d.ts.map +1 -0
  207. package/dist/workspace/index.js +2 -0
  208. package/dist/workspace/index.js.map +1 -0
  209. package/dist/workspace/workspace-binding.d.ts +74 -0
  210. package/dist/workspace/workspace-binding.d.ts.map +1 -0
  211. package/dist/workspace/workspace-binding.impl.consumer.worker.d.ts +17 -0
  212. package/dist/workspace/workspace-binding.impl.consumer.worker.d.ts.map +1 -0
  213. package/dist/workspace/workspace-binding.impl.consumer.worker.js +134 -0
  214. package/dist/workspace/workspace-binding.impl.consumer.worker.js.map +1 -0
  215. package/dist/workspace/workspace-binding.js +72 -0
  216. package/dist/workspace/workspace-binding.js.map +1 -0
  217. package/package.json +238 -4
@@ -0,0 +1,360 @@
1
+ <script lang="ts" module>
2
+ import type { SessionWithCapability, RunCommandResponse } from '@vibesdotdev/code-sessions';
3
+
4
+ /** One entry in the transcript (command + result, or pending). */
5
+ export interface TranscriptEntry {
6
+ id: string;
7
+ command: string[];
8
+ /** Undefined while the command is running. */
9
+ result?: RunCommandResponse;
10
+ /** True while the command is in-flight. */
11
+ running?: boolean;
12
+ /** Client-side error if the bridge request itself failed. */
13
+ bridgeError?: string;
14
+ }
15
+
16
+ export interface TranscriptViewProps {
17
+ session: SessionWithCapability;
18
+ entries: TranscriptEntry[];
19
+ /** Called when the user submits a new command. */
20
+ onrun?: (command: string[]) => void | Promise<void>;
21
+ /** Called when the user clicks the re-run button on an entry. */
22
+ onrerun?: (entry: TranscriptEntry) => void | Promise<void>;
23
+ /** Whether a new command is being submitted (input disabled). */
24
+ running?: boolean;
25
+ }
26
+ </script>
27
+
28
+ <script lang="ts">
29
+ import { Button } from '@vibesdotdev/kit/components/ui/button';
30
+ import { Badge } from '@vibesdotdev/kit/components/ui/badge';
31
+ import { Icon } from '@vibesdotdev/kit/components';
32
+ import {
33
+ HISTORY_DRAFT,
34
+ historyFromCommands,
35
+ isShellSyntax,
36
+ navigateHistory,
37
+ tokenizeCommand
38
+ } from '../transcript-input.js';
39
+ import { getLogger } from '@vibesdotdev/logging';
40
+ import { getRuntimeSvelteContext } from '@vibesdotdev/surface-sveltekit/svelte';
41
+ import { attempt } from '../outcome.js';
42
+
43
+ /** The page's runtime, which reports a failed copy; read once at component init. */
44
+ const runtimeContext = getRuntimeSvelteContext();
45
+
46
+ let {
47
+ session,
48
+ entries,
49
+ onrun,
50
+ onrerun,
51
+ running = false
52
+ }: TranscriptViewProps = $props();
53
+
54
+ let commandInput: string = $state('');
55
+ let outputEndEl: HTMLDivElement | undefined = $state();
56
+ let outputEl: HTMLDivElement | undefined = $state();
57
+ let copyFailed: boolean = $state(false);
58
+
59
+ /** History cursor; `HISTORY_DRAFT` while the input holds the user's own text. */
60
+ let historyCursor: number = $state(HISTORY_DRAFT);
61
+ /** The draft stashed when the user starts walking history, restored on the way back. */
62
+ let historyDraft: string = $state('');
63
+
64
+ const history = $derived(historyFromCommands(entries.map((e) => e.command.join(' '))));
65
+ const shellSyntaxWarning = $derived(isShellSyntax(commandInput));
66
+
67
+ function handleSubmit(e: SubmitEvent) {
68
+ e.preventDefault();
69
+ const command = tokenizeCommand(commandInput);
70
+ if (command.length === 0) return;
71
+
72
+ onrun?.(command);
73
+ commandInput = '';
74
+ historyCursor = HISTORY_DRAFT;
75
+ historyDraft = '';
76
+ }
77
+
78
+ /**
79
+ * ↑/↓ recall previous commands, as any terminal-shaped input is expected to.
80
+ * The data was already on screen in `entries`; nothing read it back.
81
+ */
82
+ function handleInputKeydown(event: KeyboardEvent) {
83
+ if (event.key !== 'ArrowUp' && event.key !== 'ArrowDown') return;
84
+ if (history.length === 0) return;
85
+
86
+ // Stash the draft on the first step away from it so ↓ can return to it.
87
+ if (historyCursor === HISTORY_DRAFT) historyDraft = commandInput;
88
+
89
+ const step = navigateHistory(
90
+ history,
91
+ historyCursor,
92
+ event.key === 'ArrowUp' ? 'older' : 'newer',
93
+ historyDraft
94
+ );
95
+ if (step.cursor === historyCursor && step.value === commandInput) return;
96
+
97
+ event.preventDefault();
98
+ historyCursor = step.cursor;
99
+ commandInput = step.value;
100
+ }
101
+
102
+ /** Typing anything by hand means the user has left history navigation. */
103
+ function handleInput() {
104
+ historyCursor = HISTORY_DRAFT;
105
+ }
106
+
107
+ function exitCodeColor(code: number | null, timedOut: boolean): string {
108
+ if (timedOut) return 'text-yellow-400';
109
+ if (code === 0) return 'text-green-400';
110
+ if (code === null) return 'text-muted-foreground';
111
+ return 'text-red-400';
112
+ }
113
+
114
+ function exitCodeLabel(code: number | null, timedOut: boolean): string {
115
+ if (timedOut) return 'timed out';
116
+ if (code === null) return '—';
117
+ return `exit ${code}`;
118
+ }
119
+
120
+ function durationLabel(ms: number): string {
121
+ if (ms < 1000) return `${ms}ms`;
122
+ return `${(ms / 1000).toFixed(1)}s`;
123
+ }
124
+
125
+ /**
126
+ * Copy, and SAY SO when it fails.
127
+ *
128
+ * This used to swallow the rejection with "clipboard not available —
129
+ * silently skip", so on a non-secure origin or with the permission denied
130
+ * the button did nothing at all and the user had no way to know why.
131
+ */
132
+ async function copyToClipboard(text: string) {
133
+ const copied = await attempt(() => navigator.clipboard.writeText(text));
134
+ copyFailed = !copied.ok;
135
+ if (!copied.ok) {
136
+ const logger = getLogger('code-sessions:transcript-view', runtimeContext.runtime ?? undefined);
137
+ logger.warn('clipboard copy failed', { error: copied.failure });
138
+ }
139
+ }
140
+
141
+ /**
142
+ * Distance from the bottom, in px, still treated as "the user is following
143
+ * the tail". Wide enough to survive sub-pixel rounding and a partially
144
+ * scrolled last line.
145
+ */
146
+ const AUTOSCROLL_THRESHOLD_PX = 64;
147
+
148
+ function isPinnedToBottom(el: HTMLDivElement): boolean {
149
+ return el.scrollHeight - el.scrollTop - el.clientHeight <= AUTOSCROLL_THRESHOLD_PX;
150
+ }
151
+
152
+ /**
153
+ * Was the user at the tail BEFORE this update rendered?
154
+ *
155
+ * Captured in `$effect.pre` — this is the whole trick. A plain `$effect`
156
+ * runs AFTER the DOM update, so it would measure a container that already
157
+ * contains the new output: any result taller than the threshold pushes the
158
+ * reader "away from the bottom" the instant it paints, and autoscroll would
159
+ * never fire for exactly the commands that need it most.
160
+ */
161
+ let wasPinnedToBottom = $state(true);
162
+
163
+ $effect.pre(() => {
164
+ // Depend on the entries identity so this runs before each output update.
165
+ void entries;
166
+ if (!outputEl) return;
167
+ wasPinnedToBottom = isPinnedToBottom(outputEl);
168
+ });
169
+
170
+ $effect(() => {
171
+ // Depend on the entries identity, not `.length`: a result arriving on an
172
+ // existing entry changes the array without changing its length.
173
+ void entries;
174
+ if (!outputEndEl) return;
175
+
176
+ // Only follow the tail if the user WAS already at the tail. Scrolling up
177
+ // to read earlier output used to be undone by the next result landing.
178
+ if (!wasPinnedToBottom) return;
179
+ outputEndEl.scrollIntoView({ behavior: 'smooth' });
180
+ });
181
+ </script>
182
+
183
+ <!--
184
+ TranscriptView — snapshot execution surface for CF Sandbox sessions (D1).
185
+ Honest labeling: "snapshot execution" — each command is an independent run,
186
+ not a persistent shell. Re-runnable, copyable output.
187
+ -->
188
+ <div class="flex h-full flex-col">
189
+ <!-- Header banner: honest labeling per D1 -->
190
+ <div class="flex items-center justify-between border-b bg-muted/30 px-4 py-2 text-xs text-muted-foreground">
191
+ <div class="flex items-center gap-2">
192
+ <Icon icon="lucide:film" class="size-3.5" aria-hidden="true" />
193
+ <span>Snapshot execution — commands run independently, not in a persistent shell.</span>
194
+ </div>
195
+ <Badge variant="outline" class="text-xs">
196
+ {session.hostTarget.kind === 'cloud' ? 'Cloud sandbox' : 'Host'}
197
+ </Badge>
198
+ </div>
199
+
200
+ <!--
201
+ Output area. `role="log"` + `aria-live="polite"` so a screen-reader user is
202
+ told what a command produced — without them, running a command announced
203
+ nothing at all.
204
+ -->
205
+ <div
206
+ bind:this={outputEl}
207
+ role="log"
208
+ aria-live="polite"
209
+ aria-label="Command output"
210
+ class="min-h-0 flex-1 overflow-y-auto bg-[#0d1117] p-4 font-mono text-sm"
211
+ >
212
+ {#if entries.length === 0}
213
+ <div class="flex h-full flex-col items-center justify-center gap-3 text-muted-foreground">
214
+ <Icon icon="lucide:terminal" class="size-8 opacity-40" aria-hidden="true" />
215
+ <p class="text-sm">Run a command to see output here.</p>
216
+ </div>
217
+ {:else}
218
+ {#each entries as entry (entry.id)}
219
+ <div class="mb-4">
220
+ <!-- Command line -->
221
+ <div class="flex items-center gap-2 text-[#79c0ff]">
222
+ <span class="select-none opacity-60">$</span>
223
+ <span class="flex-1 break-all">{entry.command.join(' ')}</span>
224
+ <div class="flex shrink-0 items-center gap-1">
225
+ <Button
226
+ variant="ghost"
227
+ size="icon"
228
+ class="size-5 text-muted-foreground hover:text-foreground"
229
+ onclick={() => copyToClipboard(entry.command.join(' '))}
230
+ title="Copy command"
231
+ >
232
+ <Icon icon="lucide:copy" class="size-3" aria-hidden="true" />
233
+ </Button>
234
+ {#if entry.result && onrerun}
235
+ <Button
236
+ variant="ghost"
237
+ size="icon"
238
+ class="size-5 text-muted-foreground hover:text-foreground"
239
+ onclick={() => onrerun?.(entry)}
240
+ title="Re-run"
241
+ disabled={running}
242
+ >
243
+ <Icon icon="lucide:refresh-cw" class="size-3" aria-hidden="true" />
244
+ </Button>
245
+ {/if}
246
+ </div>
247
+ </div>
248
+
249
+ <!-- Running indicator -->
250
+ {#if entry.running}
251
+ <div class="mt-1 flex items-center gap-2 text-yellow-400/80">
252
+ <Icon icon="lucide:loader-2" class="size-3 animate-spin" aria-hidden="true" />
253
+ <span class="text-xs">Running…</span>
254
+ </div>
255
+ {:else if entry.bridgeError}
256
+ <div class="mt-1 text-red-400">
257
+ <span class="text-xs">Error: {entry.bridgeError}</span>
258
+ </div>
259
+ {:else if entry.result}
260
+ <!-- stdout -->
261
+ {#if entry.result.stdout}
262
+ <pre class="mt-1 whitespace-pre-wrap break-all text-[#e6edf3]">{entry.result.stdout}</pre>
263
+ {/if}
264
+ <!-- stderr -->
265
+ {#if entry.result.stderr}
266
+ <pre class="mt-1 whitespace-pre-wrap break-all text-[#f85149]">{entry.result.stderr}</pre>
267
+ {/if}
268
+ <!-- Metadata row -->
269
+ <div class="mt-1 flex items-center gap-3 text-xs">
270
+ <span class={exitCodeColor(entry.result.exitCode, entry.result.timedOut)}>
271
+ {exitCodeLabel(entry.result.exitCode, entry.result.timedOut)}
272
+ </span>
273
+ <span class="text-muted-foreground">
274
+ {durationLabel(entry.result.durationMs)}
275
+ </span>
276
+ {#if entry.result.stdout || entry.result.stderr}
277
+ <Button
278
+ variant="ghost"
279
+ size="sm"
280
+ class="h-5 px-1.5 text-xs text-muted-foreground hover:text-foreground"
281
+ onclick={() =>
282
+ copyToClipboard(
283
+ [entry.result!.stdout, entry.result!.stderr].filter(Boolean).join('\n')
284
+ )}
285
+ >
286
+ <Icon icon="lucide:copy" class="mr-1 size-3" aria-hidden="true" />
287
+ Copy output
288
+ </Button>
289
+ {/if}
290
+ </div>
291
+ {/if}
292
+ </div>
293
+ {/each}
294
+ {/if}
295
+ <div bind:this={outputEndEl}></div>
296
+ </div>
297
+
298
+ <!--
299
+ Hints below the output and above the input, so they are read in the order
300
+ they matter. Both are `role="status"`: advisory, not an error.
301
+ -->
302
+ {#if copyFailed || shellSyntaxWarning}
303
+ <div class="space-y-1 border-t bg-[#0d1117] px-4 pt-2 text-xs" role="status" aria-live="polite">
304
+ {#if shellSyntaxWarning}
305
+ <p class="flex items-start gap-2 text-yellow-400/90">
306
+ <Icon icon="lucide:triangle-alert" class="mt-0.5 size-3 shrink-0" aria-hidden="true" />
307
+ <span>
308
+ Pipes, redirection and chaining are not interpreted here — each command runs on its
309
+ own, so <code class="font-mono">|</code>, <code class="font-mono">&gt;</code> and
310
+ <code class="font-mono">&amp;&amp;</code> are passed through as plain arguments.
311
+ </span>
312
+ </p>
313
+ {/if}
314
+ {#if copyFailed}
315
+ <p class="flex items-start gap-2 text-red-400/90">
316
+ <Icon icon="lucide:clipboard-x" class="mt-0.5 size-3 shrink-0" aria-hidden="true" />
317
+ <span>Could not copy — this browser blocked clipboard access. Select the text instead.</span>
318
+ </p>
319
+ {/if}
320
+ </div>
321
+ {/if}
322
+
323
+ <!-- Command input -->
324
+ <form
325
+ onsubmit={handleSubmit}
326
+ class="flex items-center gap-2 border-t bg-[#0d1117] px-4 py-3"
327
+ >
328
+ <span class="shrink-0 font-mono text-sm text-[#79c0ff] opacity-60" aria-hidden="true">$</span>
329
+ <input
330
+ type="text"
331
+ bind:value={commandInput}
332
+ oninput={handleInput}
333
+ onkeydown={handleInputKeydown}
334
+ placeholder="Enter a command…"
335
+ aria-label="Command"
336
+ aria-describedby="transcript-command-hint"
337
+ disabled={running}
338
+ class="flex-1 bg-transparent font-mono text-sm text-[#e6edf3] placeholder:text-muted-foreground/50 focus:outline-none disabled:cursor-not-allowed disabled:opacity-50"
339
+ autocomplete="off"
340
+ spellcheck={false}
341
+ />
342
+ <span id="transcript-command-hint" class="sr-only">
343
+ Runs as a single command. Press the up and down arrow keys to recall previous commands.
344
+ </span>
345
+ <Button
346
+ type="submit"
347
+ size="sm"
348
+ variant="ghost"
349
+ class="shrink-0"
350
+ disabled={running || !commandInput.trim()}
351
+ >
352
+ {#if running}
353
+ <Icon icon="lucide:loader-2" class="size-4 animate-spin" aria-hidden="true" />
354
+ {:else}
355
+ <Icon icon="lucide:send" class="size-4" aria-hidden="true" />
356
+ {/if}
357
+ <span class="sr-only">Run</span>
358
+ </Button>
359
+ </form>
360
+ </div>
@@ -0,0 +1,26 @@
1
+ import type { SessionWithCapability, RunCommandResponse } from '@vibesdotdev/code-sessions';
2
+ /** One entry in the transcript (command + result, or pending). */
3
+ export interface TranscriptEntry {
4
+ id: string;
5
+ command: string[];
6
+ /** Undefined while the command is running. */
7
+ result?: RunCommandResponse;
8
+ /** True while the command is in-flight. */
9
+ running?: boolean;
10
+ /** Client-side error if the bridge request itself failed. */
11
+ bridgeError?: string;
12
+ }
13
+ export interface TranscriptViewProps {
14
+ session: SessionWithCapability;
15
+ entries: TranscriptEntry[];
16
+ /** Called when the user submits a new command. */
17
+ onrun?: (command: string[]) => void | Promise<void>;
18
+ /** Called when the user clicks the re-run button on an entry. */
19
+ onrerun?: (entry: TranscriptEntry) => void | Promise<void>;
20
+ /** Whether a new command is being submitted (input disabled). */
21
+ running?: boolean;
22
+ }
23
+ declare const TranscriptView: import("svelte").Component<TranscriptViewProps, {}, "">;
24
+ type TranscriptView = ReturnType<typeof TranscriptView>;
25
+ export default TranscriptView;
26
+ //# sourceMappingURL=TranscriptView.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TranscriptView.svelte.d.ts","sourceRoot":"","sources":["../../../src/svelte/components/TranscriptView.svelte.ts"],"names":[],"mappings":"AAGC,OAAO,KAAK,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAE5F,kEAAkE;AAClE,MAAM,WAAW,eAAe;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,8CAA8C;IAC9C,MAAM,CAAC,EAAE,kBAAkB,CAAC;IAC5B,2CAA2C;IAC3C,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,6DAA6D;IAC7D,WAAW,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,mBAAmB;IACnC,OAAO,EAAE,qBAAqB,CAAC;IAC/B,OAAO,EAAE,eAAe,EAAE,CAAC;IAC3B,kDAAkD;IAClD,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACpD,iEAAiE;IACjE,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,eAAe,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3D,iEAAiE;IACjE,OAAO,CAAC,EAAE,OAAO,CAAC;CAClB;AAqSF,QAAA,MAAM,cAAc,yDAAwC,CAAC;AAC7D,KAAK,cAAc,GAAG,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC;AACxD,eAAe,cAAc,CAAC"}
@@ -0,0 +1,84 @@
1
+ import type { PlatformCodeSessionCreateInput } from '@vibesdotdev/code-sessions/api';
2
+ export interface CreateSessionSubmitState {
3
+ ephemeral: boolean;
4
+ selectedRepositoryId?: string | null;
5
+ /** Explicit intent to provision a repository at the consuming surface's submit boundary. */
6
+ createRepositoryIfMissing?: boolean;
7
+ /** The currently chosen host target. Required to gate fleet sessions. */
8
+ selectedHostTarget?: 'cloud' | 'local' | 'fleet';
9
+ /** Host targets the embedding surface can actually provision. */
10
+ allowedHostTargets?: readonly ('cloud' | 'local' | 'fleet')[];
11
+ /** The fleet machine the user picked when selectedHostTarget === 'fleet'. */
12
+ selectedFleetHostId?: string | null;
13
+ }
14
+ export interface FleetHostSelectionOption {
15
+ hostId: string;
16
+ online: boolean;
17
+ }
18
+ export type CreateSessionHostTarget = 'cloud' | 'local' | 'fleet';
19
+ /** One source of truth for what the dialog may show, select, and submit. */
20
+ export declare function resolveSelectableHostTargets(allowed: readonly CreateSessionHostTarget[], fleetHosts: readonly FleetHostSelectionOption[]): CreateSessionHostTarget[];
21
+ export declare function resolveDefaultHostTarget(selectable: readonly CreateSessionHostTarget[]): CreateSessionHostTarget | undefined;
22
+ export declare function resolveDefaultFleetHostId(fleetHosts: readonly FleetHostSelectionOption[]): string;
23
+ export declare function isSelectableFleetHost(fleetHosts: readonly FleetHostSelectionOption[], hostId: string | null | undefined): boolean;
24
+ /**
25
+ * Build the create-session request from the dialog's form state.
26
+ *
27
+ * Lives here rather than inline in the component so the *contract* — especially
28
+ * that a seed survives the trip — is pinned by a test without rendering Svelte.
29
+ * The work-items TUI pins its equivalent (`createSeededCodeSession`) the same
30
+ * way; a session started from the web must carry the same seed shape as one
31
+ * started from the TUI or it cannot be traced back to the task it came from.
32
+ */
33
+ export declare function buildCreateSessionInput(state: {
34
+ hostTarget: CreateSessionDraft['hostTarget'];
35
+ ephemeral: boolean;
36
+ selectedRepositoryId?: string | null;
37
+ createRepositoryIfMissing?: boolean;
38
+ checkoutRef?: string | null;
39
+ seed?: CreateSessionSeed;
40
+ }): CreateSessionDraft;
41
+ /**
42
+ * The create input the dialog submits: a platform create input, plus the
43
+ * surface-level intent to provision a repository that the consuming app's
44
+ * submit boundary reads (`createRepositoryIfMissing`).
45
+ */
46
+ export type CreateSessionDraft = PlatformCodeSessionCreateInput & {
47
+ createRepositoryIfMissing?: true;
48
+ };
49
+ /** Structural mirror of the platform's `CodeSessionSeed`; kept local so this pure module stays type-only-free. */
50
+ export interface CreateSessionSeed {
51
+ source: string;
52
+ title: string;
53
+ ref?: string;
54
+ body?: string;
55
+ }
56
+ export declare function canSubmitCreateSession(state: CreateSessionSubmitState): boolean;
57
+ /** Why "Start session" is unavailable, in the user's terms. */
58
+ export interface CreateSessionBlocker {
59
+ reason: 'host-target-unavailable' | 'fleet-host-required' | 'repository-required' | 'no-repositories';
60
+ message: string;
61
+ }
62
+ export interface CreateSessionBlockerState extends CreateSessionSubmitState {
63
+ /** How many repositories the picker was given. Distinguishes "pick one" from "there are none". */
64
+ repositoryCount?: number;
65
+ /** The embedding can provision a repository after the user explicitly opts in. */
66
+ repositoryCreationAvailable?: boolean;
67
+ }
68
+ /**
69
+ * Explain a disabled submit button, or `null` when submission is possible.
70
+ *
71
+ * The button was previously disabled with no explanation, which turns an
72
+ * unmet precondition into a dead end — worst on a surface whose repository
73
+ * list failed to load, where the user sees an inert control and no way
74
+ * forward. The blocker also distinguishes "you have not chosen a repository"
75
+ * from "there are no repositories to choose", because only the second one
76
+ * means the user must go somewhere else first.
77
+ *
78
+ * Invariant, pinned by test: this returns `null` exactly when
79
+ * `canSubmitCreateSession` returns `true`. Two rules that can disagree about
80
+ * whether a form is submittable is how a button ends up enabled beside a
81
+ * message saying it cannot be.
82
+ */
83
+ export declare function describeCreateSessionBlocker(state: CreateSessionBlockerState): CreateSessionBlocker | null;
84
+ //# sourceMappingURL=create-session-form.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-session-form.d.ts","sourceRoot":"","sources":["../../src/svelte/create-session-form.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,8BAA8B,EAAE,MAAM,gCAAgC,CAAC;AAErF,MAAM,WAAW,wBAAwB;IACxC,SAAS,EAAE,OAAO,CAAC;IACnB,oBAAoB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC,4FAA4F;IAC5F,yBAAyB,CAAC,EAAE,OAAO,CAAC;IACpC,yEAAyE;IACzE,kBAAkB,CAAC,EAAE,OAAO,GAAG,OAAO,GAAG,OAAO,CAAC;IACjD,iEAAiE;IACjE,kBAAkB,CAAC,EAAE,SAAS,CAAC,OAAO,GAAG,OAAO,GAAG,OAAO,CAAC,EAAE,CAAC;IAC9D,6EAA6E;IAC7E,mBAAmB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACpC;AAED,MAAM,WAAW,wBAAwB;IACxC,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,MAAM,uBAAuB,GAAG,OAAO,GAAG,OAAO,GAAG,OAAO,CAAC;AAElE,4EAA4E;AAC5E,wBAAgB,4BAA4B,CAC3C,OAAO,EAAE,SAAS,uBAAuB,EAAE,EAC3C,UAAU,EAAE,SAAS,wBAAwB,EAAE,GAC7C,uBAAuB,EAAE,CAG3B;AAED,wBAAgB,wBAAwB,CACvC,UAAU,EAAE,SAAS,uBAAuB,EAAE,GAC5C,uBAAuB,GAAG,SAAS,CAErC;AAED,wBAAgB,yBAAyB,CAAC,UAAU,EAAE,SAAS,wBAAwB,EAAE,GAAG,MAAM,CAEjG;AAED,wBAAgB,qBAAqB,CACpC,UAAU,EAAE,SAAS,wBAAwB,EAAE,EAC/C,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAC/B,OAAO,CAKT;AAED;;;;;;;;GAQG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE;IAC9C,UAAU,EAAE,kBAAkB,CAAC,YAAY,CAAC,CAAC;IAC7C,SAAS,EAAE,OAAO,CAAC;IACnB,oBAAoB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC,yBAAyB,CAAC,EAAE,OAAO,CAAC;IACpC,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,IAAI,CAAC,EAAE,iBAAiB,CAAC;CACzB,GAAG,kBAAkB,CAcrB;AAED;;;;GAIG;AACH,MAAM,MAAM,kBAAkB,GAAG,8BAA8B,GAAG;IAAE,yBAAyB,CAAC,EAAE,IAAI,CAAA;CAAE,CAAC;AAEvG,kHAAkH;AAClH,MAAM,WAAW,iBAAiB;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;CACd;AAED,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,wBAAwB,GAAG,OAAO,CAc/E;AAED,+DAA+D;AAC/D,MAAM,WAAW,oBAAoB;IACpC,MAAM,EACH,yBAAyB,GACzB,qBAAqB,GACrB,qBAAqB,GACrB,iBAAiB,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,yBAA0B,SAAQ,wBAAwB;IAC1E,kGAAkG;IAClG,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,kFAAkF;IAClF,2BAA2B,CAAC,EAAE,OAAO,CAAC;CACtC;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,4BAA4B,CAC3C,KAAK,EAAE,yBAAyB,GAC9B,oBAAoB,GAAG,IAAI,CAkC7B"}
@@ -0,0 +1,107 @@
1
+ /** One source of truth for what the dialog may show, select, and submit. */
2
+ export function resolveSelectableHostTargets(allowed, fleetHosts) {
3
+ const hasOnlineFleetHost = fleetHosts.some((host) => host.online);
4
+ return allowed.filter((target) => target !== 'fleet' || hasOnlineFleetHost);
5
+ }
6
+ export function resolveDefaultHostTarget(selectable) {
7
+ return selectable.includes('cloud') ? 'cloud' : selectable[0];
8
+ }
9
+ export function resolveDefaultFleetHostId(fleetHosts) {
10
+ return fleetHosts.find((host) => host.online)?.hostId ?? '';
11
+ }
12
+ export function isSelectableFleetHost(fleetHosts, hostId) {
13
+ const normalizedHostId = hostId?.trim();
14
+ return Boolean(normalizedHostId && fleetHosts.some((host) => host.online && host.hostId === normalizedHostId));
15
+ }
16
+ /**
17
+ * Build the create-session request from the dialog's form state.
18
+ *
19
+ * Lives here rather than inline in the component so the *contract* — especially
20
+ * that a seed survives the trip — is pinned by a test without rendering Svelte.
21
+ * The work-items TUI pins its equivalent (`createSeededCodeSession`) the same
22
+ * way; a session started from the web must carry the same seed shape as one
23
+ * started from the TUI or it cannot be traced back to the task it came from.
24
+ */
25
+ export function buildCreateSessionInput(state) {
26
+ const draft = { hostTarget: state.hostTarget };
27
+ if (state.ephemeral) {
28
+ draft.ephemeral = true;
29
+ }
30
+ else if (state.createRepositoryIfMissing) {
31
+ draft.createRepositoryIfMissing = true;
32
+ }
33
+ else {
34
+ const repositoryId = state.selectedRepositoryId?.trim();
35
+ if (repositoryId)
36
+ draft.repositoryId = repositoryId;
37
+ }
38
+ const checkoutRef = state.checkoutRef?.trim();
39
+ if (checkoutRef)
40
+ draft.checkoutRef = checkoutRef;
41
+ if (state.seed)
42
+ draft.seed = state.seed;
43
+ return draft;
44
+ }
45
+ export function canSubmitCreateSession(state) {
46
+ if (state.allowedHostTargets &&
47
+ (!state.selectedHostTarget || !state.allowedHostTargets.includes(state.selectedHostTarget))) {
48
+ return false;
49
+ }
50
+ // Fleet target requires a real machine to be selected.
51
+ if (state.selectedHostTarget === 'fleet' && !state.selectedFleetHostId?.trim()) {
52
+ return false;
53
+ }
54
+ if (state.ephemeral)
55
+ return true;
56
+ if (state.createRepositoryIfMissing)
57
+ return true;
58
+ return Boolean(state.selectedRepositoryId?.trim());
59
+ }
60
+ /**
61
+ * Explain a disabled submit button, or `null` when submission is possible.
62
+ *
63
+ * The button was previously disabled with no explanation, which turns an
64
+ * unmet precondition into a dead end — worst on a surface whose repository
65
+ * list failed to load, where the user sees an inert control and no way
66
+ * forward. The blocker also distinguishes "you have not chosen a repository"
67
+ * from "there are no repositories to choose", because only the second one
68
+ * means the user must go somewhere else first.
69
+ *
70
+ * Invariant, pinned by test: this returns `null` exactly when
71
+ * `canSubmitCreateSession` returns `true`. Two rules that can disagree about
72
+ * whether a form is submittable is how a button ends up enabled beside a
73
+ * message saying it cannot be.
74
+ */
75
+ export function describeCreateSessionBlocker(state) {
76
+ if (state.allowedHostTargets &&
77
+ (!state.selectedHostTarget || !state.allowedHostTargets.includes(state.selectedHostTarget))) {
78
+ return {
79
+ reason: 'host-target-unavailable',
80
+ message: 'No execution environment is available for this session.'
81
+ };
82
+ }
83
+ if (state.selectedHostTarget === 'fleet' && !state.selectedFleetHostId?.trim()) {
84
+ return {
85
+ reason: 'fleet-host-required',
86
+ message: 'Choose a machine to run on.'
87
+ };
88
+ }
89
+ if (state.ephemeral)
90
+ return null;
91
+ if (state.createRepositoryIfMissing)
92
+ return null;
93
+ if (state.selectedRepositoryId?.trim())
94
+ return null;
95
+ if (state.repositoryCount === 0) {
96
+ return {
97
+ reason: 'no-repositories',
98
+ message: state.repositoryCreationAvailable
99
+ ? 'Choose “Create a repository when this assignment starts” to continue.'
100
+ : 'There are no repositories to start from. Tick “Ephemeral workspace” to work in scratch space, or create a repository first.'
101
+ };
102
+ }
103
+ return {
104
+ reason: 'repository-required',
105
+ message: 'Choose a repository, or tick “Ephemeral workspace” to start without one.'
106
+ };
107
+ }
@@ -0,0 +1,20 @@
1
+ /**
2
+ * @vibesdotdev/code-sessions/svelte
3
+ *
4
+ * Svelte components for code-session management UI. Consumed by wave-2 routes
5
+ * in hq-web and consumer hq. Components are thin wrappers around vibeskit
6
+ * primitives with zero internal jargon in copy.
7
+ *
8
+ * Session display components accept the narrow renderer-safe catalog record.
9
+ * Canonical records remain structurally compatible for trusted web consumers.
10
+ *
11
+ * NOTE: Do NOT import this barrel from a server context; components contain
12
+ * Svelte reactive state. Use the named component subpaths instead.
13
+ */
14
+ export { default as SessionCard } from './components/SessionCard.svelte';
15
+ export { default as SessionList } from './components/SessionList.svelte';
16
+ export { default as SessionSeed } from './components/SessionSeed.svelte';
17
+ export { default as CreateSessionDialog } from './components/CreateSessionDialog.svelte';
18
+ export { default as TranscriptView } from './components/TranscriptView.svelte';
19
+ export type { SessionListItem } from './session-list-item.ts';
20
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/svelte/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,iCAAiC,CAAC;AACzE,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,iCAAiC,CAAC;AACzE,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,iCAAiC,CAAC;AACzE,OAAO,EAAE,OAAO,IAAI,mBAAmB,EAAE,MAAM,yCAAyC,CAAC;AACzF,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,oCAAoC,CAAC;AAC/E,YAAY,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * @vibesdotdev/code-sessions/svelte
3
+ *
4
+ * Svelte components for code-session management UI. Consumed by wave-2 routes
5
+ * in hq-web and consumer hq. Components are thin wrappers around vibeskit
6
+ * primitives with zero internal jargon in copy.
7
+ *
8
+ * Session display components accept the narrow renderer-safe catalog record.
9
+ * Canonical records remain structurally compatible for trusted web consumers.
10
+ *
11
+ * NOTE: Do NOT import this barrel from a server context; components contain
12
+ * Svelte reactive state. Use the named component subpaths instead.
13
+ */
14
+ export { default as SessionCard } from './components/SessionCard.svelte';
15
+ export { default as SessionList } from './components/SessionList.svelte';
16
+ export { default as SessionSeed } from './components/SessionSeed.svelte';
17
+ export { default as CreateSessionDialog } from './components/CreateSessionDialog.svelte';
18
+ export { default as TranscriptView } from './components/TranscriptView.svelte';