lsh-framework 0.9.2 → 0.10.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.
package/dist/cli.js CHANGED
@@ -75,11 +75,12 @@ program
75
75
  console.log(' sync Check sync status & get recommendations');
76
76
  console.log(' push Upload .env to encrypted cloud storage');
77
77
  console.log(' pull Download .env from cloud storage');
78
- console.log(' list List all stored environments');
78
+ console.log(' list List secrets in current local .env file');
79
+ console.log(' env List all stored environments');
79
80
  console.log(' show View secrets (masked)');
80
81
  console.log(' key Generate encryption key');
81
82
  console.log(' create Create new .env file');
82
- console.log(' get <key> Get a specific secret value');
83
+ console.log(' get <key> Get a specific secret value (--all for all)');
83
84
  console.log(' set <key> <value> Set a specific secret value');
84
85
  console.log(' delete Delete .env file');
85
86
  console.log(' status Get detailed secrets status');
@@ -43,10 +43,71 @@ export async function init_secrets(program) {
43
43
  process.exit(1);
44
44
  }
45
45
  });
46
- // List environments
46
+ // List current local secrets
47
47
  program
48
- .command('list [environment]')
48
+ .command('list')
49
49
  .alias('ls')
50
+ .description('List secrets in the current local .env file')
51
+ .option('-f, --file <path>', 'Path to .env file', '.env')
52
+ .option('--keys-only', 'Show only keys, not values')
53
+ .action(async (options) => {
54
+ try {
55
+ const envPath = path.resolve(options.file);
56
+ if (!fs.existsSync(envPath)) {
57
+ console.error(`āŒ File not found: ${envPath}`);
58
+ console.log('šŸ’” Tip: Pull from cloud with: lsh pull --env <environment>');
59
+ process.exit(1);
60
+ }
61
+ const content = fs.readFileSync(envPath, 'utf8');
62
+ const lines = content.split('\n');
63
+ const secrets = [];
64
+ for (const line of lines) {
65
+ if (line.trim().startsWith('#') || !line.trim())
66
+ continue;
67
+ const match = line.match(/^([^=]+)=(.*)$/);
68
+ if (match) {
69
+ const key = match[1].trim();
70
+ let value = match[2].trim();
71
+ // Remove quotes if present
72
+ if ((value.startsWith('"') && value.endsWith('"')) ||
73
+ (value.startsWith("'") && value.endsWith("'"))) {
74
+ value = value.slice(1, -1);
75
+ }
76
+ secrets.push({ key, value });
77
+ }
78
+ }
79
+ if (secrets.length === 0) {
80
+ console.log('No secrets found in .env file');
81
+ return;
82
+ }
83
+ console.log(`\nšŸ“‹ Secrets in ${options.file}:\n`);
84
+ for (const { key, value } of secrets) {
85
+ if (options.keysOnly) {
86
+ console.log(` ${key}`);
87
+ }
88
+ else {
89
+ // Mask the value but show first/last 3 chars if long enough
90
+ let maskedValue = value;
91
+ if (value.length > 8) {
92
+ maskedValue = `${value.substring(0, 3)}${'*'.repeat(value.length - 6)}${value.substring(value.length - 3)}`;
93
+ }
94
+ else if (value.length > 0) {
95
+ maskedValue = '*'.repeat(value.length);
96
+ }
97
+ console.log(` ${key}=${maskedValue}`);
98
+ }
99
+ }
100
+ console.log(`\n Total: ${secrets.length} secrets\n`);
101
+ }
102
+ catch (error) {
103
+ const err = error;
104
+ console.error('āŒ Failed to list secrets:', err.message);
105
+ process.exit(1);
106
+ }
107
+ });
108
+ // Manage environments (old 'list' functionality)
109
+ program
110
+ .command('env [environment]')
50
111
  .description('List all stored environments or show secrets for specific environment')
51
112
  .option('--all-files', 'List all tracked .env files across environments')
52
113
  .action(async (environment, options) => {
@@ -220,9 +281,11 @@ API_KEY=
220
281
  });
221
282
  // Get a specific secret value
222
283
  program
223
- .command('get <key>')
224
- .description('Get a specific secret value from .env file')
284
+ .command('get [key]')
285
+ .description('Get a specific secret value from .env file, or all secrets with --all')
225
286
  .option('-f, --file <path>', 'Path to .env file', '.env')
287
+ .option('--all', 'Get all secrets from the file')
288
+ .option('--export', 'Output in export format for shell evaluation')
226
289
  .action(async (key, options) => {
227
290
  try {
228
291
  const envPath = path.resolve(options.file);
@@ -232,6 +295,45 @@ API_KEY=
232
295
  }
233
296
  const content = fs.readFileSync(envPath, 'utf8');
234
297
  const lines = content.split('\n');
298
+ // Handle --all flag
299
+ if (options.all) {
300
+ const secrets = [];
301
+ for (const line of lines) {
302
+ if (line.trim().startsWith('#') || !line.trim())
303
+ continue;
304
+ const match = line.match(/^([^=]+)=(.*)$/);
305
+ if (match) {
306
+ const key = match[1].trim();
307
+ let value = match[2].trim();
308
+ // Remove quotes if present
309
+ if ((value.startsWith('"') && value.endsWith('"')) ||
310
+ (value.startsWith("'") && value.endsWith("'"))) {
311
+ value = value.slice(1, -1);
312
+ }
313
+ secrets.push({ key, value });
314
+ }
315
+ }
316
+ if (options.export) {
317
+ // Output in export format for shell evaluation
318
+ for (const { key, value } of secrets) {
319
+ // Escape single quotes in value and wrap in single quotes
320
+ const escapedValue = value.replace(/'/g, "'\\''");
321
+ console.log(`export ${key}='${escapedValue}'`);
322
+ }
323
+ }
324
+ else {
325
+ // Output in KEY=VALUE format
326
+ for (const { key, value } of secrets) {
327
+ console.log(`${key}=${value}`);
328
+ }
329
+ }
330
+ return;
331
+ }
332
+ // Handle single key lookup
333
+ if (!key) {
334
+ console.error('āŒ Please provide a key or use --all flag');
335
+ process.exit(1);
336
+ }
235
337
  for (const line of lines) {
236
338
  if (line.trim().startsWith('#') || !line.trim())
237
339
  continue;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lsh-framework",
3
- "version": "0.9.2",
3
+ "version": "0.10.0",
4
4
  "description": "Encrypted secrets manager with automatic rotation, team sync, and multi-environment support. Built on a powerful shell with daemon scheduling and CI/CD integration.",
5
5
  "main": "dist/app.js",
6
6
  "bin": {