@alexanderolsen/create-deepagent 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (193) hide show
  1. package/dist/index.d.ts +2 -0
  2. package/dist/index.js +661 -0
  3. package/dist/index.js.map +1 -0
  4. package/package.json +59 -0
  5. package/registry/frameworks/deno/.env.example +6 -0
  6. package/registry/frameworks/deno/README.md +137 -0
  7. package/registry/frameworks/deno/client/index.html +23 -0
  8. package/registry/frameworks/deno/client/package.json +30 -0
  9. package/registry/frameworks/deno/client/public/favicon.ico +0 -0
  10. package/registry/frameworks/deno/client/src/components/Chat.tsx +124 -0
  11. package/registry/frameworks/deno/client/src/components/ChatApp.tsx +129 -0
  12. package/registry/frameworks/deno/client/src/components/Conversation.tsx +91 -0
  13. package/registry/frameworks/deno/client/src/components/MessageBubbles.tsx +88 -0
  14. package/registry/frameworks/deno/client/src/components/MessageReasoning.tsx +71 -0
  15. package/registry/frameworks/deno/client/src/components/MessageThread.tsx +135 -0
  16. package/registry/frameworks/deno/client/src/components/StreamingIndicator.tsx +36 -0
  17. package/registry/frameworks/deno/client/src/components/Subagents.tsx +120 -0
  18. package/registry/frameworks/deno/client/src/components/ThemeIcons.tsx +31 -0
  19. package/registry/frameworks/deno/client/src/components/ThreadHistory.tsx +73 -0
  20. package/registry/frameworks/deno/client/src/components/ToolCall.tsx +89 -0
  21. package/registry/frameworks/deno/client/src/lib/agent-type.ts +4 -0
  22. package/registry/frameworks/deno/client/src/lib/chat/threads-client.ts +51 -0
  23. package/registry/frameworks/deno/client/src/main.tsx +11 -0
  24. package/registry/frameworks/deno/client/src/styles/globals.css +714 -0
  25. package/registry/frameworks/deno/client/src/vite-env.d.ts +1 -0
  26. package/registry/frameworks/deno/client/tsconfig.app.json +7 -0
  27. package/registry/frameworks/deno/client/tsconfig.json +24 -0
  28. package/registry/frameworks/deno/client/tsconfig.node.json +19 -0
  29. package/registry/frameworks/deno/client/vite.config.ts +24 -0
  30. package/registry/frameworks/deno/deno.json +16 -0
  31. package/registry/frameworks/deno/main.ts +23 -0
  32. package/registry/frameworks/deno/package.json +14 -0
  33. package/registry/frameworks/deno/server/agent/index.ts +60 -0
  34. package/registry/frameworks/deno/server/agent/middleware.ts +24 -0
  35. package/registry/frameworks/deno/server/agent/tools.ts +64 -0
  36. package/registry/frameworks/deno/server/registry.ts +40 -0
  37. package/registry/frameworks/deno/server/routes.ts +114 -0
  38. package/registry/frameworks/deno/server/serialize.ts +30 -0
  39. package/registry/frameworks/deno/server/session.ts +210 -0
  40. package/registry/frameworks/deno/server/threads.ts +404 -0
  41. package/registry/frameworks/deno.ts +17 -0
  42. package/registry/frameworks/hono/.env.example +6 -0
  43. package/registry/frameworks/hono/README.md +186 -0
  44. package/registry/frameworks/hono/index.html +22 -0
  45. package/registry/frameworks/hono/package.json +42 -0
  46. package/registry/frameworks/hono/src/components/Chat.tsx +124 -0
  47. package/registry/frameworks/hono/src/components/ChatApp.tsx +129 -0
  48. package/registry/frameworks/hono/src/components/Conversation.tsx +90 -0
  49. package/registry/frameworks/hono/src/components/MessageBubbles.tsx +88 -0
  50. package/registry/frameworks/hono/src/components/MessageReasoning.tsx +71 -0
  51. package/registry/frameworks/hono/src/components/MessageThread.tsx +135 -0
  52. package/registry/frameworks/hono/src/components/StreamingIndicator.tsx +36 -0
  53. package/registry/frameworks/hono/src/components/Subagents.tsx +120 -0
  54. package/registry/frameworks/hono/src/components/ThemeIcons.tsx +31 -0
  55. package/registry/frameworks/hono/src/components/ThreadHistory.tsx +73 -0
  56. package/registry/frameworks/hono/src/components/ToolCall.tsx +89 -0
  57. package/registry/frameworks/hono/src/lib/agent/types.ts +4 -0
  58. package/registry/frameworks/hono/src/lib/chat/threads-client.ts +57 -0
  59. package/registry/frameworks/hono/src/main.tsx +11 -0
  60. package/registry/frameworks/hono/src/styles/globals.css +714 -0
  61. package/registry/frameworks/hono/src/vite-env.d.ts +1 -0
  62. package/registry/frameworks/hono/tsconfig.app.json +22 -0
  63. package/registry/frameworks/hono/tsconfig.json +7 -0
  64. package/registry/frameworks/hono/tsconfig.worker.json +18 -0
  65. package/registry/frameworks/hono/vite.config.ts +16 -0
  66. package/registry/frameworks/hono/worker/agent/index.ts +53 -0
  67. package/registry/frameworks/hono/worker/agent/middleware.ts +20 -0
  68. package/registry/frameworks/hono/worker/agent/tools.ts +55 -0
  69. package/registry/frameworks/hono/worker/durable-objects/thread-session.ts +159 -0
  70. package/registry/frameworks/hono/worker/env.d.ts +17 -0
  71. package/registry/frameworks/hono/worker/index.ts +140 -0
  72. package/registry/frameworks/hono/worker/server/registry.ts +39 -0
  73. package/registry/frameworks/hono/worker/server/runs.ts +82 -0
  74. package/registry/frameworks/hono/worker/server/serialize.ts +30 -0
  75. package/registry/frameworks/hono/worker/server/threads.ts +404 -0
  76. package/registry/frameworks/hono/worker/tsconfig.json +4 -0
  77. package/registry/frameworks/hono/wrangler.jsonc +28 -0
  78. package/registry/frameworks/hono.ts +35 -0
  79. package/registry/frameworks/next/.env.example +6 -0
  80. package/registry/frameworks/next/README.md +173 -0
  81. package/registry/frameworks/next/app/api/threads/[threadId]/commands/route.ts +21 -0
  82. package/registry/frameworks/next/app/api/threads/[threadId]/history/route.ts +35 -0
  83. package/registry/frameworks/next/app/api/threads/[threadId]/route.ts +13 -0
  84. package/registry/frameworks/next/app/api/threads/[threadId]/state/route.ts +51 -0
  85. package/registry/frameworks/next/app/api/threads/[threadId]/stream/route.ts +30 -0
  86. package/registry/frameworks/next/app/api/threads/route.ts +11 -0
  87. package/registry/frameworks/next/app/favicon.ico +0 -0
  88. package/registry/frameworks/next/app/globals.css +712 -0
  89. package/registry/frameworks/next/app/layout.tsx +34 -0
  90. package/registry/frameworks/next/app/page.tsx +5 -0
  91. package/registry/frameworks/next/components/Chat.tsx +124 -0
  92. package/registry/frameworks/next/components/ChatApp.tsx +129 -0
  93. package/registry/frameworks/next/components/Conversation.tsx +90 -0
  94. package/registry/frameworks/next/components/MessageBubbles.tsx +88 -0
  95. package/registry/frameworks/next/components/MessageReasoning.tsx +71 -0
  96. package/registry/frameworks/next/components/MessageThread.tsx +135 -0
  97. package/registry/frameworks/next/components/StreamingIndicator.tsx +36 -0
  98. package/registry/frameworks/next/components/Subagents.tsx +120 -0
  99. package/registry/frameworks/next/components/ThemeIcons.tsx +31 -0
  100. package/registry/frameworks/next/components/ThreadHistory.tsx +73 -0
  101. package/registry/frameworks/next/components/ToolCall.tsx +89 -0
  102. package/registry/frameworks/next/eslint.config.mjs +18 -0
  103. package/registry/frameworks/next/lib/agent/index.ts +95 -0
  104. package/registry/frameworks/next/lib/agent/middleware.ts +40 -0
  105. package/registry/frameworks/next/lib/agent/tools.ts +66 -0
  106. package/registry/frameworks/next/lib/chat/threads-client.ts +57 -0
  107. package/registry/frameworks/next/lib/server/registry.ts +57 -0
  108. package/registry/frameworks/next/lib/server/serialize.ts +32 -0
  109. package/registry/frameworks/next/lib/server/session.ts +212 -0
  110. package/registry/frameworks/next/lib/server/threads.ts +406 -0
  111. package/registry/frameworks/next/next.config.ts +7 -0
  112. package/registry/frameworks/next/package.json +37 -0
  113. package/registry/frameworks/next/postcss.config.mjs +7 -0
  114. package/registry/frameworks/next/public/file.svg +1 -0
  115. package/registry/frameworks/next/public/globe.svg +1 -0
  116. package/registry/frameworks/next/public/next.svg +1 -0
  117. package/registry/frameworks/next/public/vercel.svg +1 -0
  118. package/registry/frameworks/next/public/window.svg +1 -0
  119. package/registry/frameworks/next/tsconfig.json +34 -0
  120. package/registry/frameworks/next.ts +17 -0
  121. package/registry/frameworks/nuxt/.env.example +3 -0
  122. package/registry/frameworks/nuxt/README.md +133 -0
  123. package/registry/frameworks/nuxt/app/app.vue +26 -0
  124. package/registry/frameworks/nuxt/app/assets/css/main.css +707 -0
  125. package/registry/frameworks/nuxt/app/components/Chat.vue +105 -0
  126. package/registry/frameworks/nuxt/app/components/ChatApp.vue +89 -0
  127. package/registry/frameworks/nuxt/app/components/ChatThread.vue +27 -0
  128. package/registry/frameworks/nuxt/app/components/MessageBubble.vue +60 -0
  129. package/registry/frameworks/nuxt/app/components/MessageBubbles.vue +213 -0
  130. package/registry/frameworks/nuxt/app/components/MessageList.vue +51 -0
  131. package/registry/frameworks/nuxt/app/components/MessageReasoning.vue +53 -0
  132. package/registry/frameworks/nuxt/app/components/StreamingIndicator.vue +9 -0
  133. package/registry/frameworks/nuxt/app/components/SubagentDetail.vue +51 -0
  134. package/registry/frameworks/nuxt/app/components/SubagentList.vue +49 -0
  135. package/registry/frameworks/nuxt/app/components/ThemeToggle.vue +43 -0
  136. package/registry/frameworks/nuxt/app/components/ThreadHistory.vue +65 -0
  137. package/registry/frameworks/nuxt/app/components/ToolCall.vue +81 -0
  138. package/registry/frameworks/nuxt/app/components/TypingDots.vue +14 -0
  139. package/registry/frameworks/nuxt/app/composables/useTheme.ts +14 -0
  140. package/registry/frameworks/nuxt/app/utils/streaming.ts +44 -0
  141. package/registry/frameworks/nuxt/app/utils/threads.ts +57 -0
  142. package/registry/frameworks/nuxt/nuxt.config.ts +6 -0
  143. package/registry/frameworks/nuxt/package.json +28 -0
  144. package/registry/frameworks/nuxt/public/favicon.ico +0 -0
  145. package/registry/frameworks/nuxt/public/robots.txt +2 -0
  146. package/registry/frameworks/nuxt/server/agent/index.ts +89 -0
  147. package/registry/frameworks/nuxt/server/agent/middleware.ts +38 -0
  148. package/registry/frameworks/nuxt/server/agent/tools.ts +66 -0
  149. package/registry/frameworks/nuxt/server/api/threads/[threadId]/commands.post.ts +16 -0
  150. package/registry/frameworks/nuxt/server/api/threads/[threadId]/history.post.ts +37 -0
  151. package/registry/frameworks/nuxt/server/api/threads/[threadId]/index.delete.ts +12 -0
  152. package/registry/frameworks/nuxt/server/api/threads/[threadId]/state.get.ts +22 -0
  153. package/registry/frameworks/nuxt/server/api/threads/[threadId]/state.post.ts +32 -0
  154. package/registry/frameworks/nuxt/server/api/threads/[threadId]/stream.post.ts +24 -0
  155. package/registry/frameworks/nuxt/server/api/threads/index.get.ts +13 -0
  156. package/registry/frameworks/nuxt/server/utils/runtime.ts +42 -0
  157. package/registry/frameworks/nuxt/server/utils/serialize.ts +30 -0
  158. package/registry/frameworks/nuxt/server/utils/session.ts +210 -0
  159. package/registry/frameworks/nuxt/server/utils/threads.ts +404 -0
  160. package/registry/frameworks/nuxt/tsconfig.json +18 -0
  161. package/registry/frameworks/nuxt.ts +17 -0
  162. package/registry/frameworks/vite/.env.example +20 -0
  163. package/registry/frameworks/vite/README.md +149 -0
  164. package/registry/frameworks/vite/agent/index.ts +59 -0
  165. package/registry/frameworks/vite/agent/middleware.ts +24 -0
  166. package/registry/frameworks/vite/agent/tools.ts +64 -0
  167. package/registry/frameworks/vite/index.html +23 -0
  168. package/registry/frameworks/vite/langgraph.json +16 -0
  169. package/registry/frameworks/vite/package.json +39 -0
  170. package/registry/frameworks/vite/public/favicon.ico +0 -0
  171. package/registry/frameworks/vite/scripts/vite-langgraph-proxy.ts +34 -0
  172. package/registry/frameworks/vite/src/components/Chat.tsx +124 -0
  173. package/registry/frameworks/vite/src/components/ChatApp.tsx +122 -0
  174. package/registry/frameworks/vite/src/components/Conversation.tsx +91 -0
  175. package/registry/frameworks/vite/src/components/MessageBubbles.tsx +88 -0
  176. package/registry/frameworks/vite/src/components/MessageReasoning.tsx +71 -0
  177. package/registry/frameworks/vite/src/components/MessageThread.tsx +135 -0
  178. package/registry/frameworks/vite/src/components/StreamingIndicator.tsx +36 -0
  179. package/registry/frameworks/vite/src/components/Subagents.tsx +120 -0
  180. package/registry/frameworks/vite/src/components/ThemeIcons.tsx +31 -0
  181. package/registry/frameworks/vite/src/components/ThreadHistory.tsx +73 -0
  182. package/registry/frameworks/vite/src/components/ToolCall.tsx +89 -0
  183. package/registry/frameworks/vite/src/lib/agent-type.ts +4 -0
  184. package/registry/frameworks/vite/src/lib/chat/threads-client.ts +114 -0
  185. package/registry/frameworks/vite/src/main.tsx +11 -0
  186. package/registry/frameworks/vite/src/styles/globals.css +714 -0
  187. package/registry/frameworks/vite/src/vite-env.d.ts +11 -0
  188. package/registry/frameworks/vite/tsconfig.app.json +24 -0
  189. package/registry/frameworks/vite/tsconfig.json +7 -0
  190. package/registry/frameworks/vite/tsconfig.node.json +21 -0
  191. package/registry/frameworks/vite/vercel.json +3 -0
  192. package/registry/frameworks/vite/vite.config.ts +24 -0
  193. package/registry/frameworks/vite.ts +17 -0
@@ -0,0 +1,2 @@
1
+
2
+ export { };
package/dist/index.js ADDED
@@ -0,0 +1,661 @@
1
+ #!/usr/bin/env node
2
+ import { Command } from "commander";
3
+ import fs from "node:fs";
4
+ import path from "node:path";
5
+ import { z } from "zod";
6
+ import * as clack from "@clack/prompts";
7
+ import { spinner } from "@clack/prompts";
8
+ import pc from "picocolors";
9
+ import { MODEL_PROVIDER_CONFIG } from "langchain/chat_models/universal";
10
+ import { inspect } from "node:util";
11
+ import { execSync } from "node:child_process";
12
+ import os from "node:os";
13
+ import { Readable } from "node:stream";
14
+ import { pipeline } from "node:stream/promises";
15
+ import { x } from "tar";
16
+ //#region src/utils/logger.ts
17
+ const logger = {
18
+ info: (msg) => console.log(pc.cyan(msg)),
19
+ success: (msg) => console.log(pc.green(msg)),
20
+ warn: (msg) => console.log(pc.yellow(msg)),
21
+ error: (msg) => console.error(pc.red(msg)),
22
+ break: () => console.log(),
23
+ step: (msg) => console.log(pc.dim("›") + " " + msg)
24
+ };
25
+ //#endregion
26
+ //#region src/utils/validate.ts
27
+ /** Check if a path exists and is a directory. */
28
+ async function dirExists(dir) {
29
+ try {
30
+ return (await fs.promises.stat(dir)).isDirectory();
31
+ } catch {
32
+ return false;
33
+ }
34
+ }
35
+ /** Check if an existing directory is empty. Throws if the dir cannot be read. */
36
+ async function isDirEmpty(dir) {
37
+ return (await fs.promises.readdir(dir)).length === 0;
38
+ }
39
+ /** Check if a directory is writable. */
40
+ async function isWriteable(dir) {
41
+ try {
42
+ await fs.promises.access(dir, fs.constants.W_OK);
43
+ return true;
44
+ } catch {
45
+ return false;
46
+ }
47
+ }
48
+ /** Ensure a directory exists, creating it if necessary. */
49
+ async function makeDir(dir) {
50
+ await fs.promises.mkdir(dir, { recursive: true });
51
+ }
52
+ /** Validate a npm package name. Returns an error message or null if valid. */
53
+ function validatePkgName(name) {
54
+ if (!name) return "Project name is required";
55
+ if (name.length > 214) return "Project name must be 214 characters or less";
56
+ if (name.startsWith(".") || name.startsWith("_")) return "Project name must not start with . or _";
57
+ if (name.toLowerCase() !== name) return "Project name must be lowercase";
58
+ if (/\s/.test(name)) return "Project name must not contain spaces";
59
+ if (!/^[a-z0-9._-]+$/.test(name)) return "Project name may only contain lowercase letters, numbers, ., _, and -";
60
+ return null;
61
+ }
62
+ //#endregion
63
+ //#region src/commands/create/preflightCreate.ts
64
+ /**
65
+ * Post-TUI checks before scaffolding. Fails fast on:
66
+ * - Invalid package name
67
+ * - Target directory not empty (unless --force or user confirms)
68
+ * - Target directory not writable
69
+ */
70
+ async function preflightCreate(options) {
71
+ const { projectName, force } = options;
72
+ const nameErr = validatePkgName(projectName);
73
+ if (nameErr) {
74
+ logger.error(nameErr);
75
+ process.exit(1);
76
+ }
77
+ const projectPath = path.resolve(projectName);
78
+ if (await dirExists(projectPath) && !force) {
79
+ if (!await isDirEmpty(projectPath)) {
80
+ const proceed = await clack.confirm({
81
+ message: `Directory "${projectName}" is not empty. Continue anyway?`,
82
+ initialValue: false
83
+ });
84
+ if (clack.isCancel(proceed) || proceed === false) {
85
+ clack.cancel("Cancelled, exiting...");
86
+ process.exit(0);
87
+ }
88
+ }
89
+ }
90
+ if (!await isWriteable(path.dirname(projectPath))) {
91
+ logger.error(`Cannot write to ${path.dirname(projectPath)}`);
92
+ process.exit(1);
93
+ }
94
+ return projectPath;
95
+ }
96
+ //#endregion
97
+ //#region src/registry/provider.ts
98
+ function createProvider(config) {
99
+ return {
100
+ ...config,
101
+ dependency: MODEL_PROVIDER_CONFIG[config.id].package,
102
+ chatModelClassName: MODEL_PROVIDER_CONFIG[config.id].className
103
+ };
104
+ }
105
+ //#endregion
106
+ //#region src/registry/files/model.ts
107
+ /**
108
+ * Create a ProviderAwareFile for `model.ts` that exports `coordinatorModel` and
109
+ * `subagentModel`, instantiated via direct constructor imports with the selected
110
+ * provider.
111
+ *
112
+ * @param agentPath - Path relative to project root, e.g. "lib/agent"
113
+ */
114
+ function createModelFile(agentPath) {
115
+ return {
116
+ path: `${agentPath}/model.ts`,
117
+ getContent: ({ providerConfig }) => {
118
+ const { defaultModel, coordinatorModelConfig, dependency, chatModelClassName } = providerConfig;
119
+ const coordinatorOptions = {
120
+ model: defaultModel,
121
+ ...coordinatorModelConfig ?? {}
122
+ };
123
+ return [
124
+ `import { ${chatModelClassName} } from "${dependency}";`,
125
+ "",
126
+ `const coordinatorModel = new ${chatModelClassName}(${inspect(coordinatorOptions, {
127
+ depth: null,
128
+ compact: false
129
+ })});`,
130
+ "",
131
+ `const subagentModel = new ${chatModelClassName}(${inspect({ model: defaultModel }, {
132
+ depth: null,
133
+ compact: false
134
+ })});`,
135
+ "",
136
+ "export { coordinatorModel, subagentModel };"
137
+ ].join("\n") + "\n";
138
+ }
139
+ };
140
+ }
141
+ //#endregion
142
+ //#region src/registry/files/envExample.ts
143
+ /**
144
+ * Create a ProviderAwareFile for `.env.example` with the provider's env var
145
+ * names and commented-out LangSmith tracing lines.
146
+ */
147
+ function createEnvExampleFile() {
148
+ return {
149
+ path: ".env.example",
150
+ getContent: ({ providerConfig }) => {
151
+ const { env } = providerConfig;
152
+ const lines = [];
153
+ for (const spec of env) {
154
+ const label = spec.prompt ?? spec.name;
155
+ lines.push(`# Required: ${label} used by the agent and its subagents.`);
156
+ lines.push(`${spec.name}=`);
157
+ }
158
+ lines.push("");
159
+ lines.push("# Optional: enable LangSmith tracing.");
160
+ lines.push("# LANGSMITH_TRACING=true");
161
+ lines.push("# LANGSMITH_API_KEY=lsv2-...");
162
+ return lines.join("\n") + "\n";
163
+ }
164
+ };
165
+ }
166
+ //#endregion
167
+ //#region src/registry/framework.ts
168
+ function createFramework(config) {
169
+ const defaultFiles = [createModelFile(config.agentPath), createEnvExampleFile()];
170
+ return {
171
+ ...config,
172
+ files: [...config.files, ...defaultFiles]
173
+ };
174
+ }
175
+ //#endregion
176
+ //#region registry/providers/openai.ts
177
+ const openai = createProvider({
178
+ id: "openai",
179
+ title: "OpenAI",
180
+ defaultModel: "gpt-5.4-mini",
181
+ coordinatorModelConfig: { reasoning: {
182
+ effort: "low",
183
+ summary: "auto"
184
+ } },
185
+ env: [{
186
+ name: "OPENAI_API_KEY",
187
+ prompt: "OpenAI API key",
188
+ required: false
189
+ }]
190
+ });
191
+ //#endregion
192
+ //#region registry/providers/anthropic.ts
193
+ const anthropic = createProvider({
194
+ id: "anthropic",
195
+ title: "Anthropic",
196
+ defaultModel: "claude-sonnet-4-5-20250929",
197
+ env: [{
198
+ name: "ANTHROPIC_API_KEY",
199
+ prompt: "Anthropic API key",
200
+ required: false
201
+ }]
202
+ });
203
+ //#endregion
204
+ //#region registry/providers/google.ts
205
+ const google = createProvider({
206
+ id: "google-genai",
207
+ title: "Google",
208
+ defaultModel: "gemini-3.5-flash",
209
+ env: [{
210
+ name: "GOOGLE_API_KEY",
211
+ prompt: "Google API key",
212
+ required: false
213
+ }]
214
+ });
215
+ //#endregion
216
+ //#region registry/providers/fireworks.ts
217
+ const fireworks = createProvider({
218
+ id: "fireworks",
219
+ title: "Fireworks",
220
+ defaultModel: "accounts/fireworks/models/glm-5p1",
221
+ env: [{
222
+ name: "FIREWORKS_API_KEY",
223
+ prompt: "Fireworks API key",
224
+ required: false
225
+ }]
226
+ });
227
+ //#endregion
228
+ //#region registry/frameworks/next.ts
229
+ const next = createFramework({
230
+ id: "next",
231
+ title: "Next.js",
232
+ defaultProjectName: "next-deepagents",
233
+ address: {
234
+ scheme: "github",
235
+ owner: "aolsenjazz",
236
+ repo: "deployment-cookbook",
237
+ subPath: "js-next"
238
+ },
239
+ envFilePath: ".env.local",
240
+ packageJsonPath: "package.json",
241
+ agentPath: "lib/agent",
242
+ files: []
243
+ });
244
+ //#endregion
245
+ //#region registry/frameworks/nuxt.ts
246
+ const nuxt = createFramework({
247
+ id: "nuxt",
248
+ title: "Nuxt",
249
+ defaultProjectName: "nuxt-deepagents",
250
+ address: {
251
+ scheme: "github",
252
+ owner: "aolsenjazz",
253
+ repo: "deployment-cookbook",
254
+ subPath: "js-nuxt"
255
+ },
256
+ envFilePath: ".env",
257
+ packageJsonPath: "package.json",
258
+ agentPath: "server/agent",
259
+ files: []
260
+ });
261
+ const hono = createFramework({
262
+ id: "hono",
263
+ title: "Hono",
264
+ defaultProjectName: "hono-deepagents",
265
+ address: {
266
+ scheme: "github",
267
+ owner: "aolsenjazz",
268
+ repo: "deployment-cookbook",
269
+ subPath: "js-cloudflare"
270
+ },
271
+ envFilePath: ".env",
272
+ packageJsonPath: "package.json",
273
+ agentPath: "worker/agent",
274
+ files: [{
275
+ path: "worker/env.d.ts",
276
+ getContent: ({ providerConfig }) => {
277
+ return `interface Env {
278
+ ASSETS: Fetcher;
279
+ SESSIONS: DurableObjectNamespace;
280
+ ${providerConfig.env.map((e) => ` ${e.name}: string;`).join("\n")}
281
+ [key: string]: string | undefined;
282
+ }
283
+ `;
284
+ }
285
+ }]
286
+ });
287
+ //#endregion
288
+ //#region registry/frameworks/deno.ts
289
+ const deno = createFramework({
290
+ id: "deno",
291
+ title: "Deno",
292
+ defaultProjectName: "deno-deepagents",
293
+ address: {
294
+ scheme: "github",
295
+ owner: "aolsenjazz",
296
+ repo: "deployment-cookbook",
297
+ subPath: "js-deno"
298
+ },
299
+ envFilePath: ".env",
300
+ packageJsonPath: "package.json",
301
+ agentPath: "server/agent",
302
+ files: []
303
+ });
304
+ //#endregion
305
+ //#region registry/frameworks/vite.ts
306
+ const vite = createFramework({
307
+ id: "react-vite",
308
+ title: "React + Vite",
309
+ defaultProjectName: "react-deepagents",
310
+ address: {
311
+ scheme: "github",
312
+ owner: "aolsenjazz",
313
+ repo: "deployment-cookbook",
314
+ subPath: "js-langsmith"
315
+ },
316
+ envFilePath: ".env",
317
+ packageJsonPath: "package.json",
318
+ agentPath: "agent",
319
+ files: []
320
+ });
321
+ //#endregion
322
+ //#region src/registry/index.ts
323
+ const providers = {
324
+ [openai.id]: openai,
325
+ [anthropic.id]: anthropic,
326
+ [google.id]: google,
327
+ [fireworks.id]: fireworks
328
+ };
329
+ const frameworks = {
330
+ [next.id]: next,
331
+ [nuxt.id]: nuxt,
332
+ [hono.id]: hono,
333
+ [vite.id]: vite,
334
+ [deno.id]: deno
335
+ };
336
+ //#endregion
337
+ //#region src/commands/create/runCreateConfig.ts
338
+ const PROCESSS_EXIT_MESSAGE = "Cancelled, exiting...";
339
+ /**
340
+ * Guides the user through the config TUI. On SIGINT, either moves to the next
341
+ * step or kills the process via `process.kill(0)`
342
+ */
343
+ async function runCreateConfig() {
344
+ clack.intro("create-deepagent");
345
+ const frameworkConfig = await selectFramework();
346
+ const providerConfig = await selectProvider();
347
+ const envVars = await collectEnvVars(providerConfig, frameworkConfig);
348
+ const tracing = await selectTracing() ?? false;
349
+ const langSmithKey = await collectLangSmithKey(tracing, frameworkConfig);
350
+ return {
351
+ frameworkChoice: frameworkConfig.id,
352
+ providerChoice: providerConfig.id,
353
+ envVars,
354
+ tracing,
355
+ langSmithKey
356
+ };
357
+ }
358
+ /** Prompt a user to select their framework */
359
+ async function selectFramework() {
360
+ const frameworkOptions = Object.values(frameworks).map((f) => ({
361
+ value: f.id,
362
+ label: f.title
363
+ }));
364
+ const frameworkChoice = await clack.select({
365
+ message: "Select your framework",
366
+ options: frameworkOptions
367
+ });
368
+ if (clack.isCancel(frameworkChoice)) {
369
+ clack.cancel(PROCESSS_EXIT_MESSAGE);
370
+ process.exit(0);
371
+ }
372
+ const framework = frameworks[frameworkChoice];
373
+ if (!framework) throw new Error(`Framework "${frameworkChoice}" not found`);
374
+ return framework;
375
+ }
376
+ /** Prompt a user to select their provider */
377
+ async function selectProvider() {
378
+ const providerOptions = Object.values(providers).map((p) => ({
379
+ value: p.id,
380
+ label: p.title
381
+ }));
382
+ const providerChoice = await clack.select({
383
+ message: "Select your provider",
384
+ options: providerOptions
385
+ });
386
+ if (clack.isCancel(providerChoice)) {
387
+ clack.cancel(PROCESSS_EXIT_MESSAGE);
388
+ process.exit(0);
389
+ }
390
+ const provider = providers[providerChoice];
391
+ if (!provider) throw new Error(`Provider "${providerChoice}" not found`);
392
+ return provider;
393
+ }
394
+ /** Prompt the user to enter env vars as are required by the provider spec */
395
+ async function collectEnvVars(provider, framework) {
396
+ const envVars = {};
397
+ for (const spec of provider.env) {
398
+ const optionalExitMessage = `Skipping ${spec.prompt}. You can add this later in ${framework.envFilePath}`;
399
+ const result = await clack.password({
400
+ message: `Enter ${spec.prompt ?? spec.name}${!spec.required && " (press enter to skip)?"}`,
401
+ mask: "*",
402
+ validate: (value) => {
403
+ if (typeof value !== "string" && spec.required === true) return `${spec.name} must not be empty.`;
404
+ if (value?.trim().length === 0) return `Invalid ${spec.name}. Try again.`;
405
+ }
406
+ });
407
+ const resultString = typeof result === "string" && result.trim() ? result.trim() : void 0;
408
+ if (clack.isCancel(result) || resultString === void 0) {
409
+ if (spec.required) {
410
+ clack.cancel(PROCESSS_EXIT_MESSAGE);
411
+ process.exit(0);
412
+ }
413
+ clack.cancel(optionalExitMessage);
414
+ continue;
415
+ }
416
+ envVars[spec.name] = resultString;
417
+ }
418
+ return envVars;
419
+ }
420
+ /** Prompt a user to enable tracing */
421
+ async function selectTracing() {
422
+ const tracing = await clack.confirm({
423
+ message: "Add LangSmith tracing?",
424
+ initialValue: false
425
+ });
426
+ if (clack.isCancel(tracing)) {
427
+ clack.cancel(PROCESSS_EXIT_MESSAGE);
428
+ process.exit(0);
429
+ }
430
+ return tracing;
431
+ }
432
+ /** Prompt a user for their LangSmith API if tracing is enabled */
433
+ async function collectLangSmithKey(tracing, framework) {
434
+ if (!tracing) return;
435
+ const exitMessage = `Skipping LangSmith API key. You can add this later in ${framework.envFilePath}`;
436
+ const result = await clack.password({
437
+ message: "Enter your LangSmith API key (press enter to skip)?",
438
+ mask: "*"
439
+ });
440
+ const resultString = typeof result === "string" && result.trim() ? result.trim() : void 0;
441
+ if (clack.isCancel(result) || resultString === void 0) {
442
+ clack.cancel(exitMessage);
443
+ return;
444
+ }
445
+ return resultString;
446
+ }
447
+ //#endregion
448
+ //#region src/utils/handleError.ts
449
+ function handleError(e) {
450
+ logger.break();
451
+ logger.error(`Something went wrong. Please check the error below for more details.`);
452
+ logger.error(`If the problem persists, please open an issue on GitHub.`);
453
+ logger.break();
454
+ if (e && typeof e === "object" && "name" in e && e.name === "ZodError") {
455
+ const { flatten } = e;
456
+ for (const [key, value] of Object.entries(flatten().fieldErrors)) logger.error(`- ${key}: ${value}`);
457
+ } else if (e && typeof e === "object" && "message" in e && typeof e.message === "string") logger.error(e.message);
458
+ }
459
+ //#endregion
460
+ //#region src/utils/fileUtils.ts
461
+ /**
462
+ * Copy a directory recursively. Filters out `node_modules` for dev ergonomics
463
+ */
464
+ async function copyDir(src, dest) {
465
+ await fs.promises.cp(src, dest, {
466
+ recursive: true,
467
+ filter: (source) => !source.includes("node_modules")
468
+ });
469
+ }
470
+ /** Loads a json file and asserts type. Performs no checks prior to read. */
471
+ function loadJsonSync(filePath) {
472
+ const raw = fs.readFileSync(filePath, "utf-8");
473
+ return JSON.parse(raw);
474
+ }
475
+ /**
476
+ * Write a file, creating parent directories as needed.
477
+ */
478
+ async function writeFile(filePath, content) {
479
+ const dir = path.dirname(filePath);
480
+ await fs.promises.mkdir(dir, { recursive: true });
481
+ await fs.promises.writeFile(filePath, content);
482
+ }
483
+ //#endregion
484
+ //#region src/utils/git.ts
485
+ /** Initialize a git repo and make an initial commit. Silently ignores failures. */
486
+ function gitInit(dir) {
487
+ const opts = {
488
+ cwd: dir,
489
+ stdio: "ignore"
490
+ };
491
+ try {
492
+ execSync("git init", opts);
493
+ execSync("git add -A", opts);
494
+ execSync("git commit -m \"Initial commit\"", opts);
495
+ } catch {}
496
+ }
497
+ //#endregion
498
+ //#region src/schema/packageJson.ts
499
+ const packageJsonSchema = z.looseObject({
500
+ name: z.string(),
501
+ dependencies: z.record(z.string(), z.string()),
502
+ packageManager: z.string().optional()
503
+ });
504
+ //#endregion
505
+ //#region src/commands/create/transformPackageJson.ts
506
+ /**
507
+ * Pure transformation of a template's package.json for the scaffolded project.
508
+ */
509
+ function transformPackageJson(packageJson, config) {
510
+ const result = {
511
+ ...packageJson,
512
+ dependencies: { ...packageJson.dependencies }
513
+ };
514
+ result.name = config.projectName;
515
+ for (const dep of Object.keys(result.dependencies)) if (config.providerDependencies.includes(dep)) delete result.dependencies[dep];
516
+ result.dependencies = {
517
+ ...result.dependencies,
518
+ [config.provider.dependency]: "latest"
519
+ };
520
+ delete result.packageManager;
521
+ return result;
522
+ }
523
+ //#endregion
524
+ //#region src/commands/create/installTemplate.ts
525
+ async function installTemplate(projectPath, framework) {
526
+ const { address } = framework;
527
+ switch (address.scheme) {
528
+ case "github":
529
+ await downloadGithubTemplate(address, projectPath);
530
+ break;
531
+ case "local":
532
+ await copyDir(address.path, projectPath);
533
+ break;
534
+ default: throw new Error(`Invalid address scheme. This should not happen`);
535
+ }
536
+ }
537
+ /**
538
+ * Download a GitHub template by fetching the repo tarball and extracting it
539
+ * into the project directory.
540
+ */
541
+ async function downloadGithubTemplate(address, dest) {
542
+ const tarballUrl = `https://codeload.github.com/${address.owner}/${address.repo}/tar.gz/HEAD`;
543
+ let tmpDir;
544
+ try {
545
+ tmpDir = await fs.promises.mkdtemp(path.join(os.tmpdir(), "create-deepagent"));
546
+ const response = await fetch(tarballUrl);
547
+ if (!response.ok || !response.body) throw new Error(`Failed to download template from GitHub: ${response.status} ${response.statusText}`);
548
+ const extractDir = path.join(tmpDir, "extracted");
549
+ await makeDir(extractDir);
550
+ await pipeline(Readable.fromWeb(response.body), x({
551
+ cwd: extractDir,
552
+ strip: 1
553
+ }));
554
+ if (await isDirEmpty(extractDir)) throw new Error(`Downloaded tarball for ${address.owner}/${address.repo} was empty.`);
555
+ const sourceDir = address.subPath ? path.join(extractDir, address.subPath) : extractDir;
556
+ if (address.subPath && !await dirExists(sourceDir)) throw new Error(`Subdirectory "${address.subPath}" not found in ${address.owner}/${address.repo}.`);
557
+ await copyDir(sourceDir, dest);
558
+ } catch (e) {
559
+ throw new Error(`Failed to install template from ${address.owner}/${address.repo}: ${e}`, { cause: e });
560
+ } finally {
561
+ if (tmpDir) await fs.promises.rm(tmpDir, {
562
+ recursive: true,
563
+ force: true
564
+ });
565
+ }
566
+ }
567
+ //#endregion
568
+ //#region src/commands/create/index.ts
569
+ const cliOptionsSchema = z.object({
570
+ name: z.string().optional(),
571
+ force: z.boolean().optional()
572
+ });
573
+ const create = new Command().name("create").description("Initialize your project and install dependencies").option("-f, --force", "Force overwrite of existing files").option("-n, --name <name>", "The name for the new project").action(async (opts) => {
574
+ try {
575
+ const options = mergeOptions(cliOptionsSchema.parse(opts), await runCreateConfig());
576
+ await runCreate(await preflightCreate(options), options);
577
+ } catch (e) {
578
+ handleError(e);
579
+ process.exit(1);
580
+ }
581
+ });
582
+ /**
583
+ * Merges CLI and TUI options. While CLI options are limited, this function will be
584
+ * pretty slim.
585
+ */
586
+ function mergeOptions(cliOptions, tuiOptions) {
587
+ const { name, force } = cliOptions;
588
+ const { frameworkChoice, envVars, langSmithKey, providerChoice, tracing } = tuiOptions;
589
+ const framework = frameworks[frameworkChoice];
590
+ return {
591
+ framework,
592
+ provider: providers[providerChoice],
593
+ projectName: name || framework.defaultProjectName,
594
+ force,
595
+ tracing,
596
+ langSmithKey,
597
+ envVars
598
+ };
599
+ }
600
+ async function runCreate(projectPath, options) {
601
+ const s = spinner();
602
+ try {
603
+ const { framework, provider, projectName } = options;
604
+ s.start(`Copying ${framework.title} template...`);
605
+ await installTemplate(projectPath, framework);
606
+ const envFile = createEnvFile(framework.envFilePath, options);
607
+ const allFiles = [...framework.files, envFile];
608
+ for (const file of allFiles) {
609
+ const content = file.getContent({ providerConfig: provider });
610
+ await writeFile(path.join(projectPath, file.path), content);
611
+ }
612
+ const packageJsonpath = path.join(projectPath, framework.packageJsonPath);
613
+ const transformed = transformPackageJson(packageJsonSchema.parse(loadJsonSync(packageJsonpath)), {
614
+ projectName,
615
+ provider,
616
+ providerDependencies: Object.values(providers).map((p) => p.dependency)
617
+ });
618
+ fs.writeFileSync(packageJsonpath, JSON.stringify(transformed, null, 2) + "\n");
619
+ gitInit(projectPath);
620
+ s.stop();
621
+ logger.break();
622
+ logger.success(`${framework.title} project created at ${projectName}`);
623
+ logger.break();
624
+ if (framework.postInit) framework.postInit({ projectPath });
625
+ } finally {
626
+ s.stop();
627
+ }
628
+ }
629
+ /**
630
+ * Create an env file with values the user fills in.
631
+ */
632
+ function createEnvFile(envFilePath, opts) {
633
+ const envVars = opts.envVars || {};
634
+ return {
635
+ path: envFilePath,
636
+ getContent: () => {
637
+ const lines = [];
638
+ for (const [key, value] of Object.entries(envVars)) lines.push(`${key}=${value}`);
639
+ if (opts.tracing) {
640
+ lines.push("LANGSMITH_TRACING=true");
641
+ if (opts.langSmithKey) lines.push(`LANGSMITH_API_KEY=${opts.langSmithKey}`);
642
+ }
643
+ return lines.join("\n") + "\n";
644
+ }
645
+ };
646
+ }
647
+ //#endregion
648
+ //#region package.json
649
+ var version = "0.1.0";
650
+ //#endregion
651
+ //#region src/index.ts
652
+ async function main() {
653
+ const program = new Command().name("create-deepagent").description("Scaffold a new Deep Agents project").version(version);
654
+ program.addCommand(create, { isDefault: true });
655
+ program.parse();
656
+ }
657
+ main();
658
+ //#endregion
659
+ export {};
660
+
661
+ //# sourceMappingURL=index.js.map