codebay 0.8.0 → 0.9.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.
- package/.mochi/import-css/xterm-1yy1hf1g.css +252 -0
- package/.mochi/manifest.json +330 -211
- package/.mochi/svelte-client/HydratableIsland-k6q8esj4.js +1 -0
- package/.mochi/svelte-client/_hydrate-AppShell_2rtnxn6pgp2rh-sg96rp17.js +2 -0
- package/.mochi/svelte-client/_hydrate-AvatarsView_257s9yq1wwr4f-92hepzby.js +14 -0
- package/.mochi/svelte-client/_hydrate-InstanceView_2ma45l9bybfhl-p3f649gk.js +1 -0
- package/.mochi/svelte-client/_hydrate-SettingsView_8hmarwmf8onq-dzmgmv78.js +29 -0
- package/.mochi/svelte-client/chunk-2j95sv83.js +1 -0
- package/.mochi/svelte-client/chunk-6rbs0mhx.js +1 -0
- package/.mochi/svelte-client/chunk-7wkvn2vx.js +2 -0
- package/.mochi/svelte-client/chunk-a2psjmrm.js +2 -0
- package/.mochi/svelte-client/chunk-m497q88s.js +2 -0
- package/.mochi/svelte-client/{chunk-fqg2qzj8.js → chunk-m4fzsd5b.js} +1 -1
- package/.mochi/svelte-client/chunk-mpv3qx28.js +36 -0
- package/.mochi/svelte-client/chunk-rs41by6w.js +2 -0
- package/.mochi/svelte-client/{chunk-qj7zy2d9.js → chunk-v65n8th6.js} +4 -4
- package/.mochi/svelte-compile/{App-6rcf0d74.server.js → App-7vjcp38v.server.js} +368 -37
- package/.mochi/svelte-compile/{Avatars-pzyz0tv3.server.js → Avatars-e2cfc95t.server.js} +130 -25
- package/.mochi/svelte-compile/{ClientStats-z3tn9ad6.server.js → ClientStats-4cphmrnp.server.js} +1 -1
- package/.mochi/svelte-compile/{DefaultError-wh77vebf.server.js → DefaultError-je52k17d.server.js} +1 -1
- package/.mochi/svelte-compile/{Instance-49ksrp11.server.js → Instance-h78n2dsv.server.js} +16 -13
- package/.mochi/svelte-compile/{Settings-sz5d6qj7.server.js → Settings-tav2asn7.server.js} +153 -127
- package/.mochi/svelte-compile/{chunk-fpe16ywq.js → chunk-60mpagr9.js} +17 -7
- package/.mochi/svelte-compile/chunk-9nqc2r0y.js +9706 -0
- package/.mochi/svelte-compile/{chunk-6ghzacpg.js → chunk-bpqwf1nw.js} +36 -4
- package/.mochi/svelte-compile/chunk-jx6h1xzp.js +20 -0
- package/.mochi/svelte-compile/{chunk-q8rbesaw.js → chunk-m8ygpyhr.js} +5 -4
- package/.mochi/svelte-compile/chunk-rtdne1m8.js +31 -0
- package/.mochi/svelte-compile/{chunk-we0ggtws.js → chunk-xpt1a7jm.js} +2 -1
- package/.mochi/svelte-css/AvatarEditor-2mdq8ss346drw.css +1 -0
- package/.mochi/svelte-css/{AvatarsView-2ughbzc26luyb.css → AvatarsView-2llo48w0wt0xn.css} +1 -1
- package/.mochi/svelte-css/FolderBrowser-2pxp9z1o7zixk.css +1 -0
- package/.mochi/svelte-css/{IdeBar-2qoqi2ya9zdn3.css → IdeBar-10xodudcx57qr.css} +1 -1
- package/.mochi/svelte-css/{SettingsView-3uycxa8z548m4.css → SettingsView-2qfauz68axro1.css} +1 -1
- package/.mochi/svelte-css/TerminalPane-3bwgk6ulzq6b3.css +1 -0
- package/.mochi/svelte-css/TerminalSplit-2416xfuln89a3.css +1 -0
- package/migrations/0005_instance_mode.sql +1 -0
- package/migrations/0006_terminal_split.sql +1 -0
- package/package.json +3 -1
- package/src/avatars/serialize.ts +35 -6
- package/src/components/AppShell.svelte +46 -8
- package/src/components/Avatar.svelte +3 -2
- package/src/components/AvatarEditor.svelte +96 -19
- package/src/components/AvatarsView.svelte +0 -0
- package/src/components/DashboardView.svelte +22 -7
- package/src/components/FolderBrowser.svelte +88 -8
- package/src/components/HealthBox.svelte +12 -5
- package/src/components/IdeBar.svelte +10 -0
- package/src/components/InstanceCard.svelte +3 -1
- package/src/components/InstanceView.svelte +1 -0
- package/src/components/SettingsView.svelte +108 -0
- package/src/components/TerminalPane.svelte +274 -0
- package/src/components/TerminalSplit.svelte +154 -0
- package/src/container-injections/claude-code-ide-extension.ts +2 -0
- package/src/container-injections/ttyd.ts +49 -0
- package/src/lib/config.server.ts +3 -0
- package/src/lib/db.server.ts +14 -4
- package/src/lib/devcontainer.server.ts +136 -22
- package/src/lib/health.server.ts +1 -1
- package/src/lib/injections.server.ts +15 -5
- package/src/lib/instances.server.ts +64 -10
- package/src/lib/proxy.server.ts +87 -11
- package/src/pages/App.svelte +5 -3
- package/src/pages/Settings.svelte +4 -0
- package/src/routes.ts +55 -6
- package/src/types.ts +18 -0
- package/.mochi/svelte-client/HydratableIsland-qyjx1d98.js +0 -1
- package/.mochi/svelte-client/_hydrate-AppShell_2rtnxn6pgp2rh-fkna7bj2.js +0 -2
- package/.mochi/svelte-client/_hydrate-AvatarsView_257s9yq1wwr4f-89wtkb86.js +0 -13
- package/.mochi/svelte-client/_hydrate-InstanceView_2ma45l9bybfhl-eamnbyqk.js +0 -1
- package/.mochi/svelte-client/_hydrate-SettingsView_8hmarwmf8onq-kdra4mcb.js +0 -28
- package/.mochi/svelte-client/chunk-330mrspw.js +0 -2
- package/.mochi/svelte-client/chunk-4jgkak13.js +0 -1
- package/.mochi/svelte-client/chunk-k5m4kt20.js +0 -2
- package/.mochi/svelte-client/chunk-rpdphch7.js +0 -2
- package/.mochi/svelte-compile/chunk-bacb4b0r.js +0 -14
- package/.mochi/svelte-css/AvatarEditor-2ewwtejaml4e2.css +0 -1
- package/.mochi/svelte-css/FolderBrowser-1x428zb3f2kti.css +0 -1
- /package/.mochi/svelte-compile/{chunk-btmcxhqy.js → chunk-brjv9pyd.js} +0 -0
|
@@ -6,36 +6,38 @@ import {
|
|
|
6
6
|
apiPost,
|
|
7
7
|
forwardedPortUrl,
|
|
8
8
|
ideUrl
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-brjv9pyd.js";
|
|
10
10
|
import {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
} from "./chunk-bacb4b0r.js";
|
|
11
|
+
Layout_template,
|
|
12
|
+
Plus,
|
|
13
|
+
Terminal
|
|
14
|
+
} from "./chunk-bpqwf1nw.js";
|
|
16
15
|
import {
|
|
17
16
|
AppBar,
|
|
18
17
|
Avatar,
|
|
19
18
|
Button,
|
|
20
19
|
Toaster,
|
|
21
20
|
dist_default
|
|
22
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-m8ygpyhr.js";
|
|
23
22
|
import {
|
|
24
23
|
HydratableBoundary,
|
|
25
24
|
Icon,
|
|
25
|
+
X,
|
|
26
26
|
emitIslandProps,
|
|
27
27
|
isDev,
|
|
28
28
|
withPopupMarker
|
|
29
|
-
} from "./chunk-
|
|
30
|
-
import
|
|
29
|
+
} from "./chunk-60mpagr9.js";
|
|
30
|
+
import {
|
|
31
|
+
__require
|
|
32
|
+
} from "./chunk-xpt1a7jm.js";
|
|
31
33
|
|
|
32
34
|
// src/pages/App.svelte
|
|
33
35
|
import"svelte/internal/flags/async";
|
|
34
|
-
import * as $
|
|
36
|
+
import * as $29 from "svelte/internal/server";
|
|
35
37
|
|
|
36
38
|
// src/components/AppShell.svelte
|
|
37
39
|
import"svelte/internal/flags/async";
|
|
38
|
-
import * as $
|
|
40
|
+
import * as $28 from "svelte/internal/server";
|
|
39
41
|
import { SvelteSet } from "svelte/reactivity";
|
|
40
42
|
|
|
41
43
|
// src/components/DashboardView.svelte
|
|
@@ -165,7 +167,9 @@ function Triangle_alert($$renderer, $$props) {
|
|
|
165
167
|
// src/components/FolderBrowser.svelte
|
|
166
168
|
function FolderBrowser($$renderer, $$props) {
|
|
167
169
|
$$renderer.component(($$renderer2) => {
|
|
168
|
-
let { onpick, onclose } = $$props;
|
|
170
|
+
let { onpick, onclose, defaultMode = "ide" } = $$props;
|
|
171
|
+
let modeOverride = null;
|
|
172
|
+
const mode = $6.derived(() => modeOverride ?? defaultMode);
|
|
169
173
|
let result = null;
|
|
170
174
|
let loading = true;
|
|
171
175
|
let errorMsg = null;
|
|
@@ -179,7 +183,7 @@ function FolderBrowser($$renderer, $$props) {
|
|
|
179
183
|
function cloneRepoUrl() {
|
|
180
184
|
if (!repoValid())
|
|
181
185
|
return;
|
|
182
|
-
onpick(repoUrl.trim(), { branch: repoBranch.trim() || undefined });
|
|
186
|
+
onpick(repoUrl.trim(), { branch: repoBranch.trim() || undefined, mode: mode() });
|
|
183
187
|
}
|
|
184
188
|
const filtered = $6.derived(() => result ? result.entries.filter((e) => e.name.toLowerCase().includes(query.trim().toLowerCase())) : []);
|
|
185
189
|
const shownHistory = $6.derived(() => showAll ? history2 : history2.slice(0, 5));
|
|
@@ -215,7 +219,11 @@ function FolderBrowser($$renderer, $$props) {
|
|
|
215
219
|
}
|
|
216
220
|
$$renderer2.push(`<div class="overlay svelte-oq97c4" role="button" tabindex="0"><div class="modal panel svelte-oq97c4" role="dialog" aria-modal="true" aria-label="Pick a project folder" tabindex="-1"><div class="head svelte-oq97c4"><h2 class="svelte-oq97c4">Pick a project folder</h2> <button class="x svelte-oq97c4" aria-label="Close">`);
|
|
217
221
|
X($$renderer2, { size: 16 });
|
|
218
|
-
$$renderer2.push(`<!----></button></div> <div class="
|
|
222
|
+
$$renderer2.push(`<!----></button></div> <div class="mode svelte-oq97c4"><div class="mode-label svelte-oq97c4">Editor</div> <div class="mode-toggle svelte-oq97c4" role="group" aria-label="Editor mode"><button type="button"${$6.attr_class("mode-btn svelte-oq97c4", undefined, { active: mode() === "ide" })}${$6.attr("aria-pressed", mode() === "ide")}>`);
|
|
223
|
+
Layout_template($$renderer2, { size: 15 });
|
|
224
|
+
$$renderer2.push(`<!----> Full IDE</button> <button type="button"${$6.attr_class("mode-btn svelte-oq97c4", undefined, { active: mode() === "terminal" })}${$6.attr("aria-pressed", mode() === "terminal")}>`);
|
|
225
|
+
Terminal($$renderer2, { size: 15 });
|
|
226
|
+
$$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(result?.path ?? "\u2026")}</code></div> `);
|
|
219
227
|
if (history2.length > 0) {
|
|
220
228
|
$$renderer2.push("<!--[0-->");
|
|
221
229
|
$$renderer2.push(`<div class="recent svelte-oq97c4"><div class="recent-label svelte-oq97c4">Recent</div> <!--[-->`);
|
|
@@ -449,7 +457,7 @@ function InstanceCard($$renderer, $$props) {
|
|
|
449
457
|
size: "sm",
|
|
450
458
|
href: `/ide/${instance.id}`,
|
|
451
459
|
children: ($$renderer3) => {
|
|
452
|
-
$$renderer3.push(
|
|
460
|
+
$$renderer3.push(`<!---->${$10.escape(instance.mode === "terminal" ? "Open terminal" : "Open IDE")}`);
|
|
453
461
|
},
|
|
454
462
|
$$slots: { default: true }
|
|
455
463
|
});
|
|
@@ -793,9 +801,8 @@ function TopBar($$renderer, $$props) {
|
|
|
793
801
|
// src/components/DashboardView.svelte
|
|
794
802
|
function DashboardView($$renderer, $$props) {
|
|
795
803
|
$$renderer.component(($$renderer2) => {
|
|
796
|
-
let { preflight, instances, loaded, pet } = $$props;
|
|
804
|
+
let { preflight, instances, loaded, pet, filter, onFilter } = $$props;
|
|
797
805
|
let browserOpen = false;
|
|
798
|
-
let filter = "all";
|
|
799
806
|
let creating = false;
|
|
800
807
|
let actionError = null;
|
|
801
808
|
let editingId = null;
|
|
@@ -818,7 +825,7 @@ function DashboardView($$renderer, $$props) {
|
|
|
818
825
|
creating = true;
|
|
819
826
|
actionError = null;
|
|
820
827
|
try {
|
|
821
|
-
await apiPost("/api/instances", { sourcePath, branch: opts?.branch }, "Failed to create instance");
|
|
828
|
+
await apiPost("/api/instances", { sourcePath, branch: opts?.branch, mode: opts?.mode }, "Failed to create instance");
|
|
822
829
|
} catch (err) {
|
|
823
830
|
actionError = err.message;
|
|
824
831
|
} finally {
|
|
@@ -884,7 +891,7 @@ function DashboardView($$renderer, $$props) {
|
|
|
884
891
|
ready: ready(),
|
|
885
892
|
creating,
|
|
886
893
|
filter,
|
|
887
|
-
onFilter
|
|
894
|
+
onFilter,
|
|
888
895
|
onNew: () => browserOpen = true,
|
|
889
896
|
onDeleteAll: deleteAll
|
|
890
897
|
});
|
|
@@ -965,7 +972,11 @@ function DashboardView($$renderer, $$props) {
|
|
|
965
972
|
$$renderer3.push(`<!--]--></main> `);
|
|
966
973
|
if (browserOpen) {
|
|
967
974
|
$$renderer3.push("<!--[0-->");
|
|
968
|
-
FolderBrowser($$renderer3, {
|
|
975
|
+
FolderBrowser($$renderer3, {
|
|
976
|
+
onpick: createFrom,
|
|
977
|
+
defaultMode: preflight.defaultMode,
|
|
978
|
+
onclose: () => browserOpen = false
|
|
979
|
+
});
|
|
969
980
|
} else {
|
|
970
981
|
$$renderer3.push("<!--[-1-->");
|
|
971
982
|
}
|
|
@@ -1018,7 +1029,16 @@ function IdeBar($$renderer, $$props) {
|
|
|
1018
1029
|
$$renderer3.push("<!--[-1-->");
|
|
1019
1030
|
$$renderer3.push(`<button type="button" class="tab-label svelte-r39acv"${$21.attr("title", inst.name)}>`);
|
|
1020
1031
|
Avatar($$renderer3, { id: inst.id, name: inst.name, scale: 4 });
|
|
1021
|
-
$$renderer3.push(`<!----> <span class="tab-name svelte-r39acv">${$21.escape(inst.name)}</span
|
|
1032
|
+
$$renderer3.push(`<!----> <span class="tab-name svelte-r39acv">${$21.escape(inst.name)}</span> `);
|
|
1033
|
+
if (inst.mode === "terminal") {
|
|
1034
|
+
$$renderer3.push("<!--[0-->");
|
|
1035
|
+
$$renderer3.push(`<span class="tab-mode svelte-r39acv" title="Terminal-only instance">`);
|
|
1036
|
+
Terminal($$renderer3, { size: 13 });
|
|
1037
|
+
$$renderer3.push(`<!----></span>`);
|
|
1038
|
+
} else {
|
|
1039
|
+
$$renderer3.push("<!--[-1-->");
|
|
1040
|
+
}
|
|
1041
|
+
$$renderer3.push(`<!--]--></button>`);
|
|
1022
1042
|
}
|
|
1023
1043
|
$$renderer3.push(`<!--]--></div>`);
|
|
1024
1044
|
}
|
|
@@ -1081,15 +1101,304 @@ function IdeLoader($$renderer, $$props) {
|
|
|
1081
1101
|
});
|
|
1082
1102
|
}
|
|
1083
1103
|
|
|
1104
|
+
// src/components/TerminalSplit.svelte
|
|
1105
|
+
import"svelte/internal/flags/async";
|
|
1106
|
+
import * as $27 from "svelte/internal/server";
|
|
1107
|
+
|
|
1108
|
+
// node_modules/@lucide/svelte/dist/icons/panel-right-open.svelte
|
|
1109
|
+
import"svelte/internal/flags/async";
|
|
1110
|
+
import * as $23 from "svelte/internal/server";
|
|
1111
|
+
function Panel_right_open($$renderer, $$props) {
|
|
1112
|
+
let { $$slots, $$events, ...props } = $$props;
|
|
1113
|
+
const iconNode = [
|
|
1114
|
+
[
|
|
1115
|
+
"rect",
|
|
1116
|
+
{ width: "18", height: "18", x: "3", y: "3", rx: "2" }
|
|
1117
|
+
],
|
|
1118
|
+
["path", { d: "M15 3v18" }],
|
|
1119
|
+
["path", { d: "m10 15-3-3 3-3" }]
|
|
1120
|
+
];
|
|
1121
|
+
Icon($$renderer, $23.spread_props([{ name: "panel-right-open" }, props, { iconNode }]));
|
|
1122
|
+
}
|
|
1123
|
+
// node_modules/@lucide/svelte/dist/icons/panel-right-close.svelte
|
|
1124
|
+
import"svelte/internal/flags/async";
|
|
1125
|
+
import * as $24 from "svelte/internal/server";
|
|
1126
|
+
function Panel_right_close($$renderer, $$props) {
|
|
1127
|
+
let { $$slots, $$events, ...props } = $$props;
|
|
1128
|
+
const iconNode = [
|
|
1129
|
+
[
|
|
1130
|
+
"rect",
|
|
1131
|
+
{ width: "18", height: "18", x: "3", y: "3", rx: "2" }
|
|
1132
|
+
],
|
|
1133
|
+
["path", { d: "M15 3v18" }],
|
|
1134
|
+
["path", { d: "m8 9 3 3-3 3" }]
|
|
1135
|
+
];
|
|
1136
|
+
Icon($$renderer, $24.spread_props([{ name: "panel-right-close" }, props, { iconNode }]));
|
|
1137
|
+
}
|
|
1138
|
+
// src/components/TerminalPane.svelte
|
|
1139
|
+
import"svelte/internal/flags/async";
|
|
1140
|
+
import * as $26 from "svelte/internal/server";
|
|
1141
|
+
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
|
+
function TerminalPane($$renderer, $$props) {
|
|
1158
|
+
$$renderer.component(($$renderer2) => {
|
|
1159
|
+
let { id, active, arg, focus = true, actions } = $$props;
|
|
1160
|
+
let el;
|
|
1161
|
+
let term;
|
|
1162
|
+
let fit;
|
|
1163
|
+
let ws;
|
|
1164
|
+
let retry;
|
|
1165
|
+
let disposed = false;
|
|
1166
|
+
let connected = false;
|
|
1167
|
+
let gen = 0;
|
|
1168
|
+
const CMD_INPUT = "0";
|
|
1169
|
+
const CMD_RESIZE = "1";
|
|
1170
|
+
const OUTPUT = 48;
|
|
1171
|
+
const encoder = new TextEncoder;
|
|
1172
|
+
function send(data) {
|
|
1173
|
+
if (ws?.readyState === WebSocket.OPEN)
|
|
1174
|
+
ws.send(encoder.encode(data));
|
|
1175
|
+
}
|
|
1176
|
+
function onFrame(data) {
|
|
1177
|
+
const bytes = new Uint8Array(data);
|
|
1178
|
+
if (bytes.length === 0)
|
|
1179
|
+
return;
|
|
1180
|
+
if (bytes[0] === OUTPUT)
|
|
1181
|
+
term?.write(bytes.subarray(1));
|
|
1182
|
+
}
|
|
1183
|
+
function connect() {
|
|
1184
|
+
const myGen = ++gen;
|
|
1185
|
+
const proto = location.protocol === "https:" ? "wss:" : "ws:";
|
|
1186
|
+
const query = arg ? `?arg=${encodeURIComponent(arg)}` : "";
|
|
1187
|
+
const sock = new WebSocket(`${proto}//${location.host}/p/${id}/ws${query}`, ["tty"]);
|
|
1188
|
+
ws = sock;
|
|
1189
|
+
sock.binaryType = "arraybuffer";
|
|
1190
|
+
sock.onopen = () => {
|
|
1191
|
+
if (gen !== myGen)
|
|
1192
|
+
return;
|
|
1193
|
+
connected = true;
|
|
1194
|
+
send(JSON.stringify({
|
|
1195
|
+
AuthToken: "",
|
|
1196
|
+
columns: term?.cols ?? 80,
|
|
1197
|
+
rows: term?.rows ?? 24
|
|
1198
|
+
}));
|
|
1199
|
+
};
|
|
1200
|
+
sock.onmessage = (e) => {
|
|
1201
|
+
if (gen === myGen)
|
|
1202
|
+
onFrame(e.data);
|
|
1203
|
+
};
|
|
1204
|
+
sock.onclose = () => {
|
|
1205
|
+
if (gen !== myGen || disposed)
|
|
1206
|
+
return;
|
|
1207
|
+
connected = false;
|
|
1208
|
+
retry = setTimeout(connect, 1000);
|
|
1209
|
+
};
|
|
1210
|
+
sock.onerror = () => {
|
|
1211
|
+
try {
|
|
1212
|
+
sock.close();
|
|
1213
|
+
} catch {}
|
|
1214
|
+
};
|
|
1215
|
+
}
|
|
1216
|
+
function reload() {
|
|
1217
|
+
if (retry)
|
|
1218
|
+
clearTimeout(retry);
|
|
1219
|
+
gen++;
|
|
1220
|
+
connected = false;
|
|
1221
|
+
term?.reset();
|
|
1222
|
+
const old = ws;
|
|
1223
|
+
ws = undefined;
|
|
1224
|
+
let started = false;
|
|
1225
|
+
const start = () => {
|
|
1226
|
+
if (started || disposed)
|
|
1227
|
+
return;
|
|
1228
|
+
started = true;
|
|
1229
|
+
fitSafe();
|
|
1230
|
+
connect();
|
|
1231
|
+
if (active && focus)
|
|
1232
|
+
term?.focus();
|
|
1233
|
+
};
|
|
1234
|
+
if (old && old.readyState !== WebSocket.CLOSED) {
|
|
1235
|
+
old.addEventListener("close", start, { once: true });
|
|
1236
|
+
setTimeout(start, 1500);
|
|
1237
|
+
try {
|
|
1238
|
+
old.close();
|
|
1239
|
+
} catch {}
|
|
1240
|
+
} else {
|
|
1241
|
+
start();
|
|
1242
|
+
}
|
|
1243
|
+
}
|
|
1244
|
+
function fitSafe() {
|
|
1245
|
+
if (el?.clientWidth > 0 && el?.clientHeight > 0) {
|
|
1246
|
+
try {
|
|
1247
|
+
fit?.fit();
|
|
1248
|
+
} catch {}
|
|
1249
|
+
}
|
|
1250
|
+
}
|
|
1251
|
+
function applyTheme() {
|
|
1252
|
+
if (!term)
|
|
1253
|
+
return;
|
|
1254
|
+
const cs = getComputedStyle(document.documentElement);
|
|
1255
|
+
const bg = cs.getPropertyValue("--bg").trim() || "#1a1a1a";
|
|
1256
|
+
const fg = cs.getPropertyValue("--ink").trim() || "#e6e6e6";
|
|
1257
|
+
term.options.theme = { background: bg, foreground: fg, cursor: fg, cursorAccent: bg };
|
|
1258
|
+
}
|
|
1259
|
+
onMount(() => {
|
|
1260
|
+
let themeObs;
|
|
1261
|
+
(async () => {
|
|
1262
|
+
const [{ Terminal: Terminal2 }, { FitAddon }] = await Promise.all([import("./chunk-9nqc2r0y.js"), import("./chunk-rtdne1m8.js")]);
|
|
1263
|
+
if (disposed)
|
|
1264
|
+
return;
|
|
1265
|
+
term = new Terminal2({
|
|
1266
|
+
fontFamily: "'JetBrains Mono Variable', ui-monospace, monospace",
|
|
1267
|
+
fontSize: 13,
|
|
1268
|
+
cursorBlink: true,
|
|
1269
|
+
scrollback: 1e4,
|
|
1270
|
+
allowProposedApi: true
|
|
1271
|
+
});
|
|
1272
|
+
fit = new FitAddon;
|
|
1273
|
+
term.loadAddon(fit);
|
|
1274
|
+
term.open(el);
|
|
1275
|
+
applyTheme();
|
|
1276
|
+
fitSafe();
|
|
1277
|
+
term.onData((d) => send(CMD_INPUT + d));
|
|
1278
|
+
term.onResize(({ cols, rows }) => send(CMD_RESIZE + JSON.stringify({ columns: cols, rows })));
|
|
1279
|
+
themeObs = new MutationObserver(applyTheme);
|
|
1280
|
+
themeObs.observe(document.documentElement, { attributes: true, attributeFilter: ["data-theme"] });
|
|
1281
|
+
connect();
|
|
1282
|
+
if (active && focus)
|
|
1283
|
+
term.focus();
|
|
1284
|
+
})();
|
|
1285
|
+
const sizeObs = new ResizeObserver(() => fitSafe());
|
|
1286
|
+
sizeObs.observe(el);
|
|
1287
|
+
return () => {
|
|
1288
|
+
disposed = true;
|
|
1289
|
+
sizeObs.disconnect();
|
|
1290
|
+
themeObs?.disconnect();
|
|
1291
|
+
if (retry)
|
|
1292
|
+
clearTimeout(retry);
|
|
1293
|
+
try {
|
|
1294
|
+
ws?.close();
|
|
1295
|
+
} catch {}
|
|
1296
|
+
term?.dispose();
|
|
1297
|
+
};
|
|
1298
|
+
});
|
|
1299
|
+
$$renderer2.push(`<div class="term svelte-ui3nvu"></div> <div class="overlay svelte-ui3nvu">`);
|
|
1300
|
+
if (!connected) {
|
|
1301
|
+
$$renderer2.push("<!--[0-->");
|
|
1302
|
+
$$renderer2.push(`<span class="status svelte-ui3nvu">connecting\u2026</span>`);
|
|
1303
|
+
} else {
|
|
1304
|
+
$$renderer2.push("<!--[-1-->");
|
|
1305
|
+
}
|
|
1306
|
+
$$renderer2.push(`<!--]--> `);
|
|
1307
|
+
actions?.($$renderer2);
|
|
1308
|
+
$$renderer2.push(`<!----> <button type="button" title="Reload terminal (reconnects, keeps the session)" aria-label="Reload terminal">`);
|
|
1309
|
+
Rotate_cw($$renderer2, { size: 14 });
|
|
1310
|
+
$$renderer2.push(`<!----></button></div>`);
|
|
1311
|
+
});
|
|
1312
|
+
}
|
|
1313
|
+
|
|
1314
|
+
// src/components/TerminalSplit.svelte
|
|
1315
|
+
function TerminalSplit($$renderer, $$props) {
|
|
1316
|
+
$$renderer.component(($$renderer2) => {
|
|
1317
|
+
let { id, active, initialOpen = false } = $$props;
|
|
1318
|
+
let open = initialOpen;
|
|
1319
|
+
let mounted = initialOpen;
|
|
1320
|
+
let ratio = 50;
|
|
1321
|
+
let focusSide = "left";
|
|
1322
|
+
let container;
|
|
1323
|
+
function toggle() {
|
|
1324
|
+
open = !open;
|
|
1325
|
+
if (open)
|
|
1326
|
+
mounted = true;
|
|
1327
|
+
focusSide = open ? "right" : "left";
|
|
1328
|
+
apiPost(`/api/instances/${id}/split`, { open }).catch(() => {});
|
|
1329
|
+
}
|
|
1330
|
+
function clamp(pct) {
|
|
1331
|
+
return Math.min(80, Math.max(20, pct));
|
|
1332
|
+
}
|
|
1333
|
+
function dragTo(clientX) {
|
|
1334
|
+
const rect = container.getBoundingClientRect();
|
|
1335
|
+
if (rect.width > 0)
|
|
1336
|
+
ratio = clamp((clientX - rect.left) / rect.width * 100);
|
|
1337
|
+
}
|
|
1338
|
+
function onDividerDown(e) {
|
|
1339
|
+
e.preventDefault();
|
|
1340
|
+
e.currentTarget.setPointerCapture(e.pointerId);
|
|
1341
|
+
}
|
|
1342
|
+
function onDividerMove(e) {
|
|
1343
|
+
if (e.currentTarget.hasPointerCapture(e.pointerId))
|
|
1344
|
+
dragTo(e.clientX);
|
|
1345
|
+
}
|
|
1346
|
+
function onDividerKey(e) {
|
|
1347
|
+
if (e.key === "ArrowLeft")
|
|
1348
|
+
ratio = clamp(ratio - 5);
|
|
1349
|
+
else if (e.key === "ArrowRight")
|
|
1350
|
+
ratio = clamp(ratio + 5);
|
|
1351
|
+
else
|
|
1352
|
+
return;
|
|
1353
|
+
e.preventDefault();
|
|
1354
|
+
}
|
|
1355
|
+
function splitToggle($$renderer3) {
|
|
1356
|
+
$$renderer3.push(`<button type="button"${$27.attr("aria-pressed", open)}${$27.attr("title", open ? "Hide the shell pane" : "Open a shell alongside Claude")}${$27.attr("aria-label", open ? "Hide the shell pane" : "Open a shell alongside Claude")}>`);
|
|
1357
|
+
if (open) {
|
|
1358
|
+
$$renderer3.push("<!--[0-->");
|
|
1359
|
+
Panel_right_close($$renderer3, { size: 14 });
|
|
1360
|
+
} else {
|
|
1361
|
+
$$renderer3.push("<!--[-1-->");
|
|
1362
|
+
Panel_right_open($$renderer3, { size: 14 });
|
|
1363
|
+
}
|
|
1364
|
+
$$renderer3.push(`<!--]--></button>`);
|
|
1365
|
+
}
|
|
1366
|
+
$$renderer2.push(`<div class="split svelte-1ysvu88"><div class="side svelte-1ysvu88"${$27.attr_style("", { "flex-basis": open ? `${ratio}%` : "100%" })}>`);
|
|
1367
|
+
TerminalPane($$renderer2, {
|
|
1368
|
+
id,
|
|
1369
|
+
active,
|
|
1370
|
+
focus: active && focusSide === "left",
|
|
1371
|
+
actions: open ? undefined : splitToggle
|
|
1372
|
+
});
|
|
1373
|
+
$$renderer2.push(`<!----></div> `);
|
|
1374
|
+
if (mounted) {
|
|
1375
|
+
$$renderer2.push("<!--[0-->");
|
|
1376
|
+
$$renderer2.push(`<div${$27.attr_class("divider svelte-1ysvu88", undefined, { hidden: !open })} role="separator" aria-orientation="vertical" aria-label="Resize terminal panes"${$27.attr("aria-valuenow", Math.round(ratio))}${$27.attr("aria-valuemin", 20)}${$27.attr("aria-valuemax", 80)} tabindex="0"></div> <div${$27.attr_class("side svelte-1ysvu88", undefined, { hidden: !open })}${$27.attr_style("", { "flex-basis": `${$27.stringify(100 - ratio)}%` })}>`);
|
|
1377
|
+
TerminalPane($$renderer2, {
|
|
1378
|
+
id,
|
|
1379
|
+
arg: "shell",
|
|
1380
|
+
active: active && open,
|
|
1381
|
+
focus: active && open && focusSide === "right",
|
|
1382
|
+
actions: open ? splitToggle : undefined
|
|
1383
|
+
});
|
|
1384
|
+
$$renderer2.push(`<!----></div>`);
|
|
1385
|
+
} else {
|
|
1386
|
+
$$renderer2.push("<!--[-1-->");
|
|
1387
|
+
}
|
|
1388
|
+
$$renderer2.push(`<!--]--></div>`);
|
|
1389
|
+
});
|
|
1390
|
+
}
|
|
1391
|
+
|
|
1084
1392
|
// src/components/AppShell.svelte
|
|
1085
1393
|
function AppShell($$renderer, $$props) {
|
|
1086
1394
|
$$renderer.component(($$renderer2) => {
|
|
1087
|
-
let { preflight, initialPath, snapshot, pet } = $$props;
|
|
1395
|
+
let { preflight, initialPath, snapshot, pet, filter } = $$props;
|
|
1088
1396
|
let instances = snapshot;
|
|
1089
1397
|
let livePreflight = preflight;
|
|
1090
1398
|
let livePet = pet;
|
|
1399
|
+
let liveFilter = filter;
|
|
1091
1400
|
let loaded = snapshot.length > 0;
|
|
1092
|
-
const running = $
|
|
1401
|
+
const running = $28.derived(() => instances.filter((i) => i.status === "running"));
|
|
1093
1402
|
let attention = Object.fromEntries(snapshot.map((i) => [i.id, i.attention]));
|
|
1094
1403
|
let editingId = null;
|
|
1095
1404
|
let editingName = "";
|
|
@@ -1115,10 +1424,14 @@ function AppShell($$renderer, $$props) {
|
|
|
1115
1424
|
dist_default.error(err.message);
|
|
1116
1425
|
}
|
|
1117
1426
|
}
|
|
1427
|
+
function setFilter(v) {
|
|
1428
|
+
liveFilter = v;
|
|
1429
|
+
apiPost("/api/settings/filter", { value: v }).catch(() => {});
|
|
1430
|
+
}
|
|
1118
1431
|
let path = initialPath;
|
|
1119
|
-
const onIde = $
|
|
1120
|
-
const requestedId = $
|
|
1121
|
-
const active = $
|
|
1432
|
+
const onIde = $28.derived(() => path.startsWith("/ide"));
|
|
1433
|
+
const requestedId = $28.derived(() => path.startsWith("/ide/") ? path.slice("/ide/".length) : "");
|
|
1434
|
+
const active = $28.derived(() => onIde() ? running().some((i) => i.id === requestedId()) ? requestedId() : running()[0]?.id ?? "" : "");
|
|
1122
1435
|
function navigate(to) {
|
|
1123
1436
|
if (to === path)
|
|
1124
1437
|
return;
|
|
@@ -1134,7 +1447,7 @@ function AppShell($$renderer, $$props) {
|
|
|
1134
1447
|
let $$settled = true;
|
|
1135
1448
|
let $$inner_renderer;
|
|
1136
1449
|
function $$render_inner($$renderer3) {
|
|
1137
|
-
$$renderer3.push(`<div${$
|
|
1450
|
+
$$renderer3.push(`<div${$28.attr_class("app svelte-1duc7gd", undefined, { ide: onIde() })}>`);
|
|
1138
1451
|
if (onIde()) {
|
|
1139
1452
|
$$renderer3.push("<!--[0-->");
|
|
1140
1453
|
IdeBar($$renderer3, {
|
|
@@ -1156,18 +1469,36 @@ function AppShell($$renderer, $$props) {
|
|
|
1156
1469
|
});
|
|
1157
1470
|
} else {
|
|
1158
1471
|
$$renderer3.push("<!--[-1-->");
|
|
1159
|
-
DashboardView($$renderer3, {
|
|
1472
|
+
DashboardView($$renderer3, {
|
|
1473
|
+
preflight: livePreflight,
|
|
1474
|
+
instances,
|
|
1475
|
+
loaded,
|
|
1476
|
+
pet: livePet,
|
|
1477
|
+
filter: liveFilter,
|
|
1478
|
+
onFilter: setFilter
|
|
1479
|
+
});
|
|
1160
1480
|
}
|
|
1161
|
-
$$renderer3.push(`<!--]--> <div${$
|
|
1162
|
-
const each_array = $
|
|
1481
|
+
$$renderer3.push(`<!--]--> <div${$28.attr_class("panes svelte-1duc7gd", undefined, { hidden: !onIde() })}><!--[-->`);
|
|
1482
|
+
const each_array = $28.ensure_array_like(running());
|
|
1163
1483
|
for (let $$index = 0, $$length = each_array.length;$$index < $$length; $$index++) {
|
|
1164
1484
|
let inst = each_array[$$index];
|
|
1165
1485
|
if (visited.has(inst.id)) {
|
|
1166
1486
|
$$renderer3.push("<!--[0-->");
|
|
1167
|
-
$$renderer3.push(`<div${$
|
|
1487
|
+
$$renderer3.push(`<div${$28.attr_class("pane svelte-1duc7gd", undefined, { active: inst.id === active() })}>`);
|
|
1168
1488
|
if (mountable(inst.id)) {
|
|
1169
1489
|
$$renderer3.push("<!--[0-->");
|
|
1170
|
-
|
|
1490
|
+
if (inst.mode === "terminal") {
|
|
1491
|
+
$$renderer3.push("<!--[0-->");
|
|
1492
|
+
TerminalSplit($$renderer3, {
|
|
1493
|
+
id: inst.id,
|
|
1494
|
+
active: inst.id === active(),
|
|
1495
|
+
initialOpen: inst.terminal_split === 1
|
|
1496
|
+
});
|
|
1497
|
+
} else {
|
|
1498
|
+
$$renderer3.push("<!--[-1-->");
|
|
1499
|
+
$$renderer3.push(`<iframe${$28.attr("src", ideUrl(inst))}${$28.attr("title", inst.name)} class="svelte-1duc7gd" onload="this.__e=event"></iframe>`);
|
|
1500
|
+
}
|
|
1501
|
+
$$renderer3.push(`<!--]-->`);
|
|
1171
1502
|
} else {
|
|
1172
1503
|
$$renderer3.push("<!--[-1-->");
|
|
1173
1504
|
}
|
|
@@ -1178,7 +1509,7 @@ function AppShell($$renderer, $$props) {
|
|
|
1178
1509
|
stalledAfterMs: STALLED_AFTER_MS,
|
|
1179
1510
|
onoverride: () => forced.add(inst.id)
|
|
1180
1511
|
});
|
|
1181
|
-
} else if (!loadedFrames.has(inst.id)) {
|
|
1512
|
+
} else if (inst.mode !== "terminal" && !loadedFrames.has(inst.id)) {
|
|
1182
1513
|
$$renderer3.push("<!--[1-->");
|
|
1183
1514
|
IdeLoader($$renderer3, {});
|
|
1184
1515
|
} else {
|
|
@@ -1217,10 +1548,10 @@ function AppShell($$renderer, $$props) {
|
|
|
1217
1548
|
// src/pages/App.svelte
|
|
1218
1549
|
function App($$renderer, $$props) {
|
|
1219
1550
|
$$renderer.component(($$renderer2) => {
|
|
1220
|
-
let { preflight, initialPath, snapshot, pet } = $$props;
|
|
1551
|
+
let { preflight, initialPath, snapshot, pet, filter } = $$props;
|
|
1221
1552
|
if (true) {
|
|
1222
1553
|
let failed = function($$renderer3, error) {
|
|
1223
|
-
$$renderer3.push(`<mochi-island-failure data-component="AppShell"${$
|
|
1554
|
+
$$renderer3.push(`<mochi-island-failure data-component="AppShell"${$29.attr("data-message", error.message)}></mochi-island-failure>`);
|
|
1224
1555
|
};
|
|
1225
1556
|
$$renderer2.push("<!--[0-->");
|
|
1226
1557
|
$$renderer2.boundary({ failed }, ($$renderer3) => {
|
|
@@ -1228,10 +1559,10 @@ function App($$renderer, $$props) {
|
|
|
1228
1559
|
{
|
|
1229
1560
|
HydratableBoundary($$renderer3, {
|
|
1230
1561
|
children: ($$renderer4) => {
|
|
1231
|
-
$$renderer4.push(`<mochi-hydratable-island component-name="AppShell_2rtnxn6pgp2rh" component-url="__MOCHI_COMPONENT_URL__AppShell_2rtnxn6pgp2rh__"${$
|
|
1562
|
+
$$renderer4.push(`<mochi-hydratable-island component-name="AppShell_2rtnxn6pgp2rh" component-url="__MOCHI_COMPONENT_URL__AppShell_2rtnxn6pgp2rh__"${$29.attr("props-ref", emitIslandProps({ preflight, initialPath, snapshot, pet, filter }))}>`);
|
|
1232
1563
|
$$renderer4.push(`<!--[-->`);
|
|
1233
1564
|
{
|
|
1234
|
-
AppShell($$renderer4, { preflight, initialPath, snapshot, pet });
|
|
1565
|
+
AppShell($$renderer4, { preflight, initialPath, snapshot, pet, filter });
|
|
1235
1566
|
}
|
|
1236
1567
|
$$renderer4.push(`<!--]-->`);
|
|
1237
1568
|
$$renderer4.push(`</mochi-hydratable-island>`);
|