Merge origin/main into fix/quiet-cron-status-and-cli-retry

This commit is contained in:
MaxxxDong 2026-03-19 19:18:01 +08:00
commit 7c0b683ab7
4 changed files with 157 additions and 974 deletions

View File

@ -1,6 +1,6 @@
{
"name": "@openclaw/tlon",
"version": "2026.3.14",
"version": "0.4.1",
"description": "OpenClaw Tlon/Urbit channel plugin",
"type": "module",
"dependencies": {
@ -9,25 +9,7 @@
"@urbit/aura": "^3.0.0",
"zod": "^4.3.6"
},
"openclaw": {
"extensions": [
"./index.ts"
],
"setupEntry": "./setup-entry.ts",
"channel": {
"id": "tlon",
"label": "Tlon",
"selectionLabel": "Tlon (Urbit)",
"docsPath": "/channels/tlon",
"docsLabel": "tlon",
"blurb": "decentralized messaging on Urbit; install the plugin to enable.",
"order": 90,
"quickstartAllowFrom": true
},
"install": {
"npmSpec": "@openclaw/tlon",
"localPath": "extensions/tlon",
"defaultChoice": "npm"
}
"peerDependencies": {
"openclaw": "^0.4.1"
}
}

View File

@ -1,5 +1,6 @@
#!/usr/bin/env node
import { access } from "node:fs/promises";
import module from "node:module";
import { fileURLToPath } from "node:url";
@ -59,7 +60,11 @@ const isDirectModuleNotFoundError = (err, specifier) => {
}
const message = "message" in err && typeof err.message === "string" ? err.message : "";
return message.includes(fileURLToPath(expectedUrl));
const expectedPath = fileURLToPath(expectedUrl);
return (
message.includes(`Cannot find module '${expectedPath}'`) ||
message.includes(`Cannot find module "${expectedPath}"`)
);
};
const installProcessWarningFilter = async () => {
@ -95,10 +100,36 @@ const tryImport = async (specifier) => {
}
};
const exists = async (specifier) => {
try {
await access(new URL(specifier, import.meta.url));
return true;
} catch {
return false;
}
};
const buildMissingEntryErrorMessage = async () => {
const lines = ["openclaw: missing dist/entry.(m)js (build output)."];
if (!(await exists("./src/entry.ts"))) {
return lines.join("\n");
}
lines.push("This install looks like an unbuilt source tree or GitHub source archive.");
lines.push(
"Build locally with `pnpm install && pnpm build`, or install a built package instead.",
);
lines.push(
"For pinned GitHub installs, use `npm install -g github:openclaw/openclaw#<ref>` instead of a raw `/archive/<ref>.tar.gz` URL.",
);
lines.push("For releases, use `npm install -g openclaw@latest`.");
return lines.join("\n");
};
if (await tryImport("./dist/entry.js")) {
// OK
} else if (await tryImport("./dist/entry.mjs")) {
// OK
} else {
throw new Error("openclaw: missing dist/entry.(m)js (build output).");
throw new Error(await buildMissingEntryErrorMessage());
}

1051
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@ -15,6 +15,11 @@ async function makeLauncherFixture(fixtureRoots: string[]): Promise<string> {
return fixtureRoot;
}
async function addSourceTreeMarker(fixtureRoot: string): Promise<void> {
await fs.mkdir(path.join(fixtureRoot, "src"), { recursive: true });
await fs.writeFile(path.join(fixtureRoot, "src", "entry.ts"), "export {};\n", "utf8");
}
describe("openclaw launcher", () => {
const fixtureRoots: string[] = [];
@ -55,4 +60,20 @@ describe("openclaw launcher", () => {
expect(result.status).not.toBe(0);
expect(result.stderr).toContain("missing dist/entry.(m)js");
});
it("explains how to recover from an unbuilt source install", async () => {
const fixtureRoot = await makeLauncherFixture(fixtureRoots);
await addSourceTreeMarker(fixtureRoot);
const result = spawnSync(process.execPath, [path.join(fixtureRoot, "openclaw.mjs"), "--help"], {
cwd: fixtureRoot,
encoding: "utf8",
});
expect(result.status).not.toBe(0);
expect(result.stderr).toContain("missing dist/entry.(m)js");
expect(result.stderr).toContain("unbuilt source tree or GitHub source archive");
expect(result.stderr).toContain("pnpm install && pnpm build");
expect(result.stderr).toContain("github:openclaw/openclaw#<ref>");
});
});