@burdenoff/microfe-vibecontrols 2026.523.2 → 2026.524.1

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.
@@ -1,105 +1,105 @@
1
- import { useArchiveVibeMutation as e, useCreateVibeMutation as t, useListAgentsLazyQuery as n, useListVibesQuery as r, useUpdateVibeStatusMutation as i } from "../generated/wspace-operations.js";
2
- import { useVibeControls as ee, useVibeNavigate as te } from "../providers/VibeControlsProvider.js";
3
- import { useVibeControlsStore as ne } from "../store/vibeControlsStore.js";
4
- import re from "../hooks/useCachedInitialData.js";
5
- import { PageHeader as ie } from "../components/shared/PageHeader.js";
6
- import { LoadingState as ae } from "../components/shared/LoadingState.js";
7
- import { ErrorState as oe } from "../components/shared/ErrorState.js";
1
+ import { useArchiveVibeMutation as e, useAttachAgentToVibeMutation as t, useCreateVibeMutation as n, useListAgentsLazyQuery as r, useListVibesQuery as i, useUpdateVibeStatusMutation as ee } from "../generated/wspace-operations.js";
2
+ import { useVibeControls as te, useVibeNavigate as ne } from "../providers/VibeControlsProvider.js";
3
+ import { useVibeControlsStore as re } from "../store/vibeControlsStore.js";
4
+ import ie from "../hooks/useCachedInitialData.js";
5
+ import { PageHeader as ae } from "../components/shared/PageHeader.js";
6
+ import { LoadingState as oe } from "../components/shared/LoadingState.js";
7
+ import { ErrorState as se } from "../components/shared/ErrorState.js";
8
8
  import { ConfirmDialog as a } from "../components/shared/ConfirmDialog.js";
9
- import { QuotaExhaustedDialog as se } from "../components/shared/QuotaExhaustedDialog.js";
10
- import { isQuotaExhaustedError as ce } from "../utils/quotaUtils.js";
11
- import { EntityTagPicker as le } from "../components/shared/EntityTagPicker.js";
12
- import { useDraftEntityTags as ue } from "../hooks/useDraftEntityTags.js";
13
- import { EmptyState as de } from "../components/shared/EmptyState.js";
14
- import { SearchInput as fe } from "../components/shared/SearchInput.js";
15
- import { FilterDropdown as o } from "../components/shared/FilterDropdown.js";
16
- import { GetHelpButton as pe } from "../components/shared/GetHelpButton.js";
17
- import { SelectionCheckbox as me } from "../components/shared/SelectionCheckbox.js";
9
+ import { QuotaExhaustedDialog as ce } from "../components/shared/QuotaExhaustedDialog.js";
10
+ import { isQuotaExhaustedError as le } from "../utils/quotaUtils.js";
11
+ import { EntityTagPicker as ue } from "../components/shared/EntityTagPicker.js";
12
+ import { useDraftEntityTags as de } from "../hooks/useDraftEntityTags.js";
13
+ import { EmptyState as fe } from "../components/shared/EmptyState.js";
14
+ import { SearchInput as pe } from "../components/shared/SearchInput.js";
15
+ import { FilterDropdown as me } from "../components/shared/FilterDropdown.js";
16
+ import { GetHelpButton as he } from "../components/shared/GetHelpButton.js";
17
+ import { SelectionCheckbox as ge } from "../components/shared/SelectionCheckbox.js";
18
18
  import "../components/shared/index.js";
19
- import { VIBE_PERMISSIONS as s } from "../constants/permissions.js";
20
- import { PageSkeleton as he } from "../components/shared/PageSkeleton.js";
21
- import { buildProtocolUrl as ge, getIdePreset as _e, resolveEffectiveIdeCommand as ve } from "../components/agents/idePresets.js";
22
- import { VibeCard as ye } from "../components/vibes/VibeCard.js";
23
- import { VibeList as be } from "../components/vibes/VibeList.js";
19
+ import { VIBE_PERMISSIONS as o } from "../constants/permissions.js";
20
+ import { PageSkeleton as _e } from "../components/shared/PageSkeleton.js";
21
+ import { buildProtocolUrl as ve, getIdePreset as ye, resolveEffectiveIdeCommand as be } from "../components/agents/idePresets.js";
22
+ import { VibeCard as xe } from "../components/vibes/VibeCard.js";
23
+ import { VibeList as Se } from "../components/vibes/VibeList.js";
24
24
  import "../components/vibes/index.js";
25
- import { useCallback as c, useEffect as xe, useMemo as l, useRef as u, useState as d } from "react";
26
- import { useI18n as Se } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
27
- import { Archive as Ce, Grid as we, List as Te, Play as Ee, Plus as De, RefreshCw as Oe, Zap as ke } from "lucide-react";
28
- import { usePermissions as Ae } from "@burdenoff/fe-libs/shared/providers/shell";
29
- import { AnimatePresence as je } from "framer-motion";
30
- import { Fragment as Me, jsx as f, jsxs as p } from "react/jsx-runtime";
31
- import { MotionItem as Ne, MotionList as m, MotionPage as Pe } from "@burdenoff/fe-libs/shared/motion";
32
- import { AccessDenied as Fe, PermissionButton as Ie, PermissionGate as Le } from "@burdenoff/fe-libs/shared/components";
25
+ import { useCallback as s, useEffect as Ce, useMemo as c, useRef as l, useState as u } from "react";
26
+ import { useI18n as we } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
27
+ import { Archive as Te, Grid as Ee, List as De, Play as Oe, Plus as ke, RefreshCw as Ae, Zap as je } from "lucide-react";
28
+ import { usePermissions as Me } from "@burdenoff/fe-libs/shared/providers/shell";
29
+ import { AnimatePresence as Ne } from "framer-motion";
30
+ import { Fragment as Pe, jsx as d, jsxs as f } from "react/jsx-runtime";
31
+ import { MotionItem as Fe, MotionList as p, MotionPage as Ie } from "@burdenoff/fe-libs/shared/motion";
32
+ import { AccessDenied as Le, PermissionButton as Re, PermissionGate as ze } from "@burdenoff/fe-libs/shared/components";
33
33
  //#region src/pages/VibesPage.tsx
34
- function h() {
35
- let { onVibeActivate: h } = ee(), g = te(), { hasPermission: _, isLoading: v, permissions: y } = Ae(), { t: b } = Se(), x = c((e, t, n) => {
36
- let r = b(e, n), i = r === e ? t : r;
34
+ function m() {
35
+ let { onVibeActivate: m } = te(), h = ne(), { hasPermission: g, isLoading: _, permissions: v } = Me(), { t: y } = we(), b = s((e, t, n) => {
36
+ let r = y(e, n), i = r === e ? t : r;
37
37
  return n ? Object.entries(n).reduce((e, [t, n]) => e.replace(`{{${t}}}`, String(n)), i) : i;
38
- }, [b]), Re = [
38
+ }, [y]), Be = [
39
39
  {
40
40
  value: "all",
41
- label: x("vibesPage.statusAll", "All Statuses")
41
+ label: b("vibesPage.statusAll", "All Statuses")
42
42
  },
43
43
  {
44
44
  value: "ACTIVE",
45
- label: x("vibesPage.statusActive", "Active")
45
+ label: b("vibesPage.statusActive", "Active")
46
46
  },
47
47
  {
48
48
  value: "INACTIVE",
49
- label: x("vibesPage.statusInactive", "Inactive")
49
+ label: b("vibesPage.statusInactive", "Inactive")
50
50
  },
51
51
  {
52
52
  value: "ARCHIVED",
53
- label: x("vibesPage.statusArchived", "Archived")
53
+ label: b("vibesPage.statusArchived", "Archived")
54
54
  },
55
55
  {
56
56
  value: "ERROR",
57
- label: x("vibesPage.statusError", "Error")
57
+ label: b("vibesPage.statusError", "Error")
58
58
  }
59
59
  ];
60
- x("vibesPage.typeAll", "All Types"), x("vibesPage.typeProject", "Project"), x("vibesPage.typeRepository", "Repository"), x("vibesPage.typeWorkspace", "Workspace"), x("vibesPage.typeMonorepo", "Monorepo"), x("vibesPage.typePackage", "Package"), x("vibesPage.typeCustom", "Custom");
61
- let S = _(s.VIBE_LIST), C = _(s.VIBE_UPDATE), w = v || !S, [T, ze] = d(""), [E, Be] = d("all"), [D, Ve] = d("all"), [O, He] = d("all"), [k, Ue] = d("grid"), [We, A] = d(!1), [j, M] = d(null), [N, Ge] = d(!1), [Ke, P] = d(null), [qe, F] = d(!1), [I, L] = d({}), [Je, R] = d(null), [z, B] = d(/* @__PURE__ */ new Set()), [Ye, V] = d(null), H = u(null);
62
- xe(() => () => {
63
- H.current && clearTimeout(H.current);
60
+ b("vibesPage.typeAll", "All Types"), b("vibesPage.typeProject", "Project"), b("vibesPage.typeRepository", "Repository"), b("vibesPage.typeWorkspace", "Workspace"), b("vibesPage.typeMonorepo", "Monorepo"), b("vibesPage.typePackage", "Package"), b("vibesPage.typeCustom", "Custom");
61
+ let x = g(o.VIBE_LIST), S = g(o.VIBE_UPDATE), C = _ || !x, [w, Ve] = u(""), [T, He] = u("all"), [E, Ue] = u("all"), [D, We] = u("all"), [O, k] = u("grid"), [Ge, A] = u(!1), [Ke, j] = u(null), [M, qe] = u(!1), [Je, N] = u(null), [Ye, P] = u(!1), [F, I] = u({}), [Xe, L] = u(null), [R, z] = u(/* @__PURE__ */ new Set()), [Ze, B] = u(null), V = l(null);
62
+ Ce(() => () => {
63
+ V.current && clearTimeout(V.current);
64
64
  }, []);
65
- let Xe = c(() => {
66
- R(null), H.current &&= (clearTimeout(H.current), null);
67
- }, []), Ze = u(null), Qe = u(null), $e = u(null), et = u(null), [tt] = t(), { setDraftTagIds: nt, flushTags: rt } = ue("VIBECONTROLS_VIBE"), [it] = i(), [at] = e(), { data: ot, loading: U, error: st, refetch: W } = r({
68
- variables: l(() => ({ filter: {
69
- status: E === "all" ? void 0 : E,
70
- type: D === "all" ? void 0 : D,
71
- attachedAgentIds: O === "all" ? void 0 : [O]
65
+ let Qe = s(() => {
66
+ L(null), V.current &&= (clearTimeout(V.current), null);
67
+ }, []), $e = l(null), et = l(null), tt = l(null), nt = l(null), [rt] = n(), [it] = t(), { setDraftTagIds: at, flushTags: ot } = de("VIBECONTROLS_VIBE"), [st] = ee(), [ct] = e(), { data: lt, loading: H, error: ut, refetch: U } = i({
68
+ variables: c(() => ({ filter: {
69
+ status: T === "all" ? void 0 : T,
70
+ type: E === "all" ? void 0 : E,
71
+ attachedAgentIds: D === "all" ? void 0 : [D]
72
72
  } }), [
73
+ T,
73
74
  E,
74
- D,
75
- O
75
+ D
76
76
  ]),
77
- fetchPolicy: E === "all" && D === "all" && O === "all" ? "cache-first" : "cache-and-network",
77
+ fetchPolicy: T === "all" && E === "all" && D === "all" ? "cache-first" : "cache-and-network",
78
78
  nextFetchPolicy: "cache-first",
79
- skip: w,
79
+ skip: C,
80
80
  notifyOnNetworkStatusChange: !0
81
- }), { agents: ct } = re(), [lt, { data: ut }] = n({ fetchPolicy: "cache-first" }), dt = u(!1), G = c(() => {
82
- dt.current || w || (dt.current = !0, lt({ variables: { pagination: { limit: 100 } } }));
83
- }, [lt, w]), ft = l(() => {
84
- let e = ut?.vibecontrolsAgents ?? null, t = e ? e.map((e) => ({
81
+ }), { agents: dt } = ie(), [ft, { data: pt }] = r({ fetchPolicy: "cache-first" }), mt = l(!1), W = s(() => {
82
+ mt.current || C || (mt.current = !0, ft({ variables: { pagination: { limit: 100 } } }));
83
+ }, [ft, C]), ht = c(() => {
84
+ let e = pt?.vibecontrolsAgents ?? null, t = e ? e.map((e) => ({
85
85
  id: e.id,
86
86
  name: e.name
87
- })) : ct.map((e) => ({
87
+ })) : dt.map((e) => ({
88
88
  id: e.id,
89
89
  name: e.name
90
90
  }));
91
91
  return [{
92
92
  value: "all",
93
- label: x("vibesPage.allAgents", "All Agents")
93
+ label: b("vibesPage.allAgents", "All Agents")
94
94
  }, ...t.map((e) => ({
95
95
  value: e.id,
96
96
  label: e.name
97
97
  }))];
98
98
  }, [
99
- ut?.vibecontrolsAgents,
100
- ct,
101
- x
102
- ]), K = l(() => (ot?.vibes?.items ?? []).map((e) => ({
99
+ pt?.vibecontrolsAgents,
100
+ dt,
101
+ b
102
+ ]), G = c(() => (lt?.vibes?.items ?? []).map((e) => ({
103
103
  id: e.id,
104
104
  workspaceId: e.workspaceId,
105
105
  name: e.name,
@@ -122,20 +122,20 @@ function h() {
122
122
  isActive: e.isActive,
123
123
  ownerUserId: e.ownerUserId ?? null
124
124
  }))
125
- })), [ot?.vibes?.items]), q = l(() => K.filter((e) => {
126
- if (T) {
127
- let t = T.toLowerCase();
125
+ })), [lt?.vibes?.items]), K = c(() => G.filter((e) => {
126
+ if (w) {
127
+ let t = w.toLowerCase();
128
128
  if (!(e.name.toLowerCase().includes(t) || e.description?.toLowerCase().includes(t) || e.path?.toLowerCase().includes(t) || e.tags?.some((e) => e.toLowerCase().includes(t)))) return !1;
129
129
  }
130
130
  return !0;
131
- }), [K, T]), pt = l(() => K.filter((e) => z.has(e.id)), [K, z]), J = pt.filter((e) => e.status !== "ACTIVE"), Y = pt.filter((e) => e.status !== "ARCHIVED"), X = q.length > 0 && q.every((e) => z.has(e.id)), mt = q.some((e) => z.has(e.id)) && !X, ht = (e) => {
132
- g(`/vibes/${e.id}`);
133
- }, gt = async (e) => {
131
+ }), [G, w]), gt = c(() => G.filter((e) => R.has(e.id)), [G, R]), q = gt.filter((e) => e.status !== "ACTIVE"), J = gt.filter((e) => e.status !== "ARCHIVED"), Y = K.length > 0 && K.every((e) => R.has(e.id)), _t = K.some((e) => R.has(e.id)) && !Y, vt = (e) => {
132
+ h(`/vibes/${e.id}`);
133
+ }, yt = async (e) => {
134
134
  try {
135
- (await it({ variables: {
135
+ (await st({ variables: {
136
136
  id: e.id,
137
137
  status: "ACTIVE"
138
- } })).data?.updateVibeStatus && h?.({
138
+ } })).data?.updateVibeStatus && m?.({
139
139
  id: e.id,
140
140
  name: e.name,
141
141
  type: e.type,
@@ -144,55 +144,55 @@ function h() {
144
144
  } catch (e) {
145
145
  console.error("Failed to activate vibe:", e);
146
146
  }
147
- }, _t = async (e) => {
147
+ }, bt = async (e) => {
148
148
  try {
149
- await at({ variables: { id: e.id } });
149
+ await ct({ variables: { id: e.id } });
150
150
  } catch (e) {
151
151
  console.error("Failed to archive vibe:", e);
152
152
  }
153
- }, vt = ne((e) => e.preferredIdeCommand), yt = ne((e) => e.vibeIdeOverrides), bt = (e) => {
153
+ }, xt = re((e) => e.preferredIdeCommand), St = re((e) => e.vibeIdeOverrides), X = (e) => {
154
154
  if (!e.path) {
155
- R(x("vibesPage.openEditorPathMissing", "No path available to open in editor")), H.current = setTimeout(() => {
156
- R(null), H.current = null;
155
+ L(b("vibesPage.openEditorPathMissing", "No path available to open in editor")), V.current = setTimeout(() => {
156
+ L(null), V.current = null;
157
157
  }, 3e3);
158
158
  return;
159
159
  }
160
- let t = ve(e.id, vt, yt), n = _e(t), r = n ? ge(n, e.path) : `vscode://file/${e.path}`;
161
- r ? window.location.href = r : (R(x("vibesPage.openEditorNoProtocol", `${n?.label ?? t} has no URL handler — open this Vibe and use the editor menu.`)), H.current = setTimeout(() => {
162
- R(null), H.current = null;
160
+ let t = be(e.id, xt, St), n = ye(t), r = n ? ve(n, e.path) : `vscode://file/${e.path}`;
161
+ r ? window.location.href = r : (L(b("vibesPage.openEditorNoProtocol", `${n?.label ?? t} has no URL handler — open this Vibe and use the editor menu.`)), V.current = setTimeout(() => {
162
+ L(null), V.current = null;
163
163
  }, 4e3));
164
- }, xt = () => {
165
- M(null), A(!0), G();
166
- }, St = (e, t) => {
167
- B((n) => {
164
+ }, Ct = () => {
165
+ j(null), A(!0), W();
166
+ }, wt = (e, t) => {
167
+ z((n) => {
168
168
  let r = new Set(n);
169
169
  return t ? r.add(e.id) : r.delete(e.id), r;
170
170
  });
171
- }, Ct = (e) => {
172
- B((t) => {
171
+ }, Tt = (e) => {
172
+ z((t) => {
173
173
  let n = new Set(t);
174
- return q.forEach((t) => {
174
+ return K.forEach((t) => {
175
175
  e ? n.add(t.id) : n.delete(t.id);
176
176
  }), n;
177
177
  });
178
- }, Z = () => B(/* @__PURE__ */ new Set()), wt = async () => {
179
- if (J.length === 0) return;
180
- let e = await Promise.allSettled(J.map((e) => it({ variables: {
178
+ }, Z = () => z(/* @__PURE__ */ new Set()), Et = async () => {
179
+ if (q.length === 0) return;
180
+ let e = await Promise.allSettled(q.map((e) => st({ variables: {
181
181
  id: e.id,
182
182
  status: "ACTIVE"
183
183
  } }))), t = e.filter((e) => e.status === "fulfilled").length, n = e.length - t;
184
- P(`Activated ${t} vibe${t === 1 ? "" : "s"}${n > 0 ? ` • ${n} failed` : ""}`), setTimeout(() => P(null), 4e3), Z(), V(null), await W();
185
- }, Tt = async () => {
186
- if (Y.length === 0) return;
187
- let e = await Promise.allSettled(Y.map((e) => at({ variables: { id: e.id } }))), t = e.filter((e) => e.status === "fulfilled").length, n = e.length - t;
188
- P(`Archived ${t} vibe${t === 1 ? "" : "s"}${n > 0 ? ` • ${n} failed` : ""}`), setTimeout(() => P(null), 4e3), Z(), V(null), await W();
189
- }, Et = async () => {
190
- let e = Ze.current?.value?.trim(), t = Qe.current?.value?.trim(), n = $e.current?.value, r = et.current?.value, i = {};
191
- if (e || (i.name = x("vibesPage.nameRequired", "Name is required")), t || (i.path = x("vibesPage.pathRequired", "Path is required")), i.name || i.path) {
192
- L(i), M(x("vibesPage.fillRequired", "Please fill in all required fields"));
184
+ N(`Activated ${t} vibe${t === 1 ? "" : "s"}${n > 0 ? ` • ${n} failed` : ""}`), setTimeout(() => N(null), 4e3), Z(), B(null), await U();
185
+ }, Dt = async () => {
186
+ if (J.length === 0) return;
187
+ let e = await Promise.allSettled(J.map((e) => ct({ variables: { id: e.id } }))), t = e.filter((e) => e.status === "fulfilled").length, n = e.length - t;
188
+ N(`Archived ${t} vibe${t === 1 ? "" : "s"}${n > 0 ? ` • ${n} failed` : ""}`), setTimeout(() => N(null), 4e3), Z(), B(null), await U();
189
+ }, Ot = async () => {
190
+ let e = $e.current?.value?.trim(), t = et.current?.value?.trim(), n = tt.current?.value, r = nt.current?.value, i = {};
191
+ if (e || (i.name = b("vibesPage.nameRequired", "Name is required")), t || (i.path = b("vibesPage.pathRequired", "Path is required")), i.name || i.path) {
192
+ I(i), j(b("vibesPage.fillRequired", "Please fill in all required fields"));
193
193
  return;
194
194
  }
195
- L({});
195
+ I({});
196
196
  let ee = [
197
197
  "PROJECT",
198
198
  "REPOSITORY",
@@ -201,176 +201,178 @@ function h() {
201
201
  "PACKAGE",
202
202
  "CUSTOM"
203
203
  ].includes(r) ? r : "PROJECT";
204
- Ge(!0), M(null);
204
+ qe(!0), j(null);
205
205
  try {
206
- let r = await tt({ variables: { input: {
206
+ let r = await rt({ variables: { input: {
207
207
  name: e,
208
208
  path: t,
209
- type: ee,
210
- agentId: n || void 0
209
+ type: ee
211
210
  } } });
212
- if (!r.data?.createVibe?.id) throw Error(x("vibesPage.failedCreate", "Failed to create vibe"));
211
+ if (!r.data?.createVibe?.id) throw Error(b("vibesPage.failedCreate", "Failed to create vibe"));
213
212
  let i = r.data.createVibe.id;
214
- A(!1), P(x("vibesPage.createdSuccess", "Vibe created successfully")), await rt(i), await W(), setTimeout(() => P(null), 3e3);
213
+ n && await it({ variables: { input: {
214
+ vibeId: i,
215
+ agentId: n
216
+ } } }), A(!1), N(b("vibesPage.createdSuccess", "Vibe created successfully")), await ot(i), await U(), setTimeout(() => N(null), 3e3);
215
217
  } catch (e) {
216
- if (ce(e)) {
217
- A(!1), M(null), L({}), F(!0);
218
+ if (le(e)) {
219
+ A(!1), j(null), I({}), P(!0);
218
220
  return;
219
221
  }
220
- M(e instanceof Error ? e.message : x("vibesPage.failedCreate", "Failed to create vibe"));
222
+ j(e instanceof Error ? e.message : b("vibesPage.failedCreate", "Failed to create vibe"));
221
223
  } finally {
222
- Ge(!1);
224
+ qe(!1);
223
225
  }
224
- }, Dt = {
225
- total: K.length,
226
- active: K.filter((e) => e.status === "ACTIVE").length,
227
- inactive: K.filter((e) => e.status === "INACTIVE").length
228
- }, Q = v, $ = !v && !!y && (y.permissionStrings?.length ?? 0) > 0 && !S, Ot = !Q && !$ && U && K.length === 0, kt = !Q && !$ && !!st && K.length === 0, At = !Q && !$ && !kt;
229
- return /* @__PURE__ */ p(Pe, {
226
+ }, kt = {
227
+ total: G.length,
228
+ active: G.filter((e) => e.status === "ACTIVE").length,
229
+ inactive: G.filter((e) => e.status === "INACTIVE").length
230
+ }, Q = _, $ = !_ && !!v && (v.permissionStrings?.length ?? 0) > 0 && !x, At = !Q && !$ && H && G.length === 0, jt = !Q && !$ && !!ut && G.length === 0, Mt = !Q && !$ && !jt;
231
+ return /* @__PURE__ */ f(Ie, {
230
232
  className: "space-y-6 p-4 sm:p-6 bg-bg-surface min-h-screen",
231
233
  children: [
232
- Q && /* @__PURE__ */ f(ae, { message: x("vibesPage.loadingPermissions", "Loading permissions...") }),
233
- $ && /* @__PURE__ */ f(Fe, {
234
- title: x("vibesPage.accessDeniedTitle", "Access Denied"),
235
- description: x("vibesPage.accessDeniedDescription", "You don't have permission to view vibes. Contact your workspace administrator for access.")
234
+ Q && /* @__PURE__ */ d(oe, { message: b("vibesPage.loadingPermissions", "Loading permissions...") }),
235
+ $ && /* @__PURE__ */ d(Le, {
236
+ title: b("vibesPage.accessDeniedTitle", "Access Denied"),
237
+ description: b("vibesPage.accessDeniedDescription", "You don't have permission to view vibes. Contact your workspace administrator for access.")
236
238
  }),
237
- kt && /* @__PURE__ */ f(oe, {
238
- title: x("vibesPage.failedLoad", "Failed to load vibes"),
239
- message: st?.message ?? "",
240
- onRetry: () => W()
239
+ jt && /* @__PURE__ */ d(se, {
240
+ title: b("vibesPage.failedLoad", "Failed to load vibes"),
241
+ message: ut?.message ?? "",
242
+ onRetry: () => U()
241
243
  }),
242
- At && /* @__PURE__ */ p(Me, { children: [
243
- /* @__PURE__ */ f(ie, {
244
- title: x("vibesPage.title", "Vibes"),
245
- description: x("vibesPage.descriptionActive", "{{active}} of {{total}} vibes active", {
246
- active: Dt.active,
247
- total: Dt.total
244
+ Mt && /* @__PURE__ */ f(Pe, { children: [
245
+ /* @__PURE__ */ d(ae, {
246
+ title: b("vibesPage.title", "Vibes"),
247
+ description: b("vibesPage.descriptionActive", "{{active}} of {{total}} vibes active", {
248
+ active: kt.active,
249
+ total: kt.total
248
250
  }),
249
- actions: /* @__PURE__ */ p("div", {
251
+ actions: /* @__PURE__ */ f("div", {
250
252
  className: "flex items-center gap-2",
251
- children: [/* @__PURE__ */ f("button", {
252
- onClick: () => W(),
253
- disabled: U,
253
+ children: [/* @__PURE__ */ d("button", {
254
+ onClick: () => U(),
255
+ disabled: H,
254
256
  className: "flex items-center gap-2 px-3 py-2 text-text-secondary hover:bg-bg-sunken rounded-md transition-colors disabled:opacity-50",
255
- title: x("vibesPage.refreshTitle", "Refresh vibes"),
256
- children: /* @__PURE__ */ f(Oe, { className: `w-4 h-4 ${U ? "animate-spin" : ""}` })
257
- }), /* @__PURE__ */ f(Ie, {
258
- permission: s.VIBE_CREATE,
257
+ title: b("vibesPage.refreshTitle", "Refresh vibes"),
258
+ children: /* @__PURE__ */ d(Ae, { className: `w-4 h-4 ${H ? "animate-spin" : ""}` })
259
+ }), /* @__PURE__ */ d(Re, {
260
+ permission: o.VIBE_CREATE,
259
261
  deniedBehavior: "disable",
260
- deniedTooltip: x("vibesPage.deniedCreateTooltip", "You don't have permission to create vibes"),
261
- children: /* @__PURE__ */ p("button", {
262
- onClick: xt,
262
+ deniedTooltip: b("vibesPage.deniedCreateTooltip", "You don't have permission to create vibes"),
263
+ children: /* @__PURE__ */ f("button", {
264
+ onClick: Ct,
263
265
  className: "flex items-center gap-2 px-4 py-2 bg-action-primary-bg text-action-primary-text rounded-md hover:bg-action-primary-bg-hover transition-colors disabled:opacity-50 disabled:cursor-not-allowed",
264
- children: [/* @__PURE__ */ f(De, { className: "w-4 h-4" }), x("vibesPage.addVibe", "Add Vibe")]
266
+ children: [/* @__PURE__ */ d(ke, { className: "w-4 h-4" }), b("vibesPage.addVibe", "Add Vibe")]
265
267
  })
266
268
  })]
267
269
  })
268
270
  }),
269
- /* @__PURE__ */ p("div", {
271
+ /* @__PURE__ */ f("div", {
270
272
  className: "space-y-3",
271
- children: [/* @__PURE__ */ p("div", {
273
+ children: [/* @__PURE__ */ f("div", {
272
274
  className: "flex items-center gap-2",
273
- children: [/* @__PURE__ */ f(fe, {
274
- value: T,
275
- onChange: ze,
276
- placeholder: x("vibesPage.searchPlaceholder", "Search vibes..."),
275
+ children: [/* @__PURE__ */ d(pe, {
276
+ value: w,
277
+ onChange: Ve,
278
+ placeholder: b("vibesPage.searchPlaceholder", "Search vibes..."),
277
279
  className: "flex-1 sm:w-64 sm:flex-none"
278
- }), /* @__PURE__ */ p("div", {
280
+ }), /* @__PURE__ */ f("div", {
279
281
  className: "flex items-center gap-1 bg-bg-sunken rounded-md p-1 flex-shrink-0",
280
- children: [/* @__PURE__ */ f("button", {
281
- onClick: () => Ue("grid"),
282
- className: `p-1.5 sm:p-2 rounded ${k === "grid" ? "bg-bg-surface shadow-sm" : "hover:bg-bg-surface/50"}`,
283
- title: x("vibesPage.gridViewTitle", "Grid view"),
284
- children: /* @__PURE__ */ f(we, { className: "w-4 h-4 text-text-secondary" })
285
- }), /* @__PURE__ */ f("button", {
286
- onClick: () => Ue("list"),
287
- className: `p-1.5 sm:p-2 rounded ${k === "list" ? "bg-bg-surface shadow-sm" : "hover:bg-bg-surface/50"}`,
288
- title: x("vibesPage.listViewTitle", "List view"),
289
- children: /* @__PURE__ */ f(Te, { className: "w-4 h-4 text-text-secondary" })
282
+ children: [/* @__PURE__ */ d("button", {
283
+ onClick: () => k("grid"),
284
+ className: `p-1.5 sm:p-2 rounded ${O === "grid" ? "bg-bg-surface shadow-sm" : "hover:bg-bg-surface/50"}`,
285
+ title: b("vibesPage.gridViewTitle", "Grid view"),
286
+ children: /* @__PURE__ */ d(Ee, { className: "w-4 h-4 text-text-secondary" })
287
+ }), /* @__PURE__ */ d("button", {
288
+ onClick: () => k("list"),
289
+ className: `p-1.5 sm:p-2 rounded ${O === "list" ? "bg-bg-surface shadow-sm" : "hover:bg-bg-surface/50"}`,
290
+ title: b("vibesPage.listViewTitle", "List view"),
291
+ children: /* @__PURE__ */ d(De, { className: "w-4 h-4 text-text-secondary" })
290
292
  })]
291
293
  })]
292
- }), /* @__PURE__ */ p("div", {
294
+ }), /* @__PURE__ */ f("div", {
293
295
  className: "flex items-center gap-2 sm:gap-3 flex-wrap",
294
- children: [/* @__PURE__ */ f(o, {
295
- label: x("vibesPage.filterStatus", "Status"),
296
- value: E,
297
- options: Re,
298
- onChange: Be
299
- }), /* @__PURE__ */ f("div", {
300
- onMouseDown: G,
301
- onFocus: G,
302
- children: /* @__PURE__ */ f(o, {
303
- label: x("vibesPage.filterAgent", "Agent"),
304
- value: O,
305
- options: ft,
306
- onChange: He
296
+ children: [/* @__PURE__ */ d(me, {
297
+ label: b("vibesPage.filterStatus", "Status"),
298
+ value: T,
299
+ options: Be,
300
+ onChange: He
301
+ }), /* @__PURE__ */ d("div", {
302
+ onMouseDown: W,
303
+ onFocus: W,
304
+ children: /* @__PURE__ */ d(me, {
305
+ label: b("vibesPage.filterAgent", "Agent"),
306
+ value: D,
307
+ options: ht,
308
+ onChange: We
307
309
  })
308
310
  })]
309
311
  })]
310
312
  }),
311
- T || E !== "all" || D !== "all" || O !== "all" ? /* @__PURE__ */ p("p", {
313
+ w || T !== "all" || E !== "all" || D !== "all" ? /* @__PURE__ */ f("p", {
312
314
  className: "text-sm text-text-secondary",
313
- children: [x("vibesPage.showingResults", "Showing {{filtered}} of {{total}} vibes", {
314
- filtered: q.length,
315
- total: K.length
316
- }), U && /* @__PURE__ */ f("span", {
315
+ children: [b("vibesPage.showingResults", "Showing {{filtered}} of {{total}} vibes", {
316
+ filtered: K.length,
317
+ total: G.length
318
+ }), H && /* @__PURE__ */ d("span", {
317
319
  className: "ml-2 text-text-muted",
318
- children: x("vibesPage.refreshing", "(refreshing...)")
320
+ children: b("vibesPage.refreshing", "(refreshing...)")
319
321
  })]
320
322
  }) : null,
321
- q.length > 0 && /* @__PURE__ */ f("div", {
323
+ K.length > 0 && /* @__PURE__ */ d("div", {
322
324
  className: "rounded-lg border border-border-default bg-bg-surface p-4",
323
- children: /* @__PURE__ */ p("div", {
325
+ children: /* @__PURE__ */ f("div", {
324
326
  className: "flex flex-col gap-3 lg:flex-row lg:items-center lg:justify-between",
325
- children: [/* @__PURE__ */ p("div", {
327
+ children: [/* @__PURE__ */ f("div", {
326
328
  className: "flex flex-wrap items-center gap-3",
327
- children: [/* @__PURE__ */ p("div", {
329
+ children: [/* @__PURE__ */ f("div", {
328
330
  className: "flex items-center gap-2",
329
- children: [/* @__PURE__ */ f(me, {
330
- checked: X,
331
- indeterminate: mt,
332
- onChange: Ct,
331
+ children: [/* @__PURE__ */ d(ge, {
332
+ checked: Y,
333
+ indeterminate: _t,
334
+ onChange: Tt,
333
335
  ariaLabel: "Select all visible vibes"
334
- }), /* @__PURE__ */ f("span", {
336
+ }), /* @__PURE__ */ d("span", {
335
337
  className: "text-sm font-medium text-text-primary",
336
338
  children: "Select all visible"
337
339
  })]
338
- }), z.size > 0 && /* @__PURE__ */ f("button", {
340
+ }), R.size > 0 && /* @__PURE__ */ d("button", {
339
341
  onClick: Z,
340
342
  className: "text-sm text-text-secondary hover:text-text-primary",
341
343
  children: "Clear selection"
342
344
  })]
343
- }), /* @__PURE__ */ p("div", {
345
+ }), /* @__PURE__ */ f("div", {
344
346
  className: "flex flex-wrap items-center gap-2",
345
347
  children: [
346
- /* @__PURE__ */ p("span", {
348
+ /* @__PURE__ */ f("span", {
347
349
  className: "rounded-full bg-bg-sunken px-3 py-1 text-sm font-medium text-text-secondary",
348
- children: [z.size, " selected"]
350
+ children: [R.size, " selected"]
349
351
  }),
350
- /* @__PURE__ */ f("button", {
351
- onClick: () => V("activate"),
352
- disabled: J.length === 0,
352
+ /* @__PURE__ */ d("button", {
353
+ onClick: () => B("activate"),
354
+ disabled: q.length === 0,
353
355
  title: "Mark selected vibes as ACTIVE so they appear in the default vibe list and can run sessions/tunnels via their attached agent(s).",
354
356
  className: "rounded-md border border-status-success-border px-3 py-2 text-sm font-medium text-status-success-text hover:bg-status-success-bg disabled:cursor-not-allowed disabled:opacity-50",
355
- children: /* @__PURE__ */ p("span", {
357
+ children: /* @__PURE__ */ f("span", {
356
358
  className: "inline-flex items-center gap-2",
357
359
  children: [
358
- /* @__PURE__ */ f(Ee, { className: "w-4 h-4" }),
360
+ /* @__PURE__ */ d(Oe, { className: "w-4 h-4" }),
359
361
  "Activate Selected",
360
- J.length > 0 ? ` (${J.length})` : ""
362
+ q.length > 0 ? ` (${q.length})` : ""
361
363
  ]
362
364
  })
363
365
  }),
364
- /* @__PURE__ */ f("button", {
365
- onClick: () => V("archive"),
366
- disabled: Y.length === 0,
366
+ /* @__PURE__ */ d("button", {
367
+ onClick: () => B("archive"),
368
+ disabled: J.length === 0,
367
369
  className: "rounded-md border border-status-warning-border px-3 py-2 text-sm font-medium text-status-warning-text hover:bg-status-warning-bg disabled:cursor-not-allowed disabled:opacity-50",
368
- children: /* @__PURE__ */ p("span", {
370
+ children: /* @__PURE__ */ f("span", {
369
371
  className: "inline-flex items-center gap-2",
370
372
  children: [
371
- /* @__PURE__ */ f(Ce, { className: "w-4 h-4" }),
373
+ /* @__PURE__ */ d(Te, { className: "w-4 h-4" }),
372
374
  "Archive Selected",
373
- Y.length > 0 ? ` (${Y.length})` : ""
375
+ J.length > 0 ? ` (${J.length})` : ""
374
376
  ]
375
377
  })
376
378
  })
@@ -378,219 +380,219 @@ function h() {
378
380
  })]
379
381
  })
380
382
  }),
381
- Ot ? /* @__PURE__ */ f(he, {
383
+ At ? /* @__PURE__ */ d(_e, {
382
384
  variant: "cards",
383
385
  count: 6
384
- }) : q.length > 0 ? /* @__PURE__ */ f(je, {
386
+ }) : K.length > 0 ? /* @__PURE__ */ d(Ne, {
385
387
  mode: "wait",
386
- children: k === "grid" ? /* @__PURE__ */ f(m, {
388
+ children: O === "grid" ? /* @__PURE__ */ d(p, {
387
389
  stagger: .04,
388
390
  className: "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4",
389
- children: q.map((e) => /* @__PURE__ */ f(Ne, { children: /* @__PURE__ */ f(ye, {
391
+ children: K.map((e) => /* @__PURE__ */ d(Fe, { children: /* @__PURE__ */ d(xe, {
390
392
  vibe: e,
391
- onOpen: ht,
392
- onActivate: C ? gt : void 0,
393
- onArchive: C ? _t : void 0,
394
- onOpenInEditor: bt,
395
- selected: z.has(e.id),
396
- onToggleSelect: (t) => St(e, t)
393
+ onOpen: vt,
394
+ onActivate: S ? yt : void 0,
395
+ onArchive: S ? bt : void 0,
396
+ onOpenInEditor: X,
397
+ selected: R.has(e.id),
398
+ onToggleSelect: (t) => wt(e, t)
397
399
  }) }, e.id))
398
- }, "grid") : /* @__PURE__ */ f(m, { children: /* @__PURE__ */ f(be, {
399
- vibes: q,
400
- onOpen: ht,
401
- onActivate: gt,
402
- onArchive: _t,
403
- onOpenInEditor: bt,
404
- selectedVibeIds: z,
405
- onToggleSelect: St,
406
- onToggleAllVisible: Ct,
407
- allVisibleSelected: X,
408
- partiallySelected: mt
400
+ }, "grid") : /* @__PURE__ */ d(p, { children: /* @__PURE__ */ d(Se, {
401
+ vibes: K,
402
+ onOpen: vt,
403
+ onActivate: yt,
404
+ onArchive: bt,
405
+ onOpenInEditor: X,
406
+ selectedVibeIds: R,
407
+ onToggleSelect: wt,
408
+ onToggleAllVisible: Tt,
409
+ allVisibleSelected: Y,
410
+ partiallySelected: _t
409
411
  }) }, "list")
410
- }) : /* @__PURE__ */ f(de, {
411
- icon: /* @__PURE__ */ f(ke, { className: "w-8 h-8 text-text-secondary" }),
412
- title: T || E !== "all" || D !== "all" || O !== "all" ? x("vibesPage.emptyNoVibesFound", "No vibes found") : x("vibesPage.emptyNoVibesConfigured", "No vibes configured"),
413
- description: T || E !== "all" || D !== "all" || O !== "all" ? x("vibesPage.emptyAdjustSearch", "Try adjusting your search or filters") : x("vibesPage.emptyNoVibesDescription", "Add your first vibe to start managing your development projects"),
414
- action: !T && E === "all" && D === "all" && O === "all" ? /* @__PURE__ */ p("div", {
412
+ }) : /* @__PURE__ */ d(fe, {
413
+ icon: /* @__PURE__ */ d(je, { className: "w-8 h-8 text-text-secondary" }),
414
+ title: w || T !== "all" || E !== "all" || D !== "all" ? b("vibesPage.emptyNoVibesFound", "No vibes found") : b("vibesPage.emptyNoVibesConfigured", "No vibes configured"),
415
+ description: w || T !== "all" || E !== "all" || D !== "all" ? b("vibesPage.emptyAdjustSearch", "Try adjusting your search or filters") : b("vibesPage.emptyNoVibesDescription", "Add your first vibe to start managing your development projects"),
416
+ action: !w && T === "all" && E === "all" && D === "all" ? /* @__PURE__ */ f("div", {
415
417
  className: "flex items-center gap-2",
416
- children: [/* @__PURE__ */ f(Le, {
417
- permission: s.VIBE_CREATE,
418
- children: /* @__PURE__ */ p("button", {
419
- onClick: xt,
418
+ children: [/* @__PURE__ */ d(ze, {
419
+ permission: o.VIBE_CREATE,
420
+ children: /* @__PURE__ */ f("button", {
421
+ onClick: Ct,
420
422
  className: "flex items-center gap-2 px-4 py-2 bg-action-primary-bg text-action-primary-text rounded-md hover:bg-action-primary-bg-hover transition-colors",
421
- children: [/* @__PURE__ */ f(De, { className: "w-4 h-4" }), x("vibesPage.addVibe", "Add Vibe")]
423
+ children: [/* @__PURE__ */ d(ke, { className: "w-4 h-4" }), b("vibesPage.addVibe", "Add Vibe")]
422
424
  })
423
- }), /* @__PURE__ */ f(pe, { prompt: "What is a Vibe in VibeControls and how do I create one?" })]
425
+ }), /* @__PURE__ */ d(he, { prompt: "What is a Vibe in VibeControls and how do I create one?" })]
424
426
  }) : void 0
425
427
  }),
426
- Ke && /* @__PURE__ */ f("div", {
428
+ Je && /* @__PURE__ */ d("div", {
427
429
  className: "fixed bottom-4 right-4 z-50 px-4 py-3 bg-status-success-bg text-status-success-text rounded-md shadow-lg text-sm",
428
- children: Ke
430
+ children: Je
429
431
  }),
430
- /* @__PURE__ */ f(a, {
431
- isOpen: Ye === "activate",
432
- onClose: () => V(null),
433
- onConfirm: wt,
432
+ /* @__PURE__ */ d(a, {
433
+ isOpen: Ze === "activate",
434
+ onClose: () => B(null),
435
+ onConfirm: Et,
434
436
  title: "Activate selected vibes",
435
- message: `Activate ${J.length} selected vibe${J.length === 1 ? "" : "s"}?`,
437
+ message: `Activate ${q.length} selected vibe${q.length === 1 ? "" : "s"}?`,
436
438
  confirmLabel: "Activate",
437
439
  variant: "default"
438
440
  }),
439
- /* @__PURE__ */ f(a, {
440
- isOpen: Ye === "archive",
441
- onClose: () => V(null),
442
- onConfirm: Tt,
441
+ /* @__PURE__ */ d(a, {
442
+ isOpen: Ze === "archive",
443
+ onClose: () => B(null),
444
+ onConfirm: Dt,
443
445
  title: "Archive selected vibes",
444
- message: `Archive ${Y.length} selected vibe${Y.length === 1 ? "" : "s"}? Archived vibes will be hidden from active workflows.`,
446
+ message: `Archive ${J.length} selected vibe${J.length === 1 ? "" : "s"}? Archived vibes will be hidden from active workflows.`,
445
447
  confirmLabel: "Archive",
446
448
  variant: "warning"
447
449
  }),
448
- Je && /* @__PURE__ */ p("div", {
450
+ Xe && /* @__PURE__ */ f("div", {
449
451
  role: "alert",
450
452
  className: "fixed bottom-4 right-4 z-50 px-4 py-3 bg-status-error-bg text-status-error-text rounded-md shadow-lg text-sm",
451
- children: [Je, /* @__PURE__ */ f("button", {
452
- onClick: Xe,
453
+ children: [Xe, /* @__PURE__ */ d("button", {
454
+ onClick: Qe,
453
455
  className: "ml-3 text-xs underline opacity-80 hover:opacity-100",
454
- children: x("vibesPage.dismiss", "Dismiss")
456
+ children: b("vibesPage.dismiss", "Dismiss")
455
457
  })]
456
458
  }),
457
- We && /* @__PURE__ */ f("div", {
459
+ Ge && /* @__PURE__ */ d("div", {
458
460
  className: "fixed inset-0 bg-bg-overlay flex items-center justify-center z-50 p-4",
459
- children: /* @__PURE__ */ p("div", {
461
+ children: /* @__PURE__ */ f("div", {
460
462
  className: "bg-bg-surface rounded-lg p-6 w-full max-w-lg",
461
463
  children: [
462
- /* @__PURE__ */ f("h2", {
464
+ /* @__PURE__ */ d("h2", {
463
465
  className: "text-lg font-semibold text-text-primary mb-4",
464
- children: x("vibesPage.addNewVibe", "Add New Vibe")
466
+ children: b("vibesPage.addNewVibe", "Add New Vibe")
465
467
  }),
466
- /* @__PURE__ */ p("div", {
468
+ /* @__PURE__ */ f("div", {
467
469
  className: "space-y-4",
468
470
  children: [
469
- j && /* @__PURE__ */ f("div", {
471
+ Ke && /* @__PURE__ */ d("div", {
470
472
  className: "p-3 bg-status-error-bg text-status-error-text text-sm rounded-md",
471
- children: j
473
+ children: Ke
472
474
  }),
473
- /* @__PURE__ */ p("div", { children: [
474
- /* @__PURE__ */ f("label", {
475
+ /* @__PURE__ */ f("div", { children: [
476
+ /* @__PURE__ */ d("label", {
475
477
  className: "block text-sm font-medium text-text-primary mb-1",
476
- children: x("vibesPage.nameLabel", "Name *")
478
+ children: b("vibesPage.nameLabel", "Name *")
477
479
  }),
478
- /* @__PURE__ */ f("input", {
479
- ref: Ze,
480
+ /* @__PURE__ */ d("input", {
481
+ ref: $e,
480
482
  type: "text",
481
- placeholder: x("vibesPage.namePlaceholder", "My Project"),
482
- onChange: () => I.name && L((e) => ({
483
+ placeholder: b("vibesPage.namePlaceholder", "My Project"),
484
+ onChange: () => F.name && I((e) => ({
483
485
  ...e,
484
486
  name: void 0
485
487
  })),
486
- className: `w-full px-3 py-2 bg-bg-sunken border rounded-md text-text-primary placeholder:text-text-placeholder ${I.name ? "border-status-error-border" : "border-border-default"}`
488
+ className: `w-full px-3 py-2 bg-bg-sunken border rounded-md text-text-primary placeholder:text-text-placeholder ${F.name ? "border-status-error-border" : "border-border-default"}`
487
489
  }),
488
- I.name && /* @__PURE__ */ f("p", {
490
+ F.name && /* @__PURE__ */ d("p", {
489
491
  className: "mt-1 text-xs text-status-error-text",
490
- children: I.name
492
+ children: F.name
491
493
  })
492
494
  ] }),
493
- /* @__PURE__ */ p("div", { children: [
494
- /* @__PURE__ */ f("label", {
495
+ /* @__PURE__ */ f("div", { children: [
496
+ /* @__PURE__ */ d("label", {
495
497
  className: "block text-sm font-medium text-text-primary mb-1",
496
- children: x("vibesPage.pathLabel", "Path *")
498
+ children: b("vibesPage.pathLabel", "Path *")
497
499
  }),
498
- /* @__PURE__ */ f("input", {
499
- ref: Qe,
500
+ /* @__PURE__ */ d("input", {
501
+ ref: et,
500
502
  type: "text",
501
- placeholder: x("vibesPage.pathPlaceholder", "/path/to/project"),
502
- onChange: () => I.path && L((e) => ({
503
+ placeholder: b("vibesPage.pathPlaceholder", "/path/to/project"),
504
+ onChange: () => F.path && I((e) => ({
503
505
  ...e,
504
506
  path: void 0
505
507
  })),
506
- className: `w-full px-3 py-2 bg-bg-sunken border rounded-md text-text-primary placeholder:text-text-placeholder ${I.path ? "border-status-error-border" : "border-border-default"}`
508
+ className: `w-full px-3 py-2 bg-bg-sunken border rounded-md text-text-primary placeholder:text-text-placeholder ${F.path ? "border-status-error-border" : "border-border-default"}`
507
509
  }),
508
- I.path && /* @__PURE__ */ f("p", {
510
+ F.path && /* @__PURE__ */ d("p", {
509
511
  className: "mt-1 text-xs text-status-error-text",
510
- children: I.path
512
+ children: F.path
511
513
  })
512
514
  ] }),
513
- /* @__PURE__ */ p("div", { children: [/* @__PURE__ */ f("label", {
515
+ /* @__PURE__ */ f("div", { children: [/* @__PURE__ */ d("label", {
514
516
  className: "block text-sm font-medium text-text-primary mb-1",
515
- children: x("vibesPage.agentLabel", "Agent")
516
- }), /* @__PURE__ */ p("select", {
517
- ref: $e,
517
+ children: b("vibesPage.agentLabel", "Agent")
518
+ }), /* @__PURE__ */ f("select", {
519
+ ref: tt,
518
520
  className: "w-full px-3 py-2 bg-bg-sunken border border-border-default rounded-md text-text-primary",
519
- children: [/* @__PURE__ */ f("option", {
521
+ children: [/* @__PURE__ */ d("option", {
520
522
  value: "",
521
- children: x("vibesPage.selectAgent", "Select an agent")
522
- }), ft.filter((e) => e.value !== "all").map((e) => /* @__PURE__ */ f("option", {
523
+ children: b("vibesPage.selectAgent", "Select an agent")
524
+ }), ht.filter((e) => e.value !== "all").map((e) => /* @__PURE__ */ d("option", {
523
525
  value: e.value,
524
526
  children: e.label
525
527
  }, e.value))]
526
528
  })] }),
527
- /* @__PURE__ */ p("div", { children: [/* @__PURE__ */ f("label", {
529
+ /* @__PURE__ */ f("div", { children: [/* @__PURE__ */ d("label", {
528
530
  className: "block text-sm font-medium text-text-primary mb-1",
529
- children: x("vibesPage.typeLabel", "Type")
530
- }), /* @__PURE__ */ p("select", {
531
- ref: et,
531
+ children: b("vibesPage.typeLabel", "Type")
532
+ }), /* @__PURE__ */ f("select", {
533
+ ref: nt,
532
534
  className: "w-full px-3 py-2 bg-bg-sunken border border-border-default rounded-md text-text-primary",
533
535
  children: [
534
- /* @__PURE__ */ f("option", {
536
+ /* @__PURE__ */ d("option", {
535
537
  value: "PROJECT",
536
- children: x("vibesPage.typeProject", "Project")
538
+ children: b("vibesPage.typeProject", "Project")
537
539
  }),
538
- /* @__PURE__ */ f("option", {
540
+ /* @__PURE__ */ d("option", {
539
541
  value: "REPOSITORY",
540
- children: x("vibesPage.typeRepository", "Repository")
542
+ children: b("vibesPage.typeRepository", "Repository")
541
543
  }),
542
- /* @__PURE__ */ f("option", {
544
+ /* @__PURE__ */ d("option", {
543
545
  value: "WORKSPACE",
544
- children: x("vibesPage.typeWorkspace", "Workspace")
546
+ children: b("vibesPage.typeWorkspace", "Workspace")
545
547
  }),
546
- /* @__PURE__ */ f("option", {
548
+ /* @__PURE__ */ d("option", {
547
549
  value: "MONOREPO",
548
- children: x("vibesPage.typeMonorepo", "Monorepo")
550
+ children: b("vibesPage.typeMonorepo", "Monorepo")
549
551
  }),
550
- /* @__PURE__ */ f("option", {
552
+ /* @__PURE__ */ d("option", {
551
553
  value: "PACKAGE",
552
- children: x("vibesPage.typePackage", "Package")
554
+ children: b("vibesPage.typePackage", "Package")
553
555
  }),
554
- /* @__PURE__ */ f("option", {
556
+ /* @__PURE__ */ d("option", {
555
557
  value: "CUSTOM",
556
- children: x("vibesPage.typeCustom", "Custom")
558
+ children: b("vibesPage.typeCustom", "Custom")
557
559
  })
558
560
  ]
559
561
  })] })
560
562
  ]
561
563
  }),
562
- /* @__PURE__ */ p("div", {
564
+ /* @__PURE__ */ f("div", {
563
565
  className: "mt-4 border-t border-border-default pt-4",
564
- children: [/* @__PURE__ */ f("h3", {
566
+ children: [/* @__PURE__ */ d("h3", {
565
567
  className: "text-sm font-medium text-text-secondary mb-2",
566
- children: x("vibesPage.tags", "Tags")
567
- }), /* @__PURE__ */ f(le, {
568
+ children: b("vibesPage.tags", "Tags")
569
+ }), /* @__PURE__ */ d(ue, {
568
570
  entityType: "VIBECONTROLS_VIBE",
569
- onDraftChange: nt
571
+ onDraftChange: at
570
572
  })]
571
573
  }),
572
- /* @__PURE__ */ p("div", {
574
+ /* @__PURE__ */ f("div", {
573
575
  className: "flex flex-col sm:flex-row justify-end gap-3 mt-6",
574
- children: [/* @__PURE__ */ f("button", {
576
+ children: [/* @__PURE__ */ d("button", {
575
577
  onClick: () => A(!1),
576
- disabled: N,
578
+ disabled: M,
577
579
  className: "px-4 py-2 text-text-primary hover:bg-bg-sunken rounded-md transition-colors disabled:opacity-50",
578
- children: x("vibesPage.cancel", "Cancel")
579
- }), /* @__PURE__ */ f("button", {
580
- onClick: Et,
581
- disabled: N,
580
+ children: b("vibesPage.cancel", "Cancel")
581
+ }), /* @__PURE__ */ d("button", {
582
+ onClick: Ot,
583
+ disabled: M,
582
584
  className: "px-4 py-2 bg-action-primary-bg text-action-primary-text rounded-md hover:bg-action-primary-bg-hover transition-colors disabled:opacity-50",
583
- children: N ? x("vibesPage.creating", "Creating...") : x("vibesPage.createVibe", "Create Vibe")
585
+ children: M ? b("vibesPage.creating", "Creating...") : b("vibesPage.createVibe", "Create Vibe")
584
586
  })]
585
587
  })
586
588
  ]
587
589
  })
588
590
  }),
589
- /* @__PURE__ */ f(se, {
590
- isOpen: qe,
591
- onClose: () => F(!1),
591
+ /* @__PURE__ */ d(ce, {
592
+ isOpen: Ye,
593
+ onClose: () => P(!1),
592
594
  onConfirm: () => {
593
- F(!1), g("/billing");
595
+ P(!1), h("/billing");
594
596
  },
595
597
  title: "Vibe Quota Reached",
596
598
  message: "You've used all available vibe creation quota on your current plan. Upgrade your plan to create more vibes."
@@ -600,6 +602,6 @@ function h() {
600
602
  });
601
603
  }
602
604
  //#endregion
603
- export { h as VibesPage };
605
+ export { m as VibesPage };
604
606
 
605
607
  //# sourceMappingURL=VibesPage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"VibesPage.js","names":[],"sources":["../../src/pages/VibesPage.tsx"],"sourcesContent":["import { useState, useMemo, useRef, useEffect, useCallback } from 'react';\nimport { Plus, Zap, Grid, List, RefreshCw, Archive, Play } from 'lucide-react';\nimport { VibeCard, VibeList } from '@/components/vibes';\nimport type { Vibe } from '@/components/vibes';\nimport { EntityTagPicker } from '@/components/shared/EntityTagPicker';\nimport { PageSkeleton } from '@/components/shared/PageSkeleton';\nimport { useDraftEntityTags } from '@/hooks/useDraftEntityTags';\nimport {\n PageHeader,\n SearchInput,\n FilterDropdown,\n EmptyState,\n LoadingState,\n ErrorState,\n ConfirmDialog,\n QuotaExhaustedDialog,\n SelectionCheckbox,\n GetHelpButton,\n} from '@/components/shared';\nimport { MotionPage, MotionList, MotionItem } from '@burdenoff/fe-libs/shared/motion';\nimport { AnimatePresence } from 'framer-motion';\nimport { useVibeControls, useVibeNavigate } from '@/providers/VibeControlsProvider';\nimport {\n useListVibesQuery,\n useCreateVibeMutation,\n useUpdateVibeStatusMutation,\n useArchiveVibeMutation,\n useListAgentsLazyQuery,\n type ListAgentsQuery,\n} from '@/generated/wspace-operations';\nimport { useCachedInitialData } from '@/hooks/useCachedInitialData';\n\ntype Agent = NonNullable<ListAgentsQuery['vibecontrolsAgents']>[number];\nimport {\n PermissionGate,\n PermissionButton,\n AccessDenied,\n} from '@burdenoff/fe-libs/shared/components';\nimport { usePermissions } from '@burdenoff/fe-libs/shared/providers/shell';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { VIBE_PERMISSIONS } from '@/constants/permissions';\nimport { isQuotaExhaustedError } from '@/utils/quotaUtils';\nimport {\n buildProtocolUrl,\n getIdePreset,\n resolveEffectiveIdeCommand,\n} from '@/components/agents/idePresets';\nimport { useVibeControlsStore } from '@/store/vibeControlsStore';\n\ntype ViewMode = 'grid' | 'list';\n\n/**\n * Vibes (projects/repositories) management page\n */\nexport function VibesPage() {\n const { onVibeActivate } = useVibeControls();\n const navigate = useVibeNavigate();\n const { hasPermission, isLoading: permissionsLoading, permissions } = usePermissions();\n const { t } = useI18n();\n\n const tr = useCallback(\n (key: string, fallback: string, params?: Record<string, string | number>): string => {\n const translated = t(key, params);\n const template = translated === key ? fallback : translated;\n\n if (!params) return template;\n\n return Object.entries(params).reduce(\n (acc, [paramKey, paramValue]) => acc.replace(`{{${paramKey}}}`, String(paramValue)),\n template\n );\n },\n [t]\n );\n\n const statusOptions = [\n { value: 'all', label: tr('vibesPage.statusAll', 'All Statuses') },\n { value: 'ACTIVE', label: tr('vibesPage.statusActive', 'Active') },\n { value: 'INACTIVE', label: tr('vibesPage.statusInactive', 'Inactive') },\n { value: 'ARCHIVED', label: tr('vibesPage.statusArchived', 'Archived') },\n { value: 'ERROR', label: tr('vibesPage.statusError', 'Error') },\n ];\n\n const typeOptions = [\n { value: 'all', label: tr('vibesPage.typeAll', 'All Types') },\n { value: 'PROJECT', label: tr('vibesPage.typeProject', 'Project') },\n { value: 'REPOSITORY', label: tr('vibesPage.typeRepository', 'Repository') },\n { value: 'WORKSPACE', label: tr('vibesPage.typeWorkspace', 'Workspace') },\n { value: 'MONOREPO', label: tr('vibesPage.typeMonorepo', 'Monorepo') },\n { value: 'PACKAGE', label: tr('vibesPage.typePackage', 'Package') },\n { value: 'CUSTOM', label: tr('vibesPage.typeCustom', 'Custom') },\n ];\n\n // Check permissions\n const canListVibes = hasPermission(VIBE_PERMISSIONS.VIBE_LIST);\n const canUpdateVibe = hasPermission(VIBE_PERMISSIONS.VIBE_UPDATE);\n\n // Skip queries until permissions are loaded and user has permission\n // This prevents FORBIDDEN errors from triggering auth error handlers\n const shouldSkipQueries = permissionsLoading || !canListVibes;\n\n const [searchQuery, setSearchQuery] = useState('');\n const [statusFilter, setStatusFilter] = useState('all');\n const [typeFilter, setTypeFilter] = useState('all');\n const [agentFilter, setAgentFilter] = useState('all');\n const [viewMode, setViewMode] = useState<ViewMode>('grid');\n const [showCreateForm, setShowCreateForm] = useState(false);\n const [createError, setCreateError] = useState<string | null>(null);\n const [createLoading, setCreateLoading] = useState(false);\n const [successMessage, setSuccessMessage] = useState<string | null>(null);\n const [showQuotaExhausted, setShowQuotaExhausted] = useState(false);\n const [fieldErrors, setFieldErrors] = useState<{ name?: string; path?: string }>({});\n const [pageError, setPageError] = useState<string | null>(null);\n const [selectedVibeIds, setSelectedVibeIds] = useState<Set<string>>(new Set());\n const [bulkAction, setBulkAction] = useState<'activate' | 'archive' | null>(null);\n const pageErrorTimer = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n useEffect(() => {\n return () => {\n if (pageErrorTimer.current) clearTimeout(pageErrorTimer.current);\n };\n }, []);\n\n const clearPageError = useCallback(() => {\n setPageError(null);\n if (pageErrorTimer.current) {\n clearTimeout(pageErrorTimer.current);\n pageErrorTimer.current = null;\n }\n }, []);\n\n // Form refs for create modal\n const nameRef = useRef<HTMLInputElement>(null);\n const pathRef = useRef<HTMLInputElement>(null);\n const agentRef = useRef<HTMLSelectElement>(null);\n const typeRef = useRef<HTMLSelectElement>(null);\n\n const [createVibe] = useCreateVibeMutation();\n const { setDraftTagIds, flushTags } = useDraftEntityTags('VIBECONTROLS_VIBE');\n const [updateVibeStatus] = useUpdateVibeStatusMutation();\n const [archiveVibe] = useArchiveVibeMutation();\n\n // Memoise variables so a stable identity keeps Apollo from treating each\n // render as a new query (which caused multiple loading flashes).\n // NOTE: we intentionally do NOT include `searchQuery` in the query\n // variables — the list is filtered client-side by name below, and keying\n // the query on `searchQuery` caused a fresh refetch on every keystroke\n // (previously mitigated by an unusable `limit: 1000` fire-hose). Rely on\n // the default backend pagination and filter client-side within the page.\n const listVibesVariables = useMemo(\n () => ({\n filter: {\n status:\n statusFilter !== 'all'\n ? (statusFilter as 'ACTIVE' | 'INACTIVE' | 'ARCHIVED' | 'ERROR')\n : undefined,\n type:\n typeFilter !== 'all'\n ? (typeFilter as\n | 'PROJECT'\n | 'REPOSITORY'\n | 'WORKSPACE'\n | 'MONOREPO'\n | 'PACKAGE'\n | 'CUSTOM')\n : undefined,\n // Multi-agent: server-side filter takes a list. Single-select UI maps\n // to a one-element array; \"all\" clears the filter.\n attachedAgentIds: agentFilter !== 'all' ? [agentFilter] : undefined,\n },\n }),\n [statusFilter, typeFilter, agentFilter]\n );\n\n // When no filters are applied, the variables match the InitialData\n // prefetch (no filters) — use cache-first to avoid a redundant network\n // hit on every page visit. When user actually narrows by filter, fall\n // back to cache-and-network for fresh server-side filtering.\n const noVibeFilters = statusFilter === 'all' && typeFilter === 'all' && agentFilter === 'all';\n const vibesFetchPolicy = noVibeFilters ? 'cache-first' : 'cache-and-network';\n\n // Fetch vibes from GraphQL API. cache-and-network returns the cached list\n // immediately while revalidating once in the background — avoids the\n // \"loading → cache → network → cache\" double-flash seen with cache-first\n // plus mutation refetchQueries. `notifyOnNetworkStatusChange` keeps the\n // loading flag true during refetches so the UI can show a spinner rather\n // than showing stale data silently.\n const { data, loading, error, refetch } = useListVibesQuery({\n variables: listVibesVariables,\n fetchPolicy: vibesFetchPolicy,\n nextFetchPolicy: 'cache-first',\n skip: shouldSkipQueries,\n notifyOnNetworkStatusChange: true,\n });\n\n // Cached agents (already prefetched by InitialDataPrefetcher) cover the\n // initial agent-filter dropdown without firing any network query. The\n // lazy ListAgentsQuery below is only triggered on first interaction with\n // the agent filter (in case the prefetch was stale).\n const { agents: cachedAgentsForFilter } = useCachedInitialData();\n const [fetchAgents, { data: agentsData }] = useListAgentsLazyQuery({\n fetchPolicy: 'cache-first',\n });\n const triggeredAgentsFetchRef = useRef(false);\n const handleAgentFilterInteract = useCallback(() => {\n if (triggeredAgentsFetchRef.current || shouldSkipQueries) return;\n triggeredAgentsFetchRef.current = true;\n void fetchAgents({ variables: { pagination: { limit: 100 } } });\n }, [fetchAgents, shouldSkipQueries]);\n\n // Build agent options for filter — prefer freshly-fetched data once the\n // dropdown has been opened, otherwise use the cached set from\n // InitialDataPrefetcher.\n const agentOptions = useMemo(() => {\n const live = agentsData?.vibecontrolsAgents ?? null;\n const source: Array<{ id: string; name: string }> = live\n ? live.map((a: Agent) => ({ id: a.id, name: a.name }))\n : cachedAgentsForFilter.map((a) => ({ id: a.id, name: a.name }));\n return [\n { value: 'all', label: tr('vibesPage.allAgents', 'All Agents') },\n ...source.map((agent) => ({\n value: agent.id,\n label: agent.name,\n })),\n ];\n }, [agentsData?.vibecontrolsAgents, cachedAgentsForFilter, tr]);\n\n // Map GraphQL response to Vibe type\n const vibes: Vibe[] = useMemo(() => {\n const rawVibes = data?.vibes?.items ?? [];\n return rawVibes.map((vibe: NonNullable<typeof rawVibes>[number]) => ({\n id: vibe.id,\n workspaceId: vibe.workspaceId,\n name: vibe.name,\n description: vibe.description || null,\n type: vibe.type as Vibe['type'],\n status: vibe.status as Vibe['status'],\n path: vibe.path || null,\n parentId: vibe.parentId || null,\n gitBranch: vibe.gitBranch || null,\n gitRemote: vibe.gitRemote || null,\n gitStatus: vibe.gitStatus\n ? typeof vibe.gitStatus === 'string'\n ? vibe.gitStatus\n : typeof vibe.gitStatus === 'object' &&\n vibe.gitStatus !== null &&\n 'status' in vibe.gitStatus\n ? String((vibe.gitStatus as Record<string, unknown>).status)\n : JSON.stringify(vibe.gitStatus)\n : null,\n environmentVariables: (vibe.environmentVariables as Record<string, string>) || {},\n tags: vibe.tags || [],\n metadata: (vibe.metadata as Record<string, unknown>) || {},\n createdAt: vibe.createdAt,\n updatedAt: vibe.updatedAt,\n agents: (vibe.agents ?? []).map((a: NonNullable<typeof vibe.agents>[number]) => ({\n id: a.id,\n name: a.name,\n isActive: a.isActive,\n ownerUserId: a.ownerUserId ?? null,\n })),\n }));\n }, [data?.vibes?.items]);\n\n // Filter vibes based on search (client-side filtering for search)\n const filteredVibes = useMemo(() => {\n return vibes.filter((vibe) => {\n // Search filter\n if (searchQuery) {\n const query = searchQuery.toLowerCase();\n const matchesSearch =\n vibe.name.toLowerCase().includes(query) ||\n vibe.description?.toLowerCase().includes(query) ||\n vibe.path?.toLowerCase().includes(query) ||\n vibe.tags?.some((tag) => tag.toLowerCase().includes(query));\n if (!matchesSearch) return false;\n }\n\n return true;\n });\n }, [vibes, searchQuery]);\n\n const selectedVibes = useMemo(\n () => vibes.filter((vibe) => selectedVibeIds.has(vibe.id)),\n [vibes, selectedVibeIds]\n );\n const activatableVibes = selectedVibes.filter((vibe) => vibe.status !== 'ACTIVE');\n const archivableVibes = selectedVibes.filter((vibe) => vibe.status !== 'ARCHIVED');\n const allVisibleSelected =\n filteredVibes.length > 0 && filteredVibes.every((vibe) => selectedVibeIds.has(vibe.id));\n const partiallySelected =\n filteredVibes.some((vibe) => selectedVibeIds.has(vibe.id)) && !allVisibleSelected;\n\n const handleVibeSelect = (vibe: Vibe) => {\n navigate(`/vibes/${vibe.id}`);\n };\n\n const handleVibeActivate = async (vibe: Vibe) => {\n try {\n const result = await updateVibeStatus({\n variables: { id: vibe.id, status: 'ACTIVE' as const },\n });\n if (result.data?.updateVibeStatus) {\n onVibeActivate?.({ id: vibe.id, name: vibe.name, type: vibe.type, status: 'ACTIVE' });\n }\n } catch (err) {\n console.error('Failed to activate vibe:', err);\n }\n };\n\n const handleVibeArchive = async (vibe: Vibe) => {\n try {\n await archiveVibe({ variables: { id: vibe.id } });\n } catch (err) {\n console.error('Failed to archive vibe:', err);\n }\n };\n\n // Honour the user's preferred IDE + per-Vibe override when opening from\n // the card. Falls back to `vscode://` for IDEs without a registered URL\n // protocol; for richer launching (agent-exec, browser editor) use the\n // VibeOpenInEditorMenu on the Vibe detail page.\n const preferredIdeCommand = useVibeControlsStore((s) => s.preferredIdeCommand);\n const vibeIdeOverrides = useVibeControlsStore((s) => s.vibeIdeOverrides);\n\n const handleOpenInEditor = (vibe: Vibe) => {\n if (!vibe.path) {\n setPageError(tr('vibesPage.openEditorPathMissing', 'No path available to open in editor'));\n pageErrorTimer.current = setTimeout(() => {\n setPageError(null);\n pageErrorTimer.current = null;\n }, 3000);\n return;\n }\n const cmd = resolveEffectiveIdeCommand(vibe.id, preferredIdeCommand, vibeIdeOverrides);\n const preset = getIdePreset(cmd);\n const url = preset ? buildProtocolUrl(preset, vibe.path) : `vscode://file/${vibe.path}`;\n if (url) {\n window.location.href = url;\n } else {\n setPageError(\n tr(\n 'vibesPage.openEditorNoProtocol',\n `${preset?.label ?? cmd} has no URL handler — open this Vibe and use the editor menu.`\n )\n );\n pageErrorTimer.current = setTimeout(() => {\n setPageError(null);\n pageErrorTimer.current = null;\n }, 4000);\n }\n };\n\n const handleCreateVibe = () => {\n setCreateError(null);\n setShowCreateForm(true);\n // Ensure the create-form agent dropdown has options even if the user\n // never opened the page-level agent filter.\n handleAgentFilterInteract();\n };\n\n const toggleVibeSelection = (vibe: Vibe, checked: boolean) => {\n setSelectedVibeIds((prev) => {\n const next = new Set(prev);\n if (checked) {\n next.add(vibe.id);\n } else {\n next.delete(vibe.id);\n }\n return next;\n });\n };\n\n const toggleAllVisibleVibes = (checked: boolean) => {\n setSelectedVibeIds((prev) => {\n const next = new Set(prev);\n filteredVibes.forEach((vibe) => {\n if (checked) {\n next.add(vibe.id);\n } else {\n next.delete(vibe.id);\n }\n });\n return next;\n });\n };\n\n const clearSelection = () => setSelectedVibeIds(new Set());\n\n const handleBulkActivate = async () => {\n if (activatableVibes.length === 0) return;\n\n const results = await Promise.allSettled(\n activatableVibes.map((vibe) =>\n updateVibeStatus({ variables: { id: vibe.id, status: 'ACTIVE' as const } })\n )\n );\n\n const succeeded = results.filter((result) => result.status === 'fulfilled').length;\n const failed = results.length - succeeded;\n\n setSuccessMessage(\n `Activated ${succeeded} vibe${succeeded === 1 ? '' : 's'}${failed > 0 ? ` • ${failed} failed` : ''}`\n );\n setTimeout(() => setSuccessMessage(null), 4000);\n clearSelection();\n setBulkAction(null);\n await refetch();\n };\n\n const handleBulkArchive = async () => {\n if (archivableVibes.length === 0) return;\n\n const results = await Promise.allSettled(\n archivableVibes.map((vibe) => archiveVibe({ variables: { id: vibe.id } }))\n );\n\n const succeeded = results.filter((result) => result.status === 'fulfilled').length;\n const failed = results.length - succeeded;\n\n setSuccessMessage(\n `Archived ${succeeded} vibe${succeeded === 1 ? '' : 's'}${failed > 0 ? ` • ${failed} failed` : ''}`\n );\n setTimeout(() => setSuccessMessage(null), 4000);\n clearSelection();\n setBulkAction(null);\n await refetch();\n };\n\n const handleSubmitCreateVibe = async () => {\n const name = nameRef.current?.value?.trim();\n const path = pathRef.current?.value?.trim();\n const agentId = agentRef.current?.value;\n const type = typeRef.current?.value;\n\n const errors: { name?: string; path?: string } = {};\n if (!name) errors.name = tr('vibesPage.nameRequired', 'Name is required');\n if (!path) errors.path = tr('vibesPage.pathRequired', 'Path is required');\n if (errors.name || errors.path) {\n setFieldErrors(errors);\n setCreateError(tr('vibesPage.fillRequired', 'Please fill in all required fields'));\n return;\n }\n setFieldErrors({});\n\n // Validate type against allowed enum values\n const validTypes = [\n 'PROJECT',\n 'REPOSITORY',\n 'WORKSPACE',\n 'MONOREPO',\n 'PACKAGE',\n 'CUSTOM',\n ] as const;\n const resolvedType = validTypes.includes(type as (typeof validTypes)[number])\n ? (type as (typeof validTypes)[number])\n : 'PROJECT';\n\n setCreateLoading(true);\n setCreateError(null);\n try {\n const result = await createVibe({\n variables: {\n input: {\n name,\n path,\n type: resolvedType,\n agentId: agentId || undefined,\n },\n },\n });\n if (!result.data?.createVibe?.id) {\n throw new Error(tr('vibesPage.failedCreate', 'Failed to create vibe'));\n }\n const newVibeId = result.data.createVibe.id;\n setShowCreateForm(false);\n setSuccessMessage(tr('vibesPage.createdSuccess', 'Vibe created successfully'));\n await flushTags(newVibeId);\n await refetch();\n setTimeout(() => setSuccessMessage(null), 3000);\n } catch (err) {\n if (isQuotaExhaustedError(err)) {\n setShowCreateForm(false);\n setCreateError(null);\n setFieldErrors({});\n setShowQuotaExhausted(true);\n return;\n }\n\n setCreateError(\n err instanceof Error ? err.message : tr('vibesPage.failedCreate', 'Failed to create vibe')\n );\n } finally {\n setCreateLoading(false);\n }\n };\n\n // Stats\n const stats = {\n total: vibes.length,\n active: vibes.filter((v) => v.status === 'ACTIVE').length,\n inactive: vibes.filter((v) => v.status === 'INACTIVE').length,\n };\n\n // Collapse guard states into a single MotionPage shell so transitioning\n // between loading / error / data does not unmount+remount and replay the\n // entrance animation. Contents are swapped in-place.\n const showPermissionsLoading = permissionsLoading;\n const showAccessDenied =\n !permissionsLoading &&\n !!permissions &&\n (permissions.permissionStrings?.length ?? 0) > 0 &&\n !canListVibes;\n const showInitialLoading =\n !showPermissionsLoading && !showAccessDenied && loading && vibes.length === 0;\n const showInitialError =\n !showPermissionsLoading && !showAccessDenied && !!error && vibes.length === 0;\n const showDataShell = !showPermissionsLoading && !showAccessDenied && !showInitialError;\n\n return (\n <MotionPage className=\"space-y-6 p-4 sm:p-6 bg-bg-surface min-h-screen\">\n {showPermissionsLoading && (\n <LoadingState message={tr('vibesPage.loadingPermissions', 'Loading permissions...')} />\n )}\n {showAccessDenied && (\n <AccessDenied\n title={tr('vibesPage.accessDeniedTitle', 'Access Denied')}\n description={tr(\n 'vibesPage.accessDeniedDescription',\n \"You don't have permission to view vibes. Contact your workspace administrator for access.\"\n )}\n />\n )}\n {showInitialError && (\n <ErrorState\n title={tr('vibesPage.failedLoad', 'Failed to load vibes')}\n message={error?.message ?? ''}\n onRetry={() => refetch()}\n />\n )}\n {showDataShell && (\n <>\n <PageHeader\n title={tr('vibesPage.title', 'Vibes')}\n description={tr('vibesPage.descriptionActive', '{{active}} of {{total}} vibes active', {\n active: stats.active,\n total: stats.total,\n })}\n actions={\n <div className=\"flex items-center gap-2\">\n <button\n onClick={() => refetch()}\n disabled={loading}\n className=\"flex items-center gap-2 px-3 py-2 text-text-secondary hover:bg-bg-sunken rounded-md transition-colors disabled:opacity-50\"\n title={tr('vibesPage.refreshTitle', 'Refresh vibes')}\n >\n <RefreshCw className={`w-4 h-4 ${loading ? 'animate-spin' : ''}`} />\n </button>\n <PermissionButton\n permission={VIBE_PERMISSIONS.VIBE_CREATE}\n deniedBehavior=\"disable\"\n deniedTooltip={tr(\n 'vibesPage.deniedCreateTooltip',\n \"You don't have permission to create vibes\"\n )}\n >\n <button\n onClick={handleCreateVibe}\n className=\"flex items-center gap-2 px-4 py-2 bg-action-primary-bg text-action-primary-text rounded-md hover:bg-action-primary-bg-hover transition-colors disabled:opacity-50 disabled:cursor-not-allowed\"\n >\n <Plus className=\"w-4 h-4\" />\n {tr('vibesPage.addVibe', 'Add Vibe')}\n </button>\n </PermissionButton>\n </div>\n }\n />\n\n {/* Filters Bar */}\n <div className=\"space-y-3\">\n {/* Row 1: Search + View Toggle */}\n <div className=\"flex items-center gap-2\">\n <SearchInput\n value={searchQuery}\n onChange={setSearchQuery}\n placeholder={tr('vibesPage.searchPlaceholder', 'Search vibes...')}\n className=\"flex-1 sm:w-64 sm:flex-none\"\n />\n {/* View Toggle */}\n <div className=\"flex items-center gap-1 bg-bg-sunken rounded-md p-1 flex-shrink-0\">\n <button\n onClick={() => setViewMode('grid')}\n className={`p-1.5 sm:p-2 rounded ${viewMode === 'grid' ? 'bg-bg-surface shadow-sm' : 'hover:bg-bg-surface/50'}`}\n title={tr('vibesPage.gridViewTitle', 'Grid view')}\n >\n <Grid className=\"w-4 h-4 text-text-secondary\" />\n </button>\n <button\n onClick={() => setViewMode('list')}\n className={`p-1.5 sm:p-2 rounded ${viewMode === 'list' ? 'bg-bg-surface shadow-sm' : 'hover:bg-bg-surface/50'}`}\n title={tr('vibesPage.listViewTitle', 'List view')}\n >\n <List className=\"w-4 h-4 text-text-secondary\" />\n </button>\n </div>\n </div>\n\n {/* Row 2: Filters - wrap on all screens */}\n <div className=\"flex items-center gap-2 sm:gap-3 flex-wrap\">\n <FilterDropdown\n label={tr('vibesPage.filterStatus', 'Status')}\n value={statusFilter}\n options={statusOptions}\n onChange={setStatusFilter}\n />\n <div onMouseDown={handleAgentFilterInteract} onFocus={handleAgentFilterInteract}>\n <FilterDropdown\n label={tr('vibesPage.filterAgent', 'Agent')}\n value={agentFilter}\n options={agentOptions}\n onChange={setAgentFilter}\n />\n </div>\n </div>\n </div>\n\n {/* Results Count */}\n {searchQuery ||\n statusFilter !== 'all' ||\n typeFilter !== 'all' ||\n agentFilter !== 'all' ? (\n <p className=\"text-sm text-text-secondary\">\n {tr('vibesPage.showingResults', 'Showing {{filtered}} of {{total}} vibes', {\n filtered: filteredVibes.length,\n total: vibes.length,\n })}\n {loading && (\n <span className=\"ml-2 text-text-muted\">\n {tr('vibesPage.refreshing', '(refreshing...)')}\n </span>\n )}\n </p>\n ) : null}\n\n {filteredVibes.length > 0 && (\n <div className=\"rounded-lg border border-border-default bg-bg-surface p-4\">\n <div className=\"flex flex-col gap-3 lg:flex-row lg:items-center lg:justify-between\">\n <div className=\"flex flex-wrap items-center gap-3\">\n <div className=\"flex items-center gap-2\">\n <SelectionCheckbox\n checked={allVisibleSelected}\n indeterminate={partiallySelected}\n onChange={toggleAllVisibleVibes}\n ariaLabel=\"Select all visible vibes\"\n />\n <span className=\"text-sm font-medium text-text-primary\">\n Select all visible\n </span>\n </div>\n {selectedVibeIds.size > 0 && (\n <button\n onClick={clearSelection}\n className=\"text-sm text-text-secondary hover:text-text-primary\"\n >\n Clear selection\n </button>\n )}\n </div>\n\n <div className=\"flex flex-wrap items-center gap-2\">\n <span className=\"rounded-full bg-bg-sunken px-3 py-1 text-sm font-medium text-text-secondary\">\n {selectedVibeIds.size} selected\n </span>\n <button\n onClick={() => setBulkAction('activate')}\n disabled={activatableVibes.length === 0}\n title=\"Mark selected vibes as ACTIVE so they appear in the default vibe list and can run sessions/tunnels via their attached agent(s).\"\n className=\"rounded-md border border-status-success-border px-3 py-2 text-sm font-medium text-status-success-text hover:bg-status-success-bg disabled:cursor-not-allowed disabled:opacity-50\"\n >\n <span className=\"inline-flex items-center gap-2\">\n <Play className=\"w-4 h-4\" />\n Activate Selected\n {activatableVibes.length > 0 ? ` (${activatableVibes.length})` : ''}\n </span>\n </button>\n <button\n onClick={() => setBulkAction('archive')}\n disabled={archivableVibes.length === 0}\n className=\"rounded-md border border-status-warning-border px-3 py-2 text-sm font-medium text-status-warning-text hover:bg-status-warning-bg disabled:cursor-not-allowed disabled:opacity-50\"\n >\n <span className=\"inline-flex items-center gap-2\">\n <Archive className=\"w-4 h-4\" />\n Archive Selected\n {archivableVibes.length > 0 ? ` (${archivableVibes.length})` : ''}\n </span>\n </button>\n </div>\n </div>\n </div>\n )}\n\n {/* Vibes Display */}\n {showInitialLoading ? (\n <PageSkeleton variant=\"cards\" count={6} />\n ) : filteredVibes.length > 0 ? (\n <AnimatePresence mode=\"wait\">\n {viewMode === 'grid' ? (\n <MotionList\n key=\"grid\"\n stagger={0.04}\n className=\"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4\"\n >\n {filteredVibes.map((vibe) => (\n <MotionItem key={vibe.id}>\n <VibeCard\n vibe={vibe}\n onOpen={handleVibeSelect}\n onActivate={canUpdateVibe ? handleVibeActivate : undefined}\n onArchive={canUpdateVibe ? handleVibeArchive : undefined}\n onOpenInEditor={handleOpenInEditor}\n selected={selectedVibeIds.has(vibe.id)}\n onToggleSelect={(checked) => toggleVibeSelection(vibe, checked)}\n />\n </MotionItem>\n ))}\n </MotionList>\n ) : (\n <MotionList key=\"list\">\n <VibeList\n vibes={filteredVibes}\n onOpen={handleVibeSelect}\n onActivate={handleVibeActivate}\n onArchive={handleVibeArchive}\n onOpenInEditor={handleOpenInEditor}\n selectedVibeIds={selectedVibeIds}\n onToggleSelect={toggleVibeSelection}\n onToggleAllVisible={toggleAllVisibleVibes}\n allVisibleSelected={allVisibleSelected}\n partiallySelected={partiallySelected}\n />\n </MotionList>\n )}\n </AnimatePresence>\n ) : (\n <EmptyState\n icon={<Zap className=\"w-8 h-8 text-text-secondary\" />}\n title={\n searchQuery ||\n statusFilter !== 'all' ||\n typeFilter !== 'all' ||\n agentFilter !== 'all'\n ? tr('vibesPage.emptyNoVibesFound', 'No vibes found')\n : tr('vibesPage.emptyNoVibesConfigured', 'No vibes configured')\n }\n description={\n searchQuery ||\n statusFilter !== 'all' ||\n typeFilter !== 'all' ||\n agentFilter !== 'all'\n ? tr('vibesPage.emptyAdjustSearch', 'Try adjusting your search or filters')\n : tr(\n 'vibesPage.emptyNoVibesDescription',\n 'Add your first vibe to start managing your development projects'\n )\n }\n action={\n !searchQuery &&\n statusFilter === 'all' &&\n typeFilter === 'all' &&\n agentFilter === 'all' ? (\n <div className=\"flex items-center gap-2\">\n <PermissionGate permission={VIBE_PERMISSIONS.VIBE_CREATE}>\n <button\n onClick={handleCreateVibe}\n className=\"flex items-center gap-2 px-4 py-2 bg-action-primary-bg text-action-primary-text rounded-md hover:bg-action-primary-bg-hover transition-colors\"\n >\n <Plus className=\"w-4 h-4\" />\n {tr('vibesPage.addVibe', 'Add Vibe')}\n </button>\n </PermissionGate>\n <GetHelpButton prompt=\"What is a Vibe in VibeControls and how do I create one?\" />\n </div>\n ) : undefined\n }\n />\n )}\n\n {/* Success Toast */}\n {successMessage && (\n <div className=\"fixed bottom-4 right-4 z-50 px-4 py-3 bg-status-success-bg text-status-success-text rounded-md shadow-lg text-sm\">\n {successMessage}\n </div>\n )}\n\n <ConfirmDialog\n isOpen={bulkAction === 'activate'}\n onClose={() => setBulkAction(null)}\n onConfirm={handleBulkActivate}\n title=\"Activate selected vibes\"\n message={`Activate ${activatableVibes.length} selected vibe${activatableVibes.length === 1 ? '' : 's'}?`}\n confirmLabel=\"Activate\"\n variant=\"default\"\n />\n\n <ConfirmDialog\n isOpen={bulkAction === 'archive'}\n onClose={() => setBulkAction(null)}\n onConfirm={handleBulkArchive}\n title=\"Archive selected vibes\"\n message={`Archive ${archivableVibes.length} selected vibe${archivableVibes.length === 1 ? '' : 's'}? Archived vibes will be hidden from active workflows.`}\n confirmLabel=\"Archive\"\n variant=\"warning\"\n />\n\n {/* Page-level Error Toast */}\n {pageError && (\n <div\n role=\"alert\"\n className=\"fixed bottom-4 right-4 z-50 px-4 py-3 bg-status-error-bg text-status-error-text rounded-md shadow-lg text-sm\"\n >\n {pageError}\n <button\n onClick={clearPageError}\n className=\"ml-3 text-xs underline opacity-80 hover:opacity-100\"\n >\n {tr('vibesPage.dismiss', 'Dismiss')}\n </button>\n </div>\n )}\n\n {/* Create Vibe Modal */}\n {showCreateForm && (\n <div className=\"fixed inset-0 bg-bg-overlay flex items-center justify-center z-50 p-4\">\n <div className=\"bg-bg-surface rounded-lg p-6 w-full max-w-lg\">\n <h2 className=\"text-lg font-semibold text-text-primary mb-4\">\n {tr('vibesPage.addNewVibe', 'Add New Vibe')}\n </h2>\n <div className=\"space-y-4\">\n {createError && (\n <div className=\"p-3 bg-status-error-bg text-status-error-text text-sm rounded-md\">\n {createError}\n </div>\n )}\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-1\">\n {tr('vibesPage.nameLabel', 'Name *')}\n </label>\n <input\n ref={nameRef}\n type=\"text\"\n placeholder={tr('vibesPage.namePlaceholder', 'My Project')}\n onChange={() =>\n fieldErrors.name && setFieldErrors((e) => ({ ...e, name: undefined }))\n }\n className={`w-full px-3 py-2 bg-bg-sunken border rounded-md text-text-primary placeholder:text-text-placeholder ${fieldErrors.name ? 'border-status-error-border' : 'border-border-default'}`}\n />\n {fieldErrors.name && (\n <p className=\"mt-1 text-xs text-status-error-text\">{fieldErrors.name}</p>\n )}\n </div>\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-1\">\n {tr('vibesPage.pathLabel', 'Path *')}\n </label>\n <input\n ref={pathRef}\n type=\"text\"\n placeholder={tr('vibesPage.pathPlaceholder', '/path/to/project')}\n onChange={() =>\n fieldErrors.path && setFieldErrors((e) => ({ ...e, path: undefined }))\n }\n className={`w-full px-3 py-2 bg-bg-sunken border rounded-md text-text-primary placeholder:text-text-placeholder ${fieldErrors.path ? 'border-status-error-border' : 'border-border-default'}`}\n />\n {fieldErrors.path && (\n <p className=\"mt-1 text-xs text-status-error-text\">{fieldErrors.path}</p>\n )}\n </div>\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-1\">\n {tr('vibesPage.agentLabel', 'Agent')}\n </label>\n <select\n ref={agentRef}\n className=\"w-full px-3 py-2 bg-bg-sunken border border-border-default rounded-md text-text-primary\"\n >\n <option value=\"\">{tr('vibesPage.selectAgent', 'Select an agent')}</option>\n {agentOptions\n .filter((opt) => opt.value !== 'all')\n .map((agent) => (\n <option key={agent.value} value={agent.value}>\n {agent.label}\n </option>\n ))}\n </select>\n </div>\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-1\">\n {tr('vibesPage.typeLabel', 'Type')}\n </label>\n <select\n ref={typeRef}\n className=\"w-full px-3 py-2 bg-bg-sunken border border-border-default rounded-md text-text-primary\"\n >\n <option value=\"PROJECT\">{tr('vibesPage.typeProject', 'Project')}</option>\n <option value=\"REPOSITORY\">\n {tr('vibesPage.typeRepository', 'Repository')}\n </option>\n <option value=\"WORKSPACE\">\n {tr('vibesPage.typeWorkspace', 'Workspace')}\n </option>\n <option value=\"MONOREPO\">{tr('vibesPage.typeMonorepo', 'Monorepo')}</option>\n <option value=\"PACKAGE\">{tr('vibesPage.typePackage', 'Package')}</option>\n <option value=\"CUSTOM\">{tr('vibesPage.typeCustom', 'Custom')}</option>\n </select>\n </div>\n </div>\n <div className=\"mt-4 border-t border-border-default pt-4\">\n <h3 className=\"text-sm font-medium text-text-secondary mb-2\">\n {tr('vibesPage.tags', 'Tags')}\n </h3>\n <EntityTagPicker entityType=\"VIBECONTROLS_VIBE\" onDraftChange={setDraftTagIds} />\n </div>\n <div className=\"flex flex-col sm:flex-row justify-end gap-3 mt-6\">\n <button\n onClick={() => setShowCreateForm(false)}\n disabled={createLoading}\n className=\"px-4 py-2 text-text-primary hover:bg-bg-sunken rounded-md transition-colors disabled:opacity-50\"\n >\n {tr('vibesPage.cancel', 'Cancel')}\n </button>\n <button\n onClick={handleSubmitCreateVibe}\n disabled={createLoading}\n className=\"px-4 py-2 bg-action-primary-bg text-action-primary-text rounded-md hover:bg-action-primary-bg-hover transition-colors disabled:opacity-50\"\n >\n {createLoading\n ? tr('vibesPage.creating', 'Creating...')\n : tr('vibesPage.createVibe', 'Create Vibe')}\n </button>\n </div>\n </div>\n </div>\n )}\n\n <QuotaExhaustedDialog\n isOpen={showQuotaExhausted}\n onClose={() => setShowQuotaExhausted(false)}\n onConfirm={() => {\n setShowQuotaExhausted(false);\n navigate('/billing');\n }}\n title=\"Vibe Quota Reached\"\n message=\"You've used all available vibe creation quota on your current plan. Upgrade your plan to create more vibes.\"\n />\n </>\n )}\n </MotionPage>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsDA,SAAgB,IAAY;CAC1B,IAAM,EAAE,sBAAmB,IAAiB,EACtC,IAAW,IAAiB,EAC5B,EAAE,kBAAe,WAAW,GAAoB,mBAAgB,IAAgB,EAChF,EAAE,SAAM,IAAS,EAEjB,IAAK,GACR,GAAa,GAAkB,MAAqD;EACnF,IAAM,IAAa,EAAE,GAAK,EAAO,EAC3B,IAAW,MAAe,IAAM,IAAW;AAIjD,SAFK,IAEE,OAAO,QAAQ,EAAO,CAAC,QAC3B,GAAK,CAAC,GAAU,OAAgB,EAAI,QAAQ,KAAK,EAAS,KAAK,OAAO,EAAW,CAAC,EACnF,EACD,GALmB;IAOtB,CAAC,EAAE,CACJ,EAEK,KAAgB;EACpB;GAAE,OAAO;GAAO,OAAO,EAAG,uBAAuB,eAAe;GAAE;EAClE;GAAE,OAAO;GAAU,OAAO,EAAG,0BAA0B,SAAS;GAAE;EAClE;GAAE,OAAO;GAAY,OAAO,EAAG,4BAA4B,WAAW;GAAE;EACxE;GAAE,OAAO;GAAY,OAAO,EAAG,4BAA4B,WAAW;GAAE;EACxE;GAAE,OAAO;GAAS,OAAO,EAAG,yBAAyB,QAAQ;GAAE;EAChE;AAGwB,GAAG,qBAAqB,YAAY,EAChC,EAAG,yBAAyB,UAAU,EACnC,EAAG,4BAA4B,aAAa,EAC7C,EAAG,2BAA2B,YAAY,EAC3C,EAAG,0BAA0B,WAAW,EACzC,EAAG,yBAAyB,UAAU,EACvC,EAAG,wBAAwB,SAAS;CAIhE,IAAM,IAAe,EAAc,EAAiB,UAAU,EACxD,IAAgB,EAAc,EAAiB,YAAY,EAI3D,IAAoB,KAAsB,CAAC,GAE3C,CAAC,GAAa,MAAkB,EAAS,GAAG,EAC5C,CAAC,GAAc,MAAmB,EAAS,MAAM,EACjD,CAAC,GAAY,MAAiB,EAAS,MAAM,EAC7C,CAAC,GAAa,MAAkB,EAAS,MAAM,EAC/C,CAAC,GAAU,MAAe,EAAmB,OAAO,EACpD,CAAC,IAAgB,KAAqB,EAAS,GAAM,EACrD,CAAC,GAAa,KAAkB,EAAwB,KAAK,EAC7D,CAAC,GAAe,MAAoB,EAAS,GAAM,EACnD,CAAC,IAAgB,KAAqB,EAAwB,KAAK,EACnE,CAAC,IAAoB,KAAyB,EAAS,GAAM,EAC7D,CAAC,GAAa,KAAkB,EAA2C,EAAE,CAAC,EAC9E,CAAC,IAAW,KAAgB,EAAwB,KAAK,EACzD,CAAC,GAAiB,KAAsB,kBAAsB,IAAI,KAAK,CAAC,EACxE,CAAC,IAAY,KAAiB,EAAwC,KAAK,EAC3E,IAAiB,EAA6C,KAAK;AAEzE,gBACe;AACX,EAAI,EAAe,WAAS,aAAa,EAAe,QAAQ;IAEjE,EAAE,CAAC;CAEN,IAAM,KAAiB,QAAkB;AAEvC,EADA,EAAa,KAAK,EAClB,AAEE,EAAe,aADf,aAAa,EAAe,QAAQ,EACX;IAE1B,EAAE,CAAC,EAGA,KAAU,EAAyB,KAAK,EACxC,KAAU,EAAyB,KAAK,EACxC,KAAW,EAA0B,KAAK,EAC1C,KAAU,EAA0B,KAAK,EAEzC,CAAC,MAAc,GAAuB,EACtC,EAAE,oBAAgB,kBAAc,GAAmB,oBAAoB,EACvE,CAAC,MAAoB,GAA6B,EAClD,CAAC,MAAe,GAAwB,EA+CxC,EAAE,UAAM,YAAS,WAAO,eAAY,EAAkB;EAC1D,WAvCyB,SAClB,EACL,QAAQ;GACN,QACE,MAAiB,QAEb,KAAA,IADC;GAEP,MACE,MAAe,QAQX,KAAA,IAPC;GAUP,kBAAkB,MAAgB,QAAwB,KAAA,IAAhB,CAAC,EAAY;GACxD,EACF,GACD;GAAC;GAAc;GAAY;GAAY,CACxC;EAiBC,aAXoB,MAAiB,SAAS,MAAe,SAAS,MAAgB,QAC/C,gBAAgB;EAWvD,iBAAiB;EACjB,MAAM;EACN,6BAA6B;EAC9B,CAAC,EAMI,EAAE,QAAQ,OAA0B,IAAsB,EAC1D,CAAC,IAAa,EAAE,MAAM,QAAgB,EAAuB,EACjE,aAAa,eACd,CAAC,EACI,KAA0B,EAAO,GAAM,EACvC,IAA4B,QAAkB;AAC9C,KAAwB,WAAW,MACvC,GAAwB,UAAU,IAC7B,GAAY,EAAE,WAAW,EAAE,YAAY,EAAE,OAAO,KAAK,EAAE,EAAE,CAAC;IAC9D,CAAC,IAAa,EAAkB,CAAC,EAK9B,KAAe,QAAc;EACjC,IAAM,IAAO,IAAY,sBAAsB,MACzC,IAA8C,IAChD,EAAK,KAAK,OAAc;GAAE,IAAI,EAAE;GAAI,MAAM,EAAE;GAAM,EAAE,GACpD,GAAsB,KAAK,OAAO;GAAE,IAAI,EAAE;GAAI,MAAM,EAAE;GAAM,EAAE;AAClE,SAAO,CACL;GAAE,OAAO;GAAO,OAAO,EAAG,uBAAuB,aAAa;GAAE,EAChE,GAAG,EAAO,KAAK,OAAW;GACxB,OAAO,EAAM;GACb,OAAO,EAAM;GACd,EAAE,CACJ;IACA;EAAC,IAAY;EAAoB;EAAuB;EAAG,CAAC,EAGzD,IAAgB,SACH,IAAM,OAAO,SAAS,EAAE,EACzB,KAAK,OAAgD;EACnE,IAAI,EAAK;EACT,aAAa,EAAK;EAClB,MAAM,EAAK;EACX,aAAa,EAAK,eAAe;EACjC,MAAM,EAAK;EACX,QAAQ,EAAK;EACb,MAAM,EAAK,QAAQ;EACnB,UAAU,EAAK,YAAY;EAC3B,WAAW,EAAK,aAAa;EAC7B,WAAW,EAAK,aAAa;EAC7B,WAAW,EAAK,YACZ,OAAO,EAAK,aAAc,WACxB,EAAK,YACL,OAAO,EAAK,aAAc,YACxB,EAAK,cAAc,QACnB,YAAY,EAAK,YACjB,OAAQ,EAAK,UAAsC,OAAO,GAC1D,KAAK,UAAU,EAAK,UAAU,GAClC;EACJ,sBAAuB,EAAK,wBAAmD,EAAE;EACjF,MAAM,EAAK,QAAQ,EAAE;EACrB,UAAW,EAAK,YAAwC,EAAE;EAC1D,WAAW,EAAK;EAChB,WAAW,EAAK;EAChB,SAAS,EAAK,UAAU,EAAE,EAAE,KAAK,OAAgD;GAC/E,IAAI,EAAE;GACN,MAAM,EAAE;GACR,UAAU,EAAE;GACZ,aAAa,EAAE,eAAe;GAC/B,EAAE;EACJ,EAAE,EACF,CAAC,IAAM,OAAO,MAAM,CAAC,EAGlB,IAAgB,QACb,EAAM,QAAQ,MAAS;AAE5B,MAAI,GAAa;GACf,IAAM,IAAQ,EAAY,aAAa;AAMvC,OAAI,EAJF,EAAK,KAAK,aAAa,CAAC,SAAS,EAAM,IACvC,EAAK,aAAa,aAAa,CAAC,SAAS,EAAM,IAC/C,EAAK,MAAM,aAAa,CAAC,SAAS,EAAM,IACxC,EAAK,MAAM,MAAM,MAAQ,EAAI,aAAa,CAAC,SAAS,EAAM,CAAC,EACzC,QAAO;;AAG7B,SAAO;GACP,EACD,CAAC,GAAO,EAAY,CAAC,EAElB,KAAgB,QACd,EAAM,QAAQ,MAAS,EAAgB,IAAI,EAAK,GAAG,CAAC,EAC1D,CAAC,GAAO,EAAgB,CACzB,EACK,IAAmB,GAAc,QAAQ,MAAS,EAAK,WAAW,SAAS,EAC3E,IAAkB,GAAc,QAAQ,MAAS,EAAK,WAAW,WAAW,EAC5E,IACJ,EAAc,SAAS,KAAK,EAAc,OAAO,MAAS,EAAgB,IAAI,EAAK,GAAG,CAAC,EACnF,KACJ,EAAc,MAAM,MAAS,EAAgB,IAAI,EAAK,GAAG,CAAC,IAAI,CAAC,GAE3D,MAAoB,MAAe;AACvC,IAAS,UAAU,EAAK,KAAK;IAGzB,KAAqB,OAAO,MAAe;AAC/C,MAAI;AAIF,IAHe,MAAM,GAAiB,EACpC,WAAW;IAAE,IAAI,EAAK;IAAI,QAAQ;IAAmB,EACtD,CAAC,EACS,MAAM,oBACf,IAAiB;IAAE,IAAI,EAAK;IAAI,MAAM,EAAK;IAAM,MAAM,EAAK;IAAM,QAAQ;IAAU,CAAC;WAEhF,GAAK;AACZ,WAAQ,MAAM,4BAA4B,EAAI;;IAI5C,KAAoB,OAAO,MAAe;AAC9C,MAAI;AACF,SAAM,GAAY,EAAE,WAAW,EAAE,IAAI,EAAK,IAAI,EAAE,CAAC;WAC1C,GAAK;AACZ,WAAQ,MAAM,2BAA2B,EAAI;;IAQ3C,KAAsB,IAAsB,MAAM,EAAE,oBAAoB,EACxE,KAAmB,IAAsB,MAAM,EAAE,iBAAiB,EAElE,MAAsB,MAAe;AACzC,MAAI,CAAC,EAAK,MAAM;AAEd,GADA,EAAa,EAAG,mCAAmC,sCAAsC,CAAC,EAC1F,EAAe,UAAU,iBAAiB;AAExC,IADA,EAAa,KAAK,EAClB,EAAe,UAAU;MACxB,IAAK;AACR;;EAEF,IAAM,IAAM,GAA2B,EAAK,IAAI,IAAqB,GAAiB,EAChF,IAAS,GAAa,EAAI,EAC1B,IAAM,IAAS,GAAiB,GAAQ,EAAK,KAAK,GAAG,iBAAiB,EAAK;AACjF,EAAI,IACF,OAAO,SAAS,OAAO,KAEvB,EACE,EACE,kCACA,GAAG,GAAQ,SAAS,EAAI,+DACzB,CACF,EACD,EAAe,UAAU,iBAAiB;AAExC,GADA,EAAa,KAAK,EAClB,EAAe,UAAU;KACxB,IAAK;IAIN,WAAyB;AAK7B,EAJA,EAAe,KAAK,EACpB,EAAkB,GAAK,EAGvB,GAA2B;IAGvB,MAAuB,GAAY,MAAqB;AAC5D,KAAoB,MAAS;GAC3B,IAAM,IAAO,IAAI,IAAI,EAAK;AAM1B,UALI,IACF,EAAK,IAAI,EAAK,GAAG,GAEjB,EAAK,OAAO,EAAK,GAAG,EAEf;IACP;IAGE,MAAyB,MAAqB;AAClD,KAAoB,MAAS;GAC3B,IAAM,IAAO,IAAI,IAAI,EAAK;AAQ1B,UAPA,EAAc,SAAS,MAAS;AAC9B,IAAI,IACF,EAAK,IAAI,EAAK,GAAG,GAEjB,EAAK,OAAO,EAAK,GAAG;KAEtB,EACK;IACP;IAGE,UAAuB,kBAAmB,IAAI,KAAK,CAAC,EAEpD,KAAqB,YAAY;AACrC,MAAI,EAAiB,WAAW,EAAG;EAEnC,IAAM,IAAU,MAAM,QAAQ,WAC5B,EAAiB,KAAK,MACpB,GAAiB,EAAE,WAAW;GAAE,IAAI,EAAK;GAAI,QAAQ;GAAmB,EAAE,CAAC,CAC5E,CACF,EAEK,IAAY,EAAQ,QAAQ,MAAW,EAAO,WAAW,YAAY,CAAC,QACtE,IAAS,EAAQ,SAAS;AAQhC,EANA,EACE,aAAa,EAAU,OAAO,MAAc,IAAI,KAAK,MAAM,IAAS,IAAI,MAAM,EAAO,WAAW,KACjG,EACD,iBAAiB,EAAkB,KAAK,EAAE,IAAK,EAC/C,GAAgB,EAChB,EAAc,KAAK,EACnB,MAAM,GAAS;IAGX,KAAoB,YAAY;AACpC,MAAI,EAAgB,WAAW,EAAG;EAElC,IAAM,IAAU,MAAM,QAAQ,WAC5B,EAAgB,KAAK,MAAS,GAAY,EAAE,WAAW,EAAE,IAAI,EAAK,IAAI,EAAE,CAAC,CAAC,CAC3E,EAEK,IAAY,EAAQ,QAAQ,MAAW,EAAO,WAAW,YAAY,CAAC,QACtE,IAAS,EAAQ,SAAS;AAQhC,EANA,EACE,YAAY,EAAU,OAAO,MAAc,IAAI,KAAK,MAAM,IAAS,IAAI,MAAM,EAAO,WAAW,KAChG,EACD,iBAAiB,EAAkB,KAAK,EAAE,IAAK,EAC/C,GAAgB,EAChB,EAAc,KAAK,EACnB,MAAM,GAAS;IAGX,KAAyB,YAAY;EACzC,IAAM,IAAO,GAAQ,SAAS,OAAO,MAAM,EACrC,IAAO,GAAQ,SAAS,OAAO,MAAM,EACrC,IAAU,GAAS,SAAS,OAC5B,IAAO,GAAQ,SAAS,OAExB,IAA2C,EAAE;AAGnD,MAFK,MAAM,EAAO,OAAO,EAAG,0BAA0B,mBAAmB,GACpE,MAAM,EAAO,OAAO,EAAG,0BAA0B,mBAAmB,GACrE,EAAO,QAAQ,EAAO,MAAM;AAE9B,GADA,EAAe,EAAO,EACtB,EAAe,EAAG,0BAA0B,qCAAqC,CAAC;AAClF;;AAEF,IAAe,EAAE,CAAC;EAWlB,IAAM,KARa;GACjB;GACA;GACA;GACA;GACA;GACA;GACD,CAC+B,SAAS,EAAoC,GACxE,IACD;AAGJ,EADA,GAAiB,GAAK,EACtB,EAAe,KAAK;AACpB,MAAI;GACF,IAAM,IAAS,MAAM,GAAW,EAC9B,WAAW,EACT,OAAO;IACL;IACA;IACA,MAAM;IACN,SAAS,KAAW,KAAA;IACrB,EACF,EACF,CAAC;AACF,OAAI,CAAC,EAAO,MAAM,YAAY,GAC5B,OAAU,MAAM,EAAG,0BAA0B,wBAAwB,CAAC;GAExE,IAAM,IAAY,EAAO,KAAK,WAAW;AAKzC,GAJA,EAAkB,GAAM,EACxB,EAAkB,EAAG,4BAA4B,4BAA4B,CAAC,EAC9E,MAAM,GAAU,EAAU,EAC1B,MAAM,GAAS,EACf,iBAAiB,EAAkB,KAAK,EAAE,IAAK;WACxC,GAAK;AACZ,OAAI,GAAsB,EAAI,EAAE;AAI9B,IAHA,EAAkB,GAAM,EACxB,EAAe,KAAK,EACpB,EAAe,EAAE,CAAC,EAClB,EAAsB,GAAK;AAC3B;;AAGF,KACE,aAAe,QAAQ,EAAI,UAAU,EAAG,0BAA0B,wBAAwB,CAC3F;YACO;AACR,MAAiB,GAAM;;IAKrB,KAAQ;EACZ,OAAO,EAAM;EACb,QAAQ,EAAM,QAAQ,MAAM,EAAE,WAAW,SAAS,CAAC;EACnD,UAAU,EAAM,QAAQ,MAAM,EAAE,WAAW,WAAW,CAAC;EACxD,EAKK,IAAyB,GACzB,IACJ,CAAC,KACD,CAAC,CAAC,MACD,EAAY,mBAAmB,UAAU,KAAK,KAC/C,CAAC,GACG,KACJ,CAAC,KAA0B,CAAC,KAAoB,KAAW,EAAM,WAAW,GACxE,KACJ,CAAC,KAA0B,CAAC,KAAoB,CAAC,CAAC,MAAS,EAAM,WAAW,GACxE,KAAgB,CAAC,KAA0B,CAAC,KAAoB,CAAC;AAEvE,QACE,kBAAC,IAAD;EAAY,WAAU;YAAtB;GACG,KACC,kBAAC,IAAD,EAAc,SAAS,EAAG,gCAAgC,yBAAyB,EAAI,CAAA;GAExF,KACC,kBAAC,IAAD;IACE,OAAO,EAAG,+BAA+B,gBAAgB;IACzD,aAAa,EACX,qCACA,4FACD;IACD,CAAA;GAEH,MACC,kBAAC,IAAD;IACE,OAAO,EAAG,wBAAwB,uBAAuB;IACzD,SAAS,IAAO,WAAW;IAC3B,eAAe,GAAS;IACxB,CAAA;GAEH,MACC,kBAAA,IAAA,EAAA,UAAA;IACE,kBAAC,IAAD;KACE,OAAO,EAAG,mBAAmB,QAAQ;KACrC,aAAa,EAAG,+BAA+B,wCAAwC;MACrF,QAAQ,GAAM;MACd,OAAO,GAAM;MACd,CAAC;KACF,SACE,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,UAAD;OACE,eAAe,GAAS;OACxB,UAAU;OACV,WAAU;OACV,OAAO,EAAG,0BAA0B,gBAAgB;iBAEpD,kBAAC,IAAD,EAAW,WAAW,WAAW,IAAU,iBAAiB,MAAQ,CAAA;OAC7D,CAAA,EACT,kBAAC,IAAD;OACE,YAAY,EAAiB;OAC7B,gBAAe;OACf,eAAe,EACb,iCACA,4CACD;iBAED,kBAAC,UAAD;QACE,SAAS;QACT,WAAU;kBAFZ,CAIE,kBAAC,IAAD,EAAM,WAAU,WAAY,CAAA,EAC3B,EAAG,qBAAqB,WAAW,CAC7B;;OACQ,CAAA,CACf;;KAER,CAAA;IAGF,kBAAC,OAAD;KAAK,WAAU;eAAf,CAEE,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,IAAD;OACE,OAAO;OACP,UAAU;OACV,aAAa,EAAG,+BAA+B,kBAAkB;OACjE,WAAU;OACV,CAAA,EAEF,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,UAAD;QACE,eAAe,GAAY,OAAO;QAClC,WAAW,wBAAwB,MAAa,SAAS,4BAA4B;QACrF,OAAO,EAAG,2BAA2B,YAAY;kBAEjD,kBAAC,IAAD,EAAM,WAAU,+BAAgC,CAAA;QACzC,CAAA,EACT,kBAAC,UAAD;QACE,eAAe,GAAY,OAAO;QAClC,WAAW,wBAAwB,MAAa,SAAS,4BAA4B;QACrF,OAAO,EAAG,2BAA2B,YAAY;kBAEjD,kBAAC,IAAD,EAAM,WAAU,+BAAgC,CAAA;QACzC,CAAA,CACL;SACF;SAGN,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,GAAD;OACE,OAAO,EAAG,0BAA0B,SAAS;OAC7C,OAAO;OACP,SAAS;OACT,UAAU;OACV,CAAA,EACF,kBAAC,OAAD;OAAK,aAAa;OAA2B,SAAS;iBACpD,kBAAC,GAAD;QACE,OAAO,EAAG,yBAAyB,QAAQ;QAC3C,OAAO;QACP,SAAS;QACT,UAAU;QACV,CAAA;OACE,CAAA,CACF;QACF;;IAGL,KACD,MAAiB,SACjB,MAAe,SACf,MAAgB,QACd,kBAAC,KAAD;KAAG,WAAU;eAAb,CACG,EAAG,4BAA4B,2CAA2C;MACzE,UAAU,EAAc;MACxB,OAAO,EAAM;MACd,CAAC,EACD,KACC,kBAAC,QAAD;MAAM,WAAU;gBACb,EAAG,wBAAwB,kBAAkB;MACzC,CAAA,CAEP;SACF;IAEH,EAAc,SAAS,KACtB,kBAAC,OAAD;KAAK,WAAU;eACb,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,IAAD;SACE,SAAS;SACT,eAAe;SACf,UAAU;SACV,WAAU;SACV,CAAA,EACF,kBAAC,QAAD;SAAM,WAAU;mBAAwC;SAEjD,CAAA,CACH;WACL,EAAgB,OAAO,KACtB,kBAAC,UAAD;QACE,SAAS;QACT,WAAU;kBACX;QAEQ,CAAA,CAEP;UAEN,kBAAC,OAAD;OAAK,WAAU;iBAAf;QACE,kBAAC,QAAD;SAAM,WAAU;mBAAhB,CACG,EAAgB,MAAK,YACjB;;QACP,kBAAC,UAAD;SACE,eAAe,EAAc,WAAW;SACxC,UAAU,EAAiB,WAAW;SACtC,OAAM;SACN,WAAU;mBAEV,kBAAC,QAAD;UAAM,WAAU;oBAAhB;WACE,kBAAC,IAAD,EAAM,WAAU,WAAY,CAAA;;WAE3B,EAAiB,SAAS,IAAI,KAAK,EAAiB,OAAO,KAAK;WAC5D;;SACA,CAAA;QACT,kBAAC,UAAD;SACE,eAAe,EAAc,UAAU;SACvC,UAAU,EAAgB,WAAW;SACrC,WAAU;mBAEV,kBAAC,QAAD;UAAM,WAAU;oBAAhB;WACE,kBAAC,IAAD,EAAS,WAAU,WAAY,CAAA;;WAE9B,EAAgB,SAAS,IAAI,KAAK,EAAgB,OAAO,KAAK;WAC1D;;SACA,CAAA;QACL;SACF;;KACF,CAAA;IAIP,KACC,kBAAC,IAAD;KAAc,SAAQ;KAAQ,OAAO;KAAK,CAAA,GACxC,EAAc,SAAS,IACzB,kBAAC,IAAD;KAAiB,MAAK;eACnB,MAAa,SACZ,kBAAC,GAAD;MAEE,SAAS;MACT,WAAU;gBAET,EAAc,KAAK,MAClB,kBAAC,IAAD,EAAA,UACE,kBAAC,IAAD;OACQ;OACN,QAAQ;OACR,YAAY,IAAgB,KAAqB,KAAA;OACjD,WAAW,IAAgB,KAAoB,KAAA;OAC/C,gBAAgB;OAChB,UAAU,EAAgB,IAAI,EAAK,GAAG;OACtC,iBAAiB,MAAY,GAAoB,GAAM,EAAQ;OAC/D,CAAA,EACS,EAVI,EAAK,GAUT,CACb;MACS,EAjBP,OAiBO,GAEb,kBAAC,GAAD,EAAA,UACE,kBAAC,IAAD;MACE,OAAO;MACP,QAAQ;MACR,YAAY;MACZ,WAAW;MACX,gBAAgB;MACC;MACjB,gBAAgB;MAChB,oBAAoB;MACA;MACD;MACnB,CAAA,EACS,EAbG,OAaH;KAEC,CAAA,GAElB,kBAAC,IAAD;KACE,MAAM,kBAAC,IAAD,EAAK,WAAU,+BAAgC,CAAA;KACrD,OACE,KACA,MAAiB,SACjB,MAAe,SACf,MAAgB,QACZ,EAAG,+BAA+B,iBAAiB,GACnD,EAAG,oCAAoC,sBAAsB;KAEnE,aACE,KACA,MAAiB,SACjB,MAAe,SACf,MAAgB,QACZ,EAAG,+BAA+B,uCAAuC,GACzE,EACE,qCACA,kEACD;KAEP,QACE,CAAC,KACD,MAAiB,SACjB,MAAe,SACf,MAAgB,QACd,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,IAAD;OAAgB,YAAY,EAAiB;iBAC3C,kBAAC,UAAD;QACE,SAAS;QACT,WAAU;kBAFZ,CAIE,kBAAC,IAAD,EAAM,WAAU,WAAY,CAAA,EAC3B,EAAG,qBAAqB,WAAW,CAC7B;;OACM,CAAA,EACjB,kBAAC,IAAD,EAAe,QAAO,2DAA4D,CAAA,CAC9E;UACJ,KAAA;KAEN,CAAA;IAIH,MACC,kBAAC,OAAD;KAAK,WAAU;eACZ;KACG,CAAA;IAGR,kBAAC,GAAD;KACE,QAAQ,OAAe;KACvB,eAAe,EAAc,KAAK;KAClC,WAAW;KACX,OAAM;KACN,SAAS,YAAY,EAAiB,OAAO,gBAAgB,EAAiB,WAAW,IAAI,KAAK,IAAI;KACtG,cAAa;KACb,SAAQ;KACR,CAAA;IAEF,kBAAC,GAAD;KACE,QAAQ,OAAe;KACvB,eAAe,EAAc,KAAK;KAClC,WAAW;KACX,OAAM;KACN,SAAS,WAAW,EAAgB,OAAO,gBAAgB,EAAgB,WAAW,IAAI,KAAK,IAAI;KACnG,cAAa;KACb,SAAQ;KACR,CAAA;IAGD,MACC,kBAAC,OAAD;KACE,MAAK;KACL,WAAU;eAFZ,CAIG,IACD,kBAAC,UAAD;MACE,SAAS;MACT,WAAU;gBAET,EAAG,qBAAqB,UAAU;MAC5B,CAAA,CACL;;IAIP,MACC,kBAAC,OAAD;KAAK,WAAU;eACb,kBAAC,OAAD;MAAK,WAAU;gBAAf;OACE,kBAAC,MAAD;QAAI,WAAU;kBACX,EAAG,wBAAwB,eAAe;QACxC,CAAA;OACL,kBAAC,OAAD;QAAK,WAAU;kBAAf;SACG,KACC,kBAAC,OAAD;UAAK,WAAU;oBACZ;UACG,CAAA;SAER,kBAAC,OAAD,EAAA,UAAA;UACE,kBAAC,SAAD;WAAO,WAAU;qBACd,EAAG,uBAAuB,SAAS;WAC9B,CAAA;UACR,kBAAC,SAAD;WACE,KAAK;WACL,MAAK;WACL,aAAa,EAAG,6BAA6B,aAAa;WAC1D,gBACE,EAAY,QAAQ,GAAgB,OAAO;YAAE,GAAG;YAAG,MAAM,KAAA;YAAW,EAAE;WAExE,WAAW,uGAAuG,EAAY,OAAO,+BAA+B;WACpK,CAAA;UACD,EAAY,QACX,kBAAC,KAAD;WAAG,WAAU;qBAAuC,EAAY;WAAS,CAAA;UAEvE,EAAA,CAAA;SACN,kBAAC,OAAD,EAAA,UAAA;UACE,kBAAC,SAAD;WAAO,WAAU;qBACd,EAAG,uBAAuB,SAAS;WAC9B,CAAA;UACR,kBAAC,SAAD;WACE,KAAK;WACL,MAAK;WACL,aAAa,EAAG,6BAA6B,mBAAmB;WAChE,gBACE,EAAY,QAAQ,GAAgB,OAAO;YAAE,GAAG;YAAG,MAAM,KAAA;YAAW,EAAE;WAExE,WAAW,uGAAuG,EAAY,OAAO,+BAA+B;WACpK,CAAA;UACD,EAAY,QACX,kBAAC,KAAD;WAAG,WAAU;qBAAuC,EAAY;WAAS,CAAA;UAEvE,EAAA,CAAA;SACN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,SAAD;UAAO,WAAU;oBACd,EAAG,wBAAwB,QAAQ;UAC9B,CAAA,EACR,kBAAC,UAAD;UACE,KAAK;UACL,WAAU;oBAFZ,CAIE,kBAAC,UAAD;WAAQ,OAAM;qBAAI,EAAG,yBAAyB,kBAAkB;WAAU,CAAA,EACzE,GACE,QAAQ,MAAQ,EAAI,UAAU,MAAM,CACpC,KAAK,MACJ,kBAAC,UAAD;WAA0B,OAAO,EAAM;qBACpC,EAAM;WACA,EAFI,EAAM,MAEV,CACT,CACG;YACL,EAAA,CAAA;SACN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,SAAD;UAAO,WAAU;oBACd,EAAG,uBAAuB,OAAO;UAC5B,CAAA,EACR,kBAAC,UAAD;UACE,KAAK;UACL,WAAU;oBAFZ;WAIE,kBAAC,UAAD;YAAQ,OAAM;sBAAW,EAAG,yBAAyB,UAAU;YAAU,CAAA;WACzE,kBAAC,UAAD;YAAQ,OAAM;sBACX,EAAG,4BAA4B,aAAa;YACtC,CAAA;WACT,kBAAC,UAAD;YAAQ,OAAM;sBACX,EAAG,2BAA2B,YAAY;YACpC,CAAA;WACT,kBAAC,UAAD;YAAQ,OAAM;sBAAY,EAAG,0BAA0B,WAAW;YAAU,CAAA;WAC5E,kBAAC,UAAD;YAAQ,OAAM;sBAAW,EAAG,yBAAyB,UAAU;YAAU,CAAA;WACzE,kBAAC,UAAD;YAAQ,OAAM;sBAAU,EAAG,wBAAwB,SAAS;YAAU,CAAA;WAC/D;YACL,EAAA,CAAA;SACF;;OACN,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,MAAD;SAAI,WAAU;mBACX,EAAG,kBAAkB,OAAO;SAC1B,CAAA,EACL,kBAAC,IAAD;SAAiB,YAAW;SAAoB,eAAe;SAAkB,CAAA,CAC7E;;OACN,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,UAAD;SACE,eAAe,EAAkB,GAAM;SACvC,UAAU;SACV,WAAU;mBAET,EAAG,oBAAoB,SAAS;SAC1B,CAAA,EACT,kBAAC,UAAD;SACE,SAAS;SACT,UAAU;SACV,WAAU;mBAET,IACG,EAAG,sBAAsB,cAAc,GACvC,EAAG,wBAAwB,cAAc;SACtC,CAAA,CACL;;OACF;;KACF,CAAA;IAGR,kBAAC,IAAD;KACE,QAAQ;KACR,eAAe,EAAsB,GAAM;KAC3C,iBAAiB;AAEf,MADA,EAAsB,GAAM,EAC5B,EAAS,WAAW;;KAEtB,OAAM;KACN,SAAQ;KACR,CAAA;IACD,EAAA,CAAA;GAEM"}
1
+ {"version":3,"file":"VibesPage.js","names":[],"sources":["../../src/pages/VibesPage.tsx"],"sourcesContent":["import { useState, useMemo, useRef, useEffect, useCallback } from 'react';\nimport { Plus, Zap, Grid, List, RefreshCw, Archive, Play } from 'lucide-react';\nimport { VibeCard, VibeList } from '@/components/vibes';\nimport type { Vibe } from '@/components/vibes';\nimport { EntityTagPicker } from '@/components/shared/EntityTagPicker';\nimport { PageSkeleton } from '@/components/shared/PageSkeleton';\nimport { useDraftEntityTags } from '@/hooks/useDraftEntityTags';\nimport {\n PageHeader,\n SearchInput,\n FilterDropdown,\n EmptyState,\n LoadingState,\n ErrorState,\n ConfirmDialog,\n QuotaExhaustedDialog,\n SelectionCheckbox,\n GetHelpButton,\n} from '@/components/shared';\nimport { MotionPage, MotionList, MotionItem } from '@burdenoff/fe-libs/shared/motion';\nimport { AnimatePresence } from 'framer-motion';\nimport { useVibeControls, useVibeNavigate } from '@/providers/VibeControlsProvider';\nimport {\n useListVibesQuery,\n useCreateVibeMutation,\n useAttachAgentToVibeMutation,\n useUpdateVibeStatusMutation,\n useArchiveVibeMutation,\n useListAgentsLazyQuery,\n type ListAgentsQuery,\n} from '@/generated/wspace-operations';\nimport { useCachedInitialData } from '@/hooks/useCachedInitialData';\n\ntype Agent = NonNullable<ListAgentsQuery['vibecontrolsAgents']>[number];\nimport {\n PermissionGate,\n PermissionButton,\n AccessDenied,\n} from '@burdenoff/fe-libs/shared/components';\nimport { usePermissions } from '@burdenoff/fe-libs/shared/providers/shell';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { VIBE_PERMISSIONS } from '@/constants/permissions';\nimport { isQuotaExhaustedError } from '@/utils/quotaUtils';\nimport {\n buildProtocolUrl,\n getIdePreset,\n resolveEffectiveIdeCommand,\n} from '@/components/agents/idePresets';\nimport { useVibeControlsStore } from '@/store/vibeControlsStore';\n\ntype ViewMode = 'grid' | 'list';\n\n/**\n * Vibes (projects/repositories) management page\n */\nexport function VibesPage() {\n const { onVibeActivate } = useVibeControls();\n const navigate = useVibeNavigate();\n const { hasPermission, isLoading: permissionsLoading, permissions } = usePermissions();\n const { t } = useI18n();\n\n const tr = useCallback(\n (key: string, fallback: string, params?: Record<string, string | number>): string => {\n const translated = t(key, params);\n const template = translated === key ? fallback : translated;\n\n if (!params) return template;\n\n return Object.entries(params).reduce(\n (acc, [paramKey, paramValue]) => acc.replace(`{{${paramKey}}}`, String(paramValue)),\n template\n );\n },\n [t]\n );\n\n const statusOptions = [\n { value: 'all', label: tr('vibesPage.statusAll', 'All Statuses') },\n { value: 'ACTIVE', label: tr('vibesPage.statusActive', 'Active') },\n { value: 'INACTIVE', label: tr('vibesPage.statusInactive', 'Inactive') },\n { value: 'ARCHIVED', label: tr('vibesPage.statusArchived', 'Archived') },\n { value: 'ERROR', label: tr('vibesPage.statusError', 'Error') },\n ];\n\n const typeOptions = [\n { value: 'all', label: tr('vibesPage.typeAll', 'All Types') },\n { value: 'PROJECT', label: tr('vibesPage.typeProject', 'Project') },\n { value: 'REPOSITORY', label: tr('vibesPage.typeRepository', 'Repository') },\n { value: 'WORKSPACE', label: tr('vibesPage.typeWorkspace', 'Workspace') },\n { value: 'MONOREPO', label: tr('vibesPage.typeMonorepo', 'Monorepo') },\n { value: 'PACKAGE', label: tr('vibesPage.typePackage', 'Package') },\n { value: 'CUSTOM', label: tr('vibesPage.typeCustom', 'Custom') },\n ];\n\n // Check permissions\n const canListVibes = hasPermission(VIBE_PERMISSIONS.VIBE_LIST);\n const canUpdateVibe = hasPermission(VIBE_PERMISSIONS.VIBE_UPDATE);\n\n // Skip queries until permissions are loaded and user has permission\n // This prevents FORBIDDEN errors from triggering auth error handlers\n const shouldSkipQueries = permissionsLoading || !canListVibes;\n\n const [searchQuery, setSearchQuery] = useState('');\n const [statusFilter, setStatusFilter] = useState('all');\n const [typeFilter, setTypeFilter] = useState('all');\n const [agentFilter, setAgentFilter] = useState('all');\n const [viewMode, setViewMode] = useState<ViewMode>('grid');\n const [showCreateForm, setShowCreateForm] = useState(false);\n const [createError, setCreateError] = useState<string | null>(null);\n const [createLoading, setCreateLoading] = useState(false);\n const [successMessage, setSuccessMessage] = useState<string | null>(null);\n const [showQuotaExhausted, setShowQuotaExhausted] = useState(false);\n const [fieldErrors, setFieldErrors] = useState<{ name?: string; path?: string }>({});\n const [pageError, setPageError] = useState<string | null>(null);\n const [selectedVibeIds, setSelectedVibeIds] = useState<Set<string>>(new Set());\n const [bulkAction, setBulkAction] = useState<'activate' | 'archive' | null>(null);\n const pageErrorTimer = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n useEffect(() => {\n return () => {\n if (pageErrorTimer.current) clearTimeout(pageErrorTimer.current);\n };\n }, []);\n\n const clearPageError = useCallback(() => {\n setPageError(null);\n if (pageErrorTimer.current) {\n clearTimeout(pageErrorTimer.current);\n pageErrorTimer.current = null;\n }\n }, []);\n\n // Form refs for create modal\n const nameRef = useRef<HTMLInputElement>(null);\n const pathRef = useRef<HTMLInputElement>(null);\n const agentRef = useRef<HTMLSelectElement>(null);\n const typeRef = useRef<HTMLSelectElement>(null);\n\n const [createVibe] = useCreateVibeMutation();\n const [attachAgentToVibe] = useAttachAgentToVibeMutation();\n const { setDraftTagIds, flushTags } = useDraftEntityTags('VIBECONTROLS_VIBE');\n const [updateVibeStatus] = useUpdateVibeStatusMutation();\n const [archiveVibe] = useArchiveVibeMutation();\n\n // Memoise variables so a stable identity keeps Apollo from treating each\n // render as a new query (which caused multiple loading flashes).\n // NOTE: we intentionally do NOT include `searchQuery` in the query\n // variables — the list is filtered client-side by name below, and keying\n // the query on `searchQuery` caused a fresh refetch on every keystroke\n // (previously mitigated by an unusable `limit: 1000` fire-hose). Rely on\n // the default backend pagination and filter client-side within the page.\n const listVibesVariables = useMemo(\n () => ({\n filter: {\n status:\n statusFilter !== 'all'\n ? (statusFilter as 'ACTIVE' | 'INACTIVE' | 'ARCHIVED' | 'ERROR')\n : undefined,\n type:\n typeFilter !== 'all'\n ? (typeFilter as\n | 'PROJECT'\n | 'REPOSITORY'\n | 'WORKSPACE'\n | 'MONOREPO'\n | 'PACKAGE'\n | 'CUSTOM')\n : undefined,\n // Multi-agent: server-side filter takes a list. Single-select UI maps\n // to a one-element array; \"all\" clears the filter.\n attachedAgentIds: agentFilter !== 'all' ? [agentFilter] : undefined,\n },\n }),\n [statusFilter, typeFilter, agentFilter]\n );\n\n // When no filters are applied, the variables match the InitialData\n // prefetch (no filters) — use cache-first to avoid a redundant network\n // hit on every page visit. When user actually narrows by filter, fall\n // back to cache-and-network for fresh server-side filtering.\n const noVibeFilters = statusFilter === 'all' && typeFilter === 'all' && agentFilter === 'all';\n const vibesFetchPolicy = noVibeFilters ? 'cache-first' : 'cache-and-network';\n\n // Fetch vibes from GraphQL API. cache-and-network returns the cached list\n // immediately while revalidating once in the background — avoids the\n // \"loading → cache → network → cache\" double-flash seen with cache-first\n // plus mutation refetchQueries. `notifyOnNetworkStatusChange` keeps the\n // loading flag true during refetches so the UI can show a spinner rather\n // than showing stale data silently.\n const { data, loading, error, refetch } = useListVibesQuery({\n variables: listVibesVariables,\n fetchPolicy: vibesFetchPolicy,\n nextFetchPolicy: 'cache-first',\n skip: shouldSkipQueries,\n notifyOnNetworkStatusChange: true,\n });\n\n // Cached agents (already prefetched by InitialDataPrefetcher) cover the\n // initial agent-filter dropdown without firing any network query. The\n // lazy ListAgentsQuery below is only triggered on first interaction with\n // the agent filter (in case the prefetch was stale).\n const { agents: cachedAgentsForFilter } = useCachedInitialData();\n const [fetchAgents, { data: agentsData }] = useListAgentsLazyQuery({\n fetchPolicy: 'cache-first',\n });\n const triggeredAgentsFetchRef = useRef(false);\n const handleAgentFilterInteract = useCallback(() => {\n if (triggeredAgentsFetchRef.current || shouldSkipQueries) return;\n triggeredAgentsFetchRef.current = true;\n void fetchAgents({ variables: { pagination: { limit: 100 } } });\n }, [fetchAgents, shouldSkipQueries]);\n\n // Build agent options for filter — prefer freshly-fetched data once the\n // dropdown has been opened, otherwise use the cached set from\n // InitialDataPrefetcher.\n const agentOptions = useMemo(() => {\n const live = agentsData?.vibecontrolsAgents ?? null;\n const source: Array<{ id: string; name: string }> = live\n ? live.map((a: Agent) => ({ id: a.id, name: a.name }))\n : cachedAgentsForFilter.map((a) => ({ id: a.id, name: a.name }));\n return [\n { value: 'all', label: tr('vibesPage.allAgents', 'All Agents') },\n ...source.map((agent) => ({\n value: agent.id,\n label: agent.name,\n })),\n ];\n }, [agentsData?.vibecontrolsAgents, cachedAgentsForFilter, tr]);\n\n // Map GraphQL response to Vibe type\n const vibes: Vibe[] = useMemo(() => {\n const rawVibes = data?.vibes?.items ?? [];\n return rawVibes.map((vibe: NonNullable<typeof rawVibes>[number]) => ({\n id: vibe.id,\n workspaceId: vibe.workspaceId,\n name: vibe.name,\n description: vibe.description || null,\n type: vibe.type as Vibe['type'],\n status: vibe.status as Vibe['status'],\n path: vibe.path || null,\n parentId: vibe.parentId || null,\n gitBranch: vibe.gitBranch || null,\n gitRemote: vibe.gitRemote || null,\n gitStatus: vibe.gitStatus\n ? typeof vibe.gitStatus === 'string'\n ? vibe.gitStatus\n : typeof vibe.gitStatus === 'object' &&\n vibe.gitStatus !== null &&\n 'status' in vibe.gitStatus\n ? String((vibe.gitStatus as Record<string, unknown>).status)\n : JSON.stringify(vibe.gitStatus)\n : null,\n environmentVariables: (vibe.environmentVariables as Record<string, string>) || {},\n tags: vibe.tags || [],\n metadata: (vibe.metadata as Record<string, unknown>) || {},\n createdAt: vibe.createdAt,\n updatedAt: vibe.updatedAt,\n agents: (vibe.agents ?? []).map((a: NonNullable<typeof vibe.agents>[number]) => ({\n id: a.id,\n name: a.name,\n isActive: a.isActive,\n ownerUserId: a.ownerUserId ?? null,\n })),\n }));\n }, [data?.vibes?.items]);\n\n // Filter vibes based on search (client-side filtering for search)\n const filteredVibes = useMemo(() => {\n return vibes.filter((vibe) => {\n // Search filter\n if (searchQuery) {\n const query = searchQuery.toLowerCase();\n const matchesSearch =\n vibe.name.toLowerCase().includes(query) ||\n vibe.description?.toLowerCase().includes(query) ||\n vibe.path?.toLowerCase().includes(query) ||\n vibe.tags?.some((tag) => tag.toLowerCase().includes(query));\n if (!matchesSearch) return false;\n }\n\n return true;\n });\n }, [vibes, searchQuery]);\n\n const selectedVibes = useMemo(\n () => vibes.filter((vibe) => selectedVibeIds.has(vibe.id)),\n [vibes, selectedVibeIds]\n );\n const activatableVibes = selectedVibes.filter((vibe) => vibe.status !== 'ACTIVE');\n const archivableVibes = selectedVibes.filter((vibe) => vibe.status !== 'ARCHIVED');\n const allVisibleSelected =\n filteredVibes.length > 0 && filteredVibes.every((vibe) => selectedVibeIds.has(vibe.id));\n const partiallySelected =\n filteredVibes.some((vibe) => selectedVibeIds.has(vibe.id)) && !allVisibleSelected;\n\n const handleVibeSelect = (vibe: Vibe) => {\n navigate(`/vibes/${vibe.id}`);\n };\n\n const handleVibeActivate = async (vibe: Vibe) => {\n try {\n const result = await updateVibeStatus({\n variables: { id: vibe.id, status: 'ACTIVE' as const },\n });\n if (result.data?.updateVibeStatus) {\n onVibeActivate?.({ id: vibe.id, name: vibe.name, type: vibe.type, status: 'ACTIVE' });\n }\n } catch (err) {\n console.error('Failed to activate vibe:', err);\n }\n };\n\n const handleVibeArchive = async (vibe: Vibe) => {\n try {\n await archiveVibe({ variables: { id: vibe.id } });\n } catch (err) {\n console.error('Failed to archive vibe:', err);\n }\n };\n\n // Honour the user's preferred IDE + per-Vibe override when opening from\n // the card. Falls back to `vscode://` for IDEs without a registered URL\n // protocol; for richer launching (agent-exec, browser editor) use the\n // VibeOpenInEditorMenu on the Vibe detail page.\n const preferredIdeCommand = useVibeControlsStore((s) => s.preferredIdeCommand);\n const vibeIdeOverrides = useVibeControlsStore((s) => s.vibeIdeOverrides);\n\n const handleOpenInEditor = (vibe: Vibe) => {\n if (!vibe.path) {\n setPageError(tr('vibesPage.openEditorPathMissing', 'No path available to open in editor'));\n pageErrorTimer.current = setTimeout(() => {\n setPageError(null);\n pageErrorTimer.current = null;\n }, 3000);\n return;\n }\n const cmd = resolveEffectiveIdeCommand(vibe.id, preferredIdeCommand, vibeIdeOverrides);\n const preset = getIdePreset(cmd);\n const url = preset ? buildProtocolUrl(preset, vibe.path) : `vscode://file/${vibe.path}`;\n if (url) {\n window.location.href = url;\n } else {\n setPageError(\n tr(\n 'vibesPage.openEditorNoProtocol',\n `${preset?.label ?? cmd} has no URL handler — open this Vibe and use the editor menu.`\n )\n );\n pageErrorTimer.current = setTimeout(() => {\n setPageError(null);\n pageErrorTimer.current = null;\n }, 4000);\n }\n };\n\n const handleCreateVibe = () => {\n setCreateError(null);\n setShowCreateForm(true);\n // Ensure the create-form agent dropdown has options even if the user\n // never opened the page-level agent filter.\n handleAgentFilterInteract();\n };\n\n const toggleVibeSelection = (vibe: Vibe, checked: boolean) => {\n setSelectedVibeIds((prev) => {\n const next = new Set(prev);\n if (checked) {\n next.add(vibe.id);\n } else {\n next.delete(vibe.id);\n }\n return next;\n });\n };\n\n const toggleAllVisibleVibes = (checked: boolean) => {\n setSelectedVibeIds((prev) => {\n const next = new Set(prev);\n filteredVibes.forEach((vibe) => {\n if (checked) {\n next.add(vibe.id);\n } else {\n next.delete(vibe.id);\n }\n });\n return next;\n });\n };\n\n const clearSelection = () => setSelectedVibeIds(new Set());\n\n const handleBulkActivate = async () => {\n if (activatableVibes.length === 0) return;\n\n const results = await Promise.allSettled(\n activatableVibes.map((vibe) =>\n updateVibeStatus({ variables: { id: vibe.id, status: 'ACTIVE' as const } })\n )\n );\n\n const succeeded = results.filter((result) => result.status === 'fulfilled').length;\n const failed = results.length - succeeded;\n\n setSuccessMessage(\n `Activated ${succeeded} vibe${succeeded === 1 ? '' : 's'}${failed > 0 ? ` • ${failed} failed` : ''}`\n );\n setTimeout(() => setSuccessMessage(null), 4000);\n clearSelection();\n setBulkAction(null);\n await refetch();\n };\n\n const handleBulkArchive = async () => {\n if (archivableVibes.length === 0) return;\n\n const results = await Promise.allSettled(\n archivableVibes.map((vibe) => archiveVibe({ variables: { id: vibe.id } }))\n );\n\n const succeeded = results.filter((result) => result.status === 'fulfilled').length;\n const failed = results.length - succeeded;\n\n setSuccessMessage(\n `Archived ${succeeded} vibe${succeeded === 1 ? '' : 's'}${failed > 0 ? ` • ${failed} failed` : ''}`\n );\n setTimeout(() => setSuccessMessage(null), 4000);\n clearSelection();\n setBulkAction(null);\n await refetch();\n };\n\n const handleSubmitCreateVibe = async () => {\n const name = nameRef.current?.value?.trim();\n const path = pathRef.current?.value?.trim();\n const agentId = agentRef.current?.value;\n const type = typeRef.current?.value;\n\n const errors: { name?: string; path?: string } = {};\n if (!name) errors.name = tr('vibesPage.nameRequired', 'Name is required');\n if (!path) errors.path = tr('vibesPage.pathRequired', 'Path is required');\n if (errors.name || errors.path) {\n setFieldErrors(errors);\n setCreateError(tr('vibesPage.fillRequired', 'Please fill in all required fields'));\n return;\n }\n setFieldErrors({});\n\n // Validate type against allowed enum values\n const validTypes = [\n 'PROJECT',\n 'REPOSITORY',\n 'WORKSPACE',\n 'MONOREPO',\n 'PACKAGE',\n 'CUSTOM',\n ] as const;\n const resolvedType = validTypes.includes(type as (typeof validTypes)[number])\n ? (type as (typeof validTypes)[number])\n : 'PROJECT';\n\n setCreateLoading(true);\n setCreateError(null);\n try {\n const result = await createVibe({\n variables: {\n input: {\n name,\n path,\n type: resolvedType,\n },\n },\n });\n if (!result.data?.createVibe?.id) {\n throw new Error(tr('vibesPage.failedCreate', 'Failed to create vibe'));\n }\n const newVibeId = result.data.createVibe.id;\n // Multi-agent: vibes are created agent-less; attach the optionally\n // selected agent afterward via the attachment mutation (the old\n // `agentId` field on CreateVibeInput was removed server-side).\n if (agentId) {\n await attachAgentToVibe({\n variables: { input: { vibeId: newVibeId, agentId } },\n });\n }\n setShowCreateForm(false);\n setSuccessMessage(tr('vibesPage.createdSuccess', 'Vibe created successfully'));\n await flushTags(newVibeId);\n await refetch();\n setTimeout(() => setSuccessMessage(null), 3000);\n } catch (err) {\n if (isQuotaExhaustedError(err)) {\n setShowCreateForm(false);\n setCreateError(null);\n setFieldErrors({});\n setShowQuotaExhausted(true);\n return;\n }\n\n setCreateError(\n err instanceof Error ? err.message : tr('vibesPage.failedCreate', 'Failed to create vibe')\n );\n } finally {\n setCreateLoading(false);\n }\n };\n\n // Stats\n const stats = {\n total: vibes.length,\n active: vibes.filter((v) => v.status === 'ACTIVE').length,\n inactive: vibes.filter((v) => v.status === 'INACTIVE').length,\n };\n\n // Collapse guard states into a single MotionPage shell so transitioning\n // between loading / error / data does not unmount+remount and replay the\n // entrance animation. Contents are swapped in-place.\n const showPermissionsLoading = permissionsLoading;\n const showAccessDenied =\n !permissionsLoading &&\n !!permissions &&\n (permissions.permissionStrings?.length ?? 0) > 0 &&\n !canListVibes;\n const showInitialLoading =\n !showPermissionsLoading && !showAccessDenied && loading && vibes.length === 0;\n const showInitialError =\n !showPermissionsLoading && !showAccessDenied && !!error && vibes.length === 0;\n const showDataShell = !showPermissionsLoading && !showAccessDenied && !showInitialError;\n\n return (\n <MotionPage className=\"space-y-6 p-4 sm:p-6 bg-bg-surface min-h-screen\">\n {showPermissionsLoading && (\n <LoadingState message={tr('vibesPage.loadingPermissions', 'Loading permissions...')} />\n )}\n {showAccessDenied && (\n <AccessDenied\n title={tr('vibesPage.accessDeniedTitle', 'Access Denied')}\n description={tr(\n 'vibesPage.accessDeniedDescription',\n \"You don't have permission to view vibes. Contact your workspace administrator for access.\"\n )}\n />\n )}\n {showInitialError && (\n <ErrorState\n title={tr('vibesPage.failedLoad', 'Failed to load vibes')}\n message={error?.message ?? ''}\n onRetry={() => refetch()}\n />\n )}\n {showDataShell && (\n <>\n <PageHeader\n title={tr('vibesPage.title', 'Vibes')}\n description={tr('vibesPage.descriptionActive', '{{active}} of {{total}} vibes active', {\n active: stats.active,\n total: stats.total,\n })}\n actions={\n <div className=\"flex items-center gap-2\">\n <button\n onClick={() => refetch()}\n disabled={loading}\n className=\"flex items-center gap-2 px-3 py-2 text-text-secondary hover:bg-bg-sunken rounded-md transition-colors disabled:opacity-50\"\n title={tr('vibesPage.refreshTitle', 'Refresh vibes')}\n >\n <RefreshCw className={`w-4 h-4 ${loading ? 'animate-spin' : ''}`} />\n </button>\n <PermissionButton\n permission={VIBE_PERMISSIONS.VIBE_CREATE}\n deniedBehavior=\"disable\"\n deniedTooltip={tr(\n 'vibesPage.deniedCreateTooltip',\n \"You don't have permission to create vibes\"\n )}\n >\n <button\n onClick={handleCreateVibe}\n className=\"flex items-center gap-2 px-4 py-2 bg-action-primary-bg text-action-primary-text rounded-md hover:bg-action-primary-bg-hover transition-colors disabled:opacity-50 disabled:cursor-not-allowed\"\n >\n <Plus className=\"w-4 h-4\" />\n {tr('vibesPage.addVibe', 'Add Vibe')}\n </button>\n </PermissionButton>\n </div>\n }\n />\n\n {/* Filters Bar */}\n <div className=\"space-y-3\">\n {/* Row 1: Search + View Toggle */}\n <div className=\"flex items-center gap-2\">\n <SearchInput\n value={searchQuery}\n onChange={setSearchQuery}\n placeholder={tr('vibesPage.searchPlaceholder', 'Search vibes...')}\n className=\"flex-1 sm:w-64 sm:flex-none\"\n />\n {/* View Toggle */}\n <div className=\"flex items-center gap-1 bg-bg-sunken rounded-md p-1 flex-shrink-0\">\n <button\n onClick={() => setViewMode('grid')}\n className={`p-1.5 sm:p-2 rounded ${viewMode === 'grid' ? 'bg-bg-surface shadow-sm' : 'hover:bg-bg-surface/50'}`}\n title={tr('vibesPage.gridViewTitle', 'Grid view')}\n >\n <Grid className=\"w-4 h-4 text-text-secondary\" />\n </button>\n <button\n onClick={() => setViewMode('list')}\n className={`p-1.5 sm:p-2 rounded ${viewMode === 'list' ? 'bg-bg-surface shadow-sm' : 'hover:bg-bg-surface/50'}`}\n title={tr('vibesPage.listViewTitle', 'List view')}\n >\n <List className=\"w-4 h-4 text-text-secondary\" />\n </button>\n </div>\n </div>\n\n {/* Row 2: Filters - wrap on all screens */}\n <div className=\"flex items-center gap-2 sm:gap-3 flex-wrap\">\n <FilterDropdown\n label={tr('vibesPage.filterStatus', 'Status')}\n value={statusFilter}\n options={statusOptions}\n onChange={setStatusFilter}\n />\n <div onMouseDown={handleAgentFilterInteract} onFocus={handleAgentFilterInteract}>\n <FilterDropdown\n label={tr('vibesPage.filterAgent', 'Agent')}\n value={agentFilter}\n options={agentOptions}\n onChange={setAgentFilter}\n />\n </div>\n </div>\n </div>\n\n {/* Results Count */}\n {searchQuery ||\n statusFilter !== 'all' ||\n typeFilter !== 'all' ||\n agentFilter !== 'all' ? (\n <p className=\"text-sm text-text-secondary\">\n {tr('vibesPage.showingResults', 'Showing {{filtered}} of {{total}} vibes', {\n filtered: filteredVibes.length,\n total: vibes.length,\n })}\n {loading && (\n <span className=\"ml-2 text-text-muted\">\n {tr('vibesPage.refreshing', '(refreshing...)')}\n </span>\n )}\n </p>\n ) : null}\n\n {filteredVibes.length > 0 && (\n <div className=\"rounded-lg border border-border-default bg-bg-surface p-4\">\n <div className=\"flex flex-col gap-3 lg:flex-row lg:items-center lg:justify-between\">\n <div className=\"flex flex-wrap items-center gap-3\">\n <div className=\"flex items-center gap-2\">\n <SelectionCheckbox\n checked={allVisibleSelected}\n indeterminate={partiallySelected}\n onChange={toggleAllVisibleVibes}\n ariaLabel=\"Select all visible vibes\"\n />\n <span className=\"text-sm font-medium text-text-primary\">\n Select all visible\n </span>\n </div>\n {selectedVibeIds.size > 0 && (\n <button\n onClick={clearSelection}\n className=\"text-sm text-text-secondary hover:text-text-primary\"\n >\n Clear selection\n </button>\n )}\n </div>\n\n <div className=\"flex flex-wrap items-center gap-2\">\n <span className=\"rounded-full bg-bg-sunken px-3 py-1 text-sm font-medium text-text-secondary\">\n {selectedVibeIds.size} selected\n </span>\n <button\n onClick={() => setBulkAction('activate')}\n disabled={activatableVibes.length === 0}\n title=\"Mark selected vibes as ACTIVE so they appear in the default vibe list and can run sessions/tunnels via their attached agent(s).\"\n className=\"rounded-md border border-status-success-border px-3 py-2 text-sm font-medium text-status-success-text hover:bg-status-success-bg disabled:cursor-not-allowed disabled:opacity-50\"\n >\n <span className=\"inline-flex items-center gap-2\">\n <Play className=\"w-4 h-4\" />\n Activate Selected\n {activatableVibes.length > 0 ? ` (${activatableVibes.length})` : ''}\n </span>\n </button>\n <button\n onClick={() => setBulkAction('archive')}\n disabled={archivableVibes.length === 0}\n className=\"rounded-md border border-status-warning-border px-3 py-2 text-sm font-medium text-status-warning-text hover:bg-status-warning-bg disabled:cursor-not-allowed disabled:opacity-50\"\n >\n <span className=\"inline-flex items-center gap-2\">\n <Archive className=\"w-4 h-4\" />\n Archive Selected\n {archivableVibes.length > 0 ? ` (${archivableVibes.length})` : ''}\n </span>\n </button>\n </div>\n </div>\n </div>\n )}\n\n {/* Vibes Display */}\n {showInitialLoading ? (\n <PageSkeleton variant=\"cards\" count={6} />\n ) : filteredVibes.length > 0 ? (\n <AnimatePresence mode=\"wait\">\n {viewMode === 'grid' ? (\n <MotionList\n key=\"grid\"\n stagger={0.04}\n className=\"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4\"\n >\n {filteredVibes.map((vibe) => (\n <MotionItem key={vibe.id}>\n <VibeCard\n vibe={vibe}\n onOpen={handleVibeSelect}\n onActivate={canUpdateVibe ? handleVibeActivate : undefined}\n onArchive={canUpdateVibe ? handleVibeArchive : undefined}\n onOpenInEditor={handleOpenInEditor}\n selected={selectedVibeIds.has(vibe.id)}\n onToggleSelect={(checked) => toggleVibeSelection(vibe, checked)}\n />\n </MotionItem>\n ))}\n </MotionList>\n ) : (\n <MotionList key=\"list\">\n <VibeList\n vibes={filteredVibes}\n onOpen={handleVibeSelect}\n onActivate={handleVibeActivate}\n onArchive={handleVibeArchive}\n onOpenInEditor={handleOpenInEditor}\n selectedVibeIds={selectedVibeIds}\n onToggleSelect={toggleVibeSelection}\n onToggleAllVisible={toggleAllVisibleVibes}\n allVisibleSelected={allVisibleSelected}\n partiallySelected={partiallySelected}\n />\n </MotionList>\n )}\n </AnimatePresence>\n ) : (\n <EmptyState\n icon={<Zap className=\"w-8 h-8 text-text-secondary\" />}\n title={\n searchQuery ||\n statusFilter !== 'all' ||\n typeFilter !== 'all' ||\n agentFilter !== 'all'\n ? tr('vibesPage.emptyNoVibesFound', 'No vibes found')\n : tr('vibesPage.emptyNoVibesConfigured', 'No vibes configured')\n }\n description={\n searchQuery ||\n statusFilter !== 'all' ||\n typeFilter !== 'all' ||\n agentFilter !== 'all'\n ? tr('vibesPage.emptyAdjustSearch', 'Try adjusting your search or filters')\n : tr(\n 'vibesPage.emptyNoVibesDescription',\n 'Add your first vibe to start managing your development projects'\n )\n }\n action={\n !searchQuery &&\n statusFilter === 'all' &&\n typeFilter === 'all' &&\n agentFilter === 'all' ? (\n <div className=\"flex items-center gap-2\">\n <PermissionGate permission={VIBE_PERMISSIONS.VIBE_CREATE}>\n <button\n onClick={handleCreateVibe}\n className=\"flex items-center gap-2 px-4 py-2 bg-action-primary-bg text-action-primary-text rounded-md hover:bg-action-primary-bg-hover transition-colors\"\n >\n <Plus className=\"w-4 h-4\" />\n {tr('vibesPage.addVibe', 'Add Vibe')}\n </button>\n </PermissionGate>\n <GetHelpButton prompt=\"What is a Vibe in VibeControls and how do I create one?\" />\n </div>\n ) : undefined\n }\n />\n )}\n\n {/* Success Toast */}\n {successMessage && (\n <div className=\"fixed bottom-4 right-4 z-50 px-4 py-3 bg-status-success-bg text-status-success-text rounded-md shadow-lg text-sm\">\n {successMessage}\n </div>\n )}\n\n <ConfirmDialog\n isOpen={bulkAction === 'activate'}\n onClose={() => setBulkAction(null)}\n onConfirm={handleBulkActivate}\n title=\"Activate selected vibes\"\n message={`Activate ${activatableVibes.length} selected vibe${activatableVibes.length === 1 ? '' : 's'}?`}\n confirmLabel=\"Activate\"\n variant=\"default\"\n />\n\n <ConfirmDialog\n isOpen={bulkAction === 'archive'}\n onClose={() => setBulkAction(null)}\n onConfirm={handleBulkArchive}\n title=\"Archive selected vibes\"\n message={`Archive ${archivableVibes.length} selected vibe${archivableVibes.length === 1 ? '' : 's'}? Archived vibes will be hidden from active workflows.`}\n confirmLabel=\"Archive\"\n variant=\"warning\"\n />\n\n {/* Page-level Error Toast */}\n {pageError && (\n <div\n role=\"alert\"\n className=\"fixed bottom-4 right-4 z-50 px-4 py-3 bg-status-error-bg text-status-error-text rounded-md shadow-lg text-sm\"\n >\n {pageError}\n <button\n onClick={clearPageError}\n className=\"ml-3 text-xs underline opacity-80 hover:opacity-100\"\n >\n {tr('vibesPage.dismiss', 'Dismiss')}\n </button>\n </div>\n )}\n\n {/* Create Vibe Modal */}\n {showCreateForm && (\n <div className=\"fixed inset-0 bg-bg-overlay flex items-center justify-center z-50 p-4\">\n <div className=\"bg-bg-surface rounded-lg p-6 w-full max-w-lg\">\n <h2 className=\"text-lg font-semibold text-text-primary mb-4\">\n {tr('vibesPage.addNewVibe', 'Add New Vibe')}\n </h2>\n <div className=\"space-y-4\">\n {createError && (\n <div className=\"p-3 bg-status-error-bg text-status-error-text text-sm rounded-md\">\n {createError}\n </div>\n )}\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-1\">\n {tr('vibesPage.nameLabel', 'Name *')}\n </label>\n <input\n ref={nameRef}\n type=\"text\"\n placeholder={tr('vibesPage.namePlaceholder', 'My Project')}\n onChange={() =>\n fieldErrors.name && setFieldErrors((e) => ({ ...e, name: undefined }))\n }\n className={`w-full px-3 py-2 bg-bg-sunken border rounded-md text-text-primary placeholder:text-text-placeholder ${fieldErrors.name ? 'border-status-error-border' : 'border-border-default'}`}\n />\n {fieldErrors.name && (\n <p className=\"mt-1 text-xs text-status-error-text\">{fieldErrors.name}</p>\n )}\n </div>\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-1\">\n {tr('vibesPage.pathLabel', 'Path *')}\n </label>\n <input\n ref={pathRef}\n type=\"text\"\n placeholder={tr('vibesPage.pathPlaceholder', '/path/to/project')}\n onChange={() =>\n fieldErrors.path && setFieldErrors((e) => ({ ...e, path: undefined }))\n }\n className={`w-full px-3 py-2 bg-bg-sunken border rounded-md text-text-primary placeholder:text-text-placeholder ${fieldErrors.path ? 'border-status-error-border' : 'border-border-default'}`}\n />\n {fieldErrors.path && (\n <p className=\"mt-1 text-xs text-status-error-text\">{fieldErrors.path}</p>\n )}\n </div>\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-1\">\n {tr('vibesPage.agentLabel', 'Agent')}\n </label>\n <select\n ref={agentRef}\n className=\"w-full px-3 py-2 bg-bg-sunken border border-border-default rounded-md text-text-primary\"\n >\n <option value=\"\">{tr('vibesPage.selectAgent', 'Select an agent')}</option>\n {agentOptions\n .filter((opt) => opt.value !== 'all')\n .map((agent) => (\n <option key={agent.value} value={agent.value}>\n {agent.label}\n </option>\n ))}\n </select>\n </div>\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-1\">\n {tr('vibesPage.typeLabel', 'Type')}\n </label>\n <select\n ref={typeRef}\n className=\"w-full px-3 py-2 bg-bg-sunken border border-border-default rounded-md text-text-primary\"\n >\n <option value=\"PROJECT\">{tr('vibesPage.typeProject', 'Project')}</option>\n <option value=\"REPOSITORY\">\n {tr('vibesPage.typeRepository', 'Repository')}\n </option>\n <option value=\"WORKSPACE\">\n {tr('vibesPage.typeWorkspace', 'Workspace')}\n </option>\n <option value=\"MONOREPO\">{tr('vibesPage.typeMonorepo', 'Monorepo')}</option>\n <option value=\"PACKAGE\">{tr('vibesPage.typePackage', 'Package')}</option>\n <option value=\"CUSTOM\">{tr('vibesPage.typeCustom', 'Custom')}</option>\n </select>\n </div>\n </div>\n <div className=\"mt-4 border-t border-border-default pt-4\">\n <h3 className=\"text-sm font-medium text-text-secondary mb-2\">\n {tr('vibesPage.tags', 'Tags')}\n </h3>\n <EntityTagPicker entityType=\"VIBECONTROLS_VIBE\" onDraftChange={setDraftTagIds} />\n </div>\n <div className=\"flex flex-col sm:flex-row justify-end gap-3 mt-6\">\n <button\n onClick={() => setShowCreateForm(false)}\n disabled={createLoading}\n className=\"px-4 py-2 text-text-primary hover:bg-bg-sunken rounded-md transition-colors disabled:opacity-50\"\n >\n {tr('vibesPage.cancel', 'Cancel')}\n </button>\n <button\n onClick={handleSubmitCreateVibe}\n disabled={createLoading}\n className=\"px-4 py-2 bg-action-primary-bg text-action-primary-text rounded-md hover:bg-action-primary-bg-hover transition-colors disabled:opacity-50\"\n >\n {createLoading\n ? tr('vibesPage.creating', 'Creating...')\n : tr('vibesPage.createVibe', 'Create Vibe')}\n </button>\n </div>\n </div>\n </div>\n )}\n\n <QuotaExhaustedDialog\n isOpen={showQuotaExhausted}\n onClose={() => setShowQuotaExhausted(false)}\n onConfirm={() => {\n setShowQuotaExhausted(false);\n navigate('/billing');\n }}\n title=\"Vibe Quota Reached\"\n message=\"You've used all available vibe creation quota on your current plan. Upgrade your plan to create more vibes.\"\n />\n </>\n )}\n </MotionPage>\n );\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@burdenoff/microfe-vibecontrols",
3
- "version": "2026.523.2",
3
+ "version": "2026.524.1",
4
4
  "description": "VibeControls microfrontend for Burdenoff products",
5
5
  "type": "module",
6
6
  "files": [