create-ailk 0.25.1 → 0.27.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.
Files changed (75) hide show
  1. package/README.md +14 -5
  2. package/dist/lib/fetch-template-snapshot.d.ts +2 -1
  3. package/dist/lib/fetch-template-snapshot.js +6 -5
  4. package/dist/lib/module-license-gate.js +2 -3
  5. package/dist/lib/module-tier.d.ts +2 -8
  6. package/dist/lib/module-tier.js +13 -12
  7. package/dist/module-architecture.js +14 -2
  8. package/dist/starter-grid.d.ts +6 -6
  9. package/dist/starter-grid.js +12 -5
  10. package/dist/surfaces.js +36 -2
  11. package/dist/template-record.d.ts +11 -3
  12. package/dist/template-record.js +20 -7
  13. package/dist/topology.js +23 -4
  14. package/dist/update.d.ts +1 -1
  15. package/dist/update.js +240 -20
  16. package/package.json +3 -3
  17. package/release-scope.json +1 -1
  18. package/site-templates/marketing-site/TEMPLATE-MANIFEST.json +8 -2
  19. package/site-templates/marketing-site/TEMPLATE-MANIFEST.md +2 -2
  20. package/site-templates/marketing-site/ailk-template.json +7 -1
  21. package/site-templates/marketing-site/provenance.json +7 -1
  22. package/site-templates/saas-product/ailk-template.json +2 -1
  23. package/site-templates/saas-product/provenance.json +1 -0
  24. package/templates/.env.example +22 -0
  25. package/templates/CLAUDE.md +20 -20
  26. package/templates/README.md +19 -19
  27. package/templates/apps/api/.env.example +28 -0
  28. package/templates/apps/api/CLAUDE.md +35 -9
  29. package/templates/apps/api/src/lib/__mocks__/prisma-client.js +16 -0
  30. package/templates/apps/api/vercel.json +7 -1
  31. package/templates/apps/mcp/CLAUDE.md +27 -10
  32. package/templates/apps/web/.env.example +13 -0
  33. package/templates/apps/web/CLAUDE.md +34 -6
  34. package/templates/apps/web/app/[locale]/(auth)/__tests__/auth-pages.test.tsx +43 -4
  35. package/templates/apps/web/app/[locale]/(auth)/legal-footnote.tsx +35 -0
  36. package/templates/apps/web/app/[locale]/(auth)/sign-in/__tests__/next-path.test.ts +24 -1
  37. package/templates/apps/web/app/[locale]/(auth)/sign-in/__tests__/page.test.tsx +168 -8
  38. package/templates/apps/web/app/[locale]/(auth)/sign-in/next-path.ts +13 -0
  39. package/templates/apps/web/app/[locale]/(auth)/sign-in/page.tsx +22 -39
  40. package/templates/apps/web/app/[locale]/(auth)/sign-in/sign-in-card.tsx +6 -6
  41. package/templates/apps/web/app/[locale]/(auth)/sign-in/sign-in-text.ts +20 -35
  42. package/templates/apps/web/app/[locale]/(auth)/sign-up/__tests__/page.test.tsx +301 -0
  43. package/templates/apps/web/app/[locale]/(auth)/sign-up/__tests__/sign-up-card.test.tsx +111 -5
  44. package/templates/apps/web/app/[locale]/(auth)/sign-up/page.tsx +96 -18
  45. package/templates/apps/web/app/[locale]/(auth)/sign-up/sign-up-card.tsx +132 -12
  46. package/templates/apps/web/app/[locale]/(authed)/__tests__/gate.test.tsx +53 -1
  47. package/templates/apps/web/app/[locale]/(authed)/account/__tests__/billing.test.tsx +38 -0
  48. package/templates/apps/web/app/[locale]/(authed)/account/billing/page.tsx +4 -2
  49. package/templates/apps/web/app/[locale]/(authed)/sign-in-gate.tsx +47 -24
  50. package/templates/apps/web/app/[locale]/(authed)/signed-out-gate.generated.tsx +23 -4
  51. package/templates/apps/web/app/[locale]/layout.tsx +48 -13
  52. package/templates/apps/web/app/[locale]/meet/confirmed/BookingHandOff.tsx +128 -0
  53. package/templates/apps/web/app/[locale]/meet/confirmed/__tests__/BookingHandOff.test.tsx +126 -0
  54. package/templates/apps/web/app/api/auth/hub/authorize/__tests__/route.test.ts +118 -0
  55. package/templates/apps/web/app/api/auth/hub/authorize/route.ts +14 -0
  56. package/templates/apps/web/app/api/hub-session/__tests__/routes.test.ts +51 -0
  57. package/templates/apps/web/app/api/hub-session/sign-in/route.ts +13 -0
  58. package/templates/apps/web/auth.ts +8 -4
  59. package/templates/apps/web/i18n/request.ts +49 -1
  60. package/templates/apps/web/lib/__tests__/account-config.test.ts +7 -0
  61. package/templates/apps/web/lib/__tests__/auth-email.test.ts +276 -0
  62. package/templates/apps/web/lib/__tests__/relay.test.ts +289 -1
  63. package/templates/apps/web/lib/auth-email.ts +102 -20
  64. package/templates/apps/web/lib/hub-session/__tests__/sign-in-gate.test.tsx +92 -23
  65. package/templates/apps/web/lib/hub-session/sign-in-gate.tsx +97 -70
  66. package/templates/apps/web/lib/prisma-for-auth.ts +5 -2
  67. package/templates/apps/web/lib/relay.ts +116 -1
  68. package/templates/apps/web/lib/sign-up-agreements.ts +302 -28
  69. package/templates/apps/web/lib/site-contributions.ts +18 -0
  70. package/templates/apps/web/messages/en.json +271 -20
  71. package/templates/apps/web/messages/site/en.json +1 -0
  72. package/templates/apps/web/middleware.ts +8 -1
  73. package/templates/apps/web/next.config.mjs +9 -1
  74. package/templates/apps/web/package.json +2 -1
  75. package/versions.json +48 -48
@@ -56,10 +56,10 @@
56
56
  "backToTop": "Back to top"
57
57
  },
58
58
  "consent": {
59
- "title": "Cookie Preferences",
60
- "acceptLabel": "Accept",
61
- "rejectLabel": "Reject",
62
- "policyLinkLabel": "Privacy policy",
59
+ "title": "Would You Like A Cookie? 🍪",
60
+ "acceptLabel": "Accept All",
61
+ "rejectLabel": "Decline All",
62
+ "policyLinkLabel": "Privacy Policy",
63
63
  "dismissLabel": "Close",
64
64
  "settingsLabel": "Cookie Settings"
65
65
  },
@@ -385,7 +385,10 @@
385
385
  "ctaHeadline": "While you wait",
386
386
  "ctaDescription": "Have a look around, or get in touch if something comes up before we speak.",
387
387
  "ctaPrimaryLabel": "Back to the site",
388
- "ctaSecondaryLabel": "Contact us"
388
+ "ctaSecondaryLabel": "Contact us",
389
+ "bookedTimeHeading": "Your call",
390
+ "slackHeadline": "Your Slack channel",
391
+ "slackBody": "Slack will email you an invitation to a private channel with us. Accept it to talk before the call. If you don't use Slack yet, the email walks you through a free account and workspace."
389
392
  }
390
393
  },
391
394
  "services": {
@@ -551,19 +554,19 @@
551
554
  "signIn": {
552
555
  "title": "Sign in",
553
556
  "description": "Sign in to your account.",
554
- "heading": "Welcome back",
557
+ "heading": "Sign in to {site}",
555
558
  "notConfiguredSubhead": "Sign-in is not configured for this site yet. Set a provider's environment variables to enable it.",
556
559
  "ssoPrefix": "Sign in with",
557
560
  "google": "Google",
558
561
  "github": "GitHub",
559
- "email": "Email address",
562
+ "email": "Email",
560
563
  "password": "Password",
561
564
  "forgot": "Forgot password?",
562
565
  "submit": "Sign in",
563
566
  "orContinue": "Or continue with",
564
567
  "signInFailed": "We couldn't sign you in. Check your details and try again.",
565
568
  "providerFailed": "We couldn't start sign-in with that provider. Try again.",
566
- "emailLinkSubmit": "Email me a sign-in link",
569
+ "emailLinkSubmit": "Send me a magic link",
567
570
  "emailLinkDivider": "or",
568
571
  "emailLinkSentHeading": "Check your email",
569
572
  "emailLinkSentSubhead": "Look for a message from this site.",
@@ -575,10 +578,13 @@
575
578
  "useEmailLink": "Email me a sign-in link instead",
576
579
  "emailPlaceholder": "you@example.com",
577
580
  "backTo": "Back to {site}",
578
- "acknowledgement": "You acknowledge that you read and agree to our",
581
+ "acknowledgement": "You acknowledge that you read, and agree to our",
579
582
  "termsLink": "Terms of Service",
580
583
  "privacyLink": "Privacy Policy",
581
- "workingAgreementLink": "Working Agreement"
584
+ "acknowledgementAnd": "and our",
585
+ "acknowledgementEnd": ".",
586
+ "prospectPrompt": "Don't have an account?",
587
+ "prospectLink": "Sign up"
582
588
  },
583
589
  "auth": {
584
590
  "signUpTitle": "Create an account",
@@ -589,17 +595,16 @@
589
595
  "resetDescription": "Set a new password for your account.",
590
596
  "verifyEmailTitle": "Check your email",
591
597
  "verifyEmailDescription": "Follow the link we sent to continue.",
592
- "email": "Email address",
598
+ "email": "Email",
593
599
  "password": "Password",
594
600
  "confirmPassword": "Confirm password",
595
601
  "newPassword": "New password",
596
- "orContinue": "Or continue with",
602
+ "orContinue": "or",
597
603
  "ssoPrefix": "Continue with",
598
604
  "google": "Google",
599
605
  "github": "GitHub",
600
606
  "backToSignIn": "Back to sign in",
601
- "signUpHeading": "Create your account",
602
- "signUpSubhead": "Enter your details to get started.",
607
+ "signUpHeading": "Sign up",
603
608
  "signUpSubmit": "Create account",
604
609
  "signUpFooterPrompt": "Already have an account?",
605
610
  "signUpFooterLink": "Sign in",
@@ -607,10 +612,14 @@
607
612
  "signUpAgreementsRequired": "Accept the agreements to create an account.",
608
613
  "signUpNotConfiguredSubhead": "Sign-up is not configured for this site yet. Set a provider's environment variables to enable it.",
609
614
  "signUpFailed": "We couldn't create your account. Check your details and try again.",
615
+ "magicLinkSubmit": "Send me a magic link",
616
+ "signUpLinkSentBody": "A link to finish signing up is on its way. It works once and expires in 5 minutes.",
617
+ "signUpLinkBack": "Back to sign up",
618
+ "signUpLinkFailed": "We couldn't send a sign-up link. Try again.",
619
+ "signUpLinkRateLimited": "Too many requests. Wait a minute, then try again.",
620
+ "signUpLinkExpired": "That sign-up link has expired or was already used. Request a new one.",
610
621
  "providerFailed": "We couldn't start sign-up with that provider. Try again.",
611
- "invitationHeading": "Accounts are by invitation",
612
- "invitationSubhead": "This site does not offer public sign-up.",
613
- "invitationBody": "If you were invited, open the link in your invitation email to create your account.",
622
+ "invitationBody": "This site does not offer public sign-up. If you were invited, open the link in your invitation email to create your account.",
614
623
  "forgotHeading": "Reset your password",
615
624
  "forgotSubhead": "Enter your email and we will send a reset link.",
616
625
  "forgotSubmit": "Send reset link",
@@ -921,7 +930,7 @@
921
930
  "emptyDescription": "This site hasn't turned on sign-in for members yet. Check back soon, or contact the site owner.",
922
931
  "signInLink": "Go to the sign-in page",
923
932
  "homeLink": "Back to the site",
924
- "hubHeadline": "Sign in to your account",
933
+ "hubHeadline": "Sign in to {site}",
925
934
  "hubDescription": "You sign in on our main site, then come straight back here.",
926
935
  "hubSignIn": "Sign in",
927
936
  "title": "Sign in"
@@ -1042,12 +1051,15 @@
1042
1051
  },
1043
1052
  "admin": {
1044
1053
  "title": "Workspace settings",
1045
- "description": "Your workspace name, site settings, and team.",
1054
+ "description": "Your workspace name, site settings, team, flows and meeting types.",
1046
1055
  "nav": {
1047
1056
  "account": "Account",
1048
1057
  "general": "General",
1049
1058
  "site": "Site",
1050
- "team": "Team"
1059
+ "team": "Team",
1060
+ "magnets": "Magnets",
1061
+ "meetings": "Meetings",
1062
+ "integrations": "Integrations"
1051
1063
  },
1052
1064
  "general": {
1053
1065
  "heading": "General",
@@ -1084,6 +1096,245 @@
1084
1096
  "role": "Role",
1085
1097
  "emptyHeadline": "No members yet",
1086
1098
  "emptyDescription": "People with access to this workspace will appear here."
1099
+ },
1100
+ "magnets": {
1101
+ "heading": "Magnets",
1102
+ "lead": "Forms and lists that turn visitors into leads.",
1103
+ "unavailableHeadline": "Magnets aren't part of this site",
1104
+ "unavailableDescription": "This site was set up without flows, so there is nothing to manage here.",
1105
+ "newLabel": "New magnet",
1106
+ "newMenu": {
1107
+ "diagnostic": "New diagnostic",
1108
+ "waitlist": "New waitlist",
1109
+ "contact": "New contact",
1110
+ "newsletter": "New newsletter"
1111
+ },
1112
+ "kindLabels": {
1113
+ "specialReport": "Special report",
1114
+ "diagnostic": "Diagnostic",
1115
+ "listicle": "Listicle",
1116
+ "waitlist": "Waitlist",
1117
+ "contact": "Contact",
1118
+ "newsletter": "Newsletter"
1119
+ },
1120
+ "liveAriaLabel": "{title} live",
1121
+ "liveError": "Couldn't update. Try again.",
1122
+ "emptyHeadline": "No magnets yet",
1123
+ "emptyDescription": "Create a flow from the buttons above.",
1124
+ "wizard": {
1125
+ "pageTitle": {
1126
+ "diagnostic": "New diagnostic",
1127
+ "waitlist": "New waitlist",
1128
+ "contact": "New contact",
1129
+ "newsletter": "New newsletter"
1130
+ },
1131
+ "pageLead": {
1132
+ "diagnostic": "Ask a few questions, then recommend what to do next.",
1133
+ "waitlist": "Collect interest from people before you're ready to launch.",
1134
+ "contact": "Collect a short message from visitors who want to get in touch.",
1135
+ "newsletter": "Collect email addresses for your newsletter."
1136
+ },
1137
+ "backLabel": "Back",
1138
+ "continueLabel": "Continue",
1139
+ "createDraftLabel": "Create draft",
1140
+ "draftNote": "Starts as a draft. Switch it on from Magnets.",
1141
+ "landingPageNone": "None",
1142
+ "emptyValue": "—",
1143
+ "genericError": "Something went wrong. Please try again.",
1144
+ "choiceOptions": {
1145
+ "listLabel": "Choices",
1146
+ "choiceLabel": "Choice {n}",
1147
+ "valueLabel": "Choice {n} value",
1148
+ "pointsLabel": "Choice {n} points",
1149
+ "pointsHeading": "Points",
1150
+ "pointsHelp": "Optional. A visitor's total adds the points of every choice they pick.",
1151
+ "addChoice": "Add a choice",
1152
+ "removeChoice": "Remove choice {n}",
1153
+ "moveUp": "Move choice {n} up",
1154
+ "moveDown": "Move choice {n} down"
1155
+ },
1156
+ "flow": {
1157
+ "titleLabel": "Title",
1158
+ "slugLabel": "Slug",
1159
+ "slugHelpText": "Used in the flow's URL. Auto-fills from the title.",
1160
+ "landingPageLabel": "Landing page",
1161
+ "questionsSortableLabel": "Questions",
1162
+ "promptLabel": "Prompt",
1163
+ "answerTypeLabel": "Answer type",
1164
+ "optionsLabel": "Options",
1165
+ "optionsHelpText": "One per line.",
1166
+ "requiredLabel": "Required",
1167
+ "answerTypeOptionLabels": {
1168
+ "text": "Text",
1169
+ "email": "Email",
1170
+ "url": "URL",
1171
+ "single": "One choice",
1172
+ "multi": "Several choices"
1173
+ },
1174
+ "addQuestionLabel": "Add question",
1175
+ "removeQuestionLabel": "Remove question",
1176
+ "questionFallbackLabel": "Question",
1177
+ "recommendationsSortableLabel": "Recommendations",
1178
+ "offerNameLabel": "Offer",
1179
+ "offerPriceLabel": "Price",
1180
+ "offerQuestionLabel": "Recommend when",
1181
+ "offerOptionLabel": "Is",
1182
+ "offerReasonLabel": "Because",
1183
+ "addRecommendationLabel": "Add recommendation",
1184
+ "removeRecommendationLabel": "Remove recommendation",
1185
+ "recommendationFallbackLabel": "Recommendation",
1186
+ "offerNoQuestionsOption": "Add a single- or multiple-choice question first",
1187
+ "offerTriggerLabel": "Recommend when",
1188
+ "offerTriggerAnswer": "An answer is given",
1189
+ "offerTriggerThreshold": "Total points are at least",
1190
+ "offerThresholdLabel": "Points",
1191
+ "deliverableLabel": "Deliverable",
1192
+ "deliverableHelpText": "What people get when they finish this flow, if anything.",
1193
+ "emailSubjectLabel": "Email subject",
1194
+ "emailBodyLabel": "Email body",
1195
+ "emailCtaLabel": "Email button text",
1196
+ "flowUrlLabel": "Flow URL",
1197
+ "validation": {
1198
+ "titleRequired": "Enter a title.",
1199
+ "titleTooLong": "Title is too long.",
1200
+ "slugInvalid": "Enter a valid slug.",
1201
+ "questionsRequired": "Add at least one question.",
1202
+ "promptRequired": "Every question needs a prompt.",
1203
+ "optionsRequired": "Add at least one option.",
1204
+ "optionTooLong": "An option is too long.",
1205
+ "offerFieldsRequired": "Fill in Name, Price, and Because for every recommendation.",
1206
+ "offerQuestionRequired": "Choose a question for every recommendation.",
1207
+ "offerOptionRequired": "Choose a valid answer for every recommendation.",
1208
+ "pointsNeedRecommendation": "Points need at least one recommendation.",
1209
+ "thresholdNeedsPoints": "A points threshold needs at least one choice with points.",
1210
+ "completionEmailRequired": "Add an email subject and body, or clear the Deliverable field.",
1211
+ "recommendationsRequired": "Add at least one recommendation.",
1212
+ "offeringRequired": "Choose a price for every recommendation.",
1213
+ "offerReasonRequired": "Fill in Because for every recommendation."
1214
+ }
1215
+ }
1216
+ }
1217
+ },
1218
+ "meetings": {
1219
+ "heading": "Meetings",
1220
+ "lead": "Meeting types visitors can book from your site.",
1221
+ "unavailableHeadline": "Meetings aren't part of this site",
1222
+ "unavailableDescription": "This site was set up without scheduling, so there is nothing to manage here.",
1223
+ "emptyHeadline": "No meeting types yet",
1224
+ "emptyDescription": "Meeting types are pulled from Cal.com, off by default. Turning one on gives it a /meet page.",
1225
+ "unconfiguredHeadline": "Scheduling isn't connected yet",
1226
+ "unconfiguredDescription": "Connect a Cal.com account to list your meeting types here.",
1227
+ "durationMinutesLabel": "{n} min",
1228
+ "liveAriaLabel": "{title} live",
1229
+ "liveError": "Couldn't update. Try again.",
1230
+ "detail": {
1231
+ "backLabel": "Meetings",
1232
+ "captionUnit": "Meeting",
1233
+ "statusLive": "Live",
1234
+ "statusOff": "Off",
1235
+ "customersSwitchLabel": "Members only",
1236
+ "customersAriaLabel": "{title}: members only",
1237
+ "membersOnlyHint": "Signed-in members can use this. A live item stays public.",
1238
+ "privateSwitchLabel": "Private",
1239
+ "privateAriaLabel": "{title}: private",
1240
+ "privateHint": "Listed on /private instead of /meet. Anyone with the link can still book.",
1241
+ "roleNote": "Only an owner or admin can manage meeting types.",
1242
+ "fromProviderHeading": "From Cal.com",
1243
+ "durationLabel": "Duration",
1244
+ "priceLabel": "Price",
1245
+ "linkLabel": "Link",
1246
+ "timeZoneLabel": "Time zone",
1247
+ "priceFree": "Free",
1248
+ "customersOnToast": "Members only: on for {title}",
1249
+ "customersOffToast": "Members only: off for {title}",
1250
+ "privateOnToast": "Private: on for {title}",
1251
+ "privateOffToast": "Private: off for {title}",
1252
+ "errorToast": "Couldn't update"
1253
+ }
1254
+ },
1255
+ "integrations": {
1256
+ "heading": "Integrations",
1257
+ "lead": "Connect the services your site works with.",
1258
+ "slack": {
1259
+ "title": "Slack",
1260
+ "credentialsHeading": "App credentials",
1261
+ "connectedBadge": "Connected",
1262
+ "notConnectedBadge": "Not connected",
1263
+ "lead": "Connect your Slack app so each booked prospect gets a shared channel.",
1264
+ "botTokenLabel": "Bot token",
1265
+ "signingSecretLabel": "Signing secret",
1266
+ "botTokenInvalid": "A bot token starts with xoxb- and holds only letters, digits and hyphens.",
1267
+ "signingSecretInvalid": "A signing secret is 32 to 128 letters and digits.",
1268
+ "scopesLead": "The Slack app needs these bot scopes:",
1269
+ "connect": "Connect Slack",
1270
+ "connecting": "Connecting…",
1271
+ "cancel": "Cancel",
1272
+ "replace": "Replace",
1273
+ "disconnect": "Disconnect",
1274
+ "workspaceName": "Slack workspace",
1275
+ "connectedOn": "Connected",
1276
+ "ownerOnly": "Only the site's owner can change the Slack connection.",
1277
+ "askOwner": "Slack isn't connected. Ask the site's owner to connect it.",
1278
+ "unavailable": "The Slack connection couldn't be read. Try again later.",
1279
+ "tokenRefused": {
1280
+ "tokenRefused": "Slack refused this token. Check it and try again.",
1281
+ "notBotToken": "This isn't a bot token. Copy the Bot User OAuth Token (xoxb-).",
1282
+ "enterpriseInstall": "Enterprise Grid installs aren't supported yet."
1283
+ },
1284
+ "scopesMissing": "The Slack app is missing these scopes:",
1285
+ "paidPlanRequired": "Slack Connect needs a paid Slack plan.",
1286
+ "teamConnectedElsewhere": "This Slack workspace is already connected to another site.",
1287
+ "slackUnreachable": "Slack couldn't be reached. Try again in a moment.",
1288
+ "connectFailed": "Couldn't connect Slack. Try again.",
1289
+ "disconnectFailed": "Couldn't disconnect Slack. Try again.",
1290
+ "confirmReplace": {
1291
+ "title": "Replace the Slack connection?",
1292
+ "description": "Prospect channels will open in the new Slack workspace.",
1293
+ "action": "Replace"
1294
+ },
1295
+ "confirmDisconnect": {
1296
+ "title": "Disconnect Slack?",
1297
+ "description": "New bookings will stop opening prospect channels until Slack is connected again.",
1298
+ "action": "Disconnect"
1299
+ }
1300
+ },
1301
+ "prospectChannel": {
1302
+ "heading": "Prospect channels",
1303
+ "lead": "Open a shared Slack channel with each prospect who books a meeting.",
1304
+ "enabled": "Open a channel for each booking",
1305
+ "members": "Members",
1306
+ "ownerAlwaysInvited": "The site's owner is always invited. Add anyone else by Slack member id.",
1307
+ "addMemberLabel": "Slack member id",
1308
+ "addMember": "Add",
1309
+ "removeMember": "Remove {memberId}",
1310
+ "welcomeTemplate": "Welcome message",
1311
+ "welcomeDefaultNote": "Leave blank to send the default welcome.",
1312
+ "mergeFieldsHeading": "Merge fields",
1313
+ "mergeFields": {
1314
+ "firstName": "The prospect's first name",
1315
+ "hostName": "The host's name",
1316
+ "callTime": "The meeting's time",
1317
+ "interest": "What the prospect is interested in",
1318
+ "timeline": "The prospect's timeline",
1319
+ "meetingLink": "The meeting link"
1320
+ },
1321
+ "channelPrefix": "Channel name prefix",
1322
+ "archiveDays": "Archive after (days)",
1323
+ "save": "Save",
1324
+ "saving": "Saving…",
1325
+ "saved": "Saved",
1326
+ "saveError": "Couldn't save. Try again.",
1327
+ "slackNotConnected": "Slack isn't connected, so these settings can't be changed.",
1328
+ "connectSlackLink": "Connect Slack",
1329
+ "errors": {
1330
+ "memberIds": "Enter a new Slack member id, like U012AB3CD (up to 50).",
1331
+ "welcomeTemplate": "Use only the merge fields listed, in up to 4,000 characters.",
1332
+ "channelPrefix": "Use lowercase letters, digits, - and _, starting with a letter or digit (up to 21).",
1333
+ "archiveDays": "Enter a whole number of days from 1 to 365."
1334
+ },
1335
+ "unavailableHeadline": "Prospect channel settings couldn't be read",
1336
+ "unavailableDescription": "Reload the page to try again, or come back later."
1337
+ }
1087
1338
  }
1088
1339
  },
1089
1340
  "edit": {
@@ -118,6 +118,13 @@ export function middleware(request: NextRequest): NextResponse {
118
118
  // og-default.png — and each 404'd (#4090 item 4). robots.txt and sitemap.xml are
119
119
  // route handlers rather than public/ files, but they carry extensions too and
120
120
  // are equally not locale-scoped, so the same rule covers them.
121
+ //
122
+ // BotID's proxy prefix (`withBotId`, `botid/next/config`, #9889 D7) is
123
+ // excluded too, exactly that two-segment prefix and nothing wider, so
124
+ // next-intl never rewrites it and the security headers never stamp
125
+ // `frame-ancestors 'none'` on it; `withBotId` sets that prefix's own
126
+ // `X-Frame-Options: SAMEORIGIN` and `frame-ancestors 'self'`.
121
127
  export const config = {
122
- matcher: "/((?!_next/static|_next/image|_next/server|.*\\..*).*)",
128
+ matcher:
129
+ "/((?!_next/static|_next/image|_next/server|149e9513-01fa-4fb0-aad4-566afd725d1b/2d206a39-8ed7-437e-a3be-862e0f06eea3/|.*\\..*).*)",
123
130
  };
@@ -6,6 +6,7 @@ import { withSentryConfig } from "@sentry/nextjs";
6
6
  import createNextIntlPlugin from "next-intl/plugin";
7
7
  import { legacyRedirects } from "@working-theory/templates/routes";
8
8
  import { parseStealth } from "@working-theory/web-i18n/stealth";
9
+ import { withBotId } from "botid/next/config";
9
10
 
10
11
  // @next/bundle-analyzer — enabled when ANALYZE=true (set by ci-bundle.yml).
11
12
  // analyzerMode 'json' writes .next/analyze/client.json (and nodejs.json,
@@ -197,7 +198,14 @@ const sentryBuildOptions = {
197
198
  : {}),
198
199
  };
199
200
 
201
+ // #9889 D6 — `withBotId` adds BotID's two rewrites (the challenge script and
202
+ // its proxy) and one header rule on its own proxy prefix, which middleware.ts
203
+ // keeps out of its matcher. It is not gated on `AILK_BOOKING_BOT_CHECK`: this
204
+ // config is read at build time, the switch at run time, and an unused rewrite
205
+ // answers nothing. It sits directly inside Sentry so the substrings
206
+ // (the MDX wrap and the next-intl wrap, quoted nowhere else) that create-ailk
207
+ // edits stay intact.
200
208
  export default withSentryConfig(
201
- withBundleAnalyzer(withNextIntl(nextConfig)),
209
+ withBotId(withBundleAnalyzer(withNextIntl(nextConfig))),
202
210
  sentryBuildOptions,
203
211
  );
@@ -37,8 +37,9 @@
37
37
  "@working-theory/validation": "workspace:*",
38
38
  "@working-theory/web-i18n": "workspace:*",
39
39
  "better-auth": "1.6.22",
40
+ "botid": "1.5.11",
40
41
  "lucide-react": "^0.577.0",
41
- "next": "^16.3.8",
42
+ "next": "^16.4.3",
42
43
  "next-intl": "^3.26.3",
43
44
  "next-mdx-remote": "^6.0.0",
44
45
  "pg": "^8.22.0",
package/versions.json CHANGED
@@ -1,66 +1,66 @@
1
1
  {
2
- "@working-theory/admin-ui": "0.46.0",
3
- "@working-theory/aeo": "0.46.0",
4
- "@working-theory/agent-context": "0.46.0",
2
+ "@working-theory/admin-ui": "0.49.0",
3
+ "@working-theory/aeo": "0.49.0",
4
+ "@working-theory/agent-context": "0.49.0",
5
5
  "@working-theory/agent-contract": "0.1.0",
6
6
  "@working-theory/agent-memory": "0.0.0",
7
7
  "@working-theory/ai": "0.1.0",
8
- "@working-theory/analytics": "0.46.0",
9
- "@working-theory/api": "0.46.0",
10
- "@working-theory/api-client": "0.46.0",
8
+ "@working-theory/analytics": "0.49.0",
9
+ "@working-theory/api": "0.49.0",
10
+ "@working-theory/api-client": "0.49.0",
11
11
  "@working-theory/cda-filesystem": "0.0.0",
12
- "@working-theory/cli": "0.46.0",
13
- "@working-theory/common": "0.46.0",
12
+ "@working-theory/cli": "0.49.0",
13
+ "@working-theory/common": "0.49.0",
14
14
  "@working-theory/consent": "0.1.0",
15
- "@working-theory/content-adapters": "0.46.0",
16
- "@working-theory/content-projection": "0.46.0",
17
- "@working-theory/email": "0.46.0",
15
+ "@working-theory/content-adapters": "0.49.0",
16
+ "@working-theory/content-projection": "0.49.0",
17
+ "@working-theory/email": "0.49.0",
18
18
  "@working-theory/env": "0.0.0",
19
- "@working-theory/eslint-config": "0.46.0",
20
- "@working-theory/fumadocs-schema": "0.46.0",
21
- "@working-theory/ids": "0.15.0",
22
- "@working-theory/jsonld": "0.46.0",
23
- "@working-theory/license": "0.46.0",
24
- "@working-theory/mcp-server": "0.46.0",
25
- "@working-theory/metadata": "0.46.0",
26
- "@working-theory/observability": "0.46.0",
27
- "@working-theory/page-renderer": "0.46.0",
19
+ "@working-theory/eslint-config": "0.49.0",
20
+ "@working-theory/fumadocs-schema": "0.49.0",
21
+ "@working-theory/ids": "0.16.0",
22
+ "@working-theory/jsonld": "0.49.0",
23
+ "@working-theory/license": "0.49.0",
24
+ "@working-theory/mcp-server": "0.49.0",
25
+ "@working-theory/metadata": "0.49.0",
26
+ "@working-theory/observability": "0.49.0",
27
+ "@working-theory/page-renderer": "0.49.0",
28
28
  "@working-theory/plugin-mcp": "0.1.3",
29
- "@working-theory/schema": "0.46.0",
30
- "@working-theory/schema-pack-registry": "0.46.0",
31
- "@working-theory/schema-validator": "0.46.0",
32
- "@working-theory/sections-registry": "0.46.0",
33
- "@working-theory/site-config": "0.46.0",
34
- "@working-theory/spoke-checkout": "0.7.2",
35
- "@working-theory/stripe-client": "0.46.0",
36
- "@working-theory/templates": "0.46.0",
37
- "@working-theory/theme": "0.46.0",
38
- "@working-theory/ui": "0.46.0",
39
- "@working-theory/validation": "0.46.0",
40
- "@working-theory/web-i18n": "0.46.0",
41
- "@working-theory/admin": "0.3.0",
42
- "@working-theory/api-commerce": "0.1.0",
43
- "@working-theory/api-content-write": "0.1.0",
44
- "@working-theory/api-hub": "0.1.0",
45
- "@working-theory/api-multi-tenant": "0.1.0",
46
- "@working-theory/api-scheduling": "0.1.0",
47
- "@working-theory/api-signal-collectors": "0.1.0",
48
- "@working-theory/api-workspace": "0.1.0",
29
+ "@working-theory/schema": "0.49.0",
30
+ "@working-theory/schema-pack-registry": "0.49.0",
31
+ "@working-theory/schema-validator": "0.49.0",
32
+ "@working-theory/sections-registry": "0.49.0",
33
+ "@working-theory/site-config": "0.49.0",
34
+ "@working-theory/spoke-checkout": "0.7.5",
35
+ "@working-theory/stripe-client": "0.49.0",
36
+ "@working-theory/templates": "0.49.0",
37
+ "@working-theory/theme": "0.49.0",
38
+ "@working-theory/ui": "0.49.0",
39
+ "@working-theory/validation": "0.49.0",
40
+ "@working-theory/web-i18n": "0.49.0",
41
+ "@working-theory/admin": "0.6.0",
42
+ "@working-theory/api-commerce": "0.1.3",
43
+ "@working-theory/api-content-write": "0.1.3",
44
+ "@working-theory/api-hub": "0.3.0",
45
+ "@working-theory/api-multi-tenant": "0.1.3",
46
+ "@working-theory/api-scheduling": "0.4.0",
47
+ "@working-theory/api-signal-collectors": "0.2.2",
48
+ "@working-theory/api-workspace": "0.2.2",
49
49
  "@working-theory/billing-client": "0.0.0",
50
50
  "@working-theory/branding": "0.0.0",
51
51
  "@working-theory/license-client": "0.0.0",
52
52
  "@working-theory/license-manifest": "0.0.0",
53
- "@working-theory/mcp-scheduling": "0.2.0",
54
- "@working-theory/mcp-signal-collectors": "0.2.0",
55
- "@working-theory/mcp-workspace": "0.2.0",
53
+ "@working-theory/mcp-scheduling": "0.3.2",
54
+ "@working-theory/mcp-signal-collectors": "0.2.3",
55
+ "@working-theory/mcp-workspace": "0.3.2",
56
56
  "@working-theory/partner-session": "0.0.0",
57
57
  "@working-theory/preview-protocol": "0.0.0",
58
- "@working-theory/ui-commerce": "0.23.24",
59
- "@working-theory/ui-docs-blog": "0.23.24",
60
- "@working-theory/ui-scheduling": "0.24.4",
61
- "@working-theory/ui-signal-collectors": "0.27.2",
58
+ "@working-theory/ui-commerce": "0.23.27",
59
+ "@working-theory/ui-docs-blog": "0.23.27",
60
+ "@working-theory/ui-scheduling": "0.25.1",
61
+ "@working-theory/ui-signal-collectors": "0.27.5",
62
62
  "@working-theory/web": "0.0.0",
63
63
  "@working-theory/app-api": "1.0.0",
64
64
  "@working-theory/mcp": "0.0.0",
65
- "@working-theory/database": "0.46.0"
65
+ "@working-theory/database": "0.49.0"
66
66
  }