alchemy 0.0.8 → 0.1.2

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 (105) hide show
  1. package/README.md +355 -0
  2. package/package.json +24 -20
  3. package/src/alchemize.ts +151 -0
  4. package/src/apply.ts +117 -0
  5. package/src/components/agent/agent.ts +45 -0
  6. package/src/components/agent/anthropic.ts +27 -0
  7. package/src/components/agent/index.ts +4 -0
  8. package/src/components/agent/model.ts +22 -0
  9. package/src/components/agent/openai.ts +44 -0
  10. package/src/components/agent/package.ts +126 -0
  11. package/src/components/agent/requirements.ts +111 -0
  12. package/src/components/agent/scrape.ts +47 -0
  13. package/src/components/agent/tsconfig.ts +150 -0
  14. package/src/components/agent/typescript.ts +177 -0
  15. package/src/components/aws/bucket.ts +168 -0
  16. package/src/components/aws/function.ts +302 -0
  17. package/src/components/aws/index.ts +6 -0
  18. package/src/components/aws/policy.ts +245 -0
  19. package/src/components/aws/queue.ts +222 -0
  20. package/src/components/aws/role.ts +245 -0
  21. package/src/components/aws/table.ts +172 -0
  22. package/src/components/esbuild.ts +128 -0
  23. package/src/components/fs.ts +45 -0
  24. package/src/destroy.ts +63 -0
  25. package/src/error.ts +16 -0
  26. package/src/global.ts +72 -0
  27. package/src/index.ts +6 -0
  28. package/src/input.ts +16 -0
  29. package/src/main.ts +34 -0
  30. package/src/output.ts +49 -0
  31. package/src/resource.ts +313 -0
  32. package/src/state.ts +100 -0
  33. package/test/aws/function.test.ts +144 -0
  34. package/test/aws/queue.test.ts +85 -0
  35. package/test/aws/role.test.ts +153 -0
  36. package/test/aws/table.test.ts +73 -0
  37. package/test/esbuild.test.ts +41 -0
  38. package/test/handler.ts +9 -0
  39. package/tsconfig.json +7 -0
  40. package/Column.js +0 -1
  41. package/Create.js +0 -1
  42. package/Delete.js +0 -1
  43. package/Drop.js +0 -1
  44. package/Insert.js +0 -1
  45. package/Makefile +0 -8
  46. package/Select.js +0 -1
  47. package/Table.js +0 -1
  48. package/Transaction.js +0 -1
  49. package/Types.js +0 -1
  50. package/Update.js +0 -1
  51. package/alchemy.js +0 -57
  52. package/alchemy.sublime-project +0 -9
  53. package/alchemy.sublime-workspace +0 -2304
  54. package/config/app.js +0 -8
  55. package/config/db.js +0 -20
  56. package/copy.js +0 -1
  57. package/defaultEngine.js +0 -8
  58. package/engine.js +0 -282
  59. package/getInstantiatorFunction.js +0 -28
  60. package/index.js +0 -52
  61. package/jstest.js +0 -3
  62. package/loggerFactory.js +0 -27
  63. package/logs/alchemy.log +0 -46
  64. package/logs/sql.log +0 -41
  65. package/sql/Column.js +0 -158
  66. package/sql/Columnable.js +0 -21
  67. package/sql/Create.js +0 -15
  68. package/sql/Delete.js +0 -34
  69. package/sql/Drop.js +0 -36
  70. package/sql/Insert.js +0 -96
  71. package/sql/SchemaElement.js +0 -11
  72. package/sql/Select.js +0 -192
  73. package/sql/SqlBase.js +0 -134
  74. package/sql/SqlStatement.js +0 -80
  75. package/sql/Table.js +0 -96
  76. package/sql/Transaction.js +0 -45
  77. package/sql/Update.js +0 -105
  78. package/sql/defineElement.js +0 -26
  79. package/sql/defineStatement.js +0 -26
  80. package/sql/types/BaseType.js +0 -43
  81. package/sql/types/BigSerialType.js +0 -5
  82. package/sql/types/IntegerType.js +0 -5
  83. package/sql/types/JsonType.js +0 -5
  84. package/sql/types/SerialType.js +0 -5
  85. package/sql/types/StringType.js +0 -31
  86. package/sql/types/TimestampType.js +0 -5
  87. package/sql/types/UUIDType.js +0 -5
  88. package/sql/types/defineType.js +0 -25
  89. package/sql/types/getType.js +0 -12
  90. package/sql/types/index.js +0 -11
  91. package/sql/where.js +0 -31
  92. package/sql/whereToString.js +0 -29
  93. package/test/ColumnTests.js +0 -80
  94. package/test/CreateTable.js +0 -54
  95. package/test/DeleteTests.js +0 -28
  96. package/test/DropTests.js +0 -23
  97. package/test/GetTypeTests.js +0 -56
  98. package/test/InsertTests.js +0 -86
  99. package/test/SelectExistsTests.js +0 -26
  100. package/test/SelectTests.js +0 -130
  101. package/test/TableTests.js +0 -46
  102. package/test.js +0 -8
  103. package/test.ls +0 -4
  104. package/validate.js +0 -26
  105. package/x.js +0 -5
@@ -0,0 +1,45 @@
1
+ import type { ZodType } from "zod";
2
+ import { type Context, type Provider, Resource } from "../../resource";
3
+
4
+ export function Agent<Type extends string, TInput, TOutput>(
5
+ type: Type,
6
+ {
7
+ description,
8
+ input,
9
+ output,
10
+ }: {
11
+ description: string;
12
+ input: ZodType<TInput>;
13
+ output: ZodType<TOutput>;
14
+ },
15
+ handler: (ctx: Context<TOutput>, props: TInput) => Promise<TOutput | void>,
16
+ ): Provider<Type, [TInput], Awaited<TOutput>> & {
17
+ description: string;
18
+ input: ZodType<TInput>;
19
+ output: ZodType<TOutput>;
20
+ } {
21
+ // @ts-expect-error - we don't care that the props are not statically known, they will be visible outside this scope
22
+ return class Agent extends Resource(
23
+ type,
24
+ async (ctx: Context<TOutput>, props: TInput): Promise<TOutput | void> => {
25
+ // Validate input
26
+ const validatedInput = input.parse(props);
27
+
28
+ // Call handler with validated input
29
+ const result = await handler(ctx, validatedInput);
30
+
31
+ if (ctx.event === "delete") {
32
+ return;
33
+ }
34
+
35
+ // Validate output
36
+ const validatedOutput = output.parse(result);
37
+
38
+ return validatedOutput;
39
+ },
40
+ ) {
41
+ static readonly description = description;
42
+ static readonly input = input;
43
+ static readonly output = output;
44
+ };
45
+ }
@@ -0,0 +1,27 @@
1
+ /**
2
+ * @see https://docs.anthropic.com/en/docs/about-claude/models#model-comparison-table
3
+ */
4
+ export const AnthropicModels = [
5
+ // Claude 3.5 Sonnet models
6
+ "claude-3-5-sonnet",
7
+ "claude-3-5-sonnet-20241022",
8
+ "claude-3-5-sonnet-20240620",
9
+
10
+ // Claude 3.5 Haiku models
11
+ "claude-3-5-haiku",
12
+ "claude-3-5-haiku-20241022",
13
+
14
+ // Claude 3 models
15
+ "claude-3-opus",
16
+ "claude-3-opus-20240229",
17
+ "claude-3-sonnet",
18
+ "claude-3-sonnet-20240229",
19
+ "claude-3-haiku",
20
+ "claude-3-haiku-20240307",
21
+ ] as const;
22
+
23
+ export type AnthropicModelId = (typeof AnthropicModels)[number] | (string & {});
24
+
25
+ export function isAnthropicModel(model: string): model is AnthropicModelId {
26
+ return model.startsWith("claude-");
27
+ }
@@ -0,0 +1,4 @@
1
+ export * from "./package";
2
+ export * from "./requirements";
3
+ export * from "./tsconfig";
4
+ export * from "./typescript";
@@ -0,0 +1,22 @@
1
+ import { type AnthropicModelId, isAnthropicModel } from "./anthropic";
2
+ import { type OpenAIChatModelId, isOpenAIModel } from "./openai";
3
+
4
+ export type ModelId = OpenAIChatModelId | AnthropicModelId;
5
+
6
+ export async function resolveModel(modelId: ModelId) {
7
+ if (isOpenAIModel(modelId)) {
8
+ const { openai } = await import("@ai-sdk/openai");
9
+ return {
10
+ type: "openai" as const,
11
+ model: openai(modelId as OpenAIChatModelId),
12
+ };
13
+ }
14
+ if (isAnthropicModel(modelId)) {
15
+ const { anthropic } = await import("@ai-sdk/anthropic");
16
+ return {
17
+ type: "anthropic" as const,
18
+ model: anthropic(modelId as AnthropicModelId),
19
+ };
20
+ }
21
+ throw new Error(`Unsupported model ID: ${modelId}`);
22
+ }
@@ -0,0 +1,44 @@
1
+ export const OpenAIModels = [
2
+ // O1 models
3
+ "o1",
4
+ "o1-2024-12-17",
5
+ "o1-mini",
6
+ "o1-mini-2024-09-12",
7
+ "o1-preview",
8
+ "o1-preview-2024-09-12",
9
+
10
+ // GPT-4O models
11
+ "gpt-4o",
12
+ "gpt-4o-2024-05-13",
13
+ "gpt-4o-2024-08-06",
14
+ "gpt-4o-2024-11-20",
15
+ "gpt-4o-audio-preview",
16
+ "gpt-4o-audio-preview-2024-10-01",
17
+ "gpt-4o-audio-preview-2024-12-17",
18
+ "gpt-4o-mini",
19
+ "gpt-4o-mini-2024-07-18",
20
+
21
+ // GPT-4 models
22
+ "gpt-4-turbo",
23
+ "gpt-4-turbo-2024-04-09",
24
+ "gpt-4-turbo-preview",
25
+ "gpt-4-0125-preview",
26
+ "gpt-4-1106-preview",
27
+ "gpt-4",
28
+ "gpt-4-0613",
29
+
30
+ // GPT-3.5 models
31
+ "gpt-3.5-turbo-0125",
32
+ "gpt-3.5-turbo",
33
+ "gpt-3.5-turbo-1106",
34
+ ] as const;
35
+
36
+ export type OpenAIChatModelId = (typeof OpenAIModels)[number] | (string & {});
37
+
38
+ export function isOpenAIModel(model: string): model is OpenAIChatModelId {
39
+ return (
40
+ model.startsWith("gpt-") ||
41
+ model.startsWith("o1") ||
42
+ model.startsWith("gpt-4o")
43
+ );
44
+ }
@@ -0,0 +1,126 @@
1
+ import { generateObject } from "ai";
2
+ import { mkdir, unlink, writeFile } from "fs/promises";
3
+ import { dirname } from "path";
4
+ import { z } from "zod";
5
+ import { Agent } from "./agent";
6
+ import type { AnthropicModelId } from "./anthropic";
7
+ import { resolveModel } from "./model";
8
+ import type { OpenAIChatModelId } from "./openai";
9
+
10
+ export type ModelId = OpenAIChatModelId | AnthropicModelId;
11
+
12
+ export const PackageJsonSchema = z.object({
13
+ name: z.string(),
14
+ version: z.string(),
15
+ description: z.string().optional(),
16
+ main: z.string().optional(),
17
+ types: z.string().optional(),
18
+ type: z.literal("module"),
19
+ scripts: z.record(z.string()).optional(),
20
+ peerDependencies: z.record(z.string()).optional(),
21
+ peerDependenciesMeta: z
22
+ .record(z.object({ optional: z.boolean() }))
23
+ .optional(),
24
+ devDependencies: z.record(z.string()).optional(),
25
+ keywords: z.array(z.string()).optional(),
26
+ author: z.string().optional(),
27
+ license: z.string().optional(),
28
+ repository: z
29
+ .object({
30
+ type: z.string(),
31
+ url: z.string(),
32
+ })
33
+ .optional(),
34
+ exports: z.unknown().optional(),
35
+ files: z.array(z.string()).optional(),
36
+ });
37
+
38
+ export const PackageInput = z.object({
39
+ /**
40
+ * List of requirements for the package
41
+ * Can include dependencies, dev dependencies, scripts, etc.
42
+ */
43
+ requirements: z.array(z.string()),
44
+
45
+ /**
46
+ * Name of the package
47
+ */
48
+ name: z.string(),
49
+
50
+ /**
51
+ * The ID of the model to use for generating package configuration
52
+ * @default "gpt-4o"
53
+ */
54
+ model: z.string().optional(),
55
+
56
+ /**
57
+ * Temperature setting for model generation
58
+ * @default 0.3
59
+ */
60
+ temperature: z.number().optional(),
61
+
62
+ /**
63
+ * Path to the package.json file to generate
64
+ */
65
+ path: z.string(),
66
+ });
67
+
68
+ export type PackageInput = z.infer<typeof PackageInput>;
69
+ export type PackageOutput = z.infer<typeof PackageJsonSchema>;
70
+
71
+ export class PackageJson extends Agent(
72
+ "code::Package",
73
+ {
74
+ description:
75
+ "This Agent is responsible for generating package.json configuration based on requirements.",
76
+ input: PackageInput,
77
+ output: PackageJsonSchema,
78
+ },
79
+ async (ctx, input) => {
80
+ if (ctx.event === "delete") {
81
+ await unlink(input.path);
82
+ return;
83
+ }
84
+
85
+ // Get the appropriate model
86
+ const { model } = await resolveModel(input.model ?? "gpt-4o");
87
+
88
+ // Generate the package configuration using generateObject for type safety
89
+ const result = await generateObject({
90
+ model,
91
+ schema: PackageJsonSchema,
92
+ temperature: input.temperature ?? 0.3,
93
+ messages: [
94
+ {
95
+ role: "system",
96
+ content:
97
+ "You are an expert at creating Node.js/TypeScript package configurations. You will generate a package.json configuration based on requirements.",
98
+ },
99
+ {
100
+ role: "user",
101
+ content: `Please generate a package.json configuration based on these requirements:
102
+
103
+ Package name: ${input.name}
104
+
105
+ Requirements:
106
+ ${input.requirements.map((req) => `- ${req}`).join("\n")}
107
+
108
+ Rules:
109
+ 1. All dependencies must be peer dependencies
110
+ 2. Use latest stable versions for all dependencies
111
+ 3. Include standard TypeScript configuration in devDependencies
112
+ 4. Use "bun" as the package manager
113
+ 5. Must use ESM modules (type: "module")`,
114
+ },
115
+ ],
116
+ });
117
+
118
+ // Ensure the directory exists
119
+ await mkdir(dirname(input.path), { recursive: true });
120
+
121
+ // Write the package.json file
122
+ await writeFile(input.path, JSON.stringify(result.object, null, 2));
123
+
124
+ return result.object;
125
+ },
126
+ ) {}
@@ -0,0 +1,111 @@
1
+ import { generateText } from "ai";
2
+ import { mkdir, unlink, writeFile } from "fs/promises";
3
+ import { dirname } from "path";
4
+ import { z } from "zod";
5
+ import { Agent } from "./agent";
6
+ import { resolveModel } from "./model";
7
+ import { scrapeWebPage } from "./scrape";
8
+
9
+ export const RequirementsInput = z.object({
10
+ /**
11
+ * The ID of the model to use for generating requirements documentation
12
+ * @default "gpt-4o"
13
+ */
14
+ modelId: z.string().optional(),
15
+
16
+ /**
17
+ * List of requirements to document and analyze
18
+ */
19
+ requirements: z.array(z.string()),
20
+
21
+ /**
22
+ * One-line summary of the requirements document
23
+ */
24
+ title: z.string(),
25
+
26
+ /**
27
+ * Temperature setting for model generation (higher = more creative, lower = more focused)
28
+ * @default 0.7
29
+ */
30
+ temperature: z.number().optional(),
31
+
32
+ /**
33
+ * File path where the requirements document should be written
34
+ */
35
+ path: z.string(),
36
+ });
37
+
38
+ export const RequirementsOutput = z.object({
39
+ /**
40
+ * Generated markdown document containing organized and analyzed requirements
41
+ */
42
+ content: z.string(),
43
+ });
44
+
45
+ export type RequirementsInput = z.infer<typeof RequirementsInput>;
46
+ export type RequirementsOutput = z.infer<typeof RequirementsOutput>;
47
+
48
+ export class Requirements extends Agent(
49
+ "code::Requirements",
50
+ {
51
+ description:
52
+ "This Agent is responsible for writing and refining a detailed requirements document from a list of requirements.",
53
+ input: RequirementsInput,
54
+ output: RequirementsOutput,
55
+ },
56
+ async (ctx, input) => {
57
+ if (ctx.event === "delete") {
58
+ await unlink(input.path);
59
+ return;
60
+ }
61
+
62
+ // Get the appropriate model based on the ID
63
+ const { model } = await resolveModel(input.modelId ?? "gpt-4o");
64
+
65
+ // Generate the requirements document
66
+ const { text } = await generateText({
67
+ model,
68
+ temperature: input.temperature ?? 0.7,
69
+ maxSteps: 3, // Allow multiple steps for potential tool usage
70
+ tools: {
71
+ scrapeWebPage,
72
+ },
73
+ messages: [
74
+ {
75
+ role: "system",
76
+ content:
77
+ "You are a helpful assistant that creates markdown documents from requirements. You can use the scrapeWebPage tool to get additional requirements from relevant URLs if needed.",
78
+ },
79
+ {
80
+ role: "user",
81
+ content: `Please analyze the following system requirements and create a comprehensive, unambiguous markdown document that covers all aspects:
82
+
83
+ Title: ${input.title}
84
+
85
+ Requirements:
86
+ ${input.requirements.map((req) => `- ${req}`).join("\n")}
87
+
88
+ Guidelines:
89
+ 1. Make explicit decisions for any ambiguous requirements - do not leave open questions
90
+ 2. Document the reasoning behind key decisions
91
+ 3. Be specific about technical choices and implementation details
92
+ 4. Avoid phrases like "could be", "might need", or "possibly requires" - be definitive
93
+ 5. Organize requirements into logical sections with clear dependencies and relationships
94
+
95
+ Format the output in markdown with appropriate headers, lists, and sections, starting with the title as an H1 header.
96
+ Include technical considerations and implementation details, ensuring every requirement has a clear, actionable specification.`,
97
+ },
98
+ ],
99
+ });
100
+
101
+ // Ensure the directory exists
102
+ await mkdir(dirname(input.path), { recursive: true });
103
+
104
+ // Write the requirements to the file
105
+ await writeFile(input.path, text);
106
+
107
+ return {
108
+ content: text,
109
+ };
110
+ },
111
+ ) {}
@@ -0,0 +1,47 @@
1
+ import { tool } from "ai";
2
+ import TurndownService from "turndown";
3
+ import { z } from "zod";
4
+
5
+ export const scrapeWebPage = tool({
6
+ description: "Scrapes a web page and converts HTML content to Markdown",
7
+ parameters: z.object({
8
+ url: z.string().url().describe("The URL to scrape content from"),
9
+ turndownOptions: z
10
+ .object({
11
+ headingStyle: z.enum(["setext", "atx"]).optional(),
12
+ hr: z.string().optional(),
13
+ bulletListMarker: z.enum(["-", "*", "+"]).optional(),
14
+ codeBlockStyle: z.enum(["indented", "fenced"]).optional(),
15
+ emDelimiter: z.enum(["_", "*"]).optional(),
16
+ strongDelimiter: z.enum(["__", "**"]).optional(),
17
+ linkStyle: z.enum(["inlined", "referenced"]).optional(),
18
+ linkReferenceStyle: z
19
+ .enum(["full", "collapsed", "shortcut"])
20
+ .optional(),
21
+ })
22
+ .optional()
23
+ .describe("Custom options for Turndown HTML to Markdown conversion"),
24
+ }),
25
+ execute: async ({ url, turndownOptions }) => {
26
+ console.log("Scraping web page:", url);
27
+ try {
28
+ // Fetch the page content
29
+ const response = await fetch(url);
30
+ if (!response.ok) {
31
+ throw new Error(`Failed to fetch ${url}: ${response.statusText}`);
32
+ }
33
+
34
+ // Get the HTML content
35
+ const html = await response.text();
36
+
37
+ // Initialize Turndown with options
38
+ const turndownService = new TurndownService(turndownOptions);
39
+
40
+ // Convert HTML to Markdown and return
41
+ return turndownService.turndown(html);
42
+ } catch (error) {
43
+ console.error("Error scraping web page:", error);
44
+ throw error;
45
+ }
46
+ },
47
+ });
@@ -0,0 +1,150 @@
1
+ import { generateObject } from "ai";
2
+ import { mkdir, unlink, writeFile } from "fs/promises";
3
+ import { dirname } from "path";
4
+ import { z } from "zod";
5
+ import { Agent } from "./agent";
6
+ import { resolveModel } from "./model";
7
+
8
+ export type TsConfigProps = z.infer<typeof TsConfigProps>;
9
+
10
+ export const TsConfigProps = z.object({
11
+ /**
12
+ * The ID of the model to use for generating tsconfig configuration
13
+ * @default "gpt-4o"
14
+ */
15
+ modelId: z.string().optional(),
16
+
17
+ /**
18
+ * List of requirements for the TypeScript configuration
19
+ * Can include module settings, compilation options, etc.
20
+ */
21
+ requirements: z.array(z.string()),
22
+
23
+ /**
24
+ * Temperature setting for model generation
25
+ * @default 0.3
26
+ */
27
+ temperature: z.number().optional(),
28
+
29
+ /**
30
+ * Path to the tsconfig.json file to generate
31
+ */
32
+ path: z.string(),
33
+ });
34
+
35
+ export type TsConfigJson = z.infer<typeof TsConfigSchema>;
36
+ export const TsConfigSchema = z.object({
37
+ $schema: z.string().optional(),
38
+ compilerOptions: z.object({
39
+ target: z.enum([
40
+ "es2015",
41
+ "es2016",
42
+ "es2017",
43
+ "es2018",
44
+ "es2019",
45
+ "es2020",
46
+ "es2021",
47
+ "es2022",
48
+ "esnext",
49
+ ]),
50
+ module: z.enum([
51
+ "commonjs",
52
+ "es2015",
53
+ "es2020",
54
+ "es2022",
55
+ "esnext",
56
+ "node16",
57
+ "nodenext",
58
+ ]),
59
+ lib: z.array(z.string()).optional(),
60
+ declaration: z.boolean().optional(),
61
+ declarationMap: z.boolean().optional(),
62
+ sourceMap: z.boolean().optional(),
63
+ outDir: z.string().optional(),
64
+ rootDir: z.string().optional(),
65
+ strict: z.boolean(),
66
+ esModuleInterop: z.boolean().optional(),
67
+ skipLibCheck: z.boolean().optional(),
68
+ forceConsistentCasingInFileNames: z.boolean().optional(),
69
+ moduleResolution: z
70
+ .enum(["node", "node16", "nodenext", "bundler"])
71
+ .optional(),
72
+ resolveJsonModule: z.boolean().optional(),
73
+ isolatedModules: z.boolean().optional(),
74
+ allowJs: z.boolean().optional(),
75
+ checkJs: z.boolean().optional(),
76
+ noEmit: z.boolean().optional(),
77
+ incremental: z.boolean().optional(),
78
+ composite: z.boolean().optional(),
79
+ tsBuildInfoFile: z.string().optional(),
80
+ paths: z.record(z.array(z.string())).optional(),
81
+ baseUrl: z.string().optional(),
82
+ types: z.array(z.string()).optional(),
83
+ typeRoots: z.array(z.string()).optional(),
84
+ }),
85
+ include: z.array(z.string()).optional(),
86
+ exclude: z.array(z.string()).optional(),
87
+ references: z
88
+ .array(
89
+ z.object({
90
+ path: z.string(),
91
+ }),
92
+ )
93
+ .optional(),
94
+ });
95
+
96
+ export class TypeScriptConfig extends Agent(
97
+ "code::tsconfig",
98
+ {
99
+ description:
100
+ "This Agent is responsible for generating tsconfig.json configuration based on requirements.",
101
+ input: TsConfigProps,
102
+ output: TsConfigSchema,
103
+ },
104
+ async (ctx, props) => {
105
+ if (ctx.event === "delete") {
106
+ await unlink(props.path);
107
+ return;
108
+ }
109
+
110
+ // Get the appropriate model
111
+ const { model } = await resolveModel(props.modelId ?? "gpt-4o");
112
+
113
+ // Generate the tsconfig configuration using generateObject for type safety
114
+ const result = await generateObject({
115
+ model,
116
+ schema: TsConfigSchema,
117
+ temperature: props.temperature ?? 0.3,
118
+ messages: [
119
+ {
120
+ role: "system",
121
+ content:
122
+ "You are an expert at creating TypeScript configurations. You will generate a tsconfig.json configuration based on requirements.",
123
+ },
124
+ {
125
+ role: "user",
126
+ content: `Please generate a tsconfig.json configuration based on these requirements:
127
+
128
+ Requirements:
129
+ ${props.requirements.map((req) => `- ${req}`).join("\n")}
130
+
131
+ Rules:
132
+ 1. Use modern TypeScript features
133
+ 2. Enable strict type checking
134
+ 3. Use ESM modules by default
135
+ 4. Include source maps for better debugging
136
+ 5. Infer appropriate settings for declarations, module resolution, and other options based on the requirements
137
+ 6. Use appropriate paths for source and output directories`,
138
+ },
139
+ ],
140
+ });
141
+
142
+ // Ensure the directory exists
143
+ await mkdir(dirname(props.path), { recursive: true });
144
+
145
+ // Write the tsconfig.json file
146
+ await writeFile(props.path, JSON.stringify(result.object, null, 2));
147
+
148
+ return result.object;
149
+ },
150
+ ) {}