@contractspec/bundle.marketing 3.7.5 → 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 (164) hide show
  1. package/.turbo/turbo-build.log +84 -84
  2. package/AGENTS.md +29 -21
  3. package/CHANGELOG.md +27 -0
  4. package/README.md +36 -49
  5. package/dist/browser/components/marketing/ChangelogPage.js +8 -8
  6. package/dist/browser/components/marketing/CofounderPage.js +167 -523
  7. package/dist/browser/components/marketing/ContactClient.js +200 -207
  8. package/dist/browser/components/marketing/ContributePage.js +211 -463
  9. package/dist/browser/components/marketing/DesignPartnerPage.js +165 -218
  10. package/dist/browser/components/marketing/LandingPage.js +464 -568
  11. package/dist/browser/components/marketing/PricingClient.js +213 -839
  12. package/dist/browser/components/marketing/ProductClientPage.js +265 -463
  13. package/dist/browser/components/marketing/index.js +2007 -3338
  14. package/dist/browser/components/marketing/pricing-thinking-modal.js +12 -12
  15. package/dist/browser/components/marketing/sections/AudienceSection.js +2 -2
  16. package/dist/browser/components/marketing/sections/CorePositioningSection.js +2 -2
  17. package/dist/browser/components/marketing/sections/CtaSection.js +3 -3
  18. package/dist/browser/components/marketing/sections/FearsSection.js +3 -3
  19. package/dist/browser/components/marketing/sections/HeroMarketingSection.js +6 -6
  20. package/dist/browser/components/marketing/sections/IconGridSection.js +2 -2
  21. package/dist/browser/components/marketing/sections/OutputsSection.js +2 -2
  22. package/dist/browser/components/marketing/sections/ProblemSection.js +2 -2
  23. package/dist/browser/components/marketing/sections/SolutionSection.js +2 -2
  24. package/dist/browser/components/marketing/sections/StepsSection.js +4 -4
  25. package/dist/browser/components/marketing/studio-signup-section.js +25 -41
  26. package/dist/browser/components/templates/TemplatesClientPage.js +2324 -3578
  27. package/dist/browser/components/templates/TemplatesPage.js +1 -1
  28. package/dist/browser/components/templates/TemplatesPreviewModal.js +3 -3
  29. package/dist/browser/components/templates/index.js +2361 -3615
  30. package/dist/browser/index.js +2363 -3617
  31. package/dist/browser/libs/email/client.js +1 -1
  32. package/dist/browser/libs/email/contact.js +1 -1
  33. package/dist/browser/libs/email/newsletter.js +1 -1
  34. package/dist/browser/libs/email/waitlist-application.js +1 -1
  35. package/dist/browser/libs/email/waitlist.js +1 -1
  36. package/dist/browser/registry/engine.js +2003 -3334
  37. package/dist/browser/registry/index.js +2003 -3334
  38. package/dist/browser/registry/registry-docs.js +2 -2
  39. package/dist/browser/registry/registry-landing.js +2007 -3338
  40. package/dist/browser/registry/registry.js +2003 -3334
  41. package/dist/browser/registry/utils.js +2003 -3334
  42. package/dist/components/marketing/ChangelogPage.js +8 -8
  43. package/dist/components/marketing/CofounderPage.js +167 -523
  44. package/dist/components/marketing/ContactClient.js +200 -207
  45. package/dist/components/marketing/ContributePage.d.ts +0 -2
  46. package/dist/components/marketing/ContributePage.js +211 -463
  47. package/dist/components/marketing/DesignPartnerPage.js +165 -218
  48. package/dist/components/marketing/LandingPage.js +464 -568
  49. package/dist/components/marketing/PricingClient.js +213 -839
  50. package/dist/components/marketing/ProductClientPage.js +265 -463
  51. package/dist/components/marketing/index.d.ts +5 -5
  52. package/dist/components/marketing/index.js +2007 -3338
  53. package/dist/components/marketing/pricing-thinking-modal.js +12 -12
  54. package/dist/components/marketing/sections/AudienceSection.js +2 -2
  55. package/dist/components/marketing/sections/CorePositioningSection.js +2 -2
  56. package/dist/components/marketing/sections/CtaSection.js +3 -3
  57. package/dist/components/marketing/sections/FearsSection.js +3 -3
  58. package/dist/components/marketing/sections/HeroMarketingSection.js +6 -6
  59. package/dist/components/marketing/sections/IconGridSection.d.ts +3 -3
  60. package/dist/components/marketing/sections/IconGridSection.js +2 -2
  61. package/dist/components/marketing/sections/OutputsSection.js +2 -2
  62. package/dist/components/marketing/sections/ProblemSection.js +2 -2
  63. package/dist/components/marketing/sections/SolutionSection.js +2 -2
  64. package/dist/components/marketing/sections/StepsSection.js +4 -4
  65. package/dist/components/marketing/studio-signup-section.js +25 -41
  66. package/dist/components/templates/TemplatesClientPage.js +2324 -3578
  67. package/dist/components/templates/TemplatesPage.js +1 -1
  68. package/dist/components/templates/TemplatesPreviewModal.js +3 -3
  69. package/dist/components/templates/index.js +2361 -3615
  70. package/dist/index.js +2363 -3617
  71. package/dist/libs/email/client.js +1 -1
  72. package/dist/libs/email/contact.js +1 -1
  73. package/dist/libs/email/newsletter.js +1 -1
  74. package/dist/libs/email/waitlist-application.js +1 -1
  75. package/dist/libs/email/waitlist.js +1 -1
  76. package/dist/node/components/marketing/ChangelogPage.js +8 -8
  77. package/dist/node/components/marketing/CofounderPage.js +167 -523
  78. package/dist/node/components/marketing/ContactClient.js +200 -207
  79. package/dist/node/components/marketing/ContributePage.js +211 -463
  80. package/dist/node/components/marketing/DesignPartnerPage.js +165 -218
  81. package/dist/node/components/marketing/LandingPage.js +464 -568
  82. package/dist/node/components/marketing/PricingClient.js +213 -839
  83. package/dist/node/components/marketing/ProductClientPage.js +265 -463
  84. package/dist/node/components/marketing/index.js +2007 -3338
  85. package/dist/node/components/marketing/pricing-thinking-modal.js +12 -12
  86. package/dist/node/components/marketing/sections/AudienceSection.js +2 -2
  87. package/dist/node/components/marketing/sections/CorePositioningSection.js +2 -2
  88. package/dist/node/components/marketing/sections/CtaSection.js +3 -3
  89. package/dist/node/components/marketing/sections/FearsSection.js +3 -3
  90. package/dist/node/components/marketing/sections/HeroMarketingSection.js +6 -6
  91. package/dist/node/components/marketing/sections/IconGridSection.js +2 -2
  92. package/dist/node/components/marketing/sections/OutputsSection.js +2 -2
  93. package/dist/node/components/marketing/sections/ProblemSection.js +2 -2
  94. package/dist/node/components/marketing/sections/SolutionSection.js +2 -2
  95. package/dist/node/components/marketing/sections/StepsSection.js +4 -4
  96. package/dist/node/components/marketing/studio-signup-section.js +25 -41
  97. package/dist/node/components/templates/TemplatesClientPage.js +2324 -3578
  98. package/dist/node/components/templates/TemplatesPage.js +1 -1
  99. package/dist/node/components/templates/TemplatesPreviewModal.js +3 -3
  100. package/dist/node/components/templates/index.js +2361 -3615
  101. package/dist/node/index.js +2363 -3617
  102. package/dist/node/libs/email/client.js +1 -1
  103. package/dist/node/libs/email/contact.js +1 -1
  104. package/dist/node/libs/email/newsletter.js +1 -1
  105. package/dist/node/libs/email/waitlist-application.js +1 -1
  106. package/dist/node/libs/email/waitlist.js +1 -1
  107. package/dist/node/registry/engine.js +2003 -3334
  108. package/dist/node/registry/index.js +2003 -3334
  109. package/dist/node/registry/registry-docs.js +2 -2
  110. package/dist/node/registry/registry-landing.js +2007 -3338
  111. package/dist/node/registry/registry.js +2003 -3334
  112. package/dist/node/registry/utils.js +2003 -3334
  113. package/dist/registry/engine.js +2003 -3334
  114. package/dist/registry/index.js +2003 -3334
  115. package/dist/registry/registry-docs.js +2 -2
  116. package/dist/registry/registry-landing.js +2007 -3338
  117. package/dist/registry/registry.js +2003 -3334
  118. package/dist/registry/utils.js +2003 -3334
  119. package/package.json +29 -29
  120. package/src/bundles/MarketingBundle.ts +273 -273
  121. package/src/components/marketing/ChangelogPage.tsx +72 -100
  122. package/src/components/marketing/CofounderPage.tsx +120 -384
  123. package/src/components/marketing/ContactClient.tsx +164 -154
  124. package/src/components/marketing/ContributePage.tsx +139 -313
  125. package/src/components/marketing/DesignPartnerPage.tsx +133 -171
  126. package/src/components/marketing/LandingPage.tsx +353 -25
  127. package/src/components/marketing/PricingClient.tsx +192 -437
  128. package/src/components/marketing/ProductClientPage.tsx +255 -377
  129. package/src/components/marketing/index.ts +5 -5
  130. package/src/components/marketing/pricing-thinking-modal.tsx +197 -197
  131. package/src/components/marketing/sections/AudienceSection.tsx +55 -56
  132. package/src/components/marketing/sections/CorePositioningSection.tsx +37 -37
  133. package/src/components/marketing/sections/CtaSection.tsx +49 -50
  134. package/src/components/marketing/sections/DevelopersSection.tsx +26 -27
  135. package/src/components/marketing/sections/FearsSection.tsx +36 -37
  136. package/src/components/marketing/sections/HeroMarketingSection.tsx +59 -59
  137. package/src/components/marketing/sections/IconGridSection.tsx +71 -71
  138. package/src/components/marketing/sections/OutputsSection.tsx +51 -52
  139. package/src/components/marketing/sections/ProblemSection.tsx +39 -40
  140. package/src/components/marketing/sections/SolutionSection.tsx +39 -40
  141. package/src/components/marketing/sections/StepsSection.tsx +47 -48
  142. package/src/components/marketing/studio-signup-section.tsx +39 -41
  143. package/src/components/templates/TemplatesClientPage.tsx +727 -685
  144. package/src/components/templates/TemplatesPage.tsx +110 -110
  145. package/src/components/templates/TemplatesPreviewModal.tsx +197 -198
  146. package/src/index.ts +4 -4
  147. package/src/libs/email/client.test.ts +81 -81
  148. package/src/libs/email/client.ts +111 -111
  149. package/src/libs/email/contact.ts +35 -35
  150. package/src/libs/email/newsletter.ts +46 -46
  151. package/src/libs/email/types.ts +29 -29
  152. package/src/libs/email/utils.ts +5 -5
  153. package/src/libs/email/waitlist-application.ts +72 -72
  154. package/src/libs/email/waitlist.ts +46 -46
  155. package/src/libs/pricing-examples.ts +12 -12
  156. package/src/registry/engine.ts +16 -16
  157. package/src/registry/factory.ts +57 -57
  158. package/src/registry/registry-docs.ts +656 -666
  159. package/src/registry/registry-landing.ts +94 -95
  160. package/src/registry/registry.ts +36 -37
  161. package/src/registry/types.ts +2 -2
  162. package/src/registry/utils.ts +56 -56
  163. package/tsconfig.json +11 -11
  164. 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.