@rajat-rastogi/maestro 0.2.5 → 0.3.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.
|
@@ -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;
|
|
@@ -10619,10 +10635,36 @@ function useTerminalTile({
|
|
|
10619
10635
|
terminal.onData((data) => {
|
|
10620
10636
|
window.maestro.sessions.sendInput(sessionId, data);
|
|
10621
10637
|
});
|
|
10638
|
+
terminal.attachCustomKeyEventHandler((e) => {
|
|
10639
|
+
const isPaste = (e.ctrlKey || e.metaKey) && e.key === "v" && e.type === "keydown";
|
|
10640
|
+
if (!isPaste) return true;
|
|
10641
|
+
navigator.clipboard.readText().then((text) => {
|
|
10642
|
+
if (!text) return;
|
|
10643
|
+
const lines = text.split("\n");
|
|
10644
|
+
const sendPaste = () => {
|
|
10645
|
+
const wrapped = `\x1B[200~${text}\x1B[201~`;
|
|
10646
|
+
window.maestro.sessions.sendInput(sessionId, wrapped);
|
|
10647
|
+
};
|
|
10648
|
+
if (lines.length > 5 && onLargePaste) {
|
|
10649
|
+
onLargePaste(text, sendPaste);
|
|
10650
|
+
} else if (lines.length > 1) {
|
|
10651
|
+
sendPaste();
|
|
10652
|
+
} else {
|
|
10653
|
+
window.maestro.sessions.sendInput(sessionId, text);
|
|
10654
|
+
}
|
|
10655
|
+
});
|
|
10656
|
+
return false;
|
|
10657
|
+
});
|
|
10622
10658
|
}
|
|
10623
10659
|
handleRef.current = {
|
|
10624
10660
|
fit() {
|
|
10625
10661
|
if (fitAddon && terminal) fitAddon.fit();
|
|
10662
|
+
},
|
|
10663
|
+
getSelection() {
|
|
10664
|
+
return terminal?.getSelection() ?? "";
|
|
10665
|
+
},
|
|
10666
|
+
clearTerminal() {
|
|
10667
|
+
terminal?.clear();
|
|
10626
10668
|
}
|
|
10627
10669
|
};
|
|
10628
10670
|
const prev = unsubRef.current;
|
|
@@ -10634,6 +10676,7 @@ function useTerminalTile({
|
|
|
10634
10676
|
init().catch(console.error);
|
|
10635
10677
|
return () => {
|
|
10636
10678
|
destroyed = true;
|
|
10679
|
+
if (batchRaf) cancelAnimationFrame(batchRaf);
|
|
10637
10680
|
if (interactive) {
|
|
10638
10681
|
window.maestro.sessions.resize(sessionId, 120, 30).catch(() => {
|
|
10639
10682
|
});
|
|
@@ -10649,7 +10692,9 @@ function useTerminalTile({
|
|
|
10649
10692
|
const useSessionsStore = create((set) => ({
|
|
10650
10693
|
sessions: [],
|
|
10651
10694
|
activeFullscreenId: null,
|
|
10695
|
+
splitIds: null,
|
|
10652
10696
|
filterTags: {},
|
|
10697
|
+
filterStates: /* @__PURE__ */ new Set(),
|
|
10653
10698
|
setSessions(sessions) {
|
|
10654
10699
|
set({ sessions });
|
|
10655
10700
|
},
|
|
@@ -10677,24 +10722,130 @@ const useSessionsStore = create((set) => ({
|
|
|
10677
10722
|
}));
|
|
10678
10723
|
},
|
|
10679
10724
|
setFullscreen(id2) {
|
|
10680
|
-
set({ activeFullscreenId: id2 });
|
|
10725
|
+
set({ activeFullscreenId: id2, splitIds: null });
|
|
10726
|
+
},
|
|
10727
|
+
setSplit(ids) {
|
|
10728
|
+
set({ splitIds: ids, activeFullscreenId: null });
|
|
10681
10729
|
},
|
|
10682
10730
|
setFilterTags(tags) {
|
|
10683
10731
|
set({ filterTags: tags });
|
|
10732
|
+
},
|
|
10733
|
+
toggleFilterState(state) {
|
|
10734
|
+
set((s) => {
|
|
10735
|
+
const next = new Set(s.filterStates);
|
|
10736
|
+
if (next.has(state)) next.delete(state);
|
|
10737
|
+
else next.add(state);
|
|
10738
|
+
return { filterStates: next };
|
|
10739
|
+
});
|
|
10740
|
+
},
|
|
10741
|
+
clearFilterStates() {
|
|
10742
|
+
set({ filterStates: /* @__PURE__ */ new Set() });
|
|
10684
10743
|
}
|
|
10685
10744
|
}));
|
|
10686
|
-
function filterSessions(sessions, filterTags) {
|
|
10745
|
+
function filterSessions(sessions, filterTags, filterStates) {
|
|
10687
10746
|
const filterEntries = Object.entries(filterTags).filter(([k2, v2]) => k2 && (v2 || v2 === ""));
|
|
10688
|
-
|
|
10689
|
-
|
|
10690
|
-
|
|
10691
|
-
|
|
10692
|
-
|
|
10693
|
-
|
|
10694
|
-
return
|
|
10695
|
-
|
|
10696
|
-
|
|
10747
|
+
const hasTagFilter = filterEntries.length > 0;
|
|
10748
|
+
const hasStateFilter = filterStates && filterStates.size > 0;
|
|
10749
|
+
if (!hasTagFilter && !hasStateFilter) return sessions;
|
|
10750
|
+
return sessions.filter((s) => {
|
|
10751
|
+
if (hasStateFilter && !filterStates.has(s.state)) return false;
|
|
10752
|
+
if (hasTagFilter) {
|
|
10753
|
+
return filterEntries.every(([key, value]) => {
|
|
10754
|
+
const tagVal = s.tags[key];
|
|
10755
|
+
if (tagVal === void 0) return false;
|
|
10756
|
+
if (value === "" || value === "*") return true;
|
|
10757
|
+
return tagVal === value;
|
|
10758
|
+
});
|
|
10759
|
+
}
|
|
10760
|
+
return true;
|
|
10761
|
+
});
|
|
10762
|
+
}
|
|
10763
|
+
function ContextMenu({ x: x2, y: y2, items, onClose }) {
|
|
10764
|
+
const menuRef = reactExports.useRef(null);
|
|
10765
|
+
const [pos, setPos] = reactExports.useState({ left: x2, top: y2 });
|
|
10766
|
+
reactExports.useLayoutEffect(() => {
|
|
10767
|
+
if (!menuRef.current) return;
|
|
10768
|
+
const rect = menuRef.current.getBoundingClientRect();
|
|
10769
|
+
let left = x2;
|
|
10770
|
+
let top = y2;
|
|
10771
|
+
if (left + rect.width > window.innerWidth - 8) left = window.innerWidth - rect.width - 8;
|
|
10772
|
+
if (top + rect.height > window.innerHeight - 8) top = window.innerHeight - rect.height - 8;
|
|
10773
|
+
if (left < 8) left = 8;
|
|
10774
|
+
if (top < 8) top = 8;
|
|
10775
|
+
setPos({ left, top });
|
|
10776
|
+
}, [x2, y2]);
|
|
10777
|
+
reactExports.useEffect(() => {
|
|
10778
|
+
function onMouseDown(e) {
|
|
10779
|
+
if (menuRef.current && !menuRef.current.contains(e.target)) {
|
|
10780
|
+
onClose();
|
|
10781
|
+
}
|
|
10782
|
+
}
|
|
10783
|
+
function onKeyDown(e) {
|
|
10784
|
+
if (e.key === "Escape") onClose();
|
|
10785
|
+
}
|
|
10786
|
+
document.addEventListener("mousedown", onMouseDown);
|
|
10787
|
+
document.addEventListener("keydown", onKeyDown);
|
|
10788
|
+
return () => {
|
|
10789
|
+
document.removeEventListener("mousedown", onMouseDown);
|
|
10790
|
+
document.removeEventListener("keydown", onKeyDown);
|
|
10791
|
+
};
|
|
10792
|
+
}, [onClose]);
|
|
10793
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { ref: menuRef, style: { ...styles$a.menu, left: pos.left, top: pos.top }, children: items.map(
|
|
10794
|
+
(item, i) => item.divider ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$a.divider }, i) : /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
10795
|
+
"button",
|
|
10796
|
+
{
|
|
10797
|
+
style: { ...styles$a.item, ...item.danger ? { color: "var(--state-error)" } : {} },
|
|
10798
|
+
onClick: () => {
|
|
10799
|
+
item.onClick();
|
|
10800
|
+
onClose();
|
|
10801
|
+
},
|
|
10802
|
+
children: [
|
|
10803
|
+
item.icon && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$a.icon, children: item.icon }),
|
|
10804
|
+
item.label
|
|
10805
|
+
]
|
|
10806
|
+
},
|
|
10807
|
+
i
|
|
10808
|
+
)
|
|
10809
|
+
) });
|
|
10697
10810
|
}
|
|
10811
|
+
const styles$a = {
|
|
10812
|
+
menu: {
|
|
10813
|
+
position: "fixed",
|
|
10814
|
+
zIndex: 400,
|
|
10815
|
+
background: "var(--bg-elevated)",
|
|
10816
|
+
border: "1px solid var(--border)",
|
|
10817
|
+
borderRadius: "var(--radius-sm)",
|
|
10818
|
+
boxShadow: "0 4px 16px rgba(0,0,0,0.4)",
|
|
10819
|
+
minWidth: "160px",
|
|
10820
|
+
padding: "4px",
|
|
10821
|
+
display: "flex",
|
|
10822
|
+
flexDirection: "column"
|
|
10823
|
+
},
|
|
10824
|
+
item: {
|
|
10825
|
+
display: "flex",
|
|
10826
|
+
alignItems: "center",
|
|
10827
|
+
gap: "8px",
|
|
10828
|
+
background: "transparent",
|
|
10829
|
+
border: "none",
|
|
10830
|
+
color: "var(--text-secondary)",
|
|
10831
|
+
fontSize: "12px",
|
|
10832
|
+
padding: "6px 10px",
|
|
10833
|
+
textAlign: "left",
|
|
10834
|
+
borderRadius: "var(--radius-sm)",
|
|
10835
|
+
width: "100%",
|
|
10836
|
+
cursor: "pointer"
|
|
10837
|
+
},
|
|
10838
|
+
icon: {
|
|
10839
|
+
width: "16px",
|
|
10840
|
+
textAlign: "center",
|
|
10841
|
+
flexShrink: 0
|
|
10842
|
+
},
|
|
10843
|
+
divider: {
|
|
10844
|
+
height: "1px",
|
|
10845
|
+
background: "var(--border-subtle)",
|
|
10846
|
+
margin: "4px 0"
|
|
10847
|
+
}
|
|
10848
|
+
};
|
|
10698
10849
|
function TerminalTile({ session, onFullscreen, onClose, onRename, onEditTags }) {
|
|
10699
10850
|
const containerRef = reactExports.useRef(null);
|
|
10700
10851
|
const [menuOpen, setMenuOpen] = reactExports.useState(false);
|
|
@@ -10721,6 +10872,7 @@ function TerminalTile({ session, onFullscreen, onClose, onRename, onEditTags })
|
|
|
10721
10872
|
const customTags = Object.entries(session.tags).filter(
|
|
10722
10873
|
([k2]) => !["machine", "provider", "state"].includes(k2)
|
|
10723
10874
|
);
|
|
10875
|
+
const [ctxMenu, setCtxMenu] = reactExports.useState(null);
|
|
10724
10876
|
const handleRename = reactExports.useCallback(() => {
|
|
10725
10877
|
if (renameValue.trim() && renameValue !== session.name) {
|
|
10726
10878
|
window.maestro.sessions.rename(session.id, renameValue.trim());
|
|
@@ -10729,17 +10881,32 @@ function TerminalTile({ session, onFullscreen, onClose, onRename, onEditTags })
|
|
|
10729
10881
|
setRenaming(false);
|
|
10730
10882
|
setMenuOpen(false);
|
|
10731
10883
|
}, [renameValue, session]);
|
|
10884
|
+
const ctxMenuItems = [
|
|
10885
|
+
{ label: "Fullscreen", icon: "🔍", onClick: onFullscreen },
|
|
10886
|
+
{ label: "Rename", icon: "✏", onClick: () => setRenaming(true) },
|
|
10887
|
+
{ label: "Edit tags", icon: "🏷", onClick: onEditTags },
|
|
10888
|
+
{ divider: true, label: "", onClick: () => {
|
|
10889
|
+
} },
|
|
10890
|
+
{ label: "Stop & Clear", icon: "⏹", onClick: () => window.maestro.sessions.interrupt(session.id) },
|
|
10891
|
+
{ divider: true, label: "", onClick: () => {
|
|
10892
|
+
} },
|
|
10893
|
+
{ label: "Close", icon: "✕", onClick: onClose, danger: true }
|
|
10894
|
+
];
|
|
10732
10895
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
10733
10896
|
"div",
|
|
10734
10897
|
{
|
|
10735
|
-
style: styles$
|
|
10898
|
+
style: styles$9.tile,
|
|
10899
|
+
onContextMenu: (e) => {
|
|
10900
|
+
e.preventDefault();
|
|
10901
|
+
setCtxMenu({ x: e.clientX, y: e.clientY });
|
|
10902
|
+
},
|
|
10736
10903
|
onClick: (e) => {
|
|
10737
|
-
if (menuOpen || renaming) return;
|
|
10904
|
+
if (menuOpen || renaming || ctxMenu) return;
|
|
10738
10905
|
if (e.target.closest("[data-no-fullscreen]")) return;
|
|
10739
10906
|
onFullscreen();
|
|
10740
10907
|
},
|
|
10741
10908
|
children: [
|
|
10742
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
10909
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$9.header, onClick: (e) => e.stopPropagation(), children: [
|
|
10743
10910
|
renaming ? /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
10744
10911
|
"input",
|
|
10745
10912
|
{
|
|
@@ -10751,13 +10918,13 @@ function TerminalTile({ session, onFullscreen, onClose, onRename, onEditTags })
|
|
|
10751
10918
|
if (e.key === "Enter") handleRename();
|
|
10752
10919
|
if (e.key === "Escape") setRenaming(false);
|
|
10753
10920
|
},
|
|
10754
|
-
style: styles$
|
|
10921
|
+
style: styles$9.renameInput,
|
|
10755
10922
|
"data-no-fullscreen": ""
|
|
10756
10923
|
}
|
|
10757
|
-
) : /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$
|
|
10924
|
+
) : /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$9.sessionName, title: session.name, children: session.name }),
|
|
10758
10925
|
/* @__PURE__ */ jsxRuntimeExports.jsx(StateBadge, { state: session.state, confidence: session.stateConfidence, enteredAt: session.stateEnteredAt }),
|
|
10759
10926
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: { position: "relative" }, "data-no-fullscreen": "", children: [
|
|
10760
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { style: styles$
|
|
10927
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { style: styles$9.menuBtn, onClick: () => setMenuOpen((v2) => !v2), title: "Options", children: "⋯" }),
|
|
10761
10928
|
menuOpen && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
10762
10929
|
TileContextMenu,
|
|
10763
10930
|
{
|
|
@@ -10773,6 +10940,10 @@ function TerminalTile({ session, onFullscreen, onClose, onRename, onEditTags })
|
|
|
10773
10940
|
setMenuOpen(false);
|
|
10774
10941
|
onEditTags();
|
|
10775
10942
|
},
|
|
10943
|
+
onInterrupt: () => {
|
|
10944
|
+
setMenuOpen(false);
|
|
10945
|
+
window.maestro.sessions.interrupt(session.id);
|
|
10946
|
+
},
|
|
10776
10947
|
onClose: () => {
|
|
10777
10948
|
setMenuOpen(false);
|
|
10778
10949
|
onClose();
|
|
@@ -10781,32 +10952,35 @@ function TerminalTile({ session, onFullscreen, onClose, onRename, onEditTags })
|
|
|
10781
10952
|
)
|
|
10782
10953
|
] })
|
|
10783
10954
|
] }),
|
|
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$
|
|
10955
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$9.previewWrapper, children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { ref: containerRef, style: styles$9.xtermContainer }) }),
|
|
10956
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$9.footer, children: [
|
|
10957
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$9.footerRow, children: [
|
|
10958
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$9.providerBadge, children: session.provider }),
|
|
10959
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$9.dirLabel, title: session.workingDirectory, children: shortDir(session.workingDirectory) }),
|
|
10789
10960
|
/* @__PURE__ */ jsxRuntimeExports.jsx(ElapsedTimer, { enteredAt: session.stateEnteredAt, state: session.state })
|
|
10790
10961
|
] }),
|
|
10791
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
10792
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { style: styles$
|
|
10962
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$9.footerRow, children: [
|
|
10963
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { style: styles$9.machineName, children: [
|
|
10793
10964
|
"⬡ ",
|
|
10794
10965
|
machineName
|
|
10795
10966
|
] }),
|
|
10796
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$
|
|
10967
|
+
/* @__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
10968
|
] })
|
|
10798
|
-
] })
|
|
10969
|
+
] }),
|
|
10970
|
+
ctxMenu && /* @__PURE__ */ jsxRuntimeExports.jsx(ContextMenu, { x: ctxMenu.x, y: ctxMenu.y, items: ctxMenuItems, onClose: () => setCtxMenu(null) })
|
|
10799
10971
|
]
|
|
10800
10972
|
}
|
|
10801
10973
|
);
|
|
10802
10974
|
}
|
|
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:
|
|
10975
|
+
function TileContextMenu({ onFullscreen, onRename, onEditTags, onInterrupt, onClose }) {
|
|
10976
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$9.contextMenu, children: [
|
|
10977
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { style: styles$9.ctxItem, onClick: onFullscreen, children: "🔍 Go fullscreen" }),
|
|
10978
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { style: styles$9.ctxItem, onClick: onRename, children: "✏ Rename" }),
|
|
10979
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { style: styles$9.ctxItem, onClick: onEditTags, children: "🏷 Edit tags" }),
|
|
10980
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$9.ctxDivider }),
|
|
10981
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { style: styles$9.ctxItem, onClick: onInterrupt, children: "⏹ Stop & Clear" }),
|
|
10982
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$9.ctxDivider }),
|
|
10983
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { style: { ...styles$9.ctxItem, color: "var(--red)" }, onClick: onClose, children: "✕ Close" })
|
|
10810
10984
|
] });
|
|
10811
10985
|
}
|
|
10812
10986
|
function ElapsedTimer({ enteredAt, state }) {
|
|
@@ -10820,12 +10994,12 @@ function ElapsedTimer({ enteredAt, state }) {
|
|
|
10820
10994
|
const s = Math.floor(elapsed / 1e3);
|
|
10821
10995
|
const m2 = Math.floor(s / 60);
|
|
10822
10996
|
const label = m2 > 0 ? `${m2}:${String(s % 60).padStart(2, "0")}` : `${s}s`;
|
|
10823
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$
|
|
10997
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$9.elapsed, children: label });
|
|
10824
10998
|
}
|
|
10825
10999
|
function StateBadge({ state, confidence, enteredAt }) {
|
|
10826
11000
|
const { icon, label, color } = STATE_BADGE[state] ?? STATE_BADGE.idle;
|
|
10827
11001
|
const suffix = confidence === "heuristic" ? "?" : "";
|
|
10828
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { style: { ...styles$
|
|
11002
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { style: { ...styles$9.stateBadge, color, borderColor: `${color}40` }, children: [
|
|
10829
11003
|
icon,
|
|
10830
11004
|
" ",
|
|
10831
11005
|
label,
|
|
@@ -10845,7 +11019,7 @@ function shortDir(dir) {
|
|
|
10845
11019
|
const parts = dir.replace(/\\/g, "/").split("/");
|
|
10846
11020
|
return parts.length > 2 ? `…/${parts.slice(-2).join("/")}` : dir;
|
|
10847
11021
|
}
|
|
10848
|
-
const styles$
|
|
11022
|
+
const styles$9 = {
|
|
10849
11023
|
tile: {
|
|
10850
11024
|
display: "flex",
|
|
10851
11025
|
flexDirection: "column",
|
|
@@ -11015,10 +11189,13 @@ const STATE_LABEL = {
|
|
|
11015
11189
|
};
|
|
11016
11190
|
function FullscreenOverlay({ session, onClose }) {
|
|
11017
11191
|
const containerRef = reactExports.useRef(null);
|
|
11018
|
-
|
|
11192
|
+
const [ctxMenu, setCtxMenu] = reactExports.useState(null);
|
|
11193
|
+
const [pendingPaste, setPendingPaste] = reactExports.useState(null);
|
|
11194
|
+
const handleRef = useTerminalTile({
|
|
11019
11195
|
containerRef,
|
|
11020
11196
|
sessionId: session.id,
|
|
11021
|
-
interactive: true
|
|
11197
|
+
interactive: true,
|
|
11198
|
+
onLargePaste: (text, send) => setPendingPaste({ text, send })
|
|
11022
11199
|
});
|
|
11023
11200
|
reactExports.useEffect(() => {
|
|
11024
11201
|
const handler = (e) => {
|
|
@@ -11029,25 +11206,87 @@ function FullscreenOverlay({ session, onClose }) {
|
|
|
11029
11206
|
}, [onClose]);
|
|
11030
11207
|
const stateColor = STATE_BADGE_COLOR[session.state] ?? "var(--state-idle)";
|
|
11031
11208
|
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$
|
|
11209
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$8.overlay, children: [
|
|
11210
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$8.header, children: [
|
|
11211
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$8.sessionName, children: session.name }),
|
|
11212
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$8.dot, children: "·" }),
|
|
11213
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$8.meta, children: session.provider }),
|
|
11214
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$8.dot, children: "·" }),
|
|
11215
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$8.meta, children: machineName }),
|
|
11216
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$8.dot, children: "·" }),
|
|
11217
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { style: { ...styles$8.stateBadge, color: stateColor }, children: [
|
|
11041
11218
|
STATE_LABEL[session.state] ?? session.state,
|
|
11042
11219
|
session.stateConfidence === "heuristic" ? "?" : ""
|
|
11043
11220
|
] }),
|
|
11044
11221
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: { flex: 1 } }),
|
|
11045
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { style: styles$
|
|
11222
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { style: styles$8.closeBtn, onClick: onClose, title: "Close fullscreen (Esc)", children: "⊠" })
|
|
11046
11223
|
] }),
|
|
11047
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
11224
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
11225
|
+
"div",
|
|
11226
|
+
{
|
|
11227
|
+
ref: containerRef,
|
|
11228
|
+
style: styles$8.terminalBody,
|
|
11229
|
+
onContextMenu: (e) => {
|
|
11230
|
+
e.preventDefault();
|
|
11231
|
+
setCtxMenu({ x: e.clientX, y: e.clientY });
|
|
11232
|
+
}
|
|
11233
|
+
}
|
|
11234
|
+
),
|
|
11235
|
+
ctxMenu && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
11236
|
+
ContextMenu,
|
|
11237
|
+
{
|
|
11238
|
+
x: ctxMenu.x,
|
|
11239
|
+
y: ctxMenu.y,
|
|
11240
|
+
items: [
|
|
11241
|
+
{
|
|
11242
|
+
label: "Copy",
|
|
11243
|
+
icon: "📋",
|
|
11244
|
+
onClick: () => {
|
|
11245
|
+
const sel = handleRef.current?.getSelection() ?? "";
|
|
11246
|
+
if (sel) navigator.clipboard.writeText(sel);
|
|
11247
|
+
}
|
|
11248
|
+
},
|
|
11249
|
+
{
|
|
11250
|
+
label: "Paste",
|
|
11251
|
+
icon: "📎",
|
|
11252
|
+
onClick: () => {
|
|
11253
|
+
navigator.clipboard.readText().then((text) => {
|
|
11254
|
+
if (text) window.maestro.sessions.sendInput(session.id, text);
|
|
11255
|
+
});
|
|
11256
|
+
}
|
|
11257
|
+
},
|
|
11258
|
+
{ divider: true, label: "", onClick: () => {
|
|
11259
|
+
} },
|
|
11260
|
+
{
|
|
11261
|
+
label: "Clear terminal",
|
|
11262
|
+
icon: "🗑",
|
|
11263
|
+
onClick: () => handleRef.current?.clearTerminal()
|
|
11264
|
+
}
|
|
11265
|
+
],
|
|
11266
|
+
onClose: () => setCtxMenu(null)
|
|
11267
|
+
}
|
|
11268
|
+
),
|
|
11269
|
+
pendingPaste && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$8.pasteOverlay, children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$8.pasteDialog, children: [
|
|
11270
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$8.pasteTitle, children: [
|
|
11271
|
+
"Paste ",
|
|
11272
|
+
pendingPaste.text.split("\n").length,
|
|
11273
|
+
" lines?"
|
|
11274
|
+
] }),
|
|
11275
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("pre", { style: styles$8.pastePreview, children: [
|
|
11276
|
+
pendingPaste.text.split("\n").slice(0, 10).join("\n"),
|
|
11277
|
+
pendingPaste.text.split("\n").length > 10 ? "\n..." : ""
|
|
11278
|
+
] }),
|
|
11279
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$8.pasteActions, children: [
|
|
11280
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: "btn btn-ghost btn-sm", onClick: () => setPendingPaste(null), children: "Cancel" }),
|
|
11281
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: "btn btn-primary btn-sm", onClick: () => {
|
|
11282
|
+
pendingPaste.send();
|
|
11283
|
+
setPendingPaste(null);
|
|
11284
|
+
}, children: "Paste" })
|
|
11285
|
+
] })
|
|
11286
|
+
] }) })
|
|
11048
11287
|
] });
|
|
11049
11288
|
}
|
|
11050
|
-
const styles$
|
|
11289
|
+
const styles$8 = {
|
|
11051
11290
|
overlay: {
|
|
11052
11291
|
position: "fixed",
|
|
11053
11292
|
inset: 0,
|
|
@@ -11095,6 +11334,325 @@ const styles$5 = {
|
|
|
11095
11334
|
flex: 1,
|
|
11096
11335
|
overflow: "hidden",
|
|
11097
11336
|
padding: "8px"
|
|
11337
|
+
},
|
|
11338
|
+
pasteOverlay: {
|
|
11339
|
+
position: "fixed",
|
|
11340
|
+
inset: 0,
|
|
11341
|
+
background: "rgba(0,0,0,0.6)",
|
|
11342
|
+
display: "flex",
|
|
11343
|
+
alignItems: "center",
|
|
11344
|
+
justifyContent: "center",
|
|
11345
|
+
zIndex: 250
|
|
11346
|
+
},
|
|
11347
|
+
pasteDialog: {
|
|
11348
|
+
background: "var(--bg-surface)",
|
|
11349
|
+
border: "1px solid var(--border)",
|
|
11350
|
+
borderRadius: "var(--radius)",
|
|
11351
|
+
padding: "16px",
|
|
11352
|
+
maxWidth: "480px",
|
|
11353
|
+
width: "90%"
|
|
11354
|
+
},
|
|
11355
|
+
pasteTitle: {
|
|
11356
|
+
fontSize: "14px",
|
|
11357
|
+
fontWeight: 600,
|
|
11358
|
+
marginBottom: "12px",
|
|
11359
|
+
color: "var(--text-primary)"
|
|
11360
|
+
},
|
|
11361
|
+
pastePreview: {
|
|
11362
|
+
fontSize: "11px",
|
|
11363
|
+
fontFamily: "'Cascadia Code', Consolas, monospace",
|
|
11364
|
+
background: "var(--bg-base)",
|
|
11365
|
+
border: "1px solid var(--border)",
|
|
11366
|
+
borderRadius: "var(--radius-sm)",
|
|
11367
|
+
padding: "10px",
|
|
11368
|
+
maxHeight: "200px",
|
|
11369
|
+
overflow: "auto",
|
|
11370
|
+
color: "var(--text-secondary)",
|
|
11371
|
+
whiteSpace: "pre-wrap",
|
|
11372
|
+
margin: 0
|
|
11373
|
+
},
|
|
11374
|
+
pasteActions: {
|
|
11375
|
+
display: "flex",
|
|
11376
|
+
justifyContent: "flex-end",
|
|
11377
|
+
gap: "8px",
|
|
11378
|
+
marginTop: "12px"
|
|
11379
|
+
}
|
|
11380
|
+
};
|
|
11381
|
+
function SplitPaneOverlay({ left, right, onClose }) {
|
|
11382
|
+
const leftRef = reactExports.useRef(null);
|
|
11383
|
+
const rightRef = reactExports.useRef(null);
|
|
11384
|
+
const [focusSide, setFocusSide] = reactExports.useState("left");
|
|
11385
|
+
useTerminalTile({ containerRef: leftRef, sessionId: left.id, interactive: true });
|
|
11386
|
+
useTerminalTile({ containerRef: rightRef, sessionId: right.id, interactive: true });
|
|
11387
|
+
reactExports.useEffect(() => {
|
|
11388
|
+
function onKeyDown(e) {
|
|
11389
|
+
if (e.key === "Escape") {
|
|
11390
|
+
onClose();
|
|
11391
|
+
return;
|
|
11392
|
+
}
|
|
11393
|
+
const ctrlOrCmd = e.ctrlKey || e.metaKey;
|
|
11394
|
+
if (ctrlOrCmd && e.key === "1") {
|
|
11395
|
+
e.preventDefault();
|
|
11396
|
+
setFocusSide("left");
|
|
11397
|
+
}
|
|
11398
|
+
if (ctrlOrCmd && e.key === "2") {
|
|
11399
|
+
e.preventDefault();
|
|
11400
|
+
setFocusSide("right");
|
|
11401
|
+
}
|
|
11402
|
+
}
|
|
11403
|
+
window.addEventListener("keydown", onKeyDown);
|
|
11404
|
+
return () => window.removeEventListener("keydown", onKeyDown);
|
|
11405
|
+
}, [onClose]);
|
|
11406
|
+
reactExports.useEffect(() => {
|
|
11407
|
+
const target = focusSide === "left" ? leftRef.current : rightRef.current;
|
|
11408
|
+
const textarea = target?.querySelector("textarea");
|
|
11409
|
+
textarea?.focus();
|
|
11410
|
+
}, [focusSide]);
|
|
11411
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$7.overlay, children: [
|
|
11412
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$7.header, children: [
|
|
11413
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
11414
|
+
PaneTab,
|
|
11415
|
+
{
|
|
11416
|
+
session: left,
|
|
11417
|
+
active: focusSide === "left",
|
|
11418
|
+
onClick: () => setFocusSide("left")
|
|
11419
|
+
}
|
|
11420
|
+
),
|
|
11421
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
11422
|
+
PaneTab,
|
|
11423
|
+
{
|
|
11424
|
+
session: right,
|
|
11425
|
+
active: focusSide === "right",
|
|
11426
|
+
onClick: () => setFocusSide("right")
|
|
11427
|
+
}
|
|
11428
|
+
),
|
|
11429
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: { flex: 1 } }),
|
|
11430
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$7.hint, children: "Ctrl+1/2 switch · Esc close" }),
|
|
11431
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { style: styles$7.closeBtn, onClick: onClose, title: "Close split (Esc)", children: "⊠" })
|
|
11432
|
+
] }),
|
|
11433
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$7.panes, children: [
|
|
11434
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
11435
|
+
"div",
|
|
11436
|
+
{
|
|
11437
|
+
ref: leftRef,
|
|
11438
|
+
style: {
|
|
11439
|
+
...styles$7.pane,
|
|
11440
|
+
borderColor: focusSide === "left" ? "var(--accent)" : "var(--border-subtle)"
|
|
11441
|
+
},
|
|
11442
|
+
onClick: () => setFocusSide("left")
|
|
11443
|
+
}
|
|
11444
|
+
),
|
|
11445
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$7.divider }),
|
|
11446
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
11447
|
+
"div",
|
|
11448
|
+
{
|
|
11449
|
+
ref: rightRef,
|
|
11450
|
+
style: {
|
|
11451
|
+
...styles$7.pane,
|
|
11452
|
+
borderColor: focusSide === "right" ? "var(--accent)" : "var(--border-subtle)"
|
|
11453
|
+
},
|
|
11454
|
+
onClick: () => setFocusSide("right")
|
|
11455
|
+
}
|
|
11456
|
+
)
|
|
11457
|
+
] })
|
|
11458
|
+
] });
|
|
11459
|
+
}
|
|
11460
|
+
function PaneTab({ session, active, onClick }) {
|
|
11461
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
11462
|
+
"button",
|
|
11463
|
+
{
|
|
11464
|
+
style: {
|
|
11465
|
+
...styles$7.tab,
|
|
11466
|
+
background: active ? "var(--bg-base)" : "transparent",
|
|
11467
|
+
color: active ? "var(--text-primary)" : "var(--text-muted)",
|
|
11468
|
+
borderBottomColor: active ? "var(--accent)" : "transparent"
|
|
11469
|
+
},
|
|
11470
|
+
onClick,
|
|
11471
|
+
children: session.name
|
|
11472
|
+
}
|
|
11473
|
+
);
|
|
11474
|
+
}
|
|
11475
|
+
const styles$7 = {
|
|
11476
|
+
overlay: {
|
|
11477
|
+
position: "fixed",
|
|
11478
|
+
inset: 0,
|
|
11479
|
+
zIndex: 200,
|
|
11480
|
+
background: "var(--bg-base)",
|
|
11481
|
+
display: "flex",
|
|
11482
|
+
flexDirection: "column"
|
|
11483
|
+
},
|
|
11484
|
+
header: {
|
|
11485
|
+
display: "flex",
|
|
11486
|
+
alignItems: "center",
|
|
11487
|
+
gap: "4px",
|
|
11488
|
+
padding: "6px 16px",
|
|
11489
|
+
background: "var(--bg-surface)",
|
|
11490
|
+
borderBottom: "1px solid var(--border)",
|
|
11491
|
+
flexShrink: 0
|
|
11492
|
+
},
|
|
11493
|
+
tab: {
|
|
11494
|
+
fontSize: "12px",
|
|
11495
|
+
fontWeight: 600,
|
|
11496
|
+
padding: "6px 12px",
|
|
11497
|
+
border: "none",
|
|
11498
|
+
borderBottom: "2px solid",
|
|
11499
|
+
cursor: "pointer"
|
|
11500
|
+
},
|
|
11501
|
+
hint: {
|
|
11502
|
+
fontSize: "11px",
|
|
11503
|
+
color: "var(--text-muted)",
|
|
11504
|
+
marginRight: "8px"
|
|
11505
|
+
},
|
|
11506
|
+
closeBtn: {
|
|
11507
|
+
background: "transparent",
|
|
11508
|
+
border: "none",
|
|
11509
|
+
color: "var(--text-muted)",
|
|
11510
|
+
fontSize: "18px",
|
|
11511
|
+
cursor: "pointer"
|
|
11512
|
+
},
|
|
11513
|
+
panes: {
|
|
11514
|
+
flex: 1,
|
|
11515
|
+
display: "flex",
|
|
11516
|
+
overflow: "hidden"
|
|
11517
|
+
},
|
|
11518
|
+
pane: {
|
|
11519
|
+
flex: 1,
|
|
11520
|
+
position: "relative",
|
|
11521
|
+
overflow: "hidden",
|
|
11522
|
+
padding: "4px",
|
|
11523
|
+
border: "2px solid",
|
|
11524
|
+
borderRadius: "2px"
|
|
11525
|
+
},
|
|
11526
|
+
divider: {
|
|
11527
|
+
width: "4px",
|
|
11528
|
+
background: "var(--border)",
|
|
11529
|
+
flexShrink: 0,
|
|
11530
|
+
cursor: "col-resize"
|
|
11531
|
+
}
|
|
11532
|
+
};
|
|
11533
|
+
function TabbedWorkspace({ sessions, onClose }) {
|
|
11534
|
+
const [activeTabId, setActiveTabId] = reactExports.useState(
|
|
11535
|
+
sessions[0]?.id ?? null
|
|
11536
|
+
);
|
|
11537
|
+
const [closedTabs, setClosedTabs] = reactExports.useState([]);
|
|
11538
|
+
React$2.useEffect(() => {
|
|
11539
|
+
function onKeyDown(e) {
|
|
11540
|
+
if ((e.ctrlKey || e.metaKey) && e.shiftKey && e.key === "T") {
|
|
11541
|
+
e.preventDefault();
|
|
11542
|
+
if (closedTabs.length > 0) {
|
|
11543
|
+
const lastClosed = closedTabs[closedTabs.length - 1];
|
|
11544
|
+
setClosedTabs((prev) => prev.slice(0, -1));
|
|
11545
|
+
setActiveTabId(lastClosed);
|
|
11546
|
+
}
|
|
11547
|
+
}
|
|
11548
|
+
}
|
|
11549
|
+
window.addEventListener("keydown", onKeyDown);
|
|
11550
|
+
return () => window.removeEventListener("keydown", onKeyDown);
|
|
11551
|
+
}, [closedTabs]);
|
|
11552
|
+
const activeSession = sessions.find((s) => s.id === activeTabId) ?? sessions[0];
|
|
11553
|
+
const visibleSessions = sessions.filter((s) => !closedTabs.includes(s.id));
|
|
11554
|
+
function handleCloseTab(e, id2) {
|
|
11555
|
+
e.stopPropagation();
|
|
11556
|
+
setClosedTabs((prev) => [...prev, id2]);
|
|
11557
|
+
if (activeTabId === id2) {
|
|
11558
|
+
const remaining = visibleSessions.filter((s) => s.id !== id2);
|
|
11559
|
+
setActiveTabId(remaining[0]?.id ?? null);
|
|
11560
|
+
}
|
|
11561
|
+
}
|
|
11562
|
+
if (!activeSession || visibleSessions.length === 0) {
|
|
11563
|
+
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." }) });
|
|
11564
|
+
}
|
|
11565
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$6.root, children: [
|
|
11566
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$6.tabBar, children: visibleSessions.map((session) => /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
11567
|
+
"button",
|
|
11568
|
+
{
|
|
11569
|
+
style: {
|
|
11570
|
+
...styles$6.tab,
|
|
11571
|
+
background: session.id === activeTabId ? "var(--bg-base)" : "transparent",
|
|
11572
|
+
color: session.id === activeTabId ? "var(--text-primary)" : "var(--text-muted)",
|
|
11573
|
+
borderBottomColor: session.id === activeTabId ? "var(--accent)" : "transparent"
|
|
11574
|
+
},
|
|
11575
|
+
onClick: () => setActiveTabId(session.id),
|
|
11576
|
+
onAuxClick: (e) => {
|
|
11577
|
+
if (e.button === 1) handleCloseTab(e, session.id);
|
|
11578
|
+
},
|
|
11579
|
+
title: `${session.name} · ${session.provider} · ${session.state}`,
|
|
11580
|
+
children: [
|
|
11581
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$6.tabName, children: session.name }),
|
|
11582
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
11583
|
+
"span",
|
|
11584
|
+
{
|
|
11585
|
+
style: styles$6.tabClose,
|
|
11586
|
+
onClick: (e) => handleCloseTab(e, session.id),
|
|
11587
|
+
children: "×"
|
|
11588
|
+
}
|
|
11589
|
+
)
|
|
11590
|
+
]
|
|
11591
|
+
},
|
|
11592
|
+
session.id
|
|
11593
|
+
)) }),
|
|
11594
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(ActiveTerminal, { session: activeSession }, activeSession.id)
|
|
11595
|
+
] });
|
|
11596
|
+
}
|
|
11597
|
+
function ActiveTerminal({ session }) {
|
|
11598
|
+
const containerRef = reactExports.useRef(null);
|
|
11599
|
+
useTerminalTile({
|
|
11600
|
+
containerRef,
|
|
11601
|
+
sessionId: session.id,
|
|
11602
|
+
interactive: true
|
|
11603
|
+
});
|
|
11604
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { ref: containerRef, style: styles$6.terminal });
|
|
11605
|
+
}
|
|
11606
|
+
const styles$6 = {
|
|
11607
|
+
root: {
|
|
11608
|
+
display: "flex",
|
|
11609
|
+
flexDirection: "column",
|
|
11610
|
+
height: "100%"
|
|
11611
|
+
},
|
|
11612
|
+
tabBar: {
|
|
11613
|
+
display: "flex",
|
|
11614
|
+
alignItems: "stretch",
|
|
11615
|
+
background: "var(--bg-surface)",
|
|
11616
|
+
borderBottom: "1px solid var(--border)",
|
|
11617
|
+
overflowX: "auto",
|
|
11618
|
+
flexShrink: 0
|
|
11619
|
+
},
|
|
11620
|
+
tab: {
|
|
11621
|
+
display: "flex",
|
|
11622
|
+
alignItems: "center",
|
|
11623
|
+
gap: "6px",
|
|
11624
|
+
padding: "8px 14px",
|
|
11625
|
+
fontSize: "12px",
|
|
11626
|
+
fontWeight: 500,
|
|
11627
|
+
border: "none",
|
|
11628
|
+
borderBottom: "2px solid",
|
|
11629
|
+
cursor: "pointer",
|
|
11630
|
+
maxWidth: "180px",
|
|
11631
|
+
minWidth: "80px",
|
|
11632
|
+
flexShrink: 0,
|
|
11633
|
+
whiteSpace: "nowrap"
|
|
11634
|
+
},
|
|
11635
|
+
tabName: {
|
|
11636
|
+
overflow: "hidden",
|
|
11637
|
+
textOverflow: "ellipsis"
|
|
11638
|
+
},
|
|
11639
|
+
tabClose: {
|
|
11640
|
+
fontSize: "14px",
|
|
11641
|
+
lineHeight: 1,
|
|
11642
|
+
opacity: 0.5,
|
|
11643
|
+
flexShrink: 0
|
|
11644
|
+
},
|
|
11645
|
+
terminal: {
|
|
11646
|
+
flex: 1,
|
|
11647
|
+
position: "relative",
|
|
11648
|
+
overflow: "hidden",
|
|
11649
|
+
padding: "8px"
|
|
11650
|
+
},
|
|
11651
|
+
empty: {
|
|
11652
|
+
display: "flex",
|
|
11653
|
+
alignItems: "center",
|
|
11654
|
+
justifyContent: "center",
|
|
11655
|
+
height: "100%"
|
|
11098
11656
|
}
|
|
11099
11657
|
};
|
|
11100
11658
|
function DirectoryBrowser({ machineId, initialPath, onSelect }) {
|
|
@@ -11131,9 +11689,9 @@ function DirectoryBrowser({ machineId, initialPath, onSelect }) {
|
|
|
11131
11689
|
}
|
|
11132
11690
|
}
|
|
11133
11691
|
if (loading) {
|
|
11134
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$
|
|
11692
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$5.loading, children: "Loading directory tree…" });
|
|
11135
11693
|
}
|
|
11136
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$
|
|
11694
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$5.root, children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
11137
11695
|
TreeLevel,
|
|
11138
11696
|
{
|
|
11139
11697
|
nodes: roots,
|
|
@@ -11150,15 +11708,15 @@ function TreeLevel({ nodes, setNodes, selected, onToggle, depth }) {
|
|
|
11150
11708
|
"button",
|
|
11151
11709
|
{
|
|
11152
11710
|
style: {
|
|
11153
|
-
...styles$
|
|
11711
|
+
...styles$5.treeItem,
|
|
11154
11712
|
paddingLeft: `${12 + depth * 14}px`,
|
|
11155
11713
|
background: selected === node.path ? "var(--accent-muted)" : "transparent",
|
|
11156
11714
|
color: selected === node.path ? "var(--text-primary)" : "var(--text-secondary)"
|
|
11157
11715
|
},
|
|
11158
11716
|
onClick: () => onToggle(node, nodes, setNodes),
|
|
11159
11717
|
children: [
|
|
11160
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$
|
|
11161
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$
|
|
11718
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$5.treeIcon, children: node.isDir ? node.loading ? "⏳" : node.expanded ? "▼" : "▶" : "📄" }),
|
|
11719
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$5.treeName, children: node.name })
|
|
11162
11720
|
]
|
|
11163
11721
|
}
|
|
11164
11722
|
),
|
|
@@ -11189,7 +11747,7 @@ function updateNode(nodes, targetPath, updates) {
|
|
|
11189
11747
|
return n2;
|
|
11190
11748
|
});
|
|
11191
11749
|
}
|
|
11192
|
-
const styles$
|
|
11750
|
+
const styles$5 = {
|
|
11193
11751
|
root: {
|
|
11194
11752
|
border: "1px solid var(--border)",
|
|
11195
11753
|
borderRadius: "var(--radius-sm)",
|
|
@@ -11238,6 +11796,13 @@ function CreateTerminalModal({ onClose, onCreated }) {
|
|
|
11238
11796
|
const [creating, setCreating] = reactExports.useState(false);
|
|
11239
11797
|
const [error, setError] = reactExports.useState("");
|
|
11240
11798
|
const machines = useMachinesStore((s) => s.machines.filter((m2) => m2.onboarded));
|
|
11799
|
+
const prevMachineRef = React$2.useRef(machineId);
|
|
11800
|
+
React$2.useEffect(() => {
|
|
11801
|
+
if (prevMachineRef.current !== machineId) {
|
|
11802
|
+
prevMachineRef.current = machineId;
|
|
11803
|
+
setDirectory("");
|
|
11804
|
+
}
|
|
11805
|
+
}, [machineId]);
|
|
11241
11806
|
async function handleCreate() {
|
|
11242
11807
|
setCreating(true);
|
|
11243
11808
|
setError("");
|
|
@@ -11272,17 +11837,17 @@ function CreateTerminalModal({ onClose, onCreated }) {
|
|
|
11272
11837
|
return next;
|
|
11273
11838
|
});
|
|
11274
11839
|
}
|
|
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$
|
|
11840
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$4.overlay, children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$4.dialog, children: [
|
|
11841
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$4.dialogHeader, children: [
|
|
11842
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$4.dialogTitle, children: "New Terminal" }),
|
|
11843
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { style: styles$4.stepLabel, children: [
|
|
11279
11844
|
"Step ",
|
|
11280
11845
|
step,
|
|
11281
11846
|
" of 3"
|
|
11282
11847
|
] }),
|
|
11283
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { style: styles$
|
|
11848
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { style: styles$4.closeBtn, onClick: onClose, children: "✕" })
|
|
11284
11849
|
] }),
|
|
11285
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
11850
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$4.body, children: [
|
|
11286
11851
|
step === 1 && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
11287
11852
|
Step1,
|
|
11288
11853
|
{
|
|
@@ -11319,7 +11884,7 @@ function CreateTerminalModal({ onClose, onCreated }) {
|
|
|
11319
11884
|
}
|
|
11320
11885
|
)
|
|
11321
11886
|
] }),
|
|
11322
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
11887
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$4.dialogFooter, children: [
|
|
11323
11888
|
step > 1 && /* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: "btn btn-ghost", onClick: () => setStep((s) => s - 1), children: "← Back" }),
|
|
11324
11889
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: { flex: 1 } }),
|
|
11325
11890
|
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: "btn btn-ghost", onClick: onClose, children: "Cancel" }),
|
|
@@ -11344,9 +11909,9 @@ function CreateTerminalModal({ onClose, onCreated }) {
|
|
|
11344
11909
|
] }) });
|
|
11345
11910
|
}
|
|
11346
11911
|
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$
|
|
11912
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$4.step, children: [
|
|
11913
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$4.field, children: [
|
|
11914
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("label", { style: styles$4.label, children: "Session name" }),
|
|
11350
11915
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
11351
11916
|
"input",
|
|
11352
11917
|
{
|
|
@@ -11358,14 +11923,14 @@ function Step1({ name, setName, machineId, setMachineId, provider, setProvider,
|
|
|
11358
11923
|
}
|
|
11359
11924
|
)
|
|
11360
11925
|
] }),
|
|
11361
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
11362
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("label", { style: styles$
|
|
11363
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$
|
|
11926
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$4.field, children: [
|
|
11927
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("label", { style: styles$4.label, children: "Machine" }),
|
|
11928
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$4.machineList, children: machines.map((m2) => /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
11364
11929
|
"button",
|
|
11365
11930
|
{
|
|
11366
11931
|
style: {
|
|
11367
|
-
...styles$
|
|
11368
|
-
...machineId === m2.id ? styles$
|
|
11932
|
+
...styles$4.machineOption,
|
|
11933
|
+
...machineId === m2.id ? styles$4.machineOptionSelected : {}
|
|
11369
11934
|
},
|
|
11370
11935
|
onClick: () => setMachineId(m2.id),
|
|
11371
11936
|
children: [
|
|
@@ -11377,14 +11942,14 @@ function Step1({ name, setName, machineId, setMachineId, provider, setProvider,
|
|
|
11377
11942
|
m2.id
|
|
11378
11943
|
)) })
|
|
11379
11944
|
] }),
|
|
11380
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
11381
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("label", { style: styles$
|
|
11382
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$
|
|
11945
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$4.field, children: [
|
|
11946
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("label", { style: styles$4.label, children: "AI Provider" }),
|
|
11947
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$4.providerRow, children: ["claude", "copilot", "none"].map((p2) => /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
11383
11948
|
"button",
|
|
11384
11949
|
{
|
|
11385
11950
|
style: {
|
|
11386
|
-
...styles$
|
|
11387
|
-
...provider === p2 ? styles$
|
|
11951
|
+
...styles$4.providerBtn,
|
|
11952
|
+
...provider === p2 ? styles$4.providerBtnSelected : {}
|
|
11388
11953
|
},
|
|
11389
11954
|
onClick: () => setProvider(p2),
|
|
11390
11955
|
children: p2
|
|
@@ -11398,15 +11963,16 @@ function Step2({ machineId, directory, setDirectory }) {
|
|
|
11398
11963
|
const [showBrowser, setShowBrowser] = reactExports.useState(true);
|
|
11399
11964
|
const [homeDir, setHomeDir] = reactExports.useState("C:\\");
|
|
11400
11965
|
React$2.useEffect(() => {
|
|
11966
|
+
setDirectory("");
|
|
11401
11967
|
window.maestro.fs.homeDir(machineId).then((h) => {
|
|
11402
11968
|
setHomeDir(h);
|
|
11403
|
-
|
|
11969
|
+
setDirectory(h);
|
|
11404
11970
|
}).catch(() => {
|
|
11405
11971
|
});
|
|
11406
11972
|
}, [machineId]);
|
|
11407
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
11408
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
11409
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("label", { style: styles$
|
|
11973
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$4.step, children: [
|
|
11974
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$4.field, children: [
|
|
11975
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("label", { style: styles$4.label, children: "Working directory" }),
|
|
11410
11976
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
11411
11977
|
"input",
|
|
11412
11978
|
{
|
|
@@ -11420,7 +11986,7 @@ function Step2({ machineId, directory, setDirectory }) {
|
|
|
11420
11986
|
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
11421
11987
|
"button",
|
|
11422
11988
|
{
|
|
11423
|
-
style: styles$
|
|
11989
|
+
style: styles$4.browserToggle,
|
|
11424
11990
|
onClick: () => setShowBrowser((v2) => !v2),
|
|
11425
11991
|
children: [
|
|
11426
11992
|
showBrowser ? "▼" : "▶",
|
|
@@ -11436,17 +12002,17 @@ function Step2({ machineId, directory, setDirectory }) {
|
|
|
11436
12002
|
onSelect: setDirectory
|
|
11437
12003
|
}
|
|
11438
12004
|
),
|
|
11439
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { style: styles$
|
|
12005
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { style: styles$4.hint, children: "Select a directory above or type the path manually." })
|
|
11440
12006
|
] });
|
|
11441
12007
|
}
|
|
11442
12008
|
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$
|
|
12009
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$4.step, children: [
|
|
12010
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$4.field, children: [
|
|
12011
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("label", { style: styles$4.label, children: "Tags (optional)" }),
|
|
12012
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$4.tagEditor, children: [
|
|
12013
|
+
Object.entries(tags).map(([k2, v2]) => /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { style: styles$4.tagChip, children: [
|
|
11448
12014
|
v2 ? `${k2}:${v2}` : k2,
|
|
11449
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { style: styles$
|
|
12015
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { style: styles$4.tagRemove, onClick: () => removeTag(k2), children: "×" })
|
|
11450
12016
|
] }, k2)),
|
|
11451
12017
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
11452
12018
|
"input",
|
|
@@ -11461,35 +12027,35 @@ function Step3({ name, machineId, provider, directory, tags, tagInput, setTagInp
|
|
|
11461
12027
|
}
|
|
11462
12028
|
},
|
|
11463
12029
|
placeholder: "type tag and press Enter…",
|
|
11464
|
-
style: styles$
|
|
12030
|
+
style: styles$4.tagInput
|
|
11465
12031
|
}
|
|
11466
12032
|
)
|
|
11467
12033
|
] }),
|
|
11468
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { style: styles$
|
|
12034
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { style: styles$4.hint, children: "Use key:value or plain labels. Press Enter to add." })
|
|
11469
12035
|
] }),
|
|
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$
|
|
12036
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$4.summary, children: [
|
|
12037
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$4.summaryTitle, children: "Summary" }),
|
|
12038
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$4.summaryRow, children: [
|
|
12039
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$4.summaryKey, children: "Name" }),
|
|
11474
12040
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: name })
|
|
11475
12041
|
] }),
|
|
11476
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
11477
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$
|
|
12042
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$4.summaryRow, children: [
|
|
12043
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$4.summaryKey, children: "Machine" }),
|
|
11478
12044
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: machineId })
|
|
11479
12045
|
] }),
|
|
11480
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
11481
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$
|
|
12046
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$4.summaryRow, children: [
|
|
12047
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$4.summaryKey, children: "Provider" }),
|
|
11482
12048
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: provider })
|
|
11483
12049
|
] }),
|
|
11484
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
11485
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$
|
|
12050
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$4.summaryRow, children: [
|
|
12051
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$4.summaryKey, children: "Directory" }),
|
|
11486
12052
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: { fontFamily: "monospace", fontSize: "12px" }, children: directory || "(default)" })
|
|
11487
12053
|
] })
|
|
11488
12054
|
] }),
|
|
11489
|
-
error && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$
|
|
12055
|
+
error && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$4.error, children: error })
|
|
11490
12056
|
] });
|
|
11491
12057
|
}
|
|
11492
|
-
const styles$
|
|
12058
|
+
const styles$4 = {
|
|
11493
12059
|
overlay: {
|
|
11494
12060
|
position: "fixed",
|
|
11495
12061
|
inset: 0,
|
|
@@ -11689,9 +12255,22 @@ const styles$3 = {
|
|
|
11689
12255
|
flexShrink: 0
|
|
11690
12256
|
}
|
|
11691
12257
|
};
|
|
12258
|
+
const STATUS_PILLS = {
|
|
12259
|
+
working: { icon: "●", label: "Working", color: "var(--state-working)" },
|
|
12260
|
+
waiting: { icon: "⏳", label: "Waiting", color: "var(--state-waiting)" },
|
|
12261
|
+
permission: { icon: "🔐", label: "Input Required", color: "var(--state-permission)" },
|
|
12262
|
+
idle: { icon: "○", label: "Idle", color: "var(--state-idle)" },
|
|
12263
|
+
done: { icon: "✓", label: "Done", color: "var(--state-done)" },
|
|
12264
|
+
error: { icon: "✗", label: "Error", color: "var(--state-error)" }
|
|
12265
|
+
};
|
|
12266
|
+
const ALL_STATES = ["working", "waiting", "permission", "idle", "done", "error"];
|
|
11692
12267
|
function TagFilterBar() {
|
|
11693
|
-
const { sessions, filterTags, setFilterTags } = useSessionsStore();
|
|
12268
|
+
const { sessions, filterTags, setFilterTags, filterStates, toggleFilterState, clearFilterStates } = useSessionsStore();
|
|
11694
12269
|
const [popoverOpen, setPopoverOpen] = reactExports.useState(false);
|
|
12270
|
+
const stateCounts = /* @__PURE__ */ new Map();
|
|
12271
|
+
for (const s of sessions) {
|
|
12272
|
+
stateCounts.set(s.state, (stateCounts.get(s.state) ?? 0) + 1);
|
|
12273
|
+
}
|
|
11695
12274
|
const allTags = {};
|
|
11696
12275
|
for (const s of sessions) {
|
|
11697
12276
|
for (const [k2, v2] of Object.entries(s.tags)) {
|
|
@@ -11700,14 +12279,42 @@ function TagFilterBar() {
|
|
|
11700
12279
|
}
|
|
11701
12280
|
}
|
|
11702
12281
|
const activeFilters = Object.entries(filterTags).filter(([k2]) => k2);
|
|
11703
|
-
|
|
11704
|
-
|
|
11705
|
-
|
|
12282
|
+
const hasAnyFilter = activeFilters.length > 0 || filterStates.size > 0;
|
|
12283
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$3.root, children: [
|
|
12284
|
+
ALL_STATES.map((state) => {
|
|
12285
|
+
const count = stateCounts.get(state) ?? 0;
|
|
12286
|
+
if (count === 0) return null;
|
|
12287
|
+
const { icon, label, color } = STATUS_PILLS[state];
|
|
12288
|
+
const active = filterStates.has(state);
|
|
12289
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
12290
|
+
"button",
|
|
12291
|
+
{
|
|
12292
|
+
onClick: () => toggleFilterState(state),
|
|
12293
|
+
style: {
|
|
12294
|
+
...styles$3.statusPill,
|
|
12295
|
+
color: active ? "#fff" : color,
|
|
12296
|
+
background: active ? color : "transparent",
|
|
12297
|
+
borderColor: active ? color : `${color}40`
|
|
12298
|
+
},
|
|
12299
|
+
children: [
|
|
12300
|
+
icon,
|
|
12301
|
+
" ",
|
|
12302
|
+
label,
|
|
12303
|
+
" ",
|
|
12304
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$3.pillCount, children: count })
|
|
12305
|
+
]
|
|
12306
|
+
},
|
|
12307
|
+
state
|
|
12308
|
+
);
|
|
12309
|
+
}),
|
|
12310
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$3.separator, children: "│" }),
|
|
12311
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$3.icon, children: "🏷" }),
|
|
12312
|
+
activeFilters.map(([k2, v2]) => /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { style: styles$3.chip, children: [
|
|
11706
12313
|
v2 && v2 !== "*" ? `${k2}:${v2}` : k2,
|
|
11707
12314
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
11708
12315
|
"button",
|
|
11709
12316
|
{
|
|
11710
|
-
style: styles$
|
|
12317
|
+
style: styles$3.chipRemove,
|
|
11711
12318
|
onClick: () => {
|
|
11712
12319
|
const next = { ...filterTags };
|
|
11713
12320
|
delete next[k2];
|
|
@@ -11718,7 +12325,7 @@ function TagFilterBar() {
|
|
|
11718
12325
|
)
|
|
11719
12326
|
] }, k2)),
|
|
11720
12327
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: { position: "relative" }, children: [
|
|
11721
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { style: styles$
|
|
12328
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { style: styles$3.addBtn, onClick: () => setPopoverOpen((v2) => !v2), children: "+ Filter" }),
|
|
11722
12329
|
popoverOpen && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
11723
12330
|
FilterPopover,
|
|
11724
12331
|
{
|
|
@@ -11731,17 +12338,20 @@ function TagFilterBar() {
|
|
|
11731
12338
|
}
|
|
11732
12339
|
)
|
|
11733
12340
|
] }),
|
|
11734
|
-
|
|
12341
|
+
hasAnyFilter && /* @__PURE__ */ jsxRuntimeExports.jsx("button", { style: styles$3.clearBtn, onClick: () => {
|
|
12342
|
+
setFilterTags({});
|
|
12343
|
+
clearFilterStates();
|
|
12344
|
+
}, children: "Clear filters" })
|
|
11735
12345
|
] });
|
|
11736
12346
|
}
|
|
11737
12347
|
function FilterPopover({ allTags, onApply, onClose }) {
|
|
11738
12348
|
const [selected, setSelected] = reactExports.useState({});
|
|
11739
12349
|
const systemKeys = ["machine", "provider", "state"];
|
|
11740
12350
|
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$
|
|
12351
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$3.popover, children: [
|
|
12352
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$3.popoverTitle, children: "Filter by tag" }),
|
|
12353
|
+
systemKeys.filter((k2) => allTags[k2]).map((k2) => /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$3.popoverRow, children: [
|
|
12354
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { style: styles$3.popoverKey, children: [
|
|
11745
12355
|
k2,
|
|
11746
12356
|
":"
|
|
11747
12357
|
] }),
|
|
@@ -11750,7 +12360,7 @@ function FilterPopover({ allTags, onApply, onClose }) {
|
|
|
11750
12360
|
{
|
|
11751
12361
|
value: selected[k2] ?? "",
|
|
11752
12362
|
onChange: (e) => setSelected((prev) => ({ ...prev, [k2]: e.target.value })),
|
|
11753
|
-
style: styles$
|
|
12363
|
+
style: styles$3.popoverSelect,
|
|
11754
12364
|
children: [
|
|
11755
12365
|
/* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: "", children: "any" }),
|
|
11756
12366
|
Array.from(allTags[k2]).map((v2) => /* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: v2, children: v2 }, v2))
|
|
@@ -11758,8 +12368,8 @@ function FilterPopover({ allTags, onApply, onClose }) {
|
|
|
11758
12368
|
}
|
|
11759
12369
|
)
|
|
11760
12370
|
] }, k2)),
|
|
11761
|
-
customKeys.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
11762
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$
|
|
12371
|
+
customKeys.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$3.popoverRow, children: [
|
|
12372
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$3.popoverKey, children: "custom:" }),
|
|
11763
12373
|
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
11764
12374
|
"select",
|
|
11765
12375
|
{
|
|
@@ -11768,7 +12378,7 @@ function FilterPopover({ allTags, onApply, onClose }) {
|
|
|
11768
12378
|
const v2 = e.target.value;
|
|
11769
12379
|
setSelected((prev) => v2 ? { ...prev, _custom: v2 } : { ...prev });
|
|
11770
12380
|
},
|
|
11771
|
-
style: styles$
|
|
12381
|
+
style: styles$3.popoverSelect,
|
|
11772
12382
|
children: [
|
|
11773
12383
|
/* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: "", children: "pick tag…" }),
|
|
11774
12384
|
customKeys.map((k2) => /* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: k2, children: k2 }, k2))
|
|
@@ -11776,7 +12386,7 @@ function FilterPopover({ allTags, onApply, onClose }) {
|
|
|
11776
12386
|
}
|
|
11777
12387
|
)
|
|
11778
12388
|
] }),
|
|
11779
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
12389
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$3.popoverActions, children: [
|
|
11780
12390
|
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: "btn btn-ghost btn-sm", onClick: onClose, children: "Cancel" }),
|
|
11781
12391
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
11782
12392
|
"button",
|
|
@@ -11796,7 +12406,7 @@ function FilterPopover({ allTags, onApply, onClose }) {
|
|
|
11796
12406
|
] })
|
|
11797
12407
|
] });
|
|
11798
12408
|
}
|
|
11799
|
-
const styles$
|
|
12409
|
+
const styles$3 = {
|
|
11800
12410
|
root: {
|
|
11801
12411
|
display: "flex",
|
|
11802
12412
|
alignItems: "center",
|
|
@@ -11804,6 +12414,28 @@ const styles$2 = {
|
|
|
11804
12414
|
flex: 1,
|
|
11805
12415
|
flexWrap: "wrap"
|
|
11806
12416
|
},
|
|
12417
|
+
statusPill: {
|
|
12418
|
+
display: "inline-flex",
|
|
12419
|
+
alignItems: "center",
|
|
12420
|
+
gap: "4px",
|
|
12421
|
+
fontSize: "11px",
|
|
12422
|
+
fontWeight: 600,
|
|
12423
|
+
padding: "3px 8px",
|
|
12424
|
+
borderRadius: "10px",
|
|
12425
|
+
border: "1px solid",
|
|
12426
|
+
cursor: "pointer",
|
|
12427
|
+
transition: "all 0.15s",
|
|
12428
|
+
whiteSpace: "nowrap"
|
|
12429
|
+
},
|
|
12430
|
+
pillCount: {
|
|
12431
|
+
fontSize: "10px",
|
|
12432
|
+
opacity: 0.8
|
|
12433
|
+
},
|
|
12434
|
+
separator: {
|
|
12435
|
+
color: "var(--border)",
|
|
12436
|
+
fontSize: "14px",
|
|
12437
|
+
margin: "0 2px"
|
|
12438
|
+
},
|
|
11807
12439
|
icon: {
|
|
11808
12440
|
fontSize: "14px"
|
|
11809
12441
|
},
|
|
@@ -11897,15 +12529,48 @@ function TerminalsView({ onSessionAdded }) {
|
|
|
11897
12529
|
const {
|
|
11898
12530
|
sessions,
|
|
11899
12531
|
filterTags,
|
|
12532
|
+
filterStates,
|
|
11900
12533
|
activeFullscreenId,
|
|
12534
|
+
splitIds,
|
|
11901
12535
|
setFullscreen,
|
|
12536
|
+
setSplit,
|
|
11902
12537
|
removeSession,
|
|
11903
12538
|
updateSession
|
|
11904
12539
|
} = useSessionsStore();
|
|
11905
12540
|
const [showCreate, setShowCreate] = reactExports.useState(false);
|
|
11906
12541
|
const [editTagsId, setEditTagsId] = reactExports.useState(null);
|
|
11907
|
-
const
|
|
12542
|
+
const [viewMode, setViewMode] = reactExports.useState("grid");
|
|
12543
|
+
const filtered = filterSessions(sessions, filterTags, filterStates);
|
|
11908
12544
|
const fullscreenSession = activeFullscreenId ? sessions.find((s) => s.id === activeFullscreenId) ?? null : null;
|
|
12545
|
+
reactExports.useEffect(() => {
|
|
12546
|
+
function onKeyDown(e) {
|
|
12547
|
+
if (showCreate || editTagsId) return;
|
|
12548
|
+
const target = e.target;
|
|
12549
|
+
if (target.tagName === "INPUT" || target.tagName === "TEXTAREA" || target.tagName === "SELECT") return;
|
|
12550
|
+
const ctrlOrCmd = e.ctrlKey || e.metaKey;
|
|
12551
|
+
if (ctrlOrCmd && e.key === "n") {
|
|
12552
|
+
e.preventDefault();
|
|
12553
|
+
setShowCreate(true);
|
|
12554
|
+
} else if (ctrlOrCmd && e.key === "\\") {
|
|
12555
|
+
e.preventDefault();
|
|
12556
|
+
if (splitIds) {
|
|
12557
|
+
setSplit(null);
|
|
12558
|
+
} else if (activeFullscreenId && filtered.length >= 2) {
|
|
12559
|
+
const currentIdx = filtered.findIndex((s) => s.id === activeFullscreenId);
|
|
12560
|
+
const nextIdx = (currentIdx + 1) % filtered.length;
|
|
12561
|
+
setSplit([activeFullscreenId, filtered[nextIdx].id]);
|
|
12562
|
+
}
|
|
12563
|
+
} else if (ctrlOrCmd && e.key >= "1" && e.key <= "9") {
|
|
12564
|
+
e.preventDefault();
|
|
12565
|
+
const index = parseInt(e.key) - 1;
|
|
12566
|
+
if (filtered[index]) {
|
|
12567
|
+
setFullscreen(filtered[index].id);
|
|
12568
|
+
}
|
|
12569
|
+
}
|
|
12570
|
+
}
|
|
12571
|
+
window.addEventListener("keydown", onKeyDown);
|
|
12572
|
+
return () => window.removeEventListener("keydown", onKeyDown);
|
|
12573
|
+
}, [filtered, showCreate, editTagsId, setFullscreen]);
|
|
11909
12574
|
async function handleClose(id2) {
|
|
11910
12575
|
await window.maestro.sessions.destroy(id2).catch(() => {
|
|
11911
12576
|
});
|
|
@@ -11916,15 +12581,24 @@ function TerminalsView({ onSessionAdded }) {
|
|
|
11916
12581
|
});
|
|
11917
12582
|
updateSession({ id: id2, name });
|
|
11918
12583
|
}
|
|
11919
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
11920
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
12584
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$2.root, children: [
|
|
12585
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$2.toolbar, children: [
|
|
11921
12586
|
/* @__PURE__ */ jsxRuntimeExports.jsx(TagFilterBar, {}),
|
|
11922
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
11923
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { style: styles$
|
|
12587
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$2.toolbarRight, children: [
|
|
12588
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { style: styles$2.count, children: [
|
|
11924
12589
|
filtered.length,
|
|
11925
12590
|
"/",
|
|
11926
12591
|
sessions.length
|
|
11927
12592
|
] }),
|
|
12593
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
12594
|
+
"button",
|
|
12595
|
+
{
|
|
12596
|
+
className: "btn btn-ghost btn-sm",
|
|
12597
|
+
onClick: () => setViewMode((v2) => v2 === "grid" ? "tabs" : "grid"),
|
|
12598
|
+
title: viewMode === "grid" ? "Switch to tabbed view" : "Switch to grid view",
|
|
12599
|
+
children: viewMode === "grid" ? "☰ Tabs" : "▦ Grid"
|
|
12600
|
+
}
|
|
12601
|
+
),
|
|
11928
12602
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
11929
12603
|
"button",
|
|
11930
12604
|
{
|
|
@@ -11935,12 +12609,18 @@ function TerminalsView({ onSessionAdded }) {
|
|
|
11935
12609
|
)
|
|
11936
12610
|
] })
|
|
11937
12611
|
] }),
|
|
11938
|
-
|
|
11939
|
-
|
|
12612
|
+
viewMode === "tabs" && filtered.length > 0 ? /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
12613
|
+
TabbedWorkspace,
|
|
12614
|
+
{
|
|
12615
|
+
sessions: filtered,
|
|
12616
|
+
onClose: (id2) => handleClose(id2)
|
|
12617
|
+
}
|
|
12618
|
+
) : /* @__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: [
|
|
12619
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$2.emptyIcon, children: "▦" }),
|
|
11940
12620
|
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { style: { fontWeight: 600, marginBottom: "8px" }, children: "No terminals yet" }),
|
|
11941
12621
|
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { style: { color: "var(--text-muted)", fontSize: "13px", marginBottom: "16px" }, children: "Launch an AI coding session to get started." }),
|
|
11942
12622
|
/* @__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$
|
|
12623
|
+
] }) : /* @__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
12624
|
TerminalTile,
|
|
11945
12625
|
{
|
|
11946
12626
|
session,
|
|
@@ -11958,6 +12638,19 @@ function TerminalsView({ onSessionAdded }) {
|
|
|
11958
12638
|
onClose: () => setFullscreen(null)
|
|
11959
12639
|
}
|
|
11960
12640
|
),
|
|
12641
|
+
splitIds && (() => {
|
|
12642
|
+
const leftSession = sessions.find((s) => s.id === splitIds[0]);
|
|
12643
|
+
const rightSession = sessions.find((s) => s.id === splitIds[1]);
|
|
12644
|
+
if (!leftSession || !rightSession) return null;
|
|
12645
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
12646
|
+
SplitPaneOverlay,
|
|
12647
|
+
{
|
|
12648
|
+
left: leftSession,
|
|
12649
|
+
right: rightSession,
|
|
12650
|
+
onClose: () => setSplit(null)
|
|
12651
|
+
}
|
|
12652
|
+
);
|
|
12653
|
+
})(),
|
|
11961
12654
|
showCreate && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
11962
12655
|
CreateTerminalModal,
|
|
11963
12656
|
{
|
|
@@ -11996,16 +12689,16 @@ function TagEditPanel({ sessionId, initialTags, onClose, onSave }) {
|
|
|
11996
12689
|
setTags((prev) => ({ ...prev, [key.trim()]: val.trim() }));
|
|
11997
12690
|
setInput("");
|
|
11998
12691
|
}
|
|
11999
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$
|
|
12000
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$
|
|
12692
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$2.tagEditOverlay, children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$2.tagEditPanel, children: [
|
|
12693
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$2.tagEditHeader, children: [
|
|
12001
12694
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { children: [
|
|
12002
12695
|
session?.name,
|
|
12003
12696
|
" · Tags"
|
|
12004
12697
|
] }),
|
|
12005
12698
|
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { style: { background: "transparent", border: "none", color: "var(--text-muted)", fontSize: "16px" }, onClick: onClose, children: "✕" })
|
|
12006
12699
|
] }),
|
|
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$
|
|
12700
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$2.tagEditorInline, children: [
|
|
12701
|
+
Object.entries(tags).filter(([k2]) => !["machine", "provider", "state"].includes(k2)).map(([k2, v2]) => /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { style: styles$2.tagChipEdit, children: [
|
|
12009
12702
|
v2 ? `${k2}:${v2}` : k2,
|
|
12010
12703
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
12011
12704
|
"button",
|
|
@@ -12040,7 +12733,7 @@ function TagEditPanel({ sessionId, initialTags, onClose, onSave }) {
|
|
|
12040
12733
|
] })
|
|
12041
12734
|
] }) });
|
|
12042
12735
|
}
|
|
12043
|
-
const styles$
|
|
12736
|
+
const styles$2 = {
|
|
12044
12737
|
root: {
|
|
12045
12738
|
display: "flex",
|
|
12046
12739
|
flexDirection: "column",
|
|
@@ -12141,12 +12834,92 @@ const styles$1 = {
|
|
|
12141
12834
|
borderRadius: "10px"
|
|
12142
12835
|
}
|
|
12143
12836
|
};
|
|
12837
|
+
let nextId = 0;
|
|
12838
|
+
const useToastsStore = create((set) => ({
|
|
12839
|
+
toasts: [],
|
|
12840
|
+
addToast(message, type) {
|
|
12841
|
+
const id2 = `toast-${nextId++}`;
|
|
12842
|
+
const toast = { id: id2, message, type, createdAt: Date.now() };
|
|
12843
|
+
set((s) => ({
|
|
12844
|
+
toasts: [...s.toasts.slice(-4), toast]
|
|
12845
|
+
// cap at 5
|
|
12846
|
+
}));
|
|
12847
|
+
setTimeout(() => {
|
|
12848
|
+
set((s) => ({ toasts: s.toasts.filter((t2) => t2.id !== id2) }));
|
|
12849
|
+
}, 5e3);
|
|
12850
|
+
},
|
|
12851
|
+
removeToast(id2) {
|
|
12852
|
+
set((s) => ({ toasts: s.toasts.filter((t2) => t2.id !== id2) }));
|
|
12853
|
+
}
|
|
12854
|
+
}));
|
|
12855
|
+
const TYPE_COLORS = {
|
|
12856
|
+
info: "var(--state-working)",
|
|
12857
|
+
success: "var(--state-done)",
|
|
12858
|
+
warning: "var(--state-waiting)",
|
|
12859
|
+
error: "var(--state-error)"
|
|
12860
|
+
};
|
|
12861
|
+
function ToastContainer() {
|
|
12862
|
+
const { toasts, removeToast } = useToastsStore();
|
|
12863
|
+
if (toasts.length === 0) return null;
|
|
12864
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$1.container, children: toasts.map((toast) => /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
12865
|
+
"div",
|
|
12866
|
+
{
|
|
12867
|
+
style: { ...styles$1.toast, borderLeftColor: TYPE_COLORS[toast.type] },
|
|
12868
|
+
children: [
|
|
12869
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$1.message, children: toast.message }),
|
|
12870
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { style: styles$1.dismiss, onClick: () => removeToast(toast.id), children: "✕" })
|
|
12871
|
+
]
|
|
12872
|
+
},
|
|
12873
|
+
toast.id
|
|
12874
|
+
)) });
|
|
12875
|
+
}
|
|
12876
|
+
const styles$1 = {
|
|
12877
|
+
container: {
|
|
12878
|
+
position: "fixed",
|
|
12879
|
+
bottom: "16px",
|
|
12880
|
+
right: "16px",
|
|
12881
|
+
zIndex: 300,
|
|
12882
|
+
display: "flex",
|
|
12883
|
+
flexDirection: "column",
|
|
12884
|
+
gap: "8px",
|
|
12885
|
+
maxWidth: "360px"
|
|
12886
|
+
},
|
|
12887
|
+
toast: {
|
|
12888
|
+
display: "flex",
|
|
12889
|
+
alignItems: "center",
|
|
12890
|
+
gap: "8px",
|
|
12891
|
+
padding: "10px 12px",
|
|
12892
|
+
background: "var(--bg-elevated)",
|
|
12893
|
+
border: "1px solid var(--border)",
|
|
12894
|
+
borderLeft: "3px solid",
|
|
12895
|
+
borderRadius: "var(--radius-sm)",
|
|
12896
|
+
boxShadow: "0 4px 16px rgba(0,0,0,0.4)",
|
|
12897
|
+
animation: "slideIn 0.2s ease-out"
|
|
12898
|
+
},
|
|
12899
|
+
message: {
|
|
12900
|
+
flex: 1,
|
|
12901
|
+
fontSize: "12px",
|
|
12902
|
+
color: "var(--text-primary)",
|
|
12903
|
+
lineHeight: 1.4
|
|
12904
|
+
},
|
|
12905
|
+
dismiss: {
|
|
12906
|
+
background: "transparent",
|
|
12907
|
+
border: "none",
|
|
12908
|
+
color: "var(--text-muted)",
|
|
12909
|
+
fontSize: "12px",
|
|
12910
|
+
cursor: "pointer",
|
|
12911
|
+
padding: "0 2px",
|
|
12912
|
+
flexShrink: 0
|
|
12913
|
+
}
|
|
12914
|
+
};
|
|
12144
12915
|
function App() {
|
|
12145
12916
|
const [view, setView] = reactExports.useState("home");
|
|
12146
12917
|
const [runPlanFile, setRunPlanFile] = reactExports.useState(null);
|
|
12147
12918
|
const runStatus = useRunStore((s) => s.status);
|
|
12148
12919
|
const { setMachines, addMachine, removeMachine, updateStatus } = useMachinesStore();
|
|
12149
12920
|
const { setSessions, addSession, updateSession, removeSession, applyStateChange } = useSessionsStore();
|
|
12921
|
+
const addToast = useToastsStore((s) => s.addToast);
|
|
12922
|
+
const prevStatesRef = reactExports.useRef(/* @__PURE__ */ new Map());
|
|
12150
12923
|
const waitingCount = useSessionsStore(
|
|
12151
12924
|
(s) => s.sessions.filter((sess) => sess.state === "waiting").length
|
|
12152
12925
|
);
|
|
@@ -12161,9 +12934,29 @@ function App() {
|
|
|
12161
12934
|
const unsubSessionData = window.maestro.sessions.onData((_ev) => {
|
|
12162
12935
|
});
|
|
12163
12936
|
const unsubStateChanged = window.maestro.sessions.onStateChanged((ev) => {
|
|
12164
|
-
|
|
12937
|
+
const event = ev;
|
|
12938
|
+
const prev = prevStatesRef.current.get(event.sessionId);
|
|
12939
|
+
if (prev && prev !== event.state) {
|
|
12940
|
+
const session = useSessionsStore.getState().sessions.find((s) => s.id === event.sessionId);
|
|
12941
|
+
const name = session?.name ?? event.sessionId.slice(0, 8);
|
|
12942
|
+
const labels = {
|
|
12943
|
+
working: "Working",
|
|
12944
|
+
waiting: "Waiting",
|
|
12945
|
+
permission: "Input Required",
|
|
12946
|
+
idle: "Idle",
|
|
12947
|
+
done: "Done",
|
|
12948
|
+
error: "Error"
|
|
12949
|
+
};
|
|
12950
|
+
addToast(`${name}: ${labels[prev] ?? prev} → ${labels[event.state] ?? event.state}`, "info");
|
|
12951
|
+
}
|
|
12952
|
+
prevStatesRef.current.set(event.sessionId, event.state);
|
|
12953
|
+
applyStateChange(event);
|
|
12165
12954
|
});
|
|
12166
12955
|
const unsubDestroyed = window.maestro.sessions.onDestroyed((id2) => {
|
|
12956
|
+
const session = useSessionsStore.getState().sessions.find((s) => s.id === id2);
|
|
12957
|
+
const name = session?.name ?? id2.slice(0, 8);
|
|
12958
|
+
addToast(`"${name}" session ended`, "warning");
|
|
12959
|
+
prevStatesRef.current.delete(id2);
|
|
12167
12960
|
removeSession(id2);
|
|
12168
12961
|
});
|
|
12169
12962
|
return () => {
|
|
@@ -12212,7 +13005,8 @@ function App() {
|
|
|
12212
13005
|
}
|
|
12213
13006
|
),
|
|
12214
13007
|
view === "terminals" && /* @__PURE__ */ jsxRuntimeExports.jsx(TerminalsView, { onSessionAdded: addSession })
|
|
12215
|
-
] })
|
|
13008
|
+
] }),
|
|
13009
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(ToastContainer, {})
|
|
12216
13010
|
] });
|
|
12217
13011
|
}
|
|
12218
13012
|
const styles = {
|