@burdenoff/microfe-vibecontrols 2026.601.21 → 2026.601.22

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.
Files changed (28) hide show
  1. package/dist/components/actions/ActionCard.js +77 -66
  2. package/dist/components/actions/ActionCard.js.map +1 -1
  3. package/dist/components/ai/AIContextsTab.js +186 -173
  4. package/dist/components/ai/AIContextsTab.js.map +1 -1
  5. package/dist/components/ai/AITemplatesTab.js +135 -125
  6. package/dist/components/ai/AITemplatesTab.js.map +1 -1
  7. package/dist/components/ai/InstructionFilesManager.js +151 -137
  8. package/dist/components/ai/InstructionFilesManager.js.map +1 -1
  9. package/dist/components/notes/NotesTabPanel.js +8 -8
  10. package/dist/components/sharing/EntityShareButton.js +58 -0
  11. package/dist/components/sharing/EntityShareButton.js.map +1 -0
  12. package/dist/components/sharing/entityShareOps.js +277 -0
  13. package/dist/components/sharing/entityShareOps.js.map +1 -0
  14. package/dist/components/sharing/index.js +3 -0
  15. package/dist/components/sharing/shareRegistry.js +25 -0
  16. package/dist/components/sharing/shareRegistry.js.map +1 -1
  17. package/dist/components/sharing/useEntityShareController.js +88 -0
  18. package/dist/components/sharing/useEntityShareController.js.map +1 -0
  19. package/dist/constants/permissions.js +5 -0
  20. package/dist/constants/permissions.js.map +1 -1
  21. package/dist/pages/ActionsPage.js +162 -162
  22. package/dist/pages/ActionsPage.js.map +1 -1
  23. package/dist/pages/VibeDeckPage.js +1 -1
  24. package/dist/pages/VibeDetailsPage.js +484 -484
  25. package/dist/pages/VibeDetailsPage.js.map +1 -1
  26. package/dist/pages/tunnels/TunnelDetailsPage.js +91 -77
  27. package/dist/pages/tunnels/TunnelDetailsPage.js.map +1 -1
  28. package/package.json +1 -1
@@ -4,145 +4,159 @@ import { PageHeader as n } from "../../components/shared/PageHeader.js";
4
4
  import { LoadingState as r } from "../../components/shared/LoadingState.js";
5
5
  import { ErrorState as i } from "../../components/shared/ErrorState.js";
6
6
  import { EntityTagPicker as a } from "../../components/shared/EntityTagPicker.js";
7
- import { TunnelStatusBadge as o } from "../../components/tunnels/TunnelStatusBadge.js";
8
- import { ProviderBadge as s } from "../../components/tunnels/ProviderBadge.js";
9
- import { TunnelOverviewTab as c } from "./tabs/TunnelOverviewTab.js";
10
- import { TunnelEndpointsTab as l } from "./tabs/TunnelEndpointsTab.js";
11
- import { TunnelSessionsTab as u } from "./tabs/TunnelSessionsTab.js";
12
- import { TunnelDomainsTab as d } from "./tabs/TunnelDomainsTab.js";
13
- import { TunnelUsageTab as f } from "./tabs/TunnelUsageTab.js";
14
- import { TunnelCliTab as p } from "./tabs/TunnelCliTab.js";
15
- import { TunnelAuditTab as m } from "./tabs/TunnelAuditTab.js";
16
- import { TunnelSettingsTab as h } from "./tabs/TunnelSettingsTab.js";
17
- import { useEffect as g, useMemo as _ } from "react";
18
- import { ArrowLeft as v, Tag as y } from "lucide-react";
19
- import { useNavigate as b, useParams as x, useSearchParams as S } from "react-router-dom";
20
- import { jsx as C, jsxs as w } from "react/jsx-runtime";
21
- import { Tabs as T } from "@burdenoff/fe-libs/chrome";
7
+ import { EntityShareButton as o } from "../../components/sharing/EntityShareButton.js";
8
+ import "../../components/sharing/index.js";
9
+ import { TunnelStatusBadge as s } from "../../components/tunnels/TunnelStatusBadge.js";
10
+ import { ProviderBadge as c } from "../../components/tunnels/ProviderBadge.js";
11
+ import { TunnelOverviewTab as l } from "./tabs/TunnelOverviewTab.js";
12
+ import { TunnelEndpointsTab as u } from "./tabs/TunnelEndpointsTab.js";
13
+ import { TunnelSessionsTab as d } from "./tabs/TunnelSessionsTab.js";
14
+ import { TunnelDomainsTab as f } from "./tabs/TunnelDomainsTab.js";
15
+ import { TunnelUsageTab as p } from "./tabs/TunnelUsageTab.js";
16
+ import { TunnelCliTab as m } from "./tabs/TunnelCliTab.js";
17
+ import { TunnelAuditTab as h } from "./tabs/TunnelAuditTab.js";
18
+ import { TunnelSettingsTab as g } from "./tabs/TunnelSettingsTab.js";
19
+ import { useEffect as _, useMemo as v } from "react";
20
+ import { ArrowLeft as y, Tag as b } from "lucide-react";
21
+ import { useNavigate as x, useParams as S, useSearchParams as C } from "react-router-dom";
22
+ import { jsx as w, jsxs as T } from "react/jsx-runtime";
23
+ import { Tabs as E } from "@burdenoff/fe-libs/chrome";
22
24
  //#region src/pages/tunnels/TunnelDetailsPage.tsx
23
- function E() {
24
- let E = t(), { tunnelId: D = "" } = x(), O = b(), [k, A] = S(), { data: j, loading: M, error: N, refetch: P, startPolling: F, stopPolling: I } = e({
25
- variables: { id: D },
25
+ function D() {
26
+ let D = t(), { tunnelId: O = "" } = S(), k = x(), [A, j] = C(), { data: M, loading: N, error: P, refetch: F, startPolling: I, stopPolling: L } = e({
27
+ variables: { id: O },
26
28
  fetchPolicy: "cache-and-network",
27
- skip: !D
28
- }), L = j?.tunnel?.status === "PROVISIONING" || j?.tunnel?.status === "DELETING" || j?.tunnel?.status === "ACTIVE" && !j.tunnel.primaryDomain?.hostname;
29
- g(() => {
30
- L ? F(4e3) : I();
29
+ skip: !O
30
+ }), R = M?.tunnel?.status === "PROVISIONING" || M?.tunnel?.status === "DELETING" || M?.tunnel?.status === "ACTIVE" && !M.tunnel.primaryDomain?.hostname;
31
+ _(() => {
32
+ R ? I(4e3) : L();
31
33
  }, [
32
- L,
33
- F,
34
- I
34
+ R,
35
+ I,
36
+ L
35
37
  ]);
36
- let R = _(() => [
38
+ let z = v(() => [
37
39
  {
38
40
  id: "overview",
39
- label: E("vibecontrols.tunnels.detail.overview", "Overview")
41
+ label: D("vibecontrols.tunnels.detail.overview", "Overview")
40
42
  },
41
43
  {
42
44
  id: "endpoints",
43
- label: E("vibecontrols.tunnels.detail.endpoints", "Endpoints")
45
+ label: D("vibecontrols.tunnels.detail.endpoints", "Endpoints")
44
46
  },
45
47
  {
46
48
  id: "sessions",
47
- label: E("vibecontrols.tunnels.detail.sessions", "Sessions")
49
+ label: D("vibecontrols.tunnels.detail.sessions", "Sessions")
48
50
  },
49
51
  {
50
52
  id: "domains",
51
- label: E("vibecontrols.tunnels.detail.domains", "Domains")
53
+ label: D("vibecontrols.tunnels.detail.domains", "Domains")
52
54
  },
53
55
  {
54
56
  id: "usage",
55
- label: E("vibecontrols.tunnels.detail.usage", "Usage")
57
+ label: D("vibecontrols.tunnels.detail.usage", "Usage")
56
58
  },
57
59
  {
58
60
  id: "cli",
59
- label: E("vibecontrols.tunnels.detail.cli", "CLI")
61
+ label: D("vibecontrols.tunnels.detail.cli", "CLI")
60
62
  },
61
63
  {
62
64
  id: "audit",
63
- label: E("vibecontrols.tunnels.detail.audit", "Audit")
65
+ label: D("vibecontrols.tunnels.detail.audit", "Audit")
64
66
  },
65
67
  {
66
68
  id: "settings",
67
- label: E("vibecontrols.tunnels.detail.settings", "Settings")
69
+ label: D("vibecontrols.tunnels.detail.settings", "Settings")
68
70
  }
69
- ], [E]), z = k.get("tab") ?? R[0].id, B = (e) => {
70
- let t = new URLSearchParams(k);
71
- e === R[0].id ? t.delete("tab") : t.set("tab", e), A(t, { replace: !0 });
71
+ ], [D]), B = A.get("tab") ?? z[0].id, V = (e) => {
72
+ let t = new URLSearchParams(A);
73
+ e === z[0].id ? t.delete("tab") : t.set("tab", e), j(t, { replace: !0 });
72
74
  };
73
- if (M && !j) return /* @__PURE__ */ C(r, { message: "Loading tunnel" });
74
- if (N) return /* @__PURE__ */ C(i, {
75
+ if (N && !M) return /* @__PURE__ */ w(r, { message: "Loading tunnel" });
76
+ if (P) return /* @__PURE__ */ w(i, {
75
77
  title: "Failed to load tunnel",
76
- message: N.message,
77
- onRetry: () => P()
78
+ message: P.message,
79
+ onRetry: () => F()
78
80
  });
79
- if (!j?.tunnel) return /* @__PURE__ */ C(i, {
81
+ if (!M?.tunnel) return /* @__PURE__ */ w(i, {
80
82
  title: "Tunnel not found",
81
83
  message: "This tunnel may have been deleted.",
82
- onRetry: () => O("/vibecontrols/tunnels")
84
+ onRetry: () => k("/vibecontrols/tunnels")
83
85
  });
84
- let V = j.tunnel;
85
- return /* @__PURE__ */ w("div", {
86
+ let H = M.tunnel;
87
+ return /* @__PURE__ */ T("div", {
86
88
  className: "flex flex-col h-full",
87
89
  children: [
88
- /* @__PURE__ */ w("div", {
90
+ /* @__PURE__ */ T("div", {
89
91
  className: "px-6 pt-6 pb-2 border-b border-border-subtle",
90
92
  children: [
91
- /* @__PURE__ */ w("button", {
93
+ /* @__PURE__ */ T("button", {
92
94
  type: "button",
93
- onClick: () => O("/vibecontrols/tunnels"),
95
+ onClick: () => k("/vibecontrols/tunnels"),
94
96
  className: "flex items-center gap-1.5 mb-4 text-sm text-text-secondary hover:text-text-primary transition-colors",
95
- children: [/* @__PURE__ */ C(v, { size: 16 }), "Back to Tunnels"]
97
+ children: [/* @__PURE__ */ w(y, { size: 16 }), "Back to Tunnels"]
96
98
  }),
97
- /* @__PURE__ */ C(n, {
99
+ /* @__PURE__ */ w(n, {
98
100
  breadcrumb: [{
99
101
  label: "Tunnels",
100
102
  path: "/vibecontrols/tunnels"
101
- }, { label: V.name }],
102
- title: V.name,
103
- description: V.description ?? `${V.protocol}:${V.localPort} on ${V.localHost}`,
104
- actions: /* @__PURE__ */ w("div", {
103
+ }, { label: H.name }],
104
+ title: H.name,
105
+ description: H.description ?? `${H.protocol}:${H.localPort} on ${H.localHost}`,
106
+ actions: /* @__PURE__ */ T("div", {
105
107
  className: "flex items-center gap-2",
106
- children: [/* @__PURE__ */ C(o, { status: V.status }), /* @__PURE__ */ C(s, { providerKey: V.providerKey })]
108
+ children: [
109
+ /* @__PURE__ */ w(s, { status: H.status }),
110
+ /* @__PURE__ */ w(c, { providerKey: H.providerKey }),
111
+ /* @__PURE__ */ w(o, {
112
+ entity: "tunnel",
113
+ resource: {
114
+ id: H.id,
115
+ name: H.name
116
+ },
117
+ label: D("vibecontrols.tunnels.detail.share", "Share"),
118
+ variant: "button"
119
+ })
120
+ ]
107
121
  })
108
122
  }),
109
- /* @__PURE__ */ C("div", {
123
+ /* @__PURE__ */ w("div", {
110
124
  className: "mt-2",
111
- children: /* @__PURE__ */ C(T, {
112
- items: R,
113
- activeTabId: z,
114
- onTabChange: B,
125
+ children: /* @__PURE__ */ w(E, {
126
+ items: z,
127
+ activeTabId: B,
128
+ onTabChange: V,
115
129
  variant: "underline"
116
130
  })
117
131
  })
118
132
  ]
119
133
  }),
120
- /* @__PURE__ */ w("div", {
134
+ /* @__PURE__ */ T("div", {
121
135
  className: "flex items-start gap-2 border-b border-border-subtle bg-bg-surface px-6 py-2",
122
- children: [/* @__PURE__ */ C(y, {
136
+ children: [/* @__PURE__ */ w(b, {
123
137
  className: "mt-1 size-4 flex-shrink-0 text-text-secondary",
124
138
  "aria-hidden": "true"
125
- }), /* @__PURE__ */ C("div", {
139
+ }), /* @__PURE__ */ w("div", {
126
140
  className: "min-w-0 flex-1",
127
- children: /* @__PURE__ */ C(a, {
141
+ children: /* @__PURE__ */ w(a, {
128
142
  entityType: "VIBECONTROLS_TUNNEL",
129
- entityId: V.id
143
+ entityId: H.id
130
144
  })
131
145
  })]
132
146
  }),
133
- /* @__PURE__ */ w("div", {
147
+ /* @__PURE__ */ T("div", {
134
148
  className: "flex-1 min-h-0 overflow-auto p-6",
135
149
  children: [
136
- z === "overview" && /* @__PURE__ */ C(c, { tunnel: V }),
137
- z === "endpoints" && /* @__PURE__ */ C(l, { tunnel: V }),
138
- z === "sessions" && /* @__PURE__ */ C(u, { tunnelId: V.id }),
139
- z === "domains" && /* @__PURE__ */ C(d, { tunnel: V }),
140
- z === "usage" && /* @__PURE__ */ C(f, { tunnelId: V.id }),
141
- z === "cli" && /* @__PURE__ */ C(p, { tunnel: V }),
142
- z === "audit" && /* @__PURE__ */ C(m, { tunnelId: V.id }),
143
- z === "settings" && /* @__PURE__ */ C(h, {
144
- tunnel: V,
145
- onDeleted: () => O("/vibecontrols/tunnels")
150
+ B === "overview" && /* @__PURE__ */ w(l, { tunnel: H }),
151
+ B === "endpoints" && /* @__PURE__ */ w(u, { tunnel: H }),
152
+ B === "sessions" && /* @__PURE__ */ w(d, { tunnelId: H.id }),
153
+ B === "domains" && /* @__PURE__ */ w(f, { tunnel: H }),
154
+ B === "usage" && /* @__PURE__ */ w(p, { tunnelId: H.id }),
155
+ B === "cli" && /* @__PURE__ */ w(m, { tunnel: H }),
156
+ B === "audit" && /* @__PURE__ */ w(h, { tunnelId: H.id }),
157
+ B === "settings" && /* @__PURE__ */ w(g, {
158
+ tunnel: H,
159
+ onDeleted: () => k("/vibecontrols/tunnels")
146
160
  })
147
161
  ]
148
162
  })
@@ -150,6 +164,6 @@ function E() {
150
164
  });
151
165
  }
152
166
  //#endregion
153
- export { E as TunnelDetailsPage };
167
+ export { D as TunnelDetailsPage };
154
168
 
155
169
  //# sourceMappingURL=TunnelDetailsPage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"TunnelDetailsPage.js","names":[],"sources":["../../../src/pages/tunnels/TunnelDetailsPage.tsx"],"sourcesContent":["import { useEffect, useMemo } from 'react';\nimport { useParams, useNavigate, useSearchParams } from 'react-router-dom';\nimport { Tabs, type TabItem } from '@burdenoff/fe-libs/chrome';\n\nimport { Tag, ArrowLeft } from 'lucide-react';\nimport { PageHeader } from '@/components/shared/PageHeader';\nimport { EntityTagPicker } from '@/components/shared/EntityTagPicker';\nimport { LoadingState } from '@/components/shared/LoadingState';\nimport { ErrorState } from '@/components/shared/ErrorState';\nimport { TunnelStatusBadge } from '@/components/tunnels/TunnelStatusBadge';\nimport { ProviderBadge } from '@/components/tunnels/ProviderBadge';\nimport { useGetTunnelQuery } from '@/generated/wspace-operations';\nimport { useTr } from '../../shared/hooks/useTr';\n\nimport { TunnelOverviewTab } from './tabs/TunnelOverviewTab';\nimport { TunnelEndpointsTab } from './tabs/TunnelEndpointsTab';\nimport { TunnelSessionsTab } from './tabs/TunnelSessionsTab';\nimport { TunnelDomainsTab } from './tabs/TunnelDomainsTab';\nimport { TunnelUsageTab } from './tabs/TunnelUsageTab';\nimport { TunnelCliTab } from './tabs/TunnelCliTab';\nimport { TunnelAuditTab } from './tabs/TunnelAuditTab';\nimport { TunnelSettingsTab } from './tabs/TunnelSettingsTab';\n\nexport function TunnelDetailsPage() {\n const tr = useTr();\n const { tunnelId = '' } = useParams();\n const navigate = useNavigate();\n const [params, setParams] = useSearchParams();\n\n const { data, loading, error, refetch, startPolling, stopPolling } = useGetTunnelQuery({\n variables: { id: tunnelId },\n fetchPolicy: 'cache-and-network',\n skip: !tunnelId,\n });\n\n // Poll while transitioning OR ACTIVE-but-no-domain (Cloudflare URL arrives async).\n const needsPoll =\n data?.tunnel?.status === 'PROVISIONING' ||\n data?.tunnel?.status === 'DELETING' ||\n (data?.tunnel?.status === 'ACTIVE' && !data.tunnel.primaryDomain?.hostname);\n useEffect(() => {\n if (needsPoll) {\n startPolling(4000);\n } else {\n stopPolling();\n }\n }, [needsPoll, startPolling, stopPolling]);\n\n const tabs: TabItem[] = useMemo(\n () => [\n { id: 'overview', label: tr('vibecontrols.tunnels.detail.overview', 'Overview') },\n { id: 'endpoints', label: tr('vibecontrols.tunnels.detail.endpoints', 'Endpoints') },\n { id: 'sessions', label: tr('vibecontrols.tunnels.detail.sessions', 'Sessions') },\n { id: 'domains', label: tr('vibecontrols.tunnels.detail.domains', 'Domains') },\n { id: 'usage', label: tr('vibecontrols.tunnels.detail.usage', 'Usage') },\n { id: 'cli', label: tr('vibecontrols.tunnels.detail.cli', 'CLI') },\n { id: 'audit', label: tr('vibecontrols.tunnels.detail.audit', 'Audit') },\n { id: 'settings', label: tr('vibecontrols.tunnels.detail.settings', 'Settings') },\n ],\n [tr]\n );\n\n const activeId = params.get('tab') ?? tabs[0].id;\n\n const handleTabChange = (id: string) => {\n const next = new URLSearchParams(params);\n if (id === tabs[0].id) next.delete('tab');\n else next.set('tab', id);\n setParams(next, { replace: true });\n };\n\n if (loading && !data) return <LoadingState message=\"Loading tunnel\" />;\n if (error) {\n return (\n <ErrorState title=\"Failed to load tunnel\" message={error.message} onRetry={() => refetch()} />\n );\n }\n if (!data?.tunnel) {\n return (\n <ErrorState\n title=\"Tunnel not found\"\n message=\"This tunnel may have been deleted.\"\n onRetry={() => navigate('/vibecontrols/tunnels')}\n />\n );\n }\n\n const tunnel = data.tunnel;\n\n return (\n <div className=\"flex flex-col h-full\">\n <div className=\"px-6 pt-6 pb-2 border-b border-border-subtle\">\n <button\n type=\"button\"\n onClick={() => navigate('/vibecontrols/tunnels')}\n className=\"flex items-center gap-1.5 mb-4 text-sm text-text-secondary hover:text-text-primary transition-colors\"\n >\n <ArrowLeft size={16} />\n Back to Tunnels\n </button>\n <PageHeader\n breadcrumb={[{ label: 'Tunnels', path: '/vibecontrols/tunnels' }, { label: tunnel.name }]}\n title={tunnel.name}\n description={\n tunnel.description ?? `${tunnel.protocol}:${tunnel.localPort} on ${tunnel.localHost}`\n }\n actions={\n <div className=\"flex items-center gap-2\">\n <TunnelStatusBadge status={tunnel.status} />\n <ProviderBadge providerKey={tunnel.providerKey} />\n </div>\n }\n />\n <div className=\"mt-2\">\n <Tabs\n items={tabs}\n activeTabId={activeId}\n onTabChange={handleTabChange}\n variant=\"underline\"\n />\n </div>\n </div>\n <div className=\"flex items-start gap-2 border-b border-border-subtle bg-bg-surface px-6 py-2\">\n <Tag className=\"mt-1 size-4 flex-shrink-0 text-text-secondary\" aria-hidden=\"true\" />\n <div className=\"min-w-0 flex-1\">\n <EntityTagPicker entityType=\"VIBECONTROLS_TUNNEL\" entityId={tunnel.id} />\n </div>\n </div>\n <div className=\"flex-1 min-h-0 overflow-auto p-6\">\n {activeId === 'overview' && <TunnelOverviewTab tunnel={tunnel} />}\n {activeId === 'endpoints' && <TunnelEndpointsTab tunnel={tunnel} />}\n {activeId === 'sessions' && <TunnelSessionsTab tunnelId={tunnel.id} />}\n {activeId === 'domains' && <TunnelDomainsTab tunnel={tunnel} />}\n {activeId === 'usage' && <TunnelUsageTab tunnelId={tunnel.id} />}\n {activeId === 'cli' && <TunnelCliTab tunnel={tunnel} />}\n {activeId === 'audit' && <TunnelAuditTab tunnelId={tunnel.id} />}\n {activeId === 'settings' && (\n <TunnelSettingsTab tunnel={tunnel} onDeleted={() => navigate('/vibecontrols/tunnels')} />\n )}\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"TunnelDetailsPage.js","names":[],"sources":["../../../src/pages/tunnels/TunnelDetailsPage.tsx"],"sourcesContent":["import { useEffect, useMemo } from 'react';\nimport { useParams, useNavigate, useSearchParams } from 'react-router-dom';\nimport { Tabs, type TabItem } from '@burdenoff/fe-libs/chrome';\n\nimport { Tag, ArrowLeft } from 'lucide-react';\nimport { PageHeader } from '@/components/shared/PageHeader';\nimport { EntityTagPicker } from '@/components/shared/EntityTagPicker';\nimport { LoadingState } from '@/components/shared/LoadingState';\nimport { ErrorState } from '@/components/shared/ErrorState';\nimport { TunnelStatusBadge } from '@/components/tunnels/TunnelStatusBadge';\nimport { ProviderBadge } from '@/components/tunnels/ProviderBadge';\nimport { EntityShareButton } from '@/components/sharing';\nimport { useGetTunnelQuery } from '@/generated/wspace-operations';\nimport { useTr } from '../../shared/hooks/useTr';\n\nimport { TunnelOverviewTab } from './tabs/TunnelOverviewTab';\nimport { TunnelEndpointsTab } from './tabs/TunnelEndpointsTab';\nimport { TunnelSessionsTab } from './tabs/TunnelSessionsTab';\nimport { TunnelDomainsTab } from './tabs/TunnelDomainsTab';\nimport { TunnelUsageTab } from './tabs/TunnelUsageTab';\nimport { TunnelCliTab } from './tabs/TunnelCliTab';\nimport { TunnelAuditTab } from './tabs/TunnelAuditTab';\nimport { TunnelSettingsTab } from './tabs/TunnelSettingsTab';\n\nexport function TunnelDetailsPage() {\n const tr = useTr();\n const { tunnelId = '' } = useParams();\n const navigate = useNavigate();\n const [params, setParams] = useSearchParams();\n\n const { data, loading, error, refetch, startPolling, stopPolling } = useGetTunnelQuery({\n variables: { id: tunnelId },\n fetchPolicy: 'cache-and-network',\n skip: !tunnelId,\n });\n\n // Poll while transitioning OR ACTIVE-but-no-domain (Cloudflare URL arrives async).\n const needsPoll =\n data?.tunnel?.status === 'PROVISIONING' ||\n data?.tunnel?.status === 'DELETING' ||\n (data?.tunnel?.status === 'ACTIVE' && !data.tunnel.primaryDomain?.hostname);\n useEffect(() => {\n if (needsPoll) {\n startPolling(4000);\n } else {\n stopPolling();\n }\n }, [needsPoll, startPolling, stopPolling]);\n\n const tabs: TabItem[] = useMemo(\n () => [\n { id: 'overview', label: tr('vibecontrols.tunnels.detail.overview', 'Overview') },\n { id: 'endpoints', label: tr('vibecontrols.tunnels.detail.endpoints', 'Endpoints') },\n { id: 'sessions', label: tr('vibecontrols.tunnels.detail.sessions', 'Sessions') },\n { id: 'domains', label: tr('vibecontrols.tunnels.detail.domains', 'Domains') },\n { id: 'usage', label: tr('vibecontrols.tunnels.detail.usage', 'Usage') },\n { id: 'cli', label: tr('vibecontrols.tunnels.detail.cli', 'CLI') },\n { id: 'audit', label: tr('vibecontrols.tunnels.detail.audit', 'Audit') },\n { id: 'settings', label: tr('vibecontrols.tunnels.detail.settings', 'Settings') },\n ],\n [tr]\n );\n\n const activeId = params.get('tab') ?? tabs[0].id;\n\n const handleTabChange = (id: string) => {\n const next = new URLSearchParams(params);\n if (id === tabs[0].id) next.delete('tab');\n else next.set('tab', id);\n setParams(next, { replace: true });\n };\n\n if (loading && !data) return <LoadingState message=\"Loading tunnel\" />;\n if (error) {\n return (\n <ErrorState title=\"Failed to load tunnel\" message={error.message} onRetry={() => refetch()} />\n );\n }\n if (!data?.tunnel) {\n return (\n <ErrorState\n title=\"Tunnel not found\"\n message=\"This tunnel may have been deleted.\"\n onRetry={() => navigate('/vibecontrols/tunnels')}\n />\n );\n }\n\n const tunnel = data.tunnel;\n\n return (\n <div className=\"flex flex-col h-full\">\n <div className=\"px-6 pt-6 pb-2 border-b border-border-subtle\">\n <button\n type=\"button\"\n onClick={() => navigate('/vibecontrols/tunnels')}\n className=\"flex items-center gap-1.5 mb-4 text-sm text-text-secondary hover:text-text-primary transition-colors\"\n >\n <ArrowLeft size={16} />\n Back to Tunnels\n </button>\n <PageHeader\n breadcrumb={[{ label: 'Tunnels', path: '/vibecontrols/tunnels' }, { label: tunnel.name }]}\n title={tunnel.name}\n description={\n tunnel.description ?? `${tunnel.protocol}:${tunnel.localPort} on ${tunnel.localHost}`\n }\n actions={\n <div className=\"flex items-center gap-2\">\n <TunnelStatusBadge status={tunnel.status} />\n <ProviderBadge providerKey={tunnel.providerKey} />\n <EntityShareButton\n entity=\"tunnel\"\n resource={{ id: tunnel.id, name: tunnel.name }}\n label={tr('vibecontrols.tunnels.detail.share', 'Share')}\n variant=\"button\"\n />\n </div>\n }\n />\n <div className=\"mt-2\">\n <Tabs\n items={tabs}\n activeTabId={activeId}\n onTabChange={handleTabChange}\n variant=\"underline\"\n />\n </div>\n </div>\n <div className=\"flex items-start gap-2 border-b border-border-subtle bg-bg-surface px-6 py-2\">\n <Tag className=\"mt-1 size-4 flex-shrink-0 text-text-secondary\" aria-hidden=\"true\" />\n <div className=\"min-w-0 flex-1\">\n <EntityTagPicker entityType=\"VIBECONTROLS_TUNNEL\" entityId={tunnel.id} />\n </div>\n </div>\n <div className=\"flex-1 min-h-0 overflow-auto p-6\">\n {activeId === 'overview' && <TunnelOverviewTab tunnel={tunnel} />}\n {activeId === 'endpoints' && <TunnelEndpointsTab tunnel={tunnel} />}\n {activeId === 'sessions' && <TunnelSessionsTab tunnelId={tunnel.id} />}\n {activeId === 'domains' && <TunnelDomainsTab tunnel={tunnel} />}\n {activeId === 'usage' && <TunnelUsageTab tunnelId={tunnel.id} />}\n {activeId === 'cli' && <TunnelCliTab tunnel={tunnel} />}\n {activeId === 'audit' && <TunnelAuditTab tunnelId={tunnel.id} />}\n {activeId === 'settings' && (\n <TunnelSettingsTab tunnel={tunnel} onDeleted={() => navigate('/vibecontrols/tunnels')} />\n )}\n </div>\n </div>\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.601.21",
3
+ "version": "2026.601.22",
4
4
  "description": "VibeControls microfrontend for Burdenoff products",
5
5
  "type": "module",
6
6
  "files": [