dc-ops-cli 1.0.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 (62) hide show
  1. package/README.md +310 -0
  2. package/dist/commands/copy.d.ts +23 -0
  3. package/dist/commands/copy.d.ts.map +1 -0
  4. package/dist/commands/copy.js +74 -0
  5. package/dist/commands/copy.js.map +1 -0
  6. package/dist/commands/export.d.ts +14 -0
  7. package/dist/commands/export.d.ts.map +1 -0
  8. package/dist/commands/export.js +111 -0
  9. package/dist/commands/export.js.map +1 -0
  10. package/dist/commands/get.d.ts +31 -0
  11. package/dist/commands/get.d.ts.map +1 -0
  12. package/dist/commands/get.js +142 -0
  13. package/dist/commands/get.js.map +1 -0
  14. package/dist/commands/import.d.ts +27 -0
  15. package/dist/commands/import.d.ts.map +1 -0
  16. package/dist/commands/import.js +129 -0
  17. package/dist/commands/import.js.map +1 -0
  18. package/dist/commands/inspect.d.ts +20 -0
  19. package/dist/commands/inspect.d.ts.map +1 -0
  20. package/dist/commands/inspect.js +73 -0
  21. package/dist/commands/inspect.js.map +1 -0
  22. package/dist/commands/list.d.ts +11 -0
  23. package/dist/commands/list.d.ts.map +1 -0
  24. package/dist/commands/list.js +90 -0
  25. package/dist/commands/list.js.map +1 -0
  26. package/dist/commands/resolve.d.ts +18 -0
  27. package/dist/commands/resolve.d.ts.map +1 -0
  28. package/dist/commands/resolve.js +143 -0
  29. package/dist/commands/resolve.js.map +1 -0
  30. package/dist/commands/run.d.ts +29 -0
  31. package/dist/commands/run.d.ts.map +1 -0
  32. package/dist/commands/run.js +127 -0
  33. package/dist/commands/run.js.map +1 -0
  34. package/dist/commands/set.d.ts +12 -0
  35. package/dist/commands/set.d.ts.map +1 -0
  36. package/dist/commands/set.js +86 -0
  37. package/dist/commands/set.js.map +1 -0
  38. package/dist/commands/vaults.d.ts +18 -0
  39. package/dist/commands/vaults.d.ts.map +1 -0
  40. package/dist/commands/vaults.js +54 -0
  41. package/dist/commands/vaults.js.map +1 -0
  42. package/dist/index.d.ts +3 -0
  43. package/dist/index.d.ts.map +1 -0
  44. package/dist/index.js +161 -0
  45. package/dist/index.js.map +1 -0
  46. package/dist/utils/cli.d.ts +8 -0
  47. package/dist/utils/cli.d.ts.map +1 -0
  48. package/dist/utils/cli.js +53 -0
  49. package/dist/utils/cli.js.map +1 -0
  50. package/dist/utils/io.d.ts +2 -0
  51. package/dist/utils/io.d.ts.map +1 -0
  52. package/dist/utils/io.js +8 -0
  53. package/dist/utils/io.js.map +1 -0
  54. package/dist/utils/op.d.ts +68 -0
  55. package/dist/utils/op.d.ts.map +1 -0
  56. package/dist/utils/op.js +358 -0
  57. package/dist/utils/op.js.map +1 -0
  58. package/dist/utils/types.d.ts +31 -0
  59. package/dist/utils/types.d.ts.map +1 -0
  60. package/dist/utils/types.js +9 -0
  61. package/dist/utils/types.js.map +1 -0
  62. package/package.json +52 -0
package/README.md ADDED
@@ -0,0 +1,310 @@
1
+ # ops - 1Password CLI Helper
2
+
3
+ Easy secret retrieval from 1Password with smart fallbacks and interactive prompts.
4
+
5
+ ## Features
6
+
7
+ - 🔐 **Smart retrieval** - Get secrets with automatic fallback prompts
8
+ - 📝 **Interactive prompts** - Create secrets on-the-fly if not found
9
+ - 📋 **List & search** - Browse your vault items
10
+ - ⭐ **Favorites** - Quick access to your most-used secrets
11
+ - 📤 **Export** - Generate .env files from your vault
12
+ - 🔍 **Inspect** - Discover available fields for any secret
13
+ - 🏦 **Vaults** - List and browse available vaults
14
+ - 💡 **Smart suggestions** - Get hints when secrets or fields aren't found
15
+ - 🎨 **Beautiful UI** - Colored output and progress indicators
16
+ - 🔒 **Secure** - Never exposes secrets in logs or chat
17
+
18
+ ## Installation
19
+
20
+ ```bash
21
+ # Install dependencies
22
+ cd op-cli-helper
23
+ npm install
24
+
25
+ # Build
26
+ npm run build
27
+
28
+ # Link globally for development
29
+ npm link
30
+ ```
31
+
32
+ ## Prerequisites
33
+
34
+ 1. Install [1Password CLI](https://1password.com/downloads/command-line/)
35
+ 2. Sign in: `op signin`
36
+
37
+ ## Usage
38
+
39
+ ### Get a secret
40
+
41
+ ```bash
42
+ # Get a secret (prompts to create if not found)
43
+ ops get GITHUB_TOKEN
44
+
45
+ # Specify vault and field
46
+ ops get GITHUB_TOKEN --vault Personal --field api-key
47
+
48
+ # Plain output (for piping)
49
+ export TOKEN=$(ops get GITHUB_TOKEN --plain)
50
+
51
+ # JSON output
52
+ ops get GITHUB_TOKEN --json
53
+ ```
54
+
55
+ ### Store a secret
56
+
57
+ ```bash
58
+ # Interactive prompt for value
59
+ ops set GITHUB_TOKEN
60
+
61
+ # Pass value directly
62
+ ops set GITHUB_TOKEN --value "ghp_xxxxxxxxxxxx"
63
+
64
+ # Read value from file or stdin
65
+ ops set GITHUB_TOKEN --value-file ~/.secrets/github_token
66
+ cat token.txt | ops set GITHUB_TOKEN --value -
67
+
68
+ # Specify vault
69
+ ops set GITHUB_TOKEN --vault Work
70
+ ```
71
+
72
+ ### Copy a secret to the clipboard
73
+
74
+ ```bash
75
+ # Copy and clear after 30s
76
+ ops copy GITHUB_TOKEN
77
+
78
+ # Custom TTL
79
+ ops copy GITHUB_TOKEN --ttl 10
80
+ ```
81
+
82
+ ### List secrets
83
+
84
+ ```bash
85
+ # List all items in default vault
86
+ ops list
87
+
88
+ # List from specific vault
89
+ ops list --vault Work
90
+
91
+ # Search items
92
+ ops list --search "github"
93
+
94
+ # Dedicated search command
95
+ ops search "github"
96
+
97
+ # JSON output
98
+ ops list --json
99
+
100
+ # Plain output (tab-delimited)
101
+ ops list --plain
102
+ ```
103
+
104
+ ### View favorites
105
+
106
+ ```bash
107
+ # List only favorite items (⭐ markers in regular list)
108
+ ops favorites
109
+
110
+ # Or use the flag
111
+ ops list --favorites
112
+
113
+ # Favorites also show in regular list with ⭐ markers
114
+ ops list
115
+
116
+ # Mark items as favorites in 1Password app or web interface
117
+ ```
118
+
119
+ ### Export secrets
120
+
121
+ ```bash
122
+ # Export as .env to stdout
123
+ ops export
124
+
125
+ # Export to file
126
+ ops export --output .env
127
+
128
+ # Export as JSON
129
+ ops export --format json --output secrets.json
130
+
131
+ # JSON to stdout
132
+ ops export --json
133
+
134
+ # From specific vault
135
+ ops export --vault Work --output work.env
136
+ ```
137
+
138
+ ### Import secrets
139
+
140
+ ```bash
141
+ # Import from a .env file (KEY=VALUE per line)
142
+ ops import .env
143
+
144
+ # Import into a specific vault
145
+ ops import .env --vault Work
146
+
147
+ # Preview what would be imported without making changes
148
+ ops import .env --dry-run
149
+ ```
150
+
151
+ ### Run a command with injected secrets
152
+
153
+ Create a `.env.ops` file that maps environment variables to secret names:
154
+
155
+ ```
156
+ API_KEY=MY_API_KEY_SECRET
157
+ DB_PASSWORD=MY_DB_PASSWORD
158
+ ```
159
+
160
+ Then run:
161
+
162
+ ```bash
163
+ ops run -- node app.js
164
+
165
+ # Or inline mappings
166
+ ops run --env API_KEY=MY_API_KEY_SECRET -- node app.js
167
+
168
+ # Verbose mode shows which secrets are injected
169
+ ops run --verbose --env API_KEY=MY_API_KEY_SECRET -- node app.js
170
+ ```
171
+
172
+ ### Resolve a share link
173
+
174
+ ```bash
175
+ # Resolve a 1Password share link to an op:// reference
176
+ ops resolve "https://share.1password.com/s#..."
177
+
178
+ # JSON output for scripting
179
+ ops resolve "https://share.1password.com/s#..." --json
180
+ ```
181
+
182
+ Outputs all available fields (id/label/type) so you can pick the right `--field`.
183
+
184
+ ### Inspect a secret
185
+
186
+ ```bash
187
+ # List available fields for a secret
188
+ ops inspect "GitHub PAT"
189
+
190
+ # JSON output
191
+ ops inspect "GitHub PAT" --json
192
+ ```
193
+
194
+ Useful for discovering field names before using `ops get --field`.
195
+
196
+ ### List vaults
197
+
198
+ ```bash
199
+ # List all available vaults
200
+ ops vaults
201
+
202
+ # JSON output
203
+ ops vaults --json
204
+ ```
205
+
206
+ ### Smart suggestions
207
+
208
+ When a secret or field isn't found, ops provides helpful suggestions:
209
+
210
+ ```bash
211
+ # If field doesn't exist, suggests available fields
212
+ $ ops get "GitHub PAT" --field token
213
+ Error: Field "token" not found
214
+ Available fields: password, username, otp
215
+ Try: ops get "GitHub PAT" --field password
216
+
217
+ # If secret doesn't exist, suggests similar names
218
+ $ ops get "GutHub PAT"
219
+ Error: Secret "GutHub PAT" not found
220
+ Did you mean: GitHub PAT, GitLab PAT
221
+ ```
222
+
223
+ The clipboard `copy` command also confirms when it clears the clipboard after the TTL expires.
224
+
225
+ ## Integration with AGENTS.md Pattern
226
+
227
+ This tool follows the pattern in §13 of AGENTS.md:
228
+
229
+ ```bash
230
+ # 1. Check 1Password first
231
+ ops get OPENAI_API_KEY --silent 2>/dev/null || echo "not_found"
232
+
233
+ # 2. If not found, prompt and store
234
+ ops set OPENAI_API_KEY
235
+
236
+ # 3. Never leave raw tokens in files
237
+ # Always use: ops get SERVICE_KEY --silent
238
+ ```
239
+
240
+ ## Common Patterns
241
+
242
+ ### Development Environment Setup
243
+
244
+ ```bash
245
+ # Generate .env from 1Password
246
+ ops export --vault Development --output .env
247
+
248
+ # Source it
249
+ source .env
250
+ ```
251
+
252
+ ### CI/CD Integration
253
+
254
+ ```bash
255
+ # Get secret for GitHub Actions
256
+ export TOKEN=$(ops get DEPLOY_TOKEN --silent)
257
+
258
+ # Or export all secrets
259
+ ops export --format json | jq -r 'to_entries | .[] | "\(.key)=\(.value)"' >> $GITHUB_ENV
260
+ ```
261
+
262
+ ### Shell Script Integration
263
+
264
+ ```bash
265
+ #!/bin/bash
266
+ set -e
267
+
268
+ # Get API key with automatic prompt if missing
269
+ API_KEY=$(ops get MY_SERVICE_API_KEY --silent)
270
+
271
+ # Use in curl
272
+ curl -H "Authorization: Bearer $API_KEY" https://api.example.com
273
+ ```
274
+
275
+ ## Commands Reference
276
+
277
+ | Command | Description | Options |
278
+ |---------|-------------|---------|
279
+ | `get <name>` | Get a secret | `-v, --vault`, `-f, --field`, `--plain`, `--json`, `-s, --silent`, `--no-input` |
280
+ | `set <name>` | Store a secret | `-v, --vault`, `-f, --field`, `--value`, `--value-file`, `--force`, `--no-input` |
281
+ | `copy <name>` | Copy a secret to clipboard | `-v, --vault`, `-f, --field`, `--ttl`, `-q, --quiet` |
282
+ | `list` | List vault items | `-v, --vault`, `-s, --search`, `-j, --json`, `--plain`, `--favorites` |
283
+ | `search <query>` | Search items by title | `-v, --vault`, `-j, --json`, `--plain` |
284
+ | `favorites` | List favorite items | `-v, --vault`, `-j, --json`, `--plain` |
285
+ | `export` | Export to .env/JSON | `-v, --vault`, `-f, --format`, `-j, --json`, `-o, --output` |
286
+ | `import <file>` | Import secrets from .env | `-v, --vault`, `--dry-run` |
287
+ | `run` | Run a command with secrets injected | `-v, --vault`, `-f, --field`, `-e, --env`, `--env-file`, `--verbose` |
288
+ | `resolve <shareLink>` | Resolve share link to ops reference | `-j, --json` |
289
+ | `inspect <name>` | Show available fields for a secret | `-v, --vault`, `-j, --json` |
290
+ | `vaults` | List available vaults | `-j, --json` |
291
+
292
+ ## Development
293
+
294
+ ```bash
295
+ # Install dependencies
296
+ npm install
297
+
298
+ # Run in dev mode
299
+ npm run dev -- get GITHUB_TOKEN
300
+
301
+ # Type check
302
+ npm run typecheck
303
+
304
+ # Build
305
+ npm run build
306
+ ```
307
+
308
+ ## License
309
+
310
+ MIT
@@ -0,0 +1,23 @@
1
+ import { getSecret, checkOpCli } from '../utils/op.js';
2
+ import { applyColorConfig, createSpinner, resolveBooleanOption, resolveField, resolveVault } from '../utils/cli.js';
3
+ export interface CopyOptions {
4
+ vault?: string;
5
+ field?: string;
6
+ ttl?: number;
7
+ quiet?: boolean;
8
+ color?: boolean;
9
+ }
10
+ export interface CopyDependencies {
11
+ getSecret: typeof getSecret;
12
+ checkOpCli: typeof checkOpCli;
13
+ clipboardRead: () => Promise<string>;
14
+ clipboardWrite: (value: string) => Promise<void>;
15
+ applyColorConfig: typeof applyColorConfig;
16
+ createSpinner: typeof createSpinner;
17
+ resolveBooleanOption: typeof resolveBooleanOption;
18
+ resolveField: typeof resolveField;
19
+ resolveVault: typeof resolveVault;
20
+ }
21
+ export declare function createCopyCommand(overrides?: Partial<CopyDependencies>): (name: string, options: CopyOptions) => Promise<void>;
22
+ export declare const copyCommand: (name: string, options: CopyOptions) => Promise<void>;
23
+ //# sourceMappingURL=copy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"copy.d.ts","sourceRoot":"","sources":["../../src/commands/copy.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AACvD,OAAO,EACL,gBAAgB,EAChB,aAAa,EACb,oBAAoB,EACpB,YAAY,EACZ,YAAY,EACb,MAAM,iBAAiB,CAAC;AAGzB,MAAM,WAAW,WAAW;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAYD,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,OAAO,SAAS,CAAC;IAC5B,UAAU,EAAE,OAAO,UAAU,CAAC;IAC9B,aAAa,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;IACrC,cAAc,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACjD,gBAAgB,EAAE,OAAO,gBAAgB,CAAC;IAC1C,aAAa,EAAE,OAAO,aAAa,CAAC;IACpC,oBAAoB,EAAE,OAAO,oBAAoB,CAAC;IAClD,YAAY,EAAE,OAAO,YAAY,CAAC;IAClC,YAAY,EAAE,OAAO,YAAY,CAAC;CACnC;AAcD,wBAAgB,iBAAiB,CAC/B,SAAS,GAAE,OAAO,CAAC,gBAAgB,CAAM,GACxC,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,KAAK,OAAO,CAAC,IAAI,CAAC,CA4DvD;AAED,eAAO,MAAM,WAAW,SA9Dd,MAAM,WAAW,WAAW,KAAK,OAAO,CAAC,IAAI,CA8DT,CAAC"}
@@ -0,0 +1,74 @@
1
+ import chalk from 'chalk';
2
+ import clipboardy from 'clipboardy';
3
+ import { getSecret, checkOpCli } from '../utils/op.js';
4
+ import { applyColorConfig, createSpinner, resolveBooleanOption, resolveField, resolveVault, } from '../utils/cli.js';
5
+ import { OpError } from '../utils/types.js';
6
+ const DEFAULT_TTL_SECONDS = 30;
7
+ function resolveTtlSeconds(value) {
8
+ if (value === undefined)
9
+ return DEFAULT_TTL_SECONDS;
10
+ if (!Number.isFinite(value) || value < 0) {
11
+ throw new OpError('Clipboard TTL must be a non-negative number of seconds.', 2);
12
+ }
13
+ return value;
14
+ }
15
+ const defaultDependencies = {
16
+ getSecret,
17
+ checkOpCli,
18
+ clipboardRead: () => clipboardy.read(),
19
+ clipboardWrite: (value) => clipboardy.write(value),
20
+ applyColorConfig,
21
+ createSpinner,
22
+ resolveBooleanOption,
23
+ resolveField,
24
+ resolveVault,
25
+ };
26
+ export function createCopyCommand(overrides = {}) {
27
+ const deps = { ...defaultDependencies, ...overrides };
28
+ return async function copyCommand(name, options) {
29
+ try {
30
+ deps.checkOpCli();
31
+ const vault = deps.resolveVault(options.vault);
32
+ const field = deps.resolveField(options.field);
33
+ const envQuiet = deps.resolveBooleanOption(undefined, 'OPS_QUIET');
34
+ const quiet = options.quiet === true || envQuiet;
35
+ const envNoColor = deps.resolveBooleanOption(undefined, 'OPS_NO_COLOR');
36
+ const noColor = options.color === false || envNoColor;
37
+ const ttlSeconds = resolveTtlSeconds(options.ttl);
38
+ deps.applyColorConfig(noColor);
39
+ const spinner = deps.createSpinner('Copying secret to clipboard...', quiet);
40
+ const secret = deps.getSecret(name, vault, field);
41
+ if (secret === null) {
42
+ spinner.fail(chalk.yellow(`Secret "${name}" not found in vault "${vault}"`));
43
+ throw new OpError('Secret not found.', 1);
44
+ }
45
+ await deps.clipboardWrite(secret);
46
+ if (!quiet) {
47
+ spinner.succeed(chalk.green(`Copied to clipboard! Will clear in ${ttlSeconds}s.`));
48
+ }
49
+ setTimeout(async () => {
50
+ try {
51
+ const current = await deps.clipboardRead();
52
+ if (current === secret) {
53
+ await deps.clipboardWrite('');
54
+ if (!quiet) {
55
+ console.log(chalk.gray('✓ Clipboard cleared'));
56
+ }
57
+ }
58
+ }
59
+ catch {
60
+ // Best-effort clipboard cleanup.
61
+ }
62
+ }, ttlSeconds * 1000);
63
+ }
64
+ catch (error) {
65
+ if (error instanceof OpError) {
66
+ console.error(chalk.red(`Error: ${error.message}`));
67
+ process.exit(error.exitCode);
68
+ }
69
+ throw error;
70
+ }
71
+ };
72
+ }
73
+ export const copyCommand = createCopyCommand();
74
+ //# sourceMappingURL=copy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"copy.js","sourceRoot":"","sources":["../../src/commands/copy.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import { ExportOptions, OpItem } from '../utils/types.js';
2
+ import type oraType from 'ora';
3
+ export interface ExportDeps {
4
+ checkOpCli: () => void;
5
+ listItems: (vault: string) => OpItem[];
6
+ getItem: (title: string, vault: string) => OpItem | null;
7
+ existsSync: (path: string) => boolean;
8
+ dirname: (path: string) => string;
9
+ writeFileSync: (path: string, content: string) => void;
10
+ createSpinner: (text: string, quiet: boolean) => ReturnType<typeof oraType>;
11
+ }
12
+ export declare function createExportCommand(deps?: ExportDeps): (options: ExportOptions) => Promise<void>;
13
+ export declare const exportCommand: (options: ExportOptions) => Promise<void>;
14
+ //# sourceMappingURL=export.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"export.d.ts","sourceRoot":"","sources":["../../src/commands/export.ts"],"names":[],"mappings":"AAWA,OAAO,EAAW,aAAa,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AACnE,OAAO,KAAK,OAAO,MAAM,KAAK,CAAC;AAE/B,MAAM,WAAW,UAAU;IACzB,UAAU,EAAE,MAAM,IAAI,CAAC;IACvB,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,EAAE,CAAC;IACvC,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;IACzD,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC;IACtC,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;IAClC,aAAa,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACvD,aAAa,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,KAAK,UAAU,CAAC,OAAO,OAAO,CAAC,CAAC;CAC7E;AAYD,wBAAgB,mBAAmB,CAAC,IAAI,GAAE,UAAwB,IAC5B,SAAS,aAAa,KAAG,OAAO,CAAC,IAAI,CAAC,CAgH3E;AAGD,eAAO,MAAM,aAAa,YAnHqB,aAAa,KAAG,OAAO,CAAC,IAAI,CAmHzB,CAAC"}
@@ -0,0 +1,111 @@
1
+ import { writeFileSync, existsSync } from 'fs';
2
+ import { dirname } from 'path';
3
+ import chalk from 'chalk';
4
+ import { listItems, getItem, checkOpCli } from '../utils/op.js';
5
+ import { applyColorConfig, createSpinner, resolveBooleanOption, resolveFormat, resolveVault, } from '../utils/cli.js';
6
+ import { OpError } from '../utils/types.js';
7
+ const defaultDeps = {
8
+ checkOpCli,
9
+ listItems,
10
+ getItem,
11
+ existsSync,
12
+ dirname,
13
+ writeFileSync,
14
+ createSpinner,
15
+ };
16
+ export function createExportCommand(deps = defaultDeps) {
17
+ return async function exportCommand(options) {
18
+ try {
19
+ deps.checkOpCli();
20
+ if (options.json && options.format && options.format !== 'json') {
21
+ throw new OpError('Use either --json or --format, not both.', 2);
22
+ }
23
+ const vault = resolveVault(options.vault);
24
+ const envQuiet = resolveBooleanOption(undefined, 'OPS_QUIET');
25
+ const quiet = options.quiet === true || envQuiet;
26
+ const envNoColor = resolveBooleanOption(undefined, 'OPS_NO_COLOR');
27
+ const noColor = options.color === false || envNoColor;
28
+ const format = resolveFormat(options.json ? 'json' : options.format);
29
+ applyColorConfig(noColor);
30
+ // Validate output path early (before fetching secrets)
31
+ if (options.output && options.output !== '-') {
32
+ const dir = deps.dirname(options.output);
33
+ if (!deps.existsSync(dir)) {
34
+ throw new OpError(`Output directory not found: ${dir}`, 2);
35
+ }
36
+ }
37
+ const outputToStdout = !options.output || options.output === '-';
38
+ const quietSpinner = quiet || outputToStdout || format === 'json';
39
+ const spinner = deps.createSpinner(`Exporting secrets from vault "${vault}"...`, quietSpinner);
40
+ // Get all items from vault
41
+ const items = deps.listItems(vault);
42
+ if (items.length === 0) {
43
+ if (!quietSpinner) {
44
+ spinner.warn(chalk.yellow('No items found in vault.'));
45
+ }
46
+ return;
47
+ }
48
+ // Fetch full details for each item
49
+ const secrets = {};
50
+ for (const item of items) {
51
+ const fullItem = deps.getItem(item.title, vault);
52
+ if (!fullItem?.fields)
53
+ continue;
54
+ // Find password or concealed field
55
+ const secretField = fullItem.fields.find((f) => f.type === 'CONCEALED' || f.id === 'password');
56
+ if (secretField?.value) {
57
+ // Convert title to env var format (uppercase, replace spaces/hyphens with underscore)
58
+ const envKey = item.title
59
+ .toUpperCase()
60
+ .replace(/[^A-Z0-9]/g, '_')
61
+ .replace(/_+/g, '_');
62
+ secrets[envKey] = secretField.value;
63
+ }
64
+ }
65
+ if (!quietSpinner) {
66
+ spinner.stop();
67
+ }
68
+ // Format output
69
+ let output;
70
+ if (format === 'json') {
71
+ output = JSON.stringify(secrets, null, 2);
72
+ }
73
+ else {
74
+ // .env format
75
+ output = Object.entries(secrets)
76
+ .map(([key, value]) => {
77
+ // Escape quotes and newlines
78
+ const escapedValue = value
79
+ .replace(/\\/g, '\\\\')
80
+ .replace(/"/g, '\\"')
81
+ .replace(/\n/g, '\\n');
82
+ return `${key}="${escapedValue}"`;
83
+ })
84
+ .join('\n');
85
+ }
86
+ // Output to file or stdout
87
+ if (!outputToStdout) {
88
+ deps.writeFileSync(options.output, output);
89
+ if (!quiet) {
90
+ console.log(chalk.green(`✓ Exported ${Object.keys(secrets).length} secrets to ${options.output}`));
91
+ }
92
+ }
93
+ else {
94
+ console.log(output);
95
+ }
96
+ if (!quiet && !outputToStdout) {
97
+ console.log(chalk.gray(`\n${Object.keys(secrets).length} secrets exported from "${vault}"`));
98
+ }
99
+ }
100
+ catch (error) {
101
+ if (error instanceof OpError) {
102
+ console.error(chalk.red(`Error: ${error.message}`));
103
+ process.exit(error.exitCode);
104
+ }
105
+ throw error;
106
+ }
107
+ };
108
+ }
109
+ // Default export for CLI usage
110
+ export const exportCommand = createExportCommand();
111
+ //# sourceMappingURL=export.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"export.js","sourceRoot":"","sources":["../../src/commands/export.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ import inquirer from 'inquirer';
2
+ import { getSecret, setSecret, checkOpCli, itemExists, getItemFields, findSimilarItems } from '../utils/op.js';
3
+ import { applyColorConfig, createSpinner, isInteractiveInput, resolveBooleanOption, resolveField, resolveVault } from '../utils/cli.js';
4
+ export interface GetOptions {
5
+ vault?: string;
6
+ field?: string;
7
+ silent?: boolean;
8
+ plain?: boolean;
9
+ json?: boolean;
10
+ input?: boolean;
11
+ quiet?: boolean;
12
+ color?: boolean;
13
+ }
14
+ export interface GetDependencies {
15
+ getSecret: typeof getSecret;
16
+ setSecret: typeof setSecret;
17
+ checkOpCli: typeof checkOpCli;
18
+ itemExists: typeof itemExists;
19
+ getItemFields: typeof getItemFields;
20
+ findSimilarItems: typeof findSimilarItems;
21
+ prompt: typeof inquirer.prompt;
22
+ applyColorConfig: typeof applyColorConfig;
23
+ createSpinner: typeof createSpinner;
24
+ isInteractiveInput: typeof isInteractiveInput;
25
+ resolveBooleanOption: typeof resolveBooleanOption;
26
+ resolveField: typeof resolveField;
27
+ resolveVault: typeof resolveVault;
28
+ }
29
+ export declare function createGetCommand(overrides?: Partial<GetDependencies>): (name: string, options: GetOptions) => Promise<void>;
30
+ export declare const getCommand: (name: string, options: GetOptions) => Promise<void>;
31
+ //# sourceMappingURL=get.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get.d.ts","sourceRoot":"","sources":["../../src/commands/get.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,UAAU,CAAC;AAEhC,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,UAAU,EAAE,UAAU,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAC/G,OAAO,EACL,gBAAgB,EAChB,aAAa,EACb,kBAAkB,EAClB,oBAAoB,EACpB,YAAY,EACZ,YAAY,EACb,MAAM,iBAAiB,CAAC;AAGzB,MAAM,WAAW,UAAU;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,OAAO,SAAS,CAAC;IAC5B,SAAS,EAAE,OAAO,SAAS,CAAC;IAC5B,UAAU,EAAE,OAAO,UAAU,CAAC;IAC9B,UAAU,EAAE,OAAO,UAAU,CAAC;IAC9B,aAAa,EAAE,OAAO,aAAa,CAAC;IACpC,gBAAgB,EAAE,OAAO,gBAAgB,CAAC;IAC1C,MAAM,EAAE,OAAO,QAAQ,CAAC,MAAM,CAAC;IAC/B,gBAAgB,EAAE,OAAO,gBAAgB,CAAC;IAC1C,aAAa,EAAE,OAAO,aAAa,CAAC;IACpC,kBAAkB,EAAE,OAAO,kBAAkB,CAAC;IAC9C,oBAAoB,EAAE,OAAO,oBAAoB,CAAC;IAClD,YAAY,EAAE,OAAO,YAAY,CAAC;IAClC,YAAY,EAAE,OAAO,YAAY,CAAC;CACnC;AAkBD,wBAAgB,gBAAgB,CAC9B,SAAS,GAAE,OAAO,CAAC,eAAe,CAAM,GACvC,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,KAAK,OAAO,CAAC,IAAI,CAAC,CAgJtD;AAED,eAAO,MAAM,UAAU,SAlJb,MAAM,WAAW,UAAU,KAAK,OAAO,CAAC,IAAI,CAkJV,CAAC"}