@rosthq/cli 0.7.30 → 0.7.31

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.
@@ -0,0 +1,2 @@
1
+ export declare function readCliVersion(): Promise<string | null>;
2
+ //# sourceMappingURL=cli-version.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli-version.d.ts","sourceRoot":"","sources":["../src/cli-version.ts"],"names":[],"mappings":"AAgBA,wBAAsB,cAAc,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAQ7D"}
@@ -1 +1 @@
1
- {"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../src/doctor.ts"],"names":[],"mappings":"AAOA,OAAO,EAAoB,KAAK,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAKrE,KAAK,QAAQ,GAAG;IACd,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;IAC1C,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;CAC3C,CAAC;AAEF,KAAK,aAAa,GAAG;IACnB,EAAE,EAAE,QAAQ,CAAC;IACb,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;CACzB,CAAC;AAEF,wBAAsB,SAAS,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC,CAoCvE"}
1
+ {"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../src/doctor.ts"],"names":[],"mappings":"AAQA,OAAO,EAAoB,KAAK,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAKrE,KAAK,QAAQ,GAAG;IACd,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;IAC1C,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;CAC3C,CAAC;AAEF,KAAK,aAAa,GAAG;IACnB,EAAE,EAAE,QAAQ,CAAC;IACb,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;CACzB,CAAC;AAEF,wBAAsB,SAAS,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC,CAoCvE"}
package/dist/index.js CHANGED
@@ -48826,21 +48826,32 @@ function helpText() {
48826
48826
  ].join("\n");
48827
48827
  }
48828
48828
 
48829
- // src/update-check.ts
48829
+ // src/cli-version.ts
48830
48830
  import { readFile as readFile2 } from "node:fs/promises";
48831
48831
  import { dirname as dirname2, resolve } from "node:path";
48832
48832
  import { fileURLToPath as fileURLToPath2 } from "node:url";
48833
- var latestPackageSchema = external_exports.object({
48833
+ var packageMetadataSchema = external_exports.object({
48834
48834
  version: external_exports.string()
48835
48835
  });
48836
- var packageMetadataSchema = external_exports.object({
48836
+ async function readCliVersion() {
48837
+ const packageJsonPath = resolve(dirname2(fileURLToPath2(import.meta.url)), "../package.json");
48838
+ try {
48839
+ const metadata = packageMetadataSchema.parse(JSON.parse(await readFile2(packageJsonPath, "utf8")));
48840
+ return metadata.version;
48841
+ } catch {
48842
+ return null;
48843
+ }
48844
+ }
48845
+
48846
+ // src/update-check.ts
48847
+ var latestPackageSchema = external_exports.object({
48837
48848
  version: external_exports.string()
48838
48849
  });
48839
48850
  async function maybePrintUpgradeNudge(io) {
48840
48851
  if (process.env.CI || process.env.VITEST || process.env.CLI_SKIP_UPDATE_CHECK === "1") {
48841
48852
  return;
48842
48853
  }
48843
- const currentVersion = await readCurrentVersion();
48854
+ const currentVersion = await readCliVersion();
48844
48855
  if (!currentVersion || currentVersion === "0.0.0") {
48845
48856
  return;
48846
48857
  }
@@ -48853,15 +48864,6 @@ async function maybePrintUpgradeNudge(io) {
48853
48864
  `
48854
48865
  );
48855
48866
  }
48856
- async function readCurrentVersion() {
48857
- const packageJsonPath = resolve(dirname2(fileURLToPath2(import.meta.url)), "../package.json");
48858
- try {
48859
- const metadata = packageMetadataSchema.parse(JSON.parse(await readFile2(packageJsonPath, "utf8")));
48860
- return metadata.version;
48861
- } catch {
48862
- return null;
48863
- }
48864
- }
48865
48867
  async function fetchLatestVersion(packageName) {
48866
48868
  const controller = new AbortController();
48867
48869
  const timeout = setTimeout(() => controller.abort(), 750);
@@ -51540,7 +51542,7 @@ function pendingConfirmationFromError(error51) {
51540
51542
 
51541
51543
  // src/doctor.ts
51542
51544
  import { execFile as execFileCallback2 } from "node:child_process";
51543
- import { access, readFile as readFile3 } from "node:fs/promises";
51545
+ import { access } from "node:fs/promises";
51544
51546
  import { delimiter } from "node:path";
51545
51547
  import { promisify as promisify2 } from "node:util";
51546
51548
  var execFile2 = promisify2(execFileCallback2);
@@ -51551,7 +51553,7 @@ async function runDoctor(options) {
51551
51553
  const config2 = loadConfig(env);
51552
51554
  lines.push(`app_url: ${config2.appUrl}`);
51553
51555
  lines.push(`supabase_url: ${config2.supabaseUrl}`);
51554
- const currentVersion = await readCurrentVersion2();
51556
+ const currentVersion = await readCliVersion();
51555
51557
  lines.push(`version: ${currentVersion ?? "unknown"}`);
51556
51558
  const pathStatus = await checkPath(env);
51557
51559
  lines.push(pathStatus);
@@ -51598,15 +51600,6 @@ async function probeCli(command) {
51598
51600
  return "not found";
51599
51601
  }
51600
51602
  }
51601
- async function readCurrentVersion2() {
51602
- try {
51603
- const url2 = new URL("../package.json", import.meta.url);
51604
- const parsed = JSON.parse(await readFile3(url2, "utf8"));
51605
- return typeof parsed.version === "string" ? parsed.version : null;
51606
- } catch {
51607
- return null;
51608
- }
51609
- }
51610
51603
  async function fetchLatestVersion2(packageName, env) {
51611
51604
  if (env.CI || env.VITEST || env.CLI_SKIP_UPDATE_CHECK === "1" || env[`${cliBrand.envPrefix}_CLI_NO_UPDATE_CHECK`] === "1") {
51612
51605
  return null;
@@ -51662,7 +51655,7 @@ function parseSemver2(value) {
51662
51655
  // src/runner-serve.ts
51663
51656
  import { execFile as execFileCallback3, spawn } from "node:child_process";
51664
51657
  import { createHash } from "node:crypto";
51665
- import { chmod, mkdir as mkdir2, readFile as readFile4, rename, rm as rm3, writeFile as writeFile2 } from "node:fs/promises";
51658
+ import { chmod, mkdir as mkdir2, readFile as readFile3, rename, rm as rm3, statfs, writeFile as writeFile2 } from "node:fs/promises";
51666
51659
  import { cpus, homedir as homedir2, hostname as hostname3, platform, totalmem, tmpdir } from "node:os";
51667
51660
  import path4 from "node:path";
51668
51661
  import { setTimeout as sleep2 } from "node:timers/promises";
@@ -51917,6 +51910,8 @@ var RUNNER_AICOS_TURN_TOOLS = [
51917
51910
  async function runRunnerServe(options) {
51918
51911
  const env = options.env ?? process.env;
51919
51912
  const fetchImpl = options.fetchImpl ?? fetch;
51913
+ const cliVersion = await readCliVersion();
51914
+ const homeDir = options.homeDir ?? homedir2();
51920
51915
  let config2;
51921
51916
  try {
51922
51917
  config2 = parseServeArgs(options.args, options.appUrl, env);
@@ -51955,13 +51950,13 @@ ${usage()}
51955
51950
  let failed = false;
51956
51951
  let activeSessions = 0;
51957
51952
  do {
51958
- const detectedCapabilities = await detectCapabilities();
51953
+ const detectedCapabilities = await detectCapabilities(cliVersion, env, homeDir);
51959
51954
  const capabilities = capabilitiesForConfiguredRuntime(detectedCapabilities, config2.runtime);
51960
51955
  const localRuntime = config2.execute ? effectiveExecutionRuntime(config2.runtime, capabilities) : null;
51961
51956
  try {
51962
51957
  const heartbeat = await post2(fetchImpl, options.appUrl, "/api/runner/heartbeat", {
51963
51958
  capabilities,
51964
- telemetry: detectTelemetry(capabilities, env, activeSessions)
51959
+ telemetry: detectTelemetry(capabilities, env, activeSessions, cliVersion)
51965
51960
  }, state.runner_secret);
51966
51961
  if (heartbeat.status !== 200) {
51967
51962
  options.io.stderr.write(`heartbeat ${heartbeat.status}: ${redactForLog(JSON.stringify(heartbeat.json))}
@@ -52008,17 +52003,28 @@ async function waitForNextHeartbeat(fetchImpl, appUrl2, state, config2, io, runt
52008
52003
  }
52009
52004
  }
52010
52005
  }
52011
- function detectTelemetry(capabilities, env, activeSessions) {
52012
- const accountAlias = (env.RUNNER_MODEL_ACCOUNT_ALIAS ?? env.ROST_RUNNER_MODEL_ACCOUNT_ALIAS ?? "").trim() || "default";
52006
+ function resolveAccountAlias(env) {
52007
+ return (env.RUNNER_MODEL_ACCOUNT_ALIAS ?? env.ROST_RUNNER_MODEL_ACCOUNT_ALIAS ?? "").trim() || "default";
52008
+ }
52009
+ function capabilitiesForAnalytics(capabilities) {
52010
+ return {
52011
+ ...capabilities,
52012
+ claude: { ...capabilities.claude, account_alias: null },
52013
+ codex: { ...capabilities.codex, account_alias: null }
52014
+ };
52015
+ }
52016
+ function detectTelemetry(capabilities, env, activeSessions, cliVersion) {
52013
52017
  const usageState = env.RUNNER_MODEL_ACCOUNT_STATE ?? env.ROST_RUNNER_MODEL_ACCOUNT_STATE ?? "unknown";
52014
52018
  return {
52015
52019
  os: platform(),
52016
52020
  cpu_count: cpus().length,
52017
52021
  memory_mb: Math.round(totalmem() / (1024 * 1024)),
52018
- runner_version: env.npm_package_version ?? null,
52022
+ // DER-1319: sourced from the bundled package.json, not env.npm_package_version (undefined
52023
+ // under launchd — prod runners were silently reporting a null version).
52024
+ runner_version: cliVersion,
52019
52025
  active_sessions: activeSessions,
52020
- installed_runtimes: capabilities,
52021
- account_alias: accountAlias,
52026
+ installed_runtimes: capabilitiesForAnalytics(capabilities),
52027
+ account_alias: resolveAccountAlias(env),
52022
52028
  usage_limit_observation: {
52023
52029
  state: usageState,
52024
52030
  source: "runner_env_or_unknown"
@@ -52180,7 +52186,7 @@ async function pairIfNeeded(client, fetchImpl, appUrl2, config2, io) {
52180
52186
  }
52181
52187
  async function loadState(filePath, expectedTenantId) {
52182
52188
  try {
52183
- const parsed = JSON.parse(await readFile4(filePath, "utf8"));
52189
+ const parsed = JSON.parse(await readFile3(filePath, "utf8"));
52184
52190
  if (typeof parsed.runner_id === "string" && typeof parsed.runner_secret === "string") {
52185
52191
  if (expectedTenantId && parsed.tenant_id !== expectedTenantId) {
52186
52192
  return null;
@@ -52231,9 +52237,25 @@ async function startPairing(client, config2) {
52231
52237
  }
52232
52238
  return userCode;
52233
52239
  }
52234
- async function detectCapabilities() {
52235
- const [claude, codex] = await Promise.all([probe("claude"), probe("codex")]);
52236
- return { claude, codex, turn_executions: { report_supported: true } };
52240
+ async function detectCapabilities(cliVersion, env, homeDir) {
52241
+ const [claude, codex, git, gh, forgeDiskFreeMb] = await Promise.all([
52242
+ probe("claude"),
52243
+ probe("codex"),
52244
+ probeGit(),
52245
+ probeGh(),
52246
+ probeForgeDiskFreeMb(homeDir)
52247
+ ]);
52248
+ const accountAlias = resolveAccountAlias(env);
52249
+ return {
52250
+ claude: { ...claude, account_alias: accountAlias, rate_limited_until: null },
52251
+ codex: { ...codex, account_alias: accountAlias, rate_limited_until: null },
52252
+ turn_executions: { report_supported: true },
52253
+ ...cliVersion ? { forge_build: cliVersion } : {},
52254
+ git,
52255
+ gh,
52256
+ scheduler: { max_parallel_sessions_estimate: null },
52257
+ host: { forge_disk_free_mb: forgeDiskFreeMb }
52258
+ };
52237
52259
  }
52238
52260
  async function probe(command) {
52239
52261
  try {
@@ -52243,6 +52265,43 @@ async function probe(command) {
52243
52265
  return { installed: false, version: null, auth_state: "unknown" };
52244
52266
  }
52245
52267
  }
52268
+ async function probeGit() {
52269
+ try {
52270
+ const { stdout, stderr } = await execFile3("git", ["--version"], { timeout: 1500 });
52271
+ const raw = (stdout || stderr).trim();
52272
+ return { installed: true, version: /(\d+\.\d+(?:\.\d+)?)/.exec(raw)?.[1] ?? (raw || null) };
52273
+ } catch {
52274
+ return { installed: false, version: null };
52275
+ }
52276
+ }
52277
+ async function probeGh() {
52278
+ try {
52279
+ const { stdout, stderr } = await execFile3("gh", ["--version"], { timeout: 1500 });
52280
+ const raw = (stdout || stderr).trim().split("\n")[0]?.trim() ?? "";
52281
+ const authenticated = await probeGhAuth();
52282
+ return { installed: true, version: /(\d+\.\d+\.\d+)/.exec(raw)?.[1] ?? (raw || null), authenticated };
52283
+ } catch {
52284
+ return { installed: false, version: null, authenticated: false };
52285
+ }
52286
+ }
52287
+ async function probeGhAuth() {
52288
+ try {
52289
+ await execFile3("gh", ["auth", "status"], { timeout: 1500 });
52290
+ return true;
52291
+ } catch {
52292
+ return false;
52293
+ }
52294
+ }
52295
+ async function probeForgeDiskFreeMb(homeDir) {
52296
+ const dir = path4.join(homeDir, ".rost", "forge");
52297
+ try {
52298
+ await mkdir2(dir, { recursive: true, mode: 448 });
52299
+ const stats = await statfs(dir);
52300
+ return Math.floor(stats.bavail * stats.bsize / (1024 * 1024));
52301
+ } catch {
52302
+ return null;
52303
+ }
52304
+ }
52246
52305
  async function post2(fetchImpl, appUrl2, pathName, body, token) {
52247
52306
  const headers = { "content-type": "application/json" };
52248
52307
  if (token) {
@@ -52568,7 +52627,7 @@ function usage() {
52568
52627
  // src/runner-service.ts
52569
52628
  import { execFile as execFileCallback4 } from "node:child_process";
52570
52629
  import { realpathSync as realpathSync2 } from "node:fs";
52571
- import { access as access2, mkdir as mkdir3, readFile as readFile5, rm as rm4, writeFile as writeFile3 } from "node:fs/promises";
52630
+ import { access as access2, mkdir as mkdir3, readFile as readFile4, rm as rm4, writeFile as writeFile3 } from "node:fs/promises";
52572
52631
  import { homedir as homedir3 } from "node:os";
52573
52632
  import path5 from "node:path";
52574
52633
  import { promisify as promisify4 } from "node:util";
@@ -53121,7 +53180,7 @@ async function fileExists(file2) {
53121
53180
  }
53122
53181
  async function readTail(file2, maxBytes) {
53123
53182
  try {
53124
- const content = await readFile5(file2, "utf8");
53183
+ const content = await readFile4(file2, "utf8");
53125
53184
  return content.length > maxBytes ? content.slice(content.length - maxBytes) : content;
53126
53185
  } catch {
53127
53186
  return null;