From e2fc693bf1a7ff07972884c8bfe59293ad54fe37 Mon Sep 17 00:00:00 2001 From: Carlos Villela Date: Thu, 9 Apr 2026 15:15:01 -0700 Subject: [PATCH 1/4] refactor(cli): remove legacy bin lib shims Signed-off-by: Carlos Villela --- .../nemoclaw-maintainer-day/RISKY-AREAS.md | 2 +- AGENTS.md | 14 +- CONTRIBUTING.md | 2 +- bin/lib/chat-filter.js | 7 - bin/lib/config-io.js | 7 - bin/lib/debug.js | 4 - bin/lib/inference-config.js | 7 - bin/lib/local-inference.js | 7 - bin/lib/nim.js | 7 - bin/lib/onboard-session.js | 7 - bin/lib/onboard.js | 65 ----- bin/lib/platform.js | 4 - bin/lib/policies.js | 18 -- bin/lib/preflight.js | 7 - bin/lib/registry.js | 7 - bin/lib/resolve-openshell.js | 7 - bin/lib/runner.js | 16 -- bin/lib/runtime-recovery.js | 7 - bin/lib/sandbox-build-context.js | 4 - bin/lib/services.js | 5 - bin/lib/version.js | 7 - package.json | 1 + scripts/benchmark-sandbox-image-build.js | 2 +- scripts/debug.sh | 2 +- src/lib/debug.ts | 2 +- src/lib/local-inference.ts | 2 +- src/lib/model-prompts.test.ts | 2 +- src/lib/model-prompts.ts | 4 +- src/lib/nim.test.ts | 2 +- src/lib/nim.ts | 2 +- src/lib/onboard-session.test.ts | 4 - src/lib/onboard.ts | 53 ++-- src/lib/preflight.ts | 4 +- src/lib/provider-models.test.ts | 2 +- src/lib/provider-models.ts | 4 +- src/lib/usage-notice.ts | 2 +- src/nemoclaw.ts | 38 +-- test/credentials.test.ts | 6 +- .../04-nemoclaw-openshell-status-parity.sh | 2 +- test/e2e/test-onboard-repair.sh | 2 +- test/e2e/test-onboard-resume.sh | 2 +- test/e2e/test-telegram-injection.sh | 6 +- test/onboard-readiness.test.ts | 4 +- test/onboard-selection.test.ts | 178 ++++++------- test/onboard.test.ts | 250 +++++++++--------- test/platform.test.ts | 2 +- test/policies.test.ts | 8 +- test/presets-checkbox.test.ts | 4 +- test/registry.test.ts | 4 +- test/resolve-openshell.test.ts | 2 +- test/runner.test.ts | 4 +- test/sandbox-build-context.test.ts | 2 +- test/service-env.test.ts | 4 +- test/ssh-known-hosts.test.ts | 2 +- 54 files changed, 311 insertions(+), 508 deletions(-) delete mode 100644 bin/lib/chat-filter.js delete mode 100644 bin/lib/config-io.js delete mode 100644 bin/lib/debug.js delete mode 100644 bin/lib/inference-config.js delete mode 100644 bin/lib/local-inference.js delete mode 100644 bin/lib/nim.js delete mode 100644 bin/lib/onboard-session.js delete mode 100644 bin/lib/onboard.js delete mode 100644 bin/lib/platform.js delete mode 100644 bin/lib/policies.js delete mode 100644 bin/lib/preflight.js delete mode 100644 bin/lib/registry.js delete mode 100644 bin/lib/resolve-openshell.js delete mode 100644 bin/lib/runner.js delete mode 100644 bin/lib/runtime-recovery.js delete mode 100644 bin/lib/sandbox-build-context.js delete mode 100644 bin/lib/services.js delete mode 100644 bin/lib/version.js diff --git a/.agents/skills/nemoclaw-maintainer-day/RISKY-AREAS.md b/.agents/skills/nemoclaw-maintainer-day/RISKY-AREAS.md index f22431d3f17..fa114b52b9a 100644 --- a/.agents/skills/nemoclaw-maintainer-day/RISKY-AREAS.md +++ b/.agents/skills/nemoclaw-maintainer-day/RISKY-AREAS.md @@ -5,7 +5,7 @@ PRs touching these areas need tests before approval. | Area | Key paths | |------|-----------| | Installer / bootstrap shell | `install.sh`, `setup.sh`, `brev-setup.sh`, `scripts/*.sh` | -| Onboarding / host glue | `bin/lib/onboard.js`, `bin/*.js` | +| Onboarding / host glue | `src/lib/onboard.ts`, `bin/nemoclaw.js`, `scripts/*.sh` | | Sandbox / policy / SSRF | `nemoclaw/src/blueprint/`, `nemoclaw-blueprint/`, policy presets | | Workflow / enforcement | `.github/workflows/`, prek hooks, DCO, signing, version/tag flows | | Credentials / inference / network | credential helpers, inference provider routing, approval flows | diff --git a/AGENTS.md b/AGENTS.md index 7289ed531bb..82099073f85 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -14,8 +14,8 @@ This repo ships agent skills under `.agents/skills/`, organized into three audie | Path | Language | Purpose | |------|----------|---------| -| `bin/` | JavaScript (CJS) | CLI entry point (`nemoclaw.js`) and library modules | -| `bin/lib/` | JavaScript (CJS) | Core CLI logic: onboard, credentials, inference, policies, preflight, runner | +| `bin/` | JavaScript (CJS) | CLI launcher (`nemoclaw.js`) and small compatibility helpers | +| `src/lib/` | TypeScript | Core CLI logic: onboard, credentials, inference, policies, preflight, runner | | `nemoclaw/` | TypeScript | Plugin project (Commander CLI extension for OpenClaw) | | `nemoclaw/src/blueprint/` | TypeScript | Runner, snapshot, SSRF validation, state management | | `nemoclaw/src/commands/` | TypeScript | Slash commands, migration state | @@ -47,12 +47,12 @@ This repo ships agent skills under `.agents/skills/`, organized into three audie ### Dual-Language Stack -- **CLI and plugin**: JavaScript (CJS in `bin/`, ESM in `test/`) and TypeScript (`nemoclaw/src/`) +- **CLI and plugin**: TypeScript (`src/`, `nemoclaw/src/`) with a small CommonJS launcher in `bin/`; ESM in `test/` - **Blueprint**: YAML configuration (`nemoclaw-blueprint/`) - **Docs**: Sphinx/MyST Markdown - **Tooling scripts**: Bash and Python -The `bin/` directory uses CommonJS intentionally — it's the CLI entry point that must work without a build step. The `nemoclaw/` plugin uses TypeScript and requires compilation. +The `bin/` directory uses CommonJS intentionally for the launcher and a few compatibility helpers so the CLI still has a stable executable entry point. The main CLI implementation lives in `src/` and compiles to `dist/`. The `nemoclaw/` plugin uses TypeScript and requires compilation. ### Testing Strategy @@ -105,7 +105,7 @@ For shell scripts use `#` comments. For Markdown use HTML comments. ### JavaScript -- `bin/` and `scripts/`: **CommonJS** (`require`/`module.exports`), Node.js 22.16+ +- `bin/` launcher and remaining `scripts/*.js`: **CommonJS** (`require`/`module.exports`), Node.js 22.16+ - `test/`: **ESM** (`import`/`export`) - ESLint config in `eslint.config.mjs` - Cyclomatic complexity limit: 20 (ratcheting down to 15) @@ -149,8 +149,8 @@ All hooks managed by [prek](https://prek.j178.dev/) (installed via `npm install` **Adding a CLI command:** -- Entry point: `bin/nemoclaw.js` (routes to `bin/lib/` modules) -- Keep `bin/lib/` modules as CommonJS +- Entry point: `bin/nemoclaw.js` (launches the compiled CLI in `dist/`) +- Main CLI implementation lives in `src/lib/` and compiles to `dist/lib/` - Add tests in `test/` **Adding a plugin feature:** diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 22fc7fab24a..3af1c82c7f7 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -113,7 +113,7 @@ The repository is organized as follows. All new source files must be TypeScript. Do not add new `.js` files to the project. When modifying an existing JavaScript file, prefer migrating it to TypeScript in the same PR. -Existing JavaScript in `bin/` and `scripts/` is being incrementally migrated (see `src/lib/` for completed migrations). Tests in `test/` may remain ESM JavaScript for now but new test files should use TypeScript where practical. +Only a small CommonJS launcher/compatibility layer remains in `bin/`, while the main CLI implementation now lives in `src/lib/` and compiles to `dist/`. Tests in `test/` may remain ESM JavaScript for now but new test files should use TypeScript where practical. Shell scripts (`scripts/*.sh`) must pass ShellCheck and use `shfmt` formatting. diff --git a/bin/lib/chat-filter.js b/bin/lib/chat-filter.js deleted file mode 100644 index b6f63bc46ec..00000000000 --- a/bin/lib/chat-filter.js +++ /dev/null @@ -1,7 +0,0 @@ -// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. -// SPDX-License-Identifier: Apache-2.0 -// -// Thin re-export shim — the implementation lives in src/lib/chat-filter.ts, -// compiled to dist/lib/chat-filter.js. - -module.exports = require("../../dist/lib/chat-filter"); diff --git a/bin/lib/config-io.js b/bin/lib/config-io.js deleted file mode 100644 index e2361d3cf72..00000000000 --- a/bin/lib/config-io.js +++ /dev/null @@ -1,7 +0,0 @@ -// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. -// SPDX-License-Identifier: Apache-2.0 -// -// Thin re-export shim — the implementation lives in src/lib/config-io.ts, -// compiled to dist/lib/config-io.js. - -module.exports = require("../../dist/lib/config-io"); diff --git a/bin/lib/debug.js b/bin/lib/debug.js deleted file mode 100644 index 5465b8042d0..00000000000 --- a/bin/lib/debug.js +++ /dev/null @@ -1,4 +0,0 @@ -// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. -// SPDX-License-Identifier: Apache-2.0 - -module.exports = require("../../dist/lib/debug"); diff --git a/bin/lib/inference-config.js b/bin/lib/inference-config.js deleted file mode 100644 index 7e8faf29262..00000000000 --- a/bin/lib/inference-config.js +++ /dev/null @@ -1,7 +0,0 @@ -// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. -// SPDX-License-Identifier: Apache-2.0 -// -// Thin re-export shim — the implementation lives in src/lib/inference-config.ts, -// compiled to dist/lib/inference-config.js. - -module.exports = require("../../dist/lib/inference-config"); diff --git a/bin/lib/local-inference.js b/bin/lib/local-inference.js deleted file mode 100644 index 2aa20015320..00000000000 --- a/bin/lib/local-inference.js +++ /dev/null @@ -1,7 +0,0 @@ -// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. -// SPDX-License-Identifier: Apache-2.0 -// -// Thin re-export shim — the implementation lives in src/lib/local-inference.ts, -// compiled to dist/lib/local-inference.js. - -module.exports = require("../../dist/lib/local-inference"); diff --git a/bin/lib/nim.js b/bin/lib/nim.js deleted file mode 100644 index 8da7757011b..00000000000 --- a/bin/lib/nim.js +++ /dev/null @@ -1,7 +0,0 @@ -// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. -// SPDX-License-Identifier: Apache-2.0 -// -// Thin re-export shim — the implementation lives in src/lib/nim.ts, -// compiled to dist/lib/nim.js. - -module.exports = require("../../dist/lib/nim"); diff --git a/bin/lib/onboard-session.js b/bin/lib/onboard-session.js deleted file mode 100644 index 989a1b09dde..00000000000 --- a/bin/lib/onboard-session.js +++ /dev/null @@ -1,7 +0,0 @@ -// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. -// SPDX-License-Identifier: Apache-2.0 -// -// Thin re-export shim — the implementation lives in src/lib/onboard-session.ts, -// compiled to dist/lib/onboard-session.js. - -module.exports = require("../../dist/lib/onboard-session"); diff --git a/bin/lib/onboard.js b/bin/lib/onboard.js deleted file mode 100644 index f02ff14e207..00000000000 --- a/bin/lib/onboard.js +++ /dev/null @@ -1,65 +0,0 @@ -// @ts-nocheck -// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. -// SPDX-License-Identifier: Apache-2.0 - -const mod = require("../../dist/lib/onboard"); -module.exports = { - buildProviderArgs: mod.buildProviderArgs, - buildSandboxConfigSyncScript: mod.buildSandboxConfigSyncScript, - compactText: mod.compactText, - copyBuildContextDir: mod.copyBuildContextDir, - classifySandboxCreateFailure: mod.classifySandboxCreateFailure, - createSandbox: mod.createSandbox, - formatEnvAssignment: mod.formatEnvAssignment, - getFutureShellPathHint: mod.getFutureShellPathHint, - getGatewayStartEnv: mod.getGatewayStartEnv, - getGatewayReuseState: mod.getGatewayReuseState, - getNavigationChoice: mod.getNavigationChoice, - getSandboxInferenceConfig: mod.getSandboxInferenceConfig, - getInstalledOpenshellVersion: mod.getInstalledOpenshellVersion, - getBlueprintMinOpenshellVersion: mod.getBlueprintMinOpenshellVersion, - versionGte: mod.versionGte, - getRequestedModelHint: mod.getRequestedModelHint, - getRequestedProviderHint: mod.getRequestedProviderHint, - getStableGatewayImageRef: mod.getStableGatewayImageRef, - getResumeConfigConflicts: mod.getResumeConfigConflicts, - isGatewayHealthy: mod.isGatewayHealthy, - hasStaleGateway: mod.hasStaleGateway, - getRequestedSandboxNameHint: mod.getRequestedSandboxNameHint, - getResumeSandboxConflict: mod.getResumeSandboxConflict, - getSandboxReuseState: mod.getSandboxReuseState, - getSandboxStateFromOutputs: mod.getSandboxStateFromOutputs, - getPortConflictServiceHints: mod.getPortConflictServiceHints, - classifyValidationFailure: mod.classifyValidationFailure, - isSandboxReady: mod.isSandboxReady, - isLoopbackHostname: mod.isLoopbackHostname, - normalizeProviderBaseUrl: mod.normalizeProviderBaseUrl, - onboard: mod.onboard, - onboardSession: mod.onboardSession, - printSandboxCreateRecoveryHints: mod.printSandboxCreateRecoveryHints, - providerExistsInGateway: mod.providerExistsInGateway, - parsePolicyPresetEnv: mod.parsePolicyPresetEnv, - pruneStaleSandboxEntry: mod.pruneStaleSandboxEntry, - repairRecordedSandbox: mod.repairRecordedSandbox, - recoverGatewayRuntime: mod.recoverGatewayRuntime, - resolveDashboardForwardTarget: mod.resolveDashboardForwardTarget, - startGatewayForRecovery: mod.startGatewayForRecovery, - runCaptureOpenshell: mod.runCaptureOpenshell, - setupInference: mod.setupInference, - setupMessagingChannels: mod.setupMessagingChannels, - setupNim: mod.setupNim, - isInferenceRouteReady: mod.isInferenceRouteReady, - isOpenclawReady: mod.isOpenclawReady, - arePolicyPresetsApplied: mod.arePolicyPresetsApplied, - presetsCheckboxSelector: mod.presetsCheckboxSelector, - setupPoliciesWithSelection: mod.setupPoliciesWithSelection, - summarizeCurlFailure: mod.summarizeCurlFailure, - summarizeProbeFailure: mod.summarizeProbeFailure, - hasResponsesToolCall: mod.hasResponsesToolCall, - upsertProvider: mod.upsertProvider, - hydrateCredentialEnv: mod.hydrateCredentialEnv, - pruneKnownHostsEntries: mod.pruneKnownHostsEntries, - shouldIncludeBuildContextPath: mod.shouldIncludeBuildContextPath, - writeSandboxConfigSyncFile: mod.writeSandboxConfigSyncFile, - patchStagedDockerfile: mod.patchStagedDockerfile, -}; diff --git a/bin/lib/platform.js b/bin/lib/platform.js deleted file mode 100644 index c6a79eda7a3..00000000000 --- a/bin/lib/platform.js +++ /dev/null @@ -1,4 +0,0 @@ -// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. -// SPDX-License-Identifier: Apache-2.0 - -module.exports = require("../../dist/lib/platform"); diff --git a/bin/lib/policies.js b/bin/lib/policies.js deleted file mode 100644 index 9763f6ed17f..00000000000 --- a/bin/lib/policies.js +++ /dev/null @@ -1,18 +0,0 @@ -// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. -// SPDX-License-Identifier: Apache-2.0 - -const mod = require("../../dist/lib/policies"); -module.exports = { - PRESETS_DIR: mod.PRESETS_DIR, - listPresets: mod.listPresets, - loadPreset: mod.loadPreset, - getPresetEndpoints: mod.getPresetEndpoints, - extractPresetEntries: mod.extractPresetEntries, - parseCurrentPolicy: mod.parseCurrentPolicy, - buildPolicySetCommand: mod.buildPolicySetCommand, - buildPolicyGetCommand: mod.buildPolicyGetCommand, - mergePresetIntoPolicy: mod.mergePresetIntoPolicy, - applyPreset: mod.applyPreset, - getAppliedPresets: mod.getAppliedPresets, - selectFromList: mod.selectFromList, -}; diff --git a/bin/lib/preflight.js b/bin/lib/preflight.js deleted file mode 100644 index 69ade80867d..00000000000 --- a/bin/lib/preflight.js +++ /dev/null @@ -1,7 +0,0 @@ -// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. -// SPDX-License-Identifier: Apache-2.0 -// -// Thin re-export shim — the implementation lives in src/lib/preflight.ts, -// compiled to dist/lib/preflight.js. - -module.exports = require("../../dist/lib/preflight"); diff --git a/bin/lib/registry.js b/bin/lib/registry.js deleted file mode 100644 index 66ab30da602..00000000000 --- a/bin/lib/registry.js +++ /dev/null @@ -1,7 +0,0 @@ -// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. -// SPDX-License-Identifier: Apache-2.0 -// -// Thin re-export shim — the implementation lives in src/lib/registry.ts, -// compiled to dist/lib/registry.js. - -module.exports = require("../../dist/lib/registry"); diff --git a/bin/lib/resolve-openshell.js b/bin/lib/resolve-openshell.js deleted file mode 100644 index 69c63368946..00000000000 --- a/bin/lib/resolve-openshell.js +++ /dev/null @@ -1,7 +0,0 @@ -// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. -// SPDX-License-Identifier: Apache-2.0 -// -// Thin re-export shim — the implementation lives in src/lib/resolve-openshell.ts, -// compiled to dist/lib/resolve-openshell.js. - -module.exports = require("../../dist/lib/resolve-openshell"); diff --git a/bin/lib/runner.js b/bin/lib/runner.js deleted file mode 100644 index 52eb4982011..00000000000 --- a/bin/lib/runner.js +++ /dev/null @@ -1,16 +0,0 @@ -// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. -// SPDX-License-Identifier: Apache-2.0 - -const distPath = require.resolve("../../dist/lib/runner"); -delete require.cache[distPath]; -const mod = require(distPath); -module.exports = { - ROOT: mod.ROOT, - SCRIPTS: mod.SCRIPTS, - redact: mod.redact, - run: mod.run, - runCapture: mod.runCapture, - runInteractive: mod.runInteractive, - shellQuote: mod.shellQuote, - validateName: mod.validateName, -}; diff --git a/bin/lib/runtime-recovery.js b/bin/lib/runtime-recovery.js deleted file mode 100644 index 0f0346c7d12..00000000000 --- a/bin/lib/runtime-recovery.js +++ /dev/null @@ -1,7 +0,0 @@ -// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. -// SPDX-License-Identifier: Apache-2.0 -// -// Thin re-export shim — the implementation lives in src/lib/runtime-recovery.ts, -// compiled to dist/lib/runtime-recovery.js. - -module.exports = require("../../dist/lib/runtime-recovery"); diff --git a/bin/lib/sandbox-build-context.js b/bin/lib/sandbox-build-context.js deleted file mode 100644 index d3aeadcbe31..00000000000 --- a/bin/lib/sandbox-build-context.js +++ /dev/null @@ -1,4 +0,0 @@ -// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. -// SPDX-License-Identifier: Apache-2.0 - -module.exports = require("../../dist/lib/sandbox-build-context"); diff --git a/bin/lib/services.js b/bin/lib/services.js deleted file mode 100644 index 3defe2e406c..00000000000 --- a/bin/lib/services.js +++ /dev/null @@ -1,5 +0,0 @@ -// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. -// SPDX-License-Identifier: Apache-2.0 - -// Thin CJS shim — implementation lives in src/lib/services.ts -module.exports = require("../../dist/lib/services"); diff --git a/bin/lib/version.js b/bin/lib/version.js deleted file mode 100644 index eec57e81f78..00000000000 --- a/bin/lib/version.js +++ /dev/null @@ -1,7 +0,0 @@ -// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. -// SPDX-License-Identifier: Apache-2.0 -// -// Thin re-export shim — the implementation lives in src/lib/version.ts, -// compiled to dist/lib/version.js. - -module.exports = require("../../dist/lib/version"); diff --git a/package.json b/package.json index 229bb421627..20142d563a2 100644 --- a/package.json +++ b/package.json @@ -32,6 +32,7 @@ ], "files": [ "bin/", + "dist/", "nemoclaw/dist/", "nemoclaw/openclaw.plugin.json", "nemoclaw/package.json", diff --git a/scripts/benchmark-sandbox-image-build.js b/scripts/benchmark-sandbox-image-build.js index 6d7dbd712b6..332af919bf7 100755 --- a/scripts/benchmark-sandbox-image-build.js +++ b/scripts/benchmark-sandbox-image-build.js @@ -10,7 +10,7 @@ const { collectBuildContextStats, stageLegacySandboxBuildContext, stageOptimizedSandboxBuildContext, -} = require("../bin/lib/sandbox-build-context"); +} = require("../dist/lib/sandbox-build-context"); function parseArgs(argv) { const args = { diff --git a/scripts/debug.sh b/scripts/debug.sh index 78d128b1079..5539411f97d 100755 --- a/scripts/debug.sh +++ b/scripts/debug.sh @@ -118,7 +118,7 @@ SCRIPT_PATH="${BASH_SOURCE[0]:-}" if [ -n "$SCRIPT_PATH" ] && [ -f "$SCRIPT_PATH" ]; then SCRIPT_DIR="$(cd "$(dirname "$SCRIPT_PATH")" && pwd)" REPO_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)" - ONBOARD_SESSION_HELPER="${REPO_ROOT}/bin/lib/onboard-session.js" + ONBOARD_SESSION_HELPER="${REPO_ROOT}/dist/lib/onboard-session.js" fi # Redact known sensitive patterns (API keys, tokens, passwords in env/args). diff --git a/src/lib/debug.ts b/src/lib/debug.ts index 2ce3bd480d9..36661ee4ee7 100644 --- a/src/lib/debug.ts +++ b/src/lib/debug.ts @@ -377,7 +377,7 @@ function collectNetwork(collectDir: string): void { function collectOnboardSession(collectDir: string, repoDir: string): void { section("Onboard Session"); - const helperPath = join(repoDir, "bin", "lib", "onboard-session.js"); + const helperPath = join(repoDir, "dist", "lib", "onboard-session.js"); if (!existsSync(helperPath) || !commandExists("node")) { console.log(" (onboard session helper not available, skipping)"); return; diff --git a/src/lib/local-inference.ts b/src/lib/local-inference.ts index 9390bb70ebb..0ee28689645 100644 --- a/src/lib/local-inference.ts +++ b/src/lib/local-inference.ts @@ -7,7 +7,7 @@ */ // eslint-disable-next-line @typescript-eslint/no-require-imports -const { shellQuote } = require("../../bin/lib/runner"); +const { shellQuote } = require("./runner"); export const HOST_GATEWAY_URL = "http://host.openshell.internal"; export const CONTAINER_REACHABILITY_IMAGE = "curlimages/curl:8.10.1"; diff --git a/src/lib/model-prompts.test.ts b/src/lib/model-prompts.test.ts index 13ebe4f1fa8..26d25b98c00 100644 --- a/src/lib/model-prompts.test.ts +++ b/src/lib/model-prompts.test.ts @@ -9,7 +9,7 @@ import { promptInputModel, promptManualModelId, promptRemoteModel, -} from "./model-prompts"; +} from "../../dist/lib/model-prompts"; function promptSequence(responses: string[]) { const queue = [...responses]; diff --git a/src/lib/model-prompts.ts b/src/lib/model-prompts.ts index 6ea65e29ed5..f459c2e6cc4 100644 --- a/src/lib/model-prompts.ts +++ b/src/lib/model-prompts.ts @@ -5,9 +5,9 @@ import { CLOUD_MODEL_OPTIONS } from "./inference-config"; import { isSafeModelId } from "./validation"; import { validateNvidiaEndpointModel } from "./provider-models"; -// credentials.js is CJS. +// credentials.ts still uses CommonJS-style exports. // eslint-disable-next-line @typescript-eslint/no-require-imports -const { getCredential, prompt } = require("../../bin/lib/credentials"); +const { getCredential, prompt } = require("./credentials"); export const BACK_TO_SELECTION = "__NEMOCLAW_BACK_TO_SELECTION__"; diff --git a/src/lib/nim.test.ts b/src/lib/nim.test.ts index ab3cbe5f950..a36dddf3c99 100644 --- a/src/lib/nim.test.ts +++ b/src/lib/nim.test.ts @@ -10,7 +10,7 @@ import nim from "../../dist/lib/nim"; const require = createRequire(import.meta.url); const NIM_DIST_PATH = require.resolve("../../dist/lib/nim"); -const RUNNER_PATH = require.resolve("../../bin/lib/runner"); +const RUNNER_PATH = require.resolve("../../dist/lib/runner"); function loadNimWithMockedRunner(runCapture: Mock) { const runner = require(RUNNER_PATH); diff --git a/src/lib/nim.ts b/src/lib/nim.ts index 2e10d1e601d..d0118ff393a 100644 --- a/src/lib/nim.ts +++ b/src/lib/nim.ts @@ -4,7 +4,7 @@ // NIM container management — pull, start, stop, health-check NIM images. // eslint-disable-next-line @typescript-eslint/no-require-imports -const { run, runCapture, shellQuote } = require("../../bin/lib/runner"); +const { run, runCapture, shellQuote } = require("./runner"); // eslint-disable-next-line @typescript-eslint/no-require-imports const nimImages = require("../../bin/lib/nim-images.json"); diff --git a/src/lib/onboard-session.test.ts b/src/lib/onboard-session.test.ts index 1dc479d30a6..d72ad023671 100644 --- a/src/lib/onboard-session.test.ts +++ b/src/lib/onboard-session.test.ts @@ -8,8 +8,6 @@ import path from "node:path"; import { createRequire } from "node:module"; const require = createRequire(import.meta.url); -// Clear both the shim and the dist module so HOME changes take effect. -const shimPath = require.resolve("../../bin/lib/onboard-session"); const distPath = require.resolve("../../dist/lib/onboard-session"); const originalHome = process.env.HOME; // eslint-disable-next-line @typescript-eslint/no-explicit-any @@ -23,7 +21,6 @@ beforeEach(() => { // order-dependent. See issue #1284. tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "nemoclaw-onboard-session-")); process.env.HOME = tmpDir; - delete require.cache[shimPath]; delete require.cache[distPath]; session = require("../../dist/lib/onboard-session"); session.clearSession(); @@ -31,7 +28,6 @@ beforeEach(() => { }); afterEach(() => { - delete require.cache[shimPath]; delete require.cache[distPath]; fs.rmSync(tmpDir, { recursive: true, force: true }); if (originalHome === undefined) { diff --git a/src/lib/onboard.ts b/src/lib/onboard.ts index 7aefbff41f3..93d234cc1e5 100644 --- a/src/lib/onboard.ts +++ b/src/lib/onboard.ts @@ -22,8 +22,8 @@ function envInt(name, fallback) { /** Inference timeout (seconds) for local providers (Ollama, vLLM, NIM). */ const LOCAL_INFERENCE_TIMEOUT_SECS = envInt("NEMOCLAW_LOCAL_INFERENCE_TIMEOUT", 180); -const { ROOT, SCRIPTS, redact, run, runCapture, shellQuote } = require("../../bin/lib/runner"); -const { stageOptimizedSandboxBuildContext } = require("../../bin/lib/sandbox-build-context"); +const { ROOT, SCRIPTS, redact, run, runCapture, shellQuote } = require("./runner"); +const { stageOptimizedSandboxBuildContext } = require("./sandbox-build-context"); const { getDefaultOllamaModel, getBootstrapOllamaModelOptions, @@ -33,46 +33,45 @@ const { getOllamaWarmupCommand, validateOllamaModel, validateLocalProvider, -} = require("../../bin/lib/local-inference"); +} = require("./local-inference"); const { DEFAULT_CLOUD_MODEL, getProviderSelectionConfig, parseGatewayInference, -} = require("../../bin/lib/inference-config"); -const { inferContainerRuntime, isWsl, shouldPatchCoredns } = require("../../bin/lib/platform"); -const { resolveOpenshell } = require("../../bin/lib/resolve-openshell"); +} = require("./inference-config"); +const { inferContainerRuntime, isWsl, shouldPatchCoredns } = require("./platform"); +const { resolveOpenshell } = require("./resolve-openshell"); const { prompt, ensureApiKey, getCredential, normalizeCredentialValue, saveCredential, -} = require("../../bin/lib/credentials"); -const registry = require("../../bin/lib/registry"); -const nim = require("../../bin/lib/nim"); -const onboardSession = require("../../bin/lib/onboard-session"); -const policies = require("../../bin/lib/policies"); -const { ensureUsageNoticeConsent } = require("../../bin/lib/usage-notice"); +} = require("./credentials"); +const registry = require("./registry"); +const nim = require("./nim"); +const onboardSession = require("./onboard-session"); +const policies = require("./policies"); +const { ensureUsageNoticeConsent } = require("./usage-notice"); const { assessHost, checkPortAvailable, ensureSwap, getMemoryInfo, planHostRemediation, -} = require("../../bin/lib/preflight"); - -// Typed modules (compiled from src/lib/*.ts → dist/lib/*.js) -const gatewayState = require("../../dist/lib/gateway-state"); -const validation = require("../../dist/lib/validation"); -const urlUtils = require("../../dist/lib/url-utils"); -const buildContext = require("../../dist/lib/build-context"); -const dashboard = require("../../dist/lib/dashboard"); -const httpProbe = require("../../dist/lib/http-probe"); -const modelPrompts = require("../../dist/lib/model-prompts"); -const providerModels = require("../../dist/lib/provider-models"); -const sandboxCreateStream = require("../../dist/lib/sandbox-create-stream"); -const validationRecovery = require("../../dist/lib/validation-recovery"); -const webSearch = require("../../dist/lib/web-search"); +} = require("./preflight"); + +const gatewayState = require("./gateway-state"); +const validation = require("./validation"); +const urlUtils = require("./url-utils"); +const buildContext = require("./build-context"); +const dashboard = require("./dashboard"); +const httpProbe = require("./http-probe"); +const modelPrompts = require("./model-prompts"); +const providerModels = require("./provider-models"); +const sandboxCreateStream = require("./sandbox-create-stream"); +const validationRecovery = require("./validation-recovery"); +const webSearch = require("./web-search"); /** * Create a temp file inside a directory with a cryptographically random name. @@ -419,7 +418,7 @@ function versionGte(left = "0.0.0", right = "0.0.0") { */ function getBlueprintMinOpenshellVersion(rootDir = ROOT) { try { - // Lazy require: yaml is already a dependency via bin/lib/policies.js but + // Lazy require: yaml is already a dependency via the policy helpers but // pulling it at module load would slow down `nemoclaw --help` for users // who never reach the preflight path. const YAML = require("yaml"); diff --git a/src/lib/preflight.ts b/src/lib/preflight.ts index 17e720a3f0a..62af61a3f6a 100644 --- a/src/lib/preflight.ts +++ b/src/lib/preflight.ts @@ -14,9 +14,9 @@ import net from "node:net"; import os from "node:os"; import path from "node:path"; -// runner.js is CJS — use require so we don't pull it into the TS build. +// runner.ts still uses CommonJS-style exports — use require here. // eslint-disable-next-line @typescript-eslint/no-require-imports -const { runCapture } = require("../../bin/lib/runner"); +const { runCapture } = require("./runner"); // ── Types ──────────────────────────────────────────────────────── diff --git a/src/lib/provider-models.test.ts b/src/lib/provider-models.test.ts index 3a1ffc54447..dee9d1fbf6a 100644 --- a/src/lib/provider-models.test.ts +++ b/src/lib/provider-models.test.ts @@ -11,7 +11,7 @@ import { validateAnthropicModel, validateNvidiaEndpointModel, validateOpenAiLikeModel, -} from "./provider-models"; +} from "../../dist/lib/provider-models"; describe("provider model helpers", () => { it("fetches NVIDIA endpoint model ids", () => { diff --git a/src/lib/provider-models.ts b/src/lib/provider-models.ts index 6bed4e5716f..83c4ffdf05f 100644 --- a/src/lib/provider-models.ts +++ b/src/lib/provider-models.ts @@ -5,9 +5,9 @@ import type { CurlProbeResult } from "./http-probe"; import { getCurlTimingArgs, runCurlProbe } from "./http-probe"; import type { ModelCatalogFetchResult, ModelValidationResult } from "./onboard-types"; -// credentials.js is CJS. +// credentials.ts still uses CommonJS-style exports. // eslint-disable-next-line @typescript-eslint/no-require-imports -const { normalizeCredentialValue } = require("../../bin/lib/credentials"); +const { normalizeCredentialValue } = require("./credentials"); export const BUILD_ENDPOINT_URL = "https://integrate.api.nvidia.com/v1"; diff --git a/src/lib/usage-notice.ts b/src/lib/usage-notice.ts index 547f14a4ae2..53a0997b5a7 100644 --- a/src/lib/usage-notice.ts +++ b/src/lib/usage-notice.ts @@ -149,7 +149,7 @@ export async function ensureUsageNoticeConsent({ // credentials is still CJS // eslint-disable-next-line @typescript-eslint/no-require-imports - const ask = promptFn || require("../../bin/lib/credentials").prompt; + const ask = promptFn || require("./credentials").prompt; const answer = String(await ask(` ${config.interactivePrompt}`)) .trim() .toLowerCase(); diff --git a/src/nemoclaw.ts b/src/nemoclaw.ts index 2cb402e1171..3589471e566 100644 --- a/src/nemoclaw.ts +++ b/src/nemoclaw.ts @@ -28,23 +28,23 @@ const { runInteractive, shellQuote, validateName, -} = require("../bin/lib/runner"); -const { resolveOpenshell } = require("../bin/lib/resolve-openshell"); -const { startGatewayForRecovery } = require("../bin/lib/onboard"); +} = require("./lib/runner"); +const { resolveOpenshell } = require("./lib/resolve-openshell"); +const { startGatewayForRecovery } = require("./lib/onboard"); const { getCredential, deleteCredential, listCredentialKeys, prompt: askPrompt, -} = require("../bin/lib/credentials"); -const registry = require("../bin/lib/registry"); -const nim = require("../bin/lib/nim"); -const policies = require("../bin/lib/policies"); -const { parseGatewayInference } = require("../bin/lib/inference-config"); -const { getVersion } = require("../bin/lib/version"); -const onboardSession = require("../bin/lib/onboard-session"); -const { parseLiveSandboxNames } = require("../bin/lib/runtime-recovery"); -const { NOTICE_ACCEPT_ENV, NOTICE_ACCEPT_FLAG } = require("../bin/lib/usage-notice"); +} = require("./lib/credentials"); +const registry = require("./lib/registry"); +const nim = require("./lib/nim"); +const policies = require("./lib/policies"); +const { parseGatewayInference } = require("./lib/inference-config"); +const { getVersion } = require("./lib/version"); +const onboardSession = require("./lib/onboard-session"); +const { parseLiveSandboxNames } = require("./lib/runtime-recovery"); +const { NOTICE_ACCEPT_ENV, NOTICE_ACCEPT_FLAG } = require("./lib/usage-notice"); const { runDebugCommand } = require("./lib/debug-command"); const { captureOpenshellCommand, @@ -769,7 +769,7 @@ function printDangerouslySkipPermissionsWarning() { // ── Commands ───────────────────────────────────────────────────── async function onboard(args) { - const { onboard: runOnboard } = require("../bin/lib/onboard"); + const { onboard: runOnboard } = require("./lib/onboard"); // Extract --from before the unknown-arg validator: it takes a value // so the set-based check would reject the value token as an unknown flag. @@ -855,7 +855,7 @@ async function deploy(instanceName) { } async function start() { - const { startAll } = require("../bin/lib/services"); + const { startAll } = require("./lib/services"); await runStartCommand({ listSandboxes: () => registry.listSandboxes(), startAll, @@ -863,7 +863,7 @@ async function start() { } function stop() { - const { stopAll } = require("../bin/lib/services"); + const { stopAll } = require("./lib/services"); runStopCommand({ listSandboxes: () => registry.listSandboxes(), stopAll, @@ -871,7 +871,7 @@ function stop() { } function debug(args) { - const { runDebug } = require("../bin/lib/debug"); + const { runDebug } = require("./lib/debug"); runDebugCommand(args, { getDefaultSandbox: () => registry.listSandboxes().defaultSandbox || undefined, runDebug, @@ -975,7 +975,7 @@ async function credentialsCommand(args) { } function showStatus() { - const { showStatus: showServiceStatus } = require("../bin/lib/services"); + const { showStatus: showServiceStatus } = require("./lib/services"); showStatusCommand({ listSandboxes: () => registry.listSandboxes(), getLiveInference: () => @@ -1001,7 +1001,7 @@ async function sandboxConnect(sandboxName, { dangerouslySkipPermissions = false await ensureLiveSandboxOrExit(sandboxName); if (dangerouslySkipPermissions) { printDangerouslySkipPermissionsWarning(); - const policies = require("../bin/lib/policies"); + const policies = require("./lib/policies"); policies.applyPermissivePolicy(sandboxName); } checkAndRecoverSandboxProcesses(sandboxName); @@ -1223,7 +1223,7 @@ function sandboxPolicyList(sandboxName) { function cleanupSandboxServices(sandboxName) { // Stop host services (cloudflared) and clean up PID directory. - const { stopAll } = require("../bin/lib/services"); + const { stopAll } = require("./lib/services"); stopAll({ sandboxName }); try { fs.rmSync(`/tmp/nemoclaw-services-${sandboxName}`, { recursive: true, force: true }); diff --git a/test/credentials.test.ts b/test/credentials.test.ts index 77afa9674e0..cae21a2c4a0 100644 --- a/test/credentials.test.ts +++ b/test/credentials.test.ts @@ -14,7 +14,7 @@ async function importCredentialsModule(home) { vi.doUnmock("child_process"); vi.doUnmock("readline"); vi.stubEnv("HOME", home); - const module = await import("../bin/lib/credentials.js"); + const module = await import("../dist/lib/credentials.js"); /** @type {any} */ const resolved = module.default ?? module; return resolved; @@ -35,8 +35,8 @@ describe("credential prompts", () => { credentials.saveCredential("TEST_API_KEY", " nvapi-saved-key \r\n"); - expect(credentials.CREDS_DIR).toBe(path.join(home, ".nemoclaw")); - expect(credentials.CREDS_FILE).toBe(path.join(home, ".nemoclaw", "credentials.json")); + expect(credentials.getCredsDir()).toBe(path.join(home, ".nemoclaw")); + expect(credentials.getCredsFile()).toBe(path.join(home, ".nemoclaw", "credentials.json")); expect(credentials.loadCredentials()).toEqual({ TEST_API_KEY: "nvapi-saved-key" }); expect(credentials.getCredential("TEST_API_KEY")).toBe("nvapi-saved-key"); diff --git a/test/e2e/e2e-cloud-experimental/skip/04-nemoclaw-openshell-status-parity.sh b/test/e2e/e2e-cloud-experimental/skip/04-nemoclaw-openshell-status-parity.sh index 488a8f515c0..45ddb3422bb 100755 --- a/test/e2e/e2e-cloud-experimental/skip/04-nemoclaw-openshell-status-parity.sh +++ b/test/e2e/e2e-cloud-experimental/skip/04-nemoclaw-openshell-status-parity.sh @@ -6,7 +6,7 @@ # # Sandbox “running” signal (OpenShell versions differ): # 1) openshell sandbox status --json → .state == running (nemoclaw plugin status path) -# 2) else openshell sandbox list → row for name contains Ready (bin/lib/onboard.js isSandboxReady) +# 2) else openshell sandbox list → row for name contains Ready (dist/lib/onboard.js isSandboxReady) # Inference model: prefer openshell inference get --json .model; else plain inference get # (text) must contain CLOUD_EXPERIMENTAL_INFERENCE_PROVIDER + CLOUD_EXPERIMENTAL_MODEL (same idea as 01-onboard-completion.sh). # nemoclaw list model must match openshell model (JSON or CLOUD_EXPERIMENTAL_MODEL text path). diff --git a/test/e2e/test-onboard-repair.sh b/test/e2e/test-onboard-repair.sh index 199c8b74cb5..5946cd6f583 100755 --- a/test/e2e/test-onboard-repair.sh +++ b/test/e2e/test-onboard-repair.sh @@ -115,7 +115,7 @@ fi node -e ' const { saveCredential } = require(process.argv[1]); saveCredential("NVIDIA_API_KEY", process.argv[2]); -' "$REPO/bin/lib/credentials.js" "$RESTORE_API_KEY" +' "$REPO/dist/lib/credentials.js" "$RESTORE_API_KEY" pass "Stored NVIDIA_API_KEY in ~/.nemoclaw/credentials.json for resume hydration" # ══════════════════════════════════════════════════════════════════ diff --git a/test/e2e/test-onboard-resume.sh b/test/e2e/test-onboard-resume.sh index 6760aa093fe..d14d9c382c3 100755 --- a/test/e2e/test-onboard-resume.sh +++ b/test/e2e/test-onboard-resume.sh @@ -136,7 +136,7 @@ fi node -e ' const { saveCredential } = require(process.argv[1]); saveCredential("NVIDIA_API_KEY", process.argv[2]); -' "$REPO/bin/lib/credentials.js" "$RESTORE_API_KEY" +' "$REPO/dist/lib/credentials.js" "$RESTORE_API_KEY" pass "Stored NVIDIA_API_KEY in ~/.nemoclaw/credentials.json for resume hydration" # ══════════════════════════════════════════════════════════════════ diff --git a/test/e2e/test-telegram-injection.sh b/test/e2e/test-telegram-injection.sh index 47e8a98a272..d25384526e4 100755 --- a/test/e2e/test-telegram-injection.sh +++ b/test/e2e/test-telegram-injection.sh @@ -345,7 +345,7 @@ info "T6: Testing SANDBOX_NAME with shell metacharacters..." # alphanumeric with optional internal hyphens, max 63 chars. # Test by running the validation directly via node. t6_result=$(cd "$REPO" && node -e " - const { validateName } = require('./bin/lib/runner'); + const { validateName } = require('./dist/lib/runner'); try { validateName('foo;rm -rf /', 'SANDBOX_NAME'); console.log('ACCEPTED'); @@ -364,7 +364,7 @@ fi info "T7: Testing SANDBOX_NAME with leading hyphen (option injection)..." t7_result=$(cd "$REPO" && node -e " - const { validateName } = require('./bin/lib/runner'); + const { validateName } = require('./dist/lib/runner'); try { validateName('--help', 'SANDBOX_NAME'); console.log('ACCEPTED'); @@ -383,7 +383,7 @@ fi # backticks and $() in double-quoted node -e strings. for invalid_name in '$(whoami)' '`id`' 'foo bar' '../etc/passwd' 'UPPERCASE'; do t_result=$(cd "$REPO" && node -e " - const { validateName } = require('./bin/lib/runner'); + const { validateName } = require('./dist/lib/runner'); try { validateName(process.argv[1], 'SANDBOX_NAME'); console.log('ACCEPTED'); diff --git a/test/onboard-readiness.test.ts b/test/onboard-readiness.test.ts index 913876902ea..1b872a41965 100644 --- a/test/onboard-readiness.test.ts +++ b/test/onboard-readiness.test.ts @@ -3,8 +3,8 @@ // SPDX-License-Identifier: Apache-2.0 import { describe, it, expect } from "vitest"; -import { applyPreset, buildPolicySetCommand, buildPolicyGetCommand } from "../bin/lib/policies"; -import { hasStaleGateway, isSandboxReady } from "../bin/lib/onboard"; +import { applyPreset, buildPolicySetCommand, buildPolicyGetCommand } from "../dist/lib/policies"; +import { hasStaleGateway, isSandboxReady } from "../dist/lib/onboard"; describe("sandbox readiness parsing", () => { it("detects Ready sandbox", () => { diff --git a/test/onboard-selection.test.ts b/test/onboard-selection.test.ts index 21e2b60a8b9..8865d4f9364 100644 --- a/test/onboard-selection.test.ts +++ b/test/onboard-selection.test.ts @@ -88,10 +88,10 @@ describe("onboard provider selection UX", () => { const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "nemoclaw-onboard-selection-")); const fakeBin = path.join(tmpDir, "bin"); const scriptPath = path.join(tmpDir, "selection-check.js"); - const onboardPath = JSON.stringify(path.join(repoRoot, "src", "lib", "onboard.ts")); - const credentialsPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "credentials.js")); - const runnerPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "runner.js")); - const registryPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "registry.js")); + const onboardPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "onboard.js")); + const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials.js")); + const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); + const registryPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "registry.js")); fs.mkdirSync(fakeBin, { recursive: true }); fs.writeFileSync( @@ -183,9 +183,9 @@ const { setupNim } = require(${onboardPath}); const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "nemoclaw-onboard-no-recommended-label-")); const fakeBin = path.join(tmpDir, "bin"); const scriptPath = path.join(tmpDir, "no-recommended-label-check.js"); - const onboardPath = JSON.stringify(path.join(repoRoot, "src", "lib", "onboard.ts")); - const credentialsPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "credentials.js")); - const runnerPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "runner.js")); + const onboardPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "onboard.js")); + const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials.js")); + const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); fs.mkdirSync(fakeBin, { recursive: true }); fs.writeFileSync( @@ -260,9 +260,9 @@ const { setupNim } = require(${onboardPath}); ); const fakeBin = path.join(tmpDir, "bin"); const scriptPath = path.join(tmpDir, "build-model-selection-check.js"); - const onboardPath = JSON.stringify(path.join(repoRoot, "src", "lib", "onboard.ts")); - const credentialsPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "credentials.js")); - const runnerPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "runner.js")); + const onboardPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "onboard.js")); + const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials.js")); + const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); fs.mkdirSync(fakeBin, { recursive: true }); fs.writeFileSync( @@ -353,9 +353,9 @@ const { setupNim } = require(${onboardPath}); const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "nemoclaw-onboard-build-model-retry-")); const fakeBin = path.join(tmpDir, "bin"); const scriptPath = path.join(tmpDir, "build-model-retry-check.js"); - const onboardPath = JSON.stringify(path.join(repoRoot, "src", "lib", "onboard.ts")); - const credentialsPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "credentials.js")); - const runnerPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "runner.js")); + const onboardPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "onboard.js")); + const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials.js")); + const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); fs.mkdirSync(fakeBin, { recursive: true }); fs.writeFileSync( @@ -448,9 +448,9 @@ const { setupNim } = require(${onboardPath}); const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "nemoclaw-onboard-gemini-selection-")); const fakeBin = path.join(tmpDir, "bin"); const scriptPath = path.join(tmpDir, "gemini-selection-check.js"); - const onboardPath = JSON.stringify(path.join(repoRoot, "src", "lib", "onboard.ts")); - const credentialsPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "credentials.js")); - const runnerPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "runner.js")); + const onboardPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "onboard.js")); + const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials.js")); + const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); fs.mkdirSync(fakeBin, { recursive: true }); fs.writeFileSync( @@ -541,9 +541,9 @@ const { setupNim } = require(${onboardPath}); const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "nemoclaw-onboard-ollama-validation-")); const fakeBin = path.join(tmpDir, "bin"); const scriptPath = path.join(tmpDir, "ollama-validation-check.js"); - const onboardPath = JSON.stringify(path.join(repoRoot, "src", "lib", "onboard.ts")); - const credentialsPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "credentials.js")); - const runnerPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "runner.js")); + const onboardPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "onboard.js")); + const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials.js")); + const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); fs.mkdirSync(fakeBin, { recursive: true }); fs.writeFileSync( @@ -639,9 +639,9 @@ const { setupNim } = require(${onboardPath}); const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "nemoclaw-onboard-ollama-back-")); const fakeBin = path.join(tmpDir, "bin"); const scriptPath = path.join(tmpDir, "ollama-back-check.js"); - const onboardPath = JSON.stringify(path.join(repoRoot, "src", "lib", "onboard.ts")); - const credentialsPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "credentials.js")); - const runnerPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "runner.js")); + const onboardPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "onboard.js")); + const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials.js")); + const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); fs.mkdirSync(fakeBin, { recursive: true }); fs.writeFileSync( @@ -729,9 +729,9 @@ const { setupNim } = require(${onboardPath}); const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "nemoclaw-onboard-ollama-bootstrap-")); const fakeBin = path.join(tmpDir, "bin"); const scriptPath = path.join(tmpDir, "ollama-bootstrap-check.js"); - const onboardPath = JSON.stringify(path.join(repoRoot, "src", "lib", "onboard.ts")); - const credentialsPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "credentials.js")); - const runnerPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "runner.js")); + const onboardPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "onboard.js")); + const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials.js")); + const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); const pullLog = path.join(tmpDir, "pulls.log"); fs.mkdirSync(fakeBin, { recursive: true }); @@ -833,9 +833,9 @@ const { setupNim } = require(${onboardPath}); const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "nemoclaw-onboard-ollama-retry-")); const fakeBin = path.join(tmpDir, "bin"); const scriptPath = path.join(tmpDir, "ollama-retry-check.js"); - const onboardPath = JSON.stringify(path.join(repoRoot, "src", "lib", "onboard.ts")); - const credentialsPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "credentials.js")); - const runnerPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "runner.js")); + const onboardPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "onboard.js")); + const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials.js")); + const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); const pullLog = path.join(tmpDir, "pulls.log"); fs.mkdirSync(fakeBin, { recursive: true }); @@ -944,9 +944,9 @@ const { setupNim } = require(${onboardPath}); const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "nemoclaw-onboard-openai-model-retry-")); const fakeBin = path.join(tmpDir, "bin"); const scriptPath = path.join(tmpDir, "openai-model-retry-check.js"); - const onboardPath = JSON.stringify(path.join(repoRoot, "src", "lib", "onboard.ts")); - const credentialsPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "credentials.js")); - const runnerPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "runner.js")); + const onboardPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "onboard.js")); + const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials.js")); + const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); fs.mkdirSync(fakeBin, { recursive: true }); fs.writeFileSync( @@ -1033,9 +1033,9 @@ const { setupNim } = require(${onboardPath}); ); const fakeBin = path.join(tmpDir, "bin"); const scriptPath = path.join(tmpDir, "anthropic-model-retry-check.js"); - const onboardPath = JSON.stringify(path.join(repoRoot, "src", "lib", "onboard.ts")); - const credentialsPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "credentials.js")); - const runnerPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "runner.js")); + const onboardPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "onboard.js")); + const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials.js")); + const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); fs.mkdirSync(fakeBin, { recursive: true }); fs.writeFileSync( @@ -1119,9 +1119,9 @@ const { setupNim } = require(${onboardPath}); ); const fakeBin = path.join(tmpDir, "bin"); const scriptPath = path.join(tmpDir, "anthropic-validation-retry-check.js"); - const onboardPath = JSON.stringify(path.join(repoRoot, "src", "lib", "onboard.ts")); - const credentialsPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "credentials.js")); - const runnerPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "runner.js")); + const onboardPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "onboard.js")); + const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials.js")); + const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); fs.mkdirSync(fakeBin, { recursive: true }); fs.writeFileSync( @@ -1211,9 +1211,9 @@ const { setupNim } = require(${onboardPath}); const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "nemoclaw-onboard-anthropic-compatible-")); const fakeBin = path.join(tmpDir, "bin"); const scriptPath = path.join(tmpDir, "anthropic-compatible-check.js"); - const onboardPath = JSON.stringify(path.join(repoRoot, "src", "lib", "onboard.ts")); - const credentialsPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "credentials.js")); - const runnerPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "runner.js")); + const onboardPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "onboard.js")); + const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials.js")); + const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); fs.mkdirSync(fakeBin, { recursive: true }); fs.writeFileSync( @@ -1296,9 +1296,9 @@ const { setupNim } = require(${onboardPath}); const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "nemoclaw-onboard-custom-openai-retry-")); const fakeBin = path.join(tmpDir, "bin"); const scriptPath = path.join(tmpDir, "custom-openai-retry-check.js"); - const onboardPath = JSON.stringify(path.join(repoRoot, "src", "lib", "onboard.ts")); - const credentialsPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "credentials.js")); - const runnerPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "runner.js")); + const onboardPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "onboard.js")); + const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials.js")); + const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); fs.mkdirSync(fakeBin, { recursive: true }); fs.writeFileSync( @@ -1409,9 +1409,9 @@ const { setupNim } = require(${onboardPath}); ); const fakeBin = path.join(tmpDir, "bin"); const scriptPath = path.join(tmpDir, "custom-openai-responses-fallback-check.js"); - const onboardPath = JSON.stringify(path.join(repoRoot, "src", "lib", "onboard.ts")); - const credentialsPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "credentials.js")); - const runnerPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "runner.js")); + const onboardPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "onboard.js")); + const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials.js")); + const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); fs.mkdirSync(fakeBin, { recursive: true }); fs.writeFileSync( @@ -1503,9 +1503,9 @@ const { setupNim } = require(${onboardPath}); ); const fakeBin = path.join(tmpDir, "bin"); const scriptPath = path.join(tmpDir, "custom-endpoint-blank-check.js"); - const onboardPath = JSON.stringify(path.join(repoRoot, "src", "lib", "onboard.ts")); - const credentialsPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "credentials.js")); - const runnerPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "runner.js")); + const onboardPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "onboard.js")); + const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials.js")); + const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); fs.mkdirSync(fakeBin, { recursive: true }); fs.writeFileSync( @@ -1592,9 +1592,9 @@ const { setupNim } = require(${onboardPath}); ); const fakeBin = path.join(tmpDir, "bin"); const scriptPath = path.join(tmpDir, "custom-anthropic-retry-check.js"); - const onboardPath = JSON.stringify(path.join(repoRoot, "src", "lib", "onboard.ts")); - const credentialsPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "credentials.js")); - const runnerPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "runner.js")); + const onboardPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "onboard.js")); + const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials.js")); + const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); fs.mkdirSync(fakeBin, { recursive: true }); fs.writeFileSync( @@ -1701,9 +1701,9 @@ const { setupNim } = require(${onboardPath}); const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "nemoclaw-onboard-model-back-")); const fakeBin = path.join(tmpDir, "bin"); const scriptPath = path.join(tmpDir, "model-back-check.js"); - const onboardPath = JSON.stringify(path.join(repoRoot, "src", "lib", "onboard.ts")); - const credentialsPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "credentials.js")); - const runnerPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "runner.js")); + const onboardPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "onboard.js")); + const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials.js")); + const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); fs.mkdirSync(fakeBin, { recursive: true }); fs.writeFileSync( @@ -1787,9 +1787,9 @@ const { setupNim } = require(${onboardPath}); const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "nemoclaw-onboard-transport-back-")); const fakeBin = path.join(tmpDir, "bin"); const scriptPath = path.join(tmpDir, "transport-back-check.js"); - const onboardPath = JSON.stringify(path.join(repoRoot, "src", "lib", "onboard.ts")); - const credentialsPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "credentials.js")); - const runnerPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "runner.js")); + const onboardPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "onboard.js")); + const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials.js")); + const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); fs.mkdirSync(fakeBin, { recursive: true }); fs.writeFileSync( @@ -1881,9 +1881,9 @@ const { setupNim } = require(${onboardPath}); const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "nemoclaw-onboard-selection-retry-")); const fakeBin = path.join(tmpDir, "bin"); const scriptPath = path.join(tmpDir, "selection-retry-check.js"); - const onboardPath = JSON.stringify(path.join(repoRoot, "src", "lib", "onboard.ts")); - const credentialsPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "credentials.js")); - const runnerPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "runner.js")); + const onboardPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "onboard.js")); + const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials.js")); + const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); fs.mkdirSync(fakeBin, { recursive: true }); fs.writeFileSync( @@ -1983,9 +1983,9 @@ const { setupNim } = require(${onboardPath}); const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "nemoclaw-onboard-build-noninteractive-")); const fakeBin = path.join(tmpDir, "bin"); const scriptPath = path.join(tmpDir, "build-noninteractive-check.js"); - const onboardPath = JSON.stringify(path.join(repoRoot, "src", "lib", "onboard.ts")); - const credentialsPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "credentials.js")); - const runnerPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "runner.js")); + const onboardPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "onboard.js")); + const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials.js")); + const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); fs.mkdirSync(fakeBin, { recursive: true }); @@ -2083,9 +2083,9 @@ const { setupNim, __setNonInteractive } = onboardModule.exports; const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "nemoclaw-onboard-build-auth-retry-")); const fakeBin = path.join(tmpDir, "bin"); const scriptPath = path.join(tmpDir, "build-auth-retry-check.js"); - const onboardPath = JSON.stringify(path.join(repoRoot, "src", "lib", "onboard.ts")); - const credentialsPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "credentials.js")); - const runnerPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "runner.js")); + const onboardPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "onboard.js")); + const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials.js")); + const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); fs.mkdirSync(fakeBin, { recursive: true }); fs.writeFileSync( @@ -2200,9 +2200,9 @@ const { setupNim } = require(${onboardPath}); const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "nemoclaw-onboard-openai-auth-retry-")); const fakeBin = path.join(tmpDir, "bin"); const scriptPath = path.join(tmpDir, "openai-auth-retry-check.js"); - const onboardPath = JSON.stringify(path.join(repoRoot, "src", "lib", "onboard.ts")); - const credentialsPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "credentials.js")); - const runnerPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "runner.js")); + const onboardPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "onboard.js")); + const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials.js")); + const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); fs.mkdirSync(fakeBin, { recursive: true }); writeOpenAiStyleAuthRetryCurl(fakeBin, "sk-good", ["gpt-5.4"]); @@ -2278,9 +2278,9 @@ const { setupNim } = require(${onboardPath}); const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "nemoclaw-onboard-anthropic-auth-retry-")); const fakeBin = path.join(tmpDir, "bin"); const scriptPath = path.join(tmpDir, "anthropic-auth-retry-check.js"); - const onboardPath = JSON.stringify(path.join(repoRoot, "src", "lib", "onboard.ts")); - const credentialsPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "credentials.js")); - const runnerPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "runner.js")); + const onboardPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "onboard.js")); + const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials.js")); + const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); fs.mkdirSync(fakeBin, { recursive: true }); writeAnthropicStyleAuthRetryCurl(fakeBin, "anthropic-good", ["claude-sonnet-4-6"]); @@ -2356,9 +2356,9 @@ const { setupNim } = require(${onboardPath}); const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "nemoclaw-onboard-gemini-auth-retry-")); const fakeBin = path.join(tmpDir, "bin"); const scriptPath = path.join(tmpDir, "gemini-auth-retry-check.js"); - const onboardPath = JSON.stringify(path.join(repoRoot, "src", "lib", "onboard.ts")); - const credentialsPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "credentials.js")); - const runnerPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "runner.js")); + const onboardPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "onboard.js")); + const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials.js")); + const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); fs.mkdirSync(fakeBin, { recursive: true }); writeOpenAiStyleAuthRetryCurl(fakeBin, "gemini-good", ["gemini-2.5-flash"]); @@ -2436,9 +2436,9 @@ const { setupNim } = require(${onboardPath}); ); const fakeBin = path.join(tmpDir, "bin"); const scriptPath = path.join(tmpDir, "custom-openai-auth-retry-check.js"); - const onboardPath = JSON.stringify(path.join(repoRoot, "src", "lib", "onboard.ts")); - const credentialsPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "credentials.js")); - const runnerPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "runner.js")); + const onboardPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "onboard.js")); + const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials.js")); + const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); fs.mkdirSync(fakeBin, { recursive: true }); writeOpenAiStyleAuthRetryCurl(fakeBin, "proxy-good", ["custom-model"]); @@ -2530,9 +2530,9 @@ const { setupNim } = require(${onboardPath}); ); const fakeBin = path.join(tmpDir, "bin"); const scriptPath = path.join(tmpDir, "custom-anthropic-auth-retry-check.js"); - const onboardPath = JSON.stringify(path.join(repoRoot, "src", "lib", "onboard.ts")); - const credentialsPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "credentials.js")); - const runnerPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "runner.js")); + const onboardPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "onboard.js")); + const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials.js")); + const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); fs.mkdirSync(fakeBin, { recursive: true }); writeAnthropicStyleAuthRetryCurl(fakeBin, "anthropic-proxy-good", ["claude-proxy"]); @@ -2623,9 +2623,9 @@ const { setupNim } = require(${onboardPath}); const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "nemoclaw-onboard-vllm-override-")); const fakeBin = path.join(tmpDir, "bin"); const scriptPath = path.join(tmpDir, "vllm-override-check.js"); - const onboardPath = JSON.stringify(path.join(repoRoot, "src", "lib", "onboard.ts")); - const credentialsPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "credentials.js")); - const runnerPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "runner.js")); + const onboardPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "onboard.js")); + const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials.js")); + const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); fs.mkdirSync(fakeBin, { recursive: true }); // Fake curl: /v1/responses returns 200 (so probe detects openai-responses), @@ -2722,10 +2722,10 @@ const { setupNim } = require(${onboardPath}); const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "nemoclaw-onboard-nim-override-")); const fakeBin = path.join(tmpDir, "bin"); const scriptPath = path.join(tmpDir, "nim-override-check.js"); - const onboardPath = JSON.stringify(path.join(repoRoot, "src", "lib", "onboard.ts")); - const credentialsPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "credentials.js")); - const runnerPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "runner.js")); - const nimPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "nim.js")); + const onboardPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "onboard.js")); + const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials.js")); + const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); + const nimPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "nim.js")); fs.mkdirSync(fakeBin, { recursive: true }); // Fake curl: /v1/responses returns 200 (probe detects openai-responses) diff --git a/test/onboard.test.ts b/test/onboard.test.ts index 36d747cd7a4..b0a9f522d94 100644 --- a/test/onboard.test.ts +++ b/test/onboard.test.ts @@ -43,8 +43,8 @@ import { summarizeProbeFailure, shouldIncludeBuildContextPath, writeSandboxConfigSyncFile, -} from "../bin/lib/onboard"; -import { stageOptimizedSandboxBuildContext } from "../bin/lib/sandbox-build-context"; +} from "../dist/lib/onboard"; +import { stageOptimizedSandboxBuildContext } from "../dist/lib/sandbox-build-context"; import { buildWebSearchDockerConfig } from "../dist/lib/web-search"; describe("onboard helpers", () => { @@ -1027,9 +1027,9 @@ describe("onboard helpers", () => { const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "nemoclaw-onboard-inference-")); const fakeBin = path.join(tmpDir, "bin"); const scriptPath = path.join(tmpDir, "setup-inference-check.js"); - const onboardPath = JSON.stringify(path.join(repoRoot, "src", "lib", "onboard.ts")); - const runnerPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "runner.js")); - const registryPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "registry.js")); + const onboardPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "onboard.js")); + const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); + const registryPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "registry.js")); fs.mkdirSync(fakeBin, { recursive: true }); fs.writeFileSync(path.join(fakeBin, "openshell"), "#!/usr/bin/env bash\nexit 0\n", { @@ -1099,7 +1099,7 @@ const { setupInference } = require(${onboardPath}); const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "nemoclaw-inference-ready-")); const fakeOpenshell = path.join(tmpDir, "openshell"); const scriptPath = path.join(tmpDir, "inference-ready-check.js"); - const onboardPath = JSON.stringify(path.join(repoRoot, "src", "lib", "onboard.ts")); + const onboardPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "onboard.js")); fs.writeFileSync( fakeOpenshell, @@ -1158,7 +1158,7 @@ console.log(JSON.stringify({ const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "nemoclaw-openclaw-ready-")); const fakeOpenshell = path.join(tmpDir, "openshell"); const scriptPath = path.join(tmpDir, "openclaw-ready-check.js"); - const onboardPath = JSON.stringify(path.join(repoRoot, "src", "lib", "onboard.ts")); + const onboardPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "onboard.js")); fs.writeFileSync( fakeOpenshell, @@ -1209,7 +1209,7 @@ console.log(JSON.stringify({ const registryDir = path.join(tmpDir, ".nemoclaw"); const registryFile = path.join(registryDir, "sandboxes.json"); const scriptPath = path.join(tmpDir, "policy-ready-check.js"); - const onboardPath = JSON.stringify(path.join(repoRoot, "src", "lib", "onboard.ts")); + const onboardPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "onboard.js")); fs.mkdirSync(registryDir, { recursive: true }); fs.writeFileSync( @@ -1268,9 +1268,9 @@ console.log(JSON.stringify({ const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "nemoclaw-onboard-anthropic-")); const fakeBin = path.join(tmpDir, "bin"); const scriptPath = path.join(tmpDir, "setup-anthropic-check.js"); - const onboardPath = JSON.stringify(path.join(repoRoot, "src", "lib", "onboard.ts")); - const runnerPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "runner.js")); - const registryPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "registry.js")); + const onboardPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "onboard.js")); + const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); + const registryPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "registry.js")); fs.mkdirSync(fakeBin, { recursive: true }); fs.writeFileSync(path.join(fakeBin, "openshell"), "#!/usr/bin/env bash\nexit 0\n", { @@ -1340,9 +1340,9 @@ const { setupInference } = require(${onboardPath}); const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "nemoclaw-onboard-openai-update-")); const fakeBin = path.join(tmpDir, "bin"); const scriptPath = path.join(tmpDir, "setup-openai-update-check.js"); - const onboardPath = JSON.stringify(path.join(repoRoot, "src", "lib", "onboard.ts")); - const runnerPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "runner.js")); - const registryPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "registry.js")); + const onboardPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "onboard.js")); + const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); + const registryPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "registry.js")); fs.mkdirSync(fakeBin, { recursive: true }); fs.writeFileSync(path.join(fakeBin, "openshell"), "#!/usr/bin/env bash\nexit 0\n", { @@ -1414,10 +1414,10 @@ const { setupInference } = require(${onboardPath}); const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "nemoclaw-onboard-apply-auth-retry-")); const fakeBin = path.join(tmpDir, "bin"); const scriptPath = path.join(tmpDir, "setup-inference-auth-retry-check.js"); - const onboardPath = JSON.stringify(path.join(repoRoot, "src", "lib", "onboard.ts")); - const runnerPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "runner.js")); - const registryPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "registry.js")); - const credentialsPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "credentials.js")); + const onboardPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "onboard.js")); + const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); + const registryPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "registry.js")); + const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials.js")); fs.mkdirSync(fakeBin, { recursive: true }); fs.writeFileSync(path.join(fakeBin, "openshell"), "#!/usr/bin/env bash\nexit 0\n", { @@ -1499,10 +1499,10 @@ const { setupInference } = require(${onboardPath}); const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "nemoclaw-onboard-apply-back-")); const fakeBin = path.join(tmpDir, "bin"); const scriptPath = path.join(tmpDir, "setup-inference-apply-back-check.js"); - const onboardPath = JSON.stringify(path.join(repoRoot, "src", "lib", "onboard.ts")); - const runnerPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "runner.js")); - const registryPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "registry.js")); - const credentialsPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "credentials.js")); + const onboardPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "onboard.js")); + const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); + const registryPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "registry.js")); + const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials.js")); fs.mkdirSync(fakeBin, { recursive: true }); fs.writeFileSync(path.join(fakeBin, "openshell"), "#!/usr/bin/env bash\nexit 0\n", { @@ -1636,10 +1636,10 @@ const { setupInference } = require(${onboardPath}); const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "nemoclaw-onboard-resume-cred-")); const fakeBin = path.join(tmpDir, "bin"); const scriptPath = path.join(tmpDir, "setup-resume-credential-check.js"); - const onboardPath = JSON.stringify(path.join(repoRoot, "src", "lib", "onboard.ts")); - const runnerPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "runner.js")); - const registryPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "registry.js")); - const credentialsPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "credentials.js")); + const onboardPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "onboard.js")); + const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); + const registryPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "registry.js")); + const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials.js")); fs.mkdirSync(fakeBin, { recursive: true }); fs.writeFileSync(path.join(fakeBin, "openshell"), "#!/usr/bin/env bash\nexit 0\n", { @@ -1708,9 +1708,9 @@ const { setupInference } = require(${onboardPath}); const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "nemoclaw-onboard-stale-sandbox-")); const fakeBin = path.join(tmpDir, "bin"); const scriptPath = path.join(tmpDir, "stale-sandbox-check.js"); - const onboardPath = JSON.stringify(path.join(repoRoot, "src", "lib", "onboard.ts")); - const registryPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "registry.js")); - const runnerPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "runner.js")); + const onboardPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "onboard.js")); + const registryPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "registry.js")); + const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); fs.mkdirSync(fakeBin, { recursive: true }); fs.writeFileSync(path.join(fakeBin, "openshell"), "#!/usr/bin/env bash\nexit 0\n", { @@ -1759,11 +1759,11 @@ console.log(JSON.stringify({ liveExists, sandbox: registry.getSandbox("my-assist const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "nemoclaw-onboard-create-sandbox-")); const fakeBin = path.join(tmpDir, "bin"); const scriptPath = path.join(tmpDir, "create-sandbox-check.js"); - const onboardPath = JSON.stringify(path.join(repoRoot, "src", "lib", "onboard.ts")); - const runnerPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "runner.js")); - const registryPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "registry.js")); - const preflightPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "preflight.js")); - const credentialsPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "credentials.js")); + const onboardPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "onboard.js")); + const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); + const registryPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "registry.js")); + const preflightPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "preflight.js")); + const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials.js")); fs.mkdirSync(fakeBin, { recursive: true }); fs.writeFileSync(path.join(fakeBin, "openshell"), "#!/usr/bin/env bash\nexit 0\n", { @@ -1864,11 +1864,11 @@ const { createSandbox } = require(${onboardPath}); const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "nemoclaw-onboard-remote-forward-")); const fakeBin = path.join(tmpDir, "bin"); const scriptPath = path.join(tmpDir, "create-sandbox-remote-forward.js"); - const onboardPath = JSON.stringify(path.join(repoRoot, "src", "lib", "onboard.ts")); - const runnerPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "runner.js")); - const registryPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "registry.js")); - const preflightPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "preflight.js")); - const credentialsPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "credentials.js")); + const onboardPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "onboard.js")); + const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); + const registryPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "registry.js")); + const preflightPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "preflight.js")); + const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials.js")); fs.mkdirSync(fakeBin, { recursive: true }); fs.writeFileSync(path.join(fakeBin, "openshell"), "#!/usr/bin/env bash\nexit 0\n", { @@ -1957,11 +1957,11 @@ const { createSandbox } = require(${onboardPath}); ); const fakeBin = path.join(tmpDir, "bin"); const scriptPath = path.join(tmpDir, "messaging-provider-check.js"); - const onboardPath = JSON.stringify(path.join(repoRoot, "src", "lib", "onboard.ts")); - const runnerPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "runner.js")); - const registryPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "registry.js")); - const preflightPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "preflight.js")); - const credentialsPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "credentials.js")); + const onboardPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "onboard.js")); + const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); + const registryPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "registry.js")); + const preflightPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "preflight.js")); + const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials.js")); fs.mkdirSync(fakeBin, { recursive: true }); fs.writeFileSync(path.join(fakeBin, "openshell"), "#!/usr/bin/env bash\nexit 0\n", { @@ -2122,11 +2122,11 @@ const { createSandbox } = require(${onboardPath}); const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "nemoclaw-onboard-provider-fail-")); const fakeBin = path.join(tmpDir, "bin"); const scriptPath = path.join(tmpDir, "provider-upsert-fail.js"); - const onboardPath = JSON.stringify(path.join(repoRoot, "src", "lib", "onboard.ts")); - const runnerPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "runner.js")); - const registryPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "registry.js")); - const preflightPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "preflight.js")); - const credentialsPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "credentials.js")); + const onboardPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "onboard.js")); + const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); + const registryPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "registry.js")); + const preflightPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "preflight.js")); + const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials.js")); fs.mkdirSync(fakeBin, { recursive: true }); fs.writeFileSync(path.join(fakeBin, "openshell"), "#!/usr/bin/env bash\nexit 0\n", { @@ -2199,9 +2199,9 @@ const { createSandbox } = require(${onboardPath}); const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "nemoclaw-onboard-reuse-providers-")); const fakeBin = path.join(tmpDir, "bin"); const scriptPath = path.join(tmpDir, "reuse-with-providers.js"); - const onboardPath = JSON.stringify(path.join(repoRoot, "src", "lib", "onboard.ts")); - const runnerPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "runner.js")); - const registryPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "registry.js")); + const onboardPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "onboard.js")); + const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); + const registryPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "registry.js")); fs.mkdirSync(fakeBin, { recursive: true }); fs.writeFileSync(path.join(fakeBin, "openshell"), "#!/usr/bin/env bash\nexit 0\n", { @@ -2299,9 +2299,9 @@ const { createSandbox } = require(${onboardPath}); ); const fakeBin = path.join(tmpDir, "bin"); const scriptPath = path.join(tmpDir, "noninteractive-notready.js"); - const onboardPath = JSON.stringify(path.join(repoRoot, "src", "lib", "onboard.ts")); - const runnerPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "runner.js")); - const registryPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "registry.js")); + const onboardPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "onboard.js")); + const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); + const registryPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "registry.js")); fs.mkdirSync(fakeBin, { recursive: true }); fs.writeFileSync(path.join(fakeBin, "openshell"), "#!/usr/bin/env bash\nexit 0\n", { @@ -2377,9 +2377,9 @@ const { createSandbox } = require(${onboardPath}); const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "nemoclaw-onboard-recreate-flag-")); const fakeBin = path.join(tmpDir, "bin"); const scriptPath = path.join(tmpDir, "recreate-flag.js"); - const onboardPath = JSON.stringify(path.join(repoRoot, "src", "lib", "onboard.ts")); - const runnerPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "runner.js")); - const registryPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "registry.js")); + const onboardPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "onboard.js")); + const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); + const registryPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "registry.js")); fs.mkdirSync(fakeBin, { recursive: true }); fs.writeFileSync(path.join(fakeBin, "openshell"), "#!/usr/bin/env bash\nexit 0\n", { @@ -2408,7 +2408,7 @@ registry.getSandbox = () => ({ name: "my-assistant", gpuEnabled: false }); registry.registerSandbox = () => true; registry.removeSandbox = () => true; -const preflight = require(${JSON.stringify(path.join(repoRoot, "bin", "lib", "preflight.js"))}); +const preflight = require(${JSON.stringify(path.join(repoRoot, "dist", "lib", "preflight.js"))}); preflight.checkPortAvailable = async () => ({ ok: true }); childProcess.spawn = (...args) => { @@ -2477,10 +2477,10 @@ const { createSandbox } = require(${onboardPath}); const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "nemoclaw-onboard-interactive-reuse-")); const fakeBin = path.join(tmpDir, "bin"); const scriptPath = path.join(tmpDir, "interactive-reuse.js"); - const onboardPath = JSON.stringify(path.join(repoRoot, "src", "lib", "onboard.ts")); - const runnerPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "runner.js")); - const registryPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "registry.js")); - const credentialsPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "credentials.js")); + const onboardPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "onboard.js")); + const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); + const registryPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "registry.js")); + const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials.js")); fs.mkdirSync(fakeBin, { recursive: true }); fs.writeFileSync(path.join(fakeBin, "openshell"), "#!/usr/bin/env bash\nexit 0\n", { @@ -2571,10 +2571,10 @@ const { createSandbox } = require(${onboardPath}); ); const fakeBin = path.join(tmpDir, "bin"); const scriptPath = path.join(tmpDir, "interactive-decline.js"); - const onboardPath = JSON.stringify(path.join(repoRoot, "src", "lib", "onboard.ts")); - const runnerPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "runner.js")); - const registryPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "registry.js")); - const credentialsPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "credentials.js")); + const onboardPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "onboard.js")); + const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); + const registryPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "registry.js")); + const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials.js")); fs.mkdirSync(fakeBin, { recursive: true }); fs.writeFileSync(path.join(fakeBin, "openshell"), "#!/usr/bin/env bash\nexit 0\n", { @@ -2604,7 +2604,7 @@ registry.getSandbox = () => ({ name: "my-assistant", gpuEnabled: false }); registry.registerSandbox = () => true; registry.removeSandbox = () => true; -const preflight = require(${JSON.stringify(path.join(repoRoot, "bin", "lib", "preflight.js"))}); +const preflight = require(${JSON.stringify(path.join(repoRoot, "dist", "lib", "preflight.js"))}); preflight.checkPortAvailable = async () => ({ ok: true }); // Mock prompt to return "n" (decline reuse) @@ -2684,10 +2684,10 @@ const { createSandbox } = require(${onboardPath}); ); const fakeBin = path.join(tmpDir, "bin"); const scriptPath = path.join(tmpDir, "interactive-notready.js"); - const onboardPath = JSON.stringify(path.join(repoRoot, "src", "lib", "onboard.ts")); - const runnerPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "runner.js")); - const registryPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "registry.js")); - const credentialsPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "credentials.js")); + const onboardPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "onboard.js")); + const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); + const registryPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "registry.js")); + const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials.js")); fs.mkdirSync(fakeBin, { recursive: true }); fs.writeFileSync(path.join(fakeBin, "openshell"), "#!/usr/bin/env bash\nexit 0\n", { @@ -2722,7 +2722,7 @@ registry.getSandbox = () => ({ name: "my-assistant", gpuEnabled: false }); registry.registerSandbox = () => true; registry.removeSandbox = () => true; -const preflight = require(${JSON.stringify(path.join(repoRoot, "bin", "lib", "preflight.js"))}); +const preflight = require(${JSON.stringify(path.join(repoRoot, "dist", "lib", "preflight.js"))}); preflight.checkPortAvailable = async () => ({ ok: true }); // User confirms recreation when prompted @@ -2806,8 +2806,8 @@ const { createSandbox } = require(${onboardPath}); const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "nemoclaw-upsert-provider-create-")); const fakeBin = path.join(tmpDir, "bin"); const scriptPath = path.join(tmpDir, "upsert-provider-create.js"); - const onboardPath = JSON.stringify(path.join(repoRoot, "src", "lib", "onboard.ts")); - const runnerPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "runner.js")); + const onboardPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "onboard.js")); + const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); fs.mkdirSync(fakeBin, { recursive: true }); fs.writeFileSync(path.join(fakeBin, "openshell"), "#!/usr/bin/env bash\nexit 0\n", { @@ -2846,8 +2846,8 @@ console.log(JSON.stringify({ result, commands })); const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "nemoclaw-upsert-no-dup-")); const fakeBin = path.join(tmpDir, "bin"); const scriptPath = path.join(tmpDir, "upsert-no-dup.js"); - const onboardPath = JSON.stringify(path.join(repoRoot, "src", "lib", "onboard.ts")); - const runnerPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "runner.js")); + const onboardPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "onboard.js")); + const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); fs.mkdirSync(fakeBin, { recursive: true }); fs.writeFileSync(path.join(fakeBin, "openshell"), "#!/usr/bin/env bash\nexit 0\n", { @@ -2884,8 +2884,8 @@ upsertProvider("test-bridge", "generic", "TEST_TOKEN", null, { TEST_TOKEN: "tok" const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "nemoclaw-upsert-provider-update-")); const fakeBin = path.join(tmpDir, "bin"); const scriptPath = path.join(tmpDir, "upsert-provider-update.js"); - const onboardPath = JSON.stringify(path.join(repoRoot, "src", "lib", "onboard.ts")); - const runnerPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "runner.js")); + const onboardPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "onboard.js")); + const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); fs.mkdirSync(fakeBin, { recursive: true }); fs.writeFileSync(path.join(fakeBin, "openshell"), "#!/usr/bin/env bash\nexit 0\n", { @@ -2933,8 +2933,8 @@ console.log(JSON.stringify({ result, commands })); const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "nemoclaw-upsert-provider-fail-")); const fakeBin = path.join(tmpDir, "bin"); const scriptPath = path.join(tmpDir, "upsert-provider-fail.js"); - const onboardPath = JSON.stringify(path.join(repoRoot, "src", "lib", "onboard.ts")); - const runnerPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "runner.js")); + const onboardPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "onboard.js")); + const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); fs.mkdirSync(fakeBin, { recursive: true }); fs.writeFileSync(path.join(fakeBin, "openshell"), "#!/usr/bin/env bash\nexit 0\n", { @@ -2970,8 +2970,8 @@ console.log(JSON.stringify(result)); const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "nemoclaw-provider-exists-true-")); const fakeBin = path.join(tmpDir, "bin"); const scriptPath = path.join(tmpDir, "provider-exists-true.js"); - const onboardPath = JSON.stringify(path.join(repoRoot, "src", "lib", "onboard.ts")); - const runnerPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "runner.js")); + const onboardPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "onboard.js")); + const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); fs.mkdirSync(fakeBin, { recursive: true }); fs.writeFileSync(path.join(fakeBin, "openshell"), "#!/usr/bin/env bash\nexit 0\n", { @@ -3004,8 +3004,8 @@ console.log(JSON.stringify({ exists: providerExistsInGateway("discord-bridge") } const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "nemoclaw-hydrate-cred-")); const fakeBin = path.join(tmpDir, "bin"); const scriptPath = path.join(tmpDir, "hydrate-cred.js"); - const onboardPath = JSON.stringify(path.join(repoRoot, "src", "lib", "onboard.ts")); - const credentialsPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "credentials.js")); + const onboardPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "onboard.js")); + const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials.js")); fs.mkdirSync(fakeBin, { recursive: true }); fs.writeFileSync(path.join(fakeBin, "openshell"), "#!/usr/bin/env bash\nexit 0\n", { @@ -3064,8 +3064,8 @@ console.log(JSON.stringify({ const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "nemoclaw-provider-exists-false-")); const fakeBin = path.join(tmpDir, "bin"); const scriptPath = path.join(tmpDir, "provider-exists-false.js"); - const onboardPath = JSON.stringify(path.join(repoRoot, "src", "lib", "onboard.ts")); - const runnerPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "runner.js")); + const onboardPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "onboard.js")); + const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); fs.mkdirSync(fakeBin, { recursive: true }); fs.writeFileSync(path.join(fakeBin, "openshell"), "#!/usr/bin/env bash\nexit 0\n", { @@ -3099,11 +3099,11 @@ console.log(JSON.stringify({ exists: providerExistsInGateway("nonexistent") })); const fakeBin = path.join(tmpDir, "bin"); const scriptPath = path.join(tmpDir, "create-sandbox-ready-check.js"); const payloadPath = path.join(tmpDir, "payload.json"); - const onboardPath = JSON.stringify(path.join(repoRoot, "src", "lib", "onboard.ts")); - const runnerPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "runner.js")); - const registryPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "registry.js")); - const preflightPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "preflight.js")); - const credentialsPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "credentials.js")); + const onboardPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "onboard.js")); + const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); + const registryPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "registry.js")); + const preflightPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "preflight.js")); + const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials.js")); fs.mkdirSync(fakeBin, { recursive: true }); fs.writeFileSync(path.join(fakeBin, "openshell"), "#!/usr/bin/env bash\nexit 0\n", { @@ -3220,9 +3220,9 @@ const { createSandbox } = require(${onboardPath}); const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "nemoclaw-onboard-reuse-forward-")); const fakeBin = path.join(tmpDir, "bin"); const scriptPath = path.join(tmpDir, "reuse-sandbox-forward.js"); - const onboardPath = JSON.stringify(path.join(repoRoot, "src", "lib", "onboard.ts")); - const runnerPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "runner.js")); - const registryPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "registry.js")); + const onboardPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "onboard.js")); + const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); + const registryPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "registry.js")); fs.mkdirSync(fakeBin, { recursive: true }); fs.writeFileSync(path.join(fakeBin, "openshell"), "#!/usr/bin/env bash\nexit 0\n", { @@ -3342,9 +3342,9 @@ const { createSandbox } = require(${onboardPath}); const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "nemoclaw-onboard-inference-get-")); const fakeBin = path.join(tmpDir, "bin"); const scriptPath = path.join(tmpDir, "inference-get-check.js"); - const onboardPath = JSON.stringify(path.join(repoRoot, "src", "lib", "onboard.ts")); - const runnerPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "runner.js")); - const registryPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "registry.js")); + const onboardPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "onboard.js")); + const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); + const registryPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "registry.js")); fs.mkdirSync(fakeBin, { recursive: true }); fs.writeFileSync(path.join(fakeBin, "openshell"), "#!/usr/bin/env bash\nexit 0\n", { @@ -3412,9 +3412,9 @@ const { setupInference } = require(${onboardPath}); const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "nemoclaw-onboard-inference-route-")); const fakeBin = path.join(tmpDir, "bin"); const scriptPath = path.join(tmpDir, "inference-route-check.js"); - const onboardPath = JSON.stringify(path.join(repoRoot, "src", "lib", "onboard.ts")); - const runnerPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "runner.js")); - const registryPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "registry.js")); + const onboardPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "onboard.js")); + const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); + const registryPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "registry.js")); fs.mkdirSync(fakeBin, { recursive: true }); fs.writeFileSync(path.join(fakeBin, "openshell"), "#!/usr/bin/env bash\nexit 0\n", { @@ -3486,11 +3486,11 @@ const { setupInference } = require(${onboardPath}); ); const fakeBin = path.join(tmpDir, "bin"); const scriptPath = path.join(tmpDir, "enabled-channels-filter.js"); - const onboardPath = JSON.stringify(path.join(repoRoot, "src", "lib", "onboard.ts")); - const runnerPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "runner.js")); - const registryPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "registry.js")); - const preflightPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "preflight.js")); - const credentialsPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "credentials.js")); + const onboardPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "onboard.js")); + const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); + const registryPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "registry.js")); + const preflightPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "preflight.js")); + const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials.js")); fs.mkdirSync(fakeBin, { recursive: true }); fs.writeFileSync(path.join(fakeBin, "openshell"), "#!/usr/bin/env bash\nexit 0\n", { @@ -3613,11 +3613,11 @@ const { createSandbox } = require(${onboardPath}); ); const fakeBin = path.join(tmpDir, "bin"); const scriptPath = path.join(tmpDir, "enabled-channels-empty.js"); - const onboardPath = JSON.stringify(path.join(repoRoot, "src", "lib", "onboard.ts")); - const runnerPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "runner.js")); - const registryPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "registry.js")); - const preflightPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "preflight.js")); - const credentialsPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "credentials.js")); + const onboardPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "onboard.js")); + const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); + const registryPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "registry.js")); + const preflightPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "preflight.js")); + const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials.js")); fs.mkdirSync(fakeBin, { recursive: true }); fs.writeFileSync(path.join(fakeBin, "openshell"), "#!/usr/bin/env bash\nexit 0\n", { @@ -3730,8 +3730,8 @@ const { createSandbox } = require(${onboardPath}); ); const fakeBin = path.join(tmpDir, "bin"); const scriptPath = path.join(tmpDir, "messaging-noninteractive.js"); - const onboardPath = JSON.stringify(path.join(repoRoot, "src", "lib", "onboard.ts")); - const runnerPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "runner.js")); + const onboardPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "onboard.js")); + const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); fs.mkdirSync(fakeBin, { recursive: true }); fs.writeFileSync(path.join(fakeBin, "openshell"), "#!/usr/bin/env bash\nexit 0\n", { @@ -3791,8 +3791,8 @@ const { setupMessagingChannels } = require(${onboardPath}); ); const fakeBin = path.join(tmpDir, "bin"); const scriptPath = path.join(tmpDir, "messaging-no-tokens.js"); - const onboardPath = JSON.stringify(path.join(repoRoot, "src", "lib", "onboard.ts")); - const runnerPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "runner.js")); + const onboardPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "onboard.js")); + const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); fs.mkdirSync(fakeBin, { recursive: true }); fs.writeFileSync(path.join(fakeBin, "openshell"), "#!/usr/bin/env bash\nexit 0\n", { @@ -3848,11 +3848,11 @@ const { setupMessagingChannels } = require(${onboardPath}); const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "nemoclaw-onboard-from-dockerfile-")); const fakeBin = path.join(tmpDir, "bin"); const scriptPath = path.join(tmpDir, "create-sandbox-from.js"); - const onboardPath = JSON.stringify(path.join(repoRoot, "src", "lib", "onboard.ts")); - const runnerPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "runner.js")); - const registryPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "registry.js")); - const preflightPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "preflight.js")); - const credentialsPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "credentials.js")); + const onboardPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "onboard.js")); + const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); + const registryPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "registry.js")); + const preflightPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "preflight.js")); + const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials.js")); // Create a minimal custom Dockerfile in a temporary directory const customBuildDir = path.join(tmpDir, "custom-image"); @@ -3975,11 +3975,11 @@ const { createSandbox } = require(${onboardPath}); const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "nemoclaw-onboard-from-missing-")); const fakeBin = path.join(tmpDir, "bin"); const scriptPath = path.join(tmpDir, "create-sandbox-missing.js"); - const onboardPath = JSON.stringify(path.join(repoRoot, "src", "lib", "onboard.ts")); - const runnerPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "runner.js")); - const registryPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "registry.js")); - const preflightPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "preflight.js")); - const credentialsPath = JSON.stringify(path.join(repoRoot, "bin", "lib", "credentials.js")); + const onboardPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "onboard.js")); + const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); + const registryPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "registry.js")); + const preflightPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "preflight.js")); + const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials.js")); fs.mkdirSync(fakeBin, { recursive: true }); fs.writeFileSync(path.join(fakeBin, "openshell"), "#!/usr/bin/env bash\nexit 0\n", { diff --git a/test/platform.test.ts b/test/platform.test.ts index 72589ebf849..210db909dd0 100644 --- a/test/platform.test.ts +++ b/test/platform.test.ts @@ -13,7 +13,7 @@ import { inferContainerRuntime, isWsl, shouldPatchCoredns, -} from "../bin/lib/platform"; +} from "../dist/lib/platform"; describe("platform helpers", () => { describe("isWsl", () => { diff --git a/test/policies.test.ts b/test/policies.test.ts index 100e58ca830..8f392392ae1 100644 --- a/test/policies.test.ts +++ b/test/policies.test.ts @@ -8,13 +8,13 @@ import os from "node:os"; import path from "node:path"; import { describe, it, expect, vi } from "vitest"; import { spawnSync } from "node:child_process"; -import policies from "../bin/lib/policies"; +import policies from "../dist/lib/policies"; const REPO_ROOT = path.join(import.meta.dirname, ".."); const CLI_PATH = JSON.stringify(path.join(REPO_ROOT, "bin", "nemoclaw.js")); -const CREDENTIALS_PATH = JSON.stringify(path.join(REPO_ROOT, "bin", "lib", "credentials.js")); -const POLICIES_PATH = JSON.stringify(path.join(REPO_ROOT, "bin", "lib", "policies.js")); -const REGISTRY_PATH = JSON.stringify(path.join(REPO_ROOT, "bin", "lib", "registry.js")); +const CREDENTIALS_PATH = JSON.stringify(path.join(REPO_ROOT, "dist", "lib", "credentials.js")); +const POLICIES_PATH = JSON.stringify(path.join(REPO_ROOT, "dist", "lib", "policies.js")); +const REGISTRY_PATH = JSON.stringify(path.join(REPO_ROOT, "dist", "lib", "registry.js")); const SELECT_FROM_LIST_ITEMS = [ { name: "npm", description: "npm and Yarn registry access" }, { name: "pypi", description: "Python Package Index (PyPI) access" }, diff --git a/test/presets-checkbox.test.ts b/test/presets-checkbox.test.ts index f457c9edb82..cdf4c3ff43e 100644 --- a/test/presets-checkbox.test.ts +++ b/test/presets-checkbox.test.ts @@ -7,8 +7,8 @@ import path from "node:path"; import { spawnSync } from "node:child_process"; const REPO_ROOT = path.join(import.meta.dirname, ".."); -const ONBOARD_PATH = JSON.stringify(path.join(REPO_ROOT, "bin", "lib", "onboard.js")); -const CREDENTIALS_PATH = JSON.stringify(path.join(REPO_ROOT, "bin", "lib", "credentials.js")); +const ONBOARD_PATH = JSON.stringify(path.join(REPO_ROOT, "dist", "lib", "onboard.js")); +const CREDENTIALS_PATH = JSON.stringify(path.join(REPO_ROOT, "dist", "lib", "credentials.js")); const SAMPLE_PRESETS = [ { name: "npm", description: "npm and Yarn registry access" }, diff --git a/test/registry.test.ts b/test/registry.test.ts index 0a736502be0..82f19196b55 100644 --- a/test/registry.test.ts +++ b/test/registry.test.ts @@ -15,7 +15,7 @@ const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "nemoclaw-test-")); process.env.HOME = tmpDir; const require = createRequire(import.meta.url); -const registry = require("../bin/lib/registry"); +const registry = require("../dist/lib/registry"); const regFile = path.join(tmpDir, ".nemoclaw", "sandboxes.json"); @@ -265,7 +265,7 @@ describe("advisory file locking", () => { it("concurrent writers do not corrupt the registry", () => { const { spawnSync } = require("child_process"); const registryPath = path.resolve( - path.join(import.meta.dirname, "..", "bin", "lib", "registry.js"), + path.join(import.meta.dirname, "..", "dist", "lib", "registry.js"), ); const homeDir = path.dirname(path.dirname(regFile)); // Script that spawns 4 workers in parallel, each writing 5 sandboxes diff --git a/test/resolve-openshell.test.ts b/test/resolve-openshell.test.ts index 3bc343729fa..91cbbeb38a6 100644 --- a/test/resolve-openshell.test.ts +++ b/test/resolve-openshell.test.ts @@ -4,7 +4,7 @@ import { describe, expect, it } from "vitest"; -import { resolveOpenshell } from "../bin/lib/resolve-openshell"; +import { resolveOpenshell } from "../dist/lib/resolve-openshell"; describe("resolveOpenshell", () => { it("returns an absolute command -v result immediately", () => { diff --git a/test/runner.test.ts b/test/runner.test.ts index d93a72868c8..c5009996c52 100644 --- a/test/runner.test.ts +++ b/test/runner.test.ts @@ -9,9 +9,9 @@ import os from "node:os"; import path from "node:path"; import { describe, expect, it, vi } from "vitest"; -import { runCapture } from "../bin/lib/runner"; +import { runCapture } from "../dist/lib/runner"; -const runnerPath = path.join(import.meta.dirname, "..", "bin", "lib", "runner"); +const runnerPath = path.join(import.meta.dirname, "..", "dist", "lib", "runner.js"); describe("runner helpers", () => { it("does not let child commands consume installer stdin", () => { diff --git a/test/sandbox-build-context.test.ts b/test/sandbox-build-context.test.ts index 54ed9a93235..da8d6e520ed 100644 --- a/test/sandbox-build-context.test.ts +++ b/test/sandbox-build-context.test.ts @@ -11,7 +11,7 @@ import { collectBuildContextStats, stageLegacySandboxBuildContext, stageOptimizedSandboxBuildContext, -} from "../bin/lib/sandbox-build-context"; +} from "../dist/lib/sandbox-build-context"; describe("sandbox build context staging", () => { it("optimized staging excludes blueprint .venv and extra scripts while preserving required files", () => { diff --git a/test/service-env.test.ts b/test/service-env.test.ts index d58c4d1eab5..2ba9b1d9626 100644 --- a/test/service-env.test.ts +++ b/test/service-env.test.ts @@ -7,8 +7,8 @@ import { execSync, execFileSync } from "node:child_process"; import { mkdtempSync, writeFileSync, unlinkSync, readFileSync, lstatSync } from "node:fs"; import { tmpdir } from "node:os"; import { join } from "node:path"; -import { resolveOpenshell } from "../bin/lib/resolve-openshell"; -import { parseAllowedChatIds, isChatAllowed } from "../bin/lib/chat-filter.js"; +import { resolveOpenshell } from "../dist/lib/resolve-openshell"; +import { parseAllowedChatIds, isChatAllowed } from "../dist/lib/chat-filter.js"; describe("service environment", () => { describe("start-services behavior", () => { diff --git a/test/ssh-known-hosts.test.ts b/test/ssh-known-hosts.test.ts index ac7fb5d2e83..736dbda424c 100644 --- a/test/ssh-known-hosts.test.ts +++ b/test/ssh-known-hosts.test.ts @@ -3,7 +3,7 @@ // SPDX-License-Identifier: Apache-2.0 import { describe, it, expect } from "vitest"; -import { pruneKnownHostsEntries } from "../bin/lib/onboard"; +import { pruneKnownHostsEntries } from "../dist/lib/onboard"; describe("pruneKnownHostsEntries", () => { it("removes lines with openshell- hostnames", () => { From c4e145124acbdf665f866dc5d21f6f862c32a815 Mon Sep 17 00:00:00 2001 From: Carlos Villela Date: Thu, 9 Apr 2026 15:28:32 -0700 Subject: [PATCH 2/4] fix(ci): guard removed compatibility shims Signed-off-by: Carlos Villela --- .github/workflows/legacy-path-guard.yaml | 2 +- scripts/check-legacy-migrated-paths.ts | 49 +++++++++++++++++++++--- scripts/ts-migration/README.md | 2 +- 3 files changed, 46 insertions(+), 7 deletions(-) diff --git a/.github/workflows/legacy-path-guard.yaml b/.github/workflows/legacy-path-guard.yaml index 7dcdf778d13..a8d82ed2513 100644 --- a/.github/workflows/legacy-path-guard.yaml +++ b/.github/workflows/legacy-path-guard.yaml @@ -9,7 +9,7 @@ on: jobs: guard-migrated-paths: - name: block edits to migrated legacy paths + name: block edits to migrated legacy paths and removed shims if: ${{ github.base_ref == 'main' && !startsWith(github.head_ref, 'ts-migration/') }} runs-on: ubuntu-latest diff --git a/scripts/check-legacy-migrated-paths.ts b/scripts/check-legacy-migrated-paths.ts index 69b83400b4c..c4820b1b3b3 100644 --- a/scripts/check-legacy-migrated-paths.ts +++ b/scripts/check-legacy-migrated-paths.ts @@ -10,7 +10,32 @@ type Options = { head: string; }; +type ChangedFile = { + status: string; + filePath: string; +}; + const RUNTIME_MOVES = moveMap.runtimeMoves as Record; +const REMOVED_SHIM_MOVES: Record = { + "bin/lib/chat-filter.js": "src/lib/chat-filter.ts", + "bin/lib/config-io.js": "src/lib/config-io.ts", + "bin/lib/debug.js": "src/lib/debug.ts", + "bin/lib/inference-config.js": "src/lib/inference-config.ts", + "bin/lib/local-inference.js": "src/lib/local-inference.ts", + "bin/lib/nim.js": "src/lib/nim.ts", + "bin/lib/onboard-session.js": "src/lib/onboard-session.ts", + "bin/lib/platform.js": "src/lib/platform.ts", + "bin/lib/preflight.js": "src/lib/preflight.ts", + "bin/lib/registry.js": "src/lib/registry.ts", + "bin/lib/resolve-openshell.js": "src/lib/resolve-openshell.ts", + "bin/lib/runtime-recovery.js": "src/lib/runtime-recovery.ts", + "bin/lib/sandbox-build-context.js": "src/lib/sandbox-build-context.ts", + "bin/lib/services.js": "src/lib/services.ts", + "bin/lib/version.js": "src/lib/version.ts", + "bin/lib/onboard.js": "src/lib/onboard.ts", + "bin/lib/policies.js": "src/lib/policies.ts", + "bin/lib/runner.js": "src/lib/runner.ts", +}; function parseArgs(argv: string[]): Options { let base = "origin/main"; @@ -39,25 +64,38 @@ function parseArgs(argv: string[]): Options { } function printHelp() { - console.log(`Usage: npm run ts-migration:guard -- --base origin/main [--head HEAD]\n\nFails when a PR edits legacy migrated JS paths instead of the canonical TS files.`); + console.log(`Usage: npm run ts-migration:guard -- --base origin/main [--head HEAD]\n\nFails when a PR edits migrated legacy JS paths or removed compatibility shims instead of the canonical TS files.`); } function runGit(args: string[]): string { return String(execFileSync("git", args, { encoding: "utf8" })).trim(); } -function getChangedFiles(base: string, head: string): string[] { - const output = runGit(["diff", "--name-only", `${base}...${head}`]); +function getChangedFiles(base: string, head: string): ChangedFile[] { + const output = runGit(["diff", "--name-status", `${base}...${head}`]); if (!output) { return []; } - return output.split("\n").filter(Boolean); + return output + .split("\n") + .filter(Boolean) + .map((line) => { + const [status, ...rest] = line.split("\t"); + return { + status, + filePath: rest[rest.length - 1] || "", + }; + }) + .filter((entry) => Boolean(entry.filePath)); } function canonicalPathFor(filePath: string): string | null { if (filePath in RUNTIME_MOVES) { return RUNTIME_MOVES[filePath]; } + if (filePath in REMOVED_SHIM_MOVES) { + return REMOVED_SHIM_MOVES[filePath]; + } if (/^test\/.*\.test\.js$/.test(filePath)) { return filePath.replace(/\.js$/, ".ts"); } @@ -74,7 +112,8 @@ function main() { const changedFiles = getChangedFiles(options.base, options.head); const legacyEdits = changedFiles - .map((filePath) => ({ filePath, canonical: canonicalPathFor(filePath) })) + .filter((entry) => !entry.status.startsWith("D")) + .map((entry) => ({ filePath: entry.filePath, canonical: canonicalPathFor(entry.filePath) })) .filter((entry) => entry.canonical !== null); if (legacyEdits.length === 0) { diff --git a/scripts/ts-migration/README.md b/scripts/ts-migration/README.md index e7c94a1a5cb..ec242e781e3 100644 --- a/scripts/ts-migration/README.md +++ b/scripts/ts-migration/README.md @@ -3,7 +3,7 @@ # Post-migration rescue tooling -These helpers exist for the period after the root CLI JS→TS migration lands on `main`. +These helpers exist for the period after the root CLI JS→TS migration lands on `main`. The CI guard also blocks edits that try to resurrect removed `bin/lib/*.js` compatibility shims; contributors should edit the canonical TS files instead. ## Files From cc12762fdab58b57d75b7b3ac08a2ef78ebf66d1 Mon Sep 17 00:00:00 2001 From: Carlos Villela Date: Thu, 9 Apr 2026 15:33:12 -0700 Subject: [PATCH 3/4] fix(ci): clarify shim guard failures Signed-off-by: Carlos Villela --- scripts/check-legacy-migrated-paths.ts | 53 ++++++++++++++++++++------ 1 file changed, 42 insertions(+), 11 deletions(-) diff --git a/scripts/check-legacy-migrated-paths.ts b/scripts/check-legacy-migrated-paths.ts index c4820b1b3b3..fbd0b147735 100644 --- a/scripts/check-legacy-migrated-paths.ts +++ b/scripts/check-legacy-migrated-paths.ts @@ -15,6 +15,12 @@ type ChangedFile = { filePath: string; }; +type GuardedPath = { + filePath: string; + canonical: string; + kind: "migrated-runtime" | "removed-shim" | "migrated-test"; +}; + const RUNTIME_MOVES = moveMap.runtimeMoves as Record; const REMOVED_SHIM_MOVES: Record = { "bin/lib/chat-filter.js": "src/lib/chat-filter.ts", @@ -89,15 +95,27 @@ function getChangedFiles(base: string, head: string): ChangedFile[] { .filter((entry) => Boolean(entry.filePath)); } -function canonicalPathFor(filePath: string): string | null { +function classifyGuardedPath(filePath: string): GuardedPath | null { if (filePath in RUNTIME_MOVES) { - return RUNTIME_MOVES[filePath]; + return { + filePath, + canonical: RUNTIME_MOVES[filePath], + kind: "migrated-runtime", + }; } if (filePath in REMOVED_SHIM_MOVES) { - return REMOVED_SHIM_MOVES[filePath]; + return { + filePath, + canonical: REMOVED_SHIM_MOVES[filePath], + kind: "removed-shim", + }; } if (/^test\/.*\.test\.js$/.test(filePath)) { - return filePath.replace(/\.js$/, ".ts"); + return { + filePath, + canonical: filePath.replace(/\.js$/, ".ts"), + kind: "migrated-test", + }; } return null; } @@ -113,19 +131,32 @@ function main() { const changedFiles = getChangedFiles(options.base, options.head); const legacyEdits = changedFiles .filter((entry) => !entry.status.startsWith("D")) - .map((entry) => ({ filePath: entry.filePath, canonical: canonicalPathFor(entry.filePath) })) - .filter((entry) => entry.canonical !== null); + .map((entry) => classifyGuardedPath(entry.filePath)) + .filter((entry): entry is GuardedPath => entry !== null); if (legacyEdits.length === 0) { - console.log("No edits to migrated legacy paths detected."); + console.log("No edits to migrated legacy paths or removed compatibility shims detected."); return; } - console.error("Legacy migrated paths were edited in this PR."); + const migratedPaths = legacyEdits.filter((entry) => entry.kind !== "removed-shim"); + const removedShims = legacyEdits.filter((entry) => entry.kind === "removed-shim"); + + console.error("Guarded legacy paths were edited in this PR."); console.error(""); - console.error("Edit the canonical TS files instead:"); - for (const entry of legacyEdits) { - console.error(` ${entry.filePath} -> ${entry.canonical}`); + if (migratedPaths.length > 0) { + console.error("Migrated legacy paths must be edited via their canonical TS files:"); + for (const entry of migratedPaths) { + console.error(` ${entry.filePath} -> ${entry.canonical}`); + } + console.error(""); + } + if (removedShims.length > 0) { + console.error("Removed compatibility shims must not be reintroduced or edited directly:"); + for (const entry of removedShims) { + console.error(` ${entry.filePath} -> ${entry.canonical}`); + } + console.error(""); } console.error(""); console.error("To port a stale branch automatically, run:"); From a453af5806d063f35a3d0b3b54a5bb48810139c6 Mon Sep 17 00:00:00 2001 From: Carlos Villela Date: Thu, 9 Apr 2026 15:42:21 -0700 Subject: [PATCH 4/4] fix(ci): detect renamed shim edits Signed-off-by: Carlos Villela --- scripts/check-legacy-migrated-paths.ts | 36 +++++++++------ test/legacy-path-guard.test.ts | 62 ++++++++++++++++++++++++++ 2 files changed, 84 insertions(+), 14 deletions(-) create mode 100644 test/legacy-path-guard.test.ts diff --git a/scripts/check-legacy-migrated-paths.ts b/scripts/check-legacy-migrated-paths.ts index fbd0b147735..c4b4f2cbabc 100644 --- a/scripts/check-legacy-migrated-paths.ts +++ b/scripts/check-legacy-migrated-paths.ts @@ -12,7 +12,8 @@ type Options = { type ChangedFile = { status: string; - filePath: string; + oldPath: string | null; + newPath: string; }; type GuardedPath = { @@ -86,28 +87,30 @@ function getChangedFiles(base: string, head: string): ChangedFile[] { .split("\n") .filter(Boolean) .map((line) => { - const [status, ...rest] = line.split("\t"); + const [status = "", firstPath = "", secondPath = ""] = line.split("\t"); + const isRenameOrCopy = /^[RC]/.test(status); return { status, - filePath: rest[rest.length - 1] || "", + oldPath: isRenameOrCopy ? firstPath : null, + newPath: isRenameOrCopy ? secondPath : firstPath, }; }) - .filter((entry) => Boolean(entry.filePath)); + .filter((entry) => Boolean(entry.newPath)); } function classifyGuardedPath(filePath: string): GuardedPath | null { - if (filePath in RUNTIME_MOVES) { + if (filePath in REMOVED_SHIM_MOVES) { return { filePath, - canonical: RUNTIME_MOVES[filePath], - kind: "migrated-runtime", + canonical: REMOVED_SHIM_MOVES[filePath], + kind: "removed-shim", }; } - if (filePath in REMOVED_SHIM_MOVES) { + if (filePath in RUNTIME_MOVES) { return { filePath, - canonical: REMOVED_SHIM_MOVES[filePath], - kind: "removed-shim", + canonical: RUNTIME_MOVES[filePath], + kind: "migrated-runtime", }; } if (/^test\/.*\.test\.js$/.test(filePath)) { @@ -129,10 +132,15 @@ function main() { } const changedFiles = getChangedFiles(options.base, options.head); - const legacyEdits = changedFiles - .filter((entry) => !entry.status.startsWith("D")) - .map((entry) => classifyGuardedPath(entry.filePath)) - .filter((entry): entry is GuardedPath => entry !== null); + const legacyEdits = Array.from( + new Map( + changedFiles + .filter((entry) => !entry.status.startsWith("D")) + .flatMap((entry) => [entry.oldPath, entry.newPath]) + .filter((filePath): filePath is string => Boolean(filePath)) + .map((filePath) => [filePath, classifyGuardedPath(filePath)]), + ).values(), + ).filter((entry): entry is GuardedPath => entry !== null); if (legacyEdits.length === 0) { console.log("No edits to migrated legacy paths or removed compatibility shims detected."); diff --git a/test/legacy-path-guard.test.ts b/test/legacy-path-guard.test.ts new file mode 100644 index 00000000000..30a977ca187 --- /dev/null +++ b/test/legacy-path-guard.test.ts @@ -0,0 +1,62 @@ +// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 + +import { spawnSync } from "node:child_process"; +import fs from "node:fs"; +import os from "node:os"; +import path from "node:path"; + +import { describe, expect, it } from "vitest"; + +const REPO_ROOT = path.join(import.meta.dirname, ".."); +const TSX = path.join(REPO_ROOT, "node_modules", ".bin", "tsx"); +const GUARD_SCRIPT = path.join(REPO_ROOT, "scripts", "check-legacy-migrated-paths.ts"); + +function run(command: string, args: string[], cwd: string) { + const result = spawnSync(command, args, { + cwd, + encoding: "utf-8", + }); + if (result.status !== 0) { + throw new Error(`${command} ${args.join(" ")} failed:\n${result.stderr || result.stdout}`); + } +} + +function initTempRepo(prefix: string): string { + const repoDir = fs.mkdtempSync(path.join(os.tmpdir(), prefix)); + run("git", ["init", "-b", "main"], repoDir); + run("git", ["config", "user.name", "Test User"], repoDir); + run("git", ["config", "user.email", "test@example.com"], repoDir); + return repoDir; +} + +describe("ts-migration:guard", () => { + it("blocks renaming a removed shim by checking the source path in R entries", { timeout: 15000 }, () => { + const repoDir = initTempRepo("nemoclaw-legacy-guard-"); + const originalPath = path.join(repoDir, "bin", "lib", "runner.js"); + const renamedPath = path.join(repoDir, "tmp", "runner.js"); + + fs.mkdirSync(path.dirname(originalPath), { recursive: true }); + fs.writeFileSync(originalPath, "module.exports = {};\n"); + run("git", ["add", "."], repoDir); + run("git", ["commit", "-m", "base"], repoDir); + + run("git", ["checkout", "-b", "feature"], repoDir); + fs.mkdirSync(path.dirname(renamedPath), { recursive: true }); + run("git", ["mv", "bin/lib/runner.js", "tmp/runner.js"], repoDir); + run("git", ["commit", "-m", "rename shim"], repoDir); + + const result = spawnSync(TSX, [GUARD_SCRIPT, "--base", "main", "--head", "HEAD"], { + cwd: repoDir, + encoding: "utf-8", + }); + + expect(result.status).toBe(1); + expect(`${result.stdout}${result.stderr}`).toContain( + "Removed compatibility shims must not be reintroduced or edited directly:", + ); + expect(`${result.stdout}${result.stderr}`).toContain( + "bin/lib/runner.js -> src/lib/runner.ts", + ); + }); +});