dexto 1.5.7 → 1.6.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 (178) hide show
  1. package/README.md +3 -3
  2. package/dist/agents/agent-template.yml +2 -2
  3. package/dist/agents/coding-agent/README.md +10 -10
  4. package/dist/agents/coding-agent/coding-agent.yml +81 -80
  5. package/dist/agents/default-agent.yml +32 -47
  6. package/dist/agents/explore-agent/explore-agent.yml +3 -6
  7. package/dist/agents/image-editor-agent/image-editor-agent.yml +1 -1
  8. package/dist/agents/nano-banana-agent/nano-banana-agent.yml +1 -1
  9. package/dist/agents/podcast-agent/podcast-agent.yml +1 -1
  10. package/dist/agents/product-name-researcher/product-name-researcher.yml +1 -1
  11. package/dist/agents/sora-video-agent/sora-video-agent.yml +4 -6
  12. package/dist/agents/triage-demo/triage-agent.yml +1 -1
  13. package/dist/analytics/events.d.ts +2 -2
  14. package/dist/analytics/events.d.ts.map +1 -1
  15. package/dist/api/mcp/tool-aggregation-handler.d.ts +2 -2
  16. package/dist/api/server-hono.d.ts +2 -2
  17. package/dist/api/server-hono.d.ts.map +1 -1
  18. package/dist/api/server-hono.js +37 -60
  19. package/dist/cli/approval/cli-approval-handler.d.ts +10 -3
  20. package/dist/cli/approval/cli-approval-handler.d.ts.map +1 -1
  21. package/dist/cli/approval/cli-approval-handler.js +1 -1
  22. package/dist/cli/auth/constants.d.ts +4 -0
  23. package/dist/cli/auth/constants.d.ts.map +1 -1
  24. package/dist/cli/auth/constants.js +4 -0
  25. package/dist/cli/commands/auth/logout.js +2 -2
  26. package/dist/cli/commands/billing/status.d.ts +3 -1
  27. package/dist/cli/commands/billing/status.d.ts.map +1 -1
  28. package/dist/cli/commands/billing/status.js +23 -1
  29. package/dist/cli/commands/create-app.d.ts +1 -11
  30. package/dist/cli/commands/create-app.d.ts.map +1 -1
  31. package/dist/cli/commands/create-app.js +21 -545
  32. package/dist/cli/commands/create-image.d.ts.map +1 -1
  33. package/dist/cli/commands/create-image.js +54 -53
  34. package/dist/cli/commands/image.d.ts +52 -0
  35. package/dist/cli/commands/image.d.ts.map +1 -0
  36. package/dist/cli/commands/image.js +118 -0
  37. package/dist/cli/commands/index.d.ts +2 -1
  38. package/dist/cli/commands/index.d.ts.map +1 -1
  39. package/dist/cli/commands/index.js +3 -1
  40. package/dist/cli/commands/init-app.d.ts +4 -8
  41. package/dist/cli/commands/init-app.d.ts.map +1 -1
  42. package/dist/cli/commands/init-app.js +37 -161
  43. package/dist/cli/commands/interactive-commands/command-parser.d.ts +2 -0
  44. package/dist/cli/commands/interactive-commands/command-parser.d.ts.map +1 -1
  45. package/dist/cli/commands/interactive-commands/commands.d.ts +1 -1
  46. package/dist/cli/commands/interactive-commands/commands.d.ts.map +1 -1
  47. package/dist/cli/commands/interactive-commands/commands.js +2 -2
  48. package/dist/cli/commands/interactive-commands/general-commands.js +2 -2
  49. package/dist/cli/commands/interactive-commands/prompt-commands.d.ts.map +1 -1
  50. package/dist/cli/commands/interactive-commands/prompt-commands.js +13 -2
  51. package/dist/cli/commands/interactive-commands/session/index.d.ts +2 -1
  52. package/dist/cli/commands/interactive-commands/session/index.d.ts.map +1 -1
  53. package/dist/cli/commands/interactive-commands/session/index.js +2 -1
  54. package/dist/cli/commands/interactive-commands/session/session-commands.d.ts +2 -2
  55. package/dist/cli/commands/interactive-commands/session/session-commands.js +2 -2
  56. package/dist/cli/commands/interactive-commands/system/system-commands.d.ts.map +1 -1
  57. package/dist/cli/commands/interactive-commands/system/system-commands.js +7 -29
  58. package/dist/cli/commands/list-agents.d.ts.map +1 -1
  59. package/dist/cli/commands/list-agents.js +3 -2
  60. package/dist/cli/commands/plugin.d.ts +4 -4
  61. package/dist/cli/commands/setup.d.ts +5 -5
  62. package/dist/cli/commands/setup.d.ts.map +1 -1
  63. package/dist/cli/commands/setup.js +766 -207
  64. package/dist/cli/commands/sync-agents.d.ts +2 -12
  65. package/dist/cli/commands/sync-agents.d.ts.map +1 -1
  66. package/dist/cli/commands/sync-agents.js +2 -50
  67. package/dist/cli/ink-cli/InkCLIRefactored.d.ts +7 -1
  68. package/dist/cli/ink-cli/InkCLIRefactored.d.ts.map +1 -1
  69. package/dist/cli/ink-cli/InkCLIRefactored.js +17 -7
  70. package/dist/cli/ink-cli/components/ApprovalPrompt.d.ts +2 -2
  71. package/dist/cli/ink-cli/components/ApprovalPrompt.d.ts.map +1 -1
  72. package/dist/cli/ink-cli/components/ApprovalPrompt.js +15 -14
  73. package/dist/cli/ink-cli/components/BackgroundTasksPanel.d.ts +18 -0
  74. package/dist/cli/ink-cli/components/BackgroundTasksPanel.d.ts.map +1 -0
  75. package/dist/cli/ink-cli/components/BackgroundTasksPanel.js +48 -0
  76. package/dist/cli/ink-cli/components/ErrorBoundary.js +1 -1
  77. package/dist/cli/ink-cli/components/Footer.d.ts.map +1 -1
  78. package/dist/cli/ink-cli/components/Footer.js +5 -6
  79. package/dist/cli/ink-cli/components/ResourceAutocomplete.d.ts.map +1 -1
  80. package/dist/cli/ink-cli/components/ResourceAutocomplete.js +150 -41
  81. package/dist/cli/ink-cli/components/StatusBar.d.ts +3 -1
  82. package/dist/cli/ink-cli/components/StatusBar.d.ts.map +1 -1
  83. package/dist/cli/ink-cli/components/StatusBar.js +27 -7
  84. package/dist/cli/ink-cli/components/TodoPanel.js +1 -1
  85. package/dist/cli/ink-cli/components/chat/MessageItem.d.ts.map +1 -1
  86. package/dist/cli/ink-cli/components/chat/MessageItem.js +9 -5
  87. package/dist/cli/ink-cli/components/chat/styled-boxes/ConfigBox.js +1 -1
  88. package/dist/cli/ink-cli/components/modes/AlternateBufferCLI.d.ts +3 -1
  89. package/dist/cli/ink-cli/components/modes/AlternateBufferCLI.d.ts.map +1 -1
  90. package/dist/cli/ink-cli/components/modes/AlternateBufferCLI.js +3 -2
  91. package/dist/cli/ink-cli/components/modes/StaticCLI.d.ts +3 -1
  92. package/dist/cli/ink-cli/components/modes/StaticCLI.d.ts.map +1 -1
  93. package/dist/cli/ink-cli/components/modes/StaticCLI.js +3 -2
  94. package/dist/cli/ink-cli/components/overlays/ContextStatsOverlay.js +1 -1
  95. package/dist/cli/ink-cli/components/overlays/CustomModelWizard.d.ts.map +1 -1
  96. package/dist/cli/ink-cli/components/overlays/CustomModelWizard.js +8 -4
  97. package/dist/cli/ink-cli/components/overlays/LogLevelSelector.js +1 -1
  98. package/dist/cli/ink-cli/components/overlays/McpRemoveSelector.js +1 -1
  99. package/dist/cli/ink-cli/components/overlays/ModelSelectorRefactored.d.ts +1 -0
  100. package/dist/cli/ink-cli/components/overlays/ModelSelectorRefactored.d.ts.map +1 -1
  101. package/dist/cli/ink-cli/components/overlays/ModelSelectorRefactored.js +144 -41
  102. package/dist/cli/ink-cli/components/overlays/ToolBrowser.d.ts +2 -1
  103. package/dist/cli/ink-cli/components/overlays/ToolBrowser.d.ts.map +1 -1
  104. package/dist/cli/ink-cli/components/overlays/ToolBrowser.js +286 -44
  105. package/dist/cli/ink-cli/components/overlays/custom-model-wizard/provider-config.d.ts +9 -1
  106. package/dist/cli/ink-cli/components/overlays/custom-model-wizard/provider-config.d.ts.map +1 -1
  107. package/dist/cli/ink-cli/components/overlays/custom-model-wizard/provider-config.js +35 -9
  108. package/dist/cli/ink-cli/constants/tips.js +1 -1
  109. package/dist/cli/ink-cli/containers/InputContainer.d.ts +4 -0
  110. package/dist/cli/ink-cli/containers/InputContainer.d.ts.map +1 -1
  111. package/dist/cli/ink-cli/containers/InputContainer.js +30 -8
  112. package/dist/cli/ink-cli/containers/OverlayContainer.d.ts +2 -0
  113. package/dist/cli/ink-cli/containers/OverlayContainer.d.ts.map +1 -1
  114. package/dist/cli/ink-cli/containers/OverlayContainer.js +215 -59
  115. package/dist/cli/ink-cli/hooks/useAgentEvents.d.ts.map +1 -1
  116. package/dist/cli/ink-cli/hooks/useAgentEvents.js +73 -13
  117. package/dist/cli/ink-cli/hooks/useCLIState.d.ts.map +1 -1
  118. package/dist/cli/ink-cli/hooks/useCLIState.js +3 -0
  119. package/dist/cli/ink-cli/hooks/useInputOrchestrator.d.ts.map +1 -1
  120. package/dist/cli/ink-cli/hooks/useInputOrchestrator.js +8 -0
  121. package/dist/cli/ink-cli/hooks/useTokenCounter.d.ts.map +1 -1
  122. package/dist/cli/ink-cli/hooks/useTokenCounter.js +7 -4
  123. package/dist/cli/ink-cli/services/CommandService.d.ts +1 -1
  124. package/dist/cli/ink-cli/services/CommandService.d.ts.map +1 -1
  125. package/dist/cli/ink-cli/services/CommandService.js +2 -2
  126. package/dist/cli/ink-cli/services/processStream.d.ts +2 -2
  127. package/dist/cli/ink-cli/services/processStream.d.ts.map +1 -1
  128. package/dist/cli/ink-cli/services/processStream.js +55 -8
  129. package/dist/cli/ink-cli/state/initialState.d.ts.map +1 -1
  130. package/dist/cli/ink-cli/state/initialState.js +3 -0
  131. package/dist/cli/ink-cli/state/types.d.ts +11 -2
  132. package/dist/cli/ink-cli/state/types.d.ts.map +1 -1
  133. package/dist/cli/ink-cli/utils/llm-provider-display.d.ts +3 -0
  134. package/dist/cli/ink-cli/utils/llm-provider-display.d.ts.map +1 -0
  135. package/dist/cli/ink-cli/utils/llm-provider-display.js +22 -0
  136. package/dist/cli/ink-cli/utils/messageFormatting.d.ts +13 -9
  137. package/dist/cli/ink-cli/utils/messageFormatting.d.ts.map +1 -1
  138. package/dist/cli/ink-cli/utils/messageFormatting.js +106 -151
  139. package/dist/cli/ink-cli/utils/toolUtils.d.ts.map +1 -1
  140. package/dist/cli/ink-cli/utils/toolUtils.js +2 -9
  141. package/dist/cli/utils/config-validation.d.ts +11 -11
  142. package/dist/cli/utils/config-validation.d.ts.map +1 -1
  143. package/dist/cli/utils/config-validation.js +56 -290
  144. package/dist/cli/utils/dexto-auth-check.d.ts +7 -7
  145. package/dist/cli/utils/dexto-auth-check.d.ts.map +1 -1
  146. package/dist/cli/utils/dexto-auth-check.js +16 -16
  147. package/dist/cli/utils/image-store.d.ts +16 -0
  148. package/dist/cli/utils/image-store.d.ts.map +1 -0
  149. package/dist/cli/utils/image-store.js +289 -0
  150. package/dist/cli/utils/options.js +1 -1
  151. package/dist/cli/utils/provider-setup.d.ts +2 -2
  152. package/dist/cli/utils/provider-setup.d.ts.map +1 -1
  153. package/dist/cli/utils/provider-setup.js +10 -2
  154. package/dist/cli/utils/scaffolding-utils.d.ts +5 -0
  155. package/dist/cli/utils/scaffolding-utils.d.ts.map +1 -1
  156. package/dist/cli/utils/scaffolding-utils.js +46 -4
  157. package/dist/cli/utils/template-engine.d.ts +28 -16
  158. package/dist/cli/utils/template-engine.d.ts.map +1 -1
  159. package/dist/cli/utils/template-engine.js +339 -479
  160. package/dist/config/cli-overrides.d.ts +4 -3
  161. package/dist/config/cli-overrides.d.ts.map +1 -1
  162. package/dist/config/cli-overrides.js +8 -10
  163. package/dist/config/effective-llm.d.ts +4 -4
  164. package/dist/config/effective-llm.d.ts.map +1 -1
  165. package/dist/config/effective-llm.js +4 -4
  166. package/dist/index-main.d.ts +2 -0
  167. package/dist/index-main.d.ts.map +1 -0
  168. package/dist/index-main.js +1554 -0
  169. package/dist/index.js +2 -1580
  170. package/dist/utils/session-logger-factory.d.ts +3 -0
  171. package/dist/utils/session-logger-factory.d.ts.map +1 -0
  172. package/dist/utils/session-logger-factory.js +19 -0
  173. package/dist/webui/assets/{index-Dl3mj53P.js → index-DwtueA8l.js} +231 -231
  174. package/dist/webui/index.html +1 -1
  175. package/package.json +10 -7
  176. package/dist/cli/cli-subscriber.d.ts +0 -45
  177. package/dist/cli/cli-subscriber.d.ts.map +0 -1
  178. package/dist/cli/cli-subscriber.js +0 -204
@@ -2,21 +2,12 @@ import fs from 'fs-extra';
2
2
  import path from 'path';
3
3
  import chalk from 'chalk';
4
4
  import * as p from '@clack/prompts';
5
- import { logger } from '@dexto/core';
6
- import { selectOrExit, textOrExit } from '../utils/prompt-helpers.js';
7
- import { promptForProjectName, createProjectDirectory, setupGitRepo, createGitignore, initPackageJson, createTsconfigForApp, installDependencies, createEnvExample, ensureDirectory, } from '../utils/scaffolding-utils.js';
8
- import { generateIndexForImage, generateWebServerIndex, generateWebAppHTML, generateWebAppJS, generateWebAppCSS, generateAppReadme, generateExampleTool, generateDiscoveryScript, } from '../utils/template-engine.js';
5
+ import { selectOrExit } from '../utils/prompt-helpers.js';
6
+ import { promptForProjectName, createProjectDirectory, setupGitRepo, createGitignore, initPackageJson, createTsconfigForApp, installDependencies, createEnvExample, ensureDirectory, getDextoVersionRange, } from '../utils/scaffolding-utils.js';
7
+ import { generateIndexForCodeFirstDI, generateWebServerIndexForCodeFirstDI, generateWebAppHTML, generateWebAppJS, generateWebAppCSS, generateAppReadme, } from '../utils/template-engine.js';
9
8
  import { getExecutionContext } from '@dexto/agent-management';
10
9
  /**
11
- * Creates a Dexto application with two possible modes:
12
- * - from-image: Use existing image (recommended)
13
- * - from-core: Build from @dexto/core with custom providers (advanced)
14
- *
15
- * Note: To create a new image that extends another image, use `dexto create-image` instead.
16
- *
17
- * @param name - Optional name of the app project
18
- * @param options - Optional flags to specify mode and base image
19
- * @returns The absolute path to the created project directory
10
+ * Creates a Dexto application that runs an agent using programmatic configuration.
20
11
  */
21
12
  export async function createDextoProject(name, options) {
22
13
  console.log(chalk.blue('🚀 Creating a Dexto application\n'));
@@ -25,16 +16,12 @@ export async function createDextoProject(name, options) {
25
16
  ? name
26
17
  : await promptForProjectName('my-dexto-app', 'What do you want to name your app?');
27
18
  // Step 2: Determine app type
28
- let appType = options?.type || 'script';
19
+ let appType = options?.type ?? 'script';
29
20
  if (!options?.type) {
30
21
  appType = await selectOrExit({
31
22
  message: 'What type of app?',
32
23
  options: [
33
- {
34
- value: 'script',
35
- label: 'Script',
36
- hint: 'Simple script (default)',
37
- },
24
+ { value: 'script', label: 'Script', hint: 'Simple script (default)' },
38
25
  {
39
26
  value: 'webapp',
40
27
  label: 'Web App',
@@ -43,84 +30,13 @@ export async function createDextoProject(name, options) {
43
30
  ],
44
31
  }, 'App creation cancelled');
45
32
  }
46
- // Step 3: Determine app mode (from flags or prompt)
47
- let mode;
48
- let baseImage;
49
- if (options?.fromCore) {
50
- mode = 'from-core';
51
- }
52
- else if (options?.fromImage) {
53
- mode = 'from-image';
54
- baseImage = options.fromImage;
55
- }
56
- else {
57
- // No flags provided, use interactive prompt
58
- mode = await selectOrExit({
59
- message: 'How do you want to start?',
60
- options: [
61
- {
62
- value: 'from-image',
63
- label: 'Use existing image (recommended)',
64
- hint: 'Pre-built image with providers',
65
- },
66
- {
67
- value: 'from-core',
68
- label: 'Build from core (advanced)',
69
- hint: 'Custom standalone app with your own providers',
70
- },
71
- ],
72
- }, 'App creation cancelled');
73
- }
74
33
  const spinner = p.spinner();
75
- let projectPath;
76
34
  const originalCwd = process.cwd();
35
+ let projectPath;
77
36
  try {
78
- // Create project directory
79
37
  projectPath = await createProjectDirectory(projectName, spinner);
80
- // Change to project directory
81
38
  process.chdir(projectPath);
82
- if (mode === 'from-core') {
83
- // Mode C: Build from core - custom image with bundler
84
- await scaffoldFromCore(projectPath, projectName, spinner);
85
- spinner.stop(chalk.green(`✓ Successfully created app: ${projectName}`));
86
- console.log(`\n${chalk.cyan('Next steps:')}`);
87
- console.log(` ${chalk.gray('$')} cd ${projectName}`);
88
- console.log(` ${chalk.gray('$')} pnpm start ${chalk.gray('(discovers providers, builds, and runs)')}`);
89
- console.log(`\n${chalk.gray('Learn more:')} https://docs.dexto.ai\n`);
90
- return projectPath;
91
- }
92
- // For from-image mode, select the image (if not already provided via flag)
93
- if (!baseImage) {
94
- const imageChoice = await selectOrExit({
95
- message: 'Which image?',
96
- options: [
97
- {
98
- value: '@dexto/image-local',
99
- label: '@dexto/image-local (recommended)',
100
- hint: 'Local dev - SQLite, filesystem',
101
- },
102
- { value: 'custom', label: 'Custom npm package...' },
103
- ],
104
- }, 'App creation cancelled');
105
- if (imageChoice === 'custom') {
106
- const customImage = await textOrExit({
107
- message: 'Enter the npm package name:',
108
- placeholder: '@myorg/image-custom',
109
- validate: (value) => {
110
- if (!value || value.trim() === '') {
111
- return 'Package name is required';
112
- }
113
- return undefined;
114
- },
115
- }, 'App creation cancelled');
116
- baseImage = customImage;
117
- }
118
- else {
119
- baseImage = imageChoice;
120
- }
121
- }
122
- // Scaffold from existing image
123
- await scaffoldFromImage(projectPath, projectName, baseImage, appType, originalCwd, spinner);
39
+ await scaffoldCodeFirstDI(projectPath, projectName, appType, spinner);
124
40
  spinner.stop(chalk.green(`✓ Successfully created app: ${projectName}`));
125
41
  console.log(`\n${chalk.cyan('Next steps:')}`);
126
42
  console.log(` ${chalk.gray('$')} cd ${projectName}`);
@@ -145,45 +61,19 @@ export async function createDextoProject(name, options) {
145
61
  }
146
62
  }
147
63
  /**
148
- * Mode A: Scaffold app using existing image
64
+ * Scaffold an app using programmatic configuration.
149
65
  */
150
- async function scaffoldFromImage(projectPath, projectName, imageName, appType, originalCwd, spinner) {
66
+ async function scaffoldCodeFirstDI(projectPath, projectName, appType, spinner) {
151
67
  spinner.start('Setting up app structure...');
152
- // Resolve package name for local images (needed for import statements)
153
- let packageNameForImport = imageName;
154
- if (imageName.startsWith('.')) {
155
- const fullPath = path.resolve(originalCwd, imageName);
156
- let packageDir = fullPath;
157
- // If path ends with /dist/index.js, resolve to package root (parent of dist)
158
- if (fullPath.endsWith('/dist/index.js') || fullPath.endsWith('\\dist\\index.js')) {
159
- packageDir = path.dirname(path.dirname(fullPath));
160
- }
161
- else if (fullPath.endsWith('.js')) {
162
- packageDir = path.dirname(fullPath);
163
- }
164
- // Read package.json to get the actual package name for imports
165
- try {
166
- const pkgJsonPath = path.join(packageDir, 'package.json');
167
- const pkgJson = JSON.parse(await fs.readFile(pkgJsonPath, 'utf8'));
168
- packageNameForImport = pkgJson.name;
169
- }
170
- catch (_error) {
171
- logger.warn(`Could not read package.json from ${packageDir}, using path as import`);
172
- }
173
- }
174
- // Create folders
175
68
  await ensureDirectory('src');
176
- await ensureDirectory('agents');
177
69
  // Create src/index.ts based on app type
178
70
  let indexContent;
179
71
  if (appType === 'webapp') {
180
- indexContent = generateWebServerIndex({
72
+ indexContent = generateWebServerIndexForCodeFirstDI({
181
73
  projectName,
182
74
  packageName: projectName,
183
75
  description: 'Dexto web server application',
184
- imageName: packageNameForImport,
185
76
  });
186
- // Create web app directory and files
187
77
  await ensureDirectory('app');
188
78
  await ensureDirectory('app/assets');
189
79
  await fs.writeFile('app/index.html', generateWebAppHTML(projectName));
@@ -191,69 +81,15 @@ async function scaffoldFromImage(projectPath, projectName, imageName, appType, o
191
81
  await fs.writeFile('app/assets/style.css', generateWebAppCSS());
192
82
  }
193
83
  else {
194
- indexContent = generateIndexForImage({
84
+ indexContent = generateIndexForCodeFirstDI({
195
85
  projectName,
196
86
  packageName: projectName,
197
87
  description: 'Dexto application',
198
- imageName: packageNameForImport,
199
88
  });
200
89
  }
201
90
  await fs.writeFile('src/index.ts', indexContent);
202
- // Create default agent config
203
- const agentConfig = `# Default Agent Configuration
204
-
205
- # Image: Specifies the provider bundle for this agent
206
- image: '${imageName}'
207
-
208
- # System prompt
209
- systemPrompt:
210
- contributors:
211
- - id: primary
212
- type: static
213
- priority: 0
214
- content: |
215
- You are a helpful AI assistant.
216
-
217
- # LLM configuration
218
- llm:
219
- provider: openai
220
- model: gpt-4o
221
- apiKey: $OPENAI_API_KEY
222
-
223
- # Storage
224
- storage:
225
- cache:
226
- type: in-memory
227
- database:
228
- type: sqlite
229
- path: ./data/agent.db
230
- blob:
231
- type: local
232
- storePath: ./data/blobs
233
-
234
- # Custom tools - uncomment to enable filesystem and process tools
235
- # customTools:
236
- # - type: filesystem-tools
237
- # allowedPaths: ['.']
238
- # blockedPaths: ['.git', 'node_modules']
239
- # - type: process-tools
240
- # securityLevel: moderate
241
-
242
- # MCP servers - add external tools here
243
- # mcpServers:
244
- # filesystem:
245
- # type: stdio
246
- # command: npx
247
- # args:
248
- # - -y
249
- # - "@modelcontextprotocol/server-filesystem"
250
- # - .
251
- `;
252
- await fs.writeFile('agents/default.yml', agentConfig);
253
91
  spinner.message('Creating configuration files...');
254
- // Create package.json
255
92
  await initPackageJson(projectPath, projectName, 'app');
256
- // Add scripts
257
93
  const packageJsonPath = path.join(projectPath, 'package.json');
258
94
  const packageJson = JSON.parse(await fs.readFile(packageJsonPath, 'utf8'));
259
95
  packageJson.scripts = {
@@ -262,398 +98,38 @@ storage:
262
98
  ...packageJson.scripts,
263
99
  };
264
100
  await fs.writeFile(packageJsonPath, JSON.stringify(packageJson, null, 2));
265
- // Create tsconfig.json
266
101
  await createTsconfigForApp(projectPath, 'src');
267
- // Create README
268
102
  const readmeContent = generateAppReadme({
269
103
  projectName,
270
104
  packageName: projectName,
271
- description: 'Dexto application using official image',
272
- imageName,
105
+ description: 'Dexto application',
273
106
  });
274
107
  await fs.writeFile('README.md', readmeContent);
275
- // Create .env.example
276
108
  await createEnvExample(projectPath, {
277
109
  OPENAI_API_KEY: 'sk-...',
278
110
  ANTHROPIC_API_KEY: 'sk-ant-...',
279
111
  });
280
- // Create .gitignore
281
112
  await createGitignore(projectPath);
282
- // Initialize git
283
113
  spinner.message('Initializing git repository...');
284
114
  await setupGitRepo(projectPath);
285
115
  spinner.message('Installing dependencies...');
286
- // Detect if we're in dexto source - use workspace protocol for local development
287
116
  const executionContext = getExecutionContext();
288
117
  const isDextoSource = executionContext === 'dexto-source';
289
- const agentMgmtVersion = isDextoSource ? 'workspace:*' : '^1.3.0';
290
- // Resolve relative paths to absolute for local images
291
- // (npm/pnpm need absolute paths to package directories when installing from file system)
292
- let resolvedImageName = imageName;
293
- if (imageName.startsWith('.')) {
294
- const fullPath = path.resolve(originalCwd, imageName);
295
- // If path ends with /dist/index.js, resolve to package root (parent of dist)
296
- if (fullPath.endsWith('/dist/index.js') || fullPath.endsWith('\\dist\\index.js')) {
297
- resolvedImageName = path.dirname(path.dirname(fullPath));
298
- }
299
- else if (fullPath.endsWith('.js')) {
300
- // If it's a .js file but not the standard structure, use the directory
301
- resolvedImageName = path.dirname(fullPath);
302
- }
303
- else {
304
- // It's already a directory
305
- resolvedImageName = fullPath;
306
- }
307
- }
308
- else if (isDextoSource && imageName.startsWith('@dexto/image-')) {
309
- // In dexto source, resolve official images to local workspace packages
310
- // e.g., @dexto/image-local -> packages/image-local
311
- const imagePkgName = imageName.replace('@dexto/', '');
312
- const imagePkgPath = path.resolve(originalCwd, 'packages', imagePkgName);
313
- if (await fs.pathExists(imagePkgPath)) {
314
- resolvedImageName = imagePkgPath;
315
- }
316
- }
317
- // Install dependencies (use pnpm in dexto source for workspace protocol support)
318
- // Image is loaded as "environment" - we import from core packages directly
319
- const coreVersion = isDextoSource ? 'workspace:*' : '^1.3.0';
320
- const serverVersion = isDextoSource ? 'workspace:*' : '^1.3.0';
118
+ const versionRange = getDextoVersionRange();
119
+ const dextoDependencyVersion = isDextoSource ? 'workspace:*' : versionRange;
321
120
  const dependencies = [
322
- resolvedImageName, // Image provides the environment/providers
323
- `@dexto/core@${coreVersion}`, // Import DextoAgent from here
324
- `@dexto/agent-management@${agentMgmtVersion}`, // Import loadAgentConfig from here
121
+ `@dexto/core@${dextoDependencyVersion}`,
122
+ `@dexto/storage@${dextoDependencyVersion}`,
123
+ // Intentionally omit tool packs in the scaffold to keep the onboarding example minimal.
124
+ // TODO: Revisit adding a default tool pack once tool IDs no longer require manual qualification.
125
+ 'dotenv',
325
126
  'tsx',
326
127
  ];
327
- // Add @dexto/server dependency for webapp type
328
128
  if (appType === 'webapp') {
329
- dependencies.push(`@dexto/server@${serverVersion}`);
129
+ dependencies.push(`@dexto/server@${dextoDependencyVersion}`);
330
130
  }
331
131
  await installDependencies(projectPath, {
332
132
  dependencies,
333
133
  devDependencies: ['typescript@^5.0.0', '@types/node@^20.0.0'],
334
134
  }, isDextoSource ? 'pnpm' : undefined);
335
135
  }
336
- /**
337
- * Mode B: Scaffold standalone app built from @dexto/core
338
- * Supports both dev (runtime discovery) and production (build-time discovery) workflows
339
- */
340
- async function scaffoldFromCore(projectPath, projectName, spinner) {
341
- spinner.start('Setting up app structure...');
342
- // Always include example tool for from-core mode
343
- const includeExample = true;
344
- // Create convention-based folders
345
- await ensureDirectory('src');
346
- await ensureDirectory('scripts');
347
- await ensureDirectory('tools');
348
- await ensureDirectory('blob-store');
349
- await ensureDirectory('compression');
350
- await ensureDirectory('plugins');
351
- await ensureDirectory('agents');
352
- // Create .gitkeep files for empty directories
353
- await fs.writeFile('blob-store/.gitkeep', '');
354
- await fs.writeFile('compression/.gitkeep', '');
355
- await fs.writeFile('plugins/.gitkeep', '');
356
- // Create example tool if requested
357
- if (includeExample) {
358
- await ensureDirectory('tools/example-tool');
359
- const exampleToolCode = generateExampleTool('example-tool');
360
- await fs.writeFile('tools/example-tool/index.ts', exampleToolCode);
361
- }
362
- else {
363
- await fs.writeFile('tools/.gitkeep', '');
364
- }
365
- spinner.message('Generating app files...');
366
- // Create dexto.config.ts for provider discovery configuration
367
- const dextoConfigContent = `import { defineConfig } from '@dexto/core';
368
-
369
- /**
370
- * Dexto Configuration
371
- *
372
- * Provider Discovery Modes:
373
- * - Development (pnpm dev): Runtime discovery - fast iteration, no rebuild needed
374
- * - Production (pnpm build): Build-time discovery - validates and optimizes everything
375
- *
376
- * This mirrors Next.js approach:
377
- * - next dev: Runtime compilation
378
- * - next build + next start: Pre-built production bundle
379
- */
380
- export default defineConfig({
381
- providers: {
382
- // Auto-discover providers from convention-based folders
383
- autoDiscover: true,
384
- folders: ['tools', 'blob-store', 'compression', 'plugins'],
385
- },
386
- });
387
- `;
388
- await fs.writeFile('dexto.config.ts', dextoConfigContent);
389
- // Create build-time discovery script
390
- const discoveryScript = generateDiscoveryScript();
391
- await fs.writeFile('scripts/discover-providers.ts', discoveryScript);
392
- // Create app entry point - completely clean, no provider registration code
393
- const appIndexContent = `// Standalone Dexto app
394
- // Development: Providers auto-discovered at runtime (pnpm dev)
395
- // Production: Providers bundled at build time (pnpm build + pnpm start)
396
-
397
- import { DextoAgent } from '@dexto/core';
398
- import { loadAgentConfig } from '@dexto/agent-management';
399
-
400
- async function main() {
401
- console.log('🚀 Starting ${projectName}\\n');
402
-
403
- // Load agent configuration
404
- // In dev mode: providers discovered at runtime from dexto.config.ts
405
- // In production: providers pre-registered at build time
406
- const config = await loadAgentConfig('./agents/default.yml');
407
-
408
- // Create agent
409
- const agent = new DextoAgent(config, './agents/default.yml');
410
-
411
- await agent.start();
412
- console.log('✅ Agent started\\n');
413
-
414
- // Create a session
415
- const session = await agent.createSession();
416
-
417
- // Example interaction
418
- const response = await agent.run(
419
- 'Hello! Can you help me understand what custom tools are available?',
420
- undefined, // imageDataInput
421
- undefined, // fileDataInput
422
- session.id // sessionId
423
- );
424
-
425
- console.log('Agent response:', response);
426
-
427
- // Cleanup
428
- await agent.stop();
429
- }
430
-
431
- main().catch((error) => {
432
- console.error('Error:', error);
433
- process.exit(1);
434
- });
435
- `;
436
- await fs.writeFile('src/index.ts', appIndexContent);
437
- // Create default agent config
438
- const agentConfig = `# Default Agent Configuration
439
-
440
- # System prompt
441
- systemPrompt:
442
- contributors:
443
- - id: primary
444
- type: static
445
- priority: 0
446
- content: |
447
- You are a helpful AI assistant with custom tools.
448
-
449
- # LLM configuration
450
- llm:
451
- provider: openai
452
- model: gpt-4o
453
- apiKey: $OPENAI_API_KEY
454
-
455
- # Storage
456
- storage:
457
- cache:
458
- type: in-memory
459
- database:
460
- type: sqlite
461
- path: ./data/agent.db
462
- blob:
463
- type: local
464
- storePath: ./data/blobs
465
-
466
- # Custom tools are auto-discovered at runtime from tools/ folder
467
- # See dexto.config.ts for provider discovery configuration
468
-
469
- # MCP servers - add external tools here
470
- # mcpServers:
471
- # filesystem:
472
- # type: stdio
473
- # command: npx
474
- # args:
475
- # - -y
476
- # - "@modelcontextprotocol/server-filesystem"
477
- # - .
478
- `;
479
- await fs.writeFile('agents/default.yml', agentConfig);
480
- spinner.message('Creating configuration files...');
481
- // Create package.json for standalone app
482
- await initPackageJson(projectPath, projectName, 'app');
483
- // Add scripts for both development and production workflows
484
- const packageJsonPath = path.join(projectPath, 'package.json');
485
- const packageJson = JSON.parse(await fs.readFile(packageJsonPath, 'utf8'));
486
- packageJson.scripts = {
487
- // Development: runtime discovery (fast iteration)
488
- dev: 'tsx src/index.ts',
489
- // Production: build-time discovery + bundling
490
- build: 'tsx scripts/discover-providers.ts && tsup',
491
- start: 'node dist/_entry.js',
492
- typecheck: 'tsc --noEmit',
493
- discover: 'tsx scripts/discover-providers.ts',
494
- ...packageJson.scripts,
495
- };
496
- await fs.writeFile(packageJsonPath, JSON.stringify(packageJson, null, 2));
497
- // Create tsconfig.json
498
- const tsconfigContent = {
499
- compilerOptions: {
500
- target: 'ES2022',
501
- module: 'ESNext',
502
- moduleResolution: 'bundler',
503
- lib: ['ES2022'],
504
- outDir: './dist',
505
- rootDir: './src',
506
- strict: true,
507
- esModuleInterop: true,
508
- skipLibCheck: true,
509
- forceConsistentCasingInFileNames: true,
510
- resolveJsonModule: true,
511
- declaration: true,
512
- declarationMap: true,
513
- sourceMap: true,
514
- },
515
- include: ['src/**/*', 'tools/**/*', 'blob-store/**/*', 'compression/**/*', 'plugins/**/*'],
516
- exclude: ['node_modules', 'dist'],
517
- };
518
- await fs.writeFile('tsconfig.json', JSON.stringify(tsconfigContent, null, 2));
519
- // Create tsup.config.ts - builds from generated _entry.ts for production
520
- const tsupConfig = `import { defineConfig } from 'tsup';
521
-
522
- export default defineConfig({
523
- entry: ['src/_entry.ts'], // Generated by scripts/discover-providers.ts
524
- format: ['esm'],
525
- dts: false, // Skip DTS for build artifacts
526
- sourcemap: true,
527
- clean: true,
528
- external: ['@dexto/core', '@dexto/agent-management'],
529
- noExternal: [],
530
- });
531
- `;
532
- await fs.writeFile('tsup.config.ts', tsupConfig);
533
- // Create .gitignore - ignore generated build artifacts
534
- await createGitignore(projectPath, [
535
- '*.tsbuildinfo',
536
- 'dist/',
537
- 'src/_entry.ts',
538
- 'src/_providers.ts',
539
- ]);
540
- // Create .env.example
541
- await createEnvExample(projectPath, {
542
- OPENAI_API_KEY: 'sk-...',
543
- ANTHROPIC_API_KEY: 'sk-ant-...',
544
- });
545
- // Create README
546
- const readmeContent = `# ${projectName}
547
-
548
- Standalone Dexto app with convention-based auto-discovery.
549
-
550
- ## Getting Started
551
-
552
- \`\`\`bash
553
- # Install dependencies
554
- pnpm install
555
-
556
- # Add your API key
557
- cp .env.example .env
558
- # Edit .env and add your OPENAI_API_KEY
559
-
560
- # Development (runtime discovery - fast iteration)
561
- pnpm dev
562
-
563
- # Production (build-time discovery + optimized bundle)
564
- pnpm build
565
- pnpm start
566
- \`\`\`
567
-
568
- That's it! Custom providers are discovered automatically:
569
- - **Dev mode** (\`pnpm dev\`): Runtime discovery - add/modify providers without rebuilding
570
- - **Production** (\`pnpm build\`): Build-time discovery - validates and bundles everything
571
-
572
- ## Project Structure
573
-
574
- \`\`\`
575
- ${projectName}/
576
- ├── src/
577
- │ ├── index.ts # Your app code (clean, no boilerplate!)
578
- │ ├── _entry.ts # Auto-generated (build only, gitignored)
579
- │ └── _providers.ts # Auto-generated (build only, gitignored)
580
- ├── scripts/
581
- │ └── discover-providers.ts # Build-time discovery script
582
- ├── dexto.config.ts # Provider discovery configuration
583
- ├── tools/ # Add custom tool providers here
584
- ├── blob-store/ # Add custom blob storage providers here
585
- ├── compression/ # Add custom compression providers here
586
- ├── plugins/ # Add custom plugins here
587
- └── agents/
588
- └── default.yml # Agent configuration
589
- \`\`\`
590
-
591
- ## Adding Custom Providers
592
-
593
- 1. Create a provider in the appropriate folder (tools/, blob-store/, compression/, plugins/)
594
- 2. Export it with the naming convention: \`<folderName>Provider\`
595
- 3. Run \`pnpm dev\` (instant) or \`pnpm build\` (validated) - everything is auto-discovered!
596
-
597
- **Example** - Adding a custom tool:
598
- \`\`\`typescript
599
- // tools/my-tool/index.ts
600
- import { z } from 'zod';
601
-
602
- export const myToolProvider = {
603
- type: 'my-tool',
604
- configSchema: z.object({ type: z.literal('my-tool') }),
605
- tools: [
606
- {
607
- name: 'do_something',
608
- description: 'Does something useful',
609
- parameters: z.object({ input: z.string() }),
610
- execute: async ({ input }) => {
611
- return \`Processed: \${input}\`;
612
- },
613
- },
614
- ],
615
- };
616
- \`\`\`
617
-
618
- That's it! No imports, no registration code needed.
619
-
620
- ## Scripts
621
-
622
- - \`pnpm start\` - Build and run (auto-discovers providers)
623
- - \`pnpm run dev\` - Development mode with hot reload
624
- - \`pnpm run build\` - Build only
625
- - \`pnpm run discover\` - Manually run provider discovery
626
- - \`pnpm run typecheck\` - Type check
627
-
628
- ## How It Works
629
-
630
- 1. **Discovery**: Scans conventional folders for providers
631
- 2. **Generation**: Creates \`src/_providers.ts\` (registrations) and \`src/_entry.ts\` (wiring)
632
- 3. **Build**: Bundles everything into \`dist/_entry.js\`
633
- 4. **Run**: Your clean app code runs with all providers pre-registered
634
-
635
- ## Learn More
636
-
637
- - [Dexto Documentation](https://docs.dexto.ai)
638
- - [Custom Tools Guide](https://docs.dexto.ai/docs/guides/custom-tools)
639
- `;
640
- await fs.writeFile('README.md', readmeContent);
641
- // Initialize git
642
- spinner.message('Initializing git repository...');
643
- await setupGitRepo(projectPath);
644
- spinner.message('Installing dependencies...');
645
- // Detect if we're in dexto source - use workspace protocol for local development
646
- const executionContext = getExecutionContext();
647
- const isDextoSource = executionContext === 'dexto-source';
648
- const coreVersion = isDextoSource ? 'workspace:*' : '^1.3.0';
649
- const agentMgmtVersion = isDextoSource ? 'workspace:*' : '^1.3.0';
650
- // Install dependencies (use pnpm in dexto source for workspace protocol support)
651
- await installDependencies(projectPath, {
652
- dependencies: [
653
- `@dexto/core@${coreVersion}`,
654
- 'zod',
655
- `@dexto/agent-management@${agentMgmtVersion}`,
656
- ],
657
- devDependencies: ['typescript@^5.0.0', '@types/node@^20.0.0', 'tsx', 'tsup'],
658
- }, isDextoSource ? 'pnpm' : undefined);
659
- }
@@ -1 +1 @@
1
- {"version":3,"file":"create-image.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/create-image.ts"],"names":[],"mappings":"AAsBA;;;;GAIG;AACH,wBAAsB,WAAW,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAkPhE"}
1
+ {"version":3,"file":"create-image.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/create-image.ts"],"names":[],"mappings":"AA6BA;;;;GAIG;AACH,wBAAsB,WAAW,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAyPhE"}