Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
c6414af
refactor(cli): replace race-condition sleeps with readiness probes
ksapru Apr 24, 2026
1961db8
fix(cli): bubble up errors when policy preset wait loop times out, fi…
ksapru Apr 24, 2026
ef67b43
fix(cli): abort onboarding if readiness probes timeout
ksapru Apr 24, 2026
d3c5e5c
fix(cli): add strict readiness check
ksapru Apr 24, 2026
ddf29ab
refactor(cli): extract dashboard delivery chain into contract/health/…
jyaunches Apr 24, 2026
d0f5083
fix(sandbox): ensure procps survives hardening and stale base images …
ericksoa Apr 24, 2026
93db521
refactor(types): tighten repo-wide type boundaries (#2422)
cv Apr 24, 2026
29d43b3
feat(cli): typed command registry as single source of truth (#2388) (…
jyaunches Apr 24, 2026
47b4e61
fix(onboard): validate Slack bot token format before saving (#2130)
latenighthackathon Apr 24, 2026
3308d99
refactor(types): consolidate duplicated errno and JSON type helpers (…
jyaunches Apr 24, 2026
8b55f6c
fix(test): satisfy strict typecheck on Slack token validation tests (…
cjagwani Apr 24, 2026
94bae3f
ci: gate every PR on tsc-cli regardless of touched paths (#2461)
cjagwani Apr 24, 2026
9830309
fix(security): validate symlinks in snapshot create and rollback path…
ericksoa Apr 24, 2026
d49c1d5
fix(onboard): always inject NEMOCLAW_DASHBOARD_PORT into sandbox env …
prekshivyas Apr 24, 2026
fa27a62
docs: reorganize Get Started and add Deployment Topology diagram (#2445)
miyoungc Apr 24, 2026
1547947
chore(test): apply shfmt formatting to E2E scripts (#2359)
ericksoa Apr 25, 2026
13d7a77
fix(test): move installer integration tests to CI-only vitest project…
ericksoa Apr 25, 2026
9d35df4
docs: catch up release prep for 0.0.25 (#2463)
miyoungc Apr 25, 2026
f0cbbb1
fix(cli): restore pre-#2398 gateway recovery (fixes E2E hangs) (#2471)
ericksoa Apr 25, 2026
f2ddb99
fix(install): refuse to auto-resume a failed onboarding session (#2437)
laitingsheng Apr 25, 2026
1e69692
fix(cli): resolve merge conflicts and improve onboarding readiness pr…
ksapru Apr 25, 2026
9507a85
refactor(cli): extract streamGatewayStart to reduce onboard.ts size
ksapru May 12, 2026
98b0b30
Merge current main into fix/replace-race-condition-sleeps
ericksoa May 13, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions src/lib/core/wait.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,53 @@ export function sleepMs(ms: number): void {
export function sleepSeconds(seconds: number): void {
sleepMs(seconds * 1000);
}

/**
* Synchronously wait until a condition is met.
*/
export function waitUntil(
conditionFn: () => boolean,
timeoutSeconds = 10,
pollIntervalMs = 250,
): boolean {
const start = Date.now();
while (Date.now() - start < timeoutSeconds * 1000) {
if (conditionFn()) return true;
sleepMs(pollIntervalMs);
}
return false;
}

/**
* Synchronously wait for a TCP port to become reachable on localhost.
*/
export function waitForPort(port: number, timeoutSeconds = 5): boolean {
const { spawnSync } = require("node:child_process");
return waitUntil(() => {
try {
const result = spawnSync("nc", ["-z", "127.0.0.1", String(port)], { stdio: "ignore" });
return result.status === 0;
} catch {
return false;
}
}, timeoutSeconds, 200);
}

/**
* Synchronously wait for an HTTP endpoint to return a success status code.
*/
export function waitForHttp(url: string, timeoutSeconds = 5): boolean {
const { spawnSync } = require("node:child_process");
return waitUntil(() => {
try {
const result = spawnSync(
"curl",
["-sf", "--connect-timeout", "1", "--max-time", "1", url],
{ stdio: "ignore" },
);
return result.status === 0;
} catch {
return false;
}
}, timeoutSeconds, 200);
}
8 changes: 7 additions & 1 deletion src/lib/inference/ollama/proxy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ 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("../../core/ports");
const { waitForPort } = require("../../core/wait");
const {
getDefaultOllamaModel,
getBootstrapOllamaModelOptions,
Expand Down Expand Up @@ -157,7 +158,12 @@ function startOllamaAuthProxy(): boolean {
// If the user backs out to a different provider, the token stays in memory
// only and is discarded.
const pid = spawnOllamaAuthProxy(proxyToken);
sleep(1);
if (!waitForPort(OLLAMA_PROXY_PORT, 2)) {
console.error(
` Error: Ollama auth proxy did not become ready on :${OLLAMA_PROXY_PORT} within timeout.`,
);
return false;
}
if (!isOllamaProxyProcess(pid)) {
console.error(` Error: Ollama auth proxy failed to start on :${OLLAMA_PROXY_PORT}`);
console.error(` Containers will not be able to reach Ollama without the proxy.`);
Expand Down
Loading
Loading