@burdenoff/microfe-subscriberbot 2026.801.1 → 2026.829.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.
- package/dist/subscriberbot/admin/AdminDashboardPage.d.ts.map +1 -1
- package/dist/subscriberbot/admin/AdminDashboardPage.js +80 -83
- package/dist/subscriberbot/admin/AdminDashboardPage.js.map +1 -1
- package/dist/subscriberbot/components/viz.js +51 -27
- package/dist/subscriberbot/components/viz.js.map +1 -1
- package/dist/subscriberbot/hooks/index.d.ts +2 -1
- package/dist/subscriberbot/hooks/index.d.ts.map +1 -1
- package/dist/subscriberbot/hooks/index.js +1 -0
- package/dist/subscriberbot/hooks/useSubscriberBotApi.d.ts +12 -1
- package/dist/subscriberbot/hooks/useSubscriberBotApi.d.ts.map +1 -1
- package/dist/subscriberbot/hooks/useSubscriberBotApi.js +82 -56
- package/dist/subscriberbot/hooks/useSubscriberBotApi.js.map +1 -1
- package/dist/subscriberbot/hooks/useTr.d.ts +17 -0
- package/dist/subscriberbot/hooks/useTr.d.ts.map +1 -0
- package/dist/subscriberbot/hooks/useTr.js +14 -0
- package/dist/subscriberbot/hooks/useTr.js.map +1 -0
- package/dist/subscriberbot/pages/AssetVaultPage.d.ts.map +1 -1
- package/dist/subscriberbot/pages/AssetVaultPage.js +155 -97
- package/dist/subscriberbot/pages/AssetVaultPage.js.map +1 -1
- package/dist/subscriberbot/pages/DashboardPage.d.ts.map +1 -1
- package/dist/subscriberbot/pages/DashboardPage.js +113 -105
- package/dist/subscriberbot/pages/DashboardPage.js.map +1 -1
- package/dist/subscriberbot/pages/InboxPage.d.ts.map +1 -1
- package/dist/subscriberbot/pages/InboxPage.js +404 -369
- package/dist/subscriberbot/pages/InboxPage.js.map +1 -1
- package/dist/subscriberbot/pages/InsightsPage.d.ts.map +1 -1
- package/dist/subscriberbot/pages/InsightsPage.js +94 -93
- package/dist/subscriberbot/pages/InsightsPage.js.map +1 -1
- package/dist/subscriberbot/pages/InvoicesPage.d.ts +3 -2
- package/dist/subscriberbot/pages/InvoicesPage.d.ts.map +1 -1
- package/dist/subscriberbot/pages/InvoicesPage.js +368 -362
- package/dist/subscriberbot/pages/InvoicesPage.js.map +1 -1
- package/dist/subscriberbot/pages/WorkflowsPage.d.ts.map +1 -1
- package/dist/subscriberbot/pages/WorkflowsPage.js +209 -193
- package/dist/subscriberbot/pages/WorkflowsPage.js.map +1 -1
- package/dist/subscriberbot/pages/agents/AgentDetailPage.d.ts +3 -1
- package/dist/subscriberbot/pages/agents/AgentDetailPage.d.ts.map +1 -1
- package/dist/subscriberbot/pages/agents/AgentDetailPage.js +296 -228
- package/dist/subscriberbot/pages/agents/AgentDetailPage.js.map +1 -1
- package/dist/subscriberbot/pages/agents/AgentNewPage.d.ts.map +1 -1
- package/dist/subscriberbot/pages/agents/AgentNewPage.js +96 -76
- package/dist/subscriberbot/pages/agents/AgentNewPage.js.map +1 -1
- package/dist/subscriberbot/pages/agents/AgentsListPage.d.ts.map +1 -1
- package/dist/subscriberbot/pages/agents/AgentsListPage.js +145 -161
- package/dist/subscriberbot/pages/agents/AgentsListPage.js.map +1 -1
- package/dist/subscriberbot/pages/providers/ProviderDetailPage.d.ts +4 -2
- package/dist/subscriberbot/pages/providers/ProviderDetailPage.d.ts.map +1 -1
- package/dist/subscriberbot/pages/providers/ProviderDetailPage.js +577 -402
- package/dist/subscriberbot/pages/providers/ProviderDetailPage.js.map +1 -1
- package/dist/subscriberbot/pages/providers/ProviderNewPage.d.ts.map +1 -1
- package/dist/subscriberbot/pages/providers/ProviderNewPage.js +167 -129
- package/dist/subscriberbot/pages/providers/ProviderNewPage.js.map +1 -1
- package/dist/subscriberbot/pages/providers/ProvidersListPage.d.ts.map +1 -1
- package/dist/subscriberbot/pages/providers/ProvidersListPage.js +171 -218
- package/dist/subscriberbot/pages/providers/ProvidersListPage.js.map +1 -1
- package/dist/subscriberbot/pages/relationships/RelationshipDetailPage.d.ts.map +1 -1
- package/dist/subscriberbot/pages/relationships/RelationshipDetailPage.js +340 -279
- package/dist/subscriberbot/pages/relationships/RelationshipDetailPage.js.map +1 -1
- package/dist/subscriberbot/pages/relationships/RelationshipNewPage.d.ts.map +1 -1
- package/dist/subscriberbot/pages/relationships/RelationshipNewPage.js +185 -166
- package/dist/subscriberbot/pages/relationships/RelationshipNewPage.js.map +1 -1
- package/dist/subscriberbot/pages/relationships/RelationshipsListPage.d.ts.map +1 -1
- package/dist/subscriberbot/pages/relationships/RelationshipsListPage.js +153 -182
- package/dist/subscriberbot/pages/relationships/RelationshipsListPage.js.map +1 -1
- package/dist/subscriberbot/types/index.d.ts +37 -0
- package/dist/subscriberbot/types/index.d.ts.map +1 -1
- package/package.json +2 -2
|
@@ -8,253 +8,237 @@ import { ErrorView as s, LoadingView as c } from "../../components/StateViews.js
|
|
|
8
8
|
import { Donut as l, Legend as u } from "../../components/viz.js";
|
|
9
9
|
import "../../components/index.js";
|
|
10
10
|
import { useAgents as d, useSetAgentStatus as f } from "../../hooks/useSubscriberBotApi.js";
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
11
|
+
import { useTr as p } from "../../hooks/useTr.js";
|
|
12
|
+
import { useState as m } from "react";
|
|
13
|
+
import { ArrowLeftRight as h, Bot as g, Building2 as _, Clock as v, ConciergeBell as y, DollarSign as b, Handshake as x, Mail as S, Plus as C, RefreshCw as w, Search as T, ShieldCheck as E, Sparkles as D, Zap as O } from "lucide-react";
|
|
14
|
+
import { Fragment as k, jsx as A, jsxs as j } from "react/jsx-runtime";
|
|
15
|
+
import { GlassCard as M, PagePurpose as N } from "@burdenoff/fe-libs/ui";
|
|
15
16
|
//#region src/subscriberbot/pages/agents/AgentsListPage.tsx
|
|
16
|
-
var
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
label: "Renewal"
|
|
28
|
-
},
|
|
29
|
-
{
|
|
30
|
-
value: "COST",
|
|
31
|
-
label: "Cost"
|
|
32
|
-
},
|
|
33
|
-
{
|
|
34
|
-
value: "NEWSLETTER",
|
|
35
|
-
label: "Newsletter"
|
|
36
|
-
},
|
|
37
|
-
{
|
|
38
|
-
value: "VENDOR",
|
|
39
|
-
label: "Vendor"
|
|
40
|
-
},
|
|
41
|
-
{
|
|
42
|
-
value: "COMPLIANCE",
|
|
43
|
-
label: "Compliance"
|
|
44
|
-
},
|
|
45
|
-
{
|
|
46
|
-
value: "NEGOTIATION",
|
|
47
|
-
label: "Negotiation"
|
|
48
|
-
},
|
|
49
|
-
{
|
|
50
|
-
value: "MIGRATION",
|
|
51
|
-
label: "Migration"
|
|
52
|
-
},
|
|
53
|
-
{
|
|
54
|
-
value: "CONCIERGE",
|
|
55
|
-
label: "Concierge"
|
|
56
|
-
}
|
|
57
|
-
], P = [
|
|
17
|
+
var P = {
|
|
18
|
+
DISCOVERY: "agents.kinds.discovery",
|
|
19
|
+
RENEWAL: "agents.kinds.renewal",
|
|
20
|
+
COST: "agents.kinds.cost",
|
|
21
|
+
NEWSLETTER: "agents.kinds.newsletter",
|
|
22
|
+
VENDOR: "agents.kinds.vendor",
|
|
23
|
+
COMPLIANCE: "agents.kinds.compliance",
|
|
24
|
+
NEGOTIATION: "agents.kinds.negotiation",
|
|
25
|
+
MIGRATION: "agents.kinds.migration",
|
|
26
|
+
CONCIERGE: "agents.kinds.concierge"
|
|
27
|
+
}, F = [
|
|
58
28
|
"DISABLED",
|
|
59
29
|
"SUGGEST_ONLY",
|
|
60
30
|
"AUTONOMOUS"
|
|
61
|
-
],
|
|
62
|
-
DISCOVERY:
|
|
63
|
-
RENEWAL:
|
|
64
|
-
COST:
|
|
65
|
-
NEWSLETTER:
|
|
66
|
-
VENDOR:
|
|
67
|
-
COMPLIANCE:
|
|
68
|
-
NEGOTIATION:
|
|
69
|
-
MIGRATION:
|
|
70
|
-
CONCIERGE:
|
|
71
|
-
},
|
|
31
|
+
], I = {
|
|
32
|
+
DISCOVERY: T,
|
|
33
|
+
RENEWAL: w,
|
|
34
|
+
COST: b,
|
|
35
|
+
NEWSLETTER: S,
|
|
36
|
+
VENDOR: _,
|
|
37
|
+
COMPLIANCE: E,
|
|
38
|
+
NEGOTIATION: x,
|
|
39
|
+
MIGRATION: h,
|
|
40
|
+
CONCIERGE: y
|
|
41
|
+
}, L = {
|
|
72
42
|
AUTONOMOUS: "var(--color-status-success-text)",
|
|
73
43
|
SUGGEST_ONLY: "var(--color-accent-indigo)",
|
|
74
44
|
DISABLED: "var(--color-text-secondary)"
|
|
75
|
-
},
|
|
76
|
-
function
|
|
77
|
-
let { navigateTo:
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
}
|
|
45
|
+
}, R = 1440 * 60 * 1e3;
|
|
46
|
+
function z() {
|
|
47
|
+
let h = p(), { navigateTo: _ } = e(), [y, b] = m(""), [x, S] = m(""), w = [{
|
|
48
|
+
value: "",
|
|
49
|
+
label: h("agents.filters.allKinds", "All kinds")
|
|
50
|
+
}, ...Object.entries(P).map(([e, t]) => ({
|
|
51
|
+
value: e,
|
|
52
|
+
label: h(t, r(e))
|
|
53
|
+
}))], { data: T, isLoading: E, isError: z, refetch: B } = d({
|
|
54
|
+
kind: y || void 0,
|
|
55
|
+
status: x || void 0
|
|
56
|
+
}), V = f(), H = T ?? [], U = {
|
|
81
57
|
AUTONOMOUS: 0,
|
|
82
58
|
SUGGEST_ONLY: 0,
|
|
83
59
|
DISABLED: 0
|
|
84
|
-
},
|
|
85
|
-
for (let e of
|
|
86
|
-
let
|
|
87
|
-
label: r(e),
|
|
88
|
-
value:
|
|
89
|
-
color:
|
|
60
|
+
}, W = 0, G = Date.now();
|
|
61
|
+
for (let e of H) U[e.status] += 1, e.lastRunAt && G - new Date(e.lastRunAt).getTime() <= 7 * R && (W += 1);
|
|
62
|
+
let K = F.map((e) => ({
|
|
63
|
+
label: h(`agents.postures.${e.toLowerCase()}`, r(e)),
|
|
64
|
+
value: U[e],
|
|
65
|
+
color: L[e]
|
|
90
66
|
})).filter((e) => e.value > 0);
|
|
91
|
-
return /* @__PURE__ */
|
|
92
|
-
title: "AI Agents",
|
|
93
|
-
description: "Specialized agents that automate your recurring portfolio",
|
|
94
|
-
actions: /* @__PURE__ */
|
|
67
|
+
return /* @__PURE__ */ j(t, {
|
|
68
|
+
title: h("agents.title", "AI Agents"),
|
|
69
|
+
description: h("agents.description", "Specialized agents that automate your recurring portfolio"),
|
|
70
|
+
actions: /* @__PURE__ */ j("button", {
|
|
95
71
|
type: "button",
|
|
96
|
-
onClick: () =>
|
|
72
|
+
onClick: () => _("/agents/new"),
|
|
97
73
|
className: "inline-flex items-center gap-2 rounded-lg bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:opacity-90",
|
|
98
|
-
children: [
|
|
74
|
+
children: [
|
|
75
|
+
/* @__PURE__ */ A(C, { className: "h-4 w-4" }),
|
|
76
|
+
" ",
|
|
77
|
+
h("agents.newAgent", "New agent")
|
|
78
|
+
]
|
|
99
79
|
}),
|
|
100
80
|
children: [
|
|
101
|
-
/* @__PURE__ */
|
|
81
|
+
/* @__PURE__ */ A(N, {
|
|
102
82
|
className: "mb-4",
|
|
103
|
-
children: "Agents propose; your policies decide what they may do autonomously. Set each agent's posture — Disabled, Suggest-only, or Autonomous — and open one to review its policies."
|
|
83
|
+
children: h("agents.purpose", "Agents propose; your policies decide what they may do autonomously. Set each agent's posture — Disabled, Suggest-only, or Autonomous — and open one to review its policies.")
|
|
104
84
|
}),
|
|
105
|
-
/* @__PURE__ */
|
|
85
|
+
/* @__PURE__ */ j("div", {
|
|
106
86
|
className: "flex flex-wrap items-center gap-3",
|
|
107
|
-
children: [/* @__PURE__ */
|
|
108
|
-
"aria-label": "Filter by kind",
|
|
109
|
-
value:
|
|
110
|
-
onChange: (e) =>
|
|
87
|
+
children: [/* @__PURE__ */ A("select", {
|
|
88
|
+
"aria-label": h("agents.filters.kindLabel", "Filter by kind"),
|
|
89
|
+
value: y,
|
|
90
|
+
onChange: (e) => b(e.target.value),
|
|
111
91
|
className: "rounded-lg border border-border-subtle bg-bg-surface px-3 py-2 text-xs text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]",
|
|
112
|
-
children:
|
|
92
|
+
children: w.map((e) => /* @__PURE__ */ A("option", {
|
|
113
93
|
value: e.value,
|
|
114
94
|
children: e.label
|
|
115
95
|
}, e.value))
|
|
116
|
-
}), /* @__PURE__ */
|
|
117
|
-
"aria-label": "Filter by posture",
|
|
118
|
-
value:
|
|
119
|
-
onChange: (e) =>
|
|
96
|
+
}), /* @__PURE__ */ j("select", {
|
|
97
|
+
"aria-label": h("agents.filters.postureLabel", "Filter by posture"),
|
|
98
|
+
value: x,
|
|
99
|
+
onChange: (e) => S(e.target.value),
|
|
120
100
|
className: "rounded-lg border border-border-subtle bg-bg-surface px-3 py-2 text-xs text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]",
|
|
121
|
-
children: [/* @__PURE__ */
|
|
101
|
+
children: [/* @__PURE__ */ A("option", {
|
|
122
102
|
value: "",
|
|
123
|
-
children: "Any posture"
|
|
124
|
-
}),
|
|
103
|
+
children: h("agents.filters.anyPosture", "Any posture")
|
|
104
|
+
}), F.map((e) => /* @__PURE__ */ A("option", {
|
|
125
105
|
value: e,
|
|
126
|
-
children: r(e)
|
|
106
|
+
children: h(`agents.postures.${e.toLowerCase()}`, r(e))
|
|
127
107
|
}, e))]
|
|
128
108
|
})]
|
|
129
109
|
}),
|
|
130
|
-
|
|
131
|
-
message: "Could not load agents.",
|
|
132
|
-
onRetry: () => void
|
|
133
|
-
}) :
|
|
110
|
+
E ? /* @__PURE__ */ A(c, { label: h("agents.loading", "Loading agents…") }) : z ? /* @__PURE__ */ A(s, {
|
|
111
|
+
message: h("agents.error", "Could not load agents."),
|
|
112
|
+
onRetry: () => void B()
|
|
113
|
+
}) : H.length === 0 ? /* @__PURE__ */ A("div", {
|
|
134
114
|
className: "mt-6",
|
|
135
|
-
children: /* @__PURE__ */
|
|
115
|
+
children: /* @__PURE__ */ A(o, {
|
|
136
116
|
illustration: "empty-data",
|
|
137
|
-
icon: /* @__PURE__ */
|
|
138
|
-
title: "No agents yet",
|
|
139
|
-
description: "Create your first AI agent to start automating discovery, renewals, or cost optimization.",
|
|
140
|
-
action: /* @__PURE__ */
|
|
117
|
+
icon: /* @__PURE__ */ A(g, { className: "h-12 w-12" }),
|
|
118
|
+
title: h("agents.emptyTitle", "No agents yet"),
|
|
119
|
+
description: h("agents.emptyDescription", "Create your first AI agent to start automating discovery, renewals, or cost optimization."),
|
|
120
|
+
action: /* @__PURE__ */ A("button", {
|
|
141
121
|
type: "button",
|
|
142
|
-
onClick: () =>
|
|
122
|
+
onClick: () => _("/agents/new"),
|
|
143
123
|
className: "rounded-lg bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:opacity-90",
|
|
144
|
-
children: "New agent"
|
|
124
|
+
children: h("agents.newAgent", "New agent")
|
|
145
125
|
})
|
|
146
126
|
})
|
|
147
|
-
}) : /* @__PURE__ */
|
|
127
|
+
}) : /* @__PURE__ */ j(k, { children: [/* @__PURE__ */ j("div", {
|
|
148
128
|
className: "mt-6 grid grid-cols-1 gap-4 lg:grid-cols-3",
|
|
149
|
-
children: [/* @__PURE__ */
|
|
129
|
+
children: [/* @__PURE__ */ j(M, {
|
|
150
130
|
treatment: "insight",
|
|
151
131
|
className: "p-5 lg:col-span-1",
|
|
152
132
|
children: [
|
|
153
|
-
/* @__PURE__ */
|
|
133
|
+
/* @__PURE__ */ A("p", {
|
|
154
134
|
className: "text-sm font-semibold text-text-primary",
|
|
155
|
-
children: "Fleet posture"
|
|
135
|
+
children: h("agents.fleet.title", "Fleet posture")
|
|
156
136
|
}),
|
|
157
|
-
/* @__PURE__ */
|
|
137
|
+
/* @__PURE__ */ A("p", {
|
|
158
138
|
className: "mt-0.5 text-xs text-text-secondary",
|
|
159
|
-
children: "How your agents are allowed to act"
|
|
139
|
+
children: h("agents.fleet.description", "How your agents are allowed to act")
|
|
160
140
|
}),
|
|
161
|
-
/* @__PURE__ */
|
|
141
|
+
/* @__PURE__ */ j("div", {
|
|
162
142
|
className: "mt-4 flex items-center gap-5",
|
|
163
|
-
children: [/* @__PURE__ */
|
|
164
|
-
data:
|
|
143
|
+
children: [/* @__PURE__ */ A(l, {
|
|
144
|
+
data: K,
|
|
165
145
|
size: 132,
|
|
166
146
|
thickness: 16,
|
|
167
|
-
centerLabel: String(
|
|
168
|
-
centerSub:
|
|
169
|
-
}), /* @__PURE__ */
|
|
147
|
+
centerLabel: String(H.length),
|
|
148
|
+
centerSub: H.length === 1 ? h("agents.fleet.agentSingular", "agent") : h("agents.fleet.agentPlural", "agents")
|
|
149
|
+
}), /* @__PURE__ */ A(u, {
|
|
170
150
|
className: "flex-1",
|
|
171
|
-
data:
|
|
151
|
+
data: K
|
|
172
152
|
})]
|
|
173
153
|
})
|
|
174
154
|
]
|
|
175
|
-
}), /* @__PURE__ */
|
|
155
|
+
}), /* @__PURE__ */ j("div", {
|
|
176
156
|
className: "grid grid-cols-2 gap-4 lg:col-span-2",
|
|
177
157
|
children: [
|
|
178
|
-
/* @__PURE__ */
|
|
179
|
-
icon: /* @__PURE__ */
|
|
180
|
-
value:
|
|
181
|
-
label: "Total agents"
|
|
158
|
+
/* @__PURE__ */ A(n, {
|
|
159
|
+
icon: /* @__PURE__ */ A(g, { className: "h-5 w-5" }),
|
|
160
|
+
value: H.length,
|
|
161
|
+
label: h("agents.fleet.totalAgents", "Total agents")
|
|
182
162
|
}),
|
|
183
|
-
/* @__PURE__ */
|
|
184
|
-
icon: /* @__PURE__ */
|
|
185
|
-
value:
|
|
186
|
-
label: "Autonomous"
|
|
163
|
+
/* @__PURE__ */ A(n, {
|
|
164
|
+
icon: /* @__PURE__ */ A(O, { className: "h-5 w-5" }),
|
|
165
|
+
value: U.AUTONOMOUS,
|
|
166
|
+
label: h("agents.postures.autonomous", "Autonomous")
|
|
187
167
|
}),
|
|
188
|
-
/* @__PURE__ */
|
|
189
|
-
icon: /* @__PURE__ */
|
|
190
|
-
value:
|
|
191
|
-
label: "Suggest-only"
|
|
168
|
+
/* @__PURE__ */ A(n, {
|
|
169
|
+
icon: /* @__PURE__ */ A(D, { className: "h-5 w-5" }),
|
|
170
|
+
value: U.SUGGEST_ONLY,
|
|
171
|
+
label: h("agents.postures.suggestOnly", "Suggest-only")
|
|
192
172
|
}),
|
|
193
|
-
/* @__PURE__ */
|
|
194
|
-
icon: /* @__PURE__ */
|
|
195
|
-
value:
|
|
196
|
-
label: "Ran in last 7 days"
|
|
173
|
+
/* @__PURE__ */ A(n, {
|
|
174
|
+
icon: /* @__PURE__ */ A(v, { className: "h-5 w-5" }),
|
|
175
|
+
value: W,
|
|
176
|
+
label: h("agents.fleet.ranLast7Days", "Ran in last 7 days")
|
|
197
177
|
})
|
|
198
178
|
]
|
|
199
179
|
})]
|
|
200
|
-
}), /* @__PURE__ */
|
|
180
|
+
}), /* @__PURE__ */ A("div", {
|
|
201
181
|
className: "mt-6 grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3",
|
|
202
|
-
children:
|
|
203
|
-
let t =
|
|
204
|
-
return /* @__PURE__ */
|
|
182
|
+
children: H.map((e) => {
|
|
183
|
+
let t = I[e.kind] ?? g;
|
|
184
|
+
return /* @__PURE__ */ j(M, {
|
|
205
185
|
treatment: "metric",
|
|
206
186
|
glow: e.status === "AUTONOMOUS",
|
|
207
187
|
className: "flex flex-col p-5",
|
|
208
|
-
children: [/* @__PURE__ */
|
|
188
|
+
children: [/* @__PURE__ */ j("button", {
|
|
209
189
|
type: "button",
|
|
210
|
-
onClick: () =>
|
|
190
|
+
onClick: () => _(`/agents/${e.id}`),
|
|
211
191
|
className: "rounded-lg text-left focus:outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-focus-ring)]",
|
|
212
|
-
"aria-label":
|
|
192
|
+
"aria-label": h("agents.card.openAria", "Open {{name}}", { name: e.name }),
|
|
213
193
|
children: [
|
|
214
|
-
/* @__PURE__ */
|
|
194
|
+
/* @__PURE__ */ j("div", {
|
|
215
195
|
className: "flex items-start justify-between gap-2",
|
|
216
|
-
children: [/* @__PURE__ */
|
|
196
|
+
children: [/* @__PURE__ */ A("span", {
|
|
217
197
|
className: "flex size-10 items-center justify-center rounded-xl bg-[var(--color-accent-soft)] text-text-primary",
|
|
218
|
-
children: /* @__PURE__ */
|
|
219
|
-
}), /* @__PURE__ */
|
|
198
|
+
children: /* @__PURE__ */ A(t, { className: "h-5 w-5" })
|
|
199
|
+
}), /* @__PURE__ */ A(a, { status: e.status })]
|
|
220
200
|
}),
|
|
221
|
-
/* @__PURE__ */
|
|
201
|
+
/* @__PURE__ */ A("p", {
|
|
222
202
|
className: "mt-3 truncate text-sm font-semibold text-text-primary",
|
|
223
203
|
children: e.name
|
|
224
204
|
}),
|
|
225
|
-
/* @__PURE__ */
|
|
205
|
+
/* @__PURE__ */ j("p", {
|
|
226
206
|
className: "text-xs text-text-secondary",
|
|
227
|
-
children: [
|
|
207
|
+
children: [
|
|
208
|
+
h(P[e.kind], r(e.kind)),
|
|
209
|
+
" ",
|
|
210
|
+
h("agents.card.kindSuffix", "agent")
|
|
211
|
+
]
|
|
228
212
|
}),
|
|
229
|
-
/* @__PURE__ */
|
|
213
|
+
/* @__PURE__ */ A("p", {
|
|
230
214
|
className: "mt-2 line-clamp-2 min-h-[2rem] text-xs text-text-secondary",
|
|
231
|
-
children: e.description || "No description provided."
|
|
215
|
+
children: e.description || h("agents.card.noDescription", "No description provided.")
|
|
232
216
|
}),
|
|
233
|
-
/* @__PURE__ */
|
|
217
|
+
/* @__PURE__ */ j("p", {
|
|
234
218
|
className: "mt-3 flex items-center gap-1.5 text-xs text-text-secondary",
|
|
235
|
-
children: [/* @__PURE__ */
|
|
219
|
+
children: [/* @__PURE__ */ A(v, {
|
|
236
220
|
className: "h-3.5 w-3.5",
|
|
237
221
|
"aria-hidden": !0
|
|
238
|
-
}), e.lastRunAt ?
|
|
222
|
+
}), e.lastRunAt ? h("agents.card.lastRun", "Last run {{when}}", { when: i(e.lastRunAt) }) : h("agents.card.neverRun", "Never run")]
|
|
239
223
|
})
|
|
240
224
|
]
|
|
241
|
-
}), /* @__PURE__ */
|
|
225
|
+
}), /* @__PURE__ */ j("div", {
|
|
242
226
|
className: "mt-4 border-t border-border-subtle pt-3",
|
|
243
|
-
children: [/* @__PURE__ */
|
|
227
|
+
children: [/* @__PURE__ */ A("label", {
|
|
244
228
|
className: "mb-1 block text-[10px] font-medium uppercase tracking-wide text-text-secondary",
|
|
245
|
-
children: "Posture"
|
|
246
|
-
}), /* @__PURE__ */
|
|
247
|
-
"aria-label":
|
|
229
|
+
children: h("agents.card.posture", "Posture")
|
|
230
|
+
}), /* @__PURE__ */ A("select", {
|
|
231
|
+
"aria-label": h("agents.card.postureAria", "Posture for {{name}}", { name: e.name }),
|
|
248
232
|
value: e.status,
|
|
249
|
-
disabled:
|
|
250
|
-
onChange: (t) =>
|
|
233
|
+
disabled: V.isPending,
|
|
234
|
+
onChange: (t) => V.mutate({
|
|
251
235
|
id: e.id,
|
|
252
236
|
status: t.target.value
|
|
253
237
|
}),
|
|
254
238
|
className: "w-full rounded-lg border border-border-subtle bg-bg-surface px-2 py-1.5 text-xs text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)] disabled:opacity-50",
|
|
255
|
-
children:
|
|
239
|
+
children: F.map((e) => /* @__PURE__ */ A("option", {
|
|
256
240
|
value: e,
|
|
257
|
-
children: r(e)
|
|
241
|
+
children: h(`agents.postures.${e.toLowerCase()}`, r(e))
|
|
258
242
|
}, e))
|
|
259
243
|
})]
|
|
260
244
|
})]
|
|
@@ -265,6 +249,6 @@ function R() {
|
|
|
265
249
|
});
|
|
266
250
|
}
|
|
267
251
|
//#endregion
|
|
268
|
-
export {
|
|
252
|
+
export { z as AgentsListPage };
|
|
269
253
|
|
|
270
254
|
//# sourceMappingURL=AgentsListPage.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AgentsListPage.js","names":[],"sources":["../../../../src/subscriberbot/pages/agents/AgentsListPage.tsx"],"sourcesContent":["/**\n * AI Agents list\n * @module subscriberbot/pages/agents\n *\n * The AI Agents Framework — specialized agents (Discovery, Renewal, Cost,\n * Newsletter, Vendor, Compliance, Negotiation, Migration, Concierge) that each\n * own a slice of the recurring-relationship problem. Filter by kind / posture.\n * Reads `subListAgents`; sets posture inline via `subSetAgentStatus`.\n */\n\nimport { useState } from 'react';\nimport {\n Plus,\n Bot,\n Search,\n RefreshCw,\n DollarSign,\n Mail,\n Building2,\n ShieldCheck,\n Handshake,\n ArrowLeftRight,\n ConciergeBell,\n Clock,\n Zap,\n Sparkles,\n type LucideIcon,\n} from 'lucide-react';\nimport { PagePurpose, GlassCard } from '@burdenoff/fe-libs/ui';\nimport {\n PageLayout,\n StatusBadge,\n EmptyState,\n MetricsCard,\n Donut,\n Legend,\n LoadingView,\n ErrorView,\n type Segment,\n} from '../../components';\nimport { useSubscriberBot } from '../../context/SubscriberBotContext';\nimport { useAgents, useSetAgentStatus } from '../../hooks/useSubscriberBotApi';\nimport { formatEnumLabel, formatRelativeTime } from '../../utils/formatters';\nimport type { SubAgentKind, SubAgentStatus } from '../../types';\n\nconst KIND_OPTIONS: Array<{ value: '' | SubAgentKind; label: string }> = [\n { value: '', label: 'All kinds' },\n { value: 'DISCOVERY', label: 'Discovery' },\n { value: 'RENEWAL', label: 'Renewal' },\n { value: 'COST', label: 'Cost' },\n { value: 'NEWSLETTER', label: 'Newsletter' },\n { value: 'VENDOR', label: 'Vendor' },\n { value: 'COMPLIANCE', label: 'Compliance' },\n { value: 'NEGOTIATION', label: 'Negotiation' },\n { value: 'MIGRATION', label: 'Migration' },\n { value: 'CONCIERGE', label: 'Concierge' },\n];\n\nconst STATUS_OPTIONS: SubAgentStatus[] = ['DISABLED', 'SUGGEST_ONLY', 'AUTONOMOUS'];\n\n/** Kind → glyph. Purely presentational; falls back to the generic Bot mark. */\nconst KIND_ICON: Record<SubAgentKind, LucideIcon> = {\n DISCOVERY: Search,\n RENEWAL: RefreshCw,\n COST: DollarSign,\n NEWSLETTER: Mail,\n VENDOR: Building2,\n COMPLIANCE: ShieldCheck,\n NEGOTIATION: Handshake,\n MIGRATION: ArrowLeftRight,\n CONCIERGE: ConciergeBell,\n};\n\n/** Posture → semantic chart colour (tokens only) for the fleet donut. */\nconst POSTURE_COLOR: Record<SubAgentStatus, string> = {\n AUTONOMOUS: 'var(--color-status-success-text)',\n SUGGEST_ONLY: 'var(--color-accent-indigo)',\n DISABLED: 'var(--color-text-secondary)',\n};\n\nconst DAY_MS = 24 * 60 * 60 * 1000;\n\nexport function AgentsListPage() {\n const { navigateTo } = useSubscriberBot();\n const [kind, setKind] = useState<'' | SubAgentKind>('');\n const [status, setStatus] = useState<'' | SubAgentStatus>('');\n\n const { data, isLoading, isError, refetch } = useAgents({\n kind: kind || undefined,\n status: status || undefined,\n });\n const setAgentStatus = useSetAgentStatus();\n\n const agents = data ?? [];\n\n // --- Real, computed fleet aggregates (never hardcoded) --------------------\n const postureCounts: Record<SubAgentStatus, number> = {\n AUTONOMOUS: 0,\n SUGGEST_ONLY: 0,\n DISABLED: 0,\n };\n let recentlyRun = 0;\n const now = Date.now();\n for (const a of agents) {\n postureCounts[a.status] += 1;\n if (a.lastRunAt && now - new Date(a.lastRunAt).getTime() <= 7 * DAY_MS) recentlyRun += 1;\n }\n const postureData: Segment[] = STATUS_OPTIONS.map((s) => ({\n label: formatEnumLabel(s),\n value: postureCounts[s],\n color: POSTURE_COLOR[s],\n })).filter((d) => d.value > 0);\n\n return (\n <PageLayout\n title=\"AI Agents\"\n description=\"Specialized agents that automate your recurring portfolio\"\n actions={\n <button\n type=\"button\"\n onClick={() => navigateTo('/agents/new')}\n className=\"inline-flex items-center gap-2 rounded-lg bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:opacity-90\"\n >\n <Plus className=\"h-4 w-4\" /> New agent\n </button>\n }\n >\n <PagePurpose className=\"mb-4\">\n Agents propose; your policies decide what they may do autonomously. Set each agent's posture\n — Disabled, Suggest-only, or Autonomous — and open one to review its policies.\n </PagePurpose>\n\n <div className=\"flex flex-wrap items-center gap-3\">\n <select\n aria-label=\"Filter by kind\"\n value={kind}\n onChange={(e) => setKind(e.target.value as '' | SubAgentKind)}\n className=\"rounded-lg border border-border-subtle bg-bg-surface px-3 py-2 text-xs text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n >\n {KIND_OPTIONS.map((o) => (\n <option key={o.value} value={o.value}>\n {o.label}\n </option>\n ))}\n </select>\n <select\n aria-label=\"Filter by posture\"\n value={status}\n onChange={(e) => setStatus(e.target.value as '' | SubAgentStatus)}\n className=\"rounded-lg border border-border-subtle bg-bg-surface px-3 py-2 text-xs text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n >\n <option value=\"\">Any posture</option>\n {STATUS_OPTIONS.map((s) => (\n <option key={s} value={s}>\n {formatEnumLabel(s)}\n </option>\n ))}\n </select>\n </div>\n\n {isLoading ? (\n <LoadingView label=\"Loading agents…\" />\n ) : isError ? (\n <ErrorView message=\"Could not load agents.\" onRetry={() => void refetch()} />\n ) : agents.length === 0 ? (\n <div className=\"mt-6\">\n <EmptyState\n illustration=\"empty-data\"\n icon={<Bot className=\"h-12 w-12\" />}\n title=\"No agents yet\"\n description=\"Create your first AI agent to start automating discovery, renewals, or cost optimization.\"\n action={\n <button\n type=\"button\"\n onClick={() => navigateTo('/agents/new')}\n className=\"rounded-lg bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:opacity-90\"\n >\n New agent\n </button>\n }\n />\n </div>\n ) : (\n <>\n {/* --- Fleet overview: posture mix + live counts (computed) ------ */}\n <div className=\"mt-6 grid grid-cols-1 gap-4 lg:grid-cols-3\">\n <GlassCard treatment=\"insight\" className=\"p-5 lg:col-span-1\">\n <p className=\"text-sm font-semibold text-text-primary\">Fleet posture</p>\n <p className=\"mt-0.5 text-xs text-text-secondary\">\n How your agents are allowed to act\n </p>\n <div className=\"mt-4 flex items-center gap-5\">\n <Donut\n data={postureData}\n size={132}\n thickness={16}\n centerLabel={String(agents.length)}\n centerSub={agents.length === 1 ? 'agent' : 'agents'}\n />\n <Legend className=\"flex-1\" data={postureData} />\n </div>\n </GlassCard>\n\n <div className=\"grid grid-cols-2 gap-4 lg:col-span-2\">\n <MetricsCard\n icon={<Bot className=\"h-5 w-5\" />}\n value={agents.length}\n label=\"Total agents\"\n />\n <MetricsCard\n icon={<Zap className=\"h-5 w-5\" />}\n value={postureCounts.AUTONOMOUS}\n label=\"Autonomous\"\n />\n <MetricsCard\n icon={<Sparkles className=\"h-5 w-5\" />}\n value={postureCounts.SUGGEST_ONLY}\n label=\"Suggest-only\"\n />\n <MetricsCard\n icon={<Clock className=\"h-5 w-5\" />}\n value={recentlyRun}\n label=\"Ran in last 7 days\"\n />\n </div>\n </div>\n\n {/* --- Agent cards ------------------------------------------------ */}\n <div className=\"mt-6 grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3\">\n {agents.map((a) => {\n const Icon = KIND_ICON[a.kind] ?? Bot;\n return (\n <GlassCard\n key={a.id}\n treatment=\"metric\"\n glow={a.status === 'AUTONOMOUS'}\n className=\"flex flex-col p-5\"\n >\n <button\n type=\"button\"\n onClick={() => navigateTo(`/agents/${a.id}`)}\n className=\"rounded-lg text-left focus:outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-focus-ring)]\"\n aria-label={`Open ${a.name}`}\n >\n <div className=\"flex items-start justify-between gap-2\">\n <span className=\"flex size-10 items-center justify-center rounded-xl bg-[var(--color-accent-soft)] text-text-primary\">\n <Icon className=\"h-5 w-5\" />\n </span>\n <StatusBadge status={a.status} />\n </div>\n <p className=\"mt-3 truncate text-sm font-semibold text-text-primary\">\n {a.name}\n </p>\n <p className=\"text-xs text-text-secondary\">{formatEnumLabel(a.kind)} agent</p>\n <p className=\"mt-2 line-clamp-2 min-h-[2rem] text-xs text-text-secondary\">\n {a.description || 'No description provided.'}\n </p>\n <p className=\"mt-3 flex items-center gap-1.5 text-xs text-text-secondary\">\n <Clock className=\"h-3.5 w-3.5\" aria-hidden />\n {a.lastRunAt ? `Last run ${formatRelativeTime(a.lastRunAt)}` : 'Never run'}\n </p>\n </button>\n <div className=\"mt-4 border-t border-border-subtle pt-3\">\n <label className=\"mb-1 block text-[10px] font-medium uppercase tracking-wide text-text-secondary\">\n Posture\n </label>\n <select\n aria-label={`Posture for ${a.name}`}\n value={a.status}\n disabled={setAgentStatus.isPending}\n onChange={(e) =>\n setAgentStatus.mutate({\n id: a.id,\n status: e.target.value as SubAgentStatus,\n })\n }\n className=\"w-full rounded-lg border border-border-subtle bg-bg-surface px-2 py-1.5 text-xs text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)] disabled:opacity-50\"\n >\n {STATUS_OPTIONS.map((s) => (\n <option key={s} value={s}>\n {formatEnumLabel(s)}\n </option>\n ))}\n </select>\n </div>\n </GlassCard>\n );\n })}\n </div>\n </>\n )}\n </PageLayout>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"AgentsListPage.js","names":[],"sources":["../../../../src/subscriberbot/pages/agents/AgentsListPage.tsx"],"sourcesContent":["/**\n * AI Agents list\n * @module subscriberbot/pages/agents\n *\n * The AI Agents Framework — specialized agents (Discovery, Renewal, Cost,\n * Newsletter, Vendor, Compliance, Negotiation, Migration, Concierge) that each\n * own a slice of the recurring-relationship problem. Filter by kind / posture.\n * Reads `subListAgents`; sets posture inline via `subSetAgentStatus`.\n */\n\nimport { useState } from 'react';\nimport {\n Plus,\n Bot,\n Search,\n RefreshCw,\n DollarSign,\n Mail,\n Building2,\n ShieldCheck,\n Handshake,\n ArrowLeftRight,\n ConciergeBell,\n Clock,\n Zap,\n Sparkles,\n type LucideIcon,\n} from 'lucide-react';\nimport { PagePurpose, GlassCard } from '@burdenoff/fe-libs/ui';\nimport {\n PageLayout,\n StatusBadge,\n EmptyState,\n MetricsCard,\n Donut,\n Legend,\n LoadingView,\n ErrorView,\n type Segment,\n} from '../../components';\nimport { useSubscriberBot } from '../../context/SubscriberBotContext';\nimport { useAgents, useSetAgentStatus } from '../../hooks/useSubscriberBotApi';\nimport { useTr } from '../../hooks/useTr';\nimport { formatEnumLabel, formatRelativeTime } from '../../utils/formatters';\nimport type { SubAgentKind, SubAgentStatus } from '../../types';\n\nconst KIND_KEY: Record<SubAgentKind, string> = {\n DISCOVERY: 'agents.kinds.discovery',\n RENEWAL: 'agents.kinds.renewal',\n COST: 'agents.kinds.cost',\n NEWSLETTER: 'agents.kinds.newsletter',\n VENDOR: 'agents.kinds.vendor',\n COMPLIANCE: 'agents.kinds.compliance',\n NEGOTIATION: 'agents.kinds.negotiation',\n MIGRATION: 'agents.kinds.migration',\n CONCIERGE: 'agents.kinds.concierge',\n};\n\nconst STATUS_OPTIONS: SubAgentStatus[] = ['DISABLED', 'SUGGEST_ONLY', 'AUTONOMOUS'];\n\n/** Kind → glyph. Purely presentational; falls back to the generic Bot mark. */\nconst KIND_ICON: Record<SubAgentKind, LucideIcon> = {\n DISCOVERY: Search,\n RENEWAL: RefreshCw,\n COST: DollarSign,\n NEWSLETTER: Mail,\n VENDOR: Building2,\n COMPLIANCE: ShieldCheck,\n NEGOTIATION: Handshake,\n MIGRATION: ArrowLeftRight,\n CONCIERGE: ConciergeBell,\n};\n\n/** Posture → semantic chart colour (tokens only) for the fleet donut. */\nconst POSTURE_COLOR: Record<SubAgentStatus, string> = {\n AUTONOMOUS: 'var(--color-status-success-text)',\n SUGGEST_ONLY: 'var(--color-accent-indigo)',\n DISABLED: 'var(--color-text-secondary)',\n};\n\nconst DAY_MS = 24 * 60 * 60 * 1000;\n\nexport function AgentsListPage() {\n const tr = useTr();\n const { navigateTo } = useSubscriberBot();\n const [kind, setKind] = useState<'' | SubAgentKind>('');\n const [status, setStatus] = useState<'' | SubAgentStatus>('');\n\n const kindOptions: Array<{ value: '' | SubAgentKind; label: string }> = [\n { value: '', label: tr('agents.filters.allKinds', 'All kinds') },\n ...Object.entries(KIND_KEY).map(([value, key]) => ({\n value: value as SubAgentKind,\n label: tr(key, formatEnumLabel(value as SubAgentKind)),\n })),\n ];\n\n const { data, isLoading, isError, refetch } = useAgents({\n kind: kind || undefined,\n status: status || undefined,\n });\n const setAgentStatus = useSetAgentStatus();\n\n const agents = data ?? [];\n\n // --- Real, computed fleet aggregates (never hardcoded) --------------------\n const postureCounts: Record<SubAgentStatus, number> = {\n AUTONOMOUS: 0,\n SUGGEST_ONLY: 0,\n DISABLED: 0,\n };\n let recentlyRun = 0;\n const now = Date.now();\n for (const a of agents) {\n postureCounts[a.status] += 1;\n if (a.lastRunAt && now - new Date(a.lastRunAt).getTime() <= 7 * DAY_MS) recentlyRun += 1;\n }\n const postureData: Segment[] = STATUS_OPTIONS.map((s) => ({\n label: tr(`agents.postures.${s.toLowerCase()}`, formatEnumLabel(s)),\n value: postureCounts[s],\n color: POSTURE_COLOR[s],\n })).filter((d) => d.value > 0);\n\n return (\n <PageLayout\n title={tr('agents.title', 'AI Agents')}\n description={tr(\n 'agents.description',\n 'Specialized agents that automate your recurring portfolio'\n )}\n actions={\n <button\n type=\"button\"\n onClick={() => navigateTo('/agents/new')}\n className=\"inline-flex items-center gap-2 rounded-lg bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:opacity-90\"\n >\n <Plus className=\"h-4 w-4\" /> {tr('agents.newAgent', 'New agent')}\n </button>\n }\n >\n <PagePurpose className=\"mb-4\">\n {tr(\n 'agents.purpose',\n \"Agents propose; your policies decide what they may do autonomously. Set each agent's posture — Disabled, Suggest-only, or Autonomous — and open one to review its policies.\"\n )}\n </PagePurpose>\n\n <div className=\"flex flex-wrap items-center gap-3\">\n <select\n aria-label={tr('agents.filters.kindLabel', 'Filter by kind')}\n value={kind}\n onChange={(e) => setKind(e.target.value as '' | SubAgentKind)}\n className=\"rounded-lg border border-border-subtle bg-bg-surface px-3 py-2 text-xs text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n >\n {kindOptions.map((o) => (\n <option key={o.value} value={o.value}>\n {o.label}\n </option>\n ))}\n </select>\n <select\n aria-label={tr('agents.filters.postureLabel', 'Filter by posture')}\n value={status}\n onChange={(e) => setStatus(e.target.value as '' | SubAgentStatus)}\n className=\"rounded-lg border border-border-subtle bg-bg-surface px-3 py-2 text-xs text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n >\n <option value=\"\">{tr('agents.filters.anyPosture', 'Any posture')}</option>\n {STATUS_OPTIONS.map((s) => (\n <option key={s} value={s}>\n {tr(`agents.postures.${s.toLowerCase()}`, formatEnumLabel(s))}\n </option>\n ))}\n </select>\n </div>\n\n {isLoading ? (\n <LoadingView label={tr('agents.loading', 'Loading agents…')} />\n ) : isError ? (\n <ErrorView\n message={tr('agents.error', 'Could not load agents.')}\n onRetry={() => void refetch()}\n />\n ) : agents.length === 0 ? (\n <div className=\"mt-6\">\n <EmptyState\n illustration=\"empty-data\"\n icon={<Bot className=\"h-12 w-12\" />}\n title={tr('agents.emptyTitle', 'No agents yet')}\n description={tr(\n 'agents.emptyDescription',\n 'Create your first AI agent to start automating discovery, renewals, or cost optimization.'\n )}\n action={\n <button\n type=\"button\"\n onClick={() => navigateTo('/agents/new')}\n className=\"rounded-lg bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:opacity-90\"\n >\n {tr('agents.newAgent', 'New agent')}\n </button>\n }\n />\n </div>\n ) : (\n <>\n {/* --- Fleet overview: posture mix + live counts (computed) ------ */}\n <div className=\"mt-6 grid grid-cols-1 gap-4 lg:grid-cols-3\">\n <GlassCard treatment=\"insight\" className=\"p-5 lg:col-span-1\">\n <p className=\"text-sm font-semibold text-text-primary\">\n {tr('agents.fleet.title', 'Fleet posture')}\n </p>\n <p className=\"mt-0.5 text-xs text-text-secondary\">\n {tr('agents.fleet.description', 'How your agents are allowed to act')}\n </p>\n <div className=\"mt-4 flex items-center gap-5\">\n <Donut\n data={postureData}\n size={132}\n thickness={16}\n centerLabel={String(agents.length)}\n centerSub={\n agents.length === 1\n ? tr('agents.fleet.agentSingular', 'agent')\n : tr('agents.fleet.agentPlural', 'agents')\n }\n />\n <Legend className=\"flex-1\" data={postureData} />\n </div>\n </GlassCard>\n\n <div className=\"grid grid-cols-2 gap-4 lg:col-span-2\">\n <MetricsCard\n icon={<Bot className=\"h-5 w-5\" />}\n value={agents.length}\n label={tr('agents.fleet.totalAgents', 'Total agents')}\n />\n <MetricsCard\n icon={<Zap className=\"h-5 w-5\" />}\n value={postureCounts.AUTONOMOUS}\n label={tr('agents.postures.autonomous', 'Autonomous')}\n />\n <MetricsCard\n icon={<Sparkles className=\"h-5 w-5\" />}\n value={postureCounts.SUGGEST_ONLY}\n label={tr('agents.postures.suggestOnly', 'Suggest-only')}\n />\n <MetricsCard\n icon={<Clock className=\"h-5 w-5\" />}\n value={recentlyRun}\n label={tr('agents.fleet.ranLast7Days', 'Ran in last 7 days')}\n />\n </div>\n </div>\n\n {/* --- Agent cards ------------------------------------------------ */}\n <div className=\"mt-6 grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3\">\n {agents.map((a) => {\n const Icon = KIND_ICON[a.kind] ?? Bot;\n return (\n <GlassCard\n key={a.id}\n treatment=\"metric\"\n glow={a.status === 'AUTONOMOUS'}\n className=\"flex flex-col p-5\"\n >\n <button\n type=\"button\"\n onClick={() => navigateTo(`/agents/${a.id}`)}\n className=\"rounded-lg text-left focus:outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-focus-ring)]\"\n aria-label={tr('agents.card.openAria', 'Open {{name}}', { name: a.name })}\n >\n <div className=\"flex items-start justify-between gap-2\">\n <span className=\"flex size-10 items-center justify-center rounded-xl bg-[var(--color-accent-soft)] text-text-primary\">\n <Icon className=\"h-5 w-5\" />\n </span>\n <StatusBadge status={a.status} />\n </div>\n <p className=\"mt-3 truncate text-sm font-semibold text-text-primary\">\n {a.name}\n </p>\n <p className=\"text-xs text-text-secondary\">\n {tr(KIND_KEY[a.kind], formatEnumLabel(a.kind))}{' '}\n {tr('agents.card.kindSuffix', 'agent')}\n </p>\n <p className=\"mt-2 line-clamp-2 min-h-[2rem] text-xs text-text-secondary\">\n {a.description || tr('agents.card.noDescription', 'No description provided.')}\n </p>\n <p className=\"mt-3 flex items-center gap-1.5 text-xs text-text-secondary\">\n <Clock className=\"h-3.5 w-3.5\" aria-hidden />\n {a.lastRunAt\n ? tr('agents.card.lastRun', 'Last run {{when}}', {\n when: formatRelativeTime(a.lastRunAt),\n })\n : tr('agents.card.neverRun', 'Never run')}\n </p>\n </button>\n <div className=\"mt-4 border-t border-border-subtle pt-3\">\n <label className=\"mb-1 block text-[10px] font-medium uppercase tracking-wide text-text-secondary\">\n {tr('agents.card.posture', 'Posture')}\n </label>\n <select\n aria-label={tr('agents.card.postureAria', 'Posture for {{name}}', {\n name: a.name,\n })}\n value={a.status}\n disabled={setAgentStatus.isPending}\n onChange={(e) =>\n setAgentStatus.mutate({\n id: a.id,\n status: e.target.value as SubAgentStatus,\n })\n }\n className=\"w-full rounded-lg border border-border-subtle bg-bg-surface px-2 py-1.5 text-xs text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)] disabled:opacity-50\"\n >\n {STATUS_OPTIONS.map((s) => (\n <option key={s} value={s}>\n {tr(`agents.postures.${s.toLowerCase()}`, formatEnumLabel(s))}\n </option>\n ))}\n </select>\n </div>\n </GlassCard>\n );\n })}\n </div>\n </>\n )}\n </PageLayout>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;AA8CA,IAAM,IAAyC;CAC7C,WAAW;CACX,SAAS;CACT,MAAM;CACN,YAAY;CACZ,QAAQ;CACR,YAAY;CACZ,aAAa;CACb,WAAW;CACX,WAAW;CACZ,EAEK,IAAmC;CAAC;CAAY;CAAgB;CAAa,EAG7E,IAA8C;CAClD,WAAW;CACX,SAAS;CACT,MAAM;CACN,YAAY;CACZ,QAAQ;CACR,YAAY;CACZ,aAAa;CACb,WAAW;CACX,WAAW;CACZ,EAGK,IAAgD;CACpD,YAAY;CACZ,cAAc;CACd,UAAU;CACX,EAEK,IAAS,OAAU,KAAK;AAE9B,SAAgB,IAAiB;CAC/B,IAAM,IAAK,GAAO,EACZ,EAAE,kBAAe,GAAkB,EACnC,CAAC,GAAM,KAAW,EAA4B,GAAG,EACjD,CAAC,GAAQ,KAAa,EAA8B,GAAG,EAEvD,IAAkE,CACtE;EAAE,OAAO;EAAI,OAAO,EAAG,2BAA2B,YAAY;EAAE,EAChE,GAAG,OAAO,QAAQ,EAAS,CAAC,KAAK,CAAC,GAAO,QAAU;EAC1C;EACP,OAAO,EAAG,GAAK,EAAgB,EAAsB,CAAC;EACvD,EAAE,CACJ,EAEK,EAAE,SAAM,cAAW,YAAS,eAAY,EAAU;EACtD,MAAM,KAAQ,KAAA;EACd,QAAQ,KAAU,KAAA;EACnB,CAAC,EACI,IAAiB,GAAmB,EAEpC,IAAS,KAAQ,EAAE,EAGnB,IAAgD;EACpD,YAAY;EACZ,cAAc;EACd,UAAU;EACX,EACG,IAAc,GACZ,IAAM,KAAK,KAAK;AACtB,MAAK,IAAM,KAAK,EAEd,CADA,EAAc,EAAE,WAAW,GACvB,EAAE,aAAa,IAAM,IAAI,KAAK,EAAE,UAAU,CAAC,SAAS,IAAI,IAAI,MAAQ,KAAe;CAEzF,IAAM,IAAyB,EAAe,KAAK,OAAO;EACxD,OAAO,EAAG,mBAAmB,EAAE,aAAa,IAAI,EAAgB,EAAE,CAAC;EACnE,OAAO,EAAc;EACrB,OAAO,EAAc;EACtB,EAAE,CAAC,QAAQ,MAAM,EAAE,QAAQ,EAAE;AAE9B,QACE,kBAAC,GAAD;EACE,OAAO,EAAG,gBAAgB,YAAY;EACtC,aAAa,EACX,sBACA,4DACD;EACD,SACE,kBAAC,UAAD;GACE,MAAK;GACL,eAAe,EAAW,cAAc;GACxC,WAAU;aAHZ;IAKE,kBAAC,GAAD,EAAM,WAAU,WAAY,CAAA;;IAAE,EAAG,mBAAmB,YAAY;IACzD;;YAbb;GAgBE,kBAAC,GAAD;IAAa,WAAU;cACpB,EACC,kBACA,8KACD;IACW,CAAA;GAEd,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,UAAD;KACE,cAAY,EAAG,4BAA4B,iBAAiB;KAC5D,OAAO;KACP,WAAW,MAAM,EAAQ,EAAE,OAAO,MAA2B;KAC7D,WAAU;eAET,EAAY,KAAK,MAChB,kBAAC,UAAD;MAAsB,OAAO,EAAE;gBAC5B,EAAE;MACI,EAFI,EAAE,MAEN,CACT;KACK,CAAA,EACT,kBAAC,UAAD;KACE,cAAY,EAAG,+BAA+B,oBAAoB;KAClE,OAAO;KACP,WAAW,MAAM,EAAU,EAAE,OAAO,MAA6B;KACjE,WAAU;eAJZ,CAME,kBAAC,UAAD;MAAQ,OAAM;gBAAI,EAAG,6BAA6B,cAAc;MAAU,CAAA,EACzE,EAAe,KAAK,MACnB,kBAAC,UAAD;MAAgB,OAAO;gBACpB,EAAG,mBAAmB,EAAE,aAAa,IAAI,EAAgB,EAAE,CAAC;MACtD,EAFI,EAEJ,CACT,CACK;OACL;;GAEL,IACC,kBAAC,GAAD,EAAa,OAAO,EAAG,kBAAkB,kBAAkB,EAAI,CAAA,GAC7D,IACF,kBAAC,GAAD;IACE,SAAS,EAAG,gBAAgB,yBAAyB;IACrD,eAAe,KAAK,GAAS;IAC7B,CAAA,GACA,EAAO,WAAW,IACpB,kBAAC,OAAD;IAAK,WAAU;cACb,kBAAC,GAAD;KACE,cAAa;KACb,MAAM,kBAAC,GAAD,EAAK,WAAU,aAAc,CAAA;KACnC,OAAO,EAAG,qBAAqB,gBAAgB;KAC/C,aAAa,EACX,2BACA,4FACD;KACD,QACE,kBAAC,UAAD;MACE,MAAK;MACL,eAAe,EAAW,cAAc;MACxC,WAAU;gBAET,EAAG,mBAAmB,YAAY;MAC5B,CAAA;KAEX,CAAA;IACE,CAAA,GAEN,kBAAA,GAAA,EAAA,UAAA,CAEE,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,GAAD;KAAW,WAAU;KAAU,WAAU;eAAzC;MACE,kBAAC,KAAD;OAAG,WAAU;iBACV,EAAG,sBAAsB,gBAAgB;OACxC,CAAA;MACJ,kBAAC,KAAD;OAAG,WAAU;iBACV,EAAG,4BAA4B,qCAAqC;OACnE,CAAA;MACJ,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,GAAD;QACE,MAAM;QACN,MAAM;QACN,WAAW;QACX,aAAa,OAAO,EAAO,OAAO;QAClC,WACE,EAAO,WAAW,IACd,EAAG,8BAA8B,QAAQ,GACzC,EAAG,4BAA4B,SAAS;QAE9C,CAAA,EACF,kBAAC,GAAD;QAAQ,WAAU;QAAS,MAAM;QAAe,CAAA,CAC5C;;MACI;QAEZ,kBAAC,OAAD;KAAK,WAAU;eAAf;MACE,kBAAC,GAAD;OACE,MAAM,kBAAC,GAAD,EAAK,WAAU,WAAY,CAAA;OACjC,OAAO,EAAO;OACd,OAAO,EAAG,4BAA4B,eAAe;OACrD,CAAA;MACF,kBAAC,GAAD;OACE,MAAM,kBAAC,GAAD,EAAK,WAAU,WAAY,CAAA;OACjC,OAAO,EAAc;OACrB,OAAO,EAAG,8BAA8B,aAAa;OACrD,CAAA;MACF,kBAAC,GAAD;OACE,MAAM,kBAAC,GAAD,EAAU,WAAU,WAAY,CAAA;OACtC,OAAO,EAAc;OACrB,OAAO,EAAG,+BAA+B,eAAe;OACxD,CAAA;MACF,kBAAC,GAAD;OACE,MAAM,kBAAC,GAAD,EAAO,WAAU,WAAY,CAAA;OACnC,OAAO;OACP,OAAO,EAAG,6BAA6B,qBAAqB;OAC5D,CAAA;MACE;OACF;OAGN,kBAAC,OAAD;IAAK,WAAU;cACZ,EAAO,KAAK,MAAM;KACjB,IAAM,IAAO,EAAU,EAAE,SAAS;AAClC,YACE,kBAAC,GAAD;MAEE,WAAU;MACV,MAAM,EAAE,WAAW;MACnB,WAAU;gBAJZ,CAME,kBAAC,UAAD;OACE,MAAK;OACL,eAAe,EAAW,WAAW,EAAE,KAAK;OAC5C,WAAU;OACV,cAAY,EAAG,wBAAwB,iBAAiB,EAAE,MAAM,EAAE,MAAM,CAAC;iBAJ3E;QAME,kBAAC,OAAD;SAAK,WAAU;mBAAf,CACE,kBAAC,QAAD;UAAM,WAAU;oBACd,kBAAC,GAAD,EAAM,WAAU,WAAY,CAAA;UACvB,CAAA,EACP,kBAAC,GAAD,EAAa,QAAQ,EAAE,QAAU,CAAA,CAC7B;;QACN,kBAAC,KAAD;SAAG,WAAU;mBACV,EAAE;SACD,CAAA;QACJ,kBAAC,KAAD;SAAG,WAAU;mBAAb;UACG,EAAG,EAAS,EAAE,OAAO,EAAgB,EAAE,KAAK,CAAC;UAAE;UAC/C,EAAG,0BAA0B,QAAQ;UACpC;;QACJ,kBAAC,KAAD;SAAG,WAAU;mBACV,EAAE,eAAe,EAAG,6BAA6B,2BAA2B;SAC3E,CAAA;QACJ,kBAAC,KAAD;SAAG,WAAU;mBAAb,CACE,kBAAC,GAAD;UAAO,WAAU;UAAc,eAAA;UAAc,CAAA,EAC5C,EAAE,YACC,EAAG,uBAAuB,qBAAqB,EAC7C,MAAM,EAAmB,EAAE,UAAU,EACtC,CAAC,GACF,EAAG,wBAAwB,YAAY,CACzC;;QACG;UACT,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,SAAD;QAAO,WAAU;kBACd,EAAG,uBAAuB,UAAU;QAC/B,CAAA,EACR,kBAAC,UAAD;QACE,cAAY,EAAG,2BAA2B,wBAAwB,EAChE,MAAM,EAAE,MACT,CAAC;QACF,OAAO,EAAE;QACT,UAAU,EAAe;QACzB,WAAW,MACT,EAAe,OAAO;SACpB,IAAI,EAAE;SACN,QAAQ,EAAE,OAAO;SAClB,CAAC;QAEJ,WAAU;kBAET,EAAe,KAAK,MACnB,kBAAC,UAAD;SAAgB,OAAO;mBACpB,EAAG,mBAAmB,EAAE,aAAa,IAAI,EAAgB,EAAE,CAAC;SACtD,EAFI,EAEJ,CACT;QACK,CAAA,CACL;SACI;QA7DL,EAAE,GA6DG;MAEd;IACE,CAAA,CACL,EAAA,CAAA;GAEM"}
|
|
@@ -3,8 +3,10 @@
|
|
|
3
3
|
* @module subscriberbot/pages/providers
|
|
4
4
|
*
|
|
5
5
|
* A provider profile from the registry: category, status, region, scores,
|
|
6
|
-
* tags and its published plans. Reads `subProvider(id)
|
|
7
|
-
* `
|
|
6
|
+
* tags and its published plans. Reads `subProvider(id)` and
|
|
7
|
+
* `subListBenchmarkDataPoints` (the observed price points behind the "Price
|
|
8
|
+
* history" card); writes `subUpdateProvider`, `subArchiveProvider`,
|
|
9
|
+
* `subCreatePlan`.
|
|
8
10
|
*/
|
|
9
11
|
export declare function ProviderDetailPage(): import("react").JSX.Element;
|
|
10
12
|
//# sourceMappingURL=ProviderDetailPage.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ProviderDetailPage.d.ts","sourceRoot":"","sources":["../../../../src/subscriberbot/pages/providers/ProviderDetailPage.tsx"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"ProviderDetailPage.d.ts","sourceRoot":"","sources":["../../../../src/subscriberbot/pages/providers/ProviderDetailPage.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAoxBH,wBAAgB,kBAAkB,gCAsWjC"}
|