@instafy/cli 0.1.10 → 0.1.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/runtime.js +139 -39
- package/package.json +1 -1
package/dist/runtime.js
CHANGED
|
@@ -270,6 +270,7 @@ export async function mintRuntimeAccessToken(params) {
|
|
|
270
270
|
},
|
|
271
271
|
body: JSON.stringify({
|
|
272
272
|
runtimeId: params.runtimeId,
|
|
273
|
+
leaseId: params.leaseId,
|
|
273
274
|
scopes: params.scopes,
|
|
274
275
|
}),
|
|
275
276
|
},
|
|
@@ -295,6 +296,55 @@ export async function mintRuntimeAccessToken(params) {
|
|
|
295
296
|
}
|
|
296
297
|
return token;
|
|
297
298
|
}
|
|
299
|
+
async function requestRuntimeLease(params) {
|
|
300
|
+
const url = params.controllerUrl.replace(/\/$/, "");
|
|
301
|
+
const target = `${url}/projects/${encodeURIComponent(params.projectId)}/runtime/request`;
|
|
302
|
+
const { response, accessToken } = await fetchWithControllerAuth({
|
|
303
|
+
url: target,
|
|
304
|
+
init: {
|
|
305
|
+
method: "POST",
|
|
306
|
+
headers: {
|
|
307
|
+
"content-type": "application/json",
|
|
308
|
+
},
|
|
309
|
+
body: JSON.stringify({
|
|
310
|
+
provider: params.provider,
|
|
311
|
+
displayName: params.displayName,
|
|
312
|
+
idleTtlSeconds: params.idleTtlSeconds,
|
|
313
|
+
requestTunnel: params.requestTunnel,
|
|
314
|
+
runtimeId: params.runtimeId,
|
|
315
|
+
}),
|
|
316
|
+
},
|
|
317
|
+
accessToken: params.accessToken,
|
|
318
|
+
tokenSource: params.tokenSource,
|
|
319
|
+
profile: params.profile,
|
|
320
|
+
cwd: params.cwd,
|
|
321
|
+
});
|
|
322
|
+
if (!response.ok) {
|
|
323
|
+
const text = await response.text().catch(() => "");
|
|
324
|
+
if (response.status === 401 || response.status === 403) {
|
|
325
|
+
throw formatAuthRejectedError({
|
|
326
|
+
status: response.status,
|
|
327
|
+
responseBody: text,
|
|
328
|
+
});
|
|
329
|
+
}
|
|
330
|
+
throw new Error(`Instafy server rejected runtime request (${response.status} ${response.statusText}): ${text}`);
|
|
331
|
+
}
|
|
332
|
+
const payload = (await response.json());
|
|
333
|
+
const runtime = (payload["runtime"] ?? payload);
|
|
334
|
+
const runtimeId = (typeof runtime?.["runtimeId"] === "string" ? runtime["runtimeId"] : null) ??
|
|
335
|
+
(typeof runtime?.["runtime_id"] === "string" ? runtime["runtime_id"] : null) ??
|
|
336
|
+
null;
|
|
337
|
+
const leaseId = (typeof runtime?.["leaseId"] === "string" ? runtime["leaseId"] : null) ??
|
|
338
|
+
(typeof runtime?.["lease_id"] === "string" ? runtime["lease_id"] : null) ??
|
|
339
|
+
null;
|
|
340
|
+
if (!runtimeId || !runtimeId.trim()) {
|
|
341
|
+
throw new Error("Instafy server response missing runtimeId while requesting runtime lease.");
|
|
342
|
+
}
|
|
343
|
+
if (!leaseId || !leaseId.trim()) {
|
|
344
|
+
throw new Error("Instafy server response missing leaseId while requesting runtime lease.");
|
|
345
|
+
}
|
|
346
|
+
return { runtimeId: runtimeId.trim(), leaseId: leaseId.trim(), accessToken };
|
|
347
|
+
}
|
|
298
348
|
function isProcessAlive(pid) {
|
|
299
349
|
try {
|
|
300
350
|
process.kill(pid, 0);
|
|
@@ -350,19 +400,6 @@ export async function runtimeStart(options) {
|
|
|
350
400
|
env["CONTROLLER_BASE_URL"] ??
|
|
351
401
|
manifestInfo.manifest?.controllerUrl ??
|
|
352
402
|
"http://127.0.0.1:8788";
|
|
353
|
-
if (!runtimeAccessToken && controllerAccessToken) {
|
|
354
|
-
runtimeAccessToken = await mintRuntimeAccessToken({
|
|
355
|
-
controllerUrl: env["CONTROLLER_BASE_URL"],
|
|
356
|
-
controllerAccessToken,
|
|
357
|
-
projectId,
|
|
358
|
-
tokenSource: controllerAccessTokenSource,
|
|
359
|
-
profile,
|
|
360
|
-
cwd,
|
|
361
|
-
});
|
|
362
|
-
}
|
|
363
|
-
if (runtimeAccessToken) {
|
|
364
|
-
env["RUNTIME_ACCESS_TOKEN"] = runtimeAccessToken;
|
|
365
|
-
}
|
|
366
403
|
if (options.codexBin)
|
|
367
404
|
env["CODEX_BIN"] = options.codexBin;
|
|
368
405
|
if (options.proxyBaseUrl)
|
|
@@ -381,25 +418,6 @@ export async function runtimeStart(options) {
|
|
|
381
418
|
if (options.originEndpoint && options.originEndpoint.trim()) {
|
|
382
419
|
env["ORIGIN_ENDPOINT"] = options.originEndpoint.trim();
|
|
383
420
|
}
|
|
384
|
-
let originToken = normalizeToken(options.originToken) ?? normalizeToken(env["ORIGIN_INTERNAL_TOKEN"]);
|
|
385
|
-
if (!originToken && runtimeAccessToken) {
|
|
386
|
-
originToken = runtimeAccessToken;
|
|
387
|
-
}
|
|
388
|
-
if (!originToken && controllerAccessToken) {
|
|
389
|
-
originToken = await mintRuntimeAccessToken({
|
|
390
|
-
controllerUrl: env["CONTROLLER_BASE_URL"],
|
|
391
|
-
controllerAccessToken,
|
|
392
|
-
projectId,
|
|
393
|
-
runtimeId: env["RUNTIME_ID"],
|
|
394
|
-
tokenSource: controllerAccessTokenSource,
|
|
395
|
-
profile,
|
|
396
|
-
cwd,
|
|
397
|
-
});
|
|
398
|
-
}
|
|
399
|
-
if (!originToken) {
|
|
400
|
-
throw new Error("Runtime/origin token is required (--origin-token or ORIGIN_INTERNAL_TOKEN), or provide --runtime-token/--controller-access-token to mint/use one");
|
|
401
|
-
}
|
|
402
|
-
env["ORIGIN_INTERNAL_TOKEN"] = originToken;
|
|
403
421
|
const skipAuthRaw = env["ORIGIN_SKIP_AUTH"]?.trim().toLowerCase();
|
|
404
422
|
const skipAuth = skipAuthRaw === "1" || skipAuthRaw === "true" || skipAuthRaw === "yes";
|
|
405
423
|
const usesTunnel = !env["ORIGIN_ENDPOINT"];
|
|
@@ -410,12 +428,10 @@ export async function runtimeStart(options) {
|
|
|
410
428
|
}
|
|
411
429
|
env["RUNTIME_DISPLAY_NAME"] =
|
|
412
430
|
options.displayName ?? env["RUNTIME_DISPLAY_NAME"] ?? "Instafy CLI Runtime";
|
|
413
|
-
const manifestProvider = manifestInfo.manifest?.orgName?.trim() ||
|
|
414
|
-
manifestInfo.manifest?.orgId?.toString().trim();
|
|
415
431
|
env["RUNTIME_PROVIDER"] =
|
|
416
|
-
options.provider ?? env["RUNTIME_PROVIDER"] ??
|
|
432
|
+
options.provider ?? env["RUNTIME_PROVIDER"] ?? "self-hosted";
|
|
417
433
|
env["RUNTIME_VERSION"] = env["RUNTIME_VERSION"] ?? "0.1.0";
|
|
418
|
-
env["RUNTIME_REQUIRE_CODEX_BIN"] = env["RUNTIME_REQUIRE_CODEX_BIN"] || "
|
|
434
|
+
env["RUNTIME_REQUIRE_CODEX_BIN"] = env["RUNTIME_REQUIRE_CODEX_BIN"] || "0";
|
|
419
435
|
env["RUNTIME_CAPABILITIES"] =
|
|
420
436
|
env["RUNTIME_CAPABILITIES"] ||
|
|
421
437
|
JSON.stringify({ fs: true, github: true, supabase: true, runs: true, agent: true, origin: true });
|
|
@@ -429,6 +445,90 @@ export async function runtimeStart(options) {
|
|
|
429
445
|
const runtimeBin = runtimeMode === "docker" ? null : tryResolveRuntimeBinary();
|
|
430
446
|
const useDocker = runtimeMode === "docker" ||
|
|
431
447
|
(runtimeMode === "auto" && !runtimeBin);
|
|
448
|
+
if (useDocker && !isDockerAvailable()) {
|
|
449
|
+
throw new Error("runtime-agent is not available (no local binary and docker is not installed). Install Docker Desktop, or build runtime-agent from source.");
|
|
450
|
+
}
|
|
451
|
+
const originEnabledRaw = env["ORIGIN_ENABLED"]?.trim().toLowerCase();
|
|
452
|
+
const originEnabled = !originEnabledRaw ||
|
|
453
|
+
originEnabledRaw === "1" ||
|
|
454
|
+
originEnabledRaw === "true" ||
|
|
455
|
+
originEnabledRaw === "yes" ||
|
|
456
|
+
originEnabledRaw === "on";
|
|
457
|
+
if (originEnabled && usesTunnel && !useDocker) {
|
|
458
|
+
const ratholeResolved = await resolveRatholeBinaryForCli({
|
|
459
|
+
env,
|
|
460
|
+
version: process.env["RATHOLE_VERSION"] ?? null,
|
|
461
|
+
cacheDir: process.env["RATHOLE_CACHE_DIR"] ?? null,
|
|
462
|
+
logger: (message) => console.log(kleur.cyan(`[rathole] ${message}`)),
|
|
463
|
+
warn: (message) => console.warn(kleur.yellow(message)),
|
|
464
|
+
});
|
|
465
|
+
if (!ratholeResolved) {
|
|
466
|
+
throw new Error("Tunnel is required but rathole is unavailable. Set RATHOLE_BIN (recommended) or pass --origin-endpoint to use a reachable URL.");
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
if (originEnabled && usesTunnel && !env["RUNTIME_LEASE_ID"]) {
|
|
470
|
+
const bearer = controllerAccessToken ?? runtimeAccessToken;
|
|
471
|
+
const tokenSource = controllerAccessToken ? controllerAccessTokenSource : "env";
|
|
472
|
+
if (!bearer) {
|
|
473
|
+
throw new Error("Login required to request a tunnel-enabled runtime lease. Run `instafy login` or pass --controller-access-token/--runtime-token.");
|
|
474
|
+
}
|
|
475
|
+
const ttl = typeof env["RUNTIME_LEASE_SECONDS"] === "string" ? Number(env["RUNTIME_LEASE_SECONDS"]) : NaN;
|
|
476
|
+
const idleTtlSeconds = Number.isFinite(ttl) && ttl > 0 ? ttl : undefined;
|
|
477
|
+
const lease = await requestRuntimeLease({
|
|
478
|
+
controllerUrl: env["CONTROLLER_BASE_URL"],
|
|
479
|
+
accessToken: bearer,
|
|
480
|
+
tokenSource,
|
|
481
|
+
profile,
|
|
482
|
+
cwd,
|
|
483
|
+
projectId,
|
|
484
|
+
provider: env["RUNTIME_PROVIDER"],
|
|
485
|
+
displayName: env["RUNTIME_DISPLAY_NAME"],
|
|
486
|
+
idleTtlSeconds,
|
|
487
|
+
requestTunnel: false,
|
|
488
|
+
runtimeId: env["RUNTIME_ID"],
|
|
489
|
+
});
|
|
490
|
+
env["RUNTIME_ID"] = lease.runtimeId;
|
|
491
|
+
env["RUNTIME_LEASE_ID"] = lease.leaseId;
|
|
492
|
+
if (controllerAccessToken && bearer === controllerAccessToken) {
|
|
493
|
+
controllerAccessToken = lease.accessToken;
|
|
494
|
+
env["CONTROLLER_ACCESS_TOKEN"] = controllerAccessToken;
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
if (!runtimeAccessToken && controllerAccessToken) {
|
|
498
|
+
runtimeAccessToken = await mintRuntimeAccessToken({
|
|
499
|
+
controllerUrl: env["CONTROLLER_BASE_URL"],
|
|
500
|
+
controllerAccessToken,
|
|
501
|
+
projectId,
|
|
502
|
+
runtimeId: env["RUNTIME_ID"],
|
|
503
|
+
leaseId: env["RUNTIME_LEASE_ID"],
|
|
504
|
+
tokenSource: controllerAccessTokenSource,
|
|
505
|
+
profile,
|
|
506
|
+
cwd,
|
|
507
|
+
});
|
|
508
|
+
}
|
|
509
|
+
if (runtimeAccessToken) {
|
|
510
|
+
env["RUNTIME_ACCESS_TOKEN"] = runtimeAccessToken;
|
|
511
|
+
}
|
|
512
|
+
let originToken = normalizeToken(options.originToken) ?? normalizeToken(env["ORIGIN_INTERNAL_TOKEN"]);
|
|
513
|
+
if (!originToken && runtimeAccessToken) {
|
|
514
|
+
originToken = runtimeAccessToken;
|
|
515
|
+
}
|
|
516
|
+
if (!originToken && controllerAccessToken) {
|
|
517
|
+
originToken = await mintRuntimeAccessToken({
|
|
518
|
+
controllerUrl: env["CONTROLLER_BASE_URL"],
|
|
519
|
+
controllerAccessToken,
|
|
520
|
+
projectId,
|
|
521
|
+
runtimeId: env["RUNTIME_ID"],
|
|
522
|
+
leaseId: env["RUNTIME_LEASE_ID"],
|
|
523
|
+
tokenSource: controllerAccessTokenSource,
|
|
524
|
+
profile,
|
|
525
|
+
cwd,
|
|
526
|
+
});
|
|
527
|
+
}
|
|
528
|
+
if (!originToken) {
|
|
529
|
+
throw new Error("Runtime/origin token is required (--origin-token or ORIGIN_INTERNAL_TOKEN), or provide --runtime-token/--controller-access-token to mint/use one");
|
|
530
|
+
}
|
|
531
|
+
env["ORIGIN_INTERNAL_TOKEN"] = originToken;
|
|
432
532
|
if (!useDocker) {
|
|
433
533
|
if (!env["ORIGIN_ENDPOINT"]) {
|
|
434
534
|
const ratholeResolved = await resolveRatholeBinaryForCli({
|
|
@@ -493,9 +593,6 @@ export async function runtimeStart(options) {
|
|
|
493
593
|
});
|
|
494
594
|
return;
|
|
495
595
|
}
|
|
496
|
-
if (!isDockerAvailable()) {
|
|
497
|
-
throw new Error("runtime-agent is not available (no local binary and docker is not installed). Install Docker Desktop, or build runtime-agent from source.");
|
|
498
|
-
}
|
|
499
596
|
const image = resolveRuntimeAgentImage();
|
|
500
597
|
const containerName = `instafy-runtime-${originId}`;
|
|
501
598
|
const hostPort = String(options.bindPort ?? env["ORIGIN_BIND_PORT"] ?? 54332);
|
|
@@ -503,6 +600,9 @@ export async function runtimeStart(options) {
|
|
|
503
600
|
const dockerEnv = { ...env };
|
|
504
601
|
dockerEnv["WORKSPACE_DIR"] = "/workspace";
|
|
505
602
|
dockerEnv["CODEX_HOME"] = "/workspace/.codex";
|
|
603
|
+
dockerEnv["TMPDIR"] = "/tmp";
|
|
604
|
+
dockerEnv["TMP"] = "/tmp";
|
|
605
|
+
dockerEnv["TEMP"] = "/tmp";
|
|
506
606
|
dockerEnv["ORIGIN_BIND_HOST"] = "0.0.0.0";
|
|
507
607
|
dockerEnv["CONTROLLER_BASE_URL"] = normalizeControllerUrlForDocker(env["CONTROLLER_BASE_URL"] ?? "");
|
|
508
608
|
const envArgs = [];
|