@rajat-rastogi/maestro 0.2.6 → 0.4.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/app/out/main/main.js +20 -3
- package/app/out/preload/preload.js +2 -0
- package/app/out/renderer/assets/{index-B6_qR_Gq.js → index-CAcCK5X-.js} +1274 -369
- package/app/out/renderer/index.html +1 -1
- package/dist/agent/install.js +2 -2
- package/dist/agent/install.js.map +1 -1
- package/package.json +1 -1
|
@@ -6976,9 +6976,9 @@ const NAV_ITEMS = [
|
|
|
6976
6976
|
{ id: "terminals", label: "Terminals", icon: "▦" }
|
|
6977
6977
|
];
|
|
6978
6978
|
function Sidebar({ activeView, onNavigate, runActive, waitingCount }) {
|
|
6979
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsxs("nav", { style: styles$
|
|
6980
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$
|
|
6981
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("ul", { style: styles$
|
|
6979
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("nav", { style: styles$n.sidebar, children: [
|
|
6980
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$n.logo, children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$n.logoText, children: "Maestro" }) }),
|
|
6981
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("ul", { style: styles$n.navList, children: NAV_ITEMS.map((item) => {
|
|
6982
6982
|
const isActive = activeView === item.id;
|
|
6983
6983
|
const hasRunDot = item.id === "run" && runActive;
|
|
6984
6984
|
const hasWaitingBadge = item.id === "terminals" && (waitingCount ?? 0) > 0;
|
|
@@ -6986,24 +6986,24 @@ function Sidebar({ activeView, onNavigate, runActive, waitingCount }) {
|
|
|
6986
6986
|
"button",
|
|
6987
6987
|
{
|
|
6988
6988
|
style: {
|
|
6989
|
-
...styles$
|
|
6990
|
-
...isActive ? styles$
|
|
6989
|
+
...styles$n.navBtn,
|
|
6990
|
+
...isActive ? styles$n.navBtnActive : {}
|
|
6991
6991
|
},
|
|
6992
6992
|
onClick: () => onNavigate(item.id),
|
|
6993
6993
|
title: item.label,
|
|
6994
6994
|
children: [
|
|
6995
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$
|
|
6996
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$
|
|
6997
|
-
hasRunDot && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$
|
|
6998
|
-
hasWaitingBadge && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$
|
|
6995
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$n.navIcon, children: item.icon }),
|
|
6996
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$n.navLabel, children: item.label }),
|
|
6997
|
+
hasRunDot && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$n.runDot }),
|
|
6998
|
+
hasWaitingBadge && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$n.waitingBadge, children: waitingCount })
|
|
6999
6999
|
]
|
|
7000
7000
|
}
|
|
7001
7001
|
) }, item.id);
|
|
7002
7002
|
}) }),
|
|
7003
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$
|
|
7003
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$n.footer, children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$n.footerText, children: "v0.1.0" }) })
|
|
7004
7004
|
] });
|
|
7005
7005
|
}
|
|
7006
|
-
const styles$
|
|
7006
|
+
const styles$n = {
|
|
7007
7007
|
sidebar: {
|
|
7008
7008
|
width: "var(--sidebar-width)",
|
|
7009
7009
|
minWidth: "var(--sidebar-width)",
|
|
@@ -7117,41 +7117,41 @@ function HomeView({ onNavigate }) {
|
|
|
7117
7117
|
async function handleLaunch(filePath) {
|
|
7118
7118
|
onNavigate("run", filePath);
|
|
7119
7119
|
}
|
|
7120
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
7121
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
7120
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$m.root, children: [
|
|
7121
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$m.header, children: [
|
|
7122
7122
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
|
|
7123
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("h1", { style: styles$
|
|
7124
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { style: styles$
|
|
7123
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("h1", { style: styles$m.title, children: "Maestro" }),
|
|
7124
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { style: styles$m.subtitle, children: "Autonomous AI coding orchestrator" })
|
|
7125
7125
|
] }),
|
|
7126
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
7126
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$m.headerActions, children: [
|
|
7127
7127
|
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: "btn btn-ghost", onClick: handleBrowse, children: "Open file…" }),
|
|
7128
7128
|
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: "btn btn-primary", onClick: () => onNavigate("create"), children: "✦ New Plan" })
|
|
7129
7129
|
] })
|
|
7130
7130
|
] }),
|
|
7131
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
7132
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
7133
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("h2", { style: styles$
|
|
7134
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$
|
|
7131
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$m.content, children: [
|
|
7132
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$m.sectionHeader, children: [
|
|
7133
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("h2", { style: styles$m.sectionTitle, children: "Recent Plans" }),
|
|
7134
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$m.dirLabel, children: dir })
|
|
7135
7135
|
] }),
|
|
7136
|
-
loading && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$
|
|
7137
|
-
!loading && plans.length === 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
7138
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$
|
|
7136
|
+
loading && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$m.loading, children: "Loading plans…" }),
|
|
7137
|
+
!loading && plans.length === 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$m.empty, children: [
|
|
7138
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$m.emptyIcon, children: "✦" }),
|
|
7139
7139
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("p", { children: [
|
|
7140
7140
|
"No plan files found in ",
|
|
7141
7141
|
/* @__PURE__ */ jsxRuntimeExports.jsx("code", { children: dir })
|
|
7142
7142
|
] }),
|
|
7143
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
7143
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$m.emptyActions, children: [
|
|
7144
7144
|
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: "btn btn-primary", onClick: () => onNavigate("create"), children: "Create your first plan" }),
|
|
7145
7145
|
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: "btn btn-ghost", onClick: handleBrowse, children: "Browse for a plan file" })
|
|
7146
7146
|
] })
|
|
7147
7147
|
] }),
|
|
7148
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$
|
|
7149
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
7150
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("h3", { style: styles$
|
|
7151
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$
|
|
7148
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$m.planGrid, children: plans.map((plan) => /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$m.planCard, children: [
|
|
7149
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$m.cardTop, children: [
|
|
7150
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("h3", { style: styles$m.planName, children: plan.name }),
|
|
7151
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$m.planDate, children: formatDate(plan.mtime) })
|
|
7152
7152
|
] }),
|
|
7153
|
-
plan.preview && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { style: styles$
|
|
7154
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
7153
|
+
plan.preview && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { style: styles$m.planPreview, children: plan.preview }),
|
|
7154
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$m.cardActions, children: [
|
|
7155
7155
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
7156
7156
|
"button",
|
|
7157
7157
|
{
|
|
@@ -7174,16 +7174,16 @@ function HomeView({ onNavigate }) {
|
|
|
7174
7174
|
] })
|
|
7175
7175
|
] }, plan.filePath)) })
|
|
7176
7176
|
] }),
|
|
7177
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
7178
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$
|
|
7179
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
7177
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$m.quickActions, children: [
|
|
7178
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$m.quickTitle, children: "Quick actions" }),
|
|
7179
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$m.quickGrid, children: [
|
|
7180
7180
|
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: "btn btn-ghost", onClick: () => onNavigate("replay"), children: "↺ Replay previous run" }),
|
|
7181
7181
|
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: "btn btn-ghost", onClick: () => onNavigate("config"), children: "⚙ Edit configuration" })
|
|
7182
7182
|
] })
|
|
7183
7183
|
] })
|
|
7184
7184
|
] });
|
|
7185
7185
|
}
|
|
7186
|
-
const styles$
|
|
7186
|
+
const styles$m = {
|
|
7187
7187
|
root: {
|
|
7188
7188
|
display: "flex",
|
|
7189
7189
|
flexDirection: "column",
|
|
@@ -7375,9 +7375,9 @@ function PlanCreatorView({ onNavigate }) {
|
|
|
7375
7375
|
setLogs((prev) => [...prev, `> ${stdinInput}`]);
|
|
7376
7376
|
setStdinInput("");
|
|
7377
7377
|
}
|
|
7378
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
7379
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
7380
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("h2", { style: styles$
|
|
7378
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$l.root, children: [
|
|
7379
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$l.header, children: [
|
|
7380
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("h2", { style: styles$l.title, children: "Create Plan" }),
|
|
7381
7381
|
stage === "running" && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
7382
7382
|
"button",
|
|
7383
7383
|
{
|
|
@@ -7391,17 +7391,17 @@ function PlanCreatorView({ onNavigate }) {
|
|
|
7391
7391
|
}
|
|
7392
7392
|
)
|
|
7393
7393
|
] }),
|
|
7394
|
-
stage === "input" && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$
|
|
7395
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$
|
|
7396
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("h1", { style: styles$
|
|
7397
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { style: styles$
|
|
7394
|
+
stage === "input" && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$l.inputStage, children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$l.inputCard, children: [
|
|
7395
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$l.inputIcon, children: "✦" }),
|
|
7396
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("h1", { style: styles$l.inputTitle, children: "What do you want to build?" }),
|
|
7397
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { style: styles$l.inputSubtitle, children: "Describe your goal. Maestro will explore the codebase and create a detailed plan." }),
|
|
7398
7398
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
7399
7399
|
"textarea",
|
|
7400
7400
|
{
|
|
7401
7401
|
value: description,
|
|
7402
7402
|
onChange: (e) => setDescription(e.target.value),
|
|
7403
7403
|
placeholder: "e.g. Add OAuth authentication with GitHub to the web app",
|
|
7404
|
-
style: styles$
|
|
7404
|
+
style: styles$l.descTextarea,
|
|
7405
7405
|
onKeyDown: (e) => {
|
|
7406
7406
|
if (e.key === "Enter" && (e.ctrlKey || e.metaKey)) handleStart();
|
|
7407
7407
|
},
|
|
@@ -7419,13 +7419,13 @@ function PlanCreatorView({ onNavigate }) {
|
|
|
7419
7419
|
}
|
|
7420
7420
|
)
|
|
7421
7421
|
] }) }),
|
|
7422
|
-
(stage === "running" || stage === "done" || stage === "error") && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
7423
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
7424
|
-
logs.map((line, i) => /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$
|
|
7425
|
-
stage === "running" && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$
|
|
7422
|
+
(stage === "running" || stage === "done" || stage === "error") && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$l.runStage, children: [
|
|
7423
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$l.logArea, children: [
|
|
7424
|
+
logs.map((line, i) => /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$l.logLine, className: "mono", children: line }, i)),
|
|
7425
|
+
stage === "running" && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$l.cursor, children: "▌" }),
|
|
7426
7426
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { ref: logsEndRef })
|
|
7427
7427
|
] }),
|
|
7428
|
-
stage === "running" && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
7428
|
+
stage === "running" && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$l.stdinRow, children: [
|
|
7429
7429
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
7430
7430
|
"input",
|
|
7431
7431
|
{
|
|
@@ -7434,18 +7434,18 @@ function PlanCreatorView({ onNavigate }) {
|
|
|
7434
7434
|
onChange: (e) => setStdinInput(e.target.value),
|
|
7435
7435
|
placeholder: "Type your answer and press Enter…",
|
|
7436
7436
|
onKeyDown: (e) => e.key === "Enter" && sendStdin(),
|
|
7437
|
-
style: styles$
|
|
7437
|
+
style: styles$l.stdinInput,
|
|
7438
7438
|
autoFocus: true
|
|
7439
7439
|
}
|
|
7440
7440
|
),
|
|
7441
7441
|
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: "btn btn-primary btn-sm", onClick: sendStdin, children: "Send" })
|
|
7442
7442
|
] }),
|
|
7443
|
-
stage === "done" && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
7444
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { style: styles$
|
|
7443
|
+
stage === "done" && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$l.doneBar, children: [
|
|
7444
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { style: styles$l.doneMsg, children: [
|
|
7445
7445
|
"✓ Plan created",
|
|
7446
7446
|
createdFile ? `: ${createdFile.split(/[\\/]/).pop()}` : ""
|
|
7447
7447
|
] }),
|
|
7448
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
7448
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$l.doneActions, children: [
|
|
7449
7449
|
createdFile && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
7450
7450
|
"button",
|
|
7451
7451
|
{
|
|
@@ -7457,14 +7457,14 @@ function PlanCreatorView({ onNavigate }) {
|
|
|
7457
7457
|
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: "btn btn-ghost", onClick: () => setStage("input"), children: "Create another" })
|
|
7458
7458
|
] })
|
|
7459
7459
|
] }),
|
|
7460
|
-
stage === "error" && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
7461
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$
|
|
7460
|
+
stage === "error" && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$l.errorBar, children: [
|
|
7461
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$l.errorMsg, children: error ?? "Plan creation failed." }),
|
|
7462
7462
|
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: "btn btn-ghost btn-sm", onClick: () => setStage("input"), children: "Try again" })
|
|
7463
7463
|
] })
|
|
7464
7464
|
] })
|
|
7465
7465
|
] });
|
|
7466
7466
|
}
|
|
7467
|
-
const styles$
|
|
7467
|
+
const styles$l = {
|
|
7468
7468
|
root: {
|
|
7469
7469
|
display: "flex",
|
|
7470
7470
|
flexDirection: "column",
|
|
@@ -7704,12 +7704,12 @@ function LogStream({ events, isReplay }) {
|
|
|
7704
7704
|
...s,
|
|
7705
7705
|
events: s.events.filter((e) => matchesFilter(e, filter) && matchesSearch(e, search))
|
|
7706
7706
|
})).filter((s) => s.header || s.events.length > 0);
|
|
7707
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
7708
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
7709
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$
|
|
7707
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$k.root, children: [
|
|
7708
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$k.toolbar, children: [
|
|
7709
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$k.filters, children: ["all", "task", "review"].map((f2) => /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
7710
7710
|
"button",
|
|
7711
7711
|
{
|
|
7712
|
-
style: { ...styles$
|
|
7712
|
+
style: { ...styles$k.filterBtn, ...filter === f2 ? styles$k.filterBtnActive : {} },
|
|
7713
7713
|
onClick: () => setFilter(f2),
|
|
7714
7714
|
children: f2.charAt(0).toUpperCase() + f2.slice(1)
|
|
7715
7715
|
},
|
|
@@ -7724,17 +7724,17 @@ function LogStream({ events, isReplay }) {
|
|
|
7724
7724
|
value: search,
|
|
7725
7725
|
onChange: (e) => setSearch(e.target.value),
|
|
7726
7726
|
onKeyDown: (e) => e.key === "Escape" && (setSearch(""), e.target.blur()),
|
|
7727
|
-
style: styles$
|
|
7727
|
+
style: styles$k.searchInput
|
|
7728
7728
|
}
|
|
7729
7729
|
),
|
|
7730
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
7731
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { style: styles$
|
|
7732
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { style: styles$
|
|
7733
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { style: styles$
|
|
7730
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$k.toolbarRight, children: [
|
|
7731
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { style: styles$k.iconBtn, onClick: toggleAll, title: allCollapsed ? "Expand all" : "Collapse all", children: allCollapsed ? "⊞" : "⊟" }),
|
|
7732
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { style: styles$k.iconBtn, onClick: copyLogs, title: "Copy all logs", children: copied ? "✓" : "⎘" }),
|
|
7733
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { style: styles$k.iconBtn, onClick: exportLogs, title: "Export logs", children: "↓" }),
|
|
7734
7734
|
!isReplay && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
7735
7735
|
"button",
|
|
7736
7736
|
{
|
|
7737
|
-
style: { ...styles$
|
|
7737
|
+
style: { ...styles$k.iconBtn, color: autoScroll ? "var(--green)" : "var(--text-muted)" },
|
|
7738
7738
|
onClick: () => setAutoScroll((v2) => !v2),
|
|
7739
7739
|
title: "Auto-scroll",
|
|
7740
7740
|
children: "↓↓"
|
|
@@ -7742,13 +7742,13 @@ function LogStream({ events, isReplay }) {
|
|
|
7742
7742
|
)
|
|
7743
7743
|
] })
|
|
7744
7744
|
] }),
|
|
7745
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { ref: containerRef, onScroll, style: styles$
|
|
7746
|
-
filtered.length === 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$
|
|
7745
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { ref: containerRef, onScroll, style: styles$k.logArea, children: [
|
|
7746
|
+
filtered.length === 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$k.empty, children: events.length === 0 ? "Waiting for log events…" : "No events match the current filter." }),
|
|
7747
7747
|
filtered.map((section, sIdx) => {
|
|
7748
7748
|
const isCollapsed = !!section.header && collapsedSections.has(sIdx);
|
|
7749
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
7750
|
-
section.header ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
7751
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$
|
|
7749
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$k.section, children: [
|
|
7750
|
+
section.header ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$k.sectionHeader, onClick: () => toggleSection(sIdx), children: [
|
|
7751
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$k.sectionArrow, children: isCollapsed ? "▶" : "▼" }),
|
|
7752
7752
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "log-header", children: section.header })
|
|
7753
7753
|
] }) : null,
|
|
7754
7754
|
!isCollapsed && section.events.map((ev, eIdx) => /* @__PURE__ */ jsxRuntimeExports.jsx(LogLine, { event: ev }, eIdx))
|
|
@@ -7759,15 +7759,15 @@ function LogStream({ events, isReplay }) {
|
|
|
7759
7759
|
] });
|
|
7760
7760
|
}
|
|
7761
7761
|
function LogLine({ event }) {
|
|
7762
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
7763
|
-
event.ts && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { style: styles$
|
|
7762
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$k.logLine, className: `mono log-${event.phase}`, children: [
|
|
7763
|
+
event.ts && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { style: styles$k.ts, children: [
|
|
7764
7764
|
event.ts,
|
|
7765
7765
|
" "
|
|
7766
7766
|
] }),
|
|
7767
7767
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: event.text })
|
|
7768
7768
|
] });
|
|
7769
7769
|
}
|
|
7770
|
-
const styles$
|
|
7770
|
+
const styles$k = {
|
|
7771
7771
|
root: {
|
|
7772
7772
|
display: "flex",
|
|
7773
7773
|
flexDirection: "column",
|
|
@@ -7898,9 +7898,9 @@ function parsePlan(md2) {
|
|
|
7898
7898
|
function PlanPanel({ planContent }) {
|
|
7899
7899
|
const [collapsed, setCollapsed] = reactExports.useState(false);
|
|
7900
7900
|
if (!planContent) {
|
|
7901
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
7902
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$
|
|
7903
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$
|
|
7901
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$j.panel, children: [
|
|
7902
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$j.header, children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Plan" }) }),
|
|
7903
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$j.empty, children: "Loading plan…" })
|
|
7904
7904
|
] });
|
|
7905
7905
|
}
|
|
7906
7906
|
const plan = parsePlan(planContent);
|
|
@@ -7909,39 +7909,39 @@ function PlanPanel({ planContent }) {
|
|
|
7909
7909
|
(acc, t2) => acc + t2.checkboxes.filter((c) => c.checked).length,
|
|
7910
7910
|
0
|
|
7911
7911
|
);
|
|
7912
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
7913
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
7914
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$
|
|
7915
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { style: styles$
|
|
7912
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$j.panel, children: [
|
|
7913
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$j.header, onClick: () => setCollapsed((v2) => !v2), children: [
|
|
7914
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$j.headerTitle, children: plan.title || "Plan" }),
|
|
7915
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { style: styles$j.progress, children: [
|
|
7916
7916
|
doneChecks,
|
|
7917
7917
|
"/",
|
|
7918
7918
|
totalChecks
|
|
7919
7919
|
] }),
|
|
7920
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$
|
|
7920
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$j.collapseBtn, children: collapsed ? "▶" : "▼" })
|
|
7921
7921
|
] }),
|
|
7922
|
-
!collapsed && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$
|
|
7922
|
+
!collapsed && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$j.taskList, children: plan.tasks.map((task) => {
|
|
7923
7923
|
const done = task.checkboxes.filter((c) => c.checked).length;
|
|
7924
7924
|
const total = task.checkboxes.length;
|
|
7925
7925
|
const allDone = total > 0 && done === total;
|
|
7926
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
7927
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: { ...styles$
|
|
7928
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$
|
|
7926
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$j.task, children: [
|
|
7927
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: { ...styles$j.taskTitle, ...allDone ? styles$j.taskDone : {} }, children: [
|
|
7928
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$j.taskIndex, children: task.index }),
|
|
7929
7929
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: task.title }),
|
|
7930
|
-
total > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { style: styles$
|
|
7930
|
+
total > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { style: styles$j.taskCount, children: [
|
|
7931
7931
|
done,
|
|
7932
7932
|
"/",
|
|
7933
7933
|
total
|
|
7934
7934
|
] })
|
|
7935
7935
|
] }),
|
|
7936
|
-
task.checkboxes.map((cb2, i) => /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
7937
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: { ...styles$
|
|
7938
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: { ...cb2.checked ? styles$
|
|
7936
|
+
task.checkboxes.map((cb2, i) => /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$j.checkbox, children: [
|
|
7937
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: { ...styles$j.checkIcon, ...cb2.checked ? styles$j.checkDone : {} }, children: cb2.checked ? "✓" : "○" }),
|
|
7938
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: { ...cb2.checked ? styles$j.checkTextDone : {} }, children: cb2.text })
|
|
7939
7939
|
] }, i))
|
|
7940
7940
|
] }, task.index);
|
|
7941
7941
|
}) })
|
|
7942
7942
|
] });
|
|
7943
7943
|
}
|
|
7944
|
-
const styles$
|
|
7944
|
+
const styles$j = {
|
|
7945
7945
|
panel: {
|
|
7946
7946
|
width: "var(--panel-width)",
|
|
7947
7947
|
minWidth: "var(--panel-width)",
|
|
@@ -8394,15 +8394,15 @@ function RunView({ initialPlanFile }) {
|
|
|
8394
8394
|
if (file) setTargetPlanFile(file);
|
|
8395
8395
|
}
|
|
8396
8396
|
const statusColor = store.status === "running" ? "var(--green)" : store.status === "complete" ? "var(--blue)" : store.status === "error" ? "var(--red)" : "var(--text-muted)";
|
|
8397
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
8398
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
8399
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
8400
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: { ...styles$
|
|
8401
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$
|
|
8402
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: { ...styles$
|
|
8397
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$i.root, children: [
|
|
8398
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$i.header, children: [
|
|
8399
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$i.headerLeft, children: [
|
|
8400
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: { ...styles$i.statusDot, background: statusColor } }),
|
|
8401
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$i.planLabel, children: store.planFile ? store.planFile.split(/[\\/]/).pop() : "No plan running" }),
|
|
8402
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: { ...styles$i.statusBadge, color: statusColor }, children: store.status }),
|
|
8403
8403
|
store.status === "running" && /* @__PURE__ */ jsxRuntimeExports.jsx(ElapsedTimer$1, { startedAt: store.startedAt })
|
|
8404
8404
|
] }),
|
|
8405
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
8405
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$i.headerRight, children: [
|
|
8406
8406
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
8407
8407
|
"button",
|
|
8408
8408
|
{
|
|
@@ -8421,7 +8421,7 @@ function RunView({ initialPlanFile }) {
|
|
|
8421
8421
|
)
|
|
8422
8422
|
] })
|
|
8423
8423
|
] }),
|
|
8424
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
8424
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$i.main, children: [
|
|
8425
8425
|
/* @__PURE__ */ jsxRuntimeExports.jsx(LogStream, { events: store.logs }),
|
|
8426
8426
|
showPanel && /* @__PURE__ */ jsxRuntimeExports.jsx(PlanPanel, { planContent: store.planContent })
|
|
8427
8427
|
] }),
|
|
@@ -8448,11 +8448,11 @@ function LaunchDialog({ initialPlanFile, initialOpts, onLaunch, onCancel, onBrow
|
|
|
8448
8448
|
const [tasksOnly, setTasksOnly] = reactExports.useState(initialOpts.tasksOnly ?? false);
|
|
8449
8449
|
const [reviewOnly, setReviewOnly] = reactExports.useState(initialOpts.reviewOnly ?? false);
|
|
8450
8450
|
const canLaunch = planFile.trim().length > 0;
|
|
8451
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$
|
|
8452
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("h2", { style: styles$
|
|
8453
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
8454
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("label", { style: styles$
|
|
8455
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
8451
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$i.overlay, children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$i.dialog, children: [
|
|
8452
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("h2", { style: styles$i.dialogTitle, children: "Launch Plan" }),
|
|
8453
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$i.field, children: [
|
|
8454
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("label", { style: styles$i.fieldLabel, children: "Plan file" }),
|
|
8455
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$i.fileRow, children: [
|
|
8456
8456
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
8457
8457
|
"input",
|
|
8458
8458
|
{
|
|
@@ -8466,14 +8466,14 @@ function LaunchDialog({ initialPlanFile, initialOpts, onLaunch, onCancel, onBrow
|
|
|
8466
8466
|
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: "btn btn-ghost btn-sm", onClick: onBrowse, children: "Browse" })
|
|
8467
8467
|
] })
|
|
8468
8468
|
] }),
|
|
8469
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
8470
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("label", { style: styles$
|
|
8469
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$i.field, children: [
|
|
8470
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("label", { style: styles$i.fieldLabel, children: "Provider" }),
|
|
8471
8471
|
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
8472
8472
|
"select",
|
|
8473
8473
|
{
|
|
8474
8474
|
value: provider,
|
|
8475
8475
|
onChange: (e) => setProvider(e.target.value),
|
|
8476
|
-
style: styles$
|
|
8476
|
+
style: styles$i.select,
|
|
8477
8477
|
children: [
|
|
8478
8478
|
/* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: "", children: "Default (from config)" }),
|
|
8479
8479
|
/* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: "claude", children: "Claude" }),
|
|
@@ -8482,8 +8482,8 @@ function LaunchDialog({ initialPlanFile, initialOpts, onLaunch, onCancel, onBrow
|
|
|
8482
8482
|
}
|
|
8483
8483
|
)
|
|
8484
8484
|
] }),
|
|
8485
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
8486
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("label", { style: styles$
|
|
8485
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$i.field, children: [
|
|
8486
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("label", { style: styles$i.fieldLabel, children: "Max iterations" }),
|
|
8487
8487
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
8488
8488
|
"input",
|
|
8489
8489
|
{
|
|
@@ -8494,12 +8494,12 @@ function LaunchDialog({ initialPlanFile, initialOpts, onLaunch, onCancel, onBrow
|
|
|
8494
8494
|
}
|
|
8495
8495
|
)
|
|
8496
8496
|
] }),
|
|
8497
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
8497
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$i.toggleRow, children: [
|
|
8498
8498
|
/* @__PURE__ */ jsxRuntimeExports.jsx(ToggleField$1, { label: "Worktree mode", checked: worktree, onChange: setWorktree }),
|
|
8499
8499
|
/* @__PURE__ */ jsxRuntimeExports.jsx(ToggleField$1, { label: "Tasks only", checked: tasksOnly, onChange: setTasksOnly }),
|
|
8500
8500
|
/* @__PURE__ */ jsxRuntimeExports.jsx(ToggleField$1, { label: "Review only", checked: reviewOnly, onChange: setReviewOnly })
|
|
8501
8501
|
] }),
|
|
8502
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
8502
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$i.dialogActions, children: [
|
|
8503
8503
|
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: "btn btn-ghost", onClick: onCancel, children: "Cancel" }),
|
|
8504
8504
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
8505
8505
|
"button",
|
|
@@ -8520,7 +8520,7 @@ function LaunchDialog({ initialPlanFile, initialOpts, onLaunch, onCancel, onBrow
|
|
|
8520
8520
|
] }) });
|
|
8521
8521
|
}
|
|
8522
8522
|
function ToggleField$1({ label, checked, onChange }) {
|
|
8523
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsxs("label", { style: styles$
|
|
8523
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("label", { style: styles$i.toggle, children: [
|
|
8524
8524
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
8525
8525
|
"input",
|
|
8526
8526
|
{
|
|
@@ -8533,7 +8533,7 @@ function ToggleField$1({ label, checked, onChange }) {
|
|
|
8533
8533
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: { fontSize: "13px", color: "var(--text-secondary)" }, children: label })
|
|
8534
8534
|
] });
|
|
8535
8535
|
}
|
|
8536
|
-
const styles$
|
|
8536
|
+
const styles$i = {
|
|
8537
8537
|
root: {
|
|
8538
8538
|
display: "flex",
|
|
8539
8539
|
flexDirection: "column",
|
|
@@ -8647,28 +8647,28 @@ const styles$e = {
|
|
|
8647
8647
|
};
|
|
8648
8648
|
function SessionList({ sessions, onSelect }) {
|
|
8649
8649
|
if (sessions.length === 0) {
|
|
8650
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
8650
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$h.empty, children: [
|
|
8651
8651
|
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { children: "No completed sessions found." }),
|
|
8652
8652
|
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { style: { marginTop: "8px", fontSize: "12px", color: "var(--text-muted)" }, children: "Run a plan first, then come back to replay it." })
|
|
8653
8653
|
] });
|
|
8654
8654
|
}
|
|
8655
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$
|
|
8655
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$h.grid, children: sessions.map((session) => /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
8656
8656
|
"button",
|
|
8657
8657
|
{
|
|
8658
|
-
style: styles$
|
|
8658
|
+
style: styles$h.card,
|
|
8659
8659
|
onClick: () => onSelect(session),
|
|
8660
8660
|
children: [
|
|
8661
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
8662
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$
|
|
8661
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$h.cardHeader, children: [
|
|
8662
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$h.planName, children: session.planName }),
|
|
8663
8663
|
session.active && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "badge badge-green", style: { fontSize: "10px" }, children: "active" })
|
|
8664
8664
|
] }),
|
|
8665
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$
|
|
8665
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$h.meta, children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: { color: "var(--text-muted)", fontSize: "11px" }, children: session.id }) })
|
|
8666
8666
|
]
|
|
8667
8667
|
},
|
|
8668
8668
|
session.id
|
|
8669
8669
|
)) });
|
|
8670
8670
|
}
|
|
8671
|
-
const styles$
|
|
8671
|
+
const styles$h = {
|
|
8672
8672
|
grid: {
|
|
8673
8673
|
display: "grid",
|
|
8674
8674
|
gridTemplateColumns: "repeat(auto-fill, minmax(280px, 1fr))",
|
|
@@ -8791,13 +8791,13 @@ function ReplayView() {
|
|
|
8791
8791
|
}
|
|
8792
8792
|
}
|
|
8793
8793
|
if (store.loading && !store.port) {
|
|
8794
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$
|
|
8794
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$g.loading, children: "Starting replay server…" });
|
|
8795
8795
|
}
|
|
8796
8796
|
if (error && !store.port) {
|
|
8797
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
8798
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$
|
|
8799
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$
|
|
8800
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("p", { style: styles$
|
|
8797
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$g.errorPage, children: [
|
|
8798
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$g.errorTitle, children: "Failed to start replay" }),
|
|
8799
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$g.errorMsg, children: error }),
|
|
8800
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("p", { style: styles$g.errorHint, children: [
|
|
8801
8801
|
"Make sure ",
|
|
8802
8802
|
/* @__PURE__ */ jsxRuntimeExports.jsx("code", { children: "maestro" }),
|
|
8803
8803
|
" is installed and available on your PATH."
|
|
@@ -8805,8 +8805,8 @@ function ReplayView() {
|
|
|
8805
8805
|
] });
|
|
8806
8806
|
}
|
|
8807
8807
|
if (store.activeSessionId && store.replayData) {
|
|
8808
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
8809
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
8808
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$g.root, children: [
|
|
8809
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$g.header, children: [
|
|
8810
8810
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
8811
8811
|
"button",
|
|
8812
8812
|
{
|
|
@@ -8815,7 +8815,7 @@ function ReplayView() {
|
|
|
8815
8815
|
children: "← Back"
|
|
8816
8816
|
}
|
|
8817
8817
|
),
|
|
8818
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$
|
|
8818
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$g.sessionLabel, children: store.activeSessionId }),
|
|
8819
8819
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
8820
8820
|
"button",
|
|
8821
8821
|
{
|
|
@@ -8825,15 +8825,15 @@ function ReplayView() {
|
|
|
8825
8825
|
}
|
|
8826
8826
|
)
|
|
8827
8827
|
] }),
|
|
8828
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
8828
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$g.main, children: [
|
|
8829
8829
|
/* @__PURE__ */ jsxRuntimeExports.jsx(LogStream, { events: store.replayData.events, isReplay: true }),
|
|
8830
8830
|
showPanel && /* @__PURE__ */ jsxRuntimeExports.jsx(PlanPanel, { planContent: store.replayData.planContent })
|
|
8831
8831
|
] })
|
|
8832
8832
|
] });
|
|
8833
8833
|
}
|
|
8834
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
8835
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
8836
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("h2", { style: styles$
|
|
8834
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$g.root, children: [
|
|
8835
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$g.header, children: [
|
|
8836
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("h2", { style: styles$g.title, children: "Replay" }),
|
|
8837
8837
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
8838
8838
|
"button",
|
|
8839
8839
|
{
|
|
@@ -8844,8 +8844,8 @@ function ReplayView() {
|
|
|
8844
8844
|
}
|
|
8845
8845
|
)
|
|
8846
8846
|
] }),
|
|
8847
|
-
error && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$
|
|
8848
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$
|
|
8847
|
+
error && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$g.errorBanner, children: error }),
|
|
8848
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$g.sessionArea, children: store.loading ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$g.loading, children: "Loading sessions…" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
8849
8849
|
SessionList,
|
|
8850
8850
|
{
|
|
8851
8851
|
sessions: store.sessions,
|
|
@@ -8854,7 +8854,7 @@ function ReplayView() {
|
|
|
8854
8854
|
) })
|
|
8855
8855
|
] });
|
|
8856
8856
|
}
|
|
8857
|
-
const styles$
|
|
8857
|
+
const styles$g = {
|
|
8858
8858
|
root: {
|
|
8859
8859
|
display: "flex",
|
|
8860
8860
|
flexDirection: "column",
|
|
@@ -9008,7 +9008,7 @@ function ConfigEditor({ state, target, dirtyValues, searchQuery, expandAll, onEx
|
|
|
9008
9008
|
(s) => s.fields.every((f2) => !f2.toLowerCase().includes(q2) && !(FIELD_DESCRIPTIONS[f2] ?? "").toLowerCase().includes(q2))
|
|
9009
9009
|
);
|
|
9010
9010
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
|
|
9011
|
-
noMatches && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$
|
|
9011
|
+
noMatches && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$f.noMatch, children: "No matching config keys." }),
|
|
9012
9012
|
SECTIONS.map((section) => {
|
|
9013
9013
|
const matchingFields = q2 ? section.fields.filter(
|
|
9014
9014
|
(f2) => f2.toLowerCase().includes(q2) || (FIELD_DESCRIPTIONS[f2] ?? "").toLowerCase().includes(q2)
|
|
@@ -9016,20 +9016,20 @@ function ConfigEditor({ state, target, dirtyValues, searchQuery, expandAll, onEx
|
|
|
9016
9016
|
if (q2 && matchingFields.length === 0) return null;
|
|
9017
9017
|
const isCollapsed = !q2 && collapsedSections.has(section.id);
|
|
9018
9018
|
const hasDirtyField = section.fields.some((f2) => isDirty(f2));
|
|
9019
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
9019
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$f.section, children: [
|
|
9020
9020
|
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
9021
9021
|
"div",
|
|
9022
9022
|
{
|
|
9023
|
-
style: styles$
|
|
9023
|
+
style: styles$f.sectionHeader,
|
|
9024
9024
|
onClick: () => toggleSection(section.id),
|
|
9025
9025
|
children: [
|
|
9026
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$
|
|
9027
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$
|
|
9028
|
-
hasDirtyField && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$
|
|
9026
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$f.sectionToggle, children: isCollapsed ? "▶" : "▼" }),
|
|
9027
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$f.sectionTitle, children: section.title }),
|
|
9028
|
+
hasDirtyField && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$f.dirtyDot, children: "•" })
|
|
9029
9029
|
]
|
|
9030
9030
|
}
|
|
9031
9031
|
),
|
|
9032
|
-
!isCollapsed && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$
|
|
9032
|
+
!isCollapsed && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$f.sectionBody, children: (q2 ? matchingFields : section.fields).map((key) => /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
9033
9033
|
FieldRow,
|
|
9034
9034
|
{
|
|
9035
9035
|
fieldKey: key,
|
|
@@ -9048,9 +9048,9 @@ function ConfigEditor({ state, target, dirtyValues, searchQuery, expandAll, onEx
|
|
|
9048
9048
|
function FieldRow({ fieldKey, value, dirty, overridden, onChange, onReset }) {
|
|
9049
9049
|
const desc = FIELD_DESCRIPTIONS[fieldKey];
|
|
9050
9050
|
const showReset = dirty || overridden;
|
|
9051
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
9052
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(Tooltip, { text: desc, children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$
|
|
9053
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$
|
|
9051
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$f.fieldRow, children: [
|
|
9052
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Tooltip, { text: desc, children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$f.fieldLabel, children: fieldKey }) }),
|
|
9053
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$f.fieldControl, children: fieldKey in SELECT_FIELDS ? /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
9054
9054
|
SelectField,
|
|
9055
9055
|
{
|
|
9056
9056
|
value: String(value ?? ""),
|
|
@@ -9104,7 +9104,7 @@ function FieldRow({ fieldKey, value, dirty, overridden, onChange, onReset }) {
|
|
|
9104
9104
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
9105
9105
|
"button",
|
|
9106
9106
|
{
|
|
9107
|
-
style: { ...styles$
|
|
9107
|
+
style: { ...styles$f.resetBtn, ...showReset ? styles$f.resetBtnVisible : {} },
|
|
9108
9108
|
onClick: onReset,
|
|
9109
9109
|
title: "Reset to default",
|
|
9110
9110
|
tabIndex: showReset ? 0 : -1,
|
|
@@ -9139,8 +9139,8 @@ function SelectField({ value, options, dirty, overridden, onChange }) {
|
|
|
9139
9139
|
);
|
|
9140
9140
|
}
|
|
9141
9141
|
function ToggleField({ value, dirty, overridden, onChange }) {
|
|
9142
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
9143
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("label", { style: styles$
|
|
9142
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$f.toggleWrap, children: [
|
|
9143
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("label", { style: styles$f.toggle, children: [
|
|
9144
9144
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
9145
9145
|
"input",
|
|
9146
9146
|
{
|
|
@@ -9151,11 +9151,11 @@ function ToggleField({ value, dirty, overridden, onChange }) {
|
|
|
9151
9151
|
}
|
|
9152
9152
|
),
|
|
9153
9153
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: {
|
|
9154
|
-
...styles$
|
|
9154
|
+
...styles$f.toggleSlider,
|
|
9155
9155
|
background: value ? "var(--accent-muted)" : "#333",
|
|
9156
9156
|
borderColor: value ? "var(--accent)" : "#555"
|
|
9157
9157
|
}, children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: {
|
|
9158
|
-
...styles$
|
|
9158
|
+
...styles$f.toggleThumb,
|
|
9159
9159
|
transform: value ? "translateX(18px)" : "none",
|
|
9160
9160
|
background: value ? "var(--accent)" : "#888"
|
|
9161
9161
|
} }) })
|
|
@@ -9186,7 +9186,7 @@ function TextInput({ value, hint, dirty, overridden, onChange }) {
|
|
|
9186
9186
|
style: inputClass(dirty, overridden)
|
|
9187
9187
|
}
|
|
9188
9188
|
),
|
|
9189
|
-
hint && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$
|
|
9189
|
+
hint && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$f.fieldHint, children: hint })
|
|
9190
9190
|
] });
|
|
9191
9191
|
}
|
|
9192
9192
|
function ColorField({ value, dirty, overridden, onChange }) {
|
|
@@ -9201,12 +9201,12 @@ function ColorField({ value, dirty, overridden, onChange }) {
|
|
|
9201
9201
|
picker.addEventListener("change", () => picker.remove());
|
|
9202
9202
|
picker.click();
|
|
9203
9203
|
}
|
|
9204
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
9204
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$f.colorWrap, children: [
|
|
9205
9205
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
9206
9206
|
"div",
|
|
9207
9207
|
{
|
|
9208
9208
|
style: {
|
|
9209
|
-
...styles$
|
|
9209
|
+
...styles$f.colorSwatch,
|
|
9210
9210
|
background: isHex ? value : "#333"
|
|
9211
9211
|
},
|
|
9212
9212
|
onClick: openPicker,
|
|
@@ -9237,12 +9237,12 @@ function Tooltip({ text, children }) {
|
|
|
9237
9237
|
onMouseLeave: () => setVisible(false),
|
|
9238
9238
|
children: [
|
|
9239
9239
|
children,
|
|
9240
|
-
visible && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$
|
|
9240
|
+
visible && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$f.tooltip, children: text })
|
|
9241
9241
|
]
|
|
9242
9242
|
}
|
|
9243
9243
|
);
|
|
9244
9244
|
}
|
|
9245
|
-
const styles$
|
|
9245
|
+
const styles$f = {
|
|
9246
9246
|
section: {
|
|
9247
9247
|
marginBottom: "6px",
|
|
9248
9248
|
border: "1px solid var(--border-subtle)",
|
|
@@ -9433,21 +9433,21 @@ function ConfigView() {
|
|
|
9433
9433
|
}
|
|
9434
9434
|
const hasDirty = Object.keys(dirtyValues).length > 0;
|
|
9435
9435
|
if (error) {
|
|
9436
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
9437
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$
|
|
9438
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("pre", { style: styles$
|
|
9436
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$e.errorPage, children: [
|
|
9437
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$e.errorTitle, children: "Failed to load config" }),
|
|
9438
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("pre", { style: styles$e.errorMsg, children: error })
|
|
9439
9439
|
] });
|
|
9440
9440
|
}
|
|
9441
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
9442
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
9443
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$
|
|
9444
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$
|
|
9441
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$e.root, children: [
|
|
9442
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$e.header, children: [
|
|
9443
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$e.headerTitle, children: "Maestro Config" }),
|
|
9444
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$e.spacer }),
|
|
9445
9445
|
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: "btn btn-ghost btn-sm", onClick: handleDiscard, disabled: !hasDirty, children: "Discard" }),
|
|
9446
9446
|
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: "btn btn-primary btn-sm", onClick: handleSave, disabled: !hasDirty, children: "Save" })
|
|
9447
9447
|
] }),
|
|
9448
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
9449
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$
|
|
9450
|
-
["global", "project"].map((t2) => /* @__PURE__ */ jsxRuntimeExports.jsxs("label", { style: { ...styles$
|
|
9448
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$e.toolbar, children: [
|
|
9449
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$e.toolbarLabel, children: "Save to:" }),
|
|
9450
|
+
["global", "project"].map((t2) => /* @__PURE__ */ jsxRuntimeExports.jsxs("label", { style: { ...styles$e.radioLabel, ...target === t2 ? styles$e.radioLabelActive : {} }, children: [
|
|
9451
9451
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
9452
9452
|
"input",
|
|
9453
9453
|
{
|
|
@@ -9463,25 +9463,25 @@ function ConfigView() {
|
|
|
9463
9463
|
}
|
|
9464
9464
|
),
|
|
9465
9465
|
t2.charAt(0).toUpperCase() + t2.slice(1),
|
|
9466
|
-
state && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$
|
|
9466
|
+
state && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$e.targetPath, children: t2 === "global" ? state.globalConfigPath : state.projectConfigPath })
|
|
9467
9467
|
] }, t2)),
|
|
9468
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$
|
|
9468
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$e.spacer }),
|
|
9469
9469
|
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: "btn btn-ghost btn-sm", onClick: () => setExpandAll(true), children: "Expand All" }),
|
|
9470
9470
|
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: "btn btn-ghost btn-sm", onClick: () => setExpandAll(false), children: "Collapse All" })
|
|
9471
9471
|
] }),
|
|
9472
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$
|
|
9472
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$e.searchRow, children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
9473
9473
|
"input",
|
|
9474
9474
|
{
|
|
9475
9475
|
type: "text",
|
|
9476
9476
|
placeholder: "Search config keys…",
|
|
9477
9477
|
value: search,
|
|
9478
9478
|
onChange: (e) => setSearch(e.target.value),
|
|
9479
|
-
style: styles$
|
|
9479
|
+
style: styles$e.searchInput,
|
|
9480
9480
|
autoComplete: "off",
|
|
9481
9481
|
spellCheck: false
|
|
9482
9482
|
}
|
|
9483
9483
|
) }),
|
|
9484
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$
|
|
9484
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$e.content, children: loading ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$e.loading, children: "Loading configuration…" }) : state ? /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
9485
9485
|
ConfigEditor,
|
|
9486
9486
|
{
|
|
9487
9487
|
state,
|
|
@@ -9510,14 +9510,14 @@ function ConfigView() {
|
|
|
9510
9510
|
}
|
|
9511
9511
|
) : null }),
|
|
9512
9512
|
toast && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: {
|
|
9513
|
-
...styles$
|
|
9513
|
+
...styles$e.toast,
|
|
9514
9514
|
borderColor: toast.isError ? "var(--red)" : "var(--green)",
|
|
9515
9515
|
color: toast.isError ? "var(--red)" : "var(--green)",
|
|
9516
9516
|
background: toast.isError ? "#2d0a0a" : "#0a2d0a"
|
|
9517
9517
|
}, children: toast.msg })
|
|
9518
9518
|
] });
|
|
9519
9519
|
}
|
|
9520
|
-
const styles$
|
|
9520
|
+
const styles$e = {
|
|
9521
9521
|
root: {
|
|
9522
9522
|
display: "flex",
|
|
9523
9523
|
flexDirection: "column",
|
|
@@ -9638,9 +9638,9 @@ function CopyBlock({ text }) {
|
|
|
9638
9638
|
setTimeout(() => setCopied(false), 2e3);
|
|
9639
9639
|
});
|
|
9640
9640
|
}
|
|
9641
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
9642
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("pre", { style: styles$
|
|
9643
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { style: styles$
|
|
9641
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$d.copyBlock, children: [
|
|
9642
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("pre", { style: styles$d.code, children: text }),
|
|
9643
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { style: styles$d.copyBtn, onClick: handleCopy, title: "Copy to clipboard", children: copied ? "✓ Copied" : "Copy" })
|
|
9644
9644
|
] });
|
|
9645
9645
|
}
|
|
9646
9646
|
const STATUS_DOT = {
|
|
@@ -9654,15 +9654,15 @@ function MachineCard({ machine, onSetup, onRemove, onPing, onAddressSet, onRdp,
|
|
|
9654
9654
|
const [showTunnelSetup, setShowTunnelSetup] = reactExports.useState(false);
|
|
9655
9655
|
const sshReady = machine.onboarded && (machine.authMethod === "dev-tunnel" ? !!machine.tunnelId : machine.address.length > 0);
|
|
9656
9656
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
9657
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
9658
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
9659
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: { ...styles$
|
|
9660
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
9661
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
9662
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$
|
|
9663
|
-
machine.projectName && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$
|
|
9657
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$d.card, children: [
|
|
9658
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$d.left, children: [
|
|
9659
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: { ...styles$d.statusDot, color }, children: label.split(" ")[0] }),
|
|
9660
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$d.info, children: [
|
|
9661
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$d.nameRow, children: [
|
|
9662
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$d.name, children: machine.name }),
|
|
9663
|
+
machine.projectName && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$d.project, children: machine.projectName })
|
|
9664
9664
|
] }),
|
|
9665
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
9665
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$d.meta, children: [
|
|
9666
9666
|
machine.authMethod === "dev-tunnel" ? machine.tunnelId ? /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { children: [
|
|
9667
9667
|
"tunnel: ",
|
|
9668
9668
|
machine.tunnelId
|
|
@@ -9683,10 +9683,10 @@ function MachineCard({ machine, onSetup, onRemove, onPing, onAddressSet, onRdp,
|
|
|
9683
9683
|
] })
|
|
9684
9684
|
] })
|
|
9685
9685
|
] }),
|
|
9686
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
9687
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: { ...styles$
|
|
9688
|
-
machine.type !== "host" && (sshReady ? /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$
|
|
9689
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
9686
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$d.right, children: [
|
|
9687
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: { ...styles$d.statusLabel, color }, children: label.split(" ").slice(1).join(" ") }),
|
|
9688
|
+
machine.type !== "host" && (sshReady ? /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$d.sshReadyBadge, children: "✓ Agent Ready" }) : /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$d.sshNotReadyBadge, children: "⚠ Agent Setup Required" })),
|
|
9689
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$d.actions, children: [
|
|
9690
9690
|
machine.type !== "host" && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
9691
9691
|
"button",
|
|
9692
9692
|
{
|
|
@@ -9765,16 +9765,16 @@ function TunnelSetupPanel({ machine, onClose, onSaved }) {
|
|
|
9765
9765
|
setSaving(false);
|
|
9766
9766
|
}
|
|
9767
9767
|
}
|
|
9768
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$
|
|
9769
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
9768
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$d.overlay, children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$d.panel, children: [
|
|
9769
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$d.panelHeader, children: [
|
|
9770
9770
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { children: [
|
|
9771
9771
|
"Setup Agent — ",
|
|
9772
9772
|
machine.name
|
|
9773
9773
|
] }),
|
|
9774
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { style: styles$
|
|
9774
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { style: styles$d.closeBtn, onClick: onClose, children: "✕" })
|
|
9775
9775
|
] }),
|
|
9776
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
9777
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("p", { style: styles$
|
|
9776
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$d.panelBody, children: [
|
|
9777
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("p", { style: styles$d.step, children: [
|
|
9778
9778
|
/* @__PURE__ */ jsxRuntimeExports.jsx("strong", { children: "Step 1." }),
|
|
9779
9779
|
" RDP into ",
|
|
9780
9780
|
/* @__PURE__ */ jsxRuntimeExports.jsx("strong", { children: machine.name }),
|
|
@@ -9783,24 +9783,24 @@ function TunnelSetupPanel({ machine, onClose, onSaved }) {
|
|
|
9783
9783
|
" (right-click → Run as Administrator) and install Maestro:"
|
|
9784
9784
|
] }),
|
|
9785
9785
|
/* @__PURE__ */ jsxRuntimeExports.jsx(CopyBlock, { text: `npm install -g @rajat-rastogi/maestro` }),
|
|
9786
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("p", { style: styles$
|
|
9786
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("p", { style: styles$d.step, children: [
|
|
9787
9787
|
/* @__PURE__ */ jsxRuntimeExports.jsx("strong", { children: "Step 2." }),
|
|
9788
9788
|
" In the same elevated shell, run the agent setup wizard. It will install devtunnel, deploy the agent, configure Claude hooks, and register an auto-start task. ",
|
|
9789
9789
|
/* @__PURE__ */ jsxRuntimeExports.jsx("em", { children: "Admin elevation is required for the Scheduled Task registration." })
|
|
9790
9790
|
] }),
|
|
9791
9791
|
/* @__PURE__ */ jsxRuntimeExports.jsx(CopyBlock, { text: `maestro --install-agent` }),
|
|
9792
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("p", { style: styles$
|
|
9792
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("p", { style: styles$d.step, children: [
|
|
9793
9793
|
"When prompted for the tunnel name, use: ",
|
|
9794
9794
|
/* @__PURE__ */ jsxRuntimeExports.jsx("code", { children: suggestedId })
|
|
9795
9795
|
] }),
|
|
9796
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("p", { style: styles$
|
|
9796
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("p", { style: styles$d.step, children: [
|
|
9797
9797
|
/* @__PURE__ */ jsxRuntimeExports.jsx("strong", { children: "Step 3." }),
|
|
9798
9798
|
" Enter the tunnel ID below and click ",
|
|
9799
9799
|
/* @__PURE__ */ jsxRuntimeExports.jsx("strong", { children: "Save & Ping" }),
|
|
9800
9800
|
" to verify connectivity:"
|
|
9801
9801
|
] }),
|
|
9802
9802
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "8px", marginTop: "4px" }, children: [
|
|
9803
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("label", { style: styles$
|
|
9803
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("label", { style: styles$d.inputLabel, children: "Tunnel ID (from the wizard output)" }),
|
|
9804
9804
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
9805
9805
|
"input",
|
|
9806
9806
|
{
|
|
@@ -9808,12 +9808,12 @@ function TunnelSetupPanel({ machine, onClose, onSaved }) {
|
|
|
9808
9808
|
value: tunnelId,
|
|
9809
9809
|
onChange: (e) => setTunnelId(e.target.value),
|
|
9810
9810
|
placeholder: suggestedId,
|
|
9811
|
-
style: { ...styles$
|
|
9811
|
+
style: { ...styles$d.input, fontFamily: "monospace", fontSize: "12px" }
|
|
9812
9812
|
}
|
|
9813
9813
|
)
|
|
9814
9814
|
] }),
|
|
9815
|
-
pingResult === "online" && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$
|
|
9816
|
-
pingResult === "offline" && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
9815
|
+
pingResult === "online" && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$d.pingSuccess, children: "✓ Agent connected — tunnel is reachable." }),
|
|
9816
|
+
pingResult === "offline" && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$d.pingFailure, children: [
|
|
9817
9817
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("p", { children: [
|
|
9818
9818
|
"✕ Could not reach agent on ",
|
|
9819
9819
|
machine.name,
|
|
@@ -9846,7 +9846,7 @@ function TunnelSetupPanel({ machine, onClose, onSaved }) {
|
|
|
9846
9846
|
] })
|
|
9847
9847
|
] })
|
|
9848
9848
|
] }),
|
|
9849
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
9849
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$d.panelFooter, children: [
|
|
9850
9850
|
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: "btn btn-ghost btn-sm", onClick: onClose, children: pingResult === "online" ? "Done" : "Cancel" }),
|
|
9851
9851
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
9852
9852
|
"button",
|
|
@@ -9860,7 +9860,7 @@ function TunnelSetupPanel({ machine, onClose, onSaved }) {
|
|
|
9860
9860
|
] })
|
|
9861
9861
|
] }) });
|
|
9862
9862
|
}
|
|
9863
|
-
const styles$
|
|
9863
|
+
const styles$d = {
|
|
9864
9864
|
card: {
|
|
9865
9865
|
display: "flex",
|
|
9866
9866
|
alignItems: "center",
|
|
@@ -10087,13 +10087,13 @@ function OnboardingPanel({ onClose, onAdded }) {
|
|
|
10087
10087
|
setAdding(false);
|
|
10088
10088
|
}
|
|
10089
10089
|
}
|
|
10090
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$
|
|
10091
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
10092
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$
|
|
10093
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { style: styles$
|
|
10090
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$c.overlay, children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$c.panel, children: [
|
|
10091
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$c.header, children: [
|
|
10092
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$c.title, children: "Add Windows 365 Cloud PC" }),
|
|
10093
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { style: styles$c.closeBtn, onClick: onClose, children: "✕" })
|
|
10094
10094
|
] }),
|
|
10095
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
10096
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
10095
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$c.body, children: [
|
|
10096
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$c.setupNote, children: [
|
|
10097
10097
|
/* @__PURE__ */ jsxRuntimeExports.jsx("strong", { children: "How to find your Device name:" }),
|
|
10098
10098
|
" Open the Windows App → find your Cloud PC → click ",
|
|
10099
10099
|
/* @__PURE__ */ jsxRuntimeExports.jsx("strong", { children: "⋯" }),
|
|
@@ -10105,8 +10105,8 @@ function OnboardingPanel({ onClose, onAdded }) {
|
|
|
10105
10105
|
/* @__PURE__ */ jsxRuntimeExports.jsx("code", { children: "CPC-username-XXXX" }),
|
|
10106
10106
|
")."
|
|
10107
10107
|
] }),
|
|
10108
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
10109
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("label", { style: styles$
|
|
10108
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$c.field, children: [
|
|
10109
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("label", { style: styles$c.label, children: "Display name" }),
|
|
10110
10110
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
10111
10111
|
"input",
|
|
10112
10112
|
{
|
|
@@ -10117,10 +10117,10 @@ function OnboardingPanel({ onClose, onAdded }) {
|
|
|
10117
10117
|
placeholder: "My Cloud PC"
|
|
10118
10118
|
}
|
|
10119
10119
|
),
|
|
10120
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$
|
|
10120
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$c.hint, children: 'The "Cloud PC name" shown in View Details — just for your reference.' })
|
|
10121
10121
|
] }),
|
|
10122
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
10123
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("label", { style: styles$
|
|
10122
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$c.field, children: [
|
|
10123
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("label", { style: styles$c.label, children: "Device name" }),
|
|
10124
10124
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
10125
10125
|
"input",
|
|
10126
10126
|
{
|
|
@@ -10131,13 +10131,13 @@ function OnboardingPanel({ onClose, onAdded }) {
|
|
|
10131
10131
|
style: { fontFamily: "monospace", fontSize: "13px" }
|
|
10132
10132
|
}
|
|
10133
10133
|
),
|
|
10134
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { style: styles$
|
|
10134
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { style: styles$c.hint, children: [
|
|
10135
10135
|
"From Windows App → ⋯ → View Details → ",
|
|
10136
10136
|
/* @__PURE__ */ jsxRuntimeExports.jsx("strong", { children: "Device name" })
|
|
10137
10137
|
] })
|
|
10138
10138
|
] }),
|
|
10139
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
10140
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("label", { style: styles$
|
|
10139
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$c.field, children: [
|
|
10140
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("label", { style: styles$c.label, children: "Username (UPN) — optional" }),
|
|
10141
10141
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
10142
10142
|
"input",
|
|
10143
10143
|
{
|
|
@@ -10147,18 +10147,18 @@ function OnboardingPanel({ onClose, onAdded }) {
|
|
|
10147
10147
|
placeholder: "you@contoso.com"
|
|
10148
10148
|
}
|
|
10149
10149
|
),
|
|
10150
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$
|
|
10150
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$c.hint, children: "Pre-fills the login field when RDP opens. Leave blank if unsure." })
|
|
10151
10151
|
] }),
|
|
10152
|
-
error && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$
|
|
10152
|
+
error && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$c.error, children: error })
|
|
10153
10153
|
] }),
|
|
10154
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
10154
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$c.footer, children: [
|
|
10155
10155
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: { flex: 1 } }),
|
|
10156
10156
|
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: "btn btn-ghost", onClick: onClose, children: "Cancel" }),
|
|
10157
10157
|
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: "btn btn-primary", disabled: adding || !cloudPcId.trim(), onClick: handleAdd, children: adding ? "Adding…" : "Add Cloud PC" })
|
|
10158
10158
|
] })
|
|
10159
10159
|
] }) });
|
|
10160
10160
|
}
|
|
10161
|
-
const styles$
|
|
10161
|
+
const styles$c = {
|
|
10162
10162
|
overlay: {
|
|
10163
10163
|
position: "fixed",
|
|
10164
10164
|
inset: 0,
|
|
@@ -10325,11 +10325,11 @@ function MachinesView({ onMachineAdded, onMachineRemoved }) {
|
|
|
10325
10325
|
setDiscoveryError(`RDP launch failed: ${String(err)}`);
|
|
10326
10326
|
}
|
|
10327
10327
|
}
|
|
10328
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
10329
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
10330
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
10328
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$b.root, children: [
|
|
10329
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$b.header, children: [
|
|
10330
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$b.headerLeft, children: [
|
|
10331
10331
|
/* @__PURE__ */ jsxRuntimeExports.jsx("h1", { style: { fontSize: "18px", fontWeight: 600 }, children: "Machines" }),
|
|
10332
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { style: styles$
|
|
10332
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { style: styles$b.countBadge, children: [
|
|
10333
10333
|
onlineCount,
|
|
10334
10334
|
"/",
|
|
10335
10335
|
machines.length,
|
|
@@ -10356,12 +10356,12 @@ function MachinesView({ onMachineAdded, onMachineRemoved }) {
|
|
|
10356
10356
|
)
|
|
10357
10357
|
] })
|
|
10358
10358
|
] }),
|
|
10359
|
-
discoveryError && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$
|
|
10359
|
+
discoveryError && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$b.discoveryBanner, children: /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { children: [
|
|
10360
10360
|
"⚠ ",
|
|
10361
10361
|
discoveryError
|
|
10362
10362
|
] }) }),
|
|
10363
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
10364
|
-
machines.length === 0 && discoveryState !== "loading" ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
10363
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$b.list, children: [
|
|
10364
|
+
machines.length === 0 && discoveryState !== "loading" ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$b.empty, children: [
|
|
10365
10365
|
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { children: "No machines found." }),
|
|
10366
10366
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("p", { style: { color: "var(--text-muted)", fontSize: "13px", marginTop: "8px" }, children: [
|
|
10367
10367
|
"Sign in with ",
|
|
@@ -10381,7 +10381,7 @@ function MachinesView({ onMachineAdded, onMachineRemoved }) {
|
|
|
10381
10381
|
},
|
|
10382
10382
|
machine.id
|
|
10383
10383
|
)),
|
|
10384
|
-
discoveryState === "loading" && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$
|
|
10384
|
+
discoveryState === "loading" && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$b.discovering, children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: { opacity: 0.5 }, children: "Discovering Azure Dev Boxes & Cloud PCs…" }) })
|
|
10385
10385
|
] }),
|
|
10386
10386
|
showOnboarding && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
10387
10387
|
OnboardingPanel,
|
|
@@ -10395,7 +10395,7 @@ function MachinesView({ onMachineAdded, onMachineRemoved }) {
|
|
|
10395
10395
|
)
|
|
10396
10396
|
] });
|
|
10397
10397
|
}
|
|
10398
|
-
const styles$
|
|
10398
|
+
const styles$b = {
|
|
10399
10399
|
root: {
|
|
10400
10400
|
display: "flex",
|
|
10401
10401
|
flexDirection: "column",
|
|
@@ -10532,7 +10532,8 @@ function useTerminalTile({
|
|
|
10532
10532
|
sessionId,
|
|
10533
10533
|
interactive,
|
|
10534
10534
|
refreshKey = 0,
|
|
10535
|
-
onResize
|
|
10535
|
+
onResize,
|
|
10536
|
+
onLargePaste
|
|
10536
10537
|
}) {
|
|
10537
10538
|
const handleRef = reactExports.useRef(null);
|
|
10538
10539
|
const unsubRef = reactExports.useRef(null);
|
|
@@ -10542,6 +10543,7 @@ function useTerminalTile({
|
|
|
10542
10543
|
let terminal = null;
|
|
10543
10544
|
let fitAddon = null;
|
|
10544
10545
|
let destroyed = false;
|
|
10546
|
+
let batchRaf = 0;
|
|
10545
10547
|
async function init() {
|
|
10546
10548
|
const { Terminal } = await __vitePreload(async () => {
|
|
10547
10549
|
const { Terminal: Terminal2 } = await import("./xterm-BgoKG_Sn.js").then((n2) => n2.x);
|
|
@@ -10593,6 +10595,14 @@ function useTerminalTile({
|
|
|
10593
10595
|
terminal.write(buffer);
|
|
10594
10596
|
}
|
|
10595
10597
|
let liveEventCount = 0;
|
|
10598
|
+
let batchBuffer = "";
|
|
10599
|
+
const flushBatch = () => {
|
|
10600
|
+
if (batchBuffer && terminal) {
|
|
10601
|
+
terminal.write(batchBuffer);
|
|
10602
|
+
batchBuffer = "";
|
|
10603
|
+
}
|
|
10604
|
+
batchRaf = 0;
|
|
10605
|
+
};
|
|
10596
10606
|
const unsubData = window.maestro.sessions.onData((ev) => {
|
|
10597
10607
|
const event = ev;
|
|
10598
10608
|
if (event.sessionId === sessionId && terminal) {
|
|
@@ -10600,7 +10610,13 @@ function useTerminalTile({
|
|
|
10600
10610
|
if (liveEventCount <= 3) {
|
|
10601
10611
|
console.log(`[useTerminalTile] onData #${liveEventCount} for ${sessionId}: ${event.data.length} chars`);
|
|
10602
10612
|
}
|
|
10603
|
-
|
|
10613
|
+
if (event.data.length < 128) {
|
|
10614
|
+
if (batchBuffer) flushBatch();
|
|
10615
|
+
terminal.write(event.data);
|
|
10616
|
+
} else {
|
|
10617
|
+
batchBuffer += event.data;
|
|
10618
|
+
if (!batchRaf) batchRaf = requestAnimationFrame(flushBatch);
|
|
10619
|
+
}
|
|
10604
10620
|
}
|
|
10605
10621
|
});
|
|
10606
10622
|
unsubRef.current = unsubData;
|
|
@@ -10615,14 +10631,74 @@ function useTerminalTile({
|
|
|
10615
10631
|
}
|
|
10616
10632
|
});
|
|
10617
10633
|
resizeObs.observe(container);
|
|
10634
|
+
const sendPasteText = async (payload) => {
|
|
10635
|
+
const CHUNK = 512;
|
|
10636
|
+
for (let i = 0; i < payload.length; i += CHUNK) {
|
|
10637
|
+
const chunk = payload.slice(i, i + CHUNK);
|
|
10638
|
+
window.maestro.sessions.sendInput(sessionId, chunk);
|
|
10639
|
+
if (i + CHUNK < payload.length) {
|
|
10640
|
+
await new Promise((r2) => setTimeout(r2, 10));
|
|
10641
|
+
}
|
|
10642
|
+
}
|
|
10643
|
+
};
|
|
10618
10644
|
if (interactive) {
|
|
10619
10645
|
terminal.onData((data) => {
|
|
10620
10646
|
window.maestro.sessions.sendInput(sessionId, data);
|
|
10621
10647
|
});
|
|
10648
|
+
terminal.attachCustomKeyEventHandler((e) => {
|
|
10649
|
+
if ((e.ctrlKey || e.metaKey) && e.key === "v" && e.type === "keydown") {
|
|
10650
|
+
return false;
|
|
10651
|
+
}
|
|
10652
|
+
return true;
|
|
10653
|
+
});
|
|
10654
|
+
const refocus = () => {
|
|
10655
|
+
setTimeout(() => container.querySelector("textarea")?.focus(), 50);
|
|
10656
|
+
};
|
|
10657
|
+
const pasteHandler = (e) => {
|
|
10658
|
+
if (!container.contains(document.activeElement)) return;
|
|
10659
|
+
const ce2 = e;
|
|
10660
|
+
ce2.preventDefault();
|
|
10661
|
+
ce2.stopImmediatePropagation();
|
|
10662
|
+
const text = ce2.clipboardData?.getData("text") ?? "";
|
|
10663
|
+
if (!text) return;
|
|
10664
|
+
const lines = text.split("\n");
|
|
10665
|
+
const sendPaste = () => {
|
|
10666
|
+
const wrapped = `\x1B[200~${text}\x1B[201~`;
|
|
10667
|
+
sendPasteText(wrapped).then(refocus);
|
|
10668
|
+
};
|
|
10669
|
+
if (lines.length > 5 && onLargePaste) {
|
|
10670
|
+
onLargePaste(text, sendPaste);
|
|
10671
|
+
} else if (lines.length > 1) {
|
|
10672
|
+
sendPaste();
|
|
10673
|
+
} else {
|
|
10674
|
+
sendPasteText(text).then(refocus);
|
|
10675
|
+
}
|
|
10676
|
+
};
|
|
10677
|
+
window.addEventListener("paste", pasteHandler, true);
|
|
10678
|
+
const prevUnsub = unsubRef.current;
|
|
10679
|
+
unsubRef.current = () => {
|
|
10680
|
+
prevUnsub?.();
|
|
10681
|
+
window.removeEventListener("paste", pasteHandler, true);
|
|
10682
|
+
};
|
|
10622
10683
|
}
|
|
10623
10684
|
handleRef.current = {
|
|
10624
10685
|
fit() {
|
|
10625
10686
|
if (fitAddon && terminal) fitAddon.fit();
|
|
10687
|
+
},
|
|
10688
|
+
getSelection() {
|
|
10689
|
+
return terminal?.getSelection() ?? "";
|
|
10690
|
+
},
|
|
10691
|
+
clearTerminal() {
|
|
10692
|
+
terminal?.clear();
|
|
10693
|
+
},
|
|
10694
|
+
paste(text) {
|
|
10695
|
+
if (!text) return;
|
|
10696
|
+
const lines = text.split("\n");
|
|
10697
|
+
if (lines.length > 1) {
|
|
10698
|
+
sendPasteText(`\x1B[200~${text}\x1B[201~`);
|
|
10699
|
+
} else {
|
|
10700
|
+
sendPasteText(text);
|
|
10701
|
+
}
|
|
10626
10702
|
}
|
|
10627
10703
|
};
|
|
10628
10704
|
const prev = unsubRef.current;
|
|
@@ -10634,6 +10710,7 @@ function useTerminalTile({
|
|
|
10634
10710
|
init().catch(console.error);
|
|
10635
10711
|
return () => {
|
|
10636
10712
|
destroyed = true;
|
|
10713
|
+
if (batchRaf) cancelAnimationFrame(batchRaf);
|
|
10637
10714
|
if (interactive) {
|
|
10638
10715
|
window.maestro.sessions.resize(sessionId, 120, 30).catch(() => {
|
|
10639
10716
|
});
|
|
@@ -10649,7 +10726,9 @@ function useTerminalTile({
|
|
|
10649
10726
|
const useSessionsStore = create((set) => ({
|
|
10650
10727
|
sessions: [],
|
|
10651
10728
|
activeFullscreenId: null,
|
|
10729
|
+
splitIds: null,
|
|
10652
10730
|
filterTags: {},
|
|
10731
|
+
filterStates: /* @__PURE__ */ new Set(),
|
|
10653
10732
|
setSessions(sessions) {
|
|
10654
10733
|
set({ sessions });
|
|
10655
10734
|
},
|
|
@@ -10677,24 +10756,130 @@ const useSessionsStore = create((set) => ({
|
|
|
10677
10756
|
}));
|
|
10678
10757
|
},
|
|
10679
10758
|
setFullscreen(id2) {
|
|
10680
|
-
set({ activeFullscreenId: id2 });
|
|
10759
|
+
set({ activeFullscreenId: id2, splitIds: null });
|
|
10760
|
+
},
|
|
10761
|
+
setSplit(ids) {
|
|
10762
|
+
set({ splitIds: ids, activeFullscreenId: null });
|
|
10681
10763
|
},
|
|
10682
10764
|
setFilterTags(tags) {
|
|
10683
10765
|
set({ filterTags: tags });
|
|
10766
|
+
},
|
|
10767
|
+
toggleFilterState(state) {
|
|
10768
|
+
set((s) => {
|
|
10769
|
+
const next = new Set(s.filterStates);
|
|
10770
|
+
if (next.has(state)) next.delete(state);
|
|
10771
|
+
else next.add(state);
|
|
10772
|
+
return { filterStates: next };
|
|
10773
|
+
});
|
|
10774
|
+
},
|
|
10775
|
+
clearFilterStates() {
|
|
10776
|
+
set({ filterStates: /* @__PURE__ */ new Set() });
|
|
10684
10777
|
}
|
|
10685
10778
|
}));
|
|
10686
|
-
function filterSessions(sessions, filterTags) {
|
|
10779
|
+
function filterSessions(sessions, filterTags, filterStates) {
|
|
10687
10780
|
const filterEntries = Object.entries(filterTags).filter(([k2, v2]) => k2 && (v2 || v2 === ""));
|
|
10688
|
-
|
|
10689
|
-
|
|
10690
|
-
|
|
10691
|
-
|
|
10692
|
-
|
|
10693
|
-
|
|
10694
|
-
return
|
|
10695
|
-
|
|
10696
|
-
|
|
10781
|
+
const hasTagFilter = filterEntries.length > 0;
|
|
10782
|
+
const hasStateFilter = filterStates && filterStates.size > 0;
|
|
10783
|
+
if (!hasTagFilter && !hasStateFilter) return sessions;
|
|
10784
|
+
return sessions.filter((s) => {
|
|
10785
|
+
if (hasStateFilter && !filterStates.has(s.state)) return false;
|
|
10786
|
+
if (hasTagFilter) {
|
|
10787
|
+
return filterEntries.every(([key, value]) => {
|
|
10788
|
+
const tagVal = s.tags[key];
|
|
10789
|
+
if (tagVal === void 0) return false;
|
|
10790
|
+
if (value === "" || value === "*") return true;
|
|
10791
|
+
return tagVal === value;
|
|
10792
|
+
});
|
|
10793
|
+
}
|
|
10794
|
+
return true;
|
|
10795
|
+
});
|
|
10796
|
+
}
|
|
10797
|
+
function ContextMenu({ x: x2, y: y2, items, onClose }) {
|
|
10798
|
+
const menuRef = reactExports.useRef(null);
|
|
10799
|
+
const [pos, setPos] = reactExports.useState({ left: x2, top: y2 });
|
|
10800
|
+
reactExports.useLayoutEffect(() => {
|
|
10801
|
+
if (!menuRef.current) return;
|
|
10802
|
+
const rect = menuRef.current.getBoundingClientRect();
|
|
10803
|
+
let left = x2;
|
|
10804
|
+
let top = y2;
|
|
10805
|
+
if (left + rect.width > window.innerWidth - 8) left = window.innerWidth - rect.width - 8;
|
|
10806
|
+
if (top + rect.height > window.innerHeight - 8) top = window.innerHeight - rect.height - 8;
|
|
10807
|
+
if (left < 8) left = 8;
|
|
10808
|
+
if (top < 8) top = 8;
|
|
10809
|
+
setPos({ left, top });
|
|
10810
|
+
}, [x2, y2]);
|
|
10811
|
+
reactExports.useEffect(() => {
|
|
10812
|
+
function onMouseDown(e) {
|
|
10813
|
+
if (menuRef.current && !menuRef.current.contains(e.target)) {
|
|
10814
|
+
onClose();
|
|
10815
|
+
}
|
|
10816
|
+
}
|
|
10817
|
+
function onKeyDown(e) {
|
|
10818
|
+
if (e.key === "Escape") onClose();
|
|
10819
|
+
}
|
|
10820
|
+
document.addEventListener("mousedown", onMouseDown);
|
|
10821
|
+
document.addEventListener("keydown", onKeyDown);
|
|
10822
|
+
return () => {
|
|
10823
|
+
document.removeEventListener("mousedown", onMouseDown);
|
|
10824
|
+
document.removeEventListener("keydown", onKeyDown);
|
|
10825
|
+
};
|
|
10826
|
+
}, [onClose]);
|
|
10827
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { ref: menuRef, style: { ...styles$a.menu, left: pos.left, top: pos.top }, children: items.map(
|
|
10828
|
+
(item, i) => item.divider ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$a.divider }, i) : /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
10829
|
+
"button",
|
|
10830
|
+
{
|
|
10831
|
+
style: { ...styles$a.item, ...item.danger ? { color: "var(--state-error)" } : {} },
|
|
10832
|
+
onClick: () => {
|
|
10833
|
+
item.onClick();
|
|
10834
|
+
onClose();
|
|
10835
|
+
},
|
|
10836
|
+
children: [
|
|
10837
|
+
item.icon && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$a.icon, children: item.icon }),
|
|
10838
|
+
item.label
|
|
10839
|
+
]
|
|
10840
|
+
},
|
|
10841
|
+
i
|
|
10842
|
+
)
|
|
10843
|
+
) });
|
|
10697
10844
|
}
|
|
10845
|
+
const styles$a = {
|
|
10846
|
+
menu: {
|
|
10847
|
+
position: "fixed",
|
|
10848
|
+
zIndex: 400,
|
|
10849
|
+
background: "var(--bg-elevated)",
|
|
10850
|
+
border: "1px solid var(--border)",
|
|
10851
|
+
borderRadius: "var(--radius-sm)",
|
|
10852
|
+
boxShadow: "0 4px 16px rgba(0,0,0,0.4)",
|
|
10853
|
+
minWidth: "160px",
|
|
10854
|
+
padding: "4px",
|
|
10855
|
+
display: "flex",
|
|
10856
|
+
flexDirection: "column"
|
|
10857
|
+
},
|
|
10858
|
+
item: {
|
|
10859
|
+
display: "flex",
|
|
10860
|
+
alignItems: "center",
|
|
10861
|
+
gap: "8px",
|
|
10862
|
+
background: "transparent",
|
|
10863
|
+
border: "none",
|
|
10864
|
+
color: "var(--text-secondary)",
|
|
10865
|
+
fontSize: "12px",
|
|
10866
|
+
padding: "6px 10px",
|
|
10867
|
+
textAlign: "left",
|
|
10868
|
+
borderRadius: "var(--radius-sm)",
|
|
10869
|
+
width: "100%",
|
|
10870
|
+
cursor: "pointer"
|
|
10871
|
+
},
|
|
10872
|
+
icon: {
|
|
10873
|
+
width: "16px",
|
|
10874
|
+
textAlign: "center",
|
|
10875
|
+
flexShrink: 0
|
|
10876
|
+
},
|
|
10877
|
+
divider: {
|
|
10878
|
+
height: "1px",
|
|
10879
|
+
background: "var(--border-subtle)",
|
|
10880
|
+
margin: "4px 0"
|
|
10881
|
+
}
|
|
10882
|
+
};
|
|
10698
10883
|
function TerminalTile({ session, onFullscreen, onClose, onRename, onEditTags }) {
|
|
10699
10884
|
const containerRef = reactExports.useRef(null);
|
|
10700
10885
|
const [menuOpen, setMenuOpen] = reactExports.useState(false);
|
|
@@ -10721,6 +10906,7 @@ function TerminalTile({ session, onFullscreen, onClose, onRename, onEditTags })
|
|
|
10721
10906
|
const customTags = Object.entries(session.tags).filter(
|
|
10722
10907
|
([k2]) => !["machine", "provider", "state"].includes(k2)
|
|
10723
10908
|
);
|
|
10909
|
+
const [ctxMenu, setCtxMenu] = reactExports.useState(null);
|
|
10724
10910
|
const handleRename = reactExports.useCallback(() => {
|
|
10725
10911
|
if (renameValue.trim() && renameValue !== session.name) {
|
|
10726
10912
|
window.maestro.sessions.rename(session.id, renameValue.trim());
|
|
@@ -10729,17 +10915,34 @@ function TerminalTile({ session, onFullscreen, onClose, onRename, onEditTags })
|
|
|
10729
10915
|
setRenaming(false);
|
|
10730
10916
|
setMenuOpen(false);
|
|
10731
10917
|
}, [renameValue, session]);
|
|
10918
|
+
const canAcknowledge = session.state === "waiting" || session.state === "permission";
|
|
10919
|
+
const ctxMenuItems = [
|
|
10920
|
+
{ label: "Fullscreen", icon: "🔍", onClick: onFullscreen },
|
|
10921
|
+
...canAcknowledge ? [{ label: "Acknowledge", icon: "✓", onClick: () => window.maestro.sessions.acknowledge(session.id) }] : [],
|
|
10922
|
+
{ label: "Rename", icon: "✏", onClick: () => setRenaming(true) },
|
|
10923
|
+
{ label: "Edit tags", icon: "🏷", onClick: onEditTags },
|
|
10924
|
+
{ divider: true, label: "", onClick: () => {
|
|
10925
|
+
} },
|
|
10926
|
+
{ label: "Stop & Clear", icon: "⏹", onClick: () => window.maestro.sessions.interrupt(session.id) },
|
|
10927
|
+
{ divider: true, label: "", onClick: () => {
|
|
10928
|
+
} },
|
|
10929
|
+
{ label: "Close", icon: "✕", onClick: onClose, danger: true }
|
|
10930
|
+
];
|
|
10732
10931
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
10733
10932
|
"div",
|
|
10734
10933
|
{
|
|
10735
|
-
style: styles$
|
|
10934
|
+
style: styles$9.tile,
|
|
10935
|
+
onContextMenu: (e) => {
|
|
10936
|
+
e.preventDefault();
|
|
10937
|
+
setCtxMenu({ x: e.clientX, y: e.clientY });
|
|
10938
|
+
},
|
|
10736
10939
|
onClick: (e) => {
|
|
10737
|
-
if (menuOpen || renaming) return;
|
|
10940
|
+
if (menuOpen || renaming || ctxMenu) return;
|
|
10738
10941
|
if (e.target.closest("[data-no-fullscreen]")) return;
|
|
10739
10942
|
onFullscreen();
|
|
10740
10943
|
},
|
|
10741
10944
|
children: [
|
|
10742
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
10945
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$9.header, onClick: (e) => e.stopPropagation(), children: [
|
|
10743
10946
|
renaming ? /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
10744
10947
|
"input",
|
|
10745
10948
|
{
|
|
@@ -10751,13 +10954,21 @@ function TerminalTile({ session, onFullscreen, onClose, onRename, onEditTags })
|
|
|
10751
10954
|
if (e.key === "Enter") handleRename();
|
|
10752
10955
|
if (e.key === "Escape") setRenaming(false);
|
|
10753
10956
|
},
|
|
10754
|
-
style: styles$
|
|
10957
|
+
style: styles$9.renameInput,
|
|
10755
10958
|
"data-no-fullscreen": ""
|
|
10756
10959
|
}
|
|
10757
|
-
) : /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$
|
|
10758
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
10960
|
+
) : /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$9.sessionName, title: session.name, children: session.name }),
|
|
10961
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
10962
|
+
StateBadge,
|
|
10963
|
+
{
|
|
10964
|
+
state: session.state,
|
|
10965
|
+
confidence: session.stateConfidence,
|
|
10966
|
+
enteredAt: session.stateEnteredAt,
|
|
10967
|
+
onAcknowledge: () => window.maestro.sessions.acknowledge(session.id)
|
|
10968
|
+
}
|
|
10969
|
+
),
|
|
10759
10970
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: { position: "relative" }, "data-no-fullscreen": "", children: [
|
|
10760
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { style: styles$
|
|
10971
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { style: styles$9.menuBtn, onClick: () => setMenuOpen((v2) => !v2), title: "Options", children: "⋯" }),
|
|
10761
10972
|
menuOpen && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
10762
10973
|
TileContextMenu,
|
|
10763
10974
|
{
|
|
@@ -10773,6 +10984,10 @@ function TerminalTile({ session, onFullscreen, onClose, onRename, onEditTags })
|
|
|
10773
10984
|
setMenuOpen(false);
|
|
10774
10985
|
onEditTags();
|
|
10775
10986
|
},
|
|
10987
|
+
onInterrupt: () => {
|
|
10988
|
+
setMenuOpen(false);
|
|
10989
|
+
window.maestro.sessions.interrupt(session.id);
|
|
10990
|
+
},
|
|
10776
10991
|
onClose: () => {
|
|
10777
10992
|
setMenuOpen(false);
|
|
10778
10993
|
onClose();
|
|
@@ -10781,32 +10996,35 @@ function TerminalTile({ session, onFullscreen, onClose, onRename, onEditTags })
|
|
|
10781
10996
|
)
|
|
10782
10997
|
] })
|
|
10783
10998
|
] }),
|
|
10784
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$
|
|
10785
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
10786
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
10787
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$
|
|
10788
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$
|
|
10999
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$9.previewWrapper, children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { ref: containerRef, style: styles$9.xtermContainer }) }),
|
|
11000
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$9.footer, children: [
|
|
11001
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$9.footerRow, children: [
|
|
11002
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$9.providerBadge, children: session.provider }),
|
|
11003
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$9.dirLabel, title: session.workingDirectory, children: shortDir(session.workingDirectory) }),
|
|
10789
11004
|
/* @__PURE__ */ jsxRuntimeExports.jsx(ElapsedTimer, { enteredAt: session.stateEnteredAt, state: session.state })
|
|
10790
11005
|
] }),
|
|
10791
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
10792
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { style: styles$
|
|
11006
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$9.footerRow, children: [
|
|
11007
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { style: styles$9.machineName, children: [
|
|
10793
11008
|
"⬡ ",
|
|
10794
11009
|
machineName
|
|
10795
11010
|
] }),
|
|
10796
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$
|
|
11011
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$9.tagRow, children: customTags.map(([k2, v2]) => /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$9.tag, children: v2 ? `${k2}:${v2}` : k2 }, k2)) })
|
|
10797
11012
|
] })
|
|
10798
|
-
] })
|
|
11013
|
+
] }),
|
|
11014
|
+
ctxMenu && /* @__PURE__ */ jsxRuntimeExports.jsx(ContextMenu, { x: ctxMenu.x, y: ctxMenu.y, items: ctxMenuItems, onClose: () => setCtxMenu(null) })
|
|
10799
11015
|
]
|
|
10800
11016
|
}
|
|
10801
11017
|
);
|
|
10802
11018
|
}
|
|
10803
|
-
function TileContextMenu({ onFullscreen, onRename, onEditTags, onClose }) {
|
|
10804
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
10805
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { style: styles$
|
|
10806
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { style: styles$
|
|
10807
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { style: styles$
|
|
10808
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$
|
|
10809
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { style:
|
|
11019
|
+
function TileContextMenu({ onFullscreen, onRename, onEditTags, onInterrupt, onClose }) {
|
|
11020
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$9.contextMenu, children: [
|
|
11021
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { style: styles$9.ctxItem, onClick: onFullscreen, children: "🔍 Go fullscreen" }),
|
|
11022
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { style: styles$9.ctxItem, onClick: onRename, children: "✏ Rename" }),
|
|
11023
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { style: styles$9.ctxItem, onClick: onEditTags, children: "🏷 Edit tags" }),
|
|
11024
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$9.ctxDivider }),
|
|
11025
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { style: styles$9.ctxItem, onClick: onInterrupt, children: "⏹ Stop & Clear" }),
|
|
11026
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$9.ctxDivider }),
|
|
11027
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { style: { ...styles$9.ctxItem, color: "var(--red)" }, onClick: onClose, children: "✕ Close" })
|
|
10810
11028
|
] });
|
|
10811
11029
|
}
|
|
10812
11030
|
function ElapsedTimer({ enteredAt, state }) {
|
|
@@ -10820,17 +11038,35 @@ function ElapsedTimer({ enteredAt, state }) {
|
|
|
10820
11038
|
const s = Math.floor(elapsed / 1e3);
|
|
10821
11039
|
const m2 = Math.floor(s / 60);
|
|
10822
11040
|
const label = m2 > 0 ? `${m2}:${String(s % 60).padStart(2, "0")}` : `${s}s`;
|
|
10823
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$
|
|
11041
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$9.elapsed, children: label });
|
|
10824
11042
|
}
|
|
10825
|
-
function StateBadge({ state, confidence, enteredAt }) {
|
|
11043
|
+
function StateBadge({ state, confidence, enteredAt, onAcknowledge }) {
|
|
10826
11044
|
const { icon, label, color } = STATE_BADGE[state] ?? STATE_BADGE.idle;
|
|
10827
11045
|
const suffix = confidence === "heuristic" ? "?" : "";
|
|
10828
|
-
|
|
10829
|
-
|
|
10830
|
-
"
|
|
10831
|
-
|
|
10832
|
-
|
|
10833
|
-
|
|
11046
|
+
const canAck = (state === "waiting" || state === "permission") && onAcknowledge;
|
|
11047
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
11048
|
+
"span",
|
|
11049
|
+
{
|
|
11050
|
+
style: {
|
|
11051
|
+
...styles$9.stateBadge,
|
|
11052
|
+
color,
|
|
11053
|
+
borderColor: `${color}40`,
|
|
11054
|
+
cursor: canAck ? "pointer" : "default"
|
|
11055
|
+
},
|
|
11056
|
+
onClick: canAck ? (e) => {
|
|
11057
|
+
e.stopPropagation();
|
|
11058
|
+
onAcknowledge();
|
|
11059
|
+
} : void 0,
|
|
11060
|
+
title: canAck ? "Click to acknowledge (dismiss to Idle)" : void 0,
|
|
11061
|
+
"data-no-fullscreen": "",
|
|
11062
|
+
children: [
|
|
11063
|
+
icon,
|
|
11064
|
+
" ",
|
|
11065
|
+
label,
|
|
11066
|
+
suffix
|
|
11067
|
+
]
|
|
11068
|
+
}
|
|
11069
|
+
);
|
|
10834
11070
|
}
|
|
10835
11071
|
const STATE_BADGE = {
|
|
10836
11072
|
working: { icon: "●", label: "Working", color: "var(--state-working)" },
|
|
@@ -10845,7 +11081,7 @@ function shortDir(dir) {
|
|
|
10845
11081
|
const parts = dir.replace(/\\/g, "/").split("/");
|
|
10846
11082
|
return parts.length > 2 ? `…/${parts.slice(-2).join("/")}` : dir;
|
|
10847
11083
|
}
|
|
10848
|
-
const styles$
|
|
11084
|
+
const styles$9 = {
|
|
10849
11085
|
tile: {
|
|
10850
11086
|
display: "flex",
|
|
10851
11087
|
flexDirection: "column",
|
|
@@ -11015,10 +11251,22 @@ const STATE_LABEL = {
|
|
|
11015
11251
|
};
|
|
11016
11252
|
function FullscreenOverlay({ session, onClose }) {
|
|
11017
11253
|
const containerRef = reactExports.useRef(null);
|
|
11018
|
-
|
|
11254
|
+
const [ctxMenu, setCtxMenu] = reactExports.useState(null);
|
|
11255
|
+
const [pendingPaste, setPendingPaste] = reactExports.useState(null);
|
|
11256
|
+
const refocusTerminal = () => {
|
|
11257
|
+
setTimeout(() => containerRef.current?.querySelector("textarea")?.focus(), 50);
|
|
11258
|
+
};
|
|
11259
|
+
const handleRef = useTerminalTile({
|
|
11019
11260
|
containerRef,
|
|
11020
11261
|
sessionId: session.id,
|
|
11021
|
-
interactive: true
|
|
11262
|
+
interactive: true,
|
|
11263
|
+
onLargePaste: (text, send) => setPendingPaste({
|
|
11264
|
+
text,
|
|
11265
|
+
send: () => {
|
|
11266
|
+
send();
|
|
11267
|
+
refocusTerminal();
|
|
11268
|
+
}
|
|
11269
|
+
})
|
|
11022
11270
|
});
|
|
11023
11271
|
reactExports.useEffect(() => {
|
|
11024
11272
|
const handler = (e) => {
|
|
@@ -11029,25 +11277,101 @@ function FullscreenOverlay({ session, onClose }) {
|
|
|
11029
11277
|
}, [onClose]);
|
|
11030
11278
|
const stateColor = STATE_BADGE_COLOR[session.state] ?? "var(--state-idle)";
|
|
11031
11279
|
const machineName = session.tags["machine"] ?? session.machineId;
|
|
11032
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
11033
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
11034
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$
|
|
11035
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$
|
|
11036
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$
|
|
11037
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$
|
|
11038
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$
|
|
11039
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$
|
|
11040
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { style: { ...styles$
|
|
11280
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$8.overlay, children: [
|
|
11281
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$8.header, children: [
|
|
11282
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$8.sessionName, children: session.name }),
|
|
11283
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$8.dot, children: "·" }),
|
|
11284
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$8.meta, children: session.provider }),
|
|
11285
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$8.dot, children: "·" }),
|
|
11286
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$8.meta, children: machineName }),
|
|
11287
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$8.dot, children: "·" }),
|
|
11288
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { style: { ...styles$8.stateBadge, color: stateColor }, children: [
|
|
11041
11289
|
STATE_LABEL[session.state] ?? session.state,
|
|
11042
11290
|
session.stateConfidence === "heuristic" ? "?" : ""
|
|
11043
11291
|
] }),
|
|
11044
11292
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: { flex: 1 } }),
|
|
11045
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { style: styles$
|
|
11293
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { style: styles$8.closeBtn, onClick: onClose, title: "Close fullscreen (Esc)", children: "⊠" })
|
|
11046
11294
|
] }),
|
|
11047
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
11295
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
11296
|
+
"div",
|
|
11297
|
+
{
|
|
11298
|
+
ref: containerRef,
|
|
11299
|
+
style: styles$8.terminalBody,
|
|
11300
|
+
onContextMenu: (e) => {
|
|
11301
|
+
e.preventDefault();
|
|
11302
|
+
setCtxMenu({ x: e.clientX, y: e.clientY });
|
|
11303
|
+
}
|
|
11304
|
+
}
|
|
11305
|
+
),
|
|
11306
|
+
ctxMenu && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
11307
|
+
ContextMenu,
|
|
11308
|
+
{
|
|
11309
|
+
x: ctxMenu.x,
|
|
11310
|
+
y: ctxMenu.y,
|
|
11311
|
+
items: [
|
|
11312
|
+
{
|
|
11313
|
+
label: "Copy",
|
|
11314
|
+
icon: "📋",
|
|
11315
|
+
onClick: () => {
|
|
11316
|
+
const sel = handleRef.current?.getSelection() ?? "";
|
|
11317
|
+
if (sel) navigator.clipboard.writeText(sel);
|
|
11318
|
+
}
|
|
11319
|
+
},
|
|
11320
|
+
{
|
|
11321
|
+
label: "Paste",
|
|
11322
|
+
icon: "📎",
|
|
11323
|
+
onClick: () => {
|
|
11324
|
+
navigator.clipboard.readText().then((text) => {
|
|
11325
|
+
if (!text) return;
|
|
11326
|
+
const lines = text.split("\n");
|
|
11327
|
+
if (lines.length > 5) {
|
|
11328
|
+
setPendingPaste({
|
|
11329
|
+
text,
|
|
11330
|
+
send: () => {
|
|
11331
|
+
handleRef.current?.paste(text);
|
|
11332
|
+
refocusTerminal();
|
|
11333
|
+
}
|
|
11334
|
+
});
|
|
11335
|
+
} else {
|
|
11336
|
+
handleRef.current?.paste(text);
|
|
11337
|
+
refocusTerminal();
|
|
11338
|
+
}
|
|
11339
|
+
});
|
|
11340
|
+
}
|
|
11341
|
+
},
|
|
11342
|
+
{ divider: true, label: "", onClick: () => {
|
|
11343
|
+
} },
|
|
11344
|
+
{
|
|
11345
|
+
label: "Clear terminal",
|
|
11346
|
+
icon: "🗑",
|
|
11347
|
+
onClick: () => handleRef.current?.clearTerminal()
|
|
11348
|
+
}
|
|
11349
|
+
],
|
|
11350
|
+
onClose: () => setCtxMenu(null)
|
|
11351
|
+
}
|
|
11352
|
+
),
|
|
11353
|
+
pendingPaste && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$8.pasteOverlay, children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$8.pasteDialog, children: [
|
|
11354
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$8.pasteTitle, children: [
|
|
11355
|
+
"Paste ",
|
|
11356
|
+
pendingPaste.text.split("\n").length,
|
|
11357
|
+
" lines?"
|
|
11358
|
+
] }),
|
|
11359
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("pre", { style: styles$8.pastePreview, children: [
|
|
11360
|
+
pendingPaste.text.split("\n").slice(0, 10).join("\n"),
|
|
11361
|
+
pendingPaste.text.split("\n").length > 10 ? "\n..." : ""
|
|
11362
|
+
] }),
|
|
11363
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$8.pasteActions, children: [
|
|
11364
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: "btn btn-ghost btn-sm", onClick: () => setPendingPaste(null), children: "Cancel" }),
|
|
11365
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: "btn btn-primary btn-sm", onClick: () => {
|
|
11366
|
+
pendingPaste.send();
|
|
11367
|
+
setPendingPaste(null);
|
|
11368
|
+
refocusTerminal();
|
|
11369
|
+
}, children: "Paste" })
|
|
11370
|
+
] })
|
|
11371
|
+
] }) })
|
|
11048
11372
|
] });
|
|
11049
11373
|
}
|
|
11050
|
-
const styles$
|
|
11374
|
+
const styles$8 = {
|
|
11051
11375
|
overlay: {
|
|
11052
11376
|
position: "fixed",
|
|
11053
11377
|
inset: 0,
|
|
@@ -11095,6 +11419,325 @@ const styles$5 = {
|
|
|
11095
11419
|
flex: 1,
|
|
11096
11420
|
overflow: "hidden",
|
|
11097
11421
|
padding: "8px"
|
|
11422
|
+
},
|
|
11423
|
+
pasteOverlay: {
|
|
11424
|
+
position: "fixed",
|
|
11425
|
+
inset: 0,
|
|
11426
|
+
background: "rgba(0,0,0,0.6)",
|
|
11427
|
+
display: "flex",
|
|
11428
|
+
alignItems: "center",
|
|
11429
|
+
justifyContent: "center",
|
|
11430
|
+
zIndex: 250
|
|
11431
|
+
},
|
|
11432
|
+
pasteDialog: {
|
|
11433
|
+
background: "var(--bg-surface)",
|
|
11434
|
+
border: "1px solid var(--border)",
|
|
11435
|
+
borderRadius: "var(--radius)",
|
|
11436
|
+
padding: "16px",
|
|
11437
|
+
maxWidth: "480px",
|
|
11438
|
+
width: "90%"
|
|
11439
|
+
},
|
|
11440
|
+
pasteTitle: {
|
|
11441
|
+
fontSize: "14px",
|
|
11442
|
+
fontWeight: 600,
|
|
11443
|
+
marginBottom: "12px",
|
|
11444
|
+
color: "var(--text-primary)"
|
|
11445
|
+
},
|
|
11446
|
+
pastePreview: {
|
|
11447
|
+
fontSize: "11px",
|
|
11448
|
+
fontFamily: "'Cascadia Code', Consolas, monospace",
|
|
11449
|
+
background: "var(--bg-base)",
|
|
11450
|
+
border: "1px solid var(--border)",
|
|
11451
|
+
borderRadius: "var(--radius-sm)",
|
|
11452
|
+
padding: "10px",
|
|
11453
|
+
maxHeight: "200px",
|
|
11454
|
+
overflow: "auto",
|
|
11455
|
+
color: "var(--text-secondary)",
|
|
11456
|
+
whiteSpace: "pre-wrap",
|
|
11457
|
+
margin: 0
|
|
11458
|
+
},
|
|
11459
|
+
pasteActions: {
|
|
11460
|
+
display: "flex",
|
|
11461
|
+
justifyContent: "flex-end",
|
|
11462
|
+
gap: "8px",
|
|
11463
|
+
marginTop: "12px"
|
|
11464
|
+
}
|
|
11465
|
+
};
|
|
11466
|
+
function SplitPaneOverlay({ left, right, onClose }) {
|
|
11467
|
+
const leftRef = reactExports.useRef(null);
|
|
11468
|
+
const rightRef = reactExports.useRef(null);
|
|
11469
|
+
const [focusSide, setFocusSide] = reactExports.useState("left");
|
|
11470
|
+
useTerminalTile({ containerRef: leftRef, sessionId: left.id, interactive: true });
|
|
11471
|
+
useTerminalTile({ containerRef: rightRef, sessionId: right.id, interactive: true });
|
|
11472
|
+
reactExports.useEffect(() => {
|
|
11473
|
+
function onKeyDown(e) {
|
|
11474
|
+
if (e.key === "Escape") {
|
|
11475
|
+
onClose();
|
|
11476
|
+
return;
|
|
11477
|
+
}
|
|
11478
|
+
const ctrlOrCmd = e.ctrlKey || e.metaKey;
|
|
11479
|
+
if (ctrlOrCmd && e.key === "1") {
|
|
11480
|
+
e.preventDefault();
|
|
11481
|
+
setFocusSide("left");
|
|
11482
|
+
}
|
|
11483
|
+
if (ctrlOrCmd && e.key === "2") {
|
|
11484
|
+
e.preventDefault();
|
|
11485
|
+
setFocusSide("right");
|
|
11486
|
+
}
|
|
11487
|
+
}
|
|
11488
|
+
window.addEventListener("keydown", onKeyDown);
|
|
11489
|
+
return () => window.removeEventListener("keydown", onKeyDown);
|
|
11490
|
+
}, [onClose]);
|
|
11491
|
+
reactExports.useEffect(() => {
|
|
11492
|
+
const target = focusSide === "left" ? leftRef.current : rightRef.current;
|
|
11493
|
+
const textarea = target?.querySelector("textarea");
|
|
11494
|
+
textarea?.focus();
|
|
11495
|
+
}, [focusSide]);
|
|
11496
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$7.overlay, children: [
|
|
11497
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$7.header, children: [
|
|
11498
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
11499
|
+
PaneTab,
|
|
11500
|
+
{
|
|
11501
|
+
session: left,
|
|
11502
|
+
active: focusSide === "left",
|
|
11503
|
+
onClick: () => setFocusSide("left")
|
|
11504
|
+
}
|
|
11505
|
+
),
|
|
11506
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
11507
|
+
PaneTab,
|
|
11508
|
+
{
|
|
11509
|
+
session: right,
|
|
11510
|
+
active: focusSide === "right",
|
|
11511
|
+
onClick: () => setFocusSide("right")
|
|
11512
|
+
}
|
|
11513
|
+
),
|
|
11514
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: { flex: 1 } }),
|
|
11515
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$7.hint, children: "Ctrl+1/2 switch · Esc close" }),
|
|
11516
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { style: styles$7.closeBtn, onClick: onClose, title: "Close split (Esc)", children: "⊠" })
|
|
11517
|
+
] }),
|
|
11518
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$7.panes, children: [
|
|
11519
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
11520
|
+
"div",
|
|
11521
|
+
{
|
|
11522
|
+
ref: leftRef,
|
|
11523
|
+
style: {
|
|
11524
|
+
...styles$7.pane,
|
|
11525
|
+
borderColor: focusSide === "left" ? "var(--accent)" : "var(--border-subtle)"
|
|
11526
|
+
},
|
|
11527
|
+
onClick: () => setFocusSide("left")
|
|
11528
|
+
}
|
|
11529
|
+
),
|
|
11530
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$7.divider }),
|
|
11531
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
11532
|
+
"div",
|
|
11533
|
+
{
|
|
11534
|
+
ref: rightRef,
|
|
11535
|
+
style: {
|
|
11536
|
+
...styles$7.pane,
|
|
11537
|
+
borderColor: focusSide === "right" ? "var(--accent)" : "var(--border-subtle)"
|
|
11538
|
+
},
|
|
11539
|
+
onClick: () => setFocusSide("right")
|
|
11540
|
+
}
|
|
11541
|
+
)
|
|
11542
|
+
] })
|
|
11543
|
+
] });
|
|
11544
|
+
}
|
|
11545
|
+
function PaneTab({ session, active, onClick }) {
|
|
11546
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
11547
|
+
"button",
|
|
11548
|
+
{
|
|
11549
|
+
style: {
|
|
11550
|
+
...styles$7.tab,
|
|
11551
|
+
background: active ? "var(--bg-base)" : "transparent",
|
|
11552
|
+
color: active ? "var(--text-primary)" : "var(--text-muted)",
|
|
11553
|
+
borderBottomColor: active ? "var(--accent)" : "transparent"
|
|
11554
|
+
},
|
|
11555
|
+
onClick,
|
|
11556
|
+
children: session.name
|
|
11557
|
+
}
|
|
11558
|
+
);
|
|
11559
|
+
}
|
|
11560
|
+
const styles$7 = {
|
|
11561
|
+
overlay: {
|
|
11562
|
+
position: "fixed",
|
|
11563
|
+
inset: 0,
|
|
11564
|
+
zIndex: 200,
|
|
11565
|
+
background: "var(--bg-base)",
|
|
11566
|
+
display: "flex",
|
|
11567
|
+
flexDirection: "column"
|
|
11568
|
+
},
|
|
11569
|
+
header: {
|
|
11570
|
+
display: "flex",
|
|
11571
|
+
alignItems: "center",
|
|
11572
|
+
gap: "4px",
|
|
11573
|
+
padding: "6px 16px",
|
|
11574
|
+
background: "var(--bg-surface)",
|
|
11575
|
+
borderBottom: "1px solid var(--border)",
|
|
11576
|
+
flexShrink: 0
|
|
11577
|
+
},
|
|
11578
|
+
tab: {
|
|
11579
|
+
fontSize: "12px",
|
|
11580
|
+
fontWeight: 600,
|
|
11581
|
+
padding: "6px 12px",
|
|
11582
|
+
border: "none",
|
|
11583
|
+
borderBottom: "2px solid",
|
|
11584
|
+
cursor: "pointer"
|
|
11585
|
+
},
|
|
11586
|
+
hint: {
|
|
11587
|
+
fontSize: "11px",
|
|
11588
|
+
color: "var(--text-muted)",
|
|
11589
|
+
marginRight: "8px"
|
|
11590
|
+
},
|
|
11591
|
+
closeBtn: {
|
|
11592
|
+
background: "transparent",
|
|
11593
|
+
border: "none",
|
|
11594
|
+
color: "var(--text-muted)",
|
|
11595
|
+
fontSize: "18px",
|
|
11596
|
+
cursor: "pointer"
|
|
11597
|
+
},
|
|
11598
|
+
panes: {
|
|
11599
|
+
flex: 1,
|
|
11600
|
+
display: "flex",
|
|
11601
|
+
overflow: "hidden"
|
|
11602
|
+
},
|
|
11603
|
+
pane: {
|
|
11604
|
+
flex: 1,
|
|
11605
|
+
position: "relative",
|
|
11606
|
+
overflow: "hidden",
|
|
11607
|
+
padding: "4px",
|
|
11608
|
+
border: "2px solid",
|
|
11609
|
+
borderRadius: "2px"
|
|
11610
|
+
},
|
|
11611
|
+
divider: {
|
|
11612
|
+
width: "4px",
|
|
11613
|
+
background: "var(--border)",
|
|
11614
|
+
flexShrink: 0,
|
|
11615
|
+
cursor: "col-resize"
|
|
11616
|
+
}
|
|
11617
|
+
};
|
|
11618
|
+
function TabbedWorkspace({ sessions, onClose }) {
|
|
11619
|
+
const [activeTabId, setActiveTabId] = reactExports.useState(
|
|
11620
|
+
sessions[0]?.id ?? null
|
|
11621
|
+
);
|
|
11622
|
+
const [closedTabs, setClosedTabs] = reactExports.useState([]);
|
|
11623
|
+
React$2.useEffect(() => {
|
|
11624
|
+
function onKeyDown(e) {
|
|
11625
|
+
if ((e.ctrlKey || e.metaKey) && e.shiftKey && e.key === "T") {
|
|
11626
|
+
e.preventDefault();
|
|
11627
|
+
if (closedTabs.length > 0) {
|
|
11628
|
+
const lastClosed = closedTabs[closedTabs.length - 1];
|
|
11629
|
+
setClosedTabs((prev) => prev.slice(0, -1));
|
|
11630
|
+
setActiveTabId(lastClosed);
|
|
11631
|
+
}
|
|
11632
|
+
}
|
|
11633
|
+
}
|
|
11634
|
+
window.addEventListener("keydown", onKeyDown);
|
|
11635
|
+
return () => window.removeEventListener("keydown", onKeyDown);
|
|
11636
|
+
}, [closedTabs]);
|
|
11637
|
+
const activeSession = sessions.find((s) => s.id === activeTabId) ?? sessions[0];
|
|
11638
|
+
const visibleSessions = sessions.filter((s) => !closedTabs.includes(s.id));
|
|
11639
|
+
function handleCloseTab(e, id2) {
|
|
11640
|
+
e.stopPropagation();
|
|
11641
|
+
setClosedTabs((prev) => [...prev, id2]);
|
|
11642
|
+
if (activeTabId === id2) {
|
|
11643
|
+
const remaining = visibleSessions.filter((s) => s.id !== id2);
|
|
11644
|
+
setActiveTabId(remaining[0]?.id ?? null);
|
|
11645
|
+
}
|
|
11646
|
+
}
|
|
11647
|
+
if (!activeSession || visibleSessions.length === 0) {
|
|
11648
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$6.empty, children: /* @__PURE__ */ jsxRuntimeExports.jsx("p", { style: { color: "var(--text-muted)" }, children: "No open tabs. Press Ctrl+Shift+T to reopen." }) });
|
|
11649
|
+
}
|
|
11650
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$6.root, children: [
|
|
11651
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$6.tabBar, children: visibleSessions.map((session) => /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
11652
|
+
"button",
|
|
11653
|
+
{
|
|
11654
|
+
style: {
|
|
11655
|
+
...styles$6.tab,
|
|
11656
|
+
background: session.id === activeTabId ? "var(--bg-base)" : "transparent",
|
|
11657
|
+
color: session.id === activeTabId ? "var(--text-primary)" : "var(--text-muted)",
|
|
11658
|
+
borderBottomColor: session.id === activeTabId ? "var(--accent)" : "transparent"
|
|
11659
|
+
},
|
|
11660
|
+
onClick: () => setActiveTabId(session.id),
|
|
11661
|
+
onAuxClick: (e) => {
|
|
11662
|
+
if (e.button === 1) handleCloseTab(e, session.id);
|
|
11663
|
+
},
|
|
11664
|
+
title: `${session.name} · ${session.provider} · ${session.state}`,
|
|
11665
|
+
children: [
|
|
11666
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$6.tabName, children: session.name }),
|
|
11667
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
11668
|
+
"span",
|
|
11669
|
+
{
|
|
11670
|
+
style: styles$6.tabClose,
|
|
11671
|
+
onClick: (e) => handleCloseTab(e, session.id),
|
|
11672
|
+
children: "×"
|
|
11673
|
+
}
|
|
11674
|
+
)
|
|
11675
|
+
]
|
|
11676
|
+
},
|
|
11677
|
+
session.id
|
|
11678
|
+
)) }),
|
|
11679
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(ActiveTerminal, { session: activeSession }, activeSession.id)
|
|
11680
|
+
] });
|
|
11681
|
+
}
|
|
11682
|
+
function ActiveTerminal({ session }) {
|
|
11683
|
+
const containerRef = reactExports.useRef(null);
|
|
11684
|
+
useTerminalTile({
|
|
11685
|
+
containerRef,
|
|
11686
|
+
sessionId: session.id,
|
|
11687
|
+
interactive: true
|
|
11688
|
+
});
|
|
11689
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { ref: containerRef, style: styles$6.terminal });
|
|
11690
|
+
}
|
|
11691
|
+
const styles$6 = {
|
|
11692
|
+
root: {
|
|
11693
|
+
display: "flex",
|
|
11694
|
+
flexDirection: "column",
|
|
11695
|
+
height: "100%"
|
|
11696
|
+
},
|
|
11697
|
+
tabBar: {
|
|
11698
|
+
display: "flex",
|
|
11699
|
+
alignItems: "stretch",
|
|
11700
|
+
background: "var(--bg-surface)",
|
|
11701
|
+
borderBottom: "1px solid var(--border)",
|
|
11702
|
+
overflowX: "auto",
|
|
11703
|
+
flexShrink: 0
|
|
11704
|
+
},
|
|
11705
|
+
tab: {
|
|
11706
|
+
display: "flex",
|
|
11707
|
+
alignItems: "center",
|
|
11708
|
+
gap: "6px",
|
|
11709
|
+
padding: "8px 14px",
|
|
11710
|
+
fontSize: "12px",
|
|
11711
|
+
fontWeight: 500,
|
|
11712
|
+
border: "none",
|
|
11713
|
+
borderBottom: "2px solid",
|
|
11714
|
+
cursor: "pointer",
|
|
11715
|
+
maxWidth: "180px",
|
|
11716
|
+
minWidth: "80px",
|
|
11717
|
+
flexShrink: 0,
|
|
11718
|
+
whiteSpace: "nowrap"
|
|
11719
|
+
},
|
|
11720
|
+
tabName: {
|
|
11721
|
+
overflow: "hidden",
|
|
11722
|
+
textOverflow: "ellipsis"
|
|
11723
|
+
},
|
|
11724
|
+
tabClose: {
|
|
11725
|
+
fontSize: "14px",
|
|
11726
|
+
lineHeight: 1,
|
|
11727
|
+
opacity: 0.5,
|
|
11728
|
+
flexShrink: 0
|
|
11729
|
+
},
|
|
11730
|
+
terminal: {
|
|
11731
|
+
flex: 1,
|
|
11732
|
+
position: "relative",
|
|
11733
|
+
overflow: "hidden",
|
|
11734
|
+
padding: "8px"
|
|
11735
|
+
},
|
|
11736
|
+
empty: {
|
|
11737
|
+
display: "flex",
|
|
11738
|
+
alignItems: "center",
|
|
11739
|
+
justifyContent: "center",
|
|
11740
|
+
height: "100%"
|
|
11098
11741
|
}
|
|
11099
11742
|
};
|
|
11100
11743
|
function DirectoryBrowser({ machineId, initialPath, onSelect }) {
|
|
@@ -11131,9 +11774,9 @@ function DirectoryBrowser({ machineId, initialPath, onSelect }) {
|
|
|
11131
11774
|
}
|
|
11132
11775
|
}
|
|
11133
11776
|
if (loading) {
|
|
11134
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$
|
|
11777
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$5.loading, children: "Loading directory tree…" });
|
|
11135
11778
|
}
|
|
11136
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$
|
|
11779
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$5.root, children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
11137
11780
|
TreeLevel,
|
|
11138
11781
|
{
|
|
11139
11782
|
nodes: roots,
|
|
@@ -11150,15 +11793,15 @@ function TreeLevel({ nodes, setNodes, selected, onToggle, depth }) {
|
|
|
11150
11793
|
"button",
|
|
11151
11794
|
{
|
|
11152
11795
|
style: {
|
|
11153
|
-
...styles$
|
|
11796
|
+
...styles$5.treeItem,
|
|
11154
11797
|
paddingLeft: `${12 + depth * 14}px`,
|
|
11155
11798
|
background: selected === node.path ? "var(--accent-muted)" : "transparent",
|
|
11156
11799
|
color: selected === node.path ? "var(--text-primary)" : "var(--text-secondary)"
|
|
11157
11800
|
},
|
|
11158
11801
|
onClick: () => onToggle(node, nodes, setNodes),
|
|
11159
11802
|
children: [
|
|
11160
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$
|
|
11161
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$
|
|
11803
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$5.treeIcon, children: node.isDir ? node.loading ? "⏳" : node.expanded ? "▼" : "▶" : "📄" }),
|
|
11804
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$5.treeName, children: node.name })
|
|
11162
11805
|
]
|
|
11163
11806
|
}
|
|
11164
11807
|
),
|
|
@@ -11189,7 +11832,7 @@ function updateNode(nodes, targetPath, updates) {
|
|
|
11189
11832
|
return n2;
|
|
11190
11833
|
});
|
|
11191
11834
|
}
|
|
11192
|
-
const styles$
|
|
11835
|
+
const styles$5 = {
|
|
11193
11836
|
root: {
|
|
11194
11837
|
border: "1px solid var(--border)",
|
|
11195
11838
|
borderRadius: "var(--radius-sm)",
|
|
@@ -11238,6 +11881,13 @@ function CreateTerminalModal({ onClose, onCreated }) {
|
|
|
11238
11881
|
const [creating, setCreating] = reactExports.useState(false);
|
|
11239
11882
|
const [error, setError] = reactExports.useState("");
|
|
11240
11883
|
const machines = useMachinesStore((s) => s.machines.filter((m2) => m2.onboarded));
|
|
11884
|
+
const prevMachineRef = React$2.useRef(machineId);
|
|
11885
|
+
React$2.useEffect(() => {
|
|
11886
|
+
if (prevMachineRef.current !== machineId) {
|
|
11887
|
+
prevMachineRef.current = machineId;
|
|
11888
|
+
setDirectory("");
|
|
11889
|
+
}
|
|
11890
|
+
}, [machineId]);
|
|
11241
11891
|
async function handleCreate() {
|
|
11242
11892
|
setCreating(true);
|
|
11243
11893
|
setError("");
|
|
@@ -11272,17 +11922,17 @@ function CreateTerminalModal({ onClose, onCreated }) {
|
|
|
11272
11922
|
return next;
|
|
11273
11923
|
});
|
|
11274
11924
|
}
|
|
11275
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$
|
|
11276
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
11277
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$
|
|
11278
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { style: styles$
|
|
11925
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$4.overlay, children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$4.dialog, children: [
|
|
11926
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$4.dialogHeader, children: [
|
|
11927
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$4.dialogTitle, children: "New Terminal" }),
|
|
11928
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { style: styles$4.stepLabel, children: [
|
|
11279
11929
|
"Step ",
|
|
11280
11930
|
step,
|
|
11281
11931
|
" of 3"
|
|
11282
11932
|
] }),
|
|
11283
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { style: styles$
|
|
11933
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { style: styles$4.closeBtn, onClick: onClose, children: "✕" })
|
|
11284
11934
|
] }),
|
|
11285
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
11935
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$4.body, children: [
|
|
11286
11936
|
step === 1 && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
11287
11937
|
Step1,
|
|
11288
11938
|
{
|
|
@@ -11319,7 +11969,7 @@ function CreateTerminalModal({ onClose, onCreated }) {
|
|
|
11319
11969
|
}
|
|
11320
11970
|
)
|
|
11321
11971
|
] }),
|
|
11322
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
11972
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$4.dialogFooter, children: [
|
|
11323
11973
|
step > 1 && /* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: "btn btn-ghost", onClick: () => setStep((s) => s - 1), children: "← Back" }),
|
|
11324
11974
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: { flex: 1 } }),
|
|
11325
11975
|
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: "btn btn-ghost", onClick: onClose, children: "Cancel" }),
|
|
@@ -11344,9 +11994,9 @@ function CreateTerminalModal({ onClose, onCreated }) {
|
|
|
11344
11994
|
] }) });
|
|
11345
11995
|
}
|
|
11346
11996
|
function Step1({ name, setName, machineId, setMachineId, provider, setProvider, machines }) {
|
|
11347
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
11348
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
11349
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("label", { style: styles$
|
|
11997
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$4.step, children: [
|
|
11998
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$4.field, children: [
|
|
11999
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("label", { style: styles$4.label, children: "Session name" }),
|
|
11350
12000
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
11351
12001
|
"input",
|
|
11352
12002
|
{
|
|
@@ -11358,14 +12008,14 @@ function Step1({ name, setName, machineId, setMachineId, provider, setProvider,
|
|
|
11358
12008
|
}
|
|
11359
12009
|
)
|
|
11360
12010
|
] }),
|
|
11361
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
11362
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("label", { style: styles$
|
|
11363
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$
|
|
12011
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$4.field, children: [
|
|
12012
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("label", { style: styles$4.label, children: "Machine" }),
|
|
12013
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$4.machineList, children: machines.map((m2) => /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
11364
12014
|
"button",
|
|
11365
12015
|
{
|
|
11366
12016
|
style: {
|
|
11367
|
-
...styles$
|
|
11368
|
-
...machineId === m2.id ? styles$
|
|
12017
|
+
...styles$4.machineOption,
|
|
12018
|
+
...machineId === m2.id ? styles$4.machineOptionSelected : {}
|
|
11369
12019
|
},
|
|
11370
12020
|
onClick: () => setMachineId(m2.id),
|
|
11371
12021
|
children: [
|
|
@@ -11377,14 +12027,14 @@ function Step1({ name, setName, machineId, setMachineId, provider, setProvider,
|
|
|
11377
12027
|
m2.id
|
|
11378
12028
|
)) })
|
|
11379
12029
|
] }),
|
|
11380
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
11381
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("label", { style: styles$
|
|
11382
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$
|
|
12030
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$4.field, children: [
|
|
12031
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("label", { style: styles$4.label, children: "AI Provider" }),
|
|
12032
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$4.providerRow, children: ["claude", "copilot", "none"].map((p2) => /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
11383
12033
|
"button",
|
|
11384
12034
|
{
|
|
11385
12035
|
style: {
|
|
11386
|
-
...styles$
|
|
11387
|
-
...provider === p2 ? styles$
|
|
12036
|
+
...styles$4.providerBtn,
|
|
12037
|
+
...provider === p2 ? styles$4.providerBtnSelected : {}
|
|
11388
12038
|
},
|
|
11389
12039
|
onClick: () => setProvider(p2),
|
|
11390
12040
|
children: p2
|
|
@@ -11398,15 +12048,16 @@ function Step2({ machineId, directory, setDirectory }) {
|
|
|
11398
12048
|
const [showBrowser, setShowBrowser] = reactExports.useState(true);
|
|
11399
12049
|
const [homeDir, setHomeDir] = reactExports.useState("C:\\");
|
|
11400
12050
|
React$2.useEffect(() => {
|
|
12051
|
+
setDirectory("");
|
|
11401
12052
|
window.maestro.fs.homeDir(machineId).then((h) => {
|
|
11402
12053
|
setHomeDir(h);
|
|
11403
|
-
|
|
12054
|
+
setDirectory(h);
|
|
11404
12055
|
}).catch(() => {
|
|
11405
12056
|
});
|
|
11406
12057
|
}, [machineId]);
|
|
11407
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
11408
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
11409
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("label", { style: styles$
|
|
12058
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$4.step, children: [
|
|
12059
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$4.field, children: [
|
|
12060
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("label", { style: styles$4.label, children: "Working directory" }),
|
|
11410
12061
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
11411
12062
|
"input",
|
|
11412
12063
|
{
|
|
@@ -11420,7 +12071,7 @@ function Step2({ machineId, directory, setDirectory }) {
|
|
|
11420
12071
|
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
11421
12072
|
"button",
|
|
11422
12073
|
{
|
|
11423
|
-
style: styles$
|
|
12074
|
+
style: styles$4.browserToggle,
|
|
11424
12075
|
onClick: () => setShowBrowser((v2) => !v2),
|
|
11425
12076
|
children: [
|
|
11426
12077
|
showBrowser ? "▼" : "▶",
|
|
@@ -11436,17 +12087,17 @@ function Step2({ machineId, directory, setDirectory }) {
|
|
|
11436
12087
|
onSelect: setDirectory
|
|
11437
12088
|
}
|
|
11438
12089
|
),
|
|
11439
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { style: styles$
|
|
12090
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { style: styles$4.hint, children: "Select a directory above or type the path manually." })
|
|
11440
12091
|
] });
|
|
11441
12092
|
}
|
|
11442
12093
|
function Step3({ name, machineId, provider, directory, tags, tagInput, setTagInput, addTag, removeTag, error }) {
|
|
11443
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
11444
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
11445
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("label", { style: styles$
|
|
11446
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
11447
|
-
Object.entries(tags).map(([k2, v2]) => /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { style: styles$
|
|
12094
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$4.step, children: [
|
|
12095
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$4.field, children: [
|
|
12096
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("label", { style: styles$4.label, children: "Tags (optional)" }),
|
|
12097
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$4.tagEditor, children: [
|
|
12098
|
+
Object.entries(tags).map(([k2, v2]) => /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { style: styles$4.tagChip, children: [
|
|
11448
12099
|
v2 ? `${k2}:${v2}` : k2,
|
|
11449
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { style: styles$
|
|
12100
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { style: styles$4.tagRemove, onClick: () => removeTag(k2), children: "×" })
|
|
11450
12101
|
] }, k2)),
|
|
11451
12102
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
11452
12103
|
"input",
|
|
@@ -11461,35 +12112,35 @@ function Step3({ name, machineId, provider, directory, tags, tagInput, setTagInp
|
|
|
11461
12112
|
}
|
|
11462
12113
|
},
|
|
11463
12114
|
placeholder: "type tag and press Enter…",
|
|
11464
|
-
style: styles$
|
|
12115
|
+
style: styles$4.tagInput
|
|
11465
12116
|
}
|
|
11466
12117
|
)
|
|
11467
12118
|
] }),
|
|
11468
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { style: styles$
|
|
12119
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { style: styles$4.hint, children: "Use key:value or plain labels. Press Enter to add." })
|
|
11469
12120
|
] }),
|
|
11470
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
11471
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$
|
|
11472
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
11473
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$
|
|
12121
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$4.summary, children: [
|
|
12122
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$4.summaryTitle, children: "Summary" }),
|
|
12123
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$4.summaryRow, children: [
|
|
12124
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$4.summaryKey, children: "Name" }),
|
|
11474
12125
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: name })
|
|
11475
12126
|
] }),
|
|
11476
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
11477
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$
|
|
12127
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$4.summaryRow, children: [
|
|
12128
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$4.summaryKey, children: "Machine" }),
|
|
11478
12129
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: machineId })
|
|
11479
12130
|
] }),
|
|
11480
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
11481
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$
|
|
12131
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$4.summaryRow, children: [
|
|
12132
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$4.summaryKey, children: "Provider" }),
|
|
11482
12133
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: provider })
|
|
11483
12134
|
] }),
|
|
11484
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
11485
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$
|
|
12135
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$4.summaryRow, children: [
|
|
12136
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$4.summaryKey, children: "Directory" }),
|
|
11486
12137
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: { fontFamily: "monospace", fontSize: "12px" }, children: directory || "(default)" })
|
|
11487
12138
|
] })
|
|
11488
12139
|
] }),
|
|
11489
|
-
error && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$
|
|
12140
|
+
error && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$4.error, children: error })
|
|
11490
12141
|
] });
|
|
11491
12142
|
}
|
|
11492
|
-
const styles$
|
|
12143
|
+
const styles$4 = {
|
|
11493
12144
|
overlay: {
|
|
11494
12145
|
position: "fixed",
|
|
11495
12146
|
inset: 0,
|
|
@@ -11689,9 +12340,22 @@ const styles$3 = {
|
|
|
11689
12340
|
flexShrink: 0
|
|
11690
12341
|
}
|
|
11691
12342
|
};
|
|
12343
|
+
const STATUS_PILLS = {
|
|
12344
|
+
working: { icon: "●", label: "Working", color: "var(--state-working)" },
|
|
12345
|
+
waiting: { icon: "⏳", label: "Waiting", color: "var(--state-waiting)" },
|
|
12346
|
+
permission: { icon: "🔐", label: "Input Required", color: "var(--state-permission)" },
|
|
12347
|
+
idle: { icon: "○", label: "Idle", color: "var(--state-idle)" },
|
|
12348
|
+
done: { icon: "✓", label: "Done", color: "var(--state-done)" },
|
|
12349
|
+
error: { icon: "✗", label: "Error", color: "var(--state-error)" }
|
|
12350
|
+
};
|
|
12351
|
+
const ALL_STATES = ["working", "waiting", "permission", "idle", "done", "error"];
|
|
11692
12352
|
function TagFilterBar() {
|
|
11693
|
-
const { sessions, filterTags, setFilterTags } = useSessionsStore();
|
|
12353
|
+
const { sessions, filterTags, setFilterTags, filterStates, toggleFilterState, clearFilterStates } = useSessionsStore();
|
|
11694
12354
|
const [popoverOpen, setPopoverOpen] = reactExports.useState(false);
|
|
12355
|
+
const stateCounts = /* @__PURE__ */ new Map();
|
|
12356
|
+
for (const s of sessions) {
|
|
12357
|
+
stateCounts.set(s.state, (stateCounts.get(s.state) ?? 0) + 1);
|
|
12358
|
+
}
|
|
11695
12359
|
const allTags = {};
|
|
11696
12360
|
for (const s of sessions) {
|
|
11697
12361
|
for (const [k2, v2] of Object.entries(s.tags)) {
|
|
@@ -11700,14 +12364,42 @@ function TagFilterBar() {
|
|
|
11700
12364
|
}
|
|
11701
12365
|
}
|
|
11702
12366
|
const activeFilters = Object.entries(filterTags).filter(([k2]) => k2);
|
|
11703
|
-
|
|
11704
|
-
|
|
11705
|
-
|
|
12367
|
+
const hasAnyFilter = activeFilters.length > 0 || filterStates.size > 0;
|
|
12368
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$3.root, children: [
|
|
12369
|
+
ALL_STATES.map((state) => {
|
|
12370
|
+
const count = stateCounts.get(state) ?? 0;
|
|
12371
|
+
if (count === 0) return null;
|
|
12372
|
+
const { icon, label, color } = STATUS_PILLS[state];
|
|
12373
|
+
const active = filterStates.has(state);
|
|
12374
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
12375
|
+
"button",
|
|
12376
|
+
{
|
|
12377
|
+
onClick: () => toggleFilterState(state),
|
|
12378
|
+
style: {
|
|
12379
|
+
...styles$3.statusPill,
|
|
12380
|
+
color: active ? "#fff" : color,
|
|
12381
|
+
background: active ? color : "transparent",
|
|
12382
|
+
borderColor: active ? color : `${color}40`
|
|
12383
|
+
},
|
|
12384
|
+
children: [
|
|
12385
|
+
icon,
|
|
12386
|
+
" ",
|
|
12387
|
+
label,
|
|
12388
|
+
" ",
|
|
12389
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$3.pillCount, children: count })
|
|
12390
|
+
]
|
|
12391
|
+
},
|
|
12392
|
+
state
|
|
12393
|
+
);
|
|
12394
|
+
}),
|
|
12395
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$3.separator, children: "│" }),
|
|
12396
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$3.icon, children: "🏷" }),
|
|
12397
|
+
activeFilters.map(([k2, v2]) => /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { style: styles$3.chip, children: [
|
|
11706
12398
|
v2 && v2 !== "*" ? `${k2}:${v2}` : k2,
|
|
11707
12399
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
11708
12400
|
"button",
|
|
11709
12401
|
{
|
|
11710
|
-
style: styles$
|
|
12402
|
+
style: styles$3.chipRemove,
|
|
11711
12403
|
onClick: () => {
|
|
11712
12404
|
const next = { ...filterTags };
|
|
11713
12405
|
delete next[k2];
|
|
@@ -11718,7 +12410,7 @@ function TagFilterBar() {
|
|
|
11718
12410
|
)
|
|
11719
12411
|
] }, k2)),
|
|
11720
12412
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: { position: "relative" }, children: [
|
|
11721
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { style: styles$
|
|
12413
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { style: styles$3.addBtn, onClick: () => setPopoverOpen((v2) => !v2), children: "+ Filter" }),
|
|
11722
12414
|
popoverOpen && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
11723
12415
|
FilterPopover,
|
|
11724
12416
|
{
|
|
@@ -11731,17 +12423,20 @@ function TagFilterBar() {
|
|
|
11731
12423
|
}
|
|
11732
12424
|
)
|
|
11733
12425
|
] }),
|
|
11734
|
-
|
|
12426
|
+
hasAnyFilter && /* @__PURE__ */ jsxRuntimeExports.jsx("button", { style: styles$3.clearBtn, onClick: () => {
|
|
12427
|
+
setFilterTags({});
|
|
12428
|
+
clearFilterStates();
|
|
12429
|
+
}, children: "Clear filters" })
|
|
11735
12430
|
] });
|
|
11736
12431
|
}
|
|
11737
12432
|
function FilterPopover({ allTags, onApply, onClose }) {
|
|
11738
12433
|
const [selected, setSelected] = reactExports.useState({});
|
|
11739
12434
|
const systemKeys = ["machine", "provider", "state"];
|
|
11740
12435
|
const customKeys = Object.keys(allTags).filter((k2) => !systemKeys.includes(k2));
|
|
11741
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
11742
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$
|
|
11743
|
-
systemKeys.filter((k2) => allTags[k2]).map((k2) => /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
11744
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { style: styles$
|
|
12436
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$3.popover, children: [
|
|
12437
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$3.popoverTitle, children: "Filter by tag" }),
|
|
12438
|
+
systemKeys.filter((k2) => allTags[k2]).map((k2) => /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$3.popoverRow, children: [
|
|
12439
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { style: styles$3.popoverKey, children: [
|
|
11745
12440
|
k2,
|
|
11746
12441
|
":"
|
|
11747
12442
|
] }),
|
|
@@ -11750,7 +12445,7 @@ function FilterPopover({ allTags, onApply, onClose }) {
|
|
|
11750
12445
|
{
|
|
11751
12446
|
value: selected[k2] ?? "",
|
|
11752
12447
|
onChange: (e) => setSelected((prev) => ({ ...prev, [k2]: e.target.value })),
|
|
11753
|
-
style: styles$
|
|
12448
|
+
style: styles$3.popoverSelect,
|
|
11754
12449
|
children: [
|
|
11755
12450
|
/* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: "", children: "any" }),
|
|
11756
12451
|
Array.from(allTags[k2]).map((v2) => /* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: v2, children: v2 }, v2))
|
|
@@ -11758,8 +12453,8 @@ function FilterPopover({ allTags, onApply, onClose }) {
|
|
|
11758
12453
|
}
|
|
11759
12454
|
)
|
|
11760
12455
|
] }, k2)),
|
|
11761
|
-
customKeys.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
11762
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$
|
|
12456
|
+
customKeys.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$3.popoverRow, children: [
|
|
12457
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$3.popoverKey, children: "custom:" }),
|
|
11763
12458
|
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
11764
12459
|
"select",
|
|
11765
12460
|
{
|
|
@@ -11768,7 +12463,7 @@ function FilterPopover({ allTags, onApply, onClose }) {
|
|
|
11768
12463
|
const v2 = e.target.value;
|
|
11769
12464
|
setSelected((prev) => v2 ? { ...prev, _custom: v2 } : { ...prev });
|
|
11770
12465
|
},
|
|
11771
|
-
style: styles$
|
|
12466
|
+
style: styles$3.popoverSelect,
|
|
11772
12467
|
children: [
|
|
11773
12468
|
/* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: "", children: "pick tag…" }),
|
|
11774
12469
|
customKeys.map((k2) => /* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: k2, children: k2 }, k2))
|
|
@@ -11776,7 +12471,7 @@ function FilterPopover({ allTags, onApply, onClose }) {
|
|
|
11776
12471
|
}
|
|
11777
12472
|
)
|
|
11778
12473
|
] }),
|
|
11779
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
12474
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$3.popoverActions, children: [
|
|
11780
12475
|
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: "btn btn-ghost btn-sm", onClick: onClose, children: "Cancel" }),
|
|
11781
12476
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
11782
12477
|
"button",
|
|
@@ -11796,7 +12491,7 @@ function FilterPopover({ allTags, onApply, onClose }) {
|
|
|
11796
12491
|
] })
|
|
11797
12492
|
] });
|
|
11798
12493
|
}
|
|
11799
|
-
const styles$
|
|
12494
|
+
const styles$3 = {
|
|
11800
12495
|
root: {
|
|
11801
12496
|
display: "flex",
|
|
11802
12497
|
alignItems: "center",
|
|
@@ -11804,6 +12499,28 @@ const styles$2 = {
|
|
|
11804
12499
|
flex: 1,
|
|
11805
12500
|
flexWrap: "wrap"
|
|
11806
12501
|
},
|
|
12502
|
+
statusPill: {
|
|
12503
|
+
display: "inline-flex",
|
|
12504
|
+
alignItems: "center",
|
|
12505
|
+
gap: "4px",
|
|
12506
|
+
fontSize: "11px",
|
|
12507
|
+
fontWeight: 600,
|
|
12508
|
+
padding: "3px 8px",
|
|
12509
|
+
borderRadius: "10px",
|
|
12510
|
+
border: "1px solid",
|
|
12511
|
+
cursor: "pointer",
|
|
12512
|
+
transition: "all 0.15s",
|
|
12513
|
+
whiteSpace: "nowrap"
|
|
12514
|
+
},
|
|
12515
|
+
pillCount: {
|
|
12516
|
+
fontSize: "10px",
|
|
12517
|
+
opacity: 0.8
|
|
12518
|
+
},
|
|
12519
|
+
separator: {
|
|
12520
|
+
color: "var(--border)",
|
|
12521
|
+
fontSize: "14px",
|
|
12522
|
+
margin: "0 2px"
|
|
12523
|
+
},
|
|
11807
12524
|
icon: {
|
|
11808
12525
|
fontSize: "14px"
|
|
11809
12526
|
},
|
|
@@ -11897,15 +12614,53 @@ function TerminalsView({ onSessionAdded }) {
|
|
|
11897
12614
|
const {
|
|
11898
12615
|
sessions,
|
|
11899
12616
|
filterTags,
|
|
12617
|
+
filterStates,
|
|
11900
12618
|
activeFullscreenId,
|
|
12619
|
+
splitIds,
|
|
11901
12620
|
setFullscreen,
|
|
12621
|
+
setSplit,
|
|
11902
12622
|
removeSession,
|
|
11903
12623
|
updateSession
|
|
11904
12624
|
} = useSessionsStore();
|
|
11905
12625
|
const [showCreate, setShowCreate] = reactExports.useState(false);
|
|
11906
12626
|
const [editTagsId, setEditTagsId] = reactExports.useState(null);
|
|
11907
|
-
const
|
|
12627
|
+
const [viewMode, setViewMode] = reactExports.useState("grid");
|
|
12628
|
+
const [searchQuery, setSearchQuery] = reactExports.useState("");
|
|
12629
|
+
const tagFiltered = filterSessions(sessions, filterTags, filterStates);
|
|
12630
|
+
const filtered = searchQuery.trim() ? tagFiltered.filter((s) => {
|
|
12631
|
+
const q2 = searchQuery.toLowerCase();
|
|
12632
|
+
return s.name.toLowerCase().includes(q2) || (s.tags["machine"] ?? "").toLowerCase().includes(q2) || s.provider.toLowerCase().includes(q2) || s.workingDirectory.toLowerCase().includes(q2) || s.state.toLowerCase().includes(q2);
|
|
12633
|
+
}) : tagFiltered;
|
|
11908
12634
|
const fullscreenSession = activeFullscreenId ? sessions.find((s) => s.id === activeFullscreenId) ?? null : null;
|
|
12635
|
+
reactExports.useEffect(() => {
|
|
12636
|
+
function onKeyDown(e) {
|
|
12637
|
+
if (showCreate || editTagsId) return;
|
|
12638
|
+
const target = e.target;
|
|
12639
|
+
if (target.tagName === "INPUT" || target.tagName === "TEXTAREA" || target.tagName === "SELECT") return;
|
|
12640
|
+
const ctrlOrCmd = e.ctrlKey || e.metaKey;
|
|
12641
|
+
if (ctrlOrCmd && e.key === "n") {
|
|
12642
|
+
e.preventDefault();
|
|
12643
|
+
setShowCreate(true);
|
|
12644
|
+
} else if (ctrlOrCmd && e.key === "\\") {
|
|
12645
|
+
e.preventDefault();
|
|
12646
|
+
if (splitIds) {
|
|
12647
|
+
setSplit(null);
|
|
12648
|
+
} else if (activeFullscreenId && filtered.length >= 2) {
|
|
12649
|
+
const currentIdx = filtered.findIndex((s) => s.id === activeFullscreenId);
|
|
12650
|
+
const nextIdx = (currentIdx + 1) % filtered.length;
|
|
12651
|
+
setSplit([activeFullscreenId, filtered[nextIdx].id]);
|
|
12652
|
+
}
|
|
12653
|
+
} else if (ctrlOrCmd && e.key >= "1" && e.key <= "9") {
|
|
12654
|
+
e.preventDefault();
|
|
12655
|
+
const index = parseInt(e.key) - 1;
|
|
12656
|
+
if (filtered[index]) {
|
|
12657
|
+
setFullscreen(filtered[index].id);
|
|
12658
|
+
}
|
|
12659
|
+
}
|
|
12660
|
+
}
|
|
12661
|
+
window.addEventListener("keydown", onKeyDown);
|
|
12662
|
+
return () => window.removeEventListener("keydown", onKeyDown);
|
|
12663
|
+
}, [filtered, showCreate, editTagsId, setFullscreen]);
|
|
11909
12664
|
async function handleClose(id2) {
|
|
11910
12665
|
await window.maestro.sessions.destroy(id2).catch(() => {
|
|
11911
12666
|
});
|
|
@@ -11916,15 +12671,34 @@ function TerminalsView({ onSessionAdded }) {
|
|
|
11916
12671
|
});
|
|
11917
12672
|
updateSession({ id: id2, name });
|
|
11918
12673
|
}
|
|
11919
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
11920
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
12674
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$2.root, children: [
|
|
12675
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$2.toolbar, children: [
|
|
11921
12676
|
/* @__PURE__ */ jsxRuntimeExports.jsx(TagFilterBar, {}),
|
|
11922
|
-
/* @__PURE__ */ jsxRuntimeExports.
|
|
11923
|
-
|
|
12677
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
12678
|
+
"input",
|
|
12679
|
+
{
|
|
12680
|
+
type: "text",
|
|
12681
|
+
value: searchQuery,
|
|
12682
|
+
onChange: (e) => setSearchQuery(e.target.value),
|
|
12683
|
+
placeholder: "Search terminals…",
|
|
12684
|
+
style: styles$2.searchInput
|
|
12685
|
+
}
|
|
12686
|
+
),
|
|
12687
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$2.toolbarRight, children: [
|
|
12688
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { style: styles$2.count, children: [
|
|
11924
12689
|
filtered.length,
|
|
11925
12690
|
"/",
|
|
11926
12691
|
sessions.length
|
|
11927
12692
|
] }),
|
|
12693
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
12694
|
+
"button",
|
|
12695
|
+
{
|
|
12696
|
+
className: "btn btn-ghost btn-sm",
|
|
12697
|
+
onClick: () => setViewMode((v2) => v2 === "grid" ? "tabs" : "grid"),
|
|
12698
|
+
title: viewMode === "grid" ? "Switch to tabbed view" : "Switch to grid view",
|
|
12699
|
+
children: viewMode === "grid" ? "☰ Tabs" : "▦ Grid"
|
|
12700
|
+
}
|
|
12701
|
+
),
|
|
11928
12702
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
11929
12703
|
"button",
|
|
11930
12704
|
{
|
|
@@ -11935,12 +12709,18 @@ function TerminalsView({ onSessionAdded }) {
|
|
|
11935
12709
|
)
|
|
11936
12710
|
] })
|
|
11937
12711
|
] }),
|
|
11938
|
-
|
|
11939
|
-
|
|
12712
|
+
viewMode === "tabs" && filtered.length > 0 ? /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
12713
|
+
TabbedWorkspace,
|
|
12714
|
+
{
|
|
12715
|
+
sessions: filtered,
|
|
12716
|
+
onClose: (id2) => handleClose(id2)
|
|
12717
|
+
}
|
|
12718
|
+
) : /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$2.gridWrapper, children: filtered.length === 0 ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$2.empty, children: sessions.length === 0 ? /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
12719
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$2.emptyIcon, children: "▦" }),
|
|
11940
12720
|
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { style: { fontWeight: 600, marginBottom: "8px" }, children: "No terminals yet" }),
|
|
11941
12721
|
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { style: { color: "var(--text-muted)", fontSize: "13px", marginBottom: "16px" }, children: "Launch an AI coding session to get started." }),
|
|
11942
12722
|
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: "btn btn-primary", onClick: () => setShowCreate(true), children: "+ New Terminal" })
|
|
11943
|
-
] }) : /* @__PURE__ */ jsxRuntimeExports.jsx("p", { style: { color: "var(--text-muted)" }, children: "No sessions match the current filter." }) }) : /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$
|
|
12723
|
+
] }) : /* @__PURE__ */ jsxRuntimeExports.jsx("p", { style: { color: "var(--text-muted)" }, children: "No sessions match the current filter." }) }) : /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$2.grid, children: filtered.map((session) => /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
11944
12724
|
TerminalTile,
|
|
11945
12725
|
{
|
|
11946
12726
|
session,
|
|
@@ -11958,6 +12738,19 @@ function TerminalsView({ onSessionAdded }) {
|
|
|
11958
12738
|
onClose: () => setFullscreen(null)
|
|
11959
12739
|
}
|
|
11960
12740
|
),
|
|
12741
|
+
splitIds && (() => {
|
|
12742
|
+
const leftSession = sessions.find((s) => s.id === splitIds[0]);
|
|
12743
|
+
const rightSession = sessions.find((s) => s.id === splitIds[1]);
|
|
12744
|
+
if (!leftSession || !rightSession) return null;
|
|
12745
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
12746
|
+
SplitPaneOverlay,
|
|
12747
|
+
{
|
|
12748
|
+
left: leftSession,
|
|
12749
|
+
right: rightSession,
|
|
12750
|
+
onClose: () => setSplit(null)
|
|
12751
|
+
}
|
|
12752
|
+
);
|
|
12753
|
+
})(),
|
|
11961
12754
|
showCreate && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
11962
12755
|
CreateTerminalModal,
|
|
11963
12756
|
{
|
|
@@ -11996,16 +12789,16 @@ function TagEditPanel({ sessionId, initialTags, onClose, onSave }) {
|
|
|
11996
12789
|
setTags((prev) => ({ ...prev, [key.trim()]: val.trim() }));
|
|
11997
12790
|
setInput("");
|
|
11998
12791
|
}
|
|
11999
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$
|
|
12000
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
12792
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$2.tagEditOverlay, children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$2.tagEditPanel, children: [
|
|
12793
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$2.tagEditHeader, children: [
|
|
12001
12794
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { children: [
|
|
12002
12795
|
session?.name,
|
|
12003
12796
|
" · Tags"
|
|
12004
12797
|
] }),
|
|
12005
12798
|
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { style: { background: "transparent", border: "none", color: "var(--text-muted)", fontSize: "16px" }, onClick: onClose, children: "✕" })
|
|
12006
12799
|
] }),
|
|
12007
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
12008
|
-
Object.entries(tags).filter(([k2]) => !["machine", "provider", "state"].includes(k2)).map(([k2, v2]) => /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { style: styles$
|
|
12800
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$2.tagEditorInline, children: [
|
|
12801
|
+
Object.entries(tags).filter(([k2]) => !["machine", "provider", "state"].includes(k2)).map(([k2, v2]) => /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { style: styles$2.tagChipEdit, children: [
|
|
12009
12802
|
v2 ? `${k2}:${v2}` : k2,
|
|
12010
12803
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
12011
12804
|
"button",
|
|
@@ -12040,7 +12833,7 @@ function TagEditPanel({ sessionId, initialTags, onClose, onSave }) {
|
|
|
12040
12833
|
] })
|
|
12041
12834
|
] }) });
|
|
12042
12835
|
}
|
|
12043
|
-
const styles$
|
|
12836
|
+
const styles$2 = {
|
|
12044
12837
|
root: {
|
|
12045
12838
|
display: "flex",
|
|
12046
12839
|
flexDirection: "column",
|
|
@@ -12057,6 +12850,17 @@ const styles$1 = {
|
|
|
12057
12850
|
flexShrink: 0,
|
|
12058
12851
|
height: "var(--header-height)"
|
|
12059
12852
|
},
|
|
12853
|
+
searchInput: {
|
|
12854
|
+
padding: "5px 10px",
|
|
12855
|
+
fontSize: "12px",
|
|
12856
|
+
background: "var(--bg-base)",
|
|
12857
|
+
border: "1px solid var(--border)",
|
|
12858
|
+
borderRadius: "var(--radius-sm)",
|
|
12859
|
+
color: "var(--text-primary)",
|
|
12860
|
+
outline: "none",
|
|
12861
|
+
width: "180px",
|
|
12862
|
+
flexShrink: 0
|
|
12863
|
+
},
|
|
12060
12864
|
toolbarRight: {
|
|
12061
12865
|
display: "flex",
|
|
12062
12866
|
alignItems: "center",
|
|
@@ -12141,12 +12945,92 @@ const styles$1 = {
|
|
|
12141
12945
|
borderRadius: "10px"
|
|
12142
12946
|
}
|
|
12143
12947
|
};
|
|
12948
|
+
let nextId = 0;
|
|
12949
|
+
const useToastsStore = create((set) => ({
|
|
12950
|
+
toasts: [],
|
|
12951
|
+
addToast(message, type) {
|
|
12952
|
+
const id2 = `toast-${nextId++}`;
|
|
12953
|
+
const toast = { id: id2, message, type, createdAt: Date.now() };
|
|
12954
|
+
set((s) => ({
|
|
12955
|
+
toasts: [...s.toasts.slice(-4), toast]
|
|
12956
|
+
// cap at 5
|
|
12957
|
+
}));
|
|
12958
|
+
setTimeout(() => {
|
|
12959
|
+
set((s) => ({ toasts: s.toasts.filter((t2) => t2.id !== id2) }));
|
|
12960
|
+
}, 5e3);
|
|
12961
|
+
},
|
|
12962
|
+
removeToast(id2) {
|
|
12963
|
+
set((s) => ({ toasts: s.toasts.filter((t2) => t2.id !== id2) }));
|
|
12964
|
+
}
|
|
12965
|
+
}));
|
|
12966
|
+
const TYPE_COLORS = {
|
|
12967
|
+
info: "var(--state-working)",
|
|
12968
|
+
success: "var(--state-done)",
|
|
12969
|
+
warning: "var(--state-waiting)",
|
|
12970
|
+
error: "var(--state-error)"
|
|
12971
|
+
};
|
|
12972
|
+
function ToastContainer() {
|
|
12973
|
+
const { toasts, removeToast } = useToastsStore();
|
|
12974
|
+
if (toasts.length === 0) return null;
|
|
12975
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$1.container, children: toasts.map((toast) => /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
12976
|
+
"div",
|
|
12977
|
+
{
|
|
12978
|
+
style: { ...styles$1.toast, borderLeftColor: TYPE_COLORS[toast.type] },
|
|
12979
|
+
children: [
|
|
12980
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$1.message, children: toast.message }),
|
|
12981
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { style: styles$1.dismiss, onClick: () => removeToast(toast.id), children: "✕" })
|
|
12982
|
+
]
|
|
12983
|
+
},
|
|
12984
|
+
toast.id
|
|
12985
|
+
)) });
|
|
12986
|
+
}
|
|
12987
|
+
const styles$1 = {
|
|
12988
|
+
container: {
|
|
12989
|
+
position: "fixed",
|
|
12990
|
+
bottom: "16px",
|
|
12991
|
+
right: "16px",
|
|
12992
|
+
zIndex: 300,
|
|
12993
|
+
display: "flex",
|
|
12994
|
+
flexDirection: "column",
|
|
12995
|
+
gap: "8px",
|
|
12996
|
+
maxWidth: "360px"
|
|
12997
|
+
},
|
|
12998
|
+
toast: {
|
|
12999
|
+
display: "flex",
|
|
13000
|
+
alignItems: "center",
|
|
13001
|
+
gap: "8px",
|
|
13002
|
+
padding: "10px 12px",
|
|
13003
|
+
background: "var(--bg-elevated)",
|
|
13004
|
+
border: "1px solid var(--border)",
|
|
13005
|
+
borderLeft: "3px solid",
|
|
13006
|
+
borderRadius: "var(--radius-sm)",
|
|
13007
|
+
boxShadow: "0 4px 16px rgba(0,0,0,0.4)",
|
|
13008
|
+
animation: "slideIn 0.2s ease-out"
|
|
13009
|
+
},
|
|
13010
|
+
message: {
|
|
13011
|
+
flex: 1,
|
|
13012
|
+
fontSize: "12px",
|
|
13013
|
+
color: "var(--text-primary)",
|
|
13014
|
+
lineHeight: 1.4
|
|
13015
|
+
},
|
|
13016
|
+
dismiss: {
|
|
13017
|
+
background: "transparent",
|
|
13018
|
+
border: "none",
|
|
13019
|
+
color: "var(--text-muted)",
|
|
13020
|
+
fontSize: "12px",
|
|
13021
|
+
cursor: "pointer",
|
|
13022
|
+
padding: "0 2px",
|
|
13023
|
+
flexShrink: 0
|
|
13024
|
+
}
|
|
13025
|
+
};
|
|
12144
13026
|
function App() {
|
|
12145
13027
|
const [view, setView] = reactExports.useState("home");
|
|
12146
13028
|
const [runPlanFile, setRunPlanFile] = reactExports.useState(null);
|
|
12147
13029
|
const runStatus = useRunStore((s) => s.status);
|
|
12148
13030
|
const { setMachines, addMachine, removeMachine, updateStatus } = useMachinesStore();
|
|
12149
13031
|
const { setSessions, addSession, updateSession, removeSession, applyStateChange } = useSessionsStore();
|
|
13032
|
+
const addToast = useToastsStore((s) => s.addToast);
|
|
13033
|
+
const prevStatesRef = reactExports.useRef(/* @__PURE__ */ new Map());
|
|
12150
13034
|
const waitingCount = useSessionsStore(
|
|
12151
13035
|
(s) => s.sessions.filter((sess) => sess.state === "waiting").length
|
|
12152
13036
|
);
|
|
@@ -12161,9 +13045,29 @@ function App() {
|
|
|
12161
13045
|
const unsubSessionData = window.maestro.sessions.onData((_ev) => {
|
|
12162
13046
|
});
|
|
12163
13047
|
const unsubStateChanged = window.maestro.sessions.onStateChanged((ev) => {
|
|
12164
|
-
|
|
13048
|
+
const event = ev;
|
|
13049
|
+
const prev = prevStatesRef.current.get(event.sessionId);
|
|
13050
|
+
if (prev && prev !== event.state) {
|
|
13051
|
+
const session = useSessionsStore.getState().sessions.find((s) => s.id === event.sessionId);
|
|
13052
|
+
const name = session?.name ?? event.sessionId.slice(0, 8);
|
|
13053
|
+
const labels = {
|
|
13054
|
+
working: "Working",
|
|
13055
|
+
waiting: "Waiting",
|
|
13056
|
+
permission: "Input Required",
|
|
13057
|
+
idle: "Idle",
|
|
13058
|
+
done: "Done",
|
|
13059
|
+
error: "Error"
|
|
13060
|
+
};
|
|
13061
|
+
addToast(`${name}: ${labels[prev] ?? prev} → ${labels[event.state] ?? event.state}`, "info");
|
|
13062
|
+
}
|
|
13063
|
+
prevStatesRef.current.set(event.sessionId, event.state);
|
|
13064
|
+
applyStateChange(event);
|
|
12165
13065
|
});
|
|
12166
13066
|
const unsubDestroyed = window.maestro.sessions.onDestroyed((id2) => {
|
|
13067
|
+
const session = useSessionsStore.getState().sessions.find((s) => s.id === id2);
|
|
13068
|
+
const name = session?.name ?? id2.slice(0, 8);
|
|
13069
|
+
addToast(`"${name}" session ended`, "warning");
|
|
13070
|
+
prevStatesRef.current.delete(id2);
|
|
12167
13071
|
removeSession(id2);
|
|
12168
13072
|
});
|
|
12169
13073
|
return () => {
|
|
@@ -12212,7 +13116,8 @@ function App() {
|
|
|
12212
13116
|
}
|
|
12213
13117
|
),
|
|
12214
13118
|
view === "terminals" && /* @__PURE__ */ jsxRuntimeExports.jsx(TerminalsView, { onSessionAdded: addSession })
|
|
12215
|
-
] })
|
|
13119
|
+
] }),
|
|
13120
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(ToastContainer, {})
|
|
12216
13121
|
] });
|
|
12217
13122
|
}
|
|
12218
13123
|
const styles = {
|