From b8dc697de8be860b2e6d194c3e194e4316c06e56 Mon Sep 17 00:00:00 2001 From: Carlos Villela Date: Tue, 24 Mar 2026 23:25:27 -0700 Subject: [PATCH 1/3] chore: add cyclomatic complexity rule (ratchet from 95) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add ESLint complexity rule to bin/ and scripts/ to prevent new functions from accumulating excessive branching. Starting threshold is 95 (current worst offender: setupNim in onboard.js). Ratchet plan: 95 → 40 → 25 → 15. Co-Authored-By: Claude Opus 4.6 (1M context) --- eslint.config.mjs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/eslint.config.mjs b/eslint.config.mjs index 4c2856dbc..fcfd7e9a1 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -39,6 +39,9 @@ export default [ rules: { ...js.configs.recommended.rules, "no-unused-vars": ["error", { argsIgnorePattern: "^_", varsIgnorePattern: "^_", caughtErrorsIgnorePattern: "^_" }], + // Cyclomatic complexity — ratchet down as we refactor: + // 95 (current) → 40 → 25 → 15 + "complexity": ["error", { max: 95 }], }, }, From 4bfe9db06d744fa36ffa987f256771991720015e Mon Sep 17 00:00:00 2001 From: Carlos Villela Date: Tue, 24 Mar 2026 23:27:45 -0700 Subject: [PATCH 2/3] chore: ratchet complexity to 20, suppress existing violations Suppress 6 functions that exceed the threshold with eslint-disable comments so we can start enforcing at 20 instead of 95: - setupNim (95), setupPolicies (41), setupInference (22) in onboard.js - deploy (22), main IIFE (27) in nemoclaw.js - applyPreset (24) in policies.js Co-Authored-By: Claude Opus 4.6 (1M context) --- bin/lib/onboard.js | 3 +++ bin/lib/policies.js | 1 + bin/nemoclaw.js | 2 ++ eslint.config.mjs | 5 ++--- 4 files changed, 8 insertions(+), 3 deletions(-) diff --git a/bin/lib/onboard.js b/bin/lib/onboard.js index 48a4cb241..1789e857f 100644 --- a/bin/lib/onboard.js +++ b/bin/lib/onboard.js @@ -1515,6 +1515,7 @@ async function createSandbox(gpu, model, provider, preferredInferenceApi = null) // ── Step 4: NIM ────────────────────────────────────────────────── +// eslint-disable-next-line complexity async function setupNim(gpu) { step(2, 7, "Configuring inference (NIM)"); @@ -1915,6 +1916,7 @@ async function setupNim(gpu) { // ── Step 5: Inference provider ─────────────────────────────────── +// eslint-disable-next-line complexity async function setupInference(sandboxName, model, provider, endpointUrl = null, credentialEnv = null) { step(4, 7, "Setting up inference provider"); runOpenshell(["gateway", "select", GATEWAY_NAME], { ignoreError: true }); @@ -1998,6 +2000,7 @@ async function setupOpenclaw(sandboxName, model, provider) { // ── Step 7: Policy presets ─────────────────────────────────────── +// eslint-disable-next-line complexity async function setupPolicies(sandboxName) { step(7, 7, "Policy presets"); diff --git a/bin/lib/policies.js b/bin/lib/policies.js index 75704a9a0..21b1f319d 100644 --- a/bin/lib/policies.js +++ b/bin/lib/policies.js @@ -93,6 +93,7 @@ function buildPolicyGetCommand(sandboxName) { return `${getOpenshellCommand()} policy get --full ${shellQuote(sandboxName)} 2>/dev/null`; } +// eslint-disable-next-line complexity function applyPreset(sandboxName, presetName) { // Guard against truncated sandbox names — WSL can truncate hyphenated // names during argument parsing, e.g. "my-assistant" → "m" diff --git a/bin/nemoclaw.js b/bin/nemoclaw.js index 737c59c16..a6a847c1f 100755 --- a/bin/nemoclaw.js +++ b/bin/nemoclaw.js @@ -100,6 +100,7 @@ async function setupSpark() { run(`sudo bash "${SCRIPTS}/setup-spark.sh"`); } +// eslint-disable-next-line complexity async function deploy(instanceName) { if (!instanceName) { console.error(" Usage: nemoclaw deploy "); @@ -445,6 +446,7 @@ function help() { const [cmd, ...args] = process.argv.slice(2); +// eslint-disable-next-line complexity (async () => { // No command → help if (!cmd || cmd === "help" || cmd === "--help" || cmd === "-h") { diff --git a/eslint.config.mjs b/eslint.config.mjs index fcfd7e9a1..b6b9b8aa5 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -39,9 +39,8 @@ export default [ rules: { ...js.configs.recommended.rules, "no-unused-vars": ["error", { argsIgnorePattern: "^_", varsIgnorePattern: "^_", caughtErrorsIgnorePattern: "^_" }], - // Cyclomatic complexity — ratchet down as we refactor: - // 95 (current) → 40 → 25 → 15 - "complexity": ["error", { max: 95 }], + // Cyclomatic complexity — ratchet down to 15 as we refactor suppressed functions + "complexity": ["error", { max: 20 }], }, }, From 8c49ce7dda8128ee912e40f4a8ffcb998617c584 Mon Sep 17 00:00:00 2001 From: Carlos Villela Date: Thu, 26 Mar 2026 08:36:58 -0700 Subject: [PATCH 3/3] chore: suppress complexity for 3 missed functions preflight (23), getReconciledSandboxGatewayState (25), sandboxStatus (27) --- bin/lib/onboard.js | 1 + bin/nemoclaw.js | 2 ++ 2 files changed, 3 insertions(+) diff --git a/bin/lib/onboard.js b/bin/lib/onboard.js index 90643e668..955894113 100644 --- a/bin/lib/onboard.js +++ b/bin/lib/onboard.js @@ -1216,6 +1216,7 @@ function getNonInteractiveModel(providerKey) { // ── Step 1: Preflight ──────────────────────────────────────────── +// eslint-disable-next-line complexity async function preflight() { step(1, 7, "Preflight checks"); diff --git a/bin/nemoclaw.js b/bin/nemoclaw.js index bcd11f3ee..b070b7e9a 100755 --- a/bin/nemoclaw.js +++ b/bin/nemoclaw.js @@ -201,6 +201,7 @@ function printGatewayLifecycleHint(output = "", sandboxName = "", writer = conso } } +// eslint-disable-next-line complexity async function getReconciledSandboxGatewayState(sandboxName) { let lookup = getSandboxGatewayState(sandboxName); if (lookup.state === "present") { @@ -570,6 +571,7 @@ async function sandboxConnect(sandboxName) { exitWithSpawnResult(result); } +// eslint-disable-next-line complexity async function sandboxStatus(sandboxName) { const sb = registry.getSandbox(sandboxName); const live = parseGatewayInference(