codebay 0.15.0 → 0.16.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 (90) hide show
  1. package/.mochi/manifest.json +493 -432
  2. package/.mochi/svelte-client/HydratableIsland-6y9p903x.js +1 -0
  3. package/.mochi/svelte-client/_hydrate-AppShell_2rtnxn6pgp2rh-nv6yzk0x.js +2 -0
  4. package/.mochi/svelte-client/_hydrate-AvatarsView_257s9yq1wwr4f-ry83ck8a.js +14 -0
  5. package/.mochi/svelte-client/_hydrate-InstanceView_2ma45l9bybfhl-vjt4jscf.js +3 -0
  6. package/.mochi/svelte-client/_hydrate-SettingsView_8hmarwmf8onq-1jdrk8x6.js +48 -0
  7. package/.mochi/svelte-client/{chunk-5pg0be5f.js → chunk-0vqvn81s.js} +1 -1
  8. package/.mochi/svelte-client/chunk-2dc6352a.js +1 -0
  9. package/.mochi/svelte-client/chunk-3cxaw5hr.js +2 -0
  10. package/.mochi/svelte-client/chunk-3jqc40sp.js +2 -0
  11. package/.mochi/svelte-client/chunk-3pgw6t5j.js +4 -0
  12. package/.mochi/svelte-client/chunk-7g3xt6ez.js +2 -0
  13. package/.mochi/svelte-client/chunk-b5s3mpg0.js +1 -0
  14. package/.mochi/svelte-client/chunk-bhseezf3.js +2 -0
  15. package/.mochi/svelte-client/chunk-bhwkq8er.js +1 -0
  16. package/.mochi/svelte-client/chunk-jm3ge348.js +1 -0
  17. package/.mochi/svelte-client/{chunk-ds9yn9cq.js → chunk-sxcr9gzp.js} +1 -1
  18. package/.mochi/svelte-client/{chunk-a2hty99b.js → chunk-tss2473w.js} +1 -1
  19. package/.mochi/svelte-compile/{App-68f9a9fq.server.js → App-8mpgrxza.server.js} +489 -295
  20. package/.mochi/svelte-compile/{Avatars-vyh3rwxx.server.js → Avatars-y5nf6q25.server.js} +102 -86
  21. package/.mochi/svelte-compile/{DefaultError-je52k17d.server.js → DefaultError-rrjye0s2.server.js} +1 -2
  22. package/.mochi/svelte-compile/{Instance-yfw7s5mp.server.js → Instance-3sbzyp0g.server.js} +186 -118
  23. package/.mochi/svelte-compile/{Settings-0b5t9kw9.server.js → Settings-ysvh5vhh.server.js} +739 -628
  24. package/.mochi/svelte-compile/chunk-7zaw9t5a.js +25 -0
  25. package/.mochi/svelte-compile/chunk-878xcmp4.js +65 -0
  26. package/.mochi/svelte-compile/chunk-d2z3qxxe.js +28 -0
  27. package/.mochi/svelte-compile/{chunk-60mpagr9.js → chunk-gnf5cnct.js} +661 -22
  28. package/.mochi/svelte-compile/{chunk-0y3wrae9.js → chunk-jq7jj8jd.js} +10 -6
  29. package/.mochi/svelte-compile/chunk-vr0e32mv.js +24 -0
  30. package/.mochi/svelte-compile/{chunk-apdte4nh.js → chunk-xmygdsj4.js} +35 -612
  31. package/.mochi/svelte-compile/{chunk-g0eravvj.js → chunk-zk4a9zms.js} +25 -17
  32. package/.mochi/svelte-css/DropZone-1zeitd761uwyd.css +1 -0
  33. package/.mochi/svelte-css/IdeBar-d3un7kuigxc5.css +1 -0
  34. package/.mochi/svelte-css/InstanceView-3ucotech5097w.css +1 -0
  35. package/README.md +13 -4
  36. package/migrations/0011_agent_run_rejected_structured_output.sql +2 -0
  37. package/package.json +9 -9
  38. package/src/__fixtures__/IdeBarStrip.svelte +41 -0
  39. package/src/avatars/dog.ts +1 -1
  40. package/src/avatars/lightning.ts +8 -9
  41. package/src/avatars/rocket.ts +4 -5
  42. package/src/components/AppShell.svelte +101 -1
  43. package/src/components/DropZone.svelte +77 -0
  44. package/src/components/HealthBox.svelte +6 -5
  45. package/src/components/IdeBar.svelte +222 -76
  46. package/src/components/InstanceView.svelte +75 -2
  47. package/src/components/SettingsView.svelte +87 -0
  48. package/src/components/TerminalPane.svelte +54 -0
  49. package/src/components/UiShowcase.svelte +19 -1
  50. package/src/container-injections/claude-code-install.ts +1 -1
  51. package/src/container-injections/claude-history.ts +52 -0
  52. package/src/container-injections/tmux.ts +6 -2
  53. package/src/index.ts +3 -0
  54. package/src/lib/agent-run-stream.ts +41 -1
  55. package/src/lib/agent-runs.server.ts +14 -3
  56. package/src/lib/config.server.ts +7 -1
  57. package/src/lib/db.server.ts +6 -2
  58. package/src/lib/devcontainer.server.ts +33 -2
  59. package/src/lib/injections.server.ts +5 -1
  60. package/src/lib/instances.server.ts +21 -4
  61. package/src/lib/log-capture.server.ts +46 -18
  62. package/src/lib/osc52.ts +18 -0
  63. package/src/lib/upload.ts +32 -0
  64. package/src/lib/uploads.server.ts +164 -0
  65. package/src/mcp/server.server.ts +4 -1
  66. package/src/mcp/tools.server.ts +178 -12
  67. package/src/pages/Instance.svelte +6 -2
  68. package/src/pages/Settings.svelte +3 -0
  69. package/src/routes.ts +16 -2
  70. package/src/types.ts +2 -0
  71. package/.mochi/svelte-client/HydratableIsland-smgsf0ma.js +0 -1
  72. package/.mochi/svelte-client/_hydrate-AppShell_2rtnxn6pgp2rh-9vc087ep.js +0 -2
  73. package/.mochi/svelte-client/_hydrate-AvatarsView_257s9yq1wwr4f-a48xq47a.js +0 -14
  74. package/.mochi/svelte-client/_hydrate-InstanceView_2ma45l9bybfhl-d4zehrqz.js +0 -3
  75. package/.mochi/svelte-client/_hydrate-SettingsView_8hmarwmf8onq-t5175pf5.js +0 -44
  76. package/.mochi/svelte-client/chunk-0mstgbtr.js +0 -2
  77. package/.mochi/svelte-client/chunk-0q9g0kpg.js +0 -1
  78. package/.mochi/svelte-client/chunk-3fwjzw1r.js +0 -1
  79. package/.mochi/svelte-client/chunk-fn03gxer.js +0 -4
  80. package/.mochi/svelte-client/chunk-jhgq7f65.js +0 -2
  81. package/.mochi/svelte-client/chunk-p5a07kx1.js +0 -1
  82. package/.mochi/svelte-client/chunk-p5wpyhsf.js +0 -2
  83. package/.mochi/svelte-client/chunk-t2kfvtb6.js +0 -2
  84. package/.mochi/svelte-client/chunk-v3wg9mdy.js +0 -1
  85. package/.mochi/svelte-compile/chunk-2qzc07gt.js +0 -34
  86. package/.mochi/svelte-compile/chunk-ef3hvegw.js +0 -21
  87. package/.mochi/svelte-compile/chunk-f9td8ej2.js +0 -24
  88. package/.mochi/svelte-compile/chunk-jx6h1xzp.js +0 -20
  89. package/.mochi/svelte-css/IdeBar-1mtgemqfuvqzi.css +0 -1
  90. package/.mochi/svelte-css/InstanceView-32j12hyg8v9u0.css +0 -1
@@ -1,49 +1,52 @@
1
1
  // @bun
2
2
  import {
3
3
  Chevron_right,
4
+ DropZone,
4
5
  StatusBadge,
5
- forwardedPortUrl
6
- } from "./chunk-2qzc07gt.js";
6
+ filesFrom,
7
+ forwardedPortUrl,
8
+ uploadFile
9
+ } from "./chunk-878xcmp4.js";
7
10
  import {
8
11
  Layout_template,
9
12
  Plus,
10
13
  tabShortcutsEnabled
11
- } from "./chunk-g0eravvj.js";
14
+ } from "./chunk-zk4a9zms.js";
12
15
  import {
13
16
  Terminal,
14
17
  apiDelete,
15
18
  apiFetch,
16
19
  apiPost,
17
20
  ideUrl
18
- } from "./chunk-0y3wrae9.js";
21
+ } from "./chunk-jq7jj8jd.js";
19
22
  import {
20
23
  AppBar,
21
24
  Avatar,
22
25
  Button,
23
- TOAST_OPTIONS,
24
- Toaster,
25
- dist_default,
26
26
  findAvatar
27
- } from "./chunk-apdte4nh.js";
27
+ } from "./chunk-xmygdsj4.js";
28
28
  import {
29
29
  HydratableBoundary,
30
30
  Icon,
31
+ TOAST_OPTIONS,
32
+ Toaster,
31
33
  X,
34
+ dist_default,
32
35
  emitIslandProps,
33
36
  isDev,
34
37
  withPopupMarker
35
- } from "./chunk-60mpagr9.js";
38
+ } from "./chunk-gnf5cnct.js";
36
39
  import {
37
40
  __require
38
41
  } from "./chunk-xpt1a7jm.js";
39
42
 
40
43
  // src/pages/App.svelte
41
44
  import"svelte/internal/flags/async";
42
- import * as $30 from "svelte/internal/server";
45
+ import * as $31 from "svelte/internal/server";
43
46
 
44
47
  // src/components/AppShell.svelte
45
48
  import"svelte/internal/flags/async";
46
- import * as $29 from "svelte/internal/server";
49
+ import * as $30 from "svelte/internal/server";
47
50
  import { tick as tick2 } from "svelte";
48
51
  import { SvelteSet } from "svelte/reactivity";
49
52
 
@@ -134,72 +137,93 @@ import"svelte/internal/flags/async";
134
137
  import * as $ from "svelte/internal/server";
135
138
  function Folder_clock($$renderer, $$props) {
136
139
  let { $$slots, $$events, ...props } = $$props;
137
- const iconNode = [
138
- ["path", { d: "M16 14v2.2l1.6 1" }],
139
- [
140
- "path",
141
- {
142
- d: "M7 20H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h3.9a2 2 0 0 1 1.69.9l.81 1.2a2 2 0 0 0 1.67.9H20a2 2 0 0 1 2 2"
143
- }
144
- ],
145
- ["circle", { cx: "16", cy: "16", r: "6" }]
146
- ];
147
- Icon($$renderer, $.spread_props([{ name: "folder-clock" }, props, { iconNode }]));
140
+ const iconData = {
141
+ name: "folder-clock",
142
+ size: 24,
143
+ node: [
144
+ ["path", { d: "M16 14v2.2l1.6 1" }],
145
+ [
146
+ "path",
147
+ {
148
+ d: "M7 20H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h3.9a2 2 0 0 1 1.69.9l.81 1.2a2 2 0 0 0 1.67.9H20a2 2 0 0 1 2 2"
149
+ }
150
+ ],
151
+ ["circle", { cx: "16", cy: "16", r: "6" }]
152
+ ]
153
+ };
154
+ Icon($$renderer, $.spread_props([props, { icon: iconData }]));
148
155
  }
149
156
  // node_modules/@lucide/svelte/dist/icons/git-branch.svelte
150
157
  import"svelte/internal/flags/async";
151
158
  import * as $2 from "svelte/internal/server";
152
159
  function Git_branch($$renderer, $$props) {
153
160
  let { $$slots, $$events, ...props } = $$props;
154
- const iconNode = [
155
- ["path", { d: "M15 6a9 9 0 0 0-9 9V3" }],
156
- ["circle", { cx: "18", cy: "6", r: "3" }],
157
- ["circle", { cx: "6", cy: "18", r: "3" }]
158
- ];
159
- Icon($$renderer, $2.spread_props([{ name: "git-branch" }, props, { iconNode }]));
161
+ const iconData = {
162
+ name: "git-branch",
163
+ size: 24,
164
+ node: [
165
+ ["path", { d: "M15 6a9 9 0 0 0-9 9V3" }],
166
+ ["circle", { cx: "18", cy: "6", r: "3" }],
167
+ ["circle", { cx: "6", cy: "18", r: "3" }]
168
+ ]
169
+ };
170
+ Icon($$renderer, $2.spread_props([props, { icon: iconData }]));
160
171
  }
161
172
  // node_modules/@lucide/svelte/dist/icons/arrow-up.svelte
162
173
  import"svelte/internal/flags/async";
163
174
  import * as $3 from "svelte/internal/server";
164
175
  function Arrow_up($$renderer, $$props) {
165
176
  let { $$slots, $$events, ...props } = $$props;
166
- const iconNode = [
167
- ["path", { d: "m5 12 7-7 7 7" }],
168
- ["path", { d: "M12 19V5" }]
169
- ];
170
- Icon($$renderer, $3.spread_props([{ name: "arrow-up" }, props, { iconNode }]));
177
+ const iconData = {
178
+ name: "arrow-up",
179
+ size: 24,
180
+ node: [
181
+ ["path", { d: "m5 12 7-7 7 7" }],
182
+ ["path", { d: "M12 19V5" }]
183
+ ]
184
+ };
185
+ Icon($$renderer, $3.spread_props([props, { icon: iconData }]));
171
186
  }
172
187
  // node_modules/@lucide/svelte/dist/icons/folder.svelte
173
188
  import"svelte/internal/flags/async";
174
189
  import * as $4 from "svelte/internal/server";
175
190
  function Folder($$renderer, $$props) {
176
191
  let { $$slots, $$events, ...props } = $$props;
177
- const iconNode = [
178
- [
179
- "path",
180
- {
181
- d: "M20 20a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.9a2 2 0 0 1-1.69-.9L9.6 3.9A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2Z"
182
- }
192
+ const iconData = {
193
+ name: "folder",
194
+ size: 24,
195
+ node: [
196
+ [
197
+ "path",
198
+ {
199
+ d: "M20 20a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.9a2 2 0 0 1-1.69-.9L9.6 3.9A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2Z"
200
+ }
201
+ ]
183
202
  ]
184
- ];
185
- Icon($$renderer, $4.spread_props([{ name: "folder" }, props, { iconNode }]));
203
+ };
204
+ Icon($$renderer, $4.spread_props([props, { icon: iconData }]));
186
205
  }
187
206
  // node_modules/@lucide/svelte/dist/icons/triangle-alert.svelte
188
207
  import"svelte/internal/flags/async";
189
208
  import * as $5 from "svelte/internal/server";
190
209
  function Triangle_alert($$renderer, $$props) {
191
210
  let { $$slots, $$events, ...props } = $$props;
192
- const iconNode = [
193
- [
194
- "path",
195
- {
196
- d: "m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3"
197
- }
211
+ const iconData = {
212
+ name: "triangle-alert",
213
+ size: 24,
214
+ node: [
215
+ [
216
+ "path",
217
+ {
218
+ d: "m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3"
219
+ }
220
+ ],
221
+ ["path", { d: "M12 9v4" }],
222
+ ["path", { d: "M12 17h.01" }]
198
223
  ],
199
- ["path", { d: "M12 9v4" }],
200
- ["path", { d: "M12 17h.01" }]
201
- ];
202
- Icon($$renderer, $5.spread_props([{ name: "triangle-alert" }, props, { iconNode }]));
224
+ aliases: ["alert-triangle"]
225
+ };
226
+ Icon($$renderer, $5.spread_props([props, { icon: iconData }]));
203
227
  }
204
228
  // src/components/FolderBrowser.svelte
205
229
  function FolderBrowser($$renderer, $$props) {
@@ -263,8 +287,7 @@ function FolderBrowser($$renderer, $$props) {
263
287
  Terminal($$renderer2, { size: 15 });
264
288
  $$renderer2.push(`<!----> Terminal</button></div></div> <div class="clone svelte-oq97c4"><div class="clone-label svelte-oq97c4">Clone a Git repository</div> <div class="clone-row svelte-oq97c4"><input class="clone-url svelte-oq97c4" type="text" placeholder="https://github.com/owner/repo"${$6.attr("value", repoUrl)} spellcheck="false" autocomplete="off"/> <input class="clone-branch svelte-oq97c4" type="text" placeholder="branch (optional)"${$6.attr("value", repoBranch)} spellcheck="false" autocomplete="off"/> <button class="clone-btn svelte-oq97c4"${$6.attr("disabled", !repoValid(), true)}>Clone</button></div></div> <div class="crumbs svelte-oq97c4"><code class="svelte-oq97c4">${$6.escape(atDrivesRoot() ? DRIVES_ROOT_LABEL : result?.path ?? "\u2026")}</code></div> `);
265
289
  if (history2.length > 0) {
266
- $$renderer2.push("<!--[0-->");
267
- $$renderer2.push(`<div class="recent svelte-oq97c4"><div class="recent-label svelte-oq97c4">Recent</div> <!--[-->`);
290
+ $$renderer2.push(`<!--[0--><div class="recent svelte-oq97c4"><div class="recent-label svelte-oq97c4">Recent</div> <!--[-->`);
268
291
  const each_array = $6.ensure_array_like(shownHistory());
269
292
  for (let $$index = 0, $$length = each_array.length;$$index < $$length; $$index++) {
270
293
  let entry = each_array[$$index];
@@ -282,8 +305,7 @@ function FolderBrowser($$renderer, $$props) {
282
305
  }
283
306
  $$renderer2.push(`<!--]--> `);
284
307
  if (history2.length > 5) {
285
- $$renderer2.push("<!--[0-->");
286
- $$renderer2.push(`<button class="recent-toggle svelte-oq97c4">${$6.escape(showAll ? "Show fewer" : `Show all (${history2.length})`)}</button>`);
308
+ $$renderer2.push(`<!--[0--><button class="recent-toggle svelte-oq97c4">${$6.escape(showAll ? "Show fewer" : `Show all (${history2.length})`)}</button>`);
287
309
  } else {
288
310
  $$renderer2.push("<!--[-1-->");
289
311
  }
@@ -293,16 +315,13 @@ function FolderBrowser($$renderer, $$props) {
293
315
  }
294
316
  $$renderer2.push(`<!--]--> <div class="search svelte-oq97c4"><input type="text" placeholder="Filter folders\u2026"${$6.attr("value", query)} spellcheck="false" autocomplete="off" class="svelte-oq97c4"/></div> <div class="list svelte-oq97c4">`);
295
317
  if (loading) {
296
- $$renderer2.push("<!--[0-->");
297
- $$renderer2.push(`<div class="muted svelte-oq97c4">Loading\u2026</div>`);
318
+ $$renderer2.push(`<!--[0--><div class="muted svelte-oq97c4">Loading\u2026</div>`);
298
319
  } else if (errorMsg) {
299
- $$renderer2.push("<!--[1-->");
300
- $$renderer2.push(`<div class="muted err svelte-oq97c4">${$6.escape(errorMsg)}</div>`);
320
+ $$renderer2.push(`<!--[1--><div class="muted err svelte-oq97c4">${$6.escape(errorMsg)}</div>`);
301
321
  } else if (result) {
302
322
  $$renderer2.push("<!--[2-->");
303
323
  if (result.parent && !query) {
304
- $$renderer2.push("<!--[0-->");
305
- $$renderer2.push(`<div class="row svelte-oq97c4"><button class="nav svelte-oq97c4"><span class="icon svelte-oq97c4">`);
324
+ $$renderer2.push(`<!--[0--><div class="row svelte-oq97c4"><button class="nav svelte-oq97c4"><span class="icon svelte-oq97c4">`);
306
325
  Arrow_up($$renderer2, { size: 16 });
307
326
  $$renderer2.push(`<!----></span> <span class="ename svelte-oq97c4">..</span></button></div>`);
308
327
  } else {
@@ -310,8 +329,7 @@ function FolderBrowser($$renderer, $$props) {
310
329
  }
311
330
  $$renderer2.push(`<!--]--> `);
312
331
  if (filtered().length === 0) {
313
- $$renderer2.push("<!--[0-->");
314
- $$renderer2.push(`<div class="muted svelte-oq97c4">${$6.escape(query ? "No folders match." : "No subfolders here.")}</div>`);
332
+ $$renderer2.push(`<!--[0--><div class="muted svelte-oq97c4">${$6.escape(query ? "No folders match." : "No subfolders here.")}</div>`);
315
333
  } else {
316
334
  $$renderer2.push("<!--[-1-->");
317
335
  }
@@ -323,8 +341,7 @@ function FolderBrowser($$renderer, $$props) {
323
341
  Folder($$renderer2, { size: 16 });
324
342
  $$renderer2.push(`<!----></span> <span class="ename svelte-oq97c4">${$6.escape(entry.name)}</span> `);
325
343
  if (entry.hasDevcontainer) {
326
- $$renderer2.push("<!--[0-->");
327
- $$renderer2.push(`<span class="badge svelte-oq97c4">devcontainer</span>`);
344
+ $$renderer2.push(`<!--[0--><span class="badge svelte-oq97c4">devcontainer</span>`);
328
345
  } else {
329
346
  $$renderer2.push("<!--[-1-->");
330
347
  }
@@ -336,8 +353,7 @@ function FolderBrowser($$renderer, $$props) {
336
353
  }
337
354
  $$renderer2.push(`<!--]--></div> `);
338
355
  if (result && !result.hasDevcontainer && !atDrivesRoot()) {
339
- $$renderer2.push("<!--[0-->");
340
- $$renderer2.push(`<div class="warn svelte-oq97c4">`);
356
+ $$renderer2.push(`<!--[0--><div class="warn svelte-oq97c4">`);
341
357
  Triangle_alert($$renderer2, { size: 15 });
342
358
  $$renderer2.push(`<!----> <span>No <code class="svelte-oq97c4">devcontainer.json</code> in this folder \u2014 a default image will be used if you select
343
359
  it.</span></div>`);
@@ -371,37 +387,40 @@ import"svelte/internal/flags/async";
371
387
  import * as $8 from "svelte/internal/server";
372
388
  function Cable($$renderer, $$props) {
373
389
  let { $$slots, $$events, ...props } = $$props;
374
- const iconNode = [
375
- [
376
- "path",
377
- {
378
- d: "M17 19a1 1 0 0 1-1-1v-2a2 2 0 0 1 2-2h2a2 2 0 0 1 2 2v2a1 1 0 0 1-1 1z"
379
- }
380
- ],
381
- ["path", { d: "M17 21v-2" }],
382
- [
383
- "path",
384
- { d: "M19 14V6.5a1 1 0 0 0-7 0v11a1 1 0 0 1-7 0V10" }
385
- ],
386
- ["path", { d: "M21 21v-2" }],
387
- ["path", { d: "M3 5V3" }],
388
- [
389
- "path",
390
- {
391
- d: "M4 10a2 2 0 0 1-2-2V6a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1v2a2 2 0 0 1-2 2z"
392
- }
393
- ],
394
- ["path", { d: "M7 5V3" }]
395
- ];
396
- Icon($$renderer, $8.spread_props([{ name: "cable" }, props, { iconNode }]));
390
+ const iconData = {
391
+ name: "cable",
392
+ size: 24,
393
+ node: [
394
+ [
395
+ "path",
396
+ {
397
+ d: "M17 19a1 1 0 0 1-1-1v-2a2 2 0 0 1 2-2h2a2 2 0 0 1 2 2v2a1 1 0 0 1-1 1z"
398
+ }
399
+ ],
400
+ ["path", { d: "M17 21v-2" }],
401
+ [
402
+ "path",
403
+ { d: "M19 14V6.5a1 1 0 0 0-7 0v11a1 1 0 0 1-7 0V10" }
404
+ ],
405
+ ["path", { d: "M21 21v-2" }],
406
+ ["path", { d: "M3 5V3" }],
407
+ [
408
+ "path",
409
+ {
410
+ d: "M4 10a2 2 0 0 1-2-2V6a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1v2a2 2 0 0 1-2 2z"
411
+ }
412
+ ],
413
+ ["path", { d: "M7 5V3" }]
414
+ ]
415
+ };
416
+ Icon($$renderer, $8.spread_props([props, { icon: iconData }]));
397
417
  }
398
418
  // src/components/PortsBox.svelte
399
419
  function PortsBox($$renderer, $$props) {
400
420
  $$renderer.component(($$renderer2) => {
401
421
  let { ports } = $$props;
402
422
  if (ports.length) {
403
- $$renderer2.push("<!--[0-->");
404
- $$renderer2.push(`<div class="fports svelte-1uaz383" title="Forwarded ports \u2014 click to open">`);
423
+ $$renderer2.push(`<!--[0--><div class="fports svelte-1uaz383" title="Forwarded ports \u2014 click to open">`);
405
424
  Cable($$renderer2, { size: 12 });
406
425
  $$renderer2.push(`<!----> <span class="list svelte-1uaz383"><!--[-->`);
407
426
  const each_array = $9.ensure_array_like(ports);
@@ -439,8 +458,7 @@ function InstanceCard($$renderer, $$props) {
439
458
  };
440
459
  $$renderer2.push(`<li${$10.attr_class("card panel svelte-13338y7", undefined, { busy: !!pending })}${$10.attr("aria-busy", !!pending || undefined)}>`);
441
460
  if (pending) {
442
- $$renderer2.push("<!--[0-->");
443
- $$renderer2.push(`<div class="busy-overlay svelte-13338y7" aria-live="polite"><span class="busy-label svelte-13338y7">${$10.escape(BUSY_LABEL[pending])}</span></div>`);
461
+ $$renderer2.push(`<!--[0--><div class="busy-overlay svelte-13338y7" aria-live="polite"><span class="busy-label svelte-13338y7">${$10.escape(BUSY_LABEL[pending])}</span></div>`);
444
462
  } else {
445
463
  $$renderer2.push("<!--[-1-->");
446
464
  }
@@ -452,16 +470,13 @@ function InstanceCard($$renderer, $$props) {
452
470
  });
453
471
  $$renderer2.push(`<!----> `);
454
472
  if (editing) {
455
- $$renderer2.push("<!--[0-->");
456
- $$renderer2.push(`<input class="name-edit svelte-13338y7"${$10.attr("value", editingName)} autofocus=""/>`);
473
+ $$renderer2.push(`<!--[0--><input class="name-edit svelte-13338y7"${$10.attr("value", editingName)} autofocus=""/>`);
457
474
  } else {
458
- $$renderer2.push("<!--[-1-->");
459
- $$renderer2.push(`<button class="name svelte-13338y7" title="Click to rename">${$10.escape(instance.name)}</button>`);
475
+ $$renderer2.push(`<!--[-1--><button class="name svelte-13338y7" title="Click to rename">${$10.escape(instance.name)}</button>`);
460
476
  }
461
477
  $$renderer2.push(`<!--]--> `);
462
478
  if (instance.attention) {
463
- $$renderer2.push("<!--[0-->");
464
- $$renderer2.push(`<span${$10.attr_class("attn svelte-13338y7", undefined, {
479
+ $$renderer2.push(`<!--[0--><span${$10.attr_class("attn svelte-13338y7", undefined, {
465
480
  "attn-done": instance.attention === "done",
466
481
  "attn-waiting": instance.attention === "waiting"
467
482
  })}${$10.attr("title", instance.attention === "waiting" ? "Claude is waiting for input" : "Claude finished")}${$10.attr("aria-label", instance.attention === "waiting" ? "Claude is waiting for input" : "Claude finished")}></span>`);
@@ -486,15 +501,13 @@ function InstanceCard($$renderer, $$props) {
486
501
  }
487
502
  $$renderer2.push(`<!--]--> `);
488
503
  if (instance.active_run) {
489
- $$renderer2.push("<!--[0-->");
490
- $$renderer2.push(`<div class="agent-run svelte-13338y7" title="An MCP client is driving Claude in this sandbox"><span class="agent-dot svelte-13338y7"></span> <span class="agent-text svelte-13338y7">${$10.escape(instance.active_run.status === "queued" ? "Agent run queued" : instance.active_run.last_activity ?? "Agent running")}</span></div>`);
504
+ $$renderer2.push(`<!--[0--><div class="agent-run svelte-13338y7" title="An MCP client is driving Claude in this sandbox"><span class="agent-dot svelte-13338y7"></span> <span class="agent-text svelte-13338y7">${$10.escape(instance.active_run.status === "queued" ? "Agent run queued" : instance.active_run.last_activity ?? "Agent running")}</span></div>`);
491
505
  } else {
492
506
  $$renderer2.push("<!--[-1-->");
493
507
  }
494
508
  $$renderer2.push(`<!--]--> `);
495
509
  if (instance.status === "error" && instance.error) {
496
- $$renderer2.push("<!--[0-->");
497
- $$renderer2.push(`<div class="card-error svelte-13338y7">${$10.escape(instance.error)}</div>`);
510
+ $$renderer2.push(`<!--[0--><div class="card-error svelte-13338y7">${$10.escape(instance.error)}</div>`);
498
511
  } else {
499
512
  $$renderer2.push("<!--[-1-->");
500
513
  }
@@ -596,33 +609,37 @@ import"svelte/internal/flags/async";
596
609
  import * as $11 from "svelte/internal/server";
597
610
  function Component($$renderer, $$props) {
598
611
  let { $$slots, $$events, ...props } = $$props;
599
- const iconNode = [
600
- [
601
- "path",
602
- {
603
- d: "M15.536 11.293a1 1 0 0 0 0 1.414l2.376 2.377a1 1 0 0 0 1.414 0l2.377-2.377a1 1 0 0 0 0-1.414l-2.377-2.377a1 1 0 0 0-1.414 0z"
604
- }
605
- ],
606
- [
607
- "path",
608
- {
609
- d: "M2.297 11.293a1 1 0 0 0 0 1.414l2.377 2.377a1 1 0 0 0 1.414 0l2.377-2.377a1 1 0 0 0 0-1.414L6.088 8.916a1 1 0 0 0-1.414 0z"
610
- }
611
- ],
612
- [
613
- "path",
614
- {
615
- d: "M8.916 17.912a1 1 0 0 0 0 1.415l2.377 2.376a1 1 0 0 0 1.414 0l2.377-2.376a1 1 0 0 0 0-1.415l-2.377-2.376a1 1 0 0 0-1.414 0z"
616
- }
617
- ],
618
- [
619
- "path",
620
- {
621
- d: "M8.916 4.674a1 1 0 0 0 0 1.414l2.377 2.376a1 1 0 0 0 1.414 0l2.377-2.376a1 1 0 0 0 0-1.414l-2.377-2.377a1 1 0 0 0-1.414 0z"
622
- }
612
+ const iconData = {
613
+ name: "component",
614
+ size: 24,
615
+ node: [
616
+ [
617
+ "path",
618
+ {
619
+ d: "M15.536 11.293a1 1 0 0 0 0 1.414l2.376 2.377a1 1 0 0 0 1.414 0l2.377-2.377a1 1 0 0 0 0-1.414l-2.377-2.377a1 1 0 0 0-1.414 0z"
620
+ }
621
+ ],
622
+ [
623
+ "path",
624
+ {
625
+ d: "M2.297 11.293a1 1 0 0 0 0 1.414l2.377 2.377a1 1 0 0 0 1.414 0l2.377-2.377a1 1 0 0 0 0-1.414L6.088 8.916a1 1 0 0 0-1.414 0z"
626
+ }
627
+ ],
628
+ [
629
+ "path",
630
+ {
631
+ d: "M8.916 17.912a1 1 0 0 0 0 1.415l2.377 2.376a1 1 0 0 0 1.414 0l2.377-2.376a1 1 0 0 0 0-1.415l-2.377-2.376a1 1 0 0 0-1.414 0z"
632
+ }
633
+ ],
634
+ [
635
+ "path",
636
+ {
637
+ d: "M8.916 4.674a1 1 0 0 0 0 1.414l2.377 2.376a1 1 0 0 0 1.414 0l2.377-2.376a1 1 0 0 0 0-1.414l-2.377-2.377a1 1 0 0 0-1.414 0z"
638
+ }
639
+ ]
623
640
  ]
624
- ];
625
- Icon($$renderer, $11.spread_props([{ name: "component" }, props, { iconNode }]));
641
+ };
642
+ Icon($$renderer, $11.spread_props([props, { icon: iconData }]));
626
643
  }
627
644
  // src/components/Brand.svelte
628
645
  import"svelte/internal/flags/async";
@@ -633,18 +650,22 @@ import"svelte/internal/flags/async";
633
650
  import * as $12 from "svelte/internal/server";
634
651
  function Package($$renderer, $$props) {
635
652
  let { $$slots, $$events, ...props } = $$props;
636
- const iconNode = [
637
- [
638
- "path",
639
- {
640
- d: "M11 21.73a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73z"
641
- }
642
- ],
643
- ["path", { d: "M12 22V12" }],
644
- ["polyline", { points: "3.29 7 12 12 20.71 7" }],
645
- ["path", { d: "m7.5 4.27 9 5.15" }]
646
- ];
647
- Icon($$renderer, $12.spread_props([{ name: "package" }, props, { iconNode }]));
653
+ const iconData = {
654
+ name: "package",
655
+ size: 24,
656
+ node: [
657
+ [
658
+ "path",
659
+ {
660
+ d: "M11 21.73a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73z"
661
+ }
662
+ ],
663
+ ["path", { d: "M12 22V12" }],
664
+ ["polyline", { points: "3.29 7 12 12 20.71 7" }],
665
+ ["path", { d: "m7.5 4.27 9 5.15" }]
666
+ ]
667
+ };
668
+ Icon($$renderer, $12.spread_props([props, { icon: iconData }]));
648
669
  }
649
670
  // src/components/Brand.svelte
650
671
  function Brand($$renderer, $$props) {
@@ -692,16 +713,20 @@ import"svelte/internal/flags/async";
692
713
  import * as $15 from "svelte/internal/server";
693
714
  function Settings($$renderer, $$props) {
694
715
  let { $$slots, $$events, ...props } = $$props;
695
- const iconNode = [
696
- [
697
- "path",
698
- {
699
- d: "M9.671 4.136a2.34 2.34 0 0 1 4.659 0 2.34 2.34 0 0 0 3.319 1.915 2.34 2.34 0 0 1 2.33 4.033 2.34 2.34 0 0 0 0 3.831 2.34 2.34 0 0 1-2.33 4.033 2.34 2.34 0 0 0-3.319 1.915 2.34 2.34 0 0 1-4.659 0 2.34 2.34 0 0 0-3.32-1.915 2.34 2.34 0 0 1-2.33-4.033 2.34 2.34 0 0 0 0-3.831A2.34 2.34 0 0 1 6.35 6.051a2.34 2.34 0 0 0 3.319-1.915"
700
- }
701
- ],
702
- ["circle", { cx: "12", cy: "12", r: "3" }]
703
- ];
704
- Icon($$renderer, $15.spread_props([{ name: "settings" }, props, { iconNode }]));
716
+ const iconData = {
717
+ name: "settings",
718
+ size: 24,
719
+ node: [
720
+ [
721
+ "path",
722
+ {
723
+ d: "M9.671 4.136a2.34 2.34 0 0 1 4.659 0 2.34 2.34 0 0 0 3.319 1.915 2.34 2.34 0 0 1 2.33 4.033 2.34 2.34 0 0 0 0 3.831 2.34 2.34 0 0 1-2.33 4.033 2.34 2.34 0 0 0-3.319 1.915 2.34 2.34 0 0 1-4.659 0 2.34 2.34 0 0 0-3.32-1.915 2.34 2.34 0 0 1-2.33-4.033 2.34 2.34 0 0 0 0-3.831A2.34 2.34 0 0 1 6.35 6.051a2.34 2.34 0 0 0 3.319-1.915"
724
+ }
725
+ ],
726
+ ["circle", { cx: "12", cy: "12", r: "3" }]
727
+ ]
728
+ };
729
+ Icon($$renderer, $15.spread_props([props, { icon: iconData }]));
705
730
  }
706
731
  // src/components/SettingsCog.svelte
707
732
  function SettingsCog($$renderer, $$props) {
@@ -721,21 +746,25 @@ import"svelte/internal/flags/async";
721
746
  import * as $17 from "svelte/internal/server";
722
747
  function Link($$renderer, $$props) {
723
748
  let { $$slots, $$events, ...props } = $$props;
724
- const iconNode = [
725
- [
726
- "path",
727
- {
728
- d: "M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"
729
- }
730
- ],
731
- [
732
- "path",
733
- {
734
- d: "M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"
735
- }
749
+ const iconData = {
750
+ name: "link",
751
+ size: 24,
752
+ node: [
753
+ [
754
+ "path",
755
+ {
756
+ d: "M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"
757
+ }
758
+ ],
759
+ [
760
+ "path",
761
+ {
762
+ d: "M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"
763
+ }
764
+ ]
736
765
  ]
737
- ];
738
- Icon($$renderer, $17.spread_props([{ name: "link" }, props, { iconNode }]));
766
+ };
767
+ Icon($$renderer, $17.spread_props([props, { icon: iconData }]));
739
768
  }
740
769
  // src/components/CredMenu.svelte
741
770
  function CredMenu($$renderer, $$props) {
@@ -765,8 +794,7 @@ function CredMenu($$renderer, $$props) {
765
794
  }
766
795
  $$renderer2.push(`</button> `);
767
796
  if (credOpen) {
768
- $$renderer2.push("<!--[0-->");
769
- $$renderer2.push(`<div class="cred-dropdown panel svelte-vongf9" role="menu"><!--[-->`);
797
+ $$renderer2.push(`<!--[0--><div class="cred-dropdown panel svelte-vongf9" role="menu"><!--[-->`);
770
798
  const each_array = $18.ensure_array_like(auth);
771
799
  for (let $$index = 0, $$length = each_array.length;$$index < $$length; $$index++) {
772
800
  let provider = each_array[$$index];
@@ -968,18 +996,15 @@ function DashboardView($$renderer, $$props) {
968
996
  });
969
997
  $$renderer3.push(`<!----> <main class="stage svelte-146pixd">`);
970
998
  if (!ready()) {
971
- $$renderer3.push("<!--[0-->");
972
- $$renderer3.push(`<div class="banner error svelte-146pixd"><strong>Setup needed.</strong> `);
999
+ $$renderer3.push(`<!--[0--><div class="banner error svelte-146pixd"><strong>Setup needed.</strong> `);
973
1000
  if (!preflight.docker) {
974
- $$renderer3.push("<!--[0-->");
975
- $$renderer3.push(`<span>Docker daemon is not reachable.</span>`);
1001
+ $$renderer3.push(`<!--[0--><span>Docker daemon is not reachable.</span>`);
976
1002
  } else {
977
1003
  $$renderer3.push("<!--[-1-->");
978
1004
  }
979
1005
  $$renderer3.push(`<!--]--> `);
980
1006
  if (!preflight.cli) {
981
- $$renderer3.push("<!--[0-->");
982
- $$renderer3.push(`<span>The devcontainer CLI is not available.</span>`);
1007
+ $$renderer3.push(`<!--[0--><span>The devcontainer CLI is not available.</span>`);
983
1008
  } else {
984
1009
  $$renderer3.push("<!--[-1-->");
985
1010
  }
@@ -989,18 +1014,15 @@ function DashboardView($$renderer, $$props) {
989
1014
  }
990
1015
  $$renderer3.push(`<!--]--> `);
991
1016
  if (actionError) {
992
- $$renderer3.push("<!--[0-->");
993
- $$renderer3.push(`<div class="banner error svelte-146pixd"><strong>Error.</strong> <span>${$20.escape(actionError)}</span></div>`);
1017
+ $$renderer3.push(`<!--[0--><div class="banner error svelte-146pixd"><strong>Error.</strong> <span>${$20.escape(actionError)}</span></div>`);
994
1018
  } else {
995
1019
  $$renderer3.push("<!--[-1-->");
996
1020
  }
997
1021
  $$renderer3.push(`<!--]--> `);
998
1022
  if (!loaded) {
999
- $$renderer3.push("<!--[0-->");
1000
- $$renderer3.push(`<div class="empty svelte-146pixd"><p class="empty-sub svelte-146pixd">Loading\u2026</p></div>`);
1023
+ $$renderer3.push(`<!--[0--><div class="empty svelte-146pixd"><p class="empty-sub svelte-146pixd">Loading\u2026</p></div>`);
1001
1024
  } else if (instances.length === 0) {
1002
- $$renderer3.push("<!--[1-->");
1003
- $$renderer3.push(`<div class="empty svelte-146pixd"><p class="empty-title svelte-146pixd">No instances yet</p> <p class="empty-sub svelte-146pixd">Pick a project folder to spin up an isolated devcontainer.</p> `);
1025
+ $$renderer3.push(`<!--[1--><div class="empty svelte-146pixd"><p class="empty-title svelte-146pixd">No instances yet</p> <p class="empty-sub svelte-146pixd">Pick a project folder to spin up an isolated devcontainer.</p> `);
1004
1026
  Button($$renderer3, {
1005
1027
  variant: "primary",
1006
1028
  icon: Plus,
@@ -1013,11 +1035,9 @@ function DashboardView($$renderer, $$props) {
1013
1035
  });
1014
1036
  $$renderer3.push(`<!----></div>`);
1015
1037
  } else if (visible().length === 0) {
1016
- $$renderer3.push("<!--[2-->");
1017
- $$renderer3.push(`<div class="empty svelte-146pixd"><p class="empty-sub svelte-146pixd">No ${$20.escape(filter)} instances.</p></div>`);
1038
+ $$renderer3.push(`<!--[2--><div class="empty svelte-146pixd"><p class="empty-sub svelte-146pixd">No ${$20.escape(filter)} instances.</p></div>`);
1018
1039
  } else {
1019
- $$renderer3.push("<!--[-1-->");
1020
- $$renderer3.push(`<ul class="grid svelte-146pixd"><!--[-->`);
1040
+ $$renderer3.push(`<!--[-1--><ul class="grid svelte-146pixd"><!--[-->`);
1021
1041
  const each_array = $20.ensure_array_like(visible());
1022
1042
  for (let $$index = 0, $$length = each_array.length;$$index < $$length; $$index++) {
1023
1043
  let instance = each_array[$$index];
@@ -1065,29 +1085,53 @@ function DashboardView($$renderer, $$props) {
1065
1085
 
1066
1086
  // src/components/IdeBar.svelte
1067
1087
  import"svelte/internal/flags/async";
1068
- import * as $23 from "svelte/internal/server";
1088
+ import * as $24 from "svelte/internal/server";
1069
1089
 
1070
1090
  // node_modules/@lucide/svelte/dist/icons/rotate-cw.svelte
1071
1091
  import"svelte/internal/flags/async";
1072
1092
  import * as $21 from "svelte/internal/server";
1073
1093
  function Rotate_cw($$renderer, $$props) {
1074
1094
  let { $$slots, $$events, ...props } = $$props;
1075
- const iconNode = [
1076
- [
1077
- "path",
1078
- { d: "M21 12a9 9 0 1 1-9-9c2.52 0 4.93 1 6.74 2.74L21 8" }
1079
- ],
1080
- ["path", { d: "M21 3v5h-5" }]
1081
- ];
1082
- Icon($$renderer, $21.spread_props([{ name: "rotate-cw" }, props, { iconNode }]));
1095
+ const iconData = {
1096
+ name: "rotate-cw",
1097
+ size: 24,
1098
+ node: [
1099
+ [
1100
+ "path",
1101
+ { d: "M21 12a9 9 0 1 1-9-9c2.52 0 4.93 1 6.74 2.74L21 8" }
1102
+ ],
1103
+ ["path", { d: "M21 3v5h-5" }]
1104
+ ]
1105
+ };
1106
+ Icon($$renderer, $21.spread_props([props, { icon: iconData }]));
1083
1107
  }
1084
1108
  // node_modules/@lucide/svelte/dist/icons/chevron-left.svelte
1085
1109
  import"svelte/internal/flags/async";
1086
1110
  import * as $22 from "svelte/internal/server";
1087
1111
  function Chevron_left($$renderer, $$props) {
1088
1112
  let { $$slots, $$events, ...props } = $$props;
1089
- const iconNode = [["path", { d: "m15 18-6-6 6-6" }]];
1090
- Icon($$renderer, $22.spread_props([{ name: "chevron-left" }, props, { iconNode }]));
1113
+ const iconData = {
1114
+ name: "chevron-left",
1115
+ size: 24,
1116
+ node: [["path", { d: "m15 18-6-6 6-6" }]]
1117
+ };
1118
+ Icon($$renderer, $22.spread_props([props, { icon: iconData }]));
1119
+ }
1120
+ // node_modules/@lucide/svelte/dist/icons/circle-stop.svelte
1121
+ import"svelte/internal/flags/async";
1122
+ import * as $23 from "svelte/internal/server";
1123
+ function Circle_stop($$renderer, $$props) {
1124
+ let { $$slots, $$events, ...props } = $$props;
1125
+ const iconData = {
1126
+ name: "circle-stop",
1127
+ size: 24,
1128
+ node: [
1129
+ ["circle", { cx: "12", cy: "12", r: "10" }],
1130
+ ["rect", { x: "9", y: "9", width: "6", height: "6", rx: "1" }]
1131
+ ],
1132
+ aliases: ["stop-circle"]
1133
+ };
1134
+ Icon($$renderer, $23.spread_props([props, { icon: iconData }]));
1091
1135
  }
1092
1136
  // src/components/IdeBar.svelte
1093
1137
  function IdeBar($$renderer, $$props) {
@@ -1098,20 +1142,52 @@ function IdeBar($$renderer, $$props) {
1098
1142
  attention,
1099
1143
  editingId,
1100
1144
  editingName = undefined,
1145
+ stopping = [],
1101
1146
  onreload,
1102
1147
  onselect,
1148
+ onstop,
1149
+ ondropfiles,
1103
1150
  onstartrename,
1104
1151
  oncommitrename,
1105
1152
  oncancelrename
1106
1153
  } = $$props;
1107
- const activeIndex = $23.derived(() => running.findIndex((i) => i.id === active));
1108
- const focusIndex = $23.derived(() => activeIndex() >= 0 ? activeIndex() : 0);
1154
+ const isStopping = (id) => stopping.includes(id);
1155
+ let dropTarget = null;
1156
+ let tipWidth = 0;
1157
+ const tipLeft = $24.derived(() => dropTarget ? Math.max(8, Math.min(dropTarget.x - tipWidth / 2, dropTarget.maxX - tipWidth)) : 0);
1158
+ function onSlotDrag(e, id) {
1159
+ if (!ondropfiles || !e.dataTransfer?.types.includes("Files"))
1160
+ return;
1161
+ e.preventDefault();
1162
+ e.dataTransfer.dropEffect = "copy";
1163
+ if (dropTarget?.id === id)
1164
+ return;
1165
+ const r = e.currentTarget.getBoundingClientRect();
1166
+ dropTarget = {
1167
+ id,
1168
+ x: r.left + r.width / 2,
1169
+ y: r.bottom,
1170
+ maxX: document.documentElement.clientWidth - 8
1171
+ };
1172
+ }
1173
+ function onSlotLeave(e) {
1174
+ if (e.currentTarget.contains(e.relatedTarget))
1175
+ return;
1176
+ dropTarget = null;
1177
+ }
1178
+ function onSlotDrop(e, id) {
1179
+ if (!ondropfiles)
1180
+ return;
1181
+ e.preventDefault();
1182
+ dropTarget = null;
1183
+ ondropfiles(id, filesFrom(e.dataTransfer));
1184
+ }
1109
1185
  let viewport = null;
1110
1186
  let content = null;
1111
1187
  let atStart = true;
1112
1188
  let atEnd = true;
1113
1189
  const tabEls = {};
1114
- const overflowing = $23.derived(() => !atStart || !atEnd);
1190
+ const overflowing = $24.derived(() => !atStart || !atEnd);
1115
1191
  function measure() {
1116
1192
  if (!viewport)
1117
1193
  return;
@@ -1125,8 +1201,8 @@ function IdeBar($$renderer, $$props) {
1125
1201
  onselect(inst.id);
1126
1202
  tabEls[inst.id]?.focus();
1127
1203
  }
1128
- function onTabKeydown(e) {
1129
- const next = nextTabIndex(activeIndex(), e.key, running.length);
1204
+ function onTabKeydown(e, index) {
1205
+ const next = nextTabIndex(index, e.key, running.length);
1130
1206
  if (next === null)
1131
1207
  return;
1132
1208
  e.preventDefault();
@@ -1140,38 +1216,38 @@ function IdeBar($$renderer, $$props) {
1140
1216
  AppBar($$renderer2, {
1141
1217
  children: ($$renderer3) => {
1142
1218
  if (running.length > 0) {
1143
- $$renderer3.push("<!--[0-->");
1144
- $$renderer3.push(`<div class="strip svelte-r39acv">`);
1219
+ $$renderer3.push(`<!--[0--><div class="strip svelte-r39acv">`);
1145
1220
  if (overflowing()) {
1146
- $$renderer3.push("<!--[0-->");
1147
- $$renderer3.push(`<button type="button" class="page svelte-r39acv"${$23.attr("disabled", atStart, true)} aria-label="Scroll tabs left">`);
1221
+ $$renderer3.push(`<!--[0--><button type="button" class="page svelte-r39acv"${$24.attr("disabled", atStart, true)} aria-label="Scroll tabs left">`);
1148
1222
  Chevron_left($$renderer3, { size: 16 });
1149
1223
  $$renderer3.push(`<!----></button>`);
1150
1224
  } else {
1151
1225
  $$renderer3.push("<!--[-1-->");
1152
1226
  }
1153
- $$renderer3.push(`<!--]--> <div class="viewport svelte-r39acv"><div class="tabs svelte-r39acv" role="tablist" aria-label="Instances"><!--[-->`);
1154
- const each_array = $23.ensure_array_like(running);
1227
+ $$renderer3.push(`<!--]--> <div class="viewport svelte-r39acv"><nav class="tabs svelte-r39acv" aria-label="Instances"><!--[-->`);
1228
+ const each_array = $24.ensure_array_like(running);
1155
1229
  for (let i = 0, $$length = each_array.length;i < $$length; i++) {
1156
1230
  let inst = each_array[i];
1231
+ $$renderer3.push(`<div${$24.attr_class("tab-slot svelte-r39acv", undefined, {
1232
+ active: inst.id === active,
1233
+ "drop-target": dropTarget?.id === inst.id
1234
+ })} role="presentation">`);
1157
1235
  if (editingId === inst.id) {
1158
- $$renderer3.push("<!--[0-->");
1159
- $$renderer3.push(`<div class="tab editing svelte-r39acv">`);
1236
+ $$renderer3.push(`<!--[0--><div class="tab editing svelte-r39acv">`);
1160
1237
  Avatar($$renderer3, {
1161
1238
  name: inst.name,
1162
1239
  art: findAvatar(inst.avatar ?? undefined) ?? null,
1163
1240
  scale: 3
1164
1241
  });
1165
- $$renderer3.push(`<!----> <input class="tab-name-edit svelte-r39acv"${$23.attr("value", editingName)} autofocus=""/></div>`);
1242
+ $$renderer3.push(`<!----> <input class="tab-name-edit svelte-r39acv"${$24.attr("value", editingName)} autofocus=""/></div>`);
1166
1243
  } else {
1167
- $$renderer3.push("<!--[-1-->");
1168
- $$renderer3.push(`<button type="button"${$23.attr_class("tab svelte-r39acv", undefined, { active: inst.id === active })}${$23.attr("id", `tab-${$23.stringify(inst.id)}`)} role="tab"${$23.attr("aria-selected", inst.id === active)}${$23.attr("tabindex", i === focusIndex() ? 0 : -1)}${$23.attr("title", inst.name)}>`);
1244
+ $$renderer3.push(`<!--[-1--><button type="button"${$24.attr_class("tab svelte-r39acv", undefined, { active: inst.id === active })}${$24.attr("id", `tab-${$24.stringify(inst.id)}`)}${$24.attr("aria-current", inst.id === active ? "page" : undefined)}${$24.attr("title", inst.name)}>`);
1169
1245
  Avatar($$renderer3, {
1170
1246
  name: inst.name,
1171
1247
  art: findAvatar(inst.avatar ?? undefined) ?? null,
1172
1248
  scale: 3
1173
1249
  });
1174
- $$renderer3.push(`<!----> <span class="tab-name svelte-r39acv">${$23.escape(inst.name)}</span> <span class="tab-mode svelte-r39acv"${$23.attr("aria-label", inst.mode === "terminal" ? "Terminal-only instance" : "Full IDE instance")}>`);
1250
+ $$renderer3.push(`<!----> <span class="tab-name svelte-r39acv">${$24.escape(inst.name)}</span> <span class="tab-mode svelte-r39acv"${$24.attr("aria-label", inst.mode === "terminal" ? "Terminal-only instance" : "Full IDE instance")}>`);
1175
1251
  if (inst.mode === "terminal") {
1176
1252
  $$renderer3.push("<!--[0-->");
1177
1253
  Terminal($$renderer3, { size: 11 });
@@ -1181,19 +1257,25 @@ function IdeBar($$renderer, $$props) {
1181
1257
  }
1182
1258
  $$renderer3.push(`<!--]--></span> `);
1183
1259
  if (inst.id !== active && attention[inst.id]) {
1184
- $$renderer3.push("<!--[0-->");
1185
- $$renderer3.push(`<span${$23.attr_class(`attn ${$23.stringify(attention[inst.id])}`, "svelte-r39acv")}${$23.attr("aria-label", attention[inst.id] === "waiting" ? "Claude is waiting for input" : "Claude finished")}></span>`);
1260
+ $$renderer3.push(`<!--[0--><span${$24.attr_class(`attn ${$24.stringify(attention[inst.id])}`, "svelte-r39acv")}${$24.attr("aria-label", attention[inst.id] === "waiting" ? "Claude is waiting for input" : "Claude finished")}></span>`);
1261
+ } else {
1262
+ $$renderer3.push("<!--[-1-->");
1263
+ }
1264
+ $$renderer3.push(`<!--]--></button> `);
1265
+ if (onstop) {
1266
+ $$renderer3.push(`<!--[0--><button type="button" class="tab-stop svelte-r39acv"${$24.attr("disabled", isStopping(inst.id), true)}${$24.attr("title", isStopping(inst.id) ? "Stopping\u2026" : `Stop ${inst.name}`)}${$24.attr("aria-label", isStopping(inst.id) ? "Stopping\u2026" : `Stop ${inst.name}`)}>`);
1267
+ Circle_stop($$renderer3, { size: 20 });
1268
+ $$renderer3.push(`<!----></button>`);
1186
1269
  } else {
1187
1270
  $$renderer3.push("<!--[-1-->");
1188
1271
  }
1189
- $$renderer3.push(`<!--]--></button>`);
1272
+ $$renderer3.push(`<!--]-->`);
1190
1273
  }
1191
- $$renderer3.push(`<!--]-->`);
1274
+ $$renderer3.push(`<!--]--></div>`);
1192
1275
  }
1193
- $$renderer3.push(`<!--]--></div></div> `);
1276
+ $$renderer3.push(`<!--]--></nav></div> `);
1194
1277
  if (overflowing()) {
1195
- $$renderer3.push("<!--[0-->");
1196
- $$renderer3.push(`<button type="button" class="page trailing svelte-r39acv"${$23.attr("disabled", atEnd, true)} aria-label="Scroll tabs right">`);
1278
+ $$renderer3.push(`<!--[0--><button type="button" class="page trailing svelte-r39acv"${$24.attr("disabled", atEnd, true)} aria-label="Scroll tabs right">`);
1197
1279
  Chevron_right($$renderer3, { size: 16 });
1198
1280
  $$renderer3.push(`<!----></button>`);
1199
1281
  } else {
@@ -1205,48 +1287,56 @@ function IdeBar($$renderer, $$props) {
1205
1287
  }
1206
1288
  $$renderer3.push(`<!--]--> <div class="right svelte-r39acv">`);
1207
1289
  if (onreload) {
1208
- $$renderer3.push("<!--[0-->");
1209
- $$renderer3.push(`<button type="button" class="reload svelte-r39acv" title="Reload editor" aria-label="Reload editor">`);
1290
+ $$renderer3.push(`<!--[0--><button type="button" class="reload svelte-r39acv" title="Reload editor" aria-label="Reload editor">`);
1210
1291
  Rotate_cw($$renderer3, { size: 18 });
1211
1292
  $$renderer3.push(`<!----></button>`);
1212
1293
  } else {
1213
1294
  $$renderer3.push("<!--[-1-->");
1214
1295
  }
1215
- $$renderer3.push(`<!--]--> <a class="cog svelte-r39acv"${$23.attr("href", withPopupMarker("/settings"))} target="_blank" rel="noopener noreferrer" title="Settings" aria-label="Settings">`);
1296
+ $$renderer3.push(`<!--]--> <a class="cog svelte-r39acv"${$24.attr("href", withPopupMarker("/settings"))} target="_blank" rel="noopener noreferrer" title="Settings" aria-label="Settings">`);
1216
1297
  Settings($$renderer3, { size: 18 });
1217
1298
  $$renderer3.push(`<!----></a></div>`);
1218
1299
  },
1219
1300
  $$slots: { default: true }
1220
1301
  });
1221
- $23.bind_props($$props, { editingName });
1302
+ $$renderer2.push(`<!----> `);
1303
+ if (dropTarget) {
1304
+ $$renderer2.push(`<!--[0--><div class="drop-tip panel svelte-r39acv"${$24.attr_style("", {
1305
+ left: `${$24.stringify(tipLeft())}px`,
1306
+ top: `${$24.stringify(dropTarget.y)}px`
1307
+ })}>Drop to save into codebay-inbox/</div>`);
1308
+ } else {
1309
+ $$renderer2.push("<!--[-1-->");
1310
+ }
1311
+ $$renderer2.push(`<!--]-->`);
1312
+ $24.bind_props($$props, { editingName });
1222
1313
  });
1223
1314
  }
1224
1315
 
1225
1316
  // src/components/IdeLoader.svelte
1226
1317
  import"svelte/internal/flags/async";
1227
- import * as $24 from "svelte/internal/server";
1318
+ import * as $25 from "svelte/internal/server";
1228
1319
  function IdeLoader($$renderer, $$props) {
1229
1320
  $$renderer.component(($$renderer2) => {
1230
1321
  let { speed = 1, mode = "ide", stalledAfterMs, onoverride } = $$props;
1231
- const isTerminal = $24.derived(() => mode === "terminal");
1322
+ const isTerminal = $25.derived(() => mode === "terminal");
1232
1323
  let stalled = false;
1233
1324
  const ROWS = 3;
1234
1325
  const COLS = 22;
1235
1326
  const BASE_TICK_MS = 140;
1236
1327
  const FLIPS_PER_TICK = 7;
1237
- const tickMs = $24.derived(() => Math.max(20, BASE_TICK_MS / speed));
1328
+ const tickMs = $25.derived(() => Math.max(20, BASE_TICK_MS / speed));
1238
1329
  const seed = () => Array.from({ length: ROWS }, () => Array.from({ length: COLS }, () => Math.random() < 0.5 ? 0 : 1));
1239
1330
  let grid = seed();
1240
1331
  $$renderer2.push(`<div class="loader svelte-w5e143"><div class="grid svelte-w5e143" aria-hidden="true"><!--[-->`);
1241
- const each_array = $24.ensure_array_like(grid);
1332
+ const each_array = $25.ensure_array_like(grid);
1242
1333
  for (let i = 0, $$length = each_array.length;i < $$length; i++) {
1243
1334
  let row = each_array[i];
1244
- $$renderer2.push(`<div class="row svelte-w5e143">${$24.escape(row.join(""))}</div>`);
1335
+ $$renderer2.push(`<div class="row svelte-w5e143">${$25.escape(row.join(""))}</div>`);
1245
1336
  }
1246
- $$renderer2.push(`<!--]--></div> <div class="label svelte-w5e143">Loading ${$24.escape(isTerminal() ? "terminal" : "editor")}<span class="dot svelte-w5e143">.</span><span class="dot svelte-w5e143">.</span><span class="dot svelte-w5e143">.</span></div> `);
1337
+ $$renderer2.push(`<!--]--></div> <div class="label svelte-w5e143">Loading ${$25.escape(isTerminal() ? "terminal" : "editor")}<span class="dot svelte-w5e143">.</span><span class="dot svelte-w5e143">.</span><span class="dot svelte-w5e143">.</span></div> `);
1247
1338
  if (stalled) {
1248
- $$renderer2.push("<!--[0-->");
1249
- $$renderer2.push(`<div class="stalled svelte-w5e143"><p class="svelte-w5e143">Waiting for ${$24.escape(isTerminal() ? "the terminal" : "code-server")} to answer inside the container.</p> `);
1339
+ $$renderer2.push(`<!--[0--><div class="stalled svelte-w5e143"><p class="svelte-w5e143">Waiting for ${$25.escape(isTerminal() ? "the terminal" : "code-server")} to answer inside the container.</p> `);
1250
1340
  if (onoverride) {
1251
1341
  $$renderer2.push("<!--[0-->");
1252
1342
  Button($$renderer2, {
@@ -1270,42 +1360,67 @@ function IdeLoader($$renderer, $$props) {
1270
1360
 
1271
1361
  // src/components/TerminalSplit.svelte
1272
1362
  import"svelte/internal/flags/async";
1273
- import * as $28 from "svelte/internal/server";
1363
+ import * as $29 from "svelte/internal/server";
1274
1364
 
1275
1365
  // node_modules/@lucide/svelte/dist/icons/panel-right-open.svelte
1276
1366
  import"svelte/internal/flags/async";
1277
- import * as $25 from "svelte/internal/server";
1367
+ import * as $26 from "svelte/internal/server";
1278
1368
  function Panel_right_open($$renderer, $$props) {
1279
1369
  let { $$slots, $$events, ...props } = $$props;
1280
- const iconNode = [
1281
- [
1282
- "rect",
1283
- { width: "18", height: "18", x: "3", y: "3", rx: "2" }
1284
- ],
1285
- ["path", { d: "M15 3v18" }],
1286
- ["path", { d: "m10 15-3-3 3-3" }]
1287
- ];
1288
- Icon($$renderer, $25.spread_props([{ name: "panel-right-open" }, props, { iconNode }]));
1370
+ const iconData = {
1371
+ name: "panel-right-open",
1372
+ size: 24,
1373
+ node: [
1374
+ [
1375
+ "rect",
1376
+ { width: "18", height: "18", x: "3", y: "3", rx: "2" }
1377
+ ],
1378
+ ["path", { d: "M15 3v18" }],
1379
+ ["path", { d: "m10 15-3-3 3-3" }]
1380
+ ]
1381
+ };
1382
+ Icon($$renderer, $26.spread_props([props, { icon: iconData }]));
1289
1383
  }
1290
1384
  // node_modules/@lucide/svelte/dist/icons/panel-right-close.svelte
1291
1385
  import"svelte/internal/flags/async";
1292
- import * as $26 from "svelte/internal/server";
1386
+ import * as $27 from "svelte/internal/server";
1293
1387
  function Panel_right_close($$renderer, $$props) {
1294
1388
  let { $$slots, $$events, ...props } = $$props;
1295
- const iconNode = [
1296
- [
1297
- "rect",
1298
- { width: "18", height: "18", x: "3", y: "3", rx: "2" }
1299
- ],
1300
- ["path", { d: "M15 3v18" }],
1301
- ["path", { d: "m8 9 3 3-3 3" }]
1302
- ];
1303
- Icon($$renderer, $26.spread_props([{ name: "panel-right-close" }, props, { iconNode }]));
1389
+ const iconData = {
1390
+ name: "panel-right-close",
1391
+ size: 24,
1392
+ node: [
1393
+ [
1394
+ "rect",
1395
+ { width: "18", height: "18", x: "3", y: "3", rx: "2" }
1396
+ ],
1397
+ ["path", { d: "M15 3v18" }],
1398
+ ["path", { d: "m8 9 3 3-3 3" }]
1399
+ ]
1400
+ };
1401
+ Icon($$renderer, $27.spread_props([props, { icon: iconData }]));
1304
1402
  }
1305
1403
  // src/components/TerminalPane.svelte
1306
1404
  import"svelte/internal/flags/async";
1307
- import * as $27 from "svelte/internal/server";
1405
+ import * as $28 from "svelte/internal/server";
1308
1406
  import { onMount } from "svelte";
1407
+ // src/lib/osc52.ts
1408
+ function decodeOsc52(data) {
1409
+ const sep = data.indexOf(";");
1410
+ if (sep === -1)
1411
+ return null;
1412
+ const payload = data.slice(sep + 1).replace(/\s+/g, "");
1413
+ if (payload === "" || payload === "?")
1414
+ return null;
1415
+ try {
1416
+ const bytes = Uint8Array.from(atob(payload), (c) => c.charCodeAt(0));
1417
+ return new TextDecoder().decode(bytes);
1418
+ } catch {
1419
+ return null;
1420
+ }
1421
+ }
1422
+
1423
+ // src/components/TerminalPane.svelte
1309
1424
  function TerminalPane($$renderer, $$props) {
1310
1425
  $$renderer.component(($$renderer2) => {
1311
1426
  let { id, active, arg, focus = true, actions } = $$props;
@@ -1393,6 +1508,32 @@ function TerminalPane($$renderer, $$props) {
1393
1508
  start();
1394
1509
  }
1395
1510
  }
1511
+ async function toClipboard(text) {
1512
+ if (!text)
1513
+ return;
1514
+ try {
1515
+ await navigator.clipboard.writeText(text);
1516
+ return;
1517
+ } catch {}
1518
+ const ta = document.createElement("textarea");
1519
+ ta.value = text;
1520
+ ta.setAttribute("aria-hidden", "true");
1521
+ ta.style.position = "fixed";
1522
+ ta.style.opacity = "0";
1523
+ document.body.appendChild(ta);
1524
+ ta.select();
1525
+ try {
1526
+ document.execCommand("copy");
1527
+ } catch {}
1528
+ ta.remove();
1529
+ if (active && focus)
1530
+ term?.focus();
1531
+ }
1532
+ function copySelection() {
1533
+ const sel = term?.getSelection();
1534
+ if (sel)
1535
+ toClipboard(sel);
1536
+ }
1396
1537
  function fitSafe() {
1397
1538
  if (el?.clientWidth > 0 && el?.clientHeight > 0) {
1398
1539
  try {
@@ -1429,6 +1570,21 @@ function TerminalPane($$renderer, $$props) {
1429
1570
  term.open(el);
1430
1571
  applyTheme();
1431
1572
  fitSafe();
1573
+ term.parser.registerOscHandler(52, (data) => {
1574
+ const text = decodeOsc52(data);
1575
+ if (text !== null)
1576
+ toClipboard(text);
1577
+ return true;
1578
+ });
1579
+ term.attachCustomKeyEventHandler((e) => {
1580
+ if (e.type !== "keydown" || !term?.hasSelection())
1581
+ return true;
1582
+ const isCopy = e.ctrlKey && (e.key === "Insert" || e.altKey && e.key.toLowerCase() === "c");
1583
+ if (!isCopy)
1584
+ return true;
1585
+ copySelection();
1586
+ return false;
1587
+ });
1432
1588
  term.onData((d) => send(CMD_INPUT + d));
1433
1589
  term.onResize(({ cols, rows }) => send(CMD_RESIZE + JSON.stringify({ columns: cols, rows })));
1434
1590
  themeObs = new MutationObserver(applyTheme);
@@ -1439,8 +1595,10 @@ function TerminalPane($$renderer, $$props) {
1439
1595
  })();
1440
1596
  const sizeObs = new ResizeObserver(() => fitSafe());
1441
1597
  sizeObs.observe(el);
1598
+ el.addEventListener("mouseup", copySelection);
1442
1599
  return () => {
1443
1600
  disposed = true;
1601
+ el.removeEventListener("mouseup", copySelection);
1444
1602
  sizeObs.disconnect();
1445
1603
  themeObs?.disconnect();
1446
1604
  scheme.removeEventListener("change", onScheme);
@@ -1454,8 +1612,7 @@ function TerminalPane($$renderer, $$props) {
1454
1612
  });
1455
1613
  $$renderer2.push(`<div class="term svelte-ui3nvu"></div> <div class="overlay svelte-ui3nvu">`);
1456
1614
  if (!connected) {
1457
- $$renderer2.push("<!--[0-->");
1458
- $$renderer2.push(`<span class="status svelte-ui3nvu">connecting\u2026</span>`);
1615
+ $$renderer2.push(`<!--[0--><span class="status svelte-ui3nvu">connecting\u2026</span>`);
1459
1616
  } else {
1460
1617
  $$renderer2.push("<!--[-1-->");
1461
1618
  }
@@ -1509,7 +1666,7 @@ function TerminalSplit($$renderer, $$props) {
1509
1666
  e.preventDefault();
1510
1667
  }
1511
1668
  function splitToggle($$renderer3) {
1512
- $$renderer3.push(`<button type="button"${$28.attr("aria-pressed", open)}${$28.attr("title", open ? "Hide the shell pane" : "Open a shell alongside Claude")}${$28.attr("aria-label", open ? "Hide the shell pane" : "Open a shell alongside Claude")}>`);
1669
+ $$renderer3.push(`<button type="button"${$29.attr("aria-pressed", open)}${$29.attr("title", open ? "Hide the shell pane" : "Open a shell alongside Claude")}${$29.attr("aria-label", open ? "Hide the shell pane" : "Open a shell alongside Claude")}>`);
1513
1670
  if (open) {
1514
1671
  $$renderer3.push("<!--[0-->");
1515
1672
  Panel_right_close($$renderer3, { size: 14 });
@@ -1519,7 +1676,7 @@ function TerminalSplit($$renderer, $$props) {
1519
1676
  }
1520
1677
  $$renderer3.push(`<!--]--></button>`);
1521
1678
  }
1522
- $$renderer2.push(`<div class="split svelte-1ysvu88"><div class="side svelte-1ysvu88"${$28.attr_style("", { "flex-basis": open ? `${ratio}%` : "100%" })}>`);
1679
+ $$renderer2.push(`<div class="split svelte-1ysvu88"><div class="side svelte-1ysvu88"${$29.attr_style("", { "flex-basis": open ? `${ratio}%` : "100%" })}>`);
1523
1680
  TerminalPane($$renderer2, {
1524
1681
  id,
1525
1682
  active,
@@ -1528,8 +1685,7 @@ function TerminalSplit($$renderer, $$props) {
1528
1685
  });
1529
1686
  $$renderer2.push(`<!----></div> `);
1530
1687
  if (mounted) {
1531
- $$renderer2.push("<!--[0-->");
1532
- $$renderer2.push(`<div${$28.attr_class("divider svelte-1ysvu88", undefined, { hidden: !open })} role="separator" aria-orientation="vertical" aria-label="Resize terminal panes"${$28.attr("aria-valuenow", Math.round(ratio))}${$28.attr("aria-valuemin", 20)}${$28.attr("aria-valuemax", 80)} tabindex="0"></div> <div${$28.attr_class("side svelte-1ysvu88", undefined, { hidden: !open })}${$28.attr_style("", { "flex-basis": `${$28.stringify(100 - ratio)}%` })}>`);
1688
+ $$renderer2.push(`<!--[0--><div${$29.attr_class("divider svelte-1ysvu88", undefined, { hidden: !open })} role="separator" aria-orientation="vertical" aria-label="Resize terminal panes"${$29.attr("aria-valuenow", Math.round(ratio))}${$29.attr("aria-valuemin", 20)}${$29.attr("aria-valuemax", 80)} tabindex="0"></div> <div${$29.attr_class("side svelte-1ysvu88", undefined, { hidden: !open })}${$29.attr_style("", { "flex-basis": `${$29.stringify(100 - ratio)}%` })}>`);
1533
1689
  TerminalPane($$renderer2, {
1534
1690
  id,
1535
1691
  arg: "shell",
@@ -1554,10 +1710,22 @@ function AppShell($$renderer, $$props) {
1554
1710
  let livePet = pet;
1555
1711
  let liveFilter = filter;
1556
1712
  let loaded = snapshot.length > 0;
1557
- const running = $29.derived(() => instances.filter((i) => i.status === "running"));
1713
+ const running = $30.derived(() => instances.filter((i) => i.status === "running"));
1558
1714
  let attention = Object.fromEntries(snapshot.map((i) => [i.id, i.attention]));
1559
1715
  let editingId = null;
1560
1716
  let editingName = "";
1717
+ const stopping = new SvelteSet;
1718
+ async function stopTab(id) {
1719
+ if (stopping.has(id))
1720
+ return;
1721
+ stopping.add(id);
1722
+ try {
1723
+ await apiPost(`/api/instances/${id}/stop`, undefined, "Failed to stop instance");
1724
+ } catch (err) {
1725
+ dist_default.error(err.message);
1726
+ stopping.delete(id);
1727
+ }
1728
+ }
1561
1729
  function startRename(instance) {
1562
1730
  editingId = instance.id;
1563
1731
  editingName = instance.name;
@@ -1585,9 +1753,9 @@ function AppShell($$renderer, $$props) {
1585
1753
  apiPost("/api/settings/filter", { value: v }).catch(() => {});
1586
1754
  }
1587
1755
  let path = initialPath;
1588
- const onIde = $29.derived(() => path.startsWith("/ide"));
1589
- const requestedId = $29.derived(() => path.startsWith("/ide/") ? path.slice("/ide/".length) : "");
1590
- const active = $29.derived(() => onIde() ? running().some((i) => i.id === requestedId()) ? requestedId() : running()[0]?.id ?? "" : "");
1756
+ const onIde = $30.derived(() => path.startsWith("/ide"));
1757
+ const requestedId = $30.derived(() => path.startsWith("/ide/") ? path.slice("/ide/".length) : "");
1758
+ const active = $30.derived(() => onIde() ? running().some((i) => i.id === requestedId()) ? requestedId() : running()[0]?.id ?? "" : "");
1591
1759
  function navigate(to) {
1592
1760
  if (to === path)
1593
1761
  return;
@@ -1600,7 +1768,7 @@ function AppShell($$renderer, $$props) {
1600
1768
  const forced = new SvelteSet;
1601
1769
  const mountable = (id) => everReady.has(id) || forced.has(id);
1602
1770
  const STALLED_AFTER_MS = 1e4;
1603
- const activeInstance = $29.derived(() => running().find((i) => i.id === active()));
1771
+ const activeInstance = $30.derived(() => running().find((i) => i.id === active()));
1604
1772
  const frames = {};
1605
1773
  function reloadActive() {
1606
1774
  const inst = activeInstance();
@@ -1625,11 +1793,28 @@ function AppShell($$renderer, $$props) {
1625
1793
  if (fromFrame)
1626
1794
  tick2().then(() => frames[target.id]?.contentWindow?.focus());
1627
1795
  }
1628
- const framedTabIds = $29.derived(() => running().filter((i) => i.mode !== "terminal" && loadedFrames.has(i.id)).map((i) => i.id).join(" "));
1796
+ const framedTabIds = $30.derived(() => running().filter((i) => i.mode !== "terminal" && loadedFrames.has(i.id)).map((i) => i.id).join(" "));
1797
+ async function handleUpload(id, files) {
1798
+ for (const file of files) {
1799
+ try {
1800
+ const saved = await uploadFile(id, file);
1801
+ dist_default.success(`Saved ${saved.containerPath}`);
1802
+ navigator.clipboard.writeText(saved.containerPath).catch(() => {});
1803
+ } catch (err) {
1804
+ dist_default.error(err.message);
1805
+ }
1806
+ }
1807
+ }
1808
+ let dropping = false;
1809
+ function onDrop(e) {
1810
+ e.preventDefault();
1811
+ dropping = false;
1812
+ handleUpload(active(), filesFrom(e.dataTransfer));
1813
+ }
1629
1814
  let $$settled = true;
1630
1815
  let $$inner_renderer;
1631
1816
  function $$render_inner($$renderer3) {
1632
- $$renderer3.push(`<div${$29.attr_class("app svelte-1duc7gd", undefined, { ide: onIde() })}>`);
1817
+ $$renderer3.push(`<div${$30.attr_class("app svelte-1duc7gd", undefined, { ide: onIde() })}>`);
1633
1818
  if (onIde()) {
1634
1819
  $$renderer3.push("<!--[0-->");
1635
1820
  IdeBar($$renderer3, {
@@ -1637,8 +1822,11 @@ function AppShell($$renderer, $$props) {
1637
1822
  active: active(),
1638
1823
  attention,
1639
1824
  editingId,
1825
+ stopping: [...stopping],
1640
1826
  onreload: activeInstance() && activeInstance().mode !== "terminal" && mountable(active()) ? reloadActive : undefined,
1641
1827
  onselect: (id) => navigate(`/ide/${id}`),
1828
+ onstop: stopTab,
1829
+ ondropfiles: livePreflight.uploadEnabled ? (id, files) => void handleUpload(id, files) : undefined,
1642
1830
  onstartrename: startRename,
1643
1831
  oncommitrename: commitRename,
1644
1832
  oncancelrename: cancelRename,
@@ -1661,13 +1849,12 @@ function AppShell($$renderer, $$props) {
1661
1849
  onFilter: setFilter
1662
1850
  });
1663
1851
  }
1664
- $$renderer3.push(`<!--]--> <div${$29.attr_class("panes svelte-1duc7gd", undefined, { hidden: !onIde() })}><!--[-->`);
1665
- const each_array = $29.ensure_array_like(running());
1852
+ $$renderer3.push(`<!--]--> <div${$30.attr_class("panes svelte-1duc7gd", undefined, { hidden: !onIde() })}><!--[-->`);
1853
+ const each_array = $30.ensure_array_like(running());
1666
1854
  for (let $$index = 0, $$length = each_array.length;$$index < $$length; $$index++) {
1667
1855
  let inst = each_array[$$index];
1668
1856
  if (visited.has(inst.id)) {
1669
- $$renderer3.push("<!--[0-->");
1670
- $$renderer3.push(`<div${$29.attr_class("pane svelte-1duc7gd", undefined, { active: inst.id === active() })} role="tabpanel"${$29.attr("aria-labelledby", `tab-${$29.stringify(inst.id)}`)}>`);
1857
+ $$renderer3.push(`<!--[0--><div${$30.attr_class("pane svelte-1duc7gd", undefined, { active: inst.id === active() })} role="region"${$30.attr("aria-labelledby", `tab-${$30.stringify(inst.id)}`)}>`);
1671
1858
  if (mountable(inst.id)) {
1672
1859
  $$renderer3.push("<!--[0-->");
1673
1860
  if (inst.mode === "terminal") {
@@ -1678,8 +1865,7 @@ function AppShell($$renderer, $$props) {
1678
1865
  initialOpen: inst.terminal_split === 1
1679
1866
  });
1680
1867
  } else {
1681
- $$renderer3.push("<!--[-1-->");
1682
- $$renderer3.push(`<iframe${$29.attr("src", ideUrl(inst))}${$29.attr("title", inst.name)} class="svelte-1duc7gd" onload="this.__e=event"></iframe>`);
1868
+ $$renderer3.push(`<!--[-1--><iframe${$30.attr("src", ideUrl(inst))}${$30.attr("title", inst.name)} allow="clipboard-read; clipboard-write" class="svelte-1duc7gd" onload="this.__e=event"></iframe>`);
1683
1869
  }
1684
1870
  $$renderer3.push(`<!--]-->`);
1685
1871
  } else {
@@ -1699,6 +1885,13 @@ function AppShell($$renderer, $$props) {
1699
1885
  } else {
1700
1886
  $$renderer3.push("<!--[-1-->");
1701
1887
  }
1888
+ $$renderer3.push(`<!--]--> `);
1889
+ if (dropping && inst.id === active() && inst.mode === "terminal") {
1890
+ $$renderer3.push("<!--[0-->");
1891
+ DropZone($$renderer3, { ondrop: onDrop });
1892
+ } else {
1893
+ $$renderer3.push("<!--[-1-->");
1894
+ }
1702
1895
  $$renderer3.push(`<!--]--></div>`);
1703
1896
  } else {
1704
1897
  $$renderer3.push("<!--[-1-->");
@@ -1707,8 +1900,7 @@ function AppShell($$renderer, $$props) {
1707
1900
  }
1708
1901
  $$renderer3.push(`<!--]--> `);
1709
1902
  if (onIde() && running().length === 0) {
1710
- $$renderer3.push("<!--[0-->");
1711
- $$renderer3.push(`<div class="empty svelte-1duc7gd">No running instances.</div>`);
1903
+ $$renderer3.push(`<!--[0--><div class="empty svelte-1duc7gd">No running instances.</div>`);
1712
1904
  } else {
1713
1905
  $$renderer3.push("<!--[-1-->");
1714
1906
  }
@@ -1730,28 +1922,30 @@ function App($$renderer, $$props) {
1730
1922
  $$renderer.component(($$renderer2) => {
1731
1923
  let { preflight, initialPath, snapshot, pet, filter } = $$props;
1732
1924
  if (true) {
1733
- let failed = function($$renderer3, error) {
1734
- $$renderer3.push(`<mochi-island-failure data-component="AppShell"${$30.attr("data-message", error.message)}></mochi-island-failure>`);
1735
- };
1736
1925
  $$renderer2.push("<!--[0-->");
1737
- $$renderer2.boundary({ failed }, ($$renderer3) => {
1738
- $$renderer3.push(`<!--[-->`);
1739
- {
1740
- HydratableBoundary($$renderer3, {
1741
- children: ($$renderer4) => {
1742
- $$renderer4.push(`<mochi-hydratable-island component-name="AppShell_2rtnxn6pgp2rh" component-url="__MOCHI_COMPONENT_URL__AppShell_2rtnxn6pgp2rh__"${$30.attr("props-ref", emitIslandProps({ preflight, initialPath, snapshot, pet, filter }))}>`);
1743
- $$renderer4.push(`<!--[-->`);
1744
- {
1745
- AppShell($$renderer4, { preflight, initialPath, snapshot, pet, filter });
1746
- }
1747
- $$renderer4.push(`<!--]-->`);
1748
- $$renderer4.push(`</mochi-hydratable-island>`);
1749
- },
1750
- $$slots: { default: true }
1751
- });
1752
- }
1753
- $$renderer3.push(`<!--]-->`);
1754
- });
1926
+ {
1927
+ let failed = function($$renderer3, error) {
1928
+ $$renderer3.push(`<mochi-island-failure data-component="AppShell"${$31.attr("data-message", error.message)}></mochi-island-failure>`);
1929
+ };
1930
+ $$renderer2.boundary({ failed }, ($$renderer3) => {
1931
+ $$renderer3.push(`<!--[-->`);
1932
+ {
1933
+ HydratableBoundary($$renderer3, {
1934
+ children: ($$renderer4) => {
1935
+ $$renderer4.push(`<mochi-hydratable-island component-name="AppShell_2rtnxn6pgp2rh" component-url="__MOCHI_COMPONENT_URL__AppShell_2rtnxn6pgp2rh__"${$31.attr("props-ref", emitIslandProps({ preflight, initialPath, snapshot, pet, filter }))}>`);
1936
+ $$renderer4.push(`<!--[-->`);
1937
+ {
1938
+ AppShell($$renderer4, { preflight, initialPath, snapshot, pet, filter });
1939
+ }
1940
+ $$renderer4.push(`<!--]-->`);
1941
+ $$renderer4.push(`</mochi-hydratable-island>`);
1942
+ },
1943
+ $$slots: { default: true }
1944
+ });
1945
+ }
1946
+ $$renderer3.push(`<!--]-->`);
1947
+ });
1948
+ }
1755
1949
  }
1756
1950
  $$renderer2.push(`<!--]-->`);
1757
1951
  });