@flexkit/studio 0.0.30 → 0.0.32
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/README.md +2 -2
- package/dist/asset-ZVPFS73O.js +2 -0
- package/dist/{asset-TS7J5GA5.js.map → asset-ZVPFS73O.js.map} +1 -1
- package/dist/astro.d.ts +5 -3
- package/dist/astro.js +8 -3
- package/dist/chunk-5FHCSAK2.js +2 -0
- package/dist/chunk-5FHCSAK2.js.map +1 -0
- package/dist/{chunk-R7N3MDOP.js → chunk-AEBTHXEP.js} +2 -2
- package/dist/{chunk-R7N3MDOP.js.map → chunk-AEBTHXEP.js.map} +1 -1
- package/dist/{chunk-W3TUEJJL.js → chunk-CCI3FGPF.js} +2 -2
- package/dist/{chunk-W3TUEJJL.js.map → chunk-CCI3FGPF.js.map} +1 -1
- package/dist/chunk-D62TAYLI.js +2 -0
- package/dist/chunk-D62TAYLI.js.map +1 -0
- package/dist/{chunk-UKLE7J3K.js → chunk-E7G46743.js} +139 -16
- package/dist/chunk-F2ILIHAU.js +2 -0
- package/dist/chunk-F2ILIHAU.js.map +1 -0
- package/dist/{chunk-EOCJR5EY.js → chunk-FPH4YETF.js} +2 -2
- package/dist/{chunk-EOCJR5EY.js.map → chunk-FPH4YETF.js.map} +1 -1
- package/dist/chunk-GFDWGYUR.js +2 -0
- package/dist/chunk-GFDWGYUR.js.map +1 -0
- package/dist/{chunk-CPUC4QXH.js → chunk-JAARDXQZ.js} +2 -2
- package/dist/{chunk-CPUC4QXH.js.map → chunk-JAARDXQZ.js.map} +1 -1
- package/dist/{chunk-IXO2LU47.js → chunk-JCHD4EGB.js} +2 -2
- package/dist/{chunk-IXO2LU47.js.map → chunk-JCHD4EGB.js.map} +1 -1
- package/dist/chunk-KHPTVIYT.js +2 -0
- package/dist/chunk-KHPTVIYT.js.map +1 -0
- package/dist/{chunk-DWK4NNLB.js → chunk-LKBCPAXQ.js} +2 -2
- package/dist/{chunk-DWK4NNLB.js.map → chunk-LKBCPAXQ.js.map} +1 -1
- package/dist/chunk-MGXHZDFZ.js +2 -0
- package/dist/chunk-MGXHZDFZ.js.map +1 -0
- package/dist/chunk-N2T6MKPV.js +2 -0
- package/dist/chunk-N2T6MKPV.js.map +1 -0
- package/dist/chunk-PXB5QSHN.js +2 -0
- package/dist/chunk-PXB5QSHN.js.map +1 -0
- package/dist/chunk-QSROLDUU.js +2 -0
- package/dist/chunk-QSROLDUU.js.map +1 -0
- package/dist/chunk-VHNQDP7Q.js +616 -0
- package/dist/chunk-VUAFNQK7.js +2 -0
- package/dist/chunk-VUAFNQK7.js.map +1 -0
- package/dist/chunk-XFY7MZJN.js +2 -0
- package/dist/chunk-XFY7MZJN.js.map +1 -0
- package/dist/{core-handler-XAVVKLhV.d.ts → core-handler-C3xC98bN.d.ts} +3 -0
- package/dist/datetime-DDEWTNLB.js +2 -0
- package/dist/{datetime-NQTYGZIC.js.map → datetime-DDEWTNLB.js.map} +1 -1
- package/dist/editor-HAYTKNMY.js +2 -0
- package/dist/{editor-YIRZQR3D.js.map → editor-HAYTKNMY.js.map} +1 -1
- package/dist/index.css +163 -44
- package/dist/index.d.ts +22 -21
- package/dist/index.js +157 -210
- package/dist/index.js.map +1 -1
- package/dist/logo-B6ZKLGM7.js +3 -0
- package/dist/logo-B6ZKLGM7.js.map +1 -0
- package/dist/nextjs.d.ts +40 -12
- package/dist/nextjs.js +8 -3
- package/dist/search-X5V3YOTZ.js +2 -0
- package/dist/search-X5V3YOTZ.js.map +1 -0
- package/dist/select-H3JHOCWR.js +2 -0
- package/dist/{select-A6I27JQU.js.map → select-H3JHOCWR.js.map} +1 -1
- package/dist/switch-TACKLQJH.js +2 -0
- package/dist/{switch-AFZGXSR3.js.map → switch-TACKLQJH.js.map} +1 -1
- package/dist/tanstack-start.d.ts +6 -4
- package/dist/tanstack-start.js +17 -12
- package/dist/text-M3DRK7LU.js +2 -0
- package/dist/{text-2RL2L5FT.js.map → text-M3DRK7LU.js.map} +1 -1
- package/dist/text-SQXG7XJT.js +2 -0
- package/dist/{text-6F4QTCNT.js.map → text-SQXG7XJT.js.map} +1 -1
- package/dist/textarea-YF4K2VBM.js +2 -0
- package/dist/{textarea-2A4TLWZS.js.map → textarea-YF4K2VBM.js.map} +1 -1
- package/dist/tools.d.ts +78 -0
- package/dist/tools.js +60 -0
- package/dist/types-U28Ppixq.d.ts +56 -0
- package/dist/{types.d-CX3kDxFZ.d.ts → types.d-710RgZFw.d.ts} +85 -7
- package/dist/ui.d.ts +21 -5
- package/dist/ui.js +5 -5
- package/dist/ui.js.map +1 -1
- package/dist/{user-nav-4JKIFZLB.js → user-nav-XVY7JTX6.js} +2 -2
- package/dist/{user-nav-4JKIFZLB.js.map → user-nav-XVY7JTX6.js.map} +1 -1
- package/package.json +7 -3
- package/dist/asset-TS7J5GA5.js +0 -2
- package/dist/chunk-73RMWG53.js +0 -2
- package/dist/chunk-73RMWG53.js.map +0 -1
- package/dist/chunk-HAQICAOQ.js +0 -2
- package/dist/chunk-HAQICAOQ.js.map +0 -1
- package/dist/chunk-LL2Z4TD3.js +0 -2
- package/dist/chunk-LL2Z4TD3.js.map +0 -1
- package/dist/chunk-MC6VZLKC.js +0 -2
- package/dist/chunk-MC6VZLKC.js.map +0 -1
- package/dist/chunk-N52AF6GE.js +0 -2
- package/dist/chunk-N52AF6GE.js.map +0 -1
- package/dist/chunk-V6R4AWQS.js +0 -2
- package/dist/chunk-V6R4AWQS.js.map +0 -1
- package/dist/chunk-WXMCINGZ.js +0 -2
- package/dist/chunk-WXMCINGZ.js.map +0 -1
- package/dist/chunk-WZ533Y4O.js +0 -2
- package/dist/chunk-WZ533Y4O.js.map +0 -1
- package/dist/chunk-YA4ACPM5.js +0 -2
- package/dist/chunk-YA4ACPM5.js.map +0 -1
- package/dist/chunk-ZEZ6TRCO.js +0 -2
- package/dist/chunk-ZEZ6TRCO.js.map +0 -1
- package/dist/datetime-NQTYGZIC.js +0 -2
- package/dist/editor-YIRZQR3D.js +0 -2
- package/dist/logo-GCKKZP62.js +0 -3
- package/dist/logo-GCKKZP62.js.map +0 -1
- package/dist/search-UFFZBRQV.js +0 -2
- package/dist/search-UFFZBRQV.js.map +0 -1
- package/dist/select-A6I27JQU.js +0 -2
- package/dist/switch-AFZGXSR3.js +0 -2
- package/dist/text-2RL2L5FT.js +0 -2
- package/dist/text-6F4QTCNT.js +0 -2
- package/dist/textarea-2A4TLWZS.js +0 -2
|
@@ -0,0 +1,616 @@
|
|
|
1
|
+
// src/tools/actor.ts
|
|
2
|
+
function isStringArray(value) {
|
|
3
|
+
return Array.isArray(value) && value.every((item) => typeof item === "string");
|
|
4
|
+
}
|
|
5
|
+
function parseCustomerToolActor(value) {
|
|
6
|
+
if (!value || typeof value !== "object") {
|
|
7
|
+
return null;
|
|
8
|
+
}
|
|
9
|
+
const record = value;
|
|
10
|
+
if (record.kind === "chat") {
|
|
11
|
+
if (typeof record.userId !== "string" || !record.userId) {
|
|
12
|
+
return null;
|
|
13
|
+
}
|
|
14
|
+
if (typeof record.role !== "string" || !record.role) {
|
|
15
|
+
return null;
|
|
16
|
+
}
|
|
17
|
+
if (!isStringArray(record.spaceCodes)) {
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
return {
|
|
21
|
+
kind: "chat",
|
|
22
|
+
role: record.role,
|
|
23
|
+
spaceCodes: record.spaceCodes,
|
|
24
|
+
userId: record.userId
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
if (record.kind === "automation") {
|
|
28
|
+
if (typeof record.automationId !== "string" || !record.automationId) {
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
const spaceId = record.spaceId ?? null;
|
|
32
|
+
if (spaceId !== null && typeof spaceId !== "string") {
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
if (!isStringArray(record.spaceCodes)) {
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
return {
|
|
39
|
+
automationId: record.automationId,
|
|
40
|
+
kind: "automation",
|
|
41
|
+
spaceCodes: record.spaceCodes,
|
|
42
|
+
spaceId
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// src/tools/tool-names.ts
|
|
49
|
+
var CUSTOM_TOOL_NAME_PREFIX = "custom_";
|
|
50
|
+
var TOOL_NAME_PATTERN = /^[a-z][a-zA-Z0-9_]*$/;
|
|
51
|
+
function isValidToolName(name) {
|
|
52
|
+
return TOOL_NAME_PATTERN.test(name) && !name.startsWith(CUSTOM_TOOL_NAME_PREFIX);
|
|
53
|
+
}
|
|
54
|
+
function toAgentToolName(name) {
|
|
55
|
+
return `${CUSTOM_TOOL_NAME_PREFIX}${name}`;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// src/tools/define-tool.ts
|
|
59
|
+
import { z } from "zod";
|
|
60
|
+
|
|
61
|
+
// src/tools/json-schema.ts
|
|
62
|
+
function stripJsonSchemaMeta(value) {
|
|
63
|
+
if (Array.isArray(value)) {
|
|
64
|
+
return value.map((entry) => stripJsonSchemaMeta(entry));
|
|
65
|
+
}
|
|
66
|
+
if (!value || typeof value !== "object") {
|
|
67
|
+
return value;
|
|
68
|
+
}
|
|
69
|
+
const result = {};
|
|
70
|
+
for (const [key, nested] of Object.entries(value)) {
|
|
71
|
+
if (key === "$schema") {
|
|
72
|
+
continue;
|
|
73
|
+
}
|
|
74
|
+
result[key] = stripJsonSchemaMeta(nested);
|
|
75
|
+
}
|
|
76
|
+
return result;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// src/tools/define-tool.ts
|
|
80
|
+
function defineTool(options) {
|
|
81
|
+
if (!isValidToolName(options.name)) {
|
|
82
|
+
throw new Error(
|
|
83
|
+
`Invalid custom tool name "${options.name}". Use a camelCase identifier that does not start with \`custom_\`.`
|
|
84
|
+
);
|
|
85
|
+
}
|
|
86
|
+
if (!options.description.trim()) {
|
|
87
|
+
throw new Error(`Custom tool "${options.name}" must have a description.`);
|
|
88
|
+
}
|
|
89
|
+
return {
|
|
90
|
+
description: options.description.trim(),
|
|
91
|
+
execute: (input, actor) => options.execute(input, actor),
|
|
92
|
+
input: options.input,
|
|
93
|
+
name: options.name
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
function toolToManifest(tool) {
|
|
97
|
+
const inputSchema = stripJsonSchemaMeta(
|
|
98
|
+
z.toJSONSchema(tool.input, { target: "draft-07" })
|
|
99
|
+
);
|
|
100
|
+
return {
|
|
101
|
+
description: tool.description,
|
|
102
|
+
inputSchema,
|
|
103
|
+
name: tool.name
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// src/tools/hmac.ts
|
|
108
|
+
var FLEXKIT_TIMESTAMP_HEADER = "flexkit-timestamp";
|
|
109
|
+
var FLEXKIT_SIGNATURE_HEADER = "flexkit-signature";
|
|
110
|
+
var FLEXKIT_SIGNATURE_PREVIOUS_HEADER = "flexkit-signature-previous";
|
|
111
|
+
var CUSTOMER_TOOLS_SERVE_PATH = "/api/flexkit/tools";
|
|
112
|
+
var CUSTOMER_TOOLS_HELLO_PATH = "/tools/dev-connect/hello";
|
|
113
|
+
var CUSTOMER_TOOLS_POLL_PATH = "/tools/dev-connect/poll";
|
|
114
|
+
var CUSTOMER_TOOLS_RESPOND_PATH = "/tools/dev-connect/respond";
|
|
115
|
+
var DEFAULT_MAX_SKEW_SECONDS = 300;
|
|
116
|
+
function getSubtleCrypto() {
|
|
117
|
+
const subtle = globalThis.crypto?.subtle;
|
|
118
|
+
if (!subtle) {
|
|
119
|
+
throw new Error("Web Crypto is not available.");
|
|
120
|
+
}
|
|
121
|
+
return subtle;
|
|
122
|
+
}
|
|
123
|
+
function encodeUtf8(value) {
|
|
124
|
+
return new TextEncoder().encode(value);
|
|
125
|
+
}
|
|
126
|
+
function toBase64Url(bytes) {
|
|
127
|
+
const binary = String.fromCharCode(...new Uint8Array(bytes));
|
|
128
|
+
return btoa(binary).replaceAll("+", "-").replaceAll("/", "_").replaceAll("=", "");
|
|
129
|
+
}
|
|
130
|
+
function timingSafeEqualBytes(left, right) {
|
|
131
|
+
if (left.length !== right.length) {
|
|
132
|
+
return false;
|
|
133
|
+
}
|
|
134
|
+
let diff = 0;
|
|
135
|
+
for (let index = 0; index < left.length; index += 1) {
|
|
136
|
+
diff |= (left[index] ?? 0) ^ (right[index] ?? 0);
|
|
137
|
+
}
|
|
138
|
+
return diff === 0;
|
|
139
|
+
}
|
|
140
|
+
function getUnixTimestampSeconds() {
|
|
141
|
+
return Math.floor(Date.now() / 1e3);
|
|
142
|
+
}
|
|
143
|
+
function buildSignaturePayload({
|
|
144
|
+
body,
|
|
145
|
+
method,
|
|
146
|
+
path,
|
|
147
|
+
timestamp
|
|
148
|
+
}) {
|
|
149
|
+
return `${timestamp.toString()}.${method.toUpperCase()}.${path}.${body}`;
|
|
150
|
+
}
|
|
151
|
+
async function signPayload(secret, payload) {
|
|
152
|
+
const key = await getSubtleCrypto().importKey(
|
|
153
|
+
"raw",
|
|
154
|
+
encodeUtf8(secret),
|
|
155
|
+
{ hash: "SHA-256", name: "HMAC" },
|
|
156
|
+
false,
|
|
157
|
+
["sign"]
|
|
158
|
+
);
|
|
159
|
+
const signature = await getSubtleCrypto().sign("HMAC", key, encodeUtf8(payload));
|
|
160
|
+
return `v1=${toBase64Url(signature)}`;
|
|
161
|
+
}
|
|
162
|
+
async function createSignedHeaders({
|
|
163
|
+
body,
|
|
164
|
+
method,
|
|
165
|
+
path,
|
|
166
|
+
previousSecret,
|
|
167
|
+
secret,
|
|
168
|
+
timestamp = getUnixTimestampSeconds()
|
|
169
|
+
}) {
|
|
170
|
+
const payload = buildSignaturePayload({ body, method, path, timestamp });
|
|
171
|
+
const headers = {
|
|
172
|
+
"Flexkit-Timestamp": timestamp.toString(),
|
|
173
|
+
"Flexkit-Signature": await signPayload(secret, payload)
|
|
174
|
+
};
|
|
175
|
+
if (previousSecret) {
|
|
176
|
+
headers["Flexkit-Signature-Previous"] = await signPayload(previousSecret, payload);
|
|
177
|
+
}
|
|
178
|
+
return headers;
|
|
179
|
+
}
|
|
180
|
+
function uniqueSecrets(secret) {
|
|
181
|
+
const values = Array.isArray(secret) ? secret : [secret];
|
|
182
|
+
const unique = [];
|
|
183
|
+
for (const value of values) {
|
|
184
|
+
const trimmed = value.trim();
|
|
185
|
+
if (trimmed && !unique.includes(trimmed)) {
|
|
186
|
+
unique.push(trimmed);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
return unique;
|
|
190
|
+
}
|
|
191
|
+
function parseSignatureHeader(value) {
|
|
192
|
+
const trimmed = value.trim();
|
|
193
|
+
if (trimmed.startsWith("v1=")) {
|
|
194
|
+
return trimmed.slice(3);
|
|
195
|
+
}
|
|
196
|
+
return null;
|
|
197
|
+
}
|
|
198
|
+
async function verifySignedHeaders({
|
|
199
|
+
body,
|
|
200
|
+
maxSkewSeconds = DEFAULT_MAX_SKEW_SECONDS,
|
|
201
|
+
method,
|
|
202
|
+
path,
|
|
203
|
+
previousSignatureHeader,
|
|
204
|
+
secret,
|
|
205
|
+
signatureHeader,
|
|
206
|
+
timestampHeader
|
|
207
|
+
}) {
|
|
208
|
+
const secrets = uniqueSecrets(secret);
|
|
209
|
+
const signatureHeaders = [signatureHeader, previousSignatureHeader ?? null].filter(
|
|
210
|
+
(value) => Boolean(value)
|
|
211
|
+
);
|
|
212
|
+
if (secrets.length === 0 || signatureHeaders.length === 0 || !timestampHeader) {
|
|
213
|
+
return false;
|
|
214
|
+
}
|
|
215
|
+
const timestamp = Number(timestampHeader);
|
|
216
|
+
if (!Number.isInteger(timestamp)) {
|
|
217
|
+
return false;
|
|
218
|
+
}
|
|
219
|
+
const now = getUnixTimestampSeconds();
|
|
220
|
+
if (Math.abs(now - timestamp) > maxSkewSeconds) {
|
|
221
|
+
return false;
|
|
222
|
+
}
|
|
223
|
+
const payload = buildSignaturePayload({ body, method, path, timestamp });
|
|
224
|
+
for (const candidateSecret of secrets) {
|
|
225
|
+
const expected = await signPayload(candidateSecret, payload);
|
|
226
|
+
const expectedDigest = parseSignatureHeader(expected);
|
|
227
|
+
if (!expectedDigest) {
|
|
228
|
+
continue;
|
|
229
|
+
}
|
|
230
|
+
const expectedBytes = encodeUtf8(expectedDigest);
|
|
231
|
+
for (const header of signatureHeaders) {
|
|
232
|
+
const providedDigest = parseSignatureHeader(header);
|
|
233
|
+
if (!providedDigest) {
|
|
234
|
+
continue;
|
|
235
|
+
}
|
|
236
|
+
const providedBytes = encodeUtf8(providedDigest);
|
|
237
|
+
if (providedBytes.length !== expectedBytes.length) {
|
|
238
|
+
continue;
|
|
239
|
+
}
|
|
240
|
+
if (timingSafeEqualBytes(providedBytes, expectedBytes)) {
|
|
241
|
+
return true;
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
return false;
|
|
246
|
+
}
|
|
247
|
+
function getHeader(headers, name) {
|
|
248
|
+
return headers.get(name) ?? headers.get(name.toLowerCase());
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
// src/core/domains.ts
|
|
252
|
+
var defaultFlexkitDomain = "flexkit.io";
|
|
253
|
+
var allowedFlexkitDomains = {
|
|
254
|
+
"flexkit.io": true,
|
|
255
|
+
"flexkit.test": true
|
|
256
|
+
};
|
|
257
|
+
function getConfiguredFlexkitDomain() {
|
|
258
|
+
const configuredDomain = globalThis.process?.env?.FLEXKIT_DOMAIN?.trim();
|
|
259
|
+
if (!configuredDomain) {
|
|
260
|
+
return defaultFlexkitDomain;
|
|
261
|
+
}
|
|
262
|
+
if (allowedFlexkitDomains[configuredDomain]) {
|
|
263
|
+
return configuredDomain;
|
|
264
|
+
}
|
|
265
|
+
return defaultFlexkitDomain;
|
|
266
|
+
}
|
|
267
|
+
var flexkitDomain = getConfiguredFlexkitDomain();
|
|
268
|
+
var flexkitApiDomain = `api.${flexkitDomain}`;
|
|
269
|
+
|
|
270
|
+
// src/tools/dev-connect.ts
|
|
271
|
+
var CUSTOMER_TOOLS_ME_PATH = "/users/me";
|
|
272
|
+
var FLEXKIT_STUDIO_RUNTIME_HEADER = "Flexkit-Studio-Runtime";
|
|
273
|
+
var FLEXKIT_STUDIO_RUNTIME_LOCAL = "local";
|
|
274
|
+
var DEV_CONNECT_ROLES = {
|
|
275
|
+
developer: true,
|
|
276
|
+
owner: true
|
|
277
|
+
};
|
|
278
|
+
function jsonResult(status, body) {
|
|
279
|
+
return {
|
|
280
|
+
body,
|
|
281
|
+
headers: { "Content-Type": "application/json" },
|
|
282
|
+
status,
|
|
283
|
+
type: "json"
|
|
284
|
+
};
|
|
285
|
+
}
|
|
286
|
+
function shouldHandleDevConnectTick() {
|
|
287
|
+
const env = globalThis.process?.env ?? {};
|
|
288
|
+
if (env.FLEXKIT_TOOLS_DEV_CONNECT === "1") {
|
|
289
|
+
return true;
|
|
290
|
+
}
|
|
291
|
+
return env.NODE_ENV !== "production";
|
|
292
|
+
}
|
|
293
|
+
function isDevConnectRole(role) {
|
|
294
|
+
return Boolean(role && DEV_CONNECT_ROLES[role]);
|
|
295
|
+
}
|
|
296
|
+
function getProjectApiOrigin(projectId) {
|
|
297
|
+
return `https://${projectId}.${flexkitApiDomain}`;
|
|
298
|
+
}
|
|
299
|
+
function guessClientLabel(fallbackProjectId) {
|
|
300
|
+
const env = globalThis.process?.env ?? {};
|
|
301
|
+
const port = env.PORT ?? "3000";
|
|
302
|
+
return `${env.npm_package_name ?? fallbackProjectId}@localhost:${port}`;
|
|
303
|
+
}
|
|
304
|
+
function isCustomerToolsTickPath(pathname) {
|
|
305
|
+
return /^\/api\/flexkit\/[^/]+\/tools\/dev-connect\/tick$/.test(pathname);
|
|
306
|
+
}
|
|
307
|
+
function getCustomerToolsTickPath(projectId) {
|
|
308
|
+
return `/api/flexkit/${projectId}/tools/dev-connect/tick`;
|
|
309
|
+
}
|
|
310
|
+
async function sessionFetch({
|
|
311
|
+
body,
|
|
312
|
+
method,
|
|
313
|
+
path,
|
|
314
|
+
projectId,
|
|
315
|
+
sessionToken
|
|
316
|
+
}) {
|
|
317
|
+
const headers = {
|
|
318
|
+
Cookie: `sessionToken=${sessionToken}`
|
|
319
|
+
};
|
|
320
|
+
if (body) {
|
|
321
|
+
headers["Content-Type"] = "application/json";
|
|
322
|
+
}
|
|
323
|
+
return fetch(`${getProjectApiOrigin(projectId)}${path}`, {
|
|
324
|
+
body,
|
|
325
|
+
headers,
|
|
326
|
+
method
|
|
327
|
+
});
|
|
328
|
+
}
|
|
329
|
+
var tickInFlight = false;
|
|
330
|
+
var HELLO_INTERVAL_MS = 3e4;
|
|
331
|
+
var connectDecisions = {};
|
|
332
|
+
var helloStates = {};
|
|
333
|
+
function connectDecisionKey(projectId, sessionToken) {
|
|
334
|
+
return `${sessionToken}\0${projectId}`;
|
|
335
|
+
}
|
|
336
|
+
function forgetConnectDecision({ projectId, sessionToken }) {
|
|
337
|
+
const key = connectDecisionKey(projectId, sessionToken);
|
|
338
|
+
delete connectDecisions[key];
|
|
339
|
+
delete helloStates[key];
|
|
340
|
+
}
|
|
341
|
+
function rememberConnectDecision({
|
|
342
|
+
decision,
|
|
343
|
+
projectId,
|
|
344
|
+
sessionToken
|
|
345
|
+
}) {
|
|
346
|
+
connectDecisions[connectDecisionKey(projectId, sessionToken)] = decision;
|
|
347
|
+
}
|
|
348
|
+
function hashManifest(manifest) {
|
|
349
|
+
let hash = 2166136261;
|
|
350
|
+
for (let index = 0; index < manifest.length; index += 1) {
|
|
351
|
+
hash ^= manifest.charCodeAt(index);
|
|
352
|
+
hash = Math.imul(hash, 16777619);
|
|
353
|
+
}
|
|
354
|
+
return (hash >>> 0).toString(36);
|
|
355
|
+
}
|
|
356
|
+
function shouldSendHello(input) {
|
|
357
|
+
const state = helloStates[connectDecisionKey(input.projectId, input.sessionToken)];
|
|
358
|
+
if (!state || state.manifestHash !== input.manifestHash) {
|
|
359
|
+
return true;
|
|
360
|
+
}
|
|
361
|
+
return Date.now() - state.sentAt >= HELLO_INTERVAL_MS;
|
|
362
|
+
}
|
|
363
|
+
function rememberHello(input) {
|
|
364
|
+
helloStates[connectDecisionKey(input.projectId, input.sessionToken)] = {
|
|
365
|
+
manifestHash: input.manifestHash,
|
|
366
|
+
sentAt: Date.now()
|
|
367
|
+
};
|
|
368
|
+
}
|
|
369
|
+
function deniedDevConnectResult(status) {
|
|
370
|
+
if (status === 401) {
|
|
371
|
+
return jsonResult(401, { error: "Sign in to Studio to connect local tools." });
|
|
372
|
+
}
|
|
373
|
+
return jsonResult(403, { error: "Only owners and developers can connect local tools." });
|
|
374
|
+
}
|
|
375
|
+
async function getDevConnectDenial({
|
|
376
|
+
projectId,
|
|
377
|
+
sessionToken
|
|
378
|
+
}) {
|
|
379
|
+
const cached = connectDecisions[connectDecisionKey(projectId, sessionToken)];
|
|
380
|
+
if (cached === "allow") {
|
|
381
|
+
return null;
|
|
382
|
+
}
|
|
383
|
+
if (cached === 401 || cached === 403) {
|
|
384
|
+
return deniedDevConnectResult(cached);
|
|
385
|
+
}
|
|
386
|
+
let meResponse;
|
|
387
|
+
try {
|
|
388
|
+
meResponse = await sessionFetch({
|
|
389
|
+
method: "GET",
|
|
390
|
+
path: CUSTOMER_TOOLS_ME_PATH,
|
|
391
|
+
projectId,
|
|
392
|
+
sessionToken
|
|
393
|
+
});
|
|
394
|
+
} catch {
|
|
395
|
+
return jsonResult(503, { error: "Unable to verify Studio session for local tools." });
|
|
396
|
+
}
|
|
397
|
+
if (meResponse.status === 401 || meResponse.status === 403) {
|
|
398
|
+
rememberConnectDecision({ decision: meResponse.status, projectId, sessionToken });
|
|
399
|
+
return deniedDevConnectResult(meResponse.status);
|
|
400
|
+
}
|
|
401
|
+
if (!meResponse.ok) {
|
|
402
|
+
return jsonResult(503, { error: "Unable to verify Studio session for local tools." });
|
|
403
|
+
}
|
|
404
|
+
let payload = {};
|
|
405
|
+
try {
|
|
406
|
+
payload = await meResponse.json();
|
|
407
|
+
} catch {
|
|
408
|
+
return jsonResult(503, { error: "Unable to verify Studio session for local tools." });
|
|
409
|
+
}
|
|
410
|
+
const role = typeof payload.role === "string" ? payload.role : "";
|
|
411
|
+
if (isDevConnectRole(role)) {
|
|
412
|
+
rememberConnectDecision({ decision: "allow", projectId, sessionToken });
|
|
413
|
+
return null;
|
|
414
|
+
}
|
|
415
|
+
rememberConnectDecision({ decision: 403, projectId, sessionToken });
|
|
416
|
+
return deniedDevConnectResult(403);
|
|
417
|
+
}
|
|
418
|
+
async function executeJob({
|
|
419
|
+
actor,
|
|
420
|
+
job,
|
|
421
|
+
projectId,
|
|
422
|
+
sessionToken,
|
|
423
|
+
tools
|
|
424
|
+
}) {
|
|
425
|
+
const tool = tools.find((candidate) => candidate.name === job.name);
|
|
426
|
+
let body;
|
|
427
|
+
if (!tool) {
|
|
428
|
+
body = JSON.stringify({ error: `Unknown tool "${job.name}".`, jobId: job.id });
|
|
429
|
+
} else {
|
|
430
|
+
const parsed = tool.input.safeParse(job.arguments ?? {});
|
|
431
|
+
if (!parsed.success) {
|
|
432
|
+
body = JSON.stringify({
|
|
433
|
+
error: parsed.error.issues.map((issue) => issue.message).join(", "),
|
|
434
|
+
jobId: job.id
|
|
435
|
+
});
|
|
436
|
+
} else {
|
|
437
|
+
try {
|
|
438
|
+
const result = await tool.execute(parsed.data, actor);
|
|
439
|
+
body = JSON.stringify({ jobId: job.id, result });
|
|
440
|
+
} catch (error) {
|
|
441
|
+
body = JSON.stringify({
|
|
442
|
+
error: error instanceof Error ? error.message : "Tool execution failed.",
|
|
443
|
+
jobId: job.id
|
|
444
|
+
});
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
await sessionFetch({
|
|
449
|
+
body,
|
|
450
|
+
method: "POST",
|
|
451
|
+
path: CUSTOMER_TOOLS_RESPOND_PATH,
|
|
452
|
+
projectId,
|
|
453
|
+
sessionToken
|
|
454
|
+
});
|
|
455
|
+
}
|
|
456
|
+
async function handleDevConnectTick({
|
|
457
|
+
projectId,
|
|
458
|
+
sessionToken,
|
|
459
|
+
skills,
|
|
460
|
+
tools
|
|
461
|
+
}) {
|
|
462
|
+
if (!shouldHandleDevConnectTick()) {
|
|
463
|
+
return jsonResult(204, { ok: true });
|
|
464
|
+
}
|
|
465
|
+
if (!sessionToken) {
|
|
466
|
+
return jsonResult(401, { error: "Sign in to Studio to connect local tools." });
|
|
467
|
+
}
|
|
468
|
+
if (!projectId || tools.length === 0 && skills === void 0) {
|
|
469
|
+
return jsonResult(204, { ok: true });
|
|
470
|
+
}
|
|
471
|
+
const denial = await getDevConnectDenial({ projectId, sessionToken });
|
|
472
|
+
if (denial) {
|
|
473
|
+
return denial;
|
|
474
|
+
}
|
|
475
|
+
if (tickInFlight) {
|
|
476
|
+
return jsonResult(204, { ok: true });
|
|
477
|
+
}
|
|
478
|
+
tickInFlight = true;
|
|
479
|
+
const helloBody = JSON.stringify({
|
|
480
|
+
clientLabel: guessClientLabel(projectId),
|
|
481
|
+
...skills === void 0 ? {} : { skills },
|
|
482
|
+
tools: tools.map((tool) => toolToManifest(tool))
|
|
483
|
+
});
|
|
484
|
+
const manifestHash = hashManifest(helloBody);
|
|
485
|
+
try {
|
|
486
|
+
if (shouldSendHello({ manifestHash, projectId, sessionToken })) {
|
|
487
|
+
const helloResponse = await sessionFetch({
|
|
488
|
+
body: helloBody,
|
|
489
|
+
method: "POST",
|
|
490
|
+
path: CUSTOMER_TOOLS_HELLO_PATH,
|
|
491
|
+
projectId,
|
|
492
|
+
sessionToken
|
|
493
|
+
});
|
|
494
|
+
if (helloResponse.status === 401 || helloResponse.status === 403) {
|
|
495
|
+
forgetConnectDecision({ projectId, sessionToken });
|
|
496
|
+
return jsonResult(helloResponse.status, { error: "Unable to register the local tools runtime." });
|
|
497
|
+
}
|
|
498
|
+
if (!helloResponse.ok) {
|
|
499
|
+
return jsonResult(helloResponse.status, { error: "Unable to register the local tools runtime." });
|
|
500
|
+
}
|
|
501
|
+
rememberHello({ manifestHash, projectId, sessionToken });
|
|
502
|
+
}
|
|
503
|
+
const pollResponse = await sessionFetch({
|
|
504
|
+
method: "GET",
|
|
505
|
+
path: CUSTOMER_TOOLS_POLL_PATH,
|
|
506
|
+
projectId,
|
|
507
|
+
sessionToken
|
|
508
|
+
});
|
|
509
|
+
if (pollResponse.status === 401 || pollResponse.status === 403) {
|
|
510
|
+
forgetConnectDecision({ projectId, sessionToken });
|
|
511
|
+
return jsonResult(pollResponse.status, { error: "Unable to poll for local tool jobs." });
|
|
512
|
+
}
|
|
513
|
+
if (pollResponse.status !== 200) {
|
|
514
|
+
return jsonResult(pollResponse.status, { error: "Unable to poll for local tool jobs." });
|
|
515
|
+
}
|
|
516
|
+
const { job } = await pollResponse.json();
|
|
517
|
+
if (!job) {
|
|
518
|
+
return jsonResult(200, { job: null });
|
|
519
|
+
}
|
|
520
|
+
const actor = parseCustomerToolActor(job.actor);
|
|
521
|
+
if (!actor) {
|
|
522
|
+
await sessionFetch({
|
|
523
|
+
body: JSON.stringify({ error: "A valid Flexkit actor is required.", jobId: job.id }),
|
|
524
|
+
method: "POST",
|
|
525
|
+
path: CUSTOMER_TOOLS_RESPOND_PATH,
|
|
526
|
+
projectId,
|
|
527
|
+
sessionToken
|
|
528
|
+
});
|
|
529
|
+
return jsonResult(200, { job: job.id });
|
|
530
|
+
}
|
|
531
|
+
await executeJob({ actor, job, projectId, sessionToken, tools });
|
|
532
|
+
return jsonResult(200, { job: job.id });
|
|
533
|
+
} catch {
|
|
534
|
+
return jsonResult(503, { error: "Flexkit is not reachable from this local runtime." });
|
|
535
|
+
} finally {
|
|
536
|
+
tickInFlight = false;
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
// src/tools/define-skill.ts
|
|
541
|
+
var MAX_SKILL_NAME_LENGTH = 120;
|
|
542
|
+
var MAX_SKILL_DESCRIPTION_LENGTH = 500;
|
|
543
|
+
var MAX_SKILL_CONTENT_LENGTH = 5e4;
|
|
544
|
+
function requireValue(value, field) {
|
|
545
|
+
const trimmed = value.trim();
|
|
546
|
+
if (!trimmed) {
|
|
547
|
+
throw new Error(`Custom skill ${field} is required.`);
|
|
548
|
+
}
|
|
549
|
+
return trimmed;
|
|
550
|
+
}
|
|
551
|
+
function defineSkill(options) {
|
|
552
|
+
const name = requireValue(options.name, "name");
|
|
553
|
+
const description = requireValue(options.description, `"${name}" description`);
|
|
554
|
+
const content = requireValue(options.content, `"${name}" content`);
|
|
555
|
+
const space = options.space === void 0 ? void 0 : requireValue(options.space, `"${name}" space`);
|
|
556
|
+
if (name.length > MAX_SKILL_NAME_LENGTH) {
|
|
557
|
+
throw new Error(`Custom skill name must be at most ${String(MAX_SKILL_NAME_LENGTH)} characters.`);
|
|
558
|
+
}
|
|
559
|
+
if (description.length > MAX_SKILL_DESCRIPTION_LENGTH) {
|
|
560
|
+
throw new Error(
|
|
561
|
+
`Custom skill "${name}" description must be at most ${String(MAX_SKILL_DESCRIPTION_LENGTH)} characters.`
|
|
562
|
+
);
|
|
563
|
+
}
|
|
564
|
+
if (content.length > MAX_SKILL_CONTENT_LENGTH) {
|
|
565
|
+
throw new Error(`Custom skill "${name}" content must be at most ${String(MAX_SKILL_CONTENT_LENGTH)} characters.`);
|
|
566
|
+
}
|
|
567
|
+
return {
|
|
568
|
+
content,
|
|
569
|
+
description,
|
|
570
|
+
name,
|
|
571
|
+
...space === void 0 ? {} : { space }
|
|
572
|
+
};
|
|
573
|
+
}
|
|
574
|
+
function assertUniqueSkillNames(skills) {
|
|
575
|
+
const names = /* @__PURE__ */ new Set();
|
|
576
|
+
for (const skill of skills) {
|
|
577
|
+
if (names.has(skill.name)) {
|
|
578
|
+
throw new Error(`Duplicate custom skill name "${skill.name}".`);
|
|
579
|
+
}
|
|
580
|
+
names.add(skill.name);
|
|
581
|
+
}
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
export {
|
|
585
|
+
flexkitDomain,
|
|
586
|
+
flexkitApiDomain,
|
|
587
|
+
parseCustomerToolActor,
|
|
588
|
+
CUSTOM_TOOL_NAME_PREFIX,
|
|
589
|
+
isValidToolName,
|
|
590
|
+
toAgentToolName,
|
|
591
|
+
defineTool,
|
|
592
|
+
toolToManifest,
|
|
593
|
+
FLEXKIT_TIMESTAMP_HEADER,
|
|
594
|
+
FLEXKIT_SIGNATURE_HEADER,
|
|
595
|
+
FLEXKIT_SIGNATURE_PREVIOUS_HEADER,
|
|
596
|
+
CUSTOMER_TOOLS_SERVE_PATH,
|
|
597
|
+
CUSTOMER_TOOLS_HELLO_PATH,
|
|
598
|
+
CUSTOMER_TOOLS_POLL_PATH,
|
|
599
|
+
CUSTOMER_TOOLS_RESPOND_PATH,
|
|
600
|
+
signPayload,
|
|
601
|
+
createSignedHeaders,
|
|
602
|
+
verifySignedHeaders,
|
|
603
|
+
getHeader,
|
|
604
|
+
FLEXKIT_STUDIO_RUNTIME_HEADER,
|
|
605
|
+
FLEXKIT_STUDIO_RUNTIME_LOCAL,
|
|
606
|
+
shouldHandleDevConnectTick,
|
|
607
|
+
isDevConnectRole,
|
|
608
|
+
isCustomerToolsTickPath,
|
|
609
|
+
getCustomerToolsTickPath,
|
|
610
|
+
handleDevConnectTick,
|
|
611
|
+
MAX_SKILL_NAME_LENGTH,
|
|
612
|
+
MAX_SKILL_DESCRIPTION_LENGTH,
|
|
613
|
+
MAX_SKILL_CONTENT_LENGTH,
|
|
614
|
+
defineSkill,
|
|
615
|
+
assertUniqueSkillNames
|
|
616
|
+
};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import'./index.css';import {j}from'./chunk-FVFRTCEB.js';import {useId}from'react';import {jsxs,jsx}from'react/jsx-runtime';function c({scope:e,checked:d,disabled:n,onChange:t}){let l=useId();return !e||e==="default"?null:jsxs("div",{className:"fk:flex fk:items-center fk:space-x-2",children:[jsx(j,{checked:d,disabled:n,id:l,onCheckedChange:t}),jsx("label",{className:"fk:text-xs fk:font-normal fk:leading-none fk:peer-disabled:cursor-not-allowed fk:peer-disabled:opacity-70",htmlFor:l,children:"Use default value"})]})}export{c as a};//# sourceMappingURL=chunk-VUAFNQK7.js.map
|
|
2
|
+
//# sourceMappingURL=chunk-VUAFNQK7.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/form/fields/default-value-switch.tsx"],"names":["DefaultValueSwitch","scope","checked","disabled","onChange","elementId","useId","jsxs","jsx","Checkbox"],"mappings":"2HAWO,SAASA,CAAAA,CAAmB,CAAE,KAAA,CAAAC,EAAO,OAAA,CAAAC,CAAAA,CAAS,QAAA,CAAAC,CAAAA,CAAU,QAAA,CAAAC,CAAS,CAAA,CAA8B,CACpG,IAAMC,CAAAA,CAAYC,KAAAA,EAAM,CAExB,OAAI,CAACL,GAASA,CAAAA,GAAU,SAAA,CACf,IAAA,CAIPM,IAAAA,CAAC,KAAA,CAAA,CAAI,SAAA,CAAU,sCAAA,CACb,QAAA,CAAA,CAAAC,GAAAA,CAACC,CAAAA,CAAA,CAAS,OAAA,CAASP,CAAAA,CAAS,QAAA,CAAUC,CAAAA,CAAU,EAAA,CAAIE,CAAAA,CAAW,eAAA,CAAiBD,CAAAA,CAAwB,CAAA,CACxGI,GAAAA,CAAC,OAAA,CAAA,CACC,SAAA,CAAU,2GAAA,CACV,OAAA,CAASH,CAAAA,CACV,QAAA,CAAA,mBAAA,CAED,CAAA,CAAA,CACF,CAEJ","file":"chunk-VUAFNQK7.js","sourcesContent":["import { useId } from 'react';\nimport type { JSX } from 'react';\nimport { Checkbox } from '../../ui/primitives/checkbox';\n\ntype Props = {\n scope: string | undefined;\n checked: boolean;\n disabled?: boolean;\n onChange: (checked: boolean) => void;\n};\n\nexport function DefaultValueSwitch({ scope, checked, disabled, onChange }: Props): JSX.Element | null {\n const elementId = useId();\n\n if (!scope || scope === 'default') {\n return null;\n }\n\n return (\n <div className=\"fk:flex fk:items-center fk:space-x-2\">\n <Checkbox checked={checked} disabled={disabled} id={elementId} onCheckedChange={onChange as () => void} />\n <label\n className=\"fk:text-xs fk:font-normal fk:leading-none fk:peer-disabled:cursor-not-allowed fk:peer-disabled:opacity-70\"\n htmlFor={elementId}\n >\n Use default value\n </label>\n </div>\n );\n}\n"]}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import'./index.css';import {c}from'./chunk-KHPTVIYT.js';import {a}from'./chunk-O2QMYUPS.js';import {Slot}from'radix-ui';import {cva}from'class-variance-authority';import {jsx}from'react/jsx-runtime';var l=cva("fk:flex fk:w-fit fk:items-stretch fk:has-[>[data-slot=button-group]]:gap-2 fk:[&>*]:focus-visible:relative fk:[&>*]:focus-visible:z-10 fk:has-[select[aria-hidden=true]:last-child]:[&>[data-slot=select-trigger]:last-of-type]:rounded-r-md fk:[&>[data-slot=select-trigger]:not([class*=w-])]:w-fit fk:[&>input]:flex-1",{variants:{orientation:{horizontal:"fk:[&>*:not(:first-child)]:rounded-l-none fk:[&>*:not(:first-child)]:border-l-0 fk:[&>*:not(:last-child)]:rounded-r-none",vertical:"fk:flex-col fk:[&>*:not(:first-child)]:rounded-t-none fk:[&>*:not(:first-child)]:border-t-0 fk:[&>*:not(:last-child)]:rounded-b-none"}},defaultVariants:{orientation:"horizontal"}});function k({className:o,orientation:t,...r}){return jsx("div",{role:"group","data-slot":"button-group","data-orientation":t,className:a(l({orientation:t}),o),...r})}function m({className:o,asChild:t=false,...r}){let i=t?Slot.Root:"div";return jsx(i,{className:a("fk:bg-muted fk:shadow-xs fk:flex fk:items-center fk:gap-2 fk:rounded-md fk:border fk:px-4 fk:text-sm fk:font-medium fk:[&_svg:not([class*=size-])]:size-4 fk:[&_svg]:pointer-events-none",o),...r})}function h({className:o,orientation:t="vertical",...r}){return jsx(c,{"data-slot":"button-group-separator",orientation:t,className:a("fk:bg-input fk:relative fk:!m-0 fk:self-stretch fk:data-[orientation=vertical]:h-auto",o),...r})}export{l as a,k as b,m as c,h as d};//# sourceMappingURL=chunk-XFY7MZJN.js.map
|
|
2
|
+
//# sourceMappingURL=chunk-XFY7MZJN.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/ui/primitives/button-group.tsx"],"names":["buttonGroupVariants","cva","ButtonGroup","className","orientation","props","jsx","cn","ButtonGroupText","asChild","Comp","Slot","ButtonGroupSeparator","Separator"],"mappings":"uMAMA,IAAMA,CAAAA,CAAsBC,GAAAA,CAC1B,2TAAA,CACA,CACE,QAAA,CAAU,CACR,WAAA,CAAa,CACX,UAAA,CACE,0HAAA,CACF,QAAA,CACE,sIACJ,CACF,CAAA,CACA,eAAA,CAAiB,CACf,WAAA,CAAa,YACf,CACF,CACF,EAEA,SAASC,CAAAA,CAAY,CACnB,SAAA,CAAAC,CAAAA,CACA,WAAA,CAAAC,CAAAA,CACA,GAAGC,CACL,CAAA,CAA2E,CACzE,OACEC,GAAAA,CAAC,KAAA,CAAA,CACC,IAAA,CAAK,OAAA,CACL,WAAA,CAAU,cAAA,CACV,kBAAA,CAAkBF,CAAAA,CAClB,SAAA,CAAWG,CAAAA,CAAGP,CAAAA,CAAoB,CAAE,WAAA,CAAAI,CAAY,CAAC,CAAA,CAAGD,CAAS,CAAA,CAC5D,GAAGE,CAAAA,CACN,CAEJ,CAEA,SAASG,CAAAA,CAAgB,CACvB,SAAA,CAAAL,CAAAA,CACA,OAAA,CAAAM,CAAAA,CAAU,KAAA,CACV,GAAGJ,CACL,CAAA,CAEG,CACD,IAAMK,CAAAA,CAAOD,CAAAA,CAAUE,IAAAA,CAAK,IAAA,CAAO,KAAA,CAEnC,OACEL,GAAAA,CAACI,CAAAA,CAAA,CACC,SAAA,CAAWH,CAAAA,CACT,0LAAA,CACAJ,CACF,CAAA,CACC,GAAGE,CAAAA,CACN,CAEJ,CAEA,SAASO,CAAAA,CAAqB,CAC5B,SAAA,CAAAT,CAAAA,CACA,WAAA,CAAAC,CAAAA,CAAc,UAAA,CACd,GAAGC,CACL,CAAA,CAA2C,CACzC,OACEC,GAAAA,CAACO,CAAAA,CAAA,CACC,WAAA,CAAU,wBAAA,CACV,WAAA,CAAaT,CAAAA,CACb,SAAA,CAAWG,CAAAA,CACT,uFAAA,CACAJ,CACF,CAAA,CACC,GAAGE,CAAAA,CACN,CAEJ","file":"chunk-XFY7MZJN.js","sourcesContent":["import * as React from 'react';\nimport { Slot } from 'radix-ui';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { cn } from '../lib/utils';\nimport { Separator } from './separator';\n\nconst buttonGroupVariants = cva(\n 'fk:flex fk:w-fit fk:items-stretch fk:has-[>[data-slot=button-group]]:gap-2 fk:[&>*]:focus-visible:relative fk:[&>*]:focus-visible:z-10 fk:has-[select[aria-hidden=true]:last-child]:[&>[data-slot=select-trigger]:last-of-type]:rounded-r-md fk:[&>[data-slot=select-trigger]:not([class*=w-])]:w-fit fk:[&>input]:flex-1',\n {\n variants: {\n orientation: {\n horizontal:\n 'fk:[&>*:not(:first-child)]:rounded-l-none fk:[&>*:not(:first-child)]:border-l-0 fk:[&>*:not(:last-child)]:rounded-r-none',\n vertical:\n 'fk:flex-col fk:[&>*:not(:first-child)]:rounded-t-none fk:[&>*:not(:first-child)]:border-t-0 fk:[&>*:not(:last-child)]:rounded-b-none',\n },\n },\n defaultVariants: {\n orientation: 'horizontal',\n },\n }\n);\n\nfunction ButtonGroup({\n className,\n orientation,\n ...props\n}: React.ComponentProps<'div'> & VariantProps<typeof buttonGroupVariants>) {\n return (\n <div\n role=\"group\"\n data-slot=\"button-group\"\n data-orientation={orientation}\n className={cn(buttonGroupVariants({ orientation }), className)}\n {...props}\n />\n );\n}\n\nfunction ButtonGroupText({\n className,\n asChild = false,\n ...props\n}: React.ComponentProps<'div'> & {\n asChild?: boolean;\n}) {\n const Comp = asChild ? Slot.Root : 'div';\n\n return (\n <Comp\n className={cn(\n 'fk:bg-muted fk:shadow-xs fk:flex fk:items-center fk:gap-2 fk:rounded-md fk:border fk:px-4 fk:text-sm fk:font-medium fk:[&_svg:not([class*=size-])]:size-4 fk:[&_svg]:pointer-events-none',\n className\n )}\n {...props}\n />\n );\n}\n\nfunction ButtonGroupSeparator({\n className,\n orientation = 'vertical',\n ...props\n}: React.ComponentProps<typeof Separator>) {\n return (\n <Separator\n data-slot=\"button-group-separator\"\n orientation={orientation}\n className={cn(\n 'fk:bg-input fk:relative fk:!m-0 fk:self-stretch fk:data-[orientation=vertical]:h-auto',\n className\n )}\n {...props}\n />\n );\n}\n\nexport { ButtonGroup, ButtonGroupSeparator, ButtonGroupText, buttonGroupVariants };\n"]}
|
|
@@ -1,9 +1,12 @@
|
|
|
1
|
+
import { F as FlexkitHandlerOptions } from './types-U28Ppixq.js';
|
|
2
|
+
|
|
1
3
|
interface FlexkitHandlerContext {
|
|
2
4
|
request: Request;
|
|
3
5
|
pathname: string;
|
|
4
6
|
search: string;
|
|
5
7
|
sessionToken: string;
|
|
6
8
|
contentType: string | null;
|
|
9
|
+
options?: FlexkitHandlerOptions;
|
|
7
10
|
}
|
|
8
11
|
type FlexkitHandlerHeaders = {
|
|
9
12
|
[key: string]: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":[],"names":[],"mappings":"","file":"datetime-
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"datetime-DDEWTNLB.js"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":[],"names":[],"mappings":"","file":"editor-
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"editor-HAYTKNMY.js"}
|