lsh-framework 2.1.0 → 2.1.2

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.
@@ -18,6 +18,7 @@ export function registerInitCommands(program) {
18
18
  .command('init')
19
19
  .description('Interactive setup wizard (first-time configuration)')
20
20
  .option('--local', 'Use local-only encryption (no cloud sync)')
21
+ .option('--storacha', 'Use Storacha IPFS network sync (recommended)')
21
22
  .option('--supabase', 'Use Supabase cloud storage')
22
23
  .option('--postgres', 'Use self-hosted PostgreSQL')
23
24
  .option('--skip-test', 'Skip connection testing')
@@ -58,7 +59,10 @@ async function runSetupWizard(options) {
58
59
  }
59
60
  // Determine storage type
60
61
  let storageType;
61
- if (options.local) {
62
+ if (options.storacha) {
63
+ storageType = 'storacha';
64
+ }
65
+ else if (options.local) {
62
66
  storageType = 'local';
63
67
  }
64
68
  else if (options.postgres) {
@@ -76,19 +80,23 @@ async function runSetupWizard(options) {
76
80
  message: 'Choose storage backend:',
77
81
  choices: [
78
82
  {
79
- name: 'Supabase (free, cloud-hosted, recommended)',
83
+ name: '🌐 Storacha (IPFS network, zero-config, recommended)',
84
+ value: 'storacha',
85
+ },
86
+ {
87
+ name: 'ā˜ļø Supabase (cloud-hosted, team collaboration)',
80
88
  value: 'supabase',
81
89
  },
82
90
  {
83
- name: 'Local encryption (file-based, no cloud sync)',
91
+ name: 'šŸ’¾ Local encryption (file-based, no cloud sync)',
84
92
  value: 'local',
85
93
  },
86
94
  {
87
- name: 'Self-hosted PostgreSQL',
95
+ name: '🐘 Self-hosted PostgreSQL',
88
96
  value: 'postgres',
89
97
  },
90
98
  ],
91
- default: 'supabase',
99
+ default: 'storacha',
92
100
  },
93
101
  ]);
94
102
  storageType = storage;
@@ -98,7 +106,10 @@ async function runSetupWizard(options) {
98
106
  encryptionKey: generateEncryptionKey(),
99
107
  };
100
108
  // Configure based on storage type
101
- if (storageType === 'supabase') {
109
+ if (storageType === 'storacha') {
110
+ await configureStoracha(config);
111
+ }
112
+ else if (storageType === 'supabase') {
102
113
  await configureSupabase(config, options.skipTest);
103
114
  }
104
115
  else if (storageType === 'postgres') {
@@ -195,6 +206,34 @@ async function testSupabaseConnection(url, key) {
195
206
  throw new Error(`Could not connect to Supabase: ${err.message}`);
196
207
  }
197
208
  }
209
+ /**
210
+ * Configure Storacha IPFS network sync
211
+ */
212
+ async function configureStoracha(config) {
213
+ console.log(chalk.cyan('\n🌐 Storacha IPFS Network Sync'));
214
+ console.log(chalk.gray('Zero-config multi-host secrets sync via IPFS network'));
215
+ console.log('');
216
+ const answers = await inquirer.prompt([
217
+ {
218
+ type: 'input',
219
+ name: 'email',
220
+ message: 'Enter your email for Storacha authentication:',
221
+ validate: (input) => {
222
+ if (!input.trim())
223
+ return 'Email is required';
224
+ if (!input.includes('@'))
225
+ return 'Must be a valid email address';
226
+ return true;
227
+ },
228
+ },
229
+ ]);
230
+ config.storachaEmail = answers.email.trim();
231
+ console.log('');
232
+ console.log(chalk.yellow('šŸ“§ Please check your email to complete authentication.'));
233
+ console.log(chalk.gray(' After setup completes, run:'));
234
+ console.log(chalk.cyan(' lsh storacha login ' + config.storachaEmail));
235
+ console.log('');
236
+ }
198
237
  /**
199
238
  * Configure self-hosted PostgreSQL
200
239
  */
@@ -270,6 +309,9 @@ async function saveConfiguration(config) {
270
309
  if (config.storageType === 'local') {
271
310
  updates.LSH_STORAGE_MODE = 'local';
272
311
  }
312
+ if (config.storageType === 'storacha') {
313
+ updates.LSH_STORACHA_ENABLED = 'true';
314
+ }
273
315
  // Update .env content
274
316
  for (const [key, value] of Object.entries(updates)) {
275
317
  const regex = new RegExp(`^${key}=.*$`, 'm');
@@ -335,7 +377,10 @@ function showSuccessMessage(config) {
335
377
  console.log(chalk.gray(' Share it with your team to sync secrets.'));
336
378
  console.log('');
337
379
  // Storage info
338
- if (config.storageType === 'supabase') {
380
+ if (config.storageType === 'storacha') {
381
+ console.log(chalk.cyan('🌐 Using Storacha IPFS network sync'));
382
+ }
383
+ else if (config.storageType === 'supabase') {
339
384
  console.log(chalk.cyan('ā˜ļø Using Supabase cloud storage'));
340
385
  }
341
386
  else if (config.storageType === 'postgres') {
@@ -348,21 +393,37 @@ function showSuccessMessage(config) {
348
393
  // Next steps
349
394
  console.log(chalk.bold('šŸš€ Next steps:'));
350
395
  console.log('');
351
- console.log(chalk.gray(' 1. Verify your setup:'));
352
- console.log(chalk.cyan(' lsh doctor'));
353
- console.log('');
354
- if (config.storageType !== 'local') {
396
+ if (config.storageType === 'storacha') {
397
+ console.log(chalk.gray(' 1. Authenticate with Storacha:'));
398
+ console.log(chalk.cyan(` lsh storacha login ${config.storachaEmail || 'your@email.com'}`));
399
+ console.log('');
355
400
  console.log(chalk.gray(' 2. Push your secrets:'));
356
401
  console.log(chalk.cyan(' lsh push --env dev'));
402
+ console.log(chalk.gray(' (Automatically uploads to IPFS network)'));
357
403
  console.log('');
358
404
  console.log(chalk.gray(' 3. On another machine:'));
359
- console.log(chalk.cyan(' lsh init ') + chalk.gray('# Use the same credentials'));
405
+ console.log(chalk.cyan(' lsh init --storacha'));
406
+ console.log(chalk.cyan(' lsh storacha login your@email.com'));
360
407
  console.log(chalk.cyan(' lsh pull --env dev'));
408
+ console.log(chalk.gray(' (Automatically downloads from IPFS network)'));
361
409
  }
362
410
  else {
363
- console.log(chalk.gray(' 2. Start managing secrets:'));
364
- console.log(chalk.cyan(' lsh set API_KEY myvalue'));
365
- console.log(chalk.cyan(' lsh list'));
411
+ console.log(chalk.gray(' 1. Verify your setup:'));
412
+ console.log(chalk.cyan(' lsh doctor'));
413
+ console.log('');
414
+ if (config.storageType !== 'local') {
415
+ console.log(chalk.gray(' 2. Push your secrets:'));
416
+ console.log(chalk.cyan(' lsh push --env dev'));
417
+ console.log('');
418
+ console.log(chalk.gray(' 3. On another machine:'));
419
+ console.log(chalk.cyan(' lsh init ') + chalk.gray('# Use the same credentials'));
420
+ console.log(chalk.cyan(' lsh pull --env dev'));
421
+ }
422
+ else {
423
+ console.log(chalk.gray(' 2. Start managing secrets:'));
424
+ console.log(chalk.cyan(' lsh set API_KEY myvalue'));
425
+ console.log(chalk.cyan(' lsh list'));
426
+ }
366
427
  }
367
428
  console.log('');
368
429
  console.log(chalk.gray('šŸ“– Documentation: https://github.com/gwicho38/lsh'));
@@ -236,11 +236,11 @@ export class SecretsManager {
236
236
  if (filename !== '.env' && !filename.startsWith('.env.')) {
237
237
  throw new Error(`Invalid filename: ${filename}. Must be '.env' or start with '.env.'`);
238
238
  }
239
- logger.info(`Pulling ${filename} (${this.getRepoAwareEnvironment(environment)}) from IPFS...`);
239
+ const effectiveEnv = this.getRepoAwareEnvironment(environment);
240
+ logger.info(`Pulling ${filename} (${effectiveEnv}) from IPFS...`);
240
241
  // Get secrets from IPFS storage
241
- const secrets = await this.storage.pull(environment, this.encryptionKey, this.gitInfo?.repoName);
242
+ const secrets = await this.storage.pull(effectiveEnv, this.encryptionKey, this.gitInfo?.repoName);
242
243
  if (secrets.length === 0) {
243
- const effectiveEnv = this.getRepoAwareEnvironment(environment);
244
244
  throw new Error(`No secrets found for environment: ${effectiveEnv}\n\n` +
245
245
  `šŸ’” Tip: Check available environments with: lsh env\n` +
246
246
  ` Or push secrets first with: lsh push --env ${environment}`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lsh-framework",
3
- "version": "2.1.0",
3
+ "version": "2.1.2",
4
4
  "description": "Simple, cross-platform encrypted secrets manager with automatic sync, IPFS audit logs, and multi-environment support. Just run lsh sync and start managing your secrets.",
5
5
  "main": "dist/app.js",
6
6
  "bin": {