@contractspec/bundle.marketing 3.7.6 → 3.7.7

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 (163) hide show
  1. package/.turbo/turbo-build.log +84 -84
  2. package/AGENTS.md +29 -21
  3. package/README.md +36 -49
  4. package/dist/browser/components/marketing/ChangelogPage.js +8 -8
  5. package/dist/browser/components/marketing/CofounderPage.js +167 -523
  6. package/dist/browser/components/marketing/ContactClient.js +200 -207
  7. package/dist/browser/components/marketing/ContributePage.js +211 -463
  8. package/dist/browser/components/marketing/DesignPartnerPage.js +165 -218
  9. package/dist/browser/components/marketing/LandingPage.js +464 -568
  10. package/dist/browser/components/marketing/PricingClient.js +213 -839
  11. package/dist/browser/components/marketing/ProductClientPage.js +265 -463
  12. package/dist/browser/components/marketing/index.js +2007 -3338
  13. package/dist/browser/components/marketing/pricing-thinking-modal.js +12 -12
  14. package/dist/browser/components/marketing/sections/AudienceSection.js +2 -2
  15. package/dist/browser/components/marketing/sections/CorePositioningSection.js +2 -2
  16. package/dist/browser/components/marketing/sections/CtaSection.js +3 -3
  17. package/dist/browser/components/marketing/sections/FearsSection.js +3 -3
  18. package/dist/browser/components/marketing/sections/HeroMarketingSection.js +6 -6
  19. package/dist/browser/components/marketing/sections/IconGridSection.js +2 -2
  20. package/dist/browser/components/marketing/sections/OutputsSection.js +2 -2
  21. package/dist/browser/components/marketing/sections/ProblemSection.js +2 -2
  22. package/dist/browser/components/marketing/sections/SolutionSection.js +2 -2
  23. package/dist/browser/components/marketing/sections/StepsSection.js +4 -4
  24. package/dist/browser/components/marketing/studio-signup-section.js +25 -41
  25. package/dist/browser/components/templates/TemplatesClientPage.js +2324 -3578
  26. package/dist/browser/components/templates/TemplatesPage.js +1 -1
  27. package/dist/browser/components/templates/TemplatesPreviewModal.js +3 -3
  28. package/dist/browser/components/templates/index.js +2361 -3615
  29. package/dist/browser/index.js +2363 -3617
  30. package/dist/browser/libs/email/client.js +1 -1
  31. package/dist/browser/libs/email/contact.js +1 -1
  32. package/dist/browser/libs/email/newsletter.js +1 -1
  33. package/dist/browser/libs/email/waitlist-application.js +1 -1
  34. package/dist/browser/libs/email/waitlist.js +1 -1
  35. package/dist/browser/registry/engine.js +2003 -3334
  36. package/dist/browser/registry/index.js +2003 -3334
  37. package/dist/browser/registry/registry-docs.js +2 -2
  38. package/dist/browser/registry/registry-landing.js +2007 -3338
  39. package/dist/browser/registry/registry.js +2003 -3334
  40. package/dist/browser/registry/utils.js +2003 -3334
  41. package/dist/components/marketing/ChangelogPage.js +8 -8
  42. package/dist/components/marketing/CofounderPage.js +167 -523
  43. package/dist/components/marketing/ContactClient.js +200 -207
  44. package/dist/components/marketing/ContributePage.d.ts +0 -2
  45. package/dist/components/marketing/ContributePage.js +211 -463
  46. package/dist/components/marketing/DesignPartnerPage.js +165 -218
  47. package/dist/components/marketing/LandingPage.js +464 -568
  48. package/dist/components/marketing/PricingClient.js +213 -839
  49. package/dist/components/marketing/ProductClientPage.js +265 -463
  50. package/dist/components/marketing/index.d.ts +5 -5
  51. package/dist/components/marketing/index.js +2007 -3338
  52. package/dist/components/marketing/pricing-thinking-modal.js +12 -12
  53. package/dist/components/marketing/sections/AudienceSection.js +2 -2
  54. package/dist/components/marketing/sections/CorePositioningSection.js +2 -2
  55. package/dist/components/marketing/sections/CtaSection.js +3 -3
  56. package/dist/components/marketing/sections/FearsSection.js +3 -3
  57. package/dist/components/marketing/sections/HeroMarketingSection.js +6 -6
  58. package/dist/components/marketing/sections/IconGridSection.d.ts +3 -3
  59. package/dist/components/marketing/sections/IconGridSection.js +2 -2
  60. package/dist/components/marketing/sections/OutputsSection.js +2 -2
  61. package/dist/components/marketing/sections/ProblemSection.js +2 -2
  62. package/dist/components/marketing/sections/SolutionSection.js +2 -2
  63. package/dist/components/marketing/sections/StepsSection.js +4 -4
  64. package/dist/components/marketing/studio-signup-section.js +25 -41
  65. package/dist/components/templates/TemplatesClientPage.js +2324 -3578
  66. package/dist/components/templates/TemplatesPage.js +1 -1
  67. package/dist/components/templates/TemplatesPreviewModal.js +3 -3
  68. package/dist/components/templates/index.js +2361 -3615
  69. package/dist/index.js +2363 -3617
  70. package/dist/libs/email/client.js +1 -1
  71. package/dist/libs/email/contact.js +1 -1
  72. package/dist/libs/email/newsletter.js +1 -1
  73. package/dist/libs/email/waitlist-application.js +1 -1
  74. package/dist/libs/email/waitlist.js +1 -1
  75. package/dist/node/components/marketing/ChangelogPage.js +8 -8
  76. package/dist/node/components/marketing/CofounderPage.js +167 -523
  77. package/dist/node/components/marketing/ContactClient.js +200 -207
  78. package/dist/node/components/marketing/ContributePage.js +211 -463
  79. package/dist/node/components/marketing/DesignPartnerPage.js +165 -218
  80. package/dist/node/components/marketing/LandingPage.js +464 -568
  81. package/dist/node/components/marketing/PricingClient.js +213 -839
  82. package/dist/node/components/marketing/ProductClientPage.js +265 -463
  83. package/dist/node/components/marketing/index.js +2007 -3338
  84. package/dist/node/components/marketing/pricing-thinking-modal.js +12 -12
  85. package/dist/node/components/marketing/sections/AudienceSection.js +2 -2
  86. package/dist/node/components/marketing/sections/CorePositioningSection.js +2 -2
  87. package/dist/node/components/marketing/sections/CtaSection.js +3 -3
  88. package/dist/node/components/marketing/sections/FearsSection.js +3 -3
  89. package/dist/node/components/marketing/sections/HeroMarketingSection.js +6 -6
  90. package/dist/node/components/marketing/sections/IconGridSection.js +2 -2
  91. package/dist/node/components/marketing/sections/OutputsSection.js +2 -2
  92. package/dist/node/components/marketing/sections/ProblemSection.js +2 -2
  93. package/dist/node/components/marketing/sections/SolutionSection.js +2 -2
  94. package/dist/node/components/marketing/sections/StepsSection.js +4 -4
  95. package/dist/node/components/marketing/studio-signup-section.js +25 -41
  96. package/dist/node/components/templates/TemplatesClientPage.js +2324 -3578
  97. package/dist/node/components/templates/TemplatesPage.js +1 -1
  98. package/dist/node/components/templates/TemplatesPreviewModal.js +3 -3
  99. package/dist/node/components/templates/index.js +2361 -3615
  100. package/dist/node/index.js +2363 -3617
  101. package/dist/node/libs/email/client.js +1 -1
  102. package/dist/node/libs/email/contact.js +1 -1
  103. package/dist/node/libs/email/newsletter.js +1 -1
  104. package/dist/node/libs/email/waitlist-application.js +1 -1
  105. package/dist/node/libs/email/waitlist.js +1 -1
  106. package/dist/node/registry/engine.js +2003 -3334
  107. package/dist/node/registry/index.js +2003 -3334
  108. package/dist/node/registry/registry-docs.js +2 -2
  109. package/dist/node/registry/registry-landing.js +2007 -3338
  110. package/dist/node/registry/registry.js +2003 -3334
  111. package/dist/node/registry/utils.js +2003 -3334
  112. package/dist/registry/engine.js +2003 -3334
  113. package/dist/registry/index.js +2003 -3334
  114. package/dist/registry/registry-docs.js +2 -2
  115. package/dist/registry/registry-landing.js +2007 -3338
  116. package/dist/registry/registry.js +2003 -3334
  117. package/dist/registry/utils.js +2003 -3334
  118. package/package.json +22 -22
  119. package/src/bundles/MarketingBundle.ts +273 -273
  120. package/src/components/marketing/ChangelogPage.tsx +72 -100
  121. package/src/components/marketing/CofounderPage.tsx +120 -384
  122. package/src/components/marketing/ContactClient.tsx +164 -154
  123. package/src/components/marketing/ContributePage.tsx +139 -313
  124. package/src/components/marketing/DesignPartnerPage.tsx +133 -171
  125. package/src/components/marketing/LandingPage.tsx +353 -25
  126. package/src/components/marketing/PricingClient.tsx +192 -437
  127. package/src/components/marketing/ProductClientPage.tsx +255 -377
  128. package/src/components/marketing/index.ts +5 -5
  129. package/src/components/marketing/pricing-thinking-modal.tsx +197 -197
  130. package/src/components/marketing/sections/AudienceSection.tsx +55 -56
  131. package/src/components/marketing/sections/CorePositioningSection.tsx +37 -37
  132. package/src/components/marketing/sections/CtaSection.tsx +49 -50
  133. package/src/components/marketing/sections/DevelopersSection.tsx +26 -27
  134. package/src/components/marketing/sections/FearsSection.tsx +36 -37
  135. package/src/components/marketing/sections/HeroMarketingSection.tsx +59 -59
  136. package/src/components/marketing/sections/IconGridSection.tsx +71 -71
  137. package/src/components/marketing/sections/OutputsSection.tsx +51 -52
  138. package/src/components/marketing/sections/ProblemSection.tsx +39 -40
  139. package/src/components/marketing/sections/SolutionSection.tsx +39 -40
  140. package/src/components/marketing/sections/StepsSection.tsx +47 -48
  141. package/src/components/marketing/studio-signup-section.tsx +39 -41
  142. package/src/components/templates/TemplatesClientPage.tsx +727 -685
  143. package/src/components/templates/TemplatesPage.tsx +110 -110
  144. package/src/components/templates/TemplatesPreviewModal.tsx +197 -198
  145. package/src/index.ts +4 -4
  146. package/src/libs/email/client.test.ts +81 -81
  147. package/src/libs/email/client.ts +111 -111
  148. package/src/libs/email/contact.ts +35 -35
  149. package/src/libs/email/newsletter.ts +46 -46
  150. package/src/libs/email/types.ts +29 -29
  151. package/src/libs/email/utils.ts +5 -5
  152. package/src/libs/email/waitlist-application.ts +72 -72
  153. package/src/libs/email/waitlist.ts +46 -46
  154. package/src/libs/pricing-examples.ts +12 -12
  155. package/src/registry/engine.ts +16 -16
  156. package/src/registry/factory.ts +57 -57
  157. package/src/registry/registry-docs.ts +656 -666
  158. package/src/registry/registry-landing.ts +94 -95
  159. package/src/registry/registry.ts +36 -37
  160. package/src/registry/types.ts +2 -2
  161. package/src/registry/utils.ts +56 -56
  162. package/tsconfig.json +11 -11
  163. package/tsdown.config.js +5 -5
@@ -1,54 +1,54 @@
1
1
  'use server';
2
2
 
3
3
  import { getEmailConfig, sendEmail } from './client';
4
- import { escapeHtml, formatMultilineHtml } from './utils';
5
4
  import type { SubmitWaitlistApplicationResult } from './types';
5
+ import { escapeHtml, formatMultilineHtml } from './utils';
6
6
 
7
7
  const APPLICATION_MISSING_CONFIG =
8
- 'Waitlist application service is not configured. Please try again later.';
8
+ 'Waitlist application service is not configured. Please try again later.';
9
9
  const APPLICATION_SEND_ERROR =
10
- 'Failed to submit application. Please try again later or contact us directly.';
10
+ 'Failed to submit application. Please try again later or contact us directly.';
11
11
 
12
12
  export const submitWaitlistApplication = async (
13
- formData: FormData
13
+ formData: FormData
14
14
  ): Promise<SubmitWaitlistApplicationResult> => {
15
- const email = (formData.get('email') ?? '').toString().trim();
16
- const name = (formData.get('name') ?? '').toString().trim();
17
- const company = (formData.get('company') ?? '').toString().trim();
18
- const role = (formData.get('role') ?? '').toString().trim();
19
- const useCase = (formData.get('useCase') ?? '').toString().trim();
20
- const currentStack = (formData.get('currentStack') ?? '').toString().trim();
21
- const whatBuilding = (formData.get('whatBuilding') ?? '').toString().trim();
22
- const whatSolving = (formData.get('whatSolving') ?? '').toString().trim();
23
- const teamSize = (formData.get('teamSize') ?? '').toString().trim();
24
- const timeline = (formData.get('timeline') ?? '').toString().trim();
25
-
26
- const openToSessions = formData.get('openToSessions') === 'on';
27
- const okayWithCaseStudies = formData.get('okayWithCaseStudies') === 'on';
28
-
29
- if (!email || !email.includes('@')) {
30
- return {
31
- success: false,
32
- text: 'Please enter a valid email address.',
33
- };
34
- }
35
-
36
- if (!name || !whatBuilding || !whatSolving) {
37
- return {
38
- success: false,
39
- text: 'Please fill in all required fields.',
40
- };
41
- }
42
-
43
- const configResult = getEmailConfig();
44
- if (!configResult.ok || !configResult.config) {
45
- return {
46
- success: false,
47
- text: configResult.errorMessage ?? APPLICATION_MISSING_CONFIG,
48
- };
49
- }
50
-
51
- const applicantText = `
15
+ const email = (formData.get('email') ?? '').toString().trim();
16
+ const name = (formData.get('name') ?? '').toString().trim();
17
+ const company = (formData.get('company') ?? '').toString().trim();
18
+ const role = (formData.get('role') ?? '').toString().trim();
19
+ const useCase = (formData.get('useCase') ?? '').toString().trim();
20
+ const currentStack = (formData.get('currentStack') ?? '').toString().trim();
21
+ const whatBuilding = (formData.get('whatBuilding') ?? '').toString().trim();
22
+ const whatSolving = (formData.get('whatSolving') ?? '').toString().trim();
23
+ const teamSize = (formData.get('teamSize') ?? '').toString().trim();
24
+ const timeline = (formData.get('timeline') ?? '').toString().trim();
25
+
26
+ const openToSessions = formData.get('openToSessions') === 'on';
27
+ const okayWithCaseStudies = formData.get('okayWithCaseStudies') === 'on';
28
+
29
+ if (!email || !email.includes('@')) {
30
+ return {
31
+ success: false,
32
+ text: 'Please enter a valid email address.',
33
+ };
34
+ }
35
+
36
+ if (!name || !whatBuilding || !whatSolving) {
37
+ return {
38
+ success: false,
39
+ text: 'Please fill in all required fields.',
40
+ };
41
+ }
42
+
43
+ const configResult = getEmailConfig();
44
+ if (!configResult.ok || !configResult.config) {
45
+ return {
46
+ success: false,
47
+ text: configResult.errorMessage ?? APPLICATION_MISSING_CONFIG,
48
+ };
49
+ }
50
+
51
+ const applicantText = `
52
52
  You're on the list.
53
53
 
54
54
  Thanks for applying to the ContractSpec design partner program. We're slowly onboarding design partners in waves. If your use case is a good fit, we'll reach out personally.
@@ -69,7 +69,7 @@ ContractSpec Team
69
69
  https://contractspec.io
70
70
  `.trim();
71
71
 
72
- const applicantHtml = `
72
+ const applicantHtml = `
73
73
  <div style="font-family: sans-serif; max-width: 640px; margin: 0 auto;">
74
74
  <h1 style="color: #8b5cf6;">You're on the list.</h1>
75
75
  <p>Thanks for applying to the ContractSpec design partner program. We're slowly onboarding design partners in waves. If your use case is a good fit, we'll reach out personally.</p>
@@ -93,24 +93,24 @@ https://contractspec.io
93
93
  </div>
94
94
  `;
95
95
 
96
- const applicantSend = await sendEmail(configResult.config, {
97
- to: [{ email }],
98
- subject: "You're on the ContractSpec design partner waitlist!",
99
- text: applicantText,
100
- html: applicantHtml,
101
- context: 'waitlist-application-welcome',
102
- });
96
+ const applicantSend = await sendEmail(configResult.config, {
97
+ to: [{ email }],
98
+ subject: "You're on the ContractSpec design partner waitlist!",
99
+ text: applicantText,
100
+ html: applicantHtml,
101
+ context: 'waitlist-application-welcome',
102
+ });
103
103
 
104
- if (!applicantSend.success) {
105
- return { success: false, text: APPLICATION_SEND_ERROR };
106
- }
104
+ if (!applicantSend.success) {
105
+ return { success: false, text: APPLICATION_SEND_ERROR };
106
+ }
107
107
 
108
- const preferencesText = `
108
+ const preferencesText = `
109
109
  Open to 1:1 product/design sessions: ${openToSessions ? 'Yes' : 'No'}
110
110
  Okay with anonymized case studies: ${okayWithCaseStudies ? 'Yes' : 'No'}
111
111
  `.trim();
112
112
 
113
- const teamEmailText = `
113
+ const teamEmailText = `
114
114
  New Design Partner Waitlist Application
115
115
 
116
116
  Contact Information:
@@ -139,7 +139,7 @@ Preferences:
139
139
  Submitted via ContractSpec waitlist application form
140
140
  `.trim();
141
141
 
142
- const teamEmailHtml = `
142
+ const teamEmailHtml = `
143
143
  <div style="font-family: sans-serif; max-width: 720px; margin: 0 auto;">
144
144
  <h1 style="color: #8b5cf6;">New Design Partner Waitlist Application</h1>
145
145
  <h2 style="color: #8b5cf6; margin: 16px 0 8px;">Contact Information</h2>
@@ -172,21 +172,21 @@ Submitted via ContractSpec waitlist application form
172
172
  </div>
173
173
  `;
174
174
 
175
- const teamSend = await sendEmail(configResult.config, {
176
- to: [configResult.config.teamInbox],
177
- subject: `New Design Partner Application: ${name} (${email})`,
178
- text: teamEmailText,
179
- html: teamEmailHtml,
180
- replyTo: email,
181
- context: 'waitlist-application-team-notification',
182
- });
183
-
184
- if (!teamSend.success) {
185
- return { success: false, text: APPLICATION_SEND_ERROR };
186
- }
187
-
188
- return {
189
- success: true,
190
- text: 'Application submitted successfully!',
191
- };
175
+ const teamSend = await sendEmail(configResult.config, {
176
+ to: [configResult.config.teamInbox],
177
+ subject: `New Design Partner Application: ${name} (${email})`,
178
+ text: teamEmailText,
179
+ html: teamEmailHtml,
180
+ replyTo: email,
181
+ context: 'waitlist-application-team-notification',
182
+ });
183
+
184
+ if (!teamSend.success) {
185
+ return { success: false, text: APPLICATION_SEND_ERROR };
186
+ }
187
+
188
+ return {
189
+ success: true,
190
+ text: 'Application submitted successfully!',
191
+ };
192
192
  };
@@ -1,35 +1,35 @@
1
1
  'use server';
2
2
 
3
3
  import { getEmailConfig, sendEmail } from './client';
4
- import { formatMultilineHtml } from './utils';
5
4
  import type { SubmitWaitlistResult } from './types';
5
+ import { formatMultilineHtml } from './utils';
6
6
 
7
7
  const WAITLIST_MISSING_CONFIG =
8
- 'Waitlist service is not configured. Please try again later.';
8
+ 'Waitlist service is not configured. Please try again later.';
9
9
  const WAITLIST_SEND_ERROR =
10
- 'Failed to join waitlist. Please try again later or contact us directly.';
10
+ 'Failed to join waitlist. Please try again later or contact us directly.';
11
11
 
12
12
  export const joinWaitlist = async (
13
- formData: FormData
13
+ formData: FormData
14
14
  ): Promise<SubmitWaitlistResult> => {
15
- const email = (formData.get('email') ?? '').toString().trim();
16
-
17
- if (!email || !email.includes('@')) {
18
- return {
19
- success: false,
20
- text: 'Please enter a valid email address.',
21
- };
22
- }
23
-
24
- const configResult = getEmailConfig();
25
- if (!configResult.ok || !configResult.config) {
26
- return {
27
- success: false,
28
- text: configResult.errorMessage ?? WAITLIST_MISSING_CONFIG,
29
- };
30
- }
31
-
32
- const waitlistText = `
15
+ const email = (formData.get('email') ?? '').toString().trim();
16
+
17
+ if (!email || !email.includes('@')) {
18
+ return {
19
+ success: false,
20
+ text: 'Please enter a valid email address.',
21
+ };
22
+ }
23
+
24
+ const configResult = getEmailConfig();
25
+ if (!configResult.ok || !configResult.config) {
26
+ return {
27
+ success: false,
28
+ text: configResult.errorMessage ?? WAITLIST_MISSING_CONFIG,
29
+ };
30
+ }
31
+
32
+ const waitlistText = `
33
33
  You're on the waitlist!
34
34
 
35
35
  Thanks for joining the ContractSpec waitlist. You're now in line for early access to:
@@ -54,7 +54,7 @@ https://contractspec.io
54
54
  To remove yourself from the waitlist, reply to this email with "remove"
55
55
  `.trim();
56
56
 
57
- const waitlistHtml = `
57
+ const waitlistHtml = `
58
58
  <div style="font-family: sans-serif; max-width: 640px; margin: 0 auto;">
59
59
  <h1 style="color: #8b5cf6;">You're on the waitlist!</h1>
60
60
  <p>Thanks for joining the ContractSpec waitlist. You're now in line for early access to:</p>
@@ -82,37 +82,37 @@ To remove yourself from the waitlist, reply to this email with "remove"
82
82
  </div>
83
83
  `;
84
84
 
85
- const userSend = await sendEmail(configResult.config, {
86
- to: [{ email }],
87
- subject: "You're on the ContractSpec waitlist!",
88
- text: waitlistText,
89
- html: waitlistHtml,
90
- context: 'waitlist-welcome',
91
- });
85
+ const userSend = await sendEmail(configResult.config, {
86
+ to: [{ email }],
87
+ subject: "You're on the ContractSpec waitlist!",
88
+ text: waitlistText,
89
+ html: waitlistHtml,
90
+ context: 'waitlist-welcome',
91
+ });
92
92
 
93
- if (!userSend.success) {
94
- return { success: false, text: WAITLIST_SEND_ERROR };
95
- }
93
+ if (!userSend.success) {
94
+ return { success: false, text: WAITLIST_SEND_ERROR };
95
+ }
96
96
 
97
- const teamNotificationText = `New waitlist signup from: ${email}`;
98
- const teamNotificationHtml = `
97
+ const teamNotificationText = `New waitlist signup from: ${email}`;
98
+ const teamNotificationHtml = `
99
99
  <div style="font-family: sans-serif; max-width: 640px; margin: 0 auto;">
100
100
  <p style="margin: 0 0 8px;">New waitlist signup</p>
101
101
  <p style="margin: 0;"><strong>Email:</strong> ${formatMultilineHtml(email)}</p>
102
102
  </div>
103
103
  `;
104
104
 
105
- const teamSend = await sendEmail(configResult.config, {
106
- to: [configResult.config.teamInbox],
107
- subject: `New Waitlist Signup: ${email}`,
108
- text: teamNotificationText,
109
- html: teamNotificationHtml,
110
- context: 'waitlist-team-notification',
111
- });
105
+ const teamSend = await sendEmail(configResult.config, {
106
+ to: [configResult.config.teamInbox],
107
+ subject: `New Waitlist Signup: ${email}`,
108
+ text: teamNotificationText,
109
+ html: teamNotificationHtml,
110
+ context: 'waitlist-team-notification',
111
+ });
112
112
 
113
- if (!teamSend.success) {
114
- return { success: false, text: WAITLIST_SEND_ERROR };
115
- }
113
+ if (!teamSend.success) {
114
+ return { success: false, text: WAITLIST_SEND_ERROR };
115
+ }
116
116
 
117
- return { success: true, text: 'Successfully joined waitlist!' };
117
+ return { success: true, text: 'Successfully joined waitlist!' };
118
118
  };
@@ -4,16 +4,16 @@
4
4
  */
5
5
 
6
6
  export const PRICING_EXAMPLES = {
7
- free: {
8
- regenerationsPerMonth: 200,
9
- aiActionsPerMonth: 100,
10
- projects: 1,
11
- },
12
- builder: {
13
- regenerationsPerMonthHint: '1,000–2,000+',
14
- aiActionsPerMonthHint: '1,000+',
15
- },
16
- team: {
17
- description: 'Higher limits + cheaper per-regen at scale',
18
- },
7
+ free: {
8
+ regenerationsPerMonth: 200,
9
+ aiActionsPerMonth: 100,
10
+ projects: 1,
11
+ },
12
+ builder: {
13
+ regenerationsPerMonthHint: '1,000–2,000+',
14
+ aiActionsPerMonthHint: '1,000+',
15
+ },
16
+ team: {
17
+ description: 'Higher limits + cheaper per-regen at scale',
18
+ },
19
19
  } as const;
@@ -1,9 +1,9 @@
1
1
  import {
2
- createDefaultTransformEngine,
3
- registerBasicValidation,
4
- registerDefaultReactRenderer,
5
- registerReactToMarkdownRenderer,
6
- type TransformEngine,
2
+ createDefaultTransformEngine,
3
+ registerBasicValidation,
4
+ registerDefaultReactRenderer,
5
+ registerReactToMarkdownRenderer,
6
+ type TransformEngine,
7
7
  } from '@contractspec/lib.contracts-spec/presentations/transform-engine';
8
8
  import { componentMap } from './registry';
9
9
  import type { ComponentMap } from './types';
@@ -13,22 +13,22 @@ import type { ComponentMap } from './types';
13
13
  * Includes React and Markdown renderers with component map registration.
14
14
  */
15
15
  export function createPresentationEngine(
16
- customComponentMap?: ComponentMap
16
+ customComponentMap?: ComponentMap
17
17
  ): TransformEngine {
18
- const engine = createDefaultTransformEngine();
18
+ const engine = createDefaultTransformEngine();
19
19
 
20
- // Register React renderer
21
- registerDefaultReactRenderer(engine);
20
+ // Register React renderer
21
+ registerDefaultReactRenderer(engine);
22
22
 
23
- // Register basic validation
24
- registerBasicValidation(engine);
23
+ // Register basic validation
24
+ registerBasicValidation(engine);
25
25
 
26
- // Register React-to-markdown renderer with component map
27
- // This enables rendering React components to markdown for LLM consumption
28
- const mapToUse = customComponentMap ?? componentMap;
29
- registerReactToMarkdownRenderer(engine, mapToUse);
26
+ // Register React-to-markdown renderer with component map
27
+ // This enables rendering React components to markdown for LLM consumption
28
+ const mapToUse = customComponentMap ?? componentMap;
29
+ registerReactToMarkdownRenderer(engine, mapToUse);
30
30
 
31
- return engine;
31
+ return engine;
32
32
  }
33
33
 
34
34
  /**
@@ -1,41 +1,41 @@
1
1
  import {
2
- type Owner,
3
- OwnersEnum,
4
- type Stability,
5
- StabilityEnum,
6
- type Tag,
7
- TagsEnum,
2
+ type Owner,
3
+ OwnersEnum,
4
+ type Stability,
5
+ StabilityEnum,
6
+ type Tag,
7
+ TagsEnum,
8
8
  } from '@contractspec/lib.contracts-spec/ownership';
9
9
  import type {
10
- PresentationSourceComponentReact,
11
- PresentationSpec,
12
- PresentationTarget,
10
+ PresentationSourceComponentReact,
11
+ PresentationSpec,
12
+ PresentationTarget,
13
13
  } from '@contractspec/lib.contracts-spec/presentations';
14
14
 
15
15
  /**
16
16
  * Options for creating a React component presentation.
17
17
  */
18
18
  export interface CreateComponentPresentationOptions {
19
- /** Fully-qualified spec key (e.g., "web-landing.home") */
20
- key: string;
21
- /** Component key resolved by host componentMap */
22
- componentKey: string;
23
- /** Short human-friendly summary */
24
- description: string;
25
- /** Business goal: why this exists */
26
- goal: string;
27
- /** Background, constraints, scope edges */
28
- context: string;
29
- /** Breaking changes => bump version @default '1.0.0' */
30
- version?: string;
31
- /** Lifecycle marker @default StabilityEnum.Stable */
32
- stability?: Stability;
33
- /** Owners for CODEOWNERS / on-call @default [OwnersEnum.PlatformCore] */
34
- owners?: Owner[];
35
- /** Search tags, grouping, docs navigation @default [] */
36
- tags?: Tag[];
37
- /** Render targets @default ['react', 'markdown'] */
38
- targets?: PresentationTarget[];
19
+ /** Fully-qualified spec key (e.g., "web-landing.home") */
20
+ key: string;
21
+ /** Component key resolved by host componentMap */
22
+ componentKey: string;
23
+ /** Short human-friendly summary */
24
+ description: string;
25
+ /** Business goal: why this exists */
26
+ goal: string;
27
+ /** Background, constraints, scope edges */
28
+ context: string;
29
+ /** Breaking changes => bump version @default '1.0.0' */
30
+ version?: string;
31
+ /** Lifecycle marker @default StabilityEnum.Stable */
32
+ stability?: Stability;
33
+ /** Owners for CODEOWNERS / on-call @default [OwnersEnum.PlatformCore] */
34
+ owners?: Owner[];
35
+ /** Search tags, grouping, docs navigation @default [] */
36
+ tags?: Tag[];
37
+ /** Render targets @default ['react', 'markdown'] */
38
+ targets?: PresentationTarget[];
39
39
  }
40
40
 
41
41
  /**
@@ -45,28 +45,28 @@ export interface CreateComponentPresentationOptions {
45
45
  * @returns A fully-typed PresentationSpec
46
46
  */
47
47
  export function createComponentPresentation(
48
- opts: CreateComponentPresentationOptions
48
+ opts: CreateComponentPresentationOptions
49
49
  ): PresentationSpec {
50
- const source: PresentationSourceComponentReact = {
51
- type: 'component',
52
- framework: 'react',
53
- componentKey: opts.componentKey,
54
- };
50
+ const source: PresentationSourceComponentReact = {
51
+ type: 'component',
52
+ framework: 'react',
53
+ componentKey: opts.componentKey,
54
+ };
55
55
 
56
- return {
57
- meta: {
58
- key: opts.key,
59
- version: opts.version ?? '1.0.0',
60
- description: opts.description,
61
- goal: opts.goal,
62
- context: opts.context,
63
- stability: opts.stability ?? StabilityEnum.Stable,
64
- owners: opts.owners ?? [OwnersEnum.PlatformCore],
65
- tags: opts.tags ?? [],
66
- },
67
- source,
68
- targets: opts.targets ?? ['react', 'markdown'],
69
- };
56
+ return {
57
+ meta: {
58
+ key: opts.key,
59
+ version: opts.version ?? '1.0.0',
60
+ description: opts.description,
61
+ goal: opts.goal,
62
+ context: opts.context,
63
+ stability: opts.stability ?? StabilityEnum.Stable,
64
+ owners: opts.owners ?? [OwnersEnum.PlatformCore],
65
+ tags: opts.tags ?? [],
66
+ },
67
+ source,
68
+ targets: opts.targets ?? ['react', 'markdown'],
69
+ };
70
70
  }
71
71
 
72
72
  /**
@@ -74,35 +74,35 @@ export function createComponentPresentation(
74
74
  * Example: "/docs/libraries/ai-agent" -> ["docs", "libraries", "ai-agent"]
75
75
  */
76
76
  export function tagsFromPath(path: string): Tag[] {
77
- return path
78
- .split('/')
79
- .filter((segment) => segment.length > 0)
80
- .map((segment) => segment as Tag);
77
+ return path
78
+ .split('/')
79
+ .filter((segment) => segment.length > 0)
80
+ .map((segment) => segment as Tag);
81
81
  }
82
82
 
83
83
  /**
84
84
  * Default goal for documentation pages.
85
85
  */
86
86
  export const DOCS_GOAL =
87
- 'Educate developers on ContractSpec usage and concepts';
87
+ 'Educate developers on ContractSpec usage and concepts';
88
88
 
89
89
  /**
90
90
  * Default context for documentation pages.
91
91
  */
92
92
  export const DOCS_CONTEXT =
93
- 'Part of the ContractSpec documentation site, rendered on contractspec.io';
93
+ 'Part of the ContractSpec documentation site, rendered on contractspec.io';
94
94
 
95
95
  /**
96
96
  * Default goal for marketing/landing pages.
97
97
  */
98
98
  export const MARKETING_GOAL =
99
- 'Convert visitors into ContractSpec users and customers';
99
+ 'Convert visitors into ContractSpec users and customers';
100
100
 
101
101
  /**
102
102
  * Default context for marketing pages.
103
103
  */
104
104
  export const MARKETING_CONTEXT =
105
- 'Marketing content on contractspec.io, designed for conversion';
105
+ 'Marketing content on contractspec.io, designed for conversion';
106
106
 
107
107
  /**
108
108
  * Default tags for documentation pages.