feat(tokenjuice): bundle the native adapter (#69946)

* feat(plugins): register embedded extension factories

* feat(tokenjuice): bundle the native adapter

* fix(tokenjuice): gate the bundled embedded extension seam

* fix(tokenjuice): refresh runtime sidecar baseline

* fix(plugins): harden bundled embedded extensions

* fix(plugins): install source bundled runtime deps

* fix(tokenjuice): sync lockfile importer

* fix(plugins): validate reused runtime dep versions

* fix(plugins): restore tokenjuice CI contract

* fix(plugins): remove tokenjuice dts bridge

* fix(tokenjuice): repair openclaw type shim

* fix(plugins): harden bundled runtime deps

* fix(plugins): keep source checkout runtime deps local

* fix(plugins): isolate bundled runtime dep installs

* fix(cli): keep plugin startup registration non-activating

* fix(cli): keep loader overrides out of plugin cli options
This commit is contained in:
Vincent Koc
2026-04-21 23:58:37 -07:00
committed by GitHub
parent 201385548c
commit 91ac485246
38 changed files with 1338 additions and 133 deletions

View File

@@ -0,0 +1,52 @@
import fs from "node:fs";
import { beforeEach, describe, expect, it, vi } from "vitest";
import { createTestPluginApi } from "../../test/helpers/plugins/plugin-api.js";
const { tokenjuiceFactory, createTokenjuiceOpenClawEmbeddedExtension } = vi.hoisted(() => {
const tokenjuiceFactory = vi.fn();
const createTokenjuiceOpenClawEmbeddedExtension = vi.fn(() => tokenjuiceFactory);
return {
tokenjuiceFactory,
createTokenjuiceOpenClawEmbeddedExtension,
};
});
vi.mock("./runtime-api.js", () => ({
createTokenjuiceOpenClawEmbeddedExtension,
}));
import plugin from "./index.js";
describe("tokenjuice bundled plugin", () => {
beforeEach(() => {
createTokenjuiceOpenClawEmbeddedExtension.mockClear();
tokenjuiceFactory.mockClear();
});
it("is opt-in by default", () => {
const manifest = JSON.parse(
fs.readFileSync(new URL("./openclaw.plugin.json", import.meta.url), "utf8"),
) as { enabledByDefault?: unknown };
expect(manifest.enabledByDefault).toBeUndefined();
});
it("registers the tokenjuice embedded extension factory", () => {
const registerEmbeddedExtensionFactory = vi.fn();
plugin.register(
createTestPluginApi({
id: "tokenjuice",
name: "tokenjuice",
source: "test",
config: {},
pluginConfig: {},
runtime: {} as never,
registerEmbeddedExtensionFactory,
}),
);
expect(createTokenjuiceOpenClawEmbeddedExtension).toHaveBeenCalledTimes(1);
expect(registerEmbeddedExtensionFactory).toHaveBeenCalledWith(tokenjuiceFactory);
});
});

View File

@@ -0,0 +1,11 @@
import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry";
import { createTokenjuiceOpenClawEmbeddedExtension } from "./runtime-api.js";
export default definePluginEntry({
id: "tokenjuice",
name: "tokenjuice",
description: "Compacts exec and bash tool results with tokenjuice reducers.",
register(api) {
api.registerEmbeddedExtensionFactory(createTokenjuiceOpenClawEmbeddedExtension());
},
});

View File

@@ -0,0 +1,36 @@
import fs from "node:fs";
import { describe, expect, it } from "vitest";
type TokenjuicePackageManifest = {
dependencies?: Record<string, string>;
openclaw?: {
bundle?: {
stageRuntimeDependencies?: boolean;
};
};
};
type TokenjuicePluginManifest = {
contracts?: {
embeddedExtensionFactories?: string[];
};
};
describe("tokenjuice package manifest", () => {
it("opts into staging bundled runtime dependencies", () => {
const packageJson = JSON.parse(
fs.readFileSync(new URL("./package.json", import.meta.url), "utf8"),
) as TokenjuicePackageManifest;
expect(packageJson.dependencies?.tokenjuice).toBe("0.6.1");
expect(packageJson.openclaw?.bundle?.stageRuntimeDependencies).toBe(true);
});
it("declares Pi embedded extension factory ownership in the manifest contract", () => {
const manifest = JSON.parse(
fs.readFileSync(new URL("./openclaw.plugin.json", import.meta.url), "utf8"),
) as TokenjuicePluginManifest;
expect(manifest.contracts?.embeddedExtensionFactories).toEqual(["pi"]);
});
});

View File

@@ -0,0 +1,13 @@
{
"id": "tokenjuice",
"name": "tokenjuice",
"description": "Compacts exec and bash tool results with tokenjuice reducers.",
"contracts": {
"embeddedExtensionFactories": ["pi"]
},
"configSchema": {
"type": "object",
"additionalProperties": false,
"properties": {}
}
}

View File

@@ -0,0 +1,20 @@
{
"name": "@openclaw/tokenjuice",
"version": "2026.4.21",
"description": "Bundled tokenjuice exec output compaction plugin",
"type": "module",
"dependencies": {
"tokenjuice": "0.6.1"
},
"devDependencies": {
"@openclaw/plugin-sdk": "workspace:*"
},
"openclaw": {
"extensions": [
"./index.ts"
],
"bundle": {
"stageRuntimeDependencies": true
}
}
}

View File

@@ -0,0 +1 @@
export { createTokenjuiceOpenClawEmbeddedExtension } from "tokenjuice/openclaw";

View File

@@ -0,0 +1,5 @@
import type { ExtensionFactory } from "@mariozechner/pi-coding-agent";
declare module "tokenjuice/openclaw" {
export function createTokenjuiceOpenClawEmbeddedExtension(): ExtensionFactory;
}

View File

@@ -0,0 +1,16 @@
{
"extends": "../tsconfig.package-boundary.base.json",
"compilerOptions": {
"rootDir": "."
},
"include": ["./*.ts", "./src/**/*.ts"],
"exclude": [
"./**/*.test.ts",
"./dist/**",
"./node_modules/**",
"./src/test-support/**",
"./src/**/*test-helpers.ts",
"./src/**/*test-harness.ts",
"./src/**/*test-support.ts"
]
}