-
Notifications
You must be signed in to change notification settings - Fork 2.1k
feat(onboard): add configurable port overrides via environment variables #621
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
2cf4b72
37051ac
14170ce
c9680c6
ce7daaf
9fbc644
35389ef
4718ac1
0c47a5d
de1da0a
2ea5562
bc17106
029c1d9
71ed7b9
bc0a5d0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| # NemoClaw port configuration — copy to .env and edit as needed. | ||
| # Ports must be integers in range 1024–65535. | ||
| # Run scripts/check-ports.sh to find port conflicts | ||
|
|
||
| NEMOCLAW_DASHBOARD_PORT=18789 | ||
| NEMOCLAW_GATEWAY_PORT=8080 | ||
| NEMOCLAW_VLLM_PORT=8000 | ||
| NEMOCLAW_OLLAMA_PORT=11434 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -8,3 +8,8 @@ docs/_build/ | |
| coverage/ | ||
| vdr-notes/ | ||
| draft_newsletter_* | ||
| tmp/ | ||
| .env | ||
| .env.local | ||
| .venv/ | ||
| uv.lock | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,95 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // SPDX-License-Identifier: Apache-2.0 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Lightweight .env loader — reads .env files from the project root and populates | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // process.env. Existing environment variables are never overwritten, so shell | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // exports always take precedence over file values. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Supports: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // - Multiple files (loaded in order; first file's values win over later files) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // - Comments (#) and blank lines | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // - KEY=VALUE, KEY="VALUE", KEY='VALUE' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // - Inline comments after unquoted values | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const fs = require("fs"); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const path = require("path"); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const ROOT = path.resolve(__dirname, "..", ".."); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const CWD = process.cwd(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Walk up from a directory looking for a .git marker to find the repo root. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| function findGitRoot(start) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| let dir = start; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| while (true) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| try { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| fs.statSync(path.join(dir, ".git")); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return dir; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } catch { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const parent = path.dirname(dir); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (parent === dir) return null; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| dir = parent; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const GIT_ROOT = findGitRoot(CWD); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| function parseEnvFile(filePath) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| let content; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| try { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| content = fs.readFileSync(filePath, "utf-8"); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } catch { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return; // file doesn't exist or isn't readable — skip silently | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| for (const raw of content.split("\n")) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const line = raw.trim(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (!line || line.startsWith("#")) continue; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const eqIndex = line.indexOf("="); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (eqIndex === -1) continue; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const key = line.slice(0, eqIndex).trim(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (!key) continue; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| let value = line.slice(eqIndex + 1).trim(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Remove inline comments for unquoted values first, then strip quotes. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // This handles cases like KEY='value' # comment correctly. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const hashIndex = value.indexOf(" #"); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (hashIndex !== -1) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| value = value.slice(0, hashIndex).trim(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Strip surrounding quotes | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| (value.startsWith('"') && value.endsWith('"')) || | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| (value.startsWith("'") && value.endsWith("'")) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| value = value.slice(1, -1); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+57
to
+70
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Inline comment stripping may truncate quoted values containing The current logic strips inline comments before stripping quotes. For This edge case may be acceptable if your 🔧 Proposed fix: Strip comments only for unquoted values let value = line.slice(eqIndex + 1).trim();
- // Remove inline comments for unquoted values first, then strip quotes.
- // This handles cases like KEY='value' # comment correctly.
- const hashIndex = value.indexOf(" #");
- if (hashIndex !== -1) {
- value = value.slice(0, hashIndex).trim();
- }
-
// Strip surrounding quotes
if (
(value.startsWith('"') && value.endsWith('"')) ||
(value.startsWith("'") && value.endsWith("'"))
) {
value = value.slice(1, -1);
+ } else {
+ // Remove inline comments only for unquoted values
+ const hashIndex = value.indexOf(" #");
+ if (hashIndex !== -1) {
+ value = value.slice(0, hashIndex).trim();
+ }
}📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Never overwrite existing env vars | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (process.env[key] === undefined) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| process.env[key] = value; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Collect unique directories to search for .env files. The git repo root and | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // CWD are checked in addition to the __dirname-relative ROOT so that a user's | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // .env.local (which is gitignored and therefore not synced into the sandbox | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // source directory) is still picked up on a fresh install. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const SEARCH_DIRS = [...new Set([ROOT, GIT_ROOT, CWD].filter(Boolean))]; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Load .env files in priority order — first file wins for any given key | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // because we never overwrite once set. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const ENV_FILES = [".env.local", ".env"]; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| for (const file of ENV_FILES) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| for (const dir of SEARCH_DIRS) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| parseEnvFile(path.join(dir, file)); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| module.exports = { parseEnvFile, findGitRoot }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix markdown lint warning: missing blank line after blockquote.
The static analysis tool flagged a blank line issue inside/after the blockquote. Add a blank line between the warning block (line 190) and the horizontal rule (line 191) to fix the MD028 violation.
📝 Proposed fix
> When using local inference (Ollama or vLLM), the inference service binds to `0.0.0.0` so that containers can reach it via `host.openshell.internal`. This means the service is reachable from your local network, not just localhost. This is required for the sandbox architecture but should be considered in shared or untrusted network environments. + ---📝 Committable suggestion
🤖 Prompt for AI Agents