@clipform/mcp-server 4.7.0 → 4.8.0
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/api-client.js +1 -1
- package/dist/{chunk-D4Q5ZWFO.js → chunk-7KKHHANA.js} +3 -3
- package/dist/{chunk-HV5FRLYK.js → chunk-LJZVIYLO.js} +11 -9
- package/dist/{chunk-HV5FRLYK.js.map → chunk-LJZVIYLO.js.map} +1 -1
- package/dist/{chunk-VSSV3IOU.js → chunk-MSJJEURL.js} +3 -3
- package/dist/{chunk-EFPJA3JE.js → chunk-R6E7I4GW.js} +6 -2
- package/dist/chunk-R6E7I4GW.js.map +1 -0
- package/dist/{chunk-XC3YMWCN.js → chunk-URQXLZEB.js} +84 -50
- package/dist/chunk-URQXLZEB.js.map +1 -0
- package/dist/index.js +5 -5
- package/dist/prompts.js +3 -3
- package/dist/resources.js +3 -3
- package/dist/server.js +5 -5
- package/package.json +4 -4
- package/server.json +2 -2
- package/dist/chunk-EFPJA3JE.js.map +0 -1
- package/dist/chunk-XC3YMWCN.js.map +0 -1
- /package/dist/{chunk-D4Q5ZWFO.js.map → chunk-7KKHHANA.js.map} +0 -0
- /package/dist/{chunk-VSSV3IOU.js.map → chunk-MSJJEURL.js.map} +0 -0
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import {
|
|
2
2
|
FULL_CAPS,
|
|
3
3
|
getSessionContext
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-R6E7I4GW.js";
|
|
5
5
|
import {
|
|
6
6
|
ALL_VARIANTS,
|
|
7
7
|
FORM_TYPES,
|
|
8
8
|
FORM_TYPE_KEYS,
|
|
9
9
|
callApi
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-URQXLZEB.js";
|
|
11
11
|
import {
|
|
12
12
|
getMcpAuth
|
|
13
13
|
} from "./chunk-ENVV65JX.js";
|
|
@@ -155,4 +155,4 @@ export {
|
|
|
155
155
|
getGuideUri,
|
|
156
156
|
registerResources
|
|
157
157
|
};
|
|
158
|
-
//# sourceMappingURL=chunk-
|
|
158
|
+
//# sourceMappingURL=chunk-MSJJEURL.js.map
|
|
@@ -2,7 +2,7 @@ import {
|
|
|
2
2
|
CURRENT_PLAN_VERSIONS,
|
|
3
3
|
PLAN_LIMITS,
|
|
4
4
|
callApi
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-URQXLZEB.js";
|
|
6
6
|
import {
|
|
7
7
|
getMcpAuth
|
|
8
8
|
} from "./chunk-ENVV65JX.js";
|
|
@@ -15,6 +15,9 @@ function anonPreviewNotice() {
|
|
|
15
15
|
var ANON_PREVIEW_LINK_LABEL = "Preview (answers not saved)";
|
|
16
16
|
var ANON_PREVIEW_ONLY_NOTICE = "The form is ready as a preview. To put it live, call clipform_update_form with is_live:true - no sign-in is needed. In the preview, answers are not saved: do not share the preview link with respondents.";
|
|
17
17
|
var ANON_PREVIEW_ONLY_NOTICE_DRAFTS_ONLY = 'The form is ready as a preview. To go live, say "publish it" - that prompts sign-in and keeps this chat connected to your account. In the preview, answers are not saved: do not share the preview link with respondents.';
|
|
18
|
+
function isAnonymousSession() {
|
|
19
|
+
return getMcpAuth()?.is_anonymous === true;
|
|
20
|
+
}
|
|
18
21
|
function isConnectorGuest() {
|
|
19
22
|
const auth = getMcpAuth();
|
|
20
23
|
return auth?.is_anonymous === true && auth.connector_guest === true;
|
|
@@ -130,6 +133,7 @@ export {
|
|
|
130
133
|
ANON_PREVIEW_NOTICE,
|
|
131
134
|
anonPreviewNotice,
|
|
132
135
|
ANON_PREVIEW_LINK_LABEL,
|
|
136
|
+
isAnonymousSession,
|
|
133
137
|
isConnectorGuest,
|
|
134
138
|
previewOnlyNotice,
|
|
135
139
|
PREVIEW_URL_DESCRIPTION,
|
|
@@ -141,4 +145,4 @@ export {
|
|
|
141
145
|
getSessionContextWithAuth,
|
|
142
146
|
getSessionContext
|
|
143
147
|
};
|
|
144
|
-
//# sourceMappingURL=chunk-
|
|
148
|
+
//# sourceMappingURL=chunk-R6E7I4GW.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/lib/anon-notice.ts","../src/lib/caps.ts","../src/lib/session-context.ts"],"sourcesContent":["import { getMcpAuth } from \"./auth-context.js\";\n\n/**\n * #4650: anonymous (preview) accounts are temporary. Date-free by design - the\n * generic notice promises no day count. The 7-day offline expiry of a live\n * guest form IS enforced now (#4847; ANON_MCP_LIVE_TTL_DAYS, stated in the\n * create_form reply), while the account purge keeps its own schedule (#4662).\n * Defined once; every anonymous-lane surface (create/update_form text, whoami,\n * session resource) reuses it.\n */\nexport const ANON_PREVIEW_NOTICE =\n \"Preview accounts are temporary - claim yours to keep your forms.\";\n\n/** The notice for an anonymous MCP caller, or null for everyone else. */\nexport function anonPreviewNotice(): string | null {\n return getMcpAuth()?.is_anonymous ? ANON_PREVIEW_NOTICE : null;\n}\n\n/**\n * #4845: a preview link is private, never a respondent link (answers are not\n * saved). A guest build now goes live at creation (#4847); a preview is what\n * remains for a draft (moderation held it, or it was taken offline). Wording\n * defined once; create_form, get_form, the format-form link label and the\n * output-schema descriptions all reuse it.\n */\nexport const ANON_PREVIEW_LINK_LABEL = \"Preview (answers not saved)\";\n\nexport const ANON_PREVIEW_ONLY_NOTICE =\n 'The form is ready as a preview. To put it live, call clipform_update_form with is_live:true - no sign-in is needed. In the preview, answers are not saved: do not share the preview link with respondents.';\n\n/** The drafts-only lanes (bot, email, web demo - not the MCP connector): signing up is what publishes. */\nexport const ANON_PREVIEW_ONLY_NOTICE_DRAFTS_ONLY =\n 'The form is ready as a preview. To go live, say \"publish it\" - that prompts sign-in and keeps this chat connected to your account. In the preview, answers are not saved: do not share the preview link with respondents.';\n\n/**\n * True when the caller is an anonymous session per the MCP auth context. /v1/me\n * reports `auth_mode: \"api_key\"` for the anonymous MCP lane (it runs on a bot key),\n * so `/me` alone cannot tell a guest from a signed-in key - the context can.\n */\nexport function isAnonymousSession(): boolean {\n return getMcpAuth()?.is_anonymous === true;\n}\n\n/** True on the MCP handler's anonymous connector lane (#4847). */\nexport function isConnectorGuest(): boolean {\n const auth = getMcpAuth();\n return auth?.is_anonymous === true && auth.connector_guest === true;\n}\n\n/** The preview-only notice for this caller's lane. */\nexport function previewOnlyNotice(): string {\n return isConnectorGuest() ? ANON_PREVIEW_ONLY_NOTICE : ANON_PREVIEW_ONLY_NOTICE_DRAFTS_ONLY;\n}\n\nexport const PREVIEW_URL_DESCRIPTION =\n \"Private preview of the form. Answers are not saved, so do not share it with respondents.\";\n\nexport const CLAIM_URL_DESCRIPTION =\n \"One-time link to sign up, keep this form and switch on its locked steps.\";\n\n/**\n * #5158: sign-in happens in a popup the model never sees, so after an adopt\n * (apps/api oauth-adopt.ts) the tool result tells it the form is now the\n * user's. Prepended by the server.ts registerTool wrapper.\n */\nexport const ADOPTED_FORM_NOTICE =\n \"Signed in - this form moved from the temporary preview account into your Clipform account, so it is yours now. The earlier claim link is no longer needed.\";\n\n/**\n * #4847: a claimed form with a locked step (payment, uploads, links ...) was\n * taken offline by the claim lock, so it arrives as a draft. Publishing it as\n * the new owner switches those steps on.\n */\nexport const ADOPTED_DRAFT_FORM_NOTICE =\n \"Signed in - this form moved from the temporary preview account into your Clipform account, so it is yours now. It is a draft now: publish it (clipform_update_form with is_live:true) to switch its steps on. The earlier claim link is no longer needed.\";\n\n/** The same call published the claimed form: every step is on. */\nexport const ADOPTED_LIVE_FORM_NOTICE =\n \"Signed in - this form moved from the temporary preview account into your Clipform account, so it is yours now. It is live with every step switched on. The earlier claim link is no longer needed.\";\n\n/**\n * Prepend the adopt notice to a successful result for a just-adopted form.\n * content only; structuredContent untouched. A form the claim lock drafted gets\n * the draft variant, or the live one when THIS call is update_form is_live:true.\n */\nexport function withAdoptedNotice<T>(result: T, args: unknown, toolName?: string): T {\n const formId = (args as { form_id?: unknown } | undefined)?.form_id;\n if (typeof formId !== \"string\") return result;\n const auth = getMcpAuth();\n const id = formId.toLowerCase();\n const has = (ids?: string[]) => !!ids && ids.map((i) => i.toLowerCase()).includes(id);\n if (!has(auth?.adopted_form_ids)) return result;\n const r = result as { isError?: boolean; content?: unknown } | undefined;\n if (!r || r.isError || !Array.isArray(r.content)) return result;\n let notice = ADOPTED_FORM_NOTICE;\n if (has(auth?.adopted_draft_form_ids)) {\n const publishedNow =\n toolName === \"clipform_update_form\" && (args as { is_live?: unknown } | undefined)?.is_live === true;\n notice = publishedNow ? ADOPTED_LIVE_FORM_NOTICE : ADOPTED_DRAFT_FORM_NOTICE;\n }\n return { ...r, content: [{ type: \"text\", text: notice }, ...r.content] } as T;\n}\n\n/** True for a viewer link in preview mode (an anonymous caller's draft). */\nexport function isPreviewViewerUrl(url: unknown): boolean {\n return typeof url === \"string\" && url.includes(\"mode=preview\");\n}\n","import type { McpToolset } from \"@vid-master/config\";\n\n/**\n * What a connected surface can actually do, derived from the connect-time\n * toolset filter (#3309) so the guidance layers (server instructions, prompt\n * recipes, `clipform_get_workflow`, craft guides) never reference a tool the\n * surface doesn't register (#3681).\n *\n * The Claude Connectors Directory surface (`mcp.clipform.io/forms`) is\n * account + forms only: no media generation and no research helpers. A\n * workflow that still says \"call clipform_generate_tts\" there sends the model\n * at a tool that doesn't exist, which shows up in review as failed tool\n * calls. Every guidance producer takes a ServerCaps and gates on it.\n */\nexport interface ServerCaps {\n /** Narration, video, image, music, render, and asset tools are registered. */\n media: boolean;\n /** News lookup and the generation audit log are registered. */\n research: boolean;\n /** Form tools (create, edit, publish) are registered. */\n forms: boolean;\n}\n\n/** Every toolset registered - stdio/npx and the bare remote endpoint. */\nexport const FULL_CAPS: ServerCaps = Object.freeze({ media: true, research: true, forms: true });\n\nexport function capsFromToolsets(toolsets?: readonly McpToolset[]): ServerCaps {\n if (toolsets === undefined) return FULL_CAPS;\n return {\n media: toolsets.includes(\"media\"),\n research: toolsets.includes(\"research\"),\n forms: toolsets.includes(\"forms\"),\n };\n}\n","import { BUSINESS, PLAN_LIMITS, CURRENT_PLAN_VERSIONS } from \"@vid-master/config\";\nimport { callApi } from \"./api-client.js\";\nimport { ANON_PREVIEW_NOTICE } from \"./anon-notice.js\";\nimport { getMcpAuth } from \"./auth-context.js\";\n\nexport type AuthMode = \"authenticated\" | \"anonymous\";\n\nexport interface SessionContextResult {\n text: string;\n authMode: AuthMode;\n}\n\nexport async function getSessionContextWithAuth(): Promise<SessionContextResult> {\n let me: any;\n const authCtx = getMcpAuth();\n if (authCtx?.loadInternalContent && !authCtx.api_key) {\n // #4657: the no-workspace anon lane (get_workflow with no mint) has no\n // workspace for /me to describe, so plan caps default to Free.\n const free = PLAN_LIMITS[CURRENT_PLAN_VERSIONS[0]];\n me = {\n auth_mode: \"anonymous\",\n plan: {\n name: free.name,\n tier: free.tier,\n node_limit: free.node_limit,\n form_limit: free.form_limit ?? null,\n custom_theme: free.custom_theme,\n },\n };\n } else {\n let result;\n try {\n result = await callApi(\"/me\", { method: \"GET\" });\n } catch {\n return { text: \"\", authMode: \"anonymous\" };\n }\n if (!result.ok) return { text: \"\", authMode: \"anonymous\" };\n me = result.data as any;\n }\n // The API's auth_mode is \"api_key\" | \"oauth\" | \"session\" | \"anonymous\".\n // Anything credentialed counts as authenticated - the old `=== \"oauth\"`\n // check matched nothing the API returns, so API-key sessions were labelled\n // anonymous with a \"sign in to unlock\" nudge right next to their real\n // plan (#412 F6).\n // The anon MCP lane runs as a minted bot key (/me says \"api_key\"), so the\n // auth context is the truth for anonymous (#4653).\n const apiAuthMode: string = getMcpAuth()?.is_anonymous\n ? \"anonymous\"\n : ((me.auth_mode as string) ?? \"anonymous\");\n const authMode: AuthMode = apiAuthMode === \"anonymous\" ? \"anonymous\" : \"authenticated\";\n const plan = me.plan;\n const lines: string[] = [];\n\n lines.push(\"## Your Session\");\n if (authMode === \"authenticated\") {\n lines.push(\n apiAuthMode === \"api_key\"\n ? \"Auth: API key (workspace-scoped)\"\n : \"Auth: signed in (connected to a Clipform account)\"\n );\n // Workspace NAME only - the workspace UUID and the raw user_id/company_id\n // are internal database identifiers the model never needs (response\n // hygiene / disclosure guard, #2976).\n lines.push(`Workspace: ${me.workspace?.name ?? \"Unknown\"}`);\n } else {\n lines.push(\"Auth: anonymous (not connected to a Clipform account)\");\n if (me.workspace) {\n lines.push(`Workspace: ${me.workspace.name}`);\n }\n }\n lines.push(`Plan: ${plan.name} (tier ${plan.tier})`);\n if (plan.node_limit !== null) {\n lines.push(`Question limit: ${plan.node_limit} per form`);\n } else {\n lines.push(\"Questions: unlimited\");\n }\n if (plan.form_limit !== null) {\n lines.push(`Form limit: ${plan.form_limit} forms`);\n } else {\n lines.push(\"Forms: unlimited\");\n }\n if (plan.custom_theme === false) {\n lines.push(\"Custom themes: not available on this plan\");\n }\n if (authMode === \"anonymous\") {\n // Neutral statement of fact, no upsell/CTA copy (commerce sweep, #2976):\n // an anonymous session's forms are not tied to an account until one signs in.\n lines.push(`\\nAnonymous session: forms are not tied to a Clipform account until you sign in.`);\n lines.push(ANON_PREVIEW_NOTICE);\n }\n\n return { text: lines.join(\"\\n\"), authMode };\n}\n\nexport async function getSessionContext(): Promise<string> {\n const { text } = await getSessionContextWithAuth();\n return text;\n}\n"],"mappings":"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","names":[]}
|
|
@@ -146,7 +146,7 @@ var FEATURES = {
|
|
|
146
146
|
// stored allow_skip, and the MCP hides/drops allow_skip via the config_schema `feature` marker.
|
|
147
147
|
optional_questions: {
|
|
148
148
|
name: "Optional questions",
|
|
149
|
-
description: "Builders can mark a draw or
|
|
149
|
+
description: "Builders can mark a draw, camera or booking question optional so respondents can skip it",
|
|
150
150
|
enabled: false,
|
|
151
151
|
status: "planned",
|
|
152
152
|
category: "builder"
|
|
@@ -231,7 +231,7 @@ var FEATURES = {
|
|
|
231
231
|
},
|
|
232
232
|
node_booking: {
|
|
233
233
|
name: "Booking",
|
|
234
|
-
description: "Calendly or Google Meet scheduling
|
|
234
|
+
description: "Calendly or Google Meet scheduling inside the form",
|
|
235
235
|
enabled: false,
|
|
236
236
|
status: "planned",
|
|
237
237
|
category: "node-types"
|
|
@@ -605,6 +605,13 @@ var FEATURES = {
|
|
|
605
605
|
status: "planned",
|
|
606
606
|
category: "integrations"
|
|
607
607
|
},
|
|
608
|
+
integration_google_calendar: {
|
|
609
|
+
name: "Google Meet",
|
|
610
|
+
description: "Google Calendar scheduling with Google Meet links for the Booking node",
|
|
611
|
+
enabled: false,
|
|
612
|
+
status: "planned",
|
|
613
|
+
category: "integrations"
|
|
614
|
+
},
|
|
608
615
|
integration_calcom: {
|
|
609
616
|
name: "Cal.com",
|
|
610
617
|
description: "Open-source scheduling platform for booking meetings",
|
|
@@ -881,6 +888,46 @@ var DRAW_GAME_DEFAULT_TIERS = [
|
|
|
881
888
|
var DEFAULT_MAX_RECORDING_SECONDS = 120;
|
|
882
889
|
var MAX_RECORDING_SECONDS_MIN = 10;
|
|
883
890
|
var MAX_RECORDING_SECONDS_MAX = 300;
|
|
891
|
+
var BOOKING_PROVIDERS = ["calendly", "google_meet"];
|
|
892
|
+
var BOOKING_RESULT_SCHEMA = {
|
|
893
|
+
type: "object",
|
|
894
|
+
required: ["provider", "status"],
|
|
895
|
+
properties: {
|
|
896
|
+
provider: { type: "string", enum: BOOKING_PROVIDERS },
|
|
897
|
+
status: { type: "string", enum: ["booked", "skipped"] },
|
|
898
|
+
start_time: { type: "string", format: "date-time" },
|
|
899
|
+
end_time: { type: "string", format: "date-time" },
|
|
900
|
+
timezone: { type: "string" },
|
|
901
|
+
join_url: { type: "string" },
|
|
902
|
+
reschedule_url: { type: "string" },
|
|
903
|
+
cancel_url: { type: "string" },
|
|
904
|
+
invitee: {
|
|
905
|
+
type: "object",
|
|
906
|
+
properties: {
|
|
907
|
+
name: { type: "string" },
|
|
908
|
+
email: { type: "string" }
|
|
909
|
+
}
|
|
910
|
+
},
|
|
911
|
+
provider_ids: {
|
|
912
|
+
type: "object",
|
|
913
|
+
properties: {
|
|
914
|
+
event_uri: { type: "string" },
|
|
915
|
+
invitee_uri: { type: "string" },
|
|
916
|
+
event_id: { type: "string" },
|
|
917
|
+
calendar_id: { type: "string" }
|
|
918
|
+
}
|
|
919
|
+
}
|
|
920
|
+
},
|
|
921
|
+
description: "Booking result"
|
|
922
|
+
};
|
|
923
|
+
var BOOKING_OUTPUT_SCHEMA = {
|
|
924
|
+
...BOOKING_RESULT_SCHEMA,
|
|
925
|
+
required: ["node_type", ...BOOKING_RESULT_SCHEMA.required],
|
|
926
|
+
properties: {
|
|
927
|
+
node_type: { type: "string", const: "booking" },
|
|
928
|
+
...BOOKING_RESULT_SCHEMA.properties
|
|
929
|
+
}
|
|
930
|
+
};
|
|
884
931
|
var NODE_TYPES = {
|
|
885
932
|
start: {
|
|
886
933
|
label: "Start",
|
|
@@ -1231,70 +1278,57 @@ var NODE_TYPES = {
|
|
|
1231
1278
|
// Object granularity, not a dotted path (#4618): every property under
|
|
1232
1279
|
// these provider objects (scheduling_url, event_type_uri, calendar_id) is
|
|
1233
1280
|
// the source workspace's own calendar, so save_form strips the whole
|
|
1234
|
-
// object on cross-workspace copy.
|
|
1235
|
-
//
|
|
1236
|
-
//
|
|
1237
|
-
|
|
1238
|
-
//
|
|
1281
|
+
// object on cross-workspace copy. workspace_integration_id is the top-level
|
|
1282
|
+
// connected-account pointer (Payment's convention). `calcom` is a dead key
|
|
1283
|
+
// (Cal.com support was removed, #5311) kept on purpose: save_form is SQL and
|
|
1284
|
+
// owner-scoped-config-keys.test.js binds the union of flat keys to the latest
|
|
1285
|
+
// save_form migration's strip array, so dropping it would force a migration.
|
|
1286
|
+
owner_scoped_config_keys: ["workspace_integration_id", "calendly", "calcom", "google_meet"],
|
|
1287
|
+
// The viewer iframes calendly scheduling_url (Booking.tsx): an outbound embed.
|
|
1239
1288
|
// Unclaimed anonymous-MCP forms may not go live with this node (#4847).
|
|
1240
1289
|
blocked_for_anon_mcp: true,
|
|
1241
1290
|
default_config: null,
|
|
1242
1291
|
config_schema: {
|
|
1243
1292
|
type: "object",
|
|
1244
|
-
|
|
1245
|
-
{
|
|
1246
|
-
|
|
1293
|
+
properties: {
|
|
1294
|
+
provider: { type: "string", enum: BOOKING_PROVIDERS, label: "Provider", description: "Scheduling provider (one per node)" },
|
|
1295
|
+
workspace_integration_id: { type: "string", description: "Connected workspace integration (calendar account) this booking uses" },
|
|
1296
|
+
allow_skip: { type: "boolean", feature: "optional_questions", default: false, label: "Optional", description: "Let respondents continue without booking" },
|
|
1297
|
+
calendly: {
|
|
1298
|
+
type: "object",
|
|
1247
1299
|
properties: {
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
event_type_uri: { type: "string", label: "Event type URI", format: "uri", description: "Your Calendly event type URI", placeholder: "https://calendly.com/your-link" }
|
|
1253
|
-
}
|
|
1254
|
-
}
|
|
1300
|
+
event_type_uri: { type: "string", label: "Event type URI", description: "Your Calendly event type URI" },
|
|
1301
|
+
event_name: { type: "string", label: "Event name", description: "Display name for the event" },
|
|
1302
|
+
scheduling_url: { type: "string", label: "Scheduling URL", description: "Calendly scheduling link embedded in the form" },
|
|
1303
|
+
duration: { type: "number", label: "Duration (minutes)", description: "Event duration in minutes" }
|
|
1255
1304
|
}
|
|
1256
1305
|
},
|
|
1257
|
-
{
|
|
1258
|
-
|
|
1306
|
+
google_meet: {
|
|
1307
|
+
type: "object",
|
|
1308
|
+
feature: "integration_google_calendar",
|
|
1259
1309
|
properties: {
|
|
1260
|
-
|
|
1310
|
+
calendar_id: { type: "string", label: "Calendar", description: "Google Calendar to use for bookings" },
|
|
1311
|
+
calendar_name: { type: "string", label: "Calendar name", description: "Display name for the selected calendar" },
|
|
1312
|
+
duration: { type: "number", label: "Duration (minutes)", default: 30, description: "Meeting duration in minutes" },
|
|
1313
|
+
event_title: { type: "string", label: "Event title", default: "Meeting", description: "Default title for scheduled meetings" },
|
|
1314
|
+
availability: {
|
|
1261
1315
|
type: "object",
|
|
1262
1316
|
properties: {
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1317
|
+
timezone: { type: "string", description: "IANA timezone for the weekly hours" },
|
|
1318
|
+
// Keyed mon..sun; each value is an array of { start, end } 'HH:MM' strings.
|
|
1319
|
+
weekly_hours: { type: "object", description: "Bookable hours per weekday (mon..sun), each an array of { start, end } HH:MM ranges" },
|
|
1320
|
+
buffer_minutes: { type: "number", description: "Gap between bookings in minutes" },
|
|
1321
|
+
min_notice_minutes: { type: "number", description: "Minimum notice before a slot can be booked, in minutes" },
|
|
1322
|
+
days_ahead: { type: "number", description: "How many days ahead respondents can book" }
|
|
1267
1323
|
}
|
|
1268
1324
|
}
|
|
1269
1325
|
}
|
|
1270
1326
|
}
|
|
1271
|
-
|
|
1327
|
+
},
|
|
1272
1328
|
description: "Booking provider configuration (one provider per node)"
|
|
1273
1329
|
},
|
|
1274
|
-
response_schema:
|
|
1275
|
-
|
|
1276
|
-
oneOf: [
|
|
1277
|
-
{
|
|
1278
|
-
required: ["calendly"],
|
|
1279
|
-
properties: {
|
|
1280
|
-
calendly: {
|
|
1281
|
-
type: "object",
|
|
1282
|
-
required: ["event_uri", "scheduled_time"],
|
|
1283
|
-
properties: {
|
|
1284
|
-
event_uri: { type: "string", format: "uri" },
|
|
1285
|
-
event_type: { type: "string" },
|
|
1286
|
-
invitee_uri: { type: "string", format: "uri" },
|
|
1287
|
-
reschedule_url: { type: "string", format: "uri" },
|
|
1288
|
-
scheduled_time: { type: "string", format: "date-time" },
|
|
1289
|
-
cancellation_url: { type: "string", format: "uri" }
|
|
1290
|
-
}
|
|
1291
|
-
}
|
|
1292
|
-
}
|
|
1293
|
-
}
|
|
1294
|
-
],
|
|
1295
|
-
description: "Booking response with provider-specific data"
|
|
1296
|
-
},
|
|
1297
|
-
output_schema: null
|
|
1330
|
+
response_schema: BOOKING_RESULT_SCHEMA,
|
|
1331
|
+
output_schema: BOOKING_OUTPUT_SCHEMA
|
|
1298
1332
|
},
|
|
1299
1333
|
details: {
|
|
1300
1334
|
label: "Details",
|
|
@@ -3634,4 +3668,4 @@ export {
|
|
|
3634
3668
|
textResult,
|
|
3635
3669
|
structuredResult
|
|
3636
3670
|
};
|
|
3637
|
-
//# sourceMappingURL=chunk-
|
|
3671
|
+
//# sourceMappingURL=chunk-URQXLZEB.js.map
|