diff --git a/.coderabbit.yaml b/.coderabbit.yaml index 2a7742140e9..3b5a58edbf7 100644 --- a/.coderabbit.yaml +++ b/.coderabbit.yaml @@ -251,7 +251,7 @@ reviews: gh workflow run nightly-e2e.yaml --ref -f jobs=snapshot-commands-e2e,rebuild-openclaw-e2e ``` - - path: "src/lib/shields*.ts" + - path: "src/lib/shields/**" instructions: | These files control shields down/up, config mutability, audit trail, and auto-restore timer. diff --git a/bin/lib/agent-defs.js b/bin/lib/agent-defs.js index 086c5bcc4ce..ce13367a1e1 100644 --- a/bin/lib/agent-defs.js +++ b/bin/lib/agent-defs.js @@ -1,7 +1,7 @@ // 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/agent-defs.ts, -// compiled to dist/lib/agent-defs.js. +// Thin re-export shim — the implementation lives in src/lib/agent/defs.ts, +// compiled to dist/lib/agent/defs.js. -module.exports = require("../../dist/lib/agent-defs"); +module.exports = require("../../dist/lib/agent/defs"); diff --git a/bin/lib/agent-onboard.js b/bin/lib/agent-onboard.js index 94cd467c8cf..70257c589af 100644 --- a/bin/lib/agent-onboard.js +++ b/bin/lib/agent-onboard.js @@ -1,7 +1,7 @@ // 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/agent-onboard.ts, -// compiled to dist/lib/agent-onboard.js. +// Thin re-export shim — the implementation lives in src/lib/agent/onboard.ts, +// compiled to dist/lib/agent/onboard.js. -module.exports = require("../../dist/lib/agent-onboard"); +module.exports = require("../../dist/lib/agent/onboard"); diff --git a/bin/lib/agent-runtime.js b/bin/lib/agent-runtime.js index 447eee0dc81..9ca1b64020e 100644 --- a/bin/lib/agent-runtime.js +++ b/bin/lib/agent-runtime.js @@ -1,7 +1,7 @@ // 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/agent-runtime.ts, -// compiled to dist/lib/agent-runtime.js. +// Thin re-export shim — the implementation lives in src/lib/agent/runtime.ts, +// compiled to dist/lib/agent/runtime.js. -module.exports = require("../../dist/lib/agent-runtime"); +module.exports = require("../../dist/lib/agent/runtime"); diff --git a/bin/lib/credentials.js b/bin/lib/credentials.js index aed63507308..f8f6acfb0c7 100644 --- a/bin/lib/credentials.js +++ b/bin/lib/credentials.js @@ -1,10 +1,10 @@ // 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/credentials.ts, -// compiled to dist/lib/credentials.js. +// Thin re-export shim — the implementation lives in src/lib/credentials/store.ts, +// compiled to dist/lib/credentials/store.js. -const mod = require("../../dist/lib/credentials"); +const mod = require("../../dist/lib/credentials/store"); const exports_ = { ...mod }; diff --git a/bin/lib/ports.js b/bin/lib/ports.js index f6106f4a229..8e058a6f16c 100644 --- a/bin/lib/ports.js +++ b/bin/lib/ports.js @@ -5,4 +5,4 @@ // Override any port via environment variables. // Based on the approach from jnun (PR #683). -module.exports = require("../../dist/lib/ports"); +module.exports = require("../../dist/lib/core/ports"); diff --git a/scripts/check-legacy-migrated-paths.ts b/scripts/check-legacy-migrated-paths.ts index 2368b01a7a1..afb99782136 100644 --- a/scripts/check-legacy-migrated-paths.ts +++ b/scripts/check-legacy-migrated-paths.ts @@ -26,10 +26,10 @@ const RUNTIME_MOVES: Record = moveMap.runtimeMoves; const REMOVED_SHIM_MOVES: Record = { "bin/lib/chat-filter.js": "src/lib/chat-filter.ts", "bin/lib/config-io.js": "src/lib/state/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/debug.js": "src/lib/diagnostics/debug.ts", + "bin/lib/inference-config.js": "src/lib/inference/config.ts", + "bin/lib/local-inference.js": "src/lib/inference/local.ts", + "bin/lib/nim.js": "src/lib/inference/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", @@ -38,7 +38,7 @@ const REMOVED_SHIM_MOVES: Record = { "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/version.js": "src/lib/core/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", diff --git a/scripts/dev-tier-selector.js b/scripts/dev-tier-selector.js index 38b1d01aca5..49aa6884292 100644 --- a/scripts/dev-tier-selector.js +++ b/scripts/dev-tier-selector.js @@ -18,7 +18,7 @@ const readline = require("readline"); // ── Stubs ────────────────────────────────────────────────────────────────── -const creds = require("../dist/lib/credentials.js"); +const creds = require("../dist/lib/credentials/store.js"); const runner = require("../dist/lib/runner.js"); const registry = require("../dist/lib/state/registry.js"); diff --git a/scripts/generate-openclaw-config.py b/scripts/generate-openclaw-config.py index a37852f1c38..48df4187f86 100755 --- a/scripts/generate-openclaw-config.py +++ b/scripts/generate-openclaw-config.py @@ -69,7 +69,7 @@ def _coerce_positive_int(env: dict, name: str, default: int) -> int: def is_loopback(hostname: str) -> bool: """Check if a hostname is a loopback address. - Mirrors isLoopbackHostname() from src/lib/url-utils.ts. + Mirrors isLoopbackHostname() from src/lib/core/url-utils.ts. Returns True for localhost, ::1, and 127.x.x.x addresses. """ normalized = (hostname or "").strip().lower().strip("[]") diff --git a/scripts/ts-migration-assist.ts b/scripts/ts-migration-assist.ts index 410283a00db..d0d5d5a0b2f 100644 --- a/scripts/ts-migration-assist.ts +++ b/scripts/ts-migration-assist.ts @@ -22,13 +22,13 @@ const SPECIAL_REWRITES: Record> = { "bin/lib/onboard.js": [ ['require("./runner")', 'require("../../bin/lib/runner")'], ['require("./sandbox-build-context")', 'require("../../bin/lib/sandbox-build-context")'], - ['require("./local-inference")', 'require("../../bin/lib/local-inference")'], - ['require("./inference-config")', 'require("../../bin/lib/inference-config")'], + ['require("./inference/local")', 'require("../../bin/lib/local-inference")'], + ['require("./inference/config")', 'require("../../bin/lib/inference-config")'], ['require("./platform")', 'require("../../bin/lib/platform")'], ['require("./resolve-openshell")', 'require("../../bin/lib/resolve-openshell")'], - ['require("./credentials")', 'require("../../bin/lib/credentials")'], + ['require("./credentials/store")', 'require("../../bin/lib/credentials")'], ['require("./state/registry")', 'require("../../bin/lib/registry")'], - ['require("./nim")', 'require("../../bin/lib/nim")'], + ['require("./inference/nim")', 'require("../../bin/lib/nim")'], ['require("./onboard-session")', 'require("../../bin/lib/onboard-session")'], ['require("./policies")', 'require("../../bin/lib/policies")'], ['require("./usage-notice")', 'require("../../bin/lib/usage-notice")'], @@ -42,15 +42,15 @@ const SPECIAL_REWRITES: Record> = { ['require("./lib/registry")', 'require("../bin/lib/registry")'], ['require("./lib/nim")', 'require("../bin/lib/nim")'], ['require("./lib/policies")', 'require("../bin/lib/policies")'], - ['require("./lib/inference-config")', 'require("../bin/lib/inference-config")'], + ['require("./lib/inference/config")', 'require("../bin/lib/inference-config")'], ['require("./lib/version")', 'require("../bin/lib/version")'], ['require("./lib/onboard-session")', 'require("../bin/lib/onboard-session")'], ['require("./lib/runtime-recovery")', 'require("../bin/lib/runtime-recovery")'], ['require("./lib/usage-notice")', 'require("../bin/lib/usage-notice")'], ['require("./lib/services")', 'require("../bin/lib/services")'], - ['require("./lib/debug")', 'require("../bin/lib/debug")'], - ['require("./lib/debug-command")', 'require("./lib/debug-command")'], - ['require("../dist/lib/debug-command")', 'require("./lib/debug-command")'], + ['require("./lib/debug")', 'require("./lib/diagnostics/debug")'], + ['require("./lib/debug-command")', 'require("./lib/diagnostics/debug-command")'], + ['require("../dist/lib/debug-command")', 'require("./lib/diagnostics/debug-command")'], ['require("../dist/lib/openshell")', 'require("./lib/openshell")'], ['require("../dist/lib/inventory-commands")', 'require("./lib/inventory-commands")'], ['require("../dist/lib/deploy")', 'require("./lib/deploy")'], diff --git a/src/lib/README.md b/src/lib/README.md new file mode 100644 index 00000000000..b7e9a4ece13 --- /dev/null +++ b/src/lib/README.md @@ -0,0 +1,57 @@ + + + +# `src/lib` layout + +`src/lib` is organized by architectural role first, then by product area. Use this map when adding new code or when moving legacy flat modules into clearer homes. + +## Primary layers + +```text +src/lib/commands/** oclif adapter classes and parser glue +src/lib/actions/** workflow orchestration and user-facing command behavior +src/lib/domain/** pure decisions, policy, classification, and planning +src/lib/adapters/** host boundaries: process, fs, Docker, OpenShell, HTTP +src/lib/state/** persisted local state and state-file I/O +src/lib/cli/** CLI framework, metadata, routing, and help infrastructure +src/lib/core/** tiny cross-cutting primitives with minimal dependencies +``` + +Layering rules: + +- Command classes should parse argv and call actions; they should not own product logic. +- Actions may compose domain helpers, adapters, state modules, and output. +- Domain helpers should stay pure and avoid direct process, filesystem, Docker, OpenShell, or network calls. +- Adapters isolate host-boundary calls so actions and tests can inject fakes. +- State modules own persisted local files and registry/session I/O. + +## Transitional feature folders + +Some older modules are still too large or coupled to split directly into actions/domain/adapters. Use these feature folders as intermediate homes while preserving behavior: + +```text +src/lib/agent/** agent definition, agent-specific onboarding, runtime helpers +src/lib/credentials/** credential storage and credential command support +src/lib/dashboard/** dashboard contract, health, and recovery helpers +src/lib/deploy/** deploy/build-image support that is not yet action-shaped +src/lib/diagnostics/** debug collection and diagnostic report helpers +src/lib/inference/** inference config, health probes, local runtime helpers +src/lib/messaging/** channel/messaging policy and message filtering helpers +src/lib/onboard/** onboarding support modules around the large legacy flow +src/lib/policy/** policy preset loading and application support +src/lib/runtime/** sandbox/runtime recovery helpers +src/lib/sandbox/** sandbox config, build, stream, and version support +src/lib/security/** redaction, secret patterns, and credential filtering +src/lib/shields/** shields orchestration, timers, and audit helpers +src/lib/tunnel/** local service/tunnel command support +``` + +Prefer small mechanical PRs that move one cluster at a time. High-import legacy files such as `onboard.ts`, `runner.ts`, `policies.ts`, `nim.ts`, and `services.ts` should either move late or keep temporary compatibility re-export files at their old paths. + +## Suggested migration sequence + +1. Document the target map and conventions before moving more code. +2. Move low-risk feature clusters such as `agent`, `dashboard`, `diagnostics`, and `shields`. +3. Move security/credentials/core helpers. +4. Move inference/model/local-runtime helpers. +5. Move onboarding support files before considering the large `onboard.ts` flow. diff --git a/src/lib/actions/deploy.ts b/src/lib/actions/deploy.ts index 6fc24e2c8e1..267c450a032 100644 --- a/src/lib/actions/deploy.ts +++ b/src/lib/actions/deploy.ts @@ -3,7 +3,7 @@ import { execFileSync, spawnSync } from "node:child_process"; -import { getCredential } from "../credentials"; +import { getCredential } from "../credentials/store"; import { executeDeploy } from "../deploy"; import { ROOT, run, runInteractive, shellQuote, validateName } from "../runner"; diff --git a/src/lib/actions/maintenance.ts b/src/lib/actions/maintenance.ts index e10a589c018..d4fc970bebd 100644 --- a/src/lib/actions/maintenance.ts +++ b/src/lib/actions/maintenance.ts @@ -3,7 +3,7 @@ /* v8 ignore start -- exercised through CLI subprocess maintenance tests. */ -import { prompt as askPrompt } from "../credentials"; +import { prompt as askPrompt } from "../credentials/store"; import { type GarbageCollectImagesOptions, normalizeGarbageCollectImagesOptions, diff --git a/src/lib/actions/onboard.ts b/src/lib/actions/onboard.ts index 133ff026ea4..c5a0b4963a2 100644 --- a/src/lib/actions/onboard.ts +++ b/src/lib/actions/onboard.ts @@ -1,7 +1,7 @@ // SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. // SPDX-License-Identifier: Apache-2.0 -import { listAgents } from "../agent-defs"; +import { listAgents } from "../agent/defs"; import { runDeprecatedOnboardAliasCommand, runOnboardCommand } from "../onboard-command"; import { NOTICE_ACCEPT_ENV, NOTICE_ACCEPT_FLAG } from "../usage-notice"; diff --git a/src/lib/actions/root-help.ts b/src/lib/actions/root-help.ts index c1d39fd3274..127b9106020 100644 --- a/src/lib/actions/root-help.ts +++ b/src/lib/actions/root-help.ts @@ -1,10 +1,10 @@ // SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. // SPDX-License-Identifier: Apache-2.0 -import { AGENT_PRODUCT_NAME, CLI_DISPLAY_NAME, CLI_NAME } from "../branding"; -import { commandsByGroup, visibleCommands, type CommandDef } from "../command-registry"; +import { AGENT_PRODUCT_NAME, CLI_DISPLAY_NAME, CLI_NAME } from "../cli/branding"; +import { commandsByGroup, visibleCommands, type CommandDef } from "../cli/command-registry"; import { getRegisteredOclifCommandSummary } from "../cli/oclif-metadata"; -import { getVersion } from "../version"; +import { getVersion } from "../core/version"; const useColor = !process.env.NO_COLOR && !!process.stdout.isTTY; const trueColor = diff --git a/src/lib/actions/sandbox/connect.ts b/src/lib/actions/sandbox/connect.ts index 8876d2071db..534c4c433ba 100644 --- a/src/lib/actions/sandbox/connect.ts +++ b/src/lib/actions/sandbox/connect.ts @@ -6,9 +6,9 @@ import { spawnSync } from "node:child_process"; import os from "node:os"; -import { CLI_NAME } from "../../branding"; -import { parseGatewayInference } from "../../inference-config"; -import { ensureOllamaAuthProxy } from "../../onboard-ollama-proxy"; +import { CLI_NAME } from "../../cli/branding"; +import { parseGatewayInference } from "../../inference/config"; +import { ensureOllamaAuthProxy } from "../../inference/ollama/proxy"; import { captureOpenshell, getOpenshellBinary, @@ -24,7 +24,7 @@ import { } from "../../state/sandbox-session"; import { checkAndRecoverSandboxProcesses } from "./process-recovery"; import * as sandboxVersion from "../../sandbox-version"; -import { D, G, R, YW } from "../../terminal-style"; +import { D, G, R, YW } from "../../cli/terminal-style"; import { resolveOpenshell } from "../../adapters/openshell/resolve"; const agentRuntime = require("../../../../bin/lib/agent-runtime"); diff --git a/src/lib/actions/sandbox/destroy.ts b/src/lib/actions/sandbox/destroy.ts index 79e27da0537..db02cffa90a 100644 --- a/src/lib/actions/sandbox/destroy.ts +++ b/src/lib/actions/sandbox/destroy.ts @@ -5,8 +5,8 @@ import fs from "node:fs"; -import { CLI_NAME } from "../../branding"; -import { prompt as askPrompt } from "../../credentials"; +import { CLI_NAME } from "../../cli/branding"; +import { prompt as askPrompt } from "../../credentials/store"; import { type DestroySandboxOptions, normalizeDestroySandboxOptions, @@ -14,7 +14,7 @@ import { import * as onboardSession from "../../onboard-session"; import type { Session } from "../../onboard-session"; import { OPENSHELL_PROBE_TIMEOUT_MS } from "../../adapters/openshell/timeouts"; -import { DASHBOARD_PORT } from "../../ports"; +import { DASHBOARD_PORT } from "../../core/ports"; import * as registry from "../../state/registry"; import { resolveOpenshell } from "../../adapters/openshell/resolve"; import { parseLiveSandboxNames } from "../../runtime-recovery"; @@ -27,7 +27,7 @@ import { shouldCleanupGatewayAfterDestroy, shouldStopHostServicesAfterDestroy, } from "../../domain/sandbox/destroy"; -import { G, R, YW } from "../../terminal-style"; +import { G, R, YW } from "../../cli/terminal-style"; type DockerRmi = (tag: string, opts?: { ignoreError?: boolean }) => { status: number | null }; @@ -90,7 +90,7 @@ function cleanupSandboxServices( const sb = registry.getSandbox(sandboxName); if (sb?.provider?.includes("ollama")) { - const { unloadOllamaModels } = require("../../onboard-ollama-proxy"); + const { unloadOllamaModels } = require("../../inference/ollama/proxy"); unloadOllamaModels(); } @@ -187,7 +187,7 @@ export async function destroySandbox( } } - const nim = require("../../nim") as { + const nim = require("../../inference/nim") as { stopNimContainer: (sandboxName: string, opts?: { silent?: boolean }) => void; stopNimContainerByName: (name: string) => void; }; @@ -203,7 +203,7 @@ export async function destroySandbox( } if (sb?.provider?.includes("ollama")) { - const { unloadOllamaModels, killStaleProxy } = require("../../onboard-ollama-proxy"); + const { unloadOllamaModels, killStaleProxy } = require("../../inference/ollama/proxy"); unloadOllamaModels(); killStaleProxy(); } diff --git a/src/lib/actions/sandbox/doctor.ts b/src/lib/actions/sandbox/doctor.ts index 83d17aaa08e..a1c196aec13 100644 --- a/src/lib/actions/sandbox/doctor.ts +++ b/src/lib/actions/sandbox/doctor.ts @@ -7,15 +7,15 @@ import { execFileSync, spawnSync } from "node:child_process"; import fs from "node:fs"; import path from "node:path"; -import { CLI_DISPLAY_NAME, CLI_NAME } from "../../branding"; -import { isErrnoException } from "../../errno"; +import { CLI_DISPLAY_NAME, CLI_NAME } from "../../cli/branding"; +import { isErrnoException } from "../../core/errno"; import { recoverNamedGatewayRuntime } from "../../gateway-runtime-action"; -import { probeProviderHealth } from "../../inference-health"; -import { parseGatewayInference } from "../../inference-config"; +import { probeProviderHealth } from "../../inference/health"; +import { parseGatewayInference } from "../../inference/config"; import { stripAnsi } from "../../adapters/openshell/client"; import { captureOpenshell } from "../../adapters/openshell/runtime"; import { OPENSHELL_PROBE_TIMEOUT_MS } from "../../adapters/openshell/timeouts"; -import { GATEWAY_PORT, OLLAMA_PORT } from "../../ports"; +import { GATEWAY_PORT, OLLAMA_PORT } from "../../core/ports"; import * as registry from "../../state/registry"; import type { SandboxEntry } from "../../state/registry"; import { resolveOpenshell } from "../../adapters/openshell/resolve"; @@ -24,7 +24,7 @@ import { parseLiveSandboxNames } from "../../runtime-recovery"; import * as sandboxVersion from "../../sandbox-version"; import * as shields from "../../shields"; import { buildStatusCommandDeps } from "../../status-command-deps"; -import { B, D, G, R, RD, YW } from "../../terminal-style"; +import { B, D, G, R, RD, YW } from "../../cli/terminal-style"; const agentRuntime = require("../../../../bin/lib/agent-runtime"); diff --git a/src/lib/actions/sandbox/gateway-state.ts b/src/lib/actions/sandbox/gateway-state.ts index d687594275e..b3aecb2ab13 100644 --- a/src/lib/actions/sandbox/gateway-state.ts +++ b/src/lib/actions/sandbox/gateway-state.ts @@ -7,7 +7,7 @@ import fs from "node:fs"; import os from "node:os"; import path from "node:path"; -import { CLI_DISPLAY_NAME, CLI_NAME } from "../../branding"; +import { CLI_DISPLAY_NAME, CLI_NAME } from "../../cli/branding"; import { parseSandboxPhase } from "../../state/gateway"; import { getNamedGatewayLifecycleState, diff --git a/src/lib/actions/sandbox/policy-channel.ts b/src/lib/actions/sandbox/policy-channel.ts index a7766bad35d..493fc6aa70c 100644 --- a/src/lib/actions/sandbox/policy-channel.ts +++ b/src/lib/actions/sandbox/policy-channel.ts @@ -6,9 +6,9 @@ import fs from "node:fs"; import path from "node:path"; -import { CLI_DISPLAY_NAME, CLI_NAME } from "../../branding"; -import { hashCredential } from "../../credential-hash"; -import { getCredential, prompt as askPrompt } from "../../credentials"; +import { CLI_DISPLAY_NAME, CLI_NAME } from "../../cli/branding"; +import { hashCredential } from "../../security/credential-hash"; +import { getCredential, prompt as askPrompt } from "../../credentials/store"; import { recoverNamedGatewayRuntime } from "../../gateway-runtime-action"; const { isNonInteractive } = require("../../onboard") as { isNonInteractive: () => boolean }; const onboardProviders = require("../../onboard-providers"); diff --git a/src/lib/actions/sandbox/process-recovery.ts b/src/lib/actions/sandbox/process-recovery.ts index 3686b28da99..cecdafb6ac2 100644 --- a/src/lib/actions/sandbox/process-recovery.ts +++ b/src/lib/actions/sandbox/process-recovery.ts @@ -8,7 +8,7 @@ import fs from "node:fs"; import os from "node:os"; import path from "node:path"; -import { DASHBOARD_PORT } from "../../ports"; +import { DASHBOARD_PORT } from "../../core/ports"; import { ROOT, shellQuote } from "../../runner"; import { captureOpenshell, @@ -19,8 +19,8 @@ import { } from "../../adapters/openshell/runtime"; import { OPENSHELL_PROBE_TIMEOUT_MS } from "../../adapters/openshell/timeouts"; import { parseForwardList } from "../../state/sandbox-session"; -import { G, R } from "../../terminal-style"; -import { sleepSeconds } from "../../wait"; +import { G, R } from "../../cli/terminal-style"; +import { sleepSeconds } from "../../core/wait"; const agentRuntime = require("../../../../bin/lib/agent-runtime"); diff --git a/src/lib/actions/sandbox/rebuild.ts b/src/lib/actions/sandbox/rebuild.ts index bbc70346b00..bac72a574fd 100644 --- a/src/lib/actions/sandbox/rebuild.ts +++ b/src/lib/actions/sandbox/rebuild.ts @@ -3,8 +3,8 @@ /* v8 ignore start -- exercised through CLI subprocess rebuild tests. */ -import { CLI_NAME } from "../../branding"; -import { prompt as askPrompt } from "../../credentials"; +import { CLI_NAME } from "../../cli/branding"; +import { prompt as askPrompt } from "../../credentials/store"; import { normalizeRebuildSandboxOptions, type RebuildSandboxOptions, @@ -18,10 +18,10 @@ const { LOCAL_INFERENCE_PROVIDERS, REMOTE_PROVIDER_CONFIG } = require("../../onb REMOTE_PROVIDER_CONFIG: Record; }; -import { loadAgent } from "../../agent-defs"; -import { ensureAgentBaseImage } from "../../agent-onboard"; +import { loadAgent } from "../../agent/defs"; +import { ensureAgentBaseImage } from "../../agent/onboard"; import { getSandboxDeleteOutcome } from "../../domain/sandbox/destroy"; -import * as nim from "../../nim"; +import * as nim from "../../inference/nim"; import type { Session } from "../../onboard-session"; import * as onboardSession from "../../onboard-session"; import { captureOpenshell, runOpenshell } from "../../adapters/openshell/runtime"; @@ -37,7 +37,7 @@ import { } from "../../state/sandbox-session"; import * as sandboxState from "../../state/sandbox"; import * as sandboxVersion from "../../sandbox-version"; -import { B, D, G, R, RD as _RD, YW } from "../../terminal-style"; +import { B, D, G, R, RD as _RD, YW } from "../../cli/terminal-style"; const agentRuntime = require("../../../../bin/lib/agent-runtime"); diff --git a/src/lib/actions/sandbox/skill-install.ts b/src/lib/actions/sandbox/skill-install.ts index 19d84768b9e..a671faa0130 100644 --- a/src/lib/actions/sandbox/skill-install.ts +++ b/src/lib/actions/sandbox/skill-install.ts @@ -7,11 +7,11 @@ import fs from "node:fs"; import os from "node:os"; import path from "node:path"; -import { CLI_NAME } from "../../branding"; +import { CLI_NAME } from "../../cli/branding"; import { captureOpenshell } from "../../adapters/openshell/runtime"; import { ensureLiveSandboxOrExit } from "./gateway-state"; import * as skillInstall from "../../skill-install"; -import { D, G, R, YW } from "../../terminal-style"; +import { D, G, R, YW } from "../../cli/terminal-style"; const agentRuntime = require("../../../../bin/lib/agent-runtime"); diff --git a/src/lib/actions/sandbox/snapshot.ts b/src/lib/actions/sandbox/snapshot.ts index 024f36c54a9..2a6ecb21b46 100644 --- a/src/lib/actions/sandbox/snapshot.ts +++ b/src/lib/actions/sandbox/snapshot.ts @@ -6,7 +6,7 @@ import fs from "node:fs"; import path from "node:path"; -import { CLI_NAME } from "../../branding"; +import { CLI_NAME } from "../../cli/branding"; import { dockerCapture, dockerInspect } from "../../adapters/docker"; import { parseLiveSandboxNames } from "../../runtime-recovery"; import { ROOT, run, shellQuote, validateName } from "../../runner"; diff --git a/src/lib/actions/sandbox/status.ts b/src/lib/actions/sandbox/status.ts index 9e998b01dd2..827da83c5ba 100644 --- a/src/lib/actions/sandbox/status.ts +++ b/src/lib/actions/sandbox/status.ts @@ -3,12 +3,12 @@ /* v8 ignore start -- exercised through CLI subprocess status tests. */ -import { CLI_DISPLAY_NAME, CLI_NAME } from "../../branding"; +import { CLI_DISPLAY_NAME, CLI_NAME } from "../../cli/branding"; import { parseSandboxPhase } from "../../state/gateway"; import { getNamedGatewayLifecycleState } from "../../gateway-runtime-action"; -import { parseGatewayInference } from "../../inference-config"; -import { probeProviderHealth } from "../../inference-health"; -import * as nim from "../../nim"; +import { parseGatewayInference } from "../../inference/config"; +import { probeProviderHealth } from "../../inference/health"; +import * as nim from "../../inference/nim"; import * as onboardSession from "../../onboard-session"; import type { Session } from "../../onboard-session"; import { @@ -30,7 +30,7 @@ import { } from "../../state/sandbox-session"; import * as sandboxVersion from "../../sandbox-version"; import * as shields from "../../shields"; -import { D, G, R, RD, YW } from "../../terminal-style"; +import { D, G, R, RD, YW } from "../../cli/terminal-style"; const agentRuntime = require("../../../../bin/lib/agent-runtime"); diff --git a/src/lib/actions/upgrade-sandboxes.ts b/src/lib/actions/upgrade-sandboxes.ts index 71993a7cc05..d5cdf83d4f4 100644 --- a/src/lib/actions/upgrade-sandboxes.ts +++ b/src/lib/actions/upgrade-sandboxes.ts @@ -3,8 +3,8 @@ /* v8 ignore start -- exercised through CLI subprocess upgrade tests. */ -import { CLI_NAME } from "../branding"; -import { prompt as askPrompt } from "../credentials"; +import { CLI_NAME } from "../cli/branding"; +import { prompt as askPrompt } from "../credentials/store"; import { normalizeUpgradeSandboxesOptions, type UpgradeSandboxesOptions, @@ -14,7 +14,7 @@ import * as registry from "../state/registry"; import { parseLiveSandboxNames } from "../runtime-recovery"; import { rebuildSandbox } from "./sandbox/rebuild"; import * as sandboxVersion from "../sandbox-version"; -import { B, D, G, R, YW } from "../terminal-style"; +import { B, D, G, R, YW } from "../cli/terminal-style"; import { classifyUpgradeableSandboxes, shouldSkipUpgradeConfirmation, diff --git a/src/lib/agent-base-image.test.ts b/src/lib/agent/base-image.test.ts similarity index 87% rename from src/lib/agent-base-image.test.ts rename to src/lib/agent/base-image.test.ts index 08c4d0b740a..987c46887be 100644 --- a/src/lib/agent-base-image.test.ts +++ b/src/lib/agent/base-image.test.ts @@ -2,11 +2,11 @@ // SPDX-License-Identifier: Apache-2.0 import { beforeEach, describe, expect, it, vi } from "vitest"; -import type { AgentDefinition } from "./agent-defs"; +import type { AgentDefinition } from "./defs"; -type AgentOnboardModule = typeof import("../../dist/lib/agent-onboard"); -type DockerImageModule = typeof import("../../dist/lib/adapters/docker/image"); -type DockerInspectModule = typeof import("../../dist/lib/adapters/docker/inspect"); +type AgentOnboardModule = typeof import("../../../dist/lib/agent/onboard"); +type DockerImageModule = typeof import("../../../dist/lib/adapters/docker/image"); +type DockerInspectModule = typeof import("../../../dist/lib/adapters/docker/inspect"); /** * Build a minimal Hermes agent manifest for base-image provisioning tests. @@ -56,14 +56,14 @@ function withMockedDocker( }) => T, ): T { // eslint-disable-next-line @typescript-eslint/no-require-imports - const dockerImageModule = require("../../dist/lib/adapters/docker/image") as DockerImageModule; + const dockerImageModule = require("../../../dist/lib/adapters/docker/image") as DockerImageModule; // eslint-disable-next-line @typescript-eslint/no-require-imports - const dockerInspectModule = require("../../dist/lib/adapters/docker/inspect") as DockerInspectModule; + const dockerInspectModule = require("../../../dist/lib/adapters/docker/inspect") as DockerInspectModule; // eslint-disable-next-line @typescript-eslint/no-require-imports - const runnerModule = require("../../dist/lib/runner") as { ROOT: string }; + const runnerModule = require("../../../dist/lib/runner") as { ROOT: string }; const originalDockerBuild = dockerImageModule.dockerBuild; const originalDockerImageInspect = dockerInspectModule.dockerImageInspect; - const agentOnboardModulePath = require.resolve("../../dist/lib/agent-onboard"); + const agentOnboardModulePath = require.resolve("../../../dist/lib/agent/onboard"); delete require.cache[agentOnboardModulePath]; const dockerBuildMock = vi.fn().mockReturnValue({ status: 0 }); @@ -74,7 +74,7 @@ function withMockedDocker( try { // eslint-disable-next-line @typescript-eslint/no-require-imports - const agentOnboardModule = require("../../dist/lib/agent-onboard") as AgentOnboardModule; + const agentOnboardModule = require("../../../dist/lib/agent/onboard") as AgentOnboardModule; return run({ ensureAgentBaseImage: agentOnboardModule.ensureAgentBaseImage, dockerBuildMock, diff --git a/src/lib/agent-defs.test.ts b/src/lib/agent/defs.test.ts similarity index 99% rename from src/lib/agent-defs.test.ts rename to src/lib/agent/defs.test.ts index e3329b99d7e..98ff8d24b71 100644 --- a/src/lib/agent-defs.test.ts +++ b/src/lib/agent/defs.test.ts @@ -11,7 +11,7 @@ import { getAgentChoices, loadAgent, resolveAgentName, -} from "../../dist/lib/agent-defs"; +} from "../../../dist/lib/agent/defs"; const tempAgentDirs: string[] = []; diff --git a/src/lib/agent-defs.ts b/src/lib/agent/defs.ts similarity index 99% rename from src/lib/agent-defs.ts rename to src/lib/agent/defs.ts index 5c44c441d02..c794f2dd6ff 100644 --- a/src/lib/agent-defs.ts +++ b/src/lib/agent/defs.ts @@ -7,8 +7,8 @@ import fs from "node:fs"; import path from "node:path"; -import { ROOT } from "./runner"; -import { DASHBOARD_PORT } from "./ports"; +import { ROOT } from "../runner"; +import { DASHBOARD_PORT } from "../core/ports"; export const AGENTS_DIR = path.join(ROOT, "agents"); diff --git a/src/lib/agent-onboard.test.ts b/src/lib/agent/onboard.test.ts similarity index 97% rename from src/lib/agent-onboard.test.ts rename to src/lib/agent/onboard.test.ts index d1b48d6ccc1..68ad674f299 100644 --- a/src/lib/agent-onboard.test.ts +++ b/src/lib/agent/onboard.test.ts @@ -5,8 +5,8 @@ import { describe, it, expect, beforeEach, afterEach, afterAll, vi } from "vites import fs from "node:fs"; import path from "node:path"; // Import from compiled dist/ so coverage is attributed correctly. -import { printDashboardUi, verifyAgentBinaryAvailable } from "../../dist/lib/agent-onboard"; -import type { AgentDefinition } from "./agent-defs"; +import { printDashboardUi, verifyAgentBinaryAvailable } from "../../../dist/lib/agent/onboard"; +import type { AgentDefinition } from "./defs"; function makeAgent(overrides: Partial = {}): AgentDefinition { return { @@ -128,7 +128,7 @@ describe("printDashboardUi — regression for #2078 (port 8642 is not a chat UI) describe("handleAgentSetup guards", () => { it("fails onboarding instead of completing when the agent binary or health probe is missing", () => { - const source = fs.readFileSync(path.join(import.meta.dirname, "agent-onboard.ts"), "utf-8"); + const source = fs.readFileSync(path.join(import.meta.dirname, "onboard.ts"), "utf-8"); expect(source).toContain("verifyAgentBinaryAvailable"); expect(source).toContain("AGENT_BINARY_CHECK_PREFIX"); @@ -146,7 +146,7 @@ describe("handleAgentSetup guards", () => { }); it("accepts Hermes JSON health responses without substring false positives", () => { - const source = fs.readFileSync(path.join(import.meta.dirname, "agent-onboard.ts"), "utf-8"); + const source = fs.readFileSync(path.join(import.meta.dirname, "onboard.ts"), "utf-8"); expect(source).toContain("function isHealthProbeOk"); expect(source).toContain("JSON.parse(body)"); diff --git a/src/lib/agent-onboard.ts b/src/lib/agent/onboard.ts similarity index 97% rename from src/lib/agent-onboard.ts rename to src/lib/agent/onboard.ts index 45928a3014c..711c48e5fc8 100644 --- a/src/lib/agent-onboard.ts +++ b/src/lib/agent/onboard.ts @@ -9,14 +9,14 @@ import fs from "fs"; import os from "os"; import path from "path"; -import { dockerBuild, dockerImageInspect } from "./adapters/docker"; -import { type AgentDefinition, loadAgent, resolveAgentName } from "./agent-defs"; -import { getAgentBranding } from "./branding"; -import { getProviderSelectionConfig } from "./inference-config"; -import type { JsonObject as LooseObject, JsonValue as LooseValue } from "./json-types"; -import * as onboardSession from "./onboard-session"; -import { ROOT, redact, run, shellQuote } from "./runner"; -import { sleepSeconds } from "./wait"; +import { dockerBuild, dockerImageInspect } from "../adapters/docker"; +import { getAgentBranding } from "../cli/branding"; +import { getProviderSelectionConfig } from "../inference/config"; +import type { JsonObject as LooseObject, JsonValue as LooseValue } from "../core/json-types"; +import * as onboardSession from "../onboard-session"; +import { ROOT, redact, run, shellQuote } from "../runner"; +import { sleepSeconds } from "../core/wait"; +import { type AgentDefinition, loadAgent, resolveAgentName } from "./defs"; export interface OnboardContext { step: (current: number, total: number, message: string) => void; diff --git a/src/lib/agent-runtime.test.ts b/src/lib/agent/runtime.test.ts similarity index 99% rename from src/lib/agent-runtime.test.ts rename to src/lib/agent/runtime.test.ts index 51635c02453..1f41fd3492a 100644 --- a/src/lib/agent-runtime.test.ts +++ b/src/lib/agent/runtime.test.ts @@ -7,8 +7,8 @@ import { buildManualRecoveryCommand, buildOpenClawRecoveryScript, buildRecoveryScript, -} from "../../dist/lib/agent-runtime"; -import type { AgentDefinition } from "./agent-defs"; +} from "../../../dist/lib/agent/runtime"; +import type { AgentDefinition } from "./defs"; function makeAgent(overrides: Partial = {}): AgentDefinition { return { diff --git a/src/lib/agent-runtime.ts b/src/lib/agent/runtime.ts similarity index 98% rename from src/lib/agent-runtime.ts rename to src/lib/agent/runtime.ts index 30412a73870..f63a0be745b 100644 --- a/src/lib/agent-runtime.ts +++ b/src/lib/agent/runtime.ts @@ -7,11 +7,11 @@ // When the session agent is openclaw (or absent), all functions return // defaults that match the hardcoded OpenClaw values on main. -import * as registry from "./state/registry"; -import { DASHBOARD_PORT } from "./ports"; -import * as onboardSession from "./onboard-session"; -import { loadAgent, type AgentDefinition } from "./agent-defs"; -import { shellQuote } from "./runner"; +import { DASHBOARD_PORT } from "../core/ports"; +import { shellQuote } from "../runner"; +import * as onboardSession from "../onboard-session"; +import * as registry from "../state/registry"; +import { loadAgent, type AgentDefinition } from "./defs"; /** * Resolve the agent for a sandbox. Checks the per-sandbox registry first diff --git a/src/lib/build-context.ts b/src/lib/build-context.ts index 7600e3c08b5..7532c7fd024 100644 --- a/src/lib/build-context.ts +++ b/src/lib/build-context.ts @@ -6,7 +6,7 @@ * creation failures. */ -import { CLI_NAME } from "./branding"; +import { CLI_NAME } from "./cli/branding"; import fs from "node:fs"; import path from "node:path"; diff --git a/src/lib/branding.ts b/src/lib/cli/branding.ts similarity index 100% rename from src/lib/branding.ts rename to src/lib/cli/branding.ts diff --git a/src/lib/command-display-metadata.test.ts b/src/lib/cli/command-display-metadata.test.ts similarity index 95% rename from src/lib/command-display-metadata.test.ts rename to src/lib/cli/command-display-metadata.test.ts index 5002c4ec966..5b6ba9d8eba 100644 --- a/src/lib/command-display-metadata.test.ts +++ b/src/lib/cli/command-display-metadata.test.ts @@ -4,7 +4,7 @@ import { Config as OclifConfig } from "@oclif/core"; import { describe, expect, it } from "vitest"; -import { getRegisteredOclifCommandsMetadata } from "./cli/oclif-metadata"; +import { getRegisteredOclifCommandsMetadata } from "./oclif-metadata"; import { COMMANDS, visibleCommands } from "./command-registry"; describe("public command display metadata", () => { diff --git a/src/lib/command-registry.test.ts b/src/lib/cli/command-registry.test.ts similarity index 100% rename from src/lib/command-registry.test.ts rename to src/lib/cli/command-registry.test.ts diff --git a/src/lib/command-registry.ts b/src/lib/cli/command-registry.ts similarity index 95% rename from src/lib/command-registry.ts rename to src/lib/cli/command-registry.ts index c9040c16c0d..bd2af9772a0 100644 --- a/src/lib/command-registry.ts +++ b/src/lib/cli/command-registry.ts @@ -16,10 +16,10 @@ */ import { CLI_NAME } from "./branding"; -import type { CommandDisplayEntry, CommandGroup } from "./cli/command-display"; -import { getRegisteredOclifCommandsMetadata } from "./cli/oclif-metadata"; +import type { CommandDisplayEntry, CommandGroup } from "./command-display"; +import { getRegisteredOclifCommandsMetadata } from "./oclif-metadata"; -export type { CommandGroup } from "./cli/command-display"; +export type { CommandGroup } from "./command-display"; /** Replace the canonical "nemoclaw" prefix in a usage string with CLI_NAME. */ export function brandedUsage(usage: string): string { diff --git a/src/lib/duration-flags.test.ts b/src/lib/cli/duration-flags.test.ts similarity index 100% rename from src/lib/duration-flags.test.ts rename to src/lib/cli/duration-flags.test.ts diff --git a/src/lib/duration-flags.ts b/src/lib/cli/duration-flags.ts similarity index 95% rename from src/lib/duration-flags.ts rename to src/lib/cli/duration-flags.ts index b82542223dd..9f36e6a9efb 100644 --- a/src/lib/duration-flags.ts +++ b/src/lib/cli/duration-flags.ts @@ -3,7 +3,7 @@ import { Errors, Flags } from "@oclif/core"; -import { parseDuration } from "./domain/duration"; +import { parseDuration } from "../domain/duration"; const LOGS_SINCE_DURATION_RE = /^[1-9]\d*(?:ms|s|m|h|d)$/i; diff --git a/src/lib/oclif-command-metadata.test.ts b/src/lib/cli/oclif-command-metadata.test.ts similarity index 100% rename from src/lib/oclif-command-metadata.test.ts rename to src/lib/cli/oclif-command-metadata.test.ts diff --git a/src/lib/cli/oclif-dispatch.ts b/src/lib/cli/oclif-dispatch.ts index 23204abd3e2..e408e365f36 100644 --- a/src/lib/cli/oclif-dispatch.ts +++ b/src/lib/cli/oclif-dispatch.ts @@ -1,7 +1,7 @@ // SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. // SPDX-License-Identifier: Apache-2.0 -import { sandboxCommands } from "../command-registry"; +import { sandboxCommands } from "./command-registry"; export type OclifDispatch = { kind: "oclif"; diff --git a/src/lib/cli/oclif-runner.ts b/src/lib/cli/oclif-runner.ts index 30bc0baba2d..574f7bf32a4 100644 --- a/src/lib/cli/oclif-runner.ts +++ b/src/lib/cli/oclif-runner.ts @@ -3,7 +3,7 @@ import { Config as OclifConfig, execute as executeOclif } from "@oclif/core"; -import { CLI_NAME } from "../branding"; +import { CLI_NAME } from "./branding"; export interface OclifCommandRunOptions { rootDir: string; diff --git a/src/lib/cli/public-oclif-help.ts b/src/lib/cli/public-oclif-help.ts index 28a657fd1b9..9d38add14e1 100644 --- a/src/lib/cli/public-oclif-help.ts +++ b/src/lib/cli/public-oclif-help.ts @@ -3,7 +3,7 @@ import { CommandHelp } from "@oclif/core"; -import { CLI_NAME } from "../branding"; +import { CLI_NAME } from "./branding"; import { getRegisteredOclifCommandMetadata, type OclifCommandMetadata } from "./oclif-metadata"; type PublicHelpCommand = OclifCommandMetadata & { diff --git a/src/lib/terminal-style.test.ts b/src/lib/cli/terminal-style.test.ts similarity index 100% rename from src/lib/terminal-style.test.ts rename to src/lib/cli/terminal-style.test.ts diff --git a/src/lib/terminal-style.ts b/src/lib/cli/terminal-style.ts similarity index 100% rename from src/lib/terminal-style.ts rename to src/lib/cli/terminal-style.ts diff --git a/src/lib/commands/credentials.test.ts b/src/lib/commands/credentials.test.ts index b0d784aaa14..eca150e5704 100644 --- a/src/lib/commands/credentials.test.ts +++ b/src/lib/commands/credentials.test.ts @@ -9,7 +9,7 @@ const mocks = vi.hoisted(() => ({ runOpenshellProviderCommand: vi.fn(), })); -vi.mock("../credentials", () => ({ prompt: mocks.prompt })); +vi.mock("../credentials/store", () => ({ prompt: mocks.prompt })); vi.mock("../actions/global", () => ({ recoverNamedGatewayRuntime: mocks.recoverNamedGatewayRuntime, runOpenshellProviderCommand: mocks.runOpenshellProviderCommand, diff --git a/src/lib/commands/credentials/common.ts b/src/lib/commands/credentials/common.ts index f48de6686e2..9ebdb0ef3e2 100644 --- a/src/lib/commands/credentials/common.ts +++ b/src/lib/commands/credentials/common.ts @@ -1,7 +1,7 @@ // SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. // SPDX-License-Identifier: Apache-2.0 -import { CLI_DISPLAY_NAME, CLI_NAME } from "../../branding"; +import { CLI_DISPLAY_NAME, CLI_NAME } from "../../cli/branding"; import { recoverNamedGatewayRuntime } from "../../actions/global"; // Suffixes that mark per-sandbox messaging integrations in the gateway's diff --git a/src/lib/commands/credentials/list.ts b/src/lib/commands/credentials/list.ts index 86a165fc0c9..cffd4cc4479 100644 --- a/src/lib/commands/credentials/list.ts +++ b/src/lib/commands/credentials/list.ts @@ -3,7 +3,7 @@ import { Command, Flags } from "@oclif/core"; -import { CLI_NAME } from "../../branding"; +import { CLI_NAME } from "../../cli/branding"; import { runOpenshellProviderCommand } from "../../actions/global"; import { OPENSHELL_OPERATION_TIMEOUT_MS } from "../../adapters/openshell/timeouts"; import { isBridgeProviderName, recoverGatewayOrExit } from "./common"; diff --git a/src/lib/commands/credentials/reset.ts b/src/lib/commands/credentials/reset.ts index f86e8d0f6ae..4b2265b9fa6 100644 --- a/src/lib/commands/credentials/reset.ts +++ b/src/lib/commands/credentials/reset.ts @@ -3,8 +3,8 @@ import { Args, Command, Flags } from "@oclif/core"; -import { CLI_NAME } from "../../branding"; -import { prompt as askPrompt } from "../../credentials"; +import { CLI_NAME } from "../../cli/branding"; +import { prompt as askPrompt } from "../../credentials/store"; import { runOpenshellProviderCommand } from "../../actions/global"; import { OPENSHELL_OPERATION_TIMEOUT_MS } from "../../adapters/openshell/timeouts"; import { isBridgeProviderName, recoverGatewayOrExit } from "./common"; diff --git a/src/lib/commands/debug.ts b/src/lib/commands/debug.ts index 9b1662050b3..c846d7b1529 100644 --- a/src/lib/commands/debug.ts +++ b/src/lib/commands/debug.ts @@ -3,11 +3,11 @@ import { Command, Flags } from "@oclif/core"; -import { CLI_NAME } from "../branding"; -import { runDebug } from "../debug"; -import type { DebugOptions } from "../debug"; -import type { RunDebugCommandDeps } from "../debug-command"; -import { runDebugCommandWithOptions } from "../debug-command"; +import { CLI_NAME } from "../cli/branding"; +import { runDebug } from "../diagnostics/debug"; +import type { DebugOptions } from "../diagnostics/debug"; +import type { RunDebugCommandDeps } from "../diagnostics/debug-command"; +import { runDebugCommandWithOptions } from "../diagnostics/debug-command"; import type { CaptureOpenshellResult } from "../adapters/openshell/client"; import { captureOpenshellCommand } from "../adapters/openshell/client"; import { OPENSHELL_PROBE_TIMEOUT_MS } from "../adapters/openshell/timeouts"; diff --git a/src/lib/commands/deprecated/start.ts b/src/lib/commands/deprecated/start.ts index cf93d209060..b680d4d8809 100644 --- a/src/lib/commands/deprecated/start.ts +++ b/src/lib/commands/deprecated/start.ts @@ -3,7 +3,7 @@ import { Command, Flags } from "@oclif/core"; -import { CLI_NAME } from "../../branding"; +import { CLI_NAME } from "../../cli/branding"; import { startAll } from "../../services"; import { runStartCommand } from "../../services-command"; import { serviceDeps } from "../tunnel/common"; diff --git a/src/lib/commands/deprecated/stop.ts b/src/lib/commands/deprecated/stop.ts index 61cbe01e94f..95ac2ecf980 100644 --- a/src/lib/commands/deprecated/stop.ts +++ b/src/lib/commands/deprecated/stop.ts @@ -3,7 +3,7 @@ import { Command, Flags } from "@oclif/core"; -import { CLI_NAME } from "../../branding"; +import { CLI_NAME } from "../../cli/branding"; import { stopAll } from "../../services"; import { runStopCommand } from "../../services-command"; import { serviceDeps } from "../tunnel/common"; diff --git a/src/lib/commands/sandbox/config/get.ts b/src/lib/commands/sandbox/config/get.ts index 78fb46427c9..2509d44bf31 100644 --- a/src/lib/commands/sandbox/config/get.ts +++ b/src/lib/commands/sandbox/config/get.ts @@ -3,7 +3,7 @@ import { Command, Flags } from "@oclif/core"; -import { CLI_NAME } from "../../../branding"; +import { CLI_NAME } from "../../../cli/branding"; import * as sandboxConfig from "../../../sandbox-config"; import { sandboxNameArg } from "../common"; diff --git a/src/lib/commands/sandbox/connect.ts b/src/lib/commands/sandbox/connect.ts index 8082e657945..13825f85f82 100644 --- a/src/lib/commands/sandbox/connect.ts +++ b/src/lib/commands/sandbox/connect.ts @@ -3,7 +3,7 @@ import { Args, Command, Flags } from "@oclif/core"; -import { CLI_NAME } from "../../branding"; +import { CLI_NAME } from "../../cli/branding"; import { connectSandbox } from "../../actions/sandbox/runtime"; export default class ConnectCliCommand extends Command { diff --git a/src/lib/commands/sandbox/logs.ts b/src/lib/commands/sandbox/logs.ts index e6b64a60a86..97b45a5a955 100644 --- a/src/lib/commands/sandbox/logs.ts +++ b/src/lib/commands/sandbox/logs.ts @@ -3,7 +3,7 @@ import { Args, Command, Flags } from "@oclif/core"; -import { logsSinceDurationFlag } from "../../duration-flags"; +import { logsSinceDurationFlag } from "../../cli/duration-flags"; import type { SandboxLogsOptions } from "../../domain/sandbox/log-options"; import { DEFAULT_SANDBOX_LOG_LINES } from "../../domain/sandbox/log-options"; import { showSandboxLogs } from "../../actions/sandbox/runtime"; diff --git a/src/lib/commands/sandbox/shields/down.ts b/src/lib/commands/sandbox/shields/down.ts index 7571f73aa7c..2c0c0e39592 100644 --- a/src/lib/commands/sandbox/shields/down.ts +++ b/src/lib/commands/sandbox/shields/down.ts @@ -3,7 +3,7 @@ import { Command, Flags } from "@oclif/core"; -import { shieldsTimeoutDurationFlag } from "../../../duration-flags"; +import { shieldsTimeoutDurationFlag } from "../../../cli/duration-flags"; import * as shields from "../../../shields"; import { sandboxNameArg } from "../common"; diff --git a/src/lib/commands/simple-global-oclif-adapters.test.ts b/src/lib/commands/simple-global-oclif-adapters.test.ts index b2ed49a2cf9..8f3d6cb2535 100644 --- a/src/lib/commands/simple-global-oclif-adapters.test.ts +++ b/src/lib/commands/simple-global-oclif-adapters.test.ts @@ -24,8 +24,8 @@ const mocks = vi.hoisted(() => ({ })); vi.mock("node:child_process", () => ({ spawnSync: mocks.spawnSync })); -vi.mock("../debug", () => ({ runDebug: vi.fn() })); -vi.mock("../debug-command", () => ({ +vi.mock("../diagnostics/debug", () => ({ runDebug: vi.fn() })); +vi.mock("../diagnostics/debug-command", () => ({ runDebugCommandWithOptions: mocks.runDebugCommandWithOptions, })); vi.mock("../gateway-token-command", () => ({ @@ -48,7 +48,7 @@ vi.mock("../uninstall-command", () => ({ buildVersionedUninstallUrl: mocks.buildVersionedUninstallUrl, runUninstallCommand: mocks.runUninstallCommand, })); -vi.mock("../version", () => ({ getVersion: mocks.getVersion })); +vi.mock("../core/version", () => ({ getVersion: mocks.getVersion })); import DebugCliCommand from "./debug"; import DeployCliCommand from "./deploy"; diff --git a/src/lib/commands/uninstall.ts b/src/lib/commands/uninstall.ts index 78e34fedc2a..620044dc497 100644 --- a/src/lib/commands/uninstall.ts +++ b/src/lib/commands/uninstall.ts @@ -5,7 +5,7 @@ import { spawnSync } from "node:child_process"; import { Command, Flags } from "@oclif/core"; -import { getVersion } from "../version"; +import { getVersion } from "../core/version"; import { buildVersionedUninstallUrl, runUninstallCommand } from "../uninstall-command"; export default class UninstallCliCommand extends Command { diff --git a/src/lib/core/README.md b/src/lib/core/README.md new file mode 100644 index 00000000000..ae335e9fbd8 --- /dev/null +++ b/src/lib/core/README.md @@ -0,0 +1,20 @@ + + + +# Core helpers + +`src/lib/core` is for tiny cross-cutting primitives with minimal dependencies. These helpers should be safe to import from actions, domain modules, adapters, and CLI infrastructure. + +Good candidates: + +```text +version.ts +ports.ts +json-types.ts +errno.ts +wait.ts +url-utils.ts +shell-quote.ts +``` + +Keep product workflows out of this directory. If a helper starts depending on Docker, OpenShell, filesystem state, or a specific command workflow, move it to an adapter, action, domain area, or feature folder instead. diff --git a/test/errno.test.ts b/src/lib/core/errno.test.ts similarity index 97% rename from test/errno.test.ts rename to src/lib/core/errno.test.ts index 0a12498559c..9fdd784a30f 100644 --- a/test/errno.test.ts +++ b/src/lib/core/errno.test.ts @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 import { describe, it, expect } from "vitest"; -import { isErrnoException, isPermissionError } from "../src/lib/errno"; +import { isErrnoException, isPermissionError } from "./errno"; describe("isErrnoException", () => { it("returns true for Error with code property", () => { diff --git a/src/lib/errno.ts b/src/lib/core/errno.ts similarity index 100% rename from src/lib/errno.ts rename to src/lib/core/errno.ts diff --git a/src/lib/json-types.ts b/src/lib/core/json-types.ts similarity index 100% rename from src/lib/json-types.ts rename to src/lib/core/json-types.ts diff --git a/src/lib/ports.test.ts b/src/lib/core/ports.test.ts similarity index 97% rename from src/lib/ports.test.ts rename to src/lib/core/ports.test.ts index 3769c2bf8bd..117d219072f 100644 --- a/src/lib/ports.test.ts +++ b/src/lib/core/ports.test.ts @@ -3,7 +3,7 @@ import { describe, it, expect, beforeEach, afterEach } from "vitest"; // Import from compiled dist/ so coverage is attributed correctly. -import { parsePort } from "../../dist/lib/ports"; +import { parsePort } from "../../../dist/lib/core/ports"; describe("parsePort", () => { const ENV_KEY = "TEST_PORT"; diff --git a/src/lib/ports.ts b/src/lib/core/ports.ts similarity index 100% rename from src/lib/ports.ts rename to src/lib/core/ports.ts diff --git a/src/lib/shell-quote.ts b/src/lib/core/shell-quote.ts similarity index 100% rename from src/lib/shell-quote.ts rename to src/lib/core/shell-quote.ts diff --git a/src/lib/url-utils.test.ts b/src/lib/core/url-utils.test.ts similarity index 98% rename from src/lib/url-utils.test.ts rename to src/lib/core/url-utils.test.ts index 69def4b8496..8527a897083 100644 --- a/src/lib/url-utils.test.ts +++ b/src/lib/core/url-utils.test.ts @@ -10,7 +10,7 @@ import { isLoopbackHostname, formatEnvAssignment, parsePolicyPresetEnv, -} from "../../dist/lib/url-utils"; +} from "../../../dist/lib/core/url-utils"; describe("compactText", () => { it("collapses whitespace", () => { diff --git a/src/lib/url-utils.ts b/src/lib/core/url-utils.ts similarity index 100% rename from src/lib/url-utils.ts rename to src/lib/core/url-utils.ts diff --git a/src/lib/version.test.ts b/src/lib/core/version.test.ts similarity index 96% rename from src/lib/version.test.ts rename to src/lib/core/version.test.ts index 6da6952a7c9..495ce370812 100644 --- a/src/lib/version.test.ts +++ b/src/lib/core/version.test.ts @@ -5,7 +5,7 @@ import { describe, it, expect, beforeAll, afterAll } from "vitest"; import { mkdtempSync, writeFileSync, rmSync } from "node:fs"; import { join } from "node:path"; import { tmpdir } from "node:os"; -import { getVersion } from "../../dist/lib/version"; +import { getVersion } from "../../../dist/lib/core/version"; describe("lib/version", () => { let testDir: string; diff --git a/src/lib/version.ts b/src/lib/core/version.ts similarity index 95% rename from src/lib/version.ts rename to src/lib/core/version.ts index d6ff45808fa..301b70ceddf 100644 --- a/src/lib/version.ts +++ b/src/lib/core/version.ts @@ -27,7 +27,7 @@ export interface VersionOptions { * 3. `package.json` version — hard-coded fallback */ export function getVersion(opts: VersionOptions = {}): string { - // Compiled location: dist/lib/version.js → repo root is 2 levels up + // Compiled location: dist/lib/core/version.js → repo root is 2 levels up const root = opts.rootDir ?? join(__dirname, "..", ".."); // 1. Try git (available in dev clones and CI) diff --git a/src/lib/wait.ts b/src/lib/core/wait.ts similarity index 100% rename from src/lib/wait.ts rename to src/lib/core/wait.ts diff --git a/src/lib/coverage-hotspots.test.ts b/src/lib/coverage-hotspots.test.ts index d33029e2a0e..f6241bf003d 100644 --- a/src/lib/coverage-hotspots.test.ts +++ b/src/lib/coverage-hotspots.test.ts @@ -9,7 +9,7 @@ import { describe, expect, it } from "vitest"; import { parseDuration } from "./domain/duration"; import { parseGatewayTokenArgs, runGatewayTokenCommand } from "./gateway-token-command"; import { resolveDefaultSandboxName, runStartCommand, runStopCommand } from "./services-command"; -import { getVersion } from "./version"; +import { getVersion } from "./core/version"; // Narrow coverage guard for small helper modules that are otherwise only // exercised through subprocess CLI flows in this migration stack. diff --git a/src/lib/credentials.ts b/src/lib/credentials/store.ts similarity index 99% rename from src/lib/credentials.ts rename to src/lib/credentials/store.ts index 760e3f99e66..4048a4757d0 100644 --- a/src/lib/credentials.ts +++ b/src/lib/credentials/store.ts @@ -14,8 +14,8 @@ import os from "node:os"; import path from "node:path"; import readline from "node:readline"; -import { rejectSymlinksOnPath } from "./state/config-io"; -import { isErrnoException } from "./errno"; +import { isErrnoException } from "../core/errno"; +import { rejectSymlinksOnPath } from "../state/config-io"; const UNSAFE_HOME_PATHS = new Set(["/tmp", "/var/tmp", "/dev/shm", "/"]); diff --git a/src/lib/dashboard-contract.test.ts b/src/lib/dashboard/contract.test.ts similarity index 97% rename from src/lib/dashboard-contract.test.ts rename to src/lib/dashboard/contract.test.ts index a82f5917c17..2f63e7a1887 100644 --- a/src/lib/dashboard-contract.test.ts +++ b/src/lib/dashboard/contract.test.ts @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 import { describe, it, expect } from "vitest"; -import { buildChain, buildControlUiUrls } from "../../dist/lib/dashboard-contract.js"; +import { buildChain, buildControlUiUrls } from "../../../dist/lib/dashboard/contract.js"; describe("buildChain", () => { it("returns default loopback chain with no arguments", () => { diff --git a/src/lib/dashboard-contract.ts b/src/lib/dashboard/contract.ts similarity index 96% rename from src/lib/dashboard-contract.ts rename to src/lib/dashboard/contract.ts index ea387a5b14c..bad23cc60fb 100644 --- a/src/lib/dashboard-contract.ts +++ b/src/lib/dashboard/contract.ts @@ -6,8 +6,8 @@ * Pure functions — no I/O, no process.env reads. */ -import { DASHBOARD_PORT } from "./ports"; -import { isLoopbackHostname } from "./url-utils"; +import { DASHBOARD_PORT } from "../core/ports"; +import { isLoopbackHostname } from "../core/url-utils"; export interface PlatformHints { chatUiUrl?: string; diff --git a/src/lib/dashboard-health.test.ts b/src/lib/dashboard/health.test.ts similarity index 94% rename from src/lib/dashboard-health.test.ts rename to src/lib/dashboard/health.test.ts index 5e9041f0a1d..a20e88757be 100644 --- a/src/lib/dashboard-health.test.ts +++ b/src/lib/dashboard/health.test.ts @@ -2,8 +2,8 @@ // SPDX-License-Identifier: Apache-2.0 import { describe, it, expect } from "vitest"; -import { verifyDashboardChain } from "../../dist/lib/dashboard-health.js"; -import { buildChain } from "../../dist/lib/dashboard-contract.js"; +import { verifyDashboardChain } from "../../../dist/lib/dashboard/health.js"; +import { buildChain } from "../../../dist/lib/dashboard/contract.js"; const chain = buildChain(); diff --git a/src/lib/dashboard-health.ts b/src/lib/dashboard/health.ts similarity index 98% rename from src/lib/dashboard-health.ts rename to src/lib/dashboard/health.ts index 53b43c86ad8..6529b7e6958 100644 --- a/src/lib/dashboard-health.ts +++ b/src/lib/dashboard/health.ts @@ -6,7 +6,7 @@ * chain and produces a per-link diagnosis. All deps injected. */ -import type { DashboardDeliveryChain } from "./dashboard-contract"; +import type { DashboardDeliveryChain } from "./contract"; export interface DashboardHealthDeps { executeSandboxCommand: (name: string, script: string) => { status: number; stdout: string } | null; diff --git a/src/lib/dashboard-recover.test.ts b/src/lib/dashboard/recover.test.ts similarity index 94% rename from src/lib/dashboard-recover.test.ts rename to src/lib/dashboard/recover.test.ts index b7a6432cdec..89dc75ebe22 100644 --- a/src/lib/dashboard-recover.test.ts +++ b/src/lib/dashboard/recover.test.ts @@ -2,8 +2,8 @@ // SPDX-License-Identifier: Apache-2.0 import { describe, it, expect, vi } from "vitest"; -import { recoverDashboardChain } from "../../dist/lib/dashboard-recover.js"; -import { buildChain } from "../../dist/lib/dashboard-contract.js"; +import { recoverDashboardChain } from "../../../dist/lib/dashboard/recover.js"; +import { buildChain } from "../../../dist/lib/dashboard/contract.js"; const chain = buildChain(); diff --git a/src/lib/dashboard-recover.ts b/src/lib/dashboard/recover.ts similarity index 88% rename from src/lib/dashboard-recover.ts rename to src/lib/dashboard/recover.ts index 83c1d8976f0..352f6e32151 100644 --- a/src/lib/dashboard-recover.ts +++ b/src/lib/dashboard/recover.ts @@ -5,9 +5,9 @@ * Dashboard chain recovery — link-aware, idempotent. All deps injected. */ -import type { DashboardDeliveryChain } from "./dashboard-contract"; -import type { DashboardHealthDeps, ChainStatus } from "./dashboard-health"; -import { verifyDashboardChain } from "./dashboard-health"; +import type { DashboardDeliveryChain } from "./contract"; +import type { DashboardHealthDeps, ChainStatus } from "./health"; +import { verifyDashboardChain } from "./health"; export interface DashboardRecoverDeps extends DashboardHealthDeps { restartGateway: (name: string, port: number, agent: unknown) => boolean; diff --git a/src/lib/deploy.ts b/src/lib/deploy.ts index 4dff47d1c93..aa3c6459289 100644 --- a/src/lib/deploy.ts +++ b/src/lib/deploy.ts @@ -6,7 +6,7 @@ import os from "node:os"; import path from "node:path"; import { NAME_ALLOWED_FORMAT, getNameValidationGuidance } from "./name-validation"; -import { sleepSeconds } from "./wait"; +import { sleepSeconds } from "./core/wait"; type ExecLikeValue = | string diff --git a/src/lib/debug-command.test.ts b/src/lib/diagnostics/debug-command.test.ts similarity index 98% rename from src/lib/debug-command.test.ts rename to src/lib/diagnostics/debug-command.test.ts index ef798d82c37..1419519884e 100644 --- a/src/lib/debug-command.test.ts +++ b/src/lib/diagnostics/debug-command.test.ts @@ -9,7 +9,7 @@ import { printDebugHelp, runDebugCommand, runDebugCommandWithOptions, -} from "../../dist/lib/debug-command"; +} from "../../../dist/lib/diagnostics/debug-command"; function exitWithCode(code: number): never { throw new Error(`exit:${code}`); diff --git a/src/lib/debug-command.ts b/src/lib/diagnostics/debug-command.ts similarity index 100% rename from src/lib/debug-command.ts rename to src/lib/diagnostics/debug-command.ts diff --git a/src/lib/debug.test.ts b/src/lib/diagnostics/debug.test.ts similarity index 99% rename from src/lib/debug.test.ts rename to src/lib/diagnostics/debug.test.ts index 1c7e38569eb..696ab0e0f65 100644 --- a/src/lib/debug.test.ts +++ b/src/lib/diagnostics/debug.test.ts @@ -6,7 +6,7 @@ import { existsSync, mkdtempSync, rmSync, writeFileSync } from "node:fs"; import { tmpdir } from "node:os"; import { join } from "node:path"; // Import from compiled dist/ so coverage is attributed correctly. -import { createTarball, getDebugCompletionMessages, redact } from "../../dist/lib/debug"; +import { createTarball, getDebugCompletionMessages, redact } from "../../../dist/lib/diagnostics/debug"; describe("redact", () => { it("redacts NVIDIA_API_KEY=value patterns", () => { diff --git a/src/lib/debug.ts b/src/lib/diagnostics/debug.ts similarity index 97% rename from src/lib/debug.ts rename to src/lib/diagnostics/debug.ts index aabdc7dbf8f..f1c0d0fc87a 100644 --- a/src/lib/debug.ts +++ b/src/lib/diagnostics/debug.ts @@ -3,12 +3,12 @@ import { execFileSync, spawnSync } from "node:child_process"; import { existsSync, mkdtempSync, rmSync, unlinkSync, writeFileSync } from "node:fs"; -import { dockerExecFileSync } from "./adapters/docker/exec"; import { platform, tmpdir } from "node:os"; import { basename, dirname, join } from "node:path"; -import { DASHBOARD_PORT } from "./ports"; -import { listSandboxes } from "./state/registry"; +import { dockerExecFileSync } from "../adapters/docker/exec"; +import { DASHBOARD_PORT } from "../core/ports"; +import { listSandboxes } from "../state/registry"; // --------------------------------------------------------------------------- // Types @@ -54,7 +54,7 @@ function section(title: string): void { // Secret redaction — delegates to unified redact module (#2381). // --------------------------------------------------------------------------- -import { redactFull as redact } from "./redact"; +import { redactFull as redact } from "../security/redact"; export { redact }; // --------------------------------------------------------------------------- @@ -485,8 +485,8 @@ export function getDebugCompletionMessages(output?: string): string[] { export function runDebug(opts: DebugOptions = {}): void { const quick = opts.quick ?? false; const output = opts.output ?? ""; - // Compiled location: dist/lib/debug.js → repo root is 2 levels up - const repoDir = join(__dirname, "..", ".."); + // Compiled location: dist/lib/diagnostics/debug.js → repo root is 3 levels up + const repoDir = join(__dirname, "..", "..", ".."); // Resolve sandbox name let sandboxName = diff --git a/src/lib/host-artifact-cleanup.ts b/src/lib/host-artifact-cleanup.ts index 17d51b6b5e4..a5144c4e186 100644 --- a/src/lib/host-artifact-cleanup.ts +++ b/src/lib/host-artifact-cleanup.ts @@ -12,7 +12,7 @@ // entry on STALE_FILES; the loop does not change. If a future leftover is a // folder or symlink instead of a file, widen the shape at that point. -import { removeLegacyCredentialsFileIfEmpty } from "./credentials"; +import { removeLegacyCredentialsFileIfEmpty } from "./credentials/store"; interface StaleHostFile { /** Human-readable description for the success log line. */ diff --git a/src/lib/http-probe.ts b/src/lib/http-probe.ts index 05f51c0ea90..87ebf4ea5b7 100644 --- a/src/lib/http-probe.ts +++ b/src/lib/http-probe.ts @@ -12,9 +12,9 @@ import { import type { ProbeResult } from "./onboard-types"; import { ROOT } from "./state/paths"; -import { compactText } from "./url-utils"; +import { compactText } from "./core/url-utils"; -import { isErrnoException } from "./errno"; +import { isErrnoException } from "./core/errno"; export type CurlProbeResult = ProbeResult; diff --git a/src/lib/inference/README.md b/src/lib/inference/README.md new file mode 100644 index 00000000000..7f88e31744a --- /dev/null +++ b/src/lib/inference/README.md @@ -0,0 +1,25 @@ + + + +# Inference + +`src/lib/inference` is for model/provider configuration, inference health checks, local runtime support, and model catalog helpers. + +Suggested homes: + +```text +config.ts inference config parsing and normalization +health.ts inference endpoint health checks +local.ts local inference orchestration helpers +provider-models.ts provider model catalog support +model-prompts.ts prompt/model display helpers +nim.ts NIM catalog and lifecycle support +ollama/model-size.ts Ollama model size parsing +ollama/proxy.ts Ollama auth proxy support +ollama/windows.ts Windows Ollama support +vllm.ts vLLM support +web-search.ts web-search capability helpers +onboard-probes.ts onboarding-time inference validation probes +``` + +Longer term, pure inference decisions should move under `src/lib/domain/inference/**`, and HTTP/process boundaries should move under `src/lib/adapters/**`. diff --git a/src/lib/inference-config.test.ts b/src/lib/inference/config.test.ts similarity index 99% rename from src/lib/inference-config.test.ts rename to src/lib/inference/config.test.ts index c08f446ff7b..d8eb37e7734 100644 --- a/src/lib/inference-config.test.ts +++ b/src/lib/inference/config.test.ts @@ -16,7 +16,7 @@ import { getOpenClawPrimaryModel, getProviderSelectionConfig, parseGatewayInference, -} from "../../dist/lib/inference-config"; +} from "../../../dist/lib/inference/config"; describe("inference selection config", () => { it("exposes the curated cloud model picker options", () => { diff --git a/src/lib/inference-config.ts b/src/lib/inference/config.ts similarity index 98% rename from src/lib/inference-config.ts rename to src/lib/inference/config.ts index d9b89c03296..4e0bddab25d 100644 --- a/src/lib/inference-config.ts +++ b/src/lib/inference/config.ts @@ -6,7 +6,7 @@ * inference output parsing. All functions are pure. */ -import { DEFAULT_OLLAMA_MODEL } from "./local-inference"; +import { DEFAULT_OLLAMA_MODEL } from "./local"; export const INFERENCE_ROUTE_URL = "https://inference.local/v1"; export const DEFAULT_CLOUD_MODEL = "nvidia/nemotron-3-super-120b-a12b"; diff --git a/src/lib/inference-health.test.ts b/src/lib/inference/health.test.ts similarity index 98% rename from src/lib/inference-health.test.ts rename to src/lib/inference/health.test.ts index 137fb64bd44..b190d34270a 100644 --- a/src/lib/inference-health.test.ts +++ b/src/lib/inference/health.test.ts @@ -8,9 +8,9 @@ import { getRemoteProviderHealthEndpoint, probeRemoteProviderHealth, probeProviderHealth, -} from "../../dist/lib/inference-health"; +} from "../../../dist/lib/inference/health"; -import { BUILD_ENDPOINT_URL } from "../../dist/lib/provider-models"; +import { BUILD_ENDPOINT_URL } from "../../../dist/lib/inference/provider-models"; describe("inference health", () => { describe("getRemoteProviderHealthEndpoint", () => { diff --git a/src/lib/inference-health.ts b/src/lib/inference/health.ts similarity index 92% rename from src/lib/inference-health.ts rename to src/lib/inference/health.ts index 1b7314df1e4..781f132eb54 100644 --- a/src/lib/inference-health.ts +++ b/src/lib/inference/health.ts @@ -7,11 +7,11 @@ * and performs lightweight reachability checks for remote cloud providers. */ -import type { CurlProbeResult } from "./http-probe"; -import { runCurlProbe } from "./http-probe"; -import { getProviderSelectionConfig } from "./inference-config"; -import type { LocalProviderHealthProbeOptions } from "./local-inference"; -import { probeLocalProviderHealth } from "./local-inference"; +import type { CurlProbeResult } from "../http-probe"; +import { runCurlProbe } from "../http-probe"; +import { getProviderSelectionConfig } from "./config"; +import type { LocalProviderHealthProbeOptions } from "./local"; +import { probeLocalProviderHealth } from "./local"; import { BUILD_ENDPOINT_URL } from "./provider-models"; export interface ProviderHealthStatus { diff --git a/src/lib/local-inference.test.ts b/src/lib/inference/local.test.ts similarity index 99% rename from src/lib/local-inference.test.ts rename to src/lib/inference/local.test.ts index 29912a9df8d..55e80ba69ad 100644 --- a/src/lib/local-inference.test.ts +++ b/src/lib/inference/local.test.ts @@ -27,7 +27,7 @@ import { probeLocalProviderHealth, validateOllamaModel, validateLocalProvider, -} from "../../dist/lib/local-inference"; +} from "../../../dist/lib/inference/local"; describe("local inference helpers", () => { it("returns the expected base URL for vllm-local", () => { @@ -124,13 +124,13 @@ describe("local inference helpers", () => { [ "const platform = require('./dist/lib/platform.js');", "platform.isWsl = () => false;", - "const localInference = require('./dist/lib/local-inference.js');", + "const localInference = require('./dist/lib/inference/local.js');", "const result = localInference.validateLocalProvider('ollama-local', () => '{\"models\":[]}');", "process.stdout.write(JSON.stringify(result));", ].join(""), ], { - cwd: path.resolve(__dirname, "../.."), + cwd: path.resolve(__dirname, "../../.."), encoding: "utf8", env: { ...process.env, diff --git a/src/lib/local-inference.ts b/src/lib/inference/local.ts similarity index 98% rename from src/lib/local-inference.ts rename to src/lib/inference/local.ts index bb0d9ba4085..cadfa8b98ab 100644 --- a/src/lib/local-inference.ts +++ b/src/lib/inference/local.ts @@ -6,15 +6,15 @@ * health checks, and command generators for vLLM and Ollama. */ -import type { CurlProbeResult } from "./http-probe"; -import { runCurlProbe } from "./http-probe"; +import type { CurlProbeResult } from "../http-probe"; +import { runCurlProbe } from "../http-probe"; -const { shellQuote, runCapture } = require("./runner"); +const { shellQuote, runCapture } = require("../runner"); -import { VLLM_PORT, OLLAMA_PORT, OLLAMA_PROXY_PORT } from "./ports"; -import { sleepSeconds } from "./wait"; +import { VLLM_PORT, OLLAMA_PORT, OLLAMA_PROXY_PORT } from "../core/ports"; +import { sleepSeconds } from "../core/wait"; -const { isWsl } = require("./platform"); +const { isWsl } = require("../platform"); /** Port containers use to reach Ollama — proxy on non-WSL, direct on WSL2. */ export const OLLAMA_CONTAINER_PORT = isWsl() ? OLLAMA_PORT : OLLAMA_PROXY_PORT; diff --git a/src/lib/model-prompts.test.ts b/src/lib/inference/model-prompts.test.ts similarity index 99% rename from src/lib/model-prompts.test.ts rename to src/lib/inference/model-prompts.test.ts index be3bc75cac5..6332dd2b052 100644 --- a/src/lib/model-prompts.test.ts +++ b/src/lib/inference/model-prompts.test.ts @@ -9,7 +9,7 @@ import { promptInputModel, promptManualModelId, promptRemoteModel, -} from "../../dist/lib/model-prompts"; +} from "../../../dist/lib/inference/model-prompts"; function promptSequence(responses: string[]) { const queue = [...responses]; diff --git a/src/lib/model-prompts.ts b/src/lib/inference/model-prompts.ts similarity index 98% rename from src/lib/model-prompts.ts rename to src/lib/inference/model-prompts.ts index 5096d3d39eb..5629c958860 100644 --- a/src/lib/model-prompts.ts +++ b/src/lib/inference/model-prompts.ts @@ -1,12 +1,12 @@ // SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. // SPDX-License-Identifier: Apache-2.0 -import { CLOUD_MODEL_OPTIONS } from "./inference-config"; -import { isSafeModelId } from "./validation"; +import { CLOUD_MODEL_OPTIONS } from "./config"; +import { isSafeModelId } from "../validation"; import { validateNvidiaEndpointModel } from "./provider-models"; // credentials.ts still uses CommonJS-style exports. -const { getCredential, prompt } = require("./credentials"); +const { getCredential, prompt } = require("../credentials/store"); export const BACK_TO_SELECTION = "__NEMOCLAW_BACK_TO_SELECTION__"; diff --git a/src/lib/nim.test.ts b/src/lib/inference/nim.test.ts similarity index 99% rename from src/lib/nim.test.ts rename to src/lib/inference/nim.test.ts index d04688adf3c..73a7208fc4e 100644 --- a/src/lib/nim.test.ts +++ b/src/lib/inference/nim.test.ts @@ -6,11 +6,11 @@ import type { Mock } from "vitest"; import { describe, expect, it, vi } from "vitest"; // Import from compiled dist/ for coverage attribution. -import * as nim from "../../dist/lib/nim"; +import * as nim from "../../../dist/lib/inference/nim"; const require = createRequire(import.meta.url); -const NIM_DIST_PATH = require.resolve("../../dist/lib/nim"); -const RUNNER_PATH = require.resolve("../../dist/lib/runner"); +const NIM_DIST_PATH = require.resolve("../../../dist/lib/inference/nim"); +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/inference/nim.ts similarity index 98% rename from src/lib/nim.ts rename to src/lib/inference/nim.ts index a3e4491e807..429fde23f36 100644 --- a/src/lib/nim.ts +++ b/src/lib/inference/nim.ts @@ -4,7 +4,7 @@ // NIM container management — pull, start, stop, health-check NIM images. const fs = require("fs"); -const { runCapture } = require("./runner"); +const { runCapture } = require("../runner"); const { dockerContainerInspectFormat, dockerForceRm, @@ -14,11 +14,11 @@ const { dockerRm, dockerRunDetached, dockerStop, -} = require("./adapters/docker"); -const { sleepSeconds } = require("./wait"); -const nimImages = require("../../bin/lib/nim-images.json"); +} = require("../adapters/docker"); +const { sleepSeconds } = require("../core/wait"); +const nimImages = require("../../../bin/lib/nim-images.json"); -import { VLLM_PORT } from "./ports"; +import { VLLM_PORT } from "../core/ports"; const UNIFIED_MEMORY_GPU_TAGS = ["GB10", "Thor", "Orin", "Xavier"]; const NIM_STATUS_PROBE_TIMEOUT_MS = 5000; diff --git a/src/lib/ollama-model-size.test.ts b/src/lib/inference/ollama/model-size.test.ts similarity index 98% rename from src/lib/ollama-model-size.test.ts rename to src/lib/inference/ollama/model-size.test.ts index 406294016e5..94beb4d6589 100644 --- a/src/lib/ollama-model-size.test.ts +++ b/src/lib/inference/ollama/model-size.test.ts @@ -9,7 +9,7 @@ import { formatModelSize, getOllamaModelSize, probeRegistrySize, -} from "../../dist/lib/ollama-model-size"; +} from "../../../../dist/lib/inference/ollama/model-size"; const MANIFEST = JSON.stringify({ layers: [{ size: 1_000_000_000 }, { size: 200_000_000 }, { size: 25_000 }], diff --git a/src/lib/ollama-model-size.ts b/src/lib/inference/ollama/model-size.ts similarity index 98% rename from src/lib/ollama-model-size.ts rename to src/lib/inference/ollama/model-size.ts index e5667734081..c12eb1f5750 100644 --- a/src/lib/ollama-model-size.ts +++ b/src/lib/inference/ollama/model-size.ts @@ -1,7 +1,7 @@ // SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. // SPDX-License-Identifier: Apache-2.0 -import { runCapture } from "./runner"; +import { runCapture } from "../../runner"; const MANIFEST_HOST = "https://registry.ollama.ai"; const PROBE_TIMEOUT_SECONDS = 3; diff --git a/src/lib/onboard-ollama-proxy.ts b/src/lib/inference/ollama/proxy.ts similarity index 98% rename from src/lib/onboard-ollama-proxy.ts rename to src/lib/inference/ollama/proxy.ts index 6d3c8438a81..228743ffbbd 100644 --- a/src/lib/onboard-ollama-proxy.ts +++ b/src/lib/inference/ollama/proxy.ts @@ -10,8 +10,8 @@ const os = require("os"); const path = require("path"); const { spawn, spawnSync } = require("child_process"); const http = require("http"); -const { ROOT, SCRIPTS, run, runCapture, shellQuote } = require("./runner"); -const { OLLAMA_PORT, OLLAMA_PROXY_PORT } = require("./ports"); +const { ROOT, SCRIPTS, run, runCapture, shellQuote } = require("../../runner"); +const { OLLAMA_PORT, OLLAMA_PROXY_PORT } = require("../../core/ports"); const { getDefaultOllamaModel, getBootstrapOllamaModelOptions, @@ -21,10 +21,10 @@ const { OLLAMA_HOST_DOCKER_INTERNAL, probeOllamaModelCapabilities, validateOllamaModel, -} = require("./local-inference"); -const { buildSubprocessEnv } = require("./subprocess-env"); -const { prompt } = require("./credentials"); -const { promptManualModelId } = require("./model-prompts"); +} = require("../local"); +const { buildSubprocessEnv } = require("../../subprocess-env"); +const { prompt } = require("../../credentials/store"); +const { promptManualModelId } = require("../model-prompts"); // ── State ──────────────────────────────────────────────────────── diff --git a/src/lib/onboard-windows-ollama.ts b/src/lib/inference/ollama/windows.ts similarity index 98% rename from src/lib/onboard-windows-ollama.ts rename to src/lib/inference/ollama/windows.ts index bcdf1910ea8..9d8ad8a1c98 100644 --- a/src/lib/onboard-windows-ollama.ts +++ b/src/lib/inference/ollama/windows.ts @@ -6,9 +6,9 @@ // Detection lives in onboard.ts; this module owns the action side. const { spawn, spawnSync } = require("child_process"); -const { run, runCapture } = require("./runner"); -const { OLLAMA_HOST_DOCKER_INTERNAL, setResolvedOllamaHost } = require("./local-inference"); -const { OLLAMA_PORT } = require("./ports"); +const { run, runCapture } = require("../../runner"); +const { OLLAMA_HOST_DOCKER_INTERNAL, setResolvedOllamaHost } = require("../local"); +const { OLLAMA_PORT } = require("../../core/ports"); function sleep(seconds: number): void { spawnSync("sleep", [String(seconds)]); diff --git a/src/lib/onboard-inference-probes.test.ts b/src/lib/inference/onboard-probes.test.ts similarity index 99% rename from src/lib/onboard-inference-probes.test.ts rename to src/lib/inference/onboard-probes.test.ts index 80db0763e9b..744dc7c6b81 100644 --- a/src/lib/onboard-inference-probes.test.ts +++ b/src/lib/inference/onboard-probes.test.ts @@ -14,7 +14,7 @@ const { isSandboxInternalUrl, probeOpenAiLikeEndpoint, RETRIABLE_HTTP_PROBE_STATUSES, -} = require("../../dist/lib/onboard-inference-probes"); +} = require("../../../dist/lib/inference/onboard-probes"); describe("OpenAI-compatible inference probes", () => { it("uses the NVIDIA Build request shape for DeepSeek V4 Pro", () => { diff --git a/src/lib/onboard-inference-probes.ts b/src/lib/inference/onboard-probes.ts similarity index 99% rename from src/lib/onboard-inference-probes.ts rename to src/lib/inference/onboard-probes.ts index e1b00ffa4db..a610610bd09 100644 --- a/src/lib/onboard-inference-probes.ts +++ b/src/lib/inference/onboard-probes.ts @@ -5,14 +5,14 @@ // Inference endpoint probes — validate that a provider's API responds // before committing the onboard wizard to a model selection. -const { normalizeCredentialValue } = require("./credentials"); -const { isWsl } = require("./platform"); -const httpProbe = require("./http-probe"); +const { normalizeCredentialValue } = require("../credentials/store"); +const { isWsl } = require("../platform"); +const httpProbe = require("../http-probe"); const { isNvcfFunctionNotFoundForAccount, nvcfFunctionNotFoundMessage, shouldForceCompletionsApi, -} = require("./validation"); +} = require("../validation"); const { getCurlTimingArgs, diff --git a/src/lib/provider-models.test.ts b/src/lib/inference/provider-models.test.ts similarity index 99% rename from src/lib/provider-models.test.ts rename to src/lib/inference/provider-models.test.ts index b2b3c36e03f..0db060b7902 100644 --- a/src/lib/provider-models.test.ts +++ b/src/lib/inference/provider-models.test.ts @@ -11,7 +11,7 @@ import { validateAnthropicModel, validateNvidiaEndpointModel, validateOpenAiLikeModel, -} from "../../dist/lib/provider-models"; +} from "../../../dist/lib/inference/provider-models"; describe("provider model helpers", () => { it("fetches NVIDIA endpoint model ids", () => { diff --git a/src/lib/provider-models.ts b/src/lib/inference/provider-models.ts similarity index 97% rename from src/lib/provider-models.ts rename to src/lib/inference/provider-models.ts index b58da3e39e4..d0e04b62eab 100644 --- a/src/lib/provider-models.ts +++ b/src/lib/inference/provider-models.ts @@ -1,12 +1,12 @@ // SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. // SPDX-License-Identifier: Apache-2.0 -import type { CurlProbeResult } from "./http-probe"; -import { getCurlTimingArgs, runCurlProbe } from "./http-probe"; -import type { ModelCatalogFetchResult, ModelValidationResult } from "./onboard-types"; +import type { CurlProbeResult } from "../http-probe"; +import { getCurlTimingArgs, runCurlProbe } from "../http-probe"; +import type { ModelCatalogFetchResult, ModelValidationResult } from "../onboard-types"; // credentials.ts still uses CommonJS-style exports. -const { normalizeCredentialValue } = require("./credentials"); +const { normalizeCredentialValue } = require("../credentials/store"); export const BUILD_ENDPOINT_URL = "https://integrate.api.nvidia.com/v1"; diff --git a/src/lib/onboard-vllm.ts b/src/lib/inference/vllm.ts similarity index 98% rename from src/lib/onboard-vllm.ts rename to src/lib/inference/vllm.ts index 7fe47989c2f..9e4c3e03892 100644 --- a/src/lib/onboard-vllm.ts +++ b/src/lib/inference/vllm.ts @@ -5,9 +5,9 @@ // offer vLLM at all" lives in onboard.ts; this module owns picking the // right profile per platform and running the install. -const { runCapture, runShell } = require("./runner"); -const { dockerCapture, dockerSpawn } = require("./adapters/docker"); -const { VLLM_PORT } = require("./ports"); +const { runCapture, runShell } = require("../runner"); +const { dockerCapture, dockerSpawn } = require("../adapters/docker"); +const { VLLM_PORT } = require("../core/ports"); const { getGpuIndicesByName } = require("./nim"); // Per-platform install recipe. Add new platforms by appending an entry to diff --git a/src/lib/web-search.test.ts b/src/lib/inference/web-search.test.ts similarity index 100% rename from src/lib/web-search.test.ts rename to src/lib/inference/web-search.test.ts diff --git a/src/lib/web-search.ts b/src/lib/inference/web-search.ts similarity index 100% rename from src/lib/web-search.ts rename to src/lib/inference/web-search.ts diff --git a/src/lib/inventory-commands.ts b/src/lib/inventory-commands.ts index de7de47da7b..77eac8f7b31 100644 --- a/src/lib/inventory-commands.ts +++ b/src/lib/inventory-commands.ts @@ -1,9 +1,9 @@ // SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. // SPDX-License-Identifier: Apache-2.0 -import { CLI_NAME } from "./branding"; -import type { GatewayInference } from "./inference-config"; -import { redactFull } from "./redact"; +import { CLI_NAME } from "./cli/branding"; +import type { GatewayInference } from "./inference/config"; +import { redactFull } from "./security/redact"; export interface SandboxEntry { name: string; diff --git a/src/lib/list-command-deps.ts b/src/lib/list-command-deps.ts index 41d74c6d916..72863250889 100644 --- a/src/lib/list-command-deps.ts +++ b/src/lib/list-command-deps.ts @@ -5,7 +5,7 @@ import * as onboardSession from "./onboard-session"; import type { ListSandboxesCommandDeps } from "./inventory-commands"; -import { parseGatewayInference } from "./inference-config"; +import { parseGatewayInference } from "./inference/config"; import { OPENSHELL_PROBE_TIMEOUT_MS } from "./adapters/openshell/timeouts"; import { parseSshProcesses, createSystemDeps } from "./state/sandbox-session"; import { resolveOpenshell } from "./adapters/openshell/resolve"; diff --git a/src/lib/onboard-command.ts b/src/lib/onboard-command.ts index d8a707277a3..9abfaa2d9d9 100644 --- a/src/lib/onboard-command.ts +++ b/src/lib/onboard-command.ts @@ -4,7 +4,7 @@ import fs from "node:fs"; import path from "node:path"; -import { CLI_NAME } from "./branding"; +import { CLI_NAME } from "./cli/branding"; export interface OnboardCommandOptions { nonInteractive: boolean; diff --git a/src/lib/onboard-providers.ts b/src/lib/onboard-providers.ts index 499509deaea..bdf5669d206 100644 --- a/src/lib/onboard-providers.ts +++ b/src/lib/onboard-providers.ts @@ -9,9 +9,9 @@ const { DEFAULT_CLOUD_MODEL, OLLAMA_LOCAL_CREDENTIAL_ENV, VLLM_LOCAL_CREDENTIAL_ENV, -} = require("./inference-config"); +} = require("./inference/config"); const { isSafeModelId } = require("./validation"); -const { compactText } = require("./url-utils"); +const { compactText } = require("./core/url-utils"); // ── Constants ──────────────────────────────────────────────────── diff --git a/src/lib/onboard-session.ts b/src/lib/onboard-session.ts index 5d40c58358c..af507a77118 100644 --- a/src/lib/onboard-session.ts +++ b/src/lib/onboard-session.ts @@ -10,20 +10,20 @@ import fs from "node:fs"; import path from "node:path"; -import { redactSensitiveText, redactUrl } from "./redact"; -import { isErrnoException } from "./errno"; +import { isErrnoException } from "./core/errno"; +import { redactSensitiveText, redactUrl } from "./security/redact"; import { sanitizeMessagingChannelConfig, type MessagingChannelConfig, } from "./messaging-channel-config"; -import type { WebSearchConfig } from "./web-search"; +import type { WebSearchConfig } from "./inference/web-search"; export const SESSION_VERSION = 1; export const SESSION_DIR = path.join(process.env.HOME || "/tmp", ".nemoclaw"); export const SESSION_FILE = path.join(SESSION_DIR, "onboard-session.json"); export const LOCK_FILE = path.join(SESSION_DIR, "onboard.lock"); -import type { JsonValue, JsonObject } from "./json-types"; +import type { JsonValue, JsonObject } from "./core/json-types"; // Session-specific aliases for the shared JSON types. type SessionJsonValue = JsonValue; diff --git a/src/lib/onboard.ts b/src/lib/onboard.ts index 545d72284db..bf5f5968b8d 100644 --- a/src/lib/onboard.ts +++ b/src/lib/onboard.ts @@ -5,7 +5,7 @@ // Supports non-interactive mode via --non-interactive flag or // NEMOCLAW_NON_INTERACTIVE=1 env var for CI/CD pipelines. -const { getAgentBranding } = require("./branding"); +const { getAgentBranding } = require("./cli/branding"); const crypto = require("node:crypto"); const fs = require("fs"); const os = require("os"); @@ -31,7 +31,7 @@ function setOnboardBrandingAgent(agentName: string | null | undefined): void { onboardBrandingAgent = agentName || null; } -function onboardBranding(): import("./branding").AgentBranding { +function onboardBranding(): import("./cli/branding").AgentBranding { return getAgentBranding(onboardBrandingAgent || process.env.NEMOCLAW_AGENT || null); } @@ -70,7 +70,7 @@ const { dockerRmi, dockerStop, } = docker; -const errnoUtils: typeof import("./errno") = require("./errno"); +const errnoUtils: typeof import("./core/errno") = require("./core/errno"); const { isErrnoException } = errnoUtils; type RunnerOptions = { @@ -105,8 +105,8 @@ const { OLLAMA_PROXY_PORT, DASHBOARD_PORT_RANGE_START, DASHBOARD_PORT_RANGE_END, -} = require("./ports"); -const localInference: typeof import("./local-inference") = require("./local-inference"); +} = require("./core/ports"); +const localInference: typeof import("./inference/local") = require("./inference/local"); const { findReachableOllamaHost, resetOllamaHostCache, @@ -130,15 +130,15 @@ const { killStaleProxy, persistProxyToken, startOllamaAuthProxy, -} = require("./onboard-ollama-proxy"); +} = require("./inference/ollama/proxy"); const { installOllamaOnWindowsHost, awaitWindowsOllamaReady, setupWindowsOllamaWith0000Binding, switchToWindowsOllamaHost, -} = require("./onboard-windows-ollama"); -const { detectVllmProfile, installVllm } = require("./onboard-vllm"); -const inferenceConfig: typeof import("./inference-config") = require("./inference-config"); +} = require("./inference/ollama/windows"); +const { detectVllmProfile, installVllm } = require("./inference/vllm"); +const inferenceConfig: typeof import("./inference/config") = require("./inference/config"); const { DEFAULT_CLOUD_MODEL, INFERENCE_ROUTE_URL, @@ -256,11 +256,11 @@ const { inferenceCompat: LooseObject | null; }; }; -const { sleepSeconds } = require("./wait"); +const { sleepSeconds } = require("./core/wait"); const platformUtils: typeof import("./platform") = require("./platform"); const { inferContainerRuntime, isWsl, shouldPatchCoredns } = platformUtils; const { resolveOpenshell } = require("./adapters/openshell/resolve"); -const credentials: typeof import("./credentials") = require("./credentials"); +const credentials: typeof import("./credentials/store") = require("./credentials/store"); const { prompt, ensureApiKey, @@ -271,12 +271,12 @@ const { resolveProviderCredential, saveCredential, } = credentials; -const { hashCredential }: typeof import("./credential-hash") = require("./credential-hash"); +const { hashCredential }: typeof import("./security/credential-hash") = require("./security/credential-hash"); const { cleanupStaleHostFiles, }: typeof import("./host-artifact-cleanup") = require("./host-artifact-cleanup"); const registry: typeof import("./state/registry") = require("./state/registry"); -const nim: typeof import("./nim") = require("./nim"); +const nim: typeof import("./inference/nim") = require("./inference/nim"); const onboardSession: typeof import("./onboard-session") = require("./onboard-session"); const policies: typeof import("./policies") = require("./policies"); const shields = require("./shields"); @@ -293,26 +293,26 @@ const { planHostRemediation, probeContainerDns, } = preflightUtils; -const agentOnboard = require("./agent-onboard"); -const agentDefs = require("./agent-defs"); +const agentOnboard = require("./agent/onboard"); +const agentDefs = require("./agent/defs"); const gatewayState: typeof import("./state/gateway") = require("./state/gateway"); const sandboxState: typeof import("./state/sandbox") = require("./state/sandbox"); const validation: typeof import("./validation") = require("./validation"); -const urlUtils: typeof import("./url-utils") = require("./url-utils"); +const urlUtils: typeof import("./core/url-utils") = require("./core/url-utils"); const buildContext = require("./build-context"); -const dashboardContract: typeof import("./dashboard-contract") = require("./dashboard-contract"); +const dashboardContract: typeof import("./dashboard/contract") = require("./dashboard/contract"); const httpProbe: typeof import("./http-probe") = require("./http-probe"); -const modelPrompts: typeof import("./model-prompts") = require("./model-prompts"); -const providerModels: typeof import("./provider-models") = require("./provider-models"); +const modelPrompts: typeof import("./inference/model-prompts") = require("./inference/model-prompts"); +const providerModels: typeof import("./inference/provider-models") = require("./inference/provider-models"); const sandboxCreateStream: typeof import("./sandbox-create-stream") = require("./sandbox-create-stream"); const validationRecovery: typeof import("./validation-recovery") = require("./validation-recovery"); -const webSearch: typeof import("./web-search") = require("./web-search"); +const webSearch: typeof import("./inference/web-search") = require("./inference/web-search"); -import type { AgentDefinition } from "./agent-defs"; +import type { AgentDefinition } from "./agent/defs"; import type { CurlProbeResult } from "./http-probe"; -import type { GatewayInference, ProviderSelectionConfig } from "./inference-config"; -import type { GpuInfo, ValidationResult } from "./local-inference"; +import type { GatewayInference, ProviderSelectionConfig } from "./inference/config"; +import type { GpuInfo, ValidationResult } from "./inference/local"; import { hydrateMessagingChannelConfig, mergeMessagingChannelConfigs, @@ -336,7 +336,7 @@ import type { BackupResult } from "./state/sandbox"; import type { TierDefinition, TierPreset } from "./tiers"; import type { SandboxCreateFailure, ValidationClassification } from "./validation"; import type { ProbeRecovery } from "./validation-recovery"; -import type { WebSearchConfig } from "./web-search"; +import type { WebSearchConfig } from "./inference/web-search"; /** * Create a temp file inside a directory with a cryptographically random name. @@ -412,12 +412,12 @@ const OPENCLAW_LAUNCH_AGENT_PLIST = "~/Library/LaunchAgents/ai.openclaw.gateway. const BRAVE_SEARCH_HELP_URL = "https://brave.com/search/api/"; // Re-export shared JSON types under the names used throughout this module. -// See src/lib/json-types.ts for the canonical definitions. +// See src/lib/core/json-types.ts for the canonical definitions. import type { JsonObject as LooseObject, JsonScalar as LooseScalar, JsonValue as LooseValue, -} from "./json-types"; +} from "./core/json-types"; type OnboardOptions = { nonInteractive?: boolean; @@ -1166,7 +1166,7 @@ function executeSandboxCommandForVerification( } } -// URL/string utilities — delegated to src/lib/url-utils.ts +// URL/string utilities — delegated to src/lib/core/url-utils.ts const { compactText, normalizeProviderBaseUrl, @@ -2524,7 +2524,7 @@ function patchStagedDockerfile( fs.writeFileSync(dockerfilePath, dockerfile); } -// Inference probes — moved to onboard-inference-probes.ts +// Inference probes — moved to inference/onboard-probes.ts const { hasResponsesToolCall, shouldRequireResponsesToolCalling, @@ -2532,7 +2532,7 @@ const { getValidationProbeCurlArgs, probeOpenAiLikeEndpoint, probeAnthropicEndpoint, -} = require("./onboard-inference-probes"); +} = require("./inference/onboard-probes"); // shouldSkipResponsesProbe and isNvcfFunctionNotFoundForAccount / // nvcfFunctionNotFoundMessage — see validation import above. They live in @@ -2691,16 +2691,16 @@ const { shouldIncludeBuildContextPath, copyBuildContextDir, printSandboxCreateRe // classifySandboxCreateFailure — see validation import above // --------------------------------------------------------------------------- -// Ollama model prompt/pull/prepare functions — from onboard-ollama-proxy.ts +// Ollama model prompt/pull/prepare functions — from inference/ollama/proxy.ts // (proxy lifecycle functions already imported at the top of this file) const { promptOllamaModel, printOllamaExposureWarning, pullOllamaModel, prepareOllamaModel, -} = require("./onboard-ollama-proxy"); +} = require("./inference/ollama/proxy"); -const ollamaModelSize: typeof import("./ollama-model-size") = require("./ollama-model-size"); +const ollamaModelSize: typeof import("./inference/ollama/model-size") = require("./inference/ollama/model-size"); function getRequestedSandboxNameHint(opts: { sandboxName?: string | null } = {}): string | null { const raw = @@ -3687,7 +3687,7 @@ async function preflight(): Promise> { // Required ports — gateway, plus the dashboard port when an explicit one // is requested. envVar is the override env var documented in - // src/lib/ports.ts; surfacing it in the preflight error gives users a clear + // src/lib/core/ports.ts; surfacing it in the preflight error gives users a clear // escape hatch when an unrelated process is holding the default port // (closes #2497). When --control-ui-port is set, check that port instead // of the default. When auto-allocation is possible (no explicit port), @@ -5729,14 +5729,14 @@ async function setupNim( // (#2674). const localProbeCurlArgs = ["--connect-timeout", "2", "--max-time", "5"] as const; const hasOllama = hostCommandExists("ollama"); - // run and consumed by the Ollama lifecycle helpers in local-inference.ts. + // run and consumed by the Ollama lifecycle helpers in inference/local.ts. const ollamaHost = findReachableOllamaHost(); const ollamaRunning = ollamaHost !== null; const vllmRunning = !!runCapture( ["curl", "-sf", ...localProbeCurlArgs, `http://127.0.0.1:${VLLM_PORT}/v1/models`], { ignoreError: true }, ); - // Pick a vLLM install recipe for this host. Profiles live in onboard-vllm.ts; + // Pick a vLLM install recipe for this host. Profiles live in inference/vllm.ts; // null means "no supported platform" (vLLM stays behind EXPERIMENTAL). const vllmProfile = detectVllmProfile(gpu); // If the profile's image is already cached, the install path is really a @@ -5842,7 +5842,7 @@ async function setupNim( if (EXPERIMENTAL && gpu && gpu.nimCapable) { options.push({ key: "nim-local", label: "Local NVIDIA NIM [experimental]" }); } - // vLLM: profiles in onboard-vllm.ts surface as menu entries only when + // vLLM: profiles in inference/vllm.ts surface as menu entries only when // the user explicitly opts in via NEMOCLAW_PROVIDER, or when // NEMOCLAW_EXPERIMENTAL=1 is set. // Read NEMOCLAW_PROVIDER directly so interactive runs with an explicit @@ -6835,7 +6835,7 @@ async function setupNim( } provider = bp.provider_name || "nvidia-router"; model = bp.model; - const { HOST_GATEWAY_URL } = require("./local-inference"); + const { HOST_GATEWAY_URL } = require("./inference/local"); const routerEndpointUrl = bp.endpoint || ""; endpointUrl = routerEndpointUrl; if (routerEndpointUrl.match(/localhost|127\.0\.0\.1/)) { @@ -8416,7 +8416,7 @@ function syncPresetSelection( const CONTROL_UI_PORT = DASHBOARD_PORT; -// Dashboard helpers — delegated to src/lib/dashboard-contract.ts +// Dashboard helpers — delegated to src/lib/dashboard/contract.ts const { buildChain, buildControlUiUrls } = dashboardContract; // Parses `openshell forward list` output and returns the sandbox currently diff --git a/src/lib/onboard/README.md b/src/lib/onboard/README.md new file mode 100644 index 00000000000..d54cba0b247 --- /dev/null +++ b/src/lib/onboard/README.md @@ -0,0 +1,28 @@ + + + +# Onboard support + +`src/lib/onboard` is the transitional home for onboarding support modules while the large legacy `src/lib/onboard.ts` flow is split over time. + +Good candidates: + +```text +types.ts +providers.ts +preflight.ts +usage-notice.ts +legacy-command.ts +``` + +Related modules may live outside this folder when their ownership is clearer: + +```text +src/lib/state/onboard-session.ts persisted onboarding session state +src/lib/inference/onboard-probes.ts inference validation probes used by onboarding +src/lib/inference/ollama/proxy.ts Ollama proxy lifecycle helpers +src/lib/inference/vllm.ts vLLM onboarding helpers +src/lib/inference/ollama/windows.ts Windows Ollama support +``` + +Do not move `src/lib/onboard.ts` casually. It is high-import and high-risk; if it moves, keep a compatibility re-export path or split it through focused behavior-preserving PRs. diff --git a/src/lib/policies.ts b/src/lib/policies.ts index 0bcdf3ad9b1..c2dad0850ea 100644 --- a/src/lib/policies.ts +++ b/src/lib/policies.ts @@ -3,7 +3,7 @@ // // Policy preset management — list, load, merge, and apply presets. -import type { JsonValue, JsonObject } from "./json-types"; +import type { JsonValue, JsonObject } from "./core/json-types"; const fs = require("fs"); const path = require("path"); @@ -12,7 +12,7 @@ const readline = require("readline"); const YAML = require("yaml"); const { ROOT, run, runCapture } = require("./runner"); const registry = require("./state/registry"); -const { loadAgent } = require("./agent-defs"); +const { loadAgent } = require("./agent/defs"); const PRESETS_DIR = path.join(ROOT, "nemoclaw-blueprint", "policies", "presets"); diff --git a/src/lib/preflight.ts b/src/lib/preflight.ts index 8832d10ebe5..de024d2434e 100644 --- a/src/lib/preflight.ts +++ b/src/lib/preflight.ts @@ -14,7 +14,7 @@ import net from "node:net"; import os from "node:os"; import path from "node:path"; -import { DASHBOARD_PORT } from "./ports"; +import { DASHBOARD_PORT } from "./core/ports"; // runner.ts still uses CommonJS-style exports — use require here. const { runCapture } = require("./runner"); diff --git a/src/lib/runner.ts b/src/lib/runner.ts index 73c2a61e297..b4cdca517cc 100644 --- a/src/lib/runner.ts +++ b/src/lib/runner.ts @@ -246,7 +246,7 @@ function runCapture(cmd: readonly string[], opts: CaptureOptions = {}): string { } // Unified redaction — see redact.ts (#2381). -const { redact, redactError, writeRedactedResult } = require("./redact"); +const { redact, redactError, writeRedactedResult } = require("./security/redact"); /** * Shell-quote a value for safe interpolation into bash -c strings. diff --git a/src/lib/sandbox-channels.ts b/src/lib/sandbox-channels.ts index a7e9f1e4c2b..15f65a4e207 100644 --- a/src/lib/sandbox-channels.ts +++ b/src/lib/sandbox-channels.ts @@ -1,7 +1,7 @@ // SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. // SPDX-License-Identifier: Apache-2.0 -import { deleteCredential, saveCredential } from "./credentials"; +import { deleteCredential, saveCredential } from "./credentials/store"; export interface ChannelDef { envKey: string; diff --git a/src/lib/sandbox-config.ts b/src/lib/sandbox-config.ts index 6270c44a9d9..d6f3b12d237 100644 --- a/src/lib/sandbox-config.ts +++ b/src/lib/sandbox-config.ts @@ -20,13 +20,13 @@ const { promises: dnsPromises } = require("node:dns"); const { isIP } = require("node:net"); const { validateName } = require("./runner"); const { dockerExecFileSync } = require("./adapters/docker/exec"); -const credentialFilter: typeof import("./credential-filter") = require("./credential-filter"); +const credentialFilter: typeof import("./security/credential-filter") = require("./security/credential-filter"); const { stripCredentials, isConfigObject, isConfigValue, isCredentialField } = credentialFilter; -const { appendAuditEntry } = require("./shields-audit"); +const { appendAuditEntry } = require("./shields/audit"); const { isPrivateHostname, isPrivateIp } = require("./private-networks"); -type ConfigObject = import("./credential-filter").ConfigObject; -type ConfigValue = import("./credential-filter").ConfigValue; +type ConfigObject = import("./security/credential-filter").ConfigObject; +type ConfigValue = import("./security/credential-filter").ConfigValue; const { runOpenshellCommand, captureOpenshellCommand } = require("./adapters/openshell/client"); function parseJson(text: string): T { @@ -98,7 +98,7 @@ function resolveAgentConfig(sandboxName: string): AgentConfigTarget { const entry = registry.getSandbox(sandboxName); if (!entry || !entry.agent) return DEFAULT_AGENT_CONFIG; - const agentDefs = require("./agent-defs"); + const agentDefs = require("./agent/defs"); const agent = agentDefs.loadAgent(entry.agent); const cfg = agent.configPaths; @@ -866,7 +866,7 @@ async function configRotateToken(sandboxName: string, opts: RotateTokenOpts = {} } else if (opts.fromStdin) { newToken = await readStdin(); } else { - const { promptSecret } = require("./credentials"); + const { promptSecret } = require("./credentials/store"); newToken = await promptSecret(` New ${credentialEnv} value: `); } @@ -886,7 +886,7 @@ async function configRotateToken(sandboxName: string, opts: RotateTokenOpts = {} // 4. Stage the new value in the current process so the openshell update // that follows can read it via --credential . The OpenShell // gateway becomes the system of record once the update succeeds. - const { saveCredential } = require("./credentials"); + const { saveCredential } = require("./credentials/store"); saveCredential(credentialEnv, newToken); // 5. Update the openshell provider diff --git a/src/lib/sandbox-version.test.ts b/src/lib/sandbox-version.test.ts index fe1f7f770d4..b181c7fdcc8 100644 --- a/src/lib/sandbox-version.test.ts +++ b/src/lib/sandbox-version.test.ts @@ -31,7 +31,7 @@ vi.mock("./adapters/openshell/client.js", () => ({ captureOpenshellCommand: vi.fn(), })); -vi.mock("./agent-defs.js", () => ({ +vi.mock("./agent/defs.js", () => ({ loadAgent: vi.fn((name: string) => ({ name, displayName: name === "openclaw" ? "OpenClaw" : "Hermes Agent", diff --git a/src/lib/sandbox-version.ts b/src/lib/sandbox-version.ts index 2904f274cc0..958adc10057 100644 --- a/src/lib/sandbox-version.ts +++ b/src/lib/sandbox-version.ts @@ -15,7 +15,7 @@ import path from "path"; import { parseVersionFromText, versionGte } from "./adapters/openshell/client.js"; import * as registry from "./state/registry.js"; -import { loadAgent } from "./agent-defs.js"; +import { loadAgent } from "./agent/defs.js"; import { resolveOpenshell } from "./adapters/openshell/resolve.js"; import { captureOpenshellCommand } from "./adapters/openshell/client.js"; import { OPENSHELL_PROBE_TIMEOUT_MS } from "./adapters/openshell/timeouts.js"; diff --git a/src/lib/sandbox/README.md b/src/lib/sandbox/README.md new file mode 100644 index 00000000000..3a1a4cc299f --- /dev/null +++ b/src/lib/sandbox/README.md @@ -0,0 +1,18 @@ + + + +# Sandbox support + +`src/lib/sandbox` is for sandbox configuration, build context, create-stream, version, and channel support that is not already owned by an action/domain module. + +Suggested homes: + +```text +config.ts sandbox config download/upload and mutation support +build-context.ts sandbox build context construction +create-stream.ts sandbox create progress parsing +version.ts sandbox/agent version helpers +channels.ts sandbox channel support, unless moved to messaging +``` + +Command workflows should continue to live under `src/lib/actions/sandbox/**`. Pure validation/classification helpers should live under `src/lib/domain/sandbox/**`. diff --git a/src/lib/security/README.md b/src/lib/security/README.md new file mode 100644 index 00000000000..3aeb1da673d --- /dev/null +++ b/src/lib/security/README.md @@ -0,0 +1,17 @@ + + + +# Security helpers + +`src/lib/security` is for reusable redaction, secret-pattern, credential-hash, and credential-filter helpers. + +Suggested homes: + +```text +credential-filter.ts +credential-hash.ts +redact.ts +secret-patterns.ts +``` + +Credential storage belongs under `src/lib/credentials/**`; security helpers should not own persistence or user prompts. diff --git a/src/lib/credential-filter.test.ts b/src/lib/security/credential-filter.test.ts similarity index 100% rename from src/lib/credential-filter.test.ts rename to src/lib/security/credential-filter.test.ts diff --git a/src/lib/credential-filter.ts b/src/lib/security/credential-filter.ts similarity index 100% rename from src/lib/credential-filter.ts rename to src/lib/security/credential-filter.ts diff --git a/src/lib/credential-hash.ts b/src/lib/security/credential-hash.ts similarity index 100% rename from src/lib/credential-hash.ts rename to src/lib/security/credential-hash.ts diff --git a/src/lib/redact.ts b/src/lib/security/redact.ts similarity index 100% rename from src/lib/redact.ts rename to src/lib/security/redact.ts diff --git a/src/lib/secret-patterns.ts b/src/lib/security/secret-patterns.ts similarity index 96% rename from src/lib/secret-patterns.ts rename to src/lib/security/secret-patterns.ts index f1d90c41f16..318d6e5c048 100644 --- a/src/lib/secret-patterns.ts +++ b/src/lib/security/secret-patterns.ts @@ -4,7 +4,7 @@ /** * Canonical secret redaction patterns — single source of truth. * - * All TypeScript consumers import through src/lib/redact.ts (#2381). + * All TypeScript consumers import through src/lib/security/redact.ts (#2381). * debug.sh delegates to the compiled redact module when node is available; * its sed fallback only covers the prefixes in EXPECTED_SHELL_PREFIXES. * diff --git a/src/lib/services.ts b/src/lib/services.ts index e6dd5088e10..cc2bfe4167f 100644 --- a/src/lib/services.ts +++ b/src/lib/services.ts @@ -15,9 +15,9 @@ import { } from "node:fs"; import { join } from "node:path"; -import { AGENT_PRODUCT_NAME, CLI_DISPLAY_NAME } from "./branding"; +import { AGENT_PRODUCT_NAME, CLI_DISPLAY_NAME } from "./cli/branding"; import { dockerSpawnSync } from "./adapters/docker"; -import { DASHBOARD_PORT } from "./ports"; +import { DASHBOARD_PORT } from "./core/ports"; import { resolveOpenshell } from "./adapters/openshell/resolve"; import { buildSubprocessEnv } from "./subprocess-env"; @@ -429,7 +429,7 @@ export function stopAll(opts: ServiceOptions = {}): void { } try { - const { unloadOllamaModels } = require("./onboard-ollama-proxy"); + const { unloadOllamaModels } = require("./inference/ollama/proxy"); unloadOllamaModels(); } catch { /* best-effort */ diff --git a/src/lib/share-command-deps.ts b/src/lib/share-command-deps.ts index 56d649e4834..88fc4f3271b 100644 --- a/src/lib/share-command-deps.ts +++ b/src/lib/share-command-deps.ts @@ -1,9 +1,9 @@ // SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. // SPDX-License-Identifier: Apache-2.0 -import { CLI_NAME } from "./branding"; +import { CLI_NAME } from "./cli/branding"; import { OPENSHELL_PROBE_TIMEOUT_MS } from "./adapters/openshell/timeouts"; -import { G, R } from "./terminal-style"; +import { G, R } from "./cli/terminal-style"; export interface ShareCommandDeps { /** Run `openshell sandbox ssh-config ` and return output. */ diff --git a/test/shields-audit.test.ts b/src/lib/shields/audit.test.ts similarity index 100% rename from test/shields-audit.test.ts rename to src/lib/shields/audit.test.ts diff --git a/src/lib/shields-audit.ts b/src/lib/shields/audit.ts similarity index 93% rename from src/lib/shields-audit.ts rename to src/lib/shields/audit.ts index cc21cd79be0..75a3484ad7f 100644 --- a/src/lib/shields-audit.ts +++ b/src/lib/shields/audit.ts @@ -11,8 +11,8 @@ import { appendFileSync } from "node:fs"; import { join } from "node:path"; -import { ensureConfigDir } from "./state/config-io"; -import { redactFull } from "./redact"; +import { redactFull } from "../security/redact"; +import { ensureConfigDir } from "../state/config-io"; const AUDIT_DIR = join(process.env.HOME ?? "/tmp", ".nemoclaw", "state"); const AUDIT_FILE = join(AUDIT_DIR, "shields-audit.jsonl"); diff --git a/test/shields.test.ts b/src/lib/shields/index.test.ts similarity index 95% rename from test/shields.test.ts rename to src/lib/shields/index.test.ts index 7c07b265cc5..83c509ca317 100644 --- a/test/shields.test.ts +++ b/src/lib/shields/index.test.ts @@ -9,7 +9,7 @@ import os from "node:os"; // The shields module uses CJS require("./runner") etc., which vitest resolves // relative to src/lib/. We mock the absolute paths that vitest will resolve. -vi.mock("../../src/lib/runner", () => ({ +vi.mock("../runner", () => ({ run: vi.fn(() => ({ status: 0 })), runCapture: vi.fn(() => "version: 1\nnetwork_policies:\n test: {}"), validateName: vi.fn((name) => name), @@ -18,7 +18,7 @@ vi.mock("../../src/lib/runner", () => ({ ROOT: "/mock/root", })); -vi.mock("../../src/lib/policies", () => ({ +vi.mock("../policies", () => ({ buildPolicyGetCommand: vi.fn((name) => ["openshell", "policy", "get", "--full", name]), buildPolicySetCommand: vi.fn((file, name) => [ "openshell", @@ -33,7 +33,7 @@ vi.mock("../../src/lib/policies", () => ({ PERMISSIVE_POLICY_PATH: "/mock/permissive.yaml", })); -vi.mock("../../src/lib/sandbox-config", () => ({ +vi.mock("../sandbox-config", () => ({ resolveAgentConfig: vi.fn(() => ({ agentName: "openclaw", configPath: "/sandbox/.openclaw/openclaw.json", @@ -43,7 +43,7 @@ vi.mock("../../src/lib/sandbox-config", () => ({ })), })); -vi.mock("../../src/lib/shields-audit", () => ({ +vi.mock("./audit", () => ({ appendAuditEntry: vi.fn(), })); @@ -76,29 +76,29 @@ describe("shields — unit logic", () => { // Since the CJS require resolution issue makes direct import flaky, // test the TypeScript duration module instead. it("parses minutes", async () => { - const { parseDuration } = await import("../src/lib/domain/duration.js"); + const { parseDuration } = await import("../domain/duration.js"); expect(parseDuration("5m")).toBe(300); expect(parseDuration("30m")).toBe(1800); }); it("parses seconds", async () => { - const { parseDuration } = await import("../src/lib/domain/duration.js"); + const { parseDuration } = await import("../domain/duration.js"); expect(parseDuration("90s")).toBe(90); }); it("treats bare numbers as seconds", async () => { - const { parseDuration } = await import("../src/lib/domain/duration.js"); + const { parseDuration } = await import("../domain/duration.js"); expect(parseDuration("300")).toBe(300); }); it("rejects durations exceeding 30 minutes", async () => { - const { parseDuration } = await import("../src/lib/domain/duration.js"); + const { parseDuration } = await import("../domain/duration.js"); expect(() => parseDuration("31m")).toThrow("exceeds maximum"); expect(() => parseDuration("1h")).toThrow("exceeds maximum"); }); it("rejects invalid input", async () => { - const { parseDuration } = await import("../src/lib/domain/duration.js"); + const { parseDuration } = await import("../domain/duration.js"); expect(() => parseDuration("abc")).toThrow("Invalid duration"); }); }); @@ -266,7 +266,7 @@ describe("shields — unit logic", () => { // ------------------------------------------------------------------- describe("NC-2227-02: three-state shields model", () => { it("deriveShieldsMode encodes the fresh, locked, unlocked, and legacy-state cases", async () => { - const { deriveShieldsMode } = await import("../dist/lib/shields.js"); + const { deriveShieldsMode } = await import("../../../dist/lib/shields/index.js"); expect(deriveShieldsMode({}, false)).toBe("mutable_default"); expect(deriveShieldsMode({ shieldsDown: true }, true)).toBe("temporarily_unlocked"); @@ -281,10 +281,7 @@ describe("shields — unit logic", () => { // ------------------------------------------------------------------- describe("NC-2227-04: sandbox-state.ts tar commands do not follow symlinks", () => { function getSourceCode(): string { - return fs.readFileSync( - path.join(import.meta.dirname, "..", "src", "lib", "state", "sandbox.ts"), - "utf-8", - ); + return fs.readFileSync(path.join(import.meta.dirname, "..", "state", "sandbox.ts"), "utf-8"); } it("backup tar command does not use -h flag (no symlink following)", () => { @@ -386,10 +383,7 @@ describe("NC-2227-04: sandbox-state.ts tar commands do not follow symlinks", () // ------------------------------------------------------------------- describe("NC-2227-05: shields.ts locks state directories", () => { function getSourceCode(): string { - return fs.readFileSync( - path.join(import.meta.dirname, "..", "src", "lib", "shields.ts"), - "utf-8", - ); + return fs.readFileSync(path.join(import.meta.dirname, "index.ts"), "utf-8"); } it("HIGH_RISK_STATE_DIRS constant includes executable state and workspace entry points", () => { diff --git a/src/lib/shields.ts b/src/lib/shields/index.ts similarity index 99% rename from src/lib/shields.ts rename to src/lib/shields/index.ts index fb84e767e26..cc95b5d18e1 100644 --- a/src/lib/shields.ts +++ b/src/lib/shields/index.ts @@ -13,17 +13,17 @@ const fs = require("fs"); const path = require("path"); const { fork } = require("child_process"); -const { run, runCapture, validateName, shellQuote } = require("./runner"); -const { dockerExecFileSync } = require("./adapters/docker/exec"); +const { run, runCapture, validateName, shellQuote } = require("../runner"); +const { dockerExecFileSync } = require("../adapters/docker/exec"); const { buildPolicyGetCommand, buildPolicySetCommand, parseCurrentPolicy, PERMISSIVE_POLICY_PATH, -} = require("./policies"); -const { parseDuration, MAX_SECONDS, DEFAULT_SECONDS } = require("./domain/duration"); -const { appendAuditEntry } = require("./shields-audit"); -const { resolveAgentConfig } = require("./sandbox-config"); +} = require("../policies"); +const { parseDuration, MAX_SECONDS, DEFAULT_SECONDS } = require("../domain/duration"); +const { appendAuditEntry } = require("./audit"); +const { resolveAgentConfig } = require("../sandbox-config"); const STATE_DIR = path.join(process.env.HOME ?? "/tmp", ".nemoclaw", "state"); @@ -691,7 +691,7 @@ function shieldsDown(sandboxName: string, opts: ShieldsDownOpts = {}): void { // can take minutes (policy apply + kubectl chmod), so a relative timeout // passed at fork time would fire too early. const restoreAt = new Date(Date.now() + timeoutSeconds * 1000); - const timerScript = path.join(__dirname, "shields-timer.ts"); + const timerScript = path.join(__dirname, "timer.ts"); const timerScriptJs = timerScript.replace(/\.ts$/, ".js"); const actualScript = fs.existsSync(timerScriptJs) ? timerScriptJs : timerScript; diff --git a/src/lib/shields-timer.ts b/src/lib/shields/timer.ts similarity index 97% rename from src/lib/shields-timer.ts rename to src/lib/shields/timer.ts index 331de47401c..a0b8917114e 100644 --- a/src/lib/shields-timer.ts +++ b/src/lib/shields/timer.ts @@ -11,10 +11,10 @@ import fs from "node:fs"; import path from "node:path"; -import { buildPolicySetCommand } from "./policies"; -import { run } from "./runner"; -import { DEFAULT_AGENT_CONFIG, resolveAgentConfig } from "./sandbox-config"; -import { lockAgentConfig } from "./shields"; +import { buildPolicySetCommand } from "../policies"; +import { run } from "../runner"; +import { DEFAULT_AGENT_CONFIG, resolveAgentConfig } from "../sandbox-config"; +import { lockAgentConfig } from "./index"; type UnknownRecord = { [key: string]: unknown }; diff --git a/src/lib/state/config-io.ts b/src/lib/state/config-io.ts index f9bbc5cfd55..61203f83c85 100644 --- a/src/lib/state/config-io.ts +++ b/src/lib/state/config-io.ts @@ -7,8 +7,8 @@ import fs from "node:fs"; import os from "node:os"; import path from "node:path"; -import { shellQuote } from "../shell-quote"; -import { isErrnoException, isPermissionError } from "../errno"; +import { shellQuote } from "../core/shell-quote"; +import { isErrnoException, isPermissionError } from "../core/errno"; // Strict JSON types for file serialization — unlike json-types.ts, // these exclude undefined since actual JSON cannot contain it. diff --git a/src/lib/state/registry.ts b/src/lib/state/registry.ts index 2f42b384111..b29e0b9acd8 100644 --- a/src/lib/state/registry.ts +++ b/src/lib/state/registry.ts @@ -5,7 +5,7 @@ import fs from "node:fs"; import path from "node:path"; import { ensureConfigDir, readConfigFile, writeConfigFile } from "./config-io"; -import { isErrnoException } from "../errno"; +import { isErrnoException } from "../core/errno"; import type { MessagingChannelConfig } from "../messaging-channel-config"; export interface CustomPolicyEntry { diff --git a/src/lib/state/sandbox.ts b/src/lib/state/sandbox.ts index ecaefa974c0..9e6c5cbd7f5 100644 --- a/src/lib/state/sandbox.ts +++ b/src/lib/state/sandbox.ts @@ -26,11 +26,11 @@ import os from "node:os"; import path from "node:path"; import * as registry from "./registry.js"; -import { loadAgent } from "../agent-defs.js"; -import type { AgentStateFile } from "../agent-defs.js"; +import { loadAgent } from "../agent/defs.js"; +import type { AgentStateFile } from "../agent/defs.js"; import { resolveOpenshell } from "../adapters/openshell/resolve.js"; import { captureOpenshellCommand } from "../adapters/openshell/client.js"; -import { sanitizeConfigFile, isSensitiveFile } from "../credential-filter.js"; +import { sanitizeConfigFile, isSensitiveFile } from "../security/credential-filter.js"; import { shellQuote } from "../runner.js"; const HOME_DIR = path.resolve(process.env.HOME || os.homedir()); diff --git a/src/lib/status-command-deps.ts b/src/lib/status-command-deps.ts index fb239833f97..9ba1d063200 100644 --- a/src/lib/status-command-deps.ts +++ b/src/lib/status-command-deps.ts @@ -5,7 +5,7 @@ import { spawnSync } from "node:child_process"; -import { parseGatewayInference } from "./inference-config"; +import { parseGatewayInference } from "./inference/config"; import type { MessagingBridgeHealth, ShowStatusCommandDeps } from "./inventory-commands"; import { backfillMessagingChannels, findAllOverlaps } from "./messaging-conflict"; import type { CaptureOpenshellResult } from "./adapters/openshell/client"; diff --git a/src/lib/usage-notice.ts b/src/lib/usage-notice.ts index bab1f7999bf..bd062739f27 100644 --- a/src/lib/usage-notice.ts +++ b/src/lib/usage-notice.ts @@ -212,7 +212,7 @@ export async function ensureUsageNoticeConsent({ } // credentials is still CJS - const ask: PromptFn = promptFn ?? (require("./credentials") as { prompt: PromptFn }).prompt; + const ask: PromptFn = promptFn ?? (require("./credentials/store") as { prompt: PromptFn }).prompt; let answer: string; try { answer = String(await ask(` ${config.interactivePrompt}`)) diff --git a/src/lib/validation-recovery.ts b/src/lib/validation-recovery.ts index 16bde56118a..16eb50e3882 100644 --- a/src/lib/validation-recovery.ts +++ b/src/lib/validation-recovery.ts @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 import type { ValidationFailureLike } from "./onboard-types"; -import { compactText } from "./url-utils"; +import { compactText } from "./core/url-utils"; import { classifyValidationFailure, type ValidationClassification } from "./validation"; export interface ProbeRecoveryOptions { diff --git a/src/lib/verify-deployment.test.ts b/src/lib/verify-deployment.test.ts index f94bf093ab5..39882b6e4fe 100644 --- a/src/lib/verify-deployment.test.ts +++ b/src/lib/verify-deployment.test.ts @@ -3,7 +3,7 @@ import { describe, it, expect } from "vitest"; import { verifyDeployment, formatVerificationDiagnostics } from "../../dist/lib/verify-deployment.js"; -import { buildChain } from "../../dist/lib/dashboard-contract.js"; +import { buildChain } from "../../dist/lib/dashboard/contract.js"; const chain = buildChain(); diff --git a/src/lib/verify-deployment.ts b/src/lib/verify-deployment.ts index 7f6de07c141..0a7326aa9f4 100644 --- a/src/lib/verify-deployment.ts +++ b/src/lib/verify-deployment.ts @@ -17,7 +17,7 @@ * "Health Offline" in the dashboard. */ -import type { DashboardDeliveryChain } from "./dashboard-contract"; +import type { DashboardDeliveryChain } from "./dashboard/contract"; // ── Types ──────────────────────────────────────────────────────────── diff --git a/src/nemoclaw.ts b/src/nemoclaw.ts index fe29b385c3b..76982de8fce 100644 --- a/src/nemoclaw.ts +++ b/src/nemoclaw.ts @@ -4,7 +4,7 @@ const { execFileSync, spawn, spawnSync } = require("child_process"); const path = require("path"); const fs = require("fs"); -const { DASHBOARD_PORT, GATEWAY_PORT, OLLAMA_PORT } = require("./lib/ports"); +const { DASHBOARD_PORT, GATEWAY_PORT, OLLAMA_PORT } = require("./lib/core/ports"); // --------------------------------------------------------------------------- // Color / style — respects NO_COLOR and non-TTY environments. @@ -26,7 +26,7 @@ const { ROOT, run, runInteractive, validateName } = require("./lib/runner"); // Agent branding — derived from NEMOCLAW_AGENT when an alias launcher sets it; // otherwise the branding module falls back to the OpenClaw defaults. // --------------------------------------------------------------------------- -const { CLI_NAME, CLI_DISPLAY_NAME } = require("./lib/branding"); +const { CLI_NAME, CLI_DISPLAY_NAME } = require("./lib/cli/branding"); const { dockerCapture, @@ -38,11 +38,11 @@ const { resolveOpenshell } = require("./lib/adapters/openshell/resolve"); const { hydrateCredentialEnv, isNonInteractive } = require("./lib/onboard"); const registry = require("./lib/state/registry"); import type { SandboxEntry } from "./lib/state/registry"; -const nim = require("./lib/nim"); +const nim = require("./lib/inference/nim"); const shields = require("./lib/shields"); -const { parseGatewayInference } = require("./lib/inference-config"); +const { parseGatewayInference } = require("./lib/inference/config"); const policies = require("./lib/policies"); -const { probeProviderHealth } = require("./lib/inference-health"); +const { probeProviderHealth } = require("./lib/inference/health"); const { buildStatusCommandDeps } = require("./lib/status-command-deps"); const { help, version } = require("./lib/actions/root-help"); const onboardSession = require("./lib/onboard-session"); @@ -68,7 +68,7 @@ const { getSandboxDeleteOutcome, } = require("./lib/actions/sandbox/destroy"); const { runOclifArgv, runRegisteredOclifCommand } = require("./lib/cli/oclif-runner"); -const { isErrnoException }: typeof import("./lib/errno") = require("./lib/errno"); +const { isErrnoException }: typeof import("./lib/core/errno") = require("./lib/core/errno"); const agentRuntime = require("../bin/lib/agent-runtime"); const sandboxState = require("./lib/state/sandbox"); const { parseRestoreArgs } = sandboxState; @@ -81,7 +81,7 @@ const { canonicalUsageList, globalCommandTokens, sandboxActionTokens, -} = require("./lib/command-registry"); +} = require("./lib/cli/command-registry"); import { normalizeArgv, suggestCommand } from "./lib/cli/argv-normalizer"; import { OPENSHELL_PROBE_TIMEOUT_MS } from "./lib/adapters/openshell/timeouts"; import { renderPublicOclifHelp } from "./lib/cli/public-oclif-help"; diff --git a/test/canonical-credential-resolution.test.ts b/test/canonical-credential-resolution.test.ts index 5c5d47ca3de..9b417b5b14a 100644 --- a/test/canonical-credential-resolution.test.ts +++ b/test/canonical-credential-resolution.test.ts @@ -14,7 +14,7 @@ import os from "node:os"; import path from "node:path"; import { afterEach, describe, expect, it, vi } from "vitest"; -type CredentialsModule = typeof import("../dist/lib/credentials.js"); +type CredentialsModule = typeof import("../dist/lib/credentials/store.js"); const tmpFixtures: string[] = []; @@ -37,7 +37,7 @@ async function importCredentialsModule(home: string): Promise vi.doUnmock("child_process"); vi.doUnmock("readline"); vi.stubEnv("HOME", home); - const module = await import("../dist/lib/credentials.js"); + const module = await import("../dist/lib/credentials/store.js"); const loaded = "default" in module ? module.default : module; return loaded as CredentialsModule; } diff --git a/test/config-set-nested-ssrf.test.ts b/test/config-set-nested-ssrf.test.ts index 4bdc7f4833a..b935a754094 100644 --- a/test/config-set-nested-ssrf.test.ts +++ b/test/config-set-nested-ssrf.test.ts @@ -11,7 +11,7 @@ describe("config set nested URL SSRF enforcement", () => { it("rejects nested object/array URL values that target private hosts", async () => { const sandboxConfigPath = require.resolve("../dist/lib/sandbox-config"); const openshellPath = require.resolve("../dist/lib/adapters/openshell/client"); - const shieldsAuditPath = require.resolve("../dist/lib/shields-audit"); + const shieldsAuditPath = require.resolve("../dist/lib/shields/audit"); const priorSandboxConfig = require.cache[sandboxConfigPath]; const priorOpenshell = require.cache[openshellPath]; @@ -86,7 +86,7 @@ describe("config set nested URL SSRF enforcement", () => { it("validates the key before doing URL or DNS validation", async () => { const sandboxConfigPath = require.resolve("../dist/lib/sandbox-config"); const openshellPath = require.resolve("../dist/lib/adapters/openshell/client"); - const shieldsAuditPath = require.resolve("../dist/lib/shields-audit"); + const shieldsAuditPath = require.resolve("../dist/lib/shields/audit"); const priorSandboxConfig = require.cache[sandboxConfigPath]; const priorOpenshell = require.cache[openshellPath]; @@ -165,7 +165,7 @@ describe("config set nested URL SSRF enforcement", () => { it("accepts nested object/array URL values when all are public", async () => { const sandboxConfigPath = require.resolve("../dist/lib/sandbox-config"); const openshellPath = require.resolve("../dist/lib/adapters/openshell/client"); - const shieldsAuditPath = require.resolve("../dist/lib/shields-audit"); + const shieldsAuditPath = require.resolve("../dist/lib/shields/audit"); const priorSandboxConfig = require.cache[sandboxConfigPath]; const priorOpenshell = require.cache[openshellPath]; @@ -240,7 +240,7 @@ describe("config set nested URL SSRF enforcement", () => { it("ignores nested non-http URL-like strings and does not crash", async () => { const sandboxConfigPath = require.resolve("../dist/lib/sandbox-config"); const openshellPath = require.resolve("../dist/lib/adapters/openshell/client"); - const shieldsAuditPath = require.resolve("../dist/lib/shields-audit"); + const shieldsAuditPath = require.resolve("../dist/lib/shields/audit"); const priorSandboxConfig = require.cache[sandboxConfigPath]; const priorOpenshell = require.cache[openshellPath]; @@ -316,7 +316,7 @@ describe("config set nested URL SSRF enforcement", () => { it("recognizes mixed-case http and https schemes in nested values", async () => { const sandboxConfigPath = require.resolve("../dist/lib/sandbox-config"); const openshellPath = require.resolve("../dist/lib/adapters/openshell/client"); - const shieldsAuditPath = require.resolve("../dist/lib/shields-audit"); + const shieldsAuditPath = require.resolve("../dist/lib/shields/audit"); const priorSandboxConfig = require.cache[sandboxConfigPath]; const priorOpenshell = require.cache[openshellPath]; @@ -391,7 +391,7 @@ describe("config set nested URL SSRF enforcement", () => { it("redacts credentials, query strings, and fragments in validation errors", async () => { const sandboxConfigPath = require.resolve("../dist/lib/sandbox-config"); const openshellPath = require.resolve("../dist/lib/adapters/openshell/client"); - const shieldsAuditPath = require.resolve("../dist/lib/shields-audit"); + const shieldsAuditPath = require.resolve("../dist/lib/shields/audit"); const priorSandboxConfig = require.cache[sandboxConfigPath]; const priorOpenshell = require.cache[openshellPath]; diff --git a/test/credentials.test.ts b/test/credentials.test.ts index b909e994fef..d0d5768448a 100644 --- a/test/credentials.test.ts +++ b/test/credentials.test.ts @@ -11,7 +11,7 @@ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; const require = createRequire(import.meta.url); -type CredentialsModule = typeof import("../dist/lib/credentials.js"); +type CredentialsModule = typeof import("../dist/lib/credentials/store.js"); function isCredentialsModule(value: object | null): value is CredentialsModule { return ( @@ -28,7 +28,7 @@ function isCredentialsModule(value: object | null): value is CredentialsModule { // Pull the credential-env-key allowlist from the production module so // future additions only need to be made in one place. Plus a few // fixture-only names this suite mutates directly. -import { KNOWN_CREDENTIAL_ENV_KEYS } from "../dist/lib/credentials.js"; +import { KNOWN_CREDENTIAL_ENV_KEYS } from "../dist/lib/credentials/store.js"; const TEST_FIXTURE_ENV_KEYS = ["TEST_API_KEY", "OTHER_KEY", "EMPTY_VALUE", "ZETA", "ALPHA"]; const TRACKED_ENV_KEYS = [...KNOWN_CREDENTIAL_ENV_KEYS, ...TEST_FIXTURE_ENV_KEYS]; @@ -44,7 +44,7 @@ async function importCredentialsModule(home: string): Promise vi.doUnmock("child_process"); vi.doUnmock("readline"); vi.stubEnv("HOME", home); - const module = await import("../dist/lib/credentials.js"); + const module = await import("../dist/lib/credentials/store.js"); const loaded = "default" in module ? module.default : module; const moduleObject = typeof loaded === "object" && loaded !== null ? loaded : null; if (!isCredentialsModule(moduleObject)) { @@ -644,7 +644,7 @@ describe("prompt machinery (unchanged)", () => { it("settles the outer prompt promise on secret prompt errors", () => { const script = ` -const { prompt } = require(${JSON.stringify(path.join(import.meta.dirname, "..", "dist", "lib", "credentials.js"))}); +const { prompt } = require(${JSON.stringify(path.join(import.meta.dirname, "..", "dist", "lib", "credentials", "store.js"))}); process.stdin.isTTY = true; process.stderr.isTTY = true; process.stdin.ref = () => process.stdin; @@ -681,7 +681,7 @@ prompt('secret: ', { secret: true }) const stdinUnref = vi.spyOn(process.stdin, "unref").mockImplementation(() => process.stdin); try { - const credentials = await import("../dist/lib/credentials.js"); + const credentials = await import("../dist/lib/credentials/store.js"); const pending = credentials.prompt("question: "); rl.emit("SIGINT"); await expect(pending).rejects.toMatchObject({ @@ -704,7 +704,7 @@ prompt('secret: ', { secret: true }) expect(credentials.normalizeCredentialValue(" nvapi-good-key\r\n")).toBe("nvapi-good-key"); const script = ` -const { ensureApiKey } = require(${JSON.stringify(path.join(import.meta.dirname, "..", "dist", "lib", "credentials.js"))}); +const { ensureApiKey } = require(${JSON.stringify(path.join(import.meta.dirname, "..", "dist", "lib", "credentials", "store.js"))}); delete process.env.NVIDIA_API_KEY; ensureApiKey() .then(() => console.log('STAGED=' + process.env.NVIDIA_API_KEY)) @@ -743,7 +743,7 @@ ${JSON.stringify(process.execPath)} ${JSON.stringify(scriptFile)} < "$pipe" it("normal and secret prompts re-ref, cleanup stdin, and preserve masked input", () => { const script = ` -const { prompt } = require(${JSON.stringify(path.join(import.meta.dirname, "..", "dist", "lib", "credentials.js"))}); +const { prompt } = require(${JSON.stringify(path.join(import.meta.dirname, "..", "dist", "lib", "credentials", "store.js"))}); const counts = { ref: 0, resume: 0, pause: 0, unref: 0, raw: [] }; process.stdin.ref = () => { counts.ref += 1; return process.stdin; }; process.stdin.resume = () => { counts.resume += 1; return process.stdin; }; diff --git a/test/detect-vllm-profile.test.ts b/test/detect-vllm-profile.test.ts index 32ce2413c14..b4f6af7dd82 100644 --- a/test/detect-vllm-profile.test.ts +++ b/test/detect-vllm-profile.test.ts @@ -3,7 +3,7 @@ import { describe, it, expect } from "vitest"; -import { detectVllmProfile } from "../dist/lib/onboard-vllm.js"; +import { detectVllmProfile } from "../dist/lib/inference/vllm.js"; describe("detectVllmProfile", () => { it("returns the Spark profile when gpu.platform === 'spark'", () => { diff --git a/test/e2e-port-overrides.sh b/test/e2e-port-overrides.sh index 85875316d92..f7fc8aa914e 100755 --- a/test/e2e-port-overrides.sh +++ b/test/e2e-port-overrides.sh @@ -187,7 +187,7 @@ fi info "11. NIM docker run maps host port to container internal 8000" OUT=$(docker run --rm --entrypoint "" "$IMAGE" bash -c ' - NIM_FILE=$(find / -path "*/dist/lib/nim.js" -type f 2>/dev/null | head -1) + NIM_FILE=$(find / -path "*/dist/lib/inference/nim.js" -type f 2>/dev/null | head -1) [ -z "$NIM_FILE" ] && NIM_FILE=$(find / -path "*/lib/nim.ts" -type f 2>/dev/null | head -1) if [ -z "$NIM_FILE" ]; then echo "NIM_NOT_FOUND" elif grep -q ":8000" "$NIM_FILE" 2>/dev/null; then echo "INTERNAL_PORT_OK" @@ -205,7 +205,7 @@ fi info "12. NIM status queries docker port on internal 8000" OUT=$(docker run --rm --entrypoint "" "$IMAGE" bash -c ' - NIM_FILE=$(find / -path "*/dist/lib/nim.js" -type f 2>/dev/null | head -1) + NIM_FILE=$(find / -path "*/dist/lib/inference/nim.js" -type f 2>/dev/null | head -1) [ -z "$NIM_FILE" ] && NIM_FILE=$(find / -path "*/lib/nim.ts" -type f 2>/dev/null | head -1) if [ -z "$NIM_FILE" ]; then echo "NIM_NOT_FOUND" elif grep -q "docker port.*8000" "$NIM_FILE" 2>/dev/null; then echo "DOCKER_PORT_QUERY_OK" diff --git a/test/e2e/test-credential-migration.sh b/test/e2e/test-credential-migration.sh index c2939782357..af46971b486 100755 --- a/test/e2e/test-credential-migration.sh +++ b/test/e2e/test-credential-migration.sh @@ -262,7 +262,7 @@ ln -s "$VICTIM_FILE" "$LEGACY_FILE" # Drive removeLegacyCredentialsFile() directly via a tiny node one-liner. # Using the compiled module from dist/ matches what the CLI imports. node -e " -const { removeLegacyCredentialsFile } = require('${REPO}/dist/lib/credentials.js'); +const { removeLegacyCredentialsFile } = require('${REPO}/dist/lib/credentials/store.js'); removeLegacyCredentialsFile(); " >/dev/null 2>&1 || { fail "node invocation of removeLegacyCredentialsFile failed" diff --git a/test/gateway-start-wait.test.ts b/test/gateway-start-wait.test.ts index 74fae8b46e4..c83203411c6 100644 --- a/test/gateway-start-wait.test.ts +++ b/test/gateway-start-wait.test.ts @@ -7,7 +7,7 @@ import { createRequire } from "node:module"; const require = createRequire(import.meta.url); const ORIGINAL_ENV = { ...process.env }; const ONBOARD_MODULE = require.resolve("../dist/lib/onboard.js"); -const PORTS_MODULE = require.resolve("../dist/lib/ports.js"); +const PORTS_MODULE = require.resolve("../dist/lib/core/ports.js"); function loadOnboard() { delete require.cache[ONBOARD_MODULE]; diff --git a/test/get-ollama-model-options.test.ts b/test/get-ollama-model-options.test.ts index 95560e36177..c574b6f7bfc 100644 --- a/test/get-ollama-model-options.test.ts +++ b/test/get-ollama-model-options.test.ts @@ -9,7 +9,7 @@ import { resetOllamaHostCache, OLLAMA_HOST_DOCKER_INTERNAL, OLLAMA_LOCALHOST, -} from "../dist/lib/local-inference.js"; +} from "../dist/lib/inference/local.js"; type CapturedCall = { argv: readonly string[] }; diff --git a/test/host-artifact-cleanup.test.ts b/test/host-artifact-cleanup.test.ts index 6dd3624c8f1..e1e8e1aa323 100644 --- a/test/host-artifact-cleanup.test.ts +++ b/test/host-artifact-cleanup.test.ts @@ -6,7 +6,7 @@ import os from "node:os"; import path from "node:path"; import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; -import { KNOWN_CREDENTIAL_ENV_KEYS } from "../dist/lib/credentials.js"; +import { KNOWN_CREDENTIAL_ENV_KEYS } from "../dist/lib/credentials/store.js"; import { cleanupStaleHostFiles } from "../dist/lib/host-artifact-cleanup.js"; const TRACKED_ENV_KEYS = [...KNOWN_CREDENTIAL_ENV_KEYS]; diff --git a/test/image-cleanup.test.ts b/test/image-cleanup.test.ts index d9882b1cbde..bf6376d51bd 100644 --- a/test/image-cleanup.test.ts +++ b/test/image-cleanup.test.ts @@ -15,7 +15,7 @@ import { import { getSandboxDeleteOutcome } from "../src/lib/domain/sandbox/destroy"; import { normalizeGarbageCollectImagesOptions } from "../src/lib/domain/lifecycle/options"; import { help as renderRootHelp } from "../src/lib/actions/root-help"; -import { COMMANDS, globalCommandTokens } from "../src/lib/command-registry"; +import { COMMANDS, globalCommandTokens } from "../src/lib/cli/command-registry"; import { getRegisteredOclifCommandMetadata } from "../src/lib/cli/oclif-metadata"; const ROOT = path.resolve(import.meta.dirname, ".."); diff --git a/test/ollama-gpu-cleanup.test.ts b/test/ollama-gpu-cleanup.test.ts index 22671a30efe..35d9b1ebe19 100644 --- a/test/ollama-gpu-cleanup.test.ts +++ b/test/ollama-gpu-cleanup.test.ts @@ -4,7 +4,7 @@ import { describe, expect, it, vi } from "vitest"; import http from "node:http"; -import { unloadOllamaModels } from "../dist/lib/onboard-ollama-proxy.js"; +import { unloadOllamaModels } from "../dist/lib/inference/ollama/proxy.js"; describe("Ollama GPU cleanup", () => { it("unloads all running Ollama models via the production HTTP implementation", async () => { diff --git a/test/ollama-pull-timeout.test.ts b/test/ollama-pull-timeout.test.ts index 088c75e539f..6247be0254d 100644 --- a/test/ollama-pull-timeout.test.ts +++ b/test/ollama-pull-timeout.test.ts @@ -8,7 +8,7 @@ import { spawnSync } from "child_process"; import { afterEach, describe, expect, it } from "vitest"; -import { getOllamaPullTimeoutMs } from "../dist/lib/onboard-ollama-proxy.js"; +import { getOllamaPullTimeoutMs } from "../dist/lib/inference/ollama/proxy.js"; const ENV = "NEMOCLAW_OLLAMA_PULL_TIMEOUT"; const DEFAULT_MS = 30 * 60 * 1000; @@ -46,8 +46,8 @@ describe("getOllamaPullTimeoutMs", () => { const repoRoot = path.join(import.meta.dirname, ".."); const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "nemoclaw-ollama-pull-timeout-")); const scriptPath = path.join(tmpDir, "http-timeout-check.js"); - const proxyPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "onboard-ollama-proxy.js")); - const localInferencePath = JSON.stringify(path.join(repoRoot, "dist", "lib", "local-inference.js")); + const proxyPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "inference", "ollama", "proxy.js")); + const localInferencePath = JSON.stringify(path.join(repoRoot, "dist", "lib", "inference", "local.js")); const script = ` const { EventEmitter } = require("events"); const { PassThrough } = require("stream"); diff --git a/test/ollama-tools-capability.test.ts b/test/ollama-tools-capability.test.ts index 52f6b50408d..a8d7cdfdad0 100644 --- a/test/ollama-tools-capability.test.ts +++ b/test/ollama-tools-capability.test.ts @@ -7,8 +7,8 @@ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; const require = createRequire(import.meta.url); const REPO_ROOT = path.join(import.meta.dirname, ".."); -const LOCAL_INFERENCE_PATH = path.join(REPO_ROOT, "dist", "lib", "local-inference.js"); -const ONBOARD_OLLAMA_PROXY_PATH = path.join(REPO_ROOT, "dist", "lib", "onboard-ollama-proxy.js"); +const LOCAL_INFERENCE_PATH = path.join(REPO_ROOT, "dist", "lib", "inference", "local.js"); +const ONBOARD_OLLAMA_PROXY_PATH = path.join(REPO_ROOT, "dist", "lib", "inference", "ollama", "proxy.js"); type CapturedCall = { argv: readonly string[]; opts?: Record }; @@ -235,7 +235,7 @@ function installSharedStubs(): void { _model: string, ) => SHARED.scriptedCaps; - const credentialsPath = path.join(REPO_ROOT, "dist", "lib", "credentials.js"); + const credentialsPath = path.join(REPO_ROOT, "dist", "lib", "credentials", "store.js"); const credentials = require(credentialsPath) as { prompt: (msg: string) => Promise; }; diff --git a/test/onboard-preset-diff.test.ts b/test/onboard-preset-diff.test.ts index 4319a616caf..d46c112060d 100644 --- a/test/onboard-preset-diff.test.ts +++ b/test/onboard-preset-diff.test.ts @@ -47,7 +47,7 @@ function buildPreamble({ policyPresets = "npm", alreadyApplied = ["npm", "pypi", "huggingface", "brew", "brave"], } = {}): string { - const credPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials.js")); + const credPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials", "store.js")); const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); const registryPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "state", "registry.js")); const policiesPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "policies.js")); diff --git a/test/onboard-prompt-default-case.test.ts b/test/onboard-prompt-default-case.test.ts index ff502a96b9a..af53228552e 100644 --- a/test/onboard-prompt-default-case.test.ts +++ b/test/onboard-prompt-default-case.test.ts @@ -9,7 +9,7 @@ import { describe, it, expect } from "vitest"; const repoRoot = path.join(import.meta.dirname, ".."); const onboardPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "onboard.js")); -const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials.js")); +const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials", "store.js")); type RunResult = { result: boolean; diff --git a/test/onboard-selection.test.ts b/test/onboard-selection.test.ts index 17f90205614..1984297156f 100644 --- a/test/onboard-selection.test.ts +++ b/test/onboard-selection.test.ts @@ -104,7 +104,7 @@ describe("onboard provider selection UX", () => { const fakeBin = path.join(tmpDir, "bin"); const scriptPath = path.join(tmpDir, "selection-check.js"); const onboardPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "onboard.js")); - const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials.js")); + const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials", "store.js")); const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); const registryPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "state", "registry.js")); @@ -206,7 +206,7 @@ const { setupNim } = require(${onboardPath}); const fakeBin = path.join(tmpDir, "bin"); const scriptPath = path.join(tmpDir, "no-recommended-label-check.js"); const onboardPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "onboard.js")); - const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials.js")); + const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials", "store.js")); const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); fs.mkdirSync(fakeBin, { recursive: true }); @@ -286,7 +286,7 @@ const { setupNim } = require(${onboardPath}); const scriptPath = path.join(tmpDir, "build-deepseek-selection-check.js"); const curlArgsLog = path.join(tmpDir, "deepseek-curl-args.log"); const onboardPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "onboard.js")); - const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials.js")); + const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials", "store.js")); const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); fs.mkdirSync(fakeBin, { recursive: true }); @@ -391,7 +391,7 @@ 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, "dist", "lib", "onboard.js")); - const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials.js")); + const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials", "store.js")); const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); fs.mkdirSync(fakeBin, { recursive: true }); @@ -487,7 +487,7 @@ const { setupNim } = require(${onboardPath}); const fakeBin = path.join(tmpDir, "bin"); const scriptPath = path.join(tmpDir, "build-model-retry-check.js"); const onboardPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "onboard.js")); - const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials.js")); + const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials", "store.js")); const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); fs.mkdirSync(fakeBin, { recursive: true }); @@ -586,7 +586,7 @@ const { setupNim } = require(${onboardPath}); const fakeBin = path.join(tmpDir, "bin"); const scriptPath = path.join(tmpDir, "gemini-selection-check.js"); const onboardPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "onboard.js")); - const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials.js")); + const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials", "store.js")); const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); fs.mkdirSync(fakeBin, { recursive: true }); @@ -681,7 +681,7 @@ const { setupNim } = require(${onboardPath}); const fakeBin = path.join(tmpDir, "bin"); const scriptPath = path.join(tmpDir, "ollama-validation-check.js"); const onboardPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "onboard.js")); - const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials.js")); + const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials", "store.js")); const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); fs.mkdirSync(fakeBin, { recursive: true }); @@ -802,7 +802,7 @@ const { setupNim } = require(${onboardPath}); const fakeBin = path.join(tmpDir, "bin"); const scriptPath = path.join(tmpDir, "ollama-loopback-check.js"); const onboardPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "onboard.js")); - const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials.js")); + const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials", "store.js")); const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); const platformPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "platform.js")); @@ -928,7 +928,7 @@ const { setupNim } = require(${onboardPath}); const fakeBin = path.join(tmpDir, "bin"); const scriptPath = path.join(tmpDir, "ollama-back-check.js"); const onboardPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "onboard.js")); - const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials.js")); + const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials", "store.js")); const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); fs.mkdirSync(fakeBin, { recursive: true }); @@ -1027,7 +1027,7 @@ const { setupNim } = require(${onboardPath}); const fakeBin = path.join(tmpDir, "bin"); const scriptPath = path.join(tmpDir, "ollama-bootstrap-check.js"); const onboardPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "onboard.js")); - const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials.js")); + const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials", "store.js")); const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); const pullLog = path.join(tmpDir, "pulls.log"); @@ -1139,7 +1139,7 @@ const { setupNim } = require(${onboardPath}); const fakeBin = path.join(tmpDir, "bin"); const scriptPath = path.join(tmpDir, "ollama-retry-check.js"); const onboardPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "onboard.js")); - const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials.js")); + const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials", "store.js")); const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); const pullLog = path.join(tmpDir, "pulls.log"); @@ -1259,7 +1259,7 @@ const { setupNim } = require(${onboardPath}); const fakeBin = path.join(tmpDir, "bin"); const scriptPath = path.join(tmpDir, "ollama-decline-check.js"); const onboardPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "onboard.js")); - const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials.js")); + const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials", "store.js")); const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); const pullLog = path.join(tmpDir, "pulls.log"); @@ -1376,7 +1376,7 @@ const { setupNim } = require(${onboardPath}); const fakeBin = path.join(tmpDir, "bin"); const scriptPath = path.join(tmpDir, "ollama-yes-check.js"); const onboardPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "onboard.js")); - const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials.js")); + const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials", "store.js")); const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); const pullLog = path.join(tmpDir, "pulls.log"); @@ -1492,7 +1492,7 @@ const { setupNim } = require(${onboardPath}); const fakeBin = path.join(tmpDir, "bin"); const scriptPath = path.join(tmpDir, "openai-model-retry-check.js"); const onboardPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "onboard.js")); - const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials.js")); + const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials", "store.js")); const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); fs.mkdirSync(fakeBin, { recursive: true }); @@ -1584,7 +1584,7 @@ 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, "dist", "lib", "onboard.js")); - const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials.js")); + const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials", "store.js")); const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); fs.mkdirSync(fakeBin, { recursive: true }); @@ -1672,7 +1672,7 @@ 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, "dist", "lib", "onboard.js")); - const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials.js")); + const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials", "store.js")); const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); fs.mkdirSync(fakeBin, { recursive: true }); @@ -1768,7 +1768,7 @@ const { setupNim } = require(${onboardPath}); const fakeBin = path.join(tmpDir, "bin"); const scriptPath = path.join(tmpDir, "anthropic-compatible-check.js"); const onboardPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "onboard.js")); - const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials.js")); + const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials", "store.js")); const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); fs.mkdirSync(fakeBin, { recursive: true }); @@ -1855,7 +1855,7 @@ const { setupNim } = require(${onboardPath}); const fakeBin = path.join(tmpDir, "bin"); const scriptPath = path.join(tmpDir, "custom-openai-retry-check.js"); const onboardPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "onboard.js")); - const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials.js")); + const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials", "store.js")); const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); fs.mkdirSync(fakeBin, { recursive: true }); @@ -1970,7 +1970,7 @@ 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, "dist", "lib", "onboard.js")); - const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials.js")); + const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials", "store.js")); const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); fs.mkdirSync(fakeBin, { recursive: true }); @@ -2066,7 +2066,7 @@ const { setupNim } = require(${onboardPath}); const fakeBin = path.join(tmpDir, "bin"); const scriptPath = path.join(tmpDir, "custom-openai-responses-force-completions-check.js"); const onboardPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "onboard.js")); - const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials.js")); + const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials", "store.js")); const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); fs.mkdirSync(fakeBin, { recursive: true }); @@ -2167,7 +2167,7 @@ const { setupNim } = require(${onboardPath}); const fakeBin = path.join(tmpDir, "bin"); const scriptPath = path.join(tmpDir, "custom-openai-responses-override-check.js"); const onboardPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "onboard.js")); - const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials.js")); + const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials", "store.js")); const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); fs.mkdirSync(fakeBin, { recursive: true }); @@ -2276,7 +2276,7 @@ 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, "dist", "lib", "onboard.js")); - const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials.js")); + const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials", "store.js")); const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); fs.mkdirSync(fakeBin, { recursive: true }); @@ -2369,7 +2369,7 @@ 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, "dist", "lib", "onboard.js")); - const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials.js")); + const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials", "store.js")); const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); fs.mkdirSync(fakeBin, { recursive: true }); @@ -2479,7 +2479,7 @@ const { setupNim } = require(${onboardPath}); const fakeBin = path.join(tmpDir, "bin"); const scriptPath = path.join(tmpDir, "model-back-check.js"); const onboardPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "onboard.js")); - const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials.js")); + const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials", "store.js")); const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); fs.mkdirSync(fakeBin, { recursive: true }); @@ -2568,7 +2568,7 @@ const { setupNim } = require(${onboardPath}); const fakeBin = path.join(tmpDir, "bin"); const scriptPath = path.join(tmpDir, "transport-back-check.js"); const onboardPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "onboard.js")); - const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials.js")); + const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials", "store.js")); const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); fs.mkdirSync(fakeBin, { recursive: true }); @@ -2666,7 +2666,7 @@ const { setupNim } = require(${onboardPath}); const fakeBin = path.join(tmpDir, "bin"); const scriptPath = path.join(tmpDir, "selection-retry-check.js"); const onboardPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "onboard.js")); - const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials.js")); + const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials", "store.js")); const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); fs.mkdirSync(fakeBin, { recursive: true }); @@ -2772,7 +2772,7 @@ const { setupNim } = require(${onboardPath}); const fakeBin = path.join(tmpDir, "bin"); const scriptPath = path.join(tmpDir, "build-noninteractive-check.js"); const onboardPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "onboard.js")); - const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials.js")); + const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials", "store.js")); const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); fs.mkdirSync(fakeBin, { recursive: true }); @@ -2876,7 +2876,7 @@ const { setupNim, __setNonInteractive } = onboardModule.exports; const fakeBin = path.join(tmpDir, "bin"); const scriptPath = path.join(tmpDir, "build-auth-retry-check.js"); const onboardPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "onboard.js")); - const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials.js")); + const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials", "store.js")); const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); fs.mkdirSync(fakeBin, { recursive: true }); @@ -2993,7 +2993,7 @@ const { setupNim } = require(${onboardPath}); const fakeBin = path.join(tmpDir, "bin"); const scriptPath = path.join(tmpDir, "nvidia-paste-guard-check.js"); const onboardPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "onboard.js")); - const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials.js")); + const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials", "store.js")); const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); fs.mkdirSync(fakeBin, { recursive: true }); @@ -3069,7 +3069,7 @@ const { setupNim } = require(${onboardPath}); const fakeBin = path.join(tmpDir, "bin"); const scriptPath = path.join(tmpDir, "openai-auth-retry-check.js"); const onboardPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "onboard.js")); - const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials.js")); + const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials", "store.js")); const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); fs.mkdirSync(fakeBin, { recursive: true }); @@ -3145,7 +3145,7 @@ const { setupNim } = require(${onboardPath}); const fakeBin = path.join(tmpDir, "bin"); const scriptPath = path.join(tmpDir, "anthropic-auth-retry-check.js"); const onboardPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "onboard.js")); - const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials.js")); + const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials", "store.js")); const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); fs.mkdirSync(fakeBin, { recursive: true }); @@ -3221,7 +3221,7 @@ const { setupNim } = require(${onboardPath}); const fakeBin = path.join(tmpDir, "bin"); const scriptPath = path.join(tmpDir, "gemini-auth-retry-check.js"); const onboardPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "onboard.js")); - const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials.js")); + const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials", "store.js")); const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); fs.mkdirSync(fakeBin, { recursive: true }); @@ -3299,7 +3299,7 @@ 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, "dist", "lib", "onboard.js")); - const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials.js")); + const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials", "store.js")); const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); fs.mkdirSync(fakeBin, { recursive: true }); @@ -3391,7 +3391,7 @@ 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, "dist", "lib", "onboard.js")); - const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials.js")); + const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials", "store.js")); const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); fs.mkdirSync(fakeBin, { recursive: true }); @@ -3481,7 +3481,7 @@ const { setupNim } = require(${onboardPath}); const fakeBin = path.join(tmpDir, "bin"); const scriptPath = path.join(tmpDir, "vllm-override-check.js"); const onboardPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "onboard.js")); - const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials.js")); + const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials", "store.js")); const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); fs.mkdirSync(fakeBin, { recursive: true }); @@ -3583,9 +3583,9 @@ const { setupNim } = require(${onboardPath}); const fakeBin = path.join(tmpDir, "bin"); const scriptPath = path.join(tmpDir, "nim-override-check.js"); const onboardPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "onboard.js")); - const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials.js")); + const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials", "store.js")); const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); - const nimPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "nim.js")); + const nimPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "inference", "nim.js")); fs.mkdirSync(fakeBin, { recursive: true }); // Fake curl: /v1/responses returns 200 (probe detects openai-responses) @@ -3695,7 +3695,7 @@ const { setupNim } = require(${onboardPath}); const fakeBin = path.join(tmpDir, "bin"); const scriptPath = path.join(tmpDir, "install-ollama-check.js"); const onboardPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "onboard.js")); - const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials.js")); + const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials", "store.js")); const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); const registryPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "state", "registry.js")); const platformPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "platform.js")); @@ -3869,7 +3869,7 @@ const { setupNim } = require(${onboardPath}); const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "nemoclaw-onboard-systemd-fail-")); const scriptPath = path.join(tmpDir, "systemd-fail-check.js"); const onboardPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "onboard.js")); - const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials.js")); + const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials", "store.js")); const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); const platformPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "platform.js")); @@ -3947,7 +3947,7 @@ const { setupNim } = require(${onboardPath}); const fakeBin = path.join(tmpDir, "bin"); const scriptPath = path.join(tmpDir, "noninteractive-install-ollama-check.js"); const onboardPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "onboard.js")); - const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials.js")); + const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials", "store.js")); const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); const registryPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "state", "registry.js")); const platformPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "platform.js")); diff --git a/test/onboard.test.ts b/test/onboard.test.ts index d1ae47de45f..adba29b3b6d 100644 --- a/test/onboard.test.ts +++ b/test/onboard.test.ts @@ -9,9 +9,9 @@ import path from "node:path"; import { pathToFileURL } from "node:url"; import { describe, expect, it } from "vitest"; -import type { AgentDefinition } from "../dist/lib/agent-defs.js"; -import { loadAgent } from "../dist/lib/agent-defs.js"; -import { buildChain, buildControlUiUrls } from "../dist/lib/dashboard-contract.js"; +import type { AgentDefinition } from "../dist/lib/agent/defs.js"; +import { loadAgent } from "../dist/lib/agent/defs.js"; +import { buildChain, buildControlUiUrls } from "../dist/lib/dashboard/contract.js"; import { NAME_ALLOWED_FORMAT } from "../dist/lib/name-validation.js"; import { stageOptimizedSandboxBuildContext } from "../dist/lib/sandbox-build-context.js"; @@ -1440,8 +1440,8 @@ describe("onboard helpers", () => { const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "nemoclaw-web-search-prompt-")); const scriptPath = path.join(tmpDir, "web-search-prompt-check.cjs"); const onboardPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "onboard.js")); - const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials.js")); - const agentDefsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "agent-defs.js")); + const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials", "store.js")); + const agentDefsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "agent", "defs.js")); const script = ` let promptCalls = 0; @@ -2586,9 +2586,9 @@ const { setupInference, getSandboxInferenceConfig } = require(${onboardPath}); 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", "state", "registry.js")); - const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials.js")); + const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials", "store.js")); const localInferencePath = JSON.stringify( - path.join(repoRoot, "dist", "lib", "local-inference.js"), + path.join(repoRoot, "dist", "lib", "inference", "local.js"), ); fs.mkdirSync(fakeBin, { recursive: true }); @@ -2995,7 +2995,7 @@ const { setupInference } = require(${onboardPath}); 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", "state", "registry.js")); - const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials.js")); + const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials", "store.js")); fs.mkdirSync(fakeBin, { recursive: true }); fs.writeFileSync(path.join(fakeBin, "openshell"), "#!/usr/bin/env bash\nexit 0\n", { @@ -3085,7 +3085,7 @@ const { setupInference } = require(${onboardPath}); 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", "state", "registry.js")); - const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials.js")); + const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials", "store.js")); fs.mkdirSync(fakeBin, { recursive: true }); fs.writeFileSync(path.join(fakeBin, "openshell"), "#!/usr/bin/env bash\nexit 0\n", { @@ -3560,7 +3560,7 @@ console.log(JSON.stringify({ liveExists, sandbox: registry.getSandbox("my-assist const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); const registryPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "state", "registry.js")); const preflightPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "preflight.js")); - const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials.js")); + const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials", "store.js")); fs.mkdirSync(fakeBin, { recursive: true }); fs.writeFileSync(path.join(fakeBin, "openshell"), "#!/usr/bin/env bash\nexit 0\n", { @@ -3700,7 +3700,7 @@ const { createSandbox } = require(${onboardPath}); const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); const registryPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "state", "registry.js")); const preflightPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "preflight.js")); - const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials.js")); + const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials", "store.js")); fs.mkdirSync(fakeBin, { recursive: true }); fs.writeFileSync(path.join(fakeBin, "openshell"), "#!/usr/bin/env bash\nexit 0\n", { @@ -3791,7 +3791,7 @@ const { createSandbox } = require(${onboardPath}); const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); const registryPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "state", "registry.js")); const preflightPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "preflight.js")); - const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials.js")); + const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials", "store.js")); fs.mkdirSync(fakeBin, { recursive: true }); fs.writeFileSync(path.join(fakeBin, "openshell"), "#!/usr/bin/env bash\nexit 0\n", { @@ -3923,7 +3923,7 @@ const { createSandbox } = require(${onboardPath}); const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); const registryPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "state", "registry.js")); const preflightPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "preflight.js")); - const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials.js")); + const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials", "store.js")); fs.mkdirSync(fakeBin, { recursive: true }); fs.writeFileSync(path.join(fakeBin, "openshell"), "#!/usr/bin/env bash\nexit 0\n", { @@ -4142,7 +4142,7 @@ const { createSandbox } = require(${onboardPath}); const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); const registryPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "state", "registry.js")); const preflightPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "preflight.js")); - const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials.js")); + const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials", "store.js")); fs.mkdirSync(fakeBin, { recursive: true }); fs.writeFileSync(path.join(fakeBin, "openshell"), "#!/usr/bin/env bash\nexit 0\n", { @@ -4305,7 +4305,7 @@ const { createSandbox } = require(${onboardPath}); const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); const registryPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "state", "registry.js")); const preflightPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "preflight.js")); - const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials.js")); + const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials", "store.js")); fs.mkdirSync(fakeBin, { recursive: true }); fs.writeFileSync(path.join(fakeBin, "openshell"), "#!/usr/bin/env bash\nexit 0\n", { @@ -4785,7 +4785,7 @@ const { createSandbox } = require(${onboardPath}); 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", "state", "registry.js")); - const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials.js")); + const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials", "store.js")); fs.mkdirSync(fakeBin, { recursive: true }); fs.writeFileSync(path.join(fakeBin, "openshell"), "#!/usr/bin/env bash\nexit 0\n", { @@ -4916,7 +4916,7 @@ const { createSandbox } = require(${onboardPath}); 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", "state", "registry.js")); - const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials.js")); + const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials", "store.js")); fs.mkdirSync(fakeBin, { recursive: true }); fs.writeFileSync(path.join(fakeBin, "openshell"), "#!/usr/bin/env bash\nexit 0\n", { @@ -5058,7 +5058,7 @@ const { createSandbox } = require(${onboardPath}); 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", "state", "registry.js")); - const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials.js")); + const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials", "store.js")); fs.mkdirSync(fakeBin, { recursive: true }); fs.writeFileSync(path.join(fakeBin, "openshell"), "#!/usr/bin/env bash\nexit 0\n", { @@ -5428,7 +5428,7 @@ console.log(JSON.stringify({ exists: providerExistsInGateway("discord-bridge") } const fakeBin = path.join(tmpDir, "bin"); const scriptPath = path.join(tmpDir, "hydrate-cred.js"); const onboardPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "onboard.js")); - const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials.js")); + const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials", "store.js")); fs.mkdirSync(fakeBin, { recursive: true }); fs.writeFileSync(path.join(fakeBin, "openshell"), "#!/usr/bin/env bash\nexit 0\n", { @@ -5546,7 +5546,7 @@ console.log(JSON.stringify({ exists: providerExistsInGateway("nonexistent") })); const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); const registryPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "state", "registry.js")); const preflightPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "preflight.js")); - const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials.js")); + const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials", "store.js")); fs.mkdirSync(fakeBin, { recursive: true }); fs.writeFileSync(path.join(fakeBin, "openshell"), "#!/usr/bin/env bash\nexit 0\n", { @@ -5945,7 +5945,7 @@ const { setupInference } = require(${onboardPath}); const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); const registryPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "state", "registry.js")); const preflightPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "preflight.js")); - const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials.js")); + const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials", "store.js")); fs.mkdirSync(fakeBin, { recursive: true }); fs.writeFileSync(path.join(fakeBin, "openshell"), "#!/usr/bin/env bash\nexit 0\n", { @@ -6079,7 +6079,7 @@ const { createSandbox } = require(${onboardPath}); const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); const registryPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "state", "registry.js")); const preflightPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "preflight.js")); - const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials.js")); + const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials", "store.js")); fs.mkdirSync(fakeBin, { recursive: true }); fs.writeFileSync(path.join(fakeBin, "openshell"), "#!/usr/bin/env bash\nexit 0\n", { @@ -6336,7 +6336,7 @@ const { setupMessagingChannels } = require(${onboardPath}); const scriptPath = path.join(tmpDir, "slack-format-reject.js"); const onboardPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "onboard.js")); const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); - const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials.js")); + const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials", "store.js")); fs.mkdirSync(fakeBin, { recursive: true }); fs.writeFileSync(path.join(fakeBin, "openshell"), "#!/usr/bin/env bash\nexit 0\n", { @@ -6447,7 +6447,7 @@ const { setupMessagingChannels, MESSAGING_CHANNELS } = require(${onboardPath}); const scriptPath = path.join(tmpDir, "slack-app-format-reject.js"); const onboardPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "onboard.js")); const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); - const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials.js")); + const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials", "store.js")); fs.mkdirSync(fakeBin, { recursive: true }); fs.writeFileSync(path.join(fakeBin, "openshell"), "#!/usr/bin/env bash\nexit 0\n", { @@ -6645,7 +6645,7 @@ const { setupMessagingChannels, MESSAGING_CHANNELS } = require(${onboardPath}); const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); const registryPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "state", "registry.js")); const preflightPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "preflight.js")); - const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials.js")); + const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials", "store.js")); // Create a minimal custom Dockerfile in a temporary directory const customBuildDir = path.join(tmpDir, "custom-image"); @@ -6825,7 +6825,7 @@ const { createSandbox } = require(${onboardPath}); const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); const registryPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "state", "registry.js")); const preflightPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "preflight.js")); - const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials.js")); + const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials", "store.js")); fs.mkdirSync(fakeBin, { recursive: true }); fs.writeFileSync(path.join(fakeBin, "openshell"), "#!/usr/bin/env bash\nexit 0\n", { @@ -6886,7 +6886,7 @@ const { createSandbox } = require(${onboardPath}); const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); const registryPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "state", "registry.js")); const preflightPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "preflight.js")); - const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials.js")); + const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials", "store.js")); fs.mkdirSync(fakeBin, { recursive: true }); fs.writeFileSync(path.join(fakeBin, "openshell"), "#!/usr/bin/env bash\nexit 0\n", { @@ -6946,7 +6946,7 @@ const { createSandbox } = require(${onboardPath}); const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); const registryPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "state", "registry.js")); const preflightPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "preflight.js")); - const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials.js")); + const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials", "store.js")); const ignoredDir = path.join(tmpDir, "node_modules", "pkg"); fs.mkdirSync(ignoredDir, { recursive: true }); @@ -7009,7 +7009,7 @@ const { createSandbox } = require(${onboardPath}); const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); const registryPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "state", "registry.js")); const preflightPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "preflight.js")); - const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials.js")); + const credentialsPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials", "store.js")); const customBuildDir = path.join(tmpDir, "custom-image"); fs.mkdirSync(customBuildDir, { recursive: true }); diff --git a/test/policies.test.ts b/test/policies.test.ts index e3f3797d1ba..684981e0574 100644 --- a/test/policies.test.ts +++ b/test/policies.test.ts @@ -17,7 +17,7 @@ const readline = requireForTest("node:readline") as typeof import("node:readline const YAML = requireForTest("yaml"); const REPO_ROOT = path.join(import.meta.dirname, ".."); const CLI_PATH = JSON.stringify(path.join(REPO_ROOT, "dist", "nemoclaw.js")); -const CREDENTIALS_PATH = JSON.stringify(path.join(REPO_ROOT, "dist", "lib", "credentials.js")); +const CREDENTIALS_PATH = JSON.stringify(path.join(REPO_ROOT, "dist", "lib", "credentials", "store.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", "state", "registry.js")); const SELECT_FROM_LIST_ITEMS = [ diff --git a/test/policy-tiers-onboard.test.ts b/test/policy-tiers-onboard.test.ts index 46fad5cd789..83c2cdddb6b 100644 --- a/test/policy-tiers-onboard.test.ts +++ b/test/policy-tiers-onboard.test.ts @@ -49,7 +49,7 @@ function buildPreamble({ stubOpenshellBin = false, runCaptureReturn = "", } = {}): string { - const credPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials.js")); + const credPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials", "store.js")); const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); const registryPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "state", "registry.js")); const onboardPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "onboard.js")); @@ -378,7 +378,7 @@ describe("selectTierPresetsAndAccess", () => { const policiesPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "policies.js")); function buildPresetsScript(body: string): string { - const credPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials.js")); + const credPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "credentials", "store.js")); const runnerPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "runner.js")); const registryPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "state", "registry.js")); const onboardPath = JSON.stringify(path.join(repoRoot, "dist", "lib", "onboard.js")); diff --git a/test/presets-checkbox.test.ts b/test/presets-checkbox.test.ts index d47ae2ec90f..7e55702f1b4 100644 --- a/test/presets-checkbox.test.ts +++ b/test/presets-checkbox.test.ts @@ -8,7 +8,7 @@ import { execTimeout } from "./helpers/timeouts"; const REPO_ROOT = path.join(import.meta.dirname, ".."); 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 CREDENTIALS_PATH = JSON.stringify(path.join(REPO_ROOT, "dist", "lib", "credentials", "store.js")); type Preset = { name: string; diff --git a/test/repro-2681-group-writable.test.ts b/test/repro-2681-group-writable.test.ts index 834caa4eeb0..089219383a0 100644 --- a/test/repro-2681-group-writable.test.ts +++ b/test/repro-2681-group-writable.test.ts @@ -46,7 +46,7 @@ function withMockedDockerExecFileSync(calls: string[][], run: () => T): T { dockerExecFileSync: (args: readonly string[]) => string; }; const originalDockerExecFileSync = dockerExecModule.dockerExecFileSync; - const shieldsModulePath = require.resolve("../dist/lib/shields.js"); + const shieldsModulePath = require.resolve("../dist/lib/shields/index.js"); delete require.cache[shieldsModulePath]; dockerExecModule.dockerExecFileSync = vi.fn((args: readonly string[]) => { @@ -133,7 +133,7 @@ describe("Issue #2681 — mutable OpenClaw config permissions", () => { const commands: string[][] = []; withMockedDockerExecFileSync(commands, () => { // eslint-disable-next-line @typescript-eslint/no-require-imports - const { unlockAgentConfig } = require("../dist/lib/shields.js") as { + const { unlockAgentConfig } = require("../dist/lib/shields/index.js") as { unlockAgentConfig: ( sandboxName: string, target: { @@ -173,7 +173,7 @@ const Module = require("node:module"); const originalLoad = Module._load; const calls = []; Module._load = function patchedLoad(request, parent, isMain) { - if (request === "./adapters/docker/exec") { + if (request === "../adapters/docker/exec") { return { dockerExecFileSync(args) { const separator = args.indexOf("--"); @@ -193,7 +193,7 @@ Module._load = function patchedLoad(request, parent, isMain) { } return originalLoad.call(this, request, parent, isMain); }; -const { lockAgentConfig } = require("./dist/lib/shields.js"); +const { lockAgentConfig } = require("./dist/lib/shields/index.js"); lockAgentConfig("sandbox-pod", { agentName: "openclaw", configPath: "/sandbox/.openclaw/openclaw.json", @@ -235,7 +235,7 @@ const Module = require("node:module"); const originalLoad = Module._load; const calls = []; Module._load = function patchedLoad(request, parent, isMain) { - if (request === "./adapters/docker/exec") { + if (request === "../adapters/docker/exec") { return { dockerExecFileSync(args) { const separator = args.indexOf("--"); @@ -255,7 +255,7 @@ Module._load = function patchedLoad(request, parent, isMain) { } return originalLoad.call(this, request, parent, isMain); }; -const { lockAgentConfig } = require("./dist/lib/shields.js"); +const { lockAgentConfig } = require("./dist/lib/shields/index.js"); lockAgentConfig("sandbox-pod", { agentName: "openclaw", configPath: "/sandbox/.openclaw/openclaw.json", diff --git a/test/runner.test.ts b/test/runner.test.ts index 3ef0032f55b..a426f8a0543 100644 --- a/test/runner.test.ts +++ b/test/runner.test.ts @@ -589,10 +589,10 @@ describe("regression guards", () => { defs.push(path.relative(repoRoot, file)); } } - // runner.ts (CJS consumers) and shell-quote.ts (ESM consumers like config-io.ts) + // runner.ts (CJS consumers) and core/shell-quote.ts (ESM consumers like config-io.ts) expect(defs.sort()).toEqual([ + path.join("src", "lib", "core", "shell-quote.ts"), path.join("src", "lib", "runner.ts"), - path.join("src", "lib", "shell-quote.ts"), ]); }); diff --git a/test/secret-redaction.test.ts b/test/secret-redaction.test.ts index 8ab5f8d77de..ffb79a00d48 100644 --- a/test/secret-redaction.test.ts +++ b/test/secret-redaction.test.ts @@ -6,8 +6,8 @@ import { mkdtempSync, mkdirSync, writeFileSync, rmSync, symlinkSync } from "node import { tmpdir } from "node:os"; import { join } from "node:path"; import { spawnSync } from "node:child_process"; -import { SECRET_PATTERNS } from "../src/lib/secret-patterns"; -import { redact as debugRedact } from "../src/lib/debug"; +import { SECRET_PATTERNS } from "../src/lib/security/secret-patterns"; +import { redact as debugRedact } from "../src/lib/diagnostics/debug"; import { redactSensitiveText } from "../src/lib/onboard-session"; // runner.ts uses CJS exports — import via dist import { createRequire } from "node:module"; diff --git a/test/shellquote-sandbox.test.ts b/test/shellquote-sandbox.test.ts index a161f9472ef..059cfc4da32 100644 --- a/test/shellquote-sandbox.test.ts +++ b/test/shellquote-sandbox.test.ts @@ -45,7 +45,7 @@ describe("sandboxName command hardening in onboard.js", () => { pathToFileURL(path.join(repoRoot, "dist", "lib", "preflight.js")).href, ); const credentialsUrl = JSON.stringify( - pathToFileURL(path.join(repoRoot, "dist", "lib", "credentials.js")).href, + pathToFileURL(path.join(repoRoot, "dist", "lib", "credentials", "store.js")).href, ); const streamUrl = JSON.stringify( pathToFileURL(path.join(repoRoot, "dist", "lib", "sandbox-create-stream.js")).href, diff --git a/test/wait.test.ts b/test/wait.test.ts index b6308746821..a5e4ad85264 100644 --- a/test/wait.test.ts +++ b/test/wait.test.ts @@ -3,7 +3,7 @@ import assert from "node:assert"; import { describe, expect, it } from "vitest"; -import { sleepMs, sleepSeconds } from "../src/lib/wait.js"; +import { sleepMs, sleepSeconds } from "../src/lib/core/wait.js"; describe("wait utility", () => { it("sleepMs blocks for approximately the requested time", () => { diff --git a/test/wsl2-probe-timeout.test.ts b/test/wsl2-probe-timeout.test.ts index d417247adf0..7967de66e6c 100644 --- a/test/wsl2-probe-timeout.test.ts +++ b/test/wsl2-probe-timeout.test.ts @@ -66,7 +66,7 @@ describe("WSL2 inference verification timeouts (issue #987)", () => { function runProbeWithCurlStatuses(statuses: number[]) { const httpProbePath = require.resolve("../dist/lib/http-probe.js"); const platformPath = require.resolve("../dist/lib/platform.js"); - const probesPath = require.resolve("../dist/lib/onboard-inference-probes.js"); + const probesPath = require.resolve("../dist/lib/inference/onboard-probes.js"); const httpProbe = require(httpProbePath); const platform = require(platformPath); const originalRunCurlProbe = httpProbe.runCurlProbe; @@ -153,7 +153,7 @@ describe("WSL2 inference verification timeouts (issue #987)", () => { function runProbeWithResults(results: ProbeResultFixture[], opts: { isWsl?: boolean } = {}) { const httpProbePath = require.resolve("../dist/lib/http-probe.js"); const platformPath = require.resolve("../dist/lib/platform.js"); - const probesPath = require.resolve("../dist/lib/onboard-inference-probes.js"); + const probesPath = require.resolve("../dist/lib/inference/onboard-probes.js"); const httpProbe = require(httpProbePath); const platform = require(platformPath); const originalRunCurlProbe = httpProbe.runCurlProbe;