trajectories-sh 1.15.0 → 1.17.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/dist/{auth-UD3KTSHK.js → auth-4UEZSE4C.js} +1 -1
- package/dist/{chunk-P6J5X7LP.js → chunk-Q2ZEN43L.js} +5 -0
- package/dist/cli.js +31 -17
- package/dist/{config-NOIAMV2U.js → config-4XJRECIW.js} +1 -1
- package/dist/{download-O3JONHXT.js → download-HTNOD7O4.js} +1 -1
- package/dist/{push-task-PUGFXEBK.js → push-task-IZZNF3ZA.js} +1 -1
- package/dist/{upload-I7L5SPZB.js → upload-V5ZE557B.js} +26 -7
- package/package.json +1 -1
|
@@ -29,6 +29,8 @@ function getAccessToken() {
|
|
|
29
29
|
return loadConfig().access_token;
|
|
30
30
|
}
|
|
31
31
|
async function getAuthHeader() {
|
|
32
|
+
const envKey = process.env.TRAJECTORIES_API_KEY;
|
|
33
|
+
if (envKey && envKey.trim()) return `Bearer ${envKey.trim()}`;
|
|
32
34
|
const config = loadConfig();
|
|
33
35
|
if (config.api_key) return `Bearer ${config.api_key}`;
|
|
34
36
|
if (config.access_token && config.refresh_token) {
|
|
@@ -99,6 +101,9 @@ function clearAuth() {
|
|
|
99
101
|
if (existsSync(CONFIG_FILE)) unlinkSync(CONFIG_FILE);
|
|
100
102
|
}
|
|
101
103
|
function isLoggedIn() {
|
|
104
|
+
if (process.env.TRAJECTORIES_API_KEY && process.env.TRAJECTORIES_API_KEY.trim()) {
|
|
105
|
+
return true;
|
|
106
|
+
}
|
|
102
107
|
const config = loadConfig();
|
|
103
108
|
return !!(config.api_key || config.access_token);
|
|
104
109
|
}
|
package/dist/cli.js
CHANGED
|
@@ -21,7 +21,7 @@ auth.command("login").description("Log in to trajectories.sh via your browser").
|
|
|
21
21
|
if (opts.apiKey) {
|
|
22
22
|
const spinner = ora("Validating API key...").start();
|
|
23
23
|
try {
|
|
24
|
-
const { loginWithApiKey } = await import("./auth-
|
|
24
|
+
const { loginWithApiKey } = await import("./auth-4UEZSE4C.js");
|
|
25
25
|
await loginWithApiKey(opts.apiKey);
|
|
26
26
|
spinner.succeed("Logged in with API key");
|
|
27
27
|
} catch (e) {
|
|
@@ -33,7 +33,7 @@ auth.command("login").description("Log in to trajectories.sh via your browser").
|
|
|
33
33
|
console.log(chalk.bold("\n Opening browser to log in...\n"));
|
|
34
34
|
console.log(chalk.dim(" If the browser doesn't open, visit:"));
|
|
35
35
|
try {
|
|
36
|
-
const { loginWithBrowser } = await import("./auth-
|
|
36
|
+
const { loginWithBrowser } = await import("./auth-4UEZSE4C.js");
|
|
37
37
|
const { email } = await loginWithBrowser();
|
|
38
38
|
console.log(chalk.green(`
|
|
39
39
|
\u2713 Logged in as ${email}
|
|
@@ -48,13 +48,13 @@ auth.command("login").description("Log in to trajectories.sh via your browser").
|
|
|
48
48
|
});
|
|
49
49
|
auth.command("logout").description("Log out and remove saved credentials").action(async () => {
|
|
50
50
|
const chalk = (await import("chalk")).default;
|
|
51
|
-
const { logout } = await import("./auth-
|
|
51
|
+
const { logout } = await import("./auth-4UEZSE4C.js");
|
|
52
52
|
logout();
|
|
53
53
|
console.log(chalk.green(" \u2713 Logged out. Credentials removed."));
|
|
54
54
|
});
|
|
55
55
|
auth.command("status").description("Show current authentication status").action(async () => {
|
|
56
56
|
const chalk = (await import("chalk")).default;
|
|
57
|
-
const { status } = await import("./auth-
|
|
57
|
+
const { status } = await import("./auth-4UEZSE4C.js");
|
|
58
58
|
const s = status();
|
|
59
59
|
if (s.loggedIn) {
|
|
60
60
|
console.log(chalk.green(" \u2713 Authenticated"));
|
|
@@ -71,9 +71,16 @@ async function uploadTrajectoryAction(directory, opts) {
|
|
|
71
71
|
console.error(chalk.red(` \u2717 Directory not found: ${directory}`));
|
|
72
72
|
process.exit(1);
|
|
73
73
|
}
|
|
74
|
-
|
|
74
|
+
if (opts.apiKey) {
|
|
75
|
+
process.env.TRAJECTORIES_API_KEY = String(opts.apiKey);
|
|
76
|
+
}
|
|
77
|
+
const { isLoggedIn } = await import("./config-4XJRECIW.js");
|
|
75
78
|
if (!isLoggedIn()) {
|
|
76
|
-
console.error(
|
|
79
|
+
console.error(
|
|
80
|
+
chalk.red(
|
|
81
|
+
" \u2717 Not authenticated.\n Pass --api-key YOUR_KEY, set TRAJECTORIES_API_KEY in your env,\n or run: trajectories auth login"
|
|
82
|
+
)
|
|
83
|
+
);
|
|
77
84
|
process.exit(1);
|
|
78
85
|
}
|
|
79
86
|
if (opts.visibility) {
|
|
@@ -88,7 +95,7 @@ async function uploadTrajectoryAction(directory, opts) {
|
|
|
88
95
|
Uploading trajectory ${directory} \u2192 ${chalk.cyan(slug)}
|
|
89
96
|
`));
|
|
90
97
|
try {
|
|
91
|
-
const { uploadJob } = await import("./upload-
|
|
98
|
+
const { uploadJob } = await import("./upload-V5ZE557B.js");
|
|
92
99
|
const result = await uploadJob(directory, {
|
|
93
100
|
slug,
|
|
94
101
|
name: opts.name
|
|
@@ -117,9 +124,16 @@ async function uploadTaskAction(directory, opts) {
|
|
|
117
124
|
console.error(chalk.red(` \u2717 Directory not found: ${directory}`));
|
|
118
125
|
process.exit(1);
|
|
119
126
|
}
|
|
120
|
-
|
|
127
|
+
if (opts.apiKey) {
|
|
128
|
+
process.env.TRAJECTORIES_API_KEY = String(opts.apiKey);
|
|
129
|
+
}
|
|
130
|
+
const { isLoggedIn } = await import("./config-4XJRECIW.js");
|
|
121
131
|
if (!isLoggedIn()) {
|
|
122
|
-
console.error(
|
|
132
|
+
console.error(
|
|
133
|
+
chalk.red(
|
|
134
|
+
" \u2717 Not authenticated.\n Pass --api-key YOUR_KEY, set TRAJECTORIES_API_KEY in your env,\n or run: trajectories auth login"
|
|
135
|
+
)
|
|
136
|
+
);
|
|
123
137
|
process.exit(1);
|
|
124
138
|
}
|
|
125
139
|
const name = opts.name ?? directory.replace(/\/+$/, "").split("/").pop();
|
|
@@ -127,7 +141,7 @@ async function uploadTaskAction(directory, opts) {
|
|
|
127
141
|
Uploading task ${directory} \u2192 ${chalk.cyan(name)}
|
|
128
142
|
`));
|
|
129
143
|
try {
|
|
130
|
-
const { pushTask } = await import("./push-task-
|
|
144
|
+
const { pushTask } = await import("./push-task-IZZNF3ZA.js");
|
|
131
145
|
const result = await pushTask(directory, {
|
|
132
146
|
name: opts.name,
|
|
133
147
|
visibility: opts.visibility
|
|
@@ -154,7 +168,7 @@ async function downloadTrajectoryAction(url, opts) {
|
|
|
154
168
|
Downloading trajectory...
|
|
155
169
|
`));
|
|
156
170
|
try {
|
|
157
|
-
const { downloadJob, parseJobId } = await import("./download-
|
|
171
|
+
const { downloadJob, parseJobId } = await import("./download-HTNOD7O4.js");
|
|
158
172
|
const outputDir = opts.output ?? parseJobId(url).replace(/^org:/, "").replace(/:/g, "-");
|
|
159
173
|
const result = await downloadJob(url, outputDir);
|
|
160
174
|
console.log(chalk.green.bold(` \u2713 Downloaded ${result.files} files`));
|
|
@@ -170,8 +184,8 @@ async function downloadTrajectoryAction(url, opts) {
|
|
|
170
184
|
}
|
|
171
185
|
async function deleteTrajectoryAction(url, opts) {
|
|
172
186
|
const chalk = (await import("chalk")).default;
|
|
173
|
-
const { parseJobId } = await import("./download-
|
|
174
|
-
const { getApiUrl, getAuthHeader } = await import("./config-
|
|
187
|
+
const { parseJobId } = await import("./download-HTNOD7O4.js");
|
|
188
|
+
const { getApiUrl, getAuthHeader } = await import("./config-4XJRECIW.js");
|
|
175
189
|
let jobId = parseJobId(url);
|
|
176
190
|
if (jobId.startsWith("org:")) {
|
|
177
191
|
console.error(chalk.red("\n \u2717 Please use a direct job URL or UUID for deletion.\n"));
|
|
@@ -228,16 +242,16 @@ async function deleteTrajectoryAction(url, opts) {
|
|
|
228
242
|
}
|
|
229
243
|
}
|
|
230
244
|
var upload = program.command("upload").description("Upload trajectories or tasks");
|
|
231
|
-
upload.command("trajectory <directory>").description("Upload a trajectory job directory (always uploaded as unlisted)").option("-s, --slug <slug>", "URL slug (default: directory name)").option("-n, --name <name>", "Display name (default: slug)").option("-v, --visibility <vis>", "(deprecated, ignored \u2014 set visibility in the UI)").action(uploadTrajectoryAction);
|
|
232
|
-
upload.command("task <directory>").description("Upload a benchmark task directory").option("-n, --name <name>", "Task name (default: directory name)").option("-v, --visibility <vis>", "public or private", "public").action(uploadTaskAction);
|
|
245
|
+
upload.command("trajectory <directory>").description("Upload a trajectory job directory (always uploaded as unlisted)").option("-s, --slug <slug>", "URL slug (default: directory name)").option("-n, --name <name>", "Display name (default: slug)").option("--api-key <key>", "API key (or set TRAJECTORIES_API_KEY in your env)").option("-v, --visibility <vis>", "(deprecated, ignored \u2014 set visibility in the UI)").action(uploadTrajectoryAction);
|
|
246
|
+
upload.command("task <directory>").description("Upload a benchmark task directory").option("-n, --name <name>", "Task name (default: directory name)").option("--api-key <key>", "API key (or set TRAJECTORIES_API_KEY in your env)").option("-v, --visibility <vis>", "public or private", "public").action(uploadTaskAction);
|
|
233
247
|
var download = program.command("download").description("Download trajectories");
|
|
234
248
|
download.command("trajectory <url>").description("Download a trajectory job from trajectories.sh").option("-o, --output <dir>", "Output directory (default: slug name)").action(downloadTrajectoryAction);
|
|
235
249
|
var del = program.command("delete").description("Delete trajectories");
|
|
236
250
|
del.command("trajectory <url>").description("Delete a trajectory job from trajectories.sh").option("-y, --yes", "Skip confirmation prompt").action(deleteTrajectoryAction);
|
|
237
251
|
program.command("whoami").description("Show current authentication status").action(async () => {
|
|
238
252
|
const chalk = (await import("chalk")).default;
|
|
239
|
-
const { status } = await import("./auth-
|
|
240
|
-
const { getApiUrl } = await import("./config-
|
|
253
|
+
const { status } = await import("./auth-4UEZSE4C.js");
|
|
254
|
+
const { getApiUrl } = await import("./config-4XJRECIW.js");
|
|
241
255
|
const s = status();
|
|
242
256
|
if (s.loggedIn) {
|
|
243
257
|
console.log(chalk.green(" \u2713 Authenticated"));
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
getApiUrl,
|
|
3
3
|
getAuthHeader
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-Q2ZEN43L.js";
|
|
5
5
|
|
|
6
6
|
// src/upload.ts
|
|
7
7
|
import { readdirSync, statSync, readFileSync, writeFileSync, mkdirSync, copyFileSync, unlinkSync } from "fs";
|
|
@@ -16,6 +16,7 @@ var WEBP_CONCURRENCY = Number(process.env.TRAJECTORIES_CLI_WEBP_CONCURRENCY ?? "
|
|
|
16
16
|
var HASH_CONCURRENCY = Number(process.env.TRAJECTORIES_CLI_HASH_CONCURRENCY ?? "16");
|
|
17
17
|
function collectFiles(dir) {
|
|
18
18
|
const files = [];
|
|
19
|
+
const skipped = [];
|
|
19
20
|
function walk(current) {
|
|
20
21
|
for (const entry of readdirSync(current, { withFileTypes: true })) {
|
|
21
22
|
if (SKIP.has(entry.name)) continue;
|
|
@@ -24,14 +25,17 @@ function collectFiles(dir) {
|
|
|
24
25
|
walk(full);
|
|
25
26
|
} else if (entry.isFile()) {
|
|
26
27
|
const st = statSync(full);
|
|
28
|
+
const collected = { absPath: full, relPath: relative(dir, full), size: st.size };
|
|
27
29
|
if (st.size <= MAX_FILE_SIZE) {
|
|
28
|
-
files.push(
|
|
30
|
+
files.push(collected);
|
|
31
|
+
} else {
|
|
32
|
+
skipped.push(collected);
|
|
29
33
|
}
|
|
30
34
|
}
|
|
31
35
|
}
|
|
32
36
|
}
|
|
33
37
|
walk(dir);
|
|
34
|
-
return files;
|
|
38
|
+
return { files, skipped };
|
|
35
39
|
}
|
|
36
40
|
async function apiPost(path, body, timeout = 3e5) {
|
|
37
41
|
const auth = await getAuthHeader();
|
|
@@ -44,7 +48,7 @@ async function apiPost(path, body, timeout = 3e5) {
|
|
|
44
48
|
});
|
|
45
49
|
}
|
|
46
50
|
async function convertToWebP(dir) {
|
|
47
|
-
const files = collectFiles(dir);
|
|
51
|
+
const { files } = collectFiles(dir);
|
|
48
52
|
const pngs = files.filter((f) => f.relPath.toLowerCase().endsWith(".png"));
|
|
49
53
|
if (pngs.length === 0) {
|
|
50
54
|
return { convertedDir: dir, pngsConverted: 0, savedBytes: 0 };
|
|
@@ -119,7 +123,7 @@ async function convertToWebP(dir) {
|
|
|
119
123
|
} catch {
|
|
120
124
|
}
|
|
121
125
|
}
|
|
122
|
-
const trajFiles = collectFiles(tmpDir).filter((f) => f.relPath.endsWith("trajectory.json"));
|
|
126
|
+
const trajFiles = collectFiles(tmpDir).files.filter((f) => f.relPath.endsWith("trajectory.json"));
|
|
123
127
|
for (const tf of trajFiles) {
|
|
124
128
|
try {
|
|
125
129
|
let content = readFileSync(tf.absPath, "utf-8");
|
|
@@ -174,7 +178,7 @@ async function computeContentHash(files) {
|
|
|
174
178
|
}
|
|
175
179
|
function validateAtifFormat(dir) {
|
|
176
180
|
const errors = [];
|
|
177
|
-
const files = collectFiles(dir);
|
|
181
|
+
const { files } = collectFiles(dir);
|
|
178
182
|
const relPaths = new Set(files.map((f) => f.relPath));
|
|
179
183
|
if (!relPaths.has("result.json")) {
|
|
180
184
|
errors.push("Missing result.json at the job root");
|
|
@@ -306,9 +310,24 @@ async function uploadJob(dir, opts) {
|
|
|
306
310
|
if (pngsConverted > 0) {
|
|
307
311
|
console.log(` \u2713 Converted ${pngsConverted} PNGs to WebP (saved ${(savedBytes / 1024 / 1024).toFixed(1)} MB)`);
|
|
308
312
|
}
|
|
309
|
-
const files = collectFiles(convertedDir);
|
|
313
|
+
const { files, skipped } = collectFiles(convertedDir);
|
|
310
314
|
const totalSize = files.reduce((s, f) => s + f.size, 0);
|
|
311
315
|
console.log(` ${files.length} files, ${(totalSize / 1024 / 1024).toFixed(1)} MB`);
|
|
316
|
+
if (skipped.length > 0) {
|
|
317
|
+
const skippedMB = skipped.reduce((s, f) => s + f.size, 0) / (1024 * 1024);
|
|
318
|
+
const limitMB = MAX_FILE_SIZE / (1024 * 1024);
|
|
319
|
+
const samples = skipped.sort((a, b) => b.size - a.size).slice(0, 5).map((f) => ` \u2022 ${f.relPath} (${(f.size / 1024 / 1024).toFixed(1)} MB)`).join("\n");
|
|
320
|
+
const more = skipped.length > 5 ? `
|
|
321
|
+
\u2026 and ${skipped.length - 5} more` : "";
|
|
322
|
+
console.warn(
|
|
323
|
+
`
|
|
324
|
+
\u26A0 Skipping ${skipped.length} file${skipped.length > 1 ? "s" : ""} larger than ${limitMB.toFixed(0)} MB (${skippedMB.toFixed(1)} MB total):
|
|
325
|
+
${samples}${more}
|
|
326
|
+
These won't appear in the uploaded trajectory. Split or
|
|
327
|
+
compress them first if you need them included.
|
|
328
|
+
`
|
|
329
|
+
);
|
|
330
|
+
}
|
|
312
331
|
process.stdout.write(` Hashing...\r`);
|
|
313
332
|
const t0 = Date.now();
|
|
314
333
|
const contentHash = await computeContentHash(files);
|