create-memory-soda 0.3.0 → 0.4.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 (3) hide show
  1. package/README.md +2 -2
  2. package/index.js +26 -56
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -19,8 +19,8 @@ what it can, and ends with a checklist of anything it could not do for you.
19
19
  confirms pgvector and enables the extension. Failures name the fix and let
20
20
  you retry, paste another URL, or skip.
21
21
  5. **Gemini key** — checked live. Blank allowed; goes on the checklist.
22
- 6. **Ports and admin login** — ports checked for use; blank password is
23
- generated at first boot.
22
+ 6. **Ports** — checked for use. Dashboard login starts as `admin` /
23
+ `open-sesame`; change it after signing in.
24
24
  7. **Clone, `.env`, `npm ci`, migrations** — migrations run now if the database
25
25
  passed.
26
26
 
package/index.js CHANGED
@@ -83,15 +83,8 @@ function runWithSpinner(title, cmd, args, { cwd } = {}) {
83
83
  * explicitly — everything else stays on the defaults baked into config.ts, so
84
84
  * this file does not drift every time a new option is added there.
85
85
  */
86
- export function renderEnv({
87
- databaseUrl,
88
- geminiKey,
89
- adminUser,
90
- adminPassword,
91
- apiPort,
92
- dashboardPort,
93
- }) {
94
- const lines = [
86
+ export function renderEnv({ databaseUrl, geminiKey, apiPort, dashboardPort }) {
87
+ return [
95
88
  '# Generated by create-memory-soda.',
96
89
  '# Full reference: https://github.com/alagappan17/memory-soda',
97
90
  '',
@@ -108,15 +101,11 @@ export function renderEnv({
108
101
  `CORS_ORIGIN=http://localhost:${dashboardPort}`,
109
102
  `VITE_API_URL=http://localhost:${apiPort}`,
110
103
  '',
111
- '# Dashboard login, created once on first boot.',
112
- `ADMIN_USERNAME=${adminUser}`,
113
- ];
114
- // An unset ADMIN_PASSWORD makes the API generate one and print it once. That
115
- // is a better default than writing a weak chosen password to disk, so a blank
116
- // answer omits the key entirely rather than writing an empty one.
117
- if (adminPassword) lines.push(`ADMIN_PASSWORD=${adminPassword}`);
118
- lines.push('');
119
- return lines.join('\n');
104
+ '# Dashboard login. Defaults to admin / open-sesame — change it in the dashboard after first sign-in.',
105
+ '# ADMIN_USERNAME=admin',
106
+ '# ADMIN_PASSWORD=open-sesame',
107
+ '',
108
+ ].join('\n');
120
109
  }
121
110
 
122
111
  /** True if the path is safe to scaffold into: missing, or an empty directory. */
@@ -406,40 +395,35 @@ async function main() {
406
395
  }
407
396
  if (where !== 'skip') {
408
397
  for (;;) {
409
- const s = p.spinner();
398
+ // A clack spinner cannot be restarted once stopped (its timer leaks and
399
+ // the process never exits), so every phase gets a fresh one.
400
+ let s = p.spinner();
410
401
  s.start('Checking the database');
411
402
  let result = await checkDatabase(databaseUrl);
412
403
  if (result?.missingDb) {
413
404
  s.stop(`Database "${result.missingDb}" does not exist`);
414
405
  if (
415
- guard(
406
+ !guard(
416
407
  await p.confirm({
417
408
  message: `Create database "${result.missingDb}"?`,
418
409
  initialValue: true,
419
410
  }),
420
411
  )
421
412
  ) {
422
- s.start(`Creating database ${result.missingDb}`);
423
- try {
424
- await createDatabase(databaseUrl);
425
- result = await checkDatabase(databaseUrl);
426
- } catch (err) {
427
- result = {
428
- problem: `could not create database "${result.missingDb}": ${err.message}`,
429
- fix: `createdb ${result.missingDb} (as a role with CREATEDB)`,
430
- };
431
- }
432
- } else {
433
413
  todo.push(`createdb ${result.missingDb}`);
434
414
  break;
435
415
  }
436
- if (result?.missingDb)
416
+ s = p.spinner();
417
+ s.start(`Creating database ${result.missingDb}`);
418
+ try {
419
+ await createDatabase(databaseUrl);
420
+ result = await checkDatabase(databaseUrl);
421
+ } catch (err) {
437
422
  result = {
438
- problem: `database "${result.missingDb}" still does not exist`,
439
- fix: null,
423
+ problem: `could not create database "${result.missingDb}": ${err.message}`,
424
+ fix: `createdb ${result.missingDb} (as a role with CREATEDB)`,
440
425
  };
441
- if (result === null || result?.extensionTodo)
442
- s.start('Checking the database');
426
+ }
443
427
  }
444
428
  if (result === null) {
445
429
  s.stop('Database ready — connected, pgvector enabled');
@@ -504,24 +488,9 @@ async function main() {
504
488
  'Set GOOGLE_GENERATIVE_AI_API_KEY in .env — the API refuses to start without it',
505
489
  );
506
490
 
507
- // ── 5 + 6. Ports and login
491
+ // ── 5. Ports
508
492
  const apiPort = await askPort('API port', '3004');
509
493
  const dashboardPort = await askPort('Dashboard port', '3000');
510
- const adminUser = guard(
511
- await p.text({
512
- message: 'Dashboard admin username',
513
- placeholder: 'admin',
514
- defaultValue: 'admin',
515
- }),
516
- );
517
- const adminPassword =
518
- guard(
519
- await p.password({
520
- message: `Dashboard admin password ${chalk.dim('(leave blank to generate one at first boot)')}`,
521
- mask: '•',
522
- }),
523
- ) ?? '';
524
-
525
494
  // ── 7. Install
526
495
  await runWithSpinner(`Cloning into ${chalk.bold(dirName)}`, 'git', [
527
496
  'clone',
@@ -535,8 +504,6 @@ async function main() {
535
504
  renderEnv({
536
505
  databaseUrl,
537
506
  geminiKey,
538
- adminUser,
539
- adminPassword,
540
507
  apiPort,
541
508
  dashboardPort,
542
509
  }),
@@ -596,13 +563,16 @@ async function main() {
596
563
  '',
597
564
  `Dashboard ${chalk.underline(`http://localhost:${dashboardPort}`)}`,
598
565
  `API ${chalk.underline(`http://localhost:${apiPort}`)}`,
599
- `Login ${adminUser} / ${adminPassword ? 'the password you chose' : 'password printed at first boot'}`,
566
+ `Login ${chalk.bold('admin')} / ${chalk.bold('open-sesame')} ${chalk.dim('← change it under Settings after signing in')}`,
600
567
  '',
601
568
  'Then sign in, create an API key, and: npm install @memory-soda/sdk',
602
569
  ].join('\n'),
603
570
  'Run',
604
571
  );
605
- p.outro(`${chalk.bold(basename(target))} is ready.`);
572
+ p.outro(
573
+ `Thanks for trying Memory Soda — ${chalk.bold(basename(target))} is ready.`,
574
+ );
575
+ exit(0);
606
576
  }
607
577
 
608
578
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-memory-soda",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
4
4
  "description": "Scaffold a self-hosted Memory Soda instance — API, dashboard, and Postgres",
5
5
  "keywords": [
6
6
  "ai",