@reminix/cli 0.1.2 → 0.1.4

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 (42) hide show
  1. package/README.md +1 -1
  2. package/dist/commands/agents.d.ts +6 -0
  3. package/dist/commands/agents.d.ts.map +1 -0
  4. package/dist/commands/agents.js +195 -0
  5. package/dist/commands/agents.js.map +1 -0
  6. package/dist/commands/login.d.ts +6 -0
  7. package/dist/commands/login.d.ts.map +1 -0
  8. package/dist/commands/login.js +65 -0
  9. package/dist/commands/login.js.map +1 -0
  10. package/dist/commands/logout.d.ts +6 -0
  11. package/dist/commands/logout.d.ts.map +1 -0
  12. package/dist/commands/logout.js +15 -0
  13. package/dist/commands/logout.js.map +1 -0
  14. package/dist/commands/projects.d.ts +6 -0
  15. package/dist/commands/projects.d.ts.map +1 -0
  16. package/dist/commands/projects.js +104 -0
  17. package/dist/commands/projects.js.map +1 -0
  18. package/dist/commands/version.d.ts +1 -1
  19. package/dist/commands/version.js +1 -1
  20. package/dist/commands/whoami.d.ts +6 -0
  21. package/dist/commands/whoami.d.ts.map +1 -0
  22. package/dist/commands/whoami.js +21 -0
  23. package/dist/commands/whoami.js.map +1 -0
  24. package/dist/index.js +12 -0
  25. package/dist/index.js.map +1 -1
  26. package/dist/lib/api-client.d.ts +25 -0
  27. package/dist/lib/api-client.d.ts.map +1 -0
  28. package/dist/lib/api-client.js +52 -0
  29. package/dist/lib/api-client.js.map +1 -0
  30. package/dist/lib/api-types.d.ts +518 -0
  31. package/dist/lib/api-types.d.ts.map +1 -0
  32. package/dist/lib/api-types.js +6 -0
  33. package/dist/lib/api-types.js.map +1 -0
  34. package/dist/lib/auth-server.d.ts +21 -0
  35. package/dist/lib/auth-server.d.ts.map +1 -0
  36. package/dist/lib/auth-server.js +234 -0
  37. package/dist/lib/auth-server.js.map +1 -0
  38. package/dist/lib/credentials.d.ts +32 -0
  39. package/dist/lib/credentials.d.ts.map +1 -0
  40. package/dist/lib/credentials.js +86 -0
  41. package/dist/lib/credentials.js.map +1 -0
  42. package/package.json +8 -4
@@ -0,0 +1,234 @@
1
+ import * as http from 'node:http';
2
+ /**
3
+ * HTML page shown after successful authentication
4
+ */
5
+ const SUCCESS_HTML = `
6
+ <!DOCTYPE html>
7
+ <html lang="en">
8
+ <head>
9
+ <meta charset="UTF-8">
10
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
11
+ <title>Reminix CLI - Authenticated</title>
12
+ <style>
13
+ * { margin: 0; padding: 0; box-sizing: border-box; }
14
+ body {
15
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
16
+ background: linear-gradient(135deg, #1a1a2e 0%, #16213e 100%);
17
+ min-height: 100vh;
18
+ display: flex;
19
+ align-items: center;
20
+ justify-content: center;
21
+ color: #fff;
22
+ }
23
+ .container {
24
+ text-align: center;
25
+ padding: 2rem;
26
+ }
27
+ .checkmark {
28
+ width: 80px;
29
+ height: 80px;
30
+ margin: 0 auto 1.5rem;
31
+ background: #10b981;
32
+ border-radius: 50%;
33
+ display: flex;
34
+ align-items: center;
35
+ justify-content: center;
36
+ animation: pop 0.3s ease-out;
37
+ }
38
+ .checkmark svg {
39
+ width: 40px;
40
+ height: 40px;
41
+ stroke: white;
42
+ stroke-width: 3;
43
+ fill: none;
44
+ }
45
+ h1 {
46
+ font-size: 1.5rem;
47
+ font-weight: 600;
48
+ margin-bottom: 0.5rem;
49
+ }
50
+ p {
51
+ color: #94a3b8;
52
+ font-size: 1rem;
53
+ }
54
+ @keyframes pop {
55
+ 0% { transform: scale(0); }
56
+ 80% { transform: scale(1.1); }
57
+ 100% { transform: scale(1); }
58
+ }
59
+ </style>
60
+ </head>
61
+ <body>
62
+ <div class="container">
63
+ <div class="checkmark">
64
+ <svg viewBox="0 0 24 24">
65
+ <polyline points="20 6 9 17 4 12"></polyline>
66
+ </svg>
67
+ </div>
68
+ <h1>Authentication successful!</h1>
69
+ <p>You can close this tab and return to your terminal.</p>
70
+ </div>
71
+ </body>
72
+ </html>
73
+ `;
74
+ /**
75
+ * HTML page shown when there's an error
76
+ */
77
+ const ERROR_HTML = `
78
+ <!DOCTYPE html>
79
+ <html lang="en">
80
+ <head>
81
+ <meta charset="UTF-8">
82
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
83
+ <title>Reminix CLI - Error</title>
84
+ <style>
85
+ * { margin: 0; padding: 0; box-sizing: border-box; }
86
+ body {
87
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
88
+ background: linear-gradient(135deg, #1a1a2e 0%, #16213e 100%);
89
+ min-height: 100vh;
90
+ display: flex;
91
+ align-items: center;
92
+ justify-content: center;
93
+ color: #fff;
94
+ }
95
+ .container {
96
+ text-align: center;
97
+ padding: 2rem;
98
+ }
99
+ .error-icon {
100
+ width: 80px;
101
+ height: 80px;
102
+ margin: 0 auto 1.5rem;
103
+ background: #ef4444;
104
+ border-radius: 50%;
105
+ display: flex;
106
+ align-items: center;
107
+ justify-content: center;
108
+ }
109
+ .error-icon svg {
110
+ width: 40px;
111
+ height: 40px;
112
+ stroke: white;
113
+ stroke-width: 3;
114
+ fill: none;
115
+ }
116
+ h1 {
117
+ font-size: 1.5rem;
118
+ font-weight: 600;
119
+ margin-bottom: 0.5rem;
120
+ }
121
+ p {
122
+ color: #94a3b8;
123
+ font-size: 1rem;
124
+ }
125
+ </style>
126
+ </head>
127
+ <body>
128
+ <div class="container">
129
+ <div class="error-icon">
130
+ <svg viewBox="0 0 24 24">
131
+ <line x1="18" y1="6" x2="6" y2="18"></line>
132
+ <line x1="6" y1="6" x2="18" y2="18"></line>
133
+ </svg>
134
+ </div>
135
+ <h1>Authentication failed</h1>
136
+ <p>Please try again from your terminal.</p>
137
+ </div>
138
+ </body>
139
+ </html>
140
+ `;
141
+ /**
142
+ * Start the auth server and return both the port and the result promise
143
+ * This allows the caller to get the port immediately and wait for the result separately
144
+ */
145
+ export function createAuthServer(expectedState, timeoutMs = 5 * 60 * 1000) {
146
+ return new Promise((resolve, reject) => {
147
+ let callbackResolve;
148
+ let callbackReject;
149
+ const callbackPromise = new Promise((res, rej) => {
150
+ callbackResolve = res;
151
+ callbackReject = rej;
152
+ });
153
+ const server = http.createServer((req, res) => {
154
+ // Only handle GET requests to /callback
155
+ if (!req.url?.startsWith('/callback')) {
156
+ res.writeHead(404);
157
+ res.end('Not found');
158
+ return;
159
+ }
160
+ // Parse query parameters using WHATWG URL API
161
+ const parsedUrl = new URL(req.url, `http://localhost`);
162
+ const token = parsedUrl.searchParams.get('token') ?? undefined;
163
+ const state = parsedUrl.searchParams.get('state') ?? undefined;
164
+ const email = parsedUrl.searchParams.get('email') ?? undefined;
165
+ const error = parsedUrl.searchParams.get('error') ?? undefined;
166
+ // Handle error from web app
167
+ if (error) {
168
+ res.writeHead(200, { 'Content-Type': 'text/html' });
169
+ res.end(ERROR_HTML);
170
+ cleanup();
171
+ callbackReject(new Error(`Authentication failed: ${error}`));
172
+ return;
173
+ }
174
+ // Validate required parameters
175
+ if (!token || !state || !email) {
176
+ res.writeHead(200, { 'Content-Type': 'text/html' });
177
+ res.end(ERROR_HTML);
178
+ cleanup();
179
+ callbackReject(new Error('Missing token, state, or email in callback'));
180
+ return;
181
+ }
182
+ // Verify state matches (CSRF protection)
183
+ if (state !== expectedState) {
184
+ res.writeHead(200, { 'Content-Type': 'text/html' });
185
+ res.end(ERROR_HTML);
186
+ cleanup();
187
+ callbackReject(new Error('State mismatch - possible CSRF attack'));
188
+ return;
189
+ }
190
+ // Success!
191
+ res.writeHead(200, { 'Content-Type': 'text/html' });
192
+ res.end(SUCCESS_HTML);
193
+ cleanup();
194
+ callbackResolve({ token, state, email });
195
+ });
196
+ // Handle server errors
197
+ server.on('error', (err) => {
198
+ cleanup();
199
+ reject(err);
200
+ });
201
+ // Set up timeout
202
+ const timeoutId = setTimeout(() => {
203
+ cleanup();
204
+ callbackReject(new Error('Authentication timed out. Please try again.'));
205
+ }, timeoutMs);
206
+ // Cleanup function
207
+ function cleanup() {
208
+ clearTimeout(timeoutId);
209
+ server.close();
210
+ }
211
+ // Start server on random available port (port 0)
212
+ server.listen(0, '127.0.0.1', () => {
213
+ const address = server.address();
214
+ if (typeof address === 'object' && address) {
215
+ resolve({
216
+ port: address.port,
217
+ waitForCallback: () => callbackPromise,
218
+ });
219
+ }
220
+ else {
221
+ reject(new Error('Failed to start auth server'));
222
+ }
223
+ });
224
+ });
225
+ }
226
+ /**
227
+ * Generate a random state string for CSRF protection
228
+ */
229
+ export function generateState() {
230
+ const array = new Uint8Array(32);
231
+ crypto.getRandomValues(array);
232
+ return Array.from(array, (byte) => byte.toString(16).padStart(2, '0')).join('');
233
+ }
234
+ //# sourceMappingURL=auth-server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth-server.js","sourceRoot":"","sources":["../../src/lib/auth-server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Credentials stored locally for CLI authentication
3
+ */
4
+ export interface Credentials {
5
+ token: string;
6
+ email: string;
7
+ createdAt: string;
8
+ }
9
+ /**
10
+ * Save credentials to the local filesystem
11
+ * Creates the config directory if it doesn't exist
12
+ */
13
+ export declare function saveCredentials(token: string, email: string): void;
14
+ /**
15
+ * Load credentials from the local filesystem
16
+ * Returns null if no credentials exist or file is invalid
17
+ */
18
+ export declare function loadCredentials(): Credentials | null;
19
+ /**
20
+ * Clear stored credentials
21
+ * Removes the credentials file if it exists
22
+ */
23
+ export declare function clearCredentials(): void;
24
+ /**
25
+ * Check if user is logged in (has valid credentials)
26
+ */
27
+ export declare function isLoggedIn(): boolean;
28
+ /**
29
+ * Get the credentials directory path (for display purposes)
30
+ */
31
+ export declare function getCredentialsDirPath(): string;
32
+ //# sourceMappingURL=credentials.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"credentials.d.ts","sourceRoot":"","sources":["../../src/lib/credentials.ts"],"names":[],"mappings":"AAIA;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACnB;AAqBD;;;GAGG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAmBlE;AAED;;;GAGG;AACH,wBAAgB,eAAe,IAAI,WAAW,GAAG,IAAI,CAoBpD;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,IAAI,IAAI,CAMvC;AAED;;GAEG;AACH,wBAAgB,UAAU,IAAI,OAAO,CAEpC;AAED;;GAEG;AACH,wBAAgB,qBAAqB,IAAI,MAAM,CAE9C"}
@@ -0,0 +1,86 @@
1
+ import * as fs from 'node:fs';
2
+ import * as path from 'node:path';
3
+ import * as os from 'node:os';
4
+ /**
5
+ * Get the path to the credentials directory
6
+ * Uses XDG_CONFIG_HOME if set, otherwise ~/.config/reminix
7
+ */
8
+ function getCredentialsDir() {
9
+ const xdgConfigHome = process.env.XDG_CONFIG_HOME;
10
+ if (xdgConfigHome) {
11
+ return path.join(xdgConfigHome, 'reminix');
12
+ }
13
+ return path.join(os.homedir(), '.config', 'reminix');
14
+ }
15
+ /**
16
+ * Get the path to the credentials file
17
+ */
18
+ function getCredentialsPath() {
19
+ return path.join(getCredentialsDir(), 'credentials.json');
20
+ }
21
+ /**
22
+ * Save credentials to the local filesystem
23
+ * Creates the config directory if it doesn't exist
24
+ */
25
+ export function saveCredentials(token, email) {
26
+ const dir = getCredentialsDir();
27
+ const filePath = getCredentialsPath();
28
+ // Create directory if it doesn't exist
29
+ if (!fs.existsSync(dir)) {
30
+ fs.mkdirSync(dir, { recursive: true, mode: 0o700 }); // Only owner can access
31
+ }
32
+ const credentials = {
33
+ token,
34
+ email,
35
+ createdAt: new Date().toISOString(),
36
+ };
37
+ // Write credentials file with restricted permissions
38
+ fs.writeFileSync(filePath, JSON.stringify(credentials, null, 2), {
39
+ mode: 0o600, // Only owner can read/write
40
+ });
41
+ }
42
+ /**
43
+ * Load credentials from the local filesystem
44
+ * Returns null if no credentials exist or file is invalid
45
+ */
46
+ export function loadCredentials() {
47
+ const filePath = getCredentialsPath();
48
+ if (!fs.existsSync(filePath)) {
49
+ return null;
50
+ }
51
+ try {
52
+ const content = fs.readFileSync(filePath, 'utf-8');
53
+ const credentials = JSON.parse(content);
54
+ // Basic validation
55
+ if (!credentials.token || !credentials.email) {
56
+ return null;
57
+ }
58
+ return credentials;
59
+ }
60
+ catch {
61
+ return null;
62
+ }
63
+ }
64
+ /**
65
+ * Clear stored credentials
66
+ * Removes the credentials file if it exists
67
+ */
68
+ export function clearCredentials() {
69
+ const filePath = getCredentialsPath();
70
+ if (fs.existsSync(filePath)) {
71
+ fs.unlinkSync(filePath);
72
+ }
73
+ }
74
+ /**
75
+ * Check if user is logged in (has valid credentials)
76
+ */
77
+ export function isLoggedIn() {
78
+ return loadCredentials() !== null;
79
+ }
80
+ /**
81
+ * Get the credentials directory path (for display purposes)
82
+ */
83
+ export function getCredentialsDirPath() {
84
+ return getCredentialsDir();
85
+ }
86
+ //# sourceMappingURL=credentials.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"credentials.js","sourceRoot":"","sources":["../../src/lib/credentials.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAW9B;;;GAGG;AACH,SAAS,iBAAiB;IACxB,MAAM,aAAa,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC;IAClD,IAAI,aAAa,EAAE,CAAC;QAClB,OAAO,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,SAAS,CAAC,CAAC;IAC7C,CAAC;IACD,OAAO,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;AACvD,CAAC;AAED;;GAEG;AACH,SAAS,kBAAkB;IACzB,OAAO,IAAI,CAAC,IAAI,CAAC,iBAAiB,EAAE,EAAE,kBAAkB,CAAC,CAAC;AAC5D,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,KAAa,EAAE,KAAa;IAC1D,MAAM,GAAG,GAAG,iBAAiB,EAAE,CAAC;IAChC,MAAM,QAAQ,GAAG,kBAAkB,EAAE,CAAC;IAEtC,uCAAuC;IACvC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QACxB,EAAE,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,wBAAwB;IAC/E,CAAC;IAED,MAAM,WAAW,GAAgB;QAC/B,KAAK;QACL,KAAK;QACL,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;KACpC,CAAC;IAEF,qDAAqD;IACrD,EAAE,CAAC,aAAa,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE;QAC/D,IAAI,EAAE,KAAK,EAAE,4BAA4B;KAC1C,CAAC,CAAC;AACL,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,eAAe;IAC7B,MAAM,QAAQ,GAAG,kBAAkB,EAAE,CAAC;IAEtC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC7B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QACnD,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAgB,CAAC;QAEvD,mBAAmB;QACnB,IAAI,CAAC,WAAW,CAAC,KAAK,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,CAAC;YAC7C,OAAO,IAAI,CAAC;QACd,CAAC;QAED,OAAO,WAAW,CAAC;IACrB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,gBAAgB;IAC9B,MAAM,QAAQ,GAAG,kBAAkB,EAAE,CAAC;IAEtC,IAAI,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC5B,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;IAC1B,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,UAAU;IACxB,OAAO,eAAe,EAAE,KAAK,IAAI,CAAC;AACpC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,qBAAqB;IACnC,OAAO,iBAAiB,EAAE,CAAC;AAC7B,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@reminix/cli",
3
- "version": "0.1.2",
3
+ "version": "0.1.4",
4
4
  "description": "Reminix CLI - Command-line interface for Reminix",
5
5
  "license": "Apache-2.0",
6
6
  "author": {
@@ -18,11 +18,11 @@
18
18
  "homepage": "https://reminix.com",
19
19
  "repository": {
20
20
  "type": "git",
21
- "url": "git+https://github.com/reminix-ai/reminix-cli.git",
21
+ "url": "git+https://github.com/reminix-ai/cli.git",
22
22
  "directory": "packages/cli"
23
23
  },
24
24
  "bugs": {
25
- "url": "https://github.com/reminix-ai/reminix-cli/issues"
25
+ "url": "https://github.com/reminix-ai/cli/issues"
26
26
  },
27
27
  "engines": {
28
28
  "node": ">=20"
@@ -48,10 +48,13 @@
48
48
  "LICENSE"
49
49
  ],
50
50
  "dependencies": {
51
- "commander": "^14.0.2"
51
+ "commander": "^14.0.2",
52
+ "open": "^11.0.0",
53
+ "openapi-fetch": "^0.15.0"
52
54
  },
53
55
  "devDependencies": {
54
56
  "@types/node": "^25.0.9",
57
+ "openapi-typescript": "^7.10.1",
55
58
  "tsx": "^4.21.0",
56
59
  "typescript": "^5.9.3",
57
60
  "vitest": "^4.0.17"
@@ -60,6 +63,7 @@
60
63
  "build": "tsc",
61
64
  "clean": "rm -rf dist",
62
65
  "dev": "tsx src/index.ts",
66
+ "generate:api": "openapi-typescript ${REMINIX_API_URL:-https://api.reminix.com}/v1/openapi.json -o src/lib/api-types.ts",
63
67
  "test": "vitest run",
64
68
  "test:watch": "vitest"
65
69
  }