Vendor OpenClaw source as Adolf fork baseline
Some checks failed
ClawSweeper Dispatch / dispatch (push) Has been cancelled
CodeQL / Security High (actions) (push) Has been cancelled
CodeQL / Security High (channel-runtime-boundary) (push) Has been cancelled
CodeQL / Security High (core-auth-secrets) (push) Has been cancelled
CodeQL / Security High (mcp-process-tool-boundary) (push) Has been cancelled
CodeQL / Security High (network-ssrf-boundary) (push) Has been cancelled
CodeQL / Security High (plugin-trust-boundary) (push) Has been cancelled
CodeQL / Security High (process-exec-boundary) (push) Has been cancelled
Docs Sync Publish Repo / sync-publish-repo (push) Has been cancelled
Docs / docs (push) Has been cancelled
OpenClaw Stable Main Closeout / Resolve stable release closeout inputs (push) Has been cancelled
OpenClaw Stable Main Closeout / Verify stable main closeout (push) Has been cancelled
Workflow Sanity / no-tabs (push) Has been cancelled
Workflow Sanity / actionlint (push) Has been cancelled
Workflow Sanity / generated-doc-baselines (push) Has been cancelled
CI / runner-admission (push) Has been cancelled
CI / preflight (push) Has been cancelled
CI / security-fast (push) Has been cancelled
CI / pnpm-store-warmup (push) Has been cancelled
CI / build-artifacts (push) Has been cancelled
CI / native-i18n (push) Has been cancelled
CI / ${{ matrix.check_name }} (push) Has been cancelled
CI / ${{ matrix.checkName }} (push) Has been cancelled
CI / checks-node-compat-node22 (push) Has been cancelled
CI / check-bundled-channel-config-metadata (push) Has been cancelled
CI / check-dependencies (push) Has been cancelled
CI / check-guards (push) Has been cancelled
CI / check-lint (push) Has been cancelled
CI / check-prod-types (push) Has been cancelled
CI / check-shrinkwrap (push) Has been cancelled
CI / check-test-types (push) Has been cancelled
CI / check-additional-boundaries-a (push) Has been cancelled
CI / check-additional-boundaries-bcd (push) Has been cancelled
CI / check-additional-extension-bundled (push) Has been cancelled
CI / check-additional-extension-channels (push) Has been cancelled
CI / check-additional-extension-package-boundary (push) Has been cancelled
CI / check-additional-runtime-topology-architecture (push) Has been cancelled
CI / check-session-accessor-boundary (push) Has been cancelled
CI / check-session-transcript-reader-boundary (push) Has been cancelled
CI / check-docs (push) Has been cancelled
CI / skills-python (push) Has been cancelled
CI / macos-swift (push) Has been cancelled
CI / ios-build (push) Has been cancelled
CI / ci-timings-summary (push) Has been cancelled
Native App Locale Refresh / Refresh native fa (push) Has been cancelled
Native App Locale Refresh / Refresh native fr (push) Has been cancelled
Native App Locale Refresh / Refresh native hi (push) Has been cancelled
Native App Locale Refresh / Refresh native id (push) Has been cancelled
Native App Locale Refresh / Refresh native it (push) Has been cancelled
Native App Locale Refresh / Refresh native ja-JP (push) Has been cancelled
Control UI Locale Refresh / plan (push) Has been cancelled
Control UI Locale Refresh / Refresh ${{ matrix.locale }} (push) Has been cancelled
Control UI Locale Refresh / Commit control UI locale refresh (push) Has been cancelled
Live Media Runner Image / Build live media runner image (push) Has been cancelled
Native App Locale Refresh / Refresh native ar (push) Has been cancelled
Native App Locale Refresh / Refresh native de (push) Has been cancelled
Native App Locale Refresh / Refresh native es (push) Has been cancelled
Native App Locale Refresh / Refresh native ko (push) Has been cancelled
Native App Locale Refresh / Refresh native nl (push) Has been cancelled
Native App Locale Refresh / Refresh native pl (push) Has been cancelled
Native App Locale Refresh / Refresh native pt-BR (push) Has been cancelled
Native App Locale Refresh / Refresh native ru (push) Has been cancelled
Native App Locale Refresh / Refresh native sv (push) Has been cancelled
Native App Locale Refresh / Refresh native th (push) Has been cancelled
Native App Locale Refresh / Refresh native tr (push) Has been cancelled
Native App Locale Refresh / Refresh native uk (push) Has been cancelled
Native App Locale Refresh / Refresh native vi (push) Has been cancelled
Native App Locale Refresh / Refresh native zh-CN (push) Has been cancelled
Native App Locale Refresh / Refresh native zh-TW (push) Has been cancelled
Native App Locale Refresh / Commit native locale refresh (push) Has been cancelled
Plugin Init Scaffold Validation / Validate provider scaffold (push) Has been cancelled
Plugin NPM Release / preview_plugins_npm (push) Has been cancelled
Plugin NPM Release / Validate release publish approval (push) Has been cancelled
Plugin NPM Release / preview_plugin_pack (push) Has been cancelled
Plugin NPM Release / publish_plugins_npm (push) Has been cancelled
Sandbox Common Smoke / sandbox-common-smoke (push) Has been cancelled
Website Installer Sync / static (push) Has been cancelled
Website Installer Sync / linux-docker (push) Has been cancelled
Website Installer Sync / macos-installer (push) Has been cancelled
Website Installer Sync / windows-installer (push) Has been cancelled
Website Installer Sync / sync-website (push) Has been cancelled
Some checks failed
ClawSweeper Dispatch / dispatch (push) Has been cancelled
CodeQL / Security High (actions) (push) Has been cancelled
CodeQL / Security High (channel-runtime-boundary) (push) Has been cancelled
CodeQL / Security High (core-auth-secrets) (push) Has been cancelled
CodeQL / Security High (mcp-process-tool-boundary) (push) Has been cancelled
CodeQL / Security High (network-ssrf-boundary) (push) Has been cancelled
CodeQL / Security High (plugin-trust-boundary) (push) Has been cancelled
CodeQL / Security High (process-exec-boundary) (push) Has been cancelled
Docs Sync Publish Repo / sync-publish-repo (push) Has been cancelled
Docs / docs (push) Has been cancelled
OpenClaw Stable Main Closeout / Resolve stable release closeout inputs (push) Has been cancelled
OpenClaw Stable Main Closeout / Verify stable main closeout (push) Has been cancelled
Workflow Sanity / no-tabs (push) Has been cancelled
Workflow Sanity / actionlint (push) Has been cancelled
Workflow Sanity / generated-doc-baselines (push) Has been cancelled
CI / runner-admission (push) Has been cancelled
CI / preflight (push) Has been cancelled
CI / security-fast (push) Has been cancelled
CI / pnpm-store-warmup (push) Has been cancelled
CI / build-artifacts (push) Has been cancelled
CI / native-i18n (push) Has been cancelled
CI / ${{ matrix.check_name }} (push) Has been cancelled
CI / ${{ matrix.checkName }} (push) Has been cancelled
CI / checks-node-compat-node22 (push) Has been cancelled
CI / check-bundled-channel-config-metadata (push) Has been cancelled
CI / check-dependencies (push) Has been cancelled
CI / check-guards (push) Has been cancelled
CI / check-lint (push) Has been cancelled
CI / check-prod-types (push) Has been cancelled
CI / check-shrinkwrap (push) Has been cancelled
CI / check-test-types (push) Has been cancelled
CI / check-additional-boundaries-a (push) Has been cancelled
CI / check-additional-boundaries-bcd (push) Has been cancelled
CI / check-additional-extension-bundled (push) Has been cancelled
CI / check-additional-extension-channels (push) Has been cancelled
CI / check-additional-extension-package-boundary (push) Has been cancelled
CI / check-additional-runtime-topology-architecture (push) Has been cancelled
CI / check-session-accessor-boundary (push) Has been cancelled
CI / check-session-transcript-reader-boundary (push) Has been cancelled
CI / check-docs (push) Has been cancelled
CI / skills-python (push) Has been cancelled
CI / macos-swift (push) Has been cancelled
CI / ios-build (push) Has been cancelled
CI / ci-timings-summary (push) Has been cancelled
Native App Locale Refresh / Refresh native fa (push) Has been cancelled
Native App Locale Refresh / Refresh native fr (push) Has been cancelled
Native App Locale Refresh / Refresh native hi (push) Has been cancelled
Native App Locale Refresh / Refresh native id (push) Has been cancelled
Native App Locale Refresh / Refresh native it (push) Has been cancelled
Native App Locale Refresh / Refresh native ja-JP (push) Has been cancelled
Control UI Locale Refresh / plan (push) Has been cancelled
Control UI Locale Refresh / Refresh ${{ matrix.locale }} (push) Has been cancelled
Control UI Locale Refresh / Commit control UI locale refresh (push) Has been cancelled
Live Media Runner Image / Build live media runner image (push) Has been cancelled
Native App Locale Refresh / Refresh native ar (push) Has been cancelled
Native App Locale Refresh / Refresh native de (push) Has been cancelled
Native App Locale Refresh / Refresh native es (push) Has been cancelled
Native App Locale Refresh / Refresh native ko (push) Has been cancelled
Native App Locale Refresh / Refresh native nl (push) Has been cancelled
Native App Locale Refresh / Refresh native pl (push) Has been cancelled
Native App Locale Refresh / Refresh native pt-BR (push) Has been cancelled
Native App Locale Refresh / Refresh native ru (push) Has been cancelled
Native App Locale Refresh / Refresh native sv (push) Has been cancelled
Native App Locale Refresh / Refresh native th (push) Has been cancelled
Native App Locale Refresh / Refresh native tr (push) Has been cancelled
Native App Locale Refresh / Refresh native uk (push) Has been cancelled
Native App Locale Refresh / Refresh native vi (push) Has been cancelled
Native App Locale Refresh / Refresh native zh-CN (push) Has been cancelled
Native App Locale Refresh / Refresh native zh-TW (push) Has been cancelled
Native App Locale Refresh / Commit native locale refresh (push) Has been cancelled
Plugin Init Scaffold Validation / Validate provider scaffold (push) Has been cancelled
Plugin NPM Release / preview_plugins_npm (push) Has been cancelled
Plugin NPM Release / Validate release publish approval (push) Has been cancelled
Plugin NPM Release / preview_plugin_pack (push) Has been cancelled
Plugin NPM Release / publish_plugins_npm (push) Has been cancelled
Sandbox Common Smoke / sandbox-common-smoke (push) Has been cancelled
Website Installer Sync / static (push) Has been cancelled
Website Installer Sync / linux-docker (push) Has been cancelled
Website Installer Sync / macos-installer (push) Has been cancelled
Website Installer Sync / windows-installer (push) Has been cancelled
Website Installer Sync / sync-website (push) Has been cancelled
Adolf is a fork/vendored clone of github.com/openclaw/openclaw (v2026.6.11), free to diverge. Tree copied sans upstream .git; upstream remote added for future syncs. Node pinned to 24 (.nvmrc); engines already require >=22.19. Preserves docs/ARCHITECTURE.md. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LeqyaxJF2nbRXJtae2kNB2
This commit is contained in:
169
extensions/file-transfer/src/node-host/dir-list.test.ts
Normal file
169
extensions/file-transfer/src/node-host/dir-list.test.ts
Normal file
@@ -0,0 +1,169 @@
|
||||
// File Transfer tests cover dir list plugin behavior.
|
||||
import fs from "node:fs/promises";
|
||||
import os from "node:os";
|
||||
import path from "node:path";
|
||||
import { afterEach, beforeEach, describe, expect, it } from "vitest";
|
||||
import {
|
||||
DIR_LIST_DEFAULT_MAX_ENTRIES,
|
||||
DIR_LIST_HARD_MAX_ENTRIES,
|
||||
handleDirList,
|
||||
} from "./dir-list.js";
|
||||
|
||||
let tmpRoot: string;
|
||||
|
||||
beforeEach(async () => {
|
||||
// realpath: see file-fetch.test.ts for the macOS symlinked-tmpdir reason.
|
||||
tmpRoot = await fs.realpath(await fs.mkdtemp(path.join(os.tmpdir(), "dir-list-test-")));
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
await fs.rm(tmpRoot, { recursive: true, force: true });
|
||||
});
|
||||
|
||||
async function expectDirListError(
|
||||
input: Parameters<typeof handleDirList>[0],
|
||||
code: "INVALID_PATH" | "IS_FILE" | "NOT_FOUND",
|
||||
) {
|
||||
const result = await handleDirList(input);
|
||||
expect(result.ok).toBe(false);
|
||||
if (!result.ok) {
|
||||
expect(result.code).toBe(code);
|
||||
}
|
||||
}
|
||||
|
||||
describe("handleDirList — input validation", () => {
|
||||
it("rejects empty / non-string path", async () => {
|
||||
await expectDirListError({ path: "" }, "INVALID_PATH");
|
||||
await expectDirListError({ path: undefined }, "INVALID_PATH");
|
||||
});
|
||||
|
||||
it("rejects relative paths", async () => {
|
||||
await expectDirListError({ path: "relative" }, "INVALID_PATH");
|
||||
});
|
||||
|
||||
it("rejects paths with NUL bytes", async () => {
|
||||
await expectDirListError({ path: "/tmp/foo\0bar" }, "INVALID_PATH");
|
||||
});
|
||||
});
|
||||
|
||||
describe("handleDirList — fs errors", () => {
|
||||
it("returns NOT_FOUND for a missing directory", async () => {
|
||||
await expectDirListError({ path: path.join(tmpRoot, "does-not-exist") }, "NOT_FOUND");
|
||||
});
|
||||
|
||||
it("returns IS_FILE when path resolves to a regular file", async () => {
|
||||
const f = path.join(tmpRoot, "f.txt");
|
||||
await fs.writeFile(f, "x");
|
||||
await expectDirListError({ path: f }, "IS_FILE");
|
||||
});
|
||||
});
|
||||
|
||||
describe("handleDirList — happy path", () => {
|
||||
it("lists files and subdirs with metadata, sorted by name", async () => {
|
||||
await fs.writeFile(path.join(tmpRoot, "z.txt"), "Z");
|
||||
await fs.writeFile(path.join(tmpRoot, "a.png"), "PNG-bytes");
|
||||
await fs.mkdir(path.join(tmpRoot, "subdir"));
|
||||
|
||||
const r = await handleDirList({ path: tmpRoot });
|
||||
if (!r.ok) {
|
||||
throw new Error("expected ok");
|
||||
}
|
||||
expect(r.entries.map((e) => e.name)).toEqual(["a.png", "subdir", "z.txt"]);
|
||||
|
||||
const a = r.entries.find((e) => e.name === "a.png")!;
|
||||
expect(a.isDir).toBe(false);
|
||||
expect(a.size).toBeGreaterThan(0);
|
||||
expect(a.mimeType).toBe("image/png");
|
||||
|
||||
const sub = r.entries.find((e) => e.name === "subdir")!;
|
||||
expect(sub.isDir).toBe(true);
|
||||
expect(sub.size).toBe(0);
|
||||
expect(sub.mimeType).toBe("inode/directory");
|
||||
|
||||
expect(r.truncated).toBe(false);
|
||||
expect(r.nextPageToken).toBeUndefined();
|
||||
});
|
||||
|
||||
it("includes dotfiles in the listing", async () => {
|
||||
await fs.writeFile(path.join(tmpRoot, ".hidden"), "x");
|
||||
await fs.writeFile(path.join(tmpRoot, "visible"), "x");
|
||||
|
||||
const r = await handleDirList({ path: tmpRoot });
|
||||
if (!r.ok) {
|
||||
throw new Error("expected ok");
|
||||
}
|
||||
expect(r.entries.map((e) => e.name)).toEqual([".hidden", "visible"]);
|
||||
});
|
||||
|
||||
it("paginates via pageToken (offset-based)", async () => {
|
||||
for (let i = 0; i < 7; i++) {
|
||||
// zero-pad so localeCompare-stable sort matches creation order
|
||||
await fs.writeFile(path.join(tmpRoot, `f-${i}.txt`), "x");
|
||||
}
|
||||
|
||||
const page1 = await handleDirList({ path: tmpRoot, maxEntries: 3 });
|
||||
if (!page1.ok) {
|
||||
throw new Error("page1");
|
||||
}
|
||||
expect(page1.entries.map((e) => e.name)).toEqual(["f-0.txt", "f-1.txt", "f-2.txt"]);
|
||||
expect(page1.truncated).toBe(true);
|
||||
expect(page1.nextPageToken).toBe("3");
|
||||
|
||||
const page2 = await handleDirList({
|
||||
path: tmpRoot,
|
||||
maxEntries: 3,
|
||||
pageToken: page1.nextPageToken,
|
||||
});
|
||||
if (!page2.ok) {
|
||||
throw new Error("page2");
|
||||
}
|
||||
expect(page2.entries.map((e) => e.name)).toEqual(["f-3.txt", "f-4.txt", "f-5.txt"]);
|
||||
expect(page2.truncated).toBe(true);
|
||||
|
||||
const page3 = await handleDirList({
|
||||
path: tmpRoot,
|
||||
maxEntries: 3,
|
||||
pageToken: page2.nextPageToken,
|
||||
});
|
||||
if (!page3.ok) {
|
||||
throw new Error("page3");
|
||||
}
|
||||
expect(page3.entries.map((e) => e.name)).toEqual(["f-6.txt"]);
|
||||
expect(page3.truncated).toBe(false);
|
||||
expect(page3.nextPageToken).toBeUndefined();
|
||||
});
|
||||
|
||||
it("does not coerce partial page tokens", async () => {
|
||||
for (let i = 0; i < 3; i++) {
|
||||
await fs.writeFile(path.join(tmpRoot, `f-${i}.txt`), "x");
|
||||
}
|
||||
|
||||
const r = await handleDirList({ path: tmpRoot, maxEntries: 1, pageToken: "1next" });
|
||||
if (!r.ok) {
|
||||
throw new Error("expected ok");
|
||||
}
|
||||
expect(r.entries.map((e) => e.name)).toEqual(["f-0.txt"]);
|
||||
expect(r.nextPageToken).toBe("1");
|
||||
});
|
||||
|
||||
it("accepts plus-signed page tokens", async () => {
|
||||
for (let i = 0; i < 3; i++) {
|
||||
await fs.writeFile(path.join(tmpRoot, `f-${i}.txt`), "x");
|
||||
}
|
||||
|
||||
const r = await handleDirList({ path: tmpRoot, maxEntries: 1, pageToken: "+01" });
|
||||
if (!r.ok) {
|
||||
throw new Error("expected ok");
|
||||
}
|
||||
expect(r.entries.map((e) => e.name)).toEqual(["f-1.txt"]);
|
||||
expect(r.nextPageToken).toBe("2");
|
||||
});
|
||||
});
|
||||
|
||||
describe("handleDirList — limits", () => {
|
||||
it("clamps maxEntries to the hard ceiling and uses the default for invalid values", () => {
|
||||
expect(DIR_LIST_DEFAULT_MAX_ENTRIES).toBe(200);
|
||||
expect(DIR_LIST_HARD_MAX_ENTRIES).toBe(5000);
|
||||
expect(DIR_LIST_DEFAULT_MAX_ENTRIES).toBeLessThan(DIR_LIST_HARD_MAX_ENTRIES);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user