@regressionproof/cli 0.2.25 → 0.3.1

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
@@ -3,6 +3,26 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ## [0.3.1](https://github.com/sprucelabsai-community/regressionproof/compare/v0.3.0...v0.3.1) (2026-01-13)
7
+
8
+ **Note:** Version bump only for package @regressionproof/cli
9
+
10
+
11
+
12
+
13
+
14
+ # [0.3.0](https://github.com/sprucelabsai-community/regressionproof/compare/v0.2.25...v0.3.0) (2026-01-12)
15
+
16
+
17
+ ### Features
18
+
19
+ * add invites storage and cli commands ([20464c9](https://github.com/sprucelabsai-community/regressionproof/commit/20464c9))
20
+ * invites rev 1 ([6dbee04](https://github.com/sprucelabsai-community/regressionproof/commit/6dbee04))
21
+
22
+
23
+
24
+
25
+
6
26
  ## [0.2.25](https://github.com/sprucelabsai-community/regressionproof/compare/v0.2.24...v0.2.25) (2026-01-12)
7
27
 
8
28
  **Note:** Version bump only for package @regressionproof/cli
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@regressionproof/cli",
3
- "version": "0.2.25",
3
+ "version": "0.3.1",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -33,7 +33,7 @@
33
33
  "watch.tsc": "tsc -w"
34
34
  },
35
35
  "dependencies": {
36
- "@regressionproof/client": "^0.2.25",
36
+ "@regressionproof/client": "^0.3.1",
37
37
  "dotenv": "^17.2.3",
38
38
  "ink": "^5.1.0",
39
39
  "ink-big-text": "^2.0.0",
@@ -79,5 +79,5 @@
79
79
  "^#spruce/(.*)$": "<rootDir>/build/.spruce/$1"
80
80
  }
81
81
  },
82
- "gitHead": "5538b60f0f015d0b25bba3dc1ff298878f547093"
82
+ "gitHead": "192ac0ba411c3b6b41e3b24f58ec7748f5386d22"
83
83
  }
package/src/cli.ts CHANGED
@@ -2,6 +2,10 @@
2
2
  import 'dotenv/config'
3
3
  import { render } from 'ink'
4
4
  import React from 'react'
5
+ import acceptInvite from './commands/invite/AcceptInvite.js'
6
+ import createInvite from './commands/invite/CreateInvite.js'
7
+ import listInvites from './commands/invite/ListInvites.js'
8
+ import revokeInvite from './commands/invite/RevokeInvite.js'
5
9
  import Init from './components/Init.js'
6
10
 
7
11
  const command = process.argv[2]
@@ -9,10 +13,41 @@ const projectNameArg = process.argv[3]
9
13
 
10
14
  if (command === 'init') {
11
15
  render(React.createElement(Init, { projectName: projectNameArg }))
16
+ } else if (command === 'invite') {
17
+ const subcommand = process.argv[3]
18
+ const arg = process.argv[4]
19
+
20
+ if (subcommand === 'create') {
21
+ const noteArg = process.argv.find((value) =>
22
+ value.startsWith('--note=')
23
+ )
24
+ const note = noteArg ? noteArg.replace('--note=', '') : undefined
25
+ void createInvite(arg, note)
26
+ } else if (subcommand === 'accept') {
27
+ if (!arg) {
28
+ console.error('Usage: regressionproof invite accept <token>')
29
+ process.exit(1)
30
+ }
31
+ void acceptInvite(arg)
32
+ } else if (subcommand === 'list') {
33
+ void listInvites(arg)
34
+ } else if (subcommand === 'revoke') {
35
+ if (!arg) {
36
+ console.error('Usage: regressionproof invite revoke <token>')
37
+ process.exit(1)
38
+ }
39
+ void revokeInvite(arg)
40
+ } else {
41
+ console.error(
42
+ 'Usage: regressionproof invite <create|accept|list|revoke>'
43
+ )
44
+ process.exit(1)
45
+ }
12
46
  } else {
13
47
  console.log('Usage: regressionproof <command>')
14
48
  console.log('')
15
49
  console.log('Commands:')
16
50
  console.log(' init [projectName] Initialize a new project')
51
+ console.log(' invite ... Manage project invites')
17
52
  process.exit(1)
18
53
  }
@@ -0,0 +1,21 @@
1
+ const API_URL =
2
+ process.env.REGRESSIONPROOF_API_URL ?? 'https://api.regressionproof.ai'
3
+
4
+ export default async function acceptInvite(token: string): Promise<void> {
5
+ const response = await fetch(`${API_URL}/invites/accept`, {
6
+ method: 'POST',
7
+ headers: {
8
+ 'Content-Type': 'application/json',
9
+ },
10
+ body: JSON.stringify({ token }),
11
+ })
12
+
13
+ if (!response.ok) {
14
+ const text = await response.text()
15
+ throw new Error(`Invite accept failed: ${response.status} ${text}`)
16
+ }
17
+
18
+ const data = (await response.json()) as { url: string; token: string }
19
+ console.log('Project URL:', data.url)
20
+ console.log('Project token:', data.token)
21
+ }
@@ -0,0 +1,60 @@
1
+ import ConfigManager from '../../config/ConfigManager.js'
2
+ import { getRepoNameFromGit, toSlug } from '../../utilities/slug.js'
3
+
4
+ const API_URL =
5
+ process.env.REGRESSIONPROOF_API_URL ?? 'https://api.regressionproof.ai'
6
+
7
+ class InviteCreator {
8
+ public constructor(private configManager = new ConfigManager()) {}
9
+
10
+ public async run(projectNameArg?: string, note?: string): Promise<void> {
11
+ const projectName = this.resolveProjectName(projectNameArg)
12
+ const creds = this.configManager.loadCredentials(projectName)
13
+ if (!creds) {
14
+ throw new Error(
15
+ `No credentials found for ${projectName}. Run regressionproof init first.`
16
+ )
17
+ }
18
+
19
+ const response = await fetch(`${API_URL}/invites`, {
20
+ method: 'POST',
21
+ headers: {
22
+ 'Content-Type': 'application/json',
23
+ Authorization: `Bearer ${creds.token}`,
24
+ },
25
+ body: JSON.stringify({ name: projectName, note }),
26
+ })
27
+
28
+ if (!response.ok) {
29
+ const text = await response.text()
30
+ throw new Error(`Invite create failed: ${response.status} ${text}`)
31
+ }
32
+
33
+ const data = (await response.json()) as InviteCreateResponse
34
+ console.log('Invite token:', data.token)
35
+ }
36
+
37
+ private resolveProjectName(projectNameArg?: string): string {
38
+ const provided = projectNameArg ? toSlug(projectNameArg) : ''
39
+ const name = provided || getRepoNameFromGit()
40
+ if (!name) {
41
+ throw new Error(
42
+ 'Project name is required. Provide it explicitly or ensure git origin is set.'
43
+ )
44
+ }
45
+ return name
46
+ }
47
+ }
48
+
49
+ export default async function createInvite(
50
+ projectName?: string,
51
+ note?: string
52
+ ): Promise<void> {
53
+ const creator = new InviteCreator()
54
+ await creator.run(projectName, note)
55
+ }
56
+
57
+ interface InviteCreateResponse {
58
+ token: string
59
+ projectName: string
60
+ }
@@ -0,0 +1,33 @@
1
+ const API_URL =
2
+ process.env.REGRESSIONPROOF_API_URL ?? 'https://api.regressionproof.ai'
3
+
4
+ export default async function listInvites(projectName?: string): Promise<void> {
5
+ const query = projectName ? `?name=${encodeURIComponent(projectName)}` : ''
6
+ const response = await fetch(`${API_URL}/invites${query}`)
7
+
8
+ if (!response.ok) {
9
+ const text = await response.text()
10
+ throw new Error(`Invite list failed: ${response.status} ${text}`)
11
+ }
12
+
13
+ const data = (await response.json()) as {
14
+ projectName: string
15
+ createdAt: string
16
+ usedAt?: string | null
17
+ revokedAt?: string | null
18
+ note?: string | null
19
+ status: 'active' | 'used' | 'revoked'
20
+ }[]
21
+
22
+ if (data.length === 0) {
23
+ console.log('No invites found.')
24
+ return
25
+ }
26
+
27
+ for (const invite of data) {
28
+ console.log(
29
+ `${invite.projectName} | ${invite.status} | created ${invite.createdAt}` +
30
+ (invite.note ? ` | ${invite.note}` : '')
31
+ )
32
+ }
33
+ }
@@ -0,0 +1,18 @@
1
+ const API_URL =
2
+ process.env.REGRESSIONPROOF_API_URL ?? 'https://api.regressionproof.ai'
3
+
4
+ export default async function revokeInvite(token: string): Promise<void> {
5
+ const response = await fetch(
6
+ `${API_URL}/invites/${encodeURIComponent(token)}`,
7
+ {
8
+ method: 'DELETE',
9
+ }
10
+ )
11
+
12
+ if (!response.ok) {
13
+ const text = await response.text()
14
+ throw new Error(`Invite revoke failed: ${response.status} ${text}`)
15
+ }
16
+
17
+ console.log('Invite revoked.')
18
+ }