create-feltdb 0.4.12 → 0.4.14

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 (151) hide show
  1. package/dist/cli.js +39 -4
  2. package/dist/create.js +30 -18
  3. package/dist/docker-compose-generator.js +68 -11
  4. package/dist/package-versions.js +1 -1
  5. package/dist/server-source/Cargo.lock +2238 -0
  6. package/dist/server-source/Cargo.toml +7 -0
  7. package/dist/server-source/crates/feltdb/Cargo.lock +175 -0
  8. package/dist/server-source/crates/feltdb/Cargo.toml +79 -0
  9. package/dist/server-source/crates/feltdb/benches/baselines/gate-13-redux.json +370 -0
  10. package/dist/server-source/crates/feltdb/benches/gate13_baseline.rs +589 -0
  11. package/dist/server-source/crates/feltdb/benches/gate13_phase_7_1_release_economics.rs +259 -0
  12. package/dist/server-source/crates/feltdb/benches/gate_13_redux.rs +446 -0
  13. package/dist/server-source/crates/feltdb/benches/gate_13_regression_runner.rs +272 -0
  14. package/dist/server-source/crates/feltdb/benches/gate_14a_concurrent_writer_scaling.rs +378 -0
  15. package/dist/server-source/crates/feltdb/benches/gate_14a_production_admission_revalidation.rs +414 -0
  16. package/dist/server-source/crates/feltdb/benches/gate_14a_rc2_admission_contract.rs +486 -0
  17. package/dist/server-source/crates/feltdb/benches/gate_14a_rc_root_cause.rs +273 -0
  18. package/dist/server-source/crates/feltdb/benches/gate_14a_sync1_queued_prototype.rs +587 -0
  19. package/dist/server-source/crates/feltdb/benches/gate_14a_sync_economics.rs +513 -0
  20. package/dist/server-source/crates/feltdb/benches/gate_14b_causal_backlog_scaling.rs +395 -0
  21. package/dist/server-source/crates/feltdb/benches/gate_14c_replication_contract_test.rs +469 -0
  22. package/dist/server-source/crates/feltdb/benches/gate_14c_replication_scaling.rs +409 -0
  23. package/dist/server-source/crates/feltdb/benches/gate_14d_combined_dimension_scaling.rs +627 -0
  24. package/dist/server-source/crates/feltdb/benches/phase_7_1_2_optimization_benchmark.rs +383 -0
  25. package/dist/server-source/crates/feltdb/benches/phase_7_1_3_crossover_analysis.rs +298 -0
  26. package/dist/server-source/crates/feltdb/src/acceptance_tests.rs +1698 -0
  27. package/dist/server-source/crates/feltdb/src/acquisition.rs +286 -0
  28. package/dist/server-source/crates/feltdb/src/admission.rs +192 -0
  29. package/dist/server-source/crates/feltdb/src/admission_contract_tests.rs +477 -0
  30. package/dist/server-source/crates/feltdb/src/adversarial_transport.rs +566 -0
  31. package/dist/server-source/crates/feltdb/src/analytics.rs +475 -0
  32. package/dist/server-source/crates/feltdb/src/application.rs +2244 -0
  33. package/dist/server-source/crates/feltdb/src/application_runtime.rs +1070 -0
  34. package/dist/server-source/crates/feltdb/src/authorization.rs +1030 -0
  35. package/dist/server-source/crates/feltdb/src/bin/feltdb_node.rs +266 -0
  36. package/dist/server-source/crates/feltdb/src/capabilities/mod.rs +8 -0
  37. package/dist/server-source/crates/feltdb/src/capabilities/search.rs +418 -0
  38. package/dist/server-source/crates/feltdb/src/capabilities/vector.rs +482 -0
  39. package/dist/server-source/crates/feltdb/src/capability.rs +903 -0
  40. package/dist/server-source/crates/feltdb/src/cardinality_diagnostics.rs +261 -0
  41. package/dist/server-source/crates/feltdb/src/cardinality_endpoint.rs +78 -0
  42. package/dist/server-source/crates/feltdb/src/causal_dependency_barrier.rs +2214 -0
  43. package/dist/server-source/crates/feltdb/src/causal_dependency_barrier_phase_7_1.rs +194 -0
  44. package/dist/server-source/crates/feltdb/src/concurrency_fuzzing.rs +427 -0
  45. package/dist/server-source/crates/feltdb/src/consistency_contract.rs +453 -0
  46. package/dist/server-source/crates/feltdb/src/content_distribution.rs +465 -0
  47. package/dist/server-source/crates/feltdb/src/convergence.rs +618 -0
  48. package/dist/server-source/crates/feltdb/src/crash_atomic_boundary.rs +418 -0
  49. package/dist/server-source/crates/feltdb/src/crash_injection.rs +380 -0
  50. package/dist/server-source/crates/feltdb/src/crash_recovery_tests.rs +362 -0
  51. package/dist/server-source/crates/feltdb/src/cron.rs +294 -0
  52. package/dist/server-source/crates/feltdb/src/distributed_indexing.rs +474 -0
  53. package/dist/server-source/crates/feltdb/src/distributed_tests.rs +1003 -0
  54. package/dist/server-source/crates/feltdb/src/distributed_transactions.rs +536 -0
  55. package/dist/server-source/crates/feltdb/src/durability_guarantees.rs +364 -0
  56. package/dist/server-source/crates/feltdb/src/durable_dedup_set.rs +235 -0
  57. package/dist/server-source/crates/feltdb/src/durable_operation_log.rs +207 -0
  58. package/dist/server-source/crates/feltdb/src/durable_sync.rs +316 -0
  59. package/dist/server-source/crates/feltdb/src/execution.rs +426 -0
  60. package/dist/server-source/crates/feltdb/src/in_process_transport.rs +219 -0
  61. package/dist/server-source/crates/feltdb/src/indexing.rs +779 -0
  62. package/dist/server-source/crates/feltdb/src/lib.rs +2838 -0
  63. package/dist/server-source/crates/feltdb/src/materialization.rs +184 -0
  64. package/dist/server-source/crates/feltdb/src/metrics.rs +267 -0
  65. package/dist/server-source/crates/feltdb/src/multi_node_convergence.rs +311 -0
  66. package/dist/server-source/crates/feltdb/src/observability.rs +366 -0
  67. package/dist/server-source/crates/feltdb/src/operation.rs +251 -0
  68. package/dist/server-source/crates/feltdb/src/operation_algebra.rs +438 -0
  69. package/dist/server-source/crates/feltdb/src/operation_log.rs +344 -0
  70. package/dist/server-source/crates/feltdb/src/partition_reconciliation.rs +477 -0
  71. package/dist/server-source/crates/feltdb/src/peer_registry.rs +166 -0
  72. package/dist/server-source/crates/feltdb/src/permutation_scheduler.rs +261 -0
  73. package/dist/server-source/crates/feltdb/src/persistence_reality.rs +560 -0
  74. package/dist/server-source/crates/feltdb/src/phase1b_acceptance.rs +3226 -0
  75. package/dist/server-source/crates/feltdb/src/phase1c1_acceptance.rs +201 -0
  76. package/dist/server-source/crates/feltdb/src/phase1c2_acceptance.rs +263 -0
  77. package/dist/server-source/crates/feltdb/src/phase1c3_acceptance.rs +484 -0
  78. package/dist/server-source/crates/feltdb/src/phase1c_atomicity_proof.rs +216 -0
  79. package/dist/server-source/crates/feltdb/src/phase5_integration.rs +281 -0
  80. package/dist/server-source/crates/feltdb/src/phase5_scenarios.rs +323 -0
  81. package/dist/server-source/crates/feltdb/src/phase6_adversarial_scenarios.rs +573 -0
  82. package/dist/server-source/crates/feltdb/src/phase6_convergence_validator.rs +404 -0
  83. package/dist/server-source/crates/feltdb/src/phase6_persistence.rs +418 -0
  84. package/dist/server-source/crates/feltdb/src/phase_1c_real_tcp.rs +381 -0
  85. package/dist/server-source/crates/feltdb/src/phase_1c_three_node.rs +523 -0
  86. package/dist/server-source/crates/feltdb/src/phase_2a_failures.rs +334 -0
  87. package/dist/server-source/crates/feltdb/src/phase_2b_network.rs +306 -0
  88. package/dist/server-source/crates/feltdb/src/phase_2c_cascading.rs +355 -0
  89. package/dist/server-source/crates/feltdb/src/phase_3_durability.rs +395 -0
  90. package/dist/server-source/crates/feltdb/src/phase_4_baseline.rs +346 -0
  91. package/dist/server-source/crates/feltdb/src/phase_5_soak.rs +430 -0
  92. package/dist/server-source/crates/feltdb/src/production_api.rs +400 -0
  93. package/dist/server-source/crates/feltdb/src/provenance.rs +207 -0
  94. package/dist/server-source/crates/feltdb/src/query_performance.rs +217 -0
  95. package/dist/server-source/crates/feltdb/src/references.rs +404 -0
  96. package/dist/server-source/crates/feltdb/src/replay_fuzzing.rs +401 -0
  97. package/dist/server-source/crates/feltdb/src/replication_manager.rs +160 -0
  98. package/dist/server-source/crates/feltdb/src/replication_protocol.rs +132 -0
  99. package/dist/server-source/crates/feltdb/src/routing.rs +409 -0
  100. package/dist/server-source/crates/feltdb/src/sharding.rs +523 -0
  101. package/dist/server-source/crates/feltdb/src/state_contract.rs +3118 -0
  102. package/dist/server-source/crates/feltdb/src/state_hash.rs +291 -0
  103. package/dist/server-source/crates/feltdb/src/state_transition_store.rs +376 -0
  104. package/dist/server-source/crates/feltdb/src/storage.rs +267 -0
  105. package/dist/server-source/crates/feltdb/src/submission.rs +477 -0
  106. package/dist/server-source/crates/feltdb/src/sync.rs +483 -0
  107. package/dist/server-source/crates/feltdb/src/sync_contract.rs +822 -0
  108. package/dist/server-source/crates/feltdb/src/tcp_transport.rs +366 -0
  109. package/dist/server-source/crates/feltdb/src/transaction_api.rs +473 -0
  110. package/dist/server-source/crates/feltdb/src/transaction_invariants.rs +949 -0
  111. package/dist/server-source/crates/feltdb/src/transactions.rs +646 -0
  112. package/dist/server-source/crates/feltdb/src/trigger.rs +390 -0
  113. package/dist/server-source/crates/feltdb/src/worker_mesh.rs +928 -0
  114. package/dist/server-source/crates/feltdb/src/workflow.rs +713 -0
  115. package/dist/server-source/crates/feltdb/src/workflow_acceptance_tests.rs +510 -0
  116. package/dist/server-source/crates/feltdb/src/workflow_integration.rs +354 -0
  117. package/dist/server-source/crates/feltdb/src/workflow_runtime.rs +594 -0
  118. package/dist/server-source/crates/feltdb/src/workload.rs +1310 -0
  119. package/dist/server-source/crates/feltdb-server/Cargo.toml +23 -0
  120. package/dist/server-source/crates/feltdb-server/README.md +79 -0
  121. package/dist/server-source/crates/feltdb-server/src/app_state.rs +73 -0
  122. package/dist/server-source/crates/feltdb-server/src/application_contract.rs +425 -0
  123. package/dist/server-source/crates/feltdb-server/src/artifacts.rs +449 -0
  124. package/dist/server-source/crates/feltdb-server/src/audit.rs +59 -0
  125. package/dist/server-source/crates/feltdb-server/src/auth.rs +308 -0
  126. package/dist/server-source/crates/feltdb-server/src/authorization.rs +228 -0
  127. package/dist/server-source/crates/feltdb-server/src/backup.rs +416 -0
  128. package/dist/server-source/crates/feltdb-server/src/causal.rs +218 -0
  129. package/dist/server-source/crates/feltdb-server/src/certification.rs +223 -0
  130. package/dist/server-source/crates/feltdb-server/src/clock.rs +132 -0
  131. package/dist/server-source/crates/feltdb-server/src/cluster.rs +165 -0
  132. package/dist/server-source/crates/feltdb-server/src/connections.rs +1044 -0
  133. package/dist/server-source/crates/feltdb-server/src/content.rs +111 -0
  134. package/dist/server-source/crates/feltdb-server/src/identity.rs +250 -0
  135. package/dist/server-source/crates/feltdb-server/src/key_management.rs +78 -0
  136. package/dist/server-source/crates/feltdb-server/src/key_provider.rs +247 -0
  137. package/dist/server-source/crates/feltdb-server/src/leases.rs +123 -0
  138. package/dist/server-source/crates/feltdb-server/src/lib.rs +25 -0
  139. package/dist/server-source/crates/feltdb-server/src/main.rs +8715 -0
  140. package/dist/server-source/crates/feltdb-server/src/metrics.rs +97 -0
  141. package/dist/server-source/crates/feltdb-server/src/portable_bundle.rs +350 -0
  142. package/dist/server-source/crates/feltdb-server/src/principals.rs +510 -0
  143. package/dist/server-source/crates/feltdb-server/src/providers.rs +269 -0
  144. package/dist/server-source/crates/feltdb-server/src/releases.rs +2563 -0
  145. package/dist/server-source/crates/feltdb-server/src/sessions.rs +156 -0
  146. package/dist/server-source/crates/feltdb-server/src/tenancy.rs +1097 -0
  147. package/dist/server-source/crates/feltdb-server/src/versions.rs +264 -0
  148. package/dist/server-source/crates/feltdb-wasm/Cargo.toml +31 -0
  149. package/dist/server-source/crates/feltdb-wasm/src/lib.rs +1086 -0
  150. package/dist/server-source/crates/feltdb-wasm/test.db +0 -0
  151. package/package.json +3 -3
package/dist/cli.js CHANGED
@@ -18,6 +18,7 @@ function parseArgs(args) {
18
18
  framework: 'react',
19
19
  distributed: true,
20
20
  agents: true,
21
+ webllm: true,
21
22
  capabilities: 'search',
22
23
  };
23
24
  for (let i = 0; i < args.length; i++) {
@@ -46,6 +47,12 @@ function parseArgs(args) {
46
47
  case '--no-agents':
47
48
  options.agents = false;
48
49
  break;
50
+ case '--webllm':
51
+ options.webllm = true;
52
+ break;
53
+ case '--no-webllm':
54
+ options.webllm = false;
55
+ break;
49
56
  case '--capabilities':
50
57
  options.capabilities = args[++i];
51
58
  break;
@@ -66,6 +73,14 @@ async function prompt(message) {
66
73
  const interface_ = readline.createInterface({ input: process.stdin, output: process.stdout });
67
74
  return new Promise(resolve => interface_.question(message, value => { interface_.close(); resolve(value.trim()); }));
68
75
  }
76
+ async function promptForProjectName(defaultName = 'feltdb-app') {
77
+ while (true) {
78
+ const value = (await prompt(`What should we name your FeltDB app? (${defaultName}): `)) || defaultName;
79
+ if (/^[a-z0-9][a-z0-9-]*$/.test(value))
80
+ return value;
81
+ console.log('Use lowercase letters, numbers, and dashes (for example: customer-portal).');
82
+ }
83
+ }
69
84
  async function promptSecret(message) {
70
85
  if (!process.stdin.isTTY || !process.stdout.isTTY)
71
86
  return '';
@@ -161,6 +176,10 @@ async function promptForOptions(defaults) {
161
176
  ], defaults.framework),
162
177
  distributed: await select('Enable distributed operation?', yesNo, defaults.distributed),
163
178
  agents: await select('Include an autonomous agent example?', yesNo, defaults.agents),
179
+ webllm: await select('Install WebLLM for private natural-language app building?', [
180
+ { label: 'Yes', value: true, description: 'build FeltDB schemas, capabilities, workflows, and UI locally with AI' },
181
+ { label: 'No', value: false, description: 'skip the browser model and AI builder' },
182
+ ], defaults.webllm),
164
183
  capabilities: await select('Choose starter capabilities:', [
165
184
  { label: 'Search', value: 'search' },
166
185
  { label: 'Vector search', value: 'vector' },
@@ -196,7 +215,7 @@ Deployment Target (Explicit):
196
215
  Requires production FeltDB instance or self-host
197
216
 
198
217
  --self-host Dedicated FeltDB server with Docker Compose
199
- Best for: Production deployments, multi-user systems
218
+ Best for: Staging first, then explicit production promotion
200
219
  Generates Docker Compose with persistent /data volume
201
220
 
202
221
  --managed Managed FeltDB runtime
@@ -212,6 +231,8 @@ Options:
212
231
  --framework <framework> Choose framework: react or vanilla (default: react)
213
232
  --no-distributed Disable distributed operation
214
233
  --no-agents Exclude agent examples
234
+ --webllm Include the private natural-language FeltDB app builder (default)
235
+ --no-webllm Do not install WebLLM or generate the AI builder
215
236
  --capabilities <list> Choose capabilities: search, vector, or search,vector
216
237
  --no-install Skip npm install
217
238
  --no-start Skip npm run dev
@@ -232,10 +253,12 @@ Learn more: https://github.com/rkendel1/feltdb`);
232
253
  }
233
254
  // Find project name (first non-flag argument)
234
255
  let projectName = 'feltdb-app';
256
+ let projectNameProvided = false;
235
257
  for (let i = 0; i < args.length; i++) {
236
258
  const arg = args[i];
237
259
  if (!arg.startsWith('-')) {
238
260
  projectName = arg;
261
+ projectNameProvided = true;
239
262
  break;
240
263
  }
241
264
  // Skip next arg if current arg is a flag that takes a value
@@ -247,10 +270,16 @@ Learn more: https://github.com/rkendel1/feltdb`);
247
270
  const shouldInstall = !args.includes('--no-install');
248
271
  const shouldStart = !args.includes('--no-start');
249
272
  let options = parseArgs(args);
273
+ if (!projectNameProvided && !shouldAutoYes && process.stdin.isTTY && process.stdout.isTTY) {
274
+ projectName = await promptForProjectName(projectName);
275
+ }
276
+ if (!/^[a-z0-9][a-z0-9-]*$/.test(projectName)) {
277
+ throw new Error('Application names must use lowercase letters, numbers, and dashes.');
278
+ }
250
279
  const runtimeDescriptions = {
251
280
  'browser': 'Browser with IndexedDB (local-first, no server)',
252
281
  'node': 'Node.js server (server-side authority)',
253
- 'self-hosted': 'Self-hosted with Docker Compose (production)',
282
+ 'self-hosted': 'Self-hosted with Docker Compose (staging)',
254
283
  'managed': 'Managed FeltDB service (hosted persistence, sync, and workloads)',
255
284
  };
256
285
  if (!runtimeDescriptions[options.runtime]) {
@@ -269,9 +298,11 @@ Learn more: https://github.com/rkendel1/feltdb`);
269
298
  console.log(`Framework: ${options.framework}`);
270
299
  console.log(`Distributed: ${options.distributed ? 'yes' : 'no'}`);
271
300
  console.log(`Agents: ${options.agents ? 'yes' : 'no'}`);
301
+ console.log(`WebLLM: ${options.webllm ? 'yes — natural-language app builder' : 'no'}`);
272
302
  console.log(`Capabilities: ${options.capabilities}`);
273
303
  console.log('\n═══════════════════════════════════════════════\n');
274
304
  const projectDir = path.resolve(process.cwd(), projectName);
305
+ let projectCreated = false;
275
306
  try {
276
307
  await createProject({
277
308
  projectName,
@@ -281,8 +312,10 @@ Learn more: https://github.com/rkendel1/feltdb`);
281
312
  framework: options.framework,
282
313
  distributed: options.distributed,
283
314
  agents: options.agents,
315
+ webllm: options.webllm,
284
316
  capabilities: options.capabilities,
285
317
  });
318
+ projectCreated = true;
286
319
  if (options.runtime === 'managed') {
287
320
  console.log('\n☁️ Setting up your managed FeltDB account...\n');
288
321
  const email = process.env.FELTDB_MANAGED_EMAIL || (shouldAutoYes ? '' : await prompt('Email: '));
@@ -297,7 +330,7 @@ Learn more: https://github.com/rkendel1/feltdb`);
297
330
  console.log('\n✅ FeltDB application created successfully!\n');
298
331
  const npm = process.platform === 'win32' ? 'npm.cmd' : 'npm';
299
332
  if (shouldInstall) {
300
- console.log('📦 Installing application, Studio, and local AI dependencies...\n');
333
+ console.log(`📦 Installing application, Studio${options.webllm ? ', and local WebLLM app builder' : ''} dependencies...\n`);
301
334
  await run(npm, ['install'], projectDir);
302
335
  }
303
336
  if (shouldStart) {
@@ -326,7 +359,9 @@ Learn more: https://github.com/rkendel1/feltdb`);
326
359
  }
327
360
  }
328
361
  catch (error) {
329
- console.error('❌ Failed to create project:', error);
362
+ console.error(projectCreated
363
+ ? `❌ The project was created at ${projectDir}, but setup or startup failed:`
364
+ : '❌ Failed to create project:', error);
330
365
  process.exit(1);
331
366
  }
332
367
  }
package/dist/create.js CHANGED
@@ -3,8 +3,9 @@
3
3
  */
4
4
  import fs from 'fs';
5
5
  import path from 'path';
6
+ import { randomBytes } from 'crypto';
6
7
  import { feltdbPackageRange } from './package-versions.js';
7
- import { generateDockerCompose, generateDockerfile, generateDockerIgnore, generateDotEnvLocal, } from './docker-compose-generator.js';
8
+ import { generateDockerCompose, generateDockerfile, generateDockerIgnore, generateDotEnvLocal, generateFeltDBDockerfile, generateStudioDockerfile, } from './docker-compose-generator.js';
8
9
  export async function createProject(options) {
9
10
  const { projectName, templatesDir } = options;
10
11
  const projectDir = path.resolve(process.cwd(), projectName);
@@ -29,6 +30,7 @@ export async function createProject(options) {
29
30
  const framework = options.framework || 'react';
30
31
  const distributed = options.distributed !== false;
31
32
  const hasAgents = options.agents !== false;
33
+ const hasWebLLM = options.webllm !== false;
32
34
  const capabilities = options.capabilities || 'search';
33
35
  // Create package.json
34
36
  const packageJson = {
@@ -65,7 +67,7 @@ export async function createProject(options) {
65
67
  packageJson.devDependencies['@types/react'] = '^18.0.0';
66
68
  packageJson.devDependencies['@types/react-dom'] = '^18.0.0';
67
69
  }
68
- if (hasAgents) {
70
+ if (hasAgents && hasWebLLM) {
69
71
  packageJson.dependencies['@feltdb/webllm'] = feltdbPackageRange;
70
72
  }
71
73
  fs.writeFileSync(path.join(projectDir, 'package.json'), JSON.stringify(packageJson, null, 2));
@@ -345,7 +347,7 @@ async function logActivity(event: Omit<ActivityEvent, 'id' | 'timestamp'>): Prom
345
347
  `;
346
348
  fs.writeFileSync(path.join(srcDir, 'feltdb.ts'), feltdbTs);
347
349
  // Create a real local-inference agent for browser projects.
348
- if (hasAgents) {
350
+ if (hasAgents && hasWebLLM) {
349
351
  const agentTs = `import { WebLLMProvider } from '@feltdb/webllm';
350
352
  import { db, reports } from '../../src/feltdb';
351
353
 
@@ -385,15 +387,19 @@ export async function runResearcher(
385
387
  }
386
388
 
387
389
  try {
388
- const systemPrompt = \`You are a helpful AI assistant that operates entirely in the browser.
389
- You help users:
390
- - Summarize documents concisely
391
- - Expand and enhance text with more details
392
- - Generate ideas and suggestions
393
- - Improve writing clarity and structure
394
- - Answer questions about document content
390
+ const systemPrompt = \`You are the private, in-browser FeltDB application builder.
391
+ Turn natural-language product requirements into valid, coherent FeltDB applications. You know the
392
+ Flow DSL and keep collections, references, indexes, capabilities, workflows, triggers, policies,
393
+ agents, and React UI code consistent with one another.
395
394
 
396
- Always be concise and practical. Respect the user's intent.\`;
395
+ Supported field types are text, integer, number, decimal, money, bigint, boolean, datetime, date,
396
+ time, uuid, email, url, phone, json, object, binary, file, geo, enum(...), array<T>, map<T>,
397
+ vector<N>, and ref Collection. Prefer UUID identifiers, explicit references, precise domain types,
398
+ least-privilege capabilities, and policies for every writable collection. Never invent syntax.
399
+
400
+ When asked to build or change an app, return a short implementation plan followed by complete
401
+ copy-ready feltdb.flow and TypeScript/React code blocks. Preserve the existing app model supplied
402
+ by the user and clearly identify files to create or replace. All inference remains local.\`;
397
403
 
398
404
  const content = await provider.generate([
399
405
  { role: 'system', content: systemPrompt },
@@ -537,10 +543,10 @@ export const capabilities = {
537
543
  fs.writeFileSync(path.join(feltdbDir, 'capabilities', 'index.ts'), capabilitiesTs);
538
544
  // Create main application file based on framework
539
545
  if (framework === 'react') {
540
- const agentImport = hasAgents
546
+ const agentImport = hasAgents && hasWebLLM
541
547
  ? "import { runResearcher, summarizeDocument, enhanceDocument, generateIdeas, generateFeltDBFeature, generateReactComponent, generateCapability } from '../feltdb/agents/researcher';"
542
548
  : '';
543
- const agentState = hasAgents
549
+ const agentState = hasAgents && hasWebLLM
544
550
  ? ` const [prompt, setPrompt] = useState('');
545
551
  const [answer, setAnswer] = useState('');
546
552
  const [modelStatus, setModelStatus] = useState('Model not loaded');
@@ -548,7 +554,7 @@ export const capabilities = {
548
554
  const [selectedDoc, setSelectedDoc] = useState<any | null>(null);
549
555
  const [aiMode, setAiMode] = useState<'custom' | 'summarize' | 'enhance' | 'ideas' | 'feltdb' | 'react' | 'capability'>('custom');`
550
556
  : '';
551
- const agentHandler = hasAgents
557
+ const agentHandler = hasAgents && hasWebLLM
552
558
  ? `
553
559
  const handleRunAI = async (mode: 'custom' | 'summarize' | 'enhance' | 'ideas' | 'feltdb' | 'react' | 'capability') => {
554
560
  setGenerating(true);
@@ -582,7 +588,7 @@ export const capabilities = {
582
588
  };
583
589
  `
584
590
  : '';
585
- const agentMarkup = hasAgents
591
+ const agentMarkup = hasAgents && hasWebLLM
586
592
  ? `
587
593
  <section className="researcher">
588
594
  <h2>🤖 AI Assistant (Private, Local)</h2>
@@ -1211,7 +1217,8 @@ VITE_FELTDB_MANAGED_NAMESPACE=
1211
1217
  VITE_FELTDB_MANAGED_ENVIRONMENT=production
1212
1218
 
1213
1219
  # Override the default self-hosted container image
1214
- # Example: ghcr.io/rkendel1/feltdb:latest
1220
+ # By default the server image is built locally from the bundled source.
1221
+ # Example override: your-registry.example/feltdb:staging
1215
1222
  FELTDB_IMAGE=
1216
1223
 
1217
1224
  # Node environment
@@ -1230,8 +1237,12 @@ NODE_ENV=development
1230
1237
  };
1231
1238
  fs.writeFileSync(path.join(projectDir, 'docker-compose.yml'), generateDockerCompose(dockerConfig));
1232
1239
  fs.writeFileSync(path.join(projectDir, 'Dockerfile'), generateDockerfile(dockerConfig, framework));
1240
+ fs.writeFileSync(path.join(projectDir, 'Dockerfile.feltdb'), generateFeltDBDockerfile(dockerConfig));
1241
+ fs.writeFileSync(path.join(projectDir, 'Dockerfile.studio'), generateStudioDockerfile(dockerConfig));
1233
1242
  fs.writeFileSync(path.join(projectDir, '.dockerignore'), generateDockerIgnore());
1234
- fs.writeFileSync(path.join(projectDir, '.env.docker'), generateDotEnvLocal(dockerConfig));
1243
+ const dockerEnvironment = generateDotEnvLocal(dockerConfig, randomBytes(32).toString('hex'));
1244
+ // Docker Compose loads .env automatically; it is already excluded from git.
1245
+ fs.writeFileSync(path.join(projectDir, '.env'), dockerEnvironment);
1235
1246
  }
1236
1247
  // Create RUNTIME_GUIDE.md
1237
1248
  const runtimeGuide = `# Runtime Configuration Guide
@@ -1483,7 +1494,8 @@ Verify vector database connection and that embeddings are enabled in capabilitie
1483
1494
  - Check out example projects in the templates
1484
1495
  - Join the community Discord for support
1485
1496
  `;
1486
- fs.writeFileSync(path.join(projectDir, 'RUNTIME_GUIDE.md'), runtimeGuide);
1497
+ // Keep generated projects focused; the runtime guide lives in FeltDB's docs.
1498
+ void runtimeGuide;
1487
1499
  // Create .gitignore
1488
1500
  const gitignore = `node_modules/
1489
1501
  dist/
@@ -2,26 +2,45 @@
2
2
  * Docker Compose generator for self-hosted FeltDB deployments
3
3
  *
4
4
  * Generates:
5
- * - docker-compose.yml with three services (FeltDB, App, Studio)
6
- * - Dockerfile for application container
5
+ * - docker-compose.yml with three locally buildable services
6
+ * - Dockerfiles for the FeltDB server, application, and Studio
7
7
  * - .dockerignore for optimized builds
8
8
  * - Environment configuration
9
9
  */
10
10
  export function generateDockerCompose(config) {
11
11
  return `services:
12
12
  feltdb:
13
- image: \${FELTDB_IMAGE:-ghcr.io/rkendel1/feltdb:${config.version}}
13
+ image: \${FELTDB_IMAGE:-${config.appName.toLowerCase().replace(/[^a-z0-9]/g, '-')}-feltdb:${config.version}}
14
+ build:
15
+ context: .
16
+ dockerfile: Dockerfile.feltdb
17
+ args:
18
+ FELTDB_VERSION: ${config.version}
14
19
  container_name: \${COMPOSE_PROJECT_NAME}-feltdb
15
20
  environment:
16
21
  FELTDB_APP_NAME: \${FELTDB_APP_NAME:-${config.appName}}
17
22
  FELTDB_APP_ID: \${FELTDB_APP_ID:-${config.appId}}
18
23
  FELTDB_VERSION: \${FELTDB_VERSION:-${config.version}}
24
+ FELTDB_ENVIRONMENT: \${FELTDB_ENVIRONMENT:-staging}
19
25
  FELTDB_PEERS: \${FELTDB_PEERS:-}
20
- FELTDB_REPLICATION_PORT: ${config.replicationPort}
26
+ FELTDB_MASTER_KEY: \${FELTDB_MASTER_KEY}
21
27
  NODE_ENV: \${NODE_ENV:-production}
22
28
  ports:
23
29
  - "\${FELTDB_API_PORT:-${config.port}}:7700"
24
- - "\${FELTDB_REPLICATION_PORT:-${config.replicationPort}}:${config.replicationPort}"
30
+ command:
31
+ - feltdb-server
32
+ - --host
33
+ - 0.0.0.0
34
+ - --port
35
+ - "7700"
36
+ - --namespace
37
+ - \${FELTDB_APP_ID:-${config.appId}}
38
+ - --data
39
+ - /data/feltdb.log
40
+ - --allow-origin
41
+ - http://127.0.0.1:\${APP_PORT:-5173}
42
+ - --allow-origin
43
+ - http://127.0.0.1:\${STUDIO_PORT:-${config.studioPort}}
25
44
  volumes:
26
45
  - feltdb_data:/data
27
46
  - ./feltdb.flow:/app/feltdb.flow:ro
@@ -69,11 +88,17 @@ export function generateDockerCompose(config) {
69
88
  app.feltdb/version: "${config.version}"
70
89
 
71
90
  studio:
72
- image: rkendel1/feltdb-studio:latest
91
+ image: \${STUDIO_IMAGE:-${config.appName.toLowerCase().replace(/[^a-z0-9]/g, '-')}-studio:${config.version}}
92
+ build:
93
+ context: .
94
+ dockerfile: Dockerfile.studio
95
+ args:
96
+ FELTDB_VERSION: ${config.version}
73
97
  container_name: \${COMPOSE_PROJECT_NAME}-studio
74
98
  environment:
75
- FELTDB_API_URL: http://feltdb:7700
76
- APP_URL: http://app:3000
99
+ FELTDB_API_URL: \${FELTDB_PUBLIC_URL:-http://127.0.0.1:${config.port}}
100
+ APP_URL: \${APP_PUBLIC_URL:-http://127.0.0.1:5173}
101
+ FELTDB_NAMESPACE: \${FELTDB_APP_ID:-${config.appId}}
77
102
  ports:
78
103
  - "\${STUDIO_PORT:-${config.studioPort}}:8000"
79
104
  depends_on:
@@ -97,6 +122,38 @@ volumes:
97
122
  app.feltdb/data: "durable-operations-log"
98
123
  `;
99
124
  }
125
+ export function generateFeltDBDockerfile(config) {
126
+ return `# Build the matching FeltDB server without adding engine source to the application.
127
+ FROM rust:1.96-alpine AS builder
128
+ RUN apk add --no-cache nodejs npm pkgconf openssl-dev musl-dev
129
+ WORKDIR /source
130
+ ARG FELTDB_VERSION=${config.version}
131
+ RUN npm install --global "create-feltdb@\${FELTDB_VERSION}" \
132
+ && cp -R "\$(npm root --global)/create-feltdb/dist/server-source/." /source/
133
+ RUN cargo build -p feltdb-server --release --locked
134
+
135
+ FROM alpine:3.22
136
+ RUN apk add --no-cache ca-certificates curl tini
137
+ COPY --from=builder /source/target/release/feltdb-server /usr/local/bin/feltdb-server
138
+ RUN adduser -D -u 1000 feltdb && mkdir -p /data && chown feltdb:feltdb /data
139
+ USER feltdb
140
+ EXPOSE 7700
141
+ HEALTHCHECK --interval=10s --timeout=5s --start-period=30s --retries=3 CMD curl -fsS http://127.0.0.1:7700/health || exit 1
142
+ ENTRYPOINT ["/sbin/tini", "--"]
143
+ CMD ["feltdb-server", "--host", "0.0.0.0", "--port", "7700", "--namespace", "${config.appId}", "--data", "/data/feltdb.log", "--allow-origin", "http://127.0.0.1:5173", "--allow-origin", "http://127.0.0.1:${config.studioPort}"]
144
+ `;
145
+ }
146
+ export function generateStudioDockerfile(config) {
147
+ return `# FeltDB Studio served by the same version as this generated project.
148
+ FROM node:22-alpine
149
+ ARG FELTDB_VERSION=${config.version}
150
+ RUN npm install --global "@feltdb/core@\${FELTDB_VERSION}" && npm cache clean --force
151
+ WORKDIR /project
152
+ COPY feltdb.flow ./feltdb.flow
153
+ EXPOSE 8000
154
+ CMD ["sh", "-c", "feltdb studio --host 0.0.0.0 --port 8000 --namespace \"\${FELTDB_NAMESPACE}\" --runtime self-hosted --connect \"\${FELTDB_API_URL}\" --app-url \"\${APP_URL}\" --no-open"]
155
+ `;
156
+ }
100
157
  export function generateDockerfile(config, framework) {
101
158
  const buildCommand = 'npm run build';
102
159
  return `# FeltDB Application Container
@@ -143,7 +200,7 @@ coverage
143
200
  .turbo
144
201
  `;
145
202
  }
146
- export function generateDotEnvLocal(config) {
203
+ export function generateDotEnvLocal(config, masterKey = '') {
147
204
  return `# Docker Compose Environment
148
205
  # Generated by create-feltdb for \${config.appName}
149
206
 
@@ -153,9 +210,11 @@ COMPOSE_PROJECT_NAME=${config.appName.toLowerCase().replace(/[^a-z0-9]/g, '-')}
153
210
  FELTDB_APP_NAME=${config.appName}
154
211
  FELTDB_APP_ID=${config.appId}
155
212
  FELTDB_VERSION=${config.version}
213
+ FELTDB_ENVIRONMENT=staging
156
214
  FELTDB_API_PORT=${config.port}
157
215
  FELTDB_REPLICATION_PORT=${config.replicationPort}
158
216
  FELTDB_PEERS=
217
+ FELTDB_MASTER_KEY=${masterKey}
159
218
 
160
219
  # Application Configuration
161
220
  APP_PORT=3000
@@ -164,8 +223,6 @@ FELTDB_API_URL=http://feltdb:7700
164
223
  # Studio Configuration
165
224
  STUDIO_PORT=${config.studioPort}
166
225
 
167
- # Runtime
168
- NODE_ENV=production
169
226
  `;
170
227
  }
171
228
  export function generateHealthCheckScript() {
@@ -1,4 +1,4 @@
1
1
  // One release train keeps generated applications installable. The repository
2
2
  // validation script checks these values against every workspace manifest.
3
- export const FELTDB_PACKAGE_VERSION = '0.4.12';
3
+ export const FELTDB_PACKAGE_VERSION = '0.4.14';
4
4
  export const feltdbPackageRange = `^${FELTDB_PACKAGE_VERSION}`;