lsh-framework 3.1.17 → 3.1.19

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.
package/dist/cli.js CHANGED
@@ -10,13 +10,9 @@ import { registerDoctorCommands } from './commands/doctor.js';
10
10
  import { registerCompletionCommands } from './commands/completion.js';
11
11
  import { registerConfigCommands } from './commands/config.js';
12
12
  import { registerSyncHistoryCommands } from './commands/sync-history.js';
13
- import { registerIPFSCommands } from './commands/ipfs.js';
14
13
  import { registerSyncCommands } from './commands/sync.js';
15
14
  import { registerMigrateCommand } from './commands/migrate.js';
16
15
  import { registerContextCommand } from './commands/context.js';
17
- import { init_daemon } from './services/daemon/daemon.js';
18
- import { init_supabase } from './services/supabase/supabase.js';
19
- import { init_cron } from './services/cron/cron.js';
20
16
  import { init_secrets } from './services/secrets/secrets.js';
21
17
  import { loadGlobalConfigSync } from './lib/config-manager.js';
22
18
  import * as fs from 'fs';
@@ -67,22 +63,20 @@ program
67
63
  console.log(' delete Delete .env file');
68
64
  console.log(' status Get detailed secrets status');
69
65
  console.log('');
70
- console.log('šŸ”„ Automation (Optional - schedule secret rotation):');
71
- console.log(' cron add Schedule automatic tasks');
72
- console.log(' cron list List scheduled jobs');
73
- console.log(' daemon start Start persistent daemon');
66
+ console.log('šŸ”„ IPFS Sync:');
67
+ console.log(' sync init Full IPFS setup (install, init, start)');
68
+ console.log(' sync push Push secrets to IPFS → get CID');
69
+ console.log(' sync pull <cid> Pull secrets by CID');
70
+ console.log(' sync status Check IPFS and sync status');
71
+ console.log(' sync start/stop Control IPFS daemon');
74
72
  console.log('');
75
73
  console.log('šŸš€ Quick Start:');
76
- console.log(' lsh init # Interactive setup (first time)');
77
- console.log(' lsh doctor # Verify configuration');
78
- console.log(' lsh push --env dev # Push your secrets');
79
- console.log(' lsh pull --env dev # Pull on another machine');
74
+ console.log(' lsh sync init # One-time IPFS setup');
75
+ console.log(' lsh sync push # Push secrets to IPFS');
76
+ console.log(' lsh sync pull <cid> # Pull on another machine');
80
77
  console.log('');
81
78
  console.log('šŸ“š More Commands:');
82
79
  console.log(' config Manage LSH configuration (~/.config/lsh/lshrc)');
83
- console.log(' supabase Supabase database management');
84
- console.log(' daemon Daemon management');
85
- console.log(' cron Cron job management');
86
80
  console.log(' self Self-management commands');
87
81
  console.log(' --help Show all options');
88
82
  console.log('');
@@ -148,16 +142,11 @@ function findSimilarCommands(input, validCommands) {
148
142
  registerDoctorCommands(program);
149
143
  registerConfigCommands(program);
150
144
  registerSyncHistoryCommands(program);
151
- registerIPFSCommands(program);
152
145
  registerSyncCommands(program);
153
146
  registerMigrateCommand(program);
154
147
  registerContextCommand(program);
155
148
  // Secrets management (primary feature)
156
149
  await init_secrets(program);
157
- // Supporting services
158
- await init_supabase(program);
159
- await init_daemon(program);
160
- await init_cron(program);
161
150
  // Shell completion
162
151
  registerCompletionCommands(program);
163
152
  // Self-management commands
@@ -246,50 +235,37 @@ function showDetailedHelp() {
246
235
  console.log('Main Commands:');
247
236
  console.log(' init Interactive setup wizard (first-time)');
248
237
  console.log(' doctor Health check & troubleshooting');
249
- console.log(' sync Check sync status');
250
- console.log(' push Upload encrypted secrets');
251
- console.log(' pull Download encrypted secrets');
252
- console.log(' list List local secrets');
253
- console.log(' env Manage environments');
238
+ console.log(' env Show local .env file contents');
254
239
  console.log(' key Generate encryption key');
255
240
  console.log(' status Detailed status report');
256
241
  console.log('');
257
- console.log('Automation:');
258
- console.log(' daemon start Start background daemon');
259
- console.log(' daemon stop Stop background daemon');
260
- console.log(' daemon status Check daemon status');
261
- console.log(' cron add Schedule automatic tasks');
262
- console.log(' cron list List scheduled jobs');
242
+ console.log('IPFS Sync:');
243
+ console.log(' sync init Full IPFS setup (install, init, start)');
244
+ console.log(' sync push Push secrets to IPFS → get CID');
245
+ console.log(' sync pull <cid> Pull secrets by CID');
246
+ console.log(' sync status Check IPFS client, daemon, and sync status');
247
+ console.log(' sync start Start IPFS daemon');
248
+ console.log(' sync stop Stop IPFS daemon');
249
+ console.log(' sync history View sync history');
263
250
  console.log('');
264
251
  console.log('Self-Management:');
265
252
  console.log(' self update Update to latest version');
266
253
  console.log(' self version Show version information');
267
254
  console.log(' self uninstall Uninstall from system');
268
255
  console.log('');
269
- console.log('Database:');
270
- console.log(' supabase init Initialize Supabase connection');
271
- console.log(' supabase test Test Supabase connectivity');
272
- console.log(' supabase reset Reset database schema');
273
- console.log('');
274
256
  console.log('Examples:');
275
257
  console.log('');
276
258
  console.log(' First-Time Setup:');
277
- console.log(' lsh init # Interactive wizard');
259
+ console.log(' lsh sync init # One-time IPFS setup');
278
260
  console.log(' lsh doctor # Verify setup');
279
261
  console.log('');
280
262
  console.log(' Daily Usage:');
281
- console.log(' lsh push --env dev # Push to dev env');
282
- console.log(' lsh pull --env production # Pull from prod');
283
- console.log(' lsh sync # Check status');
263
+ console.log(' lsh sync push # Push to IPFS → get CID');
264
+ console.log(' lsh sync pull <cid> # Pull by CID');
265
+ console.log(' lsh env --masked # View local secrets');
284
266
  console.log(' lsh get API_KEY # Get specific secret');
285
267
  console.log(' lsh set API_KEY newvalue # Update secret');
286
268
  console.log('');
287
- console.log(' Automation:');
288
- console.log(' lsh daemon start # Start daemon');
289
- console.log(' lsh cron add --name rotate-keys \\');
290
- console.log(' --schedule "0 0 * * *" \\');
291
- console.log(' --command "./rotate.sh" # Daily rotation');
292
- console.log('');
293
269
  console.log('Features:');
294
270
  console.log(' āœ… Cross-platform (Windows, macOS, Linux)');
295
271
  console.log(' āœ… AES-256 encryption');
@@ -10,6 +10,7 @@ import * as fs from 'fs';
10
10
  import * as path from 'path';
11
11
  import * as crypto from 'crypto';
12
12
  import { getIPFSSync } from '../lib/ipfs-sync.js';
13
+ import { IPFSClientManager } from '../lib/ipfs-client-manager.js';
13
14
  import { getGitRepoInfo } from '../lib/git-utils.js';
14
15
  import { ENV_VARS } from '../constants/index.js';
15
16
  /**
@@ -23,17 +24,21 @@ export function registerSyncCommands(program) {
23
24
  // Show help when running `lsh sync` without subcommand
24
25
  console.log(chalk.bold.cyan('\nšŸ”„ LSH Sync - IPFS Secrets Sync\n'));
25
26
  console.log(chalk.gray('Sync encrypted secrets via native IPFS (no auth required)\n'));
26
- console.log(chalk.bold('Commands:'));
27
- console.log(` ${chalk.cyan('init')} šŸš€ Initialize and start the IPFS daemon`);
27
+ console.log(chalk.bold('Setup:'));
28
+ console.log(` ${chalk.cyan('init')} šŸš€ Full setup: install IPFS, initialize, and start daemon`);
29
+ console.log(` ${chalk.cyan('status')} šŸ“Š Show IPFS client, daemon, and sync status`);
30
+ console.log(` ${chalk.cyan('start')} ā–¶ļø Start IPFS daemon`);
31
+ console.log(` ${chalk.cyan('stop')} ā¹ļø Stop IPFS daemon`);
32
+ console.log('');
33
+ console.log(chalk.bold('Sync:'));
28
34
  console.log(` ${chalk.cyan('push')} ā¬†ļø Push encrypted secrets to IPFS`);
29
35
  console.log(` ${chalk.cyan('pull')} ā¬‡ļø Pull secrets from IPFS by CID`);
30
- console.log(` ${chalk.cyan('status')} šŸ“Š Show IPFS daemon and sync status`);
31
36
  console.log(` ${chalk.cyan('history')} šŸ“œ Show IPFS sync history`);
32
37
  console.log(` ${chalk.cyan('verify')} āœ… Verify that a CID is accessible on IPFS`);
33
38
  console.log(` ${chalk.cyan('clear')} šŸ—‘ļø Clear sync history`);
34
39
  console.log('');
35
40
  console.log(chalk.bold('Examples:'));
36
- console.log(chalk.gray(' lsh sync init # Set up IPFS for first time'));
41
+ console.log(chalk.gray(' lsh sync init # One-time setup'));
37
42
  console.log(chalk.gray(' lsh sync push # Push secrets, get CID'));
38
43
  console.log(chalk.gray(' lsh sync pull <cid> # Pull secrets by CID'));
39
44
  console.log('');
@@ -43,14 +48,16 @@ export function registerSyncCommands(program) {
43
48
  // lsh sync init
44
49
  syncCommand
45
50
  .command('init')
46
- .description('šŸš€ Initialize and start the IPFS daemon')
47
- .action(async () => {
48
- console.log(chalk.bold.cyan('\nšŸš€ Initializing IPFS for sync...\n'));
51
+ .description('šŸš€ Full setup: install IPFS, initialize repo, and start daemon')
52
+ .option('-f, --force', 'Force reinstall even if already installed')
53
+ .action(async (options) => {
54
+ console.log(chalk.bold.cyan('\nšŸš€ Setting up IPFS for sync...\n'));
55
+ const manager = new IPFSClientManager();
49
56
  const ipfsSync = getIPFSSync();
50
- // Check if daemon is already running
57
+ // Step 1: Check if daemon is already running
51
58
  if (await ipfsSync.checkDaemon()) {
52
59
  const info = await ipfsSync.getDaemonInfo();
53
- console.log(chalk.green('āœ… IPFS daemon is already running!'));
60
+ console.log(chalk.green('āœ… IPFS is already set up and running!'));
54
61
  if (info) {
55
62
  console.log(chalk.gray(` Peer ID: ${info.peerId.substring(0, 16)}...`));
56
63
  console.log(chalk.gray(` Version: ${info.version}`));
@@ -61,22 +68,62 @@ export function registerSyncCommands(program) {
61
68
  console.log('');
62
69
  return;
63
70
  }
64
- // Daemon not running, show instructions
65
- console.log(chalk.yellow('āš ļø IPFS daemon not running'));
66
- console.log('');
67
- console.log(chalk.gray('To start IPFS:'));
68
- console.log('');
69
- console.log(chalk.bold('1. Install IPFS (if not installed):'));
70
- console.log(chalk.cyan(' lsh ipfs install'));
71
- console.log('');
72
- console.log(chalk.bold('2. Initialize IPFS repository:'));
73
- console.log(chalk.cyan(' lsh ipfs init'));
71
+ // Step 2: Check if IPFS is installed
72
+ const clientInfo = await manager.detect();
73
+ if (!clientInfo.installed || options.force) {
74
+ const installSpinner = ora('Installing IPFS client (Kubo)...').start();
75
+ try {
76
+ await manager.install({ force: options.force });
77
+ installSpinner.succeed(chalk.green('IPFS client installed'));
78
+ }
79
+ catch (error) {
80
+ const err = error;
81
+ installSpinner.fail(chalk.red('Failed to install IPFS'));
82
+ console.error(chalk.red(err.message));
83
+ process.exit(1);
84
+ }
85
+ }
86
+ else {
87
+ console.log(chalk.green('āœ… IPFS client already installed'));
88
+ console.log(chalk.gray(` Version: ${clientInfo.version}`));
89
+ }
90
+ // Step 3: Initialize IPFS repository if needed
91
+ const initSpinner = ora('Initializing IPFS repository...').start();
92
+ try {
93
+ await manager.init();
94
+ initSpinner.succeed(chalk.green('IPFS repository initialized'));
95
+ }
96
+ catch (error) {
97
+ const err = error;
98
+ // Check if already initialized
99
+ if (err.message.includes('already') || err.message.includes('exists')) {
100
+ initSpinner.succeed(chalk.green('IPFS repository already initialized'));
101
+ }
102
+ else {
103
+ initSpinner.fail(chalk.red('Failed to initialize IPFS'));
104
+ console.error(chalk.red(err.message));
105
+ process.exit(1);
106
+ }
107
+ }
108
+ // Step 4: Start the daemon
109
+ const startSpinner = ora('Starting IPFS daemon...').start();
110
+ try {
111
+ await manager.start();
112
+ startSpinner.succeed(chalk.green('IPFS daemon started'));
113
+ }
114
+ catch (error) {
115
+ const err = error;
116
+ startSpinner.fail(chalk.red('Failed to start daemon'));
117
+ console.error(chalk.red(err.message));
118
+ process.exit(1);
119
+ }
120
+ // Final status
74
121
  console.log('');
75
- console.log(chalk.bold('3. Start the daemon:'));
76
- console.log(chalk.cyan(' lsh ipfs start'));
122
+ console.log(chalk.green.bold('āœ… IPFS setup complete!'));
77
123
  console.log('');
78
- console.log(chalk.gray('Or run all at once:'));
79
- console.log(chalk.cyan(' lsh ipfs install && lsh ipfs init && lsh ipfs start'));
124
+ console.log(chalk.gray('You can now sync secrets:'));
125
+ console.log(chalk.cyan(' lsh sync push # Push secrets → get CID'));
126
+ console.log(chalk.cyan(' lsh sync pull <cid> # Pull secrets by CID'));
80
127
  console.log('');
81
128
  });
82
129
  // lsh sync push
@@ -258,28 +305,78 @@ export function registerSyncCommands(program) {
258
305
  // lsh sync status
259
306
  syncCommand
260
307
  .command('status')
261
- .description('šŸ“Š Show IPFS daemon and sync status')
262
- .action(async () => {
308
+ .description('šŸ“Š Show IPFS client, daemon, and sync status')
309
+ .option('--json', 'Output as JSON')
310
+ .action(async (options) => {
263
311
  try {
312
+ const manager = new IPFSClientManager();
313
+ const clientInfo = await manager.detect();
264
314
  const ipfsSync = getIPFSSync();
265
315
  const daemonInfo = await ipfsSync.getDaemonInfo();
316
+ const history = await ipfsSync.getHistory(5);
317
+ if (options.json) {
318
+ console.log(JSON.stringify({
319
+ client: clientInfo,
320
+ daemonRunning: !!daemonInfo,
321
+ daemonInfo,
322
+ recentSyncs: history.length,
323
+ }, null, 2));
324
+ return;
325
+ }
266
326
  console.log(chalk.bold.cyan('\nšŸ“Š Sync Status\n'));
267
327
  console.log(chalk.gray('━'.repeat(50)));
268
328
  console.log('');
329
+ // Client status
330
+ console.log(chalk.bold('IPFS Client:'));
331
+ if (clientInfo.installed) {
332
+ console.log(chalk.green(' āœ… Installed'));
333
+ console.log(` Type: ${clientInfo.type}`);
334
+ console.log(` Version: ${clientInfo.version}`);
335
+ }
336
+ else {
337
+ console.log(chalk.yellow(' āš ļø Not installed'));
338
+ console.log(chalk.gray(' Run: lsh sync init'));
339
+ }
340
+ console.log('');
341
+ // Daemon status
342
+ console.log(chalk.bold('IPFS Daemon:'));
269
343
  if (daemonInfo) {
270
- console.log(chalk.green('āœ… IPFS daemon running'));
271
- console.log(` Peer ID: ${daemonInfo.peerId.substring(0, 16)}...`);
272
- console.log(` Version: ${daemonInfo.version}`);
273
- console.log('');
274
- console.log(chalk.gray('Ready to sync:'));
275
- console.log(chalk.cyan(' lsh sync push # Push secrets'));
344
+ console.log(chalk.green(' āœ… Running'));
345
+ console.log(` Peer ID: ${daemonInfo.peerId.substring(0, 16)}...`);
346
+ console.log(` API: http://127.0.0.1:5001`);
347
+ console.log(` Gateway: http://127.0.0.1:8080`);
348
+ }
349
+ else {
350
+ console.log(chalk.yellow(' āš ļø Not running'));
351
+ console.log(chalk.gray(' Run: lsh sync start'));
352
+ }
353
+ console.log('');
354
+ // Recent syncs
355
+ console.log(chalk.bold('Recent Syncs:'));
356
+ if (history.length > 0) {
357
+ console.log(` ${history.length} recent sync(s)`);
358
+ const latest = history[0];
359
+ const date = new Date(latest.timestamp);
360
+ console.log(` Latest: ${date.toLocaleString()}`);
361
+ console.log(` CID: ${latest.cid.substring(0, 20)}...`);
362
+ }
363
+ else {
364
+ console.log(chalk.gray(' No sync history'));
365
+ }
366
+ console.log('');
367
+ // Quick actions
368
+ if (clientInfo.installed && daemonInfo) {
369
+ console.log(chalk.bold('Ready to sync:'));
370
+ console.log(chalk.cyan(' lsh sync push # Push secrets'));
276
371
  console.log(chalk.cyan(' lsh sync pull <cid> # Pull by CID'));
277
372
  }
373
+ else if (!clientInfo.installed) {
374
+ console.log(chalk.bold('Get started:'));
375
+ console.log(chalk.cyan(' lsh sync init # Full setup'));
376
+ }
278
377
  else {
279
- console.log(chalk.yellow('āš ļø IPFS daemon not running'));
280
- console.log('');
281
- console.log(chalk.gray('Start with:'));
282
- console.log(chalk.cyan(' lsh sync init'));
378
+ console.log(chalk.bold('Start daemon:'));
379
+ console.log(chalk.cyan(' lsh sync start'));
283
380
  }
284
381
  console.log('');
285
382
  }
@@ -389,5 +486,45 @@ export function registerSyncCommands(program) {
389
486
  process.exit(1);
390
487
  }
391
488
  });
489
+ // lsh sync start
490
+ syncCommand
491
+ .command('start')
492
+ .description('ā–¶ļø Start IPFS daemon')
493
+ .action(async () => {
494
+ try {
495
+ const manager = new IPFSClientManager();
496
+ const ipfsSync = getIPFSSync();
497
+ // Check if already running
498
+ if (await ipfsSync.checkDaemon()) {
499
+ const info = await ipfsSync.getDaemonInfo();
500
+ console.log(chalk.green('āœ… IPFS daemon is already running'));
501
+ if (info) {
502
+ console.log(chalk.gray(` Peer ID: ${info.peerId.substring(0, 16)}...`));
503
+ }
504
+ return;
505
+ }
506
+ await manager.start();
507
+ }
508
+ catch (error) {
509
+ const err = error;
510
+ console.error(chalk.red('Failed to start daemon:'), err.message);
511
+ process.exit(1);
512
+ }
513
+ });
514
+ // lsh sync stop
515
+ syncCommand
516
+ .command('stop')
517
+ .description('ā¹ļø Stop IPFS daemon')
518
+ .action(async () => {
519
+ try {
520
+ const manager = new IPFSClientManager();
521
+ await manager.stop();
522
+ }
523
+ catch (error) {
524
+ const err = error;
525
+ console.error(chalk.red('Failed to stop daemon:'), err.message);
526
+ process.exit(1);
527
+ }
528
+ });
392
529
  }
393
530
  export default registerSyncCommands;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lsh-framework",
3
- "version": "3.1.17",
3
+ "version": "3.1.19",
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": {