bitfab-cli 0.2.10 → 0.2.11
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/index.js +608 -94
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -6805,6 +6805,307 @@ import { cancel as cancel2 } from "@clack/prompts";
|
|
|
6805
6805
|
import { execSync as execSync3 } from "child_process";
|
|
6806
6806
|
import * as p4 from "@clack/prompts";
|
|
6807
6807
|
|
|
6808
|
+
// ../bitfab-plugin-lib/dist/errors.js
|
|
6809
|
+
var NotAuthenticatedError = class extends Error {
|
|
6810
|
+
constructor(message) {
|
|
6811
|
+
super(message ?? "Not authenticated. Run the login command to connect your Bitfab account.");
|
|
6812
|
+
this.name = "NotAuthenticatedError";
|
|
6813
|
+
}
|
|
6814
|
+
};
|
|
6815
|
+
|
|
6816
|
+
// ../bitfab-plugin-lib/dist/studioRoutes.js
|
|
6817
|
+
var STUDIO_ROUTE_PATTERNS = [
|
|
6818
|
+
/^\/studio$/,
|
|
6819
|
+
/^\/studio\/experiments$/,
|
|
6820
|
+
/^\/studio\/close$/,
|
|
6821
|
+
/^\/studio\/sign-in$/,
|
|
6822
|
+
/^\/studio\/trace-plan\/[^/]+$/,
|
|
6823
|
+
/^\/studio\/trace-functions\/[^/]+\/datasets\/labeled$/,
|
|
6824
|
+
/^\/studio\/trace-functions\/[^/]+\/datasets\/[^/]+$/,
|
|
6825
|
+
/^\/studio\/trace-functions\/[^/]+\/template-preview$/,
|
|
6826
|
+
/^\/studio\/trace-functions\/[^/]+\/template-preview\/[^/]+$/,
|
|
6827
|
+
/^\/studio\/auth\/[^/]+$/
|
|
6828
|
+
];
|
|
6829
|
+
function isValidStudioRoute(input) {
|
|
6830
|
+
const pathname = input.split("?")[0];
|
|
6831
|
+
return STUDIO_ROUTE_PATTERNS.some((pattern) => pattern.test(pathname));
|
|
6832
|
+
}
|
|
6833
|
+
|
|
6834
|
+
// ../bitfab-plugin-lib/dist/agentSessionChannel.js
|
|
6835
|
+
var DEFAULT_POLL_INTERVAL_MS = 1500;
|
|
6836
|
+
async function createAgentSession(opts) {
|
|
6837
|
+
if (!opts.apiKey) {
|
|
6838
|
+
throw new NotAuthenticatedError();
|
|
6839
|
+
}
|
|
6840
|
+
const url2 = `${opts.serviceUrl}/api/studio/sessions`;
|
|
6841
|
+
const res = await fetch(url2, {
|
|
6842
|
+
method: "POST",
|
|
6843
|
+
headers: {
|
|
6844
|
+
Authorization: `Bearer ${opts.apiKey}`,
|
|
6845
|
+
"Content-Type": "application/json",
|
|
6846
|
+
...opts.extraHeaders
|
|
6847
|
+
},
|
|
6848
|
+
body: JSON.stringify({ sessionId: opts.sessionId })
|
|
6849
|
+
});
|
|
6850
|
+
if (!res.ok) {
|
|
6851
|
+
if (res.status === 401) {
|
|
6852
|
+
throw new NotAuthenticatedError("Session expired or invalid. Run the login command to re-authenticate.");
|
|
6853
|
+
}
|
|
6854
|
+
throw new Error(`createAgentSession failed (${res.status}): ${await res.text()}`);
|
|
6855
|
+
}
|
|
6856
|
+
return await res.json();
|
|
6857
|
+
}
|
|
6858
|
+
async function pushAgentSessionEvent(client, event) {
|
|
6859
|
+
const url2 = `${client.serviceUrl}/api/studio/events`;
|
|
6860
|
+
const res = await fetch(url2, {
|
|
6861
|
+
method: "POST",
|
|
6862
|
+
headers: {
|
|
6863
|
+
Authorization: `Bearer ${client.apiKey}`,
|
|
6864
|
+
"Content-Type": "application/json"
|
|
6865
|
+
},
|
|
6866
|
+
body: JSON.stringify({
|
|
6867
|
+
session: client.sessionId,
|
|
6868
|
+
type: event.type,
|
|
6869
|
+
data: event.data
|
|
6870
|
+
})
|
|
6871
|
+
});
|
|
6872
|
+
if (!res.ok) {
|
|
6873
|
+
throw new Error(`pushAgentSessionEvent failed (${res.status}): ${await res.text()}`);
|
|
6874
|
+
}
|
|
6875
|
+
return await res.json();
|
|
6876
|
+
}
|
|
6877
|
+
async function pollAgentSessionEvents(opts) {
|
|
6878
|
+
const interval = opts.intervalMs ?? DEFAULT_POLL_INTERVAL_MS;
|
|
6879
|
+
const client = {
|
|
6880
|
+
serviceUrl: opts.serviceUrl,
|
|
6881
|
+
apiKey: opts.apiKey,
|
|
6882
|
+
sessionId: opts.sessionId
|
|
6883
|
+
};
|
|
6884
|
+
let since = opts.startCursor ?? null;
|
|
6885
|
+
while (!opts.abortSignal.aborted) {
|
|
6886
|
+
try {
|
|
6887
|
+
const url2 = new URL(`${opts.serviceUrl}/api/studio/events`);
|
|
6888
|
+
url2.searchParams.set("session", opts.sessionId);
|
|
6889
|
+
if (since) {
|
|
6890
|
+
url2.searchParams.set("since", since);
|
|
6891
|
+
}
|
|
6892
|
+
const res = await fetch(url2.toString(), {
|
|
6893
|
+
headers: { Authorization: `Bearer ${opts.apiKey}` },
|
|
6894
|
+
signal: opts.abortSignal
|
|
6895
|
+
});
|
|
6896
|
+
if (res.ok) {
|
|
6897
|
+
const body = await res.json();
|
|
6898
|
+
for (const event of body.events) {
|
|
6899
|
+
if (event.type === "studio:ping") {
|
|
6900
|
+
sendPong(client, event.data.ts).catch(() => {
|
|
6901
|
+
});
|
|
6902
|
+
}
|
|
6903
|
+
opts.onEvent(event);
|
|
6904
|
+
since = event.id;
|
|
6905
|
+
}
|
|
6906
|
+
if (opts.onBrowserStatus && typeof body.browserConnected === "boolean") {
|
|
6907
|
+
opts.onBrowserStatus(body.browserConnected);
|
|
6908
|
+
}
|
|
6909
|
+
} else if (opts.onError) {
|
|
6910
|
+
opts.onError(new Error(`agent-session poll failed (${res.status})`));
|
|
6911
|
+
}
|
|
6912
|
+
} catch (err) {
|
|
6913
|
+
if (opts.abortSignal.aborted) {
|
|
6914
|
+
return;
|
|
6915
|
+
}
|
|
6916
|
+
if (opts.onError) {
|
|
6917
|
+
opts.onError(err instanceof Error ? err : new Error(String(err)));
|
|
6918
|
+
}
|
|
6919
|
+
}
|
|
6920
|
+
await new Promise((resolve) => {
|
|
6921
|
+
const onAbort = () => {
|
|
6922
|
+
clearTimeout(timer);
|
|
6923
|
+
resolve();
|
|
6924
|
+
};
|
|
6925
|
+
const timer = setTimeout(() => {
|
|
6926
|
+
opts.abortSignal.removeEventListener("abort", onAbort);
|
|
6927
|
+
resolve();
|
|
6928
|
+
}, interval);
|
|
6929
|
+
opts.abortSignal.addEventListener("abort", onAbort, { once: true });
|
|
6930
|
+
});
|
|
6931
|
+
}
|
|
6932
|
+
}
|
|
6933
|
+
async function pollLoginEvents(opts) {
|
|
6934
|
+
const interval = opts.intervalMs ?? DEFAULT_POLL_INTERVAL_MS;
|
|
6935
|
+
let since = null;
|
|
6936
|
+
while (!opts.abortSignal.aborted) {
|
|
6937
|
+
try {
|
|
6938
|
+
const url2 = new URL(`${opts.serviceUrl}/api/studio/sessions/poll`);
|
|
6939
|
+
url2.searchParams.set("session", opts.sessionId);
|
|
6940
|
+
if (since) {
|
|
6941
|
+
url2.searchParams.set("since", since);
|
|
6942
|
+
}
|
|
6943
|
+
const res = await fetch(url2.toString(), {
|
|
6944
|
+
signal: opts.abortSignal
|
|
6945
|
+
});
|
|
6946
|
+
if (res.ok) {
|
|
6947
|
+
const body = await res.json();
|
|
6948
|
+
for (const event of body.events) {
|
|
6949
|
+
since = event.id;
|
|
6950
|
+
if (event.type === "studio:authenticated" && typeof event.data.token === "string") {
|
|
6951
|
+
return event.data.token;
|
|
6952
|
+
}
|
|
6953
|
+
}
|
|
6954
|
+
}
|
|
6955
|
+
} catch {
|
|
6956
|
+
if (opts.abortSignal.aborted) {
|
|
6957
|
+
break;
|
|
6958
|
+
}
|
|
6959
|
+
}
|
|
6960
|
+
await new Promise((resolve) => {
|
|
6961
|
+
const onAbort = () => {
|
|
6962
|
+
clearTimeout(timer);
|
|
6963
|
+
resolve();
|
|
6964
|
+
};
|
|
6965
|
+
const timer = setTimeout(() => {
|
|
6966
|
+
opts.abortSignal.removeEventListener("abort", onAbort);
|
|
6967
|
+
resolve();
|
|
6968
|
+
}, interval);
|
|
6969
|
+
opts.abortSignal.addEventListener("abort", onAbort, { once: true });
|
|
6970
|
+
});
|
|
6971
|
+
}
|
|
6972
|
+
throw new Error("Login polling aborted");
|
|
6973
|
+
}
|
|
6974
|
+
async function navigateStudio(client, path14) {
|
|
6975
|
+
if (!isValidStudioRoute(path14)) {
|
|
6976
|
+
throw new Error(`Studio route not allowed: ${path14}`);
|
|
6977
|
+
}
|
|
6978
|
+
return pushAgentSessionEvent(client, {
|
|
6979
|
+
type: "agent:navigate",
|
|
6980
|
+
data: { path: path14 }
|
|
6981
|
+
});
|
|
6982
|
+
}
|
|
6983
|
+
var STUDIO_NAVIGATE_ACK_TIMEOUT_MS = 12e3;
|
|
6984
|
+
var PING_PONG_TIMEOUT_MS = 5e3;
|
|
6985
|
+
function awaitNavigateAck(client, path14, ackTimeoutMs) {
|
|
6986
|
+
const abortController = new AbortController();
|
|
6987
|
+
let timer = null;
|
|
6988
|
+
const result = new Promise((resolve) => {
|
|
6989
|
+
timer = setTimeout(() => {
|
|
6990
|
+
resolve({ acked: false, reason: "timeout" });
|
|
6991
|
+
abortController.abort();
|
|
6992
|
+
}, ackTimeoutMs);
|
|
6993
|
+
const pathOnly = path14.split("?")[0];
|
|
6994
|
+
pollAgentSessionEvents({
|
|
6995
|
+
serviceUrl: client.serviceUrl,
|
|
6996
|
+
apiKey: client.apiKey,
|
|
6997
|
+
sessionId: client.sessionId,
|
|
6998
|
+
abortSignal: abortController.signal,
|
|
6999
|
+
onEvent: (event) => {
|
|
7000
|
+
if (event.type === "studio:navigated" && event.data.path === pathOnly) {
|
|
7001
|
+
if (timer) {
|
|
7002
|
+
clearTimeout(timer);
|
|
7003
|
+
}
|
|
7004
|
+
resolve({ acked: true });
|
|
7005
|
+
abortController.abort();
|
|
7006
|
+
return;
|
|
7007
|
+
}
|
|
7008
|
+
if (event.type === "studio:navigation-blocked" && event.data.path === pathOnly) {
|
|
7009
|
+
if (timer) {
|
|
7010
|
+
clearTimeout(timer);
|
|
7011
|
+
}
|
|
7012
|
+
resolve({
|
|
7013
|
+
acked: false,
|
|
7014
|
+
reason: "blocked",
|
|
7015
|
+
blockedReason: event.data.reason
|
|
7016
|
+
});
|
|
7017
|
+
abortController.abort();
|
|
7018
|
+
return;
|
|
7019
|
+
}
|
|
7020
|
+
if (event.type === "studio:session-ended" || event.type === "studio:session-closed") {
|
|
7021
|
+
if (timer) {
|
|
7022
|
+
clearTimeout(timer);
|
|
7023
|
+
}
|
|
7024
|
+
resolve({ acked: false, reason: "session-ended" });
|
|
7025
|
+
abortController.abort();
|
|
7026
|
+
}
|
|
7027
|
+
},
|
|
7028
|
+
onError: () => {
|
|
7029
|
+
}
|
|
7030
|
+
}).catch(() => {
|
|
7031
|
+
if (abortController.signal.aborted) {
|
|
7032
|
+
return;
|
|
7033
|
+
}
|
|
7034
|
+
if (timer) {
|
|
7035
|
+
clearTimeout(timer);
|
|
7036
|
+
}
|
|
7037
|
+
resolve({ acked: false, reason: "timeout" });
|
|
7038
|
+
});
|
|
7039
|
+
});
|
|
7040
|
+
return result;
|
|
7041
|
+
}
|
|
7042
|
+
function awaitPong(client, pingTs) {
|
|
7043
|
+
return new Promise((resolve) => {
|
|
7044
|
+
const abortController = new AbortController();
|
|
7045
|
+
let received = false;
|
|
7046
|
+
const timer = setTimeout(() => {
|
|
7047
|
+
abortController.abort();
|
|
7048
|
+
resolve(false);
|
|
7049
|
+
}, PING_PONG_TIMEOUT_MS);
|
|
7050
|
+
pollAgentSessionEvents({
|
|
7051
|
+
serviceUrl: client.serviceUrl,
|
|
7052
|
+
apiKey: client.apiKey,
|
|
7053
|
+
sessionId: client.sessionId,
|
|
7054
|
+
abortSignal: abortController.signal,
|
|
7055
|
+
onEvent: (event) => {
|
|
7056
|
+
if (event.type === "studio:pong" && event.data.replyTo === pingTs) {
|
|
7057
|
+
received = true;
|
|
7058
|
+
clearTimeout(timer);
|
|
7059
|
+
abortController.abort();
|
|
7060
|
+
resolve(true);
|
|
7061
|
+
}
|
|
7062
|
+
},
|
|
7063
|
+
onError: () => {
|
|
7064
|
+
}
|
|
7065
|
+
}).catch(() => {
|
|
7066
|
+
if (!received) {
|
|
7067
|
+
clearTimeout(timer);
|
|
7068
|
+
resolve(false);
|
|
7069
|
+
}
|
|
7070
|
+
});
|
|
7071
|
+
});
|
|
7072
|
+
}
|
|
7073
|
+
async function navigateStudioAndAwaitAck(client, path14, opts = {}) {
|
|
7074
|
+
const ackTimeoutMs = opts.ackTimeoutMs ?? STUDIO_NAVIGATE_ACK_TIMEOUT_MS;
|
|
7075
|
+
if (!isValidStudioRoute(path14)) {
|
|
7076
|
+
return { acked: false, reason: "invalid-route" };
|
|
7077
|
+
}
|
|
7078
|
+
try {
|
|
7079
|
+
await navigateStudio(client, path14);
|
|
7080
|
+
} catch {
|
|
7081
|
+
return { acked: false, reason: "push-failed" };
|
|
7082
|
+
}
|
|
7083
|
+
const result = await awaitNavigateAck(client, path14, ackTimeoutMs);
|
|
7084
|
+
if (result.acked || result.reason !== "timeout") {
|
|
7085
|
+
return result;
|
|
7086
|
+
}
|
|
7087
|
+
const pingTs = Date.now();
|
|
7088
|
+
try {
|
|
7089
|
+
await pushAgentSessionEvent(client, {
|
|
7090
|
+
type: "agent:ping",
|
|
7091
|
+
data: { ts: pingTs }
|
|
7092
|
+
});
|
|
7093
|
+
} catch {
|
|
7094
|
+
return result;
|
|
7095
|
+
}
|
|
7096
|
+
const pongReceived = await awaitPong(client, pingTs);
|
|
7097
|
+
if (pongReceived) {
|
|
7098
|
+
return { acked: true };
|
|
7099
|
+
}
|
|
7100
|
+
return result;
|
|
7101
|
+
}
|
|
7102
|
+
async function sendPong(client, replyTo) {
|
|
7103
|
+
return pushAgentSessionEvent(client, {
|
|
7104
|
+
type: "agent:pong",
|
|
7105
|
+
data: { ts: Date.now(), replyTo }
|
|
7106
|
+
});
|
|
7107
|
+
}
|
|
7108
|
+
|
|
6808
7109
|
// ../bitfab-plugin-lib/dist/buildInfo.js
|
|
6809
7110
|
import crypto from "crypto";
|
|
6810
7111
|
import fs from "fs";
|
|
@@ -6840,9 +7141,9 @@ var GLOBAL_CONFIG_FILE = path3.join(GLOBAL_CONFIG_DIR, "config.json");
|
|
|
6840
7141
|
var GLOBAL_CREDENTIALS_FILE = path3.join(GLOBAL_CONFIG_DIR, "credentials.json");
|
|
6841
7142
|
var PROJECT_CONFIG_RELATIVE = path3.join(".bitfab", "config.local.json");
|
|
6842
7143
|
var PROJECT_CREDENTIALS_RELATIVE = path3.join(".bitfab", "credentials.local.json");
|
|
6843
|
-
function readJsonFile(
|
|
7144
|
+
function readJsonFile(filePath2) {
|
|
6844
7145
|
try {
|
|
6845
|
-
const content = fs3.readFileSync(
|
|
7146
|
+
const content = fs3.readFileSync(filePath2, "utf-8");
|
|
6846
7147
|
return JSON.parse(content);
|
|
6847
7148
|
} catch {
|
|
6848
7149
|
return null;
|
|
@@ -6863,18 +7164,18 @@ function findProjectFile(relativePath, startDir = process.cwd()) {
|
|
|
6863
7164
|
}
|
|
6864
7165
|
}
|
|
6865
7166
|
function getProjectConfigData() {
|
|
6866
|
-
const
|
|
6867
|
-
if (!
|
|
7167
|
+
const filePath2 = findProjectFile(PROJECT_CONFIG_RELATIVE);
|
|
7168
|
+
if (!filePath2) {
|
|
6868
7169
|
return null;
|
|
6869
7170
|
}
|
|
6870
|
-
return readJsonFile(
|
|
7171
|
+
return readJsonFile(filePath2);
|
|
6871
7172
|
}
|
|
6872
7173
|
function getProjectCredentialsData() {
|
|
6873
|
-
const
|
|
6874
|
-
if (!
|
|
7174
|
+
const filePath2 = findProjectFile(PROJECT_CREDENTIALS_RELATIVE);
|
|
7175
|
+
if (!filePath2) {
|
|
6875
7176
|
return null;
|
|
6876
7177
|
}
|
|
6877
|
-
return readJsonFile(
|
|
7178
|
+
return readJsonFile(filePath2) ?? {};
|
|
6878
7179
|
}
|
|
6879
7180
|
function getConfigData() {
|
|
6880
7181
|
return readJsonFile(GLOBAL_CONFIG_FILE) ?? {};
|
|
@@ -6941,6 +7242,12 @@ function getConfig() {
|
|
|
6941
7242
|
};
|
|
6942
7243
|
}
|
|
6943
7244
|
function saveCredentials(apiKey) {
|
|
7245
|
+
const projectFile = findProjectFile(PROJECT_CREDENTIALS_RELATIVE);
|
|
7246
|
+
if (projectFile) {
|
|
7247
|
+
fs3.writeFileSync(projectFile, `${JSON.stringify({ apiKey }, null, 2)}
|
|
7248
|
+
`);
|
|
7249
|
+
return;
|
|
7250
|
+
}
|
|
6944
7251
|
fs3.mkdirSync(GLOBAL_CONFIG_DIR, { recursive: true });
|
|
6945
7252
|
fs3.writeFileSync(GLOBAL_CREDENTIALS_FILE, `${JSON.stringify({ apiKey }, null, 2)}
|
|
6946
7253
|
`);
|
|
@@ -6996,36 +7303,62 @@ function buildBitfabRequestHeaders(apiKey, pluginVersion, platform2) {
|
|
|
6996
7303
|
};
|
|
6997
7304
|
}
|
|
6998
7305
|
|
|
6999
|
-
// ../bitfab-plugin-lib/dist/
|
|
7306
|
+
// ../bitfab-plugin-lib/dist/activeStudioSession.js
|
|
7000
7307
|
import crypto3 from "crypto";
|
|
7001
|
-
|
|
7002
|
-
|
|
7003
|
-
|
|
7004
|
-
|
|
7005
|
-
|
|
7308
|
+
import fs6 from "fs";
|
|
7309
|
+
import os6 from "os";
|
|
7310
|
+
import path5 from "path";
|
|
7311
|
+
function cwdHash() {
|
|
7312
|
+
return crypto3.createHash("sha256").update(process.cwd()).digest("hex").slice(0, 16);
|
|
7313
|
+
}
|
|
7314
|
+
function filePath() {
|
|
7315
|
+
return path5.join(os6.homedir(), ".config", "bitfab", `active-studio-session.${cwdHash()}.json`);
|
|
7316
|
+
}
|
|
7317
|
+
function writeActiveStudioSession(session) {
|
|
7318
|
+
const target = filePath();
|
|
7319
|
+
fs6.mkdirSync(path5.dirname(target), { recursive: true });
|
|
7320
|
+
const payload = {
|
|
7321
|
+
...session,
|
|
7322
|
+
pid: process.pid,
|
|
7323
|
+
startedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
7324
|
+
};
|
|
7325
|
+
const tmp = `${target}.${process.pid}.tmp`;
|
|
7326
|
+
fs6.writeFileSync(tmp, `${JSON.stringify(payload, null, 2)}
|
|
7327
|
+
`);
|
|
7328
|
+
fs6.renameSync(tmp, target);
|
|
7329
|
+
}
|
|
7330
|
+
function clearActiveStudioSession() {
|
|
7006
7331
|
try {
|
|
7007
|
-
const
|
|
7008
|
-
|
|
7009
|
-
|
|
7010
|
-
body: JSON.stringify(body)
|
|
7011
|
-
});
|
|
7012
|
-
if (config2.debug && !response.ok) {
|
|
7013
|
-
console.error(`reportHandoff: server returned ${response.status} for ${body.flow}`);
|
|
7332
|
+
const current = readActiveStudioSessionRaw();
|
|
7333
|
+
if (current && current.pid !== process.pid) {
|
|
7334
|
+
return;
|
|
7014
7335
|
}
|
|
7015
|
-
|
|
7016
|
-
|
|
7017
|
-
|
|
7018
|
-
|
|
7336
|
+
fs6.rmSync(filePath(), { force: true });
|
|
7337
|
+
} catch {
|
|
7338
|
+
}
|
|
7339
|
+
}
|
|
7340
|
+
function readActiveStudioSessionRaw() {
|
|
7341
|
+
try {
|
|
7342
|
+
const raw = fs6.readFileSync(filePath(), "utf-8");
|
|
7343
|
+
const parsed = JSON.parse(raw);
|
|
7344
|
+
if (typeof parsed.sessionId === "string" && typeof parsed.serviceUrl === "string" && typeof parsed.pid === "number" && typeof parsed.startedAt === "string") {
|
|
7345
|
+
return parsed;
|
|
7019
7346
|
}
|
|
7347
|
+
return null;
|
|
7348
|
+
} catch {
|
|
7349
|
+
return null;
|
|
7020
7350
|
}
|
|
7021
7351
|
}
|
|
7352
|
+
function readActiveStudioSession() {
|
|
7353
|
+
return readActiveStudioSessionRaw();
|
|
7354
|
+
}
|
|
7022
7355
|
|
|
7023
7356
|
// ../bitfab-plugin-lib/dist/browser.js
|
|
7024
7357
|
import { execSync, spawn } from "child_process";
|
|
7025
|
-
import
|
|
7026
|
-
import
|
|
7358
|
+
import fs7 from "fs";
|
|
7359
|
+
import os7 from "os";
|
|
7027
7360
|
function getChromiumBrowsers() {
|
|
7028
|
-
const platform2 =
|
|
7361
|
+
const platform2 = os7.platform();
|
|
7029
7362
|
if (platform2 === "darwin") {
|
|
7030
7363
|
return [
|
|
7031
7364
|
{
|
|
@@ -7113,7 +7446,7 @@ function getChromiumBrowsers() {
|
|
|
7113
7446
|
function findExistingBinary(paths) {
|
|
7114
7447
|
for (const candidate of paths) {
|
|
7115
7448
|
if (candidate.includes("/") || candidate.includes("\\")) {
|
|
7116
|
-
if (
|
|
7449
|
+
if (fs7.existsSync(candidate)) {
|
|
7117
7450
|
return candidate;
|
|
7118
7451
|
}
|
|
7119
7452
|
} else {
|
|
@@ -7127,10 +7460,10 @@ function findExistingBinary(paths) {
|
|
|
7127
7460
|
return null;
|
|
7128
7461
|
}
|
|
7129
7462
|
function getDefaultBrowserId() {
|
|
7130
|
-
const platform2 =
|
|
7463
|
+
const platform2 = os7.platform();
|
|
7131
7464
|
try {
|
|
7132
7465
|
if (platform2 === "darwin") {
|
|
7133
|
-
const plistPath = `${
|
|
7466
|
+
const plistPath = `${os7.homedir()}/Library/Preferences/com.apple.LaunchServices/com.apple.launchservices.secure.plist`;
|
|
7134
7467
|
const json2 = execSync(`plutil -convert json -o - "${plistPath}"`, {
|
|
7135
7468
|
stdio: ["ignore", "pipe", "ignore"],
|
|
7136
7469
|
encoding: "utf-8",
|
|
@@ -7171,7 +7504,7 @@ function matchChromiumBrowser(defaultId, browsers) {
|
|
|
7171
7504
|
var SCREEN_FRACTION = 0.95;
|
|
7172
7505
|
function getWorkArea() {
|
|
7173
7506
|
try {
|
|
7174
|
-
const platform2 =
|
|
7507
|
+
const platform2 = os7.platform();
|
|
7175
7508
|
if (platform2 === "darwin") {
|
|
7176
7509
|
const out = execSync(`osascript -l JavaScript -e 'ObjC.import("AppKit"); const s = $.NSScreen.mainScreen; const f = s.frame; const v = s.visibleFrame; const topY = f.size.height - (v.origin.y + v.size.height); JSON.stringify([v.origin.x, topY, v.size.width, v.size.height])'`, {
|
|
7177
7510
|
stdio: ["ignore", "pipe", "ignore"],
|
|
@@ -7240,7 +7573,7 @@ function openChromiumApp(binaryPath, url2, sizeArgs) {
|
|
|
7240
7573
|
spawnDetached(binaryPath, [`--app=${url2}`, ...sizeArgs]);
|
|
7241
7574
|
}
|
|
7242
7575
|
function openOsDefault(url2) {
|
|
7243
|
-
const platform2 =
|
|
7576
|
+
const platform2 = os7.platform();
|
|
7244
7577
|
if (platform2 === "darwin") {
|
|
7245
7578
|
spawnDetached("open", [url2]);
|
|
7246
7579
|
} else if (platform2 === "win32") {
|
|
@@ -7291,9 +7624,61 @@ function openChromelessWindow(url2) {
|
|
|
7291
7624
|
openOsDefault(url2);
|
|
7292
7625
|
}
|
|
7293
7626
|
|
|
7627
|
+
// ../bitfab-plugin-lib/dist/commands/createStudioSession.js
|
|
7628
|
+
function ensureStudioPath(p5) {
|
|
7629
|
+
if (!p5.startsWith("/studio")) {
|
|
7630
|
+
return "/studio";
|
|
7631
|
+
}
|
|
7632
|
+
return p5;
|
|
7633
|
+
}
|
|
7634
|
+
async function createStudioSession({ serviceUrl, apiKey, sessionId, initialPath = "/studio", clientHeaders }) {
|
|
7635
|
+
if (!apiKey) {
|
|
7636
|
+
throw new NotAuthenticatedError();
|
|
7637
|
+
}
|
|
7638
|
+
initialPath = ensureStudioPath(initialPath);
|
|
7639
|
+
if (!isValidStudioRoute(initialPath)) {
|
|
7640
|
+
throw new Error(`Studio route not allowed: ${initialPath}`);
|
|
7641
|
+
}
|
|
7642
|
+
await createAgentSession({
|
|
7643
|
+
serviceUrl,
|
|
7644
|
+
apiKey,
|
|
7645
|
+
sessionId,
|
|
7646
|
+
extraHeaders: clientHeaders
|
|
7647
|
+
});
|
|
7648
|
+
writeActiveStudioSession({ sessionId, serviceUrl });
|
|
7649
|
+
const separator = initialPath.includes("?") ? "&" : "?";
|
|
7650
|
+
const url2 = `${serviceUrl}${initialPath}${separator}session=${encodeURIComponent(sessionId)}`;
|
|
7651
|
+
openChromelessWindow(url2);
|
|
7652
|
+
return { sessionId, serviceUrl };
|
|
7653
|
+
}
|
|
7654
|
+
|
|
7655
|
+
// ../bitfab-plugin-lib/dist/commands/login.js
|
|
7656
|
+
import crypto5 from "crypto";
|
|
7657
|
+
|
|
7658
|
+
// ../bitfab-plugin-lib/dist/analytics.js
|
|
7659
|
+
async function reportHandoff(apiKey, pluginVersion, platform2, body) {
|
|
7660
|
+
const config2 = getConfig();
|
|
7661
|
+
const headers = buildBitfabRequestHeaders(apiKey, pluginVersion, platform2);
|
|
7662
|
+
try {
|
|
7663
|
+
const response = await fetch(`${config2.serviceUrl}/api/plugin/analytics/handoff`, {
|
|
7664
|
+
method: "POST",
|
|
7665
|
+
headers,
|
|
7666
|
+
body: JSON.stringify(body)
|
|
7667
|
+
});
|
|
7668
|
+
if (config2.debug && !response.ok) {
|
|
7669
|
+
console.error(`reportHandoff: server returned ${response.status} for ${body.flow}`);
|
|
7670
|
+
}
|
|
7671
|
+
} catch (err) {
|
|
7672
|
+
if (config2.debug) {
|
|
7673
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
7674
|
+
console.error(`reportHandoff: request failed for ${body.flow}: ${message}`);
|
|
7675
|
+
}
|
|
7676
|
+
}
|
|
7677
|
+
}
|
|
7678
|
+
|
|
7294
7679
|
// ../bitfab-plugin-lib/dist/frontmostApp.js
|
|
7295
7680
|
import { execFileSync as execFileSync2, spawn as spawn2 } from "child_process";
|
|
7296
|
-
import
|
|
7681
|
+
import os8 from "os";
|
|
7297
7682
|
function findAncestorApp() {
|
|
7298
7683
|
try {
|
|
7299
7684
|
let pid = process.ppid;
|
|
@@ -7354,7 +7739,7 @@ function focusItermSession(sessionId) {
|
|
|
7354
7739
|
spawnQuiet("osascript", ["-e", script]);
|
|
7355
7740
|
}
|
|
7356
7741
|
function getFrontmostApp() {
|
|
7357
|
-
const platform2 =
|
|
7742
|
+
const platform2 = os8.platform();
|
|
7358
7743
|
try {
|
|
7359
7744
|
if (platform2 === "darwin") {
|
|
7360
7745
|
return execFileSync2("osascript", [
|
|
@@ -7388,7 +7773,7 @@ function focusApp(identifier) {
|
|
|
7388
7773
|
if (!identifier) {
|
|
7389
7774
|
return;
|
|
7390
7775
|
}
|
|
7391
|
-
const platform2 =
|
|
7776
|
+
const platform2 = os8.platform();
|
|
7392
7777
|
if (platform2 === "darwin") {
|
|
7393
7778
|
spawnQuiet("osascript", [
|
|
7394
7779
|
"-e",
|
|
@@ -7418,7 +7803,7 @@ function focusApp(identifier) {
|
|
|
7418
7803
|
}
|
|
7419
7804
|
}
|
|
7420
7805
|
function recordFocus() {
|
|
7421
|
-
const platform2 =
|
|
7806
|
+
const platform2 = os8.platform();
|
|
7422
7807
|
if (platform2 === "linux") {
|
|
7423
7808
|
const windowId = process.env.WINDOWID;
|
|
7424
7809
|
if (windowId) {
|
|
@@ -7436,9 +7821,151 @@ function recordFocus() {
|
|
|
7436
7821
|
return () => focusApp(frontmost);
|
|
7437
7822
|
}
|
|
7438
7823
|
|
|
7439
|
-
// ../bitfab-plugin-lib/dist/commands/
|
|
7824
|
+
// ../bitfab-plugin-lib/dist/commands/openStudioTo.js
|
|
7825
|
+
import crypto4 from "crypto";
|
|
7826
|
+
|
|
7827
|
+
// ../bitfab-plugin-lib/dist/commands/loginForSession.js
|
|
7440
7828
|
var LOGIN_TIMEOUT_MS = 10 * 60 * 1e3;
|
|
7441
|
-
|
|
7829
|
+
|
|
7830
|
+
// ../bitfab-plugin-lib/dist/commands/openStudioTo.js
|
|
7831
|
+
var SESSION_CLOSE_GRACE_PERIOD_MS = 1e4;
|
|
7832
|
+
var StudioNavigationError = class extends Error {
|
|
7833
|
+
reason;
|
|
7834
|
+
blockedReason;
|
|
7835
|
+
staleSessionId;
|
|
7836
|
+
constructor(reason, blockedReason, staleSessionId) {
|
|
7837
|
+
super(blockedReason ? `Studio navigation failed (${reason}): ${blockedReason}` : `Studio navigation failed: ${reason}`);
|
|
7838
|
+
this.reason = reason;
|
|
7839
|
+
this.blockedReason = blockedReason;
|
|
7840
|
+
this.staleSessionId = staleSessionId;
|
|
7841
|
+
this.name = "StudioNavigationError";
|
|
7842
|
+
}
|
|
7843
|
+
};
|
|
7844
|
+
async function openStudioTo(path14, opts) {
|
|
7845
|
+
const sessionId = opts.sessionId ?? crypto4.randomUUID();
|
|
7846
|
+
const noop = () => {
|
|
7847
|
+
};
|
|
7848
|
+
const restoreFocus = recordFocus();
|
|
7849
|
+
if (!opts.apiKey) {
|
|
7850
|
+
const separator = path14.includes("?") ? "&" : "?";
|
|
7851
|
+
const url2 = `${opts.serviceUrl}${path14}${separator}session=${encodeURIComponent(sessionId)}`;
|
|
7852
|
+
openChromelessWindow(url2);
|
|
7853
|
+
return {
|
|
7854
|
+
sessionId,
|
|
7855
|
+
serviceUrl: opts.serviceUrl,
|
|
7856
|
+
opened: true,
|
|
7857
|
+
abort: noop,
|
|
7858
|
+
done: Promise.resolve()
|
|
7859
|
+
};
|
|
7860
|
+
}
|
|
7861
|
+
if (opts.forceNew) {
|
|
7862
|
+
clearActiveStudioSession();
|
|
7863
|
+
}
|
|
7864
|
+
const existing = opts.forceNew ? null : readActiveStudioSession();
|
|
7865
|
+
if (existing) {
|
|
7866
|
+
const client = {
|
|
7867
|
+
serviceUrl: existing.serviceUrl,
|
|
7868
|
+
apiKey: opts.apiKey,
|
|
7869
|
+
sessionId: existing.sessionId
|
|
7870
|
+
};
|
|
7871
|
+
const ack = await navigateStudioAndAwaitAck(client, path14);
|
|
7872
|
+
if (ack.acked) {
|
|
7873
|
+
const poller2 = opts.onEvent ? startEventPoller(existing.serviceUrl, opts.apiKey, existing.sessionId, opts.onEvent, restoreFocus) : { abort: noop, done: Promise.resolve() };
|
|
7874
|
+
return {
|
|
7875
|
+
sessionId: existing.sessionId,
|
|
7876
|
+
serviceUrl: existing.serviceUrl,
|
|
7877
|
+
opened: false,
|
|
7878
|
+
...poller2
|
|
7879
|
+
};
|
|
7880
|
+
}
|
|
7881
|
+
if (ack.reason === "session-ended" || ack.reason === "push-failed") {
|
|
7882
|
+
if (ack.reason === "session-ended") {
|
|
7883
|
+
clearActiveStudioSession();
|
|
7884
|
+
}
|
|
7885
|
+
} else {
|
|
7886
|
+
throw new StudioNavigationError(ack.reason ?? "unknown", ack.blockedReason, existing.sessionId);
|
|
7887
|
+
}
|
|
7888
|
+
}
|
|
7889
|
+
const session = await createStudioSession({
|
|
7890
|
+
serviceUrl: opts.serviceUrl,
|
|
7891
|
+
apiKey: opts.apiKey,
|
|
7892
|
+
sessionId,
|
|
7893
|
+
initialPath: path14,
|
|
7894
|
+
clientHeaders: opts.clientHeaders
|
|
7895
|
+
});
|
|
7896
|
+
const poller = opts.onEvent ? startEventPoller(session.serviceUrl, opts.apiKey, session.sessionId, opts.onEvent, restoreFocus) : { abort: noop, done: Promise.resolve() };
|
|
7897
|
+
return {
|
|
7898
|
+
sessionId: session.sessionId,
|
|
7899
|
+
serviceUrl: session.serviceUrl,
|
|
7900
|
+
opened: true,
|
|
7901
|
+
...poller
|
|
7902
|
+
};
|
|
7903
|
+
}
|
|
7904
|
+
function startEventPoller(serviceUrl, apiKey, sessionId, onEvent, restoreFocus) {
|
|
7905
|
+
const abortController = new AbortController();
|
|
7906
|
+
let sessionEndGraceTimer = null;
|
|
7907
|
+
const done = pollAgentSessionEvents({
|
|
7908
|
+
serviceUrl,
|
|
7909
|
+
apiKey,
|
|
7910
|
+
sessionId,
|
|
7911
|
+
abortSignal: abortController.signal,
|
|
7912
|
+
onEvent: (event) => {
|
|
7913
|
+
if (event.type === "studio:session-closed") {
|
|
7914
|
+
if (sessionEndGraceTimer) {
|
|
7915
|
+
return;
|
|
7916
|
+
}
|
|
7917
|
+
sessionEndGraceTimer = setTimeout(() => {
|
|
7918
|
+
sessionEndGraceTimer = null;
|
|
7919
|
+
clearActiveStudioSession();
|
|
7920
|
+
restoreFocus();
|
|
7921
|
+
onEvent({ ...event, type: "studio:session-ended" });
|
|
7922
|
+
abortController.abort();
|
|
7923
|
+
}, SESSION_CLOSE_GRACE_PERIOD_MS);
|
|
7924
|
+
return;
|
|
7925
|
+
}
|
|
7926
|
+
if (event.type === "studio:session-started") {
|
|
7927
|
+
if (sessionEndGraceTimer) {
|
|
7928
|
+
clearTimeout(sessionEndGraceTimer);
|
|
7929
|
+
sessionEndGraceTimer = null;
|
|
7930
|
+
console.error("Studio reconnected after page refresh");
|
|
7931
|
+
}
|
|
7932
|
+
return;
|
|
7933
|
+
}
|
|
7934
|
+
if (event.type === "studio:session-ended") {
|
|
7935
|
+
if (sessionEndGraceTimer) {
|
|
7936
|
+
clearTimeout(sessionEndGraceTimer);
|
|
7937
|
+
sessionEndGraceTimer = null;
|
|
7938
|
+
}
|
|
7939
|
+
clearActiveStudioSession();
|
|
7940
|
+
restoreFocus();
|
|
7941
|
+
onEvent(event);
|
|
7942
|
+
abortController.abort();
|
|
7943
|
+
return;
|
|
7944
|
+
}
|
|
7945
|
+
if (event.type === "studio:not-member") {
|
|
7946
|
+
restoreFocus();
|
|
7947
|
+
onEvent(event);
|
|
7948
|
+
abortController.abort();
|
|
7949
|
+
return;
|
|
7950
|
+
}
|
|
7951
|
+
if (event.type === "studio:return-to-agent" || event.type === "studio:edit-with-agent") {
|
|
7952
|
+
restoreFocus();
|
|
7953
|
+
}
|
|
7954
|
+
onEvent(event);
|
|
7955
|
+
},
|
|
7956
|
+
onError: (err) => {
|
|
7957
|
+
console.error(`studio agent-event poll: ${err.message}`);
|
|
7958
|
+
}
|
|
7959
|
+
}).catch((err) => {
|
|
7960
|
+
if (!abortController.signal.aborted) {
|
|
7961
|
+
console.error(`studio agent-event poll terminated: ${err.message}`);
|
|
7962
|
+
}
|
|
7963
|
+
});
|
|
7964
|
+
return { abort: () => abortController.abort(), done };
|
|
7965
|
+
}
|
|
7966
|
+
|
|
7967
|
+
// ../bitfab-plugin-lib/dist/commands/login.js
|
|
7968
|
+
var LOGIN_TIMEOUT_MS2 = 10 * 60 * 1e3;
|
|
7442
7969
|
async function verifyToken(serviceUrl, token) {
|
|
7443
7970
|
try {
|
|
7444
7971
|
const res = await fetch(`${serviceUrl}/api/plugin/whoami`, {
|
|
@@ -7452,58 +7979,50 @@ async function verifyToken(serviceUrl, token) {
|
|
|
7452
7979
|
return null;
|
|
7453
7980
|
}
|
|
7454
7981
|
}
|
|
7455
|
-
async function pollLoginStatus(serviceUrl, loginId, signal) {
|
|
7456
|
-
while (!signal.aborted) {
|
|
7457
|
-
try {
|
|
7458
|
-
const url2 = `${serviceUrl}/api/studio/login-status?loginId=${encodeURIComponent(loginId)}`;
|
|
7459
|
-
const res = await fetch(url2, { signal });
|
|
7460
|
-
if (res.ok) {
|
|
7461
|
-
const body = await res.json();
|
|
7462
|
-
if (body.status === "complete" && body.token) {
|
|
7463
|
-
return body.token;
|
|
7464
|
-
}
|
|
7465
|
-
}
|
|
7466
|
-
} catch {
|
|
7467
|
-
if (signal.aborted) {
|
|
7468
|
-
throw new Error("Login polling aborted");
|
|
7469
|
-
}
|
|
7470
|
-
}
|
|
7471
|
-
await new Promise((resolve) => {
|
|
7472
|
-
const timer = setTimeout(resolve, POLL_INTERVAL_MS);
|
|
7473
|
-
signal.addEventListener("abort", () => {
|
|
7474
|
-
clearTimeout(timer);
|
|
7475
|
-
resolve();
|
|
7476
|
-
}, { once: true });
|
|
7477
|
-
});
|
|
7478
|
-
}
|
|
7479
|
-
throw new Error("Login polling aborted");
|
|
7480
|
-
}
|
|
7481
7982
|
async function runLogin(platform2, pluginVersion, options) {
|
|
7482
7983
|
const exitOnComplete = options?.exitOnComplete ?? true;
|
|
7483
7984
|
const config2 = getConfig();
|
|
7484
7985
|
const restoreFocus = recordFocus();
|
|
7485
|
-
const
|
|
7486
|
-
const
|
|
7487
|
-
const
|
|
7986
|
+
const sessionId = crypto5.randomUUID();
|
|
7987
|
+
const redirectPath = `/studio/close?pluginLogin=true&session=${sessionId}&autoClose=true&message=${encodeURIComponent("Login complete")}`;
|
|
7988
|
+
const signInPath = `/studio/sign-in?redirect_url=${encodeURIComponent(redirectPath)}`;
|
|
7488
7989
|
console.log("\nOpening Studio to sign in...");
|
|
7489
|
-
console.log(
|
|
7490
|
-
|
|
7491
|
-
|
|
7492
|
-
|
|
7990
|
+
console.log("(If the browser didn't open, visit the Studio URL manually.)");
|
|
7991
|
+
try {
|
|
7992
|
+
await openStudioTo(signInPath, {
|
|
7993
|
+
apiKey: hasCredentials() ? config2.apiKey : null,
|
|
7994
|
+
serviceUrl: config2.serviceUrl,
|
|
7995
|
+
sessionId
|
|
7996
|
+
});
|
|
7997
|
+
} catch (err) {
|
|
7998
|
+
if (err instanceof StudioNavigationError) {
|
|
7999
|
+
await openStudioTo(signInPath, {
|
|
8000
|
+
apiKey: null,
|
|
8001
|
+
serviceUrl: config2.serviceUrl,
|
|
8002
|
+
sessionId
|
|
8003
|
+
});
|
|
8004
|
+
} else {
|
|
8005
|
+
throw err;
|
|
8006
|
+
}
|
|
8007
|
+
}
|
|
7493
8008
|
const abortController = new AbortController();
|
|
7494
8009
|
let loginTimer;
|
|
7495
8010
|
const timeoutPromise = new Promise((_resolve, reject) => {
|
|
7496
8011
|
loginTimer = setTimeout(() => {
|
|
7497
8012
|
abortController.abort();
|
|
7498
8013
|
reject(new Error("Authentication timed out after 10 minutes. Run login again."));
|
|
7499
|
-
},
|
|
8014
|
+
}, LOGIN_TIMEOUT_MS2);
|
|
7500
8015
|
});
|
|
7501
8016
|
const keepaliveTimer = setInterval(() => {
|
|
7502
8017
|
process.stdout.write("");
|
|
7503
8018
|
}, 3e4);
|
|
7504
8019
|
try {
|
|
7505
8020
|
const token = await Promise.race([
|
|
7506
|
-
|
|
8021
|
+
pollLoginEvents({
|
|
8022
|
+
serviceUrl: config2.serviceUrl,
|
|
8023
|
+
sessionId,
|
|
8024
|
+
abortSignal: abortController.signal
|
|
8025
|
+
}),
|
|
7507
8026
|
timeoutPromise
|
|
7508
8027
|
]);
|
|
7509
8028
|
if (loginTimer) {
|
|
@@ -7511,11 +8030,6 @@ async function runLogin(platform2, pluginVersion, options) {
|
|
|
7511
8030
|
}
|
|
7512
8031
|
clearInterval(keepaliveTimer);
|
|
7513
8032
|
saveCredentials(token);
|
|
7514
|
-
const who = await verifyToken(config2.serviceUrl, token);
|
|
7515
|
-
const greeting = who?.user.email ? `Logged in as ${who.user.email}.` : "Authentication successful.";
|
|
7516
|
-
console.log(`
|
|
7517
|
-
${greeting}`);
|
|
7518
|
-
console.log("Bitfab MCP tools are now active. (via studio)");
|
|
7519
8033
|
await reportHandoff(token, pluginVersion, platform2, {
|
|
7520
8034
|
flow: "auth.login",
|
|
7521
8035
|
wonBy: "studio",
|
|
@@ -7523,6 +8037,11 @@ ${greeting}`);
|
|
|
7523
8037
|
ticketAvailable: false
|
|
7524
8038
|
});
|
|
7525
8039
|
restoreFocus();
|
|
8040
|
+
const who = await verifyToken(config2.serviceUrl, token);
|
|
8041
|
+
const greeting = who?.user.email ? `Logged in as ${who.user.email}.` : "Authentication successful.";
|
|
8042
|
+
console.log(`
|
|
8043
|
+
${greeting}`);
|
|
8044
|
+
console.log("Bitfab MCP tools are now active. (via studio)");
|
|
7526
8045
|
if (exitOnComplete) {
|
|
7527
8046
|
process.exit(0);
|
|
7528
8047
|
}
|
|
@@ -7552,19 +8071,8 @@ function runLogout() {
|
|
|
7552
8071
|
console.log("Logged out of Bitfab.");
|
|
7553
8072
|
}
|
|
7554
8073
|
|
|
7555
|
-
// ../bitfab-plugin-lib/dist/commands/openStudio.js
|
|
7556
|
-
import crypto5 from "crypto";
|
|
7557
|
-
|
|
7558
|
-
// ../bitfab-plugin-lib/dist/activeStudioSession.js
|
|
7559
|
-
import crypto4 from "crypto";
|
|
7560
|
-
import fs7 from "fs";
|
|
7561
|
-
import os8 from "os";
|
|
7562
|
-
import path5 from "path";
|
|
7563
|
-
|
|
7564
|
-
// ../bitfab-plugin-lib/dist/withStudioSession.js
|
|
7565
|
-
import crypto6 from "crypto";
|
|
7566
|
-
|
|
7567
8074
|
// ../bitfab-plugin-lib/dist/commands/openTracePlan.js
|
|
8075
|
+
import crypto6 from "crypto";
|
|
7568
8076
|
var OPEN_TRACE_PLAN_TIMEOUT_MS = 30 * 60 * 1e3;
|
|
7569
8077
|
|
|
7570
8078
|
// ../bitfab-plugin-lib/dist/commands/persistReplayLabels.js
|
|
@@ -21364,6 +21872,12 @@ var inputFileSchema = external_exports.object({
|
|
|
21364
21872
|
verdicts: external_exports.array(external_exports.unknown()).min(1)
|
|
21365
21873
|
});
|
|
21366
21874
|
|
|
21875
|
+
// ../bitfab-plugin-lib/dist/commands/startDataset.js
|
|
21876
|
+
import crypto7 from "crypto";
|
|
21877
|
+
|
|
21878
|
+
// ../bitfab-plugin-lib/dist/commands/startTemplatePreview.js
|
|
21879
|
+
import crypto8 from "crypto";
|
|
21880
|
+
|
|
21367
21881
|
// ../bitfab-plugin-lib/dist/activePreviewSession.js
|
|
21368
21882
|
import fs8 from "fs";
|
|
21369
21883
|
import os9 from "os";
|
|
@@ -27390,7 +27904,7 @@ Examples:
|
|
|
27390
27904
|
bitfab setup --skip-permissions Setup without permission prompts
|
|
27391
27905
|
bitfab assistant --skip-permissions Run assistant autonomously
|
|
27392
27906
|
`;
|
|
27393
|
-
function
|
|
27907
|
+
function parseArgs2(argv) {
|
|
27394
27908
|
const [command, ...tail] = argv;
|
|
27395
27909
|
let editor;
|
|
27396
27910
|
let skipPermissions;
|
|
@@ -27417,7 +27931,7 @@ function parseArgs(argv) {
|
|
|
27417
27931
|
return { command, editor, skipPermissions, rest };
|
|
27418
27932
|
}
|
|
27419
27933
|
async function main() {
|
|
27420
|
-
const { command, editor, skipPermissions, rest } =
|
|
27934
|
+
const { command, editor, skipPermissions, rest } = parseArgs2(
|
|
27421
27935
|
process.argv.slice(2)
|
|
27422
27936
|
);
|
|
27423
27937
|
const abortUpdateCheck = startUpdateCheck();
|
|
@@ -27473,5 +27987,5 @@ main().catch((err) => {
|
|
|
27473
27987
|
process.exit(1);
|
|
27474
27988
|
});
|
|
27475
27989
|
export {
|
|
27476
|
-
parseArgs
|
|
27990
|
+
parseArgs2 as parseArgs
|
|
27477
27991
|
};
|