codebay 0.9.0 → 0.10.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 (78) hide show
  1. package/.mochi/manifest.json +216 -149
  2. package/.mochi/svelte-client/HydratableIsland-aebn1fa1.js +1 -0
  3. package/.mochi/svelte-client/_hydrate-AppShell_2rtnxn6pgp2rh-rx6arrv5.js +2 -0
  4. package/.mochi/svelte-client/{_hydrate-AvatarsView_257s9yq1wwr4f-92hepzby.js → _hydrate-AvatarsView_257s9yq1wwr4f-jpjdmgpe.js} +1 -1
  5. package/.mochi/svelte-client/_hydrate-InstanceView_2ma45l9bybfhl-c9y47dat.js +1 -0
  6. package/.mochi/svelte-client/_hydrate-SettingsView_8hmarwmf8onq-d61feq89.js +38 -0
  7. package/.mochi/svelte-client/{chunk-2j95sv83.js → chunk-0fjx3z3r.js} +1 -1
  8. package/.mochi/svelte-client/chunk-8xvr02wh.js +2 -0
  9. package/.mochi/svelte-client/{chunk-m497q88s.js → chunk-9143wy3j.js} +2 -2
  10. package/.mochi/svelte-client/{chunk-v65n8th6.js → chunk-bn731rda.js} +1 -1
  11. package/.mochi/svelte-client/{chunk-a2psjmrm.js → chunk-j72r8pkk.js} +2 -2
  12. package/.mochi/svelte-client/chunk-k37wj1jm.js +2 -0
  13. package/.mochi/svelte-client/{chunk-mpv3qx28.js → chunk-p20tkpde.js} +1 -1
  14. package/.mochi/svelte-client/chunk-pc0fm37c.js +2 -0
  15. package/.mochi/svelte-client/{chunk-6rbs0mhx.js → chunk-t0ap7q89.js} +1 -1
  16. package/.mochi/svelte-client/{chunk-rs41by6w.js → chunk-wvtkwfsh.js} +1 -1
  17. package/.mochi/svelte-compile/{App-7vjcp38v.server.js → App-59cdj86f.server.js} +167 -103
  18. package/.mochi/svelte-compile/{Avatars-e2cfc95t.server.js → Avatars-fmagfyj2.server.js} +1 -1
  19. package/.mochi/svelte-compile/{Instance-h78n2dsv.server.js → Instance-s1gqwzmx.server.js} +16 -10
  20. package/.mochi/svelte-compile/{Settings-tav2asn7.server.js → Settings-k447mt0x.server.js} +540 -88
  21. package/.mochi/svelte-compile/{chunk-brjv9pyd.js → chunk-3t7v4hk0.js} +1 -7
  22. package/.mochi/svelte-compile/chunk-gkjgybb2.js +15 -0
  23. package/.mochi/svelte-compile/{chunk-m8ygpyhr.js → chunk-th2dbqvc.js} +20 -32
  24. package/.mochi/svelte-css/Button-oharop2xz6am.css +1 -0
  25. package/.mochi/svelte-css/IdeBar-3bgr3m5z0lpeg.css +1 -0
  26. package/.mochi/svelte-css/{InstanceView-3vzow3ttxzlh3.css → InstanceView-1pd7j16bd2b16.css} +1 -1
  27. package/.mochi/svelte-css/SettingsView-n3oy75uonzp2.css +1 -0
  28. package/.mochi/svelte-css/{TopBar-2q87li6yt8ids.css → TopBar-2y76zxwehrfos.css} +1 -1
  29. package/migrations/0007_instance_avatar.sql +1 -0
  30. package/package.json +2 -2
  31. package/src/avatars/diamond.ts +5 -6
  32. package/src/avatars/index.ts +1 -16
  33. package/src/avatars/pick.server.ts +25 -0
  34. package/src/avatars/whale.ts +7 -8
  35. package/src/components/AppShell.svelte +29 -4
  36. package/src/components/Avatar.svelte +8 -8
  37. package/src/components/Button.svelte +22 -1
  38. package/src/components/DashboardView.svelte +14 -2
  39. package/src/components/FolderBrowser.svelte +6 -2
  40. package/src/components/IdeBar.svelte +56 -13
  41. package/src/components/IdeLoader.svelte +15 -3
  42. package/src/components/InstanceCard.svelte +6 -1
  43. package/src/components/InstanceView.svelte +33 -15
  44. package/src/components/SettingsView.svelte +548 -1
  45. package/src/components/TopBar.svelte +37 -10
  46. package/src/components/UiShowcase.svelte +5 -10
  47. package/src/container-injections/claude-aliases.ts +1 -1
  48. package/src/container-injections/claude-code-custom.ts +2 -1
  49. package/src/container-injections/claude-code-ide-extension.ts +5 -0
  50. package/src/container-injections/claude-code-install.ts +67 -0
  51. package/src/container-injections/claude-code-models.ts +2 -1
  52. package/src/container-injections/claude-code-update.ts +62 -1
  53. package/src/container-injections/claude-effort-level.ts +32 -0
  54. package/src/container-injections/claude-permission-mode.ts +40 -0
  55. package/src/container-injections/custom-env-vars.ts +82 -0
  56. package/src/container-injections/host-env-vars.ts +2 -1
  57. package/src/lib/config.server.ts +3 -0
  58. package/src/lib/db.server.ts +8 -3
  59. package/src/lib/devcontainer.server.ts +182 -47
  60. package/src/lib/health.server.ts +55 -11
  61. package/src/lib/injections.server.ts +46 -36
  62. package/src/lib/instances.server.ts +185 -19
  63. package/src/lib/log-capture.server.ts +262 -0
  64. package/src/lib/ports.server.ts +31 -0
  65. package/src/lib/proxy.server.ts +21 -76
  66. package/src/pages/Settings.svelte +22 -1
  67. package/src/routes.ts +98 -2
  68. package/src/types.ts +36 -0
  69. package/.mochi/svelte-client/HydratableIsland-k6q8esj4.js +0 -1
  70. package/.mochi/svelte-client/_hydrate-AppShell_2rtnxn6pgp2rh-sg96rp17.js +0 -2
  71. package/.mochi/svelte-client/_hydrate-InstanceView_2ma45l9bybfhl-p3f649gk.js +0 -1
  72. package/.mochi/svelte-client/_hydrate-SettingsView_8hmarwmf8onq-dzmgmv78.js +0 -29
  73. package/.mochi/svelte-client/chunk-7wkvn2vx.js +0 -2
  74. package/.mochi/svelte-client/chunk-m4fzsd5b.js +0 -2
  75. package/.mochi/svelte-css/Button-2vtbrzb5kgu25.css +0 -1
  76. package/.mochi/svelte-css/IdeBar-10xodudcx57qr.css +0 -1
  77. package/.mochi/svelte-css/SettingsView-2qfauz68axro1.css +0 -1
  78. package/src/container-injections/claude-skip-permissions.ts +0 -28
@@ -4,21 +4,24 @@ import {
4
4
  apiDelete,
5
5
  apiFetch,
6
6
  apiPost,
7
- forwardedPortUrl,
8
- ideUrl
9
- } from "./chunk-brjv9pyd.js";
7
+ forwardedPortUrl
8
+ } from "./chunk-3t7v4hk0.js";
10
9
  import {
11
10
  Layout_template,
12
11
  Plus,
13
12
  Terminal
14
13
  } from "./chunk-bpqwf1nw.js";
14
+ import {
15
+ ideUrl
16
+ } from "./chunk-gkjgybb2.js";
15
17
  import {
16
18
  AppBar,
17
19
  Avatar,
18
20
  Button,
19
21
  Toaster,
20
- dist_default
21
- } from "./chunk-m8ygpyhr.js";
22
+ dist_default,
23
+ findAvatar
24
+ } from "./chunk-th2dbqvc.js";
22
25
  import {
23
26
  HydratableBoundary,
24
27
  Icon,
@@ -167,8 +170,8 @@ function Triangle_alert($$renderer, $$props) {
167
170
  // src/components/FolderBrowser.svelte
168
171
  function FolderBrowser($$renderer, $$props) {
169
172
  $$renderer.component(($$renderer2) => {
170
- let { onpick, onclose, defaultMode = "ide" } = $$props;
171
- let modeOverride = null;
173
+ let { onpick, onclose, defaultMode = "ide", initialMode = null } = $$props;
174
+ let modeOverride = initialMode;
172
175
  const mode = $6.derived(() => modeOverride ?? defaultMode);
173
176
  let result = null;
174
177
  let loading = true;
@@ -407,7 +410,11 @@ function InstanceCard($$renderer, $$props) {
407
410
  $$renderer2.push("<!--[-1-->");
408
411
  }
409
412
  $$renderer2.push(`<!--]--> <div class="card-head svelte-13338y7">`);
410
- Avatar($$renderer2, { id: instance.id, name: instance.name, interactive: true });
413
+ Avatar($$renderer2, {
414
+ name: instance.name,
415
+ art: findAvatar(instance.avatar ?? undefined) ?? null,
416
+ interactive: true
417
+ });
411
418
  $$renderer2.push(`<!----> `);
412
419
  if (editing) {
413
420
  $$renderer2.push("<!--[0-->");
@@ -733,69 +740,86 @@ function CredMenu($$renderer, $$props) {
733
740
 
734
741
  // src/components/TopBar.svelte
735
742
  function TopBar($$renderer, $$props) {
736
- let {
737
- auth,
738
- pet,
739
- canDelete = false,
740
- ready = true,
741
- creating = false,
742
- filter,
743
- onFilter,
744
- onNew,
745
- onDeleteAll
746
- } = $$props;
747
- $$renderer.push(`<header class="topbar svelte-1h259us">`);
748
- Brand($$renderer, { pet });
749
- $$renderer.push(`<!----> <div class="topbar-actions svelte-1h259us">`);
750
- if (isDev) {
751
- $$renderer.push("<!--[0-->");
752
- Button($$renderer, {
753
- variant: "default",
743
+ $$renderer.component(($$renderer2) => {
744
+ let {
745
+ auth,
746
+ pet,
747
+ canDelete = false,
748
+ ready = true,
749
+ creating = false,
750
+ filter,
751
+ defaultMode = "ide",
752
+ onFilter,
753
+ onNew,
754
+ onDeleteAll
755
+ } = $$props;
756
+ const altMode = $19.derived(() => defaultMode === "terminal" ? "ide" : "terminal");
757
+ $$renderer2.push(`<header class="topbar svelte-1h259us">`);
758
+ Brand($$renderer2, { pet });
759
+ $$renderer2.push(`<!----> <div class="topbar-actions svelte-1h259us">`);
760
+ if (isDev) {
761
+ $$renderer2.push("<!--[0-->");
762
+ Button($$renderer2, {
763
+ variant: "default",
764
+ size: "sm",
765
+ icon: Component,
766
+ href: "/debug",
767
+ children: ($$renderer3) => {
768
+ $$renderer3.push(`<!---->Debug`);
769
+ },
770
+ $$slots: { default: true }
771
+ });
772
+ } else {
773
+ $$renderer2.push("<!--[-1-->");
774
+ }
775
+ $$renderer2.push(`<!--]--> `);
776
+ if (filter && onFilter) {
777
+ $$renderer2.push("<!--[0-->");
778
+ InstanceFilter($$renderer2, { value: filter, onchange: onFilter });
779
+ } else {
780
+ $$renderer2.push("<!--[-1-->");
781
+ }
782
+ $$renderer2.push(`<!--]--> `);
783
+ SettingsCog($$renderer2, {});
784
+ $$renderer2.push(`<!----> `);
785
+ CredMenu($$renderer2, { auth });
786
+ $$renderer2.push(`<!----> `);
787
+ Button($$renderer2, {
788
+ variant: "danger",
754
789
  size: "sm",
755
- icon: Component,
756
- href: "/debug",
757
- children: ($$renderer2) => {
758
- $$renderer2.push(`<!---->Debug`);
790
+ onclick: onDeleteAll,
791
+ disabled: !canDelete,
792
+ children: ($$renderer3) => {
793
+ $$renderer3.push(`<!---->Delete all`);
759
794
  },
760
795
  $$slots: { default: true }
761
796
  });
762
- } else {
763
- $$renderer.push("<!--[-1-->");
764
- }
765
- $$renderer.push(`<!--]--> `);
766
- if (filter && onFilter) {
767
- $$renderer.push("<!--[0-->");
768
- InstanceFilter($$renderer, { value: filter, onchange: onFilter });
769
- } else {
770
- $$renderer.push("<!--[-1-->");
771
- }
772
- $$renderer.push(`<!--]--> `);
773
- SettingsCog($$renderer, {});
774
- $$renderer.push(`<!----> `);
775
- CredMenu($$renderer, { auth });
776
- $$renderer.push(`<!----> `);
777
- Button($$renderer, {
778
- variant: "danger",
779
- size: "sm",
780
- onclick: onDeleteAll,
781
- disabled: !canDelete,
782
- children: ($$renderer2) => {
783
- $$renderer2.push(`<!---->Delete all`);
784
- },
785
- $$slots: { default: true }
786
- });
787
- $$renderer.push(`<!----> `);
788
- Button($$renderer, {
789
- variant: "primary",
790
- icon: creating ? undefined : Plus,
791
- onclick: onNew,
792
- disabled: !ready || creating,
793
- children: ($$renderer2) => {
794
- $$renderer2.push(`<!---->${$19.escape(creating ? "Creating\u2026" : "New instance")}`);
795
- },
796
- $$slots: { default: true }
797
+ $$renderer2.push(`<!----> <div class="new-group svelte-1h259us">`);
798
+ Button($$renderer2, {
799
+ variant: "primary",
800
+ size: "sm",
801
+ icon: creating ? undefined : Plus,
802
+ onclick: () => onNew?.(),
803
+ disabled: !ready || creating,
804
+ children: ($$renderer3) => {
805
+ $$renderer3.push(`<!---->${$19.escape(creating ? "Creating\u2026" : "New instance")}`);
806
+ },
807
+ $$slots: { default: true }
808
+ });
809
+ $$renderer2.push(`<!----> `);
810
+ Button($$renderer2, {
811
+ variant: "primary",
812
+ size: "sm",
813
+ square: true,
814
+ icon: altMode() === "terminal" ? Terminal : Layout_template,
815
+ iconSize: 15,
816
+ onclick: () => onNew?.(altMode()),
817
+ disabled: !ready || creating,
818
+ title: altMode() === "terminal" ? "New terminal instance" : "New full IDE instance",
819
+ "aria-label": altMode() === "terminal" ? "New terminal instance" : "New full IDE instance"
820
+ });
821
+ $$renderer2.push(`<!----></div></div></header>`);
797
822
  });
798
- $$renderer.push(`<!----></div></header>`);
799
823
  }
800
824
 
801
825
  // src/components/DashboardView.svelte
@@ -803,6 +827,7 @@ function DashboardView($$renderer, $$props) {
803
827
  $$renderer.component(($$renderer2) => {
804
828
  let { preflight, instances, loaded, pet, filter, onFilter } = $$props;
805
829
  let browserOpen = false;
830
+ let browserMode = null;
806
831
  let creating = false;
807
832
  let actionError = null;
808
833
  let editingId = null;
@@ -892,7 +917,11 @@ function DashboardView($$renderer, $$props) {
892
917
  creating,
893
918
  filter,
894
919
  onFilter,
895
- onNew: () => browserOpen = true,
920
+ defaultMode: preflight.defaultMode,
921
+ onNew: (mode) => {
922
+ browserMode = mode ?? null;
923
+ browserOpen = true;
924
+ },
896
925
  onDeleteAll: deleteAll
897
926
  });
898
927
  $$renderer3.push(`<!----> <main class="stage svelte-146pixd">`);
@@ -975,6 +1004,7 @@ function DashboardView($$renderer, $$props) {
975
1004
  FolderBrowser($$renderer3, {
976
1005
  onpick: createFrom,
977
1006
  defaultMode: preflight.defaultMode,
1007
+ initialMode: browserMode,
978
1008
  onclose: () => browserOpen = false
979
1009
  });
980
1010
  } else {
@@ -993,7 +1023,23 @@ function DashboardView($$renderer, $$props) {
993
1023
 
994
1024
  // src/components/IdeBar.svelte
995
1025
  import"svelte/internal/flags/async";
1026
+ import * as $22 from "svelte/internal/server";
1027
+
1028
+ // node_modules/@lucide/svelte/dist/icons/rotate-cw.svelte
1029
+ import"svelte/internal/flags/async";
996
1030
  import * as $21 from "svelte/internal/server";
1031
+ function Rotate_cw($$renderer, $$props) {
1032
+ let { $$slots, $$events, ...props } = $$props;
1033
+ const iconNode = [
1034
+ [
1035
+ "path",
1036
+ { d: "M21 12a9 9 0 1 1-9-9c2.52 0 4.93 1 6.74 2.74L21 8" }
1037
+ ],
1038
+ ["path", { d: "M21 3v5h-5" }]
1039
+ ];
1040
+ Icon($$renderer, $21.spread_props([{ name: "rotate-cw" }, props, { iconNode }]));
1041
+ }
1042
+ // src/components/IdeBar.svelte
997
1043
  function IdeBar($$renderer, $$props) {
998
1044
  $$renderer.component(($$renderer2) => {
999
1045
  let {
@@ -1002,6 +1048,7 @@ function IdeBar($$renderer, $$props) {
1002
1048
  attention,
1003
1049
  editingId,
1004
1050
  editingName = undefined,
1051
+ onreload,
1005
1052
  onselect,
1006
1053
  onstartrename,
1007
1054
  oncommitrename,
@@ -1012,10 +1059,10 @@ function IdeBar($$renderer, $$props) {
1012
1059
  if (running.length > 0) {
1013
1060
  $$renderer3.push("<!--[0-->");
1014
1061
  $$renderer3.push(`<nav class="tabs svelte-r39acv"><!--[-->`);
1015
- const each_array = $21.ensure_array_like(running);
1062
+ const each_array = $22.ensure_array_like(running);
1016
1063
  for (let $$index = 0, $$length = each_array.length;$$index < $$length; $$index++) {
1017
1064
  let inst = each_array[$$index];
1018
- $$renderer3.push(`<div${$21.attr_class("tab svelte-r39acv", undefined, {
1065
+ $$renderer3.push(`<div${$22.attr_class("tab svelte-r39acv", undefined, {
1019
1066
  active: inst.id === active,
1020
1067
  "attn-done": inst.id !== active && attention[inst.id] === "done",
1021
1068
  "attn-waiting": inst.id !== active && attention[inst.id] === "waiting"
@@ -1023,13 +1070,21 @@ function IdeBar($$renderer, $$props) {
1023
1070
  if (editingId === inst.id) {
1024
1071
  $$renderer3.push("<!--[0-->");
1025
1072
  $$renderer3.push(`<div class="tab-label editing svelte-r39acv">`);
1026
- Avatar($$renderer3, { id: inst.id, name: inst.name, scale: 4 });
1027
- $$renderer3.push(`<!----> <input class="tab-name-edit svelte-r39acv"${$21.attr("value", editingName)} autofocus=""/></div>`);
1073
+ Avatar($$renderer3, {
1074
+ name: inst.name,
1075
+ art: findAvatar(inst.avatar ?? undefined) ?? null,
1076
+ scale: 4
1077
+ });
1078
+ $$renderer3.push(`<!----> <input class="tab-name-edit svelte-r39acv"${$22.attr("value", editingName)} autofocus=""/></div>`);
1028
1079
  } else {
1029
1080
  $$renderer3.push("<!--[-1-->");
1030
- $$renderer3.push(`<button type="button" class="tab-label svelte-r39acv"${$21.attr("title", inst.name)}>`);
1031
- Avatar($$renderer3, { id: inst.id, name: inst.name, scale: 4 });
1032
- $$renderer3.push(`<!----> <span class="tab-name svelte-r39acv">${$21.escape(inst.name)}</span> `);
1081
+ $$renderer3.push(`<button type="button" class="tab-label svelte-r39acv"${$22.attr("title", inst.name)}>`);
1082
+ Avatar($$renderer3, {
1083
+ name: inst.name,
1084
+ art: findAvatar(inst.avatar ?? undefined) ?? null,
1085
+ scale: 4
1086
+ });
1087
+ $$renderer3.push(`<!----> <span class="tab-name svelte-r39acv">${$22.escape(inst.name)}</span> `);
1033
1088
  if (inst.mode === "terminal") {
1034
1089
  $$renderer3.push("<!--[0-->");
1035
1090
  $$renderer3.push(`<span class="tab-mode svelte-r39acv" title="Terminal-only instance">`);
@@ -1037,6 +1092,9 @@ function IdeBar($$renderer, $$props) {
1037
1092
  $$renderer3.push(`<!----></span>`);
1038
1093
  } else {
1039
1094
  $$renderer3.push("<!--[-1-->");
1095
+ $$renderer3.push(`<span class="tab-mode svelte-r39acv" title="Full IDE instance">`);
1096
+ Layout_template($$renderer3, { size: 13 });
1097
+ $$renderer3.push(`<!----></span>`);
1040
1098
  }
1041
1099
  $$renderer3.push(`<!--]--></button>`);
1042
1100
  }
@@ -1046,40 +1104,50 @@ function IdeBar($$renderer, $$props) {
1046
1104
  } else {
1047
1105
  $$renderer3.push("<!--[-1-->");
1048
1106
  }
1049
- $$renderer3.push(`<!--]--> <a class="cog svelte-r39acv"${$21.attr("href", withPopupMarker("/settings"))} target="_blank" rel="noopener noreferrer" title="Settings" aria-label="Settings">`);
1107
+ $$renderer3.push(`<!--]--> <div class="right svelte-r39acv">`);
1108
+ if (onreload) {
1109
+ $$renderer3.push("<!--[0-->");
1110
+ $$renderer3.push(`<button type="button" class="reload svelte-r39acv" title="Reload editor" aria-label="Reload editor">`);
1111
+ Rotate_cw($$renderer3, { size: 18 });
1112
+ $$renderer3.push(`<!----></button>`);
1113
+ } else {
1114
+ $$renderer3.push("<!--[-1-->");
1115
+ }
1116
+ $$renderer3.push(`<!--]--> <a class="cog svelte-r39acv"${$22.attr("href", withPopupMarker("/settings"))} target="_blank" rel="noopener noreferrer" title="Settings" aria-label="Settings">`);
1050
1117
  Settings($$renderer3, { size: 18 });
1051
- $$renderer3.push(`<!----></a>`);
1118
+ $$renderer3.push(`<!----></a></div>`);
1052
1119
  },
1053
1120
  $$slots: { default: true }
1054
1121
  });
1055
- $21.bind_props($$props, { editingName });
1122
+ $22.bind_props($$props, { editingName });
1056
1123
  });
1057
1124
  }
1058
1125
 
1059
1126
  // src/components/IdeLoader.svelte
1060
1127
  import"svelte/internal/flags/async";
1061
- import * as $22 from "svelte/internal/server";
1128
+ import * as $23 from "svelte/internal/server";
1062
1129
  function IdeLoader($$renderer, $$props) {
1063
1130
  $$renderer.component(($$renderer2) => {
1064
- let { speed = 1, stalledAfterMs, onoverride } = $$props;
1131
+ let { speed = 1, mode = "ide", stalledAfterMs, onoverride } = $$props;
1132
+ const isTerminal = $23.derived(() => mode === "terminal");
1065
1133
  let stalled = false;
1066
1134
  const ROWS = 3;
1067
1135
  const COLS = 22;
1068
1136
  const BASE_TICK_MS = 140;
1069
1137
  const FLIPS_PER_TICK = 7;
1070
- const tickMs = $22.derived(() => Math.max(20, BASE_TICK_MS / speed));
1138
+ const tickMs = $23.derived(() => Math.max(20, BASE_TICK_MS / speed));
1071
1139
  const seed = () => Array.from({ length: ROWS }, () => Array.from({ length: COLS }, () => Math.random() < 0.5 ? 0 : 1));
1072
1140
  let grid = seed();
1073
1141
  $$renderer2.push(`<div class="loader svelte-w5e143"><div class="grid svelte-w5e143" aria-hidden="true"><!--[-->`);
1074
- const each_array = $22.ensure_array_like(grid);
1142
+ const each_array = $23.ensure_array_like(grid);
1075
1143
  for (let i = 0, $$length = each_array.length;i < $$length; i++) {
1076
1144
  let row = each_array[i];
1077
- $$renderer2.push(`<div class="row svelte-w5e143">${$22.escape(row.join(""))}</div>`);
1145
+ $$renderer2.push(`<div class="row svelte-w5e143">${$23.escape(row.join(""))}</div>`);
1078
1146
  }
1079
- $$renderer2.push(`<!--]--></div> <div class="label svelte-w5e143">Loading editor<span class="dot svelte-w5e143">.</span><span class="dot svelte-w5e143">.</span><span class="dot svelte-w5e143">.</span></div> `);
1147
+ $$renderer2.push(`<!--]--></div> <div class="label svelte-w5e143">Loading ${$23.escape(isTerminal() ? "terminal" : "editor")}<span class="dot svelte-w5e143">.</span><span class="dot svelte-w5e143">.</span><span class="dot svelte-w5e143">.</span></div> `);
1080
1148
  if (stalled) {
1081
1149
  $$renderer2.push("<!--[0-->");
1082
- $$renderer2.push(`<div class="stalled svelte-w5e143"><p class="svelte-w5e143">Waiting for code-server to answer inside the container.</p> `);
1150
+ $$renderer2.push(`<div class="stalled svelte-w5e143"><p class="svelte-w5e143">Waiting for ${$23.escape(isTerminal() ? "the terminal" : "code-server")} to answer inside the container.</p> `);
1083
1151
  if (onoverride) {
1084
1152
  $$renderer2.push("<!--[0-->");
1085
1153
  Button($$renderer2, {
@@ -1107,7 +1175,7 @@ import * as $27 from "svelte/internal/server";
1107
1175
 
1108
1176
  // node_modules/@lucide/svelte/dist/icons/panel-right-open.svelte
1109
1177
  import"svelte/internal/flags/async";
1110
- import * as $23 from "svelte/internal/server";
1178
+ import * as $24 from "svelte/internal/server";
1111
1179
  function Panel_right_open($$renderer, $$props) {
1112
1180
  let { $$slots, $$events, ...props } = $$props;
1113
1181
  const iconNode = [
@@ -1118,11 +1186,11 @@ function Panel_right_open($$renderer, $$props) {
1118
1186
  ["path", { d: "M15 3v18" }],
1119
1187
  ["path", { d: "m10 15-3-3 3-3" }]
1120
1188
  ];
1121
- Icon($$renderer, $23.spread_props([{ name: "panel-right-open" }, props, { iconNode }]));
1189
+ Icon($$renderer, $24.spread_props([{ name: "panel-right-open" }, props, { iconNode }]));
1122
1190
  }
1123
1191
  // node_modules/@lucide/svelte/dist/icons/panel-right-close.svelte
1124
1192
  import"svelte/internal/flags/async";
1125
- import * as $24 from "svelte/internal/server";
1193
+ import * as $25 from "svelte/internal/server";
1126
1194
  function Panel_right_close($$renderer, $$props) {
1127
1195
  let { $$slots, $$events, ...props } = $$props;
1128
1196
  const iconNode = [
@@ -1133,27 +1201,12 @@ function Panel_right_close($$renderer, $$props) {
1133
1201
  ["path", { d: "M15 3v18" }],
1134
1202
  ["path", { d: "m8 9 3 3-3 3" }]
1135
1203
  ];
1136
- Icon($$renderer, $24.spread_props([{ name: "panel-right-close" }, props, { iconNode }]));
1204
+ Icon($$renderer, $25.spread_props([{ name: "panel-right-close" }, props, { iconNode }]));
1137
1205
  }
1138
1206
  // src/components/TerminalPane.svelte
1139
1207
  import"svelte/internal/flags/async";
1140
1208
  import * as $26 from "svelte/internal/server";
1141
1209
  import { onMount } from "svelte";
1142
- // node_modules/@lucide/svelte/dist/icons/rotate-cw.svelte
1143
- import"svelte/internal/flags/async";
1144
- import * as $25 from "svelte/internal/server";
1145
- function Rotate_cw($$renderer, $$props) {
1146
- let { $$slots, $$events, ...props } = $$props;
1147
- const iconNode = [
1148
- [
1149
- "path",
1150
- { d: "M21 12a9 9 0 1 1-9-9c2.52 0 4.93 1 6.74 2.74L21 8" }
1151
- ],
1152
- ["path", { d: "M21 3v5h-5" }]
1153
- ];
1154
- Icon($$renderer, $25.spread_props([{ name: "rotate-cw" }, props, { iconNode }]));
1155
- }
1156
- // src/components/TerminalPane.svelte
1157
1210
  function TerminalPane($$renderer, $$props) {
1158
1211
  $$renderer.component(($$renderer2) => {
1159
1212
  let { id, active, arg, focus = true, actions } = $$props;
@@ -1444,6 +1497,15 @@ function AppShell($$renderer, $$props) {
1444
1497
  const forced = new SvelteSet;
1445
1498
  const mountable = (id) => everReady.has(id) || forced.has(id);
1446
1499
  const STALLED_AFTER_MS = 1e4;
1500
+ const activeInstance = $28.derived(() => running().find((i) => i.id === active()));
1501
+ const frames = {};
1502
+ function reloadActive() {
1503
+ const inst = activeInstance();
1504
+ if (!inst || inst.mode === "terminal")
1505
+ return;
1506
+ loadedFrames.delete(inst.id);
1507
+ frames[inst.id]?.contentWindow?.location.replace(ideUrl(inst));
1508
+ }
1447
1509
  let $$settled = true;
1448
1510
  let $$inner_renderer;
1449
1511
  function $$render_inner($$renderer3) {
@@ -1455,6 +1517,7 @@ function AppShell($$renderer, $$props) {
1455
1517
  active: active(),
1456
1518
  attention,
1457
1519
  editingId,
1520
+ onreload: activeInstance() && activeInstance().mode !== "terminal" && mountable(active()) ? reloadActive : undefined,
1458
1521
  onselect: (id) => navigate(`/ide/${id}`),
1459
1522
  onstartrename: startRename,
1460
1523
  oncommitrename: commitRename,
@@ -1506,6 +1569,7 @@ function AppShell($$renderer, $$props) {
1506
1569
  if (!mountable(inst.id)) {
1507
1570
  $$renderer3.push("<!--[0-->");
1508
1571
  IdeLoader($$renderer3, {
1572
+ mode: inst.mode,
1509
1573
  stalledAfterMs: STALLED_AFTER_MS,
1510
1574
  onoverride: () => forced.add(inst.id)
1511
1575
  });
@@ -15,7 +15,7 @@ import {
15
15
  avatars,
16
16
  decode,
17
17
  dist_default
18
- } from "./chunk-m8ygpyhr.js";
18
+ } from "./chunk-th2dbqvc.js";
19
19
  import {
20
20
  HydratableBoundary,
21
21
  Icon,
@@ -3,9 +3,11 @@ import {
3
3
  StatusBadge,
4
4
  apiDelete,
5
5
  apiPost,
6
- forwardedPortUrl,
6
+ forwardedPortUrl
7
+ } from "./chunk-3t7v4hk0.js";
8
+ import {
7
9
  ideUrl
8
- } from "./chunk-brjv9pyd.js";
10
+ } from "./chunk-gkjgybb2.js";
9
11
  import {
10
12
  HydratableBoundary,
11
13
  Icon,
@@ -153,17 +155,14 @@ function InstanceView($$renderer, $$props) {
153
155
  let logs = "";
154
156
  let logEl = null;
155
157
  let following = true;
156
- function onLogScroll() {
157
- if (!logEl)
158
- return;
159
- const gap = logEl.scrollHeight - logEl.clientHeight - logEl.scrollTop;
160
- if (gap > 40)
161
- following = false;
158
+ async function scrollToBottom() {
159
+ await tick();
160
+ logEl?.scrollTo(0, logEl.scrollHeight);
162
161
  }
163
162
  function toggleFollow() {
164
163
  following = !following;
165
164
  if (following)
166
- logEl?.scrollTo(0, logEl.scrollHeight);
165
+ scrollToBottom();
167
166
  }
168
167
  const url = $6.derived(() => instance ? ideUrl(instance) : "#");
169
168
  let newPort = "";
@@ -324,7 +323,14 @@ function InstanceView($$renderer, $$props) {
324
323
  } else {
325
324
  $$renderer2.push("<!--[-1-->");
326
325
  }
327
- $$renderer2.push(`<!--]--> <p class="hint svelte-15fxkvm">Your app must bind to <code class="svelte-15fxkvm">0.0.0.0</code> inside the container to be reachable.</p></div></section> <div class="logwrap panel svelte-15fxkvm"><div class="log-bar panel-bar svelte-15fxkvm"><span class="svelte-15fxkvm">Boot log</span> <div class="log-actions svelte-15fxkvm"><button${$6.attr_class("copy svelte-15fxkvm", undefined, { active: following })}>${$6.escape(following ? "Following" : "Follow log")}</button> <button class="copy svelte-15fxkvm"${$6.attr("disabled", !logs, true)}>${$6.escape(copied ? "Copied!" : "Copy logs")}</button></div></div> <div class="logs svelte-15fxkvm"><pre class="svelte-15fxkvm">${$6.escape(logs || "Waiting for output\u2026")}<span class="caret svelte-15fxkvm"></span></pre></div> `);
326
+ $$renderer2.push(`<!--]--> <p class="hint svelte-15fxkvm">Your app must bind to <code class="svelte-15fxkvm">0.0.0.0</code> inside the container to be reachable.</p></div></section> <div class="logwrap panel svelte-15fxkvm"><div class="log-bar panel-bar svelte-15fxkvm"><span class="svelte-15fxkvm">Boot log</span> <div class="log-actions svelte-15fxkvm"><button${$6.attr_class("copy svelte-15fxkvm", undefined, { active: following })}${$6.attr("aria-pressed", following)}${$6.attr("title", following ? "Following \u2014 click to pause" : "Paused \u2014 click to follow new output")}>`);
327
+ if (following) {
328
+ $$renderer2.push("<!--[0-->");
329
+ $$renderer2.push(`<span class="dot svelte-15fxkvm"></span>`);
330
+ } else {
331
+ $$renderer2.push("<!--[-1-->");
332
+ }
333
+ $$renderer2.push(`<!--]--> ${$6.escape(following ? "Following" : "Follow log")}</button> <button class="copy svelte-15fxkvm"${$6.attr("disabled", !logs, true)}>${$6.escape(copied ? "Copied!" : "Copy logs")}</button></div></div> <div class="logs svelte-15fxkvm"><pre class="svelte-15fxkvm">${$6.escape(logs || "Waiting for output\u2026")}<span class="caret svelte-15fxkvm"></span></pre></div> `);
328
334
  if (instance?.status === "error" && instance.error) {
329
335
  $$renderer2.push("<!--[0-->");
330
336
  $$renderer2.push(`<div class="err svelte-15fxkvm">${$6.escape(instance.error)}</div>`);