mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 04:40:43 +00:00
docs: complete source-backed docs sweep
This commit is contained in:
@@ -1336,6 +1336,7 @@
|
||||
"providers/anthropic",
|
||||
"providers/arcee",
|
||||
"providers/azure-speech",
|
||||
"providers/cerebras",
|
||||
"providers/chutes",
|
||||
"providers/claude-max-api-proxy",
|
||||
"providers/cloudflare-ai-gateway",
|
||||
@@ -1370,6 +1371,7 @@
|
||||
"providers/qianfan",
|
||||
"providers/qwen",
|
||||
"providers/runway",
|
||||
"providers/senseaudio",
|
||||
"providers/sglang",
|
||||
"providers/stepfun",
|
||||
"providers/synthetic",
|
||||
@@ -1575,6 +1577,7 @@
|
||||
"group": "Gateway and service",
|
||||
"pages": [
|
||||
"cli/backup",
|
||||
"cli/crestodian",
|
||||
"cli/daemon",
|
||||
"cli/doctor",
|
||||
"cli/gateway",
|
||||
@@ -1710,7 +1713,7 @@
|
||||
},
|
||||
{
|
||||
"group": "Project",
|
||||
"pages": ["reference/credits"]
|
||||
"pages": ["reference/application-modernization-plan", "reference/credits"]
|
||||
},
|
||||
{
|
||||
"group": "Release and CI",
|
||||
|
||||
@@ -69,144 +69,25 @@ If the command is running from a source checkout, prefer measuring the built
|
||||
runtime with `node dist/entry.js ...` after `pnpm build`; `pnpm openclaw ...`
|
||||
also measures source-runner overhead.
|
||||
|
||||
## Temporary CLI debug timing
|
||||
## CLI startup and command profiling
|
||||
|
||||
OpenClaw keeps `src/cli/debug-timing.ts` as a small helper for local
|
||||
investigation. It is intentionally not wired into CLI startup, command routing,
|
||||
or any command by default. Use it only while debugging a slow command, then
|
||||
remove the import and spans before landing the behavior change.
|
||||
|
||||
Use this when a command is slow and you need a quick phase breakdown before
|
||||
deciding whether to use a CPU profiler or fix a specific subsystem.
|
||||
|
||||
### Add temporary spans
|
||||
|
||||
Add the helper near the code you are investigating. For example, while debugging
|
||||
`openclaw models list`, a temporary patch in
|
||||
`src/commands/models/list.list-command.ts` might look like this:
|
||||
|
||||
```ts
|
||||
// Temporary debugging only. Remove before landing.
|
||||
import { createCliDebugTiming } from "../../cli/debug-timing.js";
|
||||
|
||||
const timing = createCliDebugTiming({ command: "models list" });
|
||||
|
||||
const authStore = timing.time("debug:models:list:auth_store", () => ensureAuthProfileStore());
|
||||
|
||||
const loaded = await timing.timeAsync(
|
||||
"debug:models:list:registry",
|
||||
() => loadListModelRegistry(cfg, { sourceConfig }),
|
||||
(result) => ({
|
||||
models: result.models.length,
|
||||
discoveredKeys: result.discoveredKeys.size,
|
||||
}),
|
||||
);
|
||||
```
|
||||
|
||||
Guidelines:
|
||||
|
||||
- Prefix temporary phase names with `debug:`.
|
||||
- Add only a few spans around suspected slow sections.
|
||||
- Prefer broad phases such as `registry`, `auth_store`, or `rows` over helper
|
||||
names.
|
||||
- Use `time()` for synchronous work and `timeAsync()` for promises.
|
||||
- Keep stdout clean. The helper writes to stderr, so command JSON output stays
|
||||
parseable.
|
||||
- Remove temporary imports and spans before opening the final fix PR.
|
||||
- Include the timing output or a short summary in the issue or PR that explains
|
||||
the optimization.
|
||||
|
||||
### Run with readable output
|
||||
|
||||
Readable mode is best for live debugging:
|
||||
Use the checked-in startup benchmark when a command feels slow:
|
||||
|
||||
```bash
|
||||
OPENCLAW_DEBUG_TIMING=1 pnpm openclaw models list --all --provider moonshot
|
||||
pnpm test:startup:bench:smoke
|
||||
pnpm tsx scripts/bench-cli-startup.ts --preset real --case status --runs 3
|
||||
pnpm tsx scripts/bench-cli-startup.ts --preset real --cpu-prof-dir .artifacts/cli-cpu
|
||||
```
|
||||
|
||||
Example output from a temporary `models list` investigation:
|
||||
|
||||
```text
|
||||
OpenClaw CLI debug timing: models list
|
||||
0ms +0ms start all=true json=false local=false plain=false provider="moonshot"
|
||||
2ms +2ms debug:models:list:import_runtime duration=2ms
|
||||
17ms +14ms debug:models:list:load_config duration=14ms sourceConfig=true
|
||||
20.3s +20.3s debug:models:list:auth_store duration=20.3s
|
||||
20.3s +0ms debug:models:list:resolve_agent_dir duration=0ms agentDir=true
|
||||
20.3s +0ms debug:models:list:resolve_provider_filter duration=0ms
|
||||
25.3s +5.0s debug:models:list:ensure_models_json duration=5.0s
|
||||
31.2s +5.9s debug:models:list:load_model_registry duration=5.9s models=869 availableKeys=38 discoveredKeys=868 availabilityError=false
|
||||
31.2s +0ms debug:models:list:resolve_configured_entries duration=0ms entries=1
|
||||
31.2s +0ms debug:models:list:build_configured_lookup duration=0ms entries=1
|
||||
33.6s +2.4s debug:models:list:read_registry_models duration=2.4s models=871
|
||||
35.2s +1.5s debug:models:list:append_discovered_rows duration=1.5s seenKeys=0 rows=0
|
||||
36.9s +1.7s debug:models:list:append_catalog_supplement_rows duration=1.7s seenKeys=5 rows=5
|
||||
|
||||
Model Input Ctx Local Auth Tags
|
||||
moonshot/kimi-k2-thinking text 256k no no
|
||||
moonshot/kimi-k2-thinking-turbo text 256k no no
|
||||
moonshot/kimi-k2-turbo text 250k no no
|
||||
moonshot/kimi-k2.5 text+image 256k no no
|
||||
moonshot/kimi-k2.6 text+image 256k no no
|
||||
|
||||
36.9s +0ms debug:models:list:print_model_table duration=0ms rows=5
|
||||
36.9s +0ms complete rows=5
|
||||
```
|
||||
|
||||
Findings from this output:
|
||||
|
||||
| Phase | Time | What it means |
|
||||
| ---------------------------------------- | ---------: | ------------------------------------------------------------------------------------------------------- |
|
||||
| `debug:models:list:auth_store` | 20.3s | The auth-profile store load is the largest cost and should be investigated first. |
|
||||
| `debug:models:list:ensure_models_json` | 5.0s | Syncing `models.json` is expensive enough to inspect for caching or skip conditions. |
|
||||
| `debug:models:list:load_model_registry` | 5.9s | Registry construction and provider availability work are also meaningful costs. |
|
||||
| `debug:models:list:read_registry_models` | 2.4s | Reading all registry models is not free and may matter for `--all`. |
|
||||
| row append phases | 3.2s total | Building five displayed rows still takes several seconds, so the filtering path deserves a closer look. |
|
||||
| `debug:models:list:print_model_table` | 0ms | Rendering is not the bottleneck. |
|
||||
|
||||
Those findings are enough to guide the next patch without keeping timing code in
|
||||
production paths.
|
||||
|
||||
### Run with JSON output
|
||||
|
||||
Use JSON mode when you want to save or compare timing data:
|
||||
For one-off profiling through the normal source runner, set
|
||||
`OPENCLAW_RUN_NODE_CPU_PROF_DIR`:
|
||||
|
||||
```bash
|
||||
OPENCLAW_DEBUG_TIMING=json pnpm openclaw models list --all --provider moonshot \
|
||||
2> .artifacts/models-list-timing.jsonl
|
||||
OPENCLAW_RUN_NODE_CPU_PROF_DIR=.artifacts/cli-cpu pnpm openclaw status
|
||||
```
|
||||
|
||||
Each stderr line is one JSON object:
|
||||
|
||||
```json
|
||||
{
|
||||
"command": "models list",
|
||||
"phase": "debug:models:list:registry",
|
||||
"elapsedMs": 31200,
|
||||
"deltaMs": 5900,
|
||||
"durationMs": 5900,
|
||||
"models": 869,
|
||||
"discoveredKeys": 868
|
||||
}
|
||||
```
|
||||
|
||||
### Clean up before landing
|
||||
|
||||
Before opening the final PR:
|
||||
|
||||
```bash
|
||||
rg 'createCliDebugTiming|debug:[a-z0-9_-]+:' src/commands src/cli \
|
||||
--glob '!src/cli/debug-timing.*' \
|
||||
--glob '!*.test.ts'
|
||||
```
|
||||
|
||||
The command should return no temporary instrumentation call sites unless the PR
|
||||
is explicitly adding a permanent diagnostics surface. For normal performance
|
||||
fixes, keep only the behavior change, tests, and a short note with the timing
|
||||
evidence.
|
||||
|
||||
For deeper CPU hotspots, use Node profiling (`--cpu-prof`) or an external
|
||||
profiler instead of adding more timing wrappers.
|
||||
The source runner adds Node CPU profile flags and writes a `.cpuprofile` for the
|
||||
command. Use this before adding temporary instrumentation to command code.
|
||||
|
||||
## Gateway watch mode
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@ dependencies are available.
|
||||
|
||||
| Plugin | Description | Distribution | Surface |
|
||||
| ----------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| [acpx](/plugins/reference/acpx) | Embedded ACP runtime backend with plugin-owned session and transport management. | `@openclaw/acpx`<br />included in OpenClaw | skills |
|
||||
| [alibaba](/plugins/reference/alibaba) | Adds video generation provider support. | `@openclaw/alibaba-provider`<br />included in OpenClaw | contracts: videoGenerationProviders |
|
||||
| [amazon-bedrock](/plugins/reference/amazon-bedrock) | Adds Amazon Bedrock model provider support to OpenClaw. | `@openclaw/amazon-bedrock-provider`<br />included in OpenClaw | providers: amazon-bedrock; contracts: memoryEmbeddingProviders |
|
||||
| [amazon-bedrock-mantle](/plugins/reference/amazon-bedrock-mantle) | Adds Amazon Bedrock Mantle model provider support to OpenClaw. | `@openclaw/amazon-bedrock-mantle-provider`<br />included in OpenClaw | providers: amazon-bedrock-mantle |
|
||||
@@ -58,6 +59,7 @@ dependencies are available.
|
||||
| [fireworks](/plugins/reference/fireworks) | Adds Fireworks model provider support to OpenClaw. | `@openclaw/fireworks-provider`<br />included in OpenClaw | providers: fireworks |
|
||||
| [github-copilot](/plugins/reference/github-copilot) | Adds GitHub Copilot model provider support to OpenClaw. | `@openclaw/github-copilot-provider`<br />included in OpenClaw | providers: github-copilot; contracts: memoryEmbeddingProviders |
|
||||
| [google](/plugins/reference/google) | Adds Google, Google Gemini CLI, Google Vertex model provider support to OpenClaw. | `@openclaw/google-plugin`<br />included in OpenClaw | providers: google, google-gemini-cli, google-vertex; contracts: imageGenerationProviders, mediaUnderstandingProviders, memoryEmbeddingProviders, musicGenerationProviders, realtimeVoiceProviders, speechProviders, videoGenerationProviders, webSearchProviders |
|
||||
| [googlechat](/plugins/reference/googlechat) | Adds the Google Chat channel surface for sending and receiving OpenClaw messages. | `@openclaw/googlechat`<br />included in OpenClaw | channels: googlechat |
|
||||
| [gradium](/plugins/reference/gradium) | Adds text-to-speech provider support. | `@openclaw/gradium-speech`<br />included in OpenClaw | contracts: speechProviders |
|
||||
| [groq](/plugins/reference/groq) | Adds Groq model provider support to OpenClaw. | `@openclaw/groq-provider`<br />included in OpenClaw | providers: groq; contracts: mediaUnderstandingProviders |
|
||||
| [huggingface](/plugins/reference/huggingface) | Adds Hugging Face model provider support to OpenClaw. | `@openclaw/huggingface-provider`<br />included in OpenClaw | providers: huggingface |
|
||||
@@ -66,6 +68,7 @@ dependencies are available.
|
||||
| [irc](/plugins/reference/irc) | Adds the IRC channel surface for sending and receiving OpenClaw messages. | `@openclaw/irc`<br />included in OpenClaw | channels: irc |
|
||||
| [kilocode](/plugins/reference/kilocode) | Adds Kilocode model provider support to OpenClaw. | `@openclaw/kilocode-provider`<br />included in OpenClaw | providers: kilocode |
|
||||
| [kimi](/plugins/reference/kimi) | Adds Kimi, Kimi Coding model provider support to OpenClaw. | `@openclaw/kimi-provider`<br />included in OpenClaw | providers: kimi, kimi-coding |
|
||||
| [line](/plugins/reference/line) | Adds the LINE channel surface for sending and receiving OpenClaw messages. | `@openclaw/line`<br />included in OpenClaw | channels: line |
|
||||
| [litellm](/plugins/reference/litellm) | Adds LiteLLM model provider support to OpenClaw. | `@openclaw/litellm-provider`<br />included in OpenClaw | providers: litellm; contracts: imageGenerationProviders |
|
||||
| [llm-task](/plugins/reference/llm-task) | Generic JSON-only LLM tool for structured tasks callable from workflows. | `@openclaw/llm-task`<br />included in OpenClaw | contracts: tools |
|
||||
| [lmstudio](/plugins/reference/lmstudio) | Adds LM Studio model provider support to OpenClaw. | `@openclaw/lmstudio-provider`<br />included in OpenClaw | providers: lmstudio; contracts: memoryEmbeddingProviders |
|
||||
@@ -120,7 +123,6 @@ dependencies are available.
|
||||
|
||||
| Plugin | Description | Distribution | Surface |
|
||||
| ------------------------------------------------------------------- | ------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------- |
|
||||
| [acpx](/plugins/reference/acpx) | Embedded ACP runtime backend with plugin-owned session and transport management. | `@openclaw/acpx`<br />ClawHub + npm | skills |
|
||||
| [bluebubbles](/plugins/reference/bluebubbles) | Adds the BlueBubbles channel surface for sending and receiving OpenClaw messages. | `@openclaw/bluebubbles`<br />ClawHub + npm | channels: bluebubbles |
|
||||
| [brave](/plugins/reference/brave) | Adds web search provider support. | `@openclaw/brave-plugin`<br />ClawHub + npm | contracts: webSearchProviders |
|
||||
| [codex](/plugins/reference/codex) | Codex app-server harness and Codex-managed GPT model catalog. | `@openclaw/codex`<br />ClawHub + npm | providers: codex; contracts: mediaUnderstandingProviders, migrationProviders |
|
||||
@@ -130,8 +132,6 @@ dependencies are available.
|
||||
| [discord](/plugins/reference/discord) | Adds the Discord channel surface for sending and receiving OpenClaw messages. | `@openclaw/discord`<br />ClawHub + npm | channels: discord |
|
||||
| [feishu](/plugins/reference/feishu) | Adds the Feishu channel surface for sending and receiving OpenClaw messages. | `@openclaw/feishu`<br />ClawHub + npm | channels: feishu; contracts: tools; skills |
|
||||
| [google-meet](/plugins/reference/google-meet) | Join Google Meet calls through Chrome or Twilio transports. | `@openclaw/google-meet`<br />ClawHub + npm | contracts: tools |
|
||||
| [googlechat](/plugins/reference/googlechat) | Adds the Google Chat channel surface for sending and receiving OpenClaw messages. | `@openclaw/googlechat`<br />ClawHub + npm | channels: googlechat |
|
||||
| [line](/plugins/reference/line) | Adds the LINE channel surface for sending and receiving OpenClaw messages. | `@openclaw/line`<br />ClawHub + npm | channels: line |
|
||||
| [lobster](/plugins/reference/lobster) | Typed workflow tool with resumable approvals. | `@openclaw/lobster`<br />ClawHub + npm | contracts: tools |
|
||||
| [matrix](/plugins/reference/matrix) | Adds the Matrix channel surface for sending and receiving OpenClaw messages. | `@openclaw/matrix`<br />ClawHub + npm | channels: matrix |
|
||||
| [mattermost](/plugins/reference/mattermost) | Adds the Mattermost channel surface for sending and receiving OpenClaw messages. | `@openclaw/mattermost`<br />ClawHub + npm | channels: mattermost |
|
||||
|
||||
@@ -17,7 +17,7 @@ pnpm plugins:inventory:gen
|
||||
|
||||
| Plugin | Description | Distribution | Surface |
|
||||
| ------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| [acpx](/plugins/reference/acpx) | Embedded ACP runtime backend with plugin-owned session and transport management. | `@openclaw/acpx`<br />ClawHub + npm | skills |
|
||||
| [acpx](/plugins/reference/acpx) | Embedded ACP runtime backend with plugin-owned session and transport management. | `@openclaw/acpx`<br />included in OpenClaw | skills |
|
||||
| [alibaba](/plugins/reference/alibaba) | Adds video generation provider support. | `@openclaw/alibaba-provider`<br />included in OpenClaw | contracts: videoGenerationProviders |
|
||||
| [amazon-bedrock](/plugins/reference/amazon-bedrock) | Adds Amazon Bedrock model provider support to OpenClaw. | `@openclaw/amazon-bedrock-provider`<br />included in OpenClaw | providers: amazon-bedrock; contracts: memoryEmbeddingProviders |
|
||||
| [amazon-bedrock-mantle](/plugins/reference/amazon-bedrock-mantle) | Adds Amazon Bedrock Mantle model provider support to OpenClaw. | `@openclaw/amazon-bedrock-mantle-provider`<br />included in OpenClaw | providers: amazon-bedrock-mantle |
|
||||
@@ -55,7 +55,7 @@ pnpm plugins:inventory:gen
|
||||
| [github-copilot](/plugins/reference/github-copilot) | Adds GitHub Copilot model provider support to OpenClaw. | `@openclaw/github-copilot-provider`<br />included in OpenClaw | providers: github-copilot; contracts: memoryEmbeddingProviders |
|
||||
| [google](/plugins/reference/google) | Adds Google, Google Gemini CLI, Google Vertex model provider support to OpenClaw. | `@openclaw/google-plugin`<br />included in OpenClaw | providers: google, google-gemini-cli, google-vertex; contracts: imageGenerationProviders, mediaUnderstandingProviders, memoryEmbeddingProviders, musicGenerationProviders, realtimeVoiceProviders, speechProviders, videoGenerationProviders, webSearchProviders |
|
||||
| [google-meet](/plugins/reference/google-meet) | Join Google Meet calls through Chrome or Twilio transports. | `@openclaw/google-meet`<br />ClawHub + npm | contracts: tools |
|
||||
| [googlechat](/plugins/reference/googlechat) | Adds the Google Chat channel surface for sending and receiving OpenClaw messages. | `@openclaw/googlechat`<br />ClawHub + npm | channels: googlechat |
|
||||
| [googlechat](/plugins/reference/googlechat) | Adds the Google Chat channel surface for sending and receiving OpenClaw messages. | `@openclaw/googlechat`<br />included in OpenClaw | channels: googlechat |
|
||||
| [gradium](/plugins/reference/gradium) | Adds text-to-speech provider support. | `@openclaw/gradium-speech`<br />included in OpenClaw | contracts: speechProviders |
|
||||
| [groq](/plugins/reference/groq) | Adds Groq model provider support to OpenClaw. | `@openclaw/groq-provider`<br />included in OpenClaw | providers: groq; contracts: mediaUnderstandingProviders |
|
||||
| [huggingface](/plugins/reference/huggingface) | Adds Hugging Face model provider support to OpenClaw. | `@openclaw/huggingface-provider`<br />included in OpenClaw | providers: huggingface |
|
||||
@@ -64,7 +64,7 @@ pnpm plugins:inventory:gen
|
||||
| [irc](/plugins/reference/irc) | Adds the IRC channel surface for sending and receiving OpenClaw messages. | `@openclaw/irc`<br />included in OpenClaw | channels: irc |
|
||||
| [kilocode](/plugins/reference/kilocode) | Adds Kilocode model provider support to OpenClaw. | `@openclaw/kilocode-provider`<br />included in OpenClaw | providers: kilocode |
|
||||
| [kimi](/plugins/reference/kimi) | Adds Kimi, Kimi Coding model provider support to OpenClaw. | `@openclaw/kimi-provider`<br />included in OpenClaw | providers: kimi, kimi-coding |
|
||||
| [line](/plugins/reference/line) | Adds the LINE channel surface for sending and receiving OpenClaw messages. | `@openclaw/line`<br />ClawHub + npm | channels: line |
|
||||
| [line](/plugins/reference/line) | Adds the LINE channel surface for sending and receiving OpenClaw messages. | `@openclaw/line`<br />included in OpenClaw | channels: line |
|
||||
| [litellm](/plugins/reference/litellm) | Adds LiteLLM model provider support to OpenClaw. | `@openclaw/litellm-provider`<br />included in OpenClaw | providers: litellm; contracts: imageGenerationProviders |
|
||||
| [llm-task](/plugins/reference/llm-task) | Generic JSON-only LLM tool for structured tasks callable from workflows. | `@openclaw/llm-task`<br />included in OpenClaw | contracts: tools |
|
||||
| [lmstudio](/plugins/reference/lmstudio) | Adds LM Studio model provider support to OpenClaw. | `@openclaw/lmstudio-provider`<br />included in OpenClaw | providers: lmstudio; contracts: memoryEmbeddingProviders |
|
||||
|
||||
@@ -12,7 +12,7 @@ Embedded ACP runtime backend with plugin-owned session and transport management.
|
||||
## Distribution
|
||||
|
||||
- Package: `@openclaw/acpx`
|
||||
- Install route: ClawHub + npm
|
||||
- Install route: included in OpenClaw
|
||||
|
||||
## Surface
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ Adds the Google Chat channel surface for sending and receiving OpenClaw messages
|
||||
## Distribution
|
||||
|
||||
- Package: `@openclaw/googlechat`
|
||||
- Install route: ClawHub + npm
|
||||
- Install route: included in OpenClaw
|
||||
|
||||
## Surface
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ Adds the LINE channel surface for sending and receiving OpenClaw messages.
|
||||
## Distribution
|
||||
|
||||
- Package: `@openclaw/line`
|
||||
- Install route: ClawHub + npm
|
||||
- Install route: included in OpenClaw
|
||||
|
||||
## Surface
|
||||
|
||||
|
||||
@@ -351,8 +351,8 @@ For contract tests only:
|
||||
|
||||
```bash
|
||||
pnpm test -- src/plugins/contracts/shape.contract.test.ts
|
||||
pnpm test -- src/plugins/contracts/auth.contract.test.ts
|
||||
pnpm test -- src/plugins/contracts/runtime.contract.test.ts
|
||||
pnpm test -- src/plugins/contracts/auth-choice.contract.test.ts
|
||||
pnpm test -- src/plugins/contracts/runtime-seams.contract.test.ts
|
||||
```
|
||||
|
||||
## Lint enforcement (in-repo plugins)
|
||||
|
||||
@@ -281,7 +281,6 @@ Primary files:
|
||||
Likely new helpers:
|
||||
|
||||
- `ui/src/ui/custom-theme.ts`
|
||||
- `ui/src/ui/custom-theme-import.ts`
|
||||
|
||||
Tests:
|
||||
|
||||
|
||||
@@ -8,9 +8,13 @@ export type BundledPluginBuildEntry = {
|
||||
export type BundledPluginBuildEntryParams = {
|
||||
cwd?: string;
|
||||
env?: NodeJS.ProcessEnv;
|
||||
includeRootPackageExcludedDirs?: boolean;
|
||||
};
|
||||
|
||||
export const NON_PACKAGED_BUNDLED_PLUGIN_DIRS: Set<string>;
|
||||
export function collectRootPackageExcludedExtensionDirs(
|
||||
params?: BundledPluginBuildEntryParams,
|
||||
): Set<string>;
|
||||
export function collectBundledPluginBuildEntries(
|
||||
params?: BundledPluginBuildEntryParams,
|
||||
): BundledPluginBuildEntry[];
|
||||
|
||||
@@ -145,9 +145,34 @@ export function listBundledPluginBuildEntries(params = {}) {
|
||||
);
|
||||
}
|
||||
|
||||
export function collectRootPackageExcludedExtensionDirs(params = {}) {
|
||||
const cwd = params.cwd ?? process.cwd();
|
||||
const packageJsonPath = path.join(cwd, "package.json");
|
||||
const excluded = new Set();
|
||||
if (!fs.existsSync(packageJsonPath)) {
|
||||
return excluded;
|
||||
}
|
||||
|
||||
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf8"));
|
||||
for (const entry of packageJson.files ?? []) {
|
||||
if (typeof entry !== "string") {
|
||||
continue;
|
||||
}
|
||||
const match = /^!dist\/extensions\/([^/]+)\/\*\*$/u.exec(entry);
|
||||
if (match?.[1]) {
|
||||
excluded.add(match[1]);
|
||||
}
|
||||
}
|
||||
return excluded;
|
||||
}
|
||||
|
||||
export function listBundledPluginPackArtifacts(params = {}) {
|
||||
const excludedPackageDirs =
|
||||
params.includeRootPackageExcludedDirs === true
|
||||
? new Set()
|
||||
: collectRootPackageExcludedExtensionDirs(params);
|
||||
const entries = collectBundledPluginBuildEntries(params).filter(
|
||||
({ id }) => !NON_PACKAGED_BUNDLED_PLUGIN_DIRS.has(id),
|
||||
({ id }) => !NON_PACKAGED_BUNDLED_PLUGIN_DIRS.has(id) && !excludedPackageDirs.has(id),
|
||||
);
|
||||
const artifacts = new Set();
|
||||
|
||||
|
||||
@@ -27,7 +27,10 @@ import {
|
||||
type BundledExtension,
|
||||
type ExtensionPackageJson as PackageJson,
|
||||
} from "./lib/bundled-extension-manifest.ts";
|
||||
import { listBundledPluginPackArtifacts } from "./lib/bundled-plugin-build-entries.mjs";
|
||||
import {
|
||||
collectRootPackageExcludedExtensionDirs,
|
||||
listBundledPluginPackArtifacts,
|
||||
} from "./lib/bundled-plugin-build-entries.mjs";
|
||||
import { collectPackUnpackedSizeErrors as collectNpmPackUnpackedSizeErrors } from "./lib/npm-pack-budget.mjs";
|
||||
import { collectBundledPluginPackageDependencySpecs } from "./lib/plugin-package-dependencies.mjs";
|
||||
import { listPluginSdkDistArtifacts } from "./lib/plugin-sdk-entries.mjs";
|
||||
@@ -45,13 +48,17 @@ export { packageNameFromSpecifier } from "./lib/plugin-package-dependencies.mjs"
|
||||
type PackFile = { path: string };
|
||||
type PackResult = { files?: PackFile[]; filename?: string; unpackedSize?: number };
|
||||
|
||||
const rootPackageExcludedExtensionDirs = collectRootPackageExcludedExtensionDirs();
|
||||
const requiredPathGroups = [
|
||||
PACKAGE_DIST_INVENTORY_RELATIVE_PATH,
|
||||
["dist/index.js", "dist/index.mjs"],
|
||||
["dist/entry.js", "dist/entry.mjs"],
|
||||
...listPluginSdkDistArtifacts(),
|
||||
...listBundledPluginPackArtifacts(),
|
||||
...listStaticExtensionAssetOutputs(),
|
||||
...listStaticExtensionAssetOutputs().filter((relativePath) => {
|
||||
const match = /^dist\/extensions\/([^/]+)\//u.exec(relativePath);
|
||||
return !match || !rootPackageExcludedExtensionDirs.has(match[1]);
|
||||
}),
|
||||
...WORKSPACE_TEMPLATE_PACK_PATHS,
|
||||
"scripts/npm-runner.mjs",
|
||||
"scripts/preinstall-package-manager-warning.mjs",
|
||||
@@ -119,7 +126,11 @@ export const PACKED_CLI_SMOKE_COMMANDS = [
|
||||
["config", "schema"],
|
||||
["models", "list", "--provider", "amazon-bedrock"],
|
||||
] as const;
|
||||
export const PACKED_BUNDLED_RUNTIME_DEPS_REPAIR_ARGS = ["plugins", "deps", "--repair"] as const;
|
||||
export const PACKED_BUNDLED_RUNTIME_DEPS_REPAIR_ARGS = [
|
||||
"doctor",
|
||||
"--fix",
|
||||
"--non-interactive",
|
||||
] as const;
|
||||
export const PACKED_COMPLETION_SMOKE_ARGS = [
|
||||
"completion",
|
||||
"--write-state",
|
||||
@@ -291,6 +302,7 @@ export function createPackedCliSmokeEnv(
|
||||
AWS_CONFIG_FILE: homeDir ? join(homeDir, ".aws", "config") : undefined,
|
||||
OPENCLAW_DISABLE_BUNDLED_ENTRY_SOURCE_FALLBACK: "1",
|
||||
OPENCLAW_NO_ONBOARD: "1",
|
||||
OPENCLAW_SERVICE_REPAIR_POLICY: "external",
|
||||
OPENCLAW_SUPPRESS_NOTES: "1",
|
||||
...overrides,
|
||||
};
|
||||
|
||||
@@ -84,7 +84,11 @@ describe("packed CLI smoke", () => {
|
||||
});
|
||||
|
||||
it("repairs bundled runtime deps before the read-only plugin doctor smoke", () => {
|
||||
expect(PACKED_BUNDLED_RUNTIME_DEPS_REPAIR_ARGS).toEqual(["plugins", "deps", "--repair"]);
|
||||
expect(PACKED_BUNDLED_RUNTIME_DEPS_REPAIR_ARGS).toEqual([
|
||||
"doctor",
|
||||
"--fix",
|
||||
"--non-interactive",
|
||||
]);
|
||||
});
|
||||
|
||||
it("keeps packed completion smoke scoped to one shell cache", () => {
|
||||
@@ -123,6 +127,7 @@ describe("packed CLI smoke", () => {
|
||||
SystemRoot: "C:\\Windows",
|
||||
OPENCLAW_DISABLE_BUNDLED_ENTRY_SOURCE_FALLBACK: "1",
|
||||
OPENCLAW_NO_ONBOARD: "1",
|
||||
OPENCLAW_SERVICE_REPAIR_POLICY: "external",
|
||||
OPENCLAW_SUPPRESS_NOTES: "1",
|
||||
OPENCLAW_STATE_DIR: "/tmp/smoke-state",
|
||||
});
|
||||
@@ -491,16 +496,15 @@ describe("collectMissingPackPaths", () => {
|
||||
"scripts/lib/package-dist-imports.mjs",
|
||||
"scripts/postinstall-bundled-plugins.mjs",
|
||||
"dist/task-registry-control.runtime.js",
|
||||
bundledDistPluginFile("diffs", "assets/viewer-runtime.js"),
|
||||
bundledDistPluginFile("matrix", "helper-api.js"),
|
||||
bundledDistPluginFile("matrix", "runtime-api.js"),
|
||||
bundledDistPluginFile("matrix", "thread-bindings-runtime.js"),
|
||||
bundledDistPluginFile("matrix", "openclaw.plugin.json"),
|
||||
bundledDistPluginFile("matrix", "package.json"),
|
||||
bundledDistPluginFile("whatsapp", "light-runtime-api.js"),
|
||||
bundledDistPluginFile("whatsapp", "runtime-api.js"),
|
||||
bundledDistPluginFile("whatsapp", "openclaw.plugin.json"),
|
||||
bundledDistPluginFile("whatsapp", "package.json"),
|
||||
bundledDistPluginFile("acpx", "runtime-api.js"),
|
||||
bundledDistPluginFile("acpx", "openclaw.plugin.json"),
|
||||
bundledDistPluginFile("acpx", "package.json"),
|
||||
bundledDistPluginFile("googlechat", "runtime-api.js"),
|
||||
bundledDistPluginFile("googlechat", "openclaw.plugin.json"),
|
||||
bundledDistPluginFile("googlechat", "package.json"),
|
||||
bundledDistPluginFile("line", "runtime-api.js"),
|
||||
bundledDistPluginFile("line", "openclaw.plugin.json"),
|
||||
bundledDistPluginFile("line", "package.json"),
|
||||
]),
|
||||
);
|
||||
});
|
||||
@@ -514,7 +518,6 @@ describe("collectMissingPackPaths", () => {
|
||||
"dist/extensions/acpx/error-format.mjs",
|
||||
"dist/extensions/acpx/mcp-command-line.mjs",
|
||||
"dist/extensions/acpx/mcp-proxy.mjs",
|
||||
bundledDistPluginFile("diffs", "assets/viewer-runtime.js"),
|
||||
...requiredBundledPluginPackPaths,
|
||||
...requiredPluginSdkPackPaths,
|
||||
...WORKSPACE_TEMPLATE_PACK_PATHS,
|
||||
@@ -537,11 +540,9 @@ describe("collectMissingPackPaths", () => {
|
||||
it("requires bundled plugin runtime sidecars that dynamic plugin boundaries resolve at runtime", () => {
|
||||
expect(requiredBundledPluginPackPaths).toEqual(
|
||||
expect.arrayContaining([
|
||||
bundledDistPluginFile("matrix", "helper-api.js"),
|
||||
bundledDistPluginFile("matrix", "runtime-api.js"),
|
||||
bundledDistPluginFile("matrix", "thread-bindings-runtime.js"),
|
||||
bundledDistPluginFile("whatsapp", "light-runtime-api.js"),
|
||||
bundledDistPluginFile("whatsapp", "runtime-api.js"),
|
||||
bundledDistPluginFile("acpx", "runtime-api.js"),
|
||||
bundledDistPluginFile("googlechat", "runtime-api.js"),
|
||||
bundledDistPluginFile("line", "runtime-api.js"),
|
||||
]),
|
||||
);
|
||||
});
|
||||
|
||||
@@ -2,6 +2,7 @@ import fs from "node:fs";
|
||||
import path from "node:path";
|
||||
import { describe, expect, it } from "vitest";
|
||||
import {
|
||||
collectRootPackageExcludedExtensionDirs,
|
||||
listBundledPluginBuildEntries,
|
||||
listBundledPluginPackArtifacts,
|
||||
} from "../../scripts/lib/bundled-plugin-build-entries.mjs";
|
||||
@@ -68,7 +69,7 @@ describe("bundled plugin build entries", () => {
|
||||
});
|
||||
|
||||
it("packs the Matrix packaged runtime shim", () => {
|
||||
const artifacts = listBundledPluginPackArtifacts();
|
||||
const artifacts = listBundledPluginPackArtifacts({ includeRootPackageExcludedDirs: true });
|
||||
|
||||
expect(artifacts).toContain("dist/extensions/matrix/plugin-entry.handlers.runtime.js");
|
||||
});
|
||||
@@ -91,12 +92,22 @@ describe("bundled plugin build entries", () => {
|
||||
const entries = listBundledPluginBuildEntries();
|
||||
const artifacts = listBundledPluginPackArtifacts();
|
||||
|
||||
expect(Object.keys(entries).some((entry) => entry.startsWith("extensions/bluebubbles/"))).toBe(
|
||||
true,
|
||||
);
|
||||
expect(artifacts.some((artifact) => artifact.startsWith("dist/extensions/bluebubbles/"))).toBe(
|
||||
false,
|
||||
);
|
||||
expect(artifacts).toContain("dist/extensions/acpx/index.js");
|
||||
expect(artifacts).toContain("dist/extensions/googlechat/index.js");
|
||||
expect(artifacts).toContain("dist/extensions/line/index.js");
|
||||
expect(Object.keys(entries).some((entry) => entry.startsWith("extensions/qqbot/"))).toBe(false);
|
||||
expect(artifacts.some((artifact) => artifact.startsWith("dist/extensions/qqbot/"))).toBe(false);
|
||||
});
|
||||
|
||||
it("keeps bundled channel secret contracts on packed top-level sidecars", () => {
|
||||
const artifacts = listBundledPluginPackArtifacts();
|
||||
const excludedPackageDirs = collectRootPackageExcludedExtensionDirs();
|
||||
const offenders: string[] = [];
|
||||
const secretBackedPluginIds = new Set<string>();
|
||||
|
||||
@@ -114,6 +125,9 @@ describe("bundled plugin build entries", () => {
|
||||
expect(offenders).toEqual([]);
|
||||
|
||||
for (const pluginId of [...secretBackedPluginIds].toSorted()) {
|
||||
if (excludedPackageDirs.has(pluginId)) {
|
||||
continue;
|
||||
}
|
||||
const secretApiPath = path.join("extensions", pluginId, "secret-contract-api.ts");
|
||||
expect(fs.readFileSync(secretApiPath, "utf8")).toContain("channelSecrets");
|
||||
expect(artifacts).toContain(`dist/extensions/${pluginId}/secret-contract-api.js`);
|
||||
|
||||
Reference in New Issue
Block a user