vaulter-cli 0.2.1 → 2.3.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vaulter-cli",
3
- "version": "0.2.1",
3
+ "version": "2.3.0",
4
4
  "description": "CLI tool for Vaulter - Secure API Key Manager",
5
5
  "author": "faris-sait",
6
6
  "repository": {
package/postinstall.js CHANGED
@@ -17,6 +17,7 @@ console.log(purple4 + ' Your keys. Your vault.' + reset);
17
17
  console.log('');
18
18
  console.log(purple + ' COMMANDS' + reset);
19
19
  console.log('');
20
+ console.log(' ' + bold + white + 'vaulter init ' + reset + dim + 'Initialize current directory as a Vaulter project' + reset);
20
21
  console.log(' ' + bold + white + 'vaulter sign-in ' + reset + dim + 'Authenticate with Vaulter via browser' + reset);
21
22
  console.log(' ' + bold + white + 'vaulter sign-out ' + reset + dim + 'Sign out and clear saved credentials' + reset);
22
23
  console.log(' ' + bold + white + 'vaulter ls ' + reset + dim + 'List all API keys in your vault' + reset);
@@ -16,6 +16,7 @@ export async function showHelp() {
16
16
  console.log('');
17
17
 
18
18
  const commands = [
19
+ { name: 'init', desc: 'Initialize current directory as a Vaulter project' },
19
20
  { name: 'sign-in', desc: 'Authenticate with Vaulter via browser' },
20
21
  { name: 'sign-out', desc: 'Sign out and clear saved credentials' },
21
22
  { name: 'ls', desc: 'List all API keys in your vault' },
@@ -0,0 +1,119 @@
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+ import inquirer from 'inquirer';
4
+ import {
5
+ isInitialized,
6
+ getProjectConfig,
7
+ createDefaultConfig,
8
+ writeProjectConfig,
9
+ getProjectDirPath,
10
+ } from '../lib/project.js';
11
+ import { isAuthenticated } from '../lib/auth.js';
12
+ import { success, error, warn, tip, dim, purple, bold, white } from '../lib/ui.js';
13
+
14
+ export async function initProject(options = {}) {
15
+ const root = process.cwd();
16
+ const dirName = path.basename(root);
17
+ const yes = options.yes || false;
18
+
19
+ console.log('');
20
+
21
+ // Check if already initialized
22
+ if (isInitialized(root)) {
23
+ const existing = getProjectConfig(root);
24
+
25
+ if (existing) {
26
+ console.log(dim(` Existing project: ${bold(existing.project?.name || 'unknown')}`));
27
+ console.log(dim(` Created: ${existing.project?.createdAt || 'unknown'}`));
28
+ console.log('');
29
+ }
30
+
31
+ if (!yes) {
32
+ const { reinit } = await inquirer.prompt([
33
+ {
34
+ type: 'confirm',
35
+ name: 'reinit',
36
+ message: purple('.vaulter/ already exists. Re-initialize?'),
37
+ default: false,
38
+ },
39
+ ]);
40
+ if (!reinit) {
41
+ warn('Cancelled.');
42
+ console.log('');
43
+ return;
44
+ }
45
+ }
46
+ }
47
+
48
+ // Prompt for project name
49
+ let projectName = options.name || null;
50
+
51
+ if (!projectName && !yes) {
52
+ const { name } = await inquirer.prompt([
53
+ {
54
+ type: 'input',
55
+ name: 'name',
56
+ message: purple('Project name:'),
57
+ default: dirName,
58
+ },
59
+ ]);
60
+ projectName = name;
61
+ }
62
+
63
+ if (!projectName) {
64
+ projectName = dirName;
65
+ }
66
+
67
+ // Create config
68
+ const config = createDefaultConfig(projectName);
69
+
70
+ try {
71
+ writeProjectConfig(root, config);
72
+ } catch (err) {
73
+ error(`Failed to create .vaulter/config.json: ${err.message}`);
74
+ console.log('');
75
+ return;
76
+ }
77
+
78
+ success(`Initialized Vaulter project "${projectName}"`);
79
+
80
+ // Append .vaulter/ to .gitignore if it exists and doesn't already contain it
81
+ const gitignorePath = path.join(root, '.gitignore');
82
+ if (fs.existsSync(gitignorePath)) {
83
+ try {
84
+ const content = fs.readFileSync(gitignorePath, 'utf-8');
85
+ if (!content.includes('.vaulter/')) {
86
+ fs.appendFileSync(gitignorePath, '\n.vaulter/\n');
87
+ success('Added .vaulter/ to .gitignore');
88
+ }
89
+ } catch {
90
+ warn('Could not update .gitignore (non-fatal)');
91
+ }
92
+ }
93
+
94
+ // .env tips based on state
95
+ const envPath = path.join(root, '.env');
96
+ const envExists = fs.existsSync(envPath);
97
+
98
+ if (envExists) {
99
+ tip('Run `vaulter save` to upload your .env to the vault, or `vaulter make` to regenerate it.');
100
+ } else if (isAuthenticated()) {
101
+ console.log('');
102
+ const { generate } = await inquirer.prompt([
103
+ {
104
+ type: 'confirm',
105
+ name: 'generate',
106
+ message: purple('No .env found. Generate one from your vault?'),
107
+ default: true,
108
+ },
109
+ ]);
110
+ if (generate) {
111
+ const { makeEnv } = await import('./make.js');
112
+ await makeEnv(undefined, {});
113
+ }
114
+ } else {
115
+ tip('Run `vaulter sign-in` to connect your vault, then `vaulter make` to generate a .env.');
116
+ }
117
+
118
+ console.log('');
119
+ }
package/src/index.js CHANGED
@@ -8,6 +8,7 @@ import { addKey } from './commands/add.js';
8
8
  import { removeKey } from './commands/remove.js';
9
9
  import { makeEnv } from './commands/make.js';
10
10
  import { saveEnv } from './commands/save.js';
11
+ import { initProject } from './commands/init.js';
11
12
  import { openWebApp } from './commands/web-app.js';
12
13
  import { showHelp } from './commands/help.js';
13
14
  import { printLogo } from './assets/logo.js';
@@ -19,7 +20,7 @@ const program = new Command();
19
20
  program
20
21
  .name('vaulter')
21
22
  .description('Vaulter CLI - Secure API Key Manager')
22
- .version('0.2.1')
23
+ .version('2.3.0')
23
24
  .action(async () => {
24
25
  await showHelp();
25
26
  });
@@ -90,6 +91,15 @@ program
90
91
  await saveEnv(filename);
91
92
  });
92
93
 
94
+ program
95
+ .command('init')
96
+ .description('Initialize current directory as a Vaulter project')
97
+ .option('-n, --name <name>', 'Project name')
98
+ .option('-y, --yes', 'Non-interactive, use all defaults')
99
+ .action(async (options) => {
100
+ await initProject(options);
101
+ });
102
+
93
103
  program
94
104
  .command('web-app')
95
105
  .description('Open the Vaulter web app in your browser')
@@ -0,0 +1,56 @@
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+
4
+ const VAULTER_PROJECT_DIR = '.vaulter';
5
+ const CONFIG_FILE = 'config.json';
6
+
7
+ export function getProjectDirPath(root = process.cwd()) {
8
+ return path.join(root, VAULTER_PROJECT_DIR);
9
+ }
10
+
11
+ export function getConfigFilePath(root = process.cwd()) {
12
+ return path.join(root, VAULTER_PROJECT_DIR, CONFIG_FILE);
13
+ }
14
+
15
+ export function isInitialized(root = process.cwd()) {
16
+ return fs.existsSync(getConfigFilePath(root));
17
+ }
18
+
19
+ export function getProjectConfig(root = process.cwd()) {
20
+ try {
21
+ const data = JSON.parse(fs.readFileSync(getConfigFilePath(root), 'utf-8'));
22
+ return data;
23
+ } catch {
24
+ return null;
25
+ }
26
+ }
27
+
28
+ export function ensureProjectDir(root = process.cwd()) {
29
+ const dirPath = getProjectDirPath(root);
30
+ if (!fs.existsSync(dirPath)) {
31
+ fs.mkdirSync(dirPath, { mode: 0o700 });
32
+ }
33
+ }
34
+
35
+ export function createDefaultConfig(name) {
36
+ const now = new Date().toISOString();
37
+ return {
38
+ version: 1,
39
+ project: {
40
+ name,
41
+ createdAt: now,
42
+ updatedAt: now,
43
+ },
44
+ sync: { enabled: false, remote: null },
45
+ env: { autoGenerate: false, filename: '.env', selectedKeys: [] },
46
+ };
47
+ }
48
+
49
+ export function writeProjectConfig(root, config) {
50
+ ensureProjectDir(root);
51
+ fs.writeFileSync(
52
+ getConfigFilePath(root),
53
+ JSON.stringify(config, null, 2) + '\n',
54
+ { mode: 0o600 }
55
+ );
56
+ }