fix(package): restore kitchen sink install artifacts
This commit is contained in:
parent
87d135b61f
commit
89449910b4
@ -135,6 +135,7 @@ npm run check:runtime
|
||||
npm run check:inspector
|
||||
npm run check:install
|
||||
npm run pack:check
|
||||
npm run pack:zip
|
||||
```
|
||||
|
||||
The `Update OpenClaw SDK Surface` workflow automatically checks
|
||||
@ -154,6 +155,11 @@ Tagged GitHub releases publish the validated package to npm through trusted
|
||||
publishing. The release tag must match `package.json`, for example `v0.0.1` for
|
||||
version `0.0.1`.
|
||||
|
||||
`npm pack` remains the canonical npm artifact. `npm run pack:zip` builds the
|
||||
legacy archive artifact at `dist/openclaw-kitchen-sink-fixture-<version>.zip`
|
||||
with `package.json`, `openclaw.plugin.json`, `plugin-inspector.config.json`,
|
||||
`README.md`, and `src/**` at the archive root for old archive installers.
|
||||
|
||||
Use the `Draft Release` workflow to create the tag and generated GitHub release
|
||||
notes. Publishing that draft release runs the npm publish workflow. `0.0.x`
|
||||
verification releases publish under the `verification` npm dist-tag so they do
|
||||
|
||||
11
package.json
11
package.json
@ -46,6 +46,16 @@
|
||||
"compat": {
|
||||
"pluginApi": "2026.4"
|
||||
},
|
||||
"install": {
|
||||
"clawhubSpec": "clawhub:@openclaw/kitchen-sink",
|
||||
"npmSpec": "@openclaw/kitchen-sink",
|
||||
"defaultChoice": "clawhub",
|
||||
"minHostVersion": "2026.4.29"
|
||||
},
|
||||
"release": {
|
||||
"publishToClawHub": true,
|
||||
"publishToNpm": true
|
||||
},
|
||||
"build": {
|
||||
"openclawVersion": "2026.4.29",
|
||||
"pluginSdkVersion": "2026.4.29"
|
||||
@ -58,6 +68,7 @@
|
||||
"check:inspector": "npm run plugin:inspect && npm run plugin:inspect:runtime",
|
||||
"check:runtime": "node scripts/check-kitchen-runtime.mjs && node scripts/check-kitchen-contract-probes.mjs",
|
||||
"pack:check": "node scripts/check-pack-payload.mjs",
|
||||
"pack:zip": "node scripts/pack-zip.mjs",
|
||||
"plugin:inspect": "plugin-inspector check --config plugin-inspector.config.json --no-openclaw",
|
||||
"plugin:inspect:runtime": "PLUGIN_INSPECTOR_EXECUTE_ISOLATED=1 plugin-inspector check --config plugin-inspector.config.json --no-openclaw --runtime --mock-sdk",
|
||||
"sdk:target-check": "node scripts/check-target-sdk-imports.mjs",
|
||||
|
||||
@ -426,6 +426,12 @@
|
||||
"kitchen-sink-node-host-command"
|
||||
]
|
||||
},
|
||||
"registerNodeInvokePolicy": {
|
||||
"count": 1,
|
||||
"ids": [
|
||||
"kitchen-sink-node-invoke-policy"
|
||||
]
|
||||
},
|
||||
"registerProvider": {
|
||||
"count": 2,
|
||||
"ids": [
|
||||
|
||||
@ -45,6 +45,7 @@ Status: PASS
|
||||
| registerMigrationProvider | 1 | kitchen-sink-migration-provider |
|
||||
| registerMusicGenerationProvider | 2 | kitchen-sink-music, kitchen-sink-music-generation-provider |
|
||||
| registerNodeHostCommand | 1 | kitchen-sink-node-host-command |
|
||||
| registerNodeInvokePolicy | 1 | kitchen-sink-node-invoke-policy |
|
||||
| registerProvider | 2 | kitchen-sink-llm, kitchen-sink-provider |
|
||||
| registerRealtimeTranscriptionProvider | 2 | kitchen-sink-realtime-transcription, kitchen-sink-realtime-transcription-provider |
|
||||
| registerRealtimeVoiceProvider | 2 | kitchen-sink-realtime-voice, kitchen-sink-realtime-voice-provider |
|
||||
|
||||
@ -100,6 +100,24 @@ if (buildPluginSdkVersion !== buildOpenClawVersion) {
|
||||
if (packageJson.dependencies?.openclaw !== buildOpenClawVersion) {
|
||||
issues.push("dependencies.openclaw must match openclaw.build.openclawVersion");
|
||||
}
|
||||
if (packageJson.openclaw?.install?.clawhubSpec !== "clawhub:@openclaw/kitchen-sink") {
|
||||
issues.push('openclaw.install.clawhubSpec must be "clawhub:@openclaw/kitchen-sink"');
|
||||
}
|
||||
if (packageJson.openclaw?.install?.npmSpec !== "@openclaw/kitchen-sink") {
|
||||
issues.push('openclaw.install.npmSpec must be "@openclaw/kitchen-sink"');
|
||||
}
|
||||
if (packageJson.openclaw?.install?.defaultChoice !== "clawhub") {
|
||||
issues.push('openclaw.install.defaultChoice must be "clawhub"');
|
||||
}
|
||||
if (packageJson.openclaw?.install?.minHostVersion !== buildOpenClawVersion) {
|
||||
issues.push("openclaw.install.minHostVersion must match openclaw.build.openclawVersion");
|
||||
}
|
||||
if (packageJson.openclaw?.release?.publishToClawHub !== true) {
|
||||
issues.push("openclaw.release.publishToClawHub must be true");
|
||||
}
|
||||
if (packageJson.openclaw?.release?.publishToNpm !== true) {
|
||||
issues.push("openclaw.release.publishToNpm must be true");
|
||||
}
|
||||
if (!packageJson.files?.includes("src/")) {
|
||||
issues.push("package files must include src/");
|
||||
}
|
||||
|
||||
134
scripts/pack-zip.mjs
Normal file
134
scripts/pack-zip.mjs
Normal file
@ -0,0 +1,134 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
import { Buffer } from "node:buffer";
|
||||
import fs from "node:fs/promises";
|
||||
import path from "node:path";
|
||||
|
||||
const repoRoot = process.cwd();
|
||||
const packageJson = JSON.parse(await fs.readFile(path.join(repoRoot, "package.json"), "utf8"));
|
||||
const pluginJson = JSON.parse(await fs.readFile(path.join(repoRoot, "openclaw.plugin.json"), "utf8"));
|
||||
const packageVersion = packageJson.version;
|
||||
const pluginId = pluginJson.id;
|
||||
const crcTable = Array.from({ length: 256 }, (_, index) => {
|
||||
let value = index;
|
||||
for (let bit = 0; bit < 8; bit += 1) {
|
||||
value = value & 1 ? 0xedb88320 ^ (value >>> 1) : value >>> 1;
|
||||
}
|
||||
return value >>> 0;
|
||||
});
|
||||
|
||||
if (pluginId !== "openclaw-kitchen-sink-fixture") {
|
||||
throw new Error(`unexpected plugin id: ${pluginId}`);
|
||||
}
|
||||
if (typeof packageVersion !== "string" || packageVersion.trim().length === 0) {
|
||||
throw new Error("package.json version must be a non-empty string");
|
||||
}
|
||||
|
||||
const distDir = path.join(repoRoot, "dist");
|
||||
const zipName = `${pluginId}-${packageVersion}.zip`;
|
||||
const zipPath = path.join(distDir, zipName);
|
||||
const entries = [
|
||||
"package.json",
|
||||
"openclaw.plugin.json",
|
||||
"plugin-inspector.config.json",
|
||||
"README.md",
|
||||
...(await listFiles("src")),
|
||||
];
|
||||
|
||||
await fs.mkdir(distDir, { recursive: true });
|
||||
await fs.writeFile(zipPath, await createZip(entries));
|
||||
|
||||
console.log(`Wrote ${path.relative(repoRoot, zipPath)} (${entries.length} files)`);
|
||||
|
||||
async function listFiles(root) {
|
||||
const files = [];
|
||||
const stack = [root];
|
||||
|
||||
while (stack.length > 0) {
|
||||
const relativeDir = stack.pop();
|
||||
const dirents = await fs.readdir(path.join(repoRoot, relativeDir), { withFileTypes: true });
|
||||
for (const dirent of dirents.sort((left, right) => left.name.localeCompare(right.name))) {
|
||||
const relativePath = path.posix.join(relativeDir, dirent.name);
|
||||
if (dirent.isDirectory()) {
|
||||
stack.push(relativePath);
|
||||
} else if (dirent.isFile()) {
|
||||
files.push(relativePath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return files.sort();
|
||||
}
|
||||
|
||||
async function createZip(files) {
|
||||
const localParts = [];
|
||||
const centralParts = [];
|
||||
let offset = 0;
|
||||
|
||||
for (const relativePath of files) {
|
||||
if (relativePath.startsWith("/") || relativePath.includes("..")) {
|
||||
throw new Error(`invalid zip entry path: ${relativePath}`);
|
||||
}
|
||||
|
||||
const data = await fs.readFile(path.join(repoRoot, relativePath));
|
||||
const name = Buffer.from(relativePath, "utf8");
|
||||
const crc = crc32(data);
|
||||
const localHeader = Buffer.alloc(30);
|
||||
localHeader.writeUInt32LE(0x04034b50, 0);
|
||||
localHeader.writeUInt16LE(20, 4);
|
||||
localHeader.writeUInt16LE(0x0800, 6);
|
||||
localHeader.writeUInt16LE(0, 8);
|
||||
localHeader.writeUInt16LE(0, 10);
|
||||
localHeader.writeUInt16LE(0, 12);
|
||||
localHeader.writeUInt32LE(crc, 14);
|
||||
localHeader.writeUInt32LE(data.length, 18);
|
||||
localHeader.writeUInt32LE(data.length, 22);
|
||||
localHeader.writeUInt16LE(name.length, 26);
|
||||
localHeader.writeUInt16LE(0, 28);
|
||||
|
||||
localParts.push(localHeader, name, data);
|
||||
|
||||
const centralHeader = Buffer.alloc(46);
|
||||
centralHeader.writeUInt32LE(0x02014b50, 0);
|
||||
centralHeader.writeUInt16LE(20, 4);
|
||||
centralHeader.writeUInt16LE(20, 6);
|
||||
centralHeader.writeUInt16LE(0x0800, 8);
|
||||
centralHeader.writeUInt16LE(0, 10);
|
||||
centralHeader.writeUInt16LE(0, 12);
|
||||
centralHeader.writeUInt16LE(0, 14);
|
||||
centralHeader.writeUInt32LE(crc, 16);
|
||||
centralHeader.writeUInt32LE(data.length, 20);
|
||||
centralHeader.writeUInt32LE(data.length, 24);
|
||||
centralHeader.writeUInt16LE(name.length, 28);
|
||||
centralHeader.writeUInt16LE(0, 30);
|
||||
centralHeader.writeUInt16LE(0, 32);
|
||||
centralHeader.writeUInt16LE(0, 34);
|
||||
centralHeader.writeUInt16LE(0, 36);
|
||||
centralHeader.writeUInt32LE(0, 38);
|
||||
centralHeader.writeUInt32LE(offset, 42);
|
||||
centralParts.push(centralHeader, name);
|
||||
|
||||
offset += localHeader.length + name.length + data.length;
|
||||
}
|
||||
|
||||
const centralDirectory = Buffer.concat(centralParts);
|
||||
const end = Buffer.alloc(22);
|
||||
end.writeUInt32LE(0x06054b50, 0);
|
||||
end.writeUInt16LE(0, 4);
|
||||
end.writeUInt16LE(0, 6);
|
||||
end.writeUInt16LE(files.length, 8);
|
||||
end.writeUInt16LE(files.length, 10);
|
||||
end.writeUInt32LE(centralDirectory.length, 12);
|
||||
end.writeUInt32LE(offset, 16);
|
||||
end.writeUInt16LE(0, 20);
|
||||
|
||||
return Buffer.concat([...localParts, centralDirectory, end]);
|
||||
}
|
||||
|
||||
function crc32(buffer) {
|
||||
let crc = 0xffffffff;
|
||||
for (const byte of buffer) {
|
||||
crc = (crc >>> 8) ^ crcTable[(crc ^ byte) & 0xff];
|
||||
}
|
||||
return (crc ^ 0xffffffff) >>> 0;
|
||||
}
|
||||
@ -251,6 +251,18 @@ function renderPackageJson({ packageVersion }) {
|
||||
openclawVersion: packageVersion,
|
||||
pluginSdkVersion: packageVersion,
|
||||
};
|
||||
packageJson.openclaw.install = {
|
||||
...(packageJson.openclaw.install ?? {}),
|
||||
clawhubSpec: "clawhub:@openclaw/kitchen-sink",
|
||||
npmSpec: "@openclaw/kitchen-sink",
|
||||
defaultChoice: "clawhub",
|
||||
minHostVersion: packageVersion,
|
||||
};
|
||||
packageJson.openclaw.release = {
|
||||
...(packageJson.openclaw.release ?? {}),
|
||||
publishToClawHub: true,
|
||||
publishToNpm: true,
|
||||
};
|
||||
if (packageJson.dependencies?.openclaw) {
|
||||
packageJson.dependencies.openclaw = packageVersion;
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user