@rajat-rastogi/maestro 0.2.6 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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$j.sidebar, children: [
6980
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$j.logo, children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$j.logoText, children: "Maestro" }) }),
6981
- /* @__PURE__ */ jsxRuntimeExports.jsx("ul", { style: styles$j.navList, children: NAV_ITEMS.map((item) => {
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$j.navBtn,
6990
- ...isActive ? styles$j.navBtnActive : {}
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$j.navIcon, children: item.icon }),
6996
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$j.navLabel, children: item.label }),
6997
- hasRunDot && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$j.runDot }),
6998
- hasWaitingBadge && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$j.waitingBadge, children: waitingCount })
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$j.footer, children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$j.footerText, children: "v0.1.0" }) })
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$j = {
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$i.root, children: [
7121
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$i.header, children: [
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$i.title, children: "Maestro" }),
7124
- /* @__PURE__ */ jsxRuntimeExports.jsx("p", { style: styles$i.subtitle, children: "Autonomous AI coding orchestrator" })
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$i.headerActions, children: [
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$i.content, children: [
7132
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$i.sectionHeader, children: [
7133
- /* @__PURE__ */ jsxRuntimeExports.jsx("h2", { style: styles$i.sectionTitle, children: "Recent Plans" }),
7134
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$i.dirLabel, children: dir })
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$i.loading, children: "Loading plans…" }),
7137
- !loading && plans.length === 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$i.empty, children: [
7138
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$i.emptyIcon, children: "✦" }),
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$i.emptyActions, children: [
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$i.planGrid, children: plans.map((plan) => /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$i.planCard, children: [
7149
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$i.cardTop, children: [
7150
- /* @__PURE__ */ jsxRuntimeExports.jsx("h3", { style: styles$i.planName, children: plan.name }),
7151
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$i.planDate, children: formatDate(plan.mtime) })
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$i.planPreview, children: plan.preview }),
7154
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$i.cardActions, children: [
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$i.quickActions, children: [
7178
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$i.quickTitle, children: "Quick actions" }),
7179
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$i.quickGrid, children: [
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$i = {
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$h.root, children: [
7379
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$h.header, children: [
7380
- /* @__PURE__ */ jsxRuntimeExports.jsx("h2", { style: styles$h.title, children: "Create Plan" }),
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$h.inputStage, children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$h.inputCard, children: [
7395
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$h.inputIcon, children: "✦" }),
7396
- /* @__PURE__ */ jsxRuntimeExports.jsx("h1", { style: styles$h.inputTitle, children: "What do you want to build?" }),
7397
- /* @__PURE__ */ jsxRuntimeExports.jsx("p", { style: styles$h.inputSubtitle, children: "Describe your goal. Maestro will explore the codebase and create a detailed plan." }),
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$h.descTextarea,
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$h.runStage, children: [
7423
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$h.logArea, children: [
7424
- logs.map((line, i) => /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$h.logLine, className: "mono", children: line }, i)),
7425
- stage === "running" && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$h.cursor, children: "▌" }),
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$h.stdinRow, children: [
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$h.stdinInput,
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$h.doneBar, children: [
7444
- /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { style: styles$h.doneMsg, children: [
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$h.doneActions, children: [
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$h.errorBar, children: [
7461
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$h.errorMsg, children: error ?? "Plan creation failed." }),
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$h = {
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$g.root, children: [
7708
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$g.toolbar, children: [
7709
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$g.filters, children: ["all", "task", "review"].map((f2) => /* @__PURE__ */ jsxRuntimeExports.jsx(
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$g.filterBtn, ...filter === f2 ? styles$g.filterBtnActive : {} },
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$g.searchInput
7727
+ style: styles$k.searchInput
7728
7728
  }
7729
7729
  ),
7730
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$g.toolbarRight, children: [
7731
- /* @__PURE__ */ jsxRuntimeExports.jsx("button", { style: styles$g.iconBtn, onClick: toggleAll, title: allCollapsed ? "Expand all" : "Collapse all", children: allCollapsed ? "⊞" : "⊟" }),
7732
- /* @__PURE__ */ jsxRuntimeExports.jsx("button", { style: styles$g.iconBtn, onClick: copyLogs, title: "Copy all logs", children: copied ? "✓" : "⎘" }),
7733
- /* @__PURE__ */ jsxRuntimeExports.jsx("button", { style: styles$g.iconBtn, onClick: exportLogs, title: "Export logs", children: "↓" }),
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$g.iconBtn, color: autoScroll ? "var(--green)" : "var(--text-muted)" },
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$g.logArea, children: [
7746
- filtered.length === 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$g.empty, children: events.length === 0 ? "Waiting for log events…" : "No events match the current filter." }),
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$g.section, children: [
7750
- section.header ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$g.sectionHeader, onClick: () => toggleSection(sIdx), children: [
7751
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$g.sectionArrow, children: isCollapsed ? "▶" : "▼" }),
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$g.logLine, className: `mono log-${event.phase}`, children: [
7763
- event.ts && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { style: styles$g.ts, children: [
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$g = {
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$f.panel, children: [
7902
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$f.header, children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Plan" }) }),
7903
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$f.empty, children: "Loading plan…" })
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$f.panel, children: [
7913
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$f.header, onClick: () => setCollapsed((v2) => !v2), children: [
7914
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$f.headerTitle, children: plan.title || "Plan" }),
7915
- /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { style: styles$f.progress, children: [
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$f.collapseBtn, children: collapsed ? "▶" : "▼" })
7920
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$j.collapseBtn, children: collapsed ? "▶" : "▼" })
7921
7921
  ] }),
7922
- !collapsed && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$f.taskList, children: plan.tasks.map((task) => {
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$f.task, children: [
7927
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: { ...styles$f.taskTitle, ...allDone ? styles$f.taskDone : {} }, children: [
7928
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$f.taskIndex, children: task.index }),
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$f.taskCount, children: [
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$f.checkbox, children: [
7937
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: { ...styles$f.checkIcon, ...cb2.checked ? styles$f.checkDone : {} }, children: cb2.checked ? "✓" : "○" }),
7938
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: { ...cb2.checked ? styles$f.checkTextDone : {} }, children: cb2.text })
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$f = {
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$e.root, children: [
8398
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$e.header, children: [
8399
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$e.headerLeft, children: [
8400
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: { ...styles$e.statusDot, background: statusColor } }),
8401
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$e.planLabel, children: store.planFile ? store.planFile.split(/[\\/]/).pop() : "No plan running" }),
8402
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: { ...styles$e.statusBadge, color: statusColor }, children: store.status }),
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$e.headerRight, children: [
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$e.main, children: [
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$e.overlay, children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$e.dialog, children: [
8452
- /* @__PURE__ */ jsxRuntimeExports.jsx("h2", { style: styles$e.dialogTitle, children: "Launch Plan" }),
8453
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$e.field, children: [
8454
- /* @__PURE__ */ jsxRuntimeExports.jsx("label", { style: styles$e.fieldLabel, children: "Plan file" }),
8455
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$e.fileRow, children: [
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$e.field, children: [
8470
- /* @__PURE__ */ jsxRuntimeExports.jsx("label", { style: styles$e.fieldLabel, children: "Provider" }),
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$e.select,
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$e.field, children: [
8486
- /* @__PURE__ */ jsxRuntimeExports.jsx("label", { style: styles$e.fieldLabel, children: "Max iterations" }),
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$e.toggleRow, children: [
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$e.dialogActions, children: [
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$e.toggle, children: [
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$e = {
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$d.empty, children: [
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$d.grid, children: sessions.map((session) => /* @__PURE__ */ jsxRuntimeExports.jsxs(
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$d.card,
8658
+ style: styles$h.card,
8659
8659
  onClick: () => onSelect(session),
8660
8660
  children: [
8661
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$d.cardHeader, children: [
8662
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$d.planName, children: session.planName }),
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$d.meta, children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: { color: "var(--text-muted)", fontSize: "11px" }, children: session.id }) })
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$d = {
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$c.loading, children: "Starting replay server…" });
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$c.errorPage, children: [
8798
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$c.errorTitle, children: "Failed to start replay" }),
8799
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$c.errorMsg, children: error }),
8800
- /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { style: styles$c.errorHint, children: [
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$c.root, children: [
8809
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$c.header, children: [
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$c.sessionLabel, children: store.activeSessionId }),
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$c.main, children: [
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$c.root, children: [
8835
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$c.header, children: [
8836
- /* @__PURE__ */ jsxRuntimeExports.jsx("h2", { style: styles$c.title, children: "Replay" }),
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$c.errorBanner, children: error }),
8848
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$c.sessionArea, children: store.loading ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$c.loading, children: "Loading sessions…" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(
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$c = {
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$b.noMatch, children: "No matching config keys." }),
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$b.section, children: [
9019
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$f.section, children: [
9020
9020
  /* @__PURE__ */ jsxRuntimeExports.jsxs(
9021
9021
  "div",
9022
9022
  {
9023
- style: styles$b.sectionHeader,
9023
+ style: styles$f.sectionHeader,
9024
9024
  onClick: () => toggleSection(section.id),
9025
9025
  children: [
9026
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$b.sectionToggle, children: isCollapsed ? "▶" : "▼" }),
9027
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$b.sectionTitle, children: section.title }),
9028
- hasDirtyField && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$b.dirtyDot, children: "•" })
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$b.sectionBody, children: (q2 ? matchingFields : section.fields).map((key) => /* @__PURE__ */ jsxRuntimeExports.jsx(
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$b.fieldRow, children: [
9052
- /* @__PURE__ */ jsxRuntimeExports.jsx(Tooltip, { text: desc, children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$b.fieldLabel, children: fieldKey }) }),
9053
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$b.fieldControl, children: fieldKey in SELECT_FIELDS ? /* @__PURE__ */ jsxRuntimeExports.jsx(
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$b.resetBtn, ...showReset ? styles$b.resetBtnVisible : {} },
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$b.toggleWrap, children: [
9143
- /* @__PURE__ */ jsxRuntimeExports.jsxs("label", { style: styles$b.toggle, children: [
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$b.toggleSlider,
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$b.toggleThumb,
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$b.fieldHint, children: hint })
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$b.colorWrap, children: [
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$b.colorSwatch,
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$b.tooltip, children: text })
9240
+ visible && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$f.tooltip, children: text })
9241
9241
  ]
9242
9242
  }
9243
9243
  );
9244
9244
  }
9245
- const styles$b = {
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$a.errorPage, children: [
9437
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$a.errorTitle, children: "Failed to load config" }),
9438
- /* @__PURE__ */ jsxRuntimeExports.jsx("pre", { style: styles$a.errorMsg, children: error })
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$a.root, children: [
9442
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$a.header, children: [
9443
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$a.headerTitle, children: "Maestro Config" }),
9444
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$a.spacer }),
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$a.toolbar, children: [
9449
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$a.toolbarLabel, children: "Save to:" }),
9450
- ["global", "project"].map((t2) => /* @__PURE__ */ jsxRuntimeExports.jsxs("label", { style: { ...styles$a.radioLabel, ...target === t2 ? styles$a.radioLabelActive : {} }, children: [
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$a.targetPath, children: t2 === "global" ? state.globalConfigPath : state.projectConfigPath })
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$a.spacer }),
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$a.searchRow, children: /* @__PURE__ */ jsxRuntimeExports.jsx(
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$a.searchInput,
9479
+ style: styles$e.searchInput,
9480
9480
  autoComplete: "off",
9481
9481
  spellCheck: false
9482
9482
  }
9483
9483
  ) }),
9484
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$a.content, children: loading ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$a.loading, children: "Loading configuration…" }) : state ? /* @__PURE__ */ jsxRuntimeExports.jsx(
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$a.toast,
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$a = {
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$9.copyBlock, children: [
9642
- /* @__PURE__ */ jsxRuntimeExports.jsx("pre", { style: styles$9.code, children: text }),
9643
- /* @__PURE__ */ jsxRuntimeExports.jsx("button", { style: styles$9.copyBtn, onClick: handleCopy, title: "Copy to clipboard", children: copied ? "✓ Copied" : "Copy" })
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$9.card, children: [
9658
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$9.left, children: [
9659
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: { ...styles$9.statusDot, color }, children: label.split(" ")[0] }),
9660
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$9.info, children: [
9661
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$9.nameRow, children: [
9662
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$9.name, children: machine.name }),
9663
- machine.projectName && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$9.project, children: machine.projectName })
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$9.meta, children: [
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$9.right, children: [
9687
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: { ...styles$9.statusLabel, color }, children: label.split(" ").slice(1).join(" ") }),
9688
- machine.type !== "host" && (sshReady ? /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$9.sshReadyBadge, children: "✓ Agent Ready" }) : /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$9.sshNotReadyBadge, children: "⚠ Agent Setup Required" })),
9689
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$9.actions, children: [
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$9.overlay, children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$9.panel, children: [
9769
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$9.panelHeader, children: [
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$9.closeBtn, onClick: onClose, children: "✕" })
9774
+ /* @__PURE__ */ jsxRuntimeExports.jsx("button", { style: styles$d.closeBtn, onClick: onClose, children: "✕" })
9775
9775
  ] }),
9776
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$9.panelBody, children: [
9777
- /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { style: styles$9.step, children: [
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$9.step, children: [
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$9.step, children: [
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$9.step, children: [
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$9.inputLabel, children: "Tunnel ID (from the wizard output)" }),
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$9.input, fontFamily: "monospace", fontSize: "12px" }
9811
+ style: { ...styles$d.input, fontFamily: "monospace", fontSize: "12px" }
9812
9812
  }
9813
9813
  )
9814
9814
  ] }),
9815
- pingResult === "online" && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$9.pingSuccess, children: "✓ Agent connected — tunnel is reachable." }),
9816
- pingResult === "offline" && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$9.pingFailure, children: [
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$9.panelFooter, children: [
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$9 = {
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$8.overlay, children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$8.panel, children: [
10091
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$8.header, children: [
10092
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$8.title, children: "Add Windows 365 Cloud PC" }),
10093
- /* @__PURE__ */ jsxRuntimeExports.jsx("button", { style: styles$8.closeBtn, onClick: onClose, children: "✕" })
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$8.body, children: [
10096
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$8.setupNote, children: [
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$8.field, children: [
10109
- /* @__PURE__ */ jsxRuntimeExports.jsx("label", { style: styles$8.label, children: "Display name" }),
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$8.hint, children: 'The "Cloud PC name" shown in View Details — just for your reference.' })
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$8.field, children: [
10123
- /* @__PURE__ */ jsxRuntimeExports.jsx("label", { style: styles$8.label, children: "Device name" }),
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$8.hint, children: [
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$8.field, children: [
10140
- /* @__PURE__ */ jsxRuntimeExports.jsx("label", { style: styles$8.label, children: "Username (UPN) — optional" }),
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$8.hint, children: "Pre-fills the login field when RDP opens. Leave blank if unsure." })
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$8.error, children: error })
10152
+ error && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$c.error, children: error })
10153
10153
  ] }),
10154
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$8.footer, children: [
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$8 = {
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$7.root, children: [
10329
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$7.header, children: [
10330
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$7.headerLeft, children: [
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$7.countBadge, children: [
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$7.discoveryBanner, children: /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { children: [
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$7.list, children: [
10364
- machines.length === 0 && discoveryState !== "loading" ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$7.empty, children: [
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$7.discovering, children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: { opacity: 0.5 }, children: "Discovering Azure Dev Boxes & Cloud PCs…" }) })
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$7 = {
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
- terminal.write(event.data);
10613
+ if (event.data.length < 128) {
10614
+ if (batchBuffer) flushBatch();
10615
+ terminal.write(event.data);
10616
+ } else {
10617
+ batchBuffer += event.data;
10618
+ if (!batchRaf) batchRaf = requestAnimationFrame(flushBatch);
10619
+ }
10604
10620
  }
10605
10621
  });
10606
10622
  unsubRef.current = unsubData;
@@ -10615,14 +10631,74 @@ function useTerminalTile({
10615
10631
  }
10616
10632
  });
10617
10633
  resizeObs.observe(container);
10634
+ const sendPasteText = async (payload) => {
10635
+ const CHUNK = 512;
10636
+ for (let i = 0; i < payload.length; i += CHUNK) {
10637
+ const chunk = payload.slice(i, i + CHUNK);
10638
+ window.maestro.sessions.sendInput(sessionId, chunk);
10639
+ if (i + CHUNK < payload.length) {
10640
+ await new Promise((r2) => setTimeout(r2, 10));
10641
+ }
10642
+ }
10643
+ };
10618
10644
  if (interactive) {
10619
10645
  terminal.onData((data) => {
10620
10646
  window.maestro.sessions.sendInput(sessionId, data);
10621
10647
  });
10648
+ terminal.attachCustomKeyEventHandler((e) => {
10649
+ if ((e.ctrlKey || e.metaKey) && e.key === "v" && e.type === "keydown") {
10650
+ return false;
10651
+ }
10652
+ return true;
10653
+ });
10654
+ const refocus = () => {
10655
+ setTimeout(() => container.querySelector("textarea")?.focus(), 50);
10656
+ };
10657
+ const pasteHandler = (e) => {
10658
+ if (!container.contains(document.activeElement)) return;
10659
+ const ce2 = e;
10660
+ ce2.preventDefault();
10661
+ ce2.stopImmediatePropagation();
10662
+ const text = ce2.clipboardData?.getData("text") ?? "";
10663
+ if (!text) return;
10664
+ const lines = text.split("\n");
10665
+ const sendPaste = () => {
10666
+ const wrapped = `\x1B[200~${text}\x1B[201~`;
10667
+ sendPasteText(wrapped).then(refocus);
10668
+ };
10669
+ if (lines.length > 5 && onLargePaste) {
10670
+ onLargePaste(text, sendPaste);
10671
+ } else if (lines.length > 1) {
10672
+ sendPaste();
10673
+ } else {
10674
+ sendPasteText(text).then(refocus);
10675
+ }
10676
+ };
10677
+ window.addEventListener("paste", pasteHandler, true);
10678
+ const prevUnsub = unsubRef.current;
10679
+ unsubRef.current = () => {
10680
+ prevUnsub?.();
10681
+ window.removeEventListener("paste", pasteHandler, true);
10682
+ };
10622
10683
  }
10623
10684
  handleRef.current = {
10624
10685
  fit() {
10625
10686
  if (fitAddon && terminal) fitAddon.fit();
10687
+ },
10688
+ getSelection() {
10689
+ return terminal?.getSelection() ?? "";
10690
+ },
10691
+ clearTerminal() {
10692
+ terminal?.clear();
10693
+ },
10694
+ paste(text) {
10695
+ if (!text) return;
10696
+ const lines = text.split("\n");
10697
+ if (lines.length > 1) {
10698
+ sendPasteText(`\x1B[200~${text}\x1B[201~`);
10699
+ } else {
10700
+ sendPasteText(text);
10701
+ }
10626
10702
  }
10627
10703
  };
10628
10704
  const prev = unsubRef.current;
@@ -10634,6 +10710,7 @@ function useTerminalTile({
10634
10710
  init().catch(console.error);
10635
10711
  return () => {
10636
10712
  destroyed = true;
10713
+ if (batchRaf) cancelAnimationFrame(batchRaf);
10637
10714
  if (interactive) {
10638
10715
  window.maestro.sessions.resize(sessionId, 120, 30).catch(() => {
10639
10716
  });
@@ -10649,7 +10726,9 @@ function useTerminalTile({
10649
10726
  const useSessionsStore = create((set) => ({
10650
10727
  sessions: [],
10651
10728
  activeFullscreenId: null,
10729
+ splitIds: null,
10652
10730
  filterTags: {},
10731
+ filterStates: /* @__PURE__ */ new Set(),
10653
10732
  setSessions(sessions) {
10654
10733
  set({ sessions });
10655
10734
  },
@@ -10677,24 +10756,130 @@ const useSessionsStore = create((set) => ({
10677
10756
  }));
10678
10757
  },
10679
10758
  setFullscreen(id2) {
10680
- set({ activeFullscreenId: id2 });
10759
+ set({ activeFullscreenId: id2, splitIds: null });
10760
+ },
10761
+ setSplit(ids) {
10762
+ set({ splitIds: ids, activeFullscreenId: null });
10681
10763
  },
10682
10764
  setFilterTags(tags) {
10683
10765
  set({ filterTags: tags });
10766
+ },
10767
+ toggleFilterState(state) {
10768
+ set((s) => {
10769
+ const next = new Set(s.filterStates);
10770
+ if (next.has(state)) next.delete(state);
10771
+ else next.add(state);
10772
+ return { filterStates: next };
10773
+ });
10774
+ },
10775
+ clearFilterStates() {
10776
+ set({ filterStates: /* @__PURE__ */ new Set() });
10684
10777
  }
10685
10778
  }));
10686
- function filterSessions(sessions, filterTags) {
10779
+ function filterSessions(sessions, filterTags, filterStates) {
10687
10780
  const filterEntries = Object.entries(filterTags).filter(([k2, v2]) => k2 && (v2 || v2 === ""));
10688
- if (filterEntries.length === 0) return sessions;
10689
- return sessions.filter(
10690
- (s) => filterEntries.every(([key, value]) => {
10691
- const tagVal = s.tags[key];
10692
- if (tagVal === void 0) return false;
10693
- if (value === "" || value === "*") return true;
10694
- return tagVal === value;
10695
- })
10696
- );
10781
+ const hasTagFilter = filterEntries.length > 0;
10782
+ const hasStateFilter = filterStates && filterStates.size > 0;
10783
+ if (!hasTagFilter && !hasStateFilter) return sessions;
10784
+ return sessions.filter((s) => {
10785
+ if (hasStateFilter && !filterStates.has(s.state)) return false;
10786
+ if (hasTagFilter) {
10787
+ return filterEntries.every(([key, value]) => {
10788
+ const tagVal = s.tags[key];
10789
+ if (tagVal === void 0) return false;
10790
+ if (value === "" || value === "*") return true;
10791
+ return tagVal === value;
10792
+ });
10793
+ }
10794
+ return true;
10795
+ });
10796
+ }
10797
+ function ContextMenu({ x: x2, y: y2, items, onClose }) {
10798
+ const menuRef = reactExports.useRef(null);
10799
+ const [pos, setPos] = reactExports.useState({ left: x2, top: y2 });
10800
+ reactExports.useLayoutEffect(() => {
10801
+ if (!menuRef.current) return;
10802
+ const rect = menuRef.current.getBoundingClientRect();
10803
+ let left = x2;
10804
+ let top = y2;
10805
+ if (left + rect.width > window.innerWidth - 8) left = window.innerWidth - rect.width - 8;
10806
+ if (top + rect.height > window.innerHeight - 8) top = window.innerHeight - rect.height - 8;
10807
+ if (left < 8) left = 8;
10808
+ if (top < 8) top = 8;
10809
+ setPos({ left, top });
10810
+ }, [x2, y2]);
10811
+ reactExports.useEffect(() => {
10812
+ function onMouseDown(e) {
10813
+ if (menuRef.current && !menuRef.current.contains(e.target)) {
10814
+ onClose();
10815
+ }
10816
+ }
10817
+ function onKeyDown(e) {
10818
+ if (e.key === "Escape") onClose();
10819
+ }
10820
+ document.addEventListener("mousedown", onMouseDown);
10821
+ document.addEventListener("keydown", onKeyDown);
10822
+ return () => {
10823
+ document.removeEventListener("mousedown", onMouseDown);
10824
+ document.removeEventListener("keydown", onKeyDown);
10825
+ };
10826
+ }, [onClose]);
10827
+ return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { ref: menuRef, style: { ...styles$a.menu, left: pos.left, top: pos.top }, children: items.map(
10828
+ (item, i) => item.divider ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$a.divider }, i) : /* @__PURE__ */ jsxRuntimeExports.jsxs(
10829
+ "button",
10830
+ {
10831
+ style: { ...styles$a.item, ...item.danger ? { color: "var(--state-error)" } : {} },
10832
+ onClick: () => {
10833
+ item.onClick();
10834
+ onClose();
10835
+ },
10836
+ children: [
10837
+ item.icon && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$a.icon, children: item.icon }),
10838
+ item.label
10839
+ ]
10840
+ },
10841
+ i
10842
+ )
10843
+ ) });
10697
10844
  }
10845
+ const styles$a = {
10846
+ menu: {
10847
+ position: "fixed",
10848
+ zIndex: 400,
10849
+ background: "var(--bg-elevated)",
10850
+ border: "1px solid var(--border)",
10851
+ borderRadius: "var(--radius-sm)",
10852
+ boxShadow: "0 4px 16px rgba(0,0,0,0.4)",
10853
+ minWidth: "160px",
10854
+ padding: "4px",
10855
+ display: "flex",
10856
+ flexDirection: "column"
10857
+ },
10858
+ item: {
10859
+ display: "flex",
10860
+ alignItems: "center",
10861
+ gap: "8px",
10862
+ background: "transparent",
10863
+ border: "none",
10864
+ color: "var(--text-secondary)",
10865
+ fontSize: "12px",
10866
+ padding: "6px 10px",
10867
+ textAlign: "left",
10868
+ borderRadius: "var(--radius-sm)",
10869
+ width: "100%",
10870
+ cursor: "pointer"
10871
+ },
10872
+ icon: {
10873
+ width: "16px",
10874
+ textAlign: "center",
10875
+ flexShrink: 0
10876
+ },
10877
+ divider: {
10878
+ height: "1px",
10879
+ background: "var(--border-subtle)",
10880
+ margin: "4px 0"
10881
+ }
10882
+ };
10698
10883
  function TerminalTile({ session, onFullscreen, onClose, onRename, onEditTags }) {
10699
10884
  const containerRef = reactExports.useRef(null);
10700
10885
  const [menuOpen, setMenuOpen] = reactExports.useState(false);
@@ -10721,6 +10906,7 @@ function TerminalTile({ session, onFullscreen, onClose, onRename, onEditTags })
10721
10906
  const customTags = Object.entries(session.tags).filter(
10722
10907
  ([k2]) => !["machine", "provider", "state"].includes(k2)
10723
10908
  );
10909
+ const [ctxMenu, setCtxMenu] = reactExports.useState(null);
10724
10910
  const handleRename = reactExports.useCallback(() => {
10725
10911
  if (renameValue.trim() && renameValue !== session.name) {
10726
10912
  window.maestro.sessions.rename(session.id, renameValue.trim());
@@ -10729,17 +10915,34 @@ function TerminalTile({ session, onFullscreen, onClose, onRename, onEditTags })
10729
10915
  setRenaming(false);
10730
10916
  setMenuOpen(false);
10731
10917
  }, [renameValue, session]);
10918
+ const canAcknowledge = session.state === "waiting" || session.state === "permission";
10919
+ const ctxMenuItems = [
10920
+ { label: "Fullscreen", icon: "🔍", onClick: onFullscreen },
10921
+ ...canAcknowledge ? [{ label: "Acknowledge", icon: "✓", onClick: () => window.maestro.sessions.acknowledge(session.id) }] : [],
10922
+ { label: "Rename", icon: "✏", onClick: () => setRenaming(true) },
10923
+ { label: "Edit tags", icon: "🏷", onClick: onEditTags },
10924
+ { divider: true, label: "", onClick: () => {
10925
+ } },
10926
+ { label: "Stop & Clear", icon: "⏹", onClick: () => window.maestro.sessions.interrupt(session.id) },
10927
+ { divider: true, label: "", onClick: () => {
10928
+ } },
10929
+ { label: "Close", icon: "✕", onClick: onClose, danger: true }
10930
+ ];
10732
10931
  return /* @__PURE__ */ jsxRuntimeExports.jsxs(
10733
10932
  "div",
10734
10933
  {
10735
- style: styles$6.tile,
10934
+ style: styles$9.tile,
10935
+ onContextMenu: (e) => {
10936
+ e.preventDefault();
10937
+ setCtxMenu({ x: e.clientX, y: e.clientY });
10938
+ },
10736
10939
  onClick: (e) => {
10737
- if (menuOpen || renaming) return;
10940
+ if (menuOpen || renaming || ctxMenu) return;
10738
10941
  if (e.target.closest("[data-no-fullscreen]")) return;
10739
10942
  onFullscreen();
10740
10943
  },
10741
10944
  children: [
10742
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$6.header, onClick: (e) => e.stopPropagation(), children: [
10945
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$9.header, onClick: (e) => e.stopPropagation(), children: [
10743
10946
  renaming ? /* @__PURE__ */ jsxRuntimeExports.jsx(
10744
10947
  "input",
10745
10948
  {
@@ -10751,13 +10954,21 @@ function TerminalTile({ session, onFullscreen, onClose, onRename, onEditTags })
10751
10954
  if (e.key === "Enter") handleRename();
10752
10955
  if (e.key === "Escape") setRenaming(false);
10753
10956
  },
10754
- style: styles$6.renameInput,
10957
+ style: styles$9.renameInput,
10755
10958
  "data-no-fullscreen": ""
10756
10959
  }
10757
- ) : /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$6.sessionName, title: session.name, children: session.name }),
10758
- /* @__PURE__ */ jsxRuntimeExports.jsx(StateBadge, { state: session.state, confidence: session.stateConfidence, enteredAt: session.stateEnteredAt }),
10960
+ ) : /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$9.sessionName, title: session.name, children: session.name }),
10961
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
10962
+ StateBadge,
10963
+ {
10964
+ state: session.state,
10965
+ confidence: session.stateConfidence,
10966
+ enteredAt: session.stateEnteredAt,
10967
+ onAcknowledge: () => window.maestro.sessions.acknowledge(session.id)
10968
+ }
10969
+ ),
10759
10970
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: { position: "relative" }, "data-no-fullscreen": "", children: [
10760
- /* @__PURE__ */ jsxRuntimeExports.jsx("button", { style: styles$6.menuBtn, onClick: () => setMenuOpen((v2) => !v2), title: "Options", children: "⋯" }),
10971
+ /* @__PURE__ */ jsxRuntimeExports.jsx("button", { style: styles$9.menuBtn, onClick: () => setMenuOpen((v2) => !v2), title: "Options", children: "⋯" }),
10761
10972
  menuOpen && /* @__PURE__ */ jsxRuntimeExports.jsx(
10762
10973
  TileContextMenu,
10763
10974
  {
@@ -10773,6 +10984,10 @@ function TerminalTile({ session, onFullscreen, onClose, onRename, onEditTags })
10773
10984
  setMenuOpen(false);
10774
10985
  onEditTags();
10775
10986
  },
10987
+ onInterrupt: () => {
10988
+ setMenuOpen(false);
10989
+ window.maestro.sessions.interrupt(session.id);
10990
+ },
10776
10991
  onClose: () => {
10777
10992
  setMenuOpen(false);
10778
10993
  onClose();
@@ -10781,32 +10996,35 @@ function TerminalTile({ session, onFullscreen, onClose, onRename, onEditTags })
10781
10996
  )
10782
10997
  ] })
10783
10998
  ] }),
10784
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$6.previewWrapper, children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { ref: containerRef, style: styles$6.xtermContainer }) }),
10785
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$6.footer, children: [
10786
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$6.footerRow, children: [
10787
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$6.providerBadge, children: session.provider }),
10788
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$6.dirLabel, title: session.workingDirectory, children: shortDir(session.workingDirectory) }),
10999
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$9.previewWrapper, children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { ref: containerRef, style: styles$9.xtermContainer }) }),
11000
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$9.footer, children: [
11001
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$9.footerRow, children: [
11002
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$9.providerBadge, children: session.provider }),
11003
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$9.dirLabel, title: session.workingDirectory, children: shortDir(session.workingDirectory) }),
10789
11004
  /* @__PURE__ */ jsxRuntimeExports.jsx(ElapsedTimer, { enteredAt: session.stateEnteredAt, state: session.state })
10790
11005
  ] }),
10791
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$6.footerRow, children: [
10792
- /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { style: styles$6.machineName, children: [
11006
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$9.footerRow, children: [
11007
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { style: styles$9.machineName, children: [
10793
11008
  "⬡ ",
10794
11009
  machineName
10795
11010
  ] }),
10796
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$6.tagRow, children: customTags.map(([k2, v2]) => /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$6.tag, children: v2 ? `${k2}:${v2}` : k2 }, k2)) })
11011
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$9.tagRow, children: customTags.map(([k2, v2]) => /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$9.tag, children: v2 ? `${k2}:${v2}` : k2 }, k2)) })
10797
11012
  ] })
10798
- ] })
11013
+ ] }),
11014
+ ctxMenu && /* @__PURE__ */ jsxRuntimeExports.jsx(ContextMenu, { x: ctxMenu.x, y: ctxMenu.y, items: ctxMenuItems, onClose: () => setCtxMenu(null) })
10799
11015
  ]
10800
11016
  }
10801
11017
  );
10802
11018
  }
10803
- function TileContextMenu({ onFullscreen, onRename, onEditTags, onClose }) {
10804
- return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$6.contextMenu, children: [
10805
- /* @__PURE__ */ jsxRuntimeExports.jsx("button", { style: styles$6.ctxItem, onClick: onFullscreen, children: "🔍 Go fullscreen" }),
10806
- /* @__PURE__ */ jsxRuntimeExports.jsx("button", { style: styles$6.ctxItem, onClick: onRename, children: "✏ Rename" }),
10807
- /* @__PURE__ */ jsxRuntimeExports.jsx("button", { style: styles$6.ctxItem, onClick: onEditTags, children: "🏷 Edit tags" }),
10808
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$6.ctxDivider }),
10809
- /* @__PURE__ */ jsxRuntimeExports.jsx("button", { style: { ...styles$6.ctxItem, color: "var(--red)" }, onClick: onClose, children: " Close" })
11019
+ function TileContextMenu({ onFullscreen, onRename, onEditTags, onInterrupt, onClose }) {
11020
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$9.contextMenu, children: [
11021
+ /* @__PURE__ */ jsxRuntimeExports.jsx("button", { style: styles$9.ctxItem, onClick: onFullscreen, children: "🔍 Go fullscreen" }),
11022
+ /* @__PURE__ */ jsxRuntimeExports.jsx("button", { style: styles$9.ctxItem, onClick: onRename, children: "✏ Rename" }),
11023
+ /* @__PURE__ */ jsxRuntimeExports.jsx("button", { style: styles$9.ctxItem, onClick: onEditTags, children: "🏷 Edit tags" }),
11024
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$9.ctxDivider }),
11025
+ /* @__PURE__ */ jsxRuntimeExports.jsx("button", { style: styles$9.ctxItem, onClick: onInterrupt, children: " Stop & Clear" }),
11026
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$9.ctxDivider }),
11027
+ /* @__PURE__ */ jsxRuntimeExports.jsx("button", { style: { ...styles$9.ctxItem, color: "var(--red)" }, onClick: onClose, children: "✕ Close" })
10810
11028
  ] });
10811
11029
  }
10812
11030
  function ElapsedTimer({ enteredAt, state }) {
@@ -10820,17 +11038,35 @@ function ElapsedTimer({ enteredAt, state }) {
10820
11038
  const s = Math.floor(elapsed / 1e3);
10821
11039
  const m2 = Math.floor(s / 60);
10822
11040
  const label = m2 > 0 ? `${m2}:${String(s % 60).padStart(2, "0")}` : `${s}s`;
10823
- return /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$6.elapsed, children: label });
11041
+ return /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$9.elapsed, children: label });
10824
11042
  }
10825
- function StateBadge({ state, confidence, enteredAt }) {
11043
+ function StateBadge({ state, confidence, enteredAt, onAcknowledge }) {
10826
11044
  const { icon, label, color } = STATE_BADGE[state] ?? STATE_BADGE.idle;
10827
11045
  const suffix = confidence === "heuristic" ? "?" : "";
10828
- return /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { style: { ...styles$6.stateBadge, color, borderColor: `${color}40` }, children: [
10829
- icon,
10830
- " ",
10831
- label,
10832
- suffix
10833
- ] });
11046
+ const canAck = (state === "waiting" || state === "permission") && onAcknowledge;
11047
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(
11048
+ "span",
11049
+ {
11050
+ style: {
11051
+ ...styles$9.stateBadge,
11052
+ color,
11053
+ borderColor: `${color}40`,
11054
+ cursor: canAck ? "pointer" : "default"
11055
+ },
11056
+ onClick: canAck ? (e) => {
11057
+ e.stopPropagation();
11058
+ onAcknowledge();
11059
+ } : void 0,
11060
+ title: canAck ? "Click to acknowledge (dismiss to Idle)" : void 0,
11061
+ "data-no-fullscreen": "",
11062
+ children: [
11063
+ icon,
11064
+ " ",
11065
+ label,
11066
+ suffix
11067
+ ]
11068
+ }
11069
+ );
10834
11070
  }
10835
11071
  const STATE_BADGE = {
10836
11072
  working: { icon: "●", label: "Working", color: "var(--state-working)" },
@@ -10845,7 +11081,7 @@ function shortDir(dir) {
10845
11081
  const parts = dir.replace(/\\/g, "/").split("/");
10846
11082
  return parts.length > 2 ? `…/${parts.slice(-2).join("/")}` : dir;
10847
11083
  }
10848
- const styles$6 = {
11084
+ const styles$9 = {
10849
11085
  tile: {
10850
11086
  display: "flex",
10851
11087
  flexDirection: "column",
@@ -11015,10 +11251,22 @@ const STATE_LABEL = {
11015
11251
  };
11016
11252
  function FullscreenOverlay({ session, onClose }) {
11017
11253
  const containerRef = reactExports.useRef(null);
11018
- useTerminalTile({
11254
+ const [ctxMenu, setCtxMenu] = reactExports.useState(null);
11255
+ const [pendingPaste, setPendingPaste] = reactExports.useState(null);
11256
+ const refocusTerminal = () => {
11257
+ setTimeout(() => containerRef.current?.querySelector("textarea")?.focus(), 50);
11258
+ };
11259
+ const handleRef = useTerminalTile({
11019
11260
  containerRef,
11020
11261
  sessionId: session.id,
11021
- interactive: true
11262
+ interactive: true,
11263
+ onLargePaste: (text, send) => setPendingPaste({
11264
+ text,
11265
+ send: () => {
11266
+ send();
11267
+ refocusTerminal();
11268
+ }
11269
+ })
11022
11270
  });
11023
11271
  reactExports.useEffect(() => {
11024
11272
  const handler = (e) => {
@@ -11029,25 +11277,101 @@ function FullscreenOverlay({ session, onClose }) {
11029
11277
  }, [onClose]);
11030
11278
  const stateColor = STATE_BADGE_COLOR[session.state] ?? "var(--state-idle)";
11031
11279
  const machineName = session.tags["machine"] ?? session.machineId;
11032
- return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$5.overlay, children: [
11033
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$5.header, children: [
11034
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$5.sessionName, children: session.name }),
11035
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$5.dot, children: "·" }),
11036
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$5.meta, children: session.provider }),
11037
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$5.dot, children: "·" }),
11038
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$5.meta, children: machineName }),
11039
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$5.dot, children: "·" }),
11040
- /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { style: { ...styles$5.stateBadge, color: stateColor }, children: [
11280
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$8.overlay, children: [
11281
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$8.header, children: [
11282
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$8.sessionName, children: session.name }),
11283
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$8.dot, children: "·" }),
11284
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$8.meta, children: session.provider }),
11285
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$8.dot, children: "·" }),
11286
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$8.meta, children: machineName }),
11287
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$8.dot, children: "·" }),
11288
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { style: { ...styles$8.stateBadge, color: stateColor }, children: [
11041
11289
  STATE_LABEL[session.state] ?? session.state,
11042
11290
  session.stateConfidence === "heuristic" ? "?" : ""
11043
11291
  ] }),
11044
11292
  /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: { flex: 1 } }),
11045
- /* @__PURE__ */ jsxRuntimeExports.jsx("button", { style: styles$5.closeBtn, onClick: onClose, title: "Close fullscreen (Esc)", children: "⊠" })
11293
+ /* @__PURE__ */ jsxRuntimeExports.jsx("button", { style: styles$8.closeBtn, onClick: onClose, title: "Close fullscreen (Esc)", children: "⊠" })
11046
11294
  ] }),
11047
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { ref: containerRef, style: styles$5.terminalBody })
11295
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
11296
+ "div",
11297
+ {
11298
+ ref: containerRef,
11299
+ style: styles$8.terminalBody,
11300
+ onContextMenu: (e) => {
11301
+ e.preventDefault();
11302
+ setCtxMenu({ x: e.clientX, y: e.clientY });
11303
+ }
11304
+ }
11305
+ ),
11306
+ ctxMenu && /* @__PURE__ */ jsxRuntimeExports.jsx(
11307
+ ContextMenu,
11308
+ {
11309
+ x: ctxMenu.x,
11310
+ y: ctxMenu.y,
11311
+ items: [
11312
+ {
11313
+ label: "Copy",
11314
+ icon: "📋",
11315
+ onClick: () => {
11316
+ const sel = handleRef.current?.getSelection() ?? "";
11317
+ if (sel) navigator.clipboard.writeText(sel);
11318
+ }
11319
+ },
11320
+ {
11321
+ label: "Paste",
11322
+ icon: "📎",
11323
+ onClick: () => {
11324
+ navigator.clipboard.readText().then((text) => {
11325
+ if (!text) return;
11326
+ const lines = text.split("\n");
11327
+ if (lines.length > 5) {
11328
+ setPendingPaste({
11329
+ text,
11330
+ send: () => {
11331
+ handleRef.current?.paste(text);
11332
+ refocusTerminal();
11333
+ }
11334
+ });
11335
+ } else {
11336
+ handleRef.current?.paste(text);
11337
+ refocusTerminal();
11338
+ }
11339
+ });
11340
+ }
11341
+ },
11342
+ { divider: true, label: "", onClick: () => {
11343
+ } },
11344
+ {
11345
+ label: "Clear terminal",
11346
+ icon: "🗑",
11347
+ onClick: () => handleRef.current?.clearTerminal()
11348
+ }
11349
+ ],
11350
+ onClose: () => setCtxMenu(null)
11351
+ }
11352
+ ),
11353
+ pendingPaste && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$8.pasteOverlay, children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$8.pasteDialog, children: [
11354
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$8.pasteTitle, children: [
11355
+ "Paste ",
11356
+ pendingPaste.text.split("\n").length,
11357
+ " lines?"
11358
+ ] }),
11359
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("pre", { style: styles$8.pastePreview, children: [
11360
+ pendingPaste.text.split("\n").slice(0, 10).join("\n"),
11361
+ pendingPaste.text.split("\n").length > 10 ? "\n..." : ""
11362
+ ] }),
11363
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$8.pasteActions, children: [
11364
+ /* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: "btn btn-ghost btn-sm", onClick: () => setPendingPaste(null), children: "Cancel" }),
11365
+ /* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: "btn btn-primary btn-sm", onClick: () => {
11366
+ pendingPaste.send();
11367
+ setPendingPaste(null);
11368
+ refocusTerminal();
11369
+ }, children: "Paste" })
11370
+ ] })
11371
+ ] }) })
11048
11372
  ] });
11049
11373
  }
11050
- const styles$5 = {
11374
+ const styles$8 = {
11051
11375
  overlay: {
11052
11376
  position: "fixed",
11053
11377
  inset: 0,
@@ -11095,6 +11419,325 @@ const styles$5 = {
11095
11419
  flex: 1,
11096
11420
  overflow: "hidden",
11097
11421
  padding: "8px"
11422
+ },
11423
+ pasteOverlay: {
11424
+ position: "fixed",
11425
+ inset: 0,
11426
+ background: "rgba(0,0,0,0.6)",
11427
+ display: "flex",
11428
+ alignItems: "center",
11429
+ justifyContent: "center",
11430
+ zIndex: 250
11431
+ },
11432
+ pasteDialog: {
11433
+ background: "var(--bg-surface)",
11434
+ border: "1px solid var(--border)",
11435
+ borderRadius: "var(--radius)",
11436
+ padding: "16px",
11437
+ maxWidth: "480px",
11438
+ width: "90%"
11439
+ },
11440
+ pasteTitle: {
11441
+ fontSize: "14px",
11442
+ fontWeight: 600,
11443
+ marginBottom: "12px",
11444
+ color: "var(--text-primary)"
11445
+ },
11446
+ pastePreview: {
11447
+ fontSize: "11px",
11448
+ fontFamily: "'Cascadia Code', Consolas, monospace",
11449
+ background: "var(--bg-base)",
11450
+ border: "1px solid var(--border)",
11451
+ borderRadius: "var(--radius-sm)",
11452
+ padding: "10px",
11453
+ maxHeight: "200px",
11454
+ overflow: "auto",
11455
+ color: "var(--text-secondary)",
11456
+ whiteSpace: "pre-wrap",
11457
+ margin: 0
11458
+ },
11459
+ pasteActions: {
11460
+ display: "flex",
11461
+ justifyContent: "flex-end",
11462
+ gap: "8px",
11463
+ marginTop: "12px"
11464
+ }
11465
+ };
11466
+ function SplitPaneOverlay({ left, right, onClose }) {
11467
+ const leftRef = reactExports.useRef(null);
11468
+ const rightRef = reactExports.useRef(null);
11469
+ const [focusSide, setFocusSide] = reactExports.useState("left");
11470
+ useTerminalTile({ containerRef: leftRef, sessionId: left.id, interactive: true });
11471
+ useTerminalTile({ containerRef: rightRef, sessionId: right.id, interactive: true });
11472
+ reactExports.useEffect(() => {
11473
+ function onKeyDown(e) {
11474
+ if (e.key === "Escape") {
11475
+ onClose();
11476
+ return;
11477
+ }
11478
+ const ctrlOrCmd = e.ctrlKey || e.metaKey;
11479
+ if (ctrlOrCmd && e.key === "1") {
11480
+ e.preventDefault();
11481
+ setFocusSide("left");
11482
+ }
11483
+ if (ctrlOrCmd && e.key === "2") {
11484
+ e.preventDefault();
11485
+ setFocusSide("right");
11486
+ }
11487
+ }
11488
+ window.addEventListener("keydown", onKeyDown);
11489
+ return () => window.removeEventListener("keydown", onKeyDown);
11490
+ }, [onClose]);
11491
+ reactExports.useEffect(() => {
11492
+ const target = focusSide === "left" ? leftRef.current : rightRef.current;
11493
+ const textarea = target?.querySelector("textarea");
11494
+ textarea?.focus();
11495
+ }, [focusSide]);
11496
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$7.overlay, children: [
11497
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$7.header, children: [
11498
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
11499
+ PaneTab,
11500
+ {
11501
+ session: left,
11502
+ active: focusSide === "left",
11503
+ onClick: () => setFocusSide("left")
11504
+ }
11505
+ ),
11506
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
11507
+ PaneTab,
11508
+ {
11509
+ session: right,
11510
+ active: focusSide === "right",
11511
+ onClick: () => setFocusSide("right")
11512
+ }
11513
+ ),
11514
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: { flex: 1 } }),
11515
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$7.hint, children: "Ctrl+1/2 switch · Esc close" }),
11516
+ /* @__PURE__ */ jsxRuntimeExports.jsx("button", { style: styles$7.closeBtn, onClick: onClose, title: "Close split (Esc)", children: "⊠" })
11517
+ ] }),
11518
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$7.panes, children: [
11519
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
11520
+ "div",
11521
+ {
11522
+ ref: leftRef,
11523
+ style: {
11524
+ ...styles$7.pane,
11525
+ borderColor: focusSide === "left" ? "var(--accent)" : "var(--border-subtle)"
11526
+ },
11527
+ onClick: () => setFocusSide("left")
11528
+ }
11529
+ ),
11530
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$7.divider }),
11531
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
11532
+ "div",
11533
+ {
11534
+ ref: rightRef,
11535
+ style: {
11536
+ ...styles$7.pane,
11537
+ borderColor: focusSide === "right" ? "var(--accent)" : "var(--border-subtle)"
11538
+ },
11539
+ onClick: () => setFocusSide("right")
11540
+ }
11541
+ )
11542
+ ] })
11543
+ ] });
11544
+ }
11545
+ function PaneTab({ session, active, onClick }) {
11546
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(
11547
+ "button",
11548
+ {
11549
+ style: {
11550
+ ...styles$7.tab,
11551
+ background: active ? "var(--bg-base)" : "transparent",
11552
+ color: active ? "var(--text-primary)" : "var(--text-muted)",
11553
+ borderBottomColor: active ? "var(--accent)" : "transparent"
11554
+ },
11555
+ onClick,
11556
+ children: session.name
11557
+ }
11558
+ );
11559
+ }
11560
+ const styles$7 = {
11561
+ overlay: {
11562
+ position: "fixed",
11563
+ inset: 0,
11564
+ zIndex: 200,
11565
+ background: "var(--bg-base)",
11566
+ display: "flex",
11567
+ flexDirection: "column"
11568
+ },
11569
+ header: {
11570
+ display: "flex",
11571
+ alignItems: "center",
11572
+ gap: "4px",
11573
+ padding: "6px 16px",
11574
+ background: "var(--bg-surface)",
11575
+ borderBottom: "1px solid var(--border)",
11576
+ flexShrink: 0
11577
+ },
11578
+ tab: {
11579
+ fontSize: "12px",
11580
+ fontWeight: 600,
11581
+ padding: "6px 12px",
11582
+ border: "none",
11583
+ borderBottom: "2px solid",
11584
+ cursor: "pointer"
11585
+ },
11586
+ hint: {
11587
+ fontSize: "11px",
11588
+ color: "var(--text-muted)",
11589
+ marginRight: "8px"
11590
+ },
11591
+ closeBtn: {
11592
+ background: "transparent",
11593
+ border: "none",
11594
+ color: "var(--text-muted)",
11595
+ fontSize: "18px",
11596
+ cursor: "pointer"
11597
+ },
11598
+ panes: {
11599
+ flex: 1,
11600
+ display: "flex",
11601
+ overflow: "hidden"
11602
+ },
11603
+ pane: {
11604
+ flex: 1,
11605
+ position: "relative",
11606
+ overflow: "hidden",
11607
+ padding: "4px",
11608
+ border: "2px solid",
11609
+ borderRadius: "2px"
11610
+ },
11611
+ divider: {
11612
+ width: "4px",
11613
+ background: "var(--border)",
11614
+ flexShrink: 0,
11615
+ cursor: "col-resize"
11616
+ }
11617
+ };
11618
+ function TabbedWorkspace({ sessions, onClose }) {
11619
+ const [activeTabId, setActiveTabId] = reactExports.useState(
11620
+ sessions[0]?.id ?? null
11621
+ );
11622
+ const [closedTabs, setClosedTabs] = reactExports.useState([]);
11623
+ React$2.useEffect(() => {
11624
+ function onKeyDown(e) {
11625
+ if ((e.ctrlKey || e.metaKey) && e.shiftKey && e.key === "T") {
11626
+ e.preventDefault();
11627
+ if (closedTabs.length > 0) {
11628
+ const lastClosed = closedTabs[closedTabs.length - 1];
11629
+ setClosedTabs((prev) => prev.slice(0, -1));
11630
+ setActiveTabId(lastClosed);
11631
+ }
11632
+ }
11633
+ }
11634
+ window.addEventListener("keydown", onKeyDown);
11635
+ return () => window.removeEventListener("keydown", onKeyDown);
11636
+ }, [closedTabs]);
11637
+ const activeSession = sessions.find((s) => s.id === activeTabId) ?? sessions[0];
11638
+ const visibleSessions = sessions.filter((s) => !closedTabs.includes(s.id));
11639
+ function handleCloseTab(e, id2) {
11640
+ e.stopPropagation();
11641
+ setClosedTabs((prev) => [...prev, id2]);
11642
+ if (activeTabId === id2) {
11643
+ const remaining = visibleSessions.filter((s) => s.id !== id2);
11644
+ setActiveTabId(remaining[0]?.id ?? null);
11645
+ }
11646
+ }
11647
+ if (!activeSession || visibleSessions.length === 0) {
11648
+ return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$6.empty, children: /* @__PURE__ */ jsxRuntimeExports.jsx("p", { style: { color: "var(--text-muted)" }, children: "No open tabs. Press Ctrl+Shift+T to reopen." }) });
11649
+ }
11650
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$6.root, children: [
11651
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$6.tabBar, children: visibleSessions.map((session) => /* @__PURE__ */ jsxRuntimeExports.jsxs(
11652
+ "button",
11653
+ {
11654
+ style: {
11655
+ ...styles$6.tab,
11656
+ background: session.id === activeTabId ? "var(--bg-base)" : "transparent",
11657
+ color: session.id === activeTabId ? "var(--text-primary)" : "var(--text-muted)",
11658
+ borderBottomColor: session.id === activeTabId ? "var(--accent)" : "transparent"
11659
+ },
11660
+ onClick: () => setActiveTabId(session.id),
11661
+ onAuxClick: (e) => {
11662
+ if (e.button === 1) handleCloseTab(e, session.id);
11663
+ },
11664
+ title: `${session.name} · ${session.provider} · ${session.state}`,
11665
+ children: [
11666
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$6.tabName, children: session.name }),
11667
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
11668
+ "span",
11669
+ {
11670
+ style: styles$6.tabClose,
11671
+ onClick: (e) => handleCloseTab(e, session.id),
11672
+ children: "×"
11673
+ }
11674
+ )
11675
+ ]
11676
+ },
11677
+ session.id
11678
+ )) }),
11679
+ /* @__PURE__ */ jsxRuntimeExports.jsx(ActiveTerminal, { session: activeSession }, activeSession.id)
11680
+ ] });
11681
+ }
11682
+ function ActiveTerminal({ session }) {
11683
+ const containerRef = reactExports.useRef(null);
11684
+ useTerminalTile({
11685
+ containerRef,
11686
+ sessionId: session.id,
11687
+ interactive: true
11688
+ });
11689
+ return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { ref: containerRef, style: styles$6.terminal });
11690
+ }
11691
+ const styles$6 = {
11692
+ root: {
11693
+ display: "flex",
11694
+ flexDirection: "column",
11695
+ height: "100%"
11696
+ },
11697
+ tabBar: {
11698
+ display: "flex",
11699
+ alignItems: "stretch",
11700
+ background: "var(--bg-surface)",
11701
+ borderBottom: "1px solid var(--border)",
11702
+ overflowX: "auto",
11703
+ flexShrink: 0
11704
+ },
11705
+ tab: {
11706
+ display: "flex",
11707
+ alignItems: "center",
11708
+ gap: "6px",
11709
+ padding: "8px 14px",
11710
+ fontSize: "12px",
11711
+ fontWeight: 500,
11712
+ border: "none",
11713
+ borderBottom: "2px solid",
11714
+ cursor: "pointer",
11715
+ maxWidth: "180px",
11716
+ minWidth: "80px",
11717
+ flexShrink: 0,
11718
+ whiteSpace: "nowrap"
11719
+ },
11720
+ tabName: {
11721
+ overflow: "hidden",
11722
+ textOverflow: "ellipsis"
11723
+ },
11724
+ tabClose: {
11725
+ fontSize: "14px",
11726
+ lineHeight: 1,
11727
+ opacity: 0.5,
11728
+ flexShrink: 0
11729
+ },
11730
+ terminal: {
11731
+ flex: 1,
11732
+ position: "relative",
11733
+ overflow: "hidden",
11734
+ padding: "8px"
11735
+ },
11736
+ empty: {
11737
+ display: "flex",
11738
+ alignItems: "center",
11739
+ justifyContent: "center",
11740
+ height: "100%"
11098
11741
  }
11099
11742
  };
11100
11743
  function DirectoryBrowser({ machineId, initialPath, onSelect }) {
@@ -11131,9 +11774,9 @@ function DirectoryBrowser({ machineId, initialPath, onSelect }) {
11131
11774
  }
11132
11775
  }
11133
11776
  if (loading) {
11134
- return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$4.loading, children: "Loading directory tree…" });
11777
+ return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$5.loading, children: "Loading directory tree…" });
11135
11778
  }
11136
- return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$4.root, children: /* @__PURE__ */ jsxRuntimeExports.jsx(
11779
+ return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$5.root, children: /* @__PURE__ */ jsxRuntimeExports.jsx(
11137
11780
  TreeLevel,
11138
11781
  {
11139
11782
  nodes: roots,
@@ -11150,15 +11793,15 @@ function TreeLevel({ nodes, setNodes, selected, onToggle, depth }) {
11150
11793
  "button",
11151
11794
  {
11152
11795
  style: {
11153
- ...styles$4.treeItem,
11796
+ ...styles$5.treeItem,
11154
11797
  paddingLeft: `${12 + depth * 14}px`,
11155
11798
  background: selected === node.path ? "var(--accent-muted)" : "transparent",
11156
11799
  color: selected === node.path ? "var(--text-primary)" : "var(--text-secondary)"
11157
11800
  },
11158
11801
  onClick: () => onToggle(node, nodes, setNodes),
11159
11802
  children: [
11160
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$4.treeIcon, children: node.isDir ? node.loading ? "⏳" : node.expanded ? "▼" : "▶" : "📄" }),
11161
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$4.treeName, children: node.name })
11803
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$5.treeIcon, children: node.isDir ? node.loading ? "⏳" : node.expanded ? "▼" : "▶" : "📄" }),
11804
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$5.treeName, children: node.name })
11162
11805
  ]
11163
11806
  }
11164
11807
  ),
@@ -11189,7 +11832,7 @@ function updateNode(nodes, targetPath, updates) {
11189
11832
  return n2;
11190
11833
  });
11191
11834
  }
11192
- const styles$4 = {
11835
+ const styles$5 = {
11193
11836
  root: {
11194
11837
  border: "1px solid var(--border)",
11195
11838
  borderRadius: "var(--radius-sm)",
@@ -11238,6 +11881,13 @@ function CreateTerminalModal({ onClose, onCreated }) {
11238
11881
  const [creating, setCreating] = reactExports.useState(false);
11239
11882
  const [error, setError] = reactExports.useState("");
11240
11883
  const machines = useMachinesStore((s) => s.machines.filter((m2) => m2.onboarded));
11884
+ const prevMachineRef = React$2.useRef(machineId);
11885
+ React$2.useEffect(() => {
11886
+ if (prevMachineRef.current !== machineId) {
11887
+ prevMachineRef.current = machineId;
11888
+ setDirectory("");
11889
+ }
11890
+ }, [machineId]);
11241
11891
  async function handleCreate() {
11242
11892
  setCreating(true);
11243
11893
  setError("");
@@ -11272,17 +11922,17 @@ function CreateTerminalModal({ onClose, onCreated }) {
11272
11922
  return next;
11273
11923
  });
11274
11924
  }
11275
- return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$3.overlay, children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$3.dialog, children: [
11276
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$3.dialogHeader, children: [
11277
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$3.dialogTitle, children: "New Terminal" }),
11278
- /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { style: styles$3.stepLabel, children: [
11925
+ return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$4.overlay, children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$4.dialog, children: [
11926
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$4.dialogHeader, children: [
11927
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$4.dialogTitle, children: "New Terminal" }),
11928
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { style: styles$4.stepLabel, children: [
11279
11929
  "Step ",
11280
11930
  step,
11281
11931
  " of 3"
11282
11932
  ] }),
11283
- /* @__PURE__ */ jsxRuntimeExports.jsx("button", { style: styles$3.closeBtn, onClick: onClose, children: "✕" })
11933
+ /* @__PURE__ */ jsxRuntimeExports.jsx("button", { style: styles$4.closeBtn, onClick: onClose, children: "✕" })
11284
11934
  ] }),
11285
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$3.body, children: [
11935
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$4.body, children: [
11286
11936
  step === 1 && /* @__PURE__ */ jsxRuntimeExports.jsx(
11287
11937
  Step1,
11288
11938
  {
@@ -11319,7 +11969,7 @@ function CreateTerminalModal({ onClose, onCreated }) {
11319
11969
  }
11320
11970
  )
11321
11971
  ] }),
11322
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$3.dialogFooter, children: [
11972
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$4.dialogFooter, children: [
11323
11973
  step > 1 && /* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: "btn btn-ghost", onClick: () => setStep((s) => s - 1), children: "← Back" }),
11324
11974
  /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: { flex: 1 } }),
11325
11975
  /* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: "btn btn-ghost", onClick: onClose, children: "Cancel" }),
@@ -11344,9 +11994,9 @@ function CreateTerminalModal({ onClose, onCreated }) {
11344
11994
  ] }) });
11345
11995
  }
11346
11996
  function Step1({ name, setName, machineId, setMachineId, provider, setProvider, machines }) {
11347
- return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$3.step, children: [
11348
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$3.field, children: [
11349
- /* @__PURE__ */ jsxRuntimeExports.jsx("label", { style: styles$3.label, children: "Session name" }),
11997
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$4.step, children: [
11998
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$4.field, children: [
11999
+ /* @__PURE__ */ jsxRuntimeExports.jsx("label", { style: styles$4.label, children: "Session name" }),
11350
12000
  /* @__PURE__ */ jsxRuntimeExports.jsx(
11351
12001
  "input",
11352
12002
  {
@@ -11358,14 +12008,14 @@ function Step1({ name, setName, machineId, setMachineId, provider, setProvider,
11358
12008
  }
11359
12009
  )
11360
12010
  ] }),
11361
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$3.field, children: [
11362
- /* @__PURE__ */ jsxRuntimeExports.jsx("label", { style: styles$3.label, children: "Machine" }),
11363
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$3.machineList, children: machines.map((m2) => /* @__PURE__ */ jsxRuntimeExports.jsxs(
12011
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$4.field, children: [
12012
+ /* @__PURE__ */ jsxRuntimeExports.jsx("label", { style: styles$4.label, children: "Machine" }),
12013
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$4.machineList, children: machines.map((m2) => /* @__PURE__ */ jsxRuntimeExports.jsxs(
11364
12014
  "button",
11365
12015
  {
11366
12016
  style: {
11367
- ...styles$3.machineOption,
11368
- ...machineId === m2.id ? styles$3.machineOptionSelected : {}
12017
+ ...styles$4.machineOption,
12018
+ ...machineId === m2.id ? styles$4.machineOptionSelected : {}
11369
12019
  },
11370
12020
  onClick: () => setMachineId(m2.id),
11371
12021
  children: [
@@ -11377,14 +12027,14 @@ function Step1({ name, setName, machineId, setMachineId, provider, setProvider,
11377
12027
  m2.id
11378
12028
  )) })
11379
12029
  ] }),
11380
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$3.field, children: [
11381
- /* @__PURE__ */ jsxRuntimeExports.jsx("label", { style: styles$3.label, children: "AI Provider" }),
11382
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$3.providerRow, children: ["claude", "copilot", "none"].map((p2) => /* @__PURE__ */ jsxRuntimeExports.jsx(
12030
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$4.field, children: [
12031
+ /* @__PURE__ */ jsxRuntimeExports.jsx("label", { style: styles$4.label, children: "AI Provider" }),
12032
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$4.providerRow, children: ["claude", "copilot", "none"].map((p2) => /* @__PURE__ */ jsxRuntimeExports.jsx(
11383
12033
  "button",
11384
12034
  {
11385
12035
  style: {
11386
- ...styles$3.providerBtn,
11387
- ...provider === p2 ? styles$3.providerBtnSelected : {}
12036
+ ...styles$4.providerBtn,
12037
+ ...provider === p2 ? styles$4.providerBtnSelected : {}
11388
12038
  },
11389
12039
  onClick: () => setProvider(p2),
11390
12040
  children: p2
@@ -11398,15 +12048,16 @@ function Step2({ machineId, directory, setDirectory }) {
11398
12048
  const [showBrowser, setShowBrowser] = reactExports.useState(true);
11399
12049
  const [homeDir, setHomeDir] = reactExports.useState("C:\\");
11400
12050
  React$2.useEffect(() => {
12051
+ setDirectory("");
11401
12052
  window.maestro.fs.homeDir(machineId).then((h) => {
11402
12053
  setHomeDir(h);
11403
- if (!directory) setDirectory(h);
12054
+ setDirectory(h);
11404
12055
  }).catch(() => {
11405
12056
  });
11406
12057
  }, [machineId]);
11407
- return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$3.step, children: [
11408
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$3.field, children: [
11409
- /* @__PURE__ */ jsxRuntimeExports.jsx("label", { style: styles$3.label, children: "Working directory" }),
12058
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$4.step, children: [
12059
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$4.field, children: [
12060
+ /* @__PURE__ */ jsxRuntimeExports.jsx("label", { style: styles$4.label, children: "Working directory" }),
11410
12061
  /* @__PURE__ */ jsxRuntimeExports.jsx(
11411
12062
  "input",
11412
12063
  {
@@ -11420,7 +12071,7 @@ function Step2({ machineId, directory, setDirectory }) {
11420
12071
  /* @__PURE__ */ jsxRuntimeExports.jsxs(
11421
12072
  "button",
11422
12073
  {
11423
- style: styles$3.browserToggle,
12074
+ style: styles$4.browserToggle,
11424
12075
  onClick: () => setShowBrowser((v2) => !v2),
11425
12076
  children: [
11426
12077
  showBrowser ? "▼" : "▶",
@@ -11436,17 +12087,17 @@ function Step2({ machineId, directory, setDirectory }) {
11436
12087
  onSelect: setDirectory
11437
12088
  }
11438
12089
  ),
11439
- /* @__PURE__ */ jsxRuntimeExports.jsx("p", { style: styles$3.hint, children: "Select a directory above or type the path manually." })
12090
+ /* @__PURE__ */ jsxRuntimeExports.jsx("p", { style: styles$4.hint, children: "Select a directory above or type the path manually." })
11440
12091
  ] });
11441
12092
  }
11442
12093
  function Step3({ name, machineId, provider, directory, tags, tagInput, setTagInput, addTag, removeTag, error }) {
11443
- return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$3.step, children: [
11444
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$3.field, children: [
11445
- /* @__PURE__ */ jsxRuntimeExports.jsx("label", { style: styles$3.label, children: "Tags (optional)" }),
11446
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$3.tagEditor, children: [
11447
- Object.entries(tags).map(([k2, v2]) => /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { style: styles$3.tagChip, children: [
12094
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$4.step, children: [
12095
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$4.field, children: [
12096
+ /* @__PURE__ */ jsxRuntimeExports.jsx("label", { style: styles$4.label, children: "Tags (optional)" }),
12097
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$4.tagEditor, children: [
12098
+ Object.entries(tags).map(([k2, v2]) => /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { style: styles$4.tagChip, children: [
11448
12099
  v2 ? `${k2}:${v2}` : k2,
11449
- /* @__PURE__ */ jsxRuntimeExports.jsx("button", { style: styles$3.tagRemove, onClick: () => removeTag(k2), children: "×" })
12100
+ /* @__PURE__ */ jsxRuntimeExports.jsx("button", { style: styles$4.tagRemove, onClick: () => removeTag(k2), children: "×" })
11450
12101
  ] }, k2)),
11451
12102
  /* @__PURE__ */ jsxRuntimeExports.jsx(
11452
12103
  "input",
@@ -11461,35 +12112,35 @@ function Step3({ name, machineId, provider, directory, tags, tagInput, setTagInp
11461
12112
  }
11462
12113
  },
11463
12114
  placeholder: "type tag and press Enter…",
11464
- style: styles$3.tagInput
12115
+ style: styles$4.tagInput
11465
12116
  }
11466
12117
  )
11467
12118
  ] }),
11468
- /* @__PURE__ */ jsxRuntimeExports.jsx("p", { style: styles$3.hint, children: "Use key:value or plain labels. Press Enter to add." })
12119
+ /* @__PURE__ */ jsxRuntimeExports.jsx("p", { style: styles$4.hint, children: "Use key:value or plain labels. Press Enter to add." })
11469
12120
  ] }),
11470
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$3.summary, children: [
11471
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$3.summaryTitle, children: "Summary" }),
11472
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$3.summaryRow, children: [
11473
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$3.summaryKey, children: "Name" }),
12121
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$4.summary, children: [
12122
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$4.summaryTitle, children: "Summary" }),
12123
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$4.summaryRow, children: [
12124
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$4.summaryKey, children: "Name" }),
11474
12125
  /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: name })
11475
12126
  ] }),
11476
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$3.summaryRow, children: [
11477
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$3.summaryKey, children: "Machine" }),
12127
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$4.summaryRow, children: [
12128
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$4.summaryKey, children: "Machine" }),
11478
12129
  /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: machineId })
11479
12130
  ] }),
11480
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$3.summaryRow, children: [
11481
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$3.summaryKey, children: "Provider" }),
12131
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$4.summaryRow, children: [
12132
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$4.summaryKey, children: "Provider" }),
11482
12133
  /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: provider })
11483
12134
  ] }),
11484
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$3.summaryRow, children: [
11485
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$3.summaryKey, children: "Directory" }),
12135
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$4.summaryRow, children: [
12136
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$4.summaryKey, children: "Directory" }),
11486
12137
  /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: { fontFamily: "monospace", fontSize: "12px" }, children: directory || "(default)" })
11487
12138
  ] })
11488
12139
  ] }),
11489
- error && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$3.error, children: error })
12140
+ error && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$4.error, children: error })
11490
12141
  ] });
11491
12142
  }
11492
- const styles$3 = {
12143
+ const styles$4 = {
11493
12144
  overlay: {
11494
12145
  position: "fixed",
11495
12146
  inset: 0,
@@ -11689,9 +12340,22 @@ const styles$3 = {
11689
12340
  flexShrink: 0
11690
12341
  }
11691
12342
  };
12343
+ const STATUS_PILLS = {
12344
+ working: { icon: "●", label: "Working", color: "var(--state-working)" },
12345
+ waiting: { icon: "⏳", label: "Waiting", color: "var(--state-waiting)" },
12346
+ permission: { icon: "🔐", label: "Input Required", color: "var(--state-permission)" },
12347
+ idle: { icon: "○", label: "Idle", color: "var(--state-idle)" },
12348
+ done: { icon: "✓", label: "Done", color: "var(--state-done)" },
12349
+ error: { icon: "✗", label: "Error", color: "var(--state-error)" }
12350
+ };
12351
+ const ALL_STATES = ["working", "waiting", "permission", "idle", "done", "error"];
11692
12352
  function TagFilterBar() {
11693
- const { sessions, filterTags, setFilterTags } = useSessionsStore();
12353
+ const { sessions, filterTags, setFilterTags, filterStates, toggleFilterState, clearFilterStates } = useSessionsStore();
11694
12354
  const [popoverOpen, setPopoverOpen] = reactExports.useState(false);
12355
+ const stateCounts = /* @__PURE__ */ new Map();
12356
+ for (const s of sessions) {
12357
+ stateCounts.set(s.state, (stateCounts.get(s.state) ?? 0) + 1);
12358
+ }
11695
12359
  const allTags = {};
11696
12360
  for (const s of sessions) {
11697
12361
  for (const [k2, v2] of Object.entries(s.tags)) {
@@ -11700,14 +12364,42 @@ function TagFilterBar() {
11700
12364
  }
11701
12365
  }
11702
12366
  const activeFilters = Object.entries(filterTags).filter(([k2]) => k2);
11703
- return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$2.root, children: [
11704
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$2.icon, children: "🏷" }),
11705
- activeFilters.map(([k2, v2]) => /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { style: styles$2.chip, children: [
12367
+ const hasAnyFilter = activeFilters.length > 0 || filterStates.size > 0;
12368
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$3.root, children: [
12369
+ ALL_STATES.map((state) => {
12370
+ const count = stateCounts.get(state) ?? 0;
12371
+ if (count === 0) return null;
12372
+ const { icon, label, color } = STATUS_PILLS[state];
12373
+ const active = filterStates.has(state);
12374
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(
12375
+ "button",
12376
+ {
12377
+ onClick: () => toggleFilterState(state),
12378
+ style: {
12379
+ ...styles$3.statusPill,
12380
+ color: active ? "#fff" : color,
12381
+ background: active ? color : "transparent",
12382
+ borderColor: active ? color : `${color}40`
12383
+ },
12384
+ children: [
12385
+ icon,
12386
+ " ",
12387
+ label,
12388
+ " ",
12389
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$3.pillCount, children: count })
12390
+ ]
12391
+ },
12392
+ state
12393
+ );
12394
+ }),
12395
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$3.separator, children: "│" }),
12396
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$3.icon, children: "🏷" }),
12397
+ activeFilters.map(([k2, v2]) => /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { style: styles$3.chip, children: [
11706
12398
  v2 && v2 !== "*" ? `${k2}:${v2}` : k2,
11707
12399
  /* @__PURE__ */ jsxRuntimeExports.jsx(
11708
12400
  "button",
11709
12401
  {
11710
- style: styles$2.chipRemove,
12402
+ style: styles$3.chipRemove,
11711
12403
  onClick: () => {
11712
12404
  const next = { ...filterTags };
11713
12405
  delete next[k2];
@@ -11718,7 +12410,7 @@ function TagFilterBar() {
11718
12410
  )
11719
12411
  ] }, k2)),
11720
12412
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: { position: "relative" }, children: [
11721
- /* @__PURE__ */ jsxRuntimeExports.jsx("button", { style: styles$2.addBtn, onClick: () => setPopoverOpen((v2) => !v2), children: "+ Filter" }),
12413
+ /* @__PURE__ */ jsxRuntimeExports.jsx("button", { style: styles$3.addBtn, onClick: () => setPopoverOpen((v2) => !v2), children: "+ Filter" }),
11722
12414
  popoverOpen && /* @__PURE__ */ jsxRuntimeExports.jsx(
11723
12415
  FilterPopover,
11724
12416
  {
@@ -11731,17 +12423,20 @@ function TagFilterBar() {
11731
12423
  }
11732
12424
  )
11733
12425
  ] }),
11734
- activeFilters.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("button", { style: styles$2.clearBtn, onClick: () => setFilterTags({}), children: "Clear filters" })
12426
+ hasAnyFilter && /* @__PURE__ */ jsxRuntimeExports.jsx("button", { style: styles$3.clearBtn, onClick: () => {
12427
+ setFilterTags({});
12428
+ clearFilterStates();
12429
+ }, children: "Clear filters" })
11735
12430
  ] });
11736
12431
  }
11737
12432
  function FilterPopover({ allTags, onApply, onClose }) {
11738
12433
  const [selected, setSelected] = reactExports.useState({});
11739
12434
  const systemKeys = ["machine", "provider", "state"];
11740
12435
  const customKeys = Object.keys(allTags).filter((k2) => !systemKeys.includes(k2));
11741
- return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$2.popover, children: [
11742
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$2.popoverTitle, children: "Filter by tag" }),
11743
- systemKeys.filter((k2) => allTags[k2]).map((k2) => /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$2.popoverRow, children: [
11744
- /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { style: styles$2.popoverKey, children: [
12436
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$3.popover, children: [
12437
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$3.popoverTitle, children: "Filter by tag" }),
12438
+ systemKeys.filter((k2) => allTags[k2]).map((k2) => /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$3.popoverRow, children: [
12439
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { style: styles$3.popoverKey, children: [
11745
12440
  k2,
11746
12441
  ":"
11747
12442
  ] }),
@@ -11750,7 +12445,7 @@ function FilterPopover({ allTags, onApply, onClose }) {
11750
12445
  {
11751
12446
  value: selected[k2] ?? "",
11752
12447
  onChange: (e) => setSelected((prev) => ({ ...prev, [k2]: e.target.value })),
11753
- style: styles$2.popoverSelect,
12448
+ style: styles$3.popoverSelect,
11754
12449
  children: [
11755
12450
  /* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: "", children: "any" }),
11756
12451
  Array.from(allTags[k2]).map((v2) => /* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: v2, children: v2 }, v2))
@@ -11758,8 +12453,8 @@ function FilterPopover({ allTags, onApply, onClose }) {
11758
12453
  }
11759
12454
  )
11760
12455
  ] }, k2)),
11761
- customKeys.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$2.popoverRow, children: [
11762
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$2.popoverKey, children: "custom:" }),
12456
+ customKeys.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$3.popoverRow, children: [
12457
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$3.popoverKey, children: "custom:" }),
11763
12458
  /* @__PURE__ */ jsxRuntimeExports.jsxs(
11764
12459
  "select",
11765
12460
  {
@@ -11768,7 +12463,7 @@ function FilterPopover({ allTags, onApply, onClose }) {
11768
12463
  const v2 = e.target.value;
11769
12464
  setSelected((prev) => v2 ? { ...prev, _custom: v2 } : { ...prev });
11770
12465
  },
11771
- style: styles$2.popoverSelect,
12466
+ style: styles$3.popoverSelect,
11772
12467
  children: [
11773
12468
  /* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: "", children: "pick tag…" }),
11774
12469
  customKeys.map((k2) => /* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: k2, children: k2 }, k2))
@@ -11776,7 +12471,7 @@ function FilterPopover({ allTags, onApply, onClose }) {
11776
12471
  }
11777
12472
  )
11778
12473
  ] }),
11779
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$2.popoverActions, children: [
12474
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$3.popoverActions, children: [
11780
12475
  /* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: "btn btn-ghost btn-sm", onClick: onClose, children: "Cancel" }),
11781
12476
  /* @__PURE__ */ jsxRuntimeExports.jsx(
11782
12477
  "button",
@@ -11796,7 +12491,7 @@ function FilterPopover({ allTags, onApply, onClose }) {
11796
12491
  ] })
11797
12492
  ] });
11798
12493
  }
11799
- const styles$2 = {
12494
+ const styles$3 = {
11800
12495
  root: {
11801
12496
  display: "flex",
11802
12497
  alignItems: "center",
@@ -11804,6 +12499,28 @@ const styles$2 = {
11804
12499
  flex: 1,
11805
12500
  flexWrap: "wrap"
11806
12501
  },
12502
+ statusPill: {
12503
+ display: "inline-flex",
12504
+ alignItems: "center",
12505
+ gap: "4px",
12506
+ fontSize: "11px",
12507
+ fontWeight: 600,
12508
+ padding: "3px 8px",
12509
+ borderRadius: "10px",
12510
+ border: "1px solid",
12511
+ cursor: "pointer",
12512
+ transition: "all 0.15s",
12513
+ whiteSpace: "nowrap"
12514
+ },
12515
+ pillCount: {
12516
+ fontSize: "10px",
12517
+ opacity: 0.8
12518
+ },
12519
+ separator: {
12520
+ color: "var(--border)",
12521
+ fontSize: "14px",
12522
+ margin: "0 2px"
12523
+ },
11807
12524
  icon: {
11808
12525
  fontSize: "14px"
11809
12526
  },
@@ -11897,15 +12614,53 @@ function TerminalsView({ onSessionAdded }) {
11897
12614
  const {
11898
12615
  sessions,
11899
12616
  filterTags,
12617
+ filterStates,
11900
12618
  activeFullscreenId,
12619
+ splitIds,
11901
12620
  setFullscreen,
12621
+ setSplit,
11902
12622
  removeSession,
11903
12623
  updateSession
11904
12624
  } = useSessionsStore();
11905
12625
  const [showCreate, setShowCreate] = reactExports.useState(false);
11906
12626
  const [editTagsId, setEditTagsId] = reactExports.useState(null);
11907
- const filtered = filterSessions(sessions, filterTags);
12627
+ const [viewMode, setViewMode] = reactExports.useState("grid");
12628
+ const [searchQuery, setSearchQuery] = reactExports.useState("");
12629
+ const tagFiltered = filterSessions(sessions, filterTags, filterStates);
12630
+ const filtered = searchQuery.trim() ? tagFiltered.filter((s) => {
12631
+ const q2 = searchQuery.toLowerCase();
12632
+ return s.name.toLowerCase().includes(q2) || (s.tags["machine"] ?? "").toLowerCase().includes(q2) || s.provider.toLowerCase().includes(q2) || s.workingDirectory.toLowerCase().includes(q2) || s.state.toLowerCase().includes(q2);
12633
+ }) : tagFiltered;
11908
12634
  const fullscreenSession = activeFullscreenId ? sessions.find((s) => s.id === activeFullscreenId) ?? null : null;
12635
+ reactExports.useEffect(() => {
12636
+ function onKeyDown(e) {
12637
+ if (showCreate || editTagsId) return;
12638
+ const target = e.target;
12639
+ if (target.tagName === "INPUT" || target.tagName === "TEXTAREA" || target.tagName === "SELECT") return;
12640
+ const ctrlOrCmd = e.ctrlKey || e.metaKey;
12641
+ if (ctrlOrCmd && e.key === "n") {
12642
+ e.preventDefault();
12643
+ setShowCreate(true);
12644
+ } else if (ctrlOrCmd && e.key === "\\") {
12645
+ e.preventDefault();
12646
+ if (splitIds) {
12647
+ setSplit(null);
12648
+ } else if (activeFullscreenId && filtered.length >= 2) {
12649
+ const currentIdx = filtered.findIndex((s) => s.id === activeFullscreenId);
12650
+ const nextIdx = (currentIdx + 1) % filtered.length;
12651
+ setSplit([activeFullscreenId, filtered[nextIdx].id]);
12652
+ }
12653
+ } else if (ctrlOrCmd && e.key >= "1" && e.key <= "9") {
12654
+ e.preventDefault();
12655
+ const index = parseInt(e.key) - 1;
12656
+ if (filtered[index]) {
12657
+ setFullscreen(filtered[index].id);
12658
+ }
12659
+ }
12660
+ }
12661
+ window.addEventListener("keydown", onKeyDown);
12662
+ return () => window.removeEventListener("keydown", onKeyDown);
12663
+ }, [filtered, showCreate, editTagsId, setFullscreen]);
11909
12664
  async function handleClose(id2) {
11910
12665
  await window.maestro.sessions.destroy(id2).catch(() => {
11911
12666
  });
@@ -11916,15 +12671,34 @@ function TerminalsView({ onSessionAdded }) {
11916
12671
  });
11917
12672
  updateSession({ id: id2, name });
11918
12673
  }
11919
- return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$1.root, children: [
11920
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$1.toolbar, children: [
12674
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$2.root, children: [
12675
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$2.toolbar, children: [
11921
12676
  /* @__PURE__ */ jsxRuntimeExports.jsx(TagFilterBar, {}),
11922
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$1.toolbarRight, children: [
11923
- /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { style: styles$1.count, children: [
12677
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
12678
+ "input",
12679
+ {
12680
+ type: "text",
12681
+ value: searchQuery,
12682
+ onChange: (e) => setSearchQuery(e.target.value),
12683
+ placeholder: "Search terminals…",
12684
+ style: styles$2.searchInput
12685
+ }
12686
+ ),
12687
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$2.toolbarRight, children: [
12688
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { style: styles$2.count, children: [
11924
12689
  filtered.length,
11925
12690
  "/",
11926
12691
  sessions.length
11927
12692
  ] }),
12693
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
12694
+ "button",
12695
+ {
12696
+ className: "btn btn-ghost btn-sm",
12697
+ onClick: () => setViewMode((v2) => v2 === "grid" ? "tabs" : "grid"),
12698
+ title: viewMode === "grid" ? "Switch to tabbed view" : "Switch to grid view",
12699
+ children: viewMode === "grid" ? "☰ Tabs" : "▦ Grid"
12700
+ }
12701
+ ),
11928
12702
  /* @__PURE__ */ jsxRuntimeExports.jsx(
11929
12703
  "button",
11930
12704
  {
@@ -11935,12 +12709,18 @@ function TerminalsView({ onSessionAdded }) {
11935
12709
  )
11936
12710
  ] })
11937
12711
  ] }),
11938
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$1.gridWrapper, children: filtered.length === 0 ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$1.empty, children: sessions.length === 0 ? /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
11939
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$1.emptyIcon, children: "▦" }),
12712
+ viewMode === "tabs" && filtered.length > 0 ? /* @__PURE__ */ jsxRuntimeExports.jsx(
12713
+ TabbedWorkspace,
12714
+ {
12715
+ sessions: filtered,
12716
+ onClose: (id2) => handleClose(id2)
12717
+ }
12718
+ ) : /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$2.gridWrapper, children: filtered.length === 0 ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$2.empty, children: sessions.length === 0 ? /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
12719
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$2.emptyIcon, children: "▦" }),
11940
12720
  /* @__PURE__ */ jsxRuntimeExports.jsx("p", { style: { fontWeight: 600, marginBottom: "8px" }, children: "No terminals yet" }),
11941
12721
  /* @__PURE__ */ jsxRuntimeExports.jsx("p", { style: { color: "var(--text-muted)", fontSize: "13px", marginBottom: "16px" }, children: "Launch an AI coding session to get started." }),
11942
12722
  /* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: "btn btn-primary", onClick: () => setShowCreate(true), children: "+ New Terminal" })
11943
- ] }) : /* @__PURE__ */ jsxRuntimeExports.jsx("p", { style: { color: "var(--text-muted)" }, children: "No sessions match the current filter." }) }) : /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$1.grid, children: filtered.map((session) => /* @__PURE__ */ jsxRuntimeExports.jsx(
12723
+ ] }) : /* @__PURE__ */ jsxRuntimeExports.jsx("p", { style: { color: "var(--text-muted)" }, children: "No sessions match the current filter." }) }) : /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$2.grid, children: filtered.map((session) => /* @__PURE__ */ jsxRuntimeExports.jsx(
11944
12724
  TerminalTile,
11945
12725
  {
11946
12726
  session,
@@ -11958,6 +12738,19 @@ function TerminalsView({ onSessionAdded }) {
11958
12738
  onClose: () => setFullscreen(null)
11959
12739
  }
11960
12740
  ),
12741
+ splitIds && (() => {
12742
+ const leftSession = sessions.find((s) => s.id === splitIds[0]);
12743
+ const rightSession = sessions.find((s) => s.id === splitIds[1]);
12744
+ if (!leftSession || !rightSession) return null;
12745
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(
12746
+ SplitPaneOverlay,
12747
+ {
12748
+ left: leftSession,
12749
+ right: rightSession,
12750
+ onClose: () => setSplit(null)
12751
+ }
12752
+ );
12753
+ })(),
11961
12754
  showCreate && /* @__PURE__ */ jsxRuntimeExports.jsx(
11962
12755
  CreateTerminalModal,
11963
12756
  {
@@ -11996,16 +12789,16 @@ function TagEditPanel({ sessionId, initialTags, onClose, onSave }) {
11996
12789
  setTags((prev) => ({ ...prev, [key.trim()]: val.trim() }));
11997
12790
  setInput("");
11998
12791
  }
11999
- return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$1.tagEditOverlay, children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$1.tagEditPanel, children: [
12000
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$1.tagEditHeader, children: [
12792
+ return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$2.tagEditOverlay, children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$2.tagEditPanel, children: [
12793
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$2.tagEditHeader, children: [
12001
12794
  /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { children: [
12002
12795
  session?.name,
12003
12796
  " · Tags"
12004
12797
  ] }),
12005
12798
  /* @__PURE__ */ jsxRuntimeExports.jsx("button", { style: { background: "transparent", border: "none", color: "var(--text-muted)", fontSize: "16px" }, onClick: onClose, children: "✕" })
12006
12799
  ] }),
12007
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$1.tagEditorInline, children: [
12008
- Object.entries(tags).filter(([k2]) => !["machine", "provider", "state"].includes(k2)).map(([k2, v2]) => /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { style: styles$1.tagChipEdit, children: [
12800
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: styles$2.tagEditorInline, children: [
12801
+ Object.entries(tags).filter(([k2]) => !["machine", "provider", "state"].includes(k2)).map(([k2, v2]) => /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { style: styles$2.tagChipEdit, children: [
12009
12802
  v2 ? `${k2}:${v2}` : k2,
12010
12803
  /* @__PURE__ */ jsxRuntimeExports.jsx(
12011
12804
  "button",
@@ -12040,7 +12833,7 @@ function TagEditPanel({ sessionId, initialTags, onClose, onSave }) {
12040
12833
  ] })
12041
12834
  ] }) });
12042
12835
  }
12043
- const styles$1 = {
12836
+ const styles$2 = {
12044
12837
  root: {
12045
12838
  display: "flex",
12046
12839
  flexDirection: "column",
@@ -12057,6 +12850,17 @@ const styles$1 = {
12057
12850
  flexShrink: 0,
12058
12851
  height: "var(--header-height)"
12059
12852
  },
12853
+ searchInput: {
12854
+ padding: "5px 10px",
12855
+ fontSize: "12px",
12856
+ background: "var(--bg-base)",
12857
+ border: "1px solid var(--border)",
12858
+ borderRadius: "var(--radius-sm)",
12859
+ color: "var(--text-primary)",
12860
+ outline: "none",
12861
+ width: "180px",
12862
+ flexShrink: 0
12863
+ },
12060
12864
  toolbarRight: {
12061
12865
  display: "flex",
12062
12866
  alignItems: "center",
@@ -12141,12 +12945,92 @@ const styles$1 = {
12141
12945
  borderRadius: "10px"
12142
12946
  }
12143
12947
  };
12948
+ let nextId = 0;
12949
+ const useToastsStore = create((set) => ({
12950
+ toasts: [],
12951
+ addToast(message, type) {
12952
+ const id2 = `toast-${nextId++}`;
12953
+ const toast = { id: id2, message, type, createdAt: Date.now() };
12954
+ set((s) => ({
12955
+ toasts: [...s.toasts.slice(-4), toast]
12956
+ // cap at 5
12957
+ }));
12958
+ setTimeout(() => {
12959
+ set((s) => ({ toasts: s.toasts.filter((t2) => t2.id !== id2) }));
12960
+ }, 5e3);
12961
+ },
12962
+ removeToast(id2) {
12963
+ set((s) => ({ toasts: s.toasts.filter((t2) => t2.id !== id2) }));
12964
+ }
12965
+ }));
12966
+ const TYPE_COLORS = {
12967
+ info: "var(--state-working)",
12968
+ success: "var(--state-done)",
12969
+ warning: "var(--state-waiting)",
12970
+ error: "var(--state-error)"
12971
+ };
12972
+ function ToastContainer() {
12973
+ const { toasts, removeToast } = useToastsStore();
12974
+ if (toasts.length === 0) return null;
12975
+ return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: styles$1.container, children: toasts.map((toast) => /* @__PURE__ */ jsxRuntimeExports.jsxs(
12976
+ "div",
12977
+ {
12978
+ style: { ...styles$1.toast, borderLeftColor: TYPE_COLORS[toast.type] },
12979
+ children: [
12980
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: styles$1.message, children: toast.message }),
12981
+ /* @__PURE__ */ jsxRuntimeExports.jsx("button", { style: styles$1.dismiss, onClick: () => removeToast(toast.id), children: "✕" })
12982
+ ]
12983
+ },
12984
+ toast.id
12985
+ )) });
12986
+ }
12987
+ const styles$1 = {
12988
+ container: {
12989
+ position: "fixed",
12990
+ bottom: "16px",
12991
+ right: "16px",
12992
+ zIndex: 300,
12993
+ display: "flex",
12994
+ flexDirection: "column",
12995
+ gap: "8px",
12996
+ maxWidth: "360px"
12997
+ },
12998
+ toast: {
12999
+ display: "flex",
13000
+ alignItems: "center",
13001
+ gap: "8px",
13002
+ padding: "10px 12px",
13003
+ background: "var(--bg-elevated)",
13004
+ border: "1px solid var(--border)",
13005
+ borderLeft: "3px solid",
13006
+ borderRadius: "var(--radius-sm)",
13007
+ boxShadow: "0 4px 16px rgba(0,0,0,0.4)",
13008
+ animation: "slideIn 0.2s ease-out"
13009
+ },
13010
+ message: {
13011
+ flex: 1,
13012
+ fontSize: "12px",
13013
+ color: "var(--text-primary)",
13014
+ lineHeight: 1.4
13015
+ },
13016
+ dismiss: {
13017
+ background: "transparent",
13018
+ border: "none",
13019
+ color: "var(--text-muted)",
13020
+ fontSize: "12px",
13021
+ cursor: "pointer",
13022
+ padding: "0 2px",
13023
+ flexShrink: 0
13024
+ }
13025
+ };
12144
13026
  function App() {
12145
13027
  const [view, setView] = reactExports.useState("home");
12146
13028
  const [runPlanFile, setRunPlanFile] = reactExports.useState(null);
12147
13029
  const runStatus = useRunStore((s) => s.status);
12148
13030
  const { setMachines, addMachine, removeMachine, updateStatus } = useMachinesStore();
12149
13031
  const { setSessions, addSession, updateSession, removeSession, applyStateChange } = useSessionsStore();
13032
+ const addToast = useToastsStore((s) => s.addToast);
13033
+ const prevStatesRef = reactExports.useRef(/* @__PURE__ */ new Map());
12150
13034
  const waitingCount = useSessionsStore(
12151
13035
  (s) => s.sessions.filter((sess) => sess.state === "waiting").length
12152
13036
  );
@@ -12161,9 +13045,29 @@ function App() {
12161
13045
  const unsubSessionData = window.maestro.sessions.onData((_ev) => {
12162
13046
  });
12163
13047
  const unsubStateChanged = window.maestro.sessions.onStateChanged((ev) => {
12164
- applyStateChange(ev);
13048
+ const event = ev;
13049
+ const prev = prevStatesRef.current.get(event.sessionId);
13050
+ if (prev && prev !== event.state) {
13051
+ const session = useSessionsStore.getState().sessions.find((s) => s.id === event.sessionId);
13052
+ const name = session?.name ?? event.sessionId.slice(0, 8);
13053
+ const labels = {
13054
+ working: "Working",
13055
+ waiting: "Waiting",
13056
+ permission: "Input Required",
13057
+ idle: "Idle",
13058
+ done: "Done",
13059
+ error: "Error"
13060
+ };
13061
+ addToast(`${name}: ${labels[prev] ?? prev} → ${labels[event.state] ?? event.state}`, "info");
13062
+ }
13063
+ prevStatesRef.current.set(event.sessionId, event.state);
13064
+ applyStateChange(event);
12165
13065
  });
12166
13066
  const unsubDestroyed = window.maestro.sessions.onDestroyed((id2) => {
13067
+ const session = useSessionsStore.getState().sessions.find((s) => s.id === id2);
13068
+ const name = session?.name ?? id2.slice(0, 8);
13069
+ addToast(`"${name}" session ended`, "warning");
13070
+ prevStatesRef.current.delete(id2);
12167
13071
  removeSession(id2);
12168
13072
  });
12169
13073
  return () => {
@@ -12212,7 +13116,8 @@ function App() {
12212
13116
  }
12213
13117
  ),
12214
13118
  view === "terminals" && /* @__PURE__ */ jsxRuntimeExports.jsx(TerminalsView, { onSessionAdded: addSession })
12215
- ] })
13119
+ ] }),
13120
+ /* @__PURE__ */ jsxRuntimeExports.jsx(ToastContainer, {})
12216
13121
  ] });
12217
13122
  }
12218
13123
  const styles = {