alchemy 0.3.0 → 0.3.1

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 (107) hide show
  1. package/lib/ai/approve.d.ts +99 -0
  2. package/lib/ai/approve.js +76 -0
  3. package/lib/ai/astro-file.js +7 -24
  4. package/lib/ai/client.d.ts +7 -0
  5. package/lib/ai/client.js +45 -0
  6. package/lib/ai/css-file.js +7 -24
  7. package/lib/ai/data.d.ts +26 -21
  8. package/lib/ai/data.js +33 -22
  9. package/lib/ai/document.d.ts +64 -4
  10. package/lib/ai/document.js +102 -55
  11. package/lib/ai/html-file.js +7 -24
  12. package/lib/ai/index.d.ts +2 -0
  13. package/lib/ai/index.js +2 -0
  14. package/lib/ai/json-file.js +11 -32
  15. package/lib/ai/review.d.ts +122 -0
  16. package/lib/ai/review.js +101 -0
  17. package/lib/ai/typescript-file.d.ts +1 -2
  18. package/lib/ai/typescript-file.js +8 -39
  19. package/lib/ai/vue-file.js +7 -24
  20. package/lib/ai/yaml-file.js +12 -48
  21. package/lib/alchemy.js +17 -2
  22. package/lib/apply.js +1 -1
  23. package/lib/cloudflare/generate-asset-manifest.js +1 -1
  24. package/lib/cloudflare/static-site-router.js +16 -7
  25. package/lib/cloudflare/static-site.js +3 -0
  26. package/lib/cloudflare/upload-asset-manifest.js +4 -2
  27. package/lib/fs/copy-file.d.ts +54 -0
  28. package/lib/fs/copy-file.js +63 -0
  29. package/lib/fs/file.d.ts +13 -0
  30. package/lib/fs/file.js +24 -5
  31. package/lib/fs/index.d.ts +6 -0
  32. package/lib/fs/index.js +6 -0
  33. package/lib/fs/static-astro-file.d.ts +34 -0
  34. package/lib/fs/static-astro-file.js +39 -0
  35. package/lib/fs/static-css-file.d.ts +24 -0
  36. package/lib/fs/static-css-file.js +29 -0
  37. package/lib/fs/static-html-file.d.ts +31 -0
  38. package/lib/fs/static-html-file.js +36 -0
  39. package/lib/fs/static-json-file.d.ts +2 -2
  40. package/lib/fs/static-json-file.js +3 -2
  41. package/lib/fs/static-text-file.d.ts +1 -1
  42. package/lib/fs/static-text-file.js +3 -2
  43. package/lib/fs/static-typescript-file.d.ts +2 -2
  44. package/lib/fs/static-typescript-file.js +3 -2
  45. package/lib/fs/static-vue-file.d.ts +28 -0
  46. package/lib/fs/static-vue-file.js +33 -0
  47. package/lib/fs/static-yaml-file.d.ts +11 -8
  48. package/lib/fs/static-yaml-file.js +3 -2
  49. package/lib/internal/getting-started.d.ts +15 -4
  50. package/lib/internal/getting-started.js +34 -41
  51. package/lib/internal/index.d.ts +3 -0
  52. package/lib/internal/index.js +3 -0
  53. package/lib/internal/providers.d.ts +7 -3
  54. package/lib/internal/providers.js +42 -18
  55. package/lib/internal/tutorial.d.ts +104 -0
  56. package/lib/internal/tutorial.js +251 -0
  57. package/lib/web/vitepress/config.d.ts +10 -0
  58. package/lib/web/vitepress/config.js +31 -0
  59. package/lib/web/vitepress/home-page.d.ts +5 -3
  60. package/lib/web/vitepress/home-page.js +48 -35
  61. package/lib/web/vitepress/index.d.ts +1 -0
  62. package/lib/web/vitepress/index.js +1 -0
  63. package/lib/web/vitepress/vitepress.d.ts +5 -4
  64. package/lib/web/vitepress/vitepress.js +17 -34
  65. package/package.json +1 -1
  66. package/src/ai/approve.ts +163 -0
  67. package/src/ai/astro-file.ts +11 -30
  68. package/src/ai/client.ts +59 -0
  69. package/src/ai/css-file.ts +11 -30
  70. package/src/ai/data.ts +50 -25
  71. package/src/ai/document.ts +146 -65
  72. package/src/ai/html-file.ts +11 -30
  73. package/src/ai/index.ts +2 -0
  74. package/src/ai/json-file.ts +13 -37
  75. package/src/ai/review.ts +213 -0
  76. package/src/ai/typescript-file.ts +14 -48
  77. package/src/ai/vue-file.ts +11 -30
  78. package/src/ai/yaml-file.ts +13 -53
  79. package/src/alchemy.ts +18 -7
  80. package/src/apply.ts +8 -8
  81. package/src/cloudflare/generate-asset-manifest.ts +4 -4
  82. package/src/cloudflare/static-site-router.ts +18 -8
  83. package/src/cloudflare/static-site.ts +11 -7
  84. package/src/cloudflare/upload-asset-manifest.ts +6 -4
  85. package/src/cloudflare/worker.ts +44 -43
  86. package/src/fs/copy-file.ts +115 -0
  87. package/src/fs/file.ts +35 -9
  88. package/src/fs/index.ts +6 -0
  89. package/src/fs/static-astro-file.ts +45 -0
  90. package/src/fs/static-css-file.ts +35 -0
  91. package/src/fs/static-html-file.ts +42 -0
  92. package/src/fs/static-json-file.ts +4 -3
  93. package/src/fs/static-text-file.ts +5 -2
  94. package/src/fs/static-typescript-file.ts +4 -3
  95. package/src/fs/static-vue-file.ts +39 -0
  96. package/src/fs/static-yaml-file.ts +13 -9
  97. package/src/internal/getting-started.ts +51 -43
  98. package/src/internal/index.ts +3 -0
  99. package/src/internal/providers.ts +59 -27
  100. package/src/internal/tutorial.ts +392 -0
  101. package/src/web/vitepress/config.ts +48 -0
  102. package/src/web/vitepress/home-page.ts +54 -42
  103. package/src/web/vitepress/index.ts +1 -0
  104. package/src/web/vitepress/vitepress.ts +31 -48
  105. package/lib/internal/project.d.ts +0 -13
  106. package/lib/internal/project.js +0 -101
  107. package/src/internal/project.ts +0 -119
@@ -0,0 +1,104 @@
1
+ import type { CoreMessage } from "ai";
2
+ import { Document } from "../ai";
3
+ import type { ModelConfig } from "../ai/client";
4
+ import type { Context } from "../context";
5
+ import type { Folder } from "../fs";
6
+ import { Resource } from "../resource";
7
+ /**
8
+ * Properties for creating or updating a Tutorial
9
+ */
10
+ export interface TutorialProps {
11
+ /**
12
+ * The output directory for the tutorial document.
13
+ */
14
+ path: string | Folder;
15
+ /**
16
+ * The title of the tutorial.
17
+ */
18
+ title: string;
19
+ /**
20
+ * The prompt to use for generating the tutorial.
21
+ * This should include specific details about the tool or framework.
22
+ */
23
+ prompt: string;
24
+ /**
25
+ * Optional difficulty level for the tutorial.
26
+ * Defaults to "beginner".
27
+ */
28
+ difficulty?: "beginner" | "intermediate" | "advanced";
29
+ /**
30
+ * Optional estimated time to complete the tutorial in minutes.
31
+ * Defaults to 30.
32
+ */
33
+ estimatedTime?: number;
34
+ /**
35
+ * Optional model configuration for generating the tutorial.
36
+ * Defaults to Claude 3.5 Sonnet.
37
+ */
38
+ model?: ModelConfig;
39
+ /**
40
+ * Maximum number of review iterations.
41
+ * Defaults to 3.
42
+ */
43
+ maxIterations?: number;
44
+ /**
45
+ * Initial message history for the conversation.
46
+ * If not provided, a new conversation will be started.
47
+ */
48
+ messages?: CoreMessage[];
49
+ }
50
+ /**
51
+ * Output returned after Tutorial creation/update
52
+ */
53
+ export interface Tutorial extends TutorialProps, Resource<"docs::Tutorial"> {
54
+ /**
55
+ * The Document resource
56
+ */
57
+ document: Document;
58
+ /**
59
+ * The content of the tutorial
60
+ */
61
+ content: string;
62
+ /**
63
+ * Message history from the conversation.
64
+ */
65
+ messages: CoreMessage[];
66
+ /**
67
+ * Time at which the tutorial was created
68
+ */
69
+ createdAt: number;
70
+ /**
71
+ * Time at which the tutorial was last updated
72
+ */
73
+ updatedAt: number;
74
+ }
75
+ /**
76
+ * Creates a tutorial document with iterative review and improvement
77
+ *
78
+ * @example
79
+ * // Create a basic tutorial
80
+ * const tutorial = await Tutorial("getting-started", {
81
+ * path: "docs/tutorials/getting-started",
82
+ * title: "Getting Started with Alchemy",
83
+ * prompt: "Create a tutorial for getting started with the Alchemy framework",
84
+ * difficulty: "beginner",
85
+ * estimatedTime: 30
86
+ * });
87
+ *
88
+ * @example
89
+ * // Create an advanced tutorial with custom model and continue from existing messages
90
+ * const advancedTutorial = await Tutorial("advanced-features", {
91
+ * path: "docs/tutorials/advanced-features",
92
+ * title: "Advanced Alchemy Features",
93
+ * prompt: "Create a tutorial covering advanced features of the Alchemy framework",
94
+ * difficulty: "advanced",
95
+ * estimatedTime: 60,
96
+ * model: {
97
+ * id: "claude-3-7-sonnet-latest",
98
+ * provider: "anthropic"
99
+ * },
100
+ * maxIterations: 5,
101
+ * messages: basicTutorial.messages
102
+ * });
103
+ */
104
+ export declare const Tutorial: (((this: any, id: string, props?: {}) => never) & (new (_: never) => never)) | ((this: Context<Tutorial>, id: string, props: TutorialProps) => Promise<Tutorial>);
@@ -0,0 +1,251 @@
1
+ import { Approve, Document, Review } from "../ai";
2
+ import { alchemy } from "../alchemy";
3
+ import { Resource } from "../resource";
4
+ /**
5
+ * Creates a tutorial document with iterative review and improvement
6
+ *
7
+ * @example
8
+ * // Create a basic tutorial
9
+ * const tutorial = await Tutorial("getting-started", {
10
+ * path: "docs/tutorials/getting-started",
11
+ * title: "Getting Started with Alchemy",
12
+ * prompt: "Create a tutorial for getting started with the Alchemy framework",
13
+ * difficulty: "beginner",
14
+ * estimatedTime: 30
15
+ * });
16
+ *
17
+ * @example
18
+ * // Create an advanced tutorial with custom model and continue from existing messages
19
+ * const advancedTutorial = await Tutorial("advanced-features", {
20
+ * path: "docs/tutorials/advanced-features",
21
+ * title: "Advanced Alchemy Features",
22
+ * prompt: "Create a tutorial covering advanced features of the Alchemy framework",
23
+ * difficulty: "advanced",
24
+ * estimatedTime: 60,
25
+ * model: {
26
+ * id: "claude-3-7-sonnet-latest",
27
+ * provider: "anthropic"
28
+ * },
29
+ * maxIterations: 5,
30
+ * messages: basicTutorial.messages
31
+ * });
32
+ */
33
+ export const Tutorial = Resource("docs::Tutorial", async function (id, props) {
34
+ const { path: outFile, title, prompt, difficulty = "beginner", estimatedTime = 30, model = {
35
+ id: "claude-3-5-sonnet-latest",
36
+ provider: "anthropic",
37
+ }, maxIterations = 3, messages: initialMessages = [], } = props;
38
+ console.log(`Tutorial: Starting creation of "${title}" (ID: ${id})`);
39
+ // Handle deletion phase
40
+ if (this.phase === "delete") {
41
+ console.log(`Tutorial: Deleting tutorial "${title}" (ID: ${id})`);
42
+ return this.destroy();
43
+ }
44
+ // System prompts
45
+ const docSystemPrompt = `You are a technical writer creating a comprehensive tutorial.
46
+
47
+ Your task is to create a detailed tutorial about ${title} with difficulty level: ${difficulty} and estimated time to complete: ${estimatedTime} minutes.
48
+
49
+ The tutorial should take users from zero knowledge to a working understanding of the tool or framework.
50
+
51
+ The tutorial should be structured as follows:
52
+
53
+ # ${title}
54
+
55
+ ## Overview
56
+
57
+ (Provide a brief introduction to the tool/framework, its purpose, and what users will learn in this tutorial)
58
+
59
+ ## Prerequisites
60
+
61
+ (List any prerequisites, tools, or knowledge required before starting the tutorial)
62
+
63
+ ## Setup
64
+
65
+ ### Installation
66
+
67
+ \`\`\`bash
68
+ # Installation commands
69
+ \`\`\`
70
+
71
+ ### Configuration
72
+
73
+ (Explain any necessary configuration steps)
74
+
75
+ \`\`\`bash
76
+ # Configuration commands or code
77
+ \`\`\`
78
+
79
+ ## Step 1: [First Step Title]
80
+
81
+ (Explain the first step in detail)
82
+
83
+ \`\`\`bash
84
+ # Commands or code for the first step
85
+ \`\`\`
86
+
87
+ (Explain what the code does and why it's important)
88
+
89
+ ## Step 2: [Second Step Title]
90
+
91
+ (Explain the second step in detail)
92
+
93
+ \`\`\`bash
94
+ # Commands or code for the second step
95
+ \`\`\`
96
+
97
+ (Explain what the code does and why it's important)
98
+
99
+ ## Step 3: [Third Step Title]
100
+
101
+ (Explain the third step in detail)
102
+
103
+ \`\`\`bash
104
+ # Commands or code for the third step
105
+ \`\`\`
106
+
107
+ (Explain what the code does and why it's important)
108
+
109
+ ## Step 4: [Fourth Step Title]
110
+
111
+ (Explain the fourth step in detail)
112
+
113
+ \`\`\`bash
114
+ # Commands or code for the fourth step
115
+ \`\`\`
116
+
117
+ (Explain what the code does and why it's important)
118
+
119
+ ## Step 5: [Fifth Step Title]
120
+
121
+ (Explain the fifth step in detail)
122
+
123
+ \`\`\`bash
124
+ # Commands or code for the fifth step
125
+ \`\`\`
126
+
127
+ (Explain what the code does and why it's important)
128
+
129
+ ## Testing Your Work
130
+
131
+ (Explain how to verify that everything is working correctly)
132
+
133
+ \`\`\`bash
134
+ # Testing commands or code
135
+ \`\`\`
136
+
137
+ ## Troubleshooting
138
+
139
+ (Common issues users might encounter and how to resolve them)
140
+
141
+ ## Next Steps
142
+
143
+ (Suggest additional resources, advanced topics, or projects to try next)
144
+
145
+ ## Additional Resources
146
+
147
+ (Links to documentation, community resources, or related tutorials)`;
148
+ // Initial message if none provided
149
+ const startingMessages = initialMessages.length > 0
150
+ ? initialMessages
151
+ : [
152
+ {
153
+ role: "user",
154
+ content: `Create a comprehensive tutorial about ${title}.\n\n${prompt}\n\nDifficulty level: ${difficulty}\nEstimated time to complete: ${estimatedTime} minutes`,
155
+ },
156
+ ];
157
+ // Generate the initial tutorial
158
+ console.log(`Tutorial: Generating initial tutorial for "${title}"`);
159
+ let tutorial = await Document(`document`, {
160
+ title: title,
161
+ path: typeof outFile === "string" ? outFile : outFile.path,
162
+ model,
163
+ messages: startingMessages,
164
+ system: docSystemPrompt,
165
+ });
166
+ console.log(`Tutorial: Initial tutorial generated for "${title}" (${tutorial.content.length} chars)`);
167
+ // Review and improve the tutorial in a loop
168
+ let iteration = 0;
169
+ let approved = false;
170
+ let finalMessages = tutorial.messages;
171
+ while (!approved && iteration < maxIterations) {
172
+ iteration++;
173
+ console.log(`Tutorial: Starting review iteration ${iteration}/${maxIterations} for "${title}"`);
174
+ // Review the tutorial using system prompt
175
+ console.log(`Tutorial: Requesting review for iteration ${iteration}`);
176
+ const review = await Review(`review-${iteration}`, {
177
+ messages: finalMessages,
178
+ system: await alchemy `Please review this tutorial for correctness, conciseness, logical flow, and accurateness.
179
+
180
+ The tutorial should:
181
+ 1. Be technically accurate and free of errors
182
+ 2. Be concise without over-explaining
183
+ 3. Have a logical flow from basic to advanced concepts
184
+ 4. Be accurate in its descriptions and instructions
185
+ 5. Be appropriate for the ${difficulty} difficulty level
186
+ 6. Be completable within approximately ${estimatedTime} minutes
187
+
188
+ Provide specific feedback on areas that need improvement.`,
189
+ model,
190
+ });
191
+ // Extract the actual review content from the last assistant message
192
+ const reviewContent = review.messages[review.messages.length - 1]?.content || "";
193
+ console.log(`Tutorial: Review received for iteration ${iteration} (${reviewContent.length} chars)`);
194
+ // Check if the tutorial is approved using system prompt
195
+ console.log(`Tutorial: Evaluating approval for iteration ${iteration}`);
196
+ const approvalResult = await Approve(`approval-${iteration}`, {
197
+ messages: review.messages,
198
+ system: await alchemy `Based on the review above, determine if the tutorial meets the quality standards.
199
+ The tutorial should be approved if:
200
+ 1. It is technically accurate and free of errors
201
+ 2. It is concise without over-explaining
202
+ 3. It has a logical flow from basic to advanced concepts
203
+ 4. It is accurate in its descriptions and instructions
204
+ 5. It is appropriate for the ${difficulty} difficulty level
205
+ 6. It is completable within approximately ${estimatedTime} minutes
206
+
207
+ Respond with APPROVED or DENIED, followed by your explanation.`,
208
+ });
209
+ console.log(`Tutorial: Approval result for iteration ${iteration}: ${approvalResult.approved ? "APPROVED" : "DENIED"}`);
210
+ // Log approval status
211
+ if (approvalResult.approved) {
212
+ console.log(`Tutorial: Final tutorial approved: ${approvalResult.explanation}`);
213
+ approved = true;
214
+ finalMessages = approvalResult.messages;
215
+ }
216
+ else {
217
+ console.log(`Tutorial: Tutorial needs improvement: ${approvalResult.explanation}`);
218
+ // Add improvement request and generate an improved tutorial
219
+ const improvementMessages = [
220
+ ...approvalResult.messages,
221
+ {
222
+ role: "user",
223
+ content: `Please create an improved version of the tutorial that addresses the issues identified in the review: ${approvalResult.explanation}`,
224
+ },
225
+ ];
226
+ console.log(`Tutorial: Regenerating tutorial based on feedback for iteration ${iteration}`);
227
+ tutorial = await Document(`tutorial-${iteration}`, {
228
+ title: title,
229
+ path: typeof outFile === "string" ? outFile : outFile.path,
230
+ model,
231
+ messages: improvementMessages,
232
+ system: docSystemPrompt,
233
+ });
234
+ console.log(`Tutorial: Improved tutorial generated for iteration ${iteration} (${tutorial.content.length} chars)`);
235
+ finalMessages = tutorial.messages;
236
+ }
237
+ }
238
+ if (!approved) {
239
+ console.log(`Tutorial: Tutorial not approved after ${maxIterations} iterations. Using the best version available.`);
240
+ }
241
+ console.log(`Tutorial: Completed creation of "${title}" (ID: ${id})`);
242
+ // Return the tutorial resource
243
+ return this({
244
+ ...props,
245
+ document: tutorial,
246
+ content: tutorial.content,
247
+ messages: finalMessages,
248
+ createdAt: Date.now(),
249
+ updatedAt: Date.now(),
250
+ });
251
+ });
@@ -0,0 +1,10 @@
1
+ import type { DefaultTheme, ThemeOptions } from "vitepress";
2
+ export type VitePressConfigProps = {
3
+ cwd: string;
4
+ title?: string;
5
+ description?: string;
6
+ theme?: ThemeOptions;
7
+ themeConfig: DefaultTheme.Config;
8
+ };
9
+ export type VitePressConfig = Awaited<ReturnType<typeof VitePressConfig>>;
10
+ export declare function VitePressConfig(props: VitePressConfigProps): Promise<import("../../fs").File>;
@@ -0,0 +1,31 @@
1
+ import path from "path";
2
+ import { StaticTypeScriptFile } from "../../fs/static-typescript-file";
3
+ export function VitePressConfig(props) {
4
+ return StaticTypeScriptFile(path.join(props.cwd, ".vitepress", "config.mts"), `import { transformerTwoslash } from "@shikijs/vitepress-twoslash";
5
+ import footnotePlugin from "markdown-it-footnote";
6
+ import { defineConfig } from "vitepress";
7
+
8
+ // https://vitepress.dev/reference/site-config
9
+ export default defineConfig({
10
+ title: ${JSON.stringify(props.title || "Alchemy")},
11
+ description: ${JSON.stringify(props.description || "Alchemy Docs")},
12
+ markdown: {
13
+ // @ts-ignore
14
+ codeTransformers: [transformerTwoslash()],
15
+ theme: ${JSON.stringify(props.theme ?? {
16
+ light: "light-plus",
17
+ dark: "dark-plus",
18
+ })},
19
+ config: (md) => md.use(footnotePlugin),
20
+ },
21
+ // https://vitepress.dev/reference/default-theme-config
22
+ themeConfig: ${JSON.stringify({
23
+ ...props.themeConfig,
24
+ search: props.themeConfig.search ?? { provider: "local" },
25
+ nav: props.themeConfig.nav ?? [{ text: "Home", link: "/" }],
26
+ sidebar: props.themeConfig.sidebar ?? [],
27
+ socialLinks: props.themeConfig.socialLinks ?? [],
28
+ })}
29
+ });
30
+ `);
31
+ }
@@ -1,3 +1,5 @@
1
+ import { Document } from "../../ai/document";
2
+ import { StaticTextFile } from "../../fs";
1
3
  import type { Secret } from "../../secret";
2
4
  /**
3
5
  * Image that can be themed for light/dark mode
@@ -151,11 +153,11 @@ export interface HomePageProps {
151
153
  /**
152
154
  * User prompt describing the design of the home page
153
155
  */
154
- prompt: string;
156
+ prompt?: string;
155
157
  /**
156
158
  * Optional extension to the built-in system prompt
157
159
  */
158
- systemPromptExtension?: string;
160
+ system?: string;
159
161
  /**
160
162
  * Base URL for the OpenAI API
161
163
  * @default 'https://api.openai.com/v1'
@@ -179,7 +181,7 @@ export interface HomePageProps {
179
181
  /**
180
182
  * Output type for the HomePage resource
181
183
  */
182
- export type HomePage = import("../../ai/document").Document;
184
+ export type HomePage = StaticTextFile | Document;
183
185
  /**
184
186
  * Parse YAML frontmatter to home page config
185
187
  */
@@ -1,6 +1,7 @@
1
- import alchemy from "alchemy";
2
1
  import yaml from "yaml";
3
2
  import { Document } from "../../ai/document";
3
+ import { alchemy } from "../../alchemy";
4
+ import { StaticTextFile } from "../../fs";
4
5
  /**
5
6
  * Parse YAML frontmatter to home page config
6
7
  */
@@ -90,45 +91,57 @@ Follow these guidelines:
90
91
  6. Ensure all links are properly formatted
91
92
  7. Use appropriate markdown formatting for headings, lists, etc.
92
93
 
93
- ${props.systemPromptExtension || ""}
94
+ ${props.system || ""}
94
95
  `;
95
96
  // Convert hero and features to YAML strings if provided
96
97
  const heroYaml = props.hero ? JSON.stringify(props.hero, null, 2) : "";
97
98
  const featuresYaml = props.features
98
99
  ? JSON.stringify(props.features, null, 2)
99
100
  : "";
100
- // Create the document using the AI Document resource
101
- return Document(`${id}`, {
102
- title: props.title,
103
- path: props.outFile,
104
- baseURL: props.baseURL,
105
- apiKey: props.apiKey,
106
- model: props.model ?? {
107
- id: "claude-3-7-sonnet-latest",
108
- provider: "anthropic",
109
- },
110
- temperature: props.temperature ?? 0.7,
111
- prompt: await alchemy `
112
- ${systemPrompt}
113
-
114
- Create a VitePress homepage based on the following description:
115
- ${props.prompt}
116
-
117
- ${props.hero
118
- ? `Use this hero section configuration:
119
- \`\`\`json
120
- ${heroYaml}
121
- \`\`\``
122
- : ""}
123
-
124
- ${props.features
125
- ? `Use these features:
126
- \`\`\`json
127
- ${featuresYaml}
128
- \`\`\``
129
- : ""}
101
+ if (props.prompt) {
102
+ return Document(id, {
103
+ title: props.title,
104
+ path: props.outFile,
105
+ baseURL: props.baseURL,
106
+ apiKey: props.apiKey,
107
+ model: props.model ?? {
108
+ id: "claude-3-7-sonnet-latest",
109
+ provider: "anthropic",
110
+ },
111
+ temperature: props.temperature ?? 0.7,
112
+ prompt: await alchemy `
113
+ ${systemPrompt}
114
+
115
+ Create a VitePress homepage based on the following description:
116
+ ${props.prompt}
130
117
 
131
- The output should be a complete index.md file with proper YAML frontmatter and markdown content.
132
- `,
133
- });
118
+ ${props.hero
119
+ ? `Use this hero section configuration:
120
+ \`\`\`json
121
+ ${heroYaml}
122
+ \`\`\``
123
+ : ""}
124
+
125
+ ${props.features
126
+ ? `Use these features:
127
+ \`\`\`json
128
+ ${featuresYaml}
129
+ \`\`\``
130
+ : ""}
131
+
132
+ The output should be a complete index.md file with proper YAML frontmatter and markdown content.
133
+ `,
134
+ });
135
+ }
136
+ else {
137
+ return StaticTextFile(id, props.outFile, `---
138
+ ${yaml.stringify({
139
+ layout: "home",
140
+ name: props.title,
141
+ hero: props.hero,
142
+ features: props.features,
143
+ })}
144
+ ---
145
+ `);
146
+ }
134
147
  }
@@ -1,3 +1,4 @@
1
+ export * from "./config";
1
2
  export * from "./custom-theme";
2
3
  export * from "./home-page";
3
4
  export * from "./vitepress";
@@ -1,3 +1,4 @@
1
+ export * from "./config";
1
2
  export * from "./custom-theme";
2
3
  export * from "./home-page";
3
4
  export * from "./vitepress";
@@ -1,4 +1,3 @@
1
- import type { DefaultTheme, ThemeOptions } from "vitepress";
2
1
  import type { Context } from "../../context";
3
2
  import { Resource } from "../../resource";
4
3
  export interface VitePressProjectProps {
@@ -47,11 +46,9 @@ export interface VitePressProjectProps {
47
46
  /**
48
47
  * The theme options to use
49
48
  */
50
- theme?: ThemeOptions;
51
49
  /**
52
50
  * The theme config to use
53
51
  */
54
- themeConfig: DefaultTheme.Config;
55
52
  /**
56
53
  * Whether to delete the project folder during the delete phase
57
54
  * @default true
@@ -69,5 +66,9 @@ export interface VitePressProject extends VitePressProjectProps, Resource {
69
66
  * The name/path of the project
70
67
  */
71
68
  name: string;
69
+ /**
70
+ * The directory of the project
71
+ */
72
+ dir: string;
72
73
  }
73
- export declare const VitePressProject: (((this: any, id: string, props?: {}) => never) & (new (_: never) => never)) | ((this: Context<VitePressProject>, id: string, props: VitePressProjectProps) => Promise<VitePressProject>);
74
+ export declare const VitepressProject: (((this: any, id: string, props?: {}) => never) & (new (_: never) => never)) | ((this: Context<VitePressProject>, id: string, props: VitePressProjectProps) => Promise<VitePressProject>);
@@ -6,7 +6,7 @@ import { Folder, StaticJsonFile, StaticTextFile, StaticTypeScriptFile, } from ".
6
6
  import { Resource } from "../../resource";
7
7
  import { InstallDependencies, fixedDependencies } from "./dependencies";
8
8
  const execAsync = promisify(exec);
9
- export const VitePressProject = Resource("project::VitePressProject", {
9
+ export const VitepressProject = Resource("project::VitepressProject", {
10
10
  alwaysUpdate: true,
11
11
  }, async function (id, props) {
12
12
  const dir = props.dir ?? props.name;
@@ -57,11 +57,18 @@ export const VitePressProject = Resource("project::VitePressProject", {
57
57
  await Folder(path.join(cwd, ".vitepress", "theme"));
58
58
  await Promise.all([
59
59
  StaticTextFile(path.join(cwd, ".gitignore"), `.vitepress/cache\n`),
60
- StaticJsonFile(path.join(cwd, "tsconfig.json"), {
61
- extends: props.tsconfig?.extends,
62
- references: props.tsconfig?.references?.map((path) => ({ path })),
63
- compilerOptions: props.tsconfig?.compilerOptions,
64
- }),
60
+ // StaticJsonFile(path.join(cwd, "tsconfig.json"), {
61
+ // extends: props.tsconfig?.extends,
62
+ // references: props.tsconfig?.references?.map((path) => ({ path })),
63
+ // compilerOptions: props.tsconfig?.compilerOptions ?? {
64
+ // target: "ES2020",
65
+ // module: "ESNext",
66
+ // moduleResolution: "Node",
67
+ // allowJs: true,
68
+ // skipLibCheck: true,
69
+ // forceConsistentCasingInFileNames: true,
70
+ // },
71
+ // }),
65
72
  // TypeScriptFile(
66
73
  // path.join(cwd, "alchemy.run.ts"),
67
74
  // `import alchemy from "alchemy";
@@ -232,34 +239,10 @@ export default {
232
239
  .DocSearch {
233
240
  --docsearch-primary-color: var(--vp-c-brand-1) !important;
234
241
  }
235
- `),
236
- StaticTypeScriptFile(path.join(cwd, ".vitepress", "config.mts"), `import { transformerTwoslash } from "@shikijs/vitepress-twoslash";
237
- import footnotePlugin from "markdown-it-footnote";
238
- import { defineConfig } from "vitepress";
239
-
240
- // https://vitepress.dev/reference/site-config
241
- export default defineConfig({
242
- title: ${JSON.stringify(props.title || "Alchemy")},
243
- description: ${JSON.stringify(props.description || "Alchemy Docs")},
244
- markdown: {
245
- // @ts-ignore
246
- codeTransformers: [transformerTwoslash()],
247
- theme: ${JSON.stringify(props.theme ?? {
248
- light: "light-plus",
249
- dark: "dark-plus",
250
- })},
251
- config: (md) => md.use(footnotePlugin),
252
- },
253
- // https://vitepress.dev/reference/default-theme-config
254
- themeConfig: ${JSON.stringify({
255
- ...props.themeConfig,
256
- search: props.themeConfig.search ?? { provider: "local" },
257
- nav: props.themeConfig.nav ?? [{ text: "Home", link: "/" }],
258
- sidebar: props.themeConfig.sidebar ?? [],
259
- socialLinks: props.themeConfig.socialLinks ?? [],
260
- })}
261
- });
262
242
  `),
263
243
  ]);
264
- return this(props);
244
+ return this({
245
+ ...props,
246
+ dir,
247
+ });
265
248
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "alchemy",
3
- "version": "0.3.0",
3
+ "version": "0.3.1",
4
4
  "type": "module",
5
5
  "module": "./lib/index.js",
6
6
  "scripts": {