@rosthq/cli 0.7.162 → 0.7.164
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 +109 -11
- package/dist/index.js.map +3 -3
- package/dist/runner-serve.d.ts +19 -1
- package/dist/runner-serve.d.ts.map +1 -1
- package/dist/runner-setup-orchestrator.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -29223,6 +29223,24 @@ var runnerSetupValidationAttemptSchema = external_exports.object({
|
|
|
29223
29223
|
(attempt) => attempt.kind === "aicos_acceptance" === (attempt.activation_receipt_id !== null),
|
|
29224
29224
|
"aicos_acceptance must be attributed to an activation receipt"
|
|
29225
29225
|
);
|
|
29226
|
+
var RUNNER_SETUP_PROBE_CAPABILITY_VERSION = 1;
|
|
29227
|
+
var runnerSetupValidationMcpCapabilityPayloadSchema = external_exports.object({
|
|
29228
|
+
capability_version: external_exports.literal(RUNNER_SETUP_PROBE_CAPABILITY_VERSION),
|
|
29229
|
+
tenant_id: uuid3,
|
|
29230
|
+
runner_id: uuid3,
|
|
29231
|
+
setup_id: uuid3,
|
|
29232
|
+
job_id: uuid3,
|
|
29233
|
+
runtime: runnerSetupRuntimeSchema,
|
|
29234
|
+
service_key_generation: external_exports.number().int().nonnegative(),
|
|
29235
|
+
nonce: external_exports.string().min(16).max(120),
|
|
29236
|
+
expires_at: external_exports.number().int().positive(),
|
|
29237
|
+
allowed_command_ids: external_exports.tuple([external_exports.literal("runner_setup.status")])
|
|
29238
|
+
}).strict();
|
|
29239
|
+
var runnerSetupValidationMcpConfigSchema = external_exports.object({
|
|
29240
|
+
url: external_exports.string().url(),
|
|
29241
|
+
token: external_exports.string().min(1).max(4096),
|
|
29242
|
+
expires_at: isoDateTime
|
|
29243
|
+
}).strict();
|
|
29226
29244
|
var runnerSetupValidationClaimRequestSchema = external_exports.object({
|
|
29227
29245
|
setup_id: uuid3,
|
|
29228
29246
|
runtime: runnerSetupRuntimeSchema
|
|
@@ -29231,7 +29249,8 @@ var runnerSetupValidationClaimResponseSchema = external_exports.object({
|
|
|
29231
29249
|
job_id: uuid3,
|
|
29232
29250
|
challenge: runnerSetupValidationChallengeSchema,
|
|
29233
29251
|
probe_capability_version: external_exports.number().int().positive(),
|
|
29234
|
-
allowed_command_ids: external_exports.array(external_exports.string().min(1).max(120)).min(1).max(20)
|
|
29252
|
+
allowed_command_ids: external_exports.array(external_exports.string().min(1).max(120)).min(1).max(20),
|
|
29253
|
+
mcp: runnerSetupValidationMcpConfigSchema
|
|
29235
29254
|
}).strict();
|
|
29236
29255
|
var runnerSetupValidationReportRequestSchema = external_exports.object({
|
|
29237
29256
|
job_id: uuid3,
|
|
@@ -29434,6 +29453,19 @@ var runnerPairingStartOutputSchema = external_exports.object({
|
|
|
29434
29453
|
expires_at: isoDateTime2,
|
|
29435
29454
|
expires_in: external_exports.number().int().nonnegative()
|
|
29436
29455
|
}).strict();
|
|
29456
|
+
var runnerPairingClaimInputSchema = external_exports.object({
|
|
29457
|
+
user_code: external_exports.string().min(8).max(12),
|
|
29458
|
+
service_key_public: external_exports.string().trim().min(1).max(1024).optional()
|
|
29459
|
+
}).strict();
|
|
29460
|
+
var runnerPairingClaimOutputSchema = external_exports.object({
|
|
29461
|
+
runner_id: uuid5,
|
|
29462
|
+
tenant_id: uuid5,
|
|
29463
|
+
runner_secret: external_exports.string().min(1),
|
|
29464
|
+
name: external_exports.string(),
|
|
29465
|
+
platform: external_exports.string(),
|
|
29466
|
+
service_key_generation: external_exports.number().int().nonnegative().optional(),
|
|
29467
|
+
service_key_bound: external_exports.boolean().optional()
|
|
29468
|
+
}).strict();
|
|
29437
29469
|
var runnerRevokeInputSchema = external_exports.object({
|
|
29438
29470
|
runner_id: uuid5
|
|
29439
29471
|
}).strict();
|
|
@@ -69609,7 +69641,7 @@ async function removeWorkspace(ws) {
|
|
|
69609
69641
|
|
|
69610
69642
|
// src/runner-serve.ts
|
|
69611
69643
|
import { execFile as execFileCallback5, spawn } from "node:child_process";
|
|
69612
|
-
import { createHash as createHash4, randomUUID } from "node:crypto";
|
|
69644
|
+
import { createHash as createHash4, createPrivateKey, createPublicKey as createPublicKey2, generateKeyPairSync, randomUUID } from "node:crypto";
|
|
69613
69645
|
import { constants as fsConstants6 } from "node:fs";
|
|
69614
69646
|
import { access as access3, chmod as chmod2, lstat as lstat2, mkdir as mkdir8, open as open2, readFile as readFile11, rename as rename2, rm as rm8, statfs, writeFile as writeFile8 } from "node:fs/promises";
|
|
69615
69647
|
import { cpus, homedir as homedir7, hostname as hostname3, platform, totalmem, tmpdir as tmpdir2 } from "node:os";
|
|
@@ -70369,16 +70401,20 @@ async function pairIfNeeded(client, fetchImpl, appUrl2, config2, io) {
|
|
|
70369
70401
|
`No paired runner state at ${config2.stateFile}. Provide --user-code <code> from Settings > Runners (Add a runner), or run \`${cliBrand.binName} login --device\` once to pair this runner.`
|
|
70370
70402
|
);
|
|
70371
70403
|
}
|
|
70404
|
+
const serviceKey = runnerServiceKeyPairForState(priorState);
|
|
70372
70405
|
const { runnerId, runnerSecret, tenantId: claimedTenantId, name: claimedName } = await claimRunnerPairingCode(
|
|
70373
70406
|
fetchImpl,
|
|
70374
70407
|
appUrl2,
|
|
70375
|
-
userCode
|
|
70408
|
+
userCode,
|
|
70409
|
+
serviceKey
|
|
70376
70410
|
);
|
|
70377
70411
|
const state = {
|
|
70378
70412
|
runner_id: runnerId,
|
|
70379
70413
|
runner_secret: runnerSecret,
|
|
70380
70414
|
...typeof claimedTenantId === "string" ? { tenant_id: claimedTenantId } : config2.expectedTenantId ? { tenant_id: config2.expectedTenantId } : {},
|
|
70381
|
-
name: typeof claimedName === "string" ? claimedName : config2.name
|
|
70415
|
+
name: typeof claimedName === "string" ? claimedName : config2.name,
|
|
70416
|
+
service_key_private: serviceKey.privateKey,
|
|
70417
|
+
service_key_public: serviceKey.publicKey
|
|
70382
70418
|
};
|
|
70383
70419
|
await saveState(config2.stateFile, state);
|
|
70384
70420
|
await reapSupersededRunnerHomes(priorState, runnerId, config2.homeDir);
|
|
@@ -70462,6 +70498,8 @@ async function loadState(filePath, expectedTenantId) {
|
|
|
70462
70498
|
runner_secret: parsed.runner_secret,
|
|
70463
70499
|
...typeof parsed.tenant_id === "string" ? { tenant_id: parsed.tenant_id } : {},
|
|
70464
70500
|
...typeof parsed.name === "string" ? { name: parsed.name } : {},
|
|
70501
|
+
...typeof parsed.service_key_private === "string" ? { service_key_private: parsed.service_key_private } : {},
|
|
70502
|
+
...typeof parsed.service_key_public === "string" ? { service_key_public: parsed.service_key_public } : {},
|
|
70465
70503
|
...isRuntimeSessionMap(parsed.runtime_sessions) ? { runtime_sessions: parsed.runtime_sessions } : {},
|
|
70466
70504
|
...isInFlightWorkOrderMap(parsed.in_flight_work_orders) ? { in_flight_work_orders: parsed.in_flight_work_orders } : {}
|
|
70467
70505
|
};
|
|
@@ -70496,8 +70534,56 @@ async function saveState(filePath, state) {
|
|
|
70496
70534
|
throw error51;
|
|
70497
70535
|
}
|
|
70498
70536
|
}
|
|
70499
|
-
|
|
70500
|
-
|
|
70537
|
+
var RUNNER_SERVICE_KEY_REPAIR_MESSAGE = "The persisted runner service key is invalid. Repair the local service-key state, then re-pair the runner or use explicit service-key rotation.";
|
|
70538
|
+
var RunnerServiceKeyError = class extends Error {
|
|
70539
|
+
code = "service_key_invalid";
|
|
70540
|
+
constructor() {
|
|
70541
|
+
super(RUNNER_SERVICE_KEY_REPAIR_MESSAGE);
|
|
70542
|
+
this.name = "RunnerServiceKeyError";
|
|
70543
|
+
}
|
|
70544
|
+
};
|
|
70545
|
+
function sshWireField(value) {
|
|
70546
|
+
const bytes = Buffer.isBuffer(value) ? value : Buffer.from(value, "utf8");
|
|
70547
|
+
const length = Buffer.allocUnsafe(4);
|
|
70548
|
+
length.writeUInt32BE(bytes.length, 0);
|
|
70549
|
+
return Buffer.concat([length, bytes]);
|
|
70550
|
+
}
|
|
70551
|
+
function openSshEd25519PublicKey(publicKey) {
|
|
70552
|
+
const der = publicKey.export({ type: "spki", format: "der" });
|
|
70553
|
+
if (!Buffer.isBuffer(der) || der.length < 32) {
|
|
70554
|
+
throw new Error("Unable to encode the runner service key.");
|
|
70555
|
+
}
|
|
70556
|
+
const rawKey = der.subarray(der.length - 32);
|
|
70557
|
+
const wire = Buffer.concat([sshWireField("ssh-ed25519"), sshWireField(rawKey)]);
|
|
70558
|
+
return `ssh-ed25519 ${wire.toString("base64")}`;
|
|
70559
|
+
}
|
|
70560
|
+
function generateRunnerServiceKeyPair() {
|
|
70561
|
+
const { publicKey, privateKey } = generateKeyPairSync("ed25519");
|
|
70562
|
+
const privatePem = privateKey.export({ type: "pkcs8", format: "pem" });
|
|
70563
|
+
if (typeof privatePem !== "string") {
|
|
70564
|
+
throw new Error("Unable to persist the runner service key.");
|
|
70565
|
+
}
|
|
70566
|
+
return { privateKey: privatePem, publicKey: openSshEd25519PublicKey(publicKey) };
|
|
70567
|
+
}
|
|
70568
|
+
function runnerServiceKeyPairFromPrivate(privatePem) {
|
|
70569
|
+
const privateKey = createPrivateKey(privatePem);
|
|
70570
|
+
return { privateKey: privatePem, publicKey: openSshEd25519PublicKey(createPublicKey2(privateKey)) };
|
|
70571
|
+
}
|
|
70572
|
+
function runnerServiceKeyPairForState(state) {
|
|
70573
|
+
if (state?.service_key_private === void 0) {
|
|
70574
|
+
return generateRunnerServiceKeyPair();
|
|
70575
|
+
}
|
|
70576
|
+
try {
|
|
70577
|
+
return runnerServiceKeyPairFromPrivate(state.service_key_private);
|
|
70578
|
+
} catch {
|
|
70579
|
+
throw new RunnerServiceKeyError();
|
|
70580
|
+
}
|
|
70581
|
+
}
|
|
70582
|
+
async function claimRunnerPairingCode(fetchImpl, appUrl2, userCode, serviceKey) {
|
|
70583
|
+
const claim = await post2(fetchImpl, appUrl2, "/api/runner/pairing/claim", {
|
|
70584
|
+
user_code: userCode,
|
|
70585
|
+
...serviceKey ? { service_key_public: serviceKey.publicKey } : {}
|
|
70586
|
+
});
|
|
70501
70587
|
const runnerSecret = claim.json.runner_secret;
|
|
70502
70588
|
const runnerId = claim.json.runner_id;
|
|
70503
70589
|
const tenantId = claim.json.tenant_id;
|
|
@@ -70508,7 +70594,10 @@ async function claimRunnerPairingCode(fetchImpl, appUrl2, userCode) {
|
|
|
70508
70594
|
runnerId,
|
|
70509
70595
|
runnerSecret,
|
|
70510
70596
|
tenantId: typeof tenantId === "string" ? tenantId : null,
|
|
70511
|
-
name: typeof claim.json.name === "string" ? claim.json.name : null
|
|
70597
|
+
name: typeof claim.json.name === "string" ? claim.json.name : null,
|
|
70598
|
+
...serviceKey ? { serviceKeyPrivate: serviceKey.privateKey, serviceKeyPublic: serviceKey.publicKey } : {},
|
|
70599
|
+
...typeof claim.json.service_key_generation === "number" ? { serviceKeyGeneration: claim.json.service_key_generation } : {},
|
|
70600
|
+
...typeof claim.json.service_key_bound === "boolean" ? { serviceKeyBound: claim.json.service_key_bound } : {}
|
|
70512
70601
|
};
|
|
70513
70602
|
}
|
|
70514
70603
|
async function startPairing(client, config2) {
|
|
@@ -73974,7 +74063,14 @@ async function runPairingStage(sidecar, userCode, agent, fetchImpl, appUrl2, hom
|
|
|
73974
74063
|
}
|
|
73975
74064
|
if (userCode !== void 0) {
|
|
73976
74065
|
const priorState = await loadState(sidecar.state_file, expectedTenantId);
|
|
73977
|
-
|
|
74066
|
+
let serviceKey;
|
|
74067
|
+
try {
|
|
74068
|
+
serviceKey = runnerServiceKeyPairForState(priorState);
|
|
74069
|
+
} catch (error51) {
|
|
74070
|
+
const message = error51 instanceof RunnerServiceKeyError ? error51.message : RUNNER_SERVICE_KEY_REPAIR_MESSAGE;
|
|
74071
|
+
return { kind: "claim_failed", exitCode: 1, message: redactForLog(message) };
|
|
74072
|
+
}
|
|
74073
|
+
const claimResult = await claimRunnerPairingCodeSafe(fetchImpl, appUrl2, userCode, serviceKey);
|
|
73978
74074
|
if (!claimResult.ok) {
|
|
73979
74075
|
return { kind: "claim_failed", exitCode: claimResult.exitCode, message: claimResult.message };
|
|
73980
74076
|
}
|
|
@@ -73996,7 +74092,9 @@ async function runPairingStage(sidecar, userCode, agent, fetchImpl, appUrl2, hom
|
|
|
73996
74092
|
runner_id: claimResult.runnerId,
|
|
73997
74093
|
runner_secret: claimResult.runnerSecret,
|
|
73998
74094
|
...claimResult.tenantId !== null ? { tenant_id: claimResult.tenantId } : {},
|
|
73999
|
-
...claimResult.name !== null ? { name: claimResult.name } : {}
|
|
74095
|
+
...claimResult.name !== null ? { name: claimResult.name } : {},
|
|
74096
|
+
...claimResult.serviceKeyPrivate !== void 0 ? { service_key_private: claimResult.serviceKeyPrivate } : {},
|
|
74097
|
+
...claimResult.serviceKeyPublic !== void 0 ? { service_key_public: claimResult.serviceKeyPublic } : {}
|
|
74000
74098
|
};
|
|
74001
74099
|
await saveState(sidecar.state_file, newState);
|
|
74002
74100
|
await reapSupersededRunnerHomes(priorState, newState.runner_id, homeDir);
|
|
@@ -74021,9 +74119,9 @@ async function runPairingStage(sidecar, userCode, agent, fetchImpl, appUrl2, hom
|
|
|
74021
74119
|
}
|
|
74022
74120
|
return { kind: "needs_user_code" };
|
|
74023
74121
|
}
|
|
74024
|
-
async function claimRunnerPairingCodeSafe(fetchImpl, appUrl2, userCode) {
|
|
74122
|
+
async function claimRunnerPairingCodeSafe(fetchImpl, appUrl2, userCode, serviceKey) {
|
|
74025
74123
|
try {
|
|
74026
|
-
const claim = await claimRunnerPairingCode(fetchImpl, appUrl2, userCode);
|
|
74124
|
+
const claim = await claimRunnerPairingCode(fetchImpl, appUrl2, userCode, serviceKey);
|
|
74027
74125
|
return { ok: true, ...claim };
|
|
74028
74126
|
} catch (error51) {
|
|
74029
74127
|
const message = error51 instanceof Error ? error51.message : String(error51);
|