@feltdb/core 0.6.12 → 0.6.13

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.
@@ -71,7 +71,7 @@ export function applicationUrlCandidate(project, environment = process.env) {
71
71
  if (project.configuredUrl)
72
72
  return project.configuredUrl;
73
73
  if (project.configuredPort)
74
- return `http://127.0.0.1:${project.configuredPort}`;
74
+ return `http://localhost:${project.configuredPort}/`;
75
75
  return undefined;
76
76
  }
77
77
  export function applicationIsRunning(url, timeoutMs = 750) {
@@ -0,0 +1,35 @@
1
+ import { spawn } from 'child_process';
2
+ function defaultSpawn(command, args) {
3
+ return spawn(command, [...args], { detached: true, stdio: 'ignore' });
4
+ }
5
+ export function browserCommand(url, platform = process.platform) {
6
+ if (platform === 'darwin')
7
+ return ['open', [url]];
8
+ if (platform === 'win32')
9
+ return ['cmd', ['/c', 'start', '', url]];
10
+ if (platform === 'linux')
11
+ return ['xdg-open', [url]];
12
+ return null;
13
+ }
14
+ export function openBrowser(url, spawnBrowser = defaultSpawn) {
15
+ const command = browserCommand(url);
16
+ if (!command || !process.stdout.isTTY || process.env.CI)
17
+ return false;
18
+ try {
19
+ const child = spawnBrowser(command[0], command[1]);
20
+ child.once('error', () => undefined);
21
+ child.unref();
22
+ return true;
23
+ }
24
+ catch {
25
+ return false;
26
+ }
27
+ }
28
+ export function openApplication(url) {
29
+ console.log(`🌐 Application: ${url}`);
30
+ return openBrowser(url);
31
+ }
32
+ export function openStudio(url) {
33
+ console.log(`šŸ› ļø Studio: ${url}`);
34
+ return openBrowser(url);
35
+ }
@@ -13,6 +13,7 @@ import { discoverWorkspace, ensureWorkspaceGitIgnored, generatePairingToken, per
13
13
  import { applicationUrlCandidate, detectApplication, discoverApplicationUrl } from './application.js';
14
14
  import { resolveApplicationLifecycle, startManagedApplication, waitForManagedApplication } from './application-lifecycle.js';
15
15
  import { createDevelopmentSession, developmentSessionEnvironment, developmentSessionSummary, transitionDevelopmentSession } from './development-session.js';
16
+ import { openApplication, openStudio } from './browser-opening.js';
16
17
  function loadProjectEnvironment(file = path.resolve('.env.local')) {
17
18
  if (!fs.existsSync(file))
18
19
  return;
@@ -511,7 +512,7 @@ async function handleDev(args) {
511
512
  if (args.includes('--help')) {
512
513
  console.log('Usage: feltdb dev [--app-url URL] [--studio-port 7701] [--authority-port 7700] [--discovery-port 7799] [--no-open]');
513
514
  console.log('\nOptions:');
514
- console.log(' --app-url <url> Application URL (e.g., http://127.0.0.1:3000)');
515
+ console.log(' --app-url <url> Application URL (e.g., http://localhost:3000/)');
515
516
  console.log(' --studio-port <port> FeltDB Studio port (default: 7701)');
516
517
  console.log(' --authority-port <port> Authority port (default: 7700)');
517
518
  console.log(' --discovery-port <port> Pairing discovery port (default: 7799)');
@@ -628,7 +629,7 @@ async function handleDev(args) {
628
629
  console.log(`Attaching existing FeltDB application (${detectedApplication.feltDBSignals.join(', ')})\n`);
629
630
  }
630
631
  const requestedStudioPort = Number(args.includes('--studio-port') ? args[args.indexOf('--studio-port') + 1] || '7701' : '7701');
631
- const studioPort = String(await availablePort(requestedStudioPort));
632
+ const studioPort = String(await availablePort(requestedStudioPort, 'localhost'));
632
633
  if (studioPort !== String(requestedStudioPort))
633
634
  console.log(`⚠ Port ${requestedStudioPort} is busy; using ${studioPort} for Studio.\n`);
634
635
  process.env.STUDIO_PORT = studioPort;
@@ -678,7 +679,7 @@ async function handleDev(args) {
678
679
  storage: config.storage,
679
680
  lifecycle: applicationLifecycle,
680
681
  authorityUrl,
681
- studioUrl: `http://127.0.0.1:${studioPort}`,
682
+ studioUrl: `http://localhost:${studioPort}/`,
682
683
  pairingUrl: `http://127.0.0.1:${discoveryPort}`,
683
684
  applicationUrl: appUrl,
684
685
  });
@@ -791,7 +792,7 @@ async function handleDev(args) {
791
792
  else {
792
793
  console.log('āŒ No application URL is configured.\n');
793
794
  console.log('Start your application, then run:\n');
794
- console.log(' feltdb dev --app-url http://127.0.0.1:<port>\n');
795
+ console.log(' feltdb dev --app-url http://localhost:<port>/\n');
795
796
  console.log('Or set applicationUrl in feltdb.config.json\n');
796
797
  console.log('FeltDB workspace is ready at:');
797
798
  console.log('Authority: ' + developmentSession.authorityUrl);
@@ -812,10 +813,21 @@ async function handleDev(args) {
812
813
  '--lifecycle', developmentSession.lifecycle,
813
814
  ...(developmentSession.applicationUrl ? ['--app-url', developmentSession.applicationUrl] : []),
814
815
  ...((developmentSession.runtime === 'self-hosted' || developmentSession.runtime === 'managed') ? ['--connect', developmentSession.authorityUrl] : []),
815
- ...(open ? [] : ['--no-open']),
816
- ], () => {
816
+ '--no-open',
817
+ ], studioUrl => {
818
+ developmentSession.studioUrl = studioUrl;
817
819
  transitionDevelopmentSession(developmentSession, 'READY');
818
820
  console.log(`\n${developmentSessionSummary(developmentSession)}\n`);
821
+ if (open) {
822
+ if (developmentSession.applicationUrl)
823
+ openApplication(developmentSession.applicationUrl);
824
+ openStudio(developmentSession.studioUrl);
825
+ }
826
+ else {
827
+ if (developmentSession.applicationUrl)
828
+ console.log(`🌐 Application: ${developmentSession.applicationUrl}`);
829
+ console.log(`šŸ› ļø Studio: ${developmentSession.studioUrl}`);
830
+ }
819
831
  transitionDevelopmentSession(developmentSession, 'RUNNING');
820
832
  });
821
833
  if (managedApplication) {
@@ -1092,8 +1104,8 @@ async function handleStudio(args, onReady) {
1092
1104
  ? args[args.indexOf('--port') + 1] || '7701'
1093
1105
  : '7701';
1094
1106
  const host = args.includes('--host')
1095
- ? args[args.indexOf('--host') + 1] || '127.0.0.1'
1096
- : '127.0.0.1';
1107
+ ? args[args.indexOf('--host') + 1] || 'localhost'
1108
+ : 'localhost';
1097
1109
  const open = !args.includes('--no-open');
1098
1110
  const namespace = args.includes('--namespace')
1099
1111
  ? args[args.indexOf('--namespace') + 1] || 'default'
@@ -1223,15 +1235,12 @@ async function handleStudio(args, onReady) {
1223
1235
  if (session.pairingUrl)
1224
1236
  parameters.set('pairing', session.pairingUrl);
1225
1237
  const query = `?${parameters.toString()}`;
1226
- const studioUrl = `http://127.0.0.1:${port}/${query}`;
1238
+ const studioUrl = `http://localhost:${port}/${query}`;
1227
1239
  console.log(`FeltDB Studio ready at ${studioUrl}`);
1228
- onReady?.();
1240
+ onReady?.(studioUrl);
1229
1241
  console.log('Use Ctrl+C to stop the server.');
1230
- if (open) {
1231
- const command = process.platform === 'darwin' ? ['open', studioUrl] : process.platform === 'win32' ? ['cmd', '/c', 'start', '', studioUrl] : ['xdg-open', studioUrl];
1232
- const child = spawn(command[0], command.slice(1), { detached: true, stdio: 'ignore' });
1233
- child.unref();
1234
- }
1242
+ if (open)
1243
+ openStudio(studioUrl);
1235
1244
  await new Promise(() => { });
1236
1245
  }
1237
1246
  function handleHelp() {
package/dist/cli/index.js CHANGED
@@ -23,7 +23,7 @@ import * as path from 'path';
23
23
  import * as readline from 'readline';
24
24
  import { getClient } from './api-client.js';
25
25
  import { loadFeltDBConfig, createDefaultConfig, validateModel, } from './config.js';
26
- const VERSION = '0.6.12';
26
+ const VERSION = '0.6.13';
27
27
  function prompt(question) {
28
28
  const rl = readline.createInterface({
29
29
  input: process.stdin,
@@ -11,6 +11,7 @@ import { spawn, spawnSync } from 'child_process';
11
11
  import { createProject } from './create.js';
12
12
  import { FELTDB_PACKAGE_VERSION } from './package-versions.js';
13
13
  import { configureManagedAccount } from './managed-account.js';
14
+ import { localFeltdbExecutable } from './development-handoff.js';
14
15
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
15
16
  function parseArgs(args) {
16
17
  const options = {
@@ -235,7 +236,7 @@ Options:
235
236
  --no-webllm Do not install WebLLM or generate the AI builder
236
237
  --capabilities <list> Choose capabilities: search, vector, or search,vector
237
238
  --no-install Skip npm install
238
- --no-start Skip npm run dev
239
+ --no-start Skip automatic feltdb dev startup
239
240
  -y, --yes Use all defaults (non-interactive mode)
240
241
  -h, --help Show this help message
241
242
  --version Show version number
@@ -314,6 +315,7 @@ Learn more: https://github.com/rkendel1/feltdb`);
314
315
  agents: options.agents,
315
316
  webllm: options.webllm,
316
317
  capabilities: options.capabilities,
318
+ showNextSteps: false,
317
319
  });
318
320
  projectCreated = true;
319
321
  if (options.runtime === 'managed') {
@@ -335,18 +337,18 @@ Learn more: https://github.com/rkendel1/feltdb`);
335
337
  }
336
338
  if (shouldStart) {
337
339
  if (!shouldInstall) {
338
- console.log(`Start after installing dependencies:\n cd ${projectName}\n npm install\n npm run dev\n`);
340
+ console.log(`Start after installing dependencies:\n cd ${projectName}\n npm install\n npm run feltdb:dev\n`);
339
341
  }
340
342
  else {
341
343
  if (options.runtime === 'self-hosted' && spawnSync('docker', ['version'], { stdio: 'ignore' }).status !== 0) {
342
344
  console.log('\nāœ… Project and Docker image definition are ready.');
343
345
  console.log('Docker is not currently running, so startup was skipped.');
344
- console.log(`Start Docker Desktop, then run:\n cd ${projectName}\n npm run dev`);
346
+ console.log(`Start Docker Desktop, then run:\n cd ${projectName}\n npm run feltdb:dev`);
345
347
  console.log('Build the production application image with: docker compose build app');
346
348
  }
347
349
  else {
348
- console.log('\nšŸš€ Starting the application...\n');
349
- await run(npm, ['run', 'dev'], projectDir);
350
+ console.log('\nšŸš€ Starting your FeltDB development session...\n');
351
+ await run(localFeltdbExecutable(projectDir), ['dev'], projectDir);
350
352
  }
351
353
  }
352
354
  }
@@ -87,7 +87,7 @@ export async function createProject(options) {
87
87
  application: {
88
88
  lifecycle: 'managed',
89
89
  },
90
- applicationUrl: 'http://127.0.0.1:5173',
90
+ applicationUrl: 'http://localhost:5173/',
91
91
  capabilities: {},
92
92
  };
93
93
  if (capabilities.includes('search')) {
@@ -1657,7 +1657,7 @@ Configuration is in \`feltdb.config.json\`:
1657
1657
  "application": {
1658
1658
  "lifecycle": "managed"
1659
1659
  },
1660
- "applicationUrl": "http://127.0.0.1:5173",
1660
+ "applicationUrl": "http://localhost:5173/",
1661
1661
  "capabilities": ["${capabilities}"]
1662
1662
  }
1663
1663
  \`\`\`
@@ -1810,9 +1810,11 @@ MIT
1810
1810
  console.log(`\nāœ“ Development Workspace initialized`);
1811
1811
  console.log(` Workspace ID: ${workspaceDiscovery.workspaceId}`);
1812
1812
  console.log(` Location: ${path.join(projectName, '.feltdb/workspace.json')}`);
1813
- console.log(`\nNext steps:`);
1814
- console.log(` cd ${projectName}`);
1815
- console.log(` npm install`);
1816
- console.log(` npm run dev`);
1817
- console.log(`\nYour Development Workspace is ready for use!`);
1813
+ if (options.showNextSteps !== false) {
1814
+ console.log(`\nNext steps:`);
1815
+ console.log(` cd ${projectName}`);
1816
+ console.log(` npm install`);
1817
+ console.log(` npm run feltdb:dev`);
1818
+ console.log(`\nYour Development Workspace is ready for use!`);
1819
+ }
1818
1820
  }
@@ -0,0 +1,4 @@
1
+ import path from 'path';
2
+ export function localFeltdbExecutable(projectDir, platform = process.platform) {
3
+ return path.join(projectDir, 'node_modules', '.bin', platform === 'win32' ? 'feltdb.cmd' : 'feltdb');
4
+ }
@@ -38,9 +38,9 @@ export function generateDockerCompose(config) {
38
38
  - --data
39
39
  - /data/feltdb.log
40
40
  - --allow-origin
41
- - http://127.0.0.1:\${APP_PORT:-5173}
41
+ - http://localhost:\${APP_PORT:-5173}
42
42
  - --allow-origin
43
- - http://127.0.0.1:\${STUDIO_PORT:-${config.studioPort}}
43
+ - http://localhost:\${STUDIO_PORT:-${config.studioPort}}
44
44
  volumes:
45
45
  - feltdb_data:/data
46
46
  - ./feltdb.flow:/app/feltdb.flow:ro
@@ -97,7 +97,7 @@ export function generateDockerCompose(config) {
97
97
  container_name: \${COMPOSE_PROJECT_NAME}-studio
98
98
  environment:
99
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}
100
+ APP_URL: \${APP_PUBLIC_URL:-http://localhost:5173/}
101
101
  FELTDB_NAMESPACE: \${FELTDB_APP_ID:-${config.appId}}
102
102
  ports:
103
103
  - "\${STUDIO_PORT:-${config.studioPort}}:8000"
@@ -140,7 +140,7 @@ USER feltdb
140
140
  EXPOSE 7700
141
141
  HEALTHCHECK --interval=10s --timeout=5s --start-period=30s --retries=3 CMD curl -fsS http://127.0.0.1:7700/health || exit 1
142
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}"]
143
+ CMD ["feltdb-server", "--host", "0.0.0.0", "--port", "7700", "--namespace", "${config.appId}", "--data", "/data/feltdb.log", "--allow-origin", "http://localhost:5173", "--allow-origin", "http://localhost:${config.studioPort}"]
144
144
  `;
145
145
  }
146
146
  export function generateStudioDockerfile(config) {
@@ -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.6.12';
3
+ export const FELTDB_PACKAGE_VERSION = '0.6.13';
4
4
  export const feltdbPackageRange = `^${FELTDB_PACKAGE_VERSION}`;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@feltdb/core",
3
- "version": "0.6.12",
3
+ "version": "0.6.13",
4
4
  "description": "FeltDB Core - Application-facing database with Browser, Local, and Server runtimes. Durable state, reactive APIs.",
5
5
  "license": "MIT",
6
6
  "type": "module",