@dotenvx/dotenvx-ops 0.45.2 → 0.46.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/CHANGELOG.md CHANGED
@@ -2,7 +2,19 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
4
4
 
5
- [Unreleased](https://github.com/dotenvx/dotenvx-ops/compare/v0.45.2...main)
5
+ [Unreleased](https://github.com/dotenvx/dotenvx-ops/compare/v0.46.0...main)
6
+
7
+ ## [0.46.0](https://github.com/dotenvx/dotenvx-ops/compare/v0.45.3...v0.46.0) (2026-05-13)
8
+
9
+ ### Added
10
+
11
+ * Surface team selector for `keypair` ([#71](https://github.com/dotenvx/dotenvx-ops/pull/71))
12
+
13
+ ## [0.45.3](https://github.com/dotenvx/dotenvx-ops/compare/v0.45.2...v0.45.3) (2026-05-11)
14
+
15
+ ### Changed
16
+
17
+ * Bump fast-uri ([#69](https://github.com/dotenvx/dotenvx-ops/pull/69) [GHSA-v39h-62p7-jpjc](https://github.com/fastify/fast-uri/security/advisories/GHSA-v39h-62p7-jpjc))
6
18
 
7
19
  ## [0.45.2](https://github.com/dotenvx/dotenvx-ops/compare/v0.45.1...v0.45.2) (2026-05-07)
8
20
 
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "0.45.2",
2
+ "version": "0.46.0",
3
3
  "name": "@dotenvx/dotenvx-ops",
4
4
  "description": "Secrets for agents–from the creator of `dotenv` and `dotenvx`",
5
5
  "author": "@motdotla",
@@ -1,7 +1,7 @@
1
1
  const { logger } = require('@dotenvx/dotenvx')
2
2
  const Session = require('./../../db/session')
3
3
  const createSpinner = require('../../lib/helpers/createSpinner2')
4
- const PostKeypair = require('../../lib/api/postKeypair')
4
+ const Keypair = require('../../lib/services/keypair')
5
5
 
6
6
  async function keypair (publicKey) {
7
7
  // debug opts
@@ -20,7 +20,7 @@ async function keypair (publicKey) {
20
20
  try {
21
21
  const devicePublicKey = sesh.devicePublicKey()
22
22
 
23
- const json = await new PostKeypair(hostname, token, devicePublicKey, publicKey).run()
23
+ const json = await new Keypair(hostname, token, devicePublicKey, publicKey, options.team).run()
24
24
 
25
25
  const output = {
26
26
  public_key: json.public_key,
@@ -35,16 +35,25 @@ async function connect () {
35
35
  org = await prompts.select({
36
36
  message: 'Select org',
37
37
  choices
38
+ }, {
39
+ input: process.stdin,
40
+ output: process.stderr
38
41
  })
39
42
  }
40
43
  }
41
44
 
42
45
  if (!username) {
43
- username = await prompts.input({ message: 'github username:' })
46
+ username = await prompts.input({ message: 'github username:' }, {
47
+ input: process.stdin,
48
+ output: process.stderr
49
+ })
44
50
  }
45
51
 
46
52
  if (!password) {
47
- password = await prompts.password({ message: 'github password:' })
53
+ password = await prompts.password({ message: 'github password:' }, {
54
+ input: process.stdin,
55
+ output: process.stderr
56
+ })
48
57
  }
49
58
 
50
59
  spinner.start()
@@ -35,16 +35,25 @@ async function connect () {
35
35
  org = await prompts.select({
36
36
  message: 'Select org',
37
37
  choices
38
+ }, {
39
+ input: process.stdin,
40
+ output: process.stderr
38
41
  })
39
42
  }
40
43
  }
41
44
 
42
45
  if (!username) {
43
- username = await prompts.input({ message: 'npm username:' })
46
+ username = await prompts.input({ message: 'npm username:' }, {
47
+ input: process.stdin,
48
+ output: process.stderr
49
+ })
44
50
  }
45
51
 
46
52
  if (!password) {
47
- password = await prompts.password({ message: 'npm password:' })
53
+ password = await prompts.password({ message: 'npm password:' }, {
54
+ input: process.stdin,
55
+ output: process.stderr
56
+ })
48
57
  }
49
58
 
50
59
  spinner.start()
@@ -35,16 +35,25 @@ async function connect () {
35
35
  org = await prompts.select({
36
36
  message: 'Select org',
37
37
  choices
38
+ }, {
39
+ input: process.stdin,
40
+ output: process.stderr
38
41
  })
39
42
  }
40
43
  }
41
44
 
42
45
  if (!username) {
43
- username = await prompts.input({ message: 'openai username:' })
46
+ username = await prompts.input({ message: 'openai username:' }, {
47
+ input: process.stdin,
48
+ output: process.stderr
49
+ })
44
50
  }
45
51
 
46
52
  if (!password) {
47
- password = await prompts.password({ message: 'openai password:' })
53
+ password = await prompts.password({ message: 'openai password:' }, {
54
+ input: process.stdin,
55
+ output: process.stderr
56
+ })
48
57
  }
49
58
 
50
59
  spinner.start()
@@ -132,6 +132,7 @@ program
132
132
  .argument('[publicKey]', 'existing public key')
133
133
  .option('-h, --hostname <url>', 'set hostname')
134
134
  .option('--token <token>', 'set token')
135
+ .option('--team <team>', 'team to generate keypair for')
135
136
  .option('--pp, --pretty-print', 'pretty print output')
136
137
  .action(keypairAction)
137
138
 
@@ -4,17 +4,19 @@ const packageJson = require('../../lib/helpers/packageJson')
4
4
  const normalizeToken = require('../../lib/helpers/normalizeToken')
5
5
 
6
6
  class PostKeypair {
7
- constructor (hostname, token, devicePublicKey, publicKey) {
7
+ constructor (hostname, token, devicePublicKey, publicKey, team) {
8
8
  this.hostname = hostname || 'https://ops.dotenvx.com'
9
9
  this.token = token
10
10
  this.devicePublicKey = devicePublicKey
11
11
  this.publicKey = publicKey
12
+ this.team = team
12
13
  }
13
14
 
14
15
  async run () {
15
16
  const token = normalizeToken(this.token)
16
17
  const devicePublicKey = this.devicePublicKey
17
18
  const publicKey = this.publicKey
19
+ const team = this.team
18
20
  const url = `${this.hostname}/api/keypair`
19
21
 
20
22
  const body = {
@@ -26,6 +28,10 @@ class PostKeypair {
26
28
  body.public_key = publicKey
27
29
  }
28
30
 
31
+ if (team) {
32
+ body.team = team
33
+ }
34
+
29
35
  const resp = await http(url, {
30
36
  method: 'POST',
31
37
  headers: {
package/src/lib/main.d.ts CHANGED
@@ -14,7 +14,9 @@ export interface DotenvOpsOptions {
14
14
  token?: string;
15
15
  }
16
16
 
17
- export type DotenvOpsKeypairOptions = DotenvOpsOptions;
17
+ export interface DotenvOpsKeypairOptions extends DotenvOpsOptions {
18
+ team?: string;
19
+ }
18
20
 
19
21
  export interface DotenvOpsKeypairOutput {
20
22
  publicKey: string;
@@ -25,7 +27,7 @@ export interface DotenvOpsKeypairOutput {
25
27
  * Creates a remote keypair for the current authenticated device.
26
28
  *
27
29
  * @param publicKey - optional existing public key to fetch
28
- * @param options - optional hostname/token overrides
30
+ * @param options - optional hostname/token/team overrides
29
31
  * @returns generated public and private keys
30
32
  */
31
33
  export function keypair(publicKey?: string, options?: DotenvOpsKeypairOptions): Promise<DotenvOpsKeypairOutput>;
package/src/lib/main.js CHANGED
@@ -5,7 +5,7 @@ const Session = require('./../db/session')
5
5
  const PostObserve = require('./api/postObserve')
6
6
  const PostGet = require('./api/postGet')
7
7
  const PostSet = require('./api/postSet')
8
- const PostKeypair = require('./api/postKeypair')
8
+ const Keypair = require('./services/keypair')
9
9
 
10
10
  const gitUrl = require('./helpers/gitUrl')
11
11
  const gitBranch = require('./helpers/gitBranch')
@@ -92,7 +92,7 @@ const keypair = async function (publicKey, options = {}) {
92
92
 
93
93
  const devicePublicKey = sesh.devicePublicKey()
94
94
 
95
- const json = await new PostKeypair(hostname, token, devicePublicKey, publicKey).run()
95
+ const json = await new Keypair(hostname, token, devicePublicKey, publicKey, options.team).run()
96
96
 
97
97
  return {
98
98
  publicKey: json.public_key,
@@ -52,6 +52,9 @@ class ArmorDown {
52
52
  team = await prompts.select({
53
53
  message: 'Select team',
54
54
  choices
55
+ }, {
56
+ input: process.stdin,
57
+ output: process.stderr
55
58
  })
56
59
  }
57
60
 
@@ -35,6 +35,9 @@ class ArmorMove {
35
35
  team = await prompts.select({
36
36
  message: 'Select team',
37
37
  choices
38
+ }, {
39
+ input: process.stdin,
40
+ output: process.stderr
38
41
  })
39
42
 
40
43
  const json = await new PostArmorMove(hostname, token, devicePublicKey, publicKey, team).run()
@@ -52,6 +52,9 @@ class ArmorPull {
52
52
  team = await prompts.select({
53
53
  message: 'Select team',
54
54
  choices
55
+ }, {
56
+ input: process.stdin,
57
+ output: process.stderr
55
58
  })
56
59
  }
57
60
 
@@ -49,6 +49,9 @@ class ArmorPush {
49
49
  team = await prompts.select({
50
50
  message: 'Select team',
51
51
  choices
52
+ }, {
53
+ input: process.stdin,
54
+ output: process.stderr
52
55
  })
53
56
  }
54
57
 
@@ -54,6 +54,9 @@ class ArmorUp {
54
54
  team = await prompts.select({
55
55
  message: 'Select team',
56
56
  choices
57
+ }, {
58
+ input: process.stdin,
59
+ output: process.stderr
57
60
  })
58
61
  }
59
62
 
@@ -56,6 +56,9 @@ class Backup {
56
56
  _org = await prompts.select({
57
57
  message: 'Select org',
58
58
  choices
59
+ }, {
60
+ input: process.stdin,
61
+ output: process.stderr
59
62
  })
60
63
  }
61
64
  }
@@ -0,0 +1,56 @@
1
+ const prompts = require('@inquirer/prompts')
2
+ const PostKeypair = require('../api/postKeypair')
3
+
4
+ function teamChoicesFromMeta (meta) {
5
+ return meta.organizations.map(org => ({
6
+ name: org.provider_slug,
7
+ value: org.provider_slug
8
+ }))
9
+ }
10
+
11
+ class Keypair {
12
+ constructor (hostname, token, devicePublicKey, publicKey, team = undefined) {
13
+ this.hostname = hostname
14
+ this.token = token
15
+ this.devicePublicKey = devicePublicKey
16
+ this.publicKey = publicKey
17
+ this.team = team
18
+ }
19
+
20
+ async run () {
21
+ const hostname = this.hostname
22
+ const token = this.token
23
+ const devicePublicKey = this.devicePublicKey
24
+ const publicKey = this.publicKey
25
+ const team = this.team
26
+
27
+ if (team) {
28
+ return await new PostKeypair(hostname, token, devicePublicKey, publicKey, team).run()
29
+ }
30
+
31
+ try {
32
+ return await new PostKeypair(hostname, token, devicePublicKey, publicKey, undefined).run()
33
+ } catch (error) {
34
+ if (error.code !== 'DOTENVX_TEAM_REQUIRED') {
35
+ throw error
36
+ }
37
+
38
+ const choices = teamChoicesFromMeta(error.meta)
39
+
40
+ let team = choices[0].value
41
+ if (choices.length > 1) {
42
+ team = await prompts.select({
43
+ message: 'Select team',
44
+ choices
45
+ }, {
46
+ input: process.stdin,
47
+ output: process.stderr
48
+ })
49
+ }
50
+
51
+ return await new PostKeypair(hostname, token, devicePublicKey, publicKey, team).run()
52
+ }
53
+ }
54
+ }
55
+
56
+ module.exports = Keypair