Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
13 changes: 5 additions & 8 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -260,14 +260,11 @@ RUN set -eu; \
if ! grep -q 'const baseLstat = await fs\.stat(baseDir)' "$isp_file"; then echo "ERROR: Patch 3a (install-safe-path) did not find patched baseLstat stat call" >&2; exit 1; fi; \
ipd_file="$(grep -RIlE --include='*.js' 'assertInstallBaseStable' "$OC_DIST/install-package-dir-"*.js || true)"; \
test -n "$ipd_file" || { echo "ERROR: install-package-dir assertInstallBaseStable not found" >&2; exit 1; }; \
if grep -q 'const baseLstat = await fs\.lstat(params\.installBaseDir)' "$ipd_file"; then \
sed -i 's/const baseLstat = await fs\.lstat(params\.installBaseDir)/const baseLstat = await fs.stat(params.installBaseDir)/' "$ipd_file"; \
sed -i 's/baseLstat\.isSymbolicLink()/false \/* nemoclaw: symlink check disabled, realpath guards containment *\//' "$ipd_file"; \
if grep -q 'fs\.lstat(params\.installBaseDir)' "$ipd_file"; then echo "ERROR: Patch 3b (install-package-dir) left lstat in assertInstallBaseStable" >&2; exit 1; fi; \
if grep -q 'baseLstat\.isSymbolicLink()' "$ipd_file"; then echo "ERROR: Patch 3b (install-package-dir) left baseLstat symlink check" >&2; exit 1; fi; \
else \
grep -q 'await fs\.realpath(params\.installBaseDir) !== params\.expectedRealPath' "$ipd_file" || { echo "ERROR: install-package-dir lacks expected realpath stability guard" >&2; exit 1; }; \
fi; \
sed -i 's/const baseLstat = await fs\.lstat(params\.installBaseDir)/const baseLstat = await fs.stat(params.installBaseDir)/' "$ipd_file"; \
sed -i 's/baseLstat\.isSymbolicLink()/false \/* nemoclaw: symlink check disabled, realpath guards containment *\//' "$ipd_file"; \
if grep -q 'fs\.lstat(params\.installBaseDir)' "$ipd_file"; then echo "ERROR: Patch 3b (install-package-dir) left lstat in assertInstallBaseStable" >&2; exit 1; fi; \
if ! grep -q 'const baseLstat = await fs\.stat(params\.installBaseDir)' "$ipd_file" && ! grep -q 'await fs\.stat(params\.installBaseDir)).isDirectory()' "$ipd_file"; then echo "ERROR: Patch 3b (install-package-dir) did not find patched/safe installBaseDir stat call" >&2; exit 1; fi; \
if grep -q 'baseLstat\.isSymbolicLink()' "$ipd_file"; then echo "ERROR: Patch 3b (install-package-dir) left baseLstat symlink check" >&2; exit 1; fi; \
# --- Patch 5: bump default WS handshake timeout 10s -> 60s (#2484) --- \
# OpenClaw's WS connect handshake has a hard-coded 10s timeout on both \
# client and server. Server-side connect-handler processing can exceed \
Expand Down
2 changes: 1 addition & 1 deletion Dockerfile.base
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ RUN printf '%s\n' \
# OpenClaw version: change the OPENCLAW_VERSION ARG default so CI rebuilds
# the base image on push to main, or use workflow_dispatch on base-image.yaml
# with the openclaw_version input for a one-off build without editing this file.
ARG OPENCLAW_VERSION=2026.5.18
ARG OPENCLAW_VERSION=2026.4.24

SHELL ["/bin/bash", "-o", "pipefail", "-c"]

Expand Down
2 changes: 1 addition & 1 deletion agents/openclaw/manifest.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ homepage: "https://openclaw.ai"
install_method: npm # npm install -g openclaw@<version>
binary_path: /usr/local/bin/openclaw
version_command: "openclaw --version"
expected_version: "2026.5.18"
expected_version: "2026.4.24"
gateway_command: "openclaw gateway run"

# ── Health probe ────────────────────────────────────────────────
Expand Down
2 changes: 1 addition & 1 deletion nemoclaw-blueprint/blueprint.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
version: "0.1.0"
min_openshell_version: "0.0.39"
max_openshell_version: "0.0.39"
min_openclaw_version: "2026.5.18"
min_openclaw_version: "2026.4.24"
# Mirrors the components.sandbox.image manifest digest below. Lets a
# downstream consumer (or release tooling) verify the blueprint declares
# a specific sandbox image without parsing the components tree, and
Expand Down
22 changes: 1 addition & 21 deletions scripts/patch-openclaw-tool-catalog.js
Original file line number Diff line number Diff line change
Expand Up @@ -213,15 +213,7 @@ function listSelectionFiles(distDir) {
.sort();
}

function hasBuiltInToolCatalog(source) {
return source.includes("applyToolSearchCatalog({") && source.includes("buildToolSearchRunPlan({");
}

function patchSelectionText(source, filePath) {
if (hasBuiltInToolCatalog(source)) {
return { patched: false, text: source, skippedBuiltIn: true };
}

if (source.includes(MARKER)) {
if (ALREADY_PATCHED_FORBIDDEN_PATTERNS.some((pattern) => source.includes(pattern))) {
throw new Error(`${filePath}: compact catalog marker is present but original targets remain`);
Expand Down Expand Up @@ -272,28 +264,16 @@ function patchOpenClawToolCatalog(distDir) {
return text.includes(ALL_CUSTOM_TOOLS_PATTERN) || text.includes(MARKER);
});
if (targetFiles.length !== 1) {
if (targetFiles.length === 0) {
const builtInCatalogFile = selectionFiles.find((file) => {
const text = fs.readFileSync(file, "utf-8");
return hasBuiltInToolCatalog(text);
});
if (builtInCatalogFile) {
return { status: "skipped-built-in", file: builtInCatalogFile, version };
}
}
throw new Error(`Expected exactly one selection-*.js target, found ${targetFiles.length}`);
}

const target = targetFiles[0];
const source = fs.readFileSync(target, "utf-8");
const { patched, text, skippedBuiltIn } = patchSelectionText(source, target);
const { patched, text } = patchSelectionText(source, target);
if (patched) {
fs.writeFileSync(target, text);
return { status: "patched", file: target, version };
}
if (skippedBuiltIn) {
return { status: "skipped-built-in", file: target, version };
}
return { status: "already-patched", file: target, version };
}

Expand Down
2 changes: 1 addition & 1 deletion test/e2e-test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@ if node --input-type=module -e "

// Verify restoration
const restored = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
const version = (restored.wizard || {}).lastRunVersion;
const version = (restored.meta || {}).lastTouchedVersion;
if (version !== '2026.3.11') throw new Error('Restored config wrong: ' + JSON.stringify(restored));
if ('corrupted' in restored) throw new Error('Config still corrupted after rollback');
console.log('Restored config: ' + JSON.stringify(restored));
Expand Down
19 changes: 0 additions & 19 deletions test/openclaw-tool-catalog-patch.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -188,25 +188,6 @@ describe("OpenClaw compact tool catalog patch", () => {
fs.rmSync(changed.root, { recursive: true, force: true });
}

const builtInCatalog = makeFixture({
allCustomToolsLine: [
"\t\tconst toolSearch = applyToolSearchCatalog({",
"\t\t\ttools: effectiveTools,",
"\t\t});",
"\t\tconst toolSearchRunPlan = buildToolSearchRunPlan({",
"\t\t\tvisibleTools: effectiveTools,",
"\t\t});",
].join("\n"),
});
try {
const result = runPatch(builtInCatalog.dist);
expect(result.status, `${result.stdout}${result.stderr}`).toBe(0);
expect(result.stdout).toContain("skipped-built-in");
expect(fs.readFileSync(builtInCatalog.selectionPath, "utf-8")).not.toContain(MARKER);
} finally {
fs.rmSync(builtInCatalog.root, { recursive: true, force: true });
}

const partial = makeFixture({
allCustomToolsLine: [
MARKER,
Expand Down
Loading