mindsim 0.1.2 → 0.1.3
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/README.md +8 -1
- package/dist/auth.d.ts +0 -3
- package/dist/auth.d.ts.map +1 -1
- package/dist/auth.js +184 -93
- package/dist/auth.js.map +1 -1
- package/dist/cli.js +2 -16
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +2 -2
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +12 -12
- package/dist/config.js.map +1 -1
- package/dist/index.d.ts +0 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -3
- package/dist/index.js.map +1 -1
- package/dist/types.d.ts +47 -28
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/auth.ts +261 -105
- package/src/cli.ts +3 -17
- package/src/config.ts +11 -11
- package/src/index.ts +0 -3
- package/src/types.ts +50 -30
- package/tests/config.test.ts +20 -15
- package/tests/version.test.ts +1 -1
- package/dist/resources/usage.d.ts +0 -14
- package/dist/resources/usage.d.ts.map +0 -1
- package/dist/resources/usage.js +0 -20
- package/dist/resources/usage.js.map +0 -1
- package/src/resources/usage.ts +0 -16
- package/tests/resources/usage.test.ts +0 -34
package/dist/types.d.ts
CHANGED
|
@@ -1,12 +1,51 @@
|
|
|
1
|
-
export interface
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
}
|
|
7
|
-
export interface
|
|
8
|
-
|
|
1
|
+
export interface DeviceAuthConfig {
|
|
2
|
+
deviceAuthUrl: string;
|
|
3
|
+
tokenUrl: string;
|
|
4
|
+
clientId: string;
|
|
5
|
+
sdkKeysApiUrl: string;
|
|
6
|
+
}
|
|
7
|
+
export interface DeviceAuthResponse {
|
|
8
|
+
device_code: string;
|
|
9
|
+
user_code: string;
|
|
10
|
+
verification_uri: string;
|
|
11
|
+
verification_uri_complete: string;
|
|
12
|
+
expires_in: number;
|
|
13
|
+
interval: number;
|
|
14
|
+
}
|
|
15
|
+
export interface TokenResponse {
|
|
16
|
+
access_token: string;
|
|
17
|
+
refresh_token?: string;
|
|
18
|
+
user?: Record<string, unknown>;
|
|
19
|
+
}
|
|
20
|
+
export interface SdkKeysResponse {
|
|
21
|
+
success: boolean;
|
|
22
|
+
user: {
|
|
9
23
|
id: string;
|
|
24
|
+
workosUserId: string;
|
|
25
|
+
email: string;
|
|
26
|
+
firstName: string | null;
|
|
27
|
+
lastName: string | null;
|
|
28
|
+
};
|
|
29
|
+
keys: SdkKeyInfo[];
|
|
30
|
+
}
|
|
31
|
+
export interface SdkKeyInfo {
|
|
32
|
+
id: string;
|
|
33
|
+
name: string;
|
|
34
|
+
description: string | null;
|
|
35
|
+
tier: "development" | "production";
|
|
36
|
+
lastUsedAt: string | null;
|
|
37
|
+
createdAt: string;
|
|
38
|
+
app: {
|
|
39
|
+
id: string;
|
|
40
|
+
name: string;
|
|
41
|
+
description: string | null;
|
|
42
|
+
mindsimOrgId: string;
|
|
43
|
+
mindsimOrgName: string | null;
|
|
44
|
+
} | null;
|
|
45
|
+
}
|
|
46
|
+
export interface SdkKeyDetailResponse {
|
|
47
|
+
success: boolean;
|
|
48
|
+
key: SdkKeyInfo & {
|
|
10
49
|
key: string;
|
|
11
50
|
};
|
|
12
51
|
}
|
|
@@ -189,24 +228,4 @@ export interface ListUsersResponse {
|
|
|
189
228
|
users: User[];
|
|
190
229
|
count: number;
|
|
191
230
|
}
|
|
192
|
-
export interface ApiKeyUsage {
|
|
193
|
-
successCount: number;
|
|
194
|
-
errorCount: number;
|
|
195
|
-
totalCount: number;
|
|
196
|
-
averageLatency: number;
|
|
197
|
-
maxLatency: number;
|
|
198
|
-
minLatency: number;
|
|
199
|
-
medianLatency: number;
|
|
200
|
-
p90Latency: number;
|
|
201
|
-
p95Latency: number;
|
|
202
|
-
p99Latency: number;
|
|
203
|
-
p999Latency: number;
|
|
204
|
-
numberOfSimulations: number;
|
|
205
|
-
numberOfSimulatedTwins: number;
|
|
206
|
-
numberOfSnapshotsCreated: number;
|
|
207
|
-
numberOfSnapshotsTotal: number;
|
|
208
|
-
numberOfCoresReprocessed: number;
|
|
209
|
-
numberOfPsychometricsRequests: number;
|
|
210
|
-
numberOfMindTopicsRequests: number;
|
|
211
|
-
}
|
|
212
231
|
//# sourceMappingURL=types.d.ts.map
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mindsim",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"description": "The official MindSim typescript SDK allows you to programmatically create digital minds, populate them with conversational data, and run powerful simulations to get an accurate preview of how the person will think, feel, say, and act in any scenario.",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
package/src/auth.ts
CHANGED
|
@@ -1,131 +1,287 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
1
|
+
import readline from "node:readline";
|
|
2
|
+
import axios from "axios";
|
|
3
3
|
import open from "open";
|
|
4
|
-
import {
|
|
5
|
-
import type {
|
|
4
|
+
import { getDeviceAuthConfig, saveApiKey } from "./config";
|
|
5
|
+
import type {
|
|
6
|
+
DeviceAuthResponse,
|
|
7
|
+
SdkKeyDetailResponse,
|
|
8
|
+
SdkKeyInfo,
|
|
9
|
+
SdkKeysResponse,
|
|
10
|
+
TokenResponse,
|
|
11
|
+
} from "./types";
|
|
6
12
|
|
|
7
|
-
|
|
8
|
-
const authConfig = getAuthConfig();
|
|
13
|
+
const HTTP_TIMEOUT = 30000;
|
|
9
14
|
|
|
10
|
-
/**
|
|
11
|
-
* Starts the login flow
|
|
12
|
-
*/
|
|
13
15
|
export async function login(): Promise<void> {
|
|
14
|
-
|
|
16
|
+
const authConfig = getDeviceAuthConfig();
|
|
15
17
|
|
|
16
|
-
|
|
17
|
-
const apiKey = await listenForCallback();
|
|
18
|
+
console.log("Initiating authentication...\n");
|
|
18
19
|
|
|
19
|
-
|
|
20
|
+
const deviceAuth = await requestDeviceCode(authConfig);
|
|
20
21
|
|
|
21
|
-
|
|
22
|
+
console.log("To authenticate, visit the following URL:");
|
|
23
|
+
console.log(`\n ${deviceAuth.verification_uri_complete}\n`);
|
|
24
|
+
console.log(`Your code: ${deviceAuth.user_code}\n`);
|
|
25
|
+
|
|
26
|
+
await open(deviceAuth.verification_uri_complete);
|
|
27
|
+
|
|
28
|
+
console.log("Waiting for authentication...");
|
|
29
|
+
|
|
30
|
+
const tokenResponse = await pollForToken(
|
|
31
|
+
authConfig,
|
|
32
|
+
deviceAuth.device_code,
|
|
33
|
+
deviceAuth.interval,
|
|
34
|
+
deviceAuth.expires_in,
|
|
35
|
+
);
|
|
36
|
+
|
|
37
|
+
console.log("\nAuthentication successful!");
|
|
38
|
+
|
|
39
|
+
console.log("Fetching your API keys...\n");
|
|
40
|
+
const keysResponse = await fetchUserKeys(authConfig, tokenResponse.access_token);
|
|
41
|
+
|
|
42
|
+
if (keysResponse.keys.length === 0) {
|
|
43
|
+
throw new Error(
|
|
44
|
+
"No API keys found. Please visit https://app.workflows.com and go to the Developer Portal to create an app and API key.",
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
let selectedKeyId: string;
|
|
49
|
+
if (keysResponse.keys.length === 1) {
|
|
50
|
+
const onlyKey = keysResponse.keys[0] as SdkKeyInfo;
|
|
51
|
+
selectedKeyId = onlyKey.id;
|
|
52
|
+
console.log(`Auto-selecting your only key: ${onlyKey.name}`);
|
|
53
|
+
} else {
|
|
54
|
+
selectedKeyId = await selectKey(keysResponse.keys);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const keyDetail = await fetchKeySecret(authConfig, tokenResponse.access_token, selectedKeyId);
|
|
58
|
+
|
|
59
|
+
saveApiKey(keyDetail.key.key);
|
|
60
|
+
|
|
61
|
+
console.log("\n✅ Successfully logged in! Credentials saved.");
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
interface AuthConfig {
|
|
65
|
+
deviceAuthUrl: string;
|
|
66
|
+
tokenUrl: string;
|
|
67
|
+
clientId: string;
|
|
68
|
+
sdkKeysApiUrl: string;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
async function requestDeviceCode(authConfig: AuthConfig): Promise<DeviceAuthResponse> {
|
|
22
72
|
try {
|
|
23
|
-
|
|
24
|
-
|
|
73
|
+
const response = await axios.post<DeviceAuthResponse>(
|
|
74
|
+
authConfig.deviceAuthUrl,
|
|
75
|
+
new URLSearchParams({
|
|
76
|
+
client_id: authConfig.clientId,
|
|
77
|
+
}).toString(),
|
|
78
|
+
{
|
|
79
|
+
headers: {
|
|
80
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
81
|
+
},
|
|
82
|
+
timeout: HTTP_TIMEOUT,
|
|
83
|
+
},
|
|
84
|
+
);
|
|
25
85
|
|
|
26
|
-
|
|
86
|
+
return response.data;
|
|
27
87
|
} catch (error) {
|
|
28
|
-
|
|
29
|
-
|
|
88
|
+
if (axios.isAxiosError(error)) {
|
|
89
|
+
if (error.code === "ECONNABORTED") {
|
|
90
|
+
throw new Error("Device authorization request timed out. Please try again.");
|
|
91
|
+
}
|
|
92
|
+
if (error.response) {
|
|
93
|
+
const data = error.response.data as { error?: string; error_description?: string };
|
|
94
|
+
throw new Error(
|
|
95
|
+
`Device authorization failed: ${data.error_description || data.error || "Unknown error"}`,
|
|
96
|
+
);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
throw error;
|
|
30
100
|
}
|
|
31
101
|
}
|
|
32
102
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
103
|
+
async function pollForToken(
|
|
104
|
+
authConfig: AuthConfig,
|
|
105
|
+
deviceCode: string,
|
|
106
|
+
interval: number,
|
|
107
|
+
expiresIn: number,
|
|
108
|
+
): Promise<TokenResponse> {
|
|
109
|
+
const startTime = Date.now();
|
|
110
|
+
const expiresAtMs = startTime + expiresIn * 1000;
|
|
111
|
+
let currentInterval = interval;
|
|
112
|
+
|
|
113
|
+
while (Date.now() < expiresAtMs) {
|
|
114
|
+
await sleep(currentInterval * 1000);
|
|
115
|
+
|
|
116
|
+
try {
|
|
117
|
+
const response = await axios.post<TokenResponse>(
|
|
118
|
+
authConfig.tokenUrl,
|
|
119
|
+
new URLSearchParams({
|
|
120
|
+
grant_type: "urn:ietf:params:oauth:grant-type:device_code",
|
|
121
|
+
device_code: deviceCode,
|
|
122
|
+
client_id: authConfig.clientId,
|
|
123
|
+
}).toString(),
|
|
124
|
+
{
|
|
125
|
+
headers: {
|
|
126
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
127
|
+
},
|
|
128
|
+
timeout: HTTP_TIMEOUT,
|
|
129
|
+
},
|
|
130
|
+
);
|
|
131
|
+
|
|
132
|
+
return response.data;
|
|
133
|
+
} catch (error) {
|
|
134
|
+
if (axios.isAxiosError(error) && error.response) {
|
|
135
|
+
const errorData = error.response.data as { error?: string };
|
|
136
|
+
const errorCode = errorData?.error;
|
|
137
|
+
|
|
138
|
+
if (errorCode === "authorization_pending") {
|
|
139
|
+
continue;
|
|
59
140
|
}
|
|
60
141
|
|
|
61
|
-
if (
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
req.on("data", (chunk) => {
|
|
65
|
-
body += chunk.toString(); // Collect data chunks
|
|
66
|
-
});
|
|
67
|
-
|
|
68
|
-
req.on("end", () => {
|
|
69
|
-
let authResponseData: AuthResponse | null = null;
|
|
70
|
-
|
|
71
|
-
try {
|
|
72
|
-
authResponseData = JSON.parse(body);
|
|
73
|
-
} catch (err) {
|
|
74
|
-
console.error(`Got an invalid response: ${body}. Reason: ${err}`);
|
|
75
|
-
reject(err);
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
if (!authResponseData) {
|
|
79
|
-
res.end("No api key found");
|
|
80
|
-
return;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
const apiKey = authResponseData?.apiKey?.key;
|
|
84
|
-
|
|
85
|
-
if (!apiKey) {
|
|
86
|
-
res.writeHead(400, { "Content-Type": "text/html" });
|
|
87
|
-
res.end(`<h1>Authentication Error</h1><p>API Key Not Found</p>`);
|
|
88
|
-
server.close();
|
|
89
|
-
reject(new Error("API Key Not Found"));
|
|
90
|
-
return;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
if (apiKey) {
|
|
94
|
-
// Send a nice "Close this window" message to the user
|
|
95
|
-
res.writeHead(200, { "Content-Type": "text/html", ...headers });
|
|
96
|
-
res.end(`
|
|
97
|
-
<h1>Authentication Successful</h1>
|
|
98
|
-
<p>You can close this window and return to your terminal.</p>
|
|
99
|
-
<script>window.close()</script>
|
|
100
|
-
`);
|
|
101
|
-
|
|
102
|
-
server.close();
|
|
103
|
-
resolve(apiKey);
|
|
104
|
-
} else {
|
|
105
|
-
res.end("No code found");
|
|
106
|
-
}
|
|
107
|
-
});
|
|
142
|
+
if (errorCode === "slow_down") {
|
|
143
|
+
currentInterval += 1;
|
|
144
|
+
continue;
|
|
108
145
|
}
|
|
109
|
-
}
|
|
110
|
-
});
|
|
111
146
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
});
|
|
147
|
+
if (errorCode === "expired_token") {
|
|
148
|
+
throw new Error("Authentication timed out. Please try again.");
|
|
149
|
+
}
|
|
116
150
|
|
|
117
|
-
|
|
151
|
+
if (errorCode === "access_denied") {
|
|
152
|
+
throw new Error("Authentication was denied. Please try again.");
|
|
153
|
+
}
|
|
154
|
+
}
|
|
118
155
|
|
|
119
|
-
|
|
156
|
+
throw error;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
120
159
|
|
|
121
|
-
|
|
122
|
-
|
|
160
|
+
throw new Error("Authentication timed out. Please try again.");
|
|
161
|
+
}
|
|
123
162
|
|
|
124
|
-
|
|
163
|
+
async function fetchUserKeys(
|
|
164
|
+
authConfig: AuthConfig,
|
|
165
|
+
accessToken: string,
|
|
166
|
+
): Promise<SdkKeysResponse> {
|
|
167
|
+
try {
|
|
168
|
+
const response = await axios.get<SdkKeysResponse>(authConfig.sdkKeysApiUrl, {
|
|
169
|
+
headers: {
|
|
170
|
+
Authorization: `Bearer ${accessToken}`,
|
|
171
|
+
},
|
|
172
|
+
timeout: HTTP_TIMEOUT,
|
|
125
173
|
});
|
|
126
174
|
|
|
127
|
-
|
|
128
|
-
|
|
175
|
+
return response.data;
|
|
176
|
+
} catch (error) {
|
|
177
|
+
if (axios.isAxiosError(error)) {
|
|
178
|
+
if (error.code === "ECONNABORTED") {
|
|
179
|
+
throw new Error("Request to fetch API keys timed out. Please try again.");
|
|
180
|
+
}
|
|
181
|
+
if (error.response) {
|
|
182
|
+
const status = error.response.status;
|
|
183
|
+
const data = error.response.data as { error?: string; code?: string };
|
|
184
|
+
|
|
185
|
+
if (status === 401) {
|
|
186
|
+
throw new Error(`Authentication failed: ${data.error || "Invalid or expired token"}`);
|
|
187
|
+
}
|
|
188
|
+
if (status === 404) {
|
|
189
|
+
throw new Error(
|
|
190
|
+
`User not found: ${data.error || "Your account may not be set up correctly"}`,
|
|
191
|
+
);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
throw new Error(`Failed to fetch API keys: ${data.error || "Unknown error"}`);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
throw error;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
async function fetchKeySecret(
|
|
202
|
+
authConfig: AuthConfig,
|
|
203
|
+
accessToken: string,
|
|
204
|
+
keyId: string,
|
|
205
|
+
): Promise<SdkKeyDetailResponse> {
|
|
206
|
+
try {
|
|
207
|
+
const response = await axios.get<SdkKeyDetailResponse>(`${authConfig.sdkKeysApiUrl}/${keyId}`, {
|
|
208
|
+
headers: {
|
|
209
|
+
Authorization: `Bearer ${accessToken}`,
|
|
210
|
+
},
|
|
211
|
+
timeout: HTTP_TIMEOUT,
|
|
129
212
|
});
|
|
213
|
+
|
|
214
|
+
return response.data;
|
|
215
|
+
} catch (error) {
|
|
216
|
+
if (axios.isAxiosError(error)) {
|
|
217
|
+
if (error.code === "ECONNABORTED") {
|
|
218
|
+
throw new Error("Request to fetch API key details timed out. Please try again.");
|
|
219
|
+
}
|
|
220
|
+
if (error.response) {
|
|
221
|
+
const status = error.response.status;
|
|
222
|
+
const data = error.response.data as { error?: string; code?: string };
|
|
223
|
+
|
|
224
|
+
if (status === 401) {
|
|
225
|
+
throw new Error(`Authentication failed: ${data.error || "Invalid or expired token"}`);
|
|
226
|
+
}
|
|
227
|
+
if (status === 403) {
|
|
228
|
+
throw new Error(`Access denied: ${data.error || "You do not have access to this key"}`);
|
|
229
|
+
}
|
|
230
|
+
if (status === 404) {
|
|
231
|
+
throw new Error(
|
|
232
|
+
`Key not found: ${data.error || "The selected key may have been deleted"}`,
|
|
233
|
+
);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
throw new Error(`Failed to fetch API key details: ${data.error || "Unknown error"}`);
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
throw error;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
async function selectKey(keys: SdkKeyInfo[]): Promise<string> {
|
|
244
|
+
if (!process.stdin.isTTY) {
|
|
245
|
+
throw new Error(
|
|
246
|
+
"Multiple API keys found but running in non-interactive mode. Please set MINDSIM_API_KEY environment variable directly.",
|
|
247
|
+
);
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
console.log("Select an API key:\n");
|
|
251
|
+
|
|
252
|
+
for (const [index, key] of keys.entries()) {
|
|
253
|
+
const appName = key.app?.name || "No app";
|
|
254
|
+
console.log(` ${index + 1}. ${key.name}`);
|
|
255
|
+
console.log(` Tier: ${key.tier} | App: ${appName}`);
|
|
256
|
+
console.log();
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
const rl = readline.createInterface({
|
|
260
|
+
input: process.stdin,
|
|
261
|
+
output: process.stdout,
|
|
130
262
|
});
|
|
263
|
+
|
|
264
|
+
return new Promise((resolve) => {
|
|
265
|
+
const askQuestion = () => {
|
|
266
|
+
rl.question(`Enter selection (1-${keys.length}): `, (answer) => {
|
|
267
|
+
const selection = Number.parseInt(answer, 10);
|
|
268
|
+
|
|
269
|
+
if (Number.isNaN(selection) || selection < 1 || selection > keys.length) {
|
|
270
|
+
console.log(`Please enter a number between 1 and ${keys.length}`);
|
|
271
|
+
askQuestion();
|
|
272
|
+
return;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
const selectedKey = keys[selection - 1] as SdkKeyInfo;
|
|
276
|
+
rl.close();
|
|
277
|
+
resolve(selectedKey.id);
|
|
278
|
+
});
|
|
279
|
+
};
|
|
280
|
+
|
|
281
|
+
askQuestion();
|
|
282
|
+
});
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
function sleep(ms: number): Promise<void> {
|
|
286
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
131
287
|
}
|
package/src/cli.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import fs from "node:fs";
|
|
4
4
|
import path from "node:path";
|
|
5
|
-
import { Command
|
|
5
|
+
import { Command } from "commander";
|
|
6
6
|
import { login } from "./auth";
|
|
7
7
|
import { MindSim } from "./index";
|
|
8
8
|
import { checkForUpdates, getPackageVersion, updateSdk } from "./version";
|
|
@@ -15,7 +15,7 @@ const program = new Command();
|
|
|
15
15
|
const getSDK = () => {
|
|
16
16
|
try {
|
|
17
17
|
return new MindSim();
|
|
18
|
-
} catch
|
|
18
|
+
} catch {
|
|
19
19
|
console.error("❌ Authentication required.");
|
|
20
20
|
console.error("Please run 'mindsim auth' or set MINDSIM_API_KEY environment variable.");
|
|
21
21
|
process.exit(1);
|
|
@@ -477,21 +477,7 @@ const main = async () => {
|
|
|
477
477
|
}
|
|
478
478
|
});
|
|
479
479
|
|
|
480
|
-
//
|
|
481
|
-
program
|
|
482
|
-
.command("usage")
|
|
483
|
-
.description("Get API key usage")
|
|
484
|
-
.option("--from <date>", "From date (YYYY-MM-DD)")
|
|
485
|
-
.option("--to <date>", "To date (YYYY-MM-DD)")
|
|
486
|
-
.action(async (opts) => {
|
|
487
|
-
try {
|
|
488
|
-
const client = getSDK();
|
|
489
|
-
printOutput(await client.usage.get({ from: opts.from, to: opts.to }));
|
|
490
|
-
} catch (e) {
|
|
491
|
-
handleError(e);
|
|
492
|
-
}
|
|
493
|
-
});
|
|
494
|
-
|
|
480
|
+
// USERS
|
|
495
481
|
program
|
|
496
482
|
.command("users")
|
|
497
483
|
.description("List organization users")
|
package/src/config.ts
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
2
|
import os from "node:os";
|
|
3
3
|
import path from "node:path";
|
|
4
|
-
import type {
|
|
4
|
+
import type { DeviceAuthConfig } from "./types";
|
|
5
5
|
|
|
6
|
-
const API_BASE_URL = "https://
|
|
7
|
-
const
|
|
8
|
-
const
|
|
9
|
-
const
|
|
10
|
-
const
|
|
6
|
+
const API_BASE_URL = "https://api.reasoner.com/api/mindsim";
|
|
7
|
+
const WORKOS_DEVICE_AUTH_URL = "https://auth.reasoner.com/user_management/authorize/device";
|
|
8
|
+
const WORKOS_TOKEN_URL = "https://auth.reasoner.com/user_management/authenticate";
|
|
9
|
+
const WORKOS_CLIENT_ID = "client_01GPECHM1J9DMY7WQNKTJ195P6";
|
|
10
|
+
const SDK_KEYS_API_URL = "https://api.reasoner.com/api/sdk/keys";
|
|
11
11
|
|
|
12
12
|
export function getConfigDir() {
|
|
13
13
|
return path.join(os.homedir(), ".mindsim");
|
|
@@ -46,12 +46,12 @@ export const saveApiKey = (apiKey: string): void => {
|
|
|
46
46
|
fs.writeFileSync(configFile, JSON.stringify({ apiKey }, null, 2));
|
|
47
47
|
};
|
|
48
48
|
|
|
49
|
-
export const
|
|
49
|
+
export const getDeviceAuthConfig = (): DeviceAuthConfig => {
|
|
50
50
|
return {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
51
|
+
deviceAuthUrl: process.env.MINDSIM_WORKOS_DEVICE_AUTH_URL || WORKOS_DEVICE_AUTH_URL,
|
|
52
|
+
tokenUrl: process.env.MINDSIM_WORKOS_TOKEN_URL || WORKOS_TOKEN_URL,
|
|
53
|
+
clientId: process.env.MINDSIM_WORKOS_CLIENT_ID || WORKOS_CLIENT_ID,
|
|
54
|
+
sdkKeysApiUrl: process.env.MINDSIM_SDK_KEYS_API_URL || SDK_KEYS_API_URL,
|
|
55
55
|
};
|
|
56
56
|
};
|
|
57
57
|
|
package/src/index.ts
CHANGED
|
@@ -7,7 +7,6 @@ import { PsychometricsResource } from "./resources/psychometrics";
|
|
|
7
7
|
import { SimulationsResource } from "./resources/simulations";
|
|
8
8
|
import { SnapshotsResource } from "./resources/snapshots";
|
|
9
9
|
import { TagsResource } from "./resources/tags";
|
|
10
|
-
import { UsageResource } from "./resources/usage";
|
|
11
10
|
import { UsersResource } from "./resources/users";
|
|
12
11
|
import { checkForUpdates, getPackageVersion } from "./version";
|
|
13
12
|
|
|
@@ -21,7 +20,6 @@ export class MindSim {
|
|
|
21
20
|
public snapshots: SnapshotsResource;
|
|
22
21
|
public simulations: SimulationsResource;
|
|
23
22
|
public tags: TagsResource;
|
|
24
|
-
public usage: UsageResource;
|
|
25
23
|
public users: UsersResource;
|
|
26
24
|
|
|
27
25
|
constructor(apiKey?: string, options?: { apiBaseUrl?: string }) {
|
|
@@ -59,7 +57,6 @@ export class MindSim {
|
|
|
59
57
|
this.snapshots = new SnapshotsResource(this.client);
|
|
60
58
|
this.simulations = new SimulationsResource(this.client);
|
|
61
59
|
this.tags = new TagsResource(this.client);
|
|
62
|
-
this.usage = new UsageResource(this.client);
|
|
63
60
|
this.users = new UsersResource(this.client);
|
|
64
61
|
}
|
|
65
62
|
}
|