@burdenoff/microfe-botmanor 2026.1027.2 → 2026.1027.3
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/botlit/BotlitRoutes.js +142 -132
- package/dist/botlit/BotlitRoutes.js.map +1 -1
- package/dist/botlit/components/AgentApprovalPanel.js +144 -126
- package/dist/botlit/components/AgentApprovalPanel.js.map +1 -1
- package/dist/botlit/components/ModelRegistrationPanel.js +4 -4
- package/dist/botlit/components/VersionHistoryPanel.js +92 -83
- package/dist/botlit/components/VersionHistoryPanel.js.map +1 -1
- package/dist/botlit/pages/A2AAgentDetailPage.js +212 -203
- package/dist/botlit/pages/A2AAgentDetailPage.js.map +1 -1
- package/dist/botlit/pages/A2ARegistryPage.js +129 -117
- package/dist/botlit/pages/A2ARegistryPage.js.map +1 -1
- package/dist/botlit/pages/AgentApprovalsPage.js +122 -110
- package/dist/botlit/pages/AgentApprovalsPage.js.map +1 -1
- package/dist/botlit/pages/AgentBuilderPage.js +18 -18
- package/dist/botlit/pages/AgentDetailPage.js +298 -273
- package/dist/botlit/pages/AgentDetailPage.js.map +1 -1
- package/dist/botlit/pages/AgentsListPage.js +145 -121
- package/dist/botlit/pages/AgentsListPage.js.map +1 -1
- package/dist/botlit/pages/BotChannelsTab.js +238 -226
- package/dist/botlit/pages/BotChannelsTab.js.map +1 -1
- package/dist/botlit/pages/BotDetailPage.js +307 -288
- package/dist/botlit/pages/BotDetailPage.js.map +1 -1
- package/dist/botlit/pages/BotWorkflowTab.js +125 -116
- package/dist/botlit/pages/BotWorkflowTab.js.map +1 -1
- package/dist/botlit/pages/BotsListPage.js +159 -144
- package/dist/botlit/pages/BotsListPage.js.map +1 -1
- package/dist/botlit/pages/BucketsPage.js +279 -258
- package/dist/botlit/pages/BucketsPage.js.map +1 -1
- package/dist/botlit/pages/ChannelDetailPage.js +346 -328
- package/dist/botlit/pages/ChannelDetailPage.js.map +1 -1
- package/dist/botlit/pages/ChannelRoutesPage.js +10 -10
- package/dist/botlit/pages/ChannelsPage.js +163 -148
- package/dist/botlit/pages/ChannelsPage.js.map +1 -1
- package/dist/botlit/pages/DashboardPage.js +129 -114
- package/dist/botlit/pages/DashboardPage.js.map +1 -1
- package/dist/botlit/pages/ExecutionDetailPage.js +145 -139
- package/dist/botlit/pages/ExecutionDetailPage.js.map +1 -1
- package/dist/botlit/pages/ExecutionsPage.js +14 -14
- package/dist/botlit/pages/InstalledPackagesPage.js +245 -227
- package/dist/botlit/pages/InstalledPackagesPage.js.map +1 -1
- package/dist/botlit/pages/KnowledgeBaseDetailPage.js +168 -156
- package/dist/botlit/pages/KnowledgeBaseDetailPage.js.map +1 -1
- package/dist/botlit/pages/KnowledgeBasesPage.js +91 -79
- package/dist/botlit/pages/KnowledgeBasesPage.js.map +1 -1
- package/dist/botlit/pages/MCPServerDetailPage.js +200 -188
- package/dist/botlit/pages/MCPServerDetailPage.js.map +1 -1
- package/dist/botlit/pages/MCPServersPage.js +170 -155
- package/dist/botlit/pages/MCPServersPage.js.map +1 -1
- package/dist/botlit/pages/PoliciesPage.js +113 -104
- package/dist/botlit/pages/PoliciesPage.js.map +1 -1
- package/dist/botlit/pages/PolicyDetailPage.js +145 -133
- package/dist/botlit/pages/PolicyDetailPage.js.map +1 -1
- package/dist/botlit/pages/PromptStudioPage.js +106 -97
- package/dist/botlit/pages/PromptStudioPage.js.map +1 -1
- package/dist/botlit/pages/PromptTemplateDetailPage.js +359 -347
- package/dist/botlit/pages/PromptTemplateDetailPage.js.map +1 -1
- package/dist/botlit/pages/PromptTemplatesPage.js +127 -112
- package/dist/botlit/pages/PromptTemplatesPage.js.map +1 -1
- package/dist/botlit/pages/RetrievalProfileDetailPage.js +219 -210
- package/dist/botlit/pages/RetrievalProfileDetailPage.js.map +1 -1
- package/dist/botlit/pages/RetrievalProfilesPage.js +112 -103
- package/dist/botlit/pages/RetrievalProfilesPage.js.map +1 -1
- package/dist/botlit/pages/SettingsPage.js +264 -252
- package/dist/botlit/pages/SettingsPage.js.map +1 -1
- package/dist/botlit/pages/SkillDetailPage.js +235 -226
- package/dist/botlit/pages/SkillDetailPage.js.map +1 -1
- package/dist/botlit/pages/SkillsPage.js +115 -106
- package/dist/botlit/pages/SkillsPage.js.map +1 -1
- package/dist/botlit/pages/StorePackageDetailPage.js +194 -188
- package/dist/botlit/pages/StorePackageDetailPage.js.map +1 -1
- package/dist/botlit/pages/StorePage.js +161 -155
- package/dist/botlit/pages/StorePage.js.map +1 -1
- package/dist/botlit/permissions/PermissionRequired.js +45 -0
- package/dist/botlit/permissions/PermissionRequired.js.map +1 -0
- package/dist/botlit/permissions/botmanorPermissions.js +72 -0
- package/dist/botlit/permissions/botmanorPermissions.js.map +1 -0
- package/dist/botlit/permissions/index.js +3 -0
- package/dist/botlit/permissions/useBotmanorPermissions.js +19 -0
- package/dist/botlit/permissions/useBotmanorPermissions.js.map +1 -0
- package/package.json +1 -1
|
@@ -1,60 +1,66 @@
|
|
|
1
1
|
import { useBotlit as e } from "../providers/BotlitProvider.js";
|
|
2
2
|
import { formatRelativeTime as t } from "../utils/formatters.js";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
3
|
+
import { BOTMANOR_PERMISSIONS as n } from "../permissions/botmanorPermissions.js";
|
|
4
|
+
import { BotmanorPermissionGate as r } from "../permissions/useBotmanorPermissions.js";
|
|
5
|
+
import { PageLayout as i } from "../components/PageLayout.js";
|
|
6
|
+
import { Button as a } from "../components/Button.js";
|
|
7
|
+
import "../permissions/index.js";
|
|
8
|
+
import { Card as o, CardContent as s, CardDescription as c, CardHeader as l, CardTitle as u } from "../components/Card.js";
|
|
9
|
+
import { Badge as d, StatusBadge as f } from "../components/Badge.js";
|
|
10
|
+
import { EmptyState as p } from "../components/EmptyState.js";
|
|
11
|
+
import { Input as m } from "../components/Input.js";
|
|
12
|
+
import { ErrorState as h } from "../components/ErrorState.js";
|
|
13
|
+
import { promptTemplateVariables as g, usePromptTemplates as _ } from "../hooks/usePromptTemplates.js";
|
|
11
14
|
import "../hooks/index.js";
|
|
12
|
-
import { useState as
|
|
13
|
-
import { GlassCard as
|
|
14
|
-
import { jsx as
|
|
15
|
-
import { Link as
|
|
16
|
-
import { Code as
|
|
15
|
+
import { useState as v } from "react";
|
|
16
|
+
import { GlassCard as y, PagePurpose as b } from "@burdenoff/fe-libs/ui";
|
|
17
|
+
import { jsx as x, jsxs as S } from "react/jsx-runtime";
|
|
18
|
+
import { Link as C } from "react-router";
|
|
19
|
+
import { Code as w, Copy as T, FileText as E, Filter as D, Play as O, Plus as k, Search as A, Tag as j, Variable as M } from "lucide-react";
|
|
17
20
|
//#region src/botlit/pages/PromptTemplatesPage.tsx
|
|
18
|
-
var
|
|
19
|
-
let { getPath:
|
|
20
|
-
return /* @__PURE__ */
|
|
21
|
+
var N = () => {
|
|
22
|
+
let { getPath: N } = e(), [P, F] = v(""), { data: I, loading: L, error: R, refetch: z } = _({ search: P });
|
|
23
|
+
return /* @__PURE__ */ x(i, {
|
|
21
24
|
title: "Prompt Templates",
|
|
22
25
|
description: "Create and manage reusable prompt templates with variable support",
|
|
23
|
-
actions: /* @__PURE__ */
|
|
24
|
-
|
|
25
|
-
children: /* @__PURE__ */
|
|
26
|
-
|
|
27
|
-
children:
|
|
26
|
+
actions: /* @__PURE__ */ x(r, {
|
|
27
|
+
permission: n.PROMPT_TEMPLATE_CREATE,
|
|
28
|
+
children: /* @__PURE__ */ x(a, {
|
|
29
|
+
leftIcon: /* @__PURE__ */ x(k, { size: 16 }),
|
|
30
|
+
children: /* @__PURE__ */ x(C, {
|
|
31
|
+
to: N("prompt-templates/new"),
|
|
32
|
+
children: "Create Template"
|
|
33
|
+
})
|
|
28
34
|
})
|
|
29
35
|
}),
|
|
30
|
-
children: /* @__PURE__ */
|
|
36
|
+
children: /* @__PURE__ */ S("div", {
|
|
31
37
|
className: "space-y-6",
|
|
32
38
|
children: [
|
|
33
|
-
/* @__PURE__ */ b
|
|
34
|
-
icon: /* @__PURE__ */
|
|
39
|
+
/* @__PURE__ */ S(b, {
|
|
40
|
+
icon: /* @__PURE__ */ x(E, { size: 18 }),
|
|
35
41
|
children: [
|
|
36
42
|
"Prompt templates are the reusable instructions that shape how an agent thinks and replies. Write the system prompt once with ",
|
|
37
|
-
/* @__PURE__ */
|
|
43
|
+
/* @__PURE__ */ x("code", { children: "{{variables}}" }),
|
|
38
44
|
" for the bits that change (role, company name, tone), version it, and reuse it across agents — so you can refine wording in one place instead of editing every agent by hand."
|
|
39
45
|
]
|
|
40
46
|
}),
|
|
41
|
-
/* @__PURE__ */
|
|
47
|
+
/* @__PURE__ */ S("div", {
|
|
42
48
|
className: "flex items-center gap-4",
|
|
43
|
-
children: [/* @__PURE__ */
|
|
49
|
+
children: [/* @__PURE__ */ S("div", {
|
|
44
50
|
className: "relative flex-1 max-w-md",
|
|
45
|
-
children: [/* @__PURE__ */
|
|
51
|
+
children: [/* @__PURE__ */ x(A, { className: "absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-text-secondary" }), /* @__PURE__ */ x(m, {
|
|
46
52
|
placeholder: "Search templates...",
|
|
47
|
-
value:
|
|
48
|
-
onChange: (e) =>
|
|
53
|
+
value: P,
|
|
54
|
+
onChange: (e) => F(e.target.value),
|
|
49
55
|
className: "pl-9"
|
|
50
56
|
})]
|
|
51
|
-
}), /* @__PURE__ */
|
|
57
|
+
}), /* @__PURE__ */ x(a, {
|
|
52
58
|
variant: "outline",
|
|
53
|
-
leftIcon: /* @__PURE__ */
|
|
59
|
+
leftIcon: /* @__PURE__ */ x(D, { size: 16 }),
|
|
54
60
|
children: "Filters"
|
|
55
61
|
})]
|
|
56
62
|
}),
|
|
57
|
-
|
|
63
|
+
L ? /* @__PURE__ */ x("div", {
|
|
58
64
|
className: "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4",
|
|
59
65
|
children: [
|
|
60
66
|
1,
|
|
@@ -63,84 +69,90 @@ var j = () => {
|
|
|
63
69
|
4,
|
|
64
70
|
5,
|
|
65
71
|
6
|
|
66
|
-
].map((e) => /* @__PURE__ */
|
|
67
|
-
}) :
|
|
72
|
+
].map((e) => /* @__PURE__ */ x("div", { className: "h-48 bg-bg-sunken motion-safe:animate-vc-shimmer rounded-lg" }, e))
|
|
73
|
+
}) : R ? /* @__PURE__ */ x(h, {
|
|
68
74
|
resource: "prompt templates",
|
|
69
|
-
error:
|
|
70
|
-
onRetry: () => void
|
|
71
|
-
}) :
|
|
75
|
+
error: R,
|
|
76
|
+
onRetry: () => void z()
|
|
77
|
+
}) : I.length > 0 ? /* @__PURE__ */ x("div", {
|
|
72
78
|
className: "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4",
|
|
73
|
-
children:
|
|
74
|
-
let
|
|
75
|
-
return /* @__PURE__ */
|
|
76
|
-
to:
|
|
77
|
-
children: /* @__PURE__ */
|
|
79
|
+
children: I.map((e) => {
|
|
80
|
+
let i = g(e).length;
|
|
81
|
+
return /* @__PURE__ */ x(C, {
|
|
82
|
+
to: N(`prompt-templates/${e.id}`),
|
|
83
|
+
children: /* @__PURE__ */ S(o, {
|
|
78
84
|
className: "h-full hover:border-primary/50 transition-colors cursor-pointer group",
|
|
79
|
-
children: [/* @__PURE__ */
|
|
85
|
+
children: [/* @__PURE__ */ x(l, { children: /* @__PURE__ */ S("div", {
|
|
80
86
|
className: "flex items-start justify-between",
|
|
81
|
-
children: [/* @__PURE__ */
|
|
87
|
+
children: [/* @__PURE__ */ S("div", {
|
|
82
88
|
className: "flex items-center gap-3",
|
|
83
|
-
children: [/* @__PURE__ */
|
|
89
|
+
children: [/* @__PURE__ */ x("div", {
|
|
84
90
|
className: "p-2 bg-action-primary-bg/10 rounded-lg",
|
|
85
|
-
children: /* @__PURE__ */
|
|
86
|
-
}), /* @__PURE__ */
|
|
91
|
+
children: /* @__PURE__ */ x(E, { className: "h-5 w-5 text-primary" })
|
|
92
|
+
}), /* @__PURE__ */ S("div", { children: [/* @__PURE__ */ x(u, {
|
|
87
93
|
className: "text-base",
|
|
88
94
|
children: e.name
|
|
89
|
-
}), /* @__PURE__ */
|
|
95
|
+
}), /* @__PURE__ */ x(c, {
|
|
90
96
|
className: "text-xs",
|
|
91
97
|
children: e.slug
|
|
92
98
|
})] })]
|
|
93
|
-
}), /* @__PURE__ */
|
|
94
|
-
}) }), /* @__PURE__ */
|
|
99
|
+
}), /* @__PURE__ */ x(f, { status: e.status })]
|
|
100
|
+
}) }), /* @__PURE__ */ x(s, { children: /* @__PURE__ */ S("div", {
|
|
95
101
|
className: "space-y-3",
|
|
96
102
|
children: [
|
|
97
|
-
/* @__PURE__ */
|
|
103
|
+
/* @__PURE__ */ x("p", {
|
|
98
104
|
className: "text-sm text-text-secondary line-clamp-2",
|
|
99
105
|
children: e.description
|
|
100
106
|
}),
|
|
101
|
-
/* @__PURE__ */
|
|
107
|
+
/* @__PURE__ */ S("div", {
|
|
102
108
|
className: "flex items-center gap-2",
|
|
103
|
-
children: [/* @__PURE__ */
|
|
109
|
+
children: [/* @__PURE__ */ x(M, {
|
|
104
110
|
size: 14,
|
|
105
111
|
className: "text-text-secondary"
|
|
106
|
-
}), /* @__PURE__ */
|
|
112
|
+
}), /* @__PURE__ */ S("span", {
|
|
107
113
|
className: "text-sm",
|
|
108
114
|
children: [
|
|
109
|
-
|
|
115
|
+
i,
|
|
110
116
|
" variable",
|
|
111
|
-
|
|
117
|
+
i === 1 ? "" : "s"
|
|
112
118
|
]
|
|
113
119
|
})]
|
|
114
120
|
}),
|
|
115
|
-
/* @__PURE__ */
|
|
121
|
+
/* @__PURE__ */ S("div", {
|
|
116
122
|
className: "flex items-center gap-2",
|
|
117
|
-
children: [/* @__PURE__ */
|
|
123
|
+
children: [/* @__PURE__ */ x(j, {
|
|
118
124
|
size: 14,
|
|
119
125
|
className: "text-text-secondary"
|
|
120
|
-
}), /* @__PURE__ */
|
|
126
|
+
}), /* @__PURE__ */ S("span", {
|
|
121
127
|
className: "text-sm",
|
|
122
128
|
children: ["v", e.version]
|
|
123
129
|
})]
|
|
124
130
|
}),
|
|
125
|
-
/* @__PURE__ */
|
|
131
|
+
/* @__PURE__ */ S("div", {
|
|
126
132
|
className: "pt-3 border-t border-border-subtle flex items-center justify-between",
|
|
127
|
-
children: [/* @__PURE__ */
|
|
133
|
+
children: [/* @__PURE__ */ x("span", {
|
|
128
134
|
className: "text-xs text-text-secondary",
|
|
129
135
|
children: t(e.createdAt)
|
|
130
|
-
}), /* @__PURE__ */
|
|
136
|
+
}), /* @__PURE__ */ S("div", {
|
|
131
137
|
className: "flex gap-1 opacity-0 group-hover:opacity-100 transition-opacity",
|
|
132
|
-
children: [/* @__PURE__ */
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
children: /* @__PURE__ */
|
|
138
|
+
children: [/* @__PURE__ */ x(r, {
|
|
139
|
+
permission: n.PROMPT_TEMPLATE_CREATE,
|
|
140
|
+
children: /* @__PURE__ */ x(a, {
|
|
141
|
+
variant: "ghost",
|
|
142
|
+
size: "icon",
|
|
143
|
+
className: "h-7 w-7",
|
|
144
|
+
onClick: (e) => e.preventDefault(),
|
|
145
|
+
children: /* @__PURE__ */ x(T, { size: 14 })
|
|
146
|
+
})
|
|
147
|
+
}), /* @__PURE__ */ x(r, {
|
|
148
|
+
permission: n.PROMPT_TEMPLATE_EXECUTE,
|
|
149
|
+
children: /* @__PURE__ */ x(a, {
|
|
150
|
+
variant: "ghost",
|
|
151
|
+
size: "icon",
|
|
152
|
+
className: "h-7 w-7",
|
|
153
|
+
onClick: (e) => e.preventDefault(),
|
|
154
|
+
children: /* @__PURE__ */ x(O, { size: 14 })
|
|
155
|
+
})
|
|
144
156
|
})]
|
|
145
157
|
})]
|
|
146
158
|
})
|
|
@@ -149,91 +161,94 @@ var j = () => {
|
|
|
149
161
|
})
|
|
150
162
|
}, e.id);
|
|
151
163
|
})
|
|
152
|
-
}) : /* @__PURE__ */
|
|
164
|
+
}) : /* @__PURE__ */ x(p, {
|
|
153
165
|
illustration: "empty-files",
|
|
154
166
|
title: "No prompt templates",
|
|
155
167
|
description: "Create reusable prompt templates with variables to ensure consistent agent behavior.",
|
|
156
|
-
action: /* @__PURE__ */
|
|
157
|
-
|
|
158
|
-
children: /* @__PURE__ */
|
|
159
|
-
|
|
160
|
-
children:
|
|
168
|
+
action: /* @__PURE__ */ x(r, {
|
|
169
|
+
permission: n.PROMPT_TEMPLATE_CREATE,
|
|
170
|
+
children: /* @__PURE__ */ x(a, {
|
|
171
|
+
leftIcon: /* @__PURE__ */ x(k, { size: 16 }),
|
|
172
|
+
children: /* @__PURE__ */ x(C, {
|
|
173
|
+
to: N("prompt-templates/new"),
|
|
174
|
+
children: "Create Template"
|
|
175
|
+
})
|
|
161
176
|
})
|
|
162
177
|
})
|
|
163
178
|
}),
|
|
164
|
-
/* @__PURE__ */
|
|
179
|
+
/* @__PURE__ */ S(y, {
|
|
165
180
|
treatment: "glass",
|
|
166
181
|
glow: !0,
|
|
167
182
|
className: "p-6",
|
|
168
183
|
children: [
|
|
169
|
-
/* @__PURE__ */
|
|
184
|
+
/* @__PURE__ */ S("div", {
|
|
170
185
|
className: "mb-4",
|
|
171
|
-
children: [/* @__PURE__ */
|
|
186
|
+
children: [/* @__PURE__ */ S("h2", {
|
|
172
187
|
className: "flex items-center gap-2 text-lg font-semibold tracking-tight text-text-primary",
|
|
173
|
-
children: [/* @__PURE__ */
|
|
174
|
-
}), /* @__PURE__ */
|
|
188
|
+
children: [/* @__PURE__ */ x(w, { size: 18 }), "Template Syntax"]
|
|
189
|
+
}), /* @__PURE__ */ x("p", {
|
|
175
190
|
className: "text-sm text-text-secondary",
|
|
176
191
|
children: "Use variables in your prompts with double curly braces"
|
|
177
192
|
})]
|
|
178
193
|
}),
|
|
179
|
-
/* @__PURE__ */
|
|
194
|
+
/* @__PURE__ */ S("div", {
|
|
180
195
|
className: "grid grid-cols-1 md:grid-cols-2 gap-6",
|
|
181
|
-
children: [/* @__PURE__ */
|
|
196
|
+
children: [/* @__PURE__ */ S("div", {
|
|
182
197
|
className: "space-y-3",
|
|
183
198
|
children: [
|
|
184
|
-
/* @__PURE__ */
|
|
199
|
+
/* @__PURE__ */ x("h4", {
|
|
185
200
|
className: "font-medium",
|
|
186
201
|
children: "Variable Syntax"
|
|
187
202
|
}),
|
|
188
|
-
/* @__PURE__ */
|
|
203
|
+
/* @__PURE__ */ S("div", {
|
|
189
204
|
className: "bg-bg-sunken p-4 rounded-lg font-mono text-sm",
|
|
190
|
-
children: [/* @__PURE__ */
|
|
205
|
+
children: [/* @__PURE__ */ x("p", { children: "You are a {{role}} for {{company_name}}." }), /* @__PURE__ */ x("p", {
|
|
191
206
|
className: "mt-2",
|
|
192
207
|
children: "Guidelines: {{guidelines}}"
|
|
193
208
|
})]
|
|
194
209
|
}),
|
|
195
|
-
/* @__PURE__ */
|
|
210
|
+
/* @__PURE__ */ x("p", {
|
|
196
211
|
className: "text-sm text-text-secondary",
|
|
197
212
|
children: "Variables are replaced at runtime with values provided by the agent configuration."
|
|
198
213
|
})
|
|
199
214
|
]
|
|
200
|
-
}), /* @__PURE__ */
|
|
215
|
+
}), /* @__PURE__ */ S("div", {
|
|
201
216
|
className: "space-y-3",
|
|
202
|
-
children: [/* @__PURE__ */
|
|
217
|
+
children: [/* @__PURE__ */ x("h4", {
|
|
203
218
|
className: "font-medium",
|
|
204
219
|
children: "Variable Types"
|
|
205
|
-
}), /* @__PURE__ */
|
|
220
|
+
}), /* @__PURE__ */ S("ul", {
|
|
206
221
|
className: "text-sm space-y-2",
|
|
207
222
|
children: [
|
|
208
|
-
/* @__PURE__ */
|
|
223
|
+
/* @__PURE__ */ S("li", {
|
|
209
224
|
className: "flex items-start gap-2",
|
|
210
|
-
children: [/* @__PURE__ */
|
|
225
|
+
children: [/* @__PURE__ */ x(d, {
|
|
211
226
|
variant: "outline",
|
|
212
227
|
className: "mt-0.5",
|
|
213
228
|
children: "string"
|
|
214
|
-
}), /* @__PURE__ */
|
|
229
|
+
}), /* @__PURE__ */ x("span", {
|
|
215
230
|
className: "text-text-secondary",
|
|
216
231
|
children: "Text values like names, descriptions"
|
|
217
232
|
})]
|
|
218
233
|
}),
|
|
219
|
-
/* @__PURE__ */
|
|
234
|
+
/* @__PURE__ */ S("li", {
|
|
220
235
|
className: "flex items-start gap-2",
|
|
221
|
-
children: [/* @__PURE__ */
|
|
236
|
+
children: [/* @__PURE__ */ x(d, {
|
|
222
237
|
variant: "outline",
|
|
223
238
|
className: "mt-0.5",
|
|
224
239
|
children: "array"
|
|
225
|
-
}), /* @__PURE__ */
|
|
240
|
+
}), /* @__PURE__ */ x("span", {
|
|
226
241
|
className: "text-text-secondary",
|
|
227
242
|
children: "Lists rendered as bullet points"
|
|
228
243
|
})]
|
|
229
244
|
}),
|
|
230
|
-
/* @__PURE__ */
|
|
245
|
+
/* @__PURE__ */ S("li", {
|
|
231
246
|
className: "flex items-start gap-2",
|
|
232
|
-
children: [/* @__PURE__ */
|
|
247
|
+
children: [/* @__PURE__ */ x(d, {
|
|
233
248
|
variant: "outline",
|
|
234
249
|
className: "mt-0.5",
|
|
235
250
|
children: "object"
|
|
236
|
-
}), /* @__PURE__ */
|
|
251
|
+
}), /* @__PURE__ */ x("span", {
|
|
237
252
|
className: "text-text-secondary",
|
|
238
253
|
children: "Structured data (JSON)"
|
|
239
254
|
})]
|
|
@@ -242,18 +257,18 @@ var j = () => {
|
|
|
242
257
|
})]
|
|
243
258
|
})]
|
|
244
259
|
}),
|
|
245
|
-
/* @__PURE__ */
|
|
260
|
+
/* @__PURE__ */ S("div", {
|
|
246
261
|
className: "mt-6 p-4 bg-bg-sunken/50 rounded-lg",
|
|
247
|
-
children: [/* @__PURE__ */
|
|
262
|
+
children: [/* @__PURE__ */ x("h4", {
|
|
248
263
|
className: "font-medium mb-2",
|
|
249
264
|
children: "Best Practices"
|
|
250
|
-
}), /* @__PURE__ */
|
|
265
|
+
}), /* @__PURE__ */ S("ul", {
|
|
251
266
|
className: "text-sm text-text-secondary space-y-1",
|
|
252
267
|
children: [
|
|
253
|
-
/* @__PURE__ */
|
|
254
|
-
/* @__PURE__ */
|
|
255
|
-
/* @__PURE__ */
|
|
256
|
-
/* @__PURE__ */
|
|
268
|
+
/* @__PURE__ */ x("li", { children: "• Use descriptive variable names (company_name vs cn)" }),
|
|
269
|
+
/* @__PURE__ */ x("li", { children: "• Provide default values for optional variables" }),
|
|
270
|
+
/* @__PURE__ */ x("li", { children: "• Document expected values in variable descriptions" }),
|
|
271
|
+
/* @__PURE__ */ x("li", { children: "• Version your templates to track changes" })
|
|
257
272
|
]
|
|
258
273
|
})]
|
|
259
274
|
})
|
|
@@ -264,6 +279,6 @@ var j = () => {
|
|
|
264
279
|
});
|
|
265
280
|
};
|
|
266
281
|
//#endregion
|
|
267
|
-
export {
|
|
282
|
+
export { N as PromptTemplatesPage };
|
|
268
283
|
|
|
269
284
|
//# sourceMappingURL=PromptTemplatesPage.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PromptTemplatesPage.js","names":[],"sources":["../../../src/botlit/pages/PromptTemplatesPage.tsx"],"sourcesContent":["/**\n * Prompt Templates Page\n * @module botlit/pages\n */\n\nimport type { FC } from 'react';\nimport { useState } from 'react';\nimport { Link } from 'react-router';\nimport { useBotlit } from '../providers/BotlitProvider';\nimport {\n Plus,\n Search as SearchIcon,\n Filter,\n FileText,\n Code,\n Variable,\n Copy,\n Play,\n Tag,\n} from 'lucide-react';\nimport { PagePurpose, GlassCard } from '@burdenoff/fe-libs/ui';\nimport { PageLayout } from '../components/PageLayout';\nimport { Card, CardHeader, CardTitle, CardContent, CardDescription } from '../components/Card';\nimport { Button } from '../components/Button';\nimport { Input } from '../components/Input';\nimport { Badge, StatusBadge } from '../components/Badge';\nimport { EmptyState } from '../components/EmptyState';\nimport { ErrorState } from '../components/ErrorState';\nimport { usePromptTemplates, promptTemplateVariables, type PromptTemplateRecord } from '../hooks';\nimport { formatRelativeTime } from '../utils/formatters';\n\nexport const PromptTemplatesPage: FC = () => {\n const { getPath } = useBotlit();\n const [search, setSearch] = useState('');\n const { data: templates, loading, error, refetch } = usePromptTemplates({ search });\n\n return (\n <PageLayout\n title=\"Prompt Templates\"\n description=\"Create and manage reusable prompt templates with variable support\"\n actions={\n <Button leftIcon={<Plus size={16} />}>\n <Link to={getPath('prompt-templates/new')}>Create Template</Link>\n </Button>\n }\n >\n <div className=\"space-y-6\">\n <PagePurpose icon={<FileText size={18} />}>\n Prompt templates are the reusable instructions that shape how an agent thinks and replies.\n Write the system prompt once with <code>{'{{variables}}'}</code> for the bits that change\n (role, company name, tone), version it, and reuse it across agents — so you can refine\n wording in one place instead of editing every agent by hand.\n </PagePurpose>\n\n {/* Search */}\n <div className=\"flex items-center gap-4\">\n <div className=\"relative flex-1 max-w-md\">\n <SearchIcon className=\"absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-text-secondary\" />\n <Input\n placeholder=\"Search templates...\"\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n className=\"pl-9\"\n />\n </div>\n <Button variant=\"outline\" leftIcon={<Filter size={16} />}>\n Filters\n </Button>\n </div>\n\n {/* Templates List */}\n {loading ? (\n <div className=\"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4\">\n {[1, 2, 3, 4, 5, 6].map((i) => (\n <div\n key={i}\n className=\"h-48 bg-bg-sunken motion-safe:animate-vc-shimmer rounded-lg\"\n />\n ))}\n </div>\n ) : error ? (\n <ErrorState resource=\"prompt templates\" error={error} onRetry={() => void refetch()} />\n ) : templates.length > 0 ? (\n <div className=\"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4\">\n {templates.map((template: PromptTemplateRecord) => {\n const variableCount = promptTemplateVariables(template).length;\n return (\n <Link key={template.id} to={getPath(`prompt-templates/${template.id}`)}>\n <Card className=\"h-full hover:border-primary/50 transition-colors cursor-pointer group\">\n <CardHeader>\n <div className=\"flex items-start justify-between\">\n <div className=\"flex items-center gap-3\">\n <div className=\"p-2 bg-action-primary-bg/10 rounded-lg\">\n <FileText className=\"h-5 w-5 text-primary\" />\n </div>\n <div>\n <CardTitle className=\"text-base\">{template.name}</CardTitle>\n <CardDescription className=\"text-xs\">{template.slug}</CardDescription>\n </div>\n </div>\n <StatusBadge status={template.status} />\n </div>\n </CardHeader>\n <CardContent>\n <div className=\"space-y-3\">\n <p className=\"text-sm text-text-secondary line-clamp-2\">\n {template.description}\n </p>\n\n {/* Variables */}\n <div className=\"flex items-center gap-2\">\n <Variable size={14} className=\"text-text-secondary\" />\n <span className=\"text-sm\">\n {variableCount} variable{variableCount !== 1 ? 's' : ''}\n </span>\n </div>\n\n {/* Version */}\n <div className=\"flex items-center gap-2\">\n <Tag size={14} className=\"text-text-secondary\" />\n <span className=\"text-sm\">v{template.version}</span>\n </div>\n\n {/* Footer */}\n <div className=\"pt-3 border-t border-border-subtle flex items-center justify-between\">\n <span className=\"text-xs text-text-secondary\">\n {formatRelativeTime(template.createdAt)}\n </span>\n <div className=\"flex gap-1 opacity-0 group-hover:opacity-100 transition-opacity\">\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-7 w-7\"\n onClick={(e) => e.preventDefault()}\n >\n <Copy size={14} />\n </Button>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-7 w-7\"\n onClick={(e) => e.preventDefault()}\n >\n <Play size={14} />\n </Button>\n </div>\n </div>\n </div>\n </CardContent>\n </Card>\n </Link>\n );\n })}\n </div>\n ) : (\n <EmptyState\n illustration=\"empty-files\"\n title=\"No prompt templates\"\n description=\"Create reusable prompt templates with variables to ensure consistent agent behavior.\"\n action={\n <Button leftIcon={<Plus size={16} />}>\n <Link to={getPath('prompt-templates/new')}>Create Template</Link>\n </Button>\n }\n />\n )}\n\n {/* Template Guide */}\n <GlassCard treatment=\"glass\" glow className=\"p-6\">\n <div className=\"mb-4\">\n <h2 className=\"flex items-center gap-2 text-lg font-semibold tracking-tight text-text-primary\">\n <Code size={18} />\n Template Syntax\n </h2>\n <p className=\"text-sm text-text-secondary\">\n Use variables in your prompts with double curly braces\n </p>\n </div>\n <div className=\"grid grid-cols-1 md:grid-cols-2 gap-6\">\n <div className=\"space-y-3\">\n <h4 className=\"font-medium\">Variable Syntax</h4>\n <div className=\"bg-bg-sunken p-4 rounded-lg font-mono text-sm\">\n <p>{'You are a {{role}} for {{company_name}}.'}</p>\n <p className=\"mt-2\">{'Guidelines: {{guidelines}}'}</p>\n </div>\n <p className=\"text-sm text-text-secondary\">\n Variables are replaced at runtime with values provided by the agent configuration.\n </p>\n </div>\n <div className=\"space-y-3\">\n <h4 className=\"font-medium\">Variable Types</h4>\n <ul className=\"text-sm space-y-2\">\n <li className=\"flex items-start gap-2\">\n <Badge variant=\"outline\" className=\"mt-0.5\">\n string\n </Badge>\n <span className=\"text-text-secondary\">Text values like names, descriptions</span>\n </li>\n <li className=\"flex items-start gap-2\">\n <Badge variant=\"outline\" className=\"mt-0.5\">\n array\n </Badge>\n <span className=\"text-text-secondary\">Lists rendered as bullet points</span>\n </li>\n <li className=\"flex items-start gap-2\">\n <Badge variant=\"outline\" className=\"mt-0.5\">\n object\n </Badge>\n <span className=\"text-text-secondary\">Structured data (JSON)</span>\n </li>\n </ul>\n </div>\n </div>\n\n <div className=\"mt-6 p-4 bg-bg-sunken/50 rounded-lg\">\n <h4 className=\"font-medium mb-2\">Best Practices</h4>\n <ul className=\"text-sm text-text-secondary space-y-1\">\n <li>• Use descriptive variable names (company_name vs cn)</li>\n <li>• Provide default values for optional variables</li>\n <li>• Document expected values in variable descriptions</li>\n <li>• Version your templates to track changes</li>\n </ul>\n </div>\n </GlassCard>\n </div>\n </PageLayout>\n );\n};\n"],"mappings":";;;;;;;;;;;;;;;;;AA+BA,IAAa,UAAgC;CAC3C,IAAM,EAAE,eAAY,GAAW,EACzB,CAAC,GAAQ,KAAa,EAAS,GAAG,EAClC,EAAE,MAAM,GAAW,YAAS,UAAO,eAAY,EAAmB,EAAE,WAAQ,CAAC;AAEnF,QACE,kBAAC,GAAD;EACE,OAAM;EACN,aAAY;EACZ,SACE,kBAAC,GAAD;GAAQ,UAAU,kBAAC,GAAD,EAAM,MAAM,IAAM,CAAA;aAClC,kBAAC,GAAD;IAAM,IAAI,EAAQ,uBAAuB;cAAE;IAAsB,CAAA;GAC1D,CAAA;YAGX,kBAAC,OAAD;GAAK,WAAU;aAAf;IACE,kBAAC,GAAD;KAAa,MAAM,kBAAC,GAAD,EAAU,MAAM,IAAM,CAAA;eAAzC;MAA2C;MAEP,kBAAC,QAAD,EAAA,UAAO,iBAAuB,CAAA;;MAGpD;;IAGd,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,GAAD,EAAY,WAAU,wEAAyE,CAAA,EAC/F,kBAAC,GAAD;OACE,aAAY;OACZ,OAAO;OACP,WAAW,MAAM,EAAU,EAAE,OAAO,MAAM;OAC1C,WAAU;OACV,CAAA,CACE;SACN,kBAAC,GAAD;MAAQ,SAAQ;MAAU,UAAU,kBAAC,GAAD,EAAQ,MAAM,IAAM,CAAA;gBAAE;MAEjD,CAAA,CACL;;IAGL,IACC,kBAAC,OAAD;KAAK,WAAU;eACZ;MAAC;MAAG;MAAG;MAAG;MAAG;MAAG;MAAE,CAAC,KAAK,MACvB,kBAAC,OAAD,EAEE,WAAU,+DACV,EAFK,EAEL,CACF;KACE,CAAA,GACJ,IACF,kBAAC,GAAD;KAAY,UAAS;KAA0B;KAAO,eAAe,KAAK,GAAS;KAAI,CAAA,GACrF,EAAU,SAAS,IACrB,kBAAC,OAAD;KAAK,WAAU;eACZ,EAAU,KAAK,MAAmC;MACjD,IAAM,IAAgB,EAAwB,EAAS,CAAC;AACxD,aACE,kBAAC,GAAD;OAAwB,IAAI,EAAQ,oBAAoB,EAAS,KAAK;iBACpE,kBAAC,GAAD;QAAM,WAAU;kBAAhB,CACE,kBAAC,GAAD,EAAA,UACE,kBAAC,OAAD;SAAK,WAAU;mBAAf,CACE,kBAAC,OAAD;UAAK,WAAU;oBAAf,CACE,kBAAC,OAAD;WAAK,WAAU;qBACb,kBAAC,GAAD,EAAU,WAAU,wBAAyB,CAAA;WACzC,CAAA,EACN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,GAAD;WAAW,WAAU;qBAAa,EAAS;WAAiB,CAAA,EAC5D,kBAAC,GAAD;WAAiB,WAAU;qBAAW,EAAS;WAAuB,CAAA,CAClE,EAAA,CAAA,CACF;aACN,kBAAC,GAAD,EAAa,QAAQ,EAAS,QAAU,CAAA,CACpC;YACK,CAAA,EACb,kBAAC,GAAD,EAAA,UACE,kBAAC,OAAD;SAAK,WAAU;mBAAf;UACE,kBAAC,KAAD;WAAG,WAAU;qBACV,EAAS;WACR,CAAA;UAGJ,kBAAC,OAAD;WAAK,WAAU;qBAAf,CACE,kBAAC,GAAD;YAAU,MAAM;YAAI,WAAU;YAAwB,CAAA,EACtD,kBAAC,QAAD;YAAM,WAAU;sBAAhB;aACG;aAAc;aAAU,MAAkB,IAAU,KAAN;aAC1C;cACH;;UAGN,kBAAC,OAAD;WAAK,WAAU;qBAAf,CACE,kBAAC,GAAD;YAAK,MAAM;YAAI,WAAU;YAAwB,CAAA,EACjD,kBAAC,QAAD;YAAM,WAAU;sBAAhB,CAA0B,KAAE,EAAS,QAAe;cAChD;;UAGN,kBAAC,OAAD;WAAK,WAAU;qBAAf,CACE,kBAAC,QAAD;YAAM,WAAU;sBACb,EAAmB,EAAS,UAAU;YAClC,CAAA,EACP,kBAAC,OAAD;YAAK,WAAU;sBAAf,CACE,kBAAC,GAAD;aACE,SAAQ;aACR,MAAK;aACL,WAAU;aACV,UAAU,MAAM,EAAE,gBAAgB;uBAElC,kBAAC,GAAD,EAAM,MAAM,IAAM,CAAA;aACX,CAAA,EACT,kBAAC,GAAD;aACE,SAAQ;aACR,MAAK;aACL,WAAU;aACV,UAAU,MAAM,EAAE,gBAAgB;uBAElC,kBAAC,GAAD,EAAM,MAAM,IAAM,CAAA;aACX,CAAA,CACL;cACF;;UACF;YACM,CAAA,CACT;;OACF,EA/DI,EAAS,GA+Db;OAET;KACE,CAAA,GAEN,kBAAC,GAAD;KACE,cAAa;KACb,OAAM;KACN,aAAY;KACZ,QACE,kBAAC,GAAD;MAAQ,UAAU,kBAAC,GAAD,EAAM,MAAM,IAAM,CAAA;gBAClC,kBAAC,GAAD;OAAM,IAAI,EAAQ,uBAAuB;iBAAE;OAAsB,CAAA;MAC1D,CAAA;KAEX,CAAA;IAIJ,kBAAC,GAAD;KAAW,WAAU;KAAQ,MAAA;KAAK,WAAU;eAA5C;MACE,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,MAAD;QAAI,WAAU;kBAAd,CACE,kBAAC,GAAD,EAAM,MAAM,IAAM,CAAA,EAAA,kBAEf;WACL,kBAAC,KAAD;QAAG,WAAU;kBAA8B;QAEvC,CAAA,CACA;;MACN,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,OAAD;QAAK,WAAU;kBAAf;SACE,kBAAC,MAAD;UAAI,WAAU;oBAAc;UAAoB,CAAA;SAChD,kBAAC,OAAD;UAAK,WAAU;oBAAf,CACE,kBAAC,KAAD,EAAA,UAAI,4CAA+C,CAAA,EACnD,kBAAC,KAAD;WAAG,WAAU;qBAAQ;WAAiC,CAAA,CAClD;;SACN,kBAAC,KAAD;UAAG,WAAU;oBAA8B;UAEvC,CAAA;SACA;WACN,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,MAAD;SAAI,WAAU;mBAAc;SAAmB,CAAA,EAC/C,kBAAC,MAAD;SAAI,WAAU;mBAAd;UACE,kBAAC,MAAD;WAAI,WAAU;qBAAd,CACE,kBAAC,GAAD;YAAO,SAAQ;YAAU,WAAU;sBAAS;YAEpC,CAAA,EACR,kBAAC,QAAD;YAAM,WAAU;sBAAsB;YAA2C,CAAA,CAC9E;;UACL,kBAAC,MAAD;WAAI,WAAU;qBAAd,CACE,kBAAC,GAAD;YAAO,SAAQ;YAAU,WAAU;sBAAS;YAEpC,CAAA,EACR,kBAAC,QAAD;YAAM,WAAU;sBAAsB;YAAsC,CAAA,CACzE;;UACL,kBAAC,MAAD;WAAI,WAAU;qBAAd,CACE,kBAAC,GAAD;YAAO,SAAQ;YAAU,WAAU;sBAAS;YAEpC,CAAA,EACR,kBAAC,QAAD;YAAM,WAAU;sBAAsB;YAA6B,CAAA,CAChE;;UACF;WACD;UACF;;MAEN,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,MAAD;QAAI,WAAU;kBAAmB;QAAmB,CAAA,EACpD,kBAAC,MAAD;QAAI,WAAU;kBAAd;SACE,kBAAC,MAAD,EAAA,UAAI,yDAA0D,CAAA;SAC9D,kBAAC,MAAD,EAAA,UAAI,mDAAoD,CAAA;SACxD,kBAAC,MAAD,EAAA,UAAI,uDAAwD,CAAA;SAC5D,kBAAC,MAAD,EAAA,UAAI,6CAA8C,CAAA;SAC/C;UACD;;MACI;;IACR;;EACK,CAAA"}
|
|
1
|
+
{"version":3,"file":"PromptTemplatesPage.js","names":[],"sources":["../../../src/botlit/pages/PromptTemplatesPage.tsx"],"sourcesContent":["/**\n * Prompt Templates Page\n * @module botlit/pages\n */\n\nimport type { FC } from 'react';\nimport { useState } from 'react';\nimport { Link } from 'react-router';\nimport { useBotlit } from '../providers/BotlitProvider';\nimport {\n Plus,\n Search as SearchIcon,\n Filter,\n FileText,\n Code,\n Variable,\n Copy,\n Play,\n Tag,\n} from 'lucide-react';\nimport { PagePurpose, GlassCard } from '@burdenoff/fe-libs/ui';\nimport { PageLayout } from '../components/PageLayout';\nimport { Card, CardHeader, CardTitle, CardContent, CardDescription } from '../components/Card';\nimport { Button } from '../components/Button';\nimport { Input } from '../components/Input';\nimport { Badge, StatusBadge } from '../components/Badge';\nimport { EmptyState } from '../components/EmptyState';\nimport { ErrorState } from '../components/ErrorState';\nimport { usePromptTemplates, promptTemplateVariables, type PromptTemplateRecord } from '../hooks';\nimport { formatRelativeTime } from '../utils/formatters';\nimport { BOTMANOR_PERMISSIONS, BotmanorPermissionGate } from '../permissions';\n\nexport const PromptTemplatesPage: FC = () => {\n const { getPath } = useBotlit();\n const [search, setSearch] = useState('');\n const { data: templates, loading, error, refetch } = usePromptTemplates({ search });\n\n return (\n <PageLayout\n title=\"Prompt Templates\"\n description=\"Create and manage reusable prompt templates with variable support\"\n actions={\n <BotmanorPermissionGate permission={BOTMANOR_PERMISSIONS.PROMPT_TEMPLATE_CREATE}>\n <Button leftIcon={<Plus size={16} />}>\n <Link to={getPath('prompt-templates/new')}>Create Template</Link>\n </Button>\n </BotmanorPermissionGate>\n }\n >\n <div className=\"space-y-6\">\n <PagePurpose icon={<FileText size={18} />}>\n Prompt templates are the reusable instructions that shape how an agent thinks and replies.\n Write the system prompt once with <code>{'{{variables}}'}</code> for the bits that change\n (role, company name, tone), version it, and reuse it across agents — so you can refine\n wording in one place instead of editing every agent by hand.\n </PagePurpose>\n\n {/* Search */}\n <div className=\"flex items-center gap-4\">\n <div className=\"relative flex-1 max-w-md\">\n <SearchIcon className=\"absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-text-secondary\" />\n <Input\n placeholder=\"Search templates...\"\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n className=\"pl-9\"\n />\n </div>\n <Button variant=\"outline\" leftIcon={<Filter size={16} />}>\n Filters\n </Button>\n </div>\n\n {/* Templates List */}\n {loading ? (\n <div className=\"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4\">\n {[1, 2, 3, 4, 5, 6].map((i) => (\n <div\n key={i}\n className=\"h-48 bg-bg-sunken motion-safe:animate-vc-shimmer rounded-lg\"\n />\n ))}\n </div>\n ) : error ? (\n <ErrorState resource=\"prompt templates\" error={error} onRetry={() => void refetch()} />\n ) : templates.length > 0 ? (\n <div className=\"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4\">\n {templates.map((template: PromptTemplateRecord) => {\n const variableCount = promptTemplateVariables(template).length;\n return (\n <Link key={template.id} to={getPath(`prompt-templates/${template.id}`)}>\n <Card className=\"h-full hover:border-primary/50 transition-colors cursor-pointer group\">\n <CardHeader>\n <div className=\"flex items-start justify-between\">\n <div className=\"flex items-center gap-3\">\n <div className=\"p-2 bg-action-primary-bg/10 rounded-lg\">\n <FileText className=\"h-5 w-5 text-primary\" />\n </div>\n <div>\n <CardTitle className=\"text-base\">{template.name}</CardTitle>\n <CardDescription className=\"text-xs\">{template.slug}</CardDescription>\n </div>\n </div>\n <StatusBadge status={template.status} />\n </div>\n </CardHeader>\n <CardContent>\n <div className=\"space-y-3\">\n <p className=\"text-sm text-text-secondary line-clamp-2\">\n {template.description}\n </p>\n\n {/* Variables */}\n <div className=\"flex items-center gap-2\">\n <Variable size={14} className=\"text-text-secondary\" />\n <span className=\"text-sm\">\n {variableCount} variable{variableCount !== 1 ? 's' : ''}\n </span>\n </div>\n\n {/* Version */}\n <div className=\"flex items-center gap-2\">\n <Tag size={14} className=\"text-text-secondary\" />\n <span className=\"text-sm\">v{template.version}</span>\n </div>\n\n {/* Footer */}\n <div className=\"pt-3 border-t border-border-subtle flex items-center justify-between\">\n <span className=\"text-xs text-text-secondary\">\n {formatRelativeTime(template.createdAt)}\n </span>\n <div className=\"flex gap-1 opacity-0 group-hover:opacity-100 transition-opacity\">\n <BotmanorPermissionGate\n permission={BOTMANOR_PERMISSIONS.PROMPT_TEMPLATE_CREATE}\n >\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-7 w-7\"\n onClick={(e) => e.preventDefault()}\n >\n <Copy size={14} />\n </Button>\n </BotmanorPermissionGate>\n <BotmanorPermissionGate\n permission={BOTMANOR_PERMISSIONS.PROMPT_TEMPLATE_EXECUTE}\n >\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-7 w-7\"\n onClick={(e) => e.preventDefault()}\n >\n <Play size={14} />\n </Button>\n </BotmanorPermissionGate>\n </div>\n </div>\n </div>\n </CardContent>\n </Card>\n </Link>\n );\n })}\n </div>\n ) : (\n <EmptyState\n illustration=\"empty-files\"\n title=\"No prompt templates\"\n description=\"Create reusable prompt templates with variables to ensure consistent agent behavior.\"\n action={\n <BotmanorPermissionGate permission={BOTMANOR_PERMISSIONS.PROMPT_TEMPLATE_CREATE}>\n <Button leftIcon={<Plus size={16} />}>\n <Link to={getPath('prompt-templates/new')}>Create Template</Link>\n </Button>\n </BotmanorPermissionGate>\n }\n />\n )}\n\n {/* Template Guide */}\n <GlassCard treatment=\"glass\" glow className=\"p-6\">\n <div className=\"mb-4\">\n <h2 className=\"flex items-center gap-2 text-lg font-semibold tracking-tight text-text-primary\">\n <Code size={18} />\n Template Syntax\n </h2>\n <p className=\"text-sm text-text-secondary\">\n Use variables in your prompts with double curly braces\n </p>\n </div>\n <div className=\"grid grid-cols-1 md:grid-cols-2 gap-6\">\n <div className=\"space-y-3\">\n <h4 className=\"font-medium\">Variable Syntax</h4>\n <div className=\"bg-bg-sunken p-4 rounded-lg font-mono text-sm\">\n <p>{'You are a {{role}} for {{company_name}}.'}</p>\n <p className=\"mt-2\">{'Guidelines: {{guidelines}}'}</p>\n </div>\n <p className=\"text-sm text-text-secondary\">\n Variables are replaced at runtime with values provided by the agent configuration.\n </p>\n </div>\n <div className=\"space-y-3\">\n <h4 className=\"font-medium\">Variable Types</h4>\n <ul className=\"text-sm space-y-2\">\n <li className=\"flex items-start gap-2\">\n <Badge variant=\"outline\" className=\"mt-0.5\">\n string\n </Badge>\n <span className=\"text-text-secondary\">Text values like names, descriptions</span>\n </li>\n <li className=\"flex items-start gap-2\">\n <Badge variant=\"outline\" className=\"mt-0.5\">\n array\n </Badge>\n <span className=\"text-text-secondary\">Lists rendered as bullet points</span>\n </li>\n <li className=\"flex items-start gap-2\">\n <Badge variant=\"outline\" className=\"mt-0.5\">\n object\n </Badge>\n <span className=\"text-text-secondary\">Structured data (JSON)</span>\n </li>\n </ul>\n </div>\n </div>\n\n <div className=\"mt-6 p-4 bg-bg-sunken/50 rounded-lg\">\n <h4 className=\"font-medium mb-2\">Best Practices</h4>\n <ul className=\"text-sm text-text-secondary space-y-1\">\n <li>• Use descriptive variable names (company_name vs cn)</li>\n <li>• Provide default values for optional variables</li>\n <li>• Document expected values in variable descriptions</li>\n <li>• Version your templates to track changes</li>\n </ul>\n </div>\n </GlassCard>\n </div>\n </PageLayout>\n );\n};\n"],"mappings":"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"}
|