pairit 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.
- package/README.md +1 -0
- package/dist/index.js +73 -63
- package/package.json +41 -41
package/README.md
CHANGED
|
@@ -38,6 +38,7 @@ This makes `pairit` available globally from the `bin` field in package.json.
|
|
|
38
38
|
|
|
39
39
|
```bash
|
|
40
40
|
pairit login # Authenticate (required first)
|
|
41
|
+
# On a remote/headless server, open the printed URL locally and paste back the one-time code
|
|
41
42
|
|
|
42
43
|
pairit config lint path/to/config.yaml
|
|
43
44
|
pairit config compile path/to/config.yaml
|
package/dist/index.js
CHANGED
|
@@ -9955,73 +9955,74 @@ async function exchangeCodeForToken(code) {
|
|
|
9955
9955
|
async function login() {
|
|
9956
9956
|
console.log("Initiating login...");
|
|
9957
9957
|
const loginUrl = `${BASE_URL}/login`;
|
|
9958
|
-
|
|
9959
|
-
|
|
9960
|
-
|
|
9961
|
-
|
|
9962
|
-
|
|
9963
|
-
server
|
|
9964
|
-
|
|
9965
|
-
|
|
9966
|
-
|
|
9967
|
-
|
|
9968
|
-
|
|
9969
|
-
}
|
|
9970
|
-
});
|
|
9971
|
-
});
|
|
9972
|
-
const redirectUri = `http://127.0.0.1:${port}`;
|
|
9973
|
-
const targetUrl = `${loginUrl}?cli_redirect_uri=${encodeURIComponent(redirectUri)}`;
|
|
9974
|
-
console.log("Opening browser for authentication...");
|
|
9975
|
-
await open2(targetUrl);
|
|
9976
|
-
console.log(`Waiting for authentication at ${redirectUri}...`);
|
|
9977
|
-
const authCode = await new Promise((resolve, reject) => {
|
|
9978
|
-
const timeout = setTimeout(() => {
|
|
9979
|
-
server.close();
|
|
9980
|
-
reject(new Error("Login timed out"));
|
|
9981
|
-
}, 120000);
|
|
9982
|
-
server.on("request", (req, res) => {
|
|
9983
|
-
try {
|
|
9984
|
-
const url = new URL(req.url || "/", `http://${req.headers.host}`);
|
|
9985
|
-
const code = url.searchParams.get("code");
|
|
9986
|
-
if (code) {
|
|
9987
|
-
res.writeHead(200, { "Content-Type": "text/html" });
|
|
9988
|
-
res.end(`<!DOCTYPE html><html><head><title>Login Successful</title></head><body style="font-family:system-ui;display:flex;align-items:center;justify-content:center;height:100vh;margin:0"><div style="text-align:center"><h1>Authenticated!</h1><p>You can close this window and return to your CLI.</p></div><script>setTimeout(()=>window.close(),3000)</script></body></html>`);
|
|
9989
|
-
clearTimeout(timeout);
|
|
9990
|
-
server.close();
|
|
9991
|
-
resolve(code);
|
|
9958
|
+
const manualLoginUrl = `${loginUrl}?manual=1`;
|
|
9959
|
+
if (canAttemptBrowserLogin()) {
|
|
9960
|
+
try {
|
|
9961
|
+
const { createServer } = await import("node:http");
|
|
9962
|
+
const { default: open2 } = await Promise.resolve().then(() => (init_open(), exports_open));
|
|
9963
|
+
const server = createServer();
|
|
9964
|
+
const port = await new Promise((resolve, reject) => {
|
|
9965
|
+
server.listen(0, "127.0.0.1", () => {
|
|
9966
|
+
const address = server.address();
|
|
9967
|
+
if (address && typeof address === "object") {
|
|
9968
|
+
resolve(address.port);
|
|
9992
9969
|
} else {
|
|
9993
|
-
|
|
9994
|
-
res.end("Missing authorization code");
|
|
9970
|
+
reject(new Error("Could not determine port"));
|
|
9995
9971
|
}
|
|
9996
|
-
}
|
|
9997
|
-
res.writeHead(500);
|
|
9998
|
-
res.end("Error processing request");
|
|
9999
|
-
}
|
|
9972
|
+
});
|
|
10000
9973
|
});
|
|
10001
|
-
|
|
10002
|
-
|
|
10003
|
-
|
|
10004
|
-
|
|
10005
|
-
|
|
10006
|
-
|
|
10007
|
-
|
|
10008
|
-
|
|
9974
|
+
const redirectUri = `http://127.0.0.1:${port}`;
|
|
9975
|
+
const targetUrl = `${loginUrl}?cli_redirect_uri=${encodeURIComponent(redirectUri)}`;
|
|
9976
|
+
console.log("Opening browser for authentication...");
|
|
9977
|
+
await open2(targetUrl);
|
|
9978
|
+
console.log(`Waiting for authentication at ${redirectUri}...`);
|
|
9979
|
+
const authCode = await new Promise((resolve, reject) => {
|
|
9980
|
+
const timeout = setTimeout(() => {
|
|
9981
|
+
server.close();
|
|
9982
|
+
reject(new Error("Login timed out"));
|
|
9983
|
+
}, 120000);
|
|
9984
|
+
server.on("request", (req, res) => {
|
|
9985
|
+
try {
|
|
9986
|
+
const url = new URL(req.url || "/", `http://${req.headers.host}`);
|
|
9987
|
+
const code2 = url.searchParams.get("code");
|
|
9988
|
+
if (code2) {
|
|
9989
|
+
res.writeHead(200, { "Content-Type": "text/html" });
|
|
9990
|
+
res.end(`<!DOCTYPE html><html><head><title>Login Successful</title></head><body style="font-family:system-ui;display:flex;align-items:center;justify-content:center;height:100vh;margin:0"><div style="text-align:center"><h1>Authenticated!</h1><p>You can close this window and return to your CLI.</p></div><script>setTimeout(()=>window.close(),3000)</script></body></html>`);
|
|
9991
|
+
clearTimeout(timeout);
|
|
9992
|
+
server.close();
|
|
9993
|
+
resolve(code2);
|
|
9994
|
+
} else {
|
|
9995
|
+
res.writeHead(400);
|
|
9996
|
+
res.end("Missing authorization code");
|
|
9997
|
+
}
|
|
9998
|
+
} catch (_e) {
|
|
9999
|
+
res.writeHead(500);
|
|
10000
|
+
res.end("Error processing request");
|
|
10001
|
+
}
|
|
10002
|
+
});
|
|
10003
|
+
});
|
|
10004
|
+
console.log("Exchanging authorization code for token...");
|
|
10005
|
+
const token2 = await exchangeCodeForToken(authCode);
|
|
10006
|
+
await saveCredentials({ token: token2 });
|
|
10007
|
+
console.log("Successfully logged in!");
|
|
10008
|
+
return;
|
|
10009
|
+
} catch (error) {
|
|
10010
|
+
console.warn("Automated login failed, falling back to manual entry:", error instanceof Error ? error.message : String(error));
|
|
10011
|
+
}
|
|
10009
10012
|
}
|
|
10010
10013
|
console.log(`
|
|
10011
|
-
|
|
10014
|
+
Open this URL in a browser on any machine:
|
|
10015
|
+
${manualLoginUrl}
|
|
10012
10016
|
|
|
10013
|
-
After
|
|
10014
|
-
|
|
10017
|
+
After signing in, the page will show a one-time authorization code.
|
|
10018
|
+
Paste that code here to complete CLI login.
|
|
10015
10019
|
`);
|
|
10016
|
-
|
|
10017
|
-
|
|
10018
|
-
|
|
10019
|
-
} catch (_e) {}
|
|
10020
|
-
const token = await prompt("Enter session token (from browser): ");
|
|
10021
|
-
if (!token) {
|
|
10022
|
-
console.error("No token provided");
|
|
10020
|
+
const code = await prompt("Enter authorization code: ");
|
|
10021
|
+
if (!code) {
|
|
10022
|
+
console.error("No authorization code provided");
|
|
10023
10023
|
process.exit(1);
|
|
10024
10024
|
}
|
|
10025
|
+
const token = await exchangeCodeForToken(code);
|
|
10025
10026
|
await saveCredentials({ token });
|
|
10026
10027
|
console.log("Successfully logged in!");
|
|
10027
10028
|
}
|
|
@@ -10086,6 +10087,15 @@ async function prompt(question) {
|
|
|
10086
10087
|
});
|
|
10087
10088
|
});
|
|
10088
10089
|
}
|
|
10090
|
+
function canAttemptBrowserLogin() {
|
|
10091
|
+
if (!process.stdout.isTTY || !process.stdin.isTTY) {
|
|
10092
|
+
return false;
|
|
10093
|
+
}
|
|
10094
|
+
if (process.env.SSH_CONNECTION || process.env.SSH_CLIENT || process.env.SSH_TTY) {
|
|
10095
|
+
return false;
|
|
10096
|
+
}
|
|
10097
|
+
return process.platform === "darwin" || process.platform === "win32" || Boolean(process.env.DISPLAY || process.env.WAYLAND_DISPLAY);
|
|
10098
|
+
}
|
|
10089
10099
|
async function loadKeytar() {
|
|
10090
10100
|
try {
|
|
10091
10101
|
const runtimeImport = new Function("s", "return import(s)");
|
|
@@ -10101,7 +10111,7 @@ async function loadKeytar() {
|
|
|
10101
10111
|
|
|
10102
10112
|
// src/index.ts
|
|
10103
10113
|
var program2 = new Command;
|
|
10104
|
-
program2.name("pairit").description("CLI for Pairit experiment configs").version("0.1.
|
|
10114
|
+
program2.name("pairit").description("CLI for Pairit experiment configs").version("0.1.3");
|
|
10105
10115
|
program2.command("login").description("Login to Pairit Manager").action(async () => {
|
|
10106
10116
|
try {
|
|
10107
10117
|
await login();
|
|
@@ -10560,11 +10570,11 @@ async function exportData(configId, options) {
|
|
|
10560
10570
|
Files written to: ${outDir}`);
|
|
10561
10571
|
}
|
|
10562
10572
|
function flattenSession(session) {
|
|
10563
|
-
const {
|
|
10573
|
+
const { session_state, prolific, ...rest } = session;
|
|
10564
10574
|
const flattened = { ...rest };
|
|
10565
|
-
if (
|
|
10566
|
-
for (const [key, value] of Object.entries(
|
|
10567
|
-
flattened[`
|
|
10575
|
+
if (session_state && typeof session_state === "object") {
|
|
10576
|
+
for (const [key, value] of Object.entries(session_state)) {
|
|
10577
|
+
flattened[`session_state.${key}`] = serializeValue(value);
|
|
10568
10578
|
}
|
|
10569
10579
|
}
|
|
10570
10580
|
if (prolific) {
|
package/package.json
CHANGED
|
@@ -1,43 +1,43 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
2
|
+
"name": "pairit",
|
|
3
|
+
"version": "0.1.4",
|
|
4
|
+
"description": "CLI for the Pairit behavioral science experiment platform",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"pairit": "dist/index.js"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"dist"
|
|
11
|
+
],
|
|
12
|
+
"scripts": {
|
|
13
|
+
"build": "bun build src/index.ts --outdir dist --target node",
|
|
14
|
+
"lint": "tsc --noEmit",
|
|
15
|
+
"prepublishOnly": "bun run build"
|
|
16
|
+
},
|
|
17
|
+
"keywords": [
|
|
18
|
+
"experiment",
|
|
19
|
+
"behavioral-science",
|
|
20
|
+
"research",
|
|
21
|
+
"cli"
|
|
22
|
+
],
|
|
23
|
+
"repository": {
|
|
24
|
+
"type": "git",
|
|
25
|
+
"url": "https://github.com/pairium/pairit.git",
|
|
26
|
+
"directory": "apps/manager/cli"
|
|
27
|
+
},
|
|
28
|
+
"homepage": "https://pairium.github.io/pairit/",
|
|
29
|
+
"license": "MIT",
|
|
30
|
+
"optionalDependencies": {
|
|
31
|
+
"keytar": "^7.9.0"
|
|
32
|
+
},
|
|
33
|
+
"devDependencies": {
|
|
34
|
+
"@types/bun": "^1.1.13",
|
|
35
|
+
"@types/open": "^6.2.1",
|
|
36
|
+
"better-auth": "^1.4.7",
|
|
37
|
+
"commander": "^12.1.0",
|
|
38
|
+
"dotenv": "^17.2.3",
|
|
39
|
+
"open": "^11.0.0",
|
|
40
|
+
"typescript": "^5.9.3",
|
|
41
|
+
"yaml": "^2.6.0"
|
|
42
|
+
}
|
|
43
43
|
}
|