@gluecharm-lab/easyspecs-cli 0.0.27 → 0.0.28

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/commands.md CHANGED
@@ -68,9 +68,11 @@ Environment (stderr styling): `**NO_COLOR`** (any non-empty value) disables ANSI
68
68
 
69
69
  ---
70
70
 
71
- ## Workstation host inventory (**SRS-64** / **SRS-62**)
71
+ ## Workstation host inventory (**SRS-69** / **SRS-62**)
72
72
 
73
- `**easyspecs-cli workstation info**` prints the CPU count used for the **SRS-64 §4.1** heuristic, total installed RAM, **`N_sys`** (JSON key **`maxSystemConcurrentAiWorkstations`**), and **`hostHardMaxConcurrentAi`** = **`min(N_sys, 64)`** (product agent ceiling per **SRS-62**). **macOS** (`darwin`) and **Linux** only; on other platforms the CLI exits **non-zero**, writes a short message to stderr, and does **not** print JSON on stdout (even if **`--json`** was passed).
73
+ `**easyspecs-cli workstation info**` prints the CPU count used for the **SRS-69 §4** heuristic, total installed RAM, **`N_sys`** (JSON key **`maxSystemConcurrentAiWorkstations`**), and **`hostHardMaxConcurrentAi`** = **`min(N_sys, 64)`** (product agent ceiling per **SRS-62**). **macOS** (`darwin`) and **Linux** only; on other platforms the CLI exits **non-zero**, writes a short message to stderr, and does **not** print JSON on stdout (even if **`--json`** was passed).
74
+
75
+ **Formula (SRS-69 §4 — supersedes SRS-64 §4.1):** `N_float = min(P, R_GiB / 8)` where **`P`** is the physical CPU count and **`R_GiB`** is total installed RAM in GiB. Then **`N_sys = max(1, Math.round(N_float))`** and **`hostHardMax = min(64, N_sys)`**. In plain English: **one AI workstation per physical core, but never more than one per 8 GiB of installed RAM** — whichever dimension is tighter wins. **Worked example:** **`P=11, R=44 GiB → N_sys = 6 → hostHardMax = 6`** (was 100 under SRS-64). Operators on shared / interactive hosts (laptops also running an IDE + browser + chat apps) should set **`easyspecs.workstations.maxConcurrentAi`** *below* the reported `hostHardMax`. See live signals via **`[host-pool]`** / **`[host-pool-rec]`** (**SRS-68**).
74
76
 
75
77
  Use the **global** **`--json`** flag (before the subcommand) for one parseable summary line. JSON includes **`totalMemBytes`**, **`platform`**, **`cpusForCap`**, **`cpusForCapSource`**, **`physicalCpus`** (integer when physical cores are known, else **`null`**), **`maxSystemConcurrentAiWorkstations`**, and **`hostHardMaxConcurrentAi`**.
76
78
 
@@ -83,7 +85,7 @@ When Analysis (or other callers) passes a **`diagnosticLog`** sink into the exte
83
85
  - **`scope=host`** — machine-wide **RAM** (**total** / **free** / **used** bytes) plus **1-minute load average**, logical **CPU** count, and **load / CPUs** (not the same metric as the **SRS-62** runtime pool **CPU guard** — see **[SRS-65](../../.gluecharm/docs/srs/srs-65.md)**).
84
86
  - **`scope=child`** — once per run: **child CPU time** (milliseconds) and **RSS** bytes for that **PID** (**Linux**: **`/proc`**, **macOS**: **`ps`**), or **`childRssBytes=unknown`** on unsupported platforms / read errors.
85
87
 
86
- Tune concurrent agents with **`easyspecs.workstations.maxConcurrentAi`**, **`applyHostConcurrencyCap`**, and **`easyspecs-cli workstation info`** (**SRS-62** / **SRS-64**); these lines help interpret **live** pressure alongside that configuration.
88
+ Tune concurrent agents with **`easyspecs.workstations.maxConcurrentAi`**, **`applyHostConcurrencyCap`**, and **`easyspecs-cli workstation info`** (**SRS-62** / **SRS-69**); these lines help interpret **live** pressure alongside that configuration.
87
89
 
88
90
  ### Workstation pool host pressure (**SRS-68**)
89
91
 
package/dist/main.cjs CHANGED
@@ -10707,7 +10707,7 @@ function createEasyspecsCliProgram() {
10707
10707
  program2.command("help").description("Show help");
10708
10708
  program2.command("version").description("Print CLI version");
10709
10709
  const workstation = program2.command("workstation").description("Host inventory for AI workstation sizing");
10710
- workstation.command("info").description("Print CPU, RAM, and SRS-64 N_sys (macOS and Linux only; use global --json)").allowUnknownOption(false);
10710
+ workstation.command("info").description("Print CPU, RAM, and SRS-69 N_sys (macOS and Linux only; use global --json)").allowUnknownOption(false);
10711
10711
  program2.command("doctor").description("Check readiness and/or inspect configuration").option("--readiness", "Print readiness summary (default)").option("--inspect-config", "Print redacted merged configuration");
10712
10712
  const auth = program2.command("auth").description("Authentication");
10713
10713
  auth.command("login").description("Log in").option("--email <email>", "Email address").option("--password <password>", "Password").option("--session-path <path>", "Session JSON path override for this run").option("--ci", "Use easyspecs.auth.ciLogin from config when argv credentials are omitted");
@@ -11245,6 +11245,8 @@ var import_node_child_process2 = require("node:child_process");
11245
11245
  var ABSOLUTE_MAX_CONCURRENT_AI = 64;
11246
11246
 
11247
11247
  // src/config/machineConcurrentAiFromHost.ts
11248
+ var AGENTS_PER_PHYSICAL_CORE = 1;
11249
+ var RAM_GIB_PER_AGENT = 8;
11248
11250
  function clampProductConcurrentLimits(n) {
11249
11251
  if (!Number.isFinite(n)) {
11250
11252
  return DEFAULT_MAX_CONCURRENT_AI;
@@ -11261,13 +11263,9 @@ function machineConcurrentAiCapFromHost(profile) {
11261
11263
  if (!Number.isFinite(rGib) || rGib <= 0) {
11262
11264
  return 1;
11263
11265
  }
11264
- let nCpuFloat;
11265
- if (p <= 11) {
11266
- nCpuFloat = 15 + 8.5 * (p - 1);
11267
- } else {
11268
- nCpuFloat = 100 + 8.5 * (p - 11);
11269
- }
11270
- const ramFactor = Math.min(1, rGib / (4 * p));
11266
+ const nCpuFloat = AGENTS_PER_PHYSICAL_CORE * p;
11267
+ const ramRefGib = RAM_GIB_PER_AGENT * p;
11268
+ const ramFactor = Math.min(1, rGib / ramRefGib);
11271
11269
  const nFloat = nCpuFloat * ramFactor;
11272
11270
  const rounded = Math.round(nFloat);
11273
11271
  return Math.max(1, rounded);
@@ -28397,7 +28395,7 @@ function formatCliStderrLine(line, useAnsi) {
28397
28395
  }
28398
28396
 
28399
28397
  // src/cli/main.ts
28400
- var PKG_VERSION = "0.0.27";
28398
+ var PKG_VERSION = "0.0.28";
28401
28399
  function isNonEmptyFactoryFailureArray(x) {
28402
28400
  if (!Array.isArray(x) || x.length === 0) {
28403
28401
  return false;