{"id":49362150,"url":"https://github.com/openclaw/plugin-inspector","last_synced_at":"2026-05-02T22:01:10.182Z","repository":{"id":354075032,"uuid":"1221809102","full_name":"openclaw/plugin-inspector","owner":"openclaw","description":" Offline compatibility inspector for mocking OpenClaw and testing plugins 💊","archived":false,"fork":false,"pushed_at":"2026-04-30T09:54:07.000Z","size":599,"stargazers_count":12,"open_issues_count":0,"forks_count":2,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-01T21:38:06.131Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/openclaw.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null},"funding":{"github":["moltbot"]}},"created_at":"2026-04-26T17:55:19.000Z","updated_at":"2026-05-01T05:13:25.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/openclaw/plugin-inspector","commit_stats":null,"previous_names":["openclaw/plugin-inspector"],"tags_count":11,"template":false,"template_full_name":null,"purl":"pkg:github/openclaw/plugin-inspector","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/openclaw%2Fplugin-inspector","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/openclaw%2Fplugin-inspector/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/openclaw%2Fplugin-inspector/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/openclaw%2Fplugin-inspector/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/openclaw","download_url":"https://codeload.github.com/openclaw/plugin-inspector/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/openclaw%2Fplugin-inspector/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32550914,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-02T21:31:48.061Z","status":"ssl_error","status_checked_at":"2026-05-02T21:31:46.574Z","response_time":132,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-04-27T17:00:21.826Z","updated_at":"2026-05-02T22:01:10.144Z","avatar_url":"https://github.com/openclaw.png","language":"JavaScript","funding_links":["https://github.com/sponsors/moltbot"],"categories":["Skills \u0026 Plugins"],"sub_categories":["Notable Skills \u0026 Plugins"],"readme":"\u003cimg src=\"docs/plugin-inspector-banner.jpg\" alt=\"OpenClaw Plugin Inspector banner\"\u003e\n\n# OpenClaw Plugin Inspector\n\n`@openclaw/plugin-inspector` is the offline compatibility checker for OpenClaw\nplugin packages and plugin fixture suites.\n\nIt answers the questions that matter before a plugin reaches users:\n\n- can OpenClaw discover the package metadata and `openclaw.plugin.json`\n  manifest?\n- which hooks, registration calls, manifest contracts, and SDK imports does the\n  plugin use?\n- does the plugin still look compatible without local OpenClaw internals?\n- if CI finds a breakage, which JSON, Markdown, SARIF, JUnit, and summary\n  artifacts should downstream automation read?\n- when a fixture-suite harness such as Crabpot runs many plugins, which findings\n  are hard breakages, known warnings, live issues, deprecations, or inspector\n  proof gaps?\n\nThe default path is static, offline, and credential-free. Runtime capture exists,\nbut it is opt-in because it imports plugin code.\n\n## Requirements\n\n- Node.js 22 or newer.\n- A plugin package root with `package.json`.\n- `openclaw.plugin.json` when the plugin uses the OpenClaw manifest contract.\n- No OpenClaw checkout, credentials, network service, or live provider access for\n  default inspection.\n\nPass `--no-openclaw` when CI should not compare against a local OpenClaw\ncheckout. If an OpenClaw checkout is supplied with `--openclaw \u003cpath\u003e`, the\ninspector only reads public compatibility surfaces such as compat records, SDK\nexports, hook names, manifest fields, and registrar metadata.\n\n## Quick Start\n\nRun this from a plugin package root:\n\n```bash\nnpx @openclaw/plugin-inspector inspect --no-openclaw\n```\n\nEquivalent one-off runners:\n\n```bash\npnpm dlx @openclaw/plugin-inspector inspect --no-openclaw\nyarn dlx @openclaw/plugin-inspector inspect --no-openclaw\nbunx @openclaw/plugin-inspector inspect --no-openclaw\n```\n\nThe command writes:\n\n- `reports/plugin-inspector-report.json`\n- `reports/plugin-inspector-report.md`\n- `reports/plugin-inspector-issues.md`\n\nIt exits non-zero when hard compatibility breakages are found. Warnings,\nsuggestions, issue classifications, and logs stay visible in the report without\nnecessarily failing the command.\n\n## Install In A Plugin Repo\n\nInstall the package when you want repeatable local scripts and CI:\n\n```bash\nnpm install --save-dev @openclaw/plugin-inspector\n```\n\nAdd scripts:\n\n```json\n{\n  \"scripts\": {\n    \"plugin:check\": \"plugin-inspector inspect --no-openclaw\",\n    \"plugin:ci\": \"plugin-inspector ci --no-openclaw --runtime --mock-sdk --allow-execute\"\n  }\n}\n```\n\nThen run:\n\n```bash\nnpm run plugin:check\n```\n\nThe initializer can write the starter config, package scripts, and GitHub\nActions workflow:\n\n```bash\nnpx @openclaw/plugin-inspector init --ci --scripts --dry-run\nnpx @openclaw/plugin-inspector init --ci --scripts\n```\n\n`init` detects `packageManager` and common lockfiles. Override that with\n`--package-manager npm`, `--package-manager pnpm`, `--package-manager yarn`, or\n`--package-manager bun`. Existing files are protected unless you pass `--force`.\n\n## Configuration\n\nSmall plugin repos can keep configuration in `package.json`:\n\n```json\n{\n  \"scripts\": {\n    \"plugin:check\": \"plugin-inspector inspect --no-openclaw\",\n    \"plugin:ci\": \"plugin-inspector ci --no-openclaw --runtime --mock-sdk --allow-execute\"\n  },\n  \"pluginInspector\": {\n    \"version\": 1,\n    \"plugin\": {\n      \"id\": \"weather\",\n      \"priority\": \"high\",\n      \"seams\": [\"dynamic-tool\"],\n      \"sourceRoot\": \"src\",\n      \"expect\": {\n        \"registrations\": [\"registerTool\"]\n      }\n    },\n    \"capture\": {\n      \"mockSdk\": true\n    }\n  }\n}\n```\n\nUse `plugin-inspector.config.json` for a standalone config file:\n\n```json\n{\n  \"version\": 1,\n  \"plugin\": {\n    \"id\": \"weather\",\n    \"priority\": \"high\",\n    \"seams\": [\"dynamic-tool\"],\n    \"sourceRoot\": \"src\",\n    \"expect\": {\n      \"registrations\": [\"registerTool\"]\n    }\n  },\n  \"capture\": {\n    \"mockSdk\": true\n  },\n  \"openclaw\": {\n    \"defaultCheckoutPath\": \"../openclaw\"\n  }\n}\n```\n\nInspect the resolved config before wiring CI:\n\n```bash\nplugin-inspector config --json\n```\n\nCopy-ready examples live in:\n\n- `examples/plugin-inspector.config.json`\n- `examples/package-json-plugin-inspector.json`\n\n## Commands\n\n| Command | Purpose |\n| --- | --- |\n| `plugin-inspector` | Default alias for `check`. |\n| `plugin-inspector check` | Script-friendly plugin-root check. |\n| `plugin-inspector inspect` | Plugin-root check unless `--config` is supplied; with `--config`, runs a fixture report. |\n| `plugin-inspector ci` | Compatibility report plus CI summary, SARIF, and JUnit outputs. |\n| `plugin-inspector config` | Print resolved plugin-root config as text or JSON. |\n| `plugin-inspector init` | Write starter config, scripts, and optional GitHub Actions workflow. |\n| `plugin-inspector report` | Run a fixture-suite config with many plugins. |\n| `plugin-inspector capture` | Runtime-capture one entrypoint directly. |\n\nCommon options:\n\n| Option | Meaning |\n| --- | --- |\n| `--plugin-root \u003cpath\u003e` / `--root \u003cpath\u003e` | Check a plugin somewhere other than the current directory. |\n| `--config \u003cpath\u003e` | Read a standalone config file. Required for fixture-suite `report`. |\n| `--out \u003cdir\u003e` | Write reports somewhere other than `reports/`. |\n| `--openclaw \u003cpath\u003e` | Compare against a local OpenClaw checkout. |\n| `--no-openclaw` | Disable OpenClaw checkout comparison. |\n| `--runtime` / `--capture` | Add opt-in runtime registration capture. |\n| `--no-runtime` / `--no-capture` | Disable runtime capture even when config enables it. |\n| `--mock-sdk` / `--sdk mock` | Use generated SDK and external-package mocks for runtime capture. |\n| `--real-sdk` / `--sdk real` | Use installed real SDK dependencies instead of mocks. |\n| `--allow-execute` | Permit commands that import plugin code. |\n| `--json` | Print machine-readable JSON to stdout. |\n| `--sarif [path]` | Write SARIF from `check` or `inspect`; `ci` enables this by default. |\n| `--junit [path]` | Write JUnit XML from `check` or `inspect`; `ci` enables this by default. |\n| `--no-sarif` / `--no-junit` | Disable default `ci` outputs. |\n\nRun the built-in help for the exact CLI surface:\n\n```bash\nplugin-inspector --help\n```\n\n## Runtime Capture\n\nRuntime capture imports plugin entrypoints in an isolated subprocess and records\nwhat `register(api)` does. Use it when static inspection cannot prove the actual\nregistrations made at runtime.\n\n```bash\nplugin-inspector inspect --no-openclaw --runtime --mock-sdk --allow-execute\n```\n\n`--allow-execute` is the deliberate safety switch. Without it, modes that import\nplugin code fail closed. The older environment guard still works for custom\nharnesses:\n\n```bash\nPLUGIN_INSPECTOR_EXECUTE_ISOLATED=1 plugin-inspector inspect --no-openclaw --runtime --mock-sdk\n```\n\nBy default, runtime capture uses generated mocks for `openclaw/plugin-sdk`\nsubpaths and unresolved external packages discovered in the plugin import graph.\nThat keeps compatibility CI offline and credential-free. It does not call live\nservices, launch OpenClaw, run provider SDKs, or emulate service lifecycle side\neffects.\n\nUse `--real-sdk` only when the plugin workspace already has real SDK\ndependencies installed and you intentionally want that path.\n\nRuntime capture writes:\n\n- `reports/plugin-inspector-runtime-capture.json`\n- `reports/plugin-inspector-runtime-capture.md`\n\nCapture one entrypoint directly:\n\n```bash\nplugin-inspector capture ./dist/index.js --mock-sdk --allow-execute\n```\n\n## CI\n\n`plugin-inspector ci` writes the normal compatibility report plus CI-native\nsummary, SARIF, and JUnit artifacts.\n\nMinimal GitHub Actions workflow:\n\n```yaml\nname: plugin-inspector\n\non:\n  pull_request:\n  push:\n    branches: [main]\n\njobs:\n  check:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v5\n      - uses: actions/setup-node@v5\n        with:\n          node-version: 24\n          cache: npm\n      - run: npm ci\n      - run: npx @openclaw/plugin-inspector ci --no-openclaw --runtime --mock-sdk --allow-execute\n      - uses: actions/upload-artifact@v5\n        if: always()\n        with:\n          name: plugin-inspector-reports\n          path: reports/plugin-inspector-*\n```\n\nGenerated `ci` artifacts:\n\n- `reports/plugin-inspector-report.json`\n- `reports/plugin-inspector-report.md`\n- `reports/plugin-inspector-issues.md`\n- `reports/plugin-inspector-ci-summary.json`\n- `reports/plugin-inspector-ci-summary.md`\n- `reports/plugin-inspector.sarif`\n- `reports/plugin-inspector.junit.xml`\n\nCI examples:\n\n- `examples/github-actions-plugin-inspector.yml`\n- `examples/github-actions-code-scanning.yml`\n- `examples/gitlab-ci-plugin-inspector.yml`\n- `examples/circleci-plugin-inspector.yml`\n\n## Report Surfaces\n\nThe compatibility report is the primary contract. Preserve field names and\nfinding codes because downstream CI and Crabpot reports may consume them.\n\nImportant report sections:\n\n| Field | Meaning |\n| --- | --- |\n| `status` | `pass` unless hard breakages exist. |\n| `summary` | Counts for fixtures, breakages, warnings, suggestions, issues, issue classes, and contract probes. |\n| `targetOpenClaw` | Status and public compatibility data read from the optional OpenClaw checkout. |\n| `fixtures` | Per-plugin metadata, hooks, registrations, manifest contracts, package data, and SDK imports. |\n| `breakages` | Blocking compatibility failures. |\n| `warnings` / `suggestions` | Non-blocking compatibility findings. |\n| `issues` | Normalized issue rows with severity and class. |\n| `contractProbes` | Suggested synthetic probes derived from observed contracts. |\n| `logs` | Informational inventory and coverage rows. |\n| `decisions` | Maintainer-facing follow-up or compatibility-policy decisions. |\n\nIssue classes currently flow through the reports as live issues, compat gaps,\ndeprecation warnings, inspector gaps, upstream metadata, and fixture regressions.\n\n## CI Policy And Shared Reporting Primitives\n\n`plugin-inspector` owns the shared CI policy and report rendering primitives.\nFixture-suite harnesses such as Crabpot should call these exports instead of\nreimplementing scoring, summaries, Markdown, SARIF, or JUnit handling.\n\nThe root API exposes grouped helpers:\n\n```js\nimport { ci } from \"@openclaw/plugin-inspector\";\n\nconst policyReport = ci.buildPolicyReport({\n  policy,\n  compatibilityReport,\n  executionResults,\n  strict: false,\n});\n\nawait ci.writePolicyReport(policyReport);\n```\n\nCI policy reports default to:\n\n- `reports/plugin-inspector-ci-policy.json`\n- `reports/plugin-inspector-ci-policy.md`\n\nA policy must use `version: 1` and define:\n\n- `allowedBlocked`\n- `expectedWarnings`\n- `thresholds`\n- `fixtureSets`\n\nPolicy scoring fails hard breakages, unknown blocked synthetic probes, hard ref\ndiff regressions, failed execution results, strict live P0 issues, and strict\nclassified blockers. Non-strict mode keeps classified blocked probes and live P0\nissues visible as warnings.\n\nCI summary helpers read the known report set from `reports/` and render one\nmachine-readable and one Markdown rollup:\n\n- compatibility\n- runtime capture\n- synthetic probes\n- cold import readiness\n- workspace plan\n- platform probes\n- import-loop profile\n- execution results\n- runtime profile\n- ref diff\n- profile diff\n- CI policy\n\n## Fixture Suites\n\nMost plugin authors should use the plugin-root workflow. Use fixture suites when\none repository intentionally checks many plugins or packages, as Crabpot does.\n\n```bash\nplugin-inspector report --config crabpot.config.json --out reports\nplugin-inspector report --config crabpot.config.json --out reports --check\nplugin-inspector ci --config crabpot.config.json --out reports --no-openclaw\n```\n\nFixture-suite configs are loaded through the explicit fixture helpers. That keeps\nnormal plugin-root configuration simple while still supporting bulk compatibility\nharnesses.\n\n## Public API\n\nPrefer the CLI for normal plugin repositories. Import the public API when a test\nharness needs to compose workflows directly:\n\n```js\nimport { pluginRoot } from \"@openclaw/plugin-inspector\";\n\nconst { report, paths } = await pluginRoot.runCheck({\n  pluginRoot: process.cwd(),\n  openclawPath: false,\n  outDir: \"reports\",\n});\n\nconsole.log(report.status, paths.jsonPath);\n```\n\nStable grouped facades:\n\n| Facade | Use |\n| --- | --- |\n| `pluginRoot` | Load config, inspect, run checks, capture entrypoints, or set up a plugin repo. |\n| `fixtureSuites` | Load fixture-suite configs, run reports, and build fixture-suite readiness plans. |\n| `staticInspection` | Inspect source text or fixture sets without the compatibility report layer. |\n| `reports` | Render/write reports and classify issue findings. |\n| `contracts` | Build, render, validate, and write contract captures and coverage. |\n| `ci` | Build summaries, policy reports, execution results, SARIF, and JUnit outputs. |\n| `runtime` | Build runtime profiles, profile diffs, ref diffs, and import-loop profiles. |\n| `synthetic` | Build and run synthetic probe plans. |\n\nNamed exports remain available for existing automation. Prefer the grouped\nfacades for new code because they show ownership and keep downstream wrappers\nthin.\n\n## Development\n\nRepository checks are intentionally small and offline:\n\n```bash\nnpm test\nnpm run release:contents\nnpm run check\n```\n\n`npm run check` runs the Node test suite and the package-contents guard. The\ncontents guard shells through `npm pack --dry-run --json` and verifies the npm\ntarball includes package entrypoints, examples, README assets, and no private\n`test/`, `scripts/`, or `.github/` paths.\n\nUseful release-prep commands:\n\n```bash\nnpm run release:local\nnpm run release:readiness\nnpm run release:notes\nnpm run release:plan\nnpm run release:crabpot -- --crabpot ../crabpot\n```\n\n`release:readiness` proves the local package and verifies Crabpot follow-through.\nIt does not publish.\n\nKeep this package dependency-light. Do not add runtime dependencies unless they\nremove real complexity. Default checks must stay offline and credential-free.\n\n## Release Notes\n\nThe package publishes from annotated `v*` tags through GitHub Actions. The\nrelease workflow runs the test suite, verifies the npm tarball, publishes the\nGitHub release, and publishes the public npm package through npm trusted\npublishing.\n\nBefore tagging a release:\n\n1. Move `CHANGELOG.md` `Unreleased` notes into a versioned section.\n2. Update `package.json` to the same version.\n3. Update Crabpot's `pluginInspectorRef` to the release commit.\n4. Run `npm run release:readiness`.\n5. Run the Crabpot plugin-inspector smoke commands printed by\n   `npm run release:crabpot -- --crabpot ../crabpot`.\n\nAfter npm publish, update Crabpot's package pin and run:\n\n```bash\nnpm run release:crabpot -- --crabpot ../crabpot --published\n```\n\nDo not publish npm packages without explicit owner approval.\n\n## Contribution Notes\n\nThere is no `CONTRIBUTING.md` in this repository. Until one exists, use the repo\nscripts above as the local contract and follow these project rules:\n\n- preserve stable report field names and finding codes;\n- prefer public OpenClaw plugin contracts over core internals;\n- isolate any OpenClaw source parsing behind explicit helpers;\n- keep runtime execution behind `--allow-execute` or\n  `PLUGIN_INSPECTOR_EXECUTE_ISOLATED=1`;\n- when behavior, entrypoints, release metadata, or the npm package version\n  change, update Crabpot's `@openclaw/plugin-inspector` pin/docs/smoke path and\n  run the Crabpot plugin-inspector smoke before calling the work done.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopenclaw%2Fplugin-inspector","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fopenclaw%2Fplugin-inspector","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopenclaw%2Fplugin-inspector/lists"}